108 lines
3.4 KiB
TypeScript
108 lines
3.4 KiB
TypeScript
|
import { Injectable } from "@nestjs/common";
|
||
|
import { BaseService } from "../base/base.service";
|
||
|
import { db, ObjectType, Prisma, UserProfile } from "@nice/common";
|
||
|
import EventBus, { CrudOperation } from "@server/utils/event-bus";
|
||
|
import { DefaultArgs } from "@prisma/client/runtime/library";
|
||
|
|
||
|
interface AgeRange {
|
||
|
start: number | null;
|
||
|
end: number | null;
|
||
|
label: string;
|
||
|
}
|
||
|
|
||
|
interface ScoreStandard {
|
||
|
ageRanges: AgeRange[];
|
||
|
scoreTable: {
|
||
|
[score: string]: number[];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Injectable()
|
||
|
export class SportStandardService extends BaseService<Prisma.SportStandardDelegate> {
|
||
|
constructor() {
|
||
|
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
|
||
|
}
|
||
|
|
||
|
async update(args:Prisma.SportStandardUpdateArgs){
|
||
|
const result = await super.update(args)
|
||
|
this.emitDataChanged(CrudOperation.UPDATED,result)
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
|
||
|
async findMany(args: Prisma.SportStandardFindManyArgs) {
|
||
|
const result = await super.findMany(args);
|
||
|
return result;
|
||
|
}
|
||
|
async findUnique(args: { select?: Prisma.SportStandardSelect<DefaultArgs>; include?: Prisma.SportStandardInclude<DefaultArgs>; where: Prisma.SportStandardWhereUniqueInput; }): Promise<{ id: string; projectId: string; gender: boolean; personType: string; ageRanges: Prisma.JsonValue; scoreTable: Prisma.JsonValue; }> {
|
||
|
const result = await super.findUnique(args)
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
private emitDataChanged(operation: CrudOperation, data: any) {
|
||
|
EventBus.emit('dataChanged', {
|
||
|
type:ObjectType.SPORT_STANDARD,
|
||
|
operation,
|
||
|
data,
|
||
|
});
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
projectId: string;
|
||
|
gender: boolean;
|
||
|
age: number;
|
||
|
performance: number;
|
||
|
personType: string;
|
||
|
}){
|
||
|
const standard = await this.findUnique({
|
||
|
where:{
|
||
|
id:data.id,
|
||
|
projectId: data.projectId,
|
||
|
gender: data.gender,
|
||
|
personType: data.personType
|
||
|
}
|
||
|
})
|
||
|
if (!standard) {
|
||
|
throw new Error('未找到对应的评分标准');
|
||
|
}
|
||
|
|
||
|
return this.SportScoreCalculator(
|
||
|
data.performance,
|
||
|
data.age,
|
||
|
standard.scoreTable as any as ScoreStandard
|
||
|
)
|
||
|
}
|
||
|
}
|