feat:优化了门店搜索组件、优化了模态框默认的内容
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
addWestPrescription,
|
||||
checkChineseMedicineConflictApi,
|
||||
getCurrentStoreTypeApi,
|
||||
getPrescriptionTypeOptionsApi,
|
||||
getDrugUseList,
|
||||
getMyStoreListApi,
|
||||
getPatientItem,
|
||||
@@ -54,6 +55,16 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
// 处方状态
|
||||
const myStoreId = ref(0);
|
||||
const activeCategory = ref(2);
|
||||
/** 后端下发的处方类型列表(含可选 icon / icon_text) */
|
||||
const categories = ref([
|
||||
{ label: '中药', value: 1, icon: '', icon_text: '' },
|
||||
{ label: '西(中成)药', value: 2, icon: '', icon_text: '' },
|
||||
{ label: '保健食品', value: 3, icon: '', icon_text: '' },
|
||||
{ label: '产品服务包', value: 5, icon: '', icon_text: '' },
|
||||
{ label: '非药品', value: 6, icon: '', icon_text: '' },
|
||||
{ label: '医疗器械', value: 7, icon: '', icon_text: '' },
|
||||
]);
|
||||
const prescriptionTypeDefault = ref(2);
|
||||
const diagnosis = ref('');
|
||||
const medicalAdvice = ref('');
|
||||
const treatmentPrice = ref(0);
|
||||
@@ -192,6 +203,33 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
return calcItemMarginPercent(drug.price, drug.buy_price);
|
||||
};
|
||||
|
||||
/**
|
||||
* 拉取后端处方类型列表与默认选中
|
||||
*/
|
||||
const loadPrescriptionTypeOptions = async (registerId?: number | string) => {
|
||||
try {
|
||||
const params: { register_id?: number; store_id?: number } = {};
|
||||
const rid = Number(registerId || currentRegisterId.value);
|
||||
if (rid) params.register_id = rid;
|
||||
if (myStoreId.value) params.store_id = myStoreId.value;
|
||||
const res = await getPrescriptionTypeOptionsApi(params);
|
||||
const list = Array.isArray(res?.list) ? res.list : [];
|
||||
if (list.length) {
|
||||
categories.value = list.map((item) => ({
|
||||
value: Number(item.value),
|
||||
label: item.label || '',
|
||||
icon: item.icon || '',
|
||||
icon_text: item.icon_text || '',
|
||||
}));
|
||||
}
|
||||
const def = Number(res?.default);
|
||||
if (def) prescriptionTypeDefault.value = def;
|
||||
} catch (error) {
|
||||
console.error('加载处方类型失败:', error);
|
||||
message.warning('处方类型加载失败,请稍后重试');
|
||||
}
|
||||
};
|
||||
|
||||
// localStorage同步方法
|
||||
const syncToLocalStorage = () => {
|
||||
try {
|
||||
@@ -260,6 +298,12 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
// 设置当前注册ID
|
||||
currentRegisterId.value = registerId;
|
||||
|
||||
// 先拉类型选项,再决定默认 Tab(无本地记忆时用后端 default)
|
||||
if (!isInitialized.value) {
|
||||
await initializeBasicData();
|
||||
}
|
||||
await loadPrescriptionTypeOptions(registerId);
|
||||
|
||||
// 恢复之前保存的 activeCategory
|
||||
const savedCategory = localStorage.getItem(
|
||||
`${storagePrefix.value}activeCategory${registerId}`
|
||||
@@ -278,17 +322,14 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
activeCategory.value = 1;
|
||||
} else if (westData && JSON.parse(westData).length > 0) {
|
||||
activeCategory.value = 2;
|
||||
} else if (prescriptionTypeDefault.value) {
|
||||
activeCategory.value = prescriptionTypeDefault.value;
|
||||
}
|
||||
}
|
||||
|
||||
// 加载localStorage数据
|
||||
loadFromLocalStorage();
|
||||
|
||||
// 如果基础数据未初始化,先初始化基础数据
|
||||
if (!isInitialized.value) {
|
||||
await initializeBasicData();
|
||||
}
|
||||
|
||||
await fetchStoreSeeRate();
|
||||
|
||||
// 获取患者信息(只在需要时调用,如 PrescriptionModal)
|
||||
@@ -1113,6 +1154,11 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
} else {
|
||||
currentDrugs.value.splice(0, currentDrugs.value.length);
|
||||
}
|
||||
// 切换后聚焦 Tab 栏当前项
|
||||
nextTick(() => {
|
||||
const el = document.getElementById(`rx-modal-tab-${categoryValue}`);
|
||||
el?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' });
|
||||
});
|
||||
};
|
||||
|
||||
// 工具函数
|
||||
@@ -1152,6 +1198,8 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
myStoreList,
|
||||
myStoreId,
|
||||
activeCategory,
|
||||
categories,
|
||||
prescriptionTypeDefault,
|
||||
diagnosis,
|
||||
medicalAdvice,
|
||||
treatmentPrice,
|
||||
@@ -1188,6 +1236,7 @@ export const usePrescriptionStore = defineStore('prescription', () => {
|
||||
initializePrescription,
|
||||
initializeForModal,
|
||||
initializeBasicData,
|
||||
loadPrescriptionTypeOptions,
|
||||
resetInitializationState,
|
||||
getDrugList,
|
||||
addProducts,
|
||||
|
||||
@@ -77,18 +77,15 @@ const commonPrescriptionName = ref('');
|
||||
/** 是否正在保存常用方 */
|
||||
const isSavingCommonPrescription = ref(false);
|
||||
|
||||
const categories = [
|
||||
{ label: '中药', value: 1 },
|
||||
{ label: '中成(西)药', value: 2 },
|
||||
{ label: '保健食品', value: 3 },
|
||||
{ label: '产品服务包', value: 5 },
|
||||
{ label: '非药品', value: 6 },
|
||||
{ label: '医疗器械', value: 7 },
|
||||
];
|
||||
|
||||
// 使用 Pinia store
|
||||
const prescriptionStore = usePrescriptionStore();
|
||||
|
||||
/** 处方类型来自后端下发(store.categories) */
|
||||
const categories = computed(() => prescriptionStore.categories);
|
||||
|
||||
const rxSwipeStartX = ref(0);
|
||||
const rxSwipeStartY = ref(0);
|
||||
|
||||
const allowInsuranceCategory = computed(
|
||||
() => Number(prescriptionStore.registerStoreInfo?.allow_insurance_category ?? 0) === 1,
|
||||
);
|
||||
@@ -133,6 +130,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
storagePrefix,
|
||||
);
|
||||
prescriptionStore.loadFromLocalStorage();
|
||||
// 开方弹窗打开时再拉一次类型,确保 Network 可见且数据最新
|
||||
await prescriptionStore.loadPrescriptionTypeOptions(modalData.value.registerId);
|
||||
// 获取挂号诊所信息
|
||||
await prescriptionStore.fetchRegisterStoreInfo();
|
||||
|
||||
@@ -446,6 +445,26 @@ const tabChange = async (id: number) => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 记录左右滑起点 */
|
||||
const onRxPanelPointerDown = (e: PointerEvent) => {
|
||||
rxSwipeStartX.value = e.clientX;
|
||||
rxSwipeStartY.value = e.clientY;
|
||||
};
|
||||
|
||||
/** 左右滑切换相邻处方类型 */
|
||||
const onRxPanelPointerUp = (e: PointerEvent) => {
|
||||
const dx = e.clientX - rxSwipeStartX.value;
|
||||
const dy = e.clientY - rxSwipeStartY.value;
|
||||
if (Math.abs(dx) < 80 || Math.abs(dx) <= Math.abs(dy)) return;
|
||||
const list = categories.value || [];
|
||||
if (list.length < 2) return;
|
||||
const idx = list.findIndex((c) => Number(c.value) === Number(prescriptionStore.activeCategory));
|
||||
if (idx < 0) return;
|
||||
const nextIdx = dx < 0 ? idx + 1 : idx - 1;
|
||||
if (nextIdx < 0 || nextIdx >= list.length) return;
|
||||
tabChange(list[nextIdx].value);
|
||||
};
|
||||
|
||||
/**
|
||||
* 检测并显示转诊提示
|
||||
* @description 当切换到中药处方时,如果当前诊所为西医诊所,显示转诊提示
|
||||
@@ -1021,16 +1040,30 @@ const cancelSaveCommonPrescription = () => {
|
||||
<div class="drug-categories sticky top-0 bg-white dark:bg-[#151515] z-10 py-2 border-b mb-4">
|
||||
<button
|
||||
v-for="categoryItem in categories"
|
||||
:id="`rx-modal-tab-${categoryItem.value}`"
|
||||
:key="categoryItem.value"
|
||||
:class="{
|
||||
active: prescriptionStore.activeCategory === categoryItem.value,
|
||||
}"
|
||||
@click="tabChange(categoryItem.value)"
|
||||
>
|
||||
{{ categoryItem.label }}
|
||||
<img
|
||||
v-if="categoryItem.icon"
|
||||
class="tab-type-icon"
|
||||
:src="categoryItem.icon"
|
||||
alt=""
|
||||
/>
|
||||
<span>{{ categoryItem.label }}</span>
|
||||
<span v-if="categoryItem.icon_text" class="tab-type-badge">{{ categoryItem.icon_text }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="rx-swipe-panel"
|
||||
@pointerdown="onRxPanelPointerDown"
|
||||
@pointerup="onRxPanelPointerUp"
|
||||
>
|
||||
|
||||
<!-- 费用类型选择和添加商品按钮 -->
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<RadioGroup v-if="allowInsuranceCategory" v-model:value="prescriptionStore.category">
|
||||
@@ -1067,6 +1100,13 @@ const cancelSaveCommonPrescription = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 中药:顶部固定展示已选种数 -->
|
||||
<div
|
||||
v-if="prescriptionStore.activeCategory === 1"
|
||||
class="mb-3 mt-2 text-base font-medium text-gray-700"
|
||||
>
|
||||
已选 {{ prescriptionStore.currentDrugs.length }} 种药
|
||||
</div>
|
||||
<!-- 中药药品列表 -->
|
||||
<div
|
||||
v-if="prescriptionStore.activeCategory === 1"
|
||||
@@ -1575,6 +1615,7 @@ const cancelSaveCommonPrescription = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 以下是各种弹窗组件,位置不动 -->
|
||||
@@ -1697,6 +1738,8 @@ const cancelSaveCommonPrescription = () => {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
/* margin: 1rem 0; 已在类中通过 sticky 处理 */
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.drug-categories button {
|
||||
@@ -1707,6 +1750,11 @@ const cancelSaveCommonPrescription = () => {
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
transition: all 0.3s;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dark .drug-categories button {
|
||||
@@ -1720,6 +1768,25 @@ const cancelSaveCommonPrescription = () => {
|
||||
background: #455cda;
|
||||
}
|
||||
|
||||
.tab-type-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tab-type-badge {
|
||||
font-size: 11px;
|
||||
color: #e6a23c;
|
||||
background: #fdf6ec;
|
||||
padding: 0 6px;
|
||||
border-radius: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.rx-swipe-panel {
|
||||
touch-action: pan-y;
|
||||
}
|
||||
|
||||
.selected-drugs {
|
||||
margin: 1rem 0;
|
||||
border: 1px solid #eee;
|
||||
|
||||
@@ -57,7 +57,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}快递公司`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}快递公司`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -37,7 +37,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="处方溯源">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="处方溯源">
|
||||
<PrescriptionSourceContent :data="data" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -79,6 +79,18 @@ export async function expressDetailByOrderId(data: Record<string, any>) {
|
||||
return requestClient.post<any>(`express-detail/detail-by-order`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改已发货运单:快递单号 / 查件手机号 / 快递公司
|
||||
*/
|
||||
export async function updateExpressNosApi(data: {
|
||||
express_no_id: number;
|
||||
express_no?: string;
|
||||
mobile?: string;
|
||||
express_company_code?: string;
|
||||
}) {
|
||||
return requestClient.post<any>(`express-detail/update-express-nos`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 超管:将历史订单级运单同步到分包裹 shipment
|
||||
*/
|
||||
|
||||
@@ -188,6 +188,20 @@ function packageTabLabel(pkg: Record<string, any>, idx: number): string {
|
||||
return name ? `包裹${no}(${name})` : `包裹${no}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 收件人姓名脱敏:保留首字,其余用 *(与物流动态弹窗一致)
|
||||
*/
|
||||
function maskExpressName(name: unknown): string {
|
||||
const str = String(name || '').trim();
|
||||
if (!str) {
|
||||
return '-';
|
||||
}
|
||||
if (str.length === 1) {
|
||||
return `${str}*`;
|
||||
}
|
||||
return str.slice(0, 1) + '*'.repeat(str.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开独立物流动态弹窗(完整轨迹)
|
||||
*/
|
||||
@@ -249,7 +263,7 @@ function prescriptionStatusColor() {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="订单详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="订单详情">
|
||||
<div v-if="data" class="flex flex-col gap-4">
|
||||
<Space>
|
||||
<Button type="primary" size="small" @click="openOrderTrace">
|
||||
@@ -528,6 +542,16 @@ function prescriptionStatusColor() {
|
||||
:column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
|
||||
bordered
|
||||
>
|
||||
<Descriptions.Item label="收件人">
|
||||
{{
|
||||
maskExpressName(
|
||||
(expressDetail as any).express_name || data?.express_name,
|
||||
)
|
||||
}}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">
|
||||
<SensitiveText :record="pkg.express" field="mobile" />
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="物流公司">
|
||||
{{ pkg.express.express_company_name || '-' }}
|
||||
</Descriptions.Item>
|
||||
@@ -553,6 +577,16 @@ function prescriptionStatusColor() {
|
||||
bordered
|
||||
class="mt-4"
|
||||
>
|
||||
<Descriptions.Item label="收件人">
|
||||
{{
|
||||
maskExpressName(
|
||||
(expressDetail as any).express_name || data?.express_name,
|
||||
)
|
||||
}}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">
|
||||
<SensitiveText :record="expressDetail" field="mobile" />
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="物流公司">
|
||||
{{ expressDetail.express_company_name || '-' }}
|
||||
</Descriptions.Item>
|
||||
|
||||
@@ -2,14 +2,30 @@
|
||||
/**
|
||||
* 独立「物流动态」弹窗:只请求 express-detail,不展示整单其它信息。
|
||||
* 仓名为空时 Tab 仅显示「包裹N」,与后端诊所开关抹名约定一致。
|
||||
* 已发货包裹展示脱敏收件人/查件手机号,并支持修改手机号与快递单号。
|
||||
*/
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, reactive, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import { Descriptions, Spin, Tabs, Tag, Timeline } from 'ant-design-vue';
|
||||
import {
|
||||
Button,
|
||||
Descriptions,
|
||||
Form,
|
||||
FormItem,
|
||||
Input,
|
||||
Modal as AModal,
|
||||
Spin,
|
||||
Tabs,
|
||||
Tag,
|
||||
Timeline,
|
||||
message,
|
||||
} from 'ant-design-vue';
|
||||
|
||||
import { expressDetailByOrderId } from '../api';
|
||||
import ExpressCompanySelect from '#/components/form/components/express-company-select.vue';
|
||||
import SensitiveText from '#/components/sensitive-text/SensitiveText.vue';
|
||||
|
||||
import { expressDetailByOrderId, updateExpressNosApi } from '../api';
|
||||
|
||||
defineOptions({
|
||||
name: 'ProductOrderLogisticsModal',
|
||||
@@ -20,6 +36,16 @@ const expressDetail = ref<Record<string, any>>({});
|
||||
const activePkg = ref('0');
|
||||
const orderId = ref<number | null>(null);
|
||||
|
||||
/** 改运单弹窗 */
|
||||
const editVisible = ref(false);
|
||||
const editSubmitting = ref(false);
|
||||
const editForm = reactive({
|
||||
express_no_id: 0,
|
||||
express_no: '',
|
||||
mobile: '',
|
||||
express_company_code: '' as string | undefined,
|
||||
});
|
||||
|
||||
/**
|
||||
* 多包裹列表:以物流接口 packages 为准(门店角色已按开关抹仓名)
|
||||
*/
|
||||
@@ -37,6 +63,32 @@ function packageTabLabel(pkg: Record<string, any>, idx: number): string {
|
||||
return name ? `包裹${no}(${name})` : `包裹${no}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 收件人姓名脱敏:保留首字,其余用 *
|
||||
*/
|
||||
function maskExpressName(name: unknown): string {
|
||||
const str = String(name || '').trim();
|
||||
if (!str) {
|
||||
return '-';
|
||||
}
|
||||
if (str.length === 1) {
|
||||
return `${str}*`;
|
||||
}
|
||||
return str.slice(0, 1) + '*'.repeat(str.length - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析运单 ID:优先 express_no_id,其次 express.id
|
||||
*/
|
||||
function resolveExpressNoId(
|
||||
express: Record<string, any> | null | undefined,
|
||||
fallbackId?: number,
|
||||
): number {
|
||||
const fromExpress = Number(express?.id || 0);
|
||||
const fromFallback = Number(fallbackId || 0);
|
||||
return fromExpress > 0 ? fromExpress : fromFallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流状态 Tag 颜色
|
||||
*/
|
||||
@@ -60,16 +112,73 @@ function getColor(status: any) {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadExpress(id: number) {
|
||||
async function loadExpress(id: number, keepActive = false) {
|
||||
loading.value = true;
|
||||
try {
|
||||
expressDetail.value = (await expressDetailByOrderId({ order_id: id })) || {};
|
||||
activePkg.value = '0';
|
||||
if (!keepActive) {
|
||||
activePkg.value = '0';
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开改运单表单(包裹或旧单运单共用)
|
||||
*/
|
||||
function openEditExpress(payload: {
|
||||
express_no_id: number;
|
||||
express_no?: string;
|
||||
mobile?: string;
|
||||
express_company_code?: string;
|
||||
}) {
|
||||
const id = Number(payload.express_no_id || 0);
|
||||
if (id <= 0) {
|
||||
message.warning('缺少运单信息,无法修改');
|
||||
return;
|
||||
}
|
||||
editForm.express_no_id = id;
|
||||
editForm.express_no = String(payload.express_no || '');
|
||||
editForm.mobile = String(payload.mobile || '');
|
||||
editForm.express_company_code = payload.express_company_code || undefined;
|
||||
editVisible.value = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交修改运单号 / 查件手机号 / 快递公司
|
||||
*/
|
||||
async function submitEditExpress() {
|
||||
if (!editForm.express_no?.trim()) {
|
||||
message.warning('请输入快递单号');
|
||||
return;
|
||||
}
|
||||
if (!editForm.express_company_code) {
|
||||
message.warning('请选择快递公司');
|
||||
return;
|
||||
}
|
||||
if (!editForm.mobile?.trim()) {
|
||||
message.warning('请输入手机号');
|
||||
return;
|
||||
}
|
||||
editSubmitting.value = true;
|
||||
try {
|
||||
await updateExpressNosApi({
|
||||
express_no_id: editForm.express_no_id,
|
||||
express_no: editForm.express_no.trim(),
|
||||
mobile: editForm.mobile.trim(),
|
||||
express_company_code: editForm.express_company_code,
|
||||
});
|
||||
message.success('修改成功');
|
||||
editVisible.value = false;
|
||||
if (orderId.value) {
|
||||
await loadExpress(orderId.value, true);
|
||||
}
|
||||
} finally {
|
||||
editSubmitting.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
@@ -84,6 +193,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
const id = Number(payload.order_id || payload.id || 0);
|
||||
orderId.value = id || null;
|
||||
expressDetail.value = {};
|
||||
editVisible.value = false;
|
||||
if (id) {
|
||||
loadExpress(id);
|
||||
}
|
||||
@@ -91,6 +201,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
orderId.value = null;
|
||||
expressDetail.value = {};
|
||||
activePkg.value = '0';
|
||||
editVisible.value = false;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -118,11 +229,57 @@ const [Modal, modalApi] = useVbenModal({
|
||||
:column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
|
||||
bordered
|
||||
>
|
||||
<Descriptions.Item label="收件人">
|
||||
{{ maskExpressName(expressDetail.express_name) }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<SensitiveText :record="pkg.express" field="mobile" />
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
class="!px-0"
|
||||
@click="
|
||||
openEditExpress({
|
||||
express_no_id: resolveExpressNoId(
|
||||
pkg.express,
|
||||
pkg.express_no_id,
|
||||
),
|
||||
express_no: pkg.express.express_no,
|
||||
mobile: pkg.express.mobile,
|
||||
express_company_code: pkg.express.express_company_code,
|
||||
})
|
||||
"
|
||||
>
|
||||
修改
|
||||
</Button>
|
||||
</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="物流公司">
|
||||
{{ pkg.express.express_company_name || '-' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="运单号">
|
||||
{{ pkg.express.express_no || '-' }}
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<span>{{ pkg.express.express_no || '-' }}</span>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
class="!px-0"
|
||||
@click="
|
||||
openEditExpress({
|
||||
express_no_id: resolveExpressNoId(
|
||||
pkg.express,
|
||||
pkg.express_no_id,
|
||||
),
|
||||
express_no: pkg.express.express_no,
|
||||
mobile: pkg.express.mobile,
|
||||
express_company_code: pkg.express.express_company_code,
|
||||
})
|
||||
"
|
||||
>
|
||||
修改
|
||||
</Button>
|
||||
</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="最新状态">
|
||||
{{ pkg.express.state_txt || '-' }}
|
||||
@@ -153,11 +310,59 @@ const [Modal, modalApi] = useVbenModal({
|
||||
:column="{ xxl: 2, xl: 2, lg: 2, md: 1, sm: 1, xs: 1 }"
|
||||
bordered
|
||||
>
|
||||
<Descriptions.Item label="收件人">
|
||||
{{ maskExpressName(expressDetail.express_name) }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="手机号">
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<SensitiveText :record="expressDetail" field="mobile" />
|
||||
<Button
|
||||
v-if="resolveExpressNoId(expressDetail, expressDetail.express_no_id)"
|
||||
type="link"
|
||||
size="small"
|
||||
class="!px-0"
|
||||
@click="
|
||||
openEditExpress({
|
||||
express_no_id: resolveExpressNoId(
|
||||
expressDetail,
|
||||
expressDetail.express_no_id,
|
||||
),
|
||||
express_no: expressDetail.express_no,
|
||||
mobile: expressDetail.mobile,
|
||||
express_company_code: expressDetail.express_company_code,
|
||||
})
|
||||
"
|
||||
>
|
||||
修改
|
||||
</Button>
|
||||
</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="物流公司">
|
||||
{{ expressDetail.express_company_name || '-' }}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="运单号">
|
||||
{{ expressDetail.express_no || '-' }}
|
||||
<span class="inline-flex items-center gap-2">
|
||||
<span>{{ expressDetail.express_no || '-' }}</span>
|
||||
<Button
|
||||
v-if="resolveExpressNoId(expressDetail, expressDetail.express_no_id)"
|
||||
type="link"
|
||||
size="small"
|
||||
class="!px-0"
|
||||
@click="
|
||||
openEditExpress({
|
||||
express_no_id: resolveExpressNoId(
|
||||
expressDetail,
|
||||
expressDetail.express_no_id,
|
||||
),
|
||||
express_no: expressDetail.express_no,
|
||||
mobile: expressDetail.mobile,
|
||||
express_company_code: expressDetail.express_company_code,
|
||||
})
|
||||
"
|
||||
>
|
||||
修改
|
||||
</Button>
|
||||
</span>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="最新状态">
|
||||
{{ expressDetail.state_txt || '-' }}
|
||||
@@ -183,6 +388,39 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</template>
|
||||
</Spin>
|
||||
</Modal>
|
||||
|
||||
<!-- 修改运单号 / 查件手机号:与发货表单字段对齐,改单号时可重匹配公司 -->
|
||||
<AModal
|
||||
v-model:open="editVisible"
|
||||
title="修改运单信息"
|
||||
:confirm-loading="editSubmitting"
|
||||
destroy-on-close
|
||||
@ok="submitEditExpress"
|
||||
>
|
||||
<Form layout="vertical" class="mt-2">
|
||||
<FormItem label="快递单号" required>
|
||||
<Input
|
||||
v-model:value="editForm.express_no"
|
||||
placeholder="请输入快递单号"
|
||||
allow-clear
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="快递公司" required>
|
||||
<ExpressCompanySelect
|
||||
v-model:value="editForm.express_company_code"
|
||||
placeholder="请选择快递公司"
|
||||
:tracking-no="editForm.express_no"
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label="手机号" required>
|
||||
<Input
|
||||
v-model:value="editForm.mobile"
|
||||
placeholder="请输入查件手机号"
|
||||
allow-clear
|
||||
/>
|
||||
</FormItem>
|
||||
</Form>
|
||||
</AModal>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -65,7 +65,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="`订单:【 ${orderNo} 】发货`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`订单:【 ${orderNo} 】发货`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -54,7 +54,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
title="退款"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -901,9 +901,9 @@ const openOrderAmountVerify = () => {
|
||||
<div class="text-xs text-gray-500">
|
||||
<Button
|
||||
v-if="row.store?.id"
|
||||
type="link"
|
||||
class="!h-auto max-w-[xxx] whitespace-normal break-words !px-0 text-left"
|
||||
size="small"
|
||||
class="!h-auto !px-0"
|
||||
type="link"
|
||||
@click="openStoreCard(row.store.id)"
|
||||
>
|
||||
{{ row.store?.name || '—' }}
|
||||
|
||||
@@ -54,7 +54,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
title="退款"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -80,7 +80,7 @@ const handleChange = (info: { file: UploadFile }) => {
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="上传Excel">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="上传Excel">
|
||||
<!-- 新增:显示文件选择状态 -->
|
||||
<div v-if="isFileSelected" class="mb-4 p-3 bg-green-50 border border-green-200 rounded">
|
||||
<p class="text-green-700 text-sm">已选择文件:{{ selectedFile?.name }}</p>
|
||||
|
||||
@@ -123,7 +123,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}中药`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -102,7 +102,7 @@ const handleChange = (info: { file: UploadFile }) => {
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="上传Excel">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="上传Excel">
|
||||
<!-- 显示文件选择状态提示 -->
|
||||
<div
|
||||
v-if="isFileSelected"
|
||||
|
||||
@@ -142,7 +142,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}保健食品`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -73,7 +73,7 @@ const handleChange = (info: { file: UploadFile }) => {
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="上传Excel">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="上传Excel">
|
||||
<div
|
||||
v-if="isFileSelected"
|
||||
class="mb-4 rounded border border-green-200 bg-green-50 p-3"
|
||||
|
||||
@@ -96,7 +96,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}医疗器械`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -73,7 +73,7 @@ const handleChange = (info: { file: UploadFile }) => {
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="上传Excel">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="上传Excel">
|
||||
<div
|
||||
v-if="isFileSelected"
|
||||
class="mb-4 rounded border border-green-200 bg-green-50 p-3"
|
||||
|
||||
@@ -96,7 +96,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}非药品`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -66,7 +66,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}产品服务包`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -80,7 +80,7 @@ const handleChange = (info: { file: UploadFile }) => {
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="上传Excel">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="上传Excel">
|
||||
<!-- 新增:显示文件选择状态 -->
|
||||
<div
|
||||
v-if="isFileSelected"
|
||||
|
||||
@@ -152,7 +152,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}西(中成)药`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -100,7 +100,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal title="编辑药方" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal title="编辑药方" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<div v-if="prescriptionType === 'chinese'">
|
||||
<ChineseDrugEditor
|
||||
ref="chineseDrugEditorRef"
|
||||
|
||||
@@ -178,7 +178,7 @@ function bindPrescriptionTypeChange() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="`${isUpdate ? '编辑' : '新增'}特色方`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`${isUpdate ? '编辑' : '新增'}特色方`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
<div v-if="prescriptionType === 'chinese'" class="mt-4 border-t pt-4">
|
||||
<ChineseDrugEditor
|
||||
|
||||
@@ -58,7 +58,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}轮播图`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -132,7 +132,7 @@ const exportWarehouseDrugManagementTemplate = () => {
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="importType === 1 ? '上传Excel' : titles" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="importType === 1 ? '上传Excel' : titles" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Button
|
||||
v-if="importType === 1"
|
||||
type="link"
|
||||
|
||||
@@ -112,7 +112,7 @@ const exportWarehouseDrugManagementStoreTemplate = () => {
|
||||
<template>
|
||||
<Modal
|
||||
:title="importType === 1 ? '上传Excel' : '批量修改价格'"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Button
|
||||
v-if="importType === 1"
|
||||
|
||||
@@ -126,7 +126,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}仓库药品`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -115,7 +115,7 @@ const exportWarehouseDrugManagementStoreTemplate = () => {
|
||||
<template>
|
||||
<Modal
|
||||
:title="importType === 1 ? '上传Excel' : '批量修改价格'"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Button
|
||||
v-if="importType === 1"
|
||||
|
||||
@@ -126,7 +126,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
<template>
|
||||
<Modal
|
||||
:title="`${isUpdate === true ? '编辑' : '新增'}仓库药品`"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%]"
|
||||
class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]"
|
||||
>
|
||||
<Form />
|
||||
</Modal>
|
||||
|
||||
@@ -104,6 +104,26 @@ export async function getCurrentStoreTypeApi(params?: {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 开方处方类型选项(含默认选中、可选 icon / icon_text)
|
||||
*/
|
||||
export async function getPrescriptionTypeOptionsApi(params?: {
|
||||
register_id?: number;
|
||||
store_id?: number;
|
||||
}) {
|
||||
return requestClient.get<{
|
||||
default: number;
|
||||
list: Array<{
|
||||
value: number;
|
||||
label: string;
|
||||
icon?: string;
|
||||
icon_text?: string;
|
||||
}>;
|
||||
}>(`${prefix}prescription-type-options`, {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 接诊
|
||||
*/
|
||||
|
||||
@@ -46,6 +46,13 @@ const userStore = useUserStore();
|
||||
const searchKey = ref('');
|
||||
// 药品类型:1-中药,2-西药
|
||||
const type = ref(1);
|
||||
/** 弹窗标题:中药时展示已选种数 */
|
||||
const modalTitle = computed(() => {
|
||||
if (Number(type.value) === 1) {
|
||||
return `选择中药(${selectList.value.length}种)`;
|
||||
}
|
||||
return '商品列表';
|
||||
});
|
||||
// 当前药品回调函数
|
||||
const currentDrugsWestern = ref();
|
||||
// 当前患者ID
|
||||
@@ -585,7 +592,7 @@ function updateProductNumber(id, number) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[60%]" title="商品列表">
|
||||
<Modal class="w-[60%]" :title="modalTitle">
|
||||
<!-- 图片预览组件 -->
|
||||
<Image
|
||||
:preview="{
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
getDrugUseList,
|
||||
getMyStoreListApi,
|
||||
getCurrentStoreTypeApi,
|
||||
getPrescriptionTypeOptionsApi,
|
||||
getPatientItem,
|
||||
getPatientList,
|
||||
getPrescriptionInfoApi,
|
||||
@@ -173,8 +174,39 @@ function getMyStoreList() {
|
||||
|
||||
getMyStoreList();
|
||||
|
||||
/** 拉取处方类型列表与默认选中 */
|
||||
async function loadPrescriptionTypeOptions(registerId?: number) {
|
||||
try {
|
||||
const params: { register_id?: number; store_id?: number } = {};
|
||||
if (registerId) params.register_id = registerId;
|
||||
if (myStoreId.value) params.store_id = myStoreId.value;
|
||||
const res = await getPrescriptionTypeOptionsApi(params);
|
||||
const list = Array.isArray(res?.list) ? res.list : [];
|
||||
if (list.length) {
|
||||
categories.value = list.map((item) => ({
|
||||
value: Number(item.value),
|
||||
label: item.label || '',
|
||||
icon: item.icon || '',
|
||||
icon_text: item.icon_text || '',
|
||||
}));
|
||||
}
|
||||
const def = Number(res?.default);
|
||||
if (def) prescriptionTypeDefault.value = def;
|
||||
} catch (e) {
|
||||
console.error('加载处方类型失败', e);
|
||||
message.warning('处方类型加载失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
/** 将当前分类 Tab 滚入可视区 */
|
||||
function focusActiveCategoryTab() {
|
||||
const el = document.getElementById(`rx-pc-tab-${activeCategory.value}`);
|
||||
el?.scrollIntoView({ behavior: 'smooth', inline: 'center', block: 'nearest' });
|
||||
}
|
||||
|
||||
const userStore = useUserStore();
|
||||
const myStoreId = ref(userStore.userInfo.store_id);
|
||||
loadPrescriptionTypeOptions();
|
||||
/** 当前取价门店是否允许查看毛利率(0/1) */
|
||||
const seeRate = ref(0);
|
||||
/** 开方是否可选医保(0=仅自费) */
|
||||
@@ -376,15 +408,20 @@ getPatientListByReception();
|
||||
// 每5秒更新数据
|
||||
setInterval(getPatientListByReception, 30_000);
|
||||
|
||||
// 药品分类
|
||||
const categories = [
|
||||
{label: '中药', value: 1},
|
||||
{label: '中成(西)药', value: 2},
|
||||
{label: '保健食品', value: 3},
|
||||
{label: '产品服务包', value: 5},
|
||||
{label: '非药品', value: 6},
|
||||
{label: '医疗器械', value: 7},
|
||||
];
|
||||
// 药品分类(后端下发;失败时用本地兜底)
|
||||
const categories = ref([
|
||||
{label: '中药', value: 1, icon: '', icon_text: ''},
|
||||
{label: '中成(西)药', value: 2, icon: '', icon_text: ''},
|
||||
{label: '保健食品', value: 3, icon: '', icon_text: ''},
|
||||
{label: '产品服务包', value: 5, icon: '', icon_text: ''},
|
||||
{label: '非药品', value: 6, icon: '', icon_text: ''},
|
||||
{label: '医疗器械', value: 7, icon: '', icon_text: ''},
|
||||
]);
|
||||
/** 后端默认处方类型 */
|
||||
const prescriptionTypeDefault = ref(2);
|
||||
/** 内容区左右滑切换 Tab */
|
||||
const rxSwipeStartX = ref(0);
|
||||
const rxSwipeStartY = ref(0);
|
||||
|
||||
// 当前状态
|
||||
const activePatient = ref<null | Patient>(null);
|
||||
@@ -601,6 +638,8 @@ const selectPatient = async (patient: Patient, isUpdateTabType = true) => {
|
||||
activePatient.value = patient.user_patient;
|
||||
|
||||
const registerId = patient.id;
|
||||
// 先拉类型,再恢复草稿/默认 Tab
|
||||
await loadPrescriptionTypeOptions(registerId);
|
||||
// 优先恢复完整草稿(诊断、医嘱、诊疗费、中药配置等)
|
||||
const hasDraft = await restoreReceptionDraft(registerId);
|
||||
if (!hasDraft) {
|
||||
@@ -614,6 +653,9 @@ const selectPatient = async (patient: Patient, isUpdateTabType = true) => {
|
||||
activeCategory.value = 1;
|
||||
} else if (westData && JSON.parse(westData).length > 0) {
|
||||
activeCategory.value = 2;
|
||||
} else if (prescriptionTypeDefault.value) {
|
||||
// 无草稿时使用后端下发的默认类型
|
||||
activeCategory.value = prescriptionTypeDefault.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1011,7 +1053,7 @@ const showPrescription = () => {
|
||||
tabType.value = 2;
|
||||
};
|
||||
|
||||
// 监听tabType.value变化
|
||||
// 监听tabType.value变化;进入开方面板时强制拉一次处方类型
|
||||
watch(
|
||||
() => tabType.value,
|
||||
(newValue) => {
|
||||
@@ -1022,6 +1064,10 @@ watch(
|
||||
prescriptionList.value = value.prescription;
|
||||
});
|
||||
}
|
||||
if (newValue === 2) {
|
||||
const rid = getRegisterId() || selectPatientId.value || 0;
|
||||
loadPrescriptionTypeOptions(Number(rid) || undefined);
|
||||
}
|
||||
newDrugInfo.value = {};
|
||||
localStorage.setItem(
|
||||
`doctorReception-type`,
|
||||
@@ -1439,6 +1485,27 @@ function tabChange(id) {
|
||||
if (id === 1) {
|
||||
checkAndShowTransferTip();
|
||||
}
|
||||
focusActiveCategoryTab();
|
||||
}
|
||||
|
||||
/** 记录左右滑起点 */
|
||||
function onRxPanelPointerDown(e: PointerEvent) {
|
||||
rxSwipeStartX.value = e.clientX;
|
||||
rxSwipeStartY.value = e.clientY;
|
||||
}
|
||||
|
||||
/** 左右滑切换相邻处方类型 */
|
||||
function onRxPanelPointerUp(e: PointerEvent) {
|
||||
const dx = e.clientX - rxSwipeStartX.value;
|
||||
const dy = e.clientY - rxSwipeStartY.value;
|
||||
if (Math.abs(dx) < 80 || Math.abs(dx) <= Math.abs(dy)) return;
|
||||
const list = categories.value || [];
|
||||
if (list.length < 2) return;
|
||||
const idx = list.findIndex((c) => Number(c.value) === Number(activeCategory.value));
|
||||
if (idx < 0) return;
|
||||
const nextIdx = dx < 0 ? idx + 1 : idx - 1;
|
||||
if (nextIdx < 0 || nextIdx >= list.length) return;
|
||||
tabChange(list[nextIdx].value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2777,14 +2844,28 @@ watch(
|
||||
<div class="drug-categories">
|
||||
<button
|
||||
v-for="category in categories"
|
||||
:id="`rx-pc-tab-${category.value}`"
|
||||
:key="category.value"
|
||||
:class="{ active: activeCategory === category.value }"
|
||||
@click="tabChange(category.value)"
|
||||
>
|
||||
{{ category.label }}
|
||||
<img
|
||||
v-if="category.icon"
|
||||
class="tab-type-icon"
|
||||
:src="category.icon"
|
||||
alt=""
|
||||
/>
|
||||
<span>{{ category.label }}</span>
|
||||
<span v-if="category.icon_text" class="tab-type-badge">{{ category.icon_text }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="rx-swipe-panel"
|
||||
@pointerdown="onRxPanelPointerDown"
|
||||
@pointerup="onRxPanelPointerUp"
|
||||
>
|
||||
|
||||
<SpecialPrescriptionImportCard
|
||||
v-if="hasSpecialPrescriptionRecord"
|
||||
class="mt-5 max-w-xl"
|
||||
@@ -2866,6 +2947,10 @@ watch(
|
||||
</ImagePreviewGroup>
|
||||
</div>
|
||||
<!-- 已选药品列表 -->
|
||||
<!-- 中药:顶部固定展示已选种数 -->
|
||||
<div v-if="activeCategory === 1" class="mb-3 mt-2 text-base font-medium text-gray-700">
|
||||
已选 {{ currentDrugs.length }} 种药
|
||||
</div>
|
||||
<!-- 中药 -->
|
||||
<div v-if="activeCategory === 1" class="mb-5 mt-3 flex" style="flex-wrap: wrap; width: 100%;">
|
||||
<Row>
|
||||
@@ -3469,6 +3554,7 @@ watch(
|
||||
保存为常用方
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
<div v-else-if="tabType === 0" class="prescription-panel">
|
||||
<Empty/>
|
||||
@@ -3650,6 +3736,9 @@ watch(
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.drug-categories button {
|
||||
@@ -3657,12 +3746,36 @@ watch(
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.dark .drug-categories button {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
.tab-type-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.tab-type-badge {
|
||||
font-size: 11px;
|
||||
color: #e6a23c;
|
||||
background: #fdf6ec;
|
||||
padding: 0 6px;
|
||||
border-radius: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.rx-swipe-panel {
|
||||
touch-action: pan-y;
|
||||
}
|
||||
|
||||
.drug-categories button.active {
|
||||
color: #fff;
|
||||
border-color: transparent;
|
||||
|
||||
@@ -54,7 +54,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[60%]" title="绑定诊所">
|
||||
<Modal class="w-[60%] h-[80%]" title="绑定诊所">
|
||||
<div style="width: 80%; margin: 30px auto">
|
||||
<StoreMultiSearch
|
||||
v-if="data"
|
||||
|
||||
@@ -55,7 +55,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[60%]" title="绑定诊所">
|
||||
<Modal class="w-[60%] h-[80%]" title="绑定诊所">
|
||||
<div style="width: 80%; margin: 30px auto">
|
||||
<StoreMultiSearch
|
||||
v-if="data"
|
||||
|
||||
@@ -60,7 +60,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="申请提现">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="申请提现">
|
||||
<InvalidatedForm />
|
||||
<SettlementForm />
|
||||
</Modal>
|
||||
|
||||
@@ -64,7 +64,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="type === 1 ? '作废订单' : '结算订单'" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="type === 1 ? '作废订单' : '结算订单'" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<InvalidatedForm v-if="type === 1" />
|
||||
<SettlementForm v-else />
|
||||
</Modal>
|
||||
|
||||
@@ -60,7 +60,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="`提现审核【${type === 1 ? '拒绝' : '通过'}】`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`提现审核【${type === 1 ? '拒绝' : '通过'}】`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<WithdrawalAuditForm />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -57,7 +57,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="编辑银行卡账户">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="编辑银行卡账户">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -61,7 +61,7 @@ const setAmount = (amount: number) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="申请提现">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="申请提现">
|
||||
<Form />
|
||||
<div class="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
<Button type="primary" @click="setAmount(1000)"> 1000 </Button>
|
||||
|
||||
@@ -39,7 +39,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="Api访问日志详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="Api访问日志详情">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Descriptions
|
||||
:column="{ xxl: 2, xl: 2, lg: 2, md: 2, sm: 2, xs: 2 }"
|
||||
|
||||
@@ -55,7 +55,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="监管回调详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="监管回调详情">
|
||||
<Spin :spinning="loading">
|
||||
<Descriptions bordered :column="2" class="mb-4">
|
||||
<Descriptions.Item label="记录ID">{{ data.id }}</Descriptions.Item>
|
||||
|
||||
@@ -30,7 +30,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="分账日志详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="分账日志详情">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Descriptions
|
||||
:column="{ xxl: 1, xl: 1, lg: 1, md: 1, sm: 1, xs: 1 }"
|
||||
|
||||
@@ -32,7 +32,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="Api访问日志详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="Api访问日志详情">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Descriptions
|
||||
:column="{ xxl: 1, xl: 1, lg: 1, md: 1, sm: 1, xs: 1 }"
|
||||
|
||||
@@ -30,7 +30,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="操作日志详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="操作日志详情">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Descriptions
|
||||
:column="{ xxl: 1, xl: 1, lg: 1, md: 1, sm: 1, xs: 1 }"
|
||||
|
||||
@@ -30,7 +30,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="订单日志详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="订单日志详情">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Descriptions
|
||||
:column="{ xxl: 1, xl: 1, lg: 1, md: 1, sm: 1, xs: 1 }"
|
||||
|
||||
@@ -30,7 +30,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="处方日志详情">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="处方日志详情">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Descriptions
|
||||
:column="{ xxl: 1, xl: 1, lg: 1, md: 1, sm: 1, xs: 1 }"
|
||||
|
||||
@@ -67,7 +67,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal title="拒绝审核" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal title="拒绝审核" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -37,7 +37,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%]" title="处方溯源">
|
||||
<Modal class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]" title="处方溯源">
|
||||
<PrescriptionSourceContent :data="data" />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -51,7 +51,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="`订单:【 ${orderNo} 】发货`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`订单:【 ${orderNo} 】发货`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -54,7 +54,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}平台`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}平台`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -54,7 +54,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}角色`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}角色`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -87,7 +87,7 @@ const rowImageSrc = (row: DrugItem) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal title="修改药品价格" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal title="修改药品价格" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<div>
|
||||
<Tabs v-model:activeKey="activeTab">
|
||||
<TabPane
|
||||
|
||||
@@ -54,7 +54,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}供应商`" class="w-[80%] md:w-[50%] lg:w-[30%]">
|
||||
<Modal :title="`${isUpdate === true ? '编辑' : '新增'}供应商`" class="w-[80%] md:w-[50%] lg:w-[30%] h-[60%]">
|
||||
<Form />
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user