1. 优化了一些交互,中药药品编辑交互

2. dev和生产环境统一鉴别
This commit is contained in:
李琦
2026-05-30 13:52:44 +08:00
parent ad370375a7
commit 6d93314222
15 changed files with 496 additions and 326 deletions

View File

@@ -41,8 +41,16 @@ const reqInterceptor = async (options) => {
...options.header ...options.header
} }
const isToken = (options.header || {}).isToken === false const isToken = (options.header || {}).isToken === false
if (uni.getStorageSync('token') && !isToken) { const isClinicAdminReq = (options.header || {})._clinicAdmin === '1'
options.header['authorization'] = `Bearer ${uni.getStorageSync('token')}`// 让每个请求携带自定义token 请根据实际情况自行修改 || (options.url && String(options.url).indexOf('clinic-admin') !== -1)
const clinicToken = uni.getStorageSync('clinic_admin_token')
const doctorToken = uni.getStorageSync('token')
if (!isToken) {
if (isClinicAdminReq && clinicToken) {
options.header['authorization'] = `Bearer ${clinicToken}`
} else if (doctorToken) {
options.header['authorization'] = `Bearer ${doctorToken}`
}
} }
return options; return options;
} }
@@ -86,14 +94,21 @@ const resInterceptor = (response, conf = {}) => {
} else if (statusCode === 401) { } else if (statusCode === 401) {
uni.showToast({ uni.showToast({
icon: 'error', icon: 'error',
title: response['msg'] || errorCode[statusCode] title: response['msg'] || response['message'] || errorCode[statusCode]
}) })
uni.removeStorageSync() const isClinic = uni.getStorageSync('loginMode') === 'clinic_admin'
setTimeout(()=>{ if (isClinic) {
uni.navigateTo({ uni.removeStorageSync('clinic_admin_token')
url:'/pages/login/index' uni.removeStorageSync('clinic_admin_user')
}) uni.removeStorageSync('loginMode')
},1000) } else {
uni.removeStorageSync('token')
uni.removeStorageSync('loginInfo')
uni.removeStorageSync('identity')
}
setTimeout(() => {
uni.reLaunch({ url: '/pages/login/index' })
}, 1000)
_responseLog(response, conf, "response 401") _responseLog(response, conf, "response 401")
// 增加一个控制字段wakaryReqToReject 使 reject的内容更加可控 // 增加一个控制字段wakaryReqToReject 使 reject的内容更加可控
return { return {

View File

@@ -71,6 +71,8 @@
* @event {Function} on-choose-complete 每次选择图片后触发,只是让外部可以得知每次选择后,内部的文件列表 * @event {Function} on-choose-complete 每次选择图片后触发,只是让外部可以得知每次选择后,内部的文件列表
* @example <u-upload :action="action" :file-list="fileList" ></u-upload> * @example <u-upload :action="action" :file-list="fileList" ></u-upload>
*/ */
import { prepareImagePath } from '@/common/js/image-compress.js';
export default { export default {
name: 'd-upload', name: 'd-upload',
props: { props: {
@@ -296,51 +298,56 @@
const { const {
name = '', maxCount, multiple, maxSize, sizeType, lists, camera, compressed, maxDuration, sourceType name = '', maxCount, multiple, maxSize, sizeType, lists, camera, compressed, maxDuration, sourceType
} = this; } = this;
let chooseFile = null;
const newMaxCount = maxCount - lists.length; const newMaxCount = maxCount - lists.length;
// 设置为只选择图片的时候使用 chooseImage 来实现
chooseFile = new Promise((resolve, reject) => {
uni.chooseImage({ uni.chooseImage({
count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1, count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,
sourceType: sourceType, sourceType: sourceType,
sizeType, sizeType,
success: resolve, success: async (res) => {
fail: reject const listOldLength = this.lists.length;
}); for (let index = 0; index < res.tempFiles.length; index++) {
}); const val = res.tempFiles[index];
chooseFile if (!this.checkFileExt(val)) continue;
.then(res => { if (!multiple && index >= 1) continue;
let file = null;
let listOldLength = this.lists.length;
res.tempFiles.map((val, index) => {
// 检查文件后缀是否允许如果不在this.limitType内就会返回false
if (!this.checkFileExt(val)) return;
// 如果是非多选index大于等于1或者超出最大限制数量时不处理
if (!multiple && index >= 1) return;
if (val.size > maxSize) { if (val.size > maxSize) {
this.$emit('on-oversize', val, this.lists, this.index); this.$emit('on-oversize', val, this.lists, this.index);
this.showToast('超出允许的文件大小'); this.showToast('超出允许的文件大小');
} else { continue;
}
if (maxCount <= lists.length) { if (maxCount <= lists.length) {
this.$emit('on-exceed', val, this.lists, this.index); this.$emit('on-exceed', val, this.lists, this.index);
this.showToast('超出最大允许的文件个数'); this.showToast('超出最大允许的文件个数');
return; break;
} }
try {
const prepared = await prepareImagePath({
path: val.path,
size: val.size,
});
if (!prepared) continue;
lists.push({ lists.push({
url: val.path, url: prepared.path,
progress: 0, progress: 0,
error: false, error: false,
file: val file: {
...val,
path: prepared.path,
size: prepared.size,
},
}); });
} catch (error) {
this.$emit('on-choose-fail', error);
this.showToast('图片处理失败');
}
} }
});
// 每次图片选择完,抛出一个事件,并将当前内部选择的图片数组抛出去
this.$emit('on-choose-complete', this.lists, this.index); this.$emit('on-choose-complete', this.lists, this.index);
if (this.autoUpload) this.uploadFile(listOldLength); if (this.autoUpload) this.uploadFile(listOldLength);
}) },
.catch(error => { fail: (error) => {
this.$emit('on-choose-fail', error); this.$emit('on-choose-fail', error);
}
}); });
}, },
// 提示用户消息 // 提示用户消息

View File

@@ -391,6 +391,61 @@
} }
] ]
}, {
"root": "subPackages/sub_clinic_admin",
"pages": [{
"path": "home/index",
"style": { "navigationBarTitleText": "工作台", "navigationStyle": "custom" }
},
{
"path": "my/index",
"style": { "navigationBarTitleText": "我的", "navigationStyle": "custom" }
},
{
"path": "withdrawal/index",
"style": { "navigationBarTitleText": "提现管理", "navigationStyle": "custom" }
},
{
"path": "withdrawal/settlement/index",
"style": { "navigationBarTitleText": "结算记录", "navigationStyle": "custom" }
},
{
"path": "withdrawal/settlement/detail",
"style": { "navigationBarTitleText": "结算明细", "navigationStyle": "custom" }
},
{
"path": "withdrawal/apply",
"style": { "navigationBarTitleText": "申请提现", "navigationStyle": "custom" }
},
{
"path": "withdrawal/card-edit",
"style": { "navigationBarTitleText": "编辑账户", "navigationStyle": "custom" }
},
{
"path": "withdrawal/record-detail",
"style": { "navigationBarTitleText": "提现详情", "navigationStyle": "custom" }
},
{
"path": "reconciliation/index",
"style": { "navigationBarTitleText": "对账单", "navigationStyle": "custom" }
},
{
"path": "order/index",
"style": { "navigationBarTitleText": "商品订单", "navigationStyle": "custom" }
},
{
"path": "order/detail",
"style": { "navigationBarTitleText": "订单详情", "navigationStyle": "custom" }
},
{
"path": "warehouse/index",
"style": { "navigationBarTitleText": "仓库管理", "navigationStyle": "custom" }
},
{
"path": "warehouse/detail",
"style": { "navigationBarTitleText": "药品详情", "navigationStyle": "custom" }
}
]
}, { }, {
"root": "subPackages/sub_agreement", "root": "subPackages/sub_agreement",
"pages": [{ "pages": [{
@@ -423,10 +478,10 @@
} }
], ],
"tabBar": { "tabBar": {
"color": "#fff", "color": "#666666",
"selectedColor": "#fff", "selectedColor": "#1575FC",
"backgroundColor": "#fff", "backgroundColor": "#ffffff",
"borderStyle": "white", "borderStyle": "black",
"list": [{ "list": [{
"pagePath": "pages/workbench/index", "pagePath": "pages/workbench/index",
"text": "工作台" "text": "工作台"

View File

@@ -10,10 +10,16 @@
<view class="pwd"> <view class="pwd">
<d-input :maxlength="11" height="96" v-model="form['mobile']" <d-input :maxlength="11" height="96" v-model="form['mobile']"
:prefixIcon="require('../../static/image/act.png')" borderRadius="96rpx" prefixIconSize="40rpx" :prefixIcon="require('../../static/image/act.png')" borderRadius="96rpx" prefixIconSize="40rpx"
placeholder="请输入手机号" @input="is_d=false" :placeholder-style="{fontSize:'32rpx'}" :placeholder="loginMode === 'clinic_admin' ? '请输入手机号' : '请输入手机号'" @input="is_d=false" :placeholder-style="{fontSize:'32rpx'}"
:custom-style="{fontSize:'32rpx',paddingLeft:'60rpx'}" /> :custom-style="{fontSize:'32rpx',paddingLeft:'60rpx'}" />
</view> </view>
<view class="pwd" v-if="loginMode === 'clinic_admin'">
<d-input height="96" v-model="clinicPassword" type="password" password
borderRadius="96rpx" placeholder="请输入后台登录密码" :placeholder-style="{fontSize:'32rpx'}"
:custom-style="{fontSize:'32rpx',paddingLeft:'32rpx'}" />
</view>
<view class="pwd"> <view class="pwd">
<u-field v-model="smsCode" placeholder="请填写验证码" :placeholder-style="{fontSize:'32rpx'}"> <u-field v-model="smsCode" placeholder="请填写验证码" :placeholder-style="{fontSize:'32rpx'}">
<u-button size="mini" slot="right" @click="getCode">{{codeText}}</u-button> <u-button size="mini" slot="right" @click="getCode">{{codeText}}</u-button>
@@ -40,10 +46,13 @@
登录</u-button> 登录</u-button>
</view> </view>
<!-- <view class="register">--> <view class="register">
<!-- <text @click="$go('../../subPackages/sub_workbench/workbench_identity')">手机号注册</text>--> <text @click="switchClinicAdmin">{{ loginMode === 'clinic_admin' ? '返回医生/药师登录' : '我是诊所管理员' }}</text>
<!-- </view>--> </view>
<!-- <view class="register">-->
<!-- <text @click="$go('../../subPackages/sub_workbench/workbench_identity')">手机号注册</text>-->
<!-- </view>-->
</view> </view>
</view> </view>
@@ -60,9 +69,15 @@
getUserInfo, getUserInfo,
loginOrRe loginOrRe
} from '../../api/all'; } from '../../api/all';
import {
sendClinicAdminCode,
clinicAdminLogin,
getClinicAdminMyInfo,
} from '../../api/clinicAdmin';
export default { export default {
data() { data() {
return { return {
loginMode: 'service_user',
loading: false, loading: false,
form: { form: {
check: false check: false
@@ -74,6 +89,7 @@
mobile: '', mobile: '',
codeText: '', codeText: '',
smsCode: '', smsCode: '',
clinicPassword: '',
code: '' code: ''
}; };
}, },
@@ -83,6 +99,13 @@
// console.log('appid', accountInfo.miniProgram.appId); // 小程序 appId // console.log('appid', accountInfo.miniProgram.appId); // 小程序 appId
}, },
mounted() { mounted() {
const clinicToken = uni.getStorageSync('clinic_admin_token')
if (clinicToken && uni.getStorageSync('loginMode') === 'clinic_admin') {
setTimeout(() => {
uni.reLaunch({ url: '/subPackages/sub_clinic_admin/home/index' })
}, 200)
return
}
const token = uni.getStorageSync('token') const token = uni.getStorageSync('token')
const info = uni.getStorageSync('loginInfo') const info = uni.getStorageSync('loginInfo')
if (token&&info) { if (token&&info) {
@@ -105,6 +128,11 @@
} }
}, },
methods: { methods: {
switchClinicAdmin() {
this.loginMode = this.loginMode === 'clinic_admin' ? 'service_user' : 'clinic_admin'
this.clinicPassword = ''
this.smsCode = ''
},
toLogin() { toLogin() {
uni.login({ uni.login({
provider: 'weixin', provider: 'weixin',
@@ -115,7 +143,6 @@
}, },
//登录或者注册接口 //登录或者注册接口
register() { register() {
//修改1
if (!uni.$u.test.mobile(this.form['mobile'])) { if (!uni.$u.test.mobile(this.form['mobile'])) {
this.$toast('请输入正确的手机号') this.$toast('请输入正确的手机号')
return return
@@ -130,6 +157,15 @@
return return
} }
if (this.loginMode === 'clinic_admin') {
if (!this.clinicPassword) {
this.$toast('请输入后台登录密码')
return
}
this.clinicAdminLoginFlow()
return
}
const data = { const data = {
store_id: '11001', store_id: '11001',
mobile: this.form['mobile'], mobile: this.form['mobile'],
@@ -257,16 +293,44 @@
codeChange(text) { codeChange(text) {
this.codeText = text; this.codeText = text;
}, },
clinicAdminLoginFlow() {
this.loading = true
clinicAdminLogin(this.form['mobile'], this.clinicPassword, this.smsCode).then(res => {
if (res.code !== 0 || !res.result || !res.result.token) {
this.$toast(res.message || res.msg || '登录失败')
return Promise.reject()
}
uni.setStorageSync('loginMode', 'clinic_admin')
uni.setStorageSync('clinic_admin_token', res.result.token)
return getClinicAdminMyInfo()
}).then((wrap) => {
if (!wrap || !wrap.ok) return
uni.setStorageSync('clinic_admin_user', wrap.data)
this.$toast('登录成功')
setTimeout(() => {
uni.reLaunch({ url: '/subPackages/sub_clinic_admin/home/index' })
}, 400)
}).catch(() => {}).finally(() => {
this.loading = false
})
},
getCode() { getCode() {
if (this.$refs.uCode.canGetCode) { if (this.$refs.uCode.canGetCode) {
// 模拟向后端请求验证码 uni.showLoading({ title: '正在获取验证码' })
uni.showLoading({
title: '正在获取验证码'
})
setTimeout(() => { setTimeout(() => {
uni.hideLoading(); uni.hideLoading();
// 通知验证码组件内部开始倒计时 if (this.loginMode === 'clinic_admin') {
//发送验证码接口 if (!this.clinicPassword) {
this.$toast('请先输入后台登录密码')
return
}
sendClinicAdminCode(this.form['mobile']).then(res => {
if (res.code === 0 || res.errcode != -1) {
this.$refs.uCode.start();
}
})
return
}
const data = { const data = {
store_id: '11001', store_id: '11001',
mobile: this.form['mobile'] mobile: this.form['mobile']

View File

@@ -135,13 +135,15 @@
</block> </block>
<block v-if="lists.prescription_type==2"> <block v-if="lists.prescription_type==2||lists.prescription_type==5||lists.prescription_type==7">
<view class="item" v-for="(it,index) in infoList.repice" :key="item.id"> <view class="item" v-for="(it,index) in infoList.repice" :key="it.id || index">
<!-- v-for="(it,index) in item.content" :key="it.id" --> <!-- v-for="(it,index) in item.content" :key="it.id" -->
<view class="name" style="justify-content: space-between;"> <view class="name" style="justify-content: space-between;">
<view class="yp_name"> <view class="yp_name">
<text>{{ it.content.drug_name}} </text> <text>{{ (it.content && it.content.drug_name) || '' }} </text>
<text style="font-size: 24rpx;margin-left: 10rpx;">{{ it.content.specification }}</text> <text
v-if="it.content && it.content.specification"
class="drug-spec">{{ it.content.specification }}</text>
</view> </view>
<text>x{{ it.number}}</text> <text>x{{ it.number}}</text>
</view> </view>
@@ -293,6 +295,25 @@
}) })
return num return num
}, },
normalizeRepice(list) {
return (list || []).map((it) => {
let content = it.content
if (typeof content === 'string') {
try {
content = JSON.parse(content || '{}')
} catch (e) {
content = {}
}
}
if (!content || typeof content !== 'object' || Array.isArray(content)) {
content = Array.isArray(content) ? content : {}
}
return {
...it,
content,
}
})
},
getInfo() { getInfo() {
prescripDetail({ prescripDetail({
store_id: uni.getStorageSync('store_id') || '11001', store_id: uni.getStorageSync('store_id') || '11001',
@@ -300,7 +321,9 @@
}).then((res) => { }).then((res) => {
// console.log(res, 'deta'); // console.log(res, 'deta');
if (res.errcode == 0) { if (res.errcode == 0) {
this.infoList = res.data.content const content = res.data.content
content.repice = this.normalizeRepice(content.repice)
this.infoList = content
this.rpList = res.data.pharmacistInfo this.rpList = res.data.pharmacistInfo
this.lists = res.data this.lists = res.data
this.status = res.data.status this.status = res.data.status
@@ -534,6 +557,12 @@
// justify-content: space-between; // justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
.drug-spec {
font-size: 24rpx;
color: #999;
margin-left: 10rpx;
}
._name { ._name {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@@ -132,13 +132,15 @@
</block> </block>
<block v-if="lists.prescription_type==2"> <block v-if="lists.prescription_type==2||lists.prescription_type==5||lists.prescription_type==7">
<view class="item" v-for="(it,index) in infoList.repice" :key="item.id"> <view class="item" v-for="(it,index) in infoList.repice" :key="it.id || index">
<!-- v-for="(it,index) in item.content" :key="it.id" --> <!-- v-for="(it,index) in item.content" :key="it.id" -->
<view class="name" style="justify-content: space-between;"> <view class="name" style="justify-content: space-between;">
<view class="yp_name"> <view class="yp_name">
<text>{{ it.content.drug_name}} </text> <text>{{ (it.content && it.content.drug_name) || '' }} </text>
<text style="font-size: 24rpx;margin-left: 10rpx;">{{ it.content.specification }}</text> <text
v-if="it.content && it.content.specification"
class="drug-spec">{{ it.content.specification }}</text>
</view> </view>
<text>x{{ it.number}}</text> <text>x{{ it.number}}</text>
</view> </view>
@@ -273,6 +275,25 @@
}) })
return num return num
}, },
normalizeRepice(list) {
return (list || []).map((it) => {
let content = it.content
if (typeof content === 'string') {
try {
content = JSON.parse(content || '{}')
} catch (e) {
content = {}
}
}
if (!content || typeof content !== 'object' || Array.isArray(content)) {
content = Array.isArray(content) ? content : {}
}
return {
...it,
content,
}
})
},
getInfo() { getInfo() {
prescripDetail({ prescripDetail({
store_id: uni.getStorageSync('store_id') || '11001', store_id: uni.getStorageSync('store_id') || '11001',
@@ -280,7 +301,9 @@
}).then((res) => { }).then((res) => {
// console.log(res, 'deta'); // console.log(res, 'deta');
if (res.errcode == 0) { if (res.errcode == 0) {
this.infoList = res.data.content const content = res.data.content
content.repice = this.normalizeRepice(content.repice)
this.infoList = content
this.rpList = res.data.pharmacistInfo this.rpList = res.data.pharmacistInfo
this.lists = res.data this.lists = res.data
this.status = res.data.status this.status = res.data.status
@@ -514,6 +537,12 @@
// justify-content: space-between; // justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
.drug-spec {
font-size: 24rpx;
color: #999;
margin-left: 10rpx;
}
._name { ._name {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@@ -101,10 +101,10 @@
} }
], ],
"tabBar": { "tabBar": {
"color": "#fff", "color": "#666666",
"selectedColor": "#fff", "selectedColor": "#1575FC",
"backgroundColor": "#fff", "backgroundColor": "#ffffff",
"borderStyle": "white", "borderStyle": "black",
"list": [{ "list": [{
"pagePath": "pages/workbench/index", "pagePath": "pages/workbench/index",
"text": "工作台" "text": "工作台"

View File

@@ -49,6 +49,7 @@
logout, logout,
toUpload, toUpload,
} from '@/api/all.js' } from '@/api/all.js'
import { chooseAvatarImage } from '@/common/js/select-avatar-image.js';
export default { export default {
data() { data() {
return { return {
@@ -85,56 +86,24 @@
} }
}, },
selectAct() { selectAct() {
uni.chooseImage({ chooseAvatarImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'],
success: (res) => {
uni.showLoading({
title: '请稍后...'
})
const tempFiles = res.tempFiles;
let resSize = tempFiles[0].size;
// 1M=1024KB=1048576B
console.log(resSize)
if (resSize > 1048576) {
uni.showToast({
title: "上传图片大小不能超过1MB",
icon: 'error'
});
return
}
uni.uploadFile({
url: 'https://api.xiaokang88.com/open-api/upload/old-admin-img',
filePath: res.tempFiles[0]['path'],
name: 'file',
header: {
authorization: `Bearer ${uni.getStorageSync('token')}`
},
formData: { formData: {
store_id: uni.getStorageSync('store_id') || '11001' store_id: uni.getStorageSync('store_id') || '11001',
}, },
success: res => { onSuccess: (res) => {
let req = this.$u.test.jsonString(res.data) ? JSON.parse(res const req = this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
.data) : res.data
// console.log(req, 'req')
if (req.errcode == 0) { if (req.errcode == 0) {
toUpload({ toUpload({
store_id: uni.getStorageSync('store_id') || store_id: uni.getStorageSync('store_id') || '11001',
'11001', avatar: req.data.url,
avatar: req.data.url }).then(() => {
}).then((res) => { this.getDoctor();
this.getDoctor()
this.$toast('编辑成功'); this.$toast('编辑成功');
});
})
uni.hideLoading()
} else { } else {
this.$toast(res.msg); this.$toast(res.msg);
} }
} },
});
}
}); });
}, },
logout() { logout() {

View File

@@ -154,7 +154,7 @@
<view v-if="parsedObj.question" class="text-block"> <view v-if="parsedObj.question" class="text-block">
<text class="block-content">{{ parsedObj.question }}</text> <text class="block-content">{{ parsedObj.question }}</text>
</view> </view>
<view v-for="(row, idx) in (parsedObj.drugs || [])" :key="'fd-' + idx" class="info-row"> <view v-for="row in followUpDrugs" :key="row._wxKey" class="info-row">
<text class="label">{{ row.name || '药品' }}</text> <text class="label">{{ row.name || '药品' }}</text>
<text class="value">×{{ row.quantity != null ? row.quantity : 1 }}</text> <text class="value">×{{ row.quantity != null ? row.quantity : 1 }}</text>
</view> </view>
@@ -290,7 +290,7 @@
</view> </view>
<view v-if="parsedObj.questions && parsedObj.questions.length" class="transfer-qa"> <view v-if="parsedObj.questions && parsedObj.questions.length" class="transfer-qa">
<text class="transfer-qa-title">咨询问题</text> <text class="transfer-qa-title">咨询问题</text>
<view v-for="(qa, qix) in parsedObj.questions" :key="qix" class="transfer-qa-item"> <view v-for="(qa, qix) in transferQuestionsWithKey" :key="qa._wxKey" class="transfer-qa-item">
<text class="transfer-qa-q">{{ qix + 1 }}. {{ qa.question }}</text> <text class="transfer-qa-q">{{ qix + 1 }}. {{ qa.question }}</text>
<text class="transfer-qa-a">{{ qa.answer }}</text> <text class="transfer-qa-a">{{ qa.answer }}</text>
</view> </view>
@@ -318,6 +318,7 @@
<script> <script>
import { parseMessageContent } from '../utils/messageParse.js'; import { parseMessageContent } from '../utils/messageParse.js';
import { withWxKey } from '@/utils/wxListKey.js';
export default { export default {
name: 'MessageBubble', name: 'MessageBubble',
@@ -388,6 +389,14 @@ export default {
if (st === 'no' || st === '0') return '否,未使用过'; if (st === 'no' || st === '0') return '否,未使用过';
return ''; return '';
}, },
followUpDrugs() {
const drugs = (this.parsedObj && this.parsedObj.drugs) || [];
return withWxKey(drugs, 'id', 'fd');
},
transferQuestionsWithKey() {
const qs = (this.parsedObj && this.parsedObj.questions) || [];
return withWxKey(qs, 'id', 'tq');
},
experienceRxPayload() { experienceRxPayload() {
const pc = this.parsedObj; const pc = this.parsedObj;
if (!pc || this.msg.message_type !== 11) return {}; if (!pc || this.msg.message_type !== 11) return {};

View File

@@ -44,7 +44,7 @@
<text class="spinner-text">历史记录加载中...</text> <text class="spinner-text">历史记录加载中...</text>
</view> </view>
<view v-for="(msg, index) in messages" :key="msg.id || 'm-' + index" class="message-wrapper"> <view v-for="(msg, index) in messages" :key="msg._wxKey" class="message-wrapper">
<view v-if="shouldShowTime(msg, index)" class="time-divider"> <view v-if="shouldShowTime(msg, index)" class="time-divider">
<text class="time-text">{{ timeDividerText(msg) }}</text> <text class="time-text">{{ timeDividerText(msg) }}</text>
</view> </view>
@@ -167,7 +167,7 @@
<view class="tool-cell-icon"><u-icon name="close-circle" size="30" color="#6ACDBB"></u-icon></view> <view class="tool-cell-icon"><u-icon name="close-circle" size="30" color="#6ACDBB"></u-icon></view>
<text class="tool-cell-label">拒诊</text> <text class="tool-cell-label">拒诊</text>
</view> </view>
<view v-for="n in 7" :key="'tool-ph-' + n" class="tool-cell tool-cell--placeholder"></view> <view v-for="ph in toolPlaceholderCells" :key="ph._wxKey" class="tool-cell tool-cell--placeholder"></view>
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>
@@ -182,8 +182,8 @@
</view> </view>
<scroll-view v-if="!quickReplyLoading && quickReplyList.length" class="quick-reply-scroll" scroll-y> <scroll-view v-if="!quickReplyLoading && quickReplyList.length" class="quick-reply-scroll" scroll-y>
<view <view
v-for="(item, idx) in quickReplyList" v-for="item in quickReplyList"
:key="idx" :key="item._wxKey"
class="quick-reply-row" class="quick-reply-row"
@click="selectQuickReply(item)" @click="selectQuickReply(item)"
> >
@@ -222,8 +222,8 @@
<text class="orders-v">{{ registerOrderStatusText(registerOrderBlock.status) }}</text> <text class="orders-v">{{ registerOrderStatusText(registerOrderBlock.status) }}</text>
</view> </view>
<view <view
v-for="(sub, six) in childOrdersBlock" v-for="sub in childOrdersWithKey"
:key="'osub-' + six" :key="sub._wxKey"
class="orders-sub" class="orders-sub"
> >
<text class="orders-sub-label">子订单</text> <text class="orders-sub-label">子订单</text>
@@ -235,10 +235,11 @@
<view v-if="ordersRxLoading" class="orders-hint">加载中</view> <view v-if="ordersRxLoading" class="orders-hint">加载中</view>
<view v-else-if="!ordersRxList.length" class="orders-hint">暂无处方</view> <view v-else-if="!ordersRxList.length" class="orders-hint">暂无处方</view>
<view <view
v-for="(rx, orix) in ordersRxList" v-for="rx in ordersRxList"
:key="'orx-' + orix" :key="rx._wxKey"
class="orders-rx-row" class="orders-rx-row"
@click="onOrdersRxTap(orix)" :data-wx-key="rx._wxKey"
@click="onOrdersRxTap"
> >
<text class="orders-rx-no">{{ rx.order_no || rx.prescription_no || '处方' }}</text> <text class="orders-rx-no">{{ rx.order_no || rx.prescription_no || '处方' }}</text>
<text v-if="rx.total_pay_price != null" class="orders-rx-price">¥{{ rx.total_pay_price }}</text> <text v-if="rx.total_pay_price != null" class="orders-rx-price">¥{{ rx.total_pay_price }}</text>
@@ -277,7 +278,7 @@
</view> </view>
<view v-if="transferCard.questions && transferCard.questions.length" class="td-qa"> <view v-if="transferCard.questions && transferCard.questions.length" class="td-qa">
<text class="td-qa-title">咨询问题</text> <text class="td-qa-title">咨询问题</text>
<view v-for="(qa, qix) in transferCard.questions" :key="'tdq-' + qix" class="td-qa-item"> <view v-for="(qa, qix) in transferQuestionsWithKey" :key="qa._wxKey" class="td-qa-item">
<text class="td-qa-q">{{ qix + 1 }}. {{ qa.question }}</text> <text class="td-qa-q">{{ qix + 1 }}. {{ qa.question }}</text>
<text class="td-qa-a">{{ qa.answer }}</text> <text class="td-qa-a">{{ qa.answer }}</text>
</view> </view>
@@ -326,9 +327,13 @@ import PatientDetailPanel from '../components/PatientDetailPanel.vue';
import MessageBubble from '../components/MessageBubble.vue'; import MessageBubble from '../components/MessageBubble.vue';
import ReceptionActionBar from '../components/ReceptionActionBar.vue'; import ReceptionActionBar from '../components/ReceptionActionBar.vue';
import RefuseReceptionModal from '../components/RefuseReceptionModal.vue'; import RefuseReceptionModal from '../components/RefuseReceptionModal.vue';
import { withWxKey, ensureWxKey } from '@/utils/wxListKey.js';
import { prepareImagePath } from '@/common/js/image-compress.js';
const PENDING_RX_FROM_CHAT = 'xk_pending_rx_from_chat'; const PENDING_RX_FROM_CHAT = 'xk_pending_rx_from_chat';
const TOOL_PLACEHOLDER_CELLS = Array.from({ length: 7 }, (_, i) => ({ _wxKey: `ph${i}` }));
export default { export default {
components: { PatientDetailPanel, MessageBubble, ReceptionActionBar, RefuseReceptionModal }, components: { PatientDetailPanel, MessageBubble, ReceptionActionBar, RefuseReceptionModal },
data() { data() {
@@ -370,7 +375,8 @@ export default {
ordersPopupOpen: false, ordersPopupOpen: false,
ordersRxList: [], ordersRxList: [],
ordersRxLoading: false, ordersRxLoading: false,
toolPanelSwiperCurrent: 0 toolPanelSwiperCurrent: 0,
toolPlaceholderCells: TOOL_PLACEHOLDER_CELLS
}; };
}, },
computed: { computed: {
@@ -427,6 +433,13 @@ export default {
const raw = ro.child_orders || ro.sub_orders || ro.orders; const raw = ro.child_orders || ro.sub_orders || ro.orders;
return Array.isArray(raw) ? raw : []; return Array.isArray(raw) ? raw : [];
}, },
childOrdersWithKey() {
return withWxKey(this.childOrdersBlock, 'id', 'osub');
},
transferQuestionsWithKey() {
const qs = (this.transferCard && this.transferCard.questions) || [];
return withWxKey(qs, 'id', 'tdq');
},
refuseToolDisabled() { refuseToolDisabled() {
return Number(this.patientInfo && this.patientInfo.status) !== 1; return Number(this.patientInfo && this.patientInfo.status) !== 1;
}, },
@@ -586,9 +599,13 @@ export default {
this.transferCard = null; this.transferCard = null;
} }
}, },
syncMessagesFromRoom() {
const raw = chatRoomManager.getRoomMessages(this.roomId) || [];
this.messages = withWxKey(raw, 'id', 'm');
},
onMessageUpdated({ roomId }) { onMessageUpdated({ roomId }) {
if (roomId === this.roomId) { if (roomId === this.roomId) {
this.messages = [...(chatRoomManager.getRoomMessages(this.roomId) || [])]; this.syncMessagesFromRoom();
this.$forceUpdate(); this.$forceUpdate();
} }
}, },
@@ -624,7 +641,7 @@ export default {
const lastMessageId = wasFirstPage ? 0 : chatRoomManager.lastMessageId; const lastMessageId = wasFirstPage ? 0 : chatRoomManager.lastMessageId;
const batch = await chatRoomManager.loadRoomMessages(this.roomId, lastMessageId); const batch = await chatRoomManager.loadRoomMessages(this.roomId, lastMessageId);
if (batch && batch.length > 0) { if (batch && batch.length > 0) {
this.messages = [...(chatRoomManager.getRoomMessages(this.roomId) || [])]; this.syncMessagesFromRoom();
this.page++; this.page++;
} else { } else {
this.hasMore = false; this.hasMore = false;
@@ -674,16 +691,17 @@ export default {
return Math.abs(a - b) < 60000; return Math.abs(a - b) < 60000;
}); });
if (tempIndex !== -1) { if (tempIndex !== -1) {
this.$set(this.messages, tempIndex, { ...message, isTemporary: false }); const patched = ensureWxKey({ ...message, isTemporary: false }, 'id', `m${tempIndex}`);
this.$set(this.messages, tempIndex, patched);
return; return;
} }
} }
const existingIndex = this.messages.findIndex((m) => m.id === message.id); const existingIndex = this.messages.findIndex((m) => m.id === message.id);
if (existingIndex !== -1) { if (existingIndex !== -1) {
this.$set(this.messages, existingIndex, message); this.$set(this.messages, existingIndex, ensureWxKey(message, 'id', `m${existingIndex}`));
return; return;
} }
this.messages.push(message); this.messages.push(ensureWxKey(message, 'id', `m${this.messages.length}`));
if (message.message_type === chatConfig.messageTypes['end-consultation']) { if (message.message_type === chatConfig.messageTypes['end-consultation']) {
this.isConsultationEnded = true; this.isConsultationEnded = true;
} }
@@ -817,7 +835,7 @@ export default {
page_size: 30 page_size: 30
}); });
const payload = this.unwrap(res) || {}; const payload = this.unwrap(res) || {};
this.ordersRxList = Array.isArray(payload.list) ? payload.list : []; this.ordersRxList = withWxKey(Array.isArray(payload.list) ? payload.list : [], 'id', 'orx');
} catch (e) { } catch (e) {
console.warn(e); console.warn(e);
this.ordersRxList = []; this.ordersRxList = [];
@@ -830,8 +848,9 @@ export default {
const n = Number(status); const n = Number(status);
return map[n] != null ? map[n] : String(status); return map[n] != null ? map[n] : String(status);
}, },
onOrdersRxTap(index) { onOrdersRxTap(e) {
const rx = this.ordersRxList[index]; const wxKey = e && e.currentTarget && e.currentTarget.dataset && e.currentTarget.dataset.wxKey;
const rx = this.ordersRxList.find((r) => r._wxKey === wxKey);
const id = rx && (rx.id || rx.prescription_id); const id = rx && (rx.id || rx.prescription_id);
if (!id) return; if (!id) return;
let url = `/pages/my/prescriptionDetail?id=${id}`; let url = `/pages/my/prescriptionDetail?id=${id}`;
@@ -967,7 +986,7 @@ export default {
const res = await getQuickReplyListApi(); const res = await getQuickReplyListApi();
const raw = this.unwrap(res); const raw = this.unwrap(res);
const list = Array.isArray(raw) ? raw : raw && Array.isArray(raw.list) ? raw.list : []; const list = Array.isArray(raw) ? raw : raw && Array.isArray(raw.list) ? raw.list : [];
this.quickReplyList = list; this.quickReplyList = withWxKey(list, 'id', 'qr');
} catch (e) { } catch (e) {
console.error(e); console.error(e);
uni.showToast({ title: '加载常用回复失败', icon: 'none' }); uni.showToast({ title: '加载常用回复失败', icon: 'none' });
@@ -1042,6 +1061,7 @@ export default {
const idx = this.messages.findIndex((m) => m.id === tempId); const idx = this.messages.findIndex((m) => m.id === tempId);
if (idx !== -1) { if (idx !== -1) {
this.$set(this.messages[idx], 'id', mid); this.$set(this.messages[idx], 'id', mid);
this.$set(this.messages[idx], '_wxKey', String(mid));
this.$set(this.messages[idx], 'isTemporary', false); this.$set(this.messages[idx], 'isTemporary', false);
} }
} }
@@ -1056,9 +1076,33 @@ export default {
if (this.inputLocked) return; if (this.inputLocked) return;
uni.chooseImage({ uni.chooseImage({
count: 1, count: 1,
success: (res) => { success: async (res) => {
this.uploadMedia(res.tempFilePaths[0], 'image'); const tempFile = res.tempFiles && res.tempFiles[0];
const filePath = tempFile ? tempFile.path : res.tempFilePaths[0];
let fileSize = tempFile ? tempFile.size : 0;
if (!fileSize && filePath) {
try {
const info = await new Promise((resolve, reject) => {
uni.getFileInfo({
filePath,
success: resolve,
fail: reject,
});
});
fileSize = info.size;
} catch (error) {
console.error(error);
} }
}
const prepared = await prepareImagePath({
path: filePath,
size: fileSize,
});
if (!prepared) return;
this.uploadMedia(prepared.path, 'image');
},
}); });
}, },
async uploadMedia(filePath, kind) { async uploadMedia(filePath, kind) {

View File

@@ -28,7 +28,7 @@
<view v-if="patientList.length" class="list"> <view v-if="patientList.length" class="list">
<view <view
v-for="(row, idx) in patientList" v-for="(row, idx) in patientList"
:key="rowKey(row, idx)" :key="row._wxKey"
class="ol-card flex-row flex-ali-center" class="ol-card flex-row flex-ali-center"
:data-idx="idx" :data-idx="idx"
@tap="onPatientCardTap" @tap="onPatientCardTap"
@@ -38,7 +38,6 @@
<u-loading slot="loading"></u-loading> <u-loading slot="loading"></u-loading>
</u-image> </u-image>
<u-badge <u-badge
:key="'ol-ub-' + rowKey(row, idx) + '-' + Number(row.unread_count || 0)"
v-if="Number(row.unread_count) > 0" v-if="Number(row.unread_count) > 0"
:count="Number(row.unread_count)" :count="Number(row.unread_count)"
:offset="[-4, -4]" :offset="[-4, -4]"
@@ -174,7 +173,7 @@ export default {
} }
const next = [...this.patientList]; const next = [...this.patientList];
next.splice(idx, 1, copy); next.splice(idx, 1, copy);
this.patientList = this.sortPatientList(next); this.patientList = this.mapPatientRows(this.sortPatientList(next));
}, },
unwrap(res) { unwrap(res) {
if (res == null) return null; if (res == null) return null;
@@ -182,11 +181,17 @@ export default {
if (res.data && res.data.result !== undefined) return res.data.result; if (res.data && res.data.result !== undefined) return res.data.result;
return res; return res;
}, },
rowKey(row, idx) { mapPatientRows(rows) {
return (rows || []).map((row, idx) => {
const room = row.room_id != null && row.room_id !== '' ? String(row.room_id) : 'r0'; const room = row.room_id != null && row.room_id !== '' ? String(row.room_id) : 'r0';
const reg = row.register_id != null ? row.register_id : row.id; const reg = row.register_id != null ? row.register_id : row.id;
const ord = row.order_no != null && row.order_no !== '' ? String(row.order_no) : ''; const ord = row.order_no != null && row.order_no !== '' ? String(row.order_no) : '';
return `${room}-${reg != null ? reg : 'x'}-${ord}-${idx}`; const ub = Number(row.unread_count || 0);
return {
...row,
_wxKey: `${room}-${reg != null ? reg : 'x'}-${ord}-${ub}`,
};
});
}, },
lastMessageSortTs(row) { lastMessageSortTs(row) {
const t = row.last_message_time || row.updated_at || row.register_time; const t = row.last_message_time || row.updated_at || row.register_time;
@@ -276,7 +281,7 @@ export default {
const res = await getOnlineConsultationPatientListApi({ type: this.listType }); const res = await getOnlineConsultationPatientListApi({ type: this.listType });
const raw = this.unwrap(res); const raw = this.unwrap(res);
const arr = Array.isArray(raw) ? raw : []; const arr = Array.isArray(raw) ? raw : [];
this.patientList = this.sortPatientList(arr); this.patientList = this.mapPatientRows(this.sortPatientList(arr));
} catch (e) { } catch (e) {
console.error(e); console.error(e);
this.patientList = []; this.patientList = [];

View File

@@ -135,13 +135,15 @@
</block> </block>
<block v-if="lists.prescription_type==2"> <block v-if="lists.prescription_type==2||lists.prescription_type==5||lists.prescription_type==7">
<view class="item" v-for="(it,index) in infoList.repice" :key="item.id"> <view class="item" v-for="(it,index) in infoList.repice" :key="it.id || index">
<!-- v-for="(it,index) in item.content" :key="it.id" --> <!-- v-for="(it,index) in item.content" :key="it.id" -->
<view class="name" style="justify-content: space-between;"> <view class="name" style="justify-content: space-between;">
<view class="yp_name"> <view class="yp_name">
<text>{{ it.content.drug_name}} </text> <text>{{ (it.content && it.content.drug_name) || '' }} </text>
<text style="font-size: 24rpx;margin-left: 10rpx;">{{ it.content.specification }}</text> <text
v-if="it.content && it.content.specification"
class="drug-spec">{{ it.content.specification }}</text>
</view> </view>
<text>x{{ it.number}}</text> <text>x{{ it.number}}</text>
</view> </view>
@@ -347,6 +349,25 @@
}) })
return num return num
}, },
normalizeRepice(list) {
return (list || []).map((it) => {
let content = it.content
if (typeof content === 'string') {
try {
content = JSON.parse(content || '{}')
} catch (e) {
content = {}
}
}
if (!content || typeof content !== 'object' || Array.isArray(content)) {
content = Array.isArray(content) ? content : {}
}
return {
...it,
content,
}
})
},
getInfo() { getInfo() {
prescripRecordDetail({ prescripRecordDetail({
store_id: uni.getStorageSync('store_id') || '11001', store_id: uni.getStorageSync('store_id') || '11001',
@@ -355,12 +376,9 @@
// console.log(res, 'deta'); // console.log(res, 'deta');
if (res.errcode == 0) { if (res.errcode == 0) {
// this.infoList = res.data.prescript const content = res.data.content
// this.time = res.data.issue_date content.repice = this.normalizeRepice(content.repice)
// this.rpList = res.data.recipe this.infoList = content
// this.price = res.data.total_price
this.infoList = res.data.content
this.rpList = res.data.pharmacistInfo this.rpList = res.data.pharmacistInfo
this.lists = res.data this.lists = res.data
// console.log(this.infoList, 'info'); // console.log(this.infoList, 'info');
@@ -644,6 +662,12 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.drug-spec {
font-size: 24rpx;
color: #999;
margin-left: 10rpx;
}
} }
.details { .details {

View File

@@ -207,6 +207,7 @@
infoEdit, infoEdit,
toUploaded toUploaded
} from "@/api/all.js"; } from "@/api/all.js";
import { chooseAvatarImage } from '@/common/js/select-avatar-image.js';
export default { export default {
data() { data() {
return { return {
@@ -377,112 +378,50 @@
}, },
selectActed(){ selectActed(){
uni.chooseImage({ chooseAvatarImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'],
success: (res) => {
uni.showLoading({
title: '请稍后...'
})
const tempFiles = res.tempFiles;
let resSize = tempFiles[0].size;
// 1M=1024KB=1048576B
console.log(resSize)
if (resSize > 1048576) {
uni.showToast({
title: "上传图片大小不能超过1MB",
icon: 'error'
});
return
}
uni.uploadFile({
url: 'https://api.xiaokang88.com/open-api/upload/old-admin-img',
filePath: res.tempFiles[0]['path'],
name: 'file',
header: {
authorization: `Bearer ${uni.getStorageSync('token')}`
},
formData: { formData: {
store_id: uni.getStorageSync('store_id') || '11001' store_id: uni.getStorageSync('store_id') || '11001',
}, },
success: res => { onSuccess: (res) => {
let req = this.$u.test.jsonString(res.data) ? JSON.parse(res const req = this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
.data) : res.data
// console.log(req, 'req')
if (req.errcode == 0) { if (req.errcode == 0) {
toUploaded({ toUploaded({
store_id: uni.getStorageSync('store_id') || store_id: uni.getStorageSync('store_id') || '11001',
'11001', avatar: req.data.url,
avatar: req.data.url }).then((uploadRes) => {
}).then((res) => { if (uploadRes.errcode == 0) {
if (res.errcode == 0) { this.getInfo();
this.getInfo()
this.$toast('编辑成功'); this.$toast('编辑成功');
} }
}) });
uni.hideLoading()
} else { } else {
this.$toast(res.msg); this.$toast(res.msg);
} }
} },
});
}
}); });
}, },
selectAct() { selectAct() {
uni.chooseImage({ chooseAvatarImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'],
success: (res) => {
uni.showLoading({
title: '请稍后...'
})
const tempFiles = res.tempFiles;
let resSize = tempFiles[0].size;
// 1M=1024KB=1048576B
console.log(resSize)
if (resSize > 1048576) {
uni.showToast({
title: "上传图片大小不能超过1MB",
icon: 'error'
});
return
}
uni.uploadFile({
url: 'https://api.xiaokang88.com/open-api/upload/old-admin-img',
filePath: res.tempFiles[0]['path'],
name: 'file',
header: {
authorization: `Bearer ${uni.getStorageSync('token')}`
},
formData: { formData: {
store_id: uni.getStorageSync('store_id') || '11001' store_id: uni.getStorageSync('store_id') || '11001',
}, },
success: res => { onSuccess: (res) => {
let req = this.$u.test.jsonString(res.data) ? JSON.parse(res const req = this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
.data) : res.data
// console.log(req, 'req')
if (req.errcode == 0) { if (req.errcode == 0) {
toUpload({ toUpload({
store_id: uni.getStorageSync('store_id') || store_id: uni.getStorageSync('store_id') || '11001',
'11001', avatar: req.data.url,
avatar: req.data.url }).then((uploadRes) => {
}).then((res) => { if (uploadRes.errcode == 0) {
if (res.errcode == 0) { this.getDoctor();
this.getDoctor()
this.$toast('编辑成功'); this.$toast('编辑成功');
} }
}) });
uni.hideLoading()
} else { } else {
this.$toast(res.msg); this.$toast(res.msg);
} }
} },
});
}
}); });
}, },
// 保存编辑 // 保存编辑

View File

@@ -32,19 +32,19 @@
<scroll-view class="selected-strip-scroll" scroll-x enable-flex> <scroll-view class="selected-strip-scroll" scroll-x enable-flex>
<view class="selected-strip-inner flex-row"> <view class="selected-strip-inner flex-row">
<view <view
v-for="(sel, six) in selectedDrugs" v-for="sel in selectedDrugs"
:key="'sch-' + six" :key="sel._wxKey"
class="selected-chip flex-row flex-ali-center" class="selected-chip flex-row flex-ali-center"
> >
<view <view
class="selected-chip-main flex-row flex-ali-center" class="selected-chip-main flex-row flex-ali-center"
:data-six="six" :data-wx-key="sel._wxKey"
@click="handleSelectedChipSearch" @click="handleSelectedChipSearch"
> >
<text class="selected-chip-name">{{ sel.drug_name || sel.name || '—' }}</text> <text class="selected-chip-name">{{ sel.drug_name || sel.name || '—' }}</text>
<text class="selected-chip-dose">{{ String(sel.number || 0) }}{{ sel.unit && sel.unit.name ? sel.unit.name : 'g' }}</text> <text class="selected-chip-dose">{{ String(sel.number || 0) }}{{ sel.unit && sel.unit.name ? sel.unit.name : 'g' }}</text>
</view> </view>
<view class="selected-chip-close" :data-six="six" @click.stop="handleSelectedChipRemove"> <view class="selected-chip-close" :data-wx-key="sel._wxKey" @click.stop="handleSelectedChipRemove">
<u-icon name="close" size="22" color="#8A92A3"></u-icon> <u-icon name="close" size="22" color="#8A92A3"></u-icon>
</view> </view>
</view> </view>
@@ -174,6 +174,7 @@
<script> <script>
// 保留所有原有逻辑代码与注释 // 保留所有原有逻辑代码与注释
import { getProductListDoctorReception, getChineseMedicineQuickGramsApi } from '@/api/reception.js'; import { getProductListDoctorReception, getChineseMedicineQuickGramsApi } from '@/api/reception.js';
import { withWxKey } from '@/utils/wxListKey.js';
export default { export default {
name: 'ChineseMedicineModal', name: 'ChineseMedicineModal',
@@ -217,7 +218,7 @@ export default {
value(newVal) { value(newVal) {
this.show = newVal; this.show = newVal;
if (newVal) { if (newVal) {
this.selectedDrugs = JSON.parse(JSON.stringify(this.currentDrugs)); this.selectedDrugs = this.mapSelectedDrugs(JSON.parse(JSON.stringify(this.currentDrugs)));
this.fetchQuickGrams(); this.fetchQuickGrams();
const kw = (this.initialSearchKey || '').trim(); const kw = (this.initialSearchKey || '').trim();
if (kw) { if (kw) {
@@ -261,9 +262,16 @@ export default {
/** /**
* 点击已选 chip用药名搜索列表小程序端勿在 @click 传对象,用 data-six + dataset * 点击已选 chip用药名搜索列表小程序端勿在 @click 传对象,用 data-six + dataset
*/ */
mapSelectedDrugs(list) {
return withWxKey(list || [], 'index_id', 'sch');
},
findSelectedChipIndex(wxKey) {
return this.selectedDrugs.findIndex((s) => s._wxKey === wxKey);
},
handleSelectedChipSearch(e) { handleSelectedChipSearch(e) {
const six = Number(e && e.currentTarget && e.currentTarget.dataset ? e.currentTarget.dataset.six : NaN); const wxKey = e && e.currentTarget && e.currentTarget.dataset && e.currentTarget.dataset.wxKey;
if (Number.isNaN(six)) return; const six = this.findSelectedChipIndex(wxKey);
if (six < 0) return;
const sel = this.selectedDrugs[six]; const sel = this.selectedDrugs[six];
if (!sel) return; if (!sel) return;
const name = String(sel.drug_name || sel.name || '').trim(); const name = String(sel.drug_name || sel.name || '').trim();
@@ -278,8 +286,9 @@ export default {
* 从已选条移除一味(不同步二次确认) * 从已选条移除一味(不同步二次确认)
*/ */
handleSelectedChipRemove(e) { handleSelectedChipRemove(e) {
const six = Number(e && e.currentTarget && e.currentTarget.dataset ? e.currentTarget.dataset.six : NaN); const wxKey = e && e.currentTarget && e.currentTarget.dataset && e.currentTarget.dataset.wxKey;
if (Number.isNaN(six) || six < 0 || six >= this.selectedDrugs.length) return; const six = this.findSelectedChipIndex(wxKey);
if (six < 0 || six >= this.selectedDrugs.length) return;
this.selectedDrugs.splice(six, 1); this.selectedDrugs.splice(six, 1);
this.emitSelect(); this.emitSelect();
const name = (this.searchKey || '').trim(); const name = (this.searchKey || '').trim();
@@ -481,14 +490,18 @@ export default {
} else if (drug.name) { } else if (drug.name) {
drugName = drug.name; drugName = drug.name;
} }
const indexId = drug.id;
const entityId = (drug.drug && drug.drug.id) || drug.id;
const wxKeyBase = indexId != null && indexId !== '' ? String(indexId) : String(entityId || '');
return { return {
index_id: drug.id, index_id: indexId,
id: (drug.drug && drug.drug.id) || drug.id, id: entityId,
drug_name: drugName, drug_name: drugName,
number: drug._quantity, number: drug._quantity,
price: drug.price || 0, price: drug.price || 0,
way_id: (drug.drug && drug.drug.way_id) || drug.way_id || 0, way_id: (drug.drug && drug.drug.way_id) || drug.way_id || 0,
select_number: 1 select_number: 1,
_wxKey: wxKeyBase ? `sch-${wxKeyBase}` : `sch${this.selectedDrugs.length}`,
}; };
}, },

View File

@@ -179,6 +179,7 @@
officeList, officeList,
newChek newChek
} from '../../../../api/all'; } from '../../../../api/all';
import { chooseAvatarImage } from '@/common/js/select-avatar-image.js';
// } from '@/api/all.js' // } from '@/api/all.js'
export default { export default {
@@ -338,58 +339,25 @@
uni.hideLoading() uni.hideLoading()
}, },
selectAct() { selectAct() {
uni.chooseImage({ chooseAvatarImage({
count: 1, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album', 'camera'],
success: (res) => {
uni.showLoading({
title: '请稍后...'
})
const tempFiles = res.tempFiles;
let resSize = tempFiles[0].size;
// 1M=1024KB=1048576B
console.log(resSize)
if (resSize > 1048576) {
uni.showToast({
title: "上传图片大小不能超过1MB",
icon: 'error'
});
return
}
uni.uploadFile({
url: 'https://api.xiaokang88.com/open-api/upload/old-admin-img',
filePath: res.tempFiles[0]['path'],
name: 'file',
header: {
authorization: `Bearer ${uni.getStorageSync('token')}`
},
formData: { formData: {
store_id: '11001' store_id: '11001',
}, },
success: res => { onSuccess: (res) => {
let req = this.$u.test.jsonString(res.data) ? JSON.parse(res const req = this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
.data) : res.data
if (req.errcode == 0) { if (req.errcode == 0) {
this.avatarShow = false this.avatarShow = false;
this.form.avatar = req.data.url this.form.avatar = req.data.url;
uni.hideLoading()
} else { } else {
this.$toast(res.msg) this.$toast(res.msg);
} }
}, },
fail: e => { onCancel: () => {
this.avatarShow = false this.avatarShow = false;
}, },
}); onFail: () => {
this.avatarShow = false;
}, },
complete: (res) => {
if (res.errMsg == "chooseImage:fail cancel") {
this.avatarShow = false
}
}
}); });
}, },
checkboxChange(e, id) { checkboxChange(e, id) {