344 lines
11 KiB
Vue
344 lines
11 KiB
Vue
|
|
<template>
|
|||
|
|
<uni-popup ref="popup" type="bottom" :mask-click="false">
|
|||
|
|
<scroll-view scroll-y="true" class="popup-wrapper" :class="{ 'popup-wrapper--elder': elderMode }">
|
|||
|
|
<view class="">
|
|||
|
|
<view class="drug" :class="{ 'drug--elder': elderMode }">
|
|||
|
|
<view>
|
|||
|
|
<view class="drug-name" :class="{ 'drug-name--elder': elderMode }">
|
|||
|
|
{{ current.name }}
|
|||
|
|
</view>
|
|||
|
|
<view v-if="drug.medication_proof_desc" class="drug-proof-tip"
|
|||
|
|
:class="{ 'drug-proof-tip--elder': elderMode }">{{ proofTipText }}</view>
|
|||
|
|
<view v-if="drug.specification" class="drug-spec" :class="{ 'drug-spec--elder': elderMode }">药品规格:{{
|
|||
|
|
drug.specification }}</view>
|
|||
|
|
<view v-if="drug.manufacturer" class="drug-spec" :class="{ 'drug-spec--elder': elderMode }">{{
|
|||
|
|
drug.manufacturer }}</view>
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<view class="row" :class="{ 'row--elder': elderMode }">
|
|||
|
|
<view class="label" :class="{ 'label--elder': elderMode }">开药数量</view>
|
|||
|
|
<view class="value">
|
|||
|
|
<input-number-box v-model="current.quantity" :elderMode="elderMode" :style="gtMax ? 'color:red' : ''" />
|
|||
|
|
</view>
|
|||
|
|
<view v-if="current.unit" class="unit" :class="{ 'unit--elder': elderMode }">{{ current.unit }}</view>
|
|||
|
|
</view>
|
|||
|
|
<view v-if="gtMax" class="max-tip" :class="{ 'max-tip--elder': elderMode }">已超过建议开药数量</view>
|
|||
|
|
<picker :value="usageIndex" mode="selector" range-key="name" :range="usageList" @change="usageChange">
|
|||
|
|
<view class="row" :class="{ 'row--elder': elderMode }">
|
|||
|
|
<view class="label" :class="{ 'label--elder': elderMode }">用药方式</view>
|
|||
|
|
<view class="value" :class="{ 'value--elder': elderMode }">{{ current.usageName }} </view>
|
|||
|
|
<uni-icons type="right" :size="elderMode ? 32 : 24"></uni-icons>
|
|||
|
|
</view>
|
|||
|
|
</picker>
|
|||
|
|
<view class="row" :class="{ 'row--elder': elderMode }">
|
|||
|
|
<view class="label" :class="{ 'label--elder': elderMode }">单次剂量</view>
|
|||
|
|
<view class="value">
|
|||
|
|
<input-number-box v-model="current.dosage" :elderMode="elderMode" :minStep="0.01" />
|
|||
|
|
</view>
|
|||
|
|
<view v-if="current.dosage_unit" class="unit" :class="{ 'unit--elder': elderMode }">{{ current.dosage_unit }}
|
|||
|
|
</view>
|
|||
|
|
</view>
|
|||
|
|
<picker :value="frequencyIndex" mode="selector" range-key="name" :range="frequencyList"
|
|||
|
|
@change="frequencyChange">
|
|||
|
|
<view class="row" :class="{ 'row--elder': elderMode }">
|
|||
|
|
<view class="label" :class="{ 'label--elder': elderMode }">用药频率</view>
|
|||
|
|
<view class="value" :class="{ 'value--elder': elderMode }">{{ current.frequencyName }} </view>
|
|||
|
|
<uni-icons type="right" :size="elderMode ? 32 : 24"></uni-icons>
|
|||
|
|
</view>
|
|||
|
|
</picker>
|
|||
|
|
<view class="tips" :class="{ 'tips--elder': elderMode }">
|
|||
|
|
<uni-icons color="red" type="info-filled" :size="elderMode ? 24 : 16"></uni-icons>
|
|||
|
|
<text style="margin-left: 12rpx;" :class="{ 'tips-text--elder': elderMode }">已为您填入药品常规用量,请确认!</text>
|
|||
|
|
</view>
|
|||
|
|
<view style="height: 80rpx;"></view>
|
|||
|
|
</view>
|
|||
|
|
</scroll-view>
|
|||
|
|
<view class="btn-footer" :class="{ 'btn-footer--elder': elderMode }">
|
|||
|
|
<view class="btn" :class="{ 'btn--elder': elderMode }" @click="close">取消</view>
|
|||
|
|
<view class="btn btn--active" :class="{ 'btn--elder': elderMode }" @click="confirm">确定</view>
|
|||
|
|
</view>
|
|||
|
|
</uni-popup>
|
|||
|
|
</template>
|
|||
|
|
<script setup>
|
|||
|
|
import { computed, ref, watch } from 'vue';
|
|||
|
|
import { storeToRefs } from "pinia";
|
|||
|
|
import useDb from '@/store/db';
|
|||
|
|
import { toast, confirm as uniConfirm } from '@/utils/widget';
|
|||
|
|
import inputNumberBox from './input-number-box.vue';
|
|||
|
|
|
|||
|
|
const emits = defineEmits(['close', 'change'])
|
|||
|
|
const props = defineProps({
|
|||
|
|
consultType: { type: String, default: 'onlineConsult' },
|
|||
|
|
drug: { type: Object, default: () => ({}) },
|
|||
|
|
visible: { type: Boolean, default: false },
|
|||
|
|
elderMode: { type: Boolean, default: false },
|
|||
|
|
type: { type: String, default: 'add', validator: (value) => ['add', 'edit'].includes(value) },
|
|||
|
|
})
|
|||
|
|
const { onlineMedicine, storeMedicine } = storeToRefs(useDb());
|
|||
|
|
const proofTipText = '*购买该药品需上传用药证明';
|
|||
|
|
const popup = ref()
|
|||
|
|
const current = ref({})
|
|||
|
|
const usageIndex = ref(0)
|
|||
|
|
const frequencyIndex = ref(0)
|
|||
|
|
const gtMax = computed(() => {
|
|||
|
|
return current.value.quantity > current.value.recommended_quantity && current.value.recommended_quantity > 0
|
|||
|
|
})
|
|||
|
|
const usageList = computed(() => {
|
|||
|
|
return props.consultType === 'onlineMedicinePurchase' ? onlineMedicine.value.usageList : storeMedicine.value.usageList;
|
|||
|
|
})
|
|||
|
|
const frequencyList = computed(() => {
|
|||
|
|
return props.consultType === 'onlineMedicinePurchase' ? onlineMedicine.value.frequencyList : storeMedicine.value.frequencyList;
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
function usageChange(e) {
|
|||
|
|
const index = e.detail.value;
|
|||
|
|
const usage = usageList.value[index];
|
|||
|
|
current.value.usageName = usage ? usage.name : '';
|
|||
|
|
current.value.usageCode = usage ? usage.code : '';
|
|||
|
|
usageIndex.value = index;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function frequencyChange(e) {
|
|||
|
|
const index = e.detail.value;
|
|||
|
|
const frequency = frequencyList.value[index];
|
|||
|
|
current.value.frequencyName = frequency ? frequency.name : '';
|
|||
|
|
current.value.frequencyCode = frequency ? frequency.code : '';
|
|||
|
|
frequencyIndex.value = index;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function close() {
|
|||
|
|
emits('close')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function confirm() {
|
|||
|
|
if (!Number.isInteger(current.value.quantity) || !(current.value.quantity > 0)) {
|
|||
|
|
return toast('请输入正确的开药数量', { mask: false })
|
|||
|
|
}
|
|||
|
|
if (!(usageIndex.value >= 0)) {
|
|||
|
|
return toast('请选择用药方式', { mask: false })
|
|||
|
|
}
|
|||
|
|
if (!validateNumber(current.value.dosage)) {
|
|||
|
|
return toast('请输入正确的单次剂量', { mask: false })
|
|||
|
|
}
|
|||
|
|
if (!(frequencyIndex.value >= 0)) {
|
|||
|
|
return toast('请选择用药频率', { mask: false })
|
|||
|
|
}
|
|||
|
|
// 延迟执行是因为 单次剂量以及数量 手动输入的时候 值改变有延时 手机端可以可以出现 开发工具不行
|
|||
|
|
setTimeout(() => {
|
|||
|
|
const arr = [current.value.usageName, current.value.frequencyName, current.value.dosage ? `每次${current.value.dosage}${current.value.dosage_unit || ''}` : ''].filter(Boolean);
|
|||
|
|
emits('change', { ...current.value, memo: arr.join(',') })
|
|||
|
|
}, 500)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
watch(() => props.visible, (val) => {
|
|||
|
|
if (val) {
|
|||
|
|
popup.value && popup.value.open();
|
|||
|
|
current.value = { ...props.drug };
|
|||
|
|
current.value.quantity = typeof current.value.quantity === 'number' ? current.value.quantity : (typeof current.value.recommended_quantity === 'number' ? current.value.recommended_quantity : 0);
|
|||
|
|
current.value.dosage = typeof current.value.dosage === 'number' ? current.value.dosage : 1;
|
|||
|
|
usageIndex.value = usageList.value.findIndex(item => item.name === (current.value.usageName || current.value.administration_method));
|
|||
|
|
const usage = usageList.value[usageIndex.value];
|
|||
|
|
current.value.usageName = usage ? usage.name : '';
|
|||
|
|
current.value.usageCode = usage ? usage.code : '';
|
|||
|
|
frequencyIndex.value = frequencyList.value.findIndex(item => item.name === (current.value.frequencyName || current.value.freq));
|
|||
|
|
const frequency = frequencyList.value[frequencyIndex.value];
|
|||
|
|
current.value.frequencyName = frequency ? frequency.name : '';
|
|||
|
|
current.value.frequencyCode = frequency ? frequency.code : '';
|
|||
|
|
} else {
|
|||
|
|
popup.value && popup.value.close()
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
function validateNumber(input, type = 'decimal') {
|
|||
|
|
const number = Number(input);
|
|||
|
|
let regex;
|
|||
|
|
|
|||
|
|
// 根据type决定是校验整数还是小数
|
|||
|
|
if (type === 'integer') {
|
|||
|
|
regex = /^[1-9]\d*$/; // 整数,且必须大于0
|
|||
|
|
} else {
|
|||
|
|
// 小数,且小数点前必须有至少一个数字,最多支持两位小数
|
|||
|
|
regex = /^(0(\.\d{1,2})?|[1-9]\d*(\.\d{1,2})?)$/; // 小数,且最多两位小数
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 校验输入是否符合要求
|
|||
|
|
if (regex.test(number)) {
|
|||
|
|
return true;
|
|||
|
|
} else {
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
watch(() => current.value.quantity, (n, o) => {
|
|||
|
|
const isAdd = !(n - 0 > (o || 0));
|
|||
|
|
if (props.visible && n > 0 && current.value.recommended_quantity && isAdd && n > current.value.recommended_quantity) {
|
|||
|
|
uniConfirm('已超过建议开药数量', { showCancel: false })
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
@import '../drug.scss';
|
|||
|
|
|
|||
|
|
.row {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 24rpx 30rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333;
|
|||
|
|
width: 690rpx;
|
|||
|
|
border-top: 1rpx solid #e5e5e5;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.value {
|
|||
|
|
margin-left: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-footer {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 24rpx 30rpx;
|
|||
|
|
background: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn {
|
|||
|
|
width: 300rpx;
|
|||
|
|
height: 60rpx;
|
|||
|
|
font-size: 28rpx;
|
|||
|
|
color: #333;
|
|||
|
|
border: 1px solid #e5e5e5;
|
|||
|
|
text-align: center;
|
|||
|
|
line-height: 60rpx;
|
|||
|
|
border-radius: 16rpx;
|
|||
|
|
|
|||
|
|
@at-root &--active {
|
|||
|
|
border-color: $theme-brown-primary;
|
|||
|
|
background-color: $theme-brown-primary;
|
|||
|
|
color: white
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@at-root &+& {
|
|||
|
|
margin-left: 30rpx;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.popup-wrapper {
|
|||
|
|
max-height: 60vh;
|
|||
|
|
background: white;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tips {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
font-size: 32rpx;
|
|||
|
|
color: red;
|
|||
|
|
padding: 24rpx 30rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.max-tip {
|
|||
|
|
padding: 0 30rpx 24rpx;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
color: red;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.drug-proof-tip {
|
|||
|
|
color: #ff4757;
|
|||
|
|
font-size: 24rpx;
|
|||
|
|
line-height: 36rpx;
|
|||
|
|
margin-top: 8rpx;
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 长辈模式样式 */
|
|||
|
|
.popup-wrapper--elder {
|
|||
|
|
max-height: 70vh; // 增加高度
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.drug--elder {
|
|||
|
|
padding: 36rpx 40rpx; // 增加内边距
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.drug-name--elder {
|
|||
|
|
font-size: 42rpx !important; // 30 * 1.4
|
|||
|
|
font-weight: bold;
|
|||
|
|
line-height: 58rpx; // 增加行高
|
|||
|
|
margin-bottom: 12rpx; // 增加间距
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.drug-spec--elder {
|
|||
|
|
font-size: 36rpx !important; // 28 * 1.29
|
|||
|
|
line-height: 50rpx; // 增加行高
|
|||
|
|
margin-bottom: 8rpx; // 增加间距
|
|||
|
|
font-weight: 500;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.drug-proof-tip--elder {
|
|||
|
|
color: #ff4757;
|
|||
|
|
font-size: 32rpx; // 24 * 1.33
|
|||
|
|
line-height: 48rpx; // 36 * 1.33
|
|||
|
|
margin-top: 12rpx; // 8 * 1.5
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.row--elder {
|
|||
|
|
padding: 36rpx 40rpx; // 24 * 1.5, 30 * 1.33
|
|||
|
|
font-size: 36rpx; // 28 * 1.29
|
|||
|
|
min-height: 100rpx; // 增加最小高度
|
|||
|
|
border-top: 2rpx solid #e5e5e5; // 加粗边框
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.label--elder {
|
|||
|
|
font-size: 36rpx; // 28 * 1.29
|
|||
|
|
font-weight: bold;
|
|||
|
|
width: 36*4rpx; // 确保标签宽度
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.value--elder {
|
|||
|
|
font-size: 36rpx; // 28 * 1.29
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.unit--elder {
|
|||
|
|
font-size: 36rpx; // 28 * 1.29
|
|||
|
|
font-weight: 500;
|
|||
|
|
margin-left: 16rpx;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn-footer--elder {
|
|||
|
|
padding: 36rpx 40rpx; // 增加内边距
|
|||
|
|
gap: 40rpx; // 增加按钮间距
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.btn--elder {
|
|||
|
|
width: 280rpx; // 300 * 0.93
|
|||
|
|
height: 80rpx; // 60 * 1.33
|
|||
|
|
font-size: 36rpx; // 28 * 1.29
|
|||
|
|
line-height: 80rpx;
|
|||
|
|
border-radius: 20rpx; // 16 * 1.25
|
|||
|
|
font-weight: bold;
|
|||
|
|
border: 2rpx solid #e5e5e5; // 加粗边框
|
|||
|
|
|
|||
|
|
&.btn--active {
|
|||
|
|
border: 2rpx solid $theme-brown-primary; // 加粗边框
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tips--elder {
|
|||
|
|
padding: 36rpx 40rpx; // 增加内边距
|
|||
|
|
font-size: 36rpx; // 32 * 1.125
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.tips-text--elder {
|
|||
|
|
font-size: 36rpx !important; // 确保文字大小
|
|||
|
|
font-weight: 500;
|
|||
|
|
margin-left: 16rpx !important; // 调整间距
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.max-tip--elder {
|
|||
|
|
padding: 0 40rpx 36rpx; // 调整内边距
|
|||
|
|
font-size: 32rpx; // 24 * 1.33
|
|||
|
|
font-weight: bold;
|
|||
|
|
}
|
|||
|
|
</style>
|