导出列顺序:
{{ fieldOrderPreview }}
diff --git a/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue b/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue
index 4eb7b3f9..26b60a3d 100644
--- a/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue
+++ b/apps/web-antd/src/views/business/order/product-order/components/cells/OrderUserInfoCell.vue
@@ -3,7 +3,7 @@
* 订单列表:下单用户 / 医生 / 就诊人信息单元
* 下单用户 → 该用户就诊人列表 Modal;就诊人 → 详情 Modal
*/
-import { Avatar, Button, Tag } from 'ant-design-vue';
+import { Avatar, Button } from 'ant-design-vue';
import { resolveAvatarUrl } from '#/views/system/store-input/utils/inputUser';
diff --git a/apps/web-antd/src/views/business/order/product-order/config/constants.ts b/apps/web-antd/src/views/business/order/product-order/config/constants.ts
new file mode 100644
index 00000000..eab344a6
--- /dev/null
+++ b/apps/web-antd/src/views/business/order/product-order/config/constants.ts
@@ -0,0 +1,58 @@
+/**
+ * 商品订单模块共用常量
+ *
+ * 处方类型/订单状态等 Tag 映射此前散落在 index.vue 模板的 if-else 链里,
+ * 漏掉了特色方(0),且列表/卡片/导出各处无法复用,统一收敛到这里。
+ */
+export interface TagMeta {
+ /** 显示文案 */
+ label: string;
+ /** antd Tag color */
+ color: string;
+}
+
+/**
+ * 处方类型(prescription_type)全量映射
+ * 对齐后端 ProductTypeEnum:含不参与开方筛选的特色方(0)与历史遗留值(4=西药)
+ */
+export const PRESCRIPTION_TYPE_MAP: Record
= {
+ 0: { label: '特色方', color: 'gold' },
+ 1: { label: '中药', color: 'orange' },
+ 2: { label: '西药', color: 'blue' },
+ 3: { label: '保健食品', color: 'purple' },
+ 4: { label: '西药', color: 'green' },
+ 5: { label: '产品服务包', color: 'pink' },
+ 6: { label: '非药品', color: 'cyan' },
+ 7: { label: '医疗器械', color: 'geekblue' },
+};
+
+/** 订单状态(status)映射,与列表原 if-else 链颜色语义一致 */
+export const ORDER_STATUS_MAP: Record = {
+ 0: { label: '待支付', color: 'red' },
+ 1: { label: '待发货', color: 'orange' },
+ 2: { label: '待收货', color: 'blue' },
+ 3: { label: '待评价', color: 'purple' },
+ 4: { label: '已退款', color: 'green' },
+ 5: { label: '退款中', color: 'pink' },
+ 6: { label: '已收货', color: 'cyan' },
+ 7: { label: '确认收货', color: 'green' },
+ 8: { label: '拒绝退款', color: '#B22222' },
+ 9: { label: '已取消', color: 'gray' },
+};
+
+/** 订单类型(order_type)映射:非 1 的订单不展示处方类型 Tag */
+export const ORDER_TYPE_MAP: Record = {
+ 1: { label: '处方订单', color: 'yellow' },
+ 2: { label: '预约购药订单', color: 'yellow' },
+ 3: { label: '商城处方订单', color: 'yellow' },
+};
+
+/** 就诊来源(is_online)映射,0/其他值视为线下就诊 */
+export const IS_ONLINE_MAP: Record = {
+ 1: { label: '在线问诊', color: 'blue' },
+ 2: { label: '在线复诊(诊所)', color: 'green' },
+ 3: { label: '在线复诊(药店)', color: 'green' },
+};
+
+/** 就诊来源兜底(线下) */
+export const IS_ONLINE_FALLBACK: TagMeta = { label: '线下就诊', color: 'default' };
diff --git a/apps/web-antd/src/views/business/order/product-order/config/search.ts b/apps/web-antd/src/views/business/order/product-order/config/search.ts
index 629594ea..92e83b7d 100644
--- a/apps/web-antd/src/views/business/order/product-order/config/search.ts
+++ b/apps/web-antd/src/views/business/order/product-order/config/search.ts
@@ -7,12 +7,39 @@ import {
} from '#/views/business/order/product-order/api';
export const formOptions: VbenFormProps = {
- // 默认展开
- collapsed: false,
+ // 默认收起只显示第一行,点「展开」看全部筛选(字段多,全展开太占高度)
+ collapsed: true,
+ commonConfig: {
+ // label 默认 100px,本页筛选名最长 4 字,收窄到 70px 让控件占满格子(否则控件被挤得只剩一半宽)
+ labelWidth: 70,
+ // antd Select/RangePicker 默认按内容收缩,统一撑满格子,保证一行里各控件等宽整齐
+ componentProps: {
+ class: 'w-full',
+ },
+ },
+ // 响应式多列:抽出 grid 后 vben form 默认单列(一行一个字段),必须显式给栅格
+ wrapperClass: 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5',
schema: [
{
- component: 'VbenInput',
+ // 放第一位:时间范围有默认值(本月至今),默认收起时必须始终可见,否则用户不知道当前查的是哪段数据
+ component: 'RangePicker',
componentProps: {
+ format: 'YYYY-MM-DD',
+ // 提交纯日期,后端 getWhereBetween 会把结束日扩到当天 23:59:59
+ valueFormat: 'YYYY-MM-DD',
+ },
+ defaultValue: [
+ dayjs().startOf('month').format('YYYY-MM-DD'),
+ dayjs().format('YYYY-MM-DD'),
+ ],
+ fieldName: 'search_time',
+ label: '时间范围',
+ },
+ {
+ // 统一 antd 系控件:与 ApiSelect/门店搜索同一套视觉(此前 VbenInput 是 shadcn 风格,高度圆角不一致)
+ component: 'Input',
+ componentProps: {
+ allowClear: true,
placeholder: '输入订单号',
},
defaultValue: '',
@@ -47,8 +74,8 @@ export const formOptions: VbenFormProps = {
label: '订单状态',
},
{
- // 医生代支付:按 pay_user_type=2 筛选,方便在列表中定位代付单
- component: 'VbenSelect',
+ // 医生代支付:2=代支付(含历史单流水回落),1=用户自付
+ component: 'Select',
componentProps: {
allowClear: true,
options: [
@@ -61,11 +88,9 @@ export const formOptions: VbenFormProps = {
label: '付款方式',
},
{
- component: 'VbenSelect',
+ component: 'Select',
componentProps: {
allowClear: true,
- filterOption: true,
- showSearch: true,
options: [
{
label: '快递到家',
@@ -101,8 +126,9 @@ export const formOptions: VbenFormProps = {
label: '订单类型',
},
{
- component: 'VbenInput',
+ component: 'Input',
componentProps: {
+ allowClear: true,
placeholder: '药品名称/拼音首拼',
},
defaultValue: '',
@@ -110,23 +136,32 @@ export const formOptions: VbenFormProps = {
label: '药品',
},
{
- component: 'RangePicker',
+ // 就诊人筛选:后端 whereHas userPatient 姓名/手机号模糊
+ component: 'Input',
componentProps: {
- format: 'YYYY-MM-DD',
- // 提交纯日期,后端 getWhereBetween 会把结束日扩到当天 23:59:59
- valueFormat: 'YYYY-MM-DD',
+ allowClear: true,
+ placeholder: '姓名/手机号',
},
- defaultValue: [
- dayjs().startOf('month').format('YYYY-MM-DD'),
- dayjs().format('YYYY-MM-DD'),
- ],
- fieldName: 'search_time',
- label: '时间范围',
+ defaultValue: '',
+ fieldName: 'patient_keyword',
+ label: '就诊人',
+ },
+ {
+ // 医生筛选:后端 whereHas doctorInfo 姓名/手机号模糊
+ component: 'Input',
+ componentProps: {
+ allowClear: true,
+ placeholder: '姓名/手机号',
+ },
+ defaultValue: '',
+ fieldName: 'doctor_keyword',
+ label: '医生',
},
],
showCollapseButton: true,
submitButtonOptions: {
content: '查询',
},
- submitOnEnter: false,
+ // 任意输入框回车即搜索;下拉面板打开时的回车只选中选项(core 层已处理),第二次回车才搜索
+ submitOnEnter: true,
};
diff --git a/apps/web-antd/src/views/business/order/product-order/config/table.ts b/apps/web-antd/src/views/business/order/product-order/config/table.ts
index a8884a70..2becbe5f 100644
--- a/apps/web-antd/src/views/business/order/product-order/config/table.ts
+++ b/apps/web-antd/src/views/business/order/product-order/config/table.ts
@@ -2,12 +2,18 @@ import type { VxeGridProps } from '#/adapter/vxe-table';
import { getOrderList } from '#/views/business/order/product-order/api';
+/**
+ * 商品订单列表行类型:后端行字段众多(含关联 store/address/salesperson/items),
+ * 用索引签名放宽,避免模板槽访问动态字段时 vue-tsc 报属性缺失
+ */
interface RowType {
- id: string;
- name: string;
- logo: string;
- introduce: string;
+ id: number;
+ order_no: string;
+ status: number;
+ order_type: number;
+ prescription_type: number;
created_at: string;
+ [key: string]: any;
}
export const gridOptions: VxeGridProps = {
@@ -115,6 +121,8 @@ export const gridOptions: VxeGridProps = {
},
border: false,
toolbarConfig: {
+ // 是否显示搜索表单控制按钮
+ // @ts-ignore 正式环境时有完整的类型声明
search: true,
refresh: true,
print: false,
diff --git a/apps/web-antd/src/views/business/order/product-order/index.vue b/apps/web-antd/src/views/business/order/product-order/index.vue
index d04cdf0d..1f38f345 100644
--- a/apps/web-antd/src/views/business/order/product-order/index.vue
+++ b/apps/web-antd/src/views/business/order/product-order/index.vue
@@ -2,18 +2,11 @@
import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridListeners } from '#/adapter/vxe-table';
-import { computed, ref } from 'vue';
+import { computed, onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
-import {
- AnalysisOverview,
- type AnalysisOverviewItem,
- Page,
- useVbenDrawer,
- useVbenModal,
-} from '@vben/common-ui';
+import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { useUserStore } from '@vben/stores';
-import { SvgCakeIcon } from '@vben/icons';
import {
Button,
@@ -30,6 +23,9 @@ import {
import dayjs from 'dayjs';
+import type { ActionItem } from '#/components/table-action';
+
+import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { TableAction } from '#/components/table-action';
import SensitiveText from '#/components/sensitive-text/SensitiveText.vue';
@@ -67,16 +63,27 @@ import DetailModal from './components/detail.vue';
import OrderUserInfoCell from './components/cells/OrderUserInfoCell.vue';
import LogisticsModal from './components/logistics-modal.vue';
import FormModalDemo from './components/modal.vue';
+import ProductOrderCardList from './components/ProductOrderCardList.vue';
import ProductOrderExportModal from './components/ProductOrderExportModal.vue';
import Refund from './components/refund.vue';
+import {
+ ORDER_STATUS_MAP,
+ ORDER_TYPE_MAP,
+ PRESCRIPTION_TYPE_MAP,
+} from './config/constants';
import { formOptions } from './config/search';
import { gridOptions } from './config/table';
+import { useViewMode, ViewModeSwitch } from '#/components/view-mode-switch';
+import { StatIslands, type StatIslandItem } from '#/components/stat-islands';
import { isPlatformSuperAdmin } from '#/views/system/admin/_shared/platform-admin-role';
const router = useRouter();
const route = useRoute();
const userStore = useUserStore();
-const canViewInviterCommission = isPlatformSuperAdmin(userStore.userInfo);
+// vben 登录态 roles 为 string[] 与本地 PlatformAdminUserInfo 结构不同,仅取 role_id 判断,直接断言
+const canViewInviterCommission = isPlatformSuperAdmin(
+ userStore.userInfo as Parameters[0],
+);
const hasTopTableDropDownActions = ref(false);
@@ -149,7 +156,14 @@ function buildFormOptionsFromRoute(): VbenFormProps {
}
if (item.fieldName === 'search_time') {
if (timeScope === 'month') {
- return { ...item, defaultValue: [dayjs().startOf('month'), dayjs()] };
+ // 与 RangePicker valueFormat 保持一致用字符串,defaultValue 会直接进入首屏搜索条件
+ return {
+ ...item,
+ defaultValue: [
+ dayjs().startOf('month').format('YYYY-MM-DD'),
+ dayjs().format('YYYY-MM-DD'),
+ ],
+ };
}
if (timeScope === 'all') {
return { ...item, defaultValue: null };
@@ -160,31 +174,118 @@ function buildFormOptionsFromRoute(): VbenFormProps {
return { ...formOptions, schema };
}
-const [Grid, gridApi] = useVbenVxeGrid({
- formOptions: buildFormOptionsFromRoute(),
- gridOptions,
- gridEvents,
+/** 列表/卡片双视图:通用 useViewMode 自带 localStorage 记忆 */
+const viewMode = useViewMode('product-order-view-mode');
+const cardListRef = ref | null>(null);
+
+/** 生效的搜索表单配置(含路由 store_id/time_scope 默认值注入) */
+const effectiveFormOptions = buildFormOptionsFromRoute();
+
+/**
+ * 从 schema 提取 defaultValue 作为首屏搜索条件
+ * 列表首屏 query 与卡片首屏 reload 都要带默认时间范围,否则查询口径与表单显示不一致
+ */
+function collectDefaultSearchValues(): Record {
+ const values: Record = {};
+ for (const item of effectiveFormOptions.schema ?? []) {
+ if (item.fieldName && item.defaultValue !== undefined) {
+ values[item.fieldName] = item.defaultValue;
+ }
+ }
+ return values;
+}
+
+/** 列表与卡片共用的搜索条件(提交/重置时整体替换,卡片靠 watch 自动拉数) */
+const searchValues = ref>(collectDefaultSearchValues());
+
+/**
+ * 顶部统一搜索表单(从 grid 内嵌表单抽出,双视图共用)
+ * 列表模式提交后 reload 回第 1 页;卡片模式改 searchValues 由 CardList watch 拉数
+ */
+const [SearchForm, searchFormApi] = useVbenForm({
+ ...effectiveFormOptions,
+ handleSubmit: async (values) => {
+ searchValues.value = { ...(values || {}) };
+ if (viewMode.value === 'list') {
+ gridApi.reload();
+ } else {
+ // 卡片视图数据由 formValues watch 驱动,这里只需同步顶部销售统计
+ saleAmount(searchValues.value);
+ }
+ },
+ handleReset: async () => {
+ // 自定义 handleReset 会接管默认行为,必须手动还原控件到 defaultValue(reset 为新 API,resetForm 已弃用)
+ await searchFormApi.reset();
+ searchValues.value = collectDefaultSearchValues();
+ if (viewMode.value === 'list') {
+ gridApi.reload();
+ } else {
+ saleAmount(searchValues.value);
+ }
+ },
});
-const initTableAjax = () => {
- gridApi.setGridOptions({
+const [Grid, gridApi] = useVbenVxeGrid({
+ gridOptions: {
+ ...gridOptions,
+ // 搜索已抽出为顶部统一表单,关闭 grid 自带的表单开关按钮
+ toolbarConfig: { ...gridOptions.toolbarConfig, search: false },
proxyConfig: {
ajax: {
- // 请求后端接口方法
- query: async ({ page }, formValues) => {
- saleAmount(formValues);
+ /** 始终合并顶部统一搜索条件;同时刷新顶部销售金额统计 */
+ query: async ({ page }: { page: { currentPage: number; pageSize: number } }) => {
+ saleAmount(searchValues.value);
return await getOrderList({
page: page.currentPage,
pageSize: page.pageSize,
- ...formValues,
+ ...searchValues.value,
});
},
},
},
- });
+ },
+ gridEvents,
+});
+
+// 记忆持久化由 useViewMode 内部完成;这里只处理切回列表时 grid 被 v-if 卸载过需重查
+watch(viewMode, (mode, prev) => {
+ if (mode === 'list' && prev === 'card') {
+ gridApi.query();
+ }
+});
+
+/** 操作成功后的视图刷新:列表保当前页,卡片原地重拉已加载范围 */
+async function refreshCurrentView() {
+ await (viewMode.value === 'list'
+ ? gridApi.query()
+ : cardListRef.value?.refreshKeepPage?.());
+}
+
+/** 回第 1 页的强刷新(弹窗内部 reload 语义) */
+function refreshCurrentViewFromPageOne() {
+ if (viewMode.value === 'list') {
+ gridApi.reload();
+ } else {
+ cardListRef.value?.reload?.();
+ }
+}
+
+/**
+ * 传给弹窗子组件的 gridApi 代理
+ * 发货/退款等弹窗内部只会调 reload()/query() 刷新列表,
+ * 卡片模式下需要转发给卡片列表,故不能直接把 gridApi 传进去
+ */
+const gridApiProxy = {
+ reload: () => refreshCurrentViewFromPageOne(),
+ query: () => refreshCurrentView(),
};
-initTableAjax();
+// 首屏是卡片模式时 grid 不渲染(ajax query 不会触发),顶部销售统计需要手动拉一次
+onMounted(() => {
+ if (viewMode.value === 'card') {
+ saleAmount(searchValues.value);
+ }
+});
const [FormModal, formModalApi] = useVbenModal({
connectedComponent: FormModalDemo,
});
@@ -208,7 +309,7 @@ const infoModal = (data: Record = {}) => {
// 带 id 走详情接口拿到 packages;values 作首屏兜底
id: data?.id,
values: data,
- gridApi,
+ gridApi: gridApiProxy,
// 详情内「发本包裹」:关详情后打开发货弹窗(仅平台包会传 0)
onShipPackage: (warehouseId: number) => {
modalApi.close();
@@ -248,7 +349,7 @@ const wareSend = (data: Record = {}, warehouseId?: number) => {
}
formModalApi.setData({
values,
- gridApi,
+ gridApi: gridApiProxy,
});
formModalApi.open();
};
@@ -259,12 +360,12 @@ const expandAll = () => {
const collapseAll = () => {
gridApi.grid?.setAllRowExpand(false);
};
-const overviewItems = ref([]);
+const overviewItems = ref([]);
const income = ref(0);
const total = ref(0);
-/** 按当前列表筛选条件刷新顶部销售金额/收益(支持门店多选 store_ids) */
+/** 按当前筛选条件刷新顶部销售金额/收益(支持门店多选 store_ids,双视图共用) */
const saleAmount = (formValues?: Record) => {
- const values = formValues ?? gridApi.formApi.latestSubmissionValues ?? {};
+ const values = formValues ?? searchValues.value ?? {};
saleAmountApi({
search_time: values.search_time,
store_ids: values.store_ids,
@@ -274,20 +375,20 @@ const saleAmount = (formValues?: Record) => {
}).then((res) => {
income.value = res.income;
total.value = res.total;
+ // 紧凑统计岛(设计对齐提现管理),替代原 AnalysisOverview 大卡
overviewItems.value = [
{
- icon: SvgCakeIcon,
- title: '销售金额',
- totalTitle: '销售金额',
- totalValue: total.value,
+ key: 'total',
+ label: '销售金额',
value: total.value,
+ icon: 'lucide:trending-up',
},
{
- icon: 'fluent-emoji:balance-scale',
- title: '我的收益',
- totalTitle: '我的收益',
- totalValue: income.value,
+ key: 'income',
+ label: '我的收益',
value: income.value,
+ icon: 'lucide:wallet',
+ emphasize: true,
},
];
});
@@ -413,7 +514,7 @@ async function openOrderPercentAdjust(row: Record) {
productOrderId: row.id,
quickOptions: normalizeQuickOptions(priceAdjustMeta.value.quickOptions),
onSuccess: () => {
- gridApi.reload();
+ refreshCurrentViewFromPageOne();
},
});
percentAdjustDrawerApi.open();
@@ -446,7 +547,7 @@ function handleSimulatePay(row: Record) {
onOk: async () => {
await simulatePayApi({ order_type: 'product', order_id: row.id });
message.success('模拟支付成功');
- await gridApi.query();
+ await refreshCurrentView();
},
});
}
@@ -469,7 +570,7 @@ function handleRetryConfirmReceive(row: Record) {
message.success(
res?.message || (isWaitReceive ? '确认收货成功' : '解冻重试成功'),
);
- await gridApi.query();
+ await refreshCurrentView();
},
});
}
@@ -485,7 +586,7 @@ async function handleAccrueSalesperson(row: Record) {
try {
await accrueSalespersonCommissionApi({ order_id: row.id });
message.success('分成成功');
- await gridApi.query();
+ await refreshCurrentView();
} catch (error: any) {
message.error(error?.message || '分成失败');
} finally {
@@ -507,7 +608,7 @@ async function handleReverseSalesperson(row: Record, salespersonId?
salesperson_id: spId,
});
message.success('退回分成成功');
- await gridApi.query();
+ await refreshCurrentView();
} catch (error: any) {
message.error(error?.message || '退回分成失败');
} finally {
@@ -546,7 +647,7 @@ function formatCommissionRecordDetail(record: Record) {
return `${typeText}${path} · ${record.commission_mode_text || '固定单价'} · ${rule}`;
}
-const openPrescriptionDetail = (values) => {
+const openPrescriptionDetail = (values: number) => {
// 打开西药处方模态框逻辑
PrescriptionDetailModalApi.setData({
values,
@@ -561,12 +662,12 @@ const openExportModal = () => {
exportModalApi.open();
};
-const openRefundModal = (id) => {
+const openRefundModal = (id: number) => {
RefundModalApi.setData({
values: {
order_id: id,
},
- gridApi,
+ gridApi: gridApiProxy,
});
RefundModalApi.open();
};
@@ -576,7 +677,7 @@ async function handleCancelOrder(row: Record) {
try {
await cancelOrderApi({ order_id: row.id });
message.success('订单已取消');
- await gridApi.query();
+ await refreshCurrentView();
} catch (error: any) {
message.error(error?.message || '取消失败');
}
@@ -741,7 +842,7 @@ async function submitChangeWarehouse() {
});
message.success(`改仓成功(${items.length} 种药品)`);
changeWhOpen.value = false;
- await gridApi.query();
+ await refreshCurrentView();
} catch (error: any) {
message.error(error?.message || '改仓失败');
} finally {
@@ -800,10 +901,119 @@ const fetchOrderAmountVerify = async () => {
}
};
-const openOrderAmountVerify = () => {
- verifyMismatchOnly.value = false;
- fetchOrderAmountVerify();
-};
+// 金额核对入口暂时下线(工具栏按钮已注释),恢复入口时一并取消本函数注释
+// const openOrderAmountVerify = () => {
+// verifyMismatchOnly.value = false;
+// fetchOrderAmountVerify();
+// };
+
+/**
+ * 列表槽用元数据取值 helper:v-if 双重索引无法类型收窄,统一在这里兜底
+ */
+function rowPrescriptionTypeMeta(row: Record) {
+ return PRESCRIPTION_TYPE_MAP[Number(row?.prescription_type)] ?? null;
+}
+function rowStatusMeta(row: Record) {
+ return ORDER_STATUS_MAP[Number(row?.status)] ?? null;
+}
+
+/**
+ * 构造行操作(列表 #action 槽与卡片 footer 共用同一份定义)
+ * 返回 TableAction 的 actions/dropDownActions,保证双视图按钮、权限(auth)、显隐条件完全一致
+ */
+function buildRowActions(row: Record): {
+ actions: ActionItem[];
+ dropDownActions: ActionItem[];
+} {
+ return {
+ actions: [
+ {
+ label: '详情',
+ type: 'link',
+ icon: 'marketeq:eye',
+ size: 'small',
+ onClick: infoModal.bind(null, row),
+ },
+ {
+ label: '物流动态',
+ type: 'link',
+ icon: 'mdi:truck-delivery-outline',
+ size: 'small',
+ // 上门快递且已支付、非取消/待支付:可单独查看物流
+ ifShow:
+ row.delivery_method === 0 &&
+ row.is_pay === 1 &&
+ row.status !== 0 &&
+ row.status !== 9,
+ onClick: openLogisticsModal.bind(null, row),
+ },
+ {
+ label: '溯源',
+ type: 'link',
+ icon: 'mdi:timeline-text',
+ size: 'small',
+ onClick: openOrderTrace.bind(null, row),
+ },
+ {
+ label: '处方',
+ type: 'link',
+ icon: 'marketeq:eye',
+ ifShow: row.order_type !== 2 && row.order_type !== 3,
+ onClick: openPrescriptionDetail.bind(null, row.p_id),
+ },
+ {
+ label: '模拟支付',
+ type: 'link',
+ icon: 'mdi:cash-check',
+ auth: ['Super Admin'],
+ ifShow: row.is_pay === 0,
+ onClick: handleSimulatePay.bind(null, row),
+ },
+ {
+ // 仅超管:待收货确认收货 / 已确认收货重试解冻
+ label: Number(row.status) === 2 ? '确认收货' : '重试解冻',
+ type: 'link',
+ icon: 'mdi:package-check',
+ auth: ['Super Admin'],
+ ifShow:
+ Number(row.is_pay) === 1 &&
+ Number(row.cancel_status) === 0 &&
+ Number(row.refund_status) === 0 &&
+ (Number(row.status) === 2 || Number(row.status) === 7),
+ onClick: handleRetryConfirmReceive.bind(null, row),
+ },
+ {
+ label: '发货',
+ type: 'link',
+ icon: 'ri:send-plane-fill',
+ auth: ['Super Admin', 'Admin'],
+ onClick: () => wareSend(row),
+ },
+ ],
+ dropDownActions: [
+ {
+ label: '取消订单',
+ type: 'link',
+ icon: 'mdi:cancel',
+ auth: ['Super Admin', 'Admin'],
+ ifShow:
+ row.status === 0 && row.is_pay === 0 && row.cancel_status === 0,
+ popConfirm: {
+ title: '确定取消该待支付订单吗?',
+ confirm: handleCancelOrder.bind(null, row),
+ },
+ },
+ {
+ label: '退款',
+ type: 'link',
+ icon: 'mingcute:refund-dollar-fill',
+ auth: ['Super Admin', 'Admin'],
+ ifShow: row.is_pay === 1,
+ onClick: openRefundModal.bind(null, row.id),
+ },
+ ],
+ };
+}
@@ -866,9 +1076,21 @@ const openOrderAmountVerify = () => {
- gridApi.query()" />
-
-
+ refreshCurrentView()" />
+
+
+
+
+
+
+
+
+
+
+
+
{
:checked="row.is_free_shipping === 1"
checked-children="包邮"
un-checked-children="不包邮"
- @change="(checked) => toggleFreeShipping(row, checked)"
+ @change="(checked: any) => toggleFreeShipping(row, Boolean(checked))"
/>
@@ -1240,37 +1462,15 @@ const openOrderAmountVerify = () => {
线下就诊
-
+
- 处方订单
-
- 预约购药订单
-
-
- 商城处方订单
+
+ {{ ORDER_TYPE_MAP[row.order_type]?.label || '预约购药订单' }}
-
- 处方订单【中药】
-
-
- 处方订单【西药】
-
-
- 处方订单【保健食品】
-
-
- 处方订单【西药】
-
-
- 处方订单【产品服务包】
-
-
- 处方订单【非药品】
-
-
- 处方订单【医疗器械】
+
+ 处方订单【{{ rowPrescriptionTypeMeta(row)!.label }}】
@@ -1280,114 +1480,17 @@ const openOrderAmountVerify = () => {
- 待支付
- 待发货
- 待收货
- 待评价
- 已退款
- 退款中
- 已收货
- 确认收货
- 拒绝退款
- 已取消
+
+ {{ rowStatusMeta(row)!.label }}
+
+
@@ -1415,7 +1518,7 @@ const openOrderAmountVerify = () => {