This commit is contained in:
van
2026-05-16 02:27:56 +08:00
parent 3980fed315
commit f55b5f46a4
3 changed files with 173 additions and 11 deletions

View File

@@ -84,3 +84,8 @@ export function refreshGoofishDetail(id) {
export function retryGoofishShip(id) { export function retryGoofishShip(id) {
return request({ url: '/jarvis/erpGoofishOrder/retryShip/' + id, method: 'post' }) return request({ url: '/jarvis/erpGoofishOrder/retryShip/' + id, method: 'post' })
} }
/** 发货预览:闲鱼订单收件串 vs 即将提交开放平台参数(与自动发货逻辑一致) */
export function previewGoofishShip(id) {
return request({ url: '/jarvis/erpGoofishOrder/shipPreview/' + id, method: 'get' })
}

View File

@@ -208,11 +208,12 @@
{{ formatModifyTime(scope.row.modifyTime) }} {{ formatModifyTime(scope.row.modifyTime) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="278" fixed="right"> <el-table-column label="操作" align="center" width="356" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button size="mini" type="text" @click="openJson(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:query']">详情JSON</el-button> <el-button size="mini" type="text" @click="openJson(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:query']">详情JSON</el-button>
<el-button size="mini" type="text" @click="handleRefresh(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:edit']">刷新详情</el-button> <el-button size="mini" type="text" @click="handleRefresh(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:edit']">刷新详情</el-button>
<el-button size="mini" type="text" class="goofish-btn-logistics" @click="handleRefreshLogistics(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:edit']">刷新物流</el-button> <el-button size="mini" type="text" class="goofish-btn-logistics" @click="handleRefreshLogistics(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:edit']">刷新物流</el-button>
<el-button size="mini" type="text" @click="handleShipPreview(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:query']">发货预览</el-button>
<el-button size="mini" type="text" @click="handleRetryShip(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:edit']">重试发货</el-button> <el-button size="mini" type="text" @click="handleRetryShip(scope.row)" v-hasPermi="['jarvis:erpGoofishOrder:edit']">重试发货</el-button>
</template> </template>
</el-table-column> </el-table-column>
@@ -220,6 +221,48 @@
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" /> <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<el-dialog
title="发货地址比对"
:visible.sync="shipPreviewDialogVisible"
width="720px"
append-to-body
:close-on-click-modal="false"
@closed="onShipPreviewDialogClosed"
>
<div v-loading="shipPreviewLoading">
<p v-if="shipPreviewVo.orderNo" class="goofish-rl-order">闲鱼订单号<code>{{ shipPreviewVo.orderNo }}</code></p>
<el-alert
v-if="shipPreviewVo.compareHint"
:title="shipPreviewVo.compareHint"
type="info"
:closable="false"
show-icon
style="margin-bottom: 12px;"
/>
<el-descriptions :column="1" border size="small">
<el-descriptions-item label="标题 goods.title">{{ shipPreviewVo.goodsTitle || '—' }}</el-descriptions-item>
<el-descriptions-item label="京东型号">{{ shipPreviewVo.jdModelNumber || '—' }}</el-descriptions-item>
<el-descriptions-item label="京东整段地址">{{ shipPreviewVo.jdAddressFull || '—' }}</el-descriptions-item>
<el-descriptions-item label="闲鱼订单收件">{{ shipGoofishRecipientLine }}</el-descriptions-item>
<el-descriptions-item label="发货提交收件">{{ shipSubmitRecipientLine }}</el-descriptions-item>
</el-descriptions>
<el-table :data="shipPreviewCompareRows" size="small" border stripe style="margin-top: 14px;">
<el-table-column prop="hint" label="" width="156" show-overflow-tooltip />
<el-table-column prop="addr" label="收件地址文本" min-width="280" show-overflow-tooltip />
<el-table-column prop="same" label="与发货一致" width="100" align="center">
<template slot-scope="scope">
<template v-if="scope.row.same === true"><el-tag type="success" size="mini">一致</el-tag></template>
<template v-else-if="scope.row.same === false"><el-tag type="danger" size="mini">不一致</el-tag></template>
<span v-else></span>
</template>
</el-table-column>
</el-table>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="shipPreviewDialogVisible = false"> </el-button>
</div>
</el-dialog>
<!-- 刷新物流结果弹窗与京东订单页一致 append-to-body 避免被表格区裁剪 --> <!-- 刷新物流结果弹窗与京东订单页一致 append-to-body 避免被表格区裁剪 -->
<el-dialog <el-dialog
title="刷新物流结果" title="刷新物流结果"
@@ -317,6 +360,7 @@
<el-descriptions-item label="手机 receiver_mobile">{{ displayReceiverMobile(jsonRow) || '—' }}</el-descriptions-item> <el-descriptions-item label="手机 receiver_mobile">{{ displayReceiverMobile(jsonRow) || '—' }}</el-descriptions-item>
<el-descriptions-item label="省/市/区/镇 prov…town">{{ displayRecvSplit(jsonRow) }}</el-descriptions-item> <el-descriptions-item label="省/市/区/镇 prov…town">{{ displayRecvSplit(jsonRow) }}</el-descriptions-item>
<el-descriptions-item label="详细地址 address">{{ displayAddressLine(jsonRow) }}</el-descriptions-item> <el-descriptions-item label="详细地址 address">{{ displayAddressLine(jsonRow) }}</el-descriptions-item>
<el-descriptions-item label="闲鱼收件(区划+明细拼接)">{{ displayFullGoofishAddress(jsonRow) }}</el-descriptions-item>
<el-descriptions-item label="拼接区划 receiver_region">{{ jsonRow.receiverRegion || '—' }}</el-descriptions-item> <el-descriptions-item label="拼接区划 receiver_region">{{ jsonRow.receiverRegion || '—' }}</el-descriptions-item>
<el-descriptions-item label="京东地址">{{ jsonRow.jdAddress || '-' }}</el-descriptions-item> <el-descriptions-item label="京东地址">{{ jsonRow.jdAddress || '-' }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
@@ -347,7 +391,7 @@
</template> </template>
<script> <script>
import { listGoofishOrder, listGoofishOrderEventLogs, pullAllGoofishOrders, pullAllGoofishOrdersFull, pullGoofishOrdersFull, refreshGoofishDetail, retryGoofishShip, getGoofishOrder } from '@/api/jarvis/goofish' import { listGoofishOrder, listGoofishOrderEventLogs, pullAllGoofishOrders, pullAllGoofishOrdersFull, pullGoofishOrdersFull, refreshGoofishDetail, retryGoofishShip, getGoofishOrder, previewGoofishShip } from '@/api/jarvis/goofish'
import { parseTime } from '@/utils/ruoyi' import { parseTime } from '@/utils/ruoyi'
/** 与闲管家开放平台 order_status 一致 */ /** 与闲管家开放平台 order_status 一致 */
@@ -420,7 +464,11 @@ export default {
refreshLogisticsOrderNo: '', refreshLogisticsOrderNo: '',
refreshLogisticsBefore: null, refreshLogisticsBefore: null,
refreshLogisticsAfter: null, refreshLogisticsAfter: null,
refreshLogisticsError: '' refreshLogisticsError: '',
/** 发货预览 */
shipPreviewDialogVisible: false,
shipPreviewLoading: false,
shipPreviewVo: {}
} }
}, },
computed: { computed: {
@@ -455,6 +503,48 @@ export default {
}, },
refreshLogisticsHasDiff() { refreshLogisticsHasDiff() {
return this.refreshLogisticsCompareRows.some(r => r.before !== r.after) return this.refreshLogisticsCompareRows.some(r => r.before !== r.after)
},
shipGoofishRecipientLine() {
const v = this.shipPreviewVo
if (!v) return '—'
const n = (v.goofishOrderReceiverName || '').trim()
const m = (v.goofishOrderReceiverMobile || '').trim()
const a = (v.goofishOrderFullAddress || '').trim()
const nm = [n, m].filter(Boolean).join(' ')
const parts = []
if (nm) parts.push(nm)
if (a) parts.push(a)
return parts.length ? parts.join(' · ') : '—'
},
shipSubmitRecipientLine() {
const v = this.shipPreviewVo
if (!v) return '—'
const n = (v.shipReceiverName || '').trim()
const m = (v.shipReceiverMobile || '').trim()
const a = (v.shipFullAddress || '').trim()
const nm = [n, m].filter(Boolean).join(' ')
const parts = []
if (nm) parts.push(nm)
if (a) parts.push(a)
return parts.length ? parts.join(' · ') : '—'
},
shipPreviewCompareRows() {
const v = this.shipPreviewVo
if (!v) return []
const ship = (v.shipFullAddress || '').trim()
const normalize = s => (s || '').trim().replace(/\s+/g, ' ')
const normShip = normalize(ship)
const cmp = text => {
const nt = normalize(text)
if (!nt || !normShip) {
return null
}
return nt === normShip
}
return [
{ hint: '闲鱼订单收件串', addr: v.goofishOrderFullAddress || '—', same: cmp(v.goofishOrderFullAddress) },
{ hint: '京东整段地址', addr: v.jdAddressFull || '—', same: cmp(v.jdAddressFull) }
]
} }
}, },
created() { created() {
@@ -467,6 +557,9 @@ export default {
this.refreshLogisticsError = '' this.refreshLogisticsError = ''
this.refreshLogisticsOrderNo = '' this.refreshLogisticsOrderNo = ''
}, },
onShipPreviewDialogClosed() {
this.shipPreviewVo = {}
},
orderStatusLabel(s) { orderStatusLabel(s) {
if (s == null || s === '') { if (s == null || s === '') {
return '—' return '—'
@@ -641,6 +734,16 @@ export default {
if (row.receiverAddress) return row.receiverAddress if (row.receiverAddress) return row.receiverAddress
return '—' return '—'
}, },
/** 列表/摘要一行展示:区划列 + 详细地址(与后端 receiverFieldsToShipParts 目视一致) */
displayFullGoofishAddress(row) {
if (!row) return '—'
const rs = this.displayRecvSplit(row)
const ln = this.displayAddressLine(row)
const parts = []
if (rs && rs !== '—') parts.push(rs)
if (ln && ln !== '—') parts.push(ln)
return parts.length ? parts.join(' ') : '—'
},
normalizeWaybill(v) { normalizeWaybill(v) {
if (v == null || v === '') return '' if (v == null || v === '') return ''
return String(v).trim() return String(v).trim()
@@ -818,6 +921,20 @@ export default {
this.getList() this.getList()
}) })
}, },
/** 后端与自动发货同源:比对闲鱼收件串 vs 开放平台发货参数 */
handleShipPreview(row) {
if (!row || !row.id) return
this.shipPreviewDialogVisible = true
this.shipPreviewLoading = true
this.shipPreviewVo = {}
previewGoofishShip(row.id).then(res => {
this.shipPreviewVo = res && res.data ? { ...res.data } : {}
}).catch(() => {
this.shipPreviewVo = { compareHint: '请求失败,请检查权限或网络', orderNo: row.orderNo }
}).finally(() => {
this.shipPreviewLoading = false
})
},
/** 打开「变更日志」排查页:与当前菜单同级路径 erpGoofishEventLog需在菜单管理配置 */ /** 打开「变更日志」排查页:与当前菜单同级路径 erpGoofishEventLog需在菜单管理配置 */
openEventLogTroubleshoot() { openEventLogTroubleshoot() {
const p = this.$route.path || '' const p = this.$route.path || ''

View File

@@ -554,6 +554,10 @@
</div> </div>
</div> </div>
<p v-if="isMobile && !loading && total > list.length" class="mobile-order-list-cap-hint">
<b>{{ total }}</b> 当前已加载 <b>{{ list.length }}</b> 单次上限 {{ queryParams.pageSize }}其余请缩小日期/筛选或在电脑端查看
</p>
<el-empty v-if="!loading && list.length === 0" description="暂无数据" :image-size="100" /> <el-empty v-if="!loading && list.length === 0" description="暂无数据" :image-size="100" />
</div> </div>
@@ -1289,6 +1293,9 @@ import TencentDocAutoWriteConfig from './components/TencentDocAutoWriteConfig'
import TencentDocPushMonitor from './components/TencentDocPushMonitor' import TencentDocPushMonitor from './components/TencentDocPushMonitor'
import DistributionMarkTouserConfig from './components/DistributionMarkTouserConfig' import DistributionMarkTouserConfig from './components/DistributionMarkTouserConfig'
/** 移动端「下好的慢单」一次拉取条数ListLayout 在窄屏隐藏分页,原先默认 50 条无法翻页) */
const MOBILE_JD_ORDER_PAGE_SIZE = 500
export default { export default {
name: 'JDOrderList', name: 'JDOrderList',
components: { components: {
@@ -1417,9 +1424,15 @@ export default {
return (base || []).filter(r => r.isRefunded !== 1) return (base || []).filter(r => r.isRefunded !== 1)
}, },
profitSummaryLabel() { profitSummaryLabel() {
return this.selectedRows && this.selectedRows.length > 0 if (this.selectedRows && this.selectedRows.length > 0) {
? `已选 ${this.selectedRows.length}` return `已选 ${this.selectedRows.length}`
: `本页 ${this.list.length}` }
if (this.isMobile) {
const n = (this.list && this.list.length) || 0
const t = this.total || 0
return t > n ? `本批 ${n} 条(共 ${t} 条)` : `本批 ${n}`
}
return `本页 ${this.list.length}`
}, },
profitSummaryRebateTotal() { profitSummaryRebateTotal() {
return this.profitSummaryRows.reduce((s, r) => s + (Number(r.rebateAmount) || 0), 0) return this.profitSummaryRows.reduce((s, r) => s + (Number(r.rebateAmount) || 0), 0)
@@ -1467,7 +1480,17 @@ export default {
] ]
} }
}, },
watch: {
device(val, oldVal) {
if (val === 'mobile' && oldVal !== 'mobile') {
this.queryParams.pageSize = MOBILE_JD_ORDER_PAGE_SIZE
this.queryParams.pageNum = 1
this.getList()
}
}
},
created() { created() {
this.applyMobileSlowOrderPageSize()
// 设置默认日期为今天 // 设置默认日期为今天
this.setDefaultDateRange() this.setDefaultDateRange()
this.getListWithFallback() this.getListWithFallback()
@@ -1571,6 +1594,12 @@ export default {
} }
}) })
}, },
/** 移动端 ListLayout 隐藏分页栏,默认 pageSize 过小会导致无法看到后序订单 */
applyMobileSlowOrderPageSize() {
if (this.device === 'mobile' || (typeof window !== 'undefined' && window.innerWidth < 768)) {
this.queryParams.pageSize = MOBILE_JD_ORDER_PAGE_SIZE
}
},
/** 处理移动端操作菜单命令 */ /** 处理移动端操作菜单命令 */
handleActionCommand({ action, row }) { handleActionCommand({ action, row }) {
switch (action) { switch (action) {
@@ -1885,7 +1914,7 @@ export default {
resetQuery() { resetQuery() {
this.queryParams = { this.queryParams = {
pageNum: 1, pageNum: 1,
pageSize: 50, pageSize: this.isMobile ? MOBILE_JD_ORDER_PAGE_SIZE : 50,
remark: undefined, remark: undefined,
orderSearch: undefined, orderSearch: undefined,
distributionMark: undefined, distributionMark: undefined,
@@ -4427,6 +4456,17 @@ export default {
margin-top: 4px; margin-top: 4px;
} }
.mobile-order-list-cap-hint {
margin: 12px 4px 4px;
padding: 10px 12px;
font-size: 12px;
line-height: 1.5;
color: #92400e;
background: #fffbeb;
border: 1px solid #fde68a;
border-radius: 8px;
}
/* 本页:避免外层 .table-section 与表格内部双纵向滚动,横向滚动仍由表体承担 */ /* 本页:避免外层 .table-section 与表格内部双纵向滚动,横向滚动仍由表体承担 */
.jd-order-list-root ::v-deep .table-section { .jd-order-list-root ::v-deep .table-section {
overflow-x: auto; overflow-x: auto;