fix: OSS客户端直传

This commit is contained in:
2025-12-25 11:18:18 +08:00
parent d81c2da3ba
commit 660717439d
8 changed files with 295 additions and 14 deletions

View File

@@ -58,7 +58,7 @@ const [Modal, modalApi] = useVbenModal({
await formApi.validateAndSubmitForm();
},
// 弹窗打开/关闭状态变化回调
onOpenChange(isOpen: boolean) {
async onOpenChange(isOpen: boolean) {
// 获取表格API引用
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
if (isOpen) {
@@ -75,14 +75,9 @@ const [Modal, modalApi] = useVbenModal({
start_time: dayjs(values.start_time || '08:00', 'HH:mm'),
end_time: dayjs(values.end_time || '20:00', 'HH:mm'),
// 确保订阅状态有值如果后端没有返回则默认为0订阅
subscribe_price_change: values.subscribe_price_change ?? 0
subscribe_price_change: values.subscribe_price_change ?? 0,
});
} else {
console.log({
start_time: dayjs('08:00', 'HH:mm'),
end_time: dayjs('20:00', 'HH:mm')
})
formApi.setValues({
start_time: dayjs('08:00', 'HH:mm'),
end_time: dayjs('20:00', 'HH:mm')

View File

@@ -33,6 +33,14 @@ export const gridOptions: VxeGridProps<RowType> = {
{ type: 'checkbox', width: 60 }, // 复选框列
{ field: 'id', align: 'left', title: 'ID', width: 100 }, // ID列
{ field: 'name', align: 'left', title: '药店名称' }, // 药店名称列(已从"诊所名称"改为"药店名称"
{
// 在线复诊配置列(合并委托诊所和负责人)
field: 'online_consultation_config',
align: 'left',
title: '在线复诊配置',
width: 160,
slots: { default: 'online_consultation_config' },
},
{
// 是否包邮列(显示为开关)
field: 'is_shipping_free',

View File

@@ -23,6 +23,8 @@ import {
} from '#/views/system/store/api';
// 导入表单弹窗组件
import FormModalDemo from './components/modal.vue';
// 导入绑定在线复诊配置弹窗使用store的组件
import BindConsultationModal from '#/views/system/store/components/BindConsultationModal.vue';
// 导入搜索表单配置
import { formOptions } from './config/search';
// 导入表格配置
@@ -76,6 +78,22 @@ const [FormModal, formModalApi] = useVbenModal({
connectedComponent: FormModalDemo,
});
// 初始化绑定在线复诊配置弹窗
const [BindConsultationModalComponent, bindConsultationModalApi] = useVbenModal({
connectedComponent: BindConsultationModal,
});
/**
* 打开绑定在线复诊配置弹窗
*/
const showBindConsultationModal = (row: any) => {
bindConsultationModalApi.setData({
values: row,
gridApi,
});
bindConsultationModalApi.open();
};
// 显示表单弹窗(新增或编辑)
const showModal = (data = {}, isUpdate = false) => {
formModalApi.setData({
@@ -163,6 +181,7 @@ const updateSubscribe = (id: number) => {
<Page auto-content-height title="药店管理">
<FormModal />
<QrCodePreviewModal />
<BindConsultationModalComponent />
<Grid>
<template #toolbar-buttons>
<TableAction
@@ -221,6 +240,26 @@ const updateSubscribe = (id: number) => {
/>
</div>
</template>
<template #online_consultation_config="{ row }">
<div
v-if="row.is_internet_medical === 1 && row.online_consultation_doctor_name"
class="cursor-pointer hover:text-blue-500"
@click="showBindConsultationModal(row)"
>
<div>负责人{{ row.online_consultation_doctor_name }}</div>
</div>
<div
v-else-if="row.delegate_store_name || row.online_consultation_doctor_name"
class="cursor-pointer hover:text-blue-500"
@click="showBindConsultationModal(row)"
>
<div v-if="row.delegate_store_name">委托{{ row.delegate_store_name }}</div>
<div v-if="row.online_consultation_doctor_name">负责人{{ row.online_consultation_doctor_name }}</div>
</div>
<Button v-else type="link" size="small" @click="showBindConsultationModal(row)">
绑定
</Button>
</template>
<template #is_shipping_free="{ row }">
<Switch
:checked="row.is_shipping_free"

View File

@@ -1,6 +1,36 @@
import { requestClient } from '#/api/request';
const prefix = 'store/';
/**
* 获取医生下拉列表(用于选择在线复诊负责人)
* 返回 su_id 作为 id需传入 store_id
*/
export async function getDoctorOptionApi(storeId?: number) {
return requestClient.get<any>(`${prefix}doctor-option`, {
params: storeId ? { store_id: storeId } : {},
});
}
/**
* 获取有互联网诊疗资质的诊所下拉列表
* 用于选择委托在线复诊的诊所
*/
export async function getInternetMedicalStoreOptionApi() {
return requestClient.get<any>(`${prefix}internet-medical-store-option`);
}
/**
* 绑定在线复诊配置
*/
export async function bindOnlineConsultationApi(data: {
id: number;
is_internet_medical: number;
delegate_store_id?: number | null;
online_consultation_doctor_id?: number | null;
}) {
return requestClient.post<any>(`${prefix}bind-online-consultation`, data);
}
/**
* 分页查询用户列表
* @param data

View File

@@ -0,0 +1,170 @@
<script lang="ts" setup>
import { ref, watch } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { Form, FormItem, message, Radio, RadioGroup, Select } from 'ant-design-vue';
import { bindOnlineConsultationApi, getDoctorOptionApi, getInternetMedicalStoreOptionApi } from '../api';
// 表单数据
const formState = ref({
id: undefined as number | undefined,
is_internet_medical: 0,
delegate_store_id: undefined as number | undefined,
online_consultation_doctor_id: undefined as number | undefined,
});
// 下拉选项
const storeOptions = ref<Array<{ id: number; name: string }>>([]);
const doctorOptions = ref<Array<{ id: number; name: string }>>([]);
const gridApiRef = ref<any>(null);
const loading = ref(false);
// 根据诊所ID获取医生列表
async function loadDoctorOptions(storeId?: number) {
if (!storeId) {
doctorOptions.value = [];
return;
}
try {
const doctors = await getDoctorOptionApi(storeId);
doctorOptions.value = doctors || [];
} catch (error) {
console.error('获取医生列表失败:', error);
doctorOptions.value = [];
}
}
// 监听资质变化
watch(
() => formState.value.is_internet_medical,
(newVal) => {
if (newVal === 1) {
// 有资质时根据当前诊所ID加载医生
formState.value.delegate_store_id = undefined;
if (formState.value.id) {
loadDoctorOptions(formState.value.id);
}
} else {
// 无资质时,清空医生列表,等待选择委托诊所
formState.value.online_consultation_doctor_id = undefined;
doctorOptions.value = [];
}
},
);
// 监听委托诊所变化
watch(
() => formState.value.delegate_store_id,
(newVal) => {
if (newVal) {
loadDoctorOptions(newVal);
formState.value.online_consultation_doctor_id = undefined;
} else {
doctorOptions.value = [];
}
},
);
const [Modal, modalApi] = useVbenModal({
fullscreenButton: false,
draggable: true,
onCancel() {
modalApi.close();
},
onConfirm: async () => {
loading.value = true;
modalApi.setState({ confirmLoading: true });
try {
await bindOnlineConsultationApi({
id: formState.value.id!,
is_internet_medical: formState.value.is_internet_medical,
delegate_store_id: formState.value.delegate_store_id || null,
online_consultation_doctor_id: formState.value.online_consultation_doctor_id || null,
});
message.success('绑定成功');
gridApiRef.value?.reload();
modalApi.close();
} catch (error) {
message.error('绑定失败');
} finally {
loading.value = false;
modalApi.setState({ confirmLoading: false });
}
},
async onOpenChange(isOpen: boolean) {
if (isOpen) {
const { values, gridApi } = modalApi.getData<Record<string, any>>();
gridApiRef.value = gridApi;
// 重置表单
formState.value = {
id: values?.id,
is_internet_medical: values?.is_internet_medical ?? 0,
delegate_store_id: values?.delegate_store_id,
online_consultation_doctor_id: values?.online_consultation_doctor_id,
};
// 加载有资质诊所列表
try {
const stores = await getInternetMedicalStoreOptionApi();
storeOptions.value = stores || [];
} catch (error) {
console.error('获取有资质诊所列表失败:', error);
storeOptions.value = [];
}
// 根据当前配置加载医生列表
if (formState.value.is_internet_medical === 1) {
// 有资质根据自身ID加载医生
loadDoctorOptions(formState.value.id);
} else if (formState.value.delegate_store_id) {
// 无资质但有委托诊所,根据委托诊所加载医生
loadDoctorOptions(formState.value.delegate_store_id);
}
}
},
});
</script>
<template>
<Modal title="绑定在线复诊配置" class="w-[500px]">
<Form :model="formState" layout="vertical">
<FormItem label="互联网诊疗资质">
<RadioGroup v-model:value="formState.is_internet_medical">
<Radio :value="0">无资质</Radio>
<Radio :value="1">有资质</Radio>
</RadioGroup>
</FormItem>
<FormItem v-if="formState.is_internet_medical === 0" label="委托在线复诊诊所">
<Select
v-model:value="formState.delegate_store_id"
:options="storeOptions"
:field-names="{ label: 'name', value: 'id' }"
placeholder="请选择委托诊所"
allow-clear
show-search
:filter-option="(input: string, option: any) => option.name.toLowerCase().includes(input.toLowerCase())"
/>
</FormItem>
<FormItem
v-if="formState.is_internet_medical === 1 || formState.delegate_store_id"
label="在线复诊负责人"
>
<Select
v-model:value="formState.online_consultation_doctor_id"
:options="doctorOptions"
:field-names="{ label: 'name', value: 'id' }"
placeholder="请选择在线复诊负责人"
allow-clear
show-search
:filter-option="(input: string, option: any) => option.name.toLowerCase().includes(input.toLowerCase())"
/>
</FormItem>
</Form>
</Modal>
</template>

View File

@@ -11,8 +11,6 @@ import { modalFormProps } from '#/views/system/store/config/form';
import { createStore, updateStore } from '../api';
import dayjs from "dayjs";
const isUpdate = ref(false);
const gridApi = ref();
@@ -44,22 +42,19 @@ const [Modal, modalApi] = useVbenModal({
});
await formApi.validateAndSubmitForm();
},
onOpenChange(isOpen: boolean) {
async onOpenChange(isOpen: boolean) {
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
if (isOpen) {
const { values, update } = modalApi.getData<Record<string, any>>();
if (values) {
isUpdate.value = update;
// 把values.start_time变成dayjs
// values.start_time = dayjs(values.start_time, 'HH:mm');
// values.end_time = dayjs(values.end_time, 'HH:mm');
values.address = [values.province_id, values.city_id];
formApi.setValues({
...values,
start_time: dayjs(values.start_time || '08:00', 'HH:mm'),
end_time: dayjs(values.end_time || '20:00', 'HH:mm'),
// 确保订阅状态有值如果后端没有返回则默认为0订阅
subscribe_price_change: values.subscribe_price_change ?? 0
subscribe_price_change: values.subscribe_price_change ?? 0,
});
}
}

View File

@@ -25,6 +25,13 @@ export const gridOptions: VxeGridProps<RowType> = {
{ type: 'checkbox', width: 60 },
{ field: 'id', align: 'left', title: 'ID', width: 100 },
{ field: 'name', align: 'left', title: '诊所名称' },
{
field: 'online_consultation_config',
align: 'left',
title: '在线复诊配置',
width: 160,
slots: { default: 'online_consultation_config' },
},
{
field: 'is_shipping_free',
align: 'left',

View File

@@ -23,6 +23,7 @@ import {
} from './api';
import FormModalDemo from './components/modal.vue';
import DrugPriceModal from './components/DrugPriceModal.vue';
import BindConsultationModal from './components/BindConsultationModal.vue';
import { formOptions } from './config/search';
import { gridOptions } from './config/table';
@@ -76,6 +77,10 @@ const [DrugPriceModalComponent, drugPriceModalApi] = useVbenModal({
connectedComponent: DrugPriceModal,
});
const [BindConsultationModalComponent, bindConsultationModalApi] = useVbenModal({
connectedComponent: BindConsultationModal,
});
const showModal = (data = {}, isUpdate = false) => {
formModalApi.setData({
// 表单值
@@ -96,6 +101,17 @@ const showDrugPriceModal = (row: any) => {
drugPriceModalApi.open();
};
/**
* 打开绑定在线复诊配置弹窗
*/
const showBindConsultationModal = (row: any) => {
bindConsultationModalApi.setData({
values: row,
gridApi,
});
bindConsultationModalApi.open();
};
const deleteApi = (row: any) => {
let ids = [];
if (row) {
@@ -159,6 +175,7 @@ const updateSubscribe = (id: number) => {
<FormModal />
<QrCodePreviewModal />
<DrugPriceModalComponent />
<BindConsultationModalComponent />
<Grid>
<template #toolbar-buttons>
<TableAction
@@ -221,6 +238,26 @@ const updateSubscribe = (id: number) => {
</template>
<template #type="{ row }">
</template>
<template #online_consultation_config="{ row }">
<div
v-if="row.is_internet_medical === 1 && row.online_consultation_doctor_name"
class="cursor-pointer hover:text-blue-500"
@click="showBindConsultationModal(row)"
>
<div>负责人{{ row.online_consultation_doctor_name }}</div>
</div>
<div
v-else-if="row.delegate_store_name || row.online_consultation_doctor_name"
class="cursor-pointer hover:text-blue-500"
@click="showBindConsultationModal(row)"
>
<div v-if="row.delegate_store_name">委托{{ row.delegate_store_name }}</div>
<div v-if="row.online_consultation_doctor_name">负责人{{ row.online_consultation_doctor_name }}</div>
</div>
<Button v-else type="link" size="small" @click="showBindConsultationModal(row)">
绑定
</Button>
</template>
<template #is_shipping_free="{ row }">
<Switch
:checked="row.is_shipping_free"