harmony/commons/basic/src/main/ets/utils/PatientsEntity.ets
2025-07-18 17:24:31 +08:00

917 lines
27 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Entity, Id, Columns, ColumnType } from '@ohos/dataorm';
import { authStore } from './auth';
import { hdHttp, HdResponse } from '../utils/request';
import { BasicConstant } from '../constants/BasicConstant';
import { BusinessError } from '@kit.BasicServicesKit';
import relationalStore from '@ohos.data.relationalStore';
import common from '@ohos.app.ability.common';
// 患者数据接口
export interface PatientData {
uuid: string;
nickname: string;
mobile: string;
realName: string;
nation: string | null;
sex: number;
type: number;
photo: string;
expertUuid: string; // 关联的专家UUID
}
// 服务器响应接口
interface updateExtraData {
expertUuid: string
}
// 患者实体类
@Entity('patients')
export class PatientEntity {
@Id()
@Columns({ columnName: 'id', types: ColumnType.num })
id: number = 0;
@Columns({ columnName: 'uuid', types: ColumnType.str })
uuid: string = '';
@Columns({ columnName: 'nickname', types: ColumnType.str })
nickname: string = '';
@Columns({ columnName: 'mobile', types: ColumnType.str })
mobile: string = '';
@Columns({ columnName: 'realName', types: ColumnType.str })
realName: string = '';
@Columns({ columnName: 'nation', types: ColumnType.str })
nation: string = '';
@Columns({ columnName: 'sex', types: ColumnType.num })
sex: number = 0;
@Columns({ columnName: 'type', types: ColumnType.num })
type: number = 0;
@Columns({ columnName: 'photo', types: ColumnType.str })
photo: string = '';
@Columns({ columnName: 'expertUuid', types: ColumnType.str })
expertUuid: string = '';
@Columns({ columnName: 'createTime', types: ColumnType.str })
createTime: string = '';
@Columns({ columnName: 'updateTime', types: ColumnType.str })
updateTime: string = '';
constructor(
uuid: string = '',
nickname: string = '',
mobile: string = '',
realName: string = '',
nation: string = '',
sex: number = 0,
type: number = 0,
photo: string = '',
expertUuid: string = ''
) {
this.uuid = uuid;
this.nickname = nickname;
this.mobile = mobile;
this.realName = realName;
this.nation = nation;
this.sex = sex;
this.type = type;
this.photo = photo;
this.expertUuid = expertUuid;
this.createTime = new Date().toISOString();
this.updateTime = new Date().toISOString();
}
}
// 患者DAO类 - 使用原生 relationalStore
export class PatientDao {
private rdbStore: relationalStore.RdbStore | null = null;
private context: common.Context;
private isInitialized: boolean = false;
constructor(context: common.Context) {
this.context = context;
}
// 初始化数据库
async initDatabase(): Promise<void> {
try {
console.info('开始初始化患者数据库...');
const storeConfig: relationalStore.StoreConfig = {
name: 'patient_database',
securityLevel: relationalStore.SecurityLevel.S1
};
this.rdbStore = await relationalStore.getRdbStore(this.context, storeConfig);
console.info('数据库连接创建成功');
// 创建表
await this.createTable();
this.isInitialized = true;
console.info('患者数据库初始化完成');
} catch (error) {
console.error('初始化患者数据库失败:', error);
this.isInitialized = false;
if (error instanceof Error) {
throw error;
} else {
throw new Error('初始化患者数据库失败');
}
}
}
// 创建患者表
private async createTable(): Promise<void> {
if (!this.rdbStore) {
throw new Error('数据库未初始化');
}
try {
const createTableSql = `
CREATE TABLE IF NOT EXISTS patients (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uuid TEXT NOT NULL,
nickname TEXT,
mobile TEXT,
realName TEXT,
nation TEXT,
sex INTEGER DEFAULT 0,
type INTEGER DEFAULT 0,
photo TEXT,
expertUuid TEXT NOT NULL,
createTime TEXT,
updateTime TEXT
)
`;
await this.rdbStore.executeSql(createTableSql);
console.info('患者表创建成功');
// 验证表是否存在
await this.verifyTableExists();
} catch (error) {
console.error('创建患者表失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('创建患者表失败');
}
}
}
// 验证表是否存在
private async verifyTableExists(): Promise<void> {
if (!this.rdbStore) {
throw new Error('数据库未初始化');
}
try {
const checkTableSql = "SELECT name FROM sqlite_master WHERE type='table' AND name='patients'";
const resultSet = await this.rdbStore.querySql(checkTableSql, []);
if (resultSet.rowCount === 0) {
throw new Error('患者表创建失败');
}
resultSet.close();
console.info('患者表验证成功');
} catch (error) {
console.error('验证患者表失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('验证患者表失败');
}
}
}
// 检查数据库状态
private checkDatabaseState(): void {
if (!this.rdbStore) {
throw new Error('数据库未初始化');
}
if (!this.isInitialized) {
throw new Error('数据库初始化未完成');
}
}
// 根据专家UUID查询所有患者
async getPatientsByExpertUuid(expertUuid: string): Promise<PatientEntity[]> {
try {
this.checkDatabaseState();
console.info(`开始查询专家 ${expertUuid} 的患者数据`);
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = 'SELECT * FROM patients WHERE expertUuid = ? ORDER BY createTime DESC';
const resultSet = await this.rdbStore.querySql(sql, [expertUuid]);
const patients: PatientEntity[] = [];
if (resultSet.rowCount > 0) {
resultSet.goToFirstRow();
do {
try {
const patient = this.parseResultSet(resultSet);
patients.push(patient);
} catch (parseError) {
console.error('解析患者数据失败:', parseError);
}
} while (resultSet.goToNextRow());
}
resultSet.close();
console.info(`成功查询到 ${patients.length} 个患者`);
return patients;
} catch (error) {
console.error('查询患者数据失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('查询患者数据失败');
}
}
}
// 根据患者UUID查询单个患者
async getPatientByUuid(uuid: string): Promise<PatientEntity | null> {
try {
this.checkDatabaseState();
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = 'SELECT * FROM patients WHERE LOWER(uuid) = LOWER(?)';
const resultSet = await this.rdbStore.querySql(sql, [uuid]);
if (resultSet.rowCount > 0) {
resultSet.goToFirstRow();
const patient = this.parseResultSet(resultSet);
resultSet.close();
return patient;
}
resultSet.close();
return null;
} catch (error) {
console.error('根据UUID查询患者失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('根据UUID查询患者失败');
}
}
}
// 根据手机号查询患者
async getPatientByMobile(mobile: string, expertUuid: string): Promise<PatientEntity | null> {
try {
this.checkDatabaseState();
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = 'SELECT * FROM patients WHERE mobile = ? AND expertUuid = ?';
const resultSet = await this.rdbStore.querySql(sql, [mobile, expertUuid]);
if (resultSet.rowCount > 0) {
resultSet.goToFirstRow();
const patient = this.parseResultSet(resultSet);
resultSet.close();
return patient;
}
resultSet.close();
return null;
} catch (error) {
console.error('根据手机号查询患者失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('根据手机号查询患者失败');
}
}
}
async getPatientTypeByUuid(uuid: string): Promise<number | null> {
this.checkDatabaseState();
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = 'SELECT type FROM patients WHERE LOWER(uuid) = LOWER(?)';
const resultSet = await this.rdbStore.querySql(sql, [uuid]);
if (resultSet.rowCount > 0) {
resultSet.goToFirstRow();
const typeIndex = resultSet.getColumnIndex('type');
const type = typeIndex >= 0 ? resultSet.getDouble(typeIndex) : null;
resultSet.close();
return type;
}
resultSet.close();
return null;
}
// 删除指定专家的所有患者数据
async deletePatientsByExpertUuid(expertUuid: string): Promise<void> {
try {
this.checkDatabaseState();
console.info(`开始删除专家 ${expertUuid} 的所有患者数据`);
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = 'DELETE FROM patients WHERE expertUuid = ?';
await this.rdbStore.executeSql(sql, [expertUuid]);
console.info('删除专家患者数据成功');
} catch (error) {
console.error('删除专家患者数据失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('删除专家患者数据失败');
}
}
}
// 删除单个患者
async deletePatientByUuid(uuid: string): Promise<void> {
try {
this.checkDatabaseState();
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = 'DELETE FROM patients WHERE uuid = ?';
await this.rdbStore.executeSql(sql, [uuid]);
} catch (error) {
console.error('删除患者失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('删除患者失败');
}
}
}
// 更新患者信息
async updatePatient(patient: PatientEntity): Promise<void> {
try {
this.checkDatabaseState();
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
patient.updateTime = new Date().toISOString();
const sql = `
UPDATE patients
SET nickname = ?, mobile = ?, realName = ?, nation = ?,
sex = ?, type = ?, photo = ?, updateTime = ?
WHERE uuid = ?
`;
await this.rdbStore.executeSql(sql, [
patient.nickname,
patient.mobile,
patient.realName,
patient.nation,
patient.sex,
patient.type,
patient.photo,
patient.updateTime,
patient.uuid
]);
} catch (error) {
console.error('更新患者信息失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('更新患者信息失败');
}
}
}
// 插入单个患者
async insertPatient(patient: PatientEntity): Promise<void> {
try {
this.checkDatabaseState();
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
const sql = `
INSERT INTO patients (uuid, nickname, mobile, realName, nation, sex, type, photo, expertUuid, createTime, updateTime)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`;
await this.rdbStore.executeSql(sql, [
patient.uuid,
patient.nickname,
patient.mobile,
patient.realName,
patient.nation,
patient.sex,
patient.type,
patient.photo,
patient.expertUuid,
patient.createTime,
patient.updateTime
]);
} catch (error) {
console.error('插入患者数据失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('插入患者数据失败');
}
}
}
// 批量插入患者数据
async insertPatients(patients: PatientEntity[]): Promise<void> {
try {
this.checkDatabaseState();
console.info(`开始批量插入 ${patients.length} 个患者数据`);
if (!this.rdbStore) {
throw new Error('数据库连接为空');
}
await this.rdbStore.beginTransaction();
try {
for (const patient of patients) {
await this.insertPatient(patient);
}
await this.rdbStore.commit();
console.info('批量插入患者数据成功');
} catch (error) {
await this.rdbStore.rollBack();
console.error('批量插入患者数据失败,已回滚:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('批量插入患者数据失败');
}
}
} catch (error) {
console.error('批量插入患者数据失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('批量插入患者数据失败');
}
}
}
// 解析查询结果
private parseResultSet(resultSet: relationalStore.ResultSet): PatientEntity {
try {
const uuidIndex = resultSet.getColumnIndex('uuid');
const nicknameIndex = resultSet.getColumnIndex('nickname');
const mobileIndex = resultSet.getColumnIndex('mobile');
const realNameIndex = resultSet.getColumnIndex('realName');
const nationIndex = resultSet.getColumnIndex('nation');
const sexIndex = resultSet.getColumnIndex('sex');
const typeIndex = resultSet.getColumnIndex('type');
const photoIndex = resultSet.getColumnIndex('photo');
const expertUuidIndex = resultSet.getColumnIndex('expertUuid');
return new PatientEntity(
uuidIndex >= 0 ? (resultSet.getString(uuidIndex) ?? '') : '',
nicknameIndex >= 0 ? (resultSet.getString(nicknameIndex) ?? '') : '',
mobileIndex >= 0 ? (resultSet.getString(mobileIndex) ?? '') : '',
realNameIndex >= 0 ? (resultSet.getString(realNameIndex) ?? '') : '',
nationIndex >= 0 ? (resultSet.getString(nationIndex) ?? '') : '',
sexIndex >= 0 ? (resultSet.getDouble(sexIndex) ?? 0) : 0,
typeIndex >= 0 ? (resultSet.getDouble(typeIndex) ?? 0) : 0,
photoIndex >= 0 ? (resultSet.getString(photoIndex) ?? '') : '',
expertUuidIndex >= 0 ? (resultSet.getString(expertUuidIndex) ?? '') : ''
);
} catch (error) {
console.error('解析查询结果失败:', error);
if (error instanceof Error) {
throw error;
} else {
throw new Error('解析查询结果失败');
}
}
}
// 关闭数据库连接
async closeDatabase(): Promise<void> {
try {
if (this.rdbStore) {
await this.rdbStore.close();
this.rdbStore = null;
this.isInitialized = false;
console.info('数据库连接已关闭');
}
} catch (error) {
console.error('关闭数据库连接失败:', error);
}
}
// 检查数据库是否已初始化
isDatabaseInitialized(): boolean {
return this.isInitialized && this.rdbStore !== null;
}
// 开始事务
async beginTransaction(): Promise<void> {
this.checkDatabaseState();
if (this.rdbStore) {
await this.rdbStore.beginTransaction();
}
}
// 提交事务
async commitTransaction(): Promise<void> {
this.checkDatabaseState();
if (this.rdbStore) {
await this.rdbStore.commit();
}
}
// 回滚事务
async rollbackTransaction(): Promise<void> {
this.checkDatabaseState();
if (this.rdbStore) {
await this.rdbStore.rollBack();
}
}
}
// 数据库管理类
export class PatientDatabaseManager {
private static instance: PatientDatabaseManager;
private patientDao: PatientDao | null = null;
private context: common.Context | null = null;
private isInitialized: boolean = false;
private constructor() {}
public static getInstance(): PatientDatabaseManager {
if (!PatientDatabaseManager.instance) {
PatientDatabaseManager.instance = new PatientDatabaseManager();
}
return PatientDatabaseManager.instance;
}
// 初始化数据库
async initDatabase(context: common.Context): Promise<void> {
try {
console.info('开始初始化患者数据库管理器...');
this.context = context;
this.patientDao = new PatientDao(context);
await this.patientDao.initDatabase();
this.isInitialized = true;
console.info('患者数据库管理器初始化成功');
} catch (error) {
console.error('初始化患者数据库管理器失败:', error);
this.isInitialized = false;
if (error instanceof Error) {
throw error;
} else {
throw new Error('初始化患者数据库管理器失败');
}
}
}
// 获取PatientDao实例
getPatientDao(): PatientDao {
if (!this.patientDao || !this.isInitialized) {
throw new Error('数据库未初始化。请先调用 initDatabase() 方法。');
}
return this.patientDao;
}
// 检查数据库状态
isDatabaseReady(): boolean {
return this.isInitialized && this.patientDao !== null && this.patientDao.isDatabaseInitialized();
}
// 从服务器获取患者列表并存储到数据库
async patientsToFMDB(): Promise<void> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法获取患者数据');
return;
}
const expertUuid = authStore.getUser().uuid;
if (!expertUuid) {
console.error('专家UUID未找到');
return;
}
console.info('开始从服务器获取患者数据...');
hdHttp.post<string>(BasicConstant.urlExpert + 'patientList', {
expertUuid: authStore.getUser().uuid
} as updateExtraData).then(async (res: HdResponse<string>) => {
try {
let json: Record<string, string> = JSON.parse(res + '') as Record<string, string>;
console.log('服务器返回的患者数据:', json);
if (json.code == '1' && json.data && Array.isArray(json.data)) {
console.info(`服务器返回 ${json.data.length} 个患者数据`);
for (const item of json.data as PatientData[]) {
const patientEntity = new PatientEntity(
item.uuid || '',
item.nickname || '',
item.mobile || '',
item.realName || '',
item.nation || '',
item.sex || 0,
item.type || 0,
item.photo || '',
expertUuid
);
// 检查本地是否已存在
const localPatient = await this.getPatientDao().getPatientByUuid(item.uuid || '');
if (localPatient) {
// 已存在,更新
await this.getPatientDao().updatePatient(patientEntity);
} else {
// 不存在,插入
await this.getPatientDao().insertPatient(patientEntity);
}
}
} else {
console.error('服务器返回数据格式错误:', json);
}
} catch (parseError) {
console.error('解析服务器响应失败:', parseError);
}
}).catch((err: BusinessError) => {
console.error('请求患者数据失败:', err);
});
} catch (error) {
console.error('获取患者数据过程中发生错误:', error);
}
}
// 获取所有患者数据
async getAllPatients(): Promise<PatientEntity[]> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法获取患者数据');
return [];
}
const expertUuid = authStore.getUser().uuid;
if (!expertUuid) {
console.error('专家UUID未找到');
return [];
}
console.info('开始获取所有患者数据...');
const patients = await this.getPatientDao().getPatientsByExpertUuid(expertUuid);
console.info(`成功获取 ${patients.length} 个患者数据`);
return patients;
} catch (error) {
console.error('获取所有患者数据失败:', error);
return [];
}
}
// 根据UUID获取单个患者
async getPatientByUuid(uuid: string): Promise<PatientEntity | null> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法获取患者数据');
return null;
}
return await this.getPatientDao().getPatientByUuid(uuid);
} catch (error) {
console.error('根据UUID获取患者失败:', error);
return null;
}
}
// 根据手机号获取患者
async getPatientByMobile(mobile: string): Promise<PatientEntity | null> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法获取患者数据');
return null;
}
const expertUuid = authStore.getUser().uuid;
if (!expertUuid) {
console.error('专家UUID未找到');
return null;
}
return await this.getPatientDao().getPatientByMobile(mobile, expertUuid);
} catch (error) {
console.error('根据手机号获取患者失败:', error);
return null;
}
}
// 更新患者信息
async updatePatient(patient: PatientEntity): Promise<boolean> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法更新患者数据');
return false;
}
await this.getPatientDao().updatePatient(patient);
return true;
} catch (error) {
console.error('更新患者信息失败:', error);
return false;
}
}
// 在 PatientDatabaseManager 类内添加
async updatePatientByData(patient: PatientData): Promise<boolean> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法更新患者数据');
return false;
}
// 构造 PatientEntity
const entity = new PatientEntity(
patient.uuid || '',
patient.nickname || '',
patient.mobile || '',
patient.realName || '',
patient.nation || '',
patient.sex || 0,
patient.type || 0,
patient.photo || '',
patient.expertUuid || '' // 注意PatientData 里 expertUuid 字段必须有
);
await this.getPatientDao().updatePatient(entity);
return true;
} catch (error) {
console.error('updatePatientByData 更新患者信息失败:', error);
return false;
}
}
// 删除患者
async deletePatient(uuid: string): Promise<boolean> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法删除患者数据');
return false;
}
await this.getPatientDao().deletePatientByUuid(uuid);
return true;
} catch (error) {
console.error('删除患者失败:', error);
return false;
}
}
// 删除当前专家的所有患者数据
async deleteAllPatients(): Promise<boolean> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法删除患者数据');
return false;
}
const expertUuid = authStore.getUser().uuid;
if (!expertUuid) {
console.error('专家UUID未找到');
return false;
}
await this.getPatientDao().deletePatientsByExpertUuid(expertUuid);
return true;
} catch (error) {
console.error('删除所有患者失败:', error);
return false;
}
}
// 搜索患者(根据姓名或昵称)
async searchPatients(keyword: string): Promise<PatientEntity[]> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法搜索患者数据');
return [];
}
const expertUuid = authStore.getUser().uuid;
if (!expertUuid) {
console.error('专家UUID未找到');
return [];
}
const allPatients = await this.getPatientDao().getPatientsByExpertUuid(expertUuid);
return allPatients.filter(patient =>
patient.realName.toLowerCase().includes(keyword.toLowerCase()) ||
patient.nickname.toLowerCase().includes(keyword.toLowerCase())
);
} catch (error) {
console.error('搜索患者失败:', error);
return [];
}
}
// 添加患者信息(支持单个或多个)
async addPatients(patients: PatientData | PatientData[]): Promise<boolean> {
try {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好,无法添加患者数据');
return false;
}
const expertUuid = authStore.getUser().uuid;
if (!expertUuid) {
console.error('专家UUID未找到');
return false;
}
// 将单个患者转换为数组
const patientsArray = Array.isArray(patients) ? patients : [patients];
if (patientsArray.length === 0) {
console.warn('没有患者数据需要添加');
return true;
}
console.info(`开始处理 ${patientsArray.length} 个患者数据...`);
// 批量处理患者数据
const patientDao = this.getPatientDao();
await patientDao.beginTransaction();
try {
for (const patientData of patientsArray) {
// 转换为PatientEntity对象
const patientEntity = new PatientEntity(
patientData.uuid || '',
patientData.nickname || '',
patientData.mobile || '',
patientData.realName || '',
patientData.nation || '',
patientData.sex || 0,
patientData.type || 0,
patientData.photo || '',
expertUuid
);
// 检查患者是否已存在根据UUID
const existingPatient = await patientDao.getPatientByUuid(patientData.uuid || '');
if (existingPatient) {
// 患者已存在,更新信息
console.info(`患者 ${patientData.uuid} 已存在,执行更新操作`);
await patientDao.updatePatient(patientEntity);
} else {
// 患者不存在,插入新记录
console.info(`患者 ${patientData.uuid} 不存在,执行插入操作`);
await patientDao.insertPatient(patientEntity);
}
}
await patientDao.commitTransaction();
console.info(`成功处理 ${patientsArray.length} 个患者数据`);
return true;
} catch (error) {
await patientDao.rollbackTransaction();
console.error('处理患者数据失败,已回滚:', error);
return false;
}
} catch (error) {
console.error('添加患者数据失败:', error);
return false;
}
}
// 添加单个患者信息(便捷方法)
async addPatient(patient: PatientData): Promise<boolean> {
return await this.addPatients(patient);
}
// 在 PatientDatabaseManager 类内添加
async getPatientTypeByUuid(uuid: string): Promise<number | null> {
if (!this.isDatabaseReady()) {
console.error('数据库未准备好无法获取患者type');
return null;
}
return await this.getPatientDao().getPatientTypeByUuid(uuid);
}
}
// 导出单例实例
export const patientDbManager = PatientDatabaseManager.getInstance();