多药房配置
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取药房分页列表
|
||||
* @param {Object} data - 查询参数及分页参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getPharmacyPage(data) {
|
||||
return request({
|
||||
url: '/admin/basic/pharmacy/page',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药房列表(下拉选择框)
|
||||
* @param {Object} params - 过滤条件
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getPharmacyList(params) {
|
||||
return request({
|
||||
url: '/admin/basic/pharmacy/list',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药房详情
|
||||
* @param {String} pharmacy_id - 药房 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getPharmacyDetail(pharmacy_id) {
|
||||
return request({
|
||||
url: `/admin/basic/pharmacy/${pharmacy_id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增药房
|
||||
* @param {Object} data - 药房实体参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addPharmacy(data) {
|
||||
return request({
|
||||
url: '/admin/basic/pharmacy',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改药房
|
||||
* @param {String} pharmacy_id - 药房 ID
|
||||
* @param {Object} data - 药房实体参数
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updatePharmacy(pharmacy_id, data) {
|
||||
return request({
|
||||
url: `/admin/basic/pharmacy/${pharmacy_id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换药房状态(快捷开关)
|
||||
* @param {String} pharmacy_id - 药房 ID
|
||||
* @param {Number} status - 0: 禁用, 1: 正常
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function updatePharmacyStatus(pharmacy_id, status) {
|
||||
return request({
|
||||
url: `/admin/basic/pharmacy/status/${pharmacy_id}`,
|
||||
method: 'put',
|
||||
data: { status },
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除药房(软删除)
|
||||
* @param {String} pharmacy_id - 药房 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function deletePharmacy(pharmacy_id) {
|
||||
return request({
|
||||
url: `/admin/basic/pharmacy/${pharmacy_id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药房绑定的医生列表-分页
|
||||
* @param {Object} data - { pharmacy_id: string, page?: number, page_size?: number, doctor_name?: string, mobile?: string }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getPharmacyDoctorPage(data) {
|
||||
return request({
|
||||
url: '/admin/basic/pharmacy/doctor/page',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药房绑定的医生列表(全部/不分页)
|
||||
* @param {String} pharmacy_id - 药房 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getPharmacyDoctorList(pharmacy_id) {
|
||||
return request({
|
||||
url: `/admin/basic/pharmacy/doctor/${pharmacy_id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出药房关联医生列表
|
||||
* @param {Object} data - 请求参数
|
||||
* @param {1|2|3} data.type - 1:当前筛选导出, 2:选中的数据导出, 3:全部导出
|
||||
* @param {string} [data.pharmacy_id] - 药房 ID
|
||||
* @param {string} [data.doctor_name] - 医生姓名
|
||||
* @param {string} [data.mobile] - 医生手机号
|
||||
* @param {string} [data.id] - 选中的数据 ID,多条用英文逗号分隔
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function exportPharmacyDoctor(data) {
|
||||
return request({
|
||||
url: '/admin/export/pharmacy/doctor',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药房下线受影响医生列表(预检接口)
|
||||
* @param {String|Number} pharmacy_id - 药房 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getAffectedDoctors(pharmacy_id) {
|
||||
return request({
|
||||
url: `/admin/pharmacy/affected-doctors/${pharmacy_id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量迁移默认药房并执行下线操作
|
||||
* @param {Object} data - { source_pharmacy_id, action: 'disable'|'delete', unbind_source: 1|0, transfers: Array<{ doctor_id, target_pharmacy_id }> }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function batchTransferAndAction(data) {
|
||||
return request({
|
||||
url: '/admin/pharmacy/batch-transfer-and-action',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 1. 获取医生绑定的药房列表
|
||||
* @param {String} doctor_id - 医生 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getDoctorPharmacyList(doctor_id) {
|
||||
return request({
|
||||
url: `/admin/doctor/pharmacy/${doctor_id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 2. 批量设置医生绑定的药房列表(全量覆盖)
|
||||
* @param {String} doctor_id - 医生 ID
|
||||
* @param {Object} data - { pharmacy_ids: string[], default_pharmacy_id?: string }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setDoctorPharmacies(doctor_id, data) {
|
||||
return request({
|
||||
url: `/admin/doctor/pharmacy/${doctor_id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 3. 为医生新增单个药房绑定
|
||||
* @param {Object} data - { doctor_id: string, pharmacy_id: string, is_default?: number }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function addDoctorPharmacy(data) {
|
||||
return request({
|
||||
url: '/admin/doctor/pharmacy',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 4. 解除单个药房绑定 (DELETE 方式,传入绑定记录 ID)
|
||||
* @param {String} doctor_pharmacy_id - 绑定记录 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function removeDoctorPharmacy(doctor_pharmacy_id) {
|
||||
return request({
|
||||
url: `/admin/doctor/pharmacy/${doctor_pharmacy_id}`,
|
||||
method: 'delete',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 4.1 快捷解除绑定 (POST 方式,Body 传参)
|
||||
* @param {Object} data - { doctor_pharmacy_id?: string, doctor_id?: string, pharmacy_id?: string }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function unbindDoctorPharmacy(data) {
|
||||
return request({
|
||||
url: '/admin/doctor/pharmacy/unbind',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 5. 设为医生的默认药房 (PUT 方式,传入绑定记录 ID)
|
||||
* @param {String} doctor_pharmacy_id - 绑定记录 ID
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setDefaultDoctorPharmacy(doctor_pharmacy_id) {
|
||||
return request({
|
||||
url: `/admin/doctor/pharmacy/default/${doctor_pharmacy_id}`,
|
||||
method: 'put',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 5.1 快捷设为默认药房 (PUT 方式,Body 传参)
|
||||
* @param {Object} data - { doctor_pharmacy_id?: string, doctor_id?: string, pharmacy_id?: string }
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setDefaultDoctorPharmacyByBody(data) {
|
||||
return request({
|
||||
url: '/admin/doctor/pharmacy/default',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
@@ -151,11 +151,37 @@
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">是否推荐</div>
|
||||
</div>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">绑定药房</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px;">
|
||||
<a-col :span="24">
|
||||
<a-form-item field="doctor_pharmacy" label="关联药房:">
|
||||
<div style="width: 100%">
|
||||
<a-space wrap v-if="modalForm.doctor_pharmacy_list && modalForm.doctor_pharmacy_list.length > 0">
|
||||
<a-tag
|
||||
v-for="item in modalForm.doctor_pharmacy_list"
|
||||
:key="item.pharmacy_id"
|
||||
:color="item.is_default === 1 ? 'arcoblue' : 'gray'"
|
||||
size="medium"
|
||||
>
|
||||
<template #icon v-if="item.is_default === 1"><icon-check-circle-fill /></template>
|
||||
{{ item.pharmacy_name }}
|
||||
<span v-if="item.is_default === 1" style="margin-left: 4px; font-weight: bold">(默认)</span>
|
||||
</a-tag>
|
||||
</a-space>
|
||||
<span v-else style="color: #86909c">暂未绑定任何药房</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">是否推荐</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px;">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="is_recommend" label="状态:">
|
||||
@@ -495,6 +521,7 @@ const modalForm = reactive({
|
||||
cur_doctor_expertise: [],
|
||||
avatar: 'https://img.applets.igandanyiyuan.com/basic/file/doctor_avatar.png',
|
||||
bank_card_code: '',
|
||||
doctor_pharmacy_list: [],
|
||||
});
|
||||
const hospital_name = ref('');
|
||||
watch(() => modalForm.hospital, () => {
|
||||
@@ -807,6 +834,11 @@ const modalForm = reactive({
|
||||
}
|
||||
modalForm.cur_doctor_expertise = arr;
|
||||
}
|
||||
if (data.doctor_pharmacy && Array.isArray(data.doctor_pharmacy)) {
|
||||
modalForm.doctor_pharmacy_list = data.doctor_pharmacy;
|
||||
} else {
|
||||
modalForm.doctor_pharmacy_list = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
const departmentData = ref([]);
|
||||
|
||||
@@ -51,24 +51,35 @@
|
||||
</a-row>
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item field="avatar" label="药店编码:">
|
||||
<span>{{modalForm.product_pharmacy_code
|
||||
}} </span>
|
||||
<a-form-item label="所属药房:">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
<span v-if="modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code" style="color: #86909c; margin-left: 8px">
|
||||
({{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code }})
|
||||
</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="第三方药品编码:">
|
||||
<span>{{ modalForm.product_pharmacy_code || modalForm.pharmacy?.product_pharmacy_code || '-' }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药店编码:">
|
||||
<span>{{ modalForm.pharmacy_code || '-' }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="处方平台编码:" >
|
||||
<div class="cardNum">{{modalForm.product_platform_code
|
||||
}}</div>
|
||||
<div class="cardNum">{{ modalForm.product_platform_code || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" >
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item field="avatar" label="创建时间:">
|
||||
<span>{{modalForm.created_at
|
||||
}} </span>
|
||||
<span>{{ modalForm.created_at || '-' }}</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
@@ -80,6 +80,37 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">发货药房信息</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房名称:">
|
||||
<div class="box">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房代码:">
|
||||
<div class="box">{{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="联系电话:">
|
||||
<div class="box">{{ modalForm.pharmacy?.telephone || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房地址:">
|
||||
<div class="box">{{ modalForm.pharmacy?.full_address || modalForm.pharmacy?.address || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox" v-if="modalForm.order_product_refund">
|
||||
<div class="bar"></div>
|
||||
<div class="name">退款信息</div>
|
||||
|
||||
@@ -91,6 +91,37 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">发货药房信息</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房名称:">
|
||||
<div class="box">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房代码:">
|
||||
<div class="box">{{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="联系电话:">
|
||||
<div class="box">{{ modalForm.pharmacy?.telephone || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房地址:">
|
||||
<div class="box">{{ modalForm.pharmacy?.full_address || modalForm.pharmacy?.address || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox" v-if="modalForm.order_product_refund">
|
||||
<div class="bar"></div>
|
||||
<div class="name">退款信息</div>
|
||||
|
||||
@@ -67,14 +67,45 @@
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="医嘱:" >
|
||||
<div class="box" >{{ modalForm.doctor_advice }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="医嘱:" >
|
||||
<div class="box" >{{ modalForm.doctor_advice }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">药房信息</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px;">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房名称:">
|
||||
<div class="box">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房代码:">
|
||||
<div class="box">{{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="联系电话:">
|
||||
<div class="box">{{ modalForm.pharmacy?.telephone || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房地址:">
|
||||
<div class="box">{{ modalForm.pharmacy?.full_address || modalForm.pharmacy?.address || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox" v-if="modalForm.inquiry_doctor && !modalForm.transfer_prescription_doctor">
|
||||
<div class="bar"></div>
|
||||
<div class="name">医生信息</div>
|
||||
|
||||
@@ -67,14 +67,45 @@
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="医嘱:" >
|
||||
<div class="box" >{{ modalForm.doctor_advice }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="医嘱:" >
|
||||
<div class="box" >{{ modalForm.doctor_advice }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">药房信息</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px;">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房名称:">
|
||||
<div class="box">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房代码:">
|
||||
<div class="box">{{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="联系电话:">
|
||||
<div class="box">{{ modalForm.pharmacy?.telephone || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房地址:">
|
||||
<div class="box">{{ modalForm.pharmacy?.full_address || modalForm.pharmacy?.address || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox" v-if="modalForm.inquiry_doctor && showTransferDoctor ">
|
||||
<div class="bar"></div>
|
||||
<div class="name">医生信息</div>
|
||||
|
||||
@@ -13,20 +13,55 @@
|
||||
<a-select :style="{width:'300px'}" allow-search placeholder="请选择药品名称" v-model="modalForm.product_name"
|
||||
:loading="loading" @change="changeMedince" @search="handList" :disabled="modalSatus=='edit'">
|
||||
<a-option size="large" style="max-width:400px" v-for="item in medinceList" :key="item.product_platform_id"
|
||||
:value="item.product_platform_id" :label="item.product_name+'('+item.product_platform_code+')'">
|
||||
{{item.product_name+'('+item.product_platform_code+')' }}
|
||||
:value="item.product_platform_id" :label="item.product_name + (item.pharmacy_name || item.pharmacy?.pharmacy_name ? ' [' + (item.pharmacy_name || item.pharmacy?.pharmacy_name) + ']' : '') + '(' + item.product_platform_code + ')'">
|
||||
<span>{{ item.product_name }}</span>
|
||||
<span v-if="item.pharmacy_name || item.pharmacy?.pharmacy_name" style="color: #165dff; margin-left: 6px;">[{{ item.pharmacy_name || item.pharmacy?.pharmacy_name }}]</span>
|
||||
<span style="color: #86909c; margin-left: 4px;">({{ item.product_platform_code }})</span>
|
||||
</a-option>
|
||||
</a-select>
|
||||
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="pharmacy_id" label="所属药房:">
|
||||
<a-select
|
||||
v-if="modalSatus == 'add'"
|
||||
v-model="modalForm.pharmacy_id"
|
||||
placeholder="选择药品后自动匹配药房"
|
||||
disabled
|
||||
:style="{ width: '300px' }"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in pharmacyList"
|
||||
:key="item.pharmacy_id"
|
||||
:value="String(item.pharmacy_id)"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }} ({{ item.pharmacy_code }})
|
||||
</a-option>
|
||||
</a-select>
|
||||
<div v-else class="box">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
<span v-if="modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code" style="color: #86909c; margin-left: 8px">
|
||||
({{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code }})
|
||||
</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="avatar" label="药品规格:">
|
||||
<span v-if="modalForm.product_spec">{{modalForm.product_spec}} </span>
|
||||
<span v-else>选择药品后展示</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
|
||||
<a-col :span="12">
|
||||
<a-form-item field="avatar" label="生产厂家:">
|
||||
<span v-if="modalForm.manufacturer">{{modalForm.manufacturer}} </span>
|
||||
<span v-else>选择药品后展示</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
@@ -44,33 +79,6 @@
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<!--<a-row :gutter="24" >
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="药品价格:" >
|
||||
<div class="cardNum">{{modalForm.product_price}}元</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="idCard" label="药品类型:" >
|
||||
<div class="box" >
|
||||
<div class="cardNum">{{formatProductType(modalForm.product_type)}}</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row> -->
|
||||
<a-row :gutter="24" >
|
||||
<!-- <a-col :span="12">
|
||||
<a-form-item field="idCard" label="批准文号:" >
|
||||
<div class="cardNum">{{modalForm.license_number}}</div>
|
||||
</a-form-item>
|
||||
</a-col> -->
|
||||
<a-col :span="12">
|
||||
<a-form-item field="avatar" label="生产厂家:">
|
||||
<span v-if="modalForm.manufacturer">{{modalForm.manufacturer}} </span>
|
||||
<span v-else>选择药品后展示</span>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<!-- <a-row :gutter="24" >
|
||||
|
||||
@@ -233,9 +241,10 @@
|
||||
</a-modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import {ref,toRefs} from 'vue';
|
||||
import {addSysMedince,editSysMedince,editMedinceStatus,getList,getMedinceDetail} from "@/api/medince/list";
|
||||
import {formatProductType} from "@/utils/format"
|
||||
import { ref, toRefs, onMounted, watch } from 'vue';
|
||||
import { addSysMedince, editSysMedince, editMedinceStatus, getList, getMedinceDetail } from "@/api/medince/list";
|
||||
import { getPharmacyList } from "@/api/basic/pharmacy";
|
||||
import { formatProductType } from "@/utils/format"
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
const props = defineProps({
|
||||
// 是否显示
|
||||
@@ -253,9 +262,75 @@ const props = defineProps({
|
||||
type: Object,
|
||||
},
|
||||
});
|
||||
const medinceList=ref([]);
|
||||
const medinceList = ref([]);
|
||||
const pharmacyList = ref([]);
|
||||
const loading = ref(false);
|
||||
const rules={
|
||||
|
||||
// 自动匹配并设置所属药房
|
||||
const matchAndSetPharmacy = (target = {}) => {
|
||||
if (!target) return;
|
||||
const pid = target.pharmacy_id ?? target.pharmacy?.pharmacy_id;
|
||||
const pcode = target.pharmacy_code ?? target.pharmacy?.pharmacy_code;
|
||||
const pname = target.pharmacy_name ?? target.pharmacy?.pharmacy_name;
|
||||
|
||||
let matched = null;
|
||||
if (pid !== undefined && pid !== null && pid !== '') {
|
||||
matched = pharmacyList.value.find((p) => String(p.pharmacy_id) === String(pid));
|
||||
}
|
||||
if (!matched && pcode) {
|
||||
const codeStr = String(pcode).trim().toLowerCase();
|
||||
matched = pharmacyList.value.find(
|
||||
(p) => p.pharmacy_code && String(p.pharmacy_code).trim().toLowerCase() === codeStr
|
||||
);
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
modalForm.value.pharmacy_id = String(matched.pharmacy_id);
|
||||
modalForm.value.pharmacy_name = matched.pharmacy_name;
|
||||
modalForm.value.pharmacy_code = matched.pharmacy_code;
|
||||
} else if (pid !== undefined && pid !== null && pid !== '') {
|
||||
modalForm.value.pharmacy_id = String(pid);
|
||||
modalForm.value.pharmacy_name = pname || '';
|
||||
modalForm.value.pharmacy_code = pcode || '';
|
||||
if (!pharmacyList.value.some((p) => String(p.pharmacy_id) === String(pid))) {
|
||||
pharmacyList.value.push({
|
||||
pharmacy_id: String(pid),
|
||||
pharmacy_name: modalForm.value.pharmacy_name || '-',
|
||||
pharmacy_code: modalForm.value.pharmacy_code || '',
|
||||
});
|
||||
}
|
||||
} else if (pcode) {
|
||||
modalForm.value.pharmacy_code = pcode;
|
||||
if (pname) modalForm.value.pharmacy_name = pname;
|
||||
}
|
||||
};
|
||||
|
||||
const fetchPharmacyList = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList();
|
||||
if (res.code === 200) {
|
||||
pharmacyList.value = res.data || [];
|
||||
if (modalForm.value && (modalForm.value.pharmacy_id || modalForm.value.pharmacy_code)) {
|
||||
matchAndSetPharmacy(modalForm.value);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取药房列表异常:', e);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchPharmacyList();
|
||||
});
|
||||
|
||||
watch(() => props.modalVisible, (val) => {
|
||||
if (val && pharmacyList.value.length === 0) {
|
||||
fetchPharmacyList();
|
||||
}
|
||||
});
|
||||
|
||||
const rules = {
|
||||
pharmacy_id: [{ required: true, message: '请先选择药品以匹配所属药房' }],
|
||||
product_platform_id: [{ required: true, message: '请输入药品名称' }],
|
||||
product_price: [{ required: true, message: '请输入药品价格' }],
|
||||
product_platform_code: [{ required: true, message: '请输入处方平台编码' }],
|
||||
@@ -276,18 +351,22 @@ const {modalVisible,modalForm,modalSatus} = toRefs(props);
|
||||
const handleClose = () => {
|
||||
emits('familyVisibleChange', false);
|
||||
};
|
||||
const handAdd=async()=>{
|
||||
const handAdd = async () => {
|
||||
if (!modalForm.value.pharmacy_id) {
|
||||
Message.warning('所属药房不能为空,请先选择药品以匹配药房');
|
||||
return;
|
||||
}
|
||||
delete modalForm.value.avatar;
|
||||
delete modalForm.value.product_id
|
||||
modalForm.value.product_status=1;
|
||||
delete modalForm.value.product_id;
|
||||
modalForm.value.product_status = 1;
|
||||
|
||||
const {code}=await addSysMedince(modalForm.value);
|
||||
if(code==200){
|
||||
const { code } = await addSysMedince(modalForm.value);
|
||||
if (code == 200) {
|
||||
Message.success("添加成功");
|
||||
handleClose(true);
|
||||
emits('freshList');
|
||||
}
|
||||
}
|
||||
};
|
||||
const handEdit=async()=>{
|
||||
const {code}=await editSysMedince(modalForm.value.product_id,modalForm.value);
|
||||
if(code==200){
|
||||
@@ -312,14 +391,14 @@ const handleEditStatus=async(status)=>{
|
||||
const { code, data, message } = await getMedinceDetail(product_platform_id);
|
||||
|
||||
if (code == 200) {
|
||||
|
||||
Object.assign(modalForm.value,data);
|
||||
modalForm.value.stock=data.stock;
|
||||
Object.assign(modalForm.value, data);
|
||||
modalForm.value.stock = data.stock;
|
||||
matchAndSetPharmacy(data);
|
||||
}
|
||||
};
|
||||
const handList= async(value)=>{
|
||||
loading.value=true;
|
||||
console.log(value)
|
||||
console.log(value)
|
||||
const {code,data}=await getList({
|
||||
product_name: value,
|
||||
});
|
||||
@@ -329,12 +408,24 @@ const handList= async(value)=>{
|
||||
}
|
||||
}
|
||||
const changeMedince = (value) => {
|
||||
if (!value) {
|
||||
modalForm.value.product_platform_id = '';
|
||||
modalForm.value.pharmacy_id = '';
|
||||
modalForm.value.pharmacy_name = '';
|
||||
modalForm.value.pharmacy_code = '';
|
||||
modalForm.value.product_spec = '';
|
||||
modalForm.value.product_pharmacy_code = '';
|
||||
modalForm.value.manufacturer = '';
|
||||
return;
|
||||
}
|
||||
let arr = medinceList.value.filter((item) => item.product_platform_id == value);
|
||||
if (!arr.length) return;
|
||||
modalForm.value.product_platform_id = arr[0].product_platform_id;
|
||||
console.log(arr[0]);
|
||||
modalForm.value.product_spec=arr[0].product_spec;
|
||||
modalForm.value.product_pharmacy_code=arr[0].product_pharmacy_code;
|
||||
modalForm.value.manufacturer=arr[0].manufacturer;
|
||||
modalForm.value.product_spec = arr[0].product_spec;
|
||||
modalForm.value.product_pharmacy_code = arr[0].product_pharmacy_code;
|
||||
modalForm.value.manufacturer = arr[0].manufacturer;
|
||||
matchAndSetPharmacy(arr[0]);
|
||||
handleDetail(arr[0].product_platform_id);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,521 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="visible"
|
||||
:title="drawerTitle"
|
||||
:width="1080"
|
||||
:footer="false"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<!-- 药房信息摘要卡片 -->
|
||||
<a-card :bordered="false" class="pharmacy-summary-card">
|
||||
<div class="pharmacy-info-box">
|
||||
<div class="pharmacy-icon-box">
|
||||
<icon-home style="font-size: 28px; color: #165dff" />
|
||||
</div>
|
||||
<div class="pharmacy-meta">
|
||||
<div class="pharmacy-meta-title">
|
||||
<span class="name">{{ currentPharmacy?.pharmacy_name || '-' }}</span>
|
||||
<a-tag color="blue" size="small" style="margin-left: 8px">
|
||||
{{ currentPharmacy?.pharmacy_code || '-' }}
|
||||
</a-tag>
|
||||
<a-tag v-if="currentPharmacy?.status === 1" color="green" size="small" style="margin-left: 4px">
|
||||
运营中
|
||||
</a-tag>
|
||||
<a-tag v-else color="red" size="small" style="margin-left: 4px">
|
||||
已停用
|
||||
</a-tag>
|
||||
</div>
|
||||
<div class="pharmacy-meta-desc">
|
||||
<span><strong>基础邮费:</strong>¥{{ Number(currentPharmacy?.postage || 0).toFixed(2) }}</span>
|
||||
<span style="margin-left: 20px">
|
||||
<strong>包邮门槛:</strong>
|
||||
{{ Number(currentPharmacy?.free_shipping_threshold) > 0 ? `¥${Number(currentPharmacy.free_shipping_threshold).toFixed(2)}` : '不设门槛' }}
|
||||
</span>
|
||||
<span style="margin-left: 20px">
|
||||
<strong>支持自提:</strong>{{ currentPharmacy?.is_pickup === 1 ? '是' : '否' }}
|
||||
</span>
|
||||
<span style="margin-left: 20px">
|
||||
<strong>联系电话:</strong>{{ currentPharmacy?.telephone || '-' }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="pharmacy-meta-address">
|
||||
<strong>详细地址:</strong>{{ currentPharmacy?.full_address || currentPharmacy?.address || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<a-divider style="margin: 16px 0" />
|
||||
|
||||
<!-- 筛选表单 -->
|
||||
<a-form :model="queryForm" ref="queryFormRef" layout="inline" class="search-form">
|
||||
<a-form-item field="doctor_name" label="医生姓名">
|
||||
<a-input
|
||||
v-model="queryForm.doctor_name"
|
||||
placeholder="请输入医生姓名"
|
||||
allow-clear
|
||||
style="width: 170px"
|
||||
@press-enter="handleQuery"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="mobile" label="手机号码">
|
||||
<a-input
|
||||
v-model="queryForm.mobile"
|
||||
placeholder="请输入手机号码"
|
||||
allow-clear
|
||||
style="width: 170px"
|
||||
@press-enter="handleQuery"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" size="small" @click="handleQuery">
|
||||
<template #icon><icon-search /></template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button size="small" @click="handleResetQuery">
|
||||
<template #icon><icon-loop /></template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<!-- 工具栏:数据统计与导出操作 -->
|
||||
<div class="table-toolbar">
|
||||
<div class="table-toolbar-left">
|
||||
<span class="table-total-tip">共找到 {{ pager.total }} 位关联医生</span>
|
||||
</div>
|
||||
<div class="table-toolbar-right">
|
||||
<a-dropdown
|
||||
v-if="hasPermission('admin:doctorPharmacy:export') || hasPermission('admin:sysPharmacy:doctor')"
|
||||
@select="handleExportCommand"
|
||||
>
|
||||
<a-button type="outline" size="small" :loading="exportLoading">
|
||||
<template #icon><icon-download /></template>
|
||||
导出医生数据
|
||||
<icon-down style="margin-left: 4px" />
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption :value="1">
|
||||
<template #icon><icon-filter /></template>
|
||||
导出当前筛选数据
|
||||
</a-doption>
|
||||
<a-doption :value="2" :disabled="selectedRowKeys.length === 0">
|
||||
<template #icon><icon-check-square /></template>
|
||||
导出已选数据 {{ selectedRowKeys.length ? `(${selectedRowKeys.length})` : '' }}
|
||||
</a-doption>
|
||||
<a-doption :value="3">
|
||||
<template #icon><icon-layers /></template>
|
||||
导出该药房全部医生
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 医生列表表格 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:loading="loading"
|
||||
:pagination="paginationProps"
|
||||
row-key="doctor_pharmacy_id"
|
||||
:row-selection="rowSelection"
|
||||
v-model:selected-keys="selectedRowKeys"
|
||||
:scroll="{ x: 860 }"
|
||||
style="margin-top: 10px"
|
||||
@page-change="handlePageChange"
|
||||
@page-size-change="handlePageSizeChange"
|
||||
>
|
||||
<!-- 序号 -->
|
||||
<template #index="{ rowIndex }">
|
||||
{{ (pager.page - 1) * pager.page_size + rowIndex + 1 }}
|
||||
</template>
|
||||
|
||||
<!-- 医生信息 -->
|
||||
<template #doctor="{ record }">
|
||||
<div class="doctor-cell">
|
||||
<a-avatar :size="36" shape="circle">
|
||||
<img v-if="record.avatar" :src="record.avatar" alt="avatar" />
|
||||
<icon-user v-else />
|
||||
</a-avatar>
|
||||
<div class="doctor-cell-info">
|
||||
<div class="doctor-name">{{ record.user_name || '-' }}</div>
|
||||
<a-tag size="mini" color="blue">{{ record.doctor_title_name || '医生' }}</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 所属医院与科室 -->
|
||||
<template #hospital="{ record }">
|
||||
<div>{{ record.hospital_name || '-' }}</div>
|
||||
<div style="font-size: 12px; color: #86909c">{{ record.department_custom_name || '-' }}</div>
|
||||
</template>
|
||||
|
||||
<!-- 是否默认 -->
|
||||
<template #is_default="{ record }">
|
||||
<a-tag v-if="record.is_default === 1" color="arcoblue" size="small">
|
||||
<template #icon><icon-check-circle-fill /></template>
|
||||
首选默认
|
||||
</a-tag>
|
||||
<a-tag v-else color="gray" size="small">普通关联</a-tag>
|
||||
</template>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<template #action="{ record }">
|
||||
<a-space :size="4">
|
||||
<a-button type="text" size="small" @click="handleViewDoctor(record)">
|
||||
<template #icon><icon-eye /></template>
|
||||
档案
|
||||
</a-button>
|
||||
<a-popconfirm
|
||||
v-if="hasPermission('admin:doctorPharmacy:remove')"
|
||||
content="确定解除该医生与当前药房的绑定关系?"
|
||||
type="warning"
|
||||
@ok="handleRemoveBinding(record)"
|
||||
>
|
||||
<a-button type="text" status="danger" size="small">
|
||||
<template #icon><icon-delete /></template>
|
||||
解绑
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 公共医生详情模态弹窗 -->
|
||||
<DoctorModal
|
||||
:doctorVisible="doctorModalVisible"
|
||||
:doctor_id="selectedDoctorId"
|
||||
@doctorVisibleChange="() => { doctorModalVisible = false; selectedDoctorId = ''; }"
|
||||
/>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { usePermissionStore } from '@/store/permission';
|
||||
import { getPharmacyDoctorPage, exportPharmacyDoctor } from '@/api/basic/pharmacy';
|
||||
import { removeDoctorPharmacy } from '@/api/doctor/pharmacy';
|
||||
import DoctorModal from '@/components/doctorModal.vue';
|
||||
|
||||
const permissionStore = usePermissionStore();
|
||||
|
||||
// 权限校验
|
||||
const hasPermission = (permission) => {
|
||||
const perms = permissionStore.buttonPermissions || [];
|
||||
return perms.includes('*') || perms.includes(permission);
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const exportLoading = ref(false);
|
||||
const currentPharmacy = ref(null);
|
||||
const tableData = ref([]);
|
||||
const selectedRowKeys = ref([]);
|
||||
|
||||
// 表格多选配置
|
||||
const rowSelection = reactive({
|
||||
type: 'checkbox',
|
||||
showCheckedAll: true,
|
||||
onlyCurrentPage: false,
|
||||
});
|
||||
|
||||
// 医生弹窗查看状态
|
||||
const doctorModalVisible = ref(false);
|
||||
const selectedDoctorId = ref('');
|
||||
|
||||
const queryFormRef = ref(null);
|
||||
const queryForm = reactive({
|
||||
doctor_name: '',
|
||||
mobile: '',
|
||||
});
|
||||
|
||||
const pager = reactive({
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const paginationProps = computed(() => ({
|
||||
total: pager.total,
|
||||
current: pager.page,
|
||||
pageSize: pager.page_size,
|
||||
showTotal: true,
|
||||
showJumper: true,
|
||||
showPageSize: true,
|
||||
pageSizeOptions: [10, 20, 50],
|
||||
}));
|
||||
|
||||
const drawerTitle = computed(() => {
|
||||
const name = currentPharmacy.value?.pharmacy_name || '';
|
||||
return name ? `关联医生列表 - ${name}` : '关联医生列表';
|
||||
});
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: '#', slotName: 'index', width: 50, align: 'center' },
|
||||
{ title: '医生信息', slotName: 'doctor', width: 170 },
|
||||
{ title: '手机号码', dataIndex: 'mobile', width: 130 },
|
||||
{ title: '执业机构与科室', slotName: 'hospital', minWidth: 180 },
|
||||
{ title: '默认状态', slotName: 'is_default', width: 110, align: 'center' },
|
||||
{ title: '绑定时间', dataIndex: 'bind_time', width: 170 },
|
||||
{ title: '操作', slotName: 'action', width: 180, align: 'center', fixed: 'right' },
|
||||
];
|
||||
|
||||
// 获取药房绑定的医生列表数据
|
||||
const fetchTableData = async () => {
|
||||
if (!currentPharmacy.value?.pharmacy_id) return;
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
pharmacy_id: String(currentPharmacy.value.pharmacy_id),
|
||||
page: pager.page,
|
||||
page_size: pager.page_size,
|
||||
};
|
||||
if (queryForm.doctor_name) params.doctor_name = queryForm.doctor_name;
|
||||
if (queryForm.mobile) params.mobile = queryForm.mobile;
|
||||
|
||||
const res = await getPharmacyDoctorPage(params);
|
||||
if (res.code === 200 && res.data) {
|
||||
tableData.value = res.data.data || [];
|
||||
pager.total = res.data.total || 0;
|
||||
pager.page = res.data.page || 1;
|
||||
pager.page_size = res.data.page_size || 10;
|
||||
} else {
|
||||
Message.error(res.message || '获取药房关联医生列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取关联医生列表异常:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const handleQuery = () => {
|
||||
pager.page = 1;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 重置搜索
|
||||
const handleResetQuery = () => {
|
||||
queryForm.doctor_name = '';
|
||||
queryForm.mobile = '';
|
||||
pager.page = 1;
|
||||
selectedRowKeys.value = [];
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const handlePageChange = (page) => {
|
||||
pager.page = page;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
const handlePageSizeChange = (pageSize) => {
|
||||
pager.page_size = pageSize;
|
||||
pager.page = 1;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 查看医生档案
|
||||
const handleViewDoctor = (record) => {
|
||||
selectedDoctorId.value = String(record.doctor_id);
|
||||
doctorModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 解绑医生
|
||||
const handleRemoveBinding = async (record) => {
|
||||
try {
|
||||
const res = await removeDoctorPharmacy(
|
||||
record.doctor_pharmacy_id || record.pharmacy_id
|
||||
);
|
||||
if (res.code === 200) {
|
||||
Message.success('已解除医生绑定');
|
||||
if (tableData.value.length === 1 && pager.page > 1) {
|
||||
pager.page -= 1;
|
||||
}
|
||||
fetchTableData();
|
||||
} else {
|
||||
Message.error(res.message || '解除绑定失败');
|
||||
}
|
||||
} catch (error) {
|
||||
Message.error('解除绑定出现异常');
|
||||
}
|
||||
};
|
||||
|
||||
// 通用文件安全下载方法
|
||||
const triggerDownload = (fileUrl, fileName = '药房关联医生列表') => {
|
||||
if (!fileUrl) return;
|
||||
const link = document.createElement('a');
|
||||
link.href = fileUrl;
|
||||
link.setAttribute('download', fileName);
|
||||
link.target = '_blank';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
};
|
||||
|
||||
// 药房关联医生列表导出
|
||||
const handleExport = async (type) => {
|
||||
const pharmacyId = currentPharmacy.value?.pharmacy_id;
|
||||
if (!pharmacyId) {
|
||||
Message.warning('未能获取当前药房信息');
|
||||
return;
|
||||
}
|
||||
|
||||
// 场景 2:按选中导出需校验勾选项
|
||||
if (type === 2 && (!selectedRowKeys.value || selectedRowKeys.value.length === 0)) {
|
||||
Message.warning('请先勾选需要导出的医生数据');
|
||||
return;
|
||||
}
|
||||
|
||||
const params = {
|
||||
type,
|
||||
pharmacy_id: String(pharmacyId),
|
||||
};
|
||||
|
||||
if (type === 1) {
|
||||
if (queryForm.doctor_name) params.doctor_name = queryForm.doctor_name.trim();
|
||||
if (queryForm.mobile) params.mobile = queryForm.mobile.trim();
|
||||
} else if (type === 2) {
|
||||
params.id = selectedRowKeys.value.join(',');
|
||||
}
|
||||
|
||||
exportLoading.value = true;
|
||||
try {
|
||||
const res = await exportPharmacyDoctor(params);
|
||||
if (res.code === 200 && res.data) {
|
||||
Message.success('导出成功,正在下载文件...');
|
||||
const pharmacyName = currentPharmacy.value?.pharmacy_name || '药房';
|
||||
triggerDownload(res.data, `${pharmacyName}_关联医生.xlsx`);
|
||||
} else {
|
||||
Message.error(res.message || '导出失败,请稍后重试');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('导出异常:', error);
|
||||
Message.error('导出请求异常,请联系系统管理员');
|
||||
} finally {
|
||||
exportLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 下拉菜单导出命令分发
|
||||
const handleExportCommand = (value) => {
|
||||
handleExport(Number(value));
|
||||
};
|
||||
|
||||
// 打开抽屉
|
||||
const open = (pharmacy) => {
|
||||
currentPharmacy.value = pharmacy;
|
||||
queryForm.doctor_name = '';
|
||||
queryForm.mobile = '';
|
||||
pager.page = 1;
|
||||
selectedRowKeys.value = [];
|
||||
visible.value = true;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
selectedRowKeys.value = [];
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
padding: 0 2px;
|
||||
|
||||
.table-total-tip {
|
||||
font-size: 13px;
|
||||
color: #86909c;
|
||||
}
|
||||
}
|
||||
|
||||
.pharmacy-summary-card {
|
||||
background-color: #f7f8fa;
|
||||
border-radius: 6px;
|
||||
|
||||
:deep(.arco-card-body) {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.pharmacy-info-box {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
.pharmacy-icon-box {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
background-color: #e8f3ff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 14px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pharmacy-meta {
|
||||
flex: 1;
|
||||
|
||||
.pharmacy-meta-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
}
|
||||
|
||||
.pharmacy-meta-desc {
|
||||
margin-top: 6px;
|
||||
font-size: 13px;
|
||||
color: #4e5969;
|
||||
}
|
||||
|
||||
.pharmacy-meta-address {
|
||||
margin-top: 4px;
|
||||
font-size: 13px;
|
||||
color: #86909c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-form {
|
||||
:deep(.arco-form-item) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.doctor-cell-info {
|
||||
margin-left: 10px;
|
||||
|
||||
.doctor-name {
|
||||
font-weight: 500;
|
||||
color: #1d2129;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,416 @@
|
||||
<template>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
:title="modalTitle"
|
||||
:width="760"
|
||||
:ok-loading="submitLoading"
|
||||
:ok-text="'保存'"
|
||||
:cancel-text="'取消'"
|
||||
:footer="mode !== 'detail'"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:rules="rules"
|
||||
:disabled="mode === 'detail'"
|
||||
auto-label-width
|
||||
layout="horizontal"
|
||||
>
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="pharmacy_name" label="药房名称">
|
||||
<a-input
|
||||
v-model="formData.pharmacy_name"
|
||||
placeholder="请输入药房名称"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="pharmacy_code" label="药房代码">
|
||||
<a-input
|
||||
v-model="formData.pharmacy_code"
|
||||
placeholder="请输入药房代码(如 PHARM_001)"
|
||||
allow-clear
|
||||
max-length="50"
|
||||
:disabled="mode === 'edit'"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="postage" label="基础邮费 (元)">
|
||||
<a-input-number
|
||||
v-model="formData.postage"
|
||||
placeholder="请输入基础邮费"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:step="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="free_shipping_threshold" label="包邮门槛 (元)">
|
||||
<a-input-number
|
||||
v-model="formData.free_shipping_threshold"
|
||||
placeholder="0表示不设门槛"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:step="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="is_pickup" label="支持自提">
|
||||
<a-radio-group v-model="formData.is_pickup">
|
||||
<a-radio :value="1">支持</a-radio>
|
||||
<a-radio :value="0">不支持</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item field="status" label="药房状态">
|
||||
<a-radio-group v-model="formData.status">
|
||||
<a-radio :value="1">正常</a-radio>
|
||||
<a-radio :value="0">禁用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-item field="telephone" label="联系电话">
|
||||
<a-input
|
||||
v-model="formData.telephone"
|
||||
placeholder="请输入联系电话"
|
||||
allow-clear
|
||||
max-length="20"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item label="所属区域">
|
||||
<a-space style="width: 100%">
|
||||
<a-select
|
||||
v-model="formData.province_id"
|
||||
placeholder="选择省份"
|
||||
style="width: 170px"
|
||||
allow-clear
|
||||
@change="handleProvinceChange"
|
||||
@clear="handleProvinceClear"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in provinceList"
|
||||
:key="item.area_id"
|
||||
:value="Number(item.area_id)"
|
||||
:label="item.area_name"
|
||||
>
|
||||
{{ item.area_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
|
||||
<a-select
|
||||
v-model="formData.city_id"
|
||||
placeholder="选择城市"
|
||||
style="width: 170px"
|
||||
allow-clear
|
||||
:disabled="!formData.province_id"
|
||||
@change="handleCityChange"
|
||||
@clear="handleCityClear"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in cityList"
|
||||
:key="item.area_id"
|
||||
:value="Number(item.area_id)"
|
||||
:label="item.area_name"
|
||||
>
|
||||
{{ item.area_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
|
||||
<a-select
|
||||
v-model="formData.county_id"
|
||||
placeholder="选择区县"
|
||||
style="width: 170px"
|
||||
allow-clear
|
||||
:disabled="!formData.city_id"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in countyList"
|
||||
:key="item.area_id"
|
||||
:value="Number(item.area_id)"
|
||||
:label="item.area_name"
|
||||
>
|
||||
{{ item.area_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="24">
|
||||
<a-form-item field="address" label="详细地址">
|
||||
<a-textarea
|
||||
v-model="formData.address"
|
||||
placeholder="请输入详细地址,如街道、门牌号等"
|
||||
:auto-size="{ minRows: 2, maxRows: 4 }"
|
||||
allow-clear
|
||||
max-length="200"
|
||||
show-word-limit
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { addPharmacy, updatePharmacy, getPharmacyDetail } from '@/api/basic/pharmacy';
|
||||
import { getAdminAreaList } from '@/api/basic/list';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const visible = ref(false);
|
||||
const mode = ref('add'); // 'add' | 'edit' | 'detail'
|
||||
const currentId = ref('');
|
||||
const submitLoading = ref(false);
|
||||
const formRef = ref(null);
|
||||
|
||||
const provinceList = ref([]);
|
||||
const cityList = ref([]);
|
||||
const countyList = ref([]);
|
||||
|
||||
const defaultFormData = {
|
||||
pharmacy_name: '',
|
||||
pharmacy_code: '',
|
||||
postage: 0,
|
||||
free_shipping_threshold: 0,
|
||||
is_pickup: 0,
|
||||
telephone: '',
|
||||
province_id: undefined,
|
||||
city_id: undefined,
|
||||
county_id: undefined,
|
||||
address: '',
|
||||
status: 1,
|
||||
};
|
||||
|
||||
const formData = reactive({ ...defaultFormData });
|
||||
|
||||
const modalTitle = computed(() => {
|
||||
if (mode.value === 'add') return '新增药房';
|
||||
if (mode.value === 'edit') return '修改药房';
|
||||
return '药房详情';
|
||||
});
|
||||
|
||||
const rules = {
|
||||
pharmacy_name: [
|
||||
{ required: true, message: '请输入药房名称' },
|
||||
{ maxLength: 50, message: '药房名称不能超过50个字符' },
|
||||
],
|
||||
pharmacy_code: [
|
||||
{ required: true, message: '请输入药房代码' },
|
||||
{ maxLength: 50, message: '药房代码不能超过50个字符' },
|
||||
],
|
||||
postage: [
|
||||
{ required: true, message: '请输入基础邮费' },
|
||||
],
|
||||
free_shipping_threshold: [
|
||||
{ required: true, message: '请输入满额包邮门槛金额' },
|
||||
],
|
||||
is_pickup: [
|
||||
{ required: true, message: '请选择是否支持自提' },
|
||||
],
|
||||
address: [
|
||||
{ required: true, message: '请输入详细地址' },
|
||||
{ maxLength: 200, message: '详细地址不能超过200个字符' },
|
||||
],
|
||||
};
|
||||
|
||||
// 获取区域列表 (area_type: 2 省份, 3 城市, 4 区县)
|
||||
const fetchAreaList = async (parentId = '', areaType = 2) => {
|
||||
try {
|
||||
const res = await getAdminAreaList({
|
||||
parent_id: parentId,
|
||||
area_type: areaType,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
if (areaType === 2) {
|
||||
provinceList.value = res.data || [];
|
||||
} else if (areaType === 3) {
|
||||
cityList.value = res.data || [];
|
||||
} else if (areaType === 4) {
|
||||
countyList.value = res.data || [];
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取区域失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleProvinceChange = (value) => {
|
||||
formData.city_id = undefined;
|
||||
formData.county_id = undefined;
|
||||
cityList.value = [];
|
||||
countyList.value = [];
|
||||
if (value) {
|
||||
fetchAreaList(value, 3);
|
||||
}
|
||||
};
|
||||
|
||||
const handleProvinceClear = () => {
|
||||
formData.province_id = undefined;
|
||||
formData.city_id = undefined;
|
||||
formData.county_id = undefined;
|
||||
cityList.value = [];
|
||||
countyList.value = [];
|
||||
};
|
||||
|
||||
const handleCityChange = (value) => {
|
||||
formData.county_id = undefined;
|
||||
countyList.value = [];
|
||||
if (value) {
|
||||
fetchAreaList(value, 4);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCityClear = () => {
|
||||
formData.city_id = undefined;
|
||||
formData.county_id = undefined;
|
||||
countyList.value = [];
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
Object.assign(formData, defaultFormData);
|
||||
cityList.value = [];
|
||||
countyList.value = [];
|
||||
if (formRef.value) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
};
|
||||
|
||||
// 打开弹窗
|
||||
const open = async (openMode = 'add', id = '') => {
|
||||
mode.value = openMode;
|
||||
currentId.value = id;
|
||||
resetForm();
|
||||
visible.value = true;
|
||||
|
||||
// 保证省份数据已加载
|
||||
if (provinceList.value.length === 0) {
|
||||
await fetchAreaList('', 2);
|
||||
}
|
||||
|
||||
if ((openMode === 'edit' || openMode === 'detail') && id) {
|
||||
try {
|
||||
const res = await getPharmacyDetail(id);
|
||||
if (res.code === 200 && res.data) {
|
||||
const d = res.data;
|
||||
Object.assign(formData, {
|
||||
pharmacy_name: d.pharmacy_name || '',
|
||||
pharmacy_code: d.pharmacy_code || '',
|
||||
postage: Number(d.postage) || 0,
|
||||
free_shipping_threshold: Number(d.free_shipping_threshold) || 0,
|
||||
is_pickup: d.is_pickup ?? 0,
|
||||
telephone: d.telephone || '',
|
||||
province_id: d.province_id ? Number(d.province_id) : undefined,
|
||||
city_id: d.city_id ? Number(d.city_id) : undefined,
|
||||
county_id: d.county_id ? Number(d.county_id) : undefined,
|
||||
address: d.address || '',
|
||||
status: d.status ?? 1,
|
||||
});
|
||||
|
||||
// 联动加载已有城市与区县选项
|
||||
if (formData.province_id) {
|
||||
await fetchAreaList(formData.province_id, 3);
|
||||
}
|
||||
if (formData.city_id) {
|
||||
await fetchAreaList(formData.city_id, 4);
|
||||
}
|
||||
} else {
|
||||
Message.error(res.message || '获取药房详情失败');
|
||||
}
|
||||
} catch (err) {
|
||||
Message.error('获取药房详情出现异常');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = async () => {
|
||||
if (!formRef.value) return;
|
||||
const errors = await formRef.value.validate();
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
pharmacy_name: formData.pharmacy_name,
|
||||
pharmacy_code: formData.pharmacy_code,
|
||||
postage: Number(formData.postage),
|
||||
free_shipping_threshold: Number(formData.free_shipping_threshold),
|
||||
is_pickup: Number(formData.is_pickup),
|
||||
telephone: formData.telephone || '',
|
||||
province_id: formData.province_id ? Number(formData.province_id) : undefined,
|
||||
city_id: formData.city_id ? Number(formData.city_id) : undefined,
|
||||
county_id: formData.county_id ? Number(formData.county_id) : undefined,
|
||||
address: formData.address,
|
||||
status: Number(formData.status),
|
||||
};
|
||||
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
let res;
|
||||
if (mode.value === 'add') {
|
||||
res = await addPharmacy(payload);
|
||||
} else {
|
||||
res = await updatePharmacy(currentId.value, payload);
|
||||
}
|
||||
|
||||
if (res.code === 200) {
|
||||
Message.success(mode.value === 'add' ? '添加药房成功' : '修改药房成功');
|
||||
visible.value = false;
|
||||
emit('success');
|
||||
} else {
|
||||
Message.error(res.message || '操作失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('提交药房表单异常:', error);
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
visible.value = false;
|
||||
resetForm();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.arco-form-item) {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,407 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="visible"
|
||||
:title="drawerTitle"
|
||||
:width="920"
|
||||
:footer="false"
|
||||
:mask-closable="false"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<!-- 顶部警告提示 -->
|
||||
<a-alert type="warning" style="margin-bottom: 16px">
|
||||
<template #icon><icon-exclamation-circle-fill /></template>
|
||||
当前【<strong>{{ sourcePharmacy?.pharmacy_name }}</strong>】共有
|
||||
<span style="color: #f53f3f; font-weight: bold">{{ affectedDoctorCount }}</span>
|
||||
位医生的首选默认药房受到影响。
|
||||
为保障处方业务正常运转,请为他们指定新的默认药房;确认后系统将自动完成迁移并执行<strong>{{ actionText }}</strong>。
|
||||
</a-alert>
|
||||
|
||||
<!-- 批量快捷配置工具栏 -->
|
||||
<div class="batch-toolbar">
|
||||
<a-space>
|
||||
<span class="batch-label">批量操作:</span>
|
||||
<a-select
|
||||
v-model="batchTargetPharmacyId"
|
||||
placeholder="选择统一替代药房"
|
||||
allow-search
|
||||
style="width: 220px"
|
||||
size="small"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in availablePharmacies"
|
||||
:key="item.pharmacy_id"
|
||||
:value="String(item.pharmacy_id)"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
<a-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:disabled="selectedRowKeys.length === 0 || !batchTargetPharmacyId"
|
||||
@click="handleApplyBatch"
|
||||
>
|
||||
应用到已选医生 ({{ selectedRowKeys.length }})
|
||||
</a-button>
|
||||
<a-button
|
||||
type="outline"
|
||||
size="small"
|
||||
:disabled="!batchTargetPharmacyId"
|
||||
@click="handleApplyAll"
|
||||
>
|
||||
应用到全部医生 ({{ doctorList.length }})
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<!-- 医生分流配置表格 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="doctorList"
|
||||
:loading="loading"
|
||||
:pagination="false"
|
||||
row-key="doctor_id"
|
||||
:row-selection="rowSelection"
|
||||
v-model:selected-keys="selectedRowKeys"
|
||||
:scroll="{ x: 800, y: 460 }"
|
||||
style="margin-top: 12px"
|
||||
>
|
||||
<!-- 医生信息 -->
|
||||
<template #doctor="{ record }">
|
||||
<div class="doctor-cell">
|
||||
<div class="doctor-name">{{ record.user_name || '-' }}</div>
|
||||
<a-tag size="mini" color="blue">{{ record.doctor_title_name || '医生' }}</a-tag>
|
||||
<div class="doctor-phone">{{ record.mobile || '-' }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 医院与科室 -->
|
||||
<template #hospital="{ record }">
|
||||
<div>{{ record.hospital_name || '-' }}</div>
|
||||
<div style="font-size: 12px; color: #86909c">{{ record.department_custom_name || '-' }}</div>
|
||||
</template>
|
||||
|
||||
<!-- 已绑定的其他药房 (快捷点选) -->
|
||||
<template #other_pharmacies="{ record }">
|
||||
<div v-if="record.other_bound_pharmacies && record.other_bound_pharmacies.length > 0" class="tag-group">
|
||||
<a-tooltip
|
||||
v-for="item in record.other_bound_pharmacies"
|
||||
:key="item.pharmacy_id"
|
||||
content="点击直接选为新默认药房"
|
||||
>
|
||||
<a-tag
|
||||
color="arcoblue"
|
||||
size="small"
|
||||
class="clickable-tag"
|
||||
:class="{ 'tag-active': String(record.target_pharmacy_id) === String(item.pharmacy_id) }"
|
||||
@click="handleQuickSelect(record, item.pharmacy_id)"
|
||||
>
|
||||
<template #icon><icon-swap /></template>
|
||||
{{ item.pharmacy_name }}
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<span v-else style="color: #c9cdd4; font-size: 13px">无其他绑定药房</span>
|
||||
</template>
|
||||
|
||||
<!-- 新默认药房 (必选) -->
|
||||
<template #target_pharmacy="{ record }">
|
||||
<a-select
|
||||
v-model="record.target_pharmacy_id"
|
||||
placeholder="请指定新默认药房"
|
||||
allow-search
|
||||
size="small"
|
||||
:error="!record.target_pharmacy_id"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in availablePharmacies"
|
||||
:key="item.pharmacy_id"
|
||||
:value="String(item.pharmacy_id)"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 抽屉底部动作栏 -->
|
||||
<div class="drawer-footer">
|
||||
<div class="footer-left">
|
||||
<a-checkbox
|
||||
v-model="unbindSource"
|
||||
:disabled="actionType === 'delete'"
|
||||
>
|
||||
同时解除医生与当前原药房的绑定关系
|
||||
</a-checkbox>
|
||||
<span v-if="actionType === 'delete'" class="delete-tip">(删除药房将强制彻底解绑)</span>
|
||||
</div>
|
||||
<div class="footer-right">
|
||||
<a-space>
|
||||
<a-button @click="handleClose">取消</a-button>
|
||||
<a-button
|
||||
type="primary"
|
||||
:status="actionType === 'delete' ? 'danger' : 'warning'"
|
||||
:loading="submitLoading"
|
||||
:disabled="!isAllConfigured"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
确认迁移并{{ actionText }}
|
||||
<template v-if="!isAllConfigured">
|
||||
({{ unconfiguredCount }}位未指定)
|
||||
</template>
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { getPharmacyList, getAffectedDoctors, batchTransferAndAction } from '@/api/basic/pharmacy';
|
||||
|
||||
const emit = defineEmits(['success']);
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const submitLoading = ref(false);
|
||||
|
||||
const sourcePharmacy = ref(null);
|
||||
const actionType = ref('disable'); // 'disable' | 'delete'
|
||||
const unbindSource = ref(true);
|
||||
|
||||
const doctorList = ref([]);
|
||||
const selectedRowKeys = ref([]);
|
||||
const batchTargetPharmacyId = ref('');
|
||||
const pharmacyOptions = ref([]);
|
||||
|
||||
// 过滤掉当前药房自身的目标药房候选列表
|
||||
const availablePharmacies = computed(() => {
|
||||
const currentId = String(sourcePharmacy.value?.pharmacy_id || '');
|
||||
return pharmacyOptions.value.filter((p) => String(p.pharmacy_id) !== currentId);
|
||||
});
|
||||
|
||||
const actionText = computed(() => (actionType.value === 'delete' ? '删除药房' : '禁用药房'));
|
||||
const drawerTitle = computed(() => `处理受影响医生默认药房(${actionText.value}前置迁移)`);
|
||||
const affectedDoctorCount = computed(() => doctorList.value.length);
|
||||
|
||||
// 校验未指定新药房的医生数量
|
||||
const unconfiguredCount = computed(() => {
|
||||
return doctorList.value.filter((d) => !d.target_pharmacy_id).length;
|
||||
});
|
||||
const isAllConfigured = computed(() => {
|
||||
return doctorList.value.length > 0 && unconfiguredCount.value === 0;
|
||||
});
|
||||
|
||||
const rowSelection = reactive({
|
||||
type: 'checkbox',
|
||||
showCheckedAll: true,
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{ title: '医生信息', slotName: 'doctor', width: 170 },
|
||||
{ title: '执业机构/科室', slotName: 'hospital', width: 180 },
|
||||
{ title: '医生已绑定其他药房(可快捷点选)', slotName: 'other_pharmacies', minWidth: 230 },
|
||||
{ title: '新默认药房(必选)', slotName: 'target_pharmacy', width: 220 },
|
||||
];
|
||||
|
||||
// 获取正常启用状态的药房列表
|
||||
const fetchPharmacyOptions = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList({ status: 1 });
|
||||
if (res.code === 200 && res.data) {
|
||||
pharmacyOptions.value = Array.isArray(res.data) ? res.data : (res.data.list || []);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取替代药房列表失败:', err);
|
||||
}
|
||||
};
|
||||
|
||||
// 快捷点选已有药房
|
||||
const handleQuickSelect = (record, pharmacyId) => {
|
||||
record.target_pharmacy_id = String(pharmacyId);
|
||||
};
|
||||
|
||||
// 批量应用到已选医生
|
||||
const handleApplyBatch = () => {
|
||||
if (!batchTargetPharmacyId.value) return;
|
||||
doctorList.value.forEach((d) => {
|
||||
if (selectedRowKeys.value.includes(d.doctor_id)) {
|
||||
d.target_pharmacy_id = batchTargetPharmacyId.value;
|
||||
}
|
||||
});
|
||||
Message.success(`已为选中的 ${selectedRowKeys.value.length} 位医生设置替代药房`);
|
||||
};
|
||||
|
||||
// 批量应用到全部受影响医生
|
||||
const handleApplyAll = () => {
|
||||
if (!batchTargetPharmacyId.value) return;
|
||||
doctorList.value.forEach((d) => {
|
||||
d.target_pharmacy_id = batchTargetPharmacyId.value;
|
||||
});
|
||||
Message.success(`已为全部 ${doctorList.value.length} 位医生设置替代药房`);
|
||||
};
|
||||
|
||||
// 初始化受影响医生列表(若只绑定了另外一家药房则智能预选)
|
||||
const initDoctorList = (list) => {
|
||||
doctorList.value = list.map((item) => ({
|
||||
...item,
|
||||
target_pharmacy_id: item.other_bound_pharmacies?.length === 1
|
||||
? String(item.other_bound_pharmacies[0].pharmacy_id)
|
||||
: '',
|
||||
}));
|
||||
};
|
||||
|
||||
// 打开抽屉主入口
|
||||
const open = async ({ pharmacy, action = 'disable', affectedData = null }) => {
|
||||
sourcePharmacy.value = pharmacy;
|
||||
actionType.value = action;
|
||||
unbindSource.value = true;
|
||||
selectedRowKeys.value = [];
|
||||
batchTargetPharmacyId.value = '';
|
||||
visible.value = true;
|
||||
|
||||
fetchPharmacyOptions();
|
||||
|
||||
if (affectedData?.doctor_list) {
|
||||
initDoctorList(affectedData.doctor_list);
|
||||
} else {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getAffectedDoctors(pharmacy.pharmacy_id);
|
||||
if (res.code === 200 && res.data) {
|
||||
initDoctorList(res.data.doctor_list || []);
|
||||
} else {
|
||||
Message.error(res.message || '获取受影响医生列表失败');
|
||||
}
|
||||
} catch (e) {
|
||||
Message.error('获取受影响医生列表异常');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
// 提交迁移并执行下线
|
||||
const handleSubmit = async () => {
|
||||
if (!isAllConfigured.value) {
|
||||
Message.warning(`尚有 ${unconfiguredCount.value} 位医生未指定新的默认药房`);
|
||||
return;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
source_pharmacy_id: String(sourcePharmacy.value.pharmacy_id),
|
||||
action: actionType.value,
|
||||
unbind_source: actionType.value === 'delete' ? 1 : (unbindSource.value ? 1 : 0),
|
||||
transfers: doctorList.value.map((d) => ({
|
||||
doctor_id: String(d.doctor_id),
|
||||
target_pharmacy_id: String(d.target_pharmacy_id),
|
||||
})),
|
||||
};
|
||||
|
||||
submitLoading.value = true;
|
||||
try {
|
||||
const res = await batchTransferAndAction(payload);
|
||||
if (res.code === 200) {
|
||||
Message.success(`医生分流完成,药房已成功${actionText.value}`);
|
||||
visible.value = false;
|
||||
emit('success', { action: actionType.value, pharmacy_id: payload.source_pharmacy_id });
|
||||
} else {
|
||||
Message.error(res.message || '迁移下线操作失败');
|
||||
}
|
||||
} catch (err) {
|
||||
Message.error('迁移下线请求异常');
|
||||
} finally {
|
||||
submitLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.batch-toolbar {
|
||||
background-color: #f7f8fa;
|
||||
padding: 10px 14px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.batch-label {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: #4e5969;
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-cell {
|
||||
.doctor-name {
|
||||
font-weight: 500;
|
||||
color: #1d2129;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.doctor-phone {
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.tag-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
|
||||
.clickable-tag {
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.85;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
}
|
||||
|
||||
.tag-active {
|
||||
background-color: #165dff !important;
|
||||
color: #fff !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60px;
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #e5e6eb;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
z-index: 10;
|
||||
|
||||
.footer-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.delete-tip {
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,620 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索筛选表单 -->
|
||||
<a-form :model="queryForm" ref="queryFormRef" layout="inline" class="search-form">
|
||||
<a-form-item field="pharmacy_name" label="药房名称">
|
||||
<a-input
|
||||
v-model="queryForm.pharmacy_name"
|
||||
placeholder="请输入药房名称"
|
||||
allow-clear
|
||||
style="width: 180px"
|
||||
@press-enter="handleQuery"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="pharmacy_code" label="药房代码">
|
||||
<a-input
|
||||
v-model="queryForm.pharmacy_code"
|
||||
placeholder="请输入药房代码"
|
||||
allow-clear
|
||||
style="width: 180px"
|
||||
@press-enter="handleQuery"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="status" label="状态">
|
||||
<a-select
|
||||
v-model="queryForm.status"
|
||||
placeholder="全部状态"
|
||||
allow-clear
|
||||
style="width: 140px"
|
||||
>
|
||||
<a-option :value="1">正常</a-option>
|
||||
<a-option :value="0">禁用</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="is_pickup" label="支持自提">
|
||||
<a-select
|
||||
v-model="queryForm.is_pickup"
|
||||
placeholder="全部"
|
||||
allow-clear
|
||||
style="width: 130px"
|
||||
>
|
||||
<a-option :value="1">支持</a-option>
|
||||
<a-option :value="0">不支持</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="province_id" label="省份">
|
||||
<a-select
|
||||
v-model="queryForm.province_id"
|
||||
placeholder="全部省份"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
@change="changeProvince"
|
||||
@clear="clearProvince"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in provinceData"
|
||||
:key="item.area_id"
|
||||
:value="Number(item.area_id)"
|
||||
:label="item.area_name"
|
||||
>
|
||||
{{ item.area_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="city_id" label="城市">
|
||||
<a-select
|
||||
v-model="queryForm.city_id"
|
||||
placeholder="全部城市"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
:disabled="!queryForm.province_id"
|
||||
@change="changeCity"
|
||||
@clear="clearCity"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in cityData"
|
||||
:key="item.area_id"
|
||||
:value="Number(item.area_id)"
|
||||
:label="item.area_name"
|
||||
>
|
||||
{{ item.area_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="county_id" label="区县">
|
||||
<a-select
|
||||
v-model="queryForm.county_id"
|
||||
placeholder="全部区县"
|
||||
allow-clear
|
||||
style="width: 150px"
|
||||
:disabled="!queryForm.city_id"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in countyData"
|
||||
:key="item.area_id"
|
||||
:value="Number(item.area_id)"
|
||||
:label="item.area_name"
|
||||
>
|
||||
{{ item.area_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-space>
|
||||
<a-button type="primary" @click="handleQuery">
|
||||
<template #icon><icon-search /></template>
|
||||
搜索
|
||||
</a-button>
|
||||
<a-button @click="handleResetQuery">
|
||||
<template #icon><icon-loop /></template>
|
||||
重置
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<a-divider style="margin: 12px 0 16px" />
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<div class="table-action-bar">
|
||||
<a-space>
|
||||
<a-button
|
||||
v-if="hasPermission('admin:sysPharmacy:add')"
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>
|
||||
<template #icon><icon-plus /></template>
|
||||
新增药房
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data="tableData"
|
||||
:loading="tableLoading"
|
||||
:pagination="paginationProps"
|
||||
row-key="pharmacy_id"
|
||||
:scroll="{ x: 1600 }"
|
||||
@page-change="handlePageChange"
|
||||
@page-size-change="handlePageSizeChange"
|
||||
>
|
||||
<!-- 序号列 -->
|
||||
<template #index="{ rowIndex }">
|
||||
{{ (pager.page - 1) * pager.page_size + rowIndex + 1 }}
|
||||
</template>
|
||||
|
||||
<!-- 基础邮费 -->
|
||||
<template #postage="{ record }">
|
||||
<span class="price-text">¥{{ Number(record.postage || 0).toFixed(2) }}</span>
|
||||
</template>
|
||||
|
||||
<!-- 包邮门槛 -->
|
||||
<template #free_shipping_threshold="{ record }">
|
||||
<span v-if="Number(record.free_shipping_threshold) > 0" class="price-text">
|
||||
¥{{ Number(record.free_shipping_threshold).toFixed(2) }}
|
||||
</span>
|
||||
<a-tag v-else size="small" color="blue">不设门槛</a-tag>
|
||||
</template>
|
||||
|
||||
<!-- 是否支持自提 -->
|
||||
<template #is_pickup="{ record }">
|
||||
<a-tag v-if="record.is_pickup === 1" color="green" size="small">支持</a-tag>
|
||||
<a-tag v-else color="gray" size="small">不支持</a-tag>
|
||||
</template>
|
||||
|
||||
<!-- 详细地址(带 Tooltip) -->
|
||||
<template #full_address="{ record }">
|
||||
<a-tooltip :content="record.full_address || record.address || '-'">
|
||||
<div class="ellipsis-text">
|
||||
{{ record.full_address || record.address || '-' }}
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<!-- 状态快捷开关(有权限可操作切换,无权限展示只读标签) -->
|
||||
<template #status="{ record }">
|
||||
<a-switch
|
||||
v-if="hasPermission('admin:sysPharmacy:status')"
|
||||
:model-value="record.status === 1"
|
||||
:loading="record._statusLoading"
|
||||
type="round"
|
||||
size="small"
|
||||
@change="(val) => handleStatusToggle(record, val)"
|
||||
>
|
||||
<template #checked>正常</template>
|
||||
<template #unchecked>禁用</template>
|
||||
</a-switch>
|
||||
<a-tag v-else :color="record.status === 1 ? 'green' : 'red'" size="small">
|
||||
{{ record.status === 1 ? '正常' : '禁用' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<template #action="{ record }">
|
||||
<a-space :size="0">
|
||||
<a-button
|
||||
v-if="hasPermission('admin:sysPharmacy:detail')"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="handleDetail(record)"
|
||||
>
|
||||
<template #icon><icon-eye /></template>
|
||||
详情
|
||||
</a-button>
|
||||
<a-button
|
||||
v-if="hasPermission('admin:sysPharmacy:edit')"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="handleEdit(record)"
|
||||
>
|
||||
<template #icon><icon-edit /></template>
|
||||
修改
|
||||
</a-button>
|
||||
<a-button
|
||||
v-if="hasPermission('admin:sysPharmacy:doctor')"
|
||||
type="text"
|
||||
size="small"
|
||||
@click="handleOpenDoctorDrawer(record)"
|
||||
>
|
||||
<template #icon><icon-user-group /></template>
|
||||
关联医生列表
|
||||
</a-button>
|
||||
<!-- <a-button
|
||||
v-if="hasPermission('admin:sysPharmacy:remove')"
|
||||
type="text"
|
||||
status="danger"
|
||||
size="small"
|
||||
@click="handleDeleteClick(record)"
|
||||
>
|
||||
<template #icon><icon-delete /></template>
|
||||
删除
|
||||
</a-button> -->
|
||||
</a-space>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 新增 / 编辑 / 详情 弹窗 -->
|
||||
<PharmacyModal ref="modalRef" @success="handleQuery" />
|
||||
|
||||
<!-- 关联医生列表抽屉 -->
|
||||
<PharmacyDoctorDrawer ref="doctorDrawerRef" />
|
||||
|
||||
<!-- 医生分流迁移抽屉 -->
|
||||
<PharmacyTransferDrawer ref="transferDrawerRef" @success="handleQuery" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { Message, Modal } from '@arco-design/web-vue';
|
||||
import { usePermissionStore } from '@/store/permission';
|
||||
import {
|
||||
getPharmacyPage,
|
||||
updatePharmacyStatus,
|
||||
deletePharmacy,
|
||||
getAffectedDoctors,
|
||||
} from '@/api/basic/pharmacy';
|
||||
import { getAdminAreaList } from '@/api/basic/list';
|
||||
import PharmacyModal from './components/pharmacyModal.vue';
|
||||
import PharmacyDoctorDrawer from './components/pharmacyDoctorDrawer.vue';
|
||||
import PharmacyTransferDrawer from './components/pharmacyTransferDrawer.vue';
|
||||
|
||||
const permissionStore = usePermissionStore();
|
||||
|
||||
// 统一权限检查方法(支持超级管理员 * 和指定权限标识)
|
||||
const hasPermission = (permission) => {
|
||||
const perms = permissionStore.buttonPermissions || [];
|
||||
return perms.includes('*') || perms.includes(permission);
|
||||
};
|
||||
|
||||
const queryFormRef = ref(null);
|
||||
const modalRef = ref(null);
|
||||
const doctorDrawerRef = ref(null);
|
||||
const transferDrawerRef = ref(null);
|
||||
|
||||
const tableLoading = ref(false);
|
||||
const tableData = ref([]);
|
||||
|
||||
// 区域数据
|
||||
const provinceData = ref([]);
|
||||
const cityData = ref([]);
|
||||
const countyData = ref([]);
|
||||
|
||||
// 分页信息
|
||||
const pager = reactive({
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
total: 0,
|
||||
});
|
||||
|
||||
const paginationProps = computed(() => ({
|
||||
total: pager.total,
|
||||
current: pager.page,
|
||||
pageSize: pager.page_size,
|
||||
showTotal: true,
|
||||
showJumper: true,
|
||||
showPageSize: true,
|
||||
pageSizeOptions: [10, 20, 50, 100],
|
||||
}));
|
||||
|
||||
// 查询表单
|
||||
const queryForm = reactive({
|
||||
pharmacy_name: '',
|
||||
pharmacy_code: '',
|
||||
status: undefined,
|
||||
is_pickup: undefined,
|
||||
province_id: undefined,
|
||||
city_id: undefined,
|
||||
county_id: undefined,
|
||||
});
|
||||
|
||||
// 表格列配置
|
||||
const columns = [
|
||||
{ title: '#', slotName: 'index', width: 60, align: 'center' },
|
||||
{ title: '药房代码', dataIndex: 'pharmacy_code', width: 140 },
|
||||
{ title: '药房名称', dataIndex: 'pharmacy_name', width: 200, ellipsis: true },
|
||||
{ title: '基础邮费', slotName: 'postage', width: 120, align: 'right' },
|
||||
{ title: '满额包邮门槛', slotName: 'free_shipping_threshold', width: 140, align: 'right' },
|
||||
{ title: '自提', slotName: 'is_pickup', width: 90, align: 'center' },
|
||||
{ title: '联系电话', dataIndex: 'telephone', width: 140 },
|
||||
{ title: '地址', slotName: 'full_address', minWidth: 240 },
|
||||
{ title: '状态', slotName: 'status', width: 100, align: 'center' },
|
||||
{ title: '创建时间', dataIndex: 'created_at', width: 180 },
|
||||
{ title: '操作', slotName: 'action', width: 350, fixed: 'right', align: 'center' },
|
||||
];
|
||||
|
||||
// 获取区域信息
|
||||
const fetchAreaList = async (parentId = '', areaType = 2) => {
|
||||
try {
|
||||
const res = await getAdminAreaList({
|
||||
parent_id: parentId,
|
||||
area_type: areaType,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
if (areaType === 2) provinceData.value = res.data || [];
|
||||
if (areaType === 3) cityData.value = res.data || [];
|
||||
if (areaType === 4) countyData.value = res.data || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取区域失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const changeProvince = (val) => {
|
||||
queryForm.city_id = undefined;
|
||||
queryForm.county_id = undefined;
|
||||
cityData.value = [];
|
||||
countyData.value = [];
|
||||
if (val) {
|
||||
fetchAreaList(val, 3);
|
||||
}
|
||||
};
|
||||
|
||||
const clearProvince = () => {
|
||||
queryForm.province_id = undefined;
|
||||
queryForm.city_id = undefined;
|
||||
queryForm.county_id = undefined;
|
||||
cityData.value = [];
|
||||
countyData.value = [];
|
||||
};
|
||||
|
||||
const changeCity = (val) => {
|
||||
queryForm.county_id = undefined;
|
||||
countyData.value = [];
|
||||
if (val) {
|
||||
fetchAreaList(val, 4);
|
||||
}
|
||||
};
|
||||
|
||||
const clearCity = () => {
|
||||
queryForm.city_id = undefined;
|
||||
queryForm.county_id = undefined;
|
||||
countyData.value = [];
|
||||
};
|
||||
|
||||
// 获取表格数据
|
||||
const fetchTableData = async () => {
|
||||
tableLoading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
page: pager.page,
|
||||
page_size: pager.page_size,
|
||||
};
|
||||
|
||||
if (queryForm.pharmacy_name) params.pharmacy_name = queryForm.pharmacy_name;
|
||||
if (queryForm.pharmacy_code) params.pharmacy_code = queryForm.pharmacy_code;
|
||||
if (queryForm.status !== undefined && queryForm.status !== null) params.status = queryForm.status;
|
||||
if (queryForm.is_pickup !== undefined && queryForm.is_pickup !== null) params.is_pickup = queryForm.is_pickup;
|
||||
if (queryForm.province_id) params.province_id = queryForm.province_id;
|
||||
if (queryForm.city_id) params.city_id = queryForm.city_id;
|
||||
if (queryForm.county_id) params.county_id = queryForm.county_id;
|
||||
|
||||
const res = await getPharmacyPage(params);
|
||||
if (res.code === 200 && res.data) {
|
||||
tableData.value = (res.data.data || []).map((item) => ({
|
||||
...item,
|
||||
_statusLoading: false,
|
||||
}));
|
||||
pager.total = res.data.total || 0;
|
||||
pager.page = res.data.page || 1;
|
||||
pager.page_size = res.data.page_size || 10;
|
||||
} else {
|
||||
Message.error(res.message || '获取药房列表失败');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('获取药房列表异常:', err);
|
||||
} finally {
|
||||
tableLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 搜索
|
||||
const handleQuery = () => {
|
||||
pager.page = 1;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 重置
|
||||
const handleResetQuery = () => {
|
||||
if (queryFormRef.value) {
|
||||
queryFormRef.value.resetFields();
|
||||
}
|
||||
queryForm.pharmacy_name = '';
|
||||
queryForm.pharmacy_code = '';
|
||||
queryForm.status = undefined;
|
||||
queryForm.is_pickup = undefined;
|
||||
queryForm.province_id = undefined;
|
||||
queryForm.city_id = undefined;
|
||||
queryForm.county_id = undefined;
|
||||
cityData.value = [];
|
||||
countyData.value = [];
|
||||
pager.page = 1;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 分页变化
|
||||
const handlePageChange = (page) => {
|
||||
pager.page = page;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
const handlePageSizeChange = (pageSize) => {
|
||||
pager.page_size = pageSize;
|
||||
pager.page = 1;
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
modalRef.value?.open('add');
|
||||
};
|
||||
|
||||
// 详情
|
||||
const handleDetail = (record) => {
|
||||
modalRef.value?.open('detail', record.pharmacy_id);
|
||||
};
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (record) => {
|
||||
modalRef.value?.open('edit', record.pharmacy_id);
|
||||
};
|
||||
|
||||
// 关联医生
|
||||
const handleOpenDoctorDrawer = (record) => {
|
||||
doctorDrawerRef.value?.open(record);
|
||||
};
|
||||
|
||||
// 状态切换(启用 / 禁用)
|
||||
const handleStatusToggle = async (record, val) => {
|
||||
const newStatus = val ? 1 : 0;
|
||||
const originalStatus = record.status;
|
||||
|
||||
// 场景 A:若是"启用"操作,无需迁移,直接调用原有接口
|
||||
if (newStatus === 1) {
|
||||
record._statusLoading = true;
|
||||
try {
|
||||
const res = await updatePharmacyStatus(record.pharmacy_id, 1);
|
||||
if (res.code === 200) {
|
||||
record.status = 1;
|
||||
Message.success('已启用该药房');
|
||||
} else {
|
||||
record.status = originalStatus;
|
||||
Message.error(res.message || '启用药房失败');
|
||||
}
|
||||
} catch (e) {
|
||||
record.status = originalStatus;
|
||||
Message.error('切换状态异常');
|
||||
} finally {
|
||||
record._statusLoading = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 场景 B:若是"禁用"操作,进行前置受影响医生预检
|
||||
record._statusLoading = true;
|
||||
try {
|
||||
const preCheckRes = await getAffectedDoctors(record.pharmacy_id);
|
||||
if (preCheckRes.code === 200 && preCheckRes.data?.default_doctor_count > 0) {
|
||||
// 存在受影响默认医生:阻止直接禁用,回滚开关状态并唤起分流抽屉
|
||||
record.status = originalStatus;
|
||||
record._statusLoading = false;
|
||||
transferDrawerRef.value?.open({
|
||||
pharmacy: record,
|
||||
action: 'disable',
|
||||
affectedData: preCheckRes.data,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 无受影响医生:执行常规禁用
|
||||
const res = await updatePharmacyStatus(record.pharmacy_id, 0);
|
||||
if (res.code === 200) {
|
||||
record.status = 0;
|
||||
Message.success('已禁用该药房');
|
||||
} else {
|
||||
record.status = originalStatus;
|
||||
Message.error(res.message || '禁用药房失败');
|
||||
}
|
||||
} catch (err) {
|
||||
record.status = originalStatus;
|
||||
Message.error('禁用药房预检或处理异常');
|
||||
} finally {
|
||||
record._statusLoading = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 点击删除按钮逻辑(带预检)
|
||||
const handleDeleteClick = async (record) => {
|
||||
try {
|
||||
// 1. 调用预检接口判断受影响医生
|
||||
const preCheckRes = await getAffectedDoctors(record.pharmacy_id);
|
||||
if (preCheckRes.code === 200 && preCheckRes.data?.default_doctor_count > 0) {
|
||||
// 存在受影响医生:打开分流抽屉,动作指定为 'delete'
|
||||
transferDrawerRef.value?.open({
|
||||
pharmacy: record,
|
||||
action: 'delete',
|
||||
affectedData: preCheckRes.data,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 无受影响医生:走常规删除二次弹窗确认
|
||||
Modal.warning({
|
||||
title: '确认删除药房',
|
||||
content: `确定要删除药房【${record.pharmacy_name || '-'}】吗?删除后不可恢复!`,
|
||||
hideCancel: false,
|
||||
okButtonProps: { status: 'danger' },
|
||||
onOk: async () => {
|
||||
await executeDeletePharmacy(record.pharmacy_id);
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('预检受影响医生异常:', error);
|
||||
Message.error('预检受影响医生异常');
|
||||
}
|
||||
};
|
||||
|
||||
// 执行常规删除请求
|
||||
const executeDeletePharmacy = async (pharmacyId) => {
|
||||
try {
|
||||
const res = await deletePharmacy(pharmacyId);
|
||||
if (res.code === 200) {
|
||||
Message.success('药房删除成功');
|
||||
// 如果当前页只有一条且非第一页,删除后向前退一页
|
||||
if (tableData.value.length === 1 && pager.page > 1) {
|
||||
pager.page -= 1;
|
||||
}
|
||||
fetchTableData();
|
||||
} else {
|
||||
Message.error(res.message || '删除药房失败');
|
||||
}
|
||||
} catch (err) {
|
||||
Message.error('删除药房异常');
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchTableData();
|
||||
fetchAreaList('', 2);
|
||||
console.log('[药房管理] 当前登录用户拥有的按钮权限列表:', permissionStore.buttonPermissions);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app-container {
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
:deep(.arco-form-item) {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-action-bar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.price-text {
|
||||
font-weight: 500;
|
||||
color: #ff5722;
|
||||
}
|
||||
|
||||
.ellipsis-text {
|
||||
max-width: 320px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,456 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
v-model:visible="visible"
|
||||
:title="drawerTitle"
|
||||
:width="960"
|
||||
:footer="false"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<!-- 医生信息摘要卡片 -->
|
||||
<a-card :bordered="false" class="doctor-summary-card">
|
||||
<div class="doctor-info-box">
|
||||
<a-avatar :size="60" shape="circle">
|
||||
<img v-if="currentDoctor?.avatar" :src="currentDoctor.avatar" alt="avatar" />
|
||||
<icon-user v-else />
|
||||
</a-avatar>
|
||||
<div class="doctor-meta">
|
||||
<div class="doctor-meta-name">
|
||||
<span class="name">{{ currentDoctor?.user_name || currentDoctor?.card_name || '医生' }}</span>
|
||||
<a-tag color="blue" size="small" style="margin-left: 8px">
|
||||
{{ formatDoctorTitle(currentDoctor?.doctor_title) }}
|
||||
</a-tag>
|
||||
</div>
|
||||
<div class="doctor-meta-desc">
|
||||
<span><strong>所属医院:</strong>{{ currentDoctor?.hospital_name || '-' }}</span>
|
||||
<span style="margin-left: 20px"><strong>科室:</strong>{{ currentDoctor?.department_custom_name || '-' }}</span>
|
||||
<span style="margin-left: 20px"><strong>电话:</strong>{{ currentDoctor?.mobile || currentDoctor?.user?.mobile || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<a-divider style="margin: 16px 0" />
|
||||
|
||||
<!-- 药房操作工具栏 -->
|
||||
<div class="pharmacy-action-bar">
|
||||
<div class="action-title">
|
||||
<span class="title-text">已绑定的药房列表</span>
|
||||
<span class="sub-text">(提示:每个医生仅支持设置 1 家默认发药药房)</span>
|
||||
</div>
|
||||
<a-button
|
||||
v-if="hasPermission('admin:doctorPharmacy:add')"
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="openAddModal"
|
||||
>
|
||||
<template #icon><icon-plus /></template>
|
||||
新增药房绑定
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 绑定药房表格 -->
|
||||
<a-table
|
||||
:data="pharmacyList"
|
||||
:loading="loading"
|
||||
:pagination="false"
|
||||
row-key="pharmacy_id"
|
||||
:scroll="{ x: 800 }"
|
||||
style="margin-top: 12px"
|
||||
>
|
||||
<template #columns>
|
||||
<a-table-column title="#" :width="50" align="center">
|
||||
<template #cell="{ rowIndex }">{{ rowIndex + 1 }}</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="药房名称" data-index="pharmacy_name" :width="180">
|
||||
<template #cell="{ record }">
|
||||
<div style="font-weight: 500">{{ record.pharmacy_name }}</div>
|
||||
<div style="font-size: 12px; color: #86909c">{{ record.pharmacy_code }}</div>
|
||||
</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="基础邮费" :width="90" align="right">
|
||||
<template #cell="{ record }">
|
||||
<span class="price-text">¥{{ Number(record.postage || 0).toFixed(2) }}</span>
|
||||
</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="包邮门槛" :width="110" align="right">
|
||||
<template #cell="{ record }">
|
||||
<span v-if="Number(record.free_shipping_threshold) > 0" class="price-text">
|
||||
¥{{ Number(record.free_shipping_threshold).toFixed(2) }}
|
||||
</span>
|
||||
<a-tag v-else size="small" color="blue">不设门槛</a-tag>
|
||||
</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="支持自提" :width="90" align="center">
|
||||
<template #cell="{ record }">
|
||||
<a-tag v-if="record.is_pickup === 1" color="green" size="small">支持</a-tag>
|
||||
<a-tag v-else color="gray" size="small">不支持</a-tag>
|
||||
</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="详细地址" data-index="full_address" :min-width="200">
|
||||
<template #cell="{ record }">
|
||||
<a-tooltip :content="record.full_address || record.address || '-'">
|
||||
<div class="address-cell">
|
||||
{{ record.full_address || record.address || '-' }}
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="默认药房" :width="120" align="center">
|
||||
<template #cell="{ record }">
|
||||
<a-tag v-if="record.is_default === 1" color="arcoblue" size="small">
|
||||
<template #icon><icon-check-circle-fill /></template>
|
||||
默认药房
|
||||
</a-tag>
|
||||
<a-button
|
||||
v-else-if="hasPermission('admin:doctorPharmacy:default')"
|
||||
type="outline"
|
||||
size="mini"
|
||||
:loading="record._defaultLoading"
|
||||
@click="handleSetDefault(record)"
|
||||
>
|
||||
设为默认
|
||||
</a-button>
|
||||
<span v-else style="color: #c9cdd4; font-size: 12px">普通药房</span>
|
||||
</template>
|
||||
</a-table-column>
|
||||
|
||||
<a-table-column title="操作" :width="100" align="center" fixed="right">
|
||||
<template #cell="{ record }">
|
||||
<a-popconfirm
|
||||
v-if="hasPermission('admin:doctorPharmacy:remove')"
|
||||
content="确定解除该医生与此药房的绑定关系?"
|
||||
type="warning"
|
||||
@ok="handleRemove(record)"
|
||||
>
|
||||
<a-button type="text" status="danger" size="small">
|
||||
<template #icon><icon-delete /></template>
|
||||
解除
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</template>
|
||||
</a-table-column>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 新增药房绑定弹窗 -->
|
||||
<a-modal
|
||||
v-model:visible="addModalVisible"
|
||||
title="新增医生药房绑定"
|
||||
:width="520"
|
||||
:ok-loading="addSubmitLoading"
|
||||
@ok="handleAddSubmit"
|
||||
@cancel="addModalVisible = false"
|
||||
>
|
||||
<a-form :model="addForm" ref="addFormRef" layout="vertical">
|
||||
<a-form-item
|
||||
field="pharmacy_id"
|
||||
label="选择药房"
|
||||
:rules="[{ required: true, message: '请选择要绑定的药房' }]"
|
||||
>
|
||||
<a-select
|
||||
v-model="addForm.pharmacy_id"
|
||||
placeholder="搜索并选择药房"
|
||||
allow-search
|
||||
:filter-option="false"
|
||||
@search="searchPharmacies"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in availablePharmacyOptions"
|
||||
:key="item.pharmacy_id"
|
||||
:value="item.pharmacy_id"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<span>{{ item.pharmacy_name }}</span>
|
||||
<span style="color: #86909c; font-size: 12px">{{ item.pharmacy_code }}</span>
|
||||
</div>
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="is_default" label="是否设为默认药房">
|
||||
<a-radio-group v-model="addForm.is_default">
|
||||
<a-radio :value="1">是(开方时默认推荐)</a-radio>
|
||||
<a-radio :value="0">否(仅作为可选药房)</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { usePermissionStore } from '@/store/permission';
|
||||
import {
|
||||
getDoctorPharmacyList,
|
||||
addDoctorPharmacy,
|
||||
removeDoctorPharmacy,
|
||||
setDefaultDoctorPharmacy,
|
||||
} from '@/api/doctor/pharmacy';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
|
||||
const permissionStore = usePermissionStore();
|
||||
|
||||
// 权限校验
|
||||
const hasPermission = (permission) => {
|
||||
const perms = permissionStore.buttonPermissions || [];
|
||||
return perms.includes('*') || perms.includes(permission);
|
||||
};
|
||||
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const currentDoctor = ref(null);
|
||||
const pharmacyList = ref([]);
|
||||
|
||||
// 弹窗表单状态
|
||||
const addModalVisible = ref(false);
|
||||
const addSubmitLoading = ref(false);
|
||||
const addFormRef = ref(null);
|
||||
const allPharmacies = ref([]);
|
||||
const searchKeyword = ref('');
|
||||
|
||||
const addForm = reactive({
|
||||
pharmacy_id: undefined,
|
||||
is_default: 0,
|
||||
});
|
||||
|
||||
const drawerTitle = computed(() => {
|
||||
const name = currentDoctor.value?.user_name || currentDoctor.value?.card_name || '';
|
||||
return name ? `药房配置 - ${name}` : '药房配置';
|
||||
});
|
||||
|
||||
// 格式化医生职称
|
||||
const formatDoctorTitle = (titleVal) => {
|
||||
const map = {
|
||||
1: '主任医师',
|
||||
2: '主任中医师',
|
||||
3: '副主任医师',
|
||||
4: '副主任中医师',
|
||||
5: '主治医师',
|
||||
6: '住院医师',
|
||||
};
|
||||
return map[titleVal] || '医生';
|
||||
};
|
||||
|
||||
// 过滤掉已绑定的药房并支持关键词搜索
|
||||
const availablePharmacyOptions = computed(() => {
|
||||
const boundIds = new Set(pharmacyList.value.map((item) => String(item.pharmacy_id)));
|
||||
return allPharmacies.value.filter((item) => {
|
||||
// 过滤掉已绑定的
|
||||
if (boundIds.has(String(item.pharmacy_id))) return false;
|
||||
// 关键字搜索
|
||||
if (!searchKeyword.value) return true;
|
||||
const kw = searchKeyword.value.toLowerCase();
|
||||
const nameMatch = item.pharmacy_name && item.pharmacy_name.toLowerCase().includes(kw);
|
||||
const codeMatch = item.pharmacy_code && item.pharmacy_code.toLowerCase().includes(kw);
|
||||
return nameMatch || codeMatch;
|
||||
});
|
||||
});
|
||||
|
||||
// 搜索药房选项
|
||||
const searchPharmacies = (query) => {
|
||||
searchKeyword.value = query || '';
|
||||
};
|
||||
|
||||
// 加载全部可用药房备选列表(状态为正常的药房)
|
||||
const fetchAllPharmacies = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList({ status: 1 });
|
||||
if (res.code === 200 && res.data) {
|
||||
allPharmacies.value = res.data;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载系统药房列表异常:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// 获取该医生的药房绑定列表
|
||||
const fetchDoctorPharmacies = async () => {
|
||||
if (!currentDoctor.value?.doctor_id) return;
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getDoctorPharmacyList(currentDoctor.value.doctor_id);
|
||||
if (res.code === 200 && res.data) {
|
||||
pharmacyList.value = res.data.map((item) => ({
|
||||
...item,
|
||||
_defaultLoading: false,
|
||||
}));
|
||||
} else {
|
||||
Message.error(res.message || '获取绑定药房列表失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取绑定药房失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 打开抽屉
|
||||
const open = async (doctor) => {
|
||||
currentDoctor.value = doctor;
|
||||
visible.value = true;
|
||||
await fetchDoctorPharmacies();
|
||||
};
|
||||
|
||||
// 打开新增绑定弹窗
|
||||
const openAddModal = () => {
|
||||
if (allPharmacies.value.length === 0) {
|
||||
fetchAllPharmacies();
|
||||
}
|
||||
addForm.pharmacy_id = undefined;
|
||||
// 若当前尚未绑定任何药房,默认勾选设为默认
|
||||
addForm.is_default = pharmacyList.value.length === 0 ? 1 : 0;
|
||||
searchKeyword.value = '';
|
||||
addModalVisible.value = true;
|
||||
};
|
||||
|
||||
// 提交新增绑定
|
||||
const handleAddSubmit = async () => {
|
||||
if (!addFormRef.value) return;
|
||||
const errors = await addFormRef.value.validate();
|
||||
if (errors) return;
|
||||
|
||||
addSubmitLoading.value = true;
|
||||
try {
|
||||
const res = await addDoctorPharmacy({
|
||||
doctor_id: String(currentDoctor.value.doctor_id),
|
||||
pharmacy_id: String(addForm.pharmacy_id),
|
||||
is_default: Number(addForm.is_default),
|
||||
});
|
||||
if (res.code === 200) {
|
||||
Message.success('药房绑定成功');
|
||||
addModalVisible.value = false;
|
||||
fetchDoctorPharmacies();
|
||||
} else {
|
||||
Message.error(res.message || '新增绑定失败');
|
||||
}
|
||||
} catch (error) {
|
||||
Message.error('新增绑定出现异常');
|
||||
} finally {
|
||||
addSubmitLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 设为默认药房
|
||||
const handleSetDefault = async (record) => {
|
||||
record._defaultLoading = true;
|
||||
try {
|
||||
const res = await setDefaultDoctorPharmacy(
|
||||
record.doctor_pharmacy_id || record.pharmacy_id
|
||||
);
|
||||
if (res.code === 200) {
|
||||
Message.success(`已将【${record.pharmacy_name}】设为默认药房`);
|
||||
fetchDoctorPharmacies();
|
||||
} else {
|
||||
Message.error(res.message || '设置默认药房失败');
|
||||
}
|
||||
} catch (error) {
|
||||
Message.error('设置默认药房异常');
|
||||
} finally {
|
||||
record._defaultLoading = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 解除绑定
|
||||
const handleRemove = async (record) => {
|
||||
try {
|
||||
const res = await removeDoctorPharmacy(
|
||||
record.doctor_pharmacy_id || record.pharmacy_id
|
||||
);
|
||||
if (res.code === 200) {
|
||||
Message.success('已解除药房绑定');
|
||||
fetchDoctorPharmacies();
|
||||
} else {
|
||||
Message.error(res.message || '解除绑定失败');
|
||||
}
|
||||
} catch (error) {
|
||||
Message.error('解除绑定出现异常');
|
||||
}
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.doctor-summary-card {
|
||||
background-color: #f7f8fa;
|
||||
border-radius: 6px;
|
||||
|
||||
:deep(.arco-card-body) {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-info-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.doctor-meta {
|
||||
margin-left: 16px;
|
||||
flex: 1;
|
||||
|
||||
.doctor-meta-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-meta-desc {
|
||||
margin-top: 6px;
|
||||
font-size: 13px;
|
||||
color: #4e5969;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pharmacy-action-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.action-title {
|
||||
.title-text {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
.sub-text {
|
||||
font-size: 12px;
|
||||
color: #86909c;
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-text {
|
||||
font-weight: 500;
|
||||
color: #ff5722;
|
||||
}
|
||||
|
||||
.address-cell {
|
||||
max-width: 260px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
</style>
|
||||
@@ -176,6 +176,8 @@
|
||||
@click="handleDetail(record)"><icon-book />详情</a-button>
|
||||
<a-button v-has="'admin:sysDoctorList:edit'" type="text" @click="handleUpdate(record)"><icon-edit />
|
||||
修改</a-button>
|
||||
<a-button v-has="'admin:doctorPharmacy:list'" type="text"
|
||||
@click="handleOpenPharmacyDrawer(record)"><icon-home />药房配置</a-button>
|
||||
<!-- <a-button v-has="'admin:sysDoctorList:remove'" type="text"
|
||||
@click="() => { deleteVisible = true; deleteData = [record.doctor_id]; }"><icon-delete /> 删除</a-button> -->
|
||||
</a-space>
|
||||
@@ -345,6 +347,50 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">绑定药房</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px;">
|
||||
<a-col :span="24">
|
||||
<a-form-item field="doctor_pharmacy" label="关联药房:">
|
||||
<a-select
|
||||
v-if="modalSatus !== 'detail'"
|
||||
v-model="modalForm.doctor_pharmacy"
|
||||
multiple
|
||||
allow-clear
|
||||
allow-search
|
||||
placeholder="请选择医生关联的药房(支持多选)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in pharmacyOptions"
|
||||
:key="item.pharmacy_id"
|
||||
:value="String(item.pharmacy_id)"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }} ({{ item.pharmacy_code }})
|
||||
</a-option>
|
||||
</a-select>
|
||||
<div v-else style="width: 100%">
|
||||
<a-space wrap v-if="modalForm.doctor_pharmacy_list && modalForm.doctor_pharmacy_list.length > 0">
|
||||
<a-tag
|
||||
v-for="item in modalForm.doctor_pharmacy_list"
|
||||
:key="item.pharmacy_id"
|
||||
:color="item.is_default === 1 ? 'arcoblue' : 'gray'"
|
||||
size="medium"
|
||||
>
|
||||
<template #icon v-if="item.is_default === 1"><icon-check-circle-fill /></template>
|
||||
{{ item.pharmacy_name }}
|
||||
<span v-if="item.is_default === 1" style="margin-left: 4px; font-weight: bold">(默认)</span>
|
||||
</a-tag>
|
||||
</a-space>
|
||||
<span v-else style="color: #86909c">暂未绑定任何药房</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">是否推荐</div>
|
||||
@@ -694,6 +740,9 @@
|
||||
<div v-else-if="okStatus == 6">确定申请CA证书?</div>
|
||||
<div v-else-if="okStatus == 7">修改职称或者执业证/资格证,需要先在【四川省互联网医疗服务监管平台】修改备案信息成功后,才可保存 (谨慎操作) 。</div>
|
||||
</a-modal>
|
||||
|
||||
<!-- 医生绑定药房抽屉 -->
|
||||
<DoctorPharmacyDrawer ref="pharmacyDrawerRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -701,6 +750,8 @@
|
||||
import { reactive, ref, getCurrentInstance, onMounted, nextTick, watch } from 'vue';
|
||||
import { getDoctorList, addDoctor, removeDoctor, updateDoctor, getDoctorDetail, departmentList, decryptCard, hospitalList, expertiseList, areaList, bankList, decryptBank, exportDoctor } from '@/api/doctor/list';
|
||||
import { applyCA, updateCA, removeCA, updateSign, applySign } from '@/api/doctor/ca';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
import DoctorPharmacyDrawer from './components/doctorPharmacyDrawer.vue';
|
||||
import { ossSign, ossUpload } from '@/api/oss';
|
||||
import { parseTime } from '@/utils/parseTime';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
@@ -772,7 +823,25 @@ const modalForm = reactive({
|
||||
cur_doctor_expertise: [],
|
||||
avatar: 'https://img.applets.igandanyiyuan.com/basic/file/doctor_avatar.png',
|
||||
bank_card_code: '',
|
||||
doctor_pharmacy: [],
|
||||
doctor_pharmacy_list: [],
|
||||
});
|
||||
const pharmacyDrawerRef = ref(null);
|
||||
const pharmacyOptions = ref([]);
|
||||
const handleOpenPharmacyDrawer = (record) => {
|
||||
pharmacyDrawerRef.value?.open(record);
|
||||
};
|
||||
const loadPharmacyOptions = async () => {
|
||||
if (pharmacyOptions.value.length > 0) return;
|
||||
try {
|
||||
const res = await getPharmacyList({ status: 1 });
|
||||
if (res.code === 200 && res.data) {
|
||||
pharmacyOptions.value = res.data;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载药房选项失败:', e);
|
||||
}
|
||||
};
|
||||
const hospital_name = ref('');
|
||||
watch(() => modalForm.hospital, () => {
|
||||
if (modalForm.hospital && modalForm.hospital.hospital_name) {
|
||||
@@ -1098,7 +1167,7 @@ const columns = [
|
||||
|
||||
{ title: '状态', dataIndex: 'status', slotName: 'status' },
|
||||
// { title: '创建时间', dataIndex: 'created_at', slotName: 'created_at' },
|
||||
{ title: '操作', slotName: 'action', fixed: "right", width: 180 },
|
||||
{ title: '操作', slotName: 'action', fixed: "right", width: 280 },
|
||||
];
|
||||
|
||||
// Table Data
|
||||
@@ -1115,6 +1184,7 @@ const changeSelect = (value) => {
|
||||
|
||||
// 新增Satus
|
||||
const handleAdd = () => {
|
||||
loadPharmacyOptions();
|
||||
modalVisible.value = true;
|
||||
modalTitle.value = '新增医生';
|
||||
modalSatus.value = 'add';
|
||||
@@ -1135,6 +1205,8 @@ const handleAdd = () => {
|
||||
modalForm.sign_image = '';
|
||||
modalForm.doctor_bank_card = {
|
||||
}
|
||||
modalForm.doctor_pharmacy = [];
|
||||
modalForm.doctor_pharmacy_list = [];
|
||||
|
||||
license_cert_list.value = [];
|
||||
qualification_cert_list.value = [];
|
||||
@@ -1198,10 +1270,18 @@ const handleDetail = async (record) => {
|
||||
}
|
||||
modalForm.cur_doctor_expertise = arr;
|
||||
}
|
||||
if (data.doctor_pharmacy && Array.isArray(data.doctor_pharmacy)) {
|
||||
modalForm.doctor_pharmacy_list = data.doctor_pharmacy;
|
||||
modalForm.doctor_pharmacy = data.doctor_pharmacy.map((item) => String(item.pharmacy_id));
|
||||
} else {
|
||||
modalForm.doctor_pharmacy_list = [];
|
||||
modalForm.doctor_pharmacy = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
// 修改
|
||||
const handleUpdate = async (record) => {
|
||||
loadPharmacyOptions();
|
||||
modalVisible.value = true;
|
||||
modalTitle.value = '修改医生';
|
||||
modalSatus.value = 'edit';
|
||||
@@ -1266,6 +1346,13 @@ const handleUpdate = async (record) => {
|
||||
})
|
||||
modalForm.cur_doctor_expertise = arr;
|
||||
}
|
||||
if (data.doctor_pharmacy && Array.isArray(data.doctor_pharmacy)) {
|
||||
modalForm.doctor_pharmacy_list = data.doctor_pharmacy;
|
||||
modalForm.doctor_pharmacy = data.doctor_pharmacy.map((item) => String(item.pharmacy_id));
|
||||
} else {
|
||||
modalForm.doctor_pharmacy_list = [];
|
||||
modalForm.doctor_pharmacy = [];
|
||||
}
|
||||
}
|
||||
//await nextTick();
|
||||
|
||||
@@ -1386,7 +1473,8 @@ const handleSubmit = (done) => {
|
||||
bank_card_province_id: modalForm.doctor_bank_card.province_id ? modalForm.doctor_bank_card.province_id : 0,
|
||||
bank_card_city_id: modalForm.doctor_bank_card.city_id ? modalForm.doctor_bank_card.city_id : 0,
|
||||
bank_card_county_id: modalForm.doctor_bank_card.county_id ? modalForm.doctor_bank_card.county_id : 0,
|
||||
bank_id: modalForm.doctor_bank_card.bank_id
|
||||
bank_id: modalForm.doctor_bank_card.bank_id,
|
||||
doctor_pharmacy: modalForm.doctor_pharmacy || []
|
||||
}
|
||||
if(modalForm.is_transfer_prescription == 1 || modalForm.is_transfer_prescription ==0) {
|
||||
modalData.is_transfer_prescription = modalForm.is_transfer_prescription;
|
||||
@@ -1784,7 +1872,6 @@ onMounted(() => {
|
||||
handelAreaList("", "", 2);
|
||||
handleBankList();
|
||||
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -5,8 +5,18 @@
|
||||
<a-form-item field="product_name" label="药品名称">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.product_name" placeholder="请输入药品名称或通用名" @press-enter="handleQuery" />
|
||||
</a-form-item>
|
||||
<a-form-item field="product_pharmacy_code" label="药店编码">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.product_pharmacy_code" placeholder="请输入药品编码" @press-enter="handleQuery" />
|
||||
<a-form-item field="pharmacy_id" label="所属药房">
|
||||
<a-select v-model="queryForm.pharmacy_id" placeholder="请选择所属药房" allow-clear allow-search :style="{ width: '182px' }">
|
||||
<a-option v-for="item in pharmacyList" :key="item.pharmacy_id" :value="String(item.pharmacy_id)">
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="product_pharmacy_code" label="第三方药品编码">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.product_pharmacy_code" placeholder="请输入第三方药品编码" @press-enter="handleQuery" />
|
||||
</a-form-item>
|
||||
<a-form-item field="pharmacy_code" label="药店编码">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.pharmacy_code" placeholder="请输入药店编码" @press-enter="handleQuery" />
|
||||
</a-form-item>
|
||||
<a-form-item field="manufacturer" label="生产企业">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.manufacturer" placeholder="请输入生产企业" @press-enter="handleQuery" />
|
||||
@@ -47,6 +57,7 @@
|
||||
|
||||
<!-- table -->
|
||||
<a-table :columns="columns" :data="tableData"
|
||||
:scroll="{ x: 1700 }"
|
||||
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
|
||||
:pagination="{ 'show-total': true, 'show-jumper': true, 'show-page-size': true, total: pager.total, current: currentPage }"
|
||||
row-key="family_id" @selection-change="(selection) => {deleteData = selection;console.log(selection)}"
|
||||
@@ -54,6 +65,12 @@
|
||||
<template #doctor_id="{record,rowIndex}">
|
||||
<div>{{(rowIndex+1)+(pager.page-1)*pager.page_size}}</div>
|
||||
</template>
|
||||
<template #pharmacy_name="{record}">
|
||||
<div>{{ record.pharmacy_name || record.pharmacy?.pharmacy_name || '-' }}</div>
|
||||
<div v-if="record.pharmacy_code || record.pharmacy?.pharmacy_code" style="font-size: 12px; color: #86909c;">
|
||||
{{ record.pharmacy_code || record.pharmacy?.pharmacy_code }}
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-button v-has="'admin:platformMedinceList:detail'" type="text"
|
||||
@@ -84,7 +101,9 @@
|
||||
<script setup>
|
||||
import { reactive, ref, getCurrentInstance, onMounted, nextTick, watch, computed } from 'vue';
|
||||
import { getMedinceList,getMedinceDetail} from '@/api/medince/list';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
import { downloadFile } from '@/utils/downloadFile';
|
||||
const pharmacyList = ref([]);
|
||||
// Akiraka 20230210 删除数据
|
||||
const deleteData = ref([])
|
||||
// Akiraka 20230210 删除对话框
|
||||
@@ -111,7 +130,9 @@
|
||||
};
|
||||
// form
|
||||
const queryForm = reactive({
|
||||
|
||||
pharmacy_id: undefined,
|
||||
pharmacy_code: '',
|
||||
product_pharmacy_code: '',
|
||||
});
|
||||
const modalForm = reactive({
|
||||
user:{},
|
||||
@@ -140,10 +161,12 @@
|
||||
{ title: '编号', dataIndex: 'doctor_id', slotName: 'doctor_id', width: '90' },
|
||||
{ title: '药品名称', dataIndex: 'product_name',width:200 },
|
||||
{ title: '规格', dataIndex: 'product_spec',width:200 },
|
||||
{ title: '所属药房', dataIndex: 'pharmacy_name', slotName: 'pharmacy_name', width: 170, ellipsis: true },
|
||||
{ title: '单价(元)', dataIndex: 'product_price', slotName: 'product_price',width: 150 },
|
||||
{ title: '批准文号', dataIndex: 'license_number',width:200 },
|
||||
{ title: '生产厂家', dataIndex: 'manufacturer',width:200 },
|
||||
{ title: '药店编码', dataIndex: 'product_pharmacy_code',width:100 },
|
||||
{ title: '第三方药品编码', dataIndex: 'product_pharmacy_code', width: 120, ellipsis: true },
|
||||
// { title: '药房编码', dataIndex: 'pharmacy_code', width: 160, ellipsis: true },
|
||||
// { title: '启用状态', dataIndex: 'status', slotName: 'status' },
|
||||
{ title: '操作', slotName: 'action', fixed: "right", width: 180 },
|
||||
];
|
||||
@@ -234,6 +257,9 @@
|
||||
// 重置搜索
|
||||
const handleResetQuery = () => {
|
||||
proxy.$refs.queryFormRef.resetFields();
|
||||
queryForm.pharmacy_id = undefined;
|
||||
queryForm.pharmacy_code = '';
|
||||
queryForm.product_pharmacy_code = '';
|
||||
getMedinceInfo(queryForm);
|
||||
}
|
||||
const handlExport=async(type)=>{
|
||||
@@ -274,8 +300,21 @@
|
||||
proxy.$loading.hide();
|
||||
}
|
||||
|
||||
// 获取药房下拉列表
|
||||
const fetchPharmacyList = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList();
|
||||
if (res.code === 200) {
|
||||
pharmacyList.value = res.data || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取药房列表异常:', e);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getMedinceInfo(pager);
|
||||
fetchPharmacyList();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -12,8 +12,18 @@
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.mnemonic_code" placeholder="请输入药品助记码" @press-enter="handleQuery" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item field="product_pharmacy_code" label="药店编码">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.product_pharmacy_code" placeholder="请输入药品编码" @press-enter="handleQuery" />
|
||||
<a-form-item field="pharmacy_code" label="药店编码">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.pharmacy_code" placeholder="请输入药品编码" @press-enter="handleQuery" />
|
||||
</a-form-item>
|
||||
<a-form-item field="pharmacy_id" label="所属药房">
|
||||
<a-select v-model="queryForm.pharmacy_id" placeholder="请选择所属药房" allow-clear allow-search :style="{ width: '182px' }">
|
||||
<a-option v-for="item in pharmacyList" :key="item.pharmacy_id" :value="item.pharmacy_id">
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="pharmacy_code" label="药房编码">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.pharmacy_code" placeholder="请输入药房编码" @press-enter="handleQuery" />
|
||||
</a-form-item>
|
||||
<a-form-item field="manufacturer" label="生产企业">
|
||||
<a-input :style="{ width: '182px' }" v-model="queryForm.manufacturer" placeholder="请输入生产企业" @press-enter="handleQuery" />
|
||||
@@ -69,6 +79,7 @@
|
||||
|
||||
<!-- table -->
|
||||
<a-table :columns="columns" :data="tableData"
|
||||
:scroll="{ x: 2000 }"
|
||||
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
|
||||
:pagination="{ 'show-total': true, 'show-jumper': true, 'show-page-size': true, total: pager.total, current: currentPage }"
|
||||
row-key="product_id" @selection-change="(selection) => {deleteData = selection;console.log(selection)}"
|
||||
@@ -76,6 +87,12 @@
|
||||
<template #doctor_id="{record,rowIndex}">
|
||||
<div>{{(rowIndex+1)+(pager.page-1)*pager.page_size}}</div>
|
||||
</template>
|
||||
<template #pharmacy_name="{record}">
|
||||
<div>{{ record.pharmacy_name || '-' }}</div>
|
||||
<div v-if="record.pharmacy_code" style="font-size: 12px; color: #86909c;">
|
||||
{{ record.pharmacy_code }}
|
||||
</div>
|
||||
</template>
|
||||
<template #product_status="{record}">
|
||||
<a-tag v-if="record.product_status == 1" color="green">{{formatProductStatus(record.product_status)}}</a-tag>
|
||||
<a-tag v-else-if="record.product_status == 2" color="red">{{formatProductStatus(record.product_status)}}</a-tag>
|
||||
@@ -113,8 +130,10 @@
|
||||
<script setup>
|
||||
import { reactive, ref, getCurrentInstance, onMounted, nextTick, watch, computed } from 'vue';
|
||||
import { getSysMedinceList,getSysMedinceDetail,exportProduct} from '@/api/medince/list';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
import { downloadFile } from '@/utils/downloadFile';
|
||||
import {formatProductStatus} from '@/utils/format';
|
||||
const pharmacyList = ref([]);
|
||||
// Akiraka 20230210 删除数据
|
||||
const deleteData = ref([])
|
||||
// Akiraka 20230210 删除对话框
|
||||
@@ -142,6 +161,8 @@
|
||||
};
|
||||
// form
|
||||
const queryForm = reactive({
|
||||
pharmacy_id: undefined,
|
||||
pharmacy_code: '',
|
||||
order:{
|
||||
stock:''
|
||||
}
|
||||
@@ -174,10 +195,11 @@
|
||||
{ title: '药品名称', dataIndex: 'product_name',width:200 },
|
||||
{ title: '通用名称', dataIndex: 'common_name',width:200 },
|
||||
{ title: '规格', dataIndex: 'product_spec',width:200 },
|
||||
{ title: '所属药房', dataIndex: 'pharmacy_name', slotName: 'pharmacy_name', width: 170, ellipsis: true },
|
||||
{ title: '单价(元)', dataIndex: 'product_price', slotName: 'product_price',width: 150 },
|
||||
{ title: '批准文号', dataIndex: 'license_number',width:200 },
|
||||
{ title: '生产厂家', dataIndex: 'manufacturer',width:200 },
|
||||
{ title: '药店编码', dataIndex: 'product_pharmacy_code',width:100 },
|
||||
{ title: '药店编码', dataIndex: 'pharmacy_code',width:100 },
|
||||
{ title: '库存', dataIndex: 'stock',width:100 },
|
||||
{ title: '购买上限', dataIndex: 'prescription_num',width:100 },
|
||||
{ title: '状态', dataIndex: 'product_status',slotName:'product_status',width:100 },
|
||||
@@ -196,6 +218,9 @@
|
||||
modalTitle.value = '新增药品';
|
||||
modalSatus.value = 'add';
|
||||
modalForm.product_id ='';
|
||||
modalForm.pharmacy_id = '';
|
||||
modalForm.pharmacy_name = '';
|
||||
modalForm.pharmacy_code = '';
|
||||
modalForm.frequency_use =null;
|
||||
modalForm.available_days =null;
|
||||
modalForm.product_name ='';
|
||||
@@ -296,6 +321,8 @@
|
||||
// 重置搜索
|
||||
const handleResetQuery = () => {
|
||||
proxy.$refs.queryFormRef.resetFields();
|
||||
queryForm.pharmacy_id = undefined;
|
||||
queryForm.pharmacy_code = '';
|
||||
queryForm.order.stock='';
|
||||
getMedinceInfo(queryForm);
|
||||
}
|
||||
@@ -339,8 +366,22 @@
|
||||
}
|
||||
proxy.$loading.hide();
|
||||
}
|
||||
|
||||
// 获取药房下拉数据
|
||||
const fetchPharmacyList = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList();
|
||||
if (res.code === 200) {
|
||||
pharmacyList.value = res.data || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取药房列表异常:', e);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getMedinceInfo(pager);
|
||||
fetchPharmacyList();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -195,6 +195,24 @@
|
||||
<a-option :value="2">上报失败</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="pharmacy_id" label="发货药房">
|
||||
<a-select
|
||||
v-model="queryForm.pharmacy_id"
|
||||
placeholder="全部药房"
|
||||
allow-clear
|
||||
allow-search
|
||||
:style="{ width: '182px' }"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in pharmacyList"
|
||||
:key="item.pharmacy_id"
|
||||
:value="item.pharmacy_id"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-row>
|
||||
<a-form-item field="delivery_range_time" label="发货时间范围">
|
||||
<a-range-picker
|
||||
@@ -252,7 +270,7 @@
|
||||
<!-- table -->
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:scroll="{ x: 1980 }"
|
||||
:scroll="{ x: 2140 }"
|
||||
:data="tableData"
|
||||
:pagination="{
|
||||
'show-total': true,
|
||||
@@ -300,6 +318,9 @@
|
||||
record.patient_sex == 1 ? '男,' : '女,'
|
||||
}}{{ record.patient_age }}岁)
|
||||
</template>
|
||||
<template #pharmacy_name="{ record }">
|
||||
<span>{{ record.pharmacy_name || '-' }}</span>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-button
|
||||
@@ -409,6 +430,37 @@
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox">
|
||||
<div class="bar"></div>
|
||||
<div class="name">发货药房信息</div>
|
||||
</div>
|
||||
<a-row :gutter="24" style="margin-top: 35px">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房名称:">
|
||||
<div class="box">
|
||||
<span>{{ modalForm.pharmacy_name || modalForm.pharmacy?.pharmacy_name || '-' }}</span>
|
||||
</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房代码:">
|
||||
<div class="box">{{ modalForm.pharmacy_code || modalForm.pharmacy?.pharmacy_code || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="24">
|
||||
<a-col :span="12">
|
||||
<a-form-item label="联系电话:">
|
||||
<div class="box">{{ modalForm.pharmacy?.telephone || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-item label="药房地址:">
|
||||
<div class="box">{{ modalForm.pharmacy?.full_address || modalForm.pharmacy?.address || '-' }}</div>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<div class="titlebox" v-if="modalForm.order_product_refund">
|
||||
<div class="bar"></div>
|
||||
<div class="name">退款信息</div>
|
||||
@@ -878,6 +930,7 @@ import {
|
||||
inquiryCase,
|
||||
exportProduct
|
||||
} from '@/api/order/list';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
import { parseTime } from '@/utils/parseTime';
|
||||
import {
|
||||
formatDoctorTitle,
|
||||
@@ -888,6 +941,7 @@ import {
|
||||
} from '@/utils/format';
|
||||
const IMG_URL = import.meta.env.VITE_IMG_URL;
|
||||
import { downloadFile } from '@/utils/downloadFile';
|
||||
const pharmacyList = ref([]);
|
||||
// Akiraka 20230210 删除数据
|
||||
const deleteData = ref([]);
|
||||
// Akiraka 20230210 删除对话框
|
||||
@@ -1044,6 +1098,7 @@ const columns = [
|
||||
{ title: '药品名称', dataIndex: 'product_name', width: 150 },
|
||||
{ title: '药品备注', dataIndex: 'remarks', width: 130 },
|
||||
{ title: '就诊人联系电话', dataIndex: 'patient_mobile', width: 130 },
|
||||
{ title: '发货药房', dataIndex: 'pharmacy_name', slotName: 'pharmacy_name', width: 160, ellipsis: true },
|
||||
{ title: '订单金额', dataIndex: 'amount_total', slotName: 'amount_total' },
|
||||
{
|
||||
title: '实付金额',
|
||||
@@ -1245,8 +1300,8 @@ const closeChangeOk = (data) => {
|
||||
// 重置搜索
|
||||
const handleResetQuery = () => {
|
||||
proxy.$refs.queryFormRef.resetFields();
|
||||
queryForm.pharmacy_id = undefined;
|
||||
currentPage.value=1;
|
||||
//getProductInfo(queryForm);
|
||||
handleQuery();
|
||||
};
|
||||
const openDcotor = () => {
|
||||
@@ -1298,11 +1353,24 @@ const handlExport=async(type)=>{
|
||||
}
|
||||
proxy.$loading.hide();
|
||||
}
|
||||
|
||||
// 获取药房下拉数据
|
||||
const fetchPharmacyList = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList();
|
||||
if (res.code === 200) {
|
||||
pharmacyList.value = res.data || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取药房列表异常:', e);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
let userInfo=localStorage.getItem('manage-userInfo')?JSON.parse(localStorage.getItem('manage-userInfo')):{};
|
||||
showTransferDoctor.value=userInfo.role_name!='处方流转平台';
|
||||
getProductInfo(pager);
|
||||
|
||||
fetchPharmacyList();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -44,6 +44,24 @@
|
||||
<a-option :value="2">审核驳回</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="pharmacy_id" label="开方药房">
|
||||
<a-select
|
||||
v-model="queryForm.pharmacy_id"
|
||||
placeholder="全部药房"
|
||||
allow-clear
|
||||
allow-search
|
||||
:style="{ width: '182px' }"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in pharmacyList"
|
||||
:key="item.pharmacy_id"
|
||||
:value="item.pharmacy_id"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-row>
|
||||
<a-form-item field="pharmacist_verify_range_time" label="审核时间范围">
|
||||
<a-range-picker
|
||||
@@ -86,7 +104,7 @@
|
||||
|
||||
<!-- table -->
|
||||
<a-table :columns="columns" :data="tableData"
|
||||
:scroll="{ x: 1400 }"
|
||||
:scroll="{ x: 1560 }"
|
||||
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
|
||||
:pagination="{ 'show-total': true, 'show-jumper': true, 'show-page-size': true, total: pager.total, current: currentPage }"
|
||||
row-key="order_prescription_id" @selection-change="(selection) => {deleteData = selection;console.log(selection)}"
|
||||
@@ -113,6 +131,9 @@
|
||||
record.patient_sex == 1 ? '男,' : '女,'
|
||||
}}{{ record.patient_age }}岁)</div>
|
||||
</template>
|
||||
<template #pharmacy_name="{record}">
|
||||
<span>{{ record.pharmacy_name || '-' }}</span>
|
||||
</template>
|
||||
<template #order_prescription_icd="{record}">
|
||||
<div class="doctor_name" :title="record.order_prescription_icd">{{record.order_prescription_icd}}</div>
|
||||
</template>
|
||||
@@ -146,9 +167,12 @@
|
||||
<script setup>
|
||||
import { reactive, ref, getCurrentInstance, onMounted, nextTick, watch, computed } from 'vue';
|
||||
import { getPrescriptionList,getPrescriptionDetail,exportPrescription} from '@/api/prescription/list';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
|
||||
import {formatPrescriptionStatus} from "@/utils/format"
|
||||
import { downloadFile } from '@/utils/downloadFile';
|
||||
|
||||
const pharmacyList = ref([]);
|
||||
// Akiraka 20230210 删除数据
|
||||
const deleteData = ref([])
|
||||
// Akiraka 20230210 删除对话框
|
||||
@@ -245,6 +269,7 @@ watch(() => queryForm.expired_range_time,
|
||||
{ title: '药师姓名', dataIndex: 'pharmacist_name',slotName:'pharmacist_name' },
|
||||
{ title: '就诊人', dataIndex: 'patient_name', slotName: 'patient_name',width:180 },
|
||||
{ title: '就诊人联系电话', dataIndex: 'mobile',width:130 },
|
||||
{ title: '开方药房', dataIndex: 'pharmacy_name', slotName: 'pharmacy_name', width: 160, ellipsis: true },
|
||||
{ title: '诊断', dataIndex: 'order_prescription_icd',slotName: 'order_prescription_icd' },
|
||||
{ title: '处方状态', dataIndex: 'prescription_status',slotName:'prescription_status' },
|
||||
{ title: '开方时间', dataIndex: 'created_at',slotName:'created_at',width:180 },
|
||||
@@ -338,10 +363,9 @@ watch(() => queryForm.expired_range_time,
|
||||
// 重置搜索
|
||||
const handleResetQuery = () => {
|
||||
proxy.$refs.queryFormRef.resetFields();
|
||||
//getPrescriptionInfo(queryForm);
|
||||
queryForm.pharmacy_id = undefined;
|
||||
currentPage.value=1;
|
||||
//getProductInfo(queryForm);
|
||||
handleQuery();
|
||||
handleQuery();
|
||||
}
|
||||
const handlExport=async(type)=>{
|
||||
proxy.$loading.show();
|
||||
@@ -381,9 +405,21 @@ watch(() => queryForm.expired_range_time,
|
||||
proxy.$loading.hide();
|
||||
}
|
||||
|
||||
// 获取药房下拉数据
|
||||
const fetchPharmacyList = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList();
|
||||
if (res.code === 200) {
|
||||
pharmacyList.value = res.data || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取药房列表异常:', e);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getPrescriptionInfo(pager);
|
||||
fetchPharmacyList();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -44,6 +44,24 @@
|
||||
<a-option :value="2">审核驳回</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="pharmacy_id" label="开方药房">
|
||||
<a-select
|
||||
v-model="queryForm.pharmacy_id"
|
||||
placeholder="全部药房"
|
||||
allow-clear
|
||||
allow-search
|
||||
:style="{ width: '182px' }"
|
||||
>
|
||||
<a-option
|
||||
v-for="item in pharmacyList"
|
||||
:key="item.pharmacy_id"
|
||||
:value="item.pharmacy_id"
|
||||
:label="item.pharmacy_name"
|
||||
>
|
||||
{{ item.pharmacy_name }}
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-row>
|
||||
<a-form-item field="pharmacist_verify_range_time" label="审核时间范围">
|
||||
<a-range-picker
|
||||
@@ -86,7 +104,7 @@
|
||||
|
||||
<!-- table -->
|
||||
<a-table :columns="columns" :data="tableData"
|
||||
:scroll="{ x: 1400 }"
|
||||
:scroll="{ x: 1560 }"
|
||||
:row-selection="{ type: 'checkbox', showCheckedAll: true }"
|
||||
:pagination="{ 'show-total': true, 'show-jumper': true, 'show-page-size': true, total: pager.total, current: currentPage }"
|
||||
row-key="order_prescription_id" @selection-change="(selection) => {deleteData = selection;console.log(selection)}"
|
||||
@@ -113,6 +131,9 @@
|
||||
record.patient_sex == 1 ? '男,' : '女,'
|
||||
}}{{ record.patient_age }}岁)</div>
|
||||
</template>
|
||||
<template #pharmacy_name="{record}">
|
||||
<span>{{ record.pharmacy_name || '-' }}</span>
|
||||
</template>
|
||||
<template #order_prescription_icd="{record}">
|
||||
<div class="doctor_name" :title="record.order_prescription_icd">{{record.order_prescription_icd}}</div>
|
||||
</template>
|
||||
@@ -146,10 +167,12 @@
|
||||
<script setup>
|
||||
import { reactive, ref, getCurrentInstance, onMounted, nextTick, watch, computed } from 'vue';
|
||||
import { getPrescriptionList,getPrescriptionDetail,exportPrescription} from '@/api/prescription/transfer-list';
|
||||
import { getPharmacyList } from '@/api/basic/pharmacy';
|
||||
|
||||
import {formatPrescriptionStatus} from "@/utils/format"
|
||||
import { downloadFile } from '@/utils/downloadFile';
|
||||
const showTransferDoctor = ref(false)
|
||||
const pharmacyList = ref([]);
|
||||
|
||||
// Akiraka 20230210 删除数据
|
||||
const deleteData = ref([])
|
||||
@@ -247,6 +270,7 @@ watch(() => queryForm.expired_range_time,
|
||||
{ title: '药师姓名', dataIndex: 'pharmacist_name',slotName:'pharmacist_name' },
|
||||
{ title: '就诊人', dataIndex: 'patient_name', slotName: 'patient_name',width:180 },
|
||||
{ title: '就诊人联系电话', dataIndex: 'mobile',width:130 },
|
||||
{ title: '开方药房', dataIndex: 'pharmacy_name', slotName: 'pharmacy_name', width: 160, ellipsis: true },
|
||||
{ title: '诊断', dataIndex: 'order_prescription_icd',slotName: 'order_prescription_icd' },
|
||||
{ title: '处方状态', dataIndex: 'prescription_status',slotName:'prescription_status' },
|
||||
{ title: '开方时间', dataIndex: 'created_at',slotName:'created_at',width:180 },
|
||||
@@ -340,10 +364,9 @@ watch(() => queryForm.expired_range_time,
|
||||
// 重置搜索
|
||||
const handleResetQuery = () => {
|
||||
proxy.$refs.queryFormRef.resetFields();
|
||||
//getPrescriptionInfo(queryForm);
|
||||
queryForm.pharmacy_id = undefined;
|
||||
currentPage.value=1;
|
||||
//getProductInfo(queryForm);
|
||||
handleQuery();
|
||||
handleQuery();
|
||||
}
|
||||
const handlExport=async(type)=>{
|
||||
proxy.$loading.show();
|
||||
@@ -383,11 +406,23 @@ watch(() => queryForm.expired_range_time,
|
||||
proxy.$loading.hide();
|
||||
}
|
||||
|
||||
// 获取药房下拉数据
|
||||
const fetchPharmacyList = async () => {
|
||||
try {
|
||||
const res = await getPharmacyList();
|
||||
if (res.code === 200) {
|
||||
pharmacyList.value = res.data || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取药房列表异常:', e);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
let userInfo=localStorage.getItem('manage-userInfo')?JSON.parse(localStorage.getItem('manage-userInfo')):{};
|
||||
showTransferDoctor.value=userInfo.role_name!='处方流转平台';
|
||||
getPrescriptionInfo(pager);
|
||||
fetchPharmacyList();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user