This commit is contained in:
liamzi
2024-12-31 14:25:51 +08:00
parent 0ec46f2fbe
commit 73f8033183
5 changed files with 34 additions and 80 deletions

View File

@@ -2,18 +2,24 @@ import { Button, Drawer, Input, Space, message } from 'antd';
import { useChat } from "ai/react"; import { useChat } from "ai/react";
import { CodeHighlight } from "@mantine/code-highlight"; import { CodeHighlight } from "@mantine/code-highlight";
import { DownloadOutlined } from '@ant-design/icons'; import { DownloadOutlined } from '@ant-design/icons';
import { useEffect, useRef } from 'react'; import { useRef, useEffect } from 'react';
import { useSessionStorage } from 'react-use';
export default function ChatAIDrawer({ open, onClose, onExport }) { export default function ChatAIDrawer({ open, onClose, onExport }) {
const STORAGE_KEY = 'chat_history'; const STORAGE_KEY = 'chat_history';
const [storedMessages, setStoredMessages] = useSessionStorage(STORAGE_KEY, '[]');
const { messages, input, handleSubmit, handleInputChange, isLoading, setMessages } = useChat({ const { messages, input, handleSubmit, handleInputChange, isLoading, setMessages } = useChat({
api: "https://test-ai-quirkyai.vercel.app/api/chat", api: "https://test-ai-quirkyai.vercel.app/api/chat",
initialMessages: JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'), initialMessages: JSON.parse(storedMessages),
}); });
const messagesEndRef = useRef(null); const messagesEndRef = useRef(null);
// 当 messages 改变时,自动更新 session storage
useEffect(() => { useEffect(() => {
localStorage.setItem(STORAGE_KEY, JSON.stringify(messages)); setStoredMessages(JSON.stringify(messages));
}, [messages]); }, [messages, setStoredMessages]);
// 新消息时自动滚动到底部 // 新消息时自动滚动到底部
useEffect(() => { useEffect(() => {
@@ -40,7 +46,7 @@ export default function ChatAIDrawer({ open, onClose, onExport }) {
size="small" size="small"
onClick={() => { onClick={() => {
setMessages([]); setMessages([]);
localStorage.removeItem(STORAGE_KEY); setStoredMessages('[]');
message.success('历史记录已清空'); message.success('历史记录已清空');
}} }}
> >

View File

@@ -121,7 +121,7 @@ const QuotationForm = () => {
// 修改初始值确保每个项目都有唯一ID // 修改初始值确保每个项目都有唯一ID
const initialValues = { const initialValues = {
currency: "CNY", currency: "TWD",
sections: [ sections: [
{ {
key: uuidv4(), key: uuidv4(),
@@ -129,10 +129,10 @@ const QuotationForm = () => {
items: [ items: [
{ {
key: uuidv4(), key: uuidv4(),
productName: "", name: "",
quantity: 1, quantity: 1,
price: 0, price: 0,
note: "", description: "",
unit: "", unit: "",
}, },
], ],
@@ -150,10 +150,10 @@ const QuotationForm = () => {
const handleAddItem = (add, sectionIndex) => { const handleAddItem = (add, sectionIndex) => {
add({ add({
key: uuidv4(), key: uuidv4(),
productName: "", name: "",
quantity: 1, quantity: 1,
price: 0, price: 0,
note: "", description: "",
}); });
}; };
@@ -173,16 +173,16 @@ const QuotationForm = () => {
quataName: data.attributes.quataName, quataName: data.attributes.quataName,
customers: data.attributes.customers.map((customer) => customer.id) || [], customers: data.attributes.customers.map((customer) => customer.id) || [],
description: data.attributes.description, description: data.attributes.description,
currency: data.attributes.currency || "CNY", currency: data.attributes.currency || "TWD",
sections: data.attributes.sections.map((section) => ({ sections: data.attributes.sections.map((section) => ({
key: uuidv4(), key: uuidv4(),
sectionName: section.sectionName, sectionName: section.sectionName,
items: section.items.map((item) => ({ items: section.items.map((item) => ({
key: uuidv4(), key: uuidv4(),
productName: item.name, name: item.name,
quantity: Number(item.quantity) || 0, quantity: Number(item.quantity) || 0,
price: Number(item.price) || 0, price: Number(item.price) || 0,
note: item.description || "", description: item.description || "",
unit: item.unit || "", unit: item.unit || "",
})), })),
})), })),
@@ -192,7 +192,7 @@ const QuotationForm = () => {
form.setFieldsValue(formData); form.setFieldsValue(formData);
setFormValues(formData); setFormValues(formData);
setCurrentCurrency(data.attributes.currency || "CNY"); setCurrentCurrency(data.attributes.currency || "TWD");
setTaxRate(data.attributes.taxRate || 0); setTaxRate(data.attributes.taxRate || 0);
setDiscount(data.attributes.discount || 0); setDiscount(data.attributes.discount || 0);
@@ -225,57 +225,6 @@ const QuotationForm = () => {
} }
}; };
// 使用选中的模版
const handleUseTemplate = (template) => {
const sections = form.getFieldValue("sections") || [];
const newSection = {
key: uuidv4(),
sectionName: template.attributes.name,
items: (template.attributes.items || []).map((item) => ({
key: uuidv4(),
productName: item.name || "",
note: item.description || "",
price: item.price || 0,
quantity: item.quantity || 1,
unit: item.unit || "",
})),
};
const newSections = [...sections, newSection];
form.setFieldValue("sections", newSections);
// 更新 formValues 以触发重新计算
const currentFormValues = form.getFieldsValue();
setFormValues({
...currentFormValues,
sections: newSections,
});
setTemplateModalVisible(false);
message.success("套用模版成功");
};
// 创建自定义小节
const handleCreateCustom = () => {
const sections = form.getFieldValue("sections") || [];
const newSection = {
key: uuidv4(),
sectionName: `服务类型 ${sections.length + 1}`,
items: [
{
key: uuidv4(),
productName: "",
note: "",
price: 0,
quantity: 1,
unit: "",
},
],
};
form.setFieldValue("sections", [...sections, newSection]);
setTemplateModalVisible(false);
};
@@ -295,22 +244,22 @@ const QuotationForm = () => {
const quotationData = { const quotationData = {
quataName: template.attributes.templateName, quataName: template.attributes.templateName,
description: template.attributes.description, description: template.attributes.description,
currency: template.attributes.currency || "CNY", currency: template.attributes.currency || "TWD",
category: template.attributes.category, category: template.attributes.category,
sections: template.attributes.sections.map((section) => ({ sections: template.attributes.sections.map((section) => ({
key: uuidv4(), key: uuidv4(),
sectionName: section.sectionName, sectionName: section.sectionName,
items: section.items.map((item) => ({ items: section.items.map((item) => ({
key: uuidv4(), key: uuidv4(),
productName: item.name, name: item.name,
quantity: item.quantity, quantity: item.quantity,
price: item.price, price: item.price,
note: item.description, description: item.description,
unit: item.unit, unit: item.unit,
})), })),
})), })),
}; };
setCurrentCurrency(template.attributes.currency || "CNY"); setCurrentCurrency(template.attributes.currency || "TWD");
form.setFieldsValue(quotationData); form.setFieldsValue(quotationData);
setFormValues(quotationData); setFormValues(quotationData);
} }
@@ -350,11 +299,11 @@ const QuotationForm = () => {
sections: values.sections.map((section) => ({ sections: values.sections.map((section) => ({
sectionName: section.sectionName, sectionName: section.sectionName,
items: section.items.map((item) => ({ items: section.items.map((item) => ({
name: item.productName, name: item.name,
unit: item.unit, unit: item.unit,
price: item.price, price: item.price,
quantity: item.quantity, quantity: item.quantity,
description: item.note, description: item.description,
})), })),
})), })),
beforeTaxAmount, beforeTaxAmount,
@@ -520,7 +469,7 @@ const QuotationForm = () => {
> >
<Input <Input
placeholder="请输入活动名" placeholder="请输入活动名"
className="rounded-md hover:border-blue-400 focus:border-blue-500" className=" hover:border-blue-400 focus:border-blue-500"
/> />
</Form.Item> </Form.Item>
@@ -544,7 +493,7 @@ const QuotationForm = () => {
<Select <Select
mode="multiple" mode="multiple"
placeholder="请选择客户" placeholder="请选择客户"
className="rounded-md hover:border-blue-400 focus:border-blue-500" className=" hover:border-blue-400 focus:border-blue-500"
showSearch showSearch
optionFilterProp="children" optionFilterProp="children"
filterOption={(input, option) => filterOption={(input, option) =>

View File

@@ -126,7 +126,7 @@ const Classify = ({activeType,typeList}) => {
> >
<Input <Input
placeholder="请输入分类名称" placeholder="请输入分类名称"
className="rounded-md"
/> />
</Form.Item> </Form.Item>
) : ( ) : (
@@ -148,7 +148,7 @@ const Classify = ({activeType,typeList}) => {
<Select <Select
options={typeList} options={typeList}
placeholder="请选择模板类型" placeholder="请选择模板类型"
className="w-full rounded-md" className="w-full "
/> />
</Form.Item> </Form.Item>
) : ( ) : (

View File

@@ -123,7 +123,6 @@ const UnitManagement = ({ activeType, typeList }) => {
> >
<Input <Input
placeholder="请输入单位名称" placeholder="请输入单位名称"
className="rounded-md"
/> />
</Form.Item> </Form.Item>
) : ( ) : (
@@ -145,7 +144,7 @@ const UnitManagement = ({ activeType, typeList }) => {
<Select <Select
options={typeList} options={typeList}
placeholder="请选择模板类型" placeholder="请选择模板类型"
className="w-full rounded-md" className="w-full "
/> />
</Form.Item> </Form.Item>
) : ( ) : (

View File

@@ -341,7 +341,7 @@ export default function TaskForm() {
<Select <Select
mode="multiple" mode="multiple"
placeholder="请选择客户" placeholder="请选择客户"
className="rounded-md hover:border-blue-400 focus:border-blue-500" className=" hover:border-blue-400 focus:border-blue-500"
showSearch showSearch
optionFilterProp="children" optionFilterProp="children"
filterOption={(input, option) => filterOption={(input, option) =>
@@ -363,7 +363,7 @@ export default function TaskForm() {
allowClear allowClear
loading={loadingUnits} loading={loadingUnits}
placeholder="请选择任务状态" placeholder="请选择任务状态"
className="rounded-md hover:border-blue-400 focus:border-blue-500" className=" hover:border-blue-400 focus:border-blue-500"
options={units.map((unit) => ({ options={units.map((unit) => ({
label: unit.attributes.name, label: unit.attributes.name,
value: unit.attributes.name, value: unit.attributes.name,
@@ -377,7 +377,7 @@ export default function TaskForm() {
rules={[{ required: true, message: "请选择时间范围" }]} rules={[{ required: true, message: "请选择时间范围" }]}
> >
<DatePicker.RangePicker <DatePicker.RangePicker
className="w-full rounded-md hover:border-blue-400 focus:border-blue-500" className="w-full hover:border-blue-400 focus:border-blue-500"
format="YYYY-MM-DD" format="YYYY-MM-DD"
onChange={(dates) => { onChange={(dates) => {
if (dates) { if (dates) {