Compare commits
4 Commits
0569f5fc1d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67fc599031 | ||
|
|
a2f866a4d9 | ||
|
|
19de22f1ed | ||
|
|
42aeb7b232 |
@@ -58,4 +58,14 @@ export function getOrderStatistics(query) {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 回填订单商品图、店铺名(goodsInfo)
|
||||||
|
export function backfillGoodsInfo(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/jdorder/orderRows/backfillGoodsInfo',
|
||||||
|
method: 'post',
|
||||||
|
data: data,
|
||||||
|
timeout: 300000
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
<img
|
<img
|
||||||
:src="item.shopLogo || defaultLogo"
|
:src="item.shopLogo || defaultLogo"
|
||||||
class="shopinfo-logo"
|
class="shopinfo-logo"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
@error="onLogoError"
|
@error="onLogoError"
|
||||||
>
|
>
|
||||||
<div class="shopinfo-name">{{ item.shopName }}</div>
|
<div class="shopinfo-name">{{ item.shopName }}</div>
|
||||||
@@ -43,10 +44,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="info-body">
|
<div class="info-body">
|
||||||
<img
|
<img
|
||||||
v-if="item.skuImageUrl"
|
v-if="item.skuImageUrl && !item._imgFailed"
|
||||||
:src="item.skuImageUrl"
|
:src="item.skuImageUrl"
|
||||||
class="info-img"
|
class="info-img"
|
||||||
@error="onImageError"
|
referrerpolicy="no-referrer"
|
||||||
|
@error="onImageError(item, $event)"
|
||||||
>
|
>
|
||||||
<div v-else class="info-img-placeholder">🖼</div>
|
<div v-else class="info-img-placeholder">🖼</div>
|
||||||
<div class="info-cell">
|
<div class="info-cell">
|
||||||
@@ -61,6 +63,9 @@
|
|||||||
<div class="info-footer">
|
<div class="info-footer">
|
||||||
<div>下单时间:{{ item.orderTime }}</div>
|
<div>下单时间:{{ item.orderTime }}</div>
|
||||||
<div>完成时间:{{ item.finishTime }}</div>
|
<div>完成时间:{{ item.finishTime }}</div>
|
||||||
|
<div v-if="item.proPriceAmount && item.proPriceAmount !== '0.00'" class="pro-price-line">
|
||||||
|
价保赔付:<span class="pro-price-val">¥{{ item.proPriceAmount }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -126,8 +131,21 @@ export default {
|
|||||||
onLogoError(e) {
|
onLogoError(e) {
|
||||||
e.target.src = this.defaultLogo
|
e.target.src = this.defaultLogo
|
||||||
},
|
},
|
||||||
onImageError(e) {
|
onImageError(item, e) {
|
||||||
e.target.style.display = 'none'
|
const tryCount = item._imgTry || 0
|
||||||
|
const fallbacks = item.skuId
|
||||||
|
? [
|
||||||
|
`https://img14.360buyimg.com/n5/s450x450_${item.skuId}.jpg`,
|
||||||
|
`https://img10.360buyimg.com/n1/s450x450_${item.skuId}.jpg`,
|
||||||
|
`https://img14.360buyimg.com/n1/s240x240_${item.skuId}.jpg`
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
if (tryCount < fallbacks.length) {
|
||||||
|
this.$set(item, '_imgTry', tryCount + 1)
|
||||||
|
e.target.src = fallbacks[tryCount]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$set(item, '_imgFailed', true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,6 +279,8 @@ export default {
|
|||||||
.info-cell-price { margin-top: 6px; text-align: right; }
|
.info-cell-price { margin-top: 6px; text-align: right; }
|
||||||
.price-val { color: #e02f2f; font-weight: bold; }
|
.price-val { color: #e02f2f; font-weight: bold; }
|
||||||
.info-footer { margin-top: 16px; color: #666; }
|
.info-footer { margin-top: 16px; color: #666; }
|
||||||
|
.pro-price-line { margin-top: 4px; }
|
||||||
|
.pro-price-val { color: #e02f2f; font-weight: bold; }
|
||||||
.tag {
|
.tag {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
|
|||||||
@@ -910,7 +910,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<!-- 操作列(统一放在最右侧) -->
|
<!-- 操作列(统一放在最右侧) -->
|
||||||
<el-table-column label="操作" fixed="right" :width="isMobile ? 60 : 330" align="center" class-name="action-column">
|
<el-table-column label="操作" fixed="right" :width="isMobile ? 60 : 300" align="center" class-name="action-column">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<!-- 移动端:悬浮操作按钮 -->
|
<!-- 移动端:悬浮操作按钮 -->
|
||||||
<div v-if="isMobile" class="mobile-action-wrapper">
|
<div v-if="isMobile" class="mobile-action-wrapper">
|
||||||
@@ -3980,7 +3980,8 @@ export default {
|
|||||||
|
|
||||||
.order-table ::v-deep .el-table {
|
.order-table ::v-deep .el-table {
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden;
|
/* 勿 overflow:hidden,否则会裁切 fixed-right 操作列 */
|
||||||
|
overflow: visible;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: var(--jd-text);
|
color: var(--jd-text);
|
||||||
border: 1px solid var(--jd-border);
|
border: 1px solid var(--jd-border);
|
||||||
@@ -4286,6 +4287,7 @@ export default {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.jd-order-el-table {
|
.jd-order-el-table {
|
||||||
@@ -4726,14 +4728,21 @@ export default {
|
|||||||
color: #67C23A;
|
color: #67C23A;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 桌面端确保操作列正常显示(宽度与 el-table-column :width="288" 一致;勿改 fixed-right-patch,否则会出现整块无意义空白列) */
|
/* 桌面端确保操作列正常显示(宽度与 el-table-column :width 一致;勿改 fixed-right-patch,否则会出现整块无意义空白列) */
|
||||||
@media (min-width: 769px) {
|
@media (min-width: 769px) {
|
||||||
.order-table ::v-deep .action-column {
|
.order-table ::v-deep .action-column {
|
||||||
width: 288px !important;
|
width: 300px !important;
|
||||||
|
min-width: 300px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.order-table ::v-deep .el-table__fixed-right {
|
.order-table ::v-deep .el-table__fixed-right {
|
||||||
width: 288px !important;
|
width: 300px !important;
|
||||||
|
right: 0 !important;
|
||||||
|
z-index: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-table ::v-deep .el-table__fixed-right-patch {
|
||||||
|
width: 300px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 隐藏移动端按钮 */
|
/* 隐藏移动端按钮 */
|
||||||
|
|||||||
@@ -150,6 +150,16 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:orderrows:export']">导出</el-button>
|
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:orderrows:export']">导出</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
plain
|
||||||
|
icon="el-icon-picture-outline"
|
||||||
|
size="mini"
|
||||||
|
:loading="backfillLoading"
|
||||||
|
@click="handleBackfillGoodsInfo"
|
||||||
|
>一键补全商品图</el-button>
|
||||||
|
</el-col>
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
@@ -220,12 +230,24 @@
|
|||||||
|
|
||||||
<!-- 查看订单详情对话框 -->
|
<!-- 查看订单详情对话框 -->
|
||||||
<el-dialog :title="'订单详情 - ' + currentOrder.orderId" :visible.sync="viewDialogVisible" width="900px" append-to-body>
|
<el-dialog :title="'订单详情 - ' + currentOrder.orderId" :visible.sync="viewDialogVisible" width="900px" append-to-body>
|
||||||
|
<div v-loading="viewLoading">
|
||||||
<el-descriptions :column="2" border>
|
<el-descriptions :column="2" border>
|
||||||
<!-- 基本信息 -->
|
<!-- 基本信息 -->
|
||||||
<el-descriptions-item label="订单号">{{ currentOrder.orderId }}</el-descriptions-item>
|
<el-descriptions-item label="订单号">{{ currentOrder.orderId }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="主单号">{{ currentOrder.parentId || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="主单号">{{ currentOrder.parentId || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="商品ID">{{ currentOrder.skuId }}</el-descriptions-item>
|
<el-descriptions-item label="商品ID">{{ currentOrder.skuId }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="商品名称" :span="2">{{ currentOrder.skuName }}</el-descriptions-item>
|
<el-descriptions-item label="商品名称" :span="2">{{ currentOrder.skuName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="店铺名称" :span="2">{{ goodsDetailShopName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="商品主图" :span="2">
|
||||||
|
<img
|
||||||
|
v-if="goodsDetailImageUrl && !detailImageFailed"
|
||||||
|
:src="goodsDetailImageUrl"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
class="detail-goods-img"
|
||||||
|
@error="detailImageFailed = true"
|
||||||
|
>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</el-descriptions-item>
|
||||||
<el-descriptions-item label="商品价格">¥{{ currentOrder.price }}</el-descriptions-item>
|
<el-descriptions-item label="商品价格">¥{{ currentOrder.price }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="商品数量">{{ currentOrder.skuNum }}</el-descriptions-item>
|
<el-descriptions-item label="商品数量">{{ currentOrder.skuNum }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="已退货数量">{{ currentOrder.skuReturnNum || 0 }}</el-descriptions-item>
|
<el-descriptions-item label="已退货数量">{{ currentOrder.skuReturnNum || 0 }}</el-descriptions-item>
|
||||||
@@ -301,13 +323,7 @@
|
|||||||
<el-descriptions-item label="计佣扩展信息">{{ currentOrder.balanceExt || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="计佣扩展信息">{{ currentOrder.balanceExt || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="价保赔付金额">¥{{ currentOrder.proPriceAmount || 0 }}</el-descriptions-item>
|
<el-descriptions-item label="价保赔付金额">¥{{ currentOrder.proPriceAmount || 0 }}</el-descriptions-item>
|
||||||
|
|
||||||
<!-- 商品信息 -->
|
<el-descriptions-item label="店铺ID">{{ (currentOrder.goodsInfo && currentOrder.goodsInfo.shopId) || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="商品主图" :span="2" v-if="currentOrder.goodsInfo">
|
|
||||||
<img :src="currentOrder.goodsInfo.imageUrl" style="max-width: 200px; max-height: 200px;" v-if="currentOrder.goodsInfo.imageUrl" />
|
|
||||||
<span v-else>-</span>
|
|
||||||
</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="店铺名称" v-if="currentOrder.goodsInfo">{{ currentOrder.goodsInfo.shopName || '-' }}</el-descriptions-item>
|
|
||||||
<el-descriptions-item label="店铺ID" v-if="currentOrder.goodsInfo">{{ currentOrder.goodsInfo.shopId || '-' }}</el-descriptions-item>
|
|
||||||
|
|
||||||
<!-- 类目信息 -->
|
<!-- 类目信息 -->
|
||||||
<el-descriptions-item label="类目信息" :span="2" v-if="currentOrder.categoryInfo">
|
<el-descriptions-item label="类目信息" :span="2" v-if="currentOrder.categoryInfo">
|
||||||
@@ -322,6 +338,7 @@
|
|||||||
<el-descriptions-item label="招商团活动ID">{{ currentOrder.cpActId || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="招商团活动ID">{{ currentOrder.cpActId || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="账户ID">{{ currentOrder.account || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="账户ID">{{ currentOrder.account || '-' }}</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="viewDialogVisible = false">关闭</el-button>
|
<el-button @click="viewDialogVisible = false">关闭</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -330,7 +347,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listOrderrows, getOrderrows, delOrderrows, addOrderrows, updateOrderrows, getValidCodeSelectData } from "@/api/system/orderrows";
|
import { listOrderrows, getOrderrows, delOrderrows, addOrderrows, updateOrderrows, getValidCodeSelectData, backfillGoodsInfo } from "@/api/system/orderrows";
|
||||||
import { getAdminSelectData } from "@/api/system/superadmin";
|
import { getAdminSelectData } from "@/api/system/superadmin";
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
@@ -351,6 +368,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
|
backfillLoading: false,
|
||||||
// 选中数组
|
// 选中数组
|
||||||
ids: [],
|
ids: [],
|
||||||
// 非单个禁用
|
// 非单个禁用
|
||||||
@@ -392,6 +410,8 @@ export default {
|
|||||||
viewDialogVisible: false,
|
viewDialogVisible: false,
|
||||||
// 当前查看的订单
|
// 当前查看的订单
|
||||||
currentOrder: {},
|
currentOrder: {},
|
||||||
|
detailImageFailed: false,
|
||||||
|
viewLoading: false,
|
||||||
// 统计相关
|
// 统计相关
|
||||||
showStatistics: true,
|
showStatistics: true,
|
||||||
statistics: {
|
statistics: {
|
||||||
@@ -428,8 +448,23 @@ export default {
|
|||||||
{ key: 'add', label: '新增', type: 'primary', icon: 'el-icon-plus', handler: () => this.handleAdd(), disabled: false },
|
{ key: 'add', label: '新增', type: 'primary', icon: 'el-icon-plus', handler: () => this.handleAdd(), disabled: false },
|
||||||
{ key: 'update', label: '修改', type: 'success', icon: 'el-icon-edit', handler: () => this.handleUpdate(), disabled: this.single },
|
{ key: 'update', label: '修改', type: 'success', icon: 'el-icon-edit', handler: () => this.handleUpdate(), disabled: this.single },
|
||||||
{ key: 'delete', label: '删除', type: 'danger', icon: 'el-icon-delete', handler: () => this.handleDelete(), disabled: this.multiple },
|
{ key: 'delete', label: '删除', type: 'danger', icon: 'el-icon-delete', handler: () => this.handleDelete(), disabled: this.multiple },
|
||||||
{ key: 'export', label: '导出', type: 'warning', icon: 'el-icon-download', handler: () => this.handleExport(), disabled: false }
|
{ key: 'export', label: '导出', type: 'warning', icon: 'el-icon-download', handler: () => this.handleExport(), disabled: false },
|
||||||
|
{ key: 'backfill', label: '补全商品图', type: 'info', icon: 'el-icon-picture-outline', handler: () => this.handleBackfillGoodsInfo(), disabled: this.backfillLoading }
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
goodsDetailShopName() {
|
||||||
|
const shopName = this.currentOrder.goodsInfo && this.currentOrder.goodsInfo.shopName
|
||||||
|
return shopName || '-'
|
||||||
|
},
|
||||||
|
goodsDetailImageUrl() {
|
||||||
|
const imageUrl = this.currentOrder.goodsInfo && this.currentOrder.goodsInfo.imageUrl
|
||||||
|
if (imageUrl) {
|
||||||
|
return imageUrl
|
||||||
|
}
|
||||||
|
if (this.currentOrder.skuId) {
|
||||||
|
return 'https://img14.360buyimg.com/n5/s450x450_' + this.currentOrder.skuId + '.jpg'
|
||||||
|
}
|
||||||
|
return ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -784,8 +819,23 @@ export default {
|
|||||||
},
|
},
|
||||||
/** 查看订单详情 */
|
/** 查看订单详情 */
|
||||||
handleView(row) {
|
handleView(row) {
|
||||||
this.currentOrder = row;
|
const id = row.id
|
||||||
this.viewDialogVisible = true;
|
this.detailImageFailed = false
|
||||||
|
if (!id) {
|
||||||
|
this.currentOrder = row
|
||||||
|
this.viewDialogVisible = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.viewLoading = true
|
||||||
|
getOrderrows(id).then(response => {
|
||||||
|
this.currentOrder = response.data || row
|
||||||
|
this.viewDialogVisible = true
|
||||||
|
}).catch(() => {
|
||||||
|
this.currentOrder = row
|
||||||
|
this.viewDialogVisible = true
|
||||||
|
}).finally(() => {
|
||||||
|
this.viewLoading = false
|
||||||
|
})
|
||||||
},
|
},
|
||||||
/** 新增按钮操作 */
|
/** 新增按钮操作 */
|
||||||
handleAdd() {
|
handleAdd() {
|
||||||
@@ -839,6 +889,31 @@ export default {
|
|||||||
...this.queryParams
|
...this.queryParams
|
||||||
}, `京粉订单数据_${new Date().getTime()}.xlsx`)
|
}, `京粉订单数据_${new Date().getTime()}.xlsx`)
|
||||||
},
|
},
|
||||||
|
/** 一键补全商品图、店铺名 */
|
||||||
|
handleBackfillGoodsInfo() {
|
||||||
|
const orderId = this.queryParams.orderId && String(this.queryParams.orderId).trim()
|
||||||
|
const tip = orderId
|
||||||
|
? `将为订单号 ${orderId} 从京东补全商品图和店铺名,是否继续?`
|
||||||
|
: '将自动补全最近 100 条缺失商品图/店铺名的订单(可多次点击直到补完),是否继续?'
|
||||||
|
this.$modal.confirm(tip).then(() => {
|
||||||
|
this.backfillLoading = true
|
||||||
|
const payload = orderId ? { orderIds: orderId } : { missing: true, limit: 100 }
|
||||||
|
return backfillGoodsInfo(payload)
|
||||||
|
}).then(res => {
|
||||||
|
const data = (res && res.data) || {}
|
||||||
|
const updated = data.updated != null ? data.updated : 0
|
||||||
|
const skipped = data.skipped != null ? data.skipped : 0
|
||||||
|
const failed = data.failed != null ? data.failed : 0
|
||||||
|
if (failed > 0) {
|
||||||
|
this.$modal.msgWarning(`补全完成:成功 ${updated},跳过 ${skipped},失败 ${failed}`)
|
||||||
|
} else {
|
||||||
|
this.$modal.msgSuccess(`补全完成:成功 ${updated},跳过 ${skipped}`)
|
||||||
|
}
|
||||||
|
this.getList()
|
||||||
|
}).catch(() => {}).finally(() => {
|
||||||
|
this.backfillLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
/** 切换统计显示 */
|
/** 切换统计显示 */
|
||||||
toggleStatistics() {
|
toggleStatistics() {
|
||||||
this.showStatistics = !this.showStatistics;
|
this.showStatistics = !this.showStatistics;
|
||||||
@@ -956,6 +1031,14 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.detail-goods-img {
|
||||||
|
max-width: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
object-fit: contain;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
/* 主容器布局 */
|
/* 主容器布局 */
|
||||||
.app-container {
|
.app-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user