From b9ea7218e3b6b72c6ac642b06783a889ab28db40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=98Liammcl=E2=80=99?= Date: Fri, 27 Dec 2024 01:10:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=9C=8D=E5=8A=A1=E6=A8=A1=E7=89=88=20?= =?UTF-8?q?=E6=8A=BD=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jsconfig.json | 7 +- src/components/SectionList/index.jsx | 76 +- src/components/TemplateTypeModal/index.jsx | 55 + src/contexts/ThemeContext.jsx | 2 +- src/hooks/supabaseService.js | 26 +- src/pages/company/customer/detail/index.jsx | 2 +- src/pages/company/quotation/detail/index.jsx | 2 +- src/pages/company/service/classify/index.jsx | 180 ++- .../detail/components/ProjectTemplate.jsx | 19 + .../detail/components/QuotationTemplate.jsx | 222 ++++ .../detail/components/TaskTemplate.jsx | 19 + src/pages/company/service/detail/index.jsx | 266 +---- src/pages/company/service/index.jsx | 1043 ++++++++--------- src/pages/company/supplier/detail/index.jsx | 2 +- .../resource/resourceTask/edit/index.jsx | 2 +- src/styles/main.scss | 38 +- 16 files changed, 1078 insertions(+), 883 deletions(-) create mode 100644 src/components/TemplateTypeModal/index.jsx create mode 100644 src/pages/company/service/detail/components/ProjectTemplate.jsx create mode 100644 src/pages/company/service/detail/components/QuotationTemplate.jsx create mode 100644 src/pages/company/service/detail/components/TaskTemplate.jsx diff --git a/jsconfig.json b/jsconfig.json index df83de4..9eeca62 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -2,7 +2,12 @@ "compilerOptions": { "baseUrl": ".", "paths": { - "@/*": ["src/*"] + "@/*": ["src/*"], + "@components/*": ["src/components/*"], + "@pages/*": ["src/pages/*"], + "@utils/*": ["src/utils/*"], + "@assets/*": ["src/assets/*"], + "@config/*": ["src/config/*"] } } } \ No newline at end of file diff --git a/src/components/SectionList/index.jsx b/src/components/SectionList/index.jsx index 38168af..d0f1ffe 100644 --- a/src/components/SectionList/index.jsx +++ b/src/components/SectionList/index.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useMemo } from 'react'; import { Form, Input, InputNumber, Button, Card, Typography, Modal, message, Divider, Select } from 'antd'; import { PlusOutlined, DeleteOutlined, EditOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons'; import { v4 as uuidv4 } from 'uuid'; @@ -247,12 +247,53 @@ const SectionList = ({ onClick={() => handleCreateCustom(add, fieldsLength)} className="w-1/3 border-2" > - 自定义小节 + 自定义模块 ); + // 修改项目小计的计算,将其封装为 memo 组件 + const ItemSubtotal = React.memo(({ quantity, price, currentCurrency }) => { + const subtotal = useMemo(() => { + const safeQuantity = Number(quantity) || 0; + const safePrice = Number(price) || 0; + return safeQuantity * safePrice; + }, [quantity, price]); + + return ( +
+ + {formatCurrency(subtotal, currentCurrency)} + +
+ ); + }); + + // 修改小节总计的计算,将其封装为 memo 组件 + const SectionTotal = React.memo(({ items, currentCurrency }) => { + const total = useMemo(() => { + if (!Array.isArray(items)) return 0; + return items.reduce((sum, item) => { + if (!item) return sum; + const safeQuantity = Number(item.quantity) || 0; + const safePrice = Number(item.price) || 0; + return sum + (safeQuantity * safePrice); + }, 0); + }, [items]); + + return ( +
+ + 小计总额: + + {formatCurrency(total, currentCurrency)} + + +
+ ); + }); + return ( <> @@ -439,16 +480,11 @@ const SectionList = ({ > -
- - {formatCurrency( - calculateItemAmount( - formValues?.sections?.[sectionIndex]?.items?.[itemIndex]?.quantity, - formValues?.sections?.[sectionIndex]?.items?.[itemIndex]?.price - ) - )} - -
+ {!isView && itemFields.length > 1 && ( @@ -368,348 +534,69 @@ const ServicePage = () => { }, ]; - // 子表格列定义 - const itemColumns = [ - { - title: "项目名称", - dataIndex: "name", - key: "name", - render: (text, record) => { - const isEditing = record.key === editingKey; - return isEditing ? ( - ( +
+ + {Object.entries(TEMPLATE_TYPES).map(([key, value]) => ( + - - - ) : ( - - - handleDeleteItem(record)} - > - - - - ); - }, - }, - ]; - - // 修改 expandedRowRender 函数,确保 key 的唯一性 - const expandedRowRender = (record) => ( -
- {record.attributes.sections?.map((section, sectionIndex) => ( - - - {section.sectionName || `服务类型 ${sectionIndex + 1}`} - - - 总计: ¥ - {section.items - .reduce( - (total, item) => - total + - (Number(item.price) || 0) * (Number(item.quantity) || 0), - 0 - ) - .toLocaleString("zh-CN", { - minimumFractionDigits: 2, - maximumFractionDigits: 2, - })} - -
- } - headStyle={{ - background: "rgba(59, 130, 246, 0.05)", - borderBottom: "1px solid rgba(59, 130, 246, 0.1)", - }} - style={{ - background: "rgba(59, 130, 246, 0.02)", - }} + + ))} + {selectedType && ( + + )} + + +