diff --git a/features/Home/src/main/ets/components/HomeIconComp.ets b/features/Home/src/main/ets/components/HomeIconComp.ets index 8b3f22b..fe430b5 100644 --- a/features/Home/src/main/ets/components/HomeIconComp.ets +++ b/features/Home/src/main/ets/components/HomeIconComp.ets @@ -1,5 +1,7 @@ import { HomeModel, iconsModel } from '../model/HomeModel' -import { BasicConstant, hdHttp, HdResponse, patientDbManager, PatientEntity } from '@itcast/basic'; +import { + applyListCallBacl, + authStore, BasicConstant, hdHttp, HdResponse, patientDbManager, PatientEntity } from '@itcast/basic'; import { promptAction, router, UIObserver, uiObserver } from '@kit.ArkUI'; import { BusinessError } from '@kit.BasicServicesKit'; import { pushService } from '@kit.PushKit'; @@ -89,6 +91,20 @@ export struct HomeIconComp { else { this.patientRed=false + hdHttp.post(BasicConstant.applyList,{ + expertUuid: authStore.getUser().uuid, + } as updateExtraData).then(async (res: HdResponse) => { + let json:applyListCallBacl = JSON.parse(res+'') as applyListCallBacl; + if(json.code == 1) { + if(json.data!=null&&json.data.length>0) + { + this.patientRed=true + } + + } + }).catch((err: BusinessError) => { + + }) } if(consultcount>0) { @@ -166,3 +182,6 @@ export struct HomeIconComp { } } +export interface updateExtraData { + expertUuid: string +} \ No newline at end of file diff --git a/features/netease/src/main/ets/view/MyOpinionComp.ets b/features/netease/src/main/ets/view/MyOpinionComp.ets index 4974f27..81964b4 100644 --- a/features/netease/src/main/ets/view/MyOpinionComp.ets +++ b/features/netease/src/main/ets/view/MyOpinionComp.ets @@ -2,6 +2,7 @@ import { authStore, BasicConstant, ChangePhotoGrids, ChangeUtil, + compressedImage, hdHttp, HdLoadingDialog, HdNav, HdResponse, @@ -11,13 +12,16 @@ import { AnswerListBean } from "../model/ConsulModel" import { promptAction, router } from "@kit.ArkUI" import { PerfactInputSheet } from "@itcast/basic/src/main/ets/Views/PerfactInputSheet" import { BusinessError } from "@kit.BasicServicesKit" -import { HashMap } from "@kit.ArkTS" +import { buffer, HashMap } from "@kit.ArkTS" import { StringIsEmpty } from "@nimkit/common" import { http } from "@kit.NetworkKit" import { TimestampBean } from "@itcast/basic/src/main/ets/utils/request" import { bundleManager } from "@kit.AbilityKit" import { rcp } from "@kit.RemoteCommunicationKit" import { CryptoJS } from '@ohos/crypto-js' +import fileIo from "@ohos.file.fs" +import { image } from "@kit.ImageKit" + @Component export struct MyOpinionComp { @State photos: string[] = [] @@ -46,12 +50,12 @@ export struct MyOpinionComp { this.photos.splice(this.removeIndex, 1) this.maxSelectNumber =6- this.photos.length; - ChangeUtil.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { - console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) - this.base64Array = base64Array - }).catch((err:BusinessError) => { - console.error('批量转换失败:', err) - }) + // this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { + // console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + // this.base64Array = base64Array + // }).catch((err:BusinessError) => { + // console.error('批量转换失败:', err) + // }) } private custom!:CustomDialogController; dialog: CustomDialogController = new CustomDialogController({ @@ -103,12 +107,12 @@ export struct MyOpinionComp { this.photos.push(...selectedUris); this.maxSelectNumber = 6- this.photos.length; - ChangeUtil.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { - console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) - this.base64Array = base64Array - }).catch((err:BusinessError) => { - console.error('批量转换失败:', err) - }) + // this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { + // console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + // this.base64Array = base64Array + // }).catch((err:BusinessError) => { + // console.error('批量转换失败:', err) + // }) } }), alignment: DialogAlignment.Bottom, @@ -128,13 +132,12 @@ export struct MyOpinionComp { if(this.params.myAnswer.imgs!=null) { this.photos.push(...this.changeToImgs(this.params.myAnswer.imgs.split(","))) this.maxSelectNumber = 6- this.photos.length; - - ChangeUtil.convertUrisOrUrlsToBase64(this.changeToImgs(this.params.myAnswer.imgs.split(","))).then(base64Array => { - console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) - this.base64Array = base64Array - }).catch((err:BusinessError) => { - console.error('批量转换失败:', err) - }) + // this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { + // console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + // this.base64Array = base64Array + // }).catch((err:BusinessError) => { + // console.error('批量转换失败:', err) + // }) } } else { this.text=preferenceStore.getItemString('MyOpinionComp'+this.params.uuid) @@ -222,6 +225,7 @@ export struct MyOpinionComp { async updateInterrogationAnswer() { this.dialog.open() + this.base64Array =await this.convertUrisOrUrlsToBase64(this.photos) this.hashMap.clear(); this.hashMap.set("note",this.text); this.hashMap.set('uuid', this.params.uuid) @@ -239,8 +243,9 @@ export struct MyOpinionComp { // let req = new rcp.Request("http://example.com", "POST", headers, simpleForm, cookies, transferRange, configuration); } - addInterrogationAnswer() { + async addInterrogationAnswer() { this.dialog.open() + this.base64Array =await this.convertUrisOrUrlsToBase64(this.photos) this.hashMap.clear(); this.hashMap.set("note",this.text); this.hashMap.set('step1_uuid', this.params.step1_uuid) @@ -314,6 +319,173 @@ export struct MyOpinionComp { } + async convertUrisOrUrlsToBase64(items: string[]): Promise { + const results: string[] = []; + const MAX_SIZE_KB = 500; // 最大500KB + + for (const item of items) { + try { + let base64Str: string; + + // 处理本地文件URI + if (item.startsWith('file://')) { + base64Str = await this.processLocalImage(item, MAX_SIZE_KB); + } + // 处理网络URL + else if (item.startsWith('http://') || item.startsWith('https://') || ChangeUtil.isImageFileByRegex(item)) { + base64Str = await this.processNetworkImage(item, MAX_SIZE_KB); + } + // 处理其他类型资源 + else { + throw new Error(`不支持的URI格式: ${item}`); + } + + results.push(base64Str); + } catch (err) { + console.error(`转换失败: ${JSON.stringify(err)}`); + results.push(''); // 失败时返回空字符串 + } + } + return results; + } + + // 处理本地图片 + private async processLocalImage(uri: string, maxSizeKB: number): Promise { + try { + // 创建图片源 + const fileSource = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); + const imageSource = image.createImageSource(fileSource.fd); + + // 获取原始图片信息 + const pixelMap = await imageSource.createPixelMap(); + const originalWidth = pixelMap.getPixelBytesNumber(); + + // 计算压缩比例,目标500KB以内 + let quality = 0.8; + let targetWidth = 800; // 初始目标宽度 + + // 如果原始图片太大,逐步压缩 + if (originalWidth > maxSizeKB * 1024) { + quality = Math.min(0.6, (maxSizeKB * 1024) / originalWidth); + targetWidth = Math.min(800, Math.sqrt((maxSizeKB * 1024) / originalWidth) * 100); + } + + // 压缩图片 + const compressedImageInfo = await compressedImage(pixelMap, targetWidth); + const compressedUri = compressedImageInfo.imageUri; + + // 读取压缩后的图片 + const compressedBuffer = await this.readLocalFile(compressedUri); + + // 如果还是太大,进一步压缩 + if (compressedBuffer.byteLength > maxSizeKB * 1024) { + const imagePackerApi = image.createImagePacker(); + const packOpts: image.PackingOption = { + format: "image/jpeg", + quality: Math.max(0.3, quality * 0.8) // 进一步降低质量 + }; + + const finalBuffer = await imagePackerApi.packing(imageSource, packOpts); + const finalBase64 = buffer.from(finalBuffer).toString('base64'); + + // 清理资源 + imagePackerApi.release(); + imageSource.release(); + await fileIo.close(fileSource.fd); + + return finalBase64; + } + + // 转换为Base64 + const base64Str = buffer.from(compressedBuffer).toString('base64'); + + // 清理资源 + imageSource.release(); + await fileIo.close(fileSource.fd); + + return base64Str; + + } catch (err) { + throw new Error(`本地图片处理失败: ${JSON.stringify(err)}`); + } + } + + // 处理网络图片 + private async processNetworkImage(url: string, maxSizeKB: number): Promise { + try { + // 下载网络资源 + const arrayBuffer = await ChangeUtil.downloadNetworkResource(url); + + // 如果下载的图片太大,进行压缩 + if (arrayBuffer.byteLength > maxSizeKB * 1024) { + // 创建临时文件来压缩 + const tempUri = await this.saveToTempFile(arrayBuffer); + const compressedBase64 = await this.processLocalImage(tempUri, maxSizeKB); + + // 清理临时文件 + await this.deleteTempFile(tempUri); + + return compressedBase64; + } + + // 直接转换为Base64 + return buffer.from(arrayBuffer).toString('base64'); + + } catch (err) { + throw new Error(`网络图片处理失败: ${JSON.stringify(err)}`); + } + } + + // 保存到临时文件 + private async saveToTempFile(arrayBuffer: ArrayBuffer): Promise { + try { + // 使用应用缓存目录作为临时目录 + const context = getContext(this); + const tempDir = context.cacheDir; + const tempFileName = `temp_${Date.now()}.jpg`; + const tempPath = `${tempDir}/${tempFileName}`; + + const file = await fileIo.open(tempPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY); + await fileIo.write(file.fd, arrayBuffer); + await fileIo.close(file.fd); + + return tempPath; + } catch (err) { + throw new Error(`临时文件保存失败: ${JSON.stringify(err)}`); + } + } + + // 删除临时文件 + private async deleteTempFile(uri: string): Promise { + try { + await fileIo.unlink(uri); + } catch (err) { + console.warn(`临时文件删除失败: ${JSON.stringify(err)}`); + } + } + + // 优化后的本地文件读取方法 + async readLocalFile(uri: string): Promise { + try { + // 使用异步方式读取,避免阻塞 + const file = await fileIo.open(uri, fileIo.OpenMode.READ_ONLY); + const stat = await fileIo.stat(uri); + const size = stat.size; + + // 限制文件大小,避免内存溢出 + if (size > 10 * 1024 * 1024) { // 10MB限制 + throw new Error('文件过大,超过10MB限制'); + } + + const buffer = new ArrayBuffer(size); + await fileIo.read(file.fd, buffer); + await fileIo.close(file); + + return buffer; + } catch (err) { + throw new Error(`文件读取失败: ${JSON.stringify(err)}`); + } + } } diff --git a/features/patient/src/main/ets/components/AddAndEditRecordComp.ets b/features/patient/src/main/ets/components/AddAndEditRecordComp.ets index ece03f9..b365f16 100644 --- a/features/patient/src/main/ets/components/AddAndEditRecordComp.ets +++ b/features/patient/src/main/ets/components/AddAndEditRecordComp.ets @@ -56,12 +56,12 @@ export struct AddAndEditRecordComp { this.photos.splice(this.removeIndex, 1) this.maxSelectNumber = 8 - this.photos.length; - this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { - console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) - this.base64Array = base64Array - }).catch((err:BusinessError) => { - console.error('批量转换失败:', err) - }) + // this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { + // console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + // this.base64Array = base64Array + // }).catch((err:BusinessError) => { + // console.error('批量转换失败:', err) + // }) } aboutToAppear(): void { @@ -75,17 +75,17 @@ export struct AddAndEditRecordComp { this.creat_time = model.create_date this.maxSelectNumber = 8 - this.photos.length - this.convertUrisOrUrlsToBase64(model.photo).then(base64Array => { - console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) - this.base64Array = base64Array - }).catch((err:BusinessError) => { - console.error('批量转换失败:', err) - }) + // this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { + // console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + // this.base64Array = base64Array + // }).catch((err:BusinessError) => { + // console.error('批量转换失败:', err) + // }) } } } - submitData() { + async submitData() { if (ChangeUtil.stringIsUndefinedAndNull(this.creat_time)) { promptAction.showToast({ message:'请选择日期', duration: 1000 }) return @@ -95,6 +95,7 @@ export struct AddAndEditRecordComp { return } this.dialog.open() + this.base64Array =await this.convertUrisOrUrlsToBase64(this.photos) const requestUrl = this.recordUuid?BasicConstant.upConditionRecord:BasicConstant.addConditionRecord const entity: rcp.MultipartForm = this.recordUuid? new rcp.MultipartForm({ "uuid":this.recordUuid, @@ -265,12 +266,12 @@ export struct AddAndEditRecordComp { } this.photos.push(...selectedUris); this.maxSelectNumber = 8 - this.photos.length - this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { - console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) - this.base64Array = base64Array - }).catch((err:BusinessError) => { - console.error('批量转换失败:', err) - }) + // this.convertUrisOrUrlsToBase64(this.photos).then(base64Array => { + // console.info('转换结果:', base64Array+'转换个数:'+base64Array.length) + // this.base64Array = base64Array + // }).catch((err:BusinessError) => { + // console.error('批量转换失败:', err) + // }) } }), alignment: DialogAlignment.Bottom, diff --git a/products/expert/src/main/ets/entryability/NimRepository.ets b/products/expert/src/main/ets/entryability/NimRepository.ets index fe07448..b1b2b0c 100644 --- a/products/expert/src/main/ets/entryability/NimRepository.ets +++ b/products/expert/src/main/ets/entryability/NimRepository.ets @@ -48,6 +48,8 @@ export class NimRepository { return NimRepository.instance } + public static isfirstloge=true + async login(accountId: string, token: string, appKey: string) { try { console.debug(`Performance Test im start loginSuccess`) @@ -56,6 +58,14 @@ export class NimRepository { { return } + if(NimRepository.isfirstloge) + { + NimRepository.isfirstloge=false + } + else + { + return + } await this.nim.loginService.login(accountId, token, { forceMode: true } as V2NIMLoginOption); diff --git a/products/expert/src/main/ets/pages/LoginPage/LoginPage.ets b/products/expert/src/main/ets/pages/LoginPage/LoginPage.ets index 3656f33..15e2cee 100644 --- a/products/expert/src/main/ets/pages/LoginPage/LoginPage.ets +++ b/products/expert/src/main/ets/pages/LoginPage/LoginPage.ets @@ -28,7 +28,7 @@ struct LoginPage { } onLogins() { - + NimRepository.isfirstloge=true this.login(this.YX_accid,this.YX_token) }