首页、患者分组、审核、列表等
This commit is contained in:
+16
-1
@@ -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 |
Reference in New Issue
Block a user