- 新增图片可读性预检查机制,识别前先判断图片质量 - 设置置信度阈值为60%,低于阈值自动识别失败 - 支持多图片上传(正面、侧面、辅助图片)提高识别准确度 - 完善识别失败场景的错误分类和用户指导提示 - 新增药品有效期字段支持 - 优化AI提示词,强调安全优先原则 - 更新模型版本为 glm-4.5v 和 glm-4.5-air 数据库变更: - Medication表新增 sideImageUrl, auxiliaryImageUrl, expiryDate 字段 - DTO层同步支持新增字段的传递和更新 质量控制策略: - 图片模糊或不可读时直接返回失败 - 无法识别药品名称时主动失败 - 置信度<60%时拒绝识别,建议重新拍摄 - 宁可识别失败也不提供不准确的药品信息
142 lines
3.1 KiB
TypeScript
142 lines
3.1 KiB
TypeScript
import { ApiProperty } from '@nestjs/swagger';
|
||
import {
|
||
IsString,
|
||
IsNotEmpty,
|
||
IsEnum,
|
||
IsNumber,
|
||
IsInt,
|
||
IsArray,
|
||
IsDateString,
|
||
IsOptional,
|
||
IsBoolean,
|
||
Min,
|
||
ArrayMinSize,
|
||
Matches,
|
||
} from 'class-validator';
|
||
import { MedicationFormEnum } from '../enums/medication-form.enum';
|
||
import { RepeatPatternEnum } from '../enums/repeat-pattern.enum';
|
||
|
||
/**
|
||
* 创建药物 DTO
|
||
*/
|
||
export class CreateMedicationDto {
|
||
@ApiProperty({ description: '药物名称', example: 'Metformin' })
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
name: string;
|
||
|
||
@ApiProperty({
|
||
description: '药物正面照片URL',
|
||
example: 'https://cdn.example.com/medications/front_001.jpg',
|
||
required: false,
|
||
})
|
||
@IsString()
|
||
@IsOptional()
|
||
photoUrl?: string;
|
||
|
||
@ApiProperty({
|
||
description: '药物侧面照片URL',
|
||
example: 'https://cdn.example.com/medications/side_001.jpg',
|
||
required: false,
|
||
})
|
||
@IsString()
|
||
@IsOptional()
|
||
sideImageUrl?: string;
|
||
|
||
@ApiProperty({
|
||
description: '药物辅助照片URL(可选的第三张图片)',
|
||
example: 'https://cdn.example.com/medications/auxiliary_001.jpg',
|
||
required: false,
|
||
})
|
||
@IsString()
|
||
@IsOptional()
|
||
auxiliaryImageUrl?: string;
|
||
|
||
@ApiProperty({
|
||
description: '药物剂型',
|
||
enum: MedicationFormEnum,
|
||
example: MedicationFormEnum.CAPSULE,
|
||
})
|
||
@IsEnum(MedicationFormEnum)
|
||
@IsNotEmpty()
|
||
form: MedicationFormEnum;
|
||
|
||
@ApiProperty({ description: '剂量数值', example: 1 })
|
||
@IsNumber()
|
||
@Min(0.01)
|
||
dosageValue: number;
|
||
|
||
@ApiProperty({ description: '剂量单位', example: '粒' })
|
||
@IsString()
|
||
@IsNotEmpty()
|
||
dosageUnit: string;
|
||
|
||
@ApiProperty({ description: '每日服用次数', example: 2 })
|
||
@IsInt()
|
||
@Min(1)
|
||
timesPerDay: number;
|
||
|
||
@ApiProperty({
|
||
description: '服药时间列表,格式:HH:mm',
|
||
example: ['08:00', '20:00'],
|
||
type: [String],
|
||
})
|
||
@IsArray()
|
||
@ArrayMinSize(1)
|
||
@IsString({ each: true })
|
||
@Matches(/^([01]\d|2[0-3]):([0-5]\d)$/, {
|
||
each: true,
|
||
message: '服药时间格式必须为 HH:mm',
|
||
})
|
||
medicationTimes: string[];
|
||
|
||
@ApiProperty({
|
||
description: '重复模式',
|
||
enum: RepeatPatternEnum,
|
||
example: RepeatPatternEnum.DAILY,
|
||
})
|
||
@IsEnum(RepeatPatternEnum)
|
||
@IsNotEmpty()
|
||
repeatPattern: RepeatPatternEnum;
|
||
|
||
@ApiProperty({
|
||
description: '开始日期,ISO 8601 格式',
|
||
example: '2025-01-01T00:00:00.000Z',
|
||
})
|
||
@IsDateString()
|
||
@IsNotEmpty()
|
||
startDate: string;
|
||
|
||
@ApiProperty({
|
||
description: '结束日期,ISO 8601 格式(可选)',
|
||
example: '2025-12-31T23:59:59.999Z',
|
||
required: false,
|
||
})
|
||
@IsDateString()
|
||
@IsOptional()
|
||
endDate?: string;
|
||
|
||
@ApiProperty({
|
||
description: '药品有效期,ISO 8601 格式(可选)',
|
||
example: '2026-12-31T23:59:59.999Z',
|
||
required: false,
|
||
})
|
||
@IsDateString()
|
||
@IsOptional()
|
||
expiryDate?: string;
|
||
|
||
@ApiProperty({ description: '备注信息', example: '饭后服用', required: false })
|
||
@IsString()
|
||
@IsOptional()
|
||
note?: string;
|
||
|
||
@ApiProperty({
|
||
description: '是否激活',
|
||
example: true,
|
||
required: false,
|
||
default: true
|
||
})
|
||
@IsOptional()
|
||
@IsBoolean()
|
||
isActive?: boolean;
|
||
} |