hn-hlw-app/pages/consult/confirm-drug-popup.vue

173 lines
5.8 KiB
Vue
Raw Normal View History

2026-07-27 11:26:39 +08:00
<template>
<uni-popup ref="popup" type="bottom" :mask-click="false">
<view class="bg-white" :style="elderVarStyle">
<view class="popup-header flex items-center justify-between px-15 py-12">
<view class="popup-title">提示</view>
<uni-icons type="closeempty" :size="elderMode ? 32 : 24" color="#999" @click="close"></uni-icons>
</view>
<view class="px-15 py-12">
<text class="text-base text-dark">您共提交{{ drugs.length }}种药品</text>
<template v-if="list.length">
<text class="text-base text-dark"></text>
<text class="text-base text-primary">{{ list.length }}</text>
<text class="text-base text-dark">种有库存</text>
</template>
<template v-if="lackList.length || noStockList.length">
<text class="text-base text-dark"></text>
<text class="text-base text-primary">{{ lackList.length + noStockList.length }}</text>
<text class="text-base text-dark">种库存不足</text>
</template>
</view>
<scroll-view scroll-y="true" class="popup-content-scroll">
<view class="px-15 py-12">
<view v-if="noStockList.length" class="bg-white rounded mt-12 px-15 py-12">
<view class="text-base text-danger">暂时缺货{{ noStockList.length }}</view>
<view v-for="i in noStockList" :key="i.insurance_code" class="flex py-5">
<!-- <image class="flex-shrink-0 drug-checked-icon" :class="elderClass" src="/static/icons/unchecked.svg">
</image> -->
<view class="flex-grow">
<text class="text-base text-drak">{{ i.name }} x {{ i.quantity }}</text>
<text class="text-base text-gray"> (暂不支持购买)</text>
</view>
</view>
</view>
<view v-if="lackList.length" class="bg-white rounded mt-12 px-15 py-12">
<view class="text-base text-danger">库存不足{{ lackList.length }}</view>
<view v-for="i in lackList" :key="i.insurance_code" class="flex py-5" @click="toggle(i)">
<image class="flex-shrink-0 drug-checked-icon" :class="elderClass"
:src="`/static/icons/${selectMap[i.insurance_code] === i.insurance_code ? 'checked' : 'unchecked'}.svg`">
</image>
<view class="flex-grow">
<text class="text-base text-drak">{{ i.name }} x{{ i.stock }}</text>
<text class="text-base text-gray"> (当前为最大可开数)</text>
</view>
</view>
</view>
<view v-if="list.length" class="bg-white rounded mt-12 px-15 py-12">
<view class="text-base text-success">库存充足{{ list.length }}</view>
<view v-for="i in list" :key="i.insurance_code" class="flex py-5" @click="toggle(i)">
<image class="flex-shrink-0 drug-checked-icon" :class="elderClass"
:src="`/static/icons/${selectMap[i.insurance_code] === i.insurance_code ? 'checked' : 'unchecked'}.svg`">
</image>
<view class="flex-grow">
<view class="text-base text-drak">{{ i.name }} x{{ i.quantity }}</view>
</view>
</view>
</view>
</view>
</scroll-view>
<view class="footer-buttons">
<footer-buttons :showConfirm="hasValidDrugs" cancelText="重新选药" confirmText="提交勾选药品" @cancel="close"
@confirm="confirm" />
</view>
</view>
</uni-popup>
</template>
<script setup>
import { computed, ref, watch } from 'vue';
import useElder from '@/hooks/useElder';
import FooterButtons from '@/components/footer-buttons.vue';
const emits = defineEmits(['close', 'confirm'])
const props = defineProps({
drugs: {
type: Array,
default: () => []
},
visible: {
type: Boolean,
default: false
}
})
const selectMap = ref({});
const popup = ref()
const { elderClass, elderVarStyle, elderMode } = useElder();
const list = computed(() => props.drugs.filter(i => i.stock >= i.quantity))
const noStockList = computed(() => props.drugs.filter(i => i.stock === 0))
const lackList = computed(() => props.drugs.filter(i => i.stock > 0 && i.stock < i.quantity))
const hasValidDrugs = computed(() => list.value.length > 0 || lackList.value.length > 0)
function close() {
emits('close')
}
function confirm() {
const data = props.drugs.map(i => {
if (selectMap.value[i.insurance_code] !== i.insurance_code) return null;
const item = { ...i };
item.quantity = Math.min(i.stock, i.quantity);
return item
}).filter(Boolean);
if (data.length === 0) {
return toast('请勾选药品')
}
emits('confirm', data)
}
function initSelect() {
selectMap.value = {};
props.drugs.forEach(i => {
selectMap.value[i.insurance_code] = i.stock > 0 ? i.insurance_code : '';
});
}
function toggle(med) {
if (selectMap.value[med.insurance_code] === med.insurance_code) {
selectMap.value[med.insurance_code] = '';
} else {
selectMap.value[med.insurance_code] = med.insurance_code;
}
}
watch(() => props.visible, n => {
if (n) {
popup.value && popup.value.open()
initSelect()
} else {
popup.value && popup.value.close()
}
})
</script>
<style lang="scss" scoped>
.popup-header {
border-bottom: 1px solid #eee;
}
.popup-title {
font-size: var(--text-base);
font-weight: bold;
color: #333;
}
.popup-content-scroll {
max-height: 55vh;
background-color: #f5f5f5;
}
.text-base {
font-size: var(--text-base);
line-height: 1.5;
}
.pl-15 {
padding-left: 30rpx;
}
.py-5 {
padding-top: 10rpx;
padding-bottom: 10rpx;
}
.drug-checked-icon {
width: 36rpx;
height: 36rpx;
transform: translateY(2rpx);
@at-root &.caring-mode-active {
width: 54rpx;
height: 54rpx;
transform: translateY(4rpx);
}
}
</style>