This commit is contained in:
Li1304553726 2025-04-08 09:18:42 +08:00
parent 1fb33c2408
commit 057c4ffe5d
5 changed files with 118 additions and 20 deletions

View File

@ -91,13 +91,21 @@ export class SportStandardService extends BaseService<Prisma.SportStandardDelega
return result; return result;
} }
private validateAgeRanges(ranges: AgeRange[]) { private validateAgeRanges(ranges: AgeRange[]) {
// 检查年龄段是否按顺序排列且无重叠 // 先按起始年龄排序
for (let i = 0; i < ranges.length - 1; i++) { const sortedRanges = [...ranges].sort(
const current = ranges[i]; (a, b) => (a.start || 0) - (b.start || 0),
const next = ranges[i + 1]; );
if (current.end !== next.start) { for (let i = 0; i < sortedRanges.length - 1; i++) {
throw new Error('年龄段必须连续且不重叠'); 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<Prisma.SportStandardDelega
} }
}); });
} }
async updateStandard(data: { async updateStandard(data: {
id: string; id: string;
ageRanges: AgeRange[]; ageRanges: AgeRange[];

View File

@ -11,10 +11,39 @@ export default function AssessmentModal() {
onCancel={handleAgeCancel} onCancel={handleAgeCancel}
> >
<Form form={ageForm} onFinish={handleAgeOk}> <Form form={ageForm} onFinish={handleAgeOk}>
<Form.Item name="start" label="起始年龄" rules={[{ required: true }]}> <Form.Item
name="start"
label="起始年龄"
rules={[
{ required: true },
({ getFieldValue }) => ({
validator(_, value) {
const end = getFieldValue('end');
if (end && value > end) {
return Promise.reject(new Error('起始年龄不能大于结束年龄'));
}
return Promise.resolve();
},
}),
]}
>
<InputNumber min={0} /> <InputNumber min={0} />
</Form.Item> </Form.Item>
<Form.Item name="end" label="结束年龄"> <Form.Item
name="end"
label="结束年龄"
rules={[
({ getFieldValue }) => ({
validator(_, value) {
const start = getFieldValue('start');
if (value && start > value) {
return Promise.reject(new Error('结束年龄不能小于起始年龄'));
}
return Promise.resolve();
},
}),
]}
>
<InputNumber min={0} /> <InputNumber min={0} />
</Form.Item> </Form.Item>
</Form> </Form>

View File

@ -8,6 +8,7 @@ import React, {
// import { useDebounce } from "use-debounce"; // import { useDebounce } from "use-debounce";
import { Form, FormInstance } from 'antd'; import { Form, FormInstance } from 'antd';
import { api } from "@nice/client"; import { api } from "@nice/client";
import toast from "react-hot-toast";
interface AssessmentStandardContextType { interface AssessmentStandardContextType {
form: FormInstance; form: FormInstance;
@ -59,8 +60,26 @@ export function AssessmentStandardProvider({ children }: AssessmentStandardProvi
}; };
// 处理年龄范围模态框确定 // 处理年龄范围模态框确定
const handleAgeOk = (values: any) => { const handleAgeOk = (values: any) => {
console.log('values',values) console.log('values', values)
const { start, end } = 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 = { const newRange = {
start, start,
end, end,
@ -101,7 +120,7 @@ export function AssessmentStandardProvider({ children }: AssessmentStandardProvi
id: item.id, id: item.id,
name: item.name, name: item.name,
unit: item.unit, unit: item.unit,
deletedAt:item.deletedAt deletedAt: item.deletedAt
})), })),
sportProjectLoading, sportProjectLoading,
ageRanges, ageRanges,

View File

@ -70,6 +70,25 @@ export default function StandardCreateContent() {
} }
} }
const createStandard = async ()=>{ 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({ const result = await createSportStandard.mutateAsync({
data: { data: {
projectId: form.getFieldsValue().projectId, projectId: form.getFieldsValue().projectId,
@ -83,6 +102,23 @@ export default function StandardCreateContent() {
toast.success("保存标准成功") toast.success("保存标准成功")
} }
const updateStandard = async ()=>{ 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({ const result = await updateSportStandard.mutateAsync({
data: { data: {
id: data[0].id, id: data[0].id,
@ -104,18 +140,20 @@ export default function StandardCreateContent() {
}); });
useEffect(() => { useEffect(() => {
if (data && data.length) { if (data && data.length) {
setIsStandardCreate(false) setIsStandardCreate(false);
const records: { const records = Object.entries(JSON.parse(String(data[0].scoreTable))).map(([score, standards]) => ({
score: number;
standards: number[];
}[] = Object.entries(JSON.parse(String(data[0].scoreTable))).map(([score, standards]) => ({
score: Number(score), score: Number(score),
standards: standards as number[] standards: standards as number[]
})); }));
setAgeRanges(JSON.parse(String(data[0].ageRanges))) setAgeRanges(JSON.parse(String(data[0].ageRanges)));
setRecords(records) setRecords(records);
} else {
// 如果没有找到数据,重置状态
setIsStandardCreate(true);
setAgeRanges([]);
setRecords([]);
} }
}, [data]) }, [data, projectId, gender, personType]); // 添加更多依赖项
return ( return (
<Form form={form} layout="vertical"> <Form form={form} layout="vertical">
<Space size="large" className="my-6"> <Space size="large" className="my-6">
@ -124,6 +162,12 @@ export default function StandardCreateContent() {
style={{ width: 200 }} style={{ width: 200 }}
placeholder="选择考核项目" placeholder="选择考核项目"
options={sportProjectList?.filter(item=>item.deletedAt === null)?.map((item) => ({ value: item.id, label: `${item.name}${item.unit}` })) || []} options={sportProjectList?.filter(item=>item.deletedAt === null)?.map((item) => ({ value: item.id, label: `${item.name}${item.unit}` })) || []}
onChange={() => {
// 重置状态,强制重新加载
setIsStandardCreate(true);
setAgeRanges([]);
setRecords([]);
}}
/> />
</Form.Item> </Form.Item>
<Form.Item label="性别" name="gender"> <Form.Item label="性别" name="gender">

View File

@ -203,7 +203,6 @@ export default function SportPage() {
</Button> </Button>
</div> </div>
</div> </div>
{staffsWithScoreLoading ? ( {staffsWithScoreLoading ? (
<Skeleton></Skeleton> <Skeleton></Skeleton>
) : ( ) : (