Files
xk-doctor-wx/subPackages/sub_reception/components/WesternMedicineUsageModal.vue
2026-03-06 13:59:22 +08:00

383 lines
11 KiB
Vue

<template>
<u-popup
v-model="show"
mode="bottom"
:closeable="true"
@close="handleClose"
:safe-area-inset-bottom="true"
:mask-close-able="false"
z-index="10078"
height="80%"
>
<view class="western-usage-modal">
<view class="modal-header">
<d-text text="用法用量" className="fs-32 main-c"></d-text>
</view>
<view class="modal-content">
<view class="drug-info white b-r-8 p-32 m-t-2" v-if="drug">
<view class="info-item">
<d-text text="名称:" className="fs-3 color9"></d-text>
<d-text :text="drug.drug_name" className="fs-3 color0"></d-text>
</view>
<view class="info-item m-t-16">
<d-text text="规格:" className="fs-3 color9"></d-text>
<d-text :text="drug.specification || '--'" className="fs-3 color0"></d-text>
</view>
</view>
<!-- 药品数量 -->
<view class="usage-item white b-r-8 p-32 m-t-2">
<view class="item-label">
<d-text text="药品数量" className="fs-3 main-c"></d-text>
</view>
<view class="item-content">
<u-number-box
v-model="usageData.select_number"
:min="1"
:max="(drug && drug.stock) || 999"
/>
<d-text text="盒" className="fs-3 color9 m-l-16"></d-text>
</view>
</view>
<!-- 用法 -->
<view class="usage-item white b-r-8 p-32 m-t-2">
<view class="item-label">
<d-text text="用法" className="fs-3 main-c"></d-text>
</view>
<view class="item-content">
<picker
mode="selector"
:range="drugUseList.drug_use_type || []"
range-key="name"
:value="usageData.type_id && drugUseList.drug_use_type ? drugUseList.drug_use_type.findIndex(item => item.id === usageData.type_id) : 0"
@change="handleChangeUsageType"
>
<view class="picker-view">
{{ (usageData.use_type && usageData.use_type.name) || '请选择' }}
</view>
</picker>
</view>
</view>
<!-- 频次 -->
<view class="usage-item white b-r-8 p-32 m-t-2">
<view class="item-label">
<d-text text="频次" className="fs-3 main-c"></d-text>
</view>
<view class="item-content">
<picker
mode="selector"
:range="drugUseList.drug_use_frequency || []"
range-key="name"
:value="usageData.frequency_id && drugUseList.drug_use_frequency ? drugUseList.drug_use_frequency.findIndex(item => item.id === usageData.frequency_id) : 0"
@change="handleChangeFrequency"
>
<view class="picker-view">
{{ (usageData.use_frequency && usageData.use_frequency.name) || '请选择' }}
</view>
</picker>
</view>
</view>
<!-- 时间 -->
<view class="usage-item white b-r-8 p-32 m-t-2">
<view class="item-label">
<d-text text="时间" className="fs-3 main-c"></d-text>
</view>
<view class="item-content">
<picker
mode="selector"
:range="drugUseList.drug_time || []"
range-key="name"
:value="usageData.time_id && drugUseList.drug_time ? drugUseList.drug_time.findIndex(item => item.id === usageData.time_id) : 0"
@change="handleChangeTime"
>
<view class="picker-view">
{{ (usageData.use_num && usageData.use_num.name) || '请选择' }}
</view>
</picker>
</view>
</view>
<!-- 单位 -->
<view class="usage-item white b-r-8 p-32 m-t-2">
<view class="item-label">
<d-text text="每次用量" className="fs-3 main-c"></d-text>
</view>
<view class="item-content">
<u-number-box v-model="usageData.number" :min="1" />
<picker
mode="selector"
:range="drugUseList.drug_unit || []"
range-key="name"
:value="usageData.unit_id && drugUseList.drug_unit ? drugUseList.drug_unit.findIndex(item => item.id === usageData.unit_id) : 0"
@change="handleChangeUnit"
>
<view class="picker-view m-l-16">
{{ (usageData.unit && usageData.unit.name) || '请选择' }}
</view>
</picker>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="modal-footer">
<u-button
@click="handleClose"
:custom-style="{ backgroundColor: '#f5f5f5', color: '#333' }"
>取消</u-button>
<u-button
@click="handleConfirm"
:custom-style="{ backgroundColor: '#6ACDBB', color: '#fff' }"
>确定</u-button>
</view>
</view>
</u-popup>
</template>
<script>
import { getDrugUseList, getDrugUseWithDefault } from '@/api/reception.js';
export default {
name: 'ReceptionWesternMedicineUsageModal',
props: {
value: {
type: Boolean,
default: false
},
drug: {
type: Object,
default: null
}
},
data() {
return {
show: false,
usageData: {
select_number: 1,
number: 1,
type_id: 0,
frequency_id: 0,
time_id: 0,
unit_id: 0,
use_type: null,
use_frequency: null,
use_num: null,
unit: null
},
drugUseList: {
drug_use_type: [],
drug_use_frequency: [],
drug_time: [],
drug_unit: []
}
};
},
watch: {
value(newVal) {
this.show = newVal;
if (newVal && this.drug) {
// 打开时直接加载列表和默认值,避免默认值被初始化覆盖
this.loadDrugUseList();
}
},
show(newVal) {
if (!newVal) {
this.$emit('input', false);
}
}
},
methods: {
initUsageData() {
if (this.drug) {
this.usageData = {
select_number: this.drug.select_number || this.drug.number || 1,
number: this.drug.number || 1,
type_id: this.drug.type_id || 0,
frequency_id: this.drug.frequency_id || 0,
time_id: this.drug.time_id || 0,
unit_id: this.drug.unit_id || 0,
use_type: this.drug.use_type || null,
use_frequency: this.drug.use_frequency || null,
use_num: this.drug.use_num || null,
unit: this.drug.unit || null
};
}
},
async loadDrugUseList() {
try {
const drugId = this.drug && (this.drug.drug_id || this.drug.id);
let payload = null;
if (drugId) {
const res = await getDrugUseWithDefault(drugId);
if (res) {
payload = res.data || res.result || res;
}
} else {
const res = await getDrugUseList();
if (res) {
payload = res.data || res.result || res;
}
}
if (!payload) {
this.drugUseList = { drug_use_type: [], drug_use_frequency: [], drug_time: [], drug_unit: [] };
this.$toast('暂无用法用量配置,请联系管理员');
return;
}
const lists = payload.lists || payload;
const def = payload.default || {};
this.drugUseList = lists;
if (!this.usageData.type_id && def.type_id && lists.drug_use_type) {
this.usageData.type_id = def.type_id;
this.usageData.use_type = (lists.drug_use_type || []).find(i => i.id === def.type_id) || null;
}
if (!this.usageData.frequency_id && def.frequency_id && lists.drug_use_frequency) {
this.usageData.frequency_id = def.frequency_id;
this.usageData.use_frequency = (lists.drug_use_frequency || []).find(i => i.id === def.frequency_id) || null;
}
if (!this.usageData.time_id && def.time_id && lists.drug_time) {
this.usageData.time_id = def.time_id;
this.usageData.use_num = (lists.drug_time || []).find(i => i.id === def.time_id) || null;
}
if (!this.usageData.unit_id && def.unit_id && lists.drug_unit) {
this.usageData.unit_id = def.unit_id;
this.usageData.unit = (lists.drug_unit || []).find(i => i.id === def.unit_id) || null;
}
const hasOptions =
(lists.drug_use_type || []).length ||
(lists.drug_use_frequency || []).length ||
(lists.drug_time || []).length ||
(lists.drug_unit || []).length;
if (!hasOptions) {
this.$toast('暂无用法用量配置,请联系管理员');
}
} catch (error) {
console.error('获取药品使用方式列表失败:', error);
this.$toast('获取用法用量失败');
}
},
handleChangeUsageType(e) {
const index = parseInt(e.detail.value);
const item = this.drugUseList.drug_use_type[index];
if (item) {
this.usageData.type_id = item.id;
this.usageData.use_type = item;
}
},
handleChangeFrequency(e) {
const index = parseInt(e.detail.value);
const item = this.drugUseList.drug_use_frequency[index];
if (item) {
this.usageData.frequency_id = item.id;
this.usageData.use_frequency = item;
}
},
handleChangeTime(e) {
const index = parseInt(e.detail.value);
const item = this.drugUseList.drug_time[index];
if (item) {
this.usageData.time_id = item.id;
this.usageData.use_num = item;
}
},
handleChangeUnit(e) {
const index = parseInt(e.detail.value);
const item = this.drugUseList.drug_unit[index];
if (item) {
this.usageData.unit_id = item.id;
this.usageData.unit = item;
}
},
handleClose() {
this.show = false;
},
handleConfirm() {
this.$emit('confirm', this.usageData);
this.handleClose();
}
}
};
</script>
<style lang="scss" scoped>
.western-usage-modal {
display: flex;
flex-direction: column;
height: 100%;
}
.modal-header {
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.modal-content {
flex: 1;
overflow-y: auto;
padding: 0 32rpx 32rpx;
}
.drug-info {
.info-item {
display: flex;
flex-direction: row;
align-items: center;
d-text + d-text {
margin-left: 8rpx;
}
}
}
.usage-item {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 24rpx;
.item-label {
width: 160rpx;
}
.item-content {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}
}
.picker-view {
min-width: 160rpx;
padding: 12rpx 16rpx;
border-radius: 9999rpx;
background-color: #f5f5f5;
text-align: center;
font-size: 26rpx;
color: #333;
}
.modal-footer {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 24rpx 32rpx;
border-top: 1rpx solid #f0f0f0;
.u-button {
flex: 1;
margin: 0 8rpx;
}
}
</style>