diff --git a/manifest.json b/manifest.json index 38b8f1e..f97c660 100644 --- a/manifest.json +++ b/manifest.json @@ -66,6 +66,7 @@ /* 小程序特有相关 */ "mp-weixin" : { "appid" : "wx1eb90a487ca945d2", + "__usePrivacyCheck__" : true, "setting" : { "urlCheck" : false, "es6" : true, diff --git a/request/api/request.js b/request/api/request.js index 76a3bea..498876e 100644 --- a/request/api/request.js +++ b/request/api/request.js @@ -26,7 +26,9 @@ function request(url, params, method = 0) { // let baseURL = "http://127.0.0.1:18000/member" if (url.split('/').indexOf('imApi') !== -1) { // baseURL = "http://127.0.0.1:12080/api" - baseURL = isDev === true? 'http://127.0.0.1:12080/api': "http://im.xiaokang88.com/api" + // baseURL = isDev === true? 'http://127.0.0.1:12080/api': "http://im.xiaokang88.com/api" + // baseURL = isDev === true? 'http://127.0.0.1:12080/api': "https://api.ws.g.xiaokang88.com/api" + baseURL = "https://api.ws.g.xiaokang88.com/api" } if (url.split('/').indexOf('newApi') !== -1) { baseURL = isDev === true? 'http://127.0.0.1:18018/member': "https://shop.xiaokang88.com/member" diff --git a/static/chat/send.png b/static/chat/send.png new file mode 100644 index 0000000..d229a19 Binary files /dev/null and b/static/chat/send.png differ diff --git a/static/chat/send2.png b/static/chat/send2.png new file mode 100644 index 0000000..be31d83 Binary files /dev/null and b/static/chat/send2.png differ diff --git a/subPackages/chat/chat.vue b/subPackages/chat/chat.vue index 278b4bc..7c0e712 100644 --- a/subPackages/chat/chat.vue +++ b/subPackages/chat/chat.vue @@ -442,25 +442,25 @@ 相册 - - - - 拍摄 - - - - - 视频 - + + + + + + + + + + - - - + + + @@ -489,11 +489,13 @@ - - - - - + + + + + + + @@ -716,6 +718,32 @@ export default { }, methods: { + /** + * 检查隐私授权 + * 微信小程序从2023年9月起要求在使用敏感API前获取用户隐私授权 + */ + checkPrivacyAuthorize() { + return new Promise((resolve, reject) => { + // #ifdef MP-WEIXIN + if (typeof uni.requirePrivacyAuthorize === 'function') { + uni.requirePrivacyAuthorize({ + success: () => resolve(), + fail: () => { + uni.showToast({ title: '需要同意隐私协议才能使用此功能', icon: 'none' }); + reject(new Error('隐私授权被拒绝')); + } + }); + } else { + // 低版本基础库不需要隐私授权 + resolve(); + } + // #endif + // #ifndef MP-WEIXIN + resolve(); + // #endif + }); + }, + /** * 计算并设置 scroll-view 的明确高度 * 根据 uni-app 文档,scroll-view 需要明确的高度才能正常滚动 @@ -1152,9 +1180,16 @@ export default { this.newMessage = ''; }, - startVoiceRecording() { + async startVoiceRecording() { if (this.recording) return; + // 先检查隐私授权 + try { + await this.checkPrivacyAuthorize(); + } catch (e) { + return; // 用户拒绝隐私授权 + } + // 检查录音权限 uni.getSetting({ success: (res) => { @@ -1214,8 +1249,16 @@ export default { return this.currentPlayingAudio === msg.id; }, - openMediaPicker(type) { + async openMediaPicker(type) { this.showMoreActions = false; + + // 先检查隐私授权 + try { + await this.checkPrivacyAuthorize(); + } catch (e) { + return; // 用户拒绝隐私授权 + } + if (type === 'image') { uni.chooseImage({ count: 9, @@ -1277,7 +1320,14 @@ export default { }); }, - openCamera() { + async openCamera() { + // 先检查隐私授权 + try { + await this.checkPrivacyAuthorize(); + } catch (e) { + return; // 用户拒绝隐私授权 + } + uni.chooseImage({ count: 1, sourceType: ['camera'], @@ -1295,26 +1345,45 @@ export default { }); }, - toggleVoiceInput() { + async toggleVoiceInput() { if (!this.voiceInputActive) { - // 切换到语音前检查权限 + // 先检查隐私授权 + try { + await this.checkPrivacyAuthorize(); + } catch (e) { + return; // 用户拒绝隐私授权 + } + + // 切换到语音前检查并请求录音权限 uni.getSetting({ success: (res) => { if (res.authSetting['scope.record']) { + // 已有权限,直接切换 this.hasRecordPermission = true; this.voiceInputActive = true; } else { - this.hasRecordPermission = false; - uni.showModal({ - title: '录音权限', - content: '需要录音权限才能使用语音输入', - showCancel: true, - cancelText: '取消', - confirmText: '去设置', - success: (modalRes) => { - if (modalRes.confirm) { - uni.openSetting(); - } + // 没有权限,请求授权(和图片一样的授权方式) + uni.authorize({ + scope: 'scope.record', + success: () => { + this.hasRecordPermission = true; + this.voiceInputActive = true; + }, + fail: () => { + // 用户拒绝了授权,这时才需要引导去设置 + this.hasRecordPermission = false; + uni.showModal({ + title: '录音权限', + content: '需要录音权限才能使用语音输入,请在设置中开启', + showCancel: true, + cancelText: '取消', + confirmText: '去设置', + success: (modalRes) => { + if (modalRes.confirm) { + uni.openSetting(); + } + } + }); } }); } diff --git a/subPackages/doctor/doctor-userinfo.vue b/subPackages/doctor/doctor-userinfo.vue index 372eeea..1d9969f 100644 --- a/subPackages/doctor/doctor-userinfo.vue +++ b/subPackages/doctor/doctor-userinfo.vue @@ -134,6 +134,7 @@ import { } from '@/request/api/api.js' import {checkDev} from "@/utils/utils"; import {genOrderApi, saveRegisterInfoApi} from "@/request/api/order"; +import request from "@/request/api/request"; export default { data() { return { @@ -353,31 +354,54 @@ export default { // this.rInfo 在 onLoad 中已经解析为对象,直接使用 let params = typeof this.rInfo === 'string' ? JSON.parse(this.rInfo) : this.rInfo; - // 保存病患信息 - saveRegisterInfoApi({ - register_id: this.register_id, - doctor_id: params.doctor_id || this.Did, - drug_id: params.drug_id || params.id, - has_visited: params.has_visited || params.hasVisited, - has_used_drug: params.has_used_drug || params.hasUsedDrug, - illnessInfo: params.illness_info || params.illnessInfo, - type: params.type, - number: params.number, - store_id: uni.getStorageSync('store_id') || '11001', - }).then(() => { - // 跳转到挂号页面,让用户确认挂号并支付 - // 将 rInfo 对象转换为 JSON 字符串并 URL 编码 - const rInfoStr = typeof this.rInfo === 'string' ? this.rInfo : JSON.stringify(this.rInfo); - uni.navigateTo({ - url: `/subPackages/register/register?id=${this.register_id}&doctor_id=${this.Did}&r_info=${encodeURIComponent(rInfoStr)}` - }); - }).catch((error) => { - console.error('保存患者就诊信息失败:', error); - // 即使保存失败,也跳转到挂号页面 + // 如果有 info_id,使用新接口更新关联;否则用旧接口保存 + if (params.info_id) { + // 新流程:更新已创建的 RegisterInfo 的 register_id + request('/xkApi/order/update-register-info-register-id', { + method: 'POST', + data: { + info_id: params.info_id, + register_id: this.register_id, + } + }).then(() => { + // 跳转到挂号页面,让用户确认挂号并支付 + const rInfoStr = typeof this.rInfo === 'string' ? this.rInfo : JSON.stringify(this.rInfo); uni.navigateTo({ - url: `/subPackages/register/register?id=${this.register_id}&doctor_id=${this.Did}&r_info=${this.rInfo}` + url: `/subPackages/register/register?id=${this.register_id}&doctor_id=${this.Did}&r_info=${encodeURIComponent(rInfoStr)}` + }); + }).catch((error) => { + console.error('更新就诊信息关联失败:', error); + // 即使更新失败,也跳转到挂号页面 + uni.navigateTo({ + url: `/subPackages/register/register?id=${this.register_id}&doctor_id=${this.Did}&r_info=${encodeURIComponent(typeof this.rInfo === 'string' ? this.rInfo : JSON.stringify(this.rInfo))}` + }); }); - }); + } else { + // 旧流程:保存病患信息(兼容没有 info_id 的情况) + saveRegisterInfoApi({ + register_id: this.register_id, + doctor_id: params.doctor_id || this.Did, + drug_id: params.drug_id || params.id, + has_visited: params.has_visited || params.hasVisited, + has_used_drug: params.has_used_drug || params.hasUsedDrug, + illnessInfo: params.illness_info || params.illnessInfo, + type: params.type, + number: params.number, + store_id: uni.getStorageSync('store_id') || '11001', + }).then(() => { + // 跳转到挂号页面,让用户确认挂号并支付 + const rInfoStr = typeof this.rInfo === 'string' ? this.rInfo : JSON.stringify(this.rInfo); + uni.navigateTo({ + url: `/subPackages/register/register?id=${this.register_id}&doctor_id=${this.Did}&r_info=${encodeURIComponent(rInfoStr)}` + }); + }).catch((error) => { + console.error('保存患者就诊信息失败:', error); + // 即使保存失败,也跳转到挂号页面 + uni.navigateTo({ + url: `/subPackages/register/register?id=${this.register_id}&doctor_id=${this.Did}&r_info=${this.rInfo}` + }); + }); + } return; } uni.setStorageSync('register_id', this.register_id) diff --git a/subPackages/my/mycollection.vue b/subPackages/my/mycollection.vue index c67ef8a..4813baa 100644 --- a/subPackages/my/mycollection.vue +++ b/subPackages/my/mycollection.vue @@ -91,8 +91,28 @@ }, // 点击头像触发click事件 changeUserPhoto - changeUserPhoto() { + async changeUserPhoto() { console.log('进入更新头像的功能') + + // 先检查隐私授权 + // #ifdef MP-WEIXIN + if (typeof uni.requirePrivacyAuthorize === 'function') { + try { + await new Promise((resolve, reject) => { + uni.requirePrivacyAuthorize({ + success: () => resolve(), + fail: () => { + uni.showToast({ title: '需要同意隐私协议才能使用此功能', icon: 'none' }); + reject(new Error('隐私授权被拒绝')); + } + }); + }); + } catch (e) { + return; // 用户拒绝隐私授权 + } + } + // #endif + uni.chooseImage({ count: 1, //默认9 sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 diff --git a/subPackages/product/symptoms.vue b/subPackages/product/symptoms.vue index 04b2aac..a3387b2 100644 --- a/subPackages/product/symptoms.vue +++ b/subPackages/product/symptoms.vue @@ -263,11 +263,11 @@ - + @@ -515,6 +515,15 @@ export default { }); return; } + + // 先保存表单数据到局部变量(因为 closePrescriptionFormPopup 会清空表单) + const formData = { + hasVisited: this.prescriptionFormData.hasVisited, + hasUsedDrug: this.prescriptionFormData.hasUsedDrug, + illnessInfo: this.prescriptionFormData.illnessInfo, + }; + const quantity = this.prescriptionQuantity; + this.submitted = true; this.closePrescriptionFormPopup(); @@ -523,21 +532,41 @@ export default { const doctorRes = await this.getDefaultDoctorId(); const doctorId = doctorRes.data.result?.doctor_id || '39'; - // 2. 准备患者就诊信息 - const rInfo = { - has_visited: this.prescriptionFormData.hasVisited, - has_used_drug: this.prescriptionFormData.hasUsedDrug, - illness_info: this.prescriptionFormData.illnessInfo, - drug_name: this.productDetail.drug_name, + // 2. 先调用后端API保存就诊信息,获取info_id + const createRes = await request('/xkApi/order/create-register-info', { + method: 'POST', + data: { + doctor_id: doctorId, + drug_id: this.productDetail.id, + has_visited: formData.hasVisited, + has_used_drug: formData.hasUsedDrug, + illnessInfo: formData.illnessInfo, + type: this.productDetail.type || 2, + number: quantity, + } + }, 1); + + const infoId = createRes.data?.result?.info_id || createRes.data?.info_id; + if (!infoId) { + throw new Error('创建就诊信息失败'); + } + + // 3. 准备患者就诊信息(包含info_id,用于后续更新register_id) + const rInfo = { + info_id: infoId, // 新增:用于挂号后更新关联 + has_visited: formData.hasVisited, + has_used_drug: formData.hasUsedDrug, + illness_info: formData.illnessInfo, + drug_name: this.productDetail.drug_name, drug_id: this.productDetail.id, - number: this.prescriptionQuantity, + number: quantity, type: this.productDetail.type || 2, // 2=西药,3=保健食品 created_at: new Date().toLocaleString('zh-CN') }; - // 3. 跳转到就诊人选择页面,传递 register_type=3 和患者就诊信息 + // 4. 跳转到就诊人选择页面,传递 register_type=3 和患者就诊信息 // 用户选择就诊人后,会创建挂号记录并跳转到 register.vue - uni.navigateTo({ + uni.navigateTo({ url: `/subPackages/doctor/doctor-userinfo?id=${doctorId}&r_type=3&r_info=${encodeURIComponent(JSON.stringify(rInfo))}` }); } catch (error) { diff --git a/utils/ws/websocket.js b/utils/ws/websocket.js index e7eddcd..1196cd4 100644 --- a/utils/ws/websocket.js +++ b/utils/ws/websocket.js @@ -204,4 +204,5 @@ export class WebSocketManager { } // 全局WebSocket实例 -export const webSocketManager = new WebSocketManager('ws://127.0.0.1:12080/ws'); \ No newline at end of file +// export const webSocketManager = new WebSocketManager('ws://127.0.0.1:12080/ws'); +export const webSocketManager = new WebSocketManager('wss://api.ws.g.xiaokang88.com/ws'); \ No newline at end of file