fix
This commit is contained in:
@@ -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('历史记录已清空');
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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) =>
|
||||||
|
|||||||
@@ -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>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user