fix: 修复患者就诊历史

This commit is contained in:
2025-12-24 16:05:41 +08:00
parent 392c9c1028
commit 69acd7a4bb
9 changed files with 217 additions and 71 deletions

View File

@@ -66,6 +66,7 @@
/* */
"mp-weixin" : {
"appid" : "wx1eb90a487ca945d2",
"__usePrivacyCheck__" : true,
"setting" : {
"urlCheck" : false,
"es6" : true,

View File

@@ -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"

BIN
static/chat/send.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
static/chat/send2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -442,25 +442,25 @@
<view class="icon-circle"><u-icon name="photo-fill" size="20" color="#606266"></u-icon></view>
<text>相册</text>
</view>
<!-- 拍照按钮 -->
<view class="action-item" @click="openCamera">
<view class="icon-circle"><u-icon name="camera-fill" size="20" color="#606266"></u-icon></view>
<text>拍摄</text>
</view>
<!-- 视频按钮 -->
<view class="action-item" @click="openMediaPicker('video')">
<view class="icon-circle"><u-icon name="play-circle-fill" size="20" color="#606266"></u-icon></view>
<text>视频</text>
</view>
<!-- &lt;!&ndash; 拍照按钮 &ndash;&gt;-->
<!-- <view class="action-item" @click="openCamera">-->
<!-- <view class="icon-circle"><u-icon name="camera-fill" size="20" color="#606266"></u-icon></view>-->
<!-- <text>拍摄</text>-->
<!-- </view>-->
<!-- &lt;!&ndash; 视频按钮 &ndash;&gt;-->
<!-- <view class="action-item" @click="openMediaPicker('video')">-->
<!-- <view class="icon-circle"><u-icon name="play-circle-fill" size="20" color="#606266"></u-icon></view>-->
<!-- <text>视频</text>-->
<!-- </view>-->
</view>
</view>
<!-- 下半部分输入框行 -->
<view class="input-bar">
<!-- 语音/键盘切换 -->
<view class="voice-switch" @click="toggleVoiceInput">
<u-icon :name="voiceInputActive ? 'keyboard' : 'mic'" size="28" color="#333"></u-icon>
</view>
<!-- <view class="voice-switch" @click="toggleVoiceInput">-->
<!-- <u-icon :name="voiceInputActive ? 'keyboard' : 'mic'" size="28" color="#333"></u-icon>-->
<!-- </view>-->
<!-- 输入区域容器 -->
<view class="input-field-wrapper">
@@ -489,11 +489,13 @@
<view class="send-btn-wrapper" v-if="newMessage.trim() || voiceInputActive">
<view class="send-btn" @click="sendTextMessage">
<!-- 文本发送图标 -->
<u-icon name="arrow-up" size="18" color="#fff" v-if="!voiceInputActive"></u-icon>
<!-- 语音状态图标 -->
<view class="voice-wave" v-else>
<u-icon name="mic-fill" size="16" color="#fff"></u-icon>
</view>
<image src="/static/chat/send2.png" style="width: 30rpx; height: 30rpx;" />
<!-- <uni-icons type="paperplane-filled"></uni-icons>-->
<!-- <u-icon name="arrow-up" size="18" color="#fff" v-if="!voiceInputActive"></u-icon>-->
<!-- &lt;!&ndash; 语音状态图标 &ndash;&gt;-->
<!-- <view class="voice-wave" v-else>-->
<!-- <u-icon name="mic-fill" size="16" color="#fff"></u-icon>-->
<!-- </view>-->
</view>
</view>
</view>
@@ -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();
}
}
});
}
});
}

View File

@@ -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)

View File

@@ -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'], //可以指定是原图还是压缩图,默认二者都有

View File

@@ -263,11 +263,11 @@
<u-radio name="0" active-color="#2B85E4"></u-radio>
</u-radio-group>
</u-form-item>
<u-form-item label="患病信息" prop="illnessInfo" label-width="200">
<u-form-item label="症状" prop="illnessInfo" label-width="200">
<u-input
v-model="prescriptionFormData.illnessInfo"
type="select"
placeholder="请选择患病信息"
placeholder="请选择症状"
@click="showIllnessPicker = true"
disabled
/>
@@ -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) {

View File

@@ -204,4 +204,5 @@ export class WebSocketManager {
}
// 全局WebSocket实例
export const webSocketManager = new WebSocketManager('ws://127.0.0.1:12080/ws');
// export const webSocketManager = new WebSocketManager('ws://127.0.0.1:12080/ws');
export const webSocketManager = new WebSocketManager('wss://api.ws.g.xiaokang88.com/ws');