This commit is contained in:
2025-11-05 15:42:51 +08:00
parent 855d22f448
commit 283cfbbfc8
4 changed files with 382 additions and 25 deletions

View File

@@ -134,11 +134,21 @@
<el-table-column label="完成时间" prop="finishTime" width="160">
<template slot-scope="scope">{{ parseTime(scope.row.finishTime) }}</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180">
<el-table-column label="操作" fixed="right" width="240">
<template slot-scope="scope">
<el-button type="text" size="mini" style="color: #409EFF;" @click="handleSyncLogistics(scope.row)">
同步物流
</el-button>
<el-button
type="text"
size="mini"
style="color: #67C23A;"
@click="handleFetchLogistics(scope.row)"
:disabled="scope.row.distributionMark !== 'F' && scope.row.distributionMark !== 'PDD'"
:title="(scope.row.distributionMark !== 'F' && scope.row.distributionMark !== 'PDD') ? '仅支持F或PDD分销标识' : '获取物流信息'"
>
获取物流
</el-button>
<el-button type="text" size="mini" style="color: #f56c6c;" @click="handleDelete(scope.row)">
删除
</el-button>
@@ -159,6 +169,89 @@
</template>
</list-layout>
<!-- 获取物流信息对话框 -->
<el-dialog
title="获取物流信息(调试)"
:visible.sync="fetchLogisticsDialogVisible"
width="800px"
:close-on-click-modal="false"
>
<div v-loading="fetchLogisticsLoading">
<el-alert
v-if="fetchLogisticsResult"
:title="fetchLogisticsResult.success ? '获取成功' : '获取失败'"
:type="fetchLogisticsResult.success ? 'success' : 'error'"
:closable="false"
style="margin-bottom: 20px;"
/>
<el-form label-width="120px" v-if="fetchLogisticsResult">
<el-form-item label="错误信息" v-if="fetchLogisticsResult.error">
<el-alert
:title="fetchLogisticsResult.error"
type="error"
:closable="false"
/>
</el-form-item>
<el-form-item label="订单ID" v-if="fetchLogisticsResult.orderId">
<span>{{ fetchLogisticsResult.orderId }}</span>
</el-form-item>
<el-form-item label="订单号" v-if="fetchLogisticsResult.orderNo">
<span>{{ fetchLogisticsResult.orderNo }}</span>
</el-form-item>
<el-form-item label="分销标识" v-if="fetchLogisticsResult.distributionMark">
<span>{{ fetchLogisticsResult.distributionMark }}</span>
</el-form-item>
<el-form-item label="物流链接" v-if="fetchLogisticsResult.logisticsLink">
<el-input
:value="fetchLogisticsResult.logisticsLink"
readonly
type="textarea"
:rows="2"
/>
</el-form-item>
<el-form-item label="请求URL" v-if="fetchLogisticsResult.requestUrl">
<el-input
:value="fetchLogisticsResult.requestUrl"
readonly
type="textarea"
:rows="2"
/>
</el-form-item>
<el-form-item label="返回数据(原始)" v-if="fetchLogisticsResult.responseRaw || fetchLogisticsResult.responseData">
<el-input
:value="fetchLogisticsResult.responseRaw || JSON.stringify(fetchLogisticsResult.responseData, null, 2)"
readonly
type="textarea"
:rows="10"
style="font-family: monospace; font-size: 12px;"
/>
</el-form-item>
<el-form-item label="返回数据(解析后)" v-if="fetchLogisticsResult.responseData">
<el-input
:value="JSON.stringify(fetchLogisticsResult.responseData, null, 2)"
readonly
type="textarea"
:rows="10"
style="font-family: monospace; font-size: 12px;"
/>
</el-form-item>
</el-form>
<div v-else style="text-align: center; padding: 40px;">
<span style="color: #999;">正在获取物流信息...</span>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="fetchLogisticsDialogVisible = false">关闭</el-button>
<el-button
type="primary"
@click="copyFetchLogisticsResult"
v-if="fetchLogisticsResult"
>
复制结果
</el-button>
</div>
</el-dialog>
<!-- 同步物流对话框 -->
<el-dialog
title="同步物流到腾讯文档"
@@ -252,7 +345,7 @@
</template>
<script>
import { listJDOrders, updateJDOrder, delJDOrder } from '@/api/system/jdorder'
import { listJDOrders, updateJDOrder, delJDOrder, fetchLogisticsManually } from '@/api/system/jdorder'
import { fillLogisticsByOrderNo, getTencentDocAuthUrl, getTencentDocAccessToken } from '@/api/jarvis/tendoc'
import ListLayout from '@/components/ListLayout'
@@ -295,7 +388,11 @@ export default {
orderNoColumn: null,
logisticsLinkColumn: null
},
currentOrder: null
currentOrder: null,
// 获取物流信息对话框
fetchLogisticsDialogVisible: false,
fetchLogisticsLoading: false,
fetchLogisticsResult: null
}
},
created() {
@@ -561,38 +658,48 @@ export default {
if (res.code === 200 && res.data) {
// 打开授权页面
const authUrl = res.data
this.$message.info('正在打开授权页面,授权完成后请将访问令牌复制到上方输入框')
const width = 600
const height = 700
const left = (window.screen.width - width) / 2
const top = (window.screen.height - height) / 2
window.open(
// 监听来自授权回调页面的消息
const messageHandler = (event) => {
if (event.data && event.data.type === 'tendoc_auth_success') {
window.removeEventListener('message', messageHandler)
this.syncLogisticsForm.accessToken = event.data.access_token
// 保存配置
localStorage.setItem('tendoc_sync_config', JSON.stringify(this.syncLogisticsForm))
this.$message.success('授权成功,访问令牌已自动保存')
}
}
window.addEventListener('message', messageHandler)
// 打开授权窗口
const authWindow = window.open(
authUrl,
'腾讯文档授权',
`width=${width},height=${height},left=${left},top=${top},resizable=yes,scrollbars=yes`
)
// 提示用户手动输入访问令牌
this.$prompt('授权完成后请从授权页面复制访问令牌access_token并粘贴到下方', '输入访问令牌', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPlaceholder: '请输入访问令牌',
inputValidator: (value) => {
if (!value || !value.trim()) {
return '访问令牌不能为空'
// 如果窗口关闭检查localStorage是否有新的token
const checkWindow = setInterval(() => {
if (authWindow.closed) {
clearInterval(checkWindow)
window.removeEventListener('message', messageHandler)
// 检查localStorage是否有新的token
const token = localStorage.getItem('tendoc_access_token')
if (token && token !== this.syncLogisticsForm.accessToken) {
this.syncLogisticsForm.accessToken = token
localStorage.setItem('tendoc_sync_config', JSON.stringify(this.syncLogisticsForm))
this.$message.success('授权成功,访问令牌已自动保存')
}
return true
}
}).then(({ value }) => {
this.syncLogisticsForm.accessToken = value.trim()
// 保存配置
localStorage.setItem('tendoc_sync_config', JSON.stringify(this.syncLogisticsForm))
this.$message.success('访问令牌已保存')
}).catch(() => {
// 用户取消
})
}, 1000)
this.$message.info('请在授权页面完成授权,授权成功后会自动保存访问令牌')
} else {
this.$message.error(res.msg || '获取授权URL失败')
}
@@ -651,6 +758,60 @@ export default {
} finally {
this.syncLogisticsLoading = false
}
},
/** 手动获取物流信息 */
async handleFetchLogistics(row) {
// 检查分销标识
if (row.distributionMark !== 'F' && row.distributionMark !== 'PDD') {
this.$message.warning('该订单的分销标识不是F或PDD无需处理')
return
}
// 检查物流链接
if (!row.logisticsLink || !row.logisticsLink.trim()) {
this.$message.warning('该订单暂无物流链接')
return
}
this.fetchLogisticsDialogVisible = true
this.fetchLogisticsLoading = true
this.fetchLogisticsResult = null
try {
const res = await fetchLogisticsManually({ orderId: row.id })
if (res.code === 200) {
this.fetchLogisticsResult = {
success: true,
...res.data
}
this.$message.success('获取物流信息成功,数据已记录到日志文件')
} else {
this.fetchLogisticsResult = {
success: false,
error: res.msg || '获取失败'
}
this.$message.error(res.msg || '获取物流信息失败')
}
} catch (e) {
this.fetchLogisticsResult = {
success: false,
error: e.message || '请求异常'
}
this.$message.error('获取物流信息失败: ' + (e.message || '未知错误'))
console.error('获取物流信息失败', e)
} finally {
this.fetchLogisticsLoading = false
}
},
/** 复制获取物流信息的结果 */
copyFetchLogisticsResult() {
if (!this.fetchLogisticsResult) return
const resultText = JSON.stringify(this.fetchLogisticsResult, null, 2)
this.copyToClipboard(resultText)
}
}