250 lines
7.0 KiB
JavaScript
250 lines
7.0 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import {
|
|
Card,
|
|
Form,
|
|
Input,
|
|
Select,
|
|
Button,
|
|
Space,
|
|
Typography,
|
|
message,
|
|
} from "antd";
|
|
import {
|
|
ArrowLeftOutlined,
|
|
} from "@ant-design/icons";
|
|
import { useNavigate, useParams, useLocation } from "react-router-dom";
|
|
import { supabase } from "@/config/supabase";
|
|
import SectionList from '@/components/SectionList';
|
|
|
|
const { Title } = Typography;
|
|
|
|
const ServiceForm = () => {
|
|
const [form] = Form.useForm();
|
|
const navigate = useNavigate();
|
|
const { id } = useParams();
|
|
const [loading, setLoading] = useState(false);
|
|
const location = useLocation();
|
|
const isEdit = location.search.includes("edit=true");
|
|
const [formValues, setFormValues] = useState({
|
|
sections: [{ items: [{}] }],
|
|
currency: "CNY"
|
|
});
|
|
const [categories, setCategories] = useState([]);
|
|
|
|
useEffect(() => {
|
|
if (id) {
|
|
fetchServiceTemplate();
|
|
}
|
|
fetchCategories();
|
|
}, [id]);
|
|
|
|
const fetchServiceTemplate = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const { data, error } = await supabase
|
|
.from("resources")
|
|
.select("*")
|
|
.eq("id", id)
|
|
.single();
|
|
|
|
if (error) throw error;
|
|
const formData = {
|
|
templateName: data.attributes.templateName,
|
|
description: data.attributes.description,
|
|
category: data.attributes.category.map(v=>v.id),
|
|
sections: data.attributes.sections,
|
|
};
|
|
form.setFieldsValue(formData);
|
|
setFormValues(formData);
|
|
} catch (error) {
|
|
console.error("获取服务模版失败:", error);
|
|
message.error("获取服务模版失败");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const fetchCategories = async () => {
|
|
try {
|
|
const { data: categoriesData, error } = await supabase
|
|
.from('resources')
|
|
.select('*')
|
|
.eq('type', 'categories')
|
|
.order('created_at', { ascending: false });
|
|
|
|
if (error) throw error;
|
|
|
|
const formattedCategories = (categoriesData || []).map(category => ({
|
|
value: category.id,
|
|
label: category.attributes.name
|
|
}));
|
|
|
|
setCategories(formattedCategories);
|
|
} catch (error) {
|
|
message.error('获取分类数据失败');
|
|
console.error(error);
|
|
}
|
|
};
|
|
|
|
const onFinish = async (values) => {
|
|
try {
|
|
setLoading(true);
|
|
const categoryData = values.category.map(categoryId => {
|
|
const category = categories.find(c => c.value === categoryId);
|
|
return {
|
|
id: categoryId,
|
|
name: category.label
|
|
};
|
|
});
|
|
const serviceData = {
|
|
type: "serviceTemplate",
|
|
attributes: {
|
|
templateName: values.templateName,
|
|
description: values.description,
|
|
sections: values.sections,
|
|
category: categoryData,
|
|
},
|
|
};
|
|
|
|
let result;
|
|
if (id) {
|
|
result = await supabase
|
|
.from("resources")
|
|
.update(serviceData)
|
|
.eq("id", id)
|
|
.select();
|
|
} else {
|
|
result = await supabase
|
|
.from("resources")
|
|
.insert([serviceData])
|
|
.select();
|
|
}
|
|
|
|
if (result.error) throw result.error;
|
|
message.success("保存成功");
|
|
navigate("/company/serviceTeamplate");
|
|
} catch (error) {
|
|
console.error("保存失败:", error);
|
|
message.error("保存失败");
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleValuesChange = (changedValues, allValues) => {
|
|
setFormValues(allValues);
|
|
};
|
|
|
|
return (
|
|
<div className="bg-gradient-to-b from-gray-50 to-white min-h-screen p-6">
|
|
<Card
|
|
className="shadow-lg rounded-lg border-0"
|
|
title={
|
|
<div className="flex justify-between items-center py-2">
|
|
<div className="flex items-center space-x-3">
|
|
<Title level={4} className="mb-0 text-gray-800">
|
|
{id ? (isEdit ? "编辑服务模版" : "查看服务模版") : "新建服务模版"}
|
|
</Title>
|
|
<span className="text-gray-400 text-sm">
|
|
{id
|
|
? isEdit
|
|
? "请修改服务模版信息"
|
|
: "服务模版详情"
|
|
: "请填写服务模版信息"}
|
|
</span>
|
|
</div>
|
|
<Space size="middle">
|
|
<Button
|
|
icon={<ArrowLeftOutlined />}
|
|
onClick={() => navigate("/company/serviceTeamplate")}
|
|
>
|
|
返回
|
|
</Button>
|
|
<Button
|
|
type="primary"
|
|
onClick={() => form.submit()}
|
|
loading={loading}
|
|
>
|
|
保存
|
|
</Button>
|
|
</Space>
|
|
</div>
|
|
}
|
|
>
|
|
<Form
|
|
form={form}
|
|
onFinish={onFinish}
|
|
onValuesChange={handleValuesChange}
|
|
layout="vertical"
|
|
>
|
|
{/* 基本信息 */}
|
|
<Card
|
|
className="shadow-sm rounded-lg mb-6"
|
|
type="inner"
|
|
title={
|
|
<span className="flex items-center space-x-2 text-gray-700">
|
|
<span className="w-1 h-4 bg-blue-500 rounded-full" />
|
|
<span>基本信息</span>
|
|
</span>
|
|
}
|
|
bordered={false}
|
|
>
|
|
<div className="grid grid-cols-2 gap-6">
|
|
<Form.Item
|
|
label="模版名称"
|
|
name="templateName"
|
|
rules={[{ required: true, message: "请输入模版名称" }]}
|
|
>
|
|
<Input placeholder="请输入模版名称" />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label="模版分类"
|
|
name="category"
|
|
rules={[{ required: true, message: "请选择或输入分类" }]}
|
|
>
|
|
<Select
|
|
placeholder="请选择或输入分类"
|
|
showSearch
|
|
allowClear
|
|
mode="tags"
|
|
options={categories}
|
|
loading={loading}
|
|
/>
|
|
</Form.Item>
|
|
<Form.Item
|
|
label="模版描述"
|
|
name="description"
|
|
className="col-span-2"
|
|
>
|
|
<Input.TextArea rows={4} placeholder="请输入模版描述" />
|
|
</Form.Item>
|
|
</div>
|
|
</Card>
|
|
|
|
{/* 服务明细 */}
|
|
<Card
|
|
className="shadow-sm rounded-lg"
|
|
type="inner"
|
|
title={
|
|
<span className="flex items-center space-x-2 text-gray-700">
|
|
<span className="w-1 h-4 bg-blue-500 rounded-full" />
|
|
<span>服务明细</span>
|
|
</span>
|
|
}
|
|
bordered={false}
|
|
>
|
|
<SectionList
|
|
form={form}
|
|
isView={!isEdit && id}
|
|
formValues={formValues}
|
|
onValuesChange={handleValuesChange}
|
|
/>
|
|
</Card>
|
|
</Form>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ServiceForm;
|