From 00ed6cf4a9fc5b78fa0789fa5f8b6f624c771cb5 Mon Sep 17 00:00:00 2001 From: Rao <1227431568@qq.com> Date: Tue, 25 Mar 2025 08:22:17 +0800 Subject: [PATCH] rht --- .../sport-standard/sportStandard.router.ts | 30 +++++- .../sport-standard/sportStandard.service.ts | 96 ++++++++++++++----- 2 files changed, 98 insertions(+), 28 deletions(-) diff --git a/apps/server/src/models/sport-standard/sportStandard.router.ts b/apps/server/src/models/sport-standard/sportStandard.router.ts index 3cbec62..bcd4851 100644 --- a/apps/server/src/models/sport-standard/sportStandard.router.ts +++ b/apps/server/src/models/sport-standard/sportStandard.router.ts @@ -7,6 +7,17 @@ import { Prisma } from "@nice/common"; const SportStandardArgsSchema:ZodType = z.any() const SportStandardUpdateArgsSchema:ZodType = z.any() const SportStandardFindManyArgsSchema:ZodType = z.any() +const SportStandardCreateStandardArgsSchema:ZodType = z.any() + +interface AgeRange { + start: number | null; + end: number | null; + label: string; +} +interface Record { + [key: string]: number[]; +} + @Injectable() export class SportStandardRouter { constructor( @@ -15,10 +26,10 @@ export class SportStandardRouter { ) { } router = this.trpc.router({ - create:this.trpc.procedure.input(SportStandardArgsSchema) - .mutation(async ({input})=>{ - return this.sportStandardService.create(input) - }), + // create:this.trpc.procedure.input(SportStandardArgsSchema) + // .mutation(async ({input})=>{ + // return this.sportStandardService.create(input) + // }), update:this.trpc.procedure.input(SportStandardUpdateArgsSchema) .mutation(async ({input})=>{ return this.sportStandardService.update(input) @@ -26,6 +37,17 @@ export class SportStandardRouter { findMany:this.trpc.procedure.input(SportStandardFindManyArgsSchema) .query(async ({input})=>{ return this.sportStandardService.findMany(input) + }), + createStandard:this.trpc.procedure.input(SportStandardCreateStandardArgsSchema) + .mutation(async ({input})=>{ + const data = { + projectId: input.data.projectId, + gender: input.data.gender, + personType: input.data.personType, + ageRanges: input.data.ageRanges as any as AgeRange[], + scoreTable: input.data.scoreTable as Record + } + return this.sportStandardService.createStandard(data,input.select,input.include) }) }) diff --git a/apps/server/src/models/sport-standard/sportStandard.service.ts b/apps/server/src/models/sport-standard/sportStandard.service.ts index 884b49d..bae7d6a 100644 --- a/apps/server/src/models/sport-standard/sportStandard.service.ts +++ b/apps/server/src/models/sport-standard/sportStandard.service.ts @@ -8,30 +8,30 @@ interface AgeRange { start: number | null; end: number | null; label: string; - } - +} +interface Record { + [key: string]: number[]; +} interface ScoreStandard { ageRanges: AgeRange[]; - scoreTable: { - [score: string]: number[]; - } - } + scoreTable: Record; +} @Injectable() export class SportStandardService extends BaseService { constructor() { - super(db,ObjectType.SPORT_STANDARD,true); + super(db, ObjectType.SPORT_STANDARD, true); } async create(args: Prisma.SportStandardCreateArgs) { console.log(args) const result = await super.create(args) - this.emitDataChanged(CrudOperation.CREATED,result) - return result + this.emitDataChanged(CrudOperation.CREATED, result) + return result } - async update(args:Prisma.SportStandardUpdateArgs){ + async update(args: Prisma.SportStandardUpdateArgs) { const result = await super.update(args) - this.emitDataChanged(CrudOperation.UPDATED,result) + this.emitDataChanged(CrudOperation.UPDATED, result) return result } @@ -47,49 +47,97 @@ export class SportStandardService extends BaseService, + include?: Prisma.SportStandardInclude + ) { + this.validateAgeRanges(data.ageRanges); + this.validateScoreTable(data.scoreTable, data.ageRanges.length); + return this.create({ + data: { + projectId: data.projectId, + gender: data.gender, + personType: data.personType, + ageRanges: JSON.stringify(data.ageRanges), + scoreTable: JSON.stringify(data.scoreTable) + }, + select, + include + }) + } + private validateAgeRanges(ranges: AgeRange[]) { + // 检查年龄段是否按顺序排列且无重叠 + for (let i = 0; i < ranges.length - 1; i++) { + const current = ranges[i]; + const next = ranges[i + 1]; + + if (current.end !== next.start) { + throw new Error('年龄段必须连续且不重叠'); + } + } + } + + private validateScoreTable( + scoreTable: Record, + expectedLength: number + ) { + Object.values(scoreTable).forEach(standards => { + if (standards.length !== expectedLength) { + throw new Error('分数表的每行数据长度必须与年龄段数量匹配'); + } + }); + } + + public SportScoreCalculator(performance: number, age: number, scoreStandard: ScoreStandard): number { // 1. 找到对应的年龄段索引 const ageRangeIndex = scoreStandard.ageRanges.findIndex(range => { const isAboveStart = range.start === null || age > range.start; const isBelowEnd = range.end === null || age <= range.end; return isAboveStart && isBelowEnd; }); - + if (ageRangeIndex === -1) { throw new Error('未找到匹配的年龄段'); } - + // 2. 查找对应分数 const scores = Object.keys(scoreStandard.scoreTable) .map(Number) .sort((a, b) => b - a); - + for (const score of scores) { if (performance >= scoreStandard.scoreTable[score][ageRangeIndex]) { return score; } } - + return 0; } async getScore(data: { - id:string; + id: string; projectId: string; gender: boolean; age: number; performance: number; personType: string; - }){ + }) { const standard = await this.findUnique({ - where:{ - id:data.id, + where: { + id: data.id, projectId: data.projectId, gender: data.gender, personType: data.personType @@ -104,5 +152,5 @@ export class SportStandardService extends BaseService