From 057c4ffe5db76cc96395c41c339b14c676e18a9e Mon Sep 17 00:00:00 2001 From: Li1304553726 <1304553726@qq.com> Date: Tue, 8 Apr 2025 09:18:42 +0800 Subject: [PATCH] add --- .../sport-standard/sportStandard.service.ts | 21 ++++--- .../assessmentstandard/assessment-modal.tsx | 33 +++++++++- .../assessment-standard-provider.tsx | 23 ++++++- .../standard-create-content.tsx | 60 ++++++++++++++++--- apps/web/src/app/main/sport/page.tsx | 1 - 5 files changed, 118 insertions(+), 20 deletions(-) diff --git a/apps/server/src/models/sport-standard/sportStandard.service.ts b/apps/server/src/models/sport-standard/sportStandard.service.ts index e228e02..b4816c9 100644 --- a/apps/server/src/models/sport-standard/sportStandard.service.ts +++ b/apps/server/src/models/sport-standard/sportStandard.service.ts @@ -91,13 +91,21 @@ export class SportStandardService extends BaseService (a.start || 0) - (b.start || 0), + ); - if (current.end !== next.start) { - throw new Error('年龄段必须连续且不重叠'); + for (let i = 0; i < sortedRanges.length - 1; i++) { + const current = sortedRanges[i]; + const next = sortedRanges[i + 1]; + // 检查重叠 + if ((current.end || Infinity) >= next.start) { + throw new Error(`年龄范围 ${current.label} 和 ${next.label} 重叠`); + } + // 检查连续性(允许有间隔) + if ((current.end || Infinity) + 1 > next.start) { + throw new Error(`年龄范围 ${current.label} 和 ${next.label} 不连续`); } } } @@ -109,7 +117,6 @@ export class SportStandardService extends BaseService
- + ({ + validator(_, value) { + const end = getFieldValue('end'); + if (end && value > end) { + return Promise.reject(new Error('起始年龄不能大于结束年龄')); + } + return Promise.resolve(); + }, + }), + ]} + > - + ({ + validator(_, value) { + const start = getFieldValue('start'); + if (value && start > value) { + return Promise.reject(new Error('结束年龄不能小于起始年龄')); + } + return Promise.resolve(); + }, + }), + ]} + > diff --git a/apps/web/src/app/admin/assessmentstandard/assessment-standard-provider.tsx b/apps/web/src/app/admin/assessmentstandard/assessment-standard-provider.tsx index 555dd7f..c4168d4 100644 --- a/apps/web/src/app/admin/assessmentstandard/assessment-standard-provider.tsx +++ b/apps/web/src/app/admin/assessmentstandard/assessment-standard-provider.tsx @@ -8,6 +8,7 @@ import React, { // import { useDebounce } from "use-debounce"; import { Form, FormInstance } from 'antd'; import { api } from "@nice/client"; +import toast from "react-hot-toast"; interface AssessmentStandardContextType { form: FormInstance; @@ -59,8 +60,26 @@ export function AssessmentStandardProvider({ children }: AssessmentStandardProvi }; // 处理年龄范围模态框确定 const handleAgeOk = (values: any) => { - console.log('values',values) + console.log('values', values) const { start, end } = values; + if (end && start == end) { + toast.error("年龄范围不能相同"); + return; + } + //年龄校验 + const isOverlap = ageRanges.some(range => { + if (end) { + return (start >= range.start && start <= (range.end || Infinity)) || + (end >= range.start && end <= (range.end || Infinity)) || + (start <= range.start && end >= (range.end || Infinity)); + } else { + return start >= range.start && start <= (range.end || Infinity); + } + }); + if (isOverlap) { + toast.error("年龄范围不能与已存在的范围重叠"); + return; + } const newRange = { start, end, @@ -101,7 +120,7 @@ export function AssessmentStandardProvider({ children }: AssessmentStandardProvi id: item.id, name: item.name, unit: item.unit, - deletedAt:item.deletedAt + deletedAt: item.deletedAt })), sportProjectLoading, ageRanges, diff --git a/apps/web/src/app/admin/assessmentstandard/standard-create-content.tsx b/apps/web/src/app/admin/assessmentstandard/standard-create-content.tsx index 0dd3ef3..d237366 100644 --- a/apps/web/src/app/admin/assessmentstandard/standard-create-content.tsx +++ b/apps/web/src/app/admin/assessmentstandard/standard-create-content.tsx @@ -70,6 +70,25 @@ export default function StandardCreateContent() { } } const createStandard = async ()=>{ + // 新增年龄范围校验 + const sortedRanges = [...ageRanges].sort((a, b) => a.start - b.start); + for (let i = 0; i < sortedRanges.length - 1; i++) { + const current = sortedRanges[i]; + const next = sortedRanges[i + 1]; + + // 检查是否有重叠 + if ((current.end || Infinity) >= next.start) { + toast.error(`年龄范围 ${current.label} 和 ${next.label} 重叠`); + return; + } + + // 检查是否有间隔 + if ((current.end || Infinity) + 1 !== next.start) { + toast.error(`年龄范围 ${current.label} 和 ${next.label} 不连续`); + return; + } + } + const result = await createSportStandard.mutateAsync({ data: { projectId: form.getFieldsValue().projectId, @@ -83,6 +102,23 @@ export default function StandardCreateContent() { toast.success("保存标准成功") } const updateStandard = async ()=>{ + // 新增年龄范围校验 + const sortedRanges = [...ageRanges].sort((a, b) => a.start - b.start); + for (let i = 0; i < sortedRanges.length - 1; i++) { + const current = sortedRanges[i]; + const next = sortedRanges[i + 1]; + + if ((current.end || Infinity) >= next.start) { + toast.error(`年龄范围 ${current.label} 和 ${next.label} 重叠`); + return; + } + + if ((current.end || Infinity) + 1 !== next.start) { + toast.error(`年龄范围 ${current.label} 和 ${next.label} 不连续`); + return; + } + } + const result = await updateSportStandard.mutateAsync({ data: { id: data[0].id, @@ -104,18 +140,20 @@ export default function StandardCreateContent() { }); useEffect(() => { if (data && data.length) { - setIsStandardCreate(false) - const records: { - score: number; - standards: number[]; - }[] = Object.entries(JSON.parse(String(data[0].scoreTable))).map(([score, standards]) => ({ + setIsStandardCreate(false); + const records = Object.entries(JSON.parse(String(data[0].scoreTable))).map(([score, standards]) => ({ score: Number(score), standards: standards as number[] })); - setAgeRanges(JSON.parse(String(data[0].ageRanges))) - setRecords(records) + setAgeRanges(JSON.parse(String(data[0].ageRanges))); + setRecords(records); + } else { + // 如果没有找到数据,重置状态 + setIsStandardCreate(true); + setAgeRanges([]); + setRecords([]); } - }, [data]) + }, [data, projectId, gender, personType]); // 添加更多依赖项 return (
@@ -124,6 +162,12 @@ export default function StandardCreateContent() { style={{ width: 200 }} placeholder="选择考核项目" options={sportProjectList?.filter(item=>item.deletedAt === null)?.map((item) => ({ value: item.id, label: `${item.name}(${item.unit})` })) || []} + onChange={() => { + // 重置状态,强制重新加载 + setIsStandardCreate(true); + setAgeRanges([]); + setRecords([]); + }} /> diff --git a/apps/web/src/app/main/sport/page.tsx b/apps/web/src/app/main/sport/page.tsx index 1f3259b..8cf8e7a 100644 --- a/apps/web/src/app/main/sport/page.tsx +++ b/apps/web/src/app/main/sport/page.tsx @@ -203,7 +203,6 @@ export default function SportPage() { - {staffsWithScoreLoading ? ( ) : (