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;
}
private validateAgeRanges(ranges: AgeRange[]) {
// 检查年龄段是否按顺序排列且无重叠
for (let i = 0; i < ranges.length - 1; i++) {
const current = ranges[i];
const next = ranges[i + 1];
// 先按起始年龄排序
const sortedRanges = [...ranges].sort(
(a, b) => (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<Prisma.SportStandardDelega
}
});
}
async updateStandard(data: {
id: string;
ageRanges: AgeRange[];

View File

@ -11,10 +11,39 @@ export default function AssessmentModal() {
onCancel={handleAgeCancel}
>
<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} />
</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} />
</Form.Item>
</Form>

View File

@ -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,

View File

@ -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 (
<Form form={form} layout="vertical">
<Space size="large" className="my-6">
@ -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([]);
}}
/>
</Form.Item>
<Form.Item label="性别" name="gender">

View File

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