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',singleton:true}) @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 == '单独选择') { const currentStack = HMRouterMgr.getCurrentPathStack() if (currentStack?.getParamByName('PatientsListComp').length == 1) { HMRouterMgr.popAsync({pageUrl:'PatientsListComp'}) return } HMRouterMgr.push({pageUrl:'PatientsListComp', param:{group_uuid:"",selectedPatients:[],pageName:"群发消息"} }) } else { const currentStack = HMRouterMgr.getCurrentPathStack() if (currentStack?.getParamByName('SelectedPatientGroupComp').length == 1) { HMRouterMgr.popAsync({pageUrl:'SelectedPatientGroupComp'}) return } HMRouterMgr.push({pageUrl:'SelectedPatientGroupComp'}) } }}), 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(',') } }