diff --git a/src/pages/company/service/detail/components/TaskTemplate.jsx b/src/pages/company/service/detail/components/TaskTemplate.jsx
index f3b5578..c6a9b38 100644
--- a/src/pages/company/service/detail/components/TaskTemplate.jsx
+++ b/src/pages/company/service/detail/components/TaskTemplate.jsx
@@ -11,9 +11,7 @@ const TaskTemplate = ({ id, isView, onCancel,isEdit }) => {
sections: [{ items: [{}] }],
});
const [categories, setCategories] = useState([]);
-
useEffect(() => {
-
if (id) {
fetchServiceTemplate();
}
diff --git a/src/pages/company/service/index.jsx b/src/pages/company/service/index.jsx
index edd8bb5..1048e2f 100644
--- a/src/pages/company/service/index.jsx
+++ b/src/pages/company/service/index.jsx
@@ -11,6 +11,8 @@ import {
Divider,
Input,
InputNumber,
+ Select,
+ DatePicker,
} from "antd";
import {
PlusOutlined,
@@ -26,6 +28,9 @@ import {
import { useNavigate } from "react-router-dom";
import { supabaseService } from "@/hooks/supabaseService";
import TemplateTypeModal from "@/components/TemplateTypeModal";
+import { useCallback } from "react";
+import { useMemo } from "react";
+import dayjs from "dayjs";
const ServicePage = () => {
const [loading, setLoading] = useState(false);
@@ -34,9 +39,14 @@ const ServicePage = () => {
const [editingKey, setEditingKey] = useState("");
const [isModalOpen, setIsModalOpen] = useState(false);
const [editingItem, setEditingItem] = useState(null);
+ const [loadingUnits, setloadingUnits] = useState(false);
const navigate = useNavigate();
-
- // 模板类型配置
+ const [units, setUnits] = useState([]);
+ const unitsFilter = useMemo(() => (type) =>
+ units.filter(v =>
+ v.attributes.template_type === type || v.attributes.template_type === "common"
+ )
+ , [units]);
const TEMPLATE_TYPES = {
quotation: {
label: "报价单模板",
@@ -78,17 +88,38 @@ const ServicePage = () => {
setData(services || []);
} catch (error) {
console.error("获取服务模板失败:", error);
- message.error("获取服务模板失败");
+ message.error("获取服���模板失败");
} finally {
setLoading(false);
}
};
-
+ useEffect(() => {
+ fetchUnits();
+ }, []);
useEffect(() => {
fetchServices();
}, [selectedType]);
- // 删除服务模板
+ const fetchUnits = async () => {
+ setloadingUnits(true);
+ try {
+ const { data: units } = await supabaseService.select("resources", {
+ filter: {
+ type: { eq: "units" },
+ },
+ order: {
+ column: "created_at",
+ ascending: false,
+ },
+ });
+ setUnits(units || []);
+ } catch (error) {
+ message.error("获取单位列表失败");
+ console.error(error);
+ } finally {
+ setloadingUnits(false);
+ }
+ };
const handleDeleteService = async (serviceId) => {
try {
await supabaseService.delete("resources", { id: serviceId });
@@ -224,301 +255,420 @@ const ServicePage = () => {
}
};
- const table_warp=(record,section)=>{
-
- switch(record.attributes.template_type){
- case 'quotation':
-return [
- {
- title: "名称",
- dataIndex: "name",
- key: "name",
- width: "15%",
- render: (text, item, index) => {
- 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)}
- >
-
-
- >
- )}
-
- );
- },
- },
-]
-case 'task':
- return [
- {
- title: "名称",
- dataIndex: "name",
- key: "name",
- width: "15%",
- render: (text, item, index) => {
- const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
- return isEditing ? (
- {
- setEditingItem((prev) => ({
- ...prev || item,
- name: e.target.value
- }));
- }}
- />
- ) : (
- {text}
- );
- },
- },
- {
- title: "执行状态",
- dataIndex: "unit",
- key: "unit",
- 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: "timeRange",
- key: "startTime",
- render: (timeRange) => timeRange?.[0] || '-',
- },
- {
- title: "结束时间",
- dataIndex: "timeRange",
- key: "endTime",
- render: (timeRange) => timeRange?.[1] || '-',
- },
- {
- 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",
- render: (_, item, index) => {
- const isEditing = editingKey === `${record.id}-${section.key}-${index}`;
- return (
-
- {isEditing ? (
- <>
- handleSave(record, section.key, index)}
- />
- {
- setEditingKey("");
- setEditingItem(null);
+ const table_warp = (record, section) => {
+ switch (record.attributes.template_type) {
+ case "quotation":
+ return [
+ {
+ title: "名称",
+ dataIndex: "name",
+ key: "name",
+ width: "15%",
+ render: (text, item, index) => {
+ const isEditing =
+ editingKey === `${record.id}-${section.key}-${index}`;
+ return isEditing ? (
+ {
+ setEditingItem((prev) => ({
+ ...(prev || item),
+ name: e.target.value,
+ }));
}}
/>
- >
- ) : (
- <>
- {/* {
- setEditingKey(`${record.id}-${section.key}-${index}`);
- setEditingItem(item); // 初始化编辑项
+ ) : (
+ {text}
+ );
+ },
+ },
+ {
+ title: "单位",
+ dataIndex: "unit",
+ key: "unit",
+ width: "10%",
+ render: (text, item, index) => {
+ const isEditing =
+ editingKey === `${record.id}-${section.key}-${index}`;
+ return isEditing ? (
+
- );
- },
- },
- ]
- case "project":
- default:[]
- }
-
+ />
+ ) : (
+ {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)
+ }
+ >
+
+
+ >
+ )}
+
+ );
+ },
+ },
+ ];
+ case "task":
+ return [
+ {
+ title: "名称",
+ dataIndex: "name",
+ key: "name",
+ width: "15%",
+ render: (text, item, index) => {
+ const isEditing =
+ editingKey === `${record.id}-${section.key}-${index}`;
+ return isEditing ? (
+ {
+ setEditingItem((prev) => ({
+ ...(prev || item),
+ name: e.target.value,
+ }));
+ }}
+ />
+ ) : (
+ {text}
+ );
+ },
+ },
+ {
+ title: "执行状态",
+ dataIndex: "unit",
+ key: "unit",
+ render: (text, item, index) => {
+ const isEditing =
+ editingKey === `${record.id}-${section.key}-${index}`;
+ return isEditing ? (
+