hn-hlw-app/pages/consult/confirm-drug-popup.vue
2026-07-27 11:26:39 +08:00

173 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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