import React, { useState, useEffect, useMemo } from "react"; import { Form, Input, InputNumber, Button, Card, Typography, Modal, message, Divider, Select, } from "antd"; import { PlusOutlined, DeleteOutlined, EditOutlined, CheckOutlined, CloseOutlined, } from "@ant-design/icons"; import { v4 as uuidv4 } from "uuid"; import { supabase } from "@/config/supabase"; import { supabaseService } from "@/hooks/supabaseService"; const { Text } = Typography; import { defaultSymbol, formatExchangeRate } from "@/utils/exchange_rate"; const SectionList = ({ form, isView, formValues, type, currentCurrency = "TWD", taxRate, setTaxRate, }) => { const [editingSectionIndex, setEditingSectionIndex] = useState(null); const [editingSectionName, setEditingSectionName] = useState(""); const [templateModalVisible, setTemplateModalVisible] = useState(false); const [availableSections, setAvailableSections] = useState([]); const [loading, setLoading] = useState(false); const [units, setUnits] = useState([]); const [loadingUnits, setLoadingUnits] = useState(false); const fetchAvailableSections = async () => { try { setLoading(true); const { data: sections, error } = await supabase .from("resources") .select("*") .eq("type", "sections") .eq("attributes->>template_type", [type]) .order("created_at", { ascending: false }); if (error) throw error; setAvailableSections(sections || []); } catch (error) { message.error("获取小节模板失败"); console.error(error); } finally { setLoading(false); } }; const handleSectionNameEdit = (sectionIndex, initialValue) => { setEditingSectionIndex(sectionIndex); setEditingSectionName(initialValue || ""); }; const handleSectionNameSave = () => { if (!editingSectionName.trim()) { message.error("请输入小节名称"); return; } const sections = form.getFieldValue("sections"); const newSections = [...sections]; newSections[editingSectionIndex] = { ...newSections[editingSectionIndex], sectionName: editingSectionName.trim(), }; form.setFieldValue("sections", newSections); setEditingSectionIndex(null); setEditingSectionName(""); }; const handleAddItem = (add) => { add({ key: uuidv4(), name: "", description: "", quantity: 1, price: 0, unit: "", }); }; const handleUseTemplate = (template, add) => { const newSection = { key: uuidv4(), sectionName: template.attributes.name, items: (template.attributes.items || []).map((item) => ({ key: uuidv4(), name: item.name || "", description: item.description || "", price: item.price || 0, quantity: item.quantity || 1, unit: item.unit || "", })), }; add(newSection); setTemplateModalVisible(false); message.success("套用模版成功"); }; const handleCreateCustom = (add, fieldsLength) => { add({ key: uuidv4(), sectionName: `服务类型 ${fieldsLength + 1}`, items: [ { key: uuidv4(), name: "", description: "", quantity: 1, price: 0, unit: "", }, ], }); setTemplateModalVisible(false); }; const fetchUnits = async () => { setLoadingUnits(true); try { const { data: units } = await supabaseService.select("resources", { filter: { type: { eq: "units" }, "attributes->>template_type": { in: `(${type},common)` }, }, order: { column: "created_at", ascending: false, }, }); setUnits(units || []); } catch (error) { message.error("获取单位列表失败"); console.error(error); } finally { setLoadingUnits(false); } }; useEffect(() => { fetchUnits(); }, []); const handleAddUnit = async (unitName) => { try { const { error } = await supabase.from("resources").insert([ { type: "units", attributes: { name: unitName, template_type: type, }, schema_version: 1, }, ]); if (error) throw error; message.success("新增单位成功"); fetchUnits(); return true; } catch (error) { message.error("新增单位失败"); console.error(error); return false; } }; const renderTemplateModalContent = (add, fieldsLength) => (
您可以选择创建一个自定义模块开始使用
} onClick={() => handleCreateCustom(add, fieldsLength)} size="large" className="shadow-md hover:shadow-lg transition-shadow" > 创建自定义模块