首页、患者分组、审核、列表等

This commit is contained in:
xiaoxiao
2025-07-10 09:27:17 +08:00
parent 5954f51701
commit 4641e9ecee
136 changed files with 7577 additions and 171 deletions
+16 -1
View File
@@ -26,7 +26,7 @@ export { DataWebModel,DataWebModels } from './src/main/ets/models/DataWebModel'
export { PromptActionClass } from './src/main/ets/components/PromptActionClass'
export { RequestDefaultModel,ExpertData } from './src/main/ets/models/RequestDefaultModel'
export { RequestDefaultModel,ExpertData} from './src/main/ets/models/RequestDefaultModel'
export { HdList, HdListController } from './src/main/ets/components/HdList'
@@ -56,8 +56,23 @@ export { huanzheDb } from './src/main/ets/utils/HuanzhelasDbHelper'
export { HdSearchNav } from './src/main/ets/components/HdSearchNav'
export { HdHomeNav } from './src/main/ets/components/HdHomeNav'
export { DefaultHintProWindows } from './src/main/ets/Views/DefaultHintProWindows'
export { TimestampUtil } from './src/main/ets/utils/TimestampUtil'
export { SignPopWindow } from './src/main/ets/Views/SignPopWindow'
// 患者数据库管理相关导出
export {
patientDbManager,
PatientDatabaseManager,
PatientEntity,
PatientDao,
PatientData
} from './src/main/ets/utils/PatientsEntity'
export { PermissionsUtils } from './src/main/ets/utils/PermissionsUtils'
export { calculateExactAge } from './src/main/ets/utils/DateUtils'
@@ -0,0 +1,75 @@
import { router } from '@kit.ArkUI'
import { BasicConstant } from '../../../../Index';
@CustomDialog
export struct SignPopWindow {
controller: CustomDialogController;
@Prop signDay:string = '今天是我们相识的第1天';
@Prop signWeek:string = '1';
@Prop signMouth:string = '1';
@Prop signNews:string = '卫健委:鼓励医务人员做兼职!可以做哪些兼职,有哪些法律分险?';
@Prop signHtml:string = '';
build() {
Column(){
Image($r('app.media.sign_popwindow_close'))
.margin({right:10}).width(20).height(70)
.onClick(()=>{
this.controller.close()
})
Stack(){
Column(){
Text('签到成功')
.textAlign(TextAlign.Center)
.fontSize(21).fontColor(Color.White).backgroundColor('rgb(255, 210,3)').height(50).width('100%')
.borderRadius({topLeft:8,topRight:8})
Text(this.signDay)
.textAlign(TextAlign.Center)
.fontSize(16).fontColor(Color.Black).height(18).width('100%').margin({top:15})
Row(){
Text('本周共签到')
.fontSize(14).fontColor('#333333')
Text(this.signWeek)
.fontSize(20).fontColor(Color.Red)
Text('次')
.fontSize(14).fontColor('#333333')
}.width('100%').justifyContent(FlexAlign.Center).height(20).margin({top:15,bottom:3}).alignItems(VerticalAlign.Bottom)
Row(){
Text('已连续签到')
.fontSize(14).fontColor('#333333')
Text(this.signMouth)
.fontSize(20).fontColor(Color.Red)
Text('天')
.fontSize(14).fontColor('#333333')
}.width('100%').justifyContent(FlexAlign.Center).height(20).alignItems(VerticalAlign.Bottom)
Text('连续签到获得更多积分')
.textAlign(TextAlign.Center)
.fontSize(14).fontColor(Color.Red).margin({top:15,bottom:10})
}.width('90%').backgroundColor(Color.White).borderRadius(8).margin({top:30})
Row(){
Image($r('app.media.sign_back_leftright_icon')).width(18).height(18)
Blank()
.width('50%').height(18)
Image($r('app.media.sign_back_leftright_icon')).width(18).height(18)
}.margin({top:20})
Column(){
Image($r('app.media.sign_back_news_icon'))
.width(36).height(36)
Text(this.signNews)
.width('100%')
.fontSize(16).fontColor(Color.Black)
.backgroundColor(Color.White).borderRadius(8).padding({left:10,top:10,right:10,bottom:10}).margin({top:5})
}.width('90%').margin({top:215,bottom:15})
.onClick(()=>{
this.controller.close();
router.pushUrl({
url: 'pages/WebView/WebPage',
params: {'title':this.signNews,'url':BasicConstant.urlHtml+this.signHtml}
})
})
}.width('100%').backgroundColor('rgb(255, 161, 24)').borderRadius(8).alignContent(Alignment.Top)
}.width('100%').alignItems(HorizontalAlign.End)
}
}
@@ -0,0 +1,59 @@
import { ChangeUtil } from "../../../../Index";
@Component
export struct HdHomeNav {
@StorageProp('topHeight')
topHeight: number = 0
@Prop
bgColor: ResourceStr = $r('app.color.top_bg')
@Prop
hasBorder: boolean = false
@Prop
leftIcon: ResourceStr = $r('app.media.home_no_qiandao_icon')
@Prop
isFocus:boolean = false;
@Prop
placeholder:string = ''
@State textInputContent:string = ''
@Prop alpha: number = 0; // 接收透明度值
@Prop backColor: string = ''
private leftItemAction: () => void = () => {};
// 添加左侧点击函数
private searchItemAction:()=> void = () => {};
build() {
Row() {
Row() {
Image(this.leftIcon)
.size({ width: 24, height: 24 })
.fillColor($r('app.color.black'))
}.size({ width: 40, height: 50 })
.onClick(()=>this.leftItemAction())
Row(){
Image($r('app.media.selected_hospital_ws'))
.width(20).height(20)
.margin({left:10})
Text(this.placeholder)
.defaultFocus(this.isFocus)
.fontSize(15)
.fontColor(Color.Gray)
.backgroundColor(Color.White)
.height('100%').width('calc(100% - 40vp)')
.padding({ left: 0 })
.margin({left:5})
}
.backgroundColor(Color.White)
.borderWidth(0.5).borderRadius(5).borderColor($r('app.color.common_main_color')).justifyContent(FlexAlign.Start)
.width('calc(100% - 40vp)').height(40)
.onClick(()=>{
this.searchItemAction();
})
}
.padding({ left: 16, right: 16, top: this.topHeight })
.height(56 + this.topHeight)
.width('100%')
.backgroundColor(ChangeUtil.hexToRgba(this.backColor,this.alpha))
}
}
@@ -29,13 +29,20 @@ export struct HdNav {
showRightText: boolean = false
@Prop
rightText: string = ''
@Prop
rightBackColor:ResourceColor = this.bgColor
@Prop
rightTextColor:ResourceColor = this.textColor
@BuilderParam
titleBuilder: () => void = defaultBuilder
@BuilderParam
menuBuilder: () => void = defaultBuilder
@Prop
isLeftAction: boolean = false
// 添加右侧点击函数
private rightItemAction:()=> void = () => {};
// 添加左侧点击函数
private leftItemAction:()=> void = () => {};
build() {
Row() {
@@ -44,7 +51,7 @@ export struct HdNav {
{
Image(this.leftIcon)
.size({ width: 24, height: 24 })
.onClick(() => router.back())
.onClick(() => this.isLeftAction? this.leftItemAction():router.back())
.fillColor($r('app.color.black'))
}
.size({ width: 50, height: 50 })
@@ -84,11 +91,16 @@ export struct HdNav {
} else if (this.showRightText) {
Text(this.rightText)
.fontSize(16)
.fontColor(this.textColor)
.maxFontSize(16)
.minFontSize(6)
.maxLines(1)
.fontColor(this.rightTextColor)
.onClick(()=>this.rightItemAction())
.width(50)
.textAlign(TextAlign.Center)
.borderRadius(5)
.backgroundColor(this.rightBackColor)
.height(35)
// .margin({right:10})
} else {
Blank()
@@ -50,7 +50,6 @@ export struct HdSearchNav {
.fontSize(15)
.backgroundColor(this.bgColor)
.height('100%').width('calc(100% - 40vp)')
.padding({ left: 0 })
.margin({left:5})
.onChange((value:string)=>{
this.textInputContent = value;
@@ -24,6 +24,22 @@ export class BasicConstant {
// static readonly polvId = "21";//保利威视学员id
static readonly addBonusPoints = BasicConstant.urlExpertApp+'addBonusPoints'
static readonly indexV2 = BasicConstant.urlExpertAPI+'indexV2';//首页轮播
static readonly applyList = BasicConstant.urlExpert+'applyList'
static readonly groupList = BasicConstant.urlExpertApp+'groupList'
static readonly isMaiLanExpert = BasicConstant.urlExpertAPI+'isMaiLanExpert'
static readonly patientListByGroup = BasicConstant.urlExpertApp+'patientListByGroup'
static readonly deleteGroup = BasicConstant.urlExpertApp+'deleteGroup'
static readonly addGroup = BasicConstant.urlExpertApp+'addGroup'
static readonly updateGroup = BasicConstant.urlExpertApp+'updateGroup'
static readonly relationRecordLately = BasicConstant.urlExpertAPI+'relationRecordLately'
static readonly updateNicknameNote = BasicConstant.urlExpertAPI+'updateNicknameNote'
static readonly applyListOperate = BasicConstant.urlExpert+'applyListOperate'
static readonly patientListNoInThisGroup = BasicConstant.urlExpertAPI+'patientListNoInThisGroup'
static readonly patientCard = BasicConstant.urlExpertAPI+'patientCard'
static readonly toAddNickname = BasicConstant.urlExpert+'toAddNickname'
static readonly patientDetail = BasicConstant.urlExpert+'patientDetail'
static readonly getStartpage=BasicConstant.urlExpertApp + "startpage";
static readonly meetingListV2=BasicConstant.urlExpertAPI + "meetingListV2";
static readonly meetingV2Video=BasicConstant.urlExpertAPI + "meetingV2Video";
@@ -53,7 +69,6 @@ export class BasicConstant {
static readonly listOutPatient = BasicConstant.urlExpertApp+'listOutPatient'//出诊
static readonly urlOutpatientnew = BasicConstant.wxUrl+"wxPatient/index.htm#/outPatient?link=share&expertUuid=";//出诊
static readonly getNewWa="https://wx.igandan.com/shop_notify/";//肝胆商城妞娃购买链接
static readonly patientDetail= BasicConstant.urlExpert + "patientDetail";// 患者详情
static readonly newConsultList = BasicConstant.urlExpertAPI + "newConsultList";// 新的公益咨询列表
static readonly consultListHis = BasicConstant.urlExpertAPI +"consultListHis";// 公益咨询历史列表
static readonly consultDetail = BasicConstant.urlExpertAPI + "consultDetail";// 公益咨询详情
@@ -1,4 +1,3 @@
export interface RequestDefaultModel{
code:string;
data:DefaulyData[];
@@ -0,0 +1,862 @@
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 uuid = ?';
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 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;
}
}
// 删除患者
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);
}
}
// 导出单例实例
export const patientDbManager = PatientDatabaseManager.getInstance();
@@ -0,0 +1,50 @@
import { systemDateTime } from '@kit.BasicServicesKit';
export class TimestampUtil {
static format(timestamp: number | string, formatStr: string): string {
const date = new Date(timestamp);
const padZero = (num: number, len: number = 2) => num.toString().padStart(len, '0');
const map: Record<string, string> = {
'YYYY': date.getFullYear().toString(),
'MM': padZero(date.getMonth() + 1),
'DD': padZero(date.getDate()),
'HH': padZero(date.getHours()),
'mm': padZero(date.getMinutes()),
'ss': padZero(date.getSeconds()),
};
let result = formatStr;
Object.keys(map).forEach((key) => {
result = result.replace(new RegExp(key, 'g'), map[key]);
});
return result;
}
static isToday(dateStr: string): boolean {
try {
// 1. 解析目标日期字符串 → Date对象
const targetDate = new Date(dateStr);
// 2. 获取当前系统日期(年、月、日)
const now = new Date(systemDateTime.getTime());
const currentYear = now.getFullYear();
const currentMonth = now.getMonth();
const currentDay = now.getDate();
// 3. 提取目标日期的年、月、日
const targetYear = targetDate.getFullYear();
const targetMonth = targetDate.getMonth();
const targetDay = targetDate.getDate();
// 4. 比较日期是否相同
return (
targetYear === currentYear &&
targetMonth === currentMonth &&
targetDay === currentDay
);
} catch (e) {
console.error("日期解析失败", e);
return false;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB