import { useState, useEffect } from "react";
import {
Card,
Table,
Button,
Space,
Badge,
message,
Popconfirm,
Tag,
Divider,
Input,
InputNumber,
} from "antd";
import {
PlusOutlined,
FileTextOutlined,
ProjectOutlined,
CheckSquareOutlined,
DeleteOutlined,
EditOutlined,
SaveOutlined,
CloseOutlined,
} from "@ant-design/icons";
import { useNavigate } from "react-router-dom";
import { supabaseService } from "@/hooks/supabaseService";
import TemplateTypeModal from "@/components/TemplateTypeModal";
const ServicePage = () => {
const [loading, setLoading] = useState(false);
const [data, setData] = useState([]);
const [selectedType, setSelectedType] = useState(null);
const [editingKey, setEditingKey] = useState("");
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingItem, setEditingItem] = useState(null);
const navigate = useNavigate();
// 模板类型配置
const TEMPLATE_TYPES = {
quotation: {
label: "报价单模板",
icon: ,
color: "blue",
path: "/company/serviceTemplateInfo",
},
project: {
label: "专案模板",
icon: ,
color: "green",
path: "/company/serviceTemplateInfo",
},
task: {
label: "任务模板",
icon: ,
color: "purple",
path: "/company/serviceTemplateInfo",
},
};
// 获取服务模板列表
const fetchServices = async () => {
try {
setLoading(true);
const { data: services } = await supabaseService.select("resources", {
filter: {
type: { eq: "serviceTemplate" },
...(selectedType
? { "attributes->>template_type": { eq: selectedType } }
: {}),
},
order: {
column: "created_at",
ascending: false,
},
});
setData(services || []);
} catch (error) {
console.error("获取服务模板失败:", error);
message.error("获取服务模板失败");
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchServices();
}, [selectedType]);
// 删除服务模板
const handleDeleteService = async (serviceId) => {
try {
await supabaseService.delete("resources", { id: serviceId });
message.success("删除成功");
fetchServices();
} catch (error) {
console.error("删除失败:", error);
message.error("删除失败");
}
};
// 添加行内编辑相关方法
const handleSave = async (record, sectionKey, itemIndex) => {
try {
if (!editingItem) {
message.error("没有要保存的数据");
return;
}
const newData = [...data];
const targetIndex = newData.findIndex((item) => item.id === record.id);
if (targetIndex > -1) {
const item = newData[targetIndex];
const sections = [...item.attributes.sections];
const sectionIndex = sections.findIndex((s) => s.key === sectionKey);
if (sectionIndex > -1) {
// 使用 editingItem 中的值更新项目
sections[sectionIndex].items[itemIndex] = editingItem;
const updatedData = {
...item,
attributes: {
...item.attributes,
sections,
},
};
await supabaseService.update(
"resources",
{ id: record.id },
{ attributes: updatedData.attributes }
);
newData[targetIndex] = updatedData;
setData(newData);
setEditingKey("");
setEditingItem(null);
message.success("保存成功");
}
}
} catch (error) {
console.error("保存失败:", error);
message.error("保存失败");
}
};
const handleDeleteSection = async (record, sectionKey) => {
try {
const newData = [...data];
const targetIndex = newData.findIndex((item) => item.id === record.id);
if (targetIndex > -1) {
const item = newData[targetIndex];
const updatedSections = item.attributes.sections.filter(
(s) => s.key !== sectionKey
);
const updatedData = {
...item,
attributes: {
...item.attributes,
sections: updatedSections,
},
};
// 修改更新数据库的调用方式
await supabaseService.update(
"resources",
{ id: record.id },
{ attributes: updatedData.attributes }
);
newData[targetIndex] = updatedData;
setData(newData);
message.success("删除成功");
}
} catch (error) {
console.error("删除失败:", error);
message.error("删除失败");
}
};
const handleDeleteItem = async (record, sectionKey, itemIndex) => {
try {
const newData = [...data];
const targetIndex = newData.findIndex((item) => item.id === record.id);
if (targetIndex > -1) {
const item = newData[targetIndex];
const sections = [...item.attributes.sections];
const sectionIndex = sections.findIndex((s) => s.key === sectionKey);
if (sectionIndex > -1) {
sections[sectionIndex].items = sections[sectionIndex].items.filter(
(_, idx) => idx !== itemIndex
);
if (sections[sectionIndex].items.length === 0) {
sections.splice(sectionIndex, 1);
}
const updatedData = {
...item,
attributes: {
...item.attributes,
sections,
},
};
await supabaseService.update(
"resources",
{ id: record.id },
{ attributes: updatedData.attributes }
);
newData[targetIndex] = updatedData;
setData(newData);
message.success("删除成功");
}
}
} catch (error) {
console.error("删除失败:", error);
message.error("删除失败");
}
};
// 子表格列定义
const expandedRowRender = (record) => {
return (
{record.attributes.sections.map((section) => (
{section.sectionName}
handleDeleteSection(record, section.key)}
>
{
const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
return isEditing ? (
{
setEditingItem((prev) => ({
...prev || item,
name: e.target.value
}));
}}
/>
) : (
{text}
);
},
},
{
title: "单位",
dataIndex: "unit",
key: "unit",
width: "10%",
render: (text, item, index) => {
const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
return isEditing ? (
{
setEditingItem((prev) => ({
...prev || item,
unit: e.target.value
}));
}}
/>
) : (
{text}
);
},
},
{
title: "单价",
dataIndex: "price",
key: "price",
width: "10%",
render: (text, item, index) => {
const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
return isEditing ? (
{
setEditingItem((prev) => ({
...prev || item,
price: value
}));
}}
/>
) : (
{text}
);
},
},
{
title: "数量",
dataIndex: "quantity",
key: "quantity",
width: "10%",
render: (text, item, index) => {
const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
return isEditing ? (
{
setEditingItem((prev) => ({
...prev || item,
quantity: value
}));
}}
/>
) : (
{text}
);
},
},
{
title: "描述",
dataIndex: "description",
key: "description",
render: (text, item, index) => {
const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
return isEditing ? (
{
setEditingItem((prev) => ({
...prev || item,
description: e.target.value
}));
}}
/>
) : (
{text}
);
},
},
{
title: "操作",
key: "action",
width: 150,
render: (_, item, index) => {
const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
return (
{isEditing ? (
<>
handleSave(record, section.key, index)}
/>
{
setEditingKey("");
setEditingItem(null);
}}
/>
>
) : (
<>
{
setEditingKey(`${record.id}-${section.key}-${index}`);
setEditingItem(item); // 初始化编辑项
}}
/>
handleDeleteItem(record, section.key, index)}
>
>
)}
);
},
},
]}
/>
))}
);
};
const handleNavigateToTemplate = (type, id, mode = "isView") => {
const basePath = TEMPLATE_TYPES[type]?.path;
if (!basePath) return;
const path = id ? `${basePath}/${id}` : basePath;
if (mode === "create") {
navigate(`${basePath}`);
} else {
navigate(`${basePath}/${id}?type=${type}&${mode}=true`);
}
};
// 处理模板类型选择
const handleTemplateSelect = (type) => {
handleNavigateToTemplate(type, null, "create");
setIsModalOpen(false);
};
// 表格列定义
const columns = [
{
title: "模板名称",
dataIndex: ["attributes", "templateName"],
key: "templateName",
className: "min-w-[200px]",
},
{
title: "模板类型",
dataIndex: ["attributes", "template_type"],
key: "template_type",
filters: Object.entries(TEMPLATE_TYPES).map(([key, value]) => ({
text: value.label,
value: key,
})),
onFilter: (value, record) => record.attributes.template_type === value,
render: (type) => {
const typeConfig = TEMPLATE_TYPES[type];
return typeConfig ? (
{typeConfig.label}
) : null;
},
},
{
title: "分类",
dataIndex: ["attributes", "category"],
key: "category",
render: (categories) => {
if (!categories || !Array.isArray(categories)) return null;
return (
{categories.map((category) => (
{category.name}
))}
);
},
},
{
title: "描述",
dataIndex: ["attributes", "description"],
key: "description",
className: "min-w-[100px]",
ellipsis: true,
},
{
title: "创建时间",
dataIndex: "created_at",
key: "created_at",
render: (text) => new Date(text).toLocaleString(),
sorter: (a, b) => new Date(a.created_at) - new Date(b.created_at),
},
{
title: "操作",
key: "action",
fixed: "right",
width: 220,
render: (_, record) => (
handleDeleteService(record.id)}
okText="确定"
cancelText="取消"
okButtonProps={{ danger: true }}
>
),
},
];
// 表格顶部的操作栏
const TableHeader = () => (
{Object.entries(TEMPLATE_TYPES).map(([key, value]) => (
))}
{selectedType && (
)}
}
onClick={() => setIsModalOpen(true)}
className="bg-blue-500 hover:bg-blue-600"
>
新建模板
);
return (
record.attributes.sections?.length > 0,
}}
pagination={{
pageSize: 10,
showTotal: (total) => `共 ${total} 条`,
}}
className="bg-white rounded-lg"
/>
{/* 添加模板类型选择弹窗 */}
setIsModalOpen(false)}
onSelect={handleTemplateSelect}
/>
);
};
export default ServicePage;