- 新增图片可读性预检查机制,识别前先判断图片质量 - 设置置信度阈值为60%,低于阈值自动识别失败 - 支持多图片上传(正面、侧面、辅助图片)提高识别准确度 - 完善识别失败场景的错误分类和用户指导提示 - 新增药品有效期字段支持 - 优化AI提示词,强调安全优先原则 - 更新模型版本为 glm-4.5v 和 glm-4.5-air 数据库变更: - Medication表新增 sideImageUrl, auxiliaryImageUrl, expiryDate 字段 - DTO层同步支持新增字段的传递和更新 质量控制策略: - 图片模糊或不可读时直接返回失败 - 无法识别药品名称时主动失败 - 置信度<60%时拒绝识别,建议重新拍摄 - 宁可识别失败也不提供不准确的药品信息
168 lines
3.5 KiB
TypeScript
168 lines
3.5 KiB
TypeScript
import { Column, Model, Table, DataType, HasMany } from 'sequelize-typescript';
|
||
import { MedicationFormEnum } from '../enums/medication-form.enum';
|
||
import { RepeatPatternEnum } from '../enums/repeat-pattern.enum';
|
||
import { MedicationRecord } from './medication-record.model';
|
||
|
||
/**
|
||
* 药物信息模型
|
||
*/
|
||
@Table({
|
||
tableName: 't_medications',
|
||
underscored: true,
|
||
paranoid: false, // 使用软删除字段 deleted 而不是 deletedAt
|
||
})
|
||
export class Medication extends Model {
|
||
@Column({
|
||
type: DataType.STRING(50),
|
||
primaryKey: true,
|
||
comment: '药物唯一标识',
|
||
})
|
||
declare id: string;
|
||
|
||
@Column({
|
||
type: DataType.STRING(50),
|
||
allowNull: false,
|
||
comment: '用户ID',
|
||
})
|
||
declare userId: string;
|
||
|
||
@Column({
|
||
type: DataType.STRING(100),
|
||
allowNull: false,
|
||
comment: '药物名称',
|
||
})
|
||
declare name: string;
|
||
|
||
@Column({
|
||
type: DataType.STRING(255),
|
||
allowNull: true,
|
||
comment: '药物正面照片URL',
|
||
})
|
||
declare photoUrl: string;
|
||
|
||
@Column({
|
||
type: DataType.STRING(255),
|
||
allowNull: true,
|
||
comment: '药物侧面照片URL',
|
||
})
|
||
declare sideImageUrl: string;
|
||
|
||
@Column({
|
||
type: DataType.STRING(255),
|
||
allowNull: true,
|
||
comment: '药物辅助照片URL(可选的第三张图片)',
|
||
})
|
||
declare auxiliaryImageUrl: string;
|
||
|
||
@Column({
|
||
type: DataType.STRING(20),
|
||
allowNull: false,
|
||
comment: '药物剂型',
|
||
})
|
||
declare form: MedicationFormEnum;
|
||
|
||
@Column({
|
||
type: DataType.DECIMAL(10, 2),
|
||
allowNull: false,
|
||
comment: '剂量数值',
|
||
})
|
||
declare dosageValue: number;
|
||
|
||
@Column({
|
||
type: DataType.STRING(20),
|
||
allowNull: false,
|
||
comment: '剂量单位',
|
||
})
|
||
declare dosageUnit: string;
|
||
|
||
@Column({
|
||
type: DataType.INTEGER,
|
||
allowNull: false,
|
||
comment: '每日服用次数',
|
||
})
|
||
declare timesPerDay: number;
|
||
|
||
@Column({
|
||
type: DataType.JSON,
|
||
allowNull: false,
|
||
comment: '服药时间列表,格式:["08:00", "20:00"]',
|
||
})
|
||
declare medicationTimes: string[];
|
||
|
||
@Column({
|
||
type: DataType.STRING(20),
|
||
allowNull: false,
|
||
defaultValue: RepeatPatternEnum.DAILY,
|
||
comment: '重复模式',
|
||
})
|
||
declare repeatPattern: RepeatPatternEnum;
|
||
|
||
@Column({
|
||
type: DataType.DATE,
|
||
allowNull: false,
|
||
comment: '开始日期(UTC时间)',
|
||
})
|
||
declare startDate: Date;
|
||
|
||
@Column({
|
||
type: DataType.DATE,
|
||
allowNull: true,
|
||
comment: '结束日期(UTC时间)',
|
||
})
|
||
declare endDate: Date | null;
|
||
|
||
@Column({
|
||
type: DataType.DATE,
|
||
allowNull: true,
|
||
comment: '药品有效期(UTC时间)',
|
||
})
|
||
declare expiryDate: Date | null;
|
||
|
||
@Column({
|
||
type: DataType.TEXT,
|
||
allowNull: true,
|
||
comment: '备注信息',
|
||
})
|
||
declare note: string;
|
||
|
||
@Column({
|
||
type: DataType.TEXT,
|
||
allowNull: true,
|
||
comment: 'AI分析结果',
|
||
})
|
||
declare aiAnalysis: string;
|
||
|
||
@Column({
|
||
type: DataType.BOOLEAN,
|
||
allowNull: false,
|
||
defaultValue: true,
|
||
comment: '是否激活',
|
||
})
|
||
declare isActive: boolean;
|
||
|
||
@Column({
|
||
type: DataType.DATE,
|
||
defaultValue: DataType.NOW,
|
||
comment: '创建时间',
|
||
})
|
||
declare createdAt: Date;
|
||
|
||
@Column({
|
||
type: DataType.DATE,
|
||
defaultValue: DataType.NOW,
|
||
comment: '更新时间',
|
||
})
|
||
declare updatedAt: Date;
|
||
|
||
@Column({
|
||
type: DataType.BOOLEAN,
|
||
allowNull: false,
|
||
defaultValue: false,
|
||
comment: '软删除标记',
|
||
})
|
||
declare deleted: boolean;
|
||
|
||
// 关联关系
|
||
@HasMany(() => MedicationRecord, 'medicationId')
|
||
declare records: MedicationRecord[];
|
||
} |