From 18d9511a893cda2557aed9940ddfa762254c6159 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Sun, 23 Aug 2026 10:59:22 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=E5=95=86=E5=93=81=E9=A2=84=E7=BA=A6?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=20feat:=E4=B8=AA=E4=BA=BA=E8=8F=9C=E8=B0=B1?= =?UTF-8?q?=E9=A2=84=E7=BA=A6=E7=BB=9F=E8=AE=A1=20feat:=E9=A2=84=E5=AE=9A?= =?UTF-8?q?=E6=89=A3=E5=BA=93=E5=AD=98=20feat:=E8=BF=87=E6=9C=9F=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E8=87=AA=E5=8A=A8=E9=80=80=E6=AC=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 8 +- src/api/canteen/canteenDailyMenu.ts | 14 ++ src/api/hard/hard-auto-refund-task.ts | 17 ++ src/api/hard/hard-total-appt.ts | 123 +++++++++++ src/api/wallet/mch-auto-refund-config.ts | 6 + src/constants/autoRefund.ts | 2 + .../appt/canteen-dept-appt-total/index.vue | 20 +- .../components/product-total-table.vue | 129 ++++++++++- .../appt/canteen-product-appt-total/index.vue | 160 +++++++++++--- .../reservation-statistics-drawer.vue | 137 ++++++++++++ .../reservation-statistics-summary.vue | 99 +++++++++ .../appt/canteen-user-appt-total/index.vue | 17 +- .../components/auto-refund-config.vue | 208 +++++++++++++++++- src/views/mch/mch-manage/detail.vue | 8 +- 14 files changed, 901 insertions(+), 47 deletions(-) create mode 100644 src/views/hard/appt/canteen-user-appt-total/components/reservation-statistics-drawer.vue create mode 100644 src/views/hard/appt/canteen-user-appt-total/components/reservation-statistics-summary.vue diff --git a/.env.development b/.env.development index ca8e0ab6..8b1842ea 100644 --- a/.env.development +++ b/.env.development @@ -10,8 +10,8 @@ ENV = 'development' # ADMIN 服务地址 # VITE_ADMIN_PROXY_PATH = http://123.157.250.162:8089/api/ # 测试线上 # VITE_ADMIN_PROXY_PATH = http://123.156.230.15:8089/api/ # 测试线上-过期 -# VITE_ADMIN_PROXY_PATH = https://www.zianxin.com/api -VITE_ADMIN_PROXY_PATH = http://localhost:9999/ +VITE_ADMIN_PROXY_PATH = https://www.zianxin.com/api +# VITE_ADMIN_PROXY_PATH = http://localhost:9999/ # VITE_ADMIN_PROXY_PATH = http://192.168.101.196:9999 # 邓-本地 # VITE_ADMIN_PROXY_PATH = http://59.202.170.152:81/api # 正式环境线上 @@ -21,8 +21,8 @@ VITE_ADMIN_PROXY_PATH = http://localhost:9999/ # 图片访问基础地址 # VITE_IMAGE_BASE_PATH = http://123.157.250.162:8089/api/ # 测试线上 # VITE_IMAGE_BASE_PATH = http://123.156.230.15:8089/api/ # 测试线上-过期 -# VITE_IMAGE_BASE_PATH = https://www.zianxin.com/api -VITE_IMAGE_BASE_PATH = http://localhost:9999 +VITE_IMAGE_BASE_PATH = https://www.zianxin.com/api +# VITE_IMAGE_BASE_PATH = http://localhost:9999 # VITE_IMAGE_BASE_PATH = http://192.168.101.196:9999 # 邓-本地 # VITE_IMAGE_BASE_PATH = http://59.202.170.152:81/api/ # 正式环境线上 diff --git a/src/api/canteen/canteenDailyMenu.ts b/src/api/canteen/canteenDailyMenu.ts index 9f5a7b0f..453f20d0 100644 --- a/src/api/canteen/canteenDailyMenu.ts +++ b/src/api/canteen/canteenDailyMenu.ts @@ -65,6 +65,20 @@ export function selectTimeFoodApi(query?: Object) { }) } +/** + * 查询指定日期、餐段和食堂的每日菜谱展示数据,返回套餐组成明细。 + * + * @param query 日期、餐段和食堂查询条件;餐段为空时查询该日全部餐段 + * @returns 每日菜谱商品列表,套餐通过 comboItems 携带组成菜品 + */ +export function getCanteenMenuList(query?: Object) { + return request({ + url: "/canteen/canteenDailyMenu/ad/getCanteenList", + method: "get", + params: query, + }) +} + // 根据每日日期和每日餐段类型获取可添加的不重复的菜品列表 export function getCanteenDailyMenuList(query?: Object) { return request({ diff --git a/src/api/hard/hard-auto-refund-task.ts b/src/api/hard/hard-auto-refund-task.ts index 684e0946..2aa00cab 100644 --- a/src/api/hard/hard-auto-refund-task.ts +++ b/src/api/hard/hard-auto-refund-task.ts @@ -9,6 +9,23 @@ export function page(query?: Object) { }) } +/** 查询已到期且仍可整单退款的每日菜谱预约订单候选。 */ +export function expiredCandidates(query?: Object) { + return request({ + url: "/hard/hard-auto-refund-task/expired-candidates", + method: "get", + params: query, + }) +} + +/** 管理端确认后逐单执行过期预约整单退款。 */ +export function expiredRefund(taskId: string) { + return request({ + url: `/hard/hard-auto-refund-task/${taskId}/expired-refund`, + method: "post", + }) +} + /** * 查询一次自动退款任务的只读尝试日志。 * diff --git a/src/api/hard/hard-total-appt.ts b/src/api/hard/hard-total-appt.ts index 4a12a957..14d0f626 100644 --- a/src/api/hard/hard-total-appt.ts +++ b/src/api/hard/hard-total-appt.ts @@ -71,6 +71,80 @@ export interface CanteenUserReservationExportTaskResponse { msg?: string } +/** 用户预约统计查询参数,字段与用户预约表格筛选条件保持一致。 */ +export type CanteenUserReservationStatisticsQuery = Omit & { + userIds?: Array +} + +/** 按餐段汇总的预约统计。金额单位为分。 */ +export interface CanteenUserReservationMealStatistics { + /** 餐段字典编码。 */ + hourType?: string + /** 该餐段去重后的预约人数。 */ + reservedUserCount?: number + /** 该餐段预约订单数。 */ + orderCount?: number + /** 该餐段菜品总份数。 */ + dishCount?: number + /** 该餐段预约总价,单位为分。 */ + totalPrice?: number +} + +/** 按餐段和菜品快照汇总的预约统计。金额单位为分。 */ +export interface CanteenUserReservationDishStatistics { + /** 餐段字典编码。 */ + hourType?: string + /** 下单时保存的菜品名称。 */ + productName?: string + /** 菜品总份数。 */ + productCount?: number + /** 包含该菜品的去重订单数。 */ + orderCount?: number + /** 菜品总价,单位为分。 */ + totalPrice?: number +} + +/** 预约统计的通用汇总结构。金额单位为分。 */ +export interface CanteenUserReservationStatisticsSummary { + /** 用户-用餐日期记录数。 */ + userCount?: number + /** 当前范围内去重用户数。 */ + uniqueUserCount?: number + /** 已订餐用户-用餐日期记录数。 */ + reservedUserCount?: number + /** 未订餐用户-用餐日期记录数。 */ + unreservedUserCount?: number + /** 有效预约订单数。 */ + orderCount?: number + /** 菜品总份数。 */ + dishCount?: number + /** 有效预约总价,单位为分。 */ + totalPrice?: number + /** 餐段统计列表。 */ + meals?: CanteenUserReservationMealStatistics[] + /** 菜品统计列表。 */ + dishes?: CanteenUserReservationDishStatistics[] +} + +/** 预约每日统计结构。 */ +export interface CanteenUserReservationDailyStatistics extends CanteenUserReservationStatisticsSummary { + /** 用餐日期,格式为 YYYY-MM-DD。 */ + date?: string +} + +/** 预约统计接口响应。 */ +export interface CanteenUserReservationStatisticsResponse { + /** 统计响应数据。 */ + data: { + /** 查询范围总计。 */ + total?: CanteenUserReservationStatisticsSummary + /** 按日统计列表。 */ + daily?: CanteenUserReservationDailyStatistics[] + } + /** 后端返回的提示信息。 */ + msg?: string +} + /** * 按预约使用日期查询食堂预约部门统计。 */ @@ -126,6 +200,20 @@ export function getCanteenUserReservationDetail(query: CanteenUserReservationDet }) } +/** + * 按当前用户预约表格筛选条件查询每日和查询范围总计。 + * + * @param query 用户、日期、部门、食堂、餐段和状态筛选条件 + * @returns 包含每日统计与总计的统一响应 + */ +export function getCanteenUserReservationStatistics(query: CanteenUserReservationStatisticsQuery) { + return request({ + url: "/hard/hard-canteen-appt-total-log/user-reserv-statistics", + method: "post", + data: query, + }) +} + /** * 按当前筛选条件提交用户每日预约异步导出任务。 * @@ -153,3 +241,38 @@ export function exportCanteenUserReservation(query: CanteenUserReservationQuery) responseType: "blob", }) } + +/** 菜品预约统计导出查询条件,日期范围使用预约使用时间闭区间。 */ +export interface CanteenProductReservationExportQuery { + /** 预约使用日期时间范围,格式为 YYYY-MM-DD HH:mm:ss。 */ + apptUseDateTimeList?: [string, string] + /** 餐段字典编码。 */ + hourType?: string | number + /** 食堂商户主键。 */ + merchantId?: string | number + /** 用户部门主键集合。 */ + userDeptIds?: Array + /** 是否包含所选部门。 */ + isInclude?: boolean + /** 商户部门主键集合。 */ + merchantDeptIds?: Array + /** 菜品预约统计允许的商户主键集合。 */ + mchIds?: Array +} + +/** 菜品预约统计异步导出提交接口的统一响应。 */ +export interface CanteenProductReservationExportTaskResponse { + /** 后端创建的异步任务进度。 */ + data: AsyncTaskProgress + /** 后端返回的任务提交提示。 */ + msg?: string +} + +/** 按当前菜品预约统计筛选条件提交异步导出任务。 */ +export function submitCanteenProductReservationExport(query: CanteenProductReservationExportQuery) { + return request({ + url: "/hard/hard-canteen-appt-total-log/product-reserv-export-task", + method: "post", + data: query, + }) +} diff --git a/src/api/wallet/mch-auto-refund-config.ts b/src/api/wallet/mch-auto-refund-config.ts index 61a7d7b7..924db874 100644 --- a/src/api/wallet/mch-auto-refund-config.ts +++ b/src/api/wallet/mch-auto-refund-config.ts @@ -14,6 +14,12 @@ export interface MchAutoRefundConfig { ruleType: "PAY_TIME_LIMIT" | "APPT_CYCLE_CLOSE" /** 支付后限时小时数,周期规则下为空。 */ payTimeLimitHours?: number | null + /** 过期预约自动退款开关,1 开启、0 关闭。 */ + expiredReserveRefundEnabled: "0" | "1" + /** 餐段结束后的延迟小时数,范围 1-168。 */ + expiredReserveRefundDelayHours?: number | null + /** 过期预约退款是否恢复库存,1 恢复、0 不恢复。 */ + expiredReserveRefundRestoreInventory: "0" | "1" } /** diff --git a/src/constants/autoRefund.ts b/src/constants/autoRefund.ts index b21ebbca..02c53b3a 100644 --- a/src/constants/autoRefund.ts +++ b/src/constants/autoRefund.ts @@ -39,6 +39,8 @@ export const AUTO_REFUND_TRIGGER_TYPE: Record = { "20": "定时重试", /** 管理端技术人员对耗尽任务额外触发一次。 */ "30": "人工技术重试", + /** 管理端具备业务退款权限的逐单过期预约退款。 */ + "40": "后台逐单过期退款", } /** 自动退款尝试结果展示配置。 */ diff --git a/src/views/hard/appt/canteen-dept-appt-total/index.vue b/src/views/hard/appt/canteen-dept-appt-total/index.vue index a35d5f9c..f7d36c06 100644 --- a/src/views/hard/appt/canteen-dept-appt-total/index.vue +++ b/src/views/hard/appt/canteen-dept-appt-total/index.vue @@ -18,7 +18,7 @@ - + @@ -128,6 +128,7 @@ import { displayPrice } from "/@/utils/formatMoney" import { useDict } from "/@/hooks/dict" import { getDicts } from "/@/api/admin/dict" import { parseTime } from "/@/utils/formatTime" +import dayjs from "dayjs" import * as hardTotalApptApi from "/@/api/hard/hard-total-appt" @@ -150,8 +151,22 @@ const selectObjs = ref([]) as any const multiple = ref(true) const draggableDepTreeRef = ref() // 树组件ref引用 +/** 获取包含今天在内的最近七个自然日预约时间闭区间。 */ +const getDefaultAppointmentDateTimeRange = (): [string, string] => { + const endDate = dayjs() + return [ + endDate.subtract(6, "day").startOf("day").format("YYYY-MM-DD HH:mm:ss"), + endDate.endOf("day").format("YYYY-MM-DD HH:mm:ss"), + ] +} + +/** 预约日期范围默认覆盖开始日零点至结束日最后一秒。 */ +const appointmentDateDefaultTime = [new Date(2000, 0, 1, 0, 0, 0), new Date(2000, 0, 1, 23, 59, 59)] + const state: BasicTableProps = reactive({ - queryForm: {}, + queryForm: { + apptUseDateTimeList: getDefaultAppointmentDateTimeRange(), + }, }) // table hook @@ -185,6 +200,7 @@ const resetQuery = () => { selectObjs.value = [] state.queryForm.deptId = "" state.queryForm.userDeptIds = [] + state.queryForm.apptUseDateTimeList = getDefaultAppointmentDateTimeRange() getDataList() } diff --git a/src/views/hard/appt/canteen-product-appt-total/components/product-total-table.vue b/src/views/hard/appt/canteen-product-appt-total/components/product-total-table.vue index 698c2558..e79d8174 100644 --- a/src/views/hard/appt/canteen-product-appt-total/components/product-total-table.vue +++ b/src/views/hard/appt/canteen-product-appt-total/components/product-total-table.vue @@ -17,12 +17,27 @@ :header-cell-style="tableStyle.headerCellStyle" :summary-method="getSummaries" :show-summary="true" @selection-change="selectionChangHandle" @sort-change="sortChangeHandle"> - + + + + - + import("./components/reservation-statistics-drawer.vue")) + /** 已完成核销订单状态编码,属于现有前后端协议。 */ const VERIFIED_ORDER_STATUS = "20" @@ -370,6 +377,8 @@ interface ReservationDetailDialogState { const draggableDepTreeRef = ref() /** 查询面板引用,用于重置表单字段和校验状态。 */ const queryRef = ref() +/** 预约统计抽屉引用,用于传入当前表格查询条件并触发统计请求。 */ +const statisticsDrawerRef = ref() /** 用户预约异步导出进度弹窗引用,用于提交成功后启动统一轮询。 */ const exportProgressRef = ref>() /** 导出任务提交中的本地互斥状态,防止接口返回前连续创建重复任务。 */ @@ -588,6 +597,12 @@ function doSearch() { getDataList() } +/** 按当前表格查询条件打开统计抽屉,日期校验与列表查询保持一致。 */ +function openStatisticsDrawer() { + if (!validateDateRange(true)) return + statisticsDrawerRef.value?.open({ ...state.queryForm }) +} + /** * 重置查询面板和部门树,恢复最近七天的默认用餐日期范围后重新查询。 */ diff --git a/src/views/mch/mch-manage/components/auto-refund-config.vue b/src/views/mch/mch-manage/components/auto-refund-config.vue index f14f3c4d..4d0ae9df 100644 --- a/src/views/mch/mch-manage/components/auto-refund-config.vue +++ b/src/views/mch/mch-manage/components/auto-refund-config.vue @@ -1,5 +1,5 @@ + +
+

