diff --git a/src/api/campus.js b/src/api/campus.js new file mode 100644 index 0000000..603cb0e --- /dev/null +++ b/src/api/campus.js @@ -0,0 +1,23 @@ +import { getRequest, postBodyRequest } from '@/libs/axios'; + +const PREFIX = '/app/campus/admin'; + +export const campusCategoryList = (params) => getRequest(`${PREFIX}/categories`, params); +export const campusCategorySave = (params) => postBodyRequest(`${PREFIX}/categories`, params); +export const campusCategoryDelete = (id) => postBodyRequest(`${PREFIX}/categories/delete?id=${id}`, {}); +export const campusCategoryStatus = (params) => postBodyRequest(`${PREFIX}/categories/status`, params); + +export const campusWallPostPage = (params) => postBodyRequest(`${PREFIX}/wall/posts/page`, params); +export const campusPartnerPostPage = (params) => postBodyRequest(`${PREFIX}/partner/posts/page`, params); +export const campusPostStatus = (params) => postBodyRequest(`${PREFIX}/posts/status`, params); +export const campusPostComments = (id, params) => getRequest(`${PREFIX}/posts/${id}/comments/page`, params); +export const campusCommentDelete = (id) => postBodyRequest(`${PREFIX}/comments/${id}/delete`, {}); + +export const campusComplaintPage = (params) => postBodyRequest(`${PREFIX}/complaints/page`, params); +export const campusComplaintHandle = (params) => postBodyRequest(`${PREFIX}/complaints/handle`, params); +export const campusComplaintUnblock = (params) => postBodyRequest(`${PREFIX}/complaints/unblock`, params); + +export const campusUserLimitPage = (params) => postBodyRequest(`${PREFIX}/users/limits/page`, params); +export const campusUserLimitSave = (params) => postBodyRequest(`${PREFIX}/users/limits`, params); +export const campusAdminLogPage = (params) => postBodyRequest(`${PREFIX}/logs/page`, params); +export const campusAuditLogPage = (params) => getRequest(`${PREFIX}/audit-logs/page`, params); diff --git a/src/api/index.js b/src/api/index.js index 6421d50..3f24f13 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -712,6 +712,11 @@ export const disableWorker = (id, params) => { return postRequest(`/worker/admin/disable/${id}`, params) } +// 设置配送员全职状态 +export const setWorkerFullTime = (id, params) => { + return postRequest(`/worker/admin/fullTime/${id}`, params) +} + // 抢单工上线 export const onLineWorker = (params) => { return postRequest(`/worker/onLine`, params) diff --git a/src/views/app/business/courier/courier.vue b/src/views/app/business/courier/courier.vue index f97c2df..82cf429 100644 --- a/src/views/app/business/courier/courier.vue +++ b/src/views/app/business/courier/courier.vue @@ -102,6 +102,7 @@ deleteWorker, offLineWorker, onLineWorker, + setWorkerFullTime, getWorkerRelaPriceByWorkerId, } from "@/api/index"; import { @@ -195,6 +196,19 @@ title: "配送员名称", key: "workerName", minWidth: 125, + render: (h, params) => { + return h("div", [ + h("div", params.row.workerName || "-"), + h("Tag", { + props: { + color: params.row.isFullTime == 1 ? "green" : "default", + }, + style: { + marginTop: "4px", + }, + }, params.row.isFullTime == 1 ? "全职配送员" : "非全职配送员"), + ]); + }, }, { title: "佣金余额(元)", @@ -334,7 +348,7 @@ { title: "操作", key: "action", - width: 260, + width: 340, align: "center", fixed: "right", render: (h, params) => { @@ -396,6 +410,17 @@ "上线" ); } + const fullTimeText = params.row.isFullTime == 1 ? "取消全职" : "设置全职"; + const fullTimeAction = h( + "a", { + on: { + click: () => { + this.changeFullTime(params.row); + }, + }, + }, + fullTimeText + ); return h("div", [ /* h( "a", { @@ -449,6 +474,12 @@ }, "接单规则" ), + h("Divider", { + props: { + type: "vertical", + }, + }), + fullTimeAction, ]); }, }, @@ -759,6 +790,26 @@ }, }); }, + changeFullTime(v) { + const isFullTime = v.isFullTime == 1 ? 0 : 1; + const actionText = isFullTime == 1 ? "设置为全职配送员" : "取消全职配送员"; + this.$Modal.confirm({ + title: actionText, + content: "您确认要将配送员 " + v.workerName + " " + actionText + "吗?", + loading: true, + onOk: () => { + setWorkerFullTime(v.workerId, { + isFullTime + }).then((res) => { + this.$Modal.remove(); + if (res.success) { + this.$Message.success("操作成功"); + this.getDataList(); + } + }); + }, + }); + }, remove(v) { this.$Modal.confirm({ title: "确认删除", diff --git a/src/views/app/business/courier/logisticsAddress.vue b/src/views/app/business/courier/logisticsAddress.vue index f99db43..5100f5a 100644 --- a/src/views/app/business/courier/logisticsAddress.vue +++ b/src/views/app/business/courier/logisticsAddress.vue @@ -15,6 +15,14 @@ + +
+ +
+
+ +
+
@@ -24,8 +32,6 @@ deleteComment, getCommentList } from "@/api/app"; - import "viewerjs/dist/viewer.css"; - import Viewer from "viewerjs"; export default { name: "logisticsAddress", components: { @@ -45,6 +51,8 @@ selectList: [], // 多选数据 replyVisible: false, replyList: [], + previewVisible: false, + previewImage: "", replyColumns: [ { type: "index", @@ -111,7 +119,7 @@ key: "picture", minWidth: 125, render: (h, params) => { - + if (!params.row.picture) return h("span", "-"); return h("img", { attrs: { src: params.row.picture, @@ -124,7 +132,8 @@ "object-fit": "contain", }, on: { - click: () => { + click: (event) => { + event.stopPropagation(); this.showPic(params.row.picture); }, }, @@ -239,17 +248,12 @@ return content; }, showPic(v) { - if(v == ''){ - this.$Message.warning("没有评价图");return + if (!v) { + this.$Message.warning("没有评价图"); + return; } - let image = new Image(); - image.src = v; - let viewer = new Viewer(image, { - hidden: function() { - viewer.destroy(); - }, - }); - viewer.show(); + this.previewImage = v; + this.previewVisible = true; }, formatDateTime(isoString) { if (!isoString) return '' @@ -289,4 +293,14 @@ \ No newline at end of file diff --git a/src/views/app/business/deliverytruck/deliveryTruck.vue b/src/views/app/business/deliverytruck/deliveryTruck.vue index d38308c..b0ec2e8 100644 --- a/src/views/app/business/deliverytruck/deliveryTruck.vue +++ b/src/views/app/business/deliverytruck/deliveryTruck.vue @@ -1,701 +1,598 @@ \ No newline at end of file + diff --git a/src/views/app/business/logistics/logistics.vue b/src/views/app/business/logistics/logistics.vue index c6981d6..7428eca 100644 --- a/src/views/app/business/logistics/logistics.vue +++ b/src/views/app/business/logistics/logistics.vue @@ -200,6 +200,7 @@ +
@@ -342,7 +343,8 @@ }, workerOrderCounts: { daiqu: 0, - daisong: 0 + daisong: 0, + zhipai: 0 }, workerList: this.buildWorkerColumns(), workerOrderColumns: [], @@ -354,6 +356,8 @@ workerOrderTotal: 0, orderId: "", currentTransferWorkerId: "", + currentTransferOrder: null, + currentTransferHallTab: "", transferActionTitle: "指派配送员", transferActionType: "assign", currentRegionId: regionId, @@ -396,6 +400,20 @@ key: "workerName", width: 200, align: "center", + render: (h, params) => { + const isFullTime = params.row.isFullTime == 1; + return h("div", [ + h("div", params.row.workerName || "-"), + h("Tag", { + props: { + color: isFullTime ? "green" : "orange" + }, + style: { + marginTop: "4px" + } + }, isFullTime ? "全职配送员" : "兼职配送员") + ]); + } }, { title: "联系电话", key: "mobile", @@ -446,33 +464,31 @@ key: "createTime", width: 190, align: "center", - render: (h, params) => h("div", [ - h("div", this.formatDateTime(params.row.createTime)), - h("div", { class: "order-time-order-no" }, "订单编号:" + this.getOrderNo(params.row)) - ]) - }, { - title: "配送员", - key: "workerName", - width: 170, - align: "center", - render: (h, params) => this.renderWorkerInfo(h, params.row, clickableWorker) + render: (h, params) => { + const children = []; + if (this.tabName === "delivery" && params.row.numberCode) { + children.push(h("div", { + style: { color: "#515a6e", fontWeight: 700, marginBottom: "4px" } + }, "编号:" + params.row.numberCode)); + } + children.push(h("div", this.formatDateTime(params.row.createTime))); + children.push(h("div", { class: "order-time-order-no" }, "订单编号:" + this.getOrderNo(params.row))); + return h("div", children); + } },{ title: "送达时间", key: "mustFinishTime", - width: 210, + width: 260, align: "center", render: (h, params) => h("div", [ - h("span", { class: "must-finish-time" }, this.formatDateTime(params.row.mustFinishTime)), + params.row.shopMakeTime ? h("div", { + style: { color: "red", marginTop: "4px", fontWeight: 700 } + }, "商家已出餐:" + this.formatDateTime(params.row.shopMakeTime)) : null, + h("span", { class: "must-finish-time" }, "要求送达:" +this.formatDateTime(params.row.mustFinishTime)), this.isNearMustFinishTime(params.row) ? h("div", { style: { color: "#515a6e", marginTop: "4px", fontWeight: 700 } }, this.getMustFinishWarningText(params.row)) : null ]) - },{ - title: "配送类型", - key: "deliveryType", - width: 140, - align: "center", - render: (h, params) => this.renderDeliveryTags(h, params.row) }, { title: "商家/取货地址", key: "shopAddress", @@ -483,6 +499,18 @@ key: "receiverAddress", minWidth: 240, render: (h, params) => this.renderAddressBlock(h, params.row, "receiver") + }, { + title: "配送员", + key: "workerName", + width: 170, + align: "center", + render: (h, params) => this.renderWorkerInfo(h, params.row, clickableWorker) + },{ + title: "配送类型", + key: "deliveryType", + width: 140, + align: "center", + render: (h, params) => this.renderDeliveryTags(h, params.row) }, { title: "操作", key: "action", @@ -675,10 +703,13 @@ this.getWorkerOrders(); }, buildWorkerOrderParams() { + if (this.workerOrderTab === "zhipai") { + return this.buildWorkerAssignedOrderParams(); + } const source = this.activeSearchForm || {}; const params = { regionId: source.regionId || this.currentRegionId, - deliveryType: source.deliveryType, + deliveryType: this.getWorkerDeliveryTypeFilter(source), getAreaId: source.getAreaId, putAreaId: source.putAreaId, shopName: source.shopName, @@ -690,31 +721,71 @@ }; return this.cleanParams(params); }, + buildWorkerAssignedOrderParams() { + const source = this.activeSearchForm || {}; + const params = { + regionId: source.regionId || this.currentRegionId, + deliveryType: HALL_TYPE_MAP.zhipai, + workerId: this.selectedWorker.workerId, + getAreaId: source.getAreaId, + putAreaId: source.putAreaId, + shopName: source.shopName, + order: source.order, + pageNum: this.workerOrderForm.pageNum, + pageSize: this.workerOrderForm.pageSize + }; + return this.cleanParams(params); + }, buildWorkerOrderCountParams(status) { - return Object.assign({}, this.buildWorkerOrderParams(), { + const source = this.activeSearchForm || {}; + const params = { + regionId: source.regionId || this.currentRegionId, + deliveryType: this.getWorkerDeliveryTypeFilter(source), + getAreaId: source.getAreaId, + putAreaId: source.putAreaId, + shopName: source.shopName, + order: source.order, + workerId: this.selectedWorker.workerId, status: status, pageNum: 1, pageSize: 1 + }; + return this.cleanParams(params); + }, + getWorkerDeliveryTypeFilter(source) { + return source.deliveryType === HALL_TYPE_MAP.zhipai ? null : source.deliveryType; + }, + buildWorkerAssignedOrderCountParams() { + return Object.assign({}, this.buildWorkerAssignedOrderParams(), { + pageNum: 1, + pageSize: 1 }); }, getWorkerOrderCounts() { if (!this.selectedWorker.workerId) return; Promise.all([ orderSchedulingAdmin(this.buildWorkerOrderCountParams(DELIVERY_STATUS_MAP.daiqu)), - orderSchedulingAdmin(this.buildWorkerOrderCountParams(DELIVERY_STATUS_MAP.daisong)) - ]).then(([daiqu, daisong]) => { + orderSchedulingAdmin(this.buildWorkerOrderCountParams(DELIVERY_STATUS_MAP.daisong)), + getAdminDeliveryHallData(this.buildWorkerAssignedOrderCountParams()) + ]).then(([daiqu, daisong, zhipai]) => { if (this.isSuccess(daiqu)) { this.workerOrderCounts.daiqu = Number((daiqu.result || {}).total) || 0; } if (this.isSuccess(daisong)) { this.workerOrderCounts.daisong = Number((daisong.result || {}).total) || 0; } + if (this.isSuccess(zhipai)) { + this.workerOrderCounts.zhipai = Number((zhipai.result || {}).total) || 0; + } }); }, getWorkerOrders() { if (!this.selectedWorker.workerId) return; this.workerOrderLoading = true; - orderSchedulingAdmin(this.buildWorkerOrderParams()).then((res) => { + const request = this.workerOrderTab === "zhipai" + ? getAdminDeliveryHallData(this.buildWorkerOrderParams()) + : orderSchedulingAdmin(this.buildWorkerOrderParams()); + request.then((res) => { if (this.isSuccess(res)) { const result = res.result || {}; this.workerOrderList = this.normalizeRecords(result.records); @@ -895,6 +966,7 @@ this.$Message.success(actionText + "配送员成功"); this.transferOrder = false; this.workerOrderVisible = false; + this.updateHallCountsAfterReassign(); this.getLogisticsInfo(); } }); @@ -932,10 +1004,29 @@ this.searchWorker.orderType = this.getWorkerOrderType(v); this.orderId = v.id; this.currentTransferWorkerId = v.workerId || ""; + this.currentTransferOrder = v; + this.currentTransferHallTab = this.tabName === "hall" ? this.hallTab : ""; this.transferActionType = v.workerId ? "reassign" : "assign"; this.transferActionTitle = v.workerId ? "改派配送员" : "指派配送员"; this.getWorker(); }, + updateHallCountsAfterReassign() { + if (this.transferActionType !== "reassign") return; + if (["waimai", "kuaidi", "paotui"].indexOf(this.currentTransferHallTab) === -1) return; + const sourceKey = this.getHallCountKeyByDeliveryType(this.currentTransferOrder && this.currentTransferOrder.deliveryType); + if (sourceKey !== this.currentTransferHallTab) return; + this.hallCounts[sourceKey] = Math.max(this.toNumber(this.hallCounts[sourceKey]) - 1, 0); + this.hallCounts.zhipai = this.toNumber(this.hallCounts.zhipai) + 1; + }, + getHallCountKeyByDeliveryType(deliveryType) { + const map = { + 1: "waimai", + 2: "kuaidi", + 3: "paotui", + 4: "zhipai" + }; + return map[Number(deliveryType)] || ""; + }, getWorker() { this.workerLoading = true; getMatchingWorkerListData(this.cleanParams(this.searchWorker)).then((res) => { @@ -1005,7 +1096,7 @@ ]); }, getDeliveryTypeText(type, row) { - if (row && row.workerId && this.tabName === "hall") return "指派单"; + if (row && row.workerId && (this.tabName === "hall" || (this.workerOrderVisible && this.workerOrderTab === "zhipai"))) return "指派单"; if (type == 1) return "外卖"; if (type == 2) return "快递"; if (type == 3) return "跑腿"; @@ -1031,7 +1122,7 @@ return h("div", tags); }, getDeliveryTypeColor(type, row) { - if (row && row.workerId && this.tabName === "hall") return "blue"; + if (row && row.workerId && (this.tabName === "hall" || (this.workerOrderVisible && this.workerOrderTab === "zhipai"))) return "blue"; if (type == 1) return "gold"; if (type == 2) return "orange"; if (type == 3) return "green"; @@ -1069,19 +1160,26 @@ ]); }, renderActions(h, row) { - const children = [h("a", { + const actions = [h("a", { on: { click: () => this.orderDetail(row) } }, "订单详情")]; if (this.canAssignWorker(row)) { - children.push(h("Divider", { props: { type: "vertical" } })); - children.push(h("a", { + actions.push(h("Divider", { props: { type: "vertical" } })); + actions.push(h("a", { on: { click: () => this.unbind(row) } }, row.workerId ? "改派订单" : "指派订单")); } + const children = []; + if (row.isReturn == 1) { + children.push(h("div", { + style: { color: "#ed4014", fontWeight: 700, marginBottom: "4px" } + }, "订单申请退款")); + } + children.push(h("div", actions)); return h("div", children); }, canAssignWorker(row) { diff --git a/src/views/app/business/luckey/luckey.vue b/src/views/app/business/luckey/luckey.vue index 46a4eae..1ec3cf8 100644 --- a/src/views/app/business/luckey/luckey.vue +++ b/src/views/app/business/luckey/luckey.vue @@ -12,7 +12,7 @@ 现金奖池采用“主动投入”规则:用户投入星球券后即从余额扣除并回收,本期按投入券数加权开奖,投入越多中奖概率越高 - +
- + + + + - +
@@ -453,6 +457,9 @@ } }, computed: { + canCreatePool() { + return !this.pool.loading && Number(this.pool.total || 0) === 0 && this.pool.data.length === 0 + }, operateTitle() { const map = { tree: '券树周期', warehouse: '仓库等级', tower: '防御塔等级', search: '搜查规则', stamina: '体力道具', landmark: '校园地标', college: '学院配置' } return (this.operateForm.id ? '编辑' : '新增') + (map[this.operateType] || '经营配置') @@ -934,18 +941,21 @@ }, // ---- 奖池 ---- openPool(row) { - this.poolForm = row ? Object.assign({}, row) : { + this.poolForm = row ? Object.assign({}, row, { + poolDate: this.poolDateFromRow(row) + }) : { regionId: this.regionId || '', poolAmount: 0, drawTime: this.defaultDrawTime(), status: 0 } - if (this.poolForm.status !== 1) this.poolForm.drawTime = this.defaultDrawTime(this.poolForm.drawTime) + this.syncPoolPeriodNo(this.poolForm) this.poolModal = true }, savePool() { const form = Object.assign({}, this.poolForm) - if (form.status !== 1) form.drawTime = this.defaultDrawTime(form.drawTime) + this.syncPoolPeriodNo(form) + delete form.poolDate planetPoolSave(form).then(r => { if (r && r.success) { this.$Message.success('保存成功') @@ -1114,6 +1124,32 @@ const p = n => (n < 10 ? '0' + n : n) return `${value.getFullYear()}-${p(value.getMonth() + 1)}-${p(value.getDate())}` }, + parseDate(value) { + if (!value) return null + if (value instanceof Date) return value + if (typeof value === 'string' && value.length >= 10) { + return new Date(value.slice(0, 10).replace(/-/g, '/')) + } + return null + }, + poolDateFromRow(row) { + if (row.drawTime) return this.formatDateParam(this.parseDate(row.drawTime)) + if (row.periodNo && row.periodNo.length >= 8) { + const periodNo = row.periodNo.replace(/^P/, '').slice(0, 8) + return `${periodNo.slice(0, 4)}-${periodNo.slice(4, 6)}-${periodNo.slice(6, 8)}` + } + return this.formatDateParam(this.parseDate(this.defaultDrawTime())) + }, + onPoolDateChange(value) { + this.poolForm.poolDate = value + this.syncPoolPeriodNo(this.poolForm) + }, + syncPoolPeriodNo(form) { + const poolDate = this.formatDateParam(this.parseDate(form.poolDate || form.drawTime) || new Date()) + form.poolDate = poolDate + form.periodNo = poolDate.replace(/-/g, '') + form.drawTime = `${poolDate} 22:00:00` + }, defaultDrawTime(value) { let d = value instanceof Date ? value : new Date() if (!(value instanceof Date) && typeof value === 'string' && value.length >= 10) { diff --git a/src/views/app/data-statistics/data-statistics.vue b/src/views/app/data-statistics/data-statistics.vue index bee3157..445e2b0 100644 --- a/src/views/app/data-statistics/data-statistics.vue +++ b/src/views/app/data-statistics/data-statistics.vue @@ -54,7 +54,7 @@ - 统计口径:订单按支付时间,退款/售后按成功时间,抽奖按开奖时间;流水和配送费已扣微信0.6%手续费,内容审核按每100次0.05元向上取整。 + 统计口径:订单按支付时间,退款/售后按成功时间,抽奖按开奖时间;流水总金额=商品价格+打包费+配送费,有效流水总金额=订单商品价格+打包费后扣微信0.6%手续费。
订单数据 @@ -67,7 +67,15 @@
{{ statistics.orderCount }}
-
订单数量(单)
+
+ 订单数量(单) + + +
+ 订单记录数(待支付、已取消不计入) +
+
+
@@ -78,7 +86,15 @@
{{ statistics.grossFlowAmount }}
-
流水总金额(元)
+
+ 流水总金额(元) + + +
+ 商品价格+打包费+配送费 +
+
+
@@ -89,7 +105,15 @@
{{ statistics.effectiveFlowAmount }}
-
有效流水总金额(元)
+
+ 有效流水总金额(元) + + +
+ 订单商品价格+打包费,再扣微信0.6%手续费 +
+
+
@@ -174,8 +198,17 @@
-
{{ statistics.actualIncomeAmount }}
-
实际所得(元)
+
{{ statistics.actualIncomeAmount }}
+
--
+
+ 实际所得(元) + + +
+ 仅结束时间小于今天且范围不超过31天时计算 +
+
+
@@ -186,7 +219,15 @@
{{ statistics.headquartersDeductionAmount }}
-
总部扣点(元)
+
+ 总部扣点(元) + + +
+ 有效流水总金额 * 0.01 +
+
+
@@ -482,6 +523,8 @@ couponDiscountAmount: "0.00", customerAverageAmount: "0.00", actualIncomeAmount: "0.00", + actualIncomeAvailable: false, + settledAmount: "0.00", headquartersDeductionAmount: "0.00", deliveryFeeAmount: "0.00", smsCount: 0, @@ -753,7 +796,36 @@ this.searchForm.startDate = v && v[0] ? v[0] : "" this.searchForm.endDate = v && v[1] ? v[1] : "" }, + parseDateString(value) { + return value ? new Date(value.replace(/-/g, "/")) : null + }, + rangeDays(startDate, endDate) { + const start = this.parseDateString(startDate) + const end = this.parseDateString(endDate) + if (!start || !end) { + return 0 + } + return Math.floor((end.getTime() - start.getTime()) / (24 * 60 * 60 * 1000)) + 1 + }, + validateStatisticsRange() { + if (!this.searchForm.startDate || !this.searchForm.endDate) { + return true + } + const days = this.rangeDays(this.searchForm.startDate, this.searchForm.endDate) + if (days < 1) { + this.$Message.warning("结束日期不能小于开始日期") + return false + } + if (days > 31) { + this.$Message.warning("日期范围最多选择31天") + return false + } + return true + }, getDataList() { + if (!this.validateStatisticsRange()) { + return + } this.statisticsLoading = true const params = Object.assign({}, this.searchForm, { regionId: this.resolveRegionId() diff --git a/src/views/app/shop/logisticsAddress.vue b/src/views/app/shop/logisticsAddress.vue index a277914..2c971f0 100644 --- a/src/views/app/shop/logisticsAddress.vue +++ b/src/views/app/shop/logisticsAddress.vue @@ -15,6 +15,14 @@ + +
+ +
+
+ +
+
@@ -24,8 +32,6 @@ deleteComment, getCommentList } from "@/api/app"; - import "viewerjs/dist/viewer.css"; - import Viewer from "viewerjs"; export default { name: "logisticsAddress", components: { @@ -46,6 +52,8 @@ selectList: [], // 多选数据 replyVisible: false, replyList: [], + previewVisible: false, + previewImage: "", replyColumns: [ { type: "index", @@ -112,7 +120,7 @@ key: "picture", minWidth: 125, render: (h, params) => { - + if (!params.row.picture) return h("span", "-"); return h("img", { attrs: { src: params.row.picture, @@ -125,7 +133,8 @@ "object-fit": "contain", }, on: { - click: () => { + click: (event) => { + event.stopPropagation(); this.showPic(params.row.picture); }, }, @@ -240,17 +249,12 @@ return content; }, showPic(v) { - if(v == ''){ - this.$Message.warning("没有评价图");return + if (!v) { + this.$Message.warning("没有评价图"); + return; } - let image = new Image(); - image.src = v; - let viewer = new Viewer(image, { - hidden: function() { - viewer.destroy(); - }, - }); - viewer.show(); + this.previewImage = v; + this.previewVisible = true; }, formatDateTime(isoString) { if (!isoString) return '' @@ -290,4 +294,14 @@ \ No newline at end of file diff --git a/src/views/sys/order-manage/logisticsAddress.vue b/src/views/sys/order-manage/logisticsAddress.vue index 9539fb4..3ca4b8c 100644 --- a/src/views/sys/order-manage/logisticsAddress.vue +++ b/src/views/sys/order-manage/logisticsAddress.vue @@ -32,16 +32,7 @@
备注:{{orderData.deliveryInfo.remark}}
-
-
-
售后原因说明
- -
-
同意退款
-
拒绝退款
-
-
-
+
商品信息
@@ -125,7 +116,8 @@
图片 - +
@@ -150,6 +142,24 @@
+
+
+
售后原因说明
+ +
+
同意退款
+
拒绝退款
+
+
+
+ +
+ +
+
+ +
+
@@ -174,7 +184,9 @@ returnFormData:{}, refundReason: "", refundLoading: false, - refundActionData: null + refundActionData: null, + previewVisible: false, + previewImage: "" }; }, filters: { @@ -351,6 +363,14 @@ } return String(pictures).split(",").map((item) => item.trim()).filter((item) => item !== ""); }, + showRefundPicture(picture) { + if (!picture) { + this.$Message.warning("没有退款/售后图片"); + return; + } + this.previewImage = picture; + this.previewVisible = true; + }, getRefundTypeText(item) { if (!item) return ""; if (item.refundType == 1) return "退商品"; @@ -555,6 +575,22 @@ margin-right: 8px; border-radius: 4px; object-fit: cover; + cursor: pointer; + } + + .refund-image-preview { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + max-height: 70vh; + overflow: hidden; + } + + .refund-image-preview img { + max-width: 100%; + max-height: 70vh; + object-fit: contain; } .text { diff --git a/src/views/sys/order-manage/orderManage.vue b/src/views/sys/order-manage/orderManage.vue index f601637..c733bf3 100644 --- a/src/views/sys/order-manage/orderManage.vue +++ b/src/views/sys/order-manage/orderManage.vue @@ -81,6 +81,21 @@ margin-top: 12px; gap: 12px; } + + .refund-type-status-wrap { + display: inline-block; + max-width: 100%; + white-space: normal; + word-break: break-all; + line-height: 20px; + } + + .search-date-row { + display: inline-flex; + align-items: flex-start; + white-space: nowrap; + vertical-align: top; + }