药房管理
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
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',
|
||||
});
|
||||
}
|
||||
@@ -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,495 @@
|
||||
<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 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
|
||||
: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>
|
||||
</template>
|
||||
|
||||
<!-- 操作列 -->
|
||||
<template #action="{ record }">
|
||||
<a-space>
|
||||
<a-button type="text" size="small" @click="handleDetail(record)">
|
||||
<template #icon><icon-eye /></template>
|
||||
详情
|
||||
</a-button>
|
||||
<a-button type="text" size="small" @click="handleEdit(record)">
|
||||
<template #icon><icon-edit /></template>
|
||||
修改
|
||||
</a-button>
|
||||
<a-popconfirm
|
||||
content="确定要删除此药房吗?删除后不可恢复!"
|
||||
type="warning"
|
||||
@ok="handleDelete(record)"
|
||||
>
|
||||
<a-button type="text" status="danger" size="small">
|
||||
<template #icon><icon-delete /></template>
|
||||
删除
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-table>
|
||||
|
||||
<!-- 新增 / 编辑 / 详情 弹窗 -->
|
||||
<PharmacyModal ref="modalRef" @success="handleQuery" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import { getPharmacyPage, updatePharmacyStatus, deletePharmacy } from '@/api/basic/pharmacy';
|
||||
import { getAdminAreaList } from '@/api/basic/list';
|
||||
import PharmacyModal from './components/pharmacyModal.vue';
|
||||
|
||||
const queryFormRef = ref(null);
|
||||
const modalRef = 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: 190, 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 handleStatusToggle = async (record, val) => {
|
||||
const newStatus = val ? 1 : 0;
|
||||
const originalStatus = record.status;
|
||||
record._statusLoading = true;
|
||||
try {
|
||||
const res = await updatePharmacyStatus(record.pharmacy_id, newStatus);
|
||||
if (res.code === 200) {
|
||||
record.status = newStatus;
|
||||
Message.success(newStatus === 1 ? '已启用该药房' : '已禁用该药房');
|
||||
} else {
|
||||
record.status = originalStatus;
|
||||
Message.error(res.message || '修改状态失败');
|
||||
}
|
||||
} catch (err) {
|
||||
record.status = originalStatus;
|
||||
Message.error('切换状态异常');
|
||||
} finally {
|
||||
record._statusLoading = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 删除
|
||||
const handleDelete = async (record) => {
|
||||
try {
|
||||
const res = await deletePharmacy(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 (err) {
|
||||
Message.error('删除药房异常');
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchTableData();
|
||||
fetchAreaList('', 2);
|
||||
});
|
||||
</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>
|
||||
Reference in New Issue
Block a user