rht
This commit is contained in:
parent
960366282f
commit
00ed6cf4a9
|
@ -7,6 +7,17 @@ import { Prisma } from "@nice/common";
|
||||||
const SportStandardArgsSchema:ZodType<Prisma.SportStandardCreateArgs> = z.any()
|
const SportStandardArgsSchema:ZodType<Prisma.SportStandardCreateArgs> = z.any()
|
||||||
const SportStandardUpdateArgsSchema:ZodType<Prisma.SportStandardUpdateArgs> = z.any()
|
const SportStandardUpdateArgsSchema:ZodType<Prisma.SportStandardUpdateArgs> = z.any()
|
||||||
const SportStandardFindManyArgsSchema:ZodType<Prisma.SportStandardFindManyArgs> = z.any()
|
const SportStandardFindManyArgsSchema:ZodType<Prisma.SportStandardFindManyArgs> = z.any()
|
||||||
|
const SportStandardCreateStandardArgsSchema:ZodType<Prisma.SportStandardCreateArgs> = z.any()
|
||||||
|
|
||||||
|
interface AgeRange {
|
||||||
|
start: number | null;
|
||||||
|
end: number | null;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
interface Record {
|
||||||
|
[key: string]: number[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SportStandardRouter {
|
export class SportStandardRouter {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -15,10 +26,10 @@ export class SportStandardRouter {
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
router = this.trpc.router({
|
router = this.trpc.router({
|
||||||
create:this.trpc.procedure.input(SportStandardArgsSchema)
|
// create:this.trpc.procedure.input(SportStandardArgsSchema)
|
||||||
.mutation(async ({input})=>{
|
// .mutation(async ({input})=>{
|
||||||
return this.sportStandardService.create(input)
|
// return this.sportStandardService.create(input)
|
||||||
}),
|
// }),
|
||||||
update:this.trpc.procedure.input(SportStandardUpdateArgsSchema)
|
update:this.trpc.procedure.input(SportStandardUpdateArgsSchema)
|
||||||
.mutation(async ({input})=>{
|
.mutation(async ({input})=>{
|
||||||
return this.sportStandardService.update(input)
|
return this.sportStandardService.update(input)
|
||||||
|
@ -26,6 +37,17 @@ export class SportStandardRouter {
|
||||||
findMany:this.trpc.procedure.input(SportStandardFindManyArgsSchema)
|
findMany:this.trpc.procedure.input(SportStandardFindManyArgsSchema)
|
||||||
.query(async ({input})=>{
|
.query(async ({input})=>{
|
||||||
return this.sportStandardService.findMany(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)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -8,30 +8,30 @@ interface AgeRange {
|
||||||
start: number | null;
|
start: number | null;
|
||||||
end: number | null;
|
end: number | null;
|
||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
interface Record {
|
||||||
|
[key: string]: number[];
|
||||||
|
}
|
||||||
interface ScoreStandard {
|
interface ScoreStandard {
|
||||||
ageRanges: AgeRange[];
|
ageRanges: AgeRange[];
|
||||||
scoreTable: {
|
scoreTable: Record;
|
||||||
[score: string]: number[];
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SportStandardService extends BaseService<Prisma.SportStandardDelegate> {
|
export class SportStandardService extends BaseService<Prisma.SportStandardDelegate> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(db,ObjectType.SPORT_STANDARD,true);
|
super(db, ObjectType.SPORT_STANDARD, true);
|
||||||
}
|
}
|
||||||
async create(args: Prisma.SportStandardCreateArgs) {
|
async create(args: Prisma.SportStandardCreateArgs) {
|
||||||
console.log(args)
|
console.log(args)
|
||||||
const result = await super.create(args)
|
const result = await super.create(args)
|
||||||
this.emitDataChanged(CrudOperation.CREATED,result)
|
this.emitDataChanged(CrudOperation.CREATED, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(args:Prisma.SportStandardUpdateArgs){
|
async update(args: Prisma.SportStandardUpdateArgs) {
|
||||||
const result = await super.update(args)
|
const result = await super.update(args)
|
||||||
this.emitDataChanged(CrudOperation.UPDATED,result)
|
this.emitDataChanged(CrudOperation.UPDATED, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,49 +47,97 @@ export class SportStandardService extends BaseService<Prisma.SportStandardDelega
|
||||||
|
|
||||||
private emitDataChanged(operation: CrudOperation, data: any) {
|
private emitDataChanged(operation: CrudOperation, data: any) {
|
||||||
EventBus.emit('dataChanged', {
|
EventBus.emit('dataChanged', {
|
||||||
type:ObjectType.SPORT_STANDARD,
|
type: ObjectType.SPORT_STANDARD,
|
||||||
operation,
|
operation,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public SportScoreCalculator(performance:number,age:number,scoreStandard:ScoreStandard):number{
|
async createStandard(
|
||||||
|
data: {
|
||||||
|
projectId: string;
|
||||||
|
gender: boolean;
|
||||||
|
personType: string;
|
||||||
|
ageRanges: AgeRange[];
|
||||||
|
scoreTable: Record;
|
||||||
|
},
|
||||||
|
select?: Prisma.SportStandardSelect<DefaultArgs>,
|
||||||
|
include?: Prisma.SportStandardInclude<DefaultArgs>
|
||||||
|
) {
|
||||||
|
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. 找到对应的年龄段索引
|
// 1. 找到对应的年龄段索引
|
||||||
const ageRangeIndex = scoreStandard.ageRanges.findIndex(range => {
|
const ageRangeIndex = scoreStandard.ageRanges.findIndex(range => {
|
||||||
const isAboveStart = range.start === null || age > range.start;
|
const isAboveStart = range.start === null || age > range.start;
|
||||||
const isBelowEnd = range.end === null || age <= range.end;
|
const isBelowEnd = range.end === null || age <= range.end;
|
||||||
return isAboveStart && isBelowEnd;
|
return isAboveStart && isBelowEnd;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ageRangeIndex === -1) {
|
if (ageRangeIndex === -1) {
|
||||||
throw new Error('未找到匹配的年龄段');
|
throw new Error('未找到匹配的年龄段');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 查找对应分数
|
// 2. 查找对应分数
|
||||||
const scores = Object.keys(scoreStandard.scoreTable)
|
const scores = Object.keys(scoreStandard.scoreTable)
|
||||||
.map(Number)
|
.map(Number)
|
||||||
.sort((a, b) => b - a);
|
.sort((a, b) => b - a);
|
||||||
|
|
||||||
for (const score of scores) {
|
for (const score of scores) {
|
||||||
if (performance >= scoreStandard.scoreTable[score][ageRangeIndex]) {
|
if (performance >= scoreStandard.scoreTable[score][ageRangeIndex]) {
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getScore(data: {
|
async getScore(data: {
|
||||||
id:string;
|
id: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
gender: boolean;
|
gender: boolean;
|
||||||
age: number;
|
age: number;
|
||||||
performance: number;
|
performance: number;
|
||||||
personType: string;
|
personType: string;
|
||||||
}){
|
}) {
|
||||||
const standard = await this.findUnique({
|
const standard = await this.findUnique({
|
||||||
where:{
|
where: {
|
||||||
id:data.id,
|
id: data.id,
|
||||||
projectId: data.projectId,
|
projectId: data.projectId,
|
||||||
gender: data.gender,
|
gender: data.gender,
|
||||||
personType: data.personType
|
personType: data.personType
|
||||||
|
@ -104,5 +152,5 @@ export class SportStandardService extends BaseService<Prisma.SportStandardDelega
|
||||||
data.age,
|
data.age,
|
||||||
standard.scoreTable as any as ScoreStandard
|
standard.scoreTable as any as ScoreStandard
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue