From abbd0540ab6fde3e14fa79e67f972d9f50def1d3 Mon Sep 17 00:00:00 2001 From: xiaoxiao Date: Fri, 25 Jul 2025 13:38:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=82=A3=E8=80=85=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chatkit_ui/Index.ets | 4 +- commons/basic/Index.ets | 4 +- .../main/ets/Views/DefaultHintProWindows.ets | 2 +- .../src/main/ets/Views/PreviewPhotos.ets | 143 ++++-- .../src/main/ets/Views/TripleOptionDialog.ets | 65 +++ .../src/main/ets/constants/BasicConstant.ets | 6 + .../basic/src/main/ets/utils/ChangeUtil.ets | 165 +++--- features/Home/src/main/ets/pages/HomePage.ets | 98 ++-- .../mypage/src/main/ets/view/OneSection.ets | 2 +- features/patient/Index.ets | 4 +- features/patient/oh-package.json5 | 4 +- .../ets/components/AddAndEditRecordComp.ets | 263 ++++++++++ .../ets/components/AddRecordIllnessComp.ets | 22 - .../ets/components/BuildOrEditGroupPage.ets | 9 +- .../main/ets/components/PatientApplyPage.ets | 2 +- .../ets/components/PatientDetailsComp.ets | 100 ++-- .../src/main/ets/components/PatientsGroup.ets | 2 +- .../main/ets/components/PatientsListComp.ets | 68 ++- .../ets/components/RecordTheIllnessComp.ets | 47 +- .../components/SelectedPatientGroupComp.ets | 238 +++++++++ .../ets/components/SendGroupMessageComp.ets | 471 ++++++++++++++++++ .../src/main/ets/models/ApplyModel.ets | 1 + .../main/ets/models/PatientsGroupModel.ets | 3 +- .../patient/src/main/ets/views/ApplyViews.ets | 6 + .../base/media/group_message_more_icon.png | Bin 0 -> 2636 bytes .../base/media/group_message_navi_righr.png | Bin 0 -> 2324 bytes .../resources/base/media/im_icon_camera.png | Bin 0 -> 3779 bytes .../resources/base/media/im_icon_images.png | Bin 0 -> 4388 bytes .../base/media/message_sendgroup_delete.png | Bin 0 -> 3180 bytes .../main/resources/base/media/mine_logo.png | Bin 0 -> 24460 bytes .../resources/base/media/outpatient_true.png | Bin 0 -> 2566 bytes .../base/media/patient_teach_call.png | Bin 0 -> 2703 bytes .../resources/base/media/quck_message.png | Bin 0 -> 2499 bytes .../base/media/ytx_chatting_hospital.png | Bin 0 -> 1801 bytes .../media/ytx_chattingfooter_shopping.png | Bin 0 -> 2602 bytes .../main/ets/pages/MinePage/FeedbackPage.ets | 3 +- .../PatientsPage/GroupSendMessagePage.ets | 41 ++ .../ets/pages/PatientsPage/PatientPages.ets | 32 +- .../resources/base/profile/main_pages.json | 3 +- 39 files changed, 1527 insertions(+), 281 deletions(-) create mode 100644 commons/basic/src/main/ets/Views/TripleOptionDialog.ets create mode 100644 features/patient/src/main/ets/components/AddAndEditRecordComp.ets delete mode 100644 features/patient/src/main/ets/components/AddRecordIllnessComp.ets create mode 100644 features/patient/src/main/ets/components/SelectedPatientGroupComp.ets create mode 100644 features/patient/src/main/ets/components/SendGroupMessageComp.ets create mode 100644 features/patient/src/main/resources/base/media/group_message_more_icon.png create mode 100644 features/patient/src/main/resources/base/media/group_message_navi_righr.png create mode 100644 features/patient/src/main/resources/base/media/im_icon_camera.png create mode 100644 features/patient/src/main/resources/base/media/im_icon_images.png create mode 100644 features/patient/src/main/resources/base/media/message_sendgroup_delete.png create mode 100644 features/patient/src/main/resources/base/media/mine_logo.png create mode 100644 features/patient/src/main/resources/base/media/outpatient_true.png create mode 100644 features/patient/src/main/resources/base/media/patient_teach_call.png create mode 100644 features/patient/src/main/resources/base/media/quck_message.png create mode 100644 features/patient/src/main/resources/base/media/ytx_chatting_hospital.png create mode 100644 features/patient/src/main/resources/base/media/ytx_chattingfooter_shopping.png create mode 100644 products/expert/src/main/ets/pages/PatientsPage/GroupSendMessagePage.ets diff --git a/chatkit_ui/Index.ets b/chatkit_ui/Index.ets index f5dcbe9..f2d2e0c 100644 --- a/chatkit_ui/Index.ets +++ b/chatkit_ui/Index.ets @@ -13,4 +13,6 @@ export { ForwardMessageDialog } from './src/main/ets/view/ForwardMessageDialog' export { TextMessageDetailDialog } from './src/main/ets/view/TextMessageDetailDialog' -export { MessageItemClick } from './src/main/ets/view/MessageItemClick' \ No newline at end of file +export { MessageItemClick } from './src/main/ets/view/MessageItemClick' + +export { TeachDialog } from './src/main/ets/view/TeachDialog' \ No newline at end of file diff --git a/commons/basic/Index.ets b/commons/basic/Index.ets index 40dec70..5c4a753 100644 --- a/commons/basic/Index.ets +++ b/commons/basic/Index.ets @@ -91,4 +91,6 @@ export { ChatExtModel,ChatParam } from './src/main/ets/models/ChatExtModel' export { PatientListModel,PatientsData } from './src/main/ets/models/PatientListModel' -export { applyListCallBacl, applyListModel, applyHistoryCallBacl , historyObjectModel, historyModel } from './src/main/ets/models/ApplyModel' \ No newline at end of file +export { applyListCallBacl, applyListModel, applyHistoryCallBacl , historyObjectModel, historyModel } from './src/main/ets/models/ApplyModel' + +export { TripleOptionDialog } from './src/main//ets/Views/TripleOptionDialog' \ No newline at end of file diff --git a/commons/basic/src/main/ets/Views/DefaultHintProWindows.ets b/commons/basic/src/main/ets/Views/DefaultHintProWindows.ets index f693341..6c0c59c 100644 --- a/commons/basic/src/main/ets/Views/DefaultHintProWindows.ets +++ b/commons/basic/src/main/ets/Views/DefaultHintProWindows.ets @@ -53,7 +53,7 @@ export struct DefaultHintProWindows { Text(this.confirmTitle) .fontSize(15) .fontColor(this.confirmTitleColor) - }.width('45%').height(30).backgroundColor(this.cancleColor) + }.width('45%').height(30).backgroundColor(this.confirmColor) .onClick(() => { this.selectedButton(1) }) diff --git a/commons/basic/src/main/ets/Views/PreviewPhotos.ets b/commons/basic/src/main/ets/Views/PreviewPhotos.ets index 5dd6fe1..9b31d42 100644 --- a/commons/basic/src/main/ets/Views/PreviewPhotos.ets +++ b/commons/basic/src/main/ets/Views/PreviewPhotos.ets @@ -1,5 +1,5 @@ -import { router } from "@kit.ArkUI"; +import { promptAction, router } from "@kit.ArkUI"; import http from '@ohos.net.http' import fileio from '@ohos.fileio' import prompt from '@ohos.promptAction' @@ -8,11 +8,15 @@ import { BusinessError } from '@kit.BasicServicesKit'; import { BasicConstant } from "../constants/BasicConstant"; import { ViewImageInfo } from "../models/ViewImageInfo"; import { PermissionsUtils } from "../utils/PermissionsUtils"; +import { fileIo, fileUri } from "@kit.CoreFileKit"; +import { photoAccessHelper } from "@kit.MediaLibraryKit"; +import fs from '@ohos.file.fs' @Component export struct PreviewPhotos { + private imageBuffer?: ArrayBuffer @State imgList: ViewImageInfo[]=[] // 传入图片数组 @State params:paramPhoto= router.getParams() as paramPhoto @@ -46,54 +50,85 @@ export struct PreviewPhotos { } } - // 下载图片方法(伪代码,需根据实际API实现) - async downloadImage(url: string) { + // // 下载图片方法(伪代码,需根据实际API实现) + // async downloadImage(url: string) { + // try { + // // 1. 检查权限 + // const hasPermission = await this.checkStoragePermission(); + // if (!hasPermission) { + // // 申请权限 + // const granted = await this.requestStoragePermission(); + // if (!granted) { + // prompt.showToast({ message: $r('app.string.netease_permission_denied_tips') }); + // return; + // } + // } + // + // // 显示下载中提示 + // prompt.showToast({ message: $r('app.string.netease_saving_image_tips') }); + // + // // 2. 下载图片 + // const httpRequest = http.createHttp() + // const response = await httpRequest.request(url, { + // method: http.RequestMethod.GET, + // expectDataType: http.HttpDataType.ARRAY_BUFFER, + // connectTimeout: 30000, // 30秒连接超时 + // readTimeout: 30000, // 30秒读取超时 + // }) + // httpRequest.destroy() + // + // if (response.responseCode !== 200) { + // prompt.showToast({ message: $r('app.string.netease_download_failed_tips') }) + // return + // } + // + // // 3. 写入到公共图片目录 + // const fileName = 'img_' + Date.now() + '.jpg' + // const filePath = '/storage/media/100/local/photos/' + fileName + // + // try { + // const fd = await fileio.open(filePath, 0o2 | 0o100) // 写入+创建 + // await fileio.write(fd, new Uint8Array(response.result as ArrayBuffer)) + // await fileio.close(fd) + // prompt.showToast({ message: $r('app.string.netease_save_success_tips') }) + // } catch (fileError) { + // console.error('文件写入失败:', fileError); + // prompt.showToast({ message: $r('app.string.netease_save_failed_tips') }) + // } + // } catch (e) { + // console.error('下载图片失败:', e); + // prompt.showToast({ message: $r('app.string.netease_save_error_tips') }) + // } + // } + + async downloadImage(url: string,result: SaveButtonOnClickResult) { + if (result !== SaveButtonOnClickResult.SUCCESS) { + promptAction.showToast({ message: '权限获取失败', duration: 2000 }) + return + } + const context = getContext(this) as common.UIAbilityContext try { - // 1. 检查权限 - const hasPermission = await this.checkStoragePermission(); - if (!hasPermission) { - // 申请权限 - const granted = await this.requestStoragePermission(); - if (!granted) { - prompt.showToast({ message: $r('app.string.netease_permission_denied_tips') }); - return; - } - } - - // 显示下载中提示 - prompt.showToast({ message: $r('app.string.netease_saving_image_tips') }); - - // 2. 下载图片 const httpRequest = http.createHttp() const response = await httpRequest.request(url, { method: http.RequestMethod.GET, - expectDataType: http.HttpDataType.ARRAY_BUFFER, - connectTimeout: 30000, // 30秒连接超时 - readTimeout: 30000, // 30秒读取超时 + expectDataType: http.HttpDataType.ARRAY_BUFFER }) - httpRequest.destroy() + this.imageBuffer = response.result as ArrayBuffer + const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context) + const uri = await phAccessHelper.createAsset( + photoAccessHelper.PhotoType.IMAGE, + 'jpg' // 文件扩展名 + ) - if (response.responseCode !== 200) { - prompt.showToast({ message: $r('app.string.netease_download_failed_tips') }) - return - } + const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + await fs.write(file.fd, this.imageBuffer) + await fs.close(file.fd) - // 3. 写入到公共图片目录 - const fileName = 'img_' + Date.now() + '.jpg' - const filePath = '/storage/media/100/local/photos/' + fileName - - try { - const fd = await fileio.open(filePath, 0o2 | 0o100) // 写入+创建 - await fileio.write(fd, new Uint8Array(response.result as ArrayBuffer)) - await fileio.close(fd) - prompt.showToast({ message: $r('app.string.netease_save_success_tips') }) - } catch (fileError) { - console.error('文件写入失败:', fileError); - prompt.showToast({ message: $r('app.string.netease_save_failed_tips') }) - } - } catch (e) { - console.error('下载图片失败:', e); - prompt.showToast({ message: $r('app.string.netease_save_error_tips') }) + promptAction.showToast({ message: '图片已保存到相册', duration: 2000 }) + } catch (error) { + const err = error as BusinessError + console.error(`保存失败: Code=${err.code}, Message=${err.message}`) + promptAction.showToast({ message: `保存失败: ${err.code}` }) } } @@ -165,25 +200,29 @@ export struct PreviewPhotos { .onClick(() => { router.back() }) - Row() - { - Image($r('app.media.ic_topbar_save')).width(30).height(30) - .onClick(()=>{ - this.downloadImage( this.imgList[this.previewIndex].url?(BasicConstant.urlHtml + this.imgList[this.previewIndex].url): this.imgList[this.previewIndex].url) - }) + Row() { + SaveButton({icon:SaveIconStyle.FULL_FILLED,buttonType:ButtonType.Capsule}) + .iconSize(25) + .iconColor($r('app.color.main_color')) + .backgroundColor('rgba(255,255,255,0.01)') + .width(50) + .height(30) + .onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => { + const url = this.imgList[this.previewIndex].url + ? (BasicConstant.urlHtml + this.imgList[this.previewIndex].url) + : this.imgList[this.previewIndex].url; + this.downloadImage(url,result) + }) Blank() Text(`${this.previewIndex + 1}/${this.imgList.length}`) .fontSize(18) .fontColor($r('app.color.top_title')) - - - } .visibility(this.downLoad?Visibility.Visible:Visibility.Hidden) .height(30) .width('100%') - .padding({ left:20,right:20 }) + .padding({ left:10,right:20 }) .margin({bottom:40}) .alignRules({bottom: { anchor: "__container__", align: VerticalAlign.Bottom }} ) } diff --git a/commons/basic/src/main/ets/Views/TripleOptionDialog.ets b/commons/basic/src/main/ets/Views/TripleOptionDialog.ets new file mode 100644 index 0000000..dc584fa --- /dev/null +++ b/commons/basic/src/main/ets/Views/TripleOptionDialog.ets @@ -0,0 +1,65 @@ + +@CustomDialog +export struct TripleOptionDialog { + controller: CustomDialogController; // 必须包含的控制器属性 + @Prop title: string = '' + @Prop subTitle:string = '' + @Prop oneButtonTitle:string = '' + @Prop twoButtonTitle:string = '' + + private buttonSelected: (actionType:string) => void = () => {}; + + // 按钮点击事件处理 + private handleAction(actionType: string) { + this.buttonSelected(actionType) + this.controller.close(); // 关闭弹窗 + } + + build() { + Column() { + Text(this.title) + .fontSize(20) + .fontWeight(FontWeight.Bold) + .margin({ top: 20 }) + if (this.subTitle.length) { + Text(this.subTitle) + .fontSize(15) + .padding({top:5}) + } + Column() { + Blank() + .width('100%') + .height(1) + .backgroundColor('#f4f4f4') + Text(this.oneButtonTitle) + .height(40) + .fontSize(14) + .fontColor('#333333') + .onClick(() => this.handleAction(this.oneButtonTitle)) + Blank() + .width('100%') + .height(1) + .backgroundColor('#f4f4f4') + Text(this.twoButtonTitle) + .height(40) + .fontSize(14) + .fontColor('#333333') + .onClick(() => this.handleAction(this.twoButtonTitle)) + Blank() + .width('100%') + .height(1) + .backgroundColor('#f4f4f4') + Text('取消') + .height(40) + .fontSize(14) + .fontColor('#999999') + .onClick(() => this.controller.close()) + } + .width('100%') + .margin({ top:20,bottom: 20 }) + } + .backgroundColor(Color.Transparent) + .borderRadius(16) + .width('100%') + } +} \ No newline at end of file diff --git a/commons/basic/src/main/ets/constants/BasicConstant.ets b/commons/basic/src/main/ets/constants/BasicConstant.ets index 68d0e43..93e44a7 100644 --- a/commons/basic/src/main/ets/constants/BasicConstant.ets +++ b/commons/basic/src/main/ets/constants/BasicConstant.ets @@ -38,6 +38,12 @@ export class BasicConstant { static readonly updateNicknameNote = BasicConstant.urlExpertAPI+'updateNicknameNote' static readonly applyListOperate = BasicConstant.urlExpert+'applyListOperate' static readonly patientListNoInThisGroup = BasicConstant.urlExpertAPI+'patientListNoInThisGroup' + static readonly patientList = BasicConstant.urlExpert+'patientList' + static readonly listGroupSendMsg = BasicConstant.urlExpertAPI+'listGroupSendMsg' + static readonly delGroupSendMsg = BasicConstant.urlExpertAPI+'delGroupSendMsg' + static readonly addGroupSendMsg4YunXin = BasicConstant.urlExpertAPI+'addGroupSendMsg4YunXin' + static readonly addConditionRecord = BasicConstant.urlExpert+'addConditionRecord' + static readonly upConditionRecord = BasicConstant.urlExpert+'upConditionRecord' static readonly patientCard = BasicConstant.urlExpertAPI+'patientCard' static readonly toAddNickname = BasicConstant.urlExpert+'toAddNickname' static readonly cancelRes = BasicConstant.urlExpert+'cancelRes' diff --git a/commons/basic/src/main/ets/utils/ChangeUtil.ets b/commons/basic/src/main/ets/utils/ChangeUtil.ets index 160645e..8e17d3f 100644 --- a/commons/basic/src/main/ets/utils/ChangeUtil.ets +++ b/commons/basic/src/main/ets/utils/ChangeUtil.ets @@ -9,6 +9,7 @@ import util from '@ohos.util'; import { i18n } from '@kit.LocalizationKit'; import { connection } from '@kit.NetworkKit'; import http from '@ohos.net.http' +import {BasicConstant} from '../constants/BasicConstant' export class ChangeUtil { /** * 将HashMap转成JsonString @@ -98,67 +99,6 @@ export class ChangeUtil { return bf } - /** - * 将图片转换为base64字符串 - * @param imageUri 图片URI - * @returns Promise base64字符串 - */ - static async imageToBase64(imageUri: string): Promise { - // 1. 验证URI有效性 - if (!imageUri || !imageUri.startsWith('file://')) { - throw new Error('无效的图片URI,必须以file://开头'); - } - let imageSource: image.ImageSource | undefined; - let pixelMap: image.PixelMap | undefined; - let imagePacker: image.ImagePacker | undefined; - try { - const file = fs.openSync(imageUri, fs.OpenMode.READ_ONLY); - const imageSource = image.createImageSource(file.fd); - if (!imageSource) { - throw new Error('创建ImageSource失败,请检查图片路径'); - } - logger.info('正在获取图片信息...'); - const imageInfo = await imageSource.getImageInfo(); - logger.info(`图片尺寸: ${imageInfo.size.width}x${imageInfo.size.height}`); - pixelMap = await imageSource.createPixelMap({ - desiredSize: { - width: imageInfo.size.width, - height: imageInfo.size.height - } - }); - if (!pixelMap) { - throw new Error('创建PixelMap失败'); - } - // 5. 压缩图片 - imagePacker = image.createImagePacker(); - const packOpts: image.PackingOption = { - format: "image/jpeg", - quality: 80 // 适当提高质量保证清晰度 - }; - logger.info('正在压缩图片...'); - const arrayBuffer = await imagePacker.packing(pixelMap, packOpts); - const unit8Array = new Uint8Array(arrayBuffer); - let binary = ''; - unit8Array.forEach(byte => { - binary += String.fromCharCode(byte); - }); - const base64String = Base64Util.encodeToStrSync(binary); - logger.info(`图片转换成功,大小: ${Math.round(base64String.length / 1024)}KB`); - return base64String; - } catch (error) { - logger.error('图片处理失败: ' + JSON.stringify(error)); - throw new Error(`图片处理失败: ${error.message}`); - } finally { - // 7. 确保释放资源 - try { - pixelMap?.release(); - imageSource?.release(); - imagePacker?.release(); - } catch (e) { - logger.error('资源释放异常: ' + JSON.stringify(e)); - } - } - } static isLetter(char: string): boolean { if (char.length !== 1) return false; @@ -244,4 +184,107 @@ export class ChangeUtil { arr[arr.length - 1] = first; // 首位移至末尾 return arr; } + + /** + * 将URI或URL数组转换为Base64字符串数组 + * @param items - 包含文件URI或网络URL的数组 + * @returns Promise - Base64字符串数组 + */ + static async convertUrisOrUrlsToBase64(items: string[]): Promise { + const results: string[] = []; + + for (const item of items) { + try { + let arrayBuffer: ArrayBuffer; + let mimeType = 'image/jpeg'; // 默认MIME类型 + // 处理本地文件URI + if (item.startsWith('file://')) {// || !item.includes('://') + arrayBuffer = await ChangeUtil.readLocalFile(item); + } + // 处理网络URL + else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) { + arrayBuffer = await ChangeUtil.downloadNetworkResource(item); + } + // 处理其他类型资源 + else { + throw new Error(`Unsupported URI scheme: ${item}`); + } + // 关键优化:添加图片压缩步骤[6,8](@ref) + const compressedBuffer = await ChangeUtil.compression( + arrayBuffer, + mimeType, + 0.5 // 压缩质量为50% + ); + // 转换为Base64 + results.push(ChangeUtil.convertToBase64(compressedBuffer)); + } catch (err) { + console.error(`转换失败: ${JSON.stringify(err)}`); + results.push(''); // 失败时返回空字符串 + } + } + return results; + } + + /** + * 读取本地文件到ArrayBuffer + * @param uri - 文件URI + * @returns Promise + */ + static async readLocalFile(uri: string): Promise { + try { + // 打开文件 + const file = fs.openSync(uri, fs.OpenMode.READ_ONLY); + // 获取文件大小 + const stat = fs.statSync(file.fd); + const size = stat.size; + // 创建缓冲区并读取数据 + const buffer = new ArrayBuffer(size); + fs.readSync(file.fd, buffer); + // 关闭文件 + fs.closeSync(file); + return buffer; + } catch (err) { + throw new Error(`文件读取失败: ${JSON.stringify(err)}`); + } + } + + /** + * 下载网络资源到ArrayBuffer + * @param url - 资源URL + * @returns Promise + */ + static async downloadNetworkResource(url: string): Promise { + return new Promise((resolve, reject) => { + const httpRequest = http.createHttp(); + httpRequest.request( + BasicConstant.urlImage+url, + { + method: http.RequestMethod.GET + }, + (err, data) => { + httpRequest.destroy(); + if (err) { + reject(new Error(`网络请求失败: ${JSON.stringify(err)}`)); + return; + } + if (data.responseCode === 200) { + resolve(data.result as ArrayBuffer); + } else { + reject(new Error(`HTTP错误: ${data.responseCode}`)); + } + } + ) + }) + } + + static convertToBase64(buffer: ArrayBuffer): string { + const helper = new util.Base64Helper(); + const uint8Array = new Uint8Array(buffer); + return helper.encodeToStringSync(uint8Array); + } + + static isImageFileByRegex(path: string): boolean { + const pattern = /\.(jpg|jpeg|png|gif|bmp|webp)$/i; + return pattern.test(path); + } } \ No newline at end of file diff --git a/features/Home/src/main/ets/pages/HomePage.ets b/features/Home/src/main/ets/pages/HomePage.ets index 1c34d49..ec849c6 100644 --- a/features/Home/src/main/ets/pages/HomePage.ets +++ b/features/Home/src/main/ets/pages/HomePage.ets @@ -23,8 +23,6 @@ export struct HomePage { @State signData:Record = {}; scroller:Scroller = new Scroller() - private hintWindowDialog!: CustomDialogController; - private signWindowDialog!:CustomDialogController; dialog: CustomDialogController = new CustomDialogController({ builder: HdLoadingDialog({ message: '加载中...' }), @@ -32,42 +30,36 @@ export struct HomePage { alignment: DialogAlignment.Center }) - private hintPopWindowDialog() { - this.hintWindowDialog = new CustomDialogController({ - builder:DefaultHintProWindows({ - controller:this.hintWindowDialog, - message:this.hintMessage, - cancleTitle:'', - confirmTitle:'关闭', - confirmTitleColor: '#000000', - selectedButton: (index:number)=>{ - this.hintWindowDialog.close(); - } - }), - alignment: DialogAlignment.Center, - cornerRadius:24, - autoCancel:false, - backgroundColor: ('rgba(0,0,0,0.5)'), - }) - } + hintWindowDialog: CustomDialogController = new CustomDialogController({ + builder:DefaultHintProWindows({ + message:this.hintMessage, + cancleTitle:'', + confirmTitle:'关闭', + confirmTitleColor: '#000000', + selectedButton: (index:number)=>{ + this.hintWindowDialog.close(); + } + }), + alignment: DialogAlignment.Center, + cornerRadius:24, + autoCancel:false, + backgroundColor: ('rgba(0,0,0,0.5)'), + }) - private signPopWindowDialog(){ - this.signWindowDialog = new CustomDialogController({ - builder:SignPopWindow({ - controller:this.signWindowDialog, - signDay:'今天是我们相识的第'+this.signData.gdxzday+'天', - signWeek:this.signData.totalDay, - signMouth:this.signData.continuous_day, - signNews:this.signData.news['title'], - signHtml:this.signData.news['path'], - }), - alignment: DialogAlignment.Center, - cornerRadius:8, - autoCancel:false, - backgroundColor: Color.Transparent, - backgroundBlurStyle: BlurStyle.NONE, - }) - } + signWindowDialog:CustomDialogController = new CustomDialogController({ + builder:SignPopWindow({ + signDay:'今天是我们相识的第'+String(this.signData.gdxzday)+'天', + signWeek:String(this.signData.totalDay), + signMouth:String(this.signData.continuous_day), + signNews:this.signData.news['title'], + signHtml:this.signData.news['path'], + }), + alignment: DialogAlignment.Center, + cornerRadius:8, + autoCancel:false, + backgroundColor: Color.Transparent, + backgroundBlurStyle: BlurStyle.NONE, + }) gotoTop() { this.scroller.scrollToIndex(0); @@ -76,8 +68,6 @@ export struct HomePage { aboutToAppear(): void { this.initData() - this.hintPopWindowDialog(); - this.signPopWindowDialog(); } initData() { @@ -100,25 +90,25 @@ export struct HomePage { } getSignData() { - const hashMap: HashMap = new HashMap(); + const hashMap: HashMap = new HashMap() this.dialog.open() - hashMap.clear(); - hashMap.set('score_type','1'); + hashMap.clear() + hashMap.set('score_type','1') hdHttp.httpReq(BasicConstant.addBonusPoints,hashMap).then(async (res: HdResponse) => { - logger.info('Response addBonusPoints'+res); - this.dialog.close(); - let json:Record = JSON.parse(res+'') as Record; + logger.info('Response addBonusPoints'+res) + this.dialog.close() + let json:Record = JSON.parse(res+'') as Record if (json.code == '1') { - this.homeData.sign_in = '1'; - this.signData = json; - this.signWindowDialog.open(); + this.homeData.sign_in = '1' + this.signData = json + this.signWindowDialog.open() } else if (json.code == '201') { - this.homeData.sign_in = '1'; - this.hintMessage = '今日已签到,每日只能签到一次。\n请明日继续哦~'; - this.hintWindowDialog.open(); + this.homeData.sign_in = '1' + this.hintMessage = '今日已签到,每日只能签到一次。\n请明日继续哦~' + this.hintWindowDialog.open() } }).catch((err: BusinessError) => { - this.dialog.close(); + this.dialog.close() }) } @@ -170,9 +160,7 @@ export struct HomePage { searchItemAction:()=>{ router.pushUrl({ url:'pages/SearchPage/VideoSearchPage', - params: { - params:{'pageName':'视频'} - } + params:{'pageName':'视频'} }) } }) diff --git a/features/mypage/src/main/ets/view/OneSection.ets b/features/mypage/src/main/ets/view/OneSection.ets index 7919f9f..6a8d87f 100644 --- a/features/mypage/src/main/ets/view/OneSection.ets +++ b/features/mypage/src/main/ets/view/OneSection.ets @@ -26,7 +26,7 @@ export struct OneSection { @State oneSectionList: Array = [ new MyPageSectionClass('oneItem', $r('app.media.my_page_patientAudit'), '患者审核', 'pages/PatientsPage/PatientPages',false), new MyPageSectionClass('twoItem', $r('app.media.my_page_patientList'), '患者分组', 'pages/PatientsPage/PatientsGroupPage',false), - new MyPageSectionClass('threeItem', $r('app.media.my_page_message'), '群发消息', '/pages/MyHomePage',false), + new MyPageSectionClass('threeItem', $r('app.media.my_page_message'), '群发消息', 'pages/PatientsPage/GroupSendMessagePage',false), new MyPageSectionClass('fourItem', $r('app.media.my_page_QrCode'), '随访二维码', 'pages/WebView/WebPage',false), new MyPageSectionClass('fiveItem', $r('app.media.my_page_visitPlan'), '出诊计划', 'pages/Netease/OutpatientPage',false) ]; diff --git a/features/patient/Index.ets b/features/patient/Index.ets index c460c9f..37328bc 100644 --- a/features/patient/Index.ets +++ b/features/patient/Index.ets @@ -14,4 +14,6 @@ export { PatientsListComp } from './src/main/ets/components/PatientsListComp' export { PatientDetailsComp } from './src/main/ets/components/PatientDetailsComp' -export { GroupManagementComp } from './src/main/ets/components/GroupManagementComp' \ No newline at end of file +export { GroupManagementComp } from './src/main/ets/components/GroupManagementComp' + +export { MassSendingComp } from './src/main/ets/components/MassSendingComp' \ No newline at end of file diff --git a/features/patient/oh-package.json5 b/features/patient/oh-package.json5 index 81ee9ae..c3c5d8e 100644 --- a/features/patient/oh-package.json5 +++ b/features/patient/oh-package.json5 @@ -7,6 +7,8 @@ "license": "Apache-2.0", "dependencies": { "@itcast/basic": "file:../../commons/basic", - "refreshlib": "file:../../RefreshLib" + "refreshlib": "file:../../RefreshLib", + '@nimkit/chatkit': 'file:../../chatkit', + "@nimkit/chatkit_ui": 'file:../../chatkit_ui' } } diff --git a/features/patient/src/main/ets/components/AddAndEditRecordComp.ets b/features/patient/src/main/ets/components/AddAndEditRecordComp.ets new file mode 100644 index 0000000..0e1aa26 --- /dev/null +++ b/features/patient/src/main/ets/components/AddAndEditRecordComp.ets @@ -0,0 +1,263 @@ +import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"; +import { + authStore, + BasicConstant, + ChangePhotoGrids, ChangeUtil, + hdHttp, + HdLoadingDialog, + HdNav, + HdResponse, + logger, + PhotoActionSheet, TimestampUtil, ViewImageInfo } from "@itcast/basic"; +import { promptAction } from "@kit.ArkUI"; +import { BusinessError } from "@kit.BasicServicesKit"; +import { values } from "@nimsdk/vendor"; +import { uri } from "@kit.ArkTS"; +import { rcp } from "@kit.RemoteCommunicationKit"; + +@HMRouter({pageUrl:'AddAndEditRecordComp'}) +@Component +export struct AddAndEditRecordComp { + @State photos: string[] = [] + @State base64Array:string[] = [] + @State maxSelectNumber: number = 8 + private params: ESObject = HMRouterMgr.getCurrentParam() + private photoSheetDialog!: CustomDialogController; + @State nowDate:Date = new Date + @State creat_time:string = TimestampUtil.format(this.nowDate,'YYYY-MM-DD') + @State recordUuid:string = '' + @State inputContent:string = '' + @State + @Watch('onAddImg') + addImg: boolean=false + @State + @Watch('onRemoveImg') + removeImg: boolean=false + @State removeIndex: number = 0 + + dialog: CustomDialogController = new CustomDialogController({ + builder: HdLoadingDialog({ message: '加载中...' }), + customStyle: true, + alignment: DialogAlignment.Center + }) + + onAddImg() { + this.photoSheetDialog.open() + } + onRemoveImg() { + this.photos.splice(this.removeIndex, 1) + this.maxSelectNumber = 8 - this.photos.length; + } + + aboutToAppear(): void { + this.initPhotoDialog() + if (this.params) { + if (this.params["model"]) { + const model:recordList = this.params["model"] + this.photos.push(...this.changeToImgs(model.photo)) + this.inputContent = model.des + this.recordUuid = model.uuid + this.creat_time = model.create_date + this.maxSelectNumber = 8 - this.photos.length + + ChangeUtil.convertUrisOrUrlsToBase64(model.photo).then(base64Array => { + console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + this.base64Array = base64Array + }).catch((err:BusinessError) => { + console.error('批量转换失败:', err) + }) + } + } + } + + submitData() { + if (ChangeUtil.stringIsUndefinedAndNull(this.creat_time)) { + promptAction.showToast({ message:'请选择日期', duration: 1000 }) + return + } + if (ChangeUtil.stringIsUndefinedAndNull(this.inputContent)) { + promptAction.showToast({ message:'请描述患者病情', duration: 1000 }) + return + } + this.dialog.open() + const requestUrl = this.recordUuid?BasicConstant.upConditionRecord:BasicConstant.addConditionRecord + const entity: rcp.MultipartForm = this.recordUuid? new rcp.MultipartForm({ + "uuid":this.recordUuid, + "des":this.inputContent, + "create_date":this.creat_time + }) : new rcp.MultipartForm({ + "expert_uuid":authStore.getUser().uuid, + "patient_uuid":this.params["patient_uuid"], + "des":this.inputContent, + "create_date":this.creat_time, + // "img1":this.base64Array[0] + }) + this.base64Array.forEach((base64Str: string, index: number) => { + if (index < 8) { + entity.fields[`img${index + 1}`] = base64Str; + } + }) + const session = rcp.createSession(); + session.post(requestUrl, entity) + .then((response) => { + this.dialog.close(); + logger.info('Response '+requestUrl+':'+response); + let json:Record | Array>> = JSON.parse(response+'') as Record | Array>>; + if(json.code == '1') { + HMRouterMgr.pop({param:{"isRefresh":"1"}}) + promptAction.showToast({ message:'提交病情记录成功', duration: 1000 }) + } else { + console.error('获取患者信息失败:'+json.message) + promptAction.showToast({ message: String(json.message), duration: 1000 }) + } + }) + .catch((err: BusinessError) => { + this.dialog.close(); + console.error(`Response fails: ${err}`); + }) + } + + build() { + Column() { + HdNav({title:'病情记录',isLeftAction:true,showRightIcon:false,showRightText:true,rightText:'提交',rightItemAction:()=>{ + this.submitData() + },leftItemAction:()=>{ + HMRouterMgr.pop() + }}) + this.contentView() + } + .width('100%') + } + + @Builder + contentView() { + Row(){ + Text('日期') + .fontColor($r('app.color.main_color')) + .margin({left:10}) + .layoutWeight(1) + + Text(this.creat_time) + .margin({right:10}) + .onClick(()=>{ + this.selectedData() + }) + } + .width('100%') + .height(50) + .margin({top:5}) + + Blank() + .width('100%') + .height(0.5) + .margin({left:10}) + .backgroundColor('#999999') + + TextArea({ + placeholder:'请描述患者病情', + text:this.inputContent + }) + .backgroundColor(Color.White) + .margin({top:10}) + .width('100%') + .height(150) + .onChange((values:string)=>{ + this.inputContent = values + }) + + ChangePhotoGrids({ + imgList:this.changeToImg(this.photos), + maxSelectNumber:8, + addImg:this.addImg, + removeImg:this.removeImg, + removeIndex:this.removeIndex + }) + .height(200) + .padding({top:10}) + .backgroundColor('#f4f4f4') + + } + + changeToImg( imgListurl:string[]) { + let imgListtmps:ViewImageInfo[]=[] + imgListurl.forEach((url: string) => { + let item = {uri:url} as ViewImageInfo + imgListtmps.push(item) + }) + return imgListtmps + } + + changeToImgs( imgListurl:string[]) + { + let imgListtmps:string[]=[] + imgListurl.forEach((url: string) => { + let item = BasicConstant.urlHtml + url + imgListtmps.push(item) + }) + return imgListtmps + + } + + private initPhotoDialog() { + this.photoSheetDialog = new CustomDialogController({ + builder: PhotoActionSheet({ + controller: this.photoSheetDialog, + maxSelectNumber:this.maxSelectNumber, + onPhotoSelected: async (uris: string[] | string) => { + let selectedUris: string[] = []; + if (Array.isArray(uris)) { + selectedUris = uris; + } else if (typeof uris === 'string') { + selectedUris = [uris]; + } + this.photos.push(...selectedUris); + this.maxSelectNumber = 8 - this.photos.length + // ChangeUtil.convertUriToBase64(selectedUris[0]).then((base64)=>{ + // this.base64Array = [base64] + // }) + ChangeUtil.convertUrisOrUrlsToBase64(selectedUris).then(base64Array => { + console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + this.base64Array = base64Array + }).catch((err:BusinessError) => { + console.error('批量转换失败:', err) + }) + } + }), + alignment: DialogAlignment.Bottom, + customStyle: true, + autoCancel: false, + backgroundColor: ('rgba(0,0,0,0.5)'), + height: '100%' + }); + } + + selectedData(){ + CalendarPickerDialog.show({ + selected: new Date(), + backgroundColor: Color.White, + backgroundBlurStyle: BlurStyle.NONE, + shadow: ShadowStyle.OUTER_FLOATING_SM, + onAccept: (value) => { + const today = new Date(); + today.setHours(0, 0, 0, 0); + const selected = new Date(value); + selected.setHours(0, 0, 0, 0); + if (selected < today) { + promptAction.showToast({ message: '只能选择今天及以后的日期', duration: 1500 }) + return + } + this.creat_time = TimestampUtil.format(value,'YYYY-MM-DD') + } + }) + } +} + +interface recordList { + create_date: string + des: string + patient_uuid: string + expert_uuid: string + uuid:string + photo:Array + lineHeight:Length +} diff --git a/features/patient/src/main/ets/components/AddRecordIllnessComp.ets b/features/patient/src/main/ets/components/AddRecordIllnessComp.ets deleted file mode 100644 index 5b03043..0000000 --- a/features/patient/src/main/ets/components/AddRecordIllnessComp.ets +++ /dev/null @@ -1,22 +0,0 @@ -import { HMRouter } from "@hadss/hmrouter"; - -@HMRouter({pageUrl:'AddRecordIllnessComp'}) -@Component -export struct AddRecordIllnessComp { - @State message: string = 'Hello World'; - - build() { - Row() { - Column() { - Text(this.message) - .fontSize($r('app.float.page_text_font_size')) - .fontWeight(FontWeight.Bold) - .onClick(() => { - this.message = 'Welcome'; - }) - } - .width('100%') - } - .height('100%') - } -} diff --git a/features/patient/src/main/ets/components/BuildOrEditGroupPage.ets b/features/patient/src/main/ets/components/BuildOrEditGroupPage.ets index 540f35f..29e72e3 100644 --- a/features/patient/src/main/ets/components/BuildOrEditGroupPage.ets +++ b/features/patient/src/main/ets/components/BuildOrEditGroupPage.ets @@ -82,7 +82,7 @@ export struct BuildOrEditGroupPage { if(json.code == '1') { promptAction.showToast({ message: '删除分组成功', duration: 1000 }) // router.back(); - HMRouterMgr.pop() + HMRouterMgr.pop({param:{"nameString":true}}) } else { console.error('删除患者分组列表失败:'+json.message) promptAction.showToast({ message: json.message, duration: 1000 }) @@ -114,8 +114,7 @@ export struct BuildOrEditGroupPage { let json:Record = JSON.parse(res+'') as Record; if(json.code == '1') { promptAction.showToast({ message:'分组成功', duration: 1000 }) - // router.back(); - HMRouterMgr.pop() + HMRouterMgr.pop({param:{"nameString":true}}) } else if (json.code == '2') { promptAction.showToast({ message:'该分组已存在', duration: 1000 }) } else { @@ -139,7 +138,7 @@ export struct BuildOrEditGroupPage { showRightText: true, isLeftAction:true, leftItemAction:()=>{ - HMRouterMgr.pop() + HMRouterMgr.pop({param:{"nameString":false}}) }, rightItemAction: () => { if (this.params.title == '新建分组') { @@ -248,7 +247,7 @@ export struct BuildOrEditGroupPage { .onClick(()=>{ this.hintWindowDialog.open(); }) - .visibility(this.params.title == '新建分组'?Visibility.Hidden:Visibility.Visible) + .visibility(this.params.title == '新建分组'?Visibility.None:Visibility.Visible) }.width('100%') .height(120) .justifyContent(FlexAlign.End) diff --git a/features/patient/src/main/ets/components/PatientApplyPage.ets b/features/patient/src/main/ets/components/PatientApplyPage.ets index d67346d..a6cc106 100644 --- a/features/patient/src/main/ets/components/PatientApplyPage.ets +++ b/features/patient/src/main/ets/components/PatientApplyPage.ets @@ -48,7 +48,7 @@ export struct PatientApplyPage { let json:applyHistoryCallBacl = JSON.parse(res+'') as applyHistoryCallBacl; if(json.code == 200) { this.historyArray = json.data.list; - this.totalPageNumer = Number(json.data.total); + this.totalPageNumer = Number(json.data.pages); } else { console.error('患者申请记录列表失败:'+json.message) promptAction.showToast({ message: json.message, duration: 1000 }) diff --git a/features/patient/src/main/ets/components/PatientDetailsComp.ets b/features/patient/src/main/ets/components/PatientDetailsComp.ets index 2980ca1..0e7e82c 100644 --- a/features/patient/src/main/ets/components/PatientDetailsComp.ets +++ b/features/patient/src/main/ets/components/PatientDetailsComp.ets @@ -1,4 +1,4 @@ -import { authStore, ChangeUtil, HdNav } from '@itcast/basic'; +import { authStore, ChangeUtil, ChatParam, HdNav, preferenceStore } from '@itcast/basic'; import { promptAction } from '@kit.ArkUI' import { HdLoadingDialog } from '@itcast/basic' import { BasicConstant,hdHttp, HdResponse ,logger} from '@itcast/basic/Index' @@ -9,6 +9,7 @@ import { applyListModel } from '../models/ApplyModel' import { TextExpandView } from '../views/TextExpandView' import call from '@ohos.telephony.call' import { HMLifecycleContext, HMRouter, HMRouterMgr, IHMLifecycle } from "@hadss/hmrouter" +import { ChatKitClient } from '@nimkit/chatkit'; @HMRouter({ pageUrl: 'PatientDetailsComp' }) @Component @@ -152,44 +153,41 @@ export struct PatientDetailsComp { } build() { - Row() { - Column() { - HdNav({ - title: '患者详情', - showRightIcon: true, - hasBorder: true, - rightIcon: $r("app.media.patient_details_navigation_right"), - showRightText: false, - isLeftAction:true, - leftItemAction:()=>{ - HMRouterMgr.pop() - }, - rightItemAction: () => { - HMRouterMgr.push({pageUrl: 'PatientCommonSettingComp',param:{"title":"患者详情","patient_uuid":this.params.patient_uuid}}) - } - }) - Scroll(this.scroller) { - Column() { - this.patientsView() - this.otherMsgView() - this.historyView() - if (this.patientCase.length > 0) { - this.patientCaseView() - } - this.footerView() - } - .width('100%') - .justifyContent(FlexAlign.Start) - } - .width('100%') - .height('calc(100% - 56vp)') - .backgroundColor('#f4f4f4') - .scrollBar(BarState.Off) - .align(Alignment.TopStart) + Column() { + HdNav({ + title: '患者详情', + showRightIcon: true, + hasBorder: true, + rightIcon: $r("app.media.patient_details_navigation_right"), + showRightText: false, + isLeftAction:true, + leftItemAction:()=>{ + HMRouterMgr.pop() + }, + rightItemAction: () => { + HMRouterMgr.push({pageUrl: 'PatientCommonSettingComp',param:{"title":"患者详情","patient_uuid":this.params.patient_uuid}}) } - .width('100%').height('100%') + }) + Scroll(this.scroller) { + Column() { + this.patientsView() + this.otherMsgView() + this.historyView() + if (this.patientCase.length > 0) { + this.patientCaseView() + } + this.footerView() + } + .width('100%') + .justifyContent(FlexAlign.Start) } - .height('100%') + .width('100%') + .height('calc(100% - 106vp)') + .backgroundColor('#f4f4f4') + .scrollBar(BarState.Off) + .align(Alignment.TopStart) + } + .width('100%') } @Builder @@ -295,7 +293,7 @@ export struct PatientDetailsComp { Text('患者病史') .fontSize(15) .fontColor('#333333') - + if (this.medicalHistoryContent.title) { TextExpandView({ textSectionAttribute: this.medicalHistoryContent, @@ -324,9 +322,9 @@ export struct PatientDetailsComp { .fontColor('#333333') .margin({bottom:10}) - Grid(){ - ForEach(this.patientCase,(item:Record)=>{ - GridItem(){ + Scroll() { + Row({ space: 10 }) { + ForEach(this.patientCase,(item:Record)=>{ Column(){ Text(String(item.createDate).substring(0,10)) .fontSize(15) @@ -341,13 +339,14 @@ export struct PatientDetailsComp { .height(70) .backgroundColor('#f4f4f4') .borderRadius(3) - } - .padding({right:10}) - .onClick(()=>{ - HMRouterMgr.push({pageUrl:'InspectionReportComp',param:item}) + .onClick(()=>{ + HMRouterMgr.push({pageUrl:'InspectionReportComp',param:item}) + }) }) - }) + } } + .scrollable(ScrollDirection.Horizontal) + .scrollBar(BarState.Off) } .alignItems(HorizontalAlign.Start) .backgroundColor(Color.White) @@ -377,13 +376,20 @@ export struct PatientDetailsComp { if (index == 1) { HMRouterMgr.push({pageUrl:"FollowPlanListComp", param:{ - "patient_uuid":this.params.patient_uuid, + "patient_uuid":this.params.patient_uuid, "FollowUpUuid":this.patientGroupData.FollowUpUuid, "nickname":this.patientData2.nickname, "realName":this.patientData2.realName}}) } else if (index == 2) { HMRouterMgr.push({pageUrl:"RecordTheIllnessComp", param:{"patient_uuid":this.params.patient_uuid}}) + } else { + preferenceStore.setItemString('gdxz_consult_uuid',this.params.patient_uuid) + preferenceStore.setItemString('gdxz_sessionType',BasicConstant.general) + HMRouterMgr.push({ pageUrl: 'ChatP2PPage' , param: { + conversationId: ChatKitClient.nim.conversationIdUtil.p2pConversationId(this.params.patient_uuid + .toLowerCase()) + } as ChatParam}) } }) }) diff --git a/features/patient/src/main/ets/components/PatientsGroup.ets b/features/patient/src/main/ets/components/PatientsGroup.ets index 16150ea..9a0b4a2 100644 --- a/features/patient/src/main/ets/components/PatientsGroup.ets +++ b/features/patient/src/main/ets/components/PatientsGroup.ets @@ -43,10 +43,10 @@ export struct PatientsGroup { list_sort:this.list_sort } as groupRequest).then(async (res: HdResponse) => { this.dialog.close(); + this.groupListArray = [] logger.info('Response groupList'+res); let json:groupRequestCall = JSON.parse(res+'') as groupRequestCall; if(json.code == 1) { - this.groupListArray = [] this.groupListArray = json.data } else { console.error('患者分组列表失败:'+json.message) diff --git a/features/patient/src/main/ets/components/PatientsListComp.ets b/features/patient/src/main/ets/components/PatientsListComp.ets index 8550965..229ccb2 100644 --- a/features/patient/src/main/ets/components/PatientsListComp.ets +++ b/features/patient/src/main/ets/components/PatientsListComp.ets @@ -1,10 +1,10 @@ -import { HdNav, EmptyViewComp,HdLoadingDialog } from '@itcast/basic'; +import { HdNav, EmptyViewComp,HdLoadingDialog, authStore } from '@itcast/basic'; import { promptAction } from '@kit.ArkUI' import { BasicConstant,hdHttp, HdResponse ,logger} from '@itcast/basic/Index' import { BusinessError } from '@kit.BasicServicesKit'; import HashMap from '@ohos.util.HashMap' import { patientListModel } from '../models/PatientsGroupModel' -import { HMRouter, HMRouterMgr } from "@hadss/hmrouter" +import { HMPopInfo, HMRouter, HMRouterMgr } from "@hadss/hmrouter" @HMRouter({ pageUrl: 'PatientsListComp' }) @Component @@ -18,7 +18,12 @@ export struct PatientsListComp { @State isEmptyViewVisible: boolean = false; // 控制显隐的状态变量 aboutToAppear(): void { - this.getPatientsListData(); + const groupPatientsList = this.params?.selectedPatients as patientListModel[] | undefined + if (groupPatientsList?.length) { + this.getPatientsListData() + } else { + this.getAllPatientsListData() + } } dialog: CustomDialogController = new CustomDialogController({ @@ -28,22 +33,22 @@ export struct PatientsListComp { }) getPatientsListData() { - const hashMap: HashMap = new HashMap(); - hashMap.set('group_uuid',String(this.params.group_uuid)); + const hashMap: HashMap = new HashMap() + hashMap.set('group_uuid',this.params.group_uuid) this.dialog.open() hdHttp.httpReq(BasicConstant.patientListNoInThisGroup,hashMap).then(async (res: HdResponse) => { - this.dialog.close(); - logger.info('Response patientListNoInThisGroup'+res); - let json:Record = JSON.parse(res+'') as Record; + this.dialog.close() + logger.info('Response patientListNoInThisGroup'+res) + let json:Record = JSON.parse(res+'') as Record if(json.code == '1') { - const patientsList = this.params?.selectedPatients as patientListModel[] | undefined; + const patientsList = this.params?.selectedPatients as patientListModel[] | undefined if (patientsList?.length) { - const uuidSet = new Set(patientsList.map(item => item.uuid)); + const uuidSet = new Set(patientsList.map(item => item.uuid)) const dataArray = json.data as patientListModel[]; for (const model of dataArray) { if (!uuidSet.has(model.uuid)) { - this.patientsList.push(model); - this.patientsArray.push(model); + this.patientsList.push(model) + this.patientsArray.push(model) } } } else { @@ -61,6 +66,27 @@ export struct PatientsListComp { }) } + getAllPatientsListData() { + this.dialog.open() + hdHttp.post(BasicConstant.patientList, { + "expertUuid": authStore.getUser().uuid + } as Record).then(async (res: HdResponse) => { + this.dialog.close() + logger.info('Response patientList'+res) + let json:Record = JSON.parse(res+'') as Record + if(json.code == '1') { + this.patientsList = json.data as patientListModel[]; + this.patientsArray = json.data as patientListModel[]; + } else { + console.error('患者列表失败:'+json.message) + promptAction.showToast({ message: String(json.message), duration: 1000 }) + } + }).catch((err: BusinessError) => { + this.dialog.close(); + console.error(`Response fails: ${err}`); + }) + } + searchPatientAction(){ if (this.inputString.length > 0) { this.patientsList = [] @@ -82,7 +108,21 @@ export struct PatientsListComp { leftItemAction:()=>{ HMRouterMgr.pop() },rightItemAction:()=>{ - HMRouterMgr.pop({param:{'selectedPatients':this.patientsList}}) + if (this.params.pageName) { + if (this.patientsList.length > 200) { + promptAction.showToast({message:'最多发送200个患者,请重新选择!',duration:1000}) + return + } + HMRouterMgr.push({pageUrl:'SendGroupMessageComp',param:{'selectedPatients':this.patientsList}},{ + onResult:(popInfo:HMPopInfo)=>{ + if (popInfo && popInfo.result && popInfo.result["isPop"] !== undefined) { + HMRouterMgr.pop({param:{'isRefresh':true}}) + } + } + }) + } else { + HMRouterMgr.pop({param:{'selectedPatients':this.patientsList}}) + } // router.back({ // url:'pages/PatientsPage/BuildOrEditGroupPage', // params:{'selectedPatients':this.patientsList} @@ -158,7 +198,7 @@ export struct PatientsListComp { .width(50) .height(50) .margin({ left: 15 }) - Text(item.nickname ? item.nickname : item.realname) + Text(item.nickname ? item.nickname : item.realname?item.realname:item.realName) .fontSize(16) .fontColor('#333333') .margin({ left: 15 }) diff --git a/features/patient/src/main/ets/components/RecordTheIllnessComp.ets b/features/patient/src/main/ets/components/RecordTheIllnessComp.ets index 3ac135d..178839e 100644 --- a/features/patient/src/main/ets/components/RecordTheIllnessComp.ets +++ b/features/patient/src/main/ets/components/RecordTheIllnessComp.ets @@ -1,4 +1,4 @@ -import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"; +import { HMPopInfo, HMRouter, HMRouterMgr } from "@hadss/hmrouter"; import { authStore, hdHttp, BasicConstant, HdNav, HdResponse, logger, HdLoadingDialog, EmptyViewComp } from "@itcast/basic"; import { PullToRefreshLayout, RefreshController } from "refreshlib"; @@ -60,7 +60,15 @@ export struct RecordTheIllnessComp { build() { Column() { HdNav({isLeftAction:true,title:'病情记录',showRightText:false,rightIcon:$r('app.media.record_add_list'),rightItemAction:()=>{ - HMRouterMgr.push({pageUrl:'AddRecordIllnessComp'}) + HMRouterMgr.push({pageUrl:'AddAndEditRecordComp',param:{"patient_uuid":this.params.patient_uuid}},{ + onResult:(popInfo:HMPopInfo)=>{ + if (popInfo && popInfo.result && popInfo.result["isRefresh"] !== undefined) { + this.pageNumber = 1 + this.recordList = [] + this.getRecordListData() + } + } + }) },leftItemAction:()=>{ HMRouterMgr.pop() }}) @@ -104,11 +112,12 @@ export struct RecordTheIllnessComp { @Builder contentView(){ List({scroller:this.scroller}){ - ForEach(this.recordList,(item:recordList)=>{ + ForEach(this.recordList,(item:recordList,index:number)=>{ ListItem(){ Stack(){ Text() .width(2) + .height(item.lineHeight ?? 0) .backgroundColor($r('app.color.main_color')) .margin({left:13}) Image($r('app.media.record_list_time_dian')) @@ -130,8 +139,7 @@ export struct RecordTheIllnessComp { Column() { Text(item.des) .fontSize(16) - .width('100%') - + .margin({left:35,right:15}) Grid() { ForEach(item.photo, (photo: string) => { GridItem() { @@ -143,23 +151,37 @@ export struct RecordTheIllnessComp { .margin({ right: 10, bottom: 10 }) }) } - .width('100%') - .margin({top:20}) + .margin({left:35,top:20,right:50}) - Blank() + Text() .width('100%') - .height(1) - .backgroundColor('#f4f4f4') - .margin({top: 10}) + .height(0.5) + .backgroundColor('#999999') + .margin({left:15,top:10}) } - .margin({left:35,top:60,right:15}) + .margin({top:60}) .alignItems(HorizontalAlign.Start) .justifyContent(FlexAlign.Start) } .width('100%') .alignContent(Alignment.TopStart) + .onAreaChange((oldVal, newVal) => { + this.recordList[index].lineHeight = newVal.height + this.recordList = [...this.recordList] + }) } .width('100%') + .onClick(()=>{ + HMRouterMgr.push({pageUrl:'AddAndEditRecordComp',param:{"model":item}},{ + onResult:(popInfo:HMPopInfo)=>{ + if (popInfo && popInfo.result && popInfo.result["isRefresh"] !== undefined) { + this.pageNumber = 1 + this.recordList = [] + this.getRecordListData() + } + } + }) + }) }) } .width('100%') @@ -180,4 +202,5 @@ interface recordList { expert_uuid: string uuid:string photo:Array + lineHeight:Length } diff --git a/features/patient/src/main/ets/components/SelectedPatientGroupComp.ets b/features/patient/src/main/ets/components/SelectedPatientGroupComp.ets new file mode 100644 index 0000000..86307a1 --- /dev/null +++ b/features/patient/src/main/ets/components/SelectedPatientGroupComp.ets @@ -0,0 +1,238 @@ +import { authStore, HdNav, PositionSelectedSheet } from '@itcast/basic'; +import { promptAction } from '@kit.ArkUI' +import { HdLoadingDialog } from '@itcast/basic' +import { BasicConstant,hdHttp, HdResponse ,logger} from '@itcast/basic/Index' +import { BusinessError } from '@kit.BasicServicesKit'; +import HashMap from '@ohos.util.HashMap'; +import { groupRequest,groupRequestCall,groupModel,patientListModel } from '../models/PatientsGroupModel' +import { HMRouterMgr, HMRouterPathInfo, HMRouterPathCallback, HMRouter, HMPopInfo } from "@hadss/hmrouter" + +@HMRouter({pageUrl:'SelectedPatientGroupComp'}) +@Component +export struct SelectedPatientGroupComp { + private params: ESObject = HMRouterMgr.getCurrentParam() + @State group_sort:string = '0' + @State list_sort:string = '0' + scroller:Scroller = new Scroller() + @State groupListArray: groupModel[] = [] + @State patientsList: patientListModel[] = [] + @State naviRightText:string = '确定(0)' + + dialog: CustomDialogController = new CustomDialogController({ + builder: HdLoadingDialog({ message: '加载中...' }), + customStyle: true, + alignment: DialogAlignment.Center + }) + + aboutToAppear(): void { + this.getGroupData() + } + + getGroupData(){ + this.dialog.open() + hdHttp.post(BasicConstant.groupList, { + expert_uuid: authStore.getUser().uuid, + group_sort:this.group_sort, + list_sort:this.list_sort + } as groupRequest).then(async (res: HdResponse) => { + this.dialog.close(); + this.groupListArray = [] + logger.info('Response groupList'+res); + let json:groupRequestCall = JSON.parse(res+'') as groupRequestCall; + if(json.code == 1) { + this.groupListArray = json.data + } else { + console.error('患者分组列表失败:'+json.message) + promptAction.showToast({ message: json.message, duration: 1000 }) + } + }).catch((err: BusinessError) => { + this.dialog.close(); + console.error(`Response fails: ${err}`); + }) + } + + build() { + Column() { + HdNav({ + title: '患者分组', + showRightIcon: false, + hasBorder: true, + rightText: this.naviRightText, + showRightText: true, + isLeftAction: true, + rightTextColor:Color.White, + rightBackColor:$r('app.color.main_color'), + leftItemAction:() => { + HMRouterMgr.pop() + }, + rightItemAction: () => { + this.getSelectedPatients() + if (this.patientsList.length <= 0) { + promptAction.showToast({message:'请选择患者',duration:1000}) + return + } + if (this.patientsList.length > 200) { + promptAction.showToast({message:'最多发送200个患者,请重新选择!',duration:1000}) + return + } + HMRouterMgr.push({pageUrl:'SendGroupMessageComp',param:{'selectedPatients':this.patientsList}},{ + onResult:(popInfo:HMPopInfo)=>{ + if (popInfo && popInfo.result && popInfo.result["isPop"] !== undefined) { + HMRouterMgr.pop({param:{'isRefresh':true}}) + } + } + }) + } + }) + this.contentView() + } + } + + @Builder + contentView() { + Scroll(this.scroller) { + Column() { + List() { + ForEach(this.groupListArray, (sectionModel: groupModel, index: number) => { + ListItemGroup({ header: this.itemHeaderView(sectionModel, index) }) { + ForEach(sectionModel.isShow ? sectionModel.patientList : [], (rowModel: patientListModel,rowIndex:number) => { + ListItem() { + Stack() { + Row({ space: 15 }) { + Image(BasicConstant.urlImage + rowModel.photo) + .alt($r('app.media.userPhoto_default')) + .width(54) + .height(54) + .borderRadius(6) + .margin({ left: 15 }) + Text(rowModel.nickname ? rowModel.nickname : rowModel.realName) + .fontSize(16).fontColor('#666666') + .layoutWeight(1) + Row() { + Image(rowModel.isSelected?$r('app.media.patiemts_list_selected'):$r('app.media.patients_list_noSelect')) + .width(22) + .height(22) + } + .width(60) + .height(60) + .justifyContent(FlexAlign.End) + .margin({ right: 15 }) + }.width('100%').height(80) + Row() + .width('95%').height(0.5) + .backgroundColor('#999999') + }.width('100%').height(80).alignContent(Alignment.BottomEnd) + .onClick(() => { + this.groupListArray[index].patientList[rowIndex].isSelected = !this.groupListArray[index].patientList[rowIndex].isSelected + const allSelected = this.groupListArray[index].patientList.every(patient => patient.isSelected) + this.groupListArray[index].isSelected = allSelected + this.groupListArray = [...this.groupListArray] + this.updateNaviRightText() + }) + }.width('100%') + }) + } + }) + } + .width('100%') + .scrollBar(BarState.Off) + .sticky(StickyStyle.Header) + + Text('清空选择') + .fontColor($r('app.color.main_color')) + .borderWidth(1) + .borderRadius(5) + .fontSize(16) + .textAlign(TextAlign.Center) + .backgroundColor(Color.White) + .borderColor($r('app.color.main_color')) + .width('90%') + .height(45) + .margin({ top: 50,left:10,right:10 }) + .onClick(()=>{ + for (const group of this.groupListArray) { + group.isSelected = false + if (group.patientList) { + for (const patient of group.patientList) { + patient.isSelected = false + } + } + } + this.groupListArray = [...this.groupListArray] + this.updateNaviRightText() + }) + } + } + .height('calc(100% - 55vp - 56vp)') + .align(Alignment.TopStart) + .backgroundColor('#f4f4f4') + } + + @Builder + itemHeaderView(model:groupModel,index:number) { + Column() { + Row() { + Image(model.isShow ? $r('app.media.group_turnDown') : $r('app.media.group_turnRight')) + .width(model.isShow ? 10 : 5).height(model.isShow ? 5 : 10).margin({ left: 15 }) + Text(model.name + ' | ' + model.patientNum) + .fontSize(16) + .fontColor('#333333') + .margin({ left: 15 }) + .layoutWeight(1) + Row() { + Image(model.isSelected?$r('app.media.patiemts_list_selected'):$r('app.media.patients_list_noSelect')) + .width(22) + .height(22) + } + .width(60) + .height(60) + .justifyContent(FlexAlign.End) + .margin({ right: 15 }) + .onClick(()=>{ + const newSelected = !this.groupListArray[index].isSelected + this.groupListArray[index].isSelected = newSelected + if (this.groupListArray[index].patientList) { + for (const patient of this.groupListArray[index].patientList) { + patient.isSelected = newSelected + } + } + this.groupListArray = [...this.groupListArray] + this.updateNaviRightText() + }) + } + .width('100%') + .height(60) + .onClick(() => { + this.groupListArray[index].isShow = !this.groupListArray[index].isShow; + this.groupListArray = [...this.groupListArray]; + }) + Blank() + .width('100%').height(1).backgroundColor('#666666') + }.width('100%').height(61).backgroundColor(Color.White) + } + + updateNaviRightText() { + let total = 0 + for (const group of this.groupListArray) { + if (group.patientList) { + total += group.patientList.filter(patient => patient.isSelected).length + } + } + this.naviRightText = `确定(${total})` + } + + getSelectedPatients() { + let result: patientListModel[] = [] + for (const group of this.groupListArray) { + if (group.patientList) { + result = result.concat(group.patientList.filter(patient => patient.isSelected)) + } + } + this.patientsList = result + } +} + +export class sortModel { + name?:string; + isSeleted:boolean = false; +} diff --git a/features/patient/src/main/ets/components/SendGroupMessageComp.ets b/features/patient/src/main/ets/components/SendGroupMessageComp.ets new file mode 100644 index 0000000..415566d --- /dev/null +++ b/features/patient/src/main/ets/components/SendGroupMessageComp.ets @@ -0,0 +1,471 @@ +import { HMPopInfo, HMRouter, HMRouterMgr, IHMAnimator } from "@hadss/hmrouter" +import { BasicConstant, + ChangeUtil, + DefaultHintProWindows, + hdHttp, HdLoadingDialog, HdNav, HdResponse, logger, TripleOptionDialog } from "@itcast/basic" +import { patientListModel } from "../models/PatientsGroupModel" +import { display, promptAction } from "@kit.ArkUI" +import { HashMap } from "@kit.ArkTS" +import { BusinessError } from "@kit.BasicServicesKit" +import { camera, cameraPicker } from "@kit.CameraKit" +import { picker } from "@kit.CoreFileKit" +import { TeachDialog } from "@nimkit/chatkit_ui" +import { PerfactInputSheet } from "@itcast/basic/src/main/ets/Views/PerfactInputSheet" +import { NewWaDialog } from "@nimkit/chatkit_ui/src/main/ets/view/NewWaDialog" + +@HMRouter({pageUrl:'SendGroupMessageComp'}) +@Component +export struct SendGroupMessageComp { + private params: ESObject = HMRouterMgr.getCurrentParam() + @State patientsList:patientListModel[] = [] + @State patientsName:string = '' + @State patient_user_uuid:string = '' + @State functionsVisible: boolean = false + @State inputValue: string = '' + @State msg_content: string = '' + @State screenWidth: number = vp2px(display.getDefaultDisplaySync().width) + @State isPossessList:boolean = false + + dialogController: CustomDialogController = new CustomDialogController({ + builder: TripleOptionDialog({ title: '温馨提示',subTitle:'',oneButtonTitle:'单独选择',twoButtonTitle:'分组选择',buttonSelected:(actionType:string)=>{ + if (actionType == '单独选择') { + HMRouterMgr.push({pageUrl:'PatientsListComp', + param:{group_uuid:"",selectedPatients:[],pageName:"群发消息"} + },{ + onResult:(popInfo:HMPopInfo)=>{ + if (popInfo && popInfo.result && popInfo.result["isRefresh"] !== undefined) { + + } + } + }) + } else { + HMRouterMgr.push({pageUrl:'SelectedPatientGroupComp' + },{ + onResult:(popInfo:HMPopInfo)=>{ + if (popInfo && popInfo.result && popInfo.result["isRefresh"] !== undefined) { + + } + } + }) + } + }}), + alignment: DialogAlignment.Center, + offset: { dx: 0, dy: 0 }, + autoCancel: true + }) + + dialog: CustomDialogController = new CustomDialogController({ + builder: HdLoadingDialog({ message: '加载中...' }), + customStyle: true, + alignment: DialogAlignment.Center + }) + + outpatient:CustomDialogController = new CustomDialogController({ + builder:PerfactInputSheet({ + inputTitle:'提示', + inputPlaceholder:this.isPossessList?'您是否发送您的出/停诊公告?':'暂未设置停/出诊公告是否前往设置?', + style:'2', + okColor:$r('app.color.top_title'), + inputCallBack:(input: string,title:string)=>{ + if (this.isPossessList) { + this.submintMessage("5") + } else { + HMRouterMgr.push({}) + } + this.outpatient.close(); + } + }), + alignment: DialogAlignment.Center, + customStyle: true, + autoCancel: false, + backgroundColor: ('rgba(0,0,0,0.5)'), + height: '100%' + }) + + teachDialog: CustomDialogController = new CustomDialogController({ + builder: TeachDialog({ + imgCallBack:()=>{ + HMRouterMgr.push({pageUrl:'TuwenCompPage'},{ + onResult: (popInfo: PopInfo) => { + const result = JSON.parse(String(popInfo.result)) as Record + this.msg_content = result["gdxz_id"] + this.submintMessage("3") + } + }) + }, + videoCallBack:()=>{ + HMRouterMgr.push({pageUrl:'VideoTeach'},{ + onResult: (popInfo: PopInfo) => { + const result = JSON.parse(String(popInfo.result)) as Record + this.msg_content = result["gdxz_id"] + this.submintMessage("4") + } + }) + } + }), + cornerRadius: 4, + width: '70%', + }) + + waDialog: CustomDialogController = new CustomDialogController({ + builder: NewWaDialog({ + firstCallBack:()=> { + this.msg_content = "纽娃复合营养素固体饮料主要成分是:蜂花粉、乳清蛋白粉、灰树花粉、低聚木糖、蚕蛹氨基酸、麦芽粉、薏苡仁粉、烟酸、磷脂,以及其他调味品、辅助原料。科学配比制成,含有丰富的蛋白质、氨基酸、维生素、微量元素及其他营养元素,点击链接了解详情。" + this.submintMessage("6") + } + }), + cornerRadius: 4, + width: '70%', + }) + + aboutToAppear(): void { + const patients = this.params?.selectedPatients as patientListModel[] | undefined + const realname = this.params?.realname as string[] | string + const patient_uuid = this.params?.patient_uuid as string[] | string + if (patients?.length) { + for (const model of this.params?.selectedPatients as patientListModel[]) { + if (model.isSelected) { + this.patientsList.push(model) + this.patientsName = this.converNameToString(this.patientsList) + this.patient_user_uuid = this.converUuidToString(this.patientsList) + console.info('数组转字符串文字为:',this.patientsName) + } + } + } + if (realname) { + this.patientsName = realname as string + this.patient_user_uuid = patient_uuid as string + } + this.getStopOutPatientList() + } + + submintMessage(type:string) { + const hashMap: HashMap = new HashMap(); + hashMap.set('msg_type',type) + hashMap.set('msg_content',this.msg_content) + hashMap.set('patient_user_uuid',this.patient_user_uuid) + this.dialog.open() + hdHttp.httpReq(BasicConstant.addGroupSendMsg4YunXin,hashMap).then(async (res: HdResponse) => { + this.dialog.close(); + logger.info('Response addGroupSendMsg4YunXin'+res); + let json:Record = JSON.parse(res+'') as Record; + if(json.code == '200') { + promptAction.showToast({ message: '消息已发出', duration: 1000 }) + // HMRouterMgr.pop({param:{"isPop":true},pageUrl:'MassSendingComp',navigationId:'GroupSendMessagePageNavigation'})//无用 + HMRouterMgr.pop({param:{"isPop":true}}) + } else { + console.error('群发消息失败:'+json.message) + promptAction.showToast({ message: json.message, duration: 1000 }) + } + }).catch((err: BusinessError) => { + this.dialog.close(); + console.info(`Response fails: ${err}`); + }) + } + + getStopOutPatientList() { + const hashMap: HashMap = new HashMap(); + this.dialog.open() + hdHttp.httpReq(BasicConstant.stopOutPatientList,hashMap).then(async (res: HdResponse) => { + this.dialog.close(); + logger.info('Response stopOutPatientList'+res); + let json:Record = JSON.parse(res+'') as Record; + if(json.code == '200') { + if (Array.isArray(json.data)) { + const data:Array> = json.data + if (data.length>0) { + this.isPossessList = true + } else { + this.getListOutPatient() + } + } else { + this.getListOutPatient() + } + } else { + console.error('停/出诊公告列表失败:'+json.message) + promptAction.showToast({ message: json.message, duration: 1000 }) + } + }).catch((err: BusinessError) => { + this.dialog.close(); + console.info(`Response fails: ${err}`); + }) + } + + getListOutPatient() { + const hashMap: HashMap = new HashMap(); + hashMap.set('page',"1") + this.dialog.open() + hdHttp.httpReq(BasicConstant.listOutPatient,hashMap).then(async (res: HdResponse) => { + this.dialog.close(); + logger.info('Response listOutPatient'+res); + let json:Record = JSON.parse(res+'') as Record; + if(json.code == '200') { + if (Array.isArray(json.data)) { + const data:Array> = json.data + if (data.length>0) { + this.isPossessList = true + } + } + } else { + console.error('门诊列表失败:'+json.message) + promptAction.showToast({ message: json.message, duration: 1000 }) + } + }).catch((err: BusinessError) => { + this.dialog.close(); + console.info(`Response fails: ${err}`); + }) + } + + build() { + Column() { + HdNav({isLeftAction:true,title:'群发消息',rightIcon:$r('app.media.group_message_navi_righr'),showRightIcon:true,showRightText:false,rightItemAction:()=>{ + this.dialogController.open() + },leftItemAction:()=>{ + HMRouterMgr.pop() + }}) + this.contentView() + Blank().layoutWeight(1) + + this.buildInputArea() + } + .width('100%') + .height('100%') + .backgroundColor('#f4f4f4') + .onClick(()=>{ + this.functionsVisible = false + this.getUIContext().getFocusController().clearFocus() + }) + } + + @Builder + contentView() { + Column() { + Row() { + Image($r('app.media.addPatientApply_reminder_icon')) + .width(18).height(21) + Blank() + .width(1) + .backgroundColor('rgba(239,239,239,1)') + .margin({left:10, top: 10, bottom: 10 }) + Text('若群发消息选择患者过多(建议少于200个),部分患者可能将延迟收到消息') + .fontSize(13).fontColor('#666666') + .margin({left:10,right:20}) + } + .padding({left:10,top:10,bottom:10,right:20}) + .width('100%') + .backgroundColor(Color.White) + + Column() { + Blank() + .width('100%') + .height(3) + .backgroundColor($r('app.color.main_color')) + + Text('消息将发送给'+this.patientsList.length+'位患者') + .fontSize(16) + .margin({top:10}) + + Text(this.patientsName) + .width('100%') + .fontSize(14) + .fontColor('#666666') + .padding({top:10,bottom:10}) + } + // .width('90%') + .borderRadius(5) + .backgroundColor(Color.White) + .margin({top:10,left:10,right:10}) + .alignItems(HorizontalAlign.Start) + .justifyContent(FlexAlign.Start) + } + .layoutWeight(1) + .margin({bottom:80}) + } + + @Builder + buildInputArea() { + Column() { + Row() { + TextArea({ placeholder: '输入内容...', text: this.inputValue }) + .width('85%') + .flexGrow(1) + .padding({ left: 10, right: 10 }) + .borderRadius(15) + .backgroundColor('#FFFFFF') + .constraintSize({ maxHeight: 150 }) + .border({ width: 1, color: '#DDDDDD' }) + .onChange((value:string)=>{ + this.inputValue = value + this.msg_content = value + }) + + if (this.inputValue.length) { + Text('发送') + .textAlign(TextAlign.Center) + .fontSize(12) + .borderWidth(1) + .borderRadius(5) + .margin({ left: 8 }) + .borderColor('#999999') + .backgroundColor('#f4f4f4') + .width(41) + .height(35) + .onClick(()=>this.submintMessage('1')) + } else { + Image($r('app.media.group_message_more_icon')) + .width(35) + .height(35) + .objectFit(ImageFit.Fill) + .margin({ left: 8 }) + .onClick(() => { + this.hideKeyboard() + }) + } + } + .padding(8) + .width('100%') + .alignItems(VerticalAlign.Bottom) + + if (this.functionsVisible) { + this.buildFunctionButtons() + } + } + .width('100%') + .backgroundColor('rgba(0.98,0.98,0.98,1)') + .border({ width: 1, color: '#EEEEEE'}) + .shadow({ radius: 4, color: '#1A000000', offsetX: 0, offsetY: -2 }) + .margin({ bottom: 20 }) + } + + @Builder + buildFunctionButtons() { + Flex({ wrap: FlexWrap.Wrap }) { + this.buildFunctionButton('图片', $r('app.media.im_icon_images'), () => { this.onFunctionClick('图片'); }) + this.buildFunctionButton('拍摄', $r('app.media.im_icon_camera'), () => { this.onFunctionClick('拍摄'); }) + this.buildFunctionButton('快捷回复', $r('app.media.quck_message'), () => { this.onFunctionClick('快捷回复'); }) + this.buildFunctionButton('患教', $r('app.media.patient_teach_call'), () => { this.onFunctionClick('患教'); }) + this.buildFunctionButton('出/停诊公告', $r('app.media.outpatient_true'), () => { this.onFunctionClick('出/停诊公告'); }) + this.buildFunctionButton('商城', $r('app.media.ytx_chattingfooter_shopping'), () => { this.onFunctionClick('商城'); }) + } + .width('100%') + .padding({ top: 10, bottom: 10 }) + .backgroundColor('rgba(0.96,0.96,0.96,1)') + } + + @Builder + buildFunctionButton(text: string, iconString: Resource, onClick: () => void) { + Column() { + Image(iconString) + .width(50) + .height(50) + .objectFit(ImageFit.Fill) + + Text(text) + .width('200%') + .fontSize(13) + .fontColor('#666666') + .textAlign(TextAlign.Center) + .margin({ top: 5 }) + } + .width('25%') + .alignItems(HorizontalAlign.Center) + .justifyContent(FlexAlign.Start) + .margin({ bottom: 20 }) + .onClick(onClick) + } + + onFunctionClick(functionName: string) { + if (functionName == '快捷回复') { + HMRouterMgr.push({pageUrl:'QuickMessagePage'},{ + onResult: (popInfo: PopInfo) => { + const result = popInfo.result as string; + if (result == undefined) return + this.inputValue = result + } + }) + } else if (functionName == '患教') { + this.teachDialog.open() + } else if (functionName == '图片') { + this.selectPhoto() + } else if (functionName == '拍摄') { + this.openSystemCamera() + } else if (functionName == '商城') { + this.waDialog.open() + } else { + this.outpatient.open() + } + } + + private async openSystemCamera() { + try { + const pickerProfile: cameraPicker.PickerProfile = { + cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, + videoDuration: 15 + }; + const result = await cameraPicker.pick( + getContext(), + [cameraPicker.PickerMediaType.PHOTO], + pickerProfile + ); + if (result.resultCode === 0) { + ChangeUtil.convertUriToBase64(result.resultUri).then(base64 =>{ + this.msg_content = base64 + this.submintMessage("2") + }) + } + } catch (error) { + console.error('Camera error:', error.code); + } + } + + private selectPhoto() { + let photoSelectOptions = new picker.PhotoSelectOptions(); + photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; + photoSelectOptions.maxSelectNumber = 1; + + let photoViewPicker = new picker.PhotoViewPicker(); + photoViewPicker.select(photoSelectOptions) + .then((photoSelectResult) => { + console.info('PhotoViewPicker.select successfully, photoSelectResult uri: ' + + JSON.stringify(photoSelectResult)) + if (photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) { + ChangeUtil.convertUriToBase64(photoSelectResult.photoUris[0]).then(base64 =>{ + this.msg_content = base64 + this.submintMessage("2") + }) + } + }) + .catch((err: BusinessError) => { + console.error('PhotoViewPicker.select failed with err: ' + err); + }); + } + + showKeyboard() { + this.functionsVisible = false + } + + hideKeyboard() { + this.getUIContext().getFocusController().clearFocus() + this.functionsVisible = !this.functionsVisible + } + + converNameToString(patients:patientListModel[]):string { + if (!patients?.length) return '[]'; + const nameList = patients + .map(patient => { + return patient.nickname || patient.realname || patient.realName || '' + }) + .filter(name => name.trim() !== '') + return nameList.join(',') + } + + converUuidToString(patients:patientListModel[]):string { + if (!patients?.length) return '[]'; + const nameList = patients + .map(patient => { + return patient.uuid || '' + }) + .filter(name => name.trim() !== '') + return nameList.join(',') + } +} diff --git a/features/patient/src/main/ets/models/ApplyModel.ets b/features/patient/src/main/ets/models/ApplyModel.ets index 44ce5ce..90ed34f 100644 --- a/features/patient/src/main/ets/models/ApplyModel.ets +++ b/features/patient/src/main/ets/models/ApplyModel.ets @@ -53,4 +53,5 @@ export class historyModel { content?:string; nickname?:string; patient_name?:string; + patient_uuid?:string } \ No newline at end of file diff --git a/features/patient/src/main/ets/models/PatientsGroupModel.ets b/features/patient/src/main/ets/models/PatientsGroupModel.ets index fdcbdc2..779c7de 100644 --- a/features/patient/src/main/ets/models/PatientsGroupModel.ets +++ b/features/patient/src/main/ets/models/PatientsGroupModel.ets @@ -18,7 +18,8 @@ export class groupModel { name:string = '' type:number = 0 uuid:string = '' - isShow:boolean = false; + isShow:boolean = false + isSelected:boolean = false constructor(data: groupModel) { this.patientList = data.patientList diff --git a/features/patient/src/main/ets/views/ApplyViews.ets b/features/patient/src/main/ets/views/ApplyViews.ets index d00c0c7..0cfb7f5 100644 --- a/features/patient/src/main/ets/views/ApplyViews.ets +++ b/features/patient/src/main/ets/views/ApplyViews.ets @@ -1,5 +1,6 @@ import { applyListModel,historyModel } from '../models/ApplyModel' import { BasicConstant } from '@itcast/basic/Index' +import { HMRouterMgr } from '@hadss/hmrouter'; @Component export struct ApplyViews { @@ -57,6 +58,11 @@ export struct ApplyViews { .width('100%').height(1) .backgroundColor('#f4f4f4') }.width('100%').margin({left:10,right:10}).alignItems(HorizontalAlign.Start) + .onClick(()=>{ + if (!this.isApply && this.historyItem.status == '2') { + HMRouterMgr.push({pageUrl:'PatientDetailsComp',param:{"patient_uuid":this.historyItem.patient_uuid}}) + } + }) }.width('100%').backgroundColor(Color.White) } } diff --git a/features/patient/src/main/resources/base/media/group_message_more_icon.png b/features/patient/src/main/resources/base/media/group_message_more_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1add5743c55592d600198c40d3daa61a5508070 GIT binary patch literal 2636 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 R9d~~#jr7cPtFO literal 0 HcmV?d00001 diff --git a/features/patient/src/main/resources/base/media/im_icon_images.png b/features/patient/src/main/resources/base/media/im_icon_images.png new file mode 100644 index 0000000000000000000000000000000000000000..5b4e90dfd95ca4f7ab518d34ae38801ea62f4722 GIT binary patch literal 4388 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 literal 0 HcmV?d00001 diff --git a/features/patient/src/main/resources/base/media/mine_logo.png b/features/patient/src/main/resources/base/media/mine_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..728981f428b57232f86d2156609fe677e4767734 GIT binary patch literal 24460 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 Q-Pf9Goz_z;P_YUAKbC0MTmS$7 literal 0 HcmV?d00001 diff --git a/features/patient/src/main/resources/base/media/outpatient_true.png b/features/patient/src/main/resources/base/media/outpatient_true.png new file mode 100644 index 0000000000000000000000000000000000000000..d4440880291342de303dc9484a68684bf103c422 GIT binary patch literal 2566 zcmaJ@3p7+~8y-X`5fM(YjS^z^4C6AxxXlnwBgV+BFwDkaF3k)kDY=ZOsQigAIXQ`w z#)xi`h+IxZ^;1kIO`TEc{A>NEf3LOo_kHhrpXa@N&wAI+_4V1JrmC+B zgTd6iJP9P(N?m-Fm1JMm<3h4*(c`)Yas8Rm+++$Hg1J(ekr3cTr^G-ch(g`H>sQDT z22(Jhk%PEF#I4vUCLKXp^g;0GEEyUGb9CmhC{ghc7l?#nXbc?ubyEu*piyz~KpP^G z$ihRhG|v<^8o^}8fG7+G10tgG=FAGC0Od z3|E_fU zH*XG?1pS@wKN54uyIBxOf;h}Xc9iVmqKy|rv9NeHMBy^oWF|9Vsf)g`OfHiX%VYs~ z{9@NIfN3C&L1iX$%syj?M64Hs!=*5yATI(AE@MH^XjClT8iR3lN84N5Vq8%ucUMfcz*cd?6dptEF=2@so>1W`TMOgiwnY%J~j zx!8V}?<)V*r6ezc zE15SkEePGVBVbL}kU_SdZbY_xrMx)A;)G6SvX)I}P^pqoU8+Hx&IF}!eJx@f$vLBw zKs+~iRy|A;>^DVU+-|W^@wQ-+R7~kjlHTKE?ykJZKgsF6dp@ncq*vGwBb^T`+B@$h z{ttiU@6YTfUtW#BS7d#*EFV*Gy4WTL!O4*p=^T7Q;^kkf~yo%aZkOdu=x!Yr!tpF>**B%5hFz zt6QdcRBpyS0u2MkA0KF~cAy3ZRYaI-Y8oyRt#oMkz%)&FSn zyU}(k?PvHwiD}%c0P>Y`!xW@EU86_(3++juzG#V9X7`?L2tO>TDV^Om;o`U`I8_l>S< zJ5LN~hn^YM7isyRUh&kANV03!0o{7}NMmLirSE+LQj->Ea9KS3247;}pjF{(@30Tt z&(ocZdWr}!+SibV_QR`$ok?A{BqiHBxqoiG$X2*NJ3WtN^Cgqg0=)M~-SdJQ z;ckQYxc4!1MxH~>h5{h&)t%Z5zESgVpApq^d<{_f(kxFHsvoOVx==3y^E8C{@#cYl zYSz0!R%#z~t3a2K@JGRWuiO7R==oy3;p^?XhMmFME`5H6yu3R@b_UlYM||R~*PZ<+ zjyA>LXq{?Sp1OGz>GXSMa;loa%qH!QtD@rfex*L+J4r_REqBwZo5L3vDQS*JTM&Y4)kdH&0&+hCJ{>!9sA;Kp(FHC7mwr2Cebh1~s)qR4$Gwn^+mF6?E(eN_u zr+Vw0q5sN9)we~ThI9M37guC0c zXDqm;kS*9HSxy{iiCtwjc)PW7cmcCkRO6X+N9x)n6+4s^*yWyJK6jxHEU%5p=G55~ zTu;{%^$3pz6|HB7BoE=Dv>&Zeahv#KeSEy)X7e1?w-7+exj}v|H!rVY9->X9ZN$0+Ail`@|6sAwG{OiC=+nU{Ivr87UhDZg58{dVNm z;7lO7yDgEm1{sS#Os#rB@{}OLXhPti3hAccR9rqsjcoP`hm>Msqa|OM2}l#&ciL z3i%vTR5LxepBo9g}H{k-Pxsg?mup*i09M0=Vt~Io<4Ym d0Y8GRFziKD_lGXeniv1fyxe^VwQdm^e*sA}D+K@m literal 0 HcmV?d00001 diff --git a/features/patient/src/main/resources/base/media/patient_teach_call.png b/features/patient/src/main/resources/base/media/patient_teach_call.png new file mode 100644 index 0000000000000000000000000000000000000000..f9291485f10b5eddbeb0e8f5bb4e56d8daa97a77 GIT binary patch literal 2703 zcma)8dpwhEA76;lLq%FC*)#PNu@l3_2s2hqT8ov)4mW1Dd$wsqq$3F>ourc-qU3Ew zPg(Njuu#sYtbDF!Az}$b2teG}AQOO*d5lni3NYBwk#&GG z1fu;Lhej9EDeLhpkcVJsd=OHeK#f+@xJm^K78el1m_R6pPk;~0E8s8=n*jI6Qcx6u z2N1^bju8TzVti<<7%mIPhP%4JoTYd*0S^!}U{YQLUxb$u;9q(1>b>R|35R`k5pxOf zzmlR;d|@7-5P)G3_BJfEts~3BG|0q2V(^Z|=^u+Q4Y#`pFX1T$&9 ziMrG;7Wd58CTVH8&l^c_hwR_F`-Go~zM>9{ZOI@INaX&_l8 zjfO?u9P?UsJ7HBuU(#`pWw82QN2Y_hQ2u{9rSSAca(GX~r6B&G?^2 z(mow(v!4Ihv5z&2qW$F)1Ig|(`zBB8emqG@IsGXYHF3R=9#?sU5mPt!eRN$}<<-Cp zQt6-a;IrO?Tc)--8+^Kb6KuTSaH!_gi1>*gexe!5G*j(sjBQ^W8M^cL?410T1>>rY z*zk43CwBDZn(p?^V4wVA)GbOq1vi={LN0u4H1Yms=lxLC@WPP0CJ&Ud0{`vEky@Yh z8Fk7g%fqTtZQJ^yeqiVeDW;`L(=|Q<*1&r8>{s$Zp^JJvto>F$gCK1 zQJJDe(4_Pa7p7K{ELKDn>4fm1@)0MA%ax&}%&52e<>6;ewYmD=ZY`!az)uuEXNDCF zAF7Y5$}y^~HRisZ!`$w8fF9_cIR3h1a|3lIx4hbrZ`0FEWNeT^A`CZ25pE@vPV<= zaEomxYpl9W#%k(|t$%5VoH_J~wj4+$0b|yx^73;-*Nq|Cb@fKb~;}1w7}YE;!Apb_(8Lf3H`%X$mTg$A3bQJ z=PxM>IWf^;LnV=bXM!aP&5jZ4Q3lLiik*H3haLDR^BDskiTxc^7Q zKi7J{xoUip9@6;bS=>E^ldj=fld;Y&)TN4KfL-y(YwP2WuBZ&rW06x<;YGG9n$^;dUMSCqY3nI#Jyqou z&#fKLoq5jhI_Ftb+}ysA;=O?NC8M_eI-MfT=NLrDBg~mm{-_0&~+)Umn(~(N=WW_)xE#xneoKP$!zTGShGvBBxGMB7+UETMYWEGmK*waM2 zY=Vv*V#bDL&n}tVW+`OmoN6p<;$#qY^WN0i#oSD}#NPiIr5JG{9>`5xC5a=HfsO0W<9Dq;;hqKu( z7buPXyqfycE!(zyL_+2Lu_TlDH>?j^sIAv)?nur~th?ry_`XlM?3ncG<6pwJTi^P% ziD0 z>MMiDAoJ#EhI;dJj7x@)>#5+-1&tdmRc z)w;OvWowLAk$Wmwt4ExDKd(~p=0F$ra_wxQ_whbzoAU_~*w=@>B{vsCABzeK^5}-2 zOb@*Q-5l~_Iz-+G=!561)J)Ukz4~R%UkKSP;h8DpF0I`K=`XvzKI};&?Mk!gHhqie zdGiE&J4Y`x{9#A!*ty_ax`*@>D^J?3tvT!4^CERJEzwD}Ylbcax%^-0v<$>C%`YO^ L(}!5>9=zv2b47tH literal 0 HcmV?d00001 diff --git a/features/patient/src/main/resources/base/media/quck_message.png b/features/patient/src/main/resources/base/media/quck_message.png new file mode 100644 index 0000000000000000000000000000000000000000..f92f10735dac858e3d8b1794d084815510bbfd3e GIT binary patch literal 2499 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 y2TZ-NSB`Y~4BkJV0Fl literal 0 HcmV?d00001 diff --git a/features/patient/src/main/resources/base/media/ytx_chattingfooter_shopping.png b/features/patient/src/main/resources/base/media/ytx_chattingfooter_shopping.png new file mode 100644 index 0000000000000000000000000000000000000000..744f0af74f2238a5cdbc7e1b08e745953528ad1a GIT binary patch literal 2602 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 M07*qoM6N<$g0wr&qW}N^ literal 0 HcmV?d00001 diff --git a/products/expert/src/main/ets/pages/MinePage/FeedbackPage.ets b/products/expert/src/main/ets/pages/MinePage/FeedbackPage.ets index d06723e..2e23cc1 100644 --- a/products/expert/src/main/ets/pages/MinePage/FeedbackPage.ets +++ b/products/expert/src/main/ets/pages/MinePage/FeedbackPage.ets @@ -21,6 +21,7 @@ interface callBackData { struct FeedbackPage { @State feedbackText: string = '' controller:TextAreaController = new TextAreaController(); + @State params:Record = router.getParams() as Record; uploadChangePasswordAction() { hdHttp.post(BasicConstant.urlExpert + 'feedBack', { @@ -42,7 +43,7 @@ struct FeedbackPage { build() { Column() { - HdNav({ title: '意见反馈', showRightIcon: false, hasBorder: true }) + HdNav({ title: this.params.title, showRightIcon: false, hasBorder: true }) // 输入框区域 TextArea({ placeholder:'欢迎对我们的软件提供建议,帮助我们更快更好地改进"肝胆相照"APP(200字以内)', diff --git a/products/expert/src/main/ets/pages/PatientsPage/GroupSendMessagePage.ets b/products/expert/src/main/ets/pages/PatientsPage/GroupSendMessagePage.ets new file mode 100644 index 0000000..07a68d4 --- /dev/null +++ b/products/expert/src/main/ets/pages/PatientsPage/GroupSendMessagePage.ets @@ -0,0 +1,41 @@ +import { MassSendingComp } from 'patient' +import { HMDefaultGlobalAnimator, HMNavigation } from '@hadss/hmrouter'; +import { AttributeUpdater } from '@kit.ArkUI'; + +class NavModifier extends AttributeUpdater { + initializeModifier(instance: NavigationAttribute): void { + instance.mode(NavigationMode.Stack); + instance.navBarWidth('100%'); + instance.hideTitleBar(true); + instance.hideToolBar(true); + } +} + +@Entry +@Component +struct GroupSendMessagePage { + @Provide refreshFlag:boolean = false; + modifier: NavModifier = new NavModifier(); + + onPageShow(): void { + this.refreshFlag = !this.refreshFlag; + } + + build() { + Column() { + HMNavigation({ + navigationId:"GroupSendMessagePageNavigation", + homePageUrl:'MassSendingComp', + options:{ + standardAnimator:HMDefaultGlobalAnimator.STANDARD_ANIMATOR, + dialogAnimator:HMDefaultGlobalAnimator.DIALOG_ANIMATOR, + modifier:this.modifier + } + }) { + MassSendingComp() + } + } + .height('100%') + .width('100%') + } +} \ No newline at end of file diff --git a/products/expert/src/main/ets/pages/PatientsPage/PatientPages.ets b/products/expert/src/main/ets/pages/PatientsPage/PatientPages.ets index f4b076d..25dae4b 100644 --- a/products/expert/src/main/ets/pages/PatientsPage/PatientPages.ets +++ b/products/expert/src/main/ets/pages/PatientsPage/PatientPages.ets @@ -1,11 +1,39 @@ import { PatientApplyPage } from 'patient' +import { HMDefaultGlobalAnimator, HMNavigation } from '@hadss/hmrouter'; +import { AttributeUpdater } from '@kit.ArkUI'; + +class NavModifier extends AttributeUpdater { + initializeModifier(instance: NavigationAttribute): void { + instance.mode(NavigationMode.Stack); + instance.navBarWidth('100%'); + instance.hideTitleBar(true); + instance.hideToolBar(true); + } +} @Entry @Component struct PatientPages { + @Provide refreshFlag:boolean = false; + modifier: NavModifier = new NavModifier(); + + onPageShow(): void { + this.refreshFlag = !this.refreshFlag; + } + build() { - RelativeContainer() { - PatientApplyPage(); + Column() { + HMNavigation({ + navigationId:"PatientPagesNavigation", + homePageUrl:'PatientApplyPage', + options:{ + standardAnimator:HMDefaultGlobalAnimator.STANDARD_ANIMATOR, + dialogAnimator:HMDefaultGlobalAnimator.DIALOG_ANIMATOR, + modifier:this.modifier + } + }) { + PatientApplyPage() + } } .height('100%') .width('100%') diff --git a/products/expert/src/main/resources/base/profile/main_pages.json b/products/expert/src/main/resources/base/profile/main_pages.json index 4e852fe..1fb6b96 100644 --- a/products/expert/src/main/resources/base/profile/main_pages.json +++ b/products/expert/src/main/resources/base/profile/main_pages.json @@ -44,6 +44,7 @@ "pages/PatientsPage/GroupManagementPage", "pages/WebView/WebPageSnapshot", "pages/VideoPage/PLVMediaPlayerOnlyVideoPage", - "pages/Netease/OutpatientPage" + "pages/Netease/OutpatientPage", + "pages/PatientsPage/GroupSendMessagePage" ] } \ No newline at end of file