过期预约自动退款

+ + + +
+ + + + + + + + + + + + + + + + + + + +
+

待过期退款订单

+ 刷新列表 +
+ + + + + + + + + + + + + + + + + + + diff --git a/src/components/UserIdentityQuery/types.ts b/src/components/UserIdentityQuery/types.ts new file mode 100644 index 00000000..8aa8d65b --- /dev/null +++ b/src/components/UserIdentityQuery/types.ts @@ -0,0 +1,62 @@ +/** 用户身份扩展查询字段所属的前端模型。 */ +export type UserIdentityQueryModelName = "studentInfo" | "teacherInfo" + +/** 用户身份扩展查询字段使用的表单控件。 */ +export type UserIdentityQueryControl = "input" | "dict-select" + +/** 单个用户身份扩展查询字段的渲染配置。 */ +export interface UserIdentityQueryFieldConfig { + /** 显示该字段所需的身份协议编码。 */ + identityType: string + /** 字段所属的查询模型名称。 */ + modelName: UserIdentityQueryModelName + /** 前后端 DTO 共同使用的字段名称。 */ + field: string + /** 查询表单展示的字段名称。 */ + label: string + /** 字段未填写时展示的输入提示。 */ + placeholder: string + /** 字段使用的表单控件类型。 */ + control: UserIdentityQueryControl + /** 字典选择控件的数据字典编码;普通输入框不设置。 */ + dictCode?: string +} + +/** 学生身份扩展查询条件;学号和学校使用精确匹配,其余文本字段使用包含匹配。 */ +export interface UserIdentityStudentQuery { + /** 学生学号,来源于学生身份扩展表,按完整学号精确匹配。 */ + studentNo?: string + /** 学校名称,来源于学生身份扩展表,按学校字典值精确匹配。 */ + schoolName?: string + /** 班级名称,来源于学生身份扩展表。 */ + className?: string + /** 监护人手机号,来源于学生身份扩展表中逗号分隔的手机号集合。 */ + guardianPhones?: string +} + +/** 老师身份扩展查询条件。 */ +export interface UserIdentityTeacherQuery { + /** 老师学号,来源于老师身份扩展表,按完整学号精确匹配。 */ + teacherNo?: string +} + +/** + * 创建用户身份通用查询组件的学生扩展字段初始值。 + * + * @returns 所有学生身份查询字段均为空的独立对象 + */ +export const createEmptyUserIdentityStudentQuery = (): UserIdentityStudentQuery => ({ + studentNo: "", + schoolName: "", + className: "", + guardianPhones: "", +}) + +/** + * 创建用户身份通用查询组件的老师扩展字段初始值。 + * + * @returns 老师学号为空的独立对象 + */ +export const createEmptyUserIdentityTeacherQuery = (): UserIdentityTeacherQuery => ({ + teacherNo: "", +}) diff --git a/src/components/index.ts b/src/components/index.ts index dc1682f2..49391536 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -19,6 +19,7 @@ import DraggableDepTree from "/@/components/DraggableDepTree/index.vue" import SearchPanel from "/@/components/SearchPanel/index.vue" import UserInfoCell from "/@/components/UserInfoCell/index.vue" import UserIdentityInfo from "/@/components/UserIdentityInfo/index.vue" +import UserIdentityQuery from "/@/components/UserIdentityQuery/index.vue" // 业务组件 import TreeMultipleSelect from "/@/components/TreeMultipleSelect/index.vue" @@ -89,6 +90,7 @@ export default { app.component("SearchPanel", SearchPanel) app.component("UserInfoCell", UserInfoCell) app.component("UserIdentityInfo", UserIdentityInfo) + app.component("UserIdentityQuery", UserIdentityQuery) app.component("TreeMultipleSelect", TreeMultipleSelect) app.component("SelectHard", SelectHard) app.component("SelectHardSpuCategory", SelectHardSpuCategory) diff --git a/src/constants/autoRefund.ts b/src/constants/autoRefund.ts index 02c53b3a..326aa6c8 100644 --- a/src/constants/autoRefund.ts +++ b/src/constants/autoRefund.ts @@ -15,6 +15,22 @@ export const AUTO_REFUND_RULE_OPTIONS: Array<{ label: string; value: AutoRefundR { label: "周期预约截止", value: AUTO_REFUND_RULE.APPT_CYCLE_CLOSE }, ] +/** 自动退款任务场景编码,与 Hardware 任务表中的 task_type 保持一致。 */ +export const AUTO_REFUND_TASK_TYPE = { + /** 规定时间内用户申请的免审核退款。 */ + AFTER_SALE: "10", + /** 预约订单超过使用期限后的系统自动退款。 */ + EXPIRED_RESERVE: "20", +} as const + +/** 自动退款任务场景的管理端展示配置。 */ +export const AUTO_REFUND_TASK_TYPE_META: Record = { + /** 管理端标识在商户规定时限内由用户发起且无需人工审核的退款。 */ + [AUTO_REFUND_TASK_TYPE.AFTER_SALE]: { label: "规定时间内用户免审核退款", type: "success" }, + /** 管理端标识订单超过预约使用期限后由系统创建的退款。 */ + [AUTO_REFUND_TASK_TYPE.EXPIRED_RESERVE]: { label: "过期订单自动退款", type: "warning" }, +} + /** 自动退款任务状态展示配置。 */ export const AUTO_REFUND_TASK_STATUS: Record = { /** 售后事务已创建任务,等待首次同步执行。 */ @@ -63,6 +79,14 @@ export const AUTO_REFUND_ATTEMPT_RESULT: Record AUTO_REFUND_TASK_STATUS[status || ""] || { label: status || "-", type: "info" as const } +/** + * 获取自动退款任务场景展示配置,未知编码保留原值便于排查协议兼容问题。 + * + * @param taskType 自动退款任务场景编码。 + */ +export const getAutoRefundTaskType = (taskType?: string) => + AUTO_REFUND_TASK_TYPE_META[taskType || ""] || { label: taskType || "-", type: "info" as const } + /** * 获取尝试结果展示配置,未知状态保留原编码便于技术排查。 * diff --git a/src/views/admin/system/user/index.vue b/src/views/admin/system/user/index.vue index 5bedc050..c9c95633 100644 --- a/src/views/admin/system/user/index.vue +++ b/src/views/admin/system/user/index.vue @@ -28,10 +28,9 @@ - - - + @@ -257,6 +256,10 @@ import { useDict } from "/@/hooks/dict" import UserRoleTags from "./components/user-role-tags.vue" import AsyncTaskProgressComponent from "/@/components/AsyncTaskProgress.vue" import { downBlobFile } from "/@/utils/other" +import { + createEmptyUserIdentityStudentQuery, + createEmptyUserIdentityTeacherQuery, +} from "/@/components/UserIdentityQuery/types" const UserForm = defineAsyncComponent(() => import("./form.vue")) const FaceManage = defineAsyncComponent(() => import("./face-manage.vue")) @@ -308,6 +311,8 @@ const state: BasicTableProps = reactive({ username: "", phone: "", identityTypes: [], + studentInfo: createEmptyUserIdentityStudentQuery(), + teacherInfo: createEmptyUserIdentityTeacherQuery(), isDeepDept: false, processStatus: "2", lockFlag: "", @@ -339,15 +344,23 @@ const advancedFilterCount = computed(() => { state.queryForm.role, state.queryForm.staffingType, state.queryForm.identityTypes, + state.queryForm.studentInfo?.studentNo, + state.queryForm.studentInfo?.schoolName, + state.queryForm.studentInfo?.className, + state.queryForm.studentInfo?.guardianPhones, + state.queryForm.teacherInfo?.teacherNo, state.queryForm.lockFlag, state.queryForm.hasFace, ].filter((value) => (Array.isArray(value) ? value.length > 0 : value !== undefined && value !== null && value !== "")).length }) -// 清空搜索条件 +/** 清空表单、身份扩展条件和部门树选择后重新查询第一页。 */ const resetQuery = () => { queryRef.value?.resetFields() state.queryForm.deptId = "" state.queryForm.deptIds = [] + state.queryForm.identityTypes = [] + Object.assign(state.queryForm.studentInfo, createEmptyUserIdentityStudentQuery()) + Object.assign(state.queryForm.teacherInfo, createEmptyUserIdentityTeacherQuery()) draggableDepTreeRef.value.resetData() getDataList() } diff --git a/src/views/hard/hard-after-sale/auto-refund-task.vue b/src/views/hard/hard-after-sale/auto-refund-task.vue index 6ead511c..34389891 100644 --- a/src/views/hard/hard-after-sale/auto-refund-task.vue +++ b/src/views/hard/hard-after-sale/auto-refund-task.vue @@ -1,15 +1,8 @@
- + - + - + - + - + + + + + + +