add
This commit is contained in:
parent
1fb33c2408
commit
057c4ffe5d
|
@ -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[];
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -61,6 +62,24 @@ 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,
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -203,7 +203,6 @@ export default function SportPage() {
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{staffsWithScoreLoading ? (
|
{staffsWithScoreLoading ? (
|
||||||
<Skeleton></Skeleton>
|
<Skeleton></Skeleton>
|
||||||
) : (
|
) : (
|
||||||
|
|
Loading…
Reference in New Issue