1
This commit is contained in:
82
src/api/jarvis/tendoc.js
Normal file
82
src/api/jarvis/tendoc.js
Normal file
@@ -0,0 +1,82 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取腾讯文档授权URL
|
||||
export function getTencentDocAuthUrl() {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/authUrl',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// OAuth回调获取访问令牌
|
||||
export function getTencentDocAccessToken(code) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/oauth/callback',
|
||||
method: 'get',
|
||||
params: { code }
|
||||
})
|
||||
}
|
||||
|
||||
// 刷新访问令牌
|
||||
export function refreshTencentDocToken(data) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/refreshToken',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 根据单号填充物流链接
|
||||
export function fillLogisticsByOrderNo(data) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/fillLogisticsByOrderNo',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 追加单个订单物流信息
|
||||
export function appendLogistics(data) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/appendLogistics',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 自动发货
|
||||
export function autoShip(data) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/autoShip',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 读取表格数据
|
||||
export function readSheetData(params) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/readSheet',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取文件信息
|
||||
export function getFileInfo(params) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/fileInfo',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取工作表列表
|
||||
export function getSheetList(params) {
|
||||
return request({
|
||||
url: '/jarvis/tendoc/sheetList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
@@ -134,8 +134,11 @@
|
||||
<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="120">
|
||||
<el-table-column label="操作" fixed="right" width="180">
|
||||
<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: #f56c6c;" @click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
@@ -155,11 +158,102 @@
|
||||
/>
|
||||
</template>
|
||||
</list-layout>
|
||||
|
||||
<!-- 同步物流对话框 -->
|
||||
<el-dialog
|
||||
title="同步物流到腾讯文档"
|
||||
:visible.sync="syncLogisticsDialogVisible"
|
||||
width="600px"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<el-form :model="syncLogisticsForm" label-width="140px">
|
||||
<el-form-item label="访问令牌">
|
||||
<el-input
|
||||
v-model="syncLogisticsForm.accessToken"
|
||||
placeholder="点击下方按钮获取授权"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
style="margin-top: 8px;"
|
||||
@click="handleAuthorize"
|
||||
>
|
||||
获取授权
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件ID" required>
|
||||
<el-input
|
||||
v-model="syncLogisticsForm.fileId"
|
||||
placeholder="从腾讯文档URL中获取,例如:Dxxxxxxxxxxxxx"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="工作表ID" required>
|
||||
<el-input
|
||||
v-model="syncLogisticsForm.sheetId"
|
||||
placeholder="从腾讯文档URL中获取,例如:BB08J2"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="表头行号">
|
||||
<el-input-number
|
||||
v-model="syncLogisticsForm.headerRow"
|
||||
:min="1"
|
||||
style="width: 100%"
|
||||
/>
|
||||
<div style="font-size: 12px; color: #999; margin-top: 4px;">
|
||||
表头所在行号(默认第1行)
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="单号列索引(可选)">
|
||||
<el-input-number
|
||||
v-model="syncLogisticsForm.orderNoColumn"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="不填写则自动识别"
|
||||
/>
|
||||
<div style="font-size: 12px; color: #999; margin-top: 4px;">
|
||||
单号列的索引(从0开始),不填写则自动识别
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="物流链接列索引(可选)">
|
||||
<el-input-number
|
||||
v-model="syncLogisticsForm.logisticsLinkColumn"
|
||||
:min="0"
|
||||
style="width: 100%"
|
||||
placeholder="不填写则自动识别"
|
||||
/>
|
||||
<div style="font-size: 12px; color: #999; margin-top: 4px;">
|
||||
物流链接列的索引(从0开始),不填写则自动识别
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="说明">
|
||||
<div style="font-size: 12px; color: #666; line-height: 1.6;">
|
||||
<p>1. 首次使用需要点击"获取授权"按钮完成腾讯文档授权</p>
|
||||
<p>2. 文件ID和工作表ID可以从腾讯文档URL中获取</p>
|
||||
<p>3. 系统会自动从上次处理的最大行数-100开始读取,避免重复处理历史数据</p>
|
||||
<p>4. 配置会自动保存,下次使用时无需重新填写</p>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="syncLogisticsDialogVisible = false">取消</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="syncLogisticsLoading"
|
||||
@click="handleSyncLogisticsSubmit"
|
||||
>
|
||||
开始同步
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listJDOrders, updateJDOrder, delJDOrder } from '@/api/system/jdorder'
|
||||
import { fillLogisticsByOrderNo, getTencentDocAuthUrl, getTencentDocAccessToken } from '@/api/jarvis/tendoc'
|
||||
import ListLayout from '@/components/ListLayout'
|
||||
|
||||
export default {
|
||||
@@ -189,7 +283,19 @@ export default {
|
||||
orderBy: 'create_time',
|
||||
isAsc: 'desc',
|
||||
hasFinishTime: false
|
||||
}
|
||||
},
|
||||
// 同步物流对话框
|
||||
syncLogisticsDialogVisible: false,
|
||||
syncLogisticsLoading: false,
|
||||
syncLogisticsForm: {
|
||||
accessToken: '',
|
||||
fileId: '',
|
||||
sheetId: '',
|
||||
headerRow: 1,
|
||||
orderNoColumn: null,
|
||||
logisticsLinkColumn: null
|
||||
},
|
||||
currentOrder: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -415,6 +521,136 @@ export default {
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
/** 同步物流到腾讯文档 */
|
||||
handleSyncLogistics(row) {
|
||||
// 检查是否有物流链接
|
||||
if (!row.logisticsLink || !row.logisticsLink.trim()) {
|
||||
this.$message.warning('该订单暂无物流链接,无法同步')
|
||||
return
|
||||
}
|
||||
|
||||
this.currentOrder = row
|
||||
this.syncLogisticsDialogVisible = true
|
||||
|
||||
// 从localStorage获取之前保存的配置
|
||||
const savedConfig = localStorage.getItem('tendoc_sync_config')
|
||||
if (savedConfig) {
|
||||
try {
|
||||
const config = JSON.parse(savedConfig)
|
||||
this.syncLogisticsForm = {
|
||||
...this.syncLogisticsForm,
|
||||
...config
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析保存的配置失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否有访问令牌,如果没有则引导授权
|
||||
if (!this.syncLogisticsForm.accessToken) {
|
||||
this.handleAuthorize()
|
||||
}
|
||||
},
|
||||
|
||||
/** 腾讯文档授权 */
|
||||
async handleAuthorize() {
|
||||
try {
|
||||
const res = await getTencentDocAuthUrl()
|
||||
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(
|
||||
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 '访问令牌不能为空'
|
||||
}
|
||||
return true
|
||||
}
|
||||
}).then(({ value }) => {
|
||||
this.syncLogisticsForm.accessToken = value.trim()
|
||||
// 保存配置
|
||||
localStorage.setItem('tendoc_sync_config', JSON.stringify(this.syncLogisticsForm))
|
||||
this.$message.success('访问令牌已保存')
|
||||
}).catch(() => {
|
||||
// 用户取消
|
||||
})
|
||||
} else {
|
||||
this.$message.error(res.msg || '获取授权URL失败')
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.error('授权失败,请稍后重试')
|
||||
console.error('授权失败', e)
|
||||
}
|
||||
},
|
||||
|
||||
/** 同步物流链接 */
|
||||
async handleSyncLogisticsSubmit() {
|
||||
if (!this.syncLogisticsForm.accessToken) {
|
||||
this.$message.warning('请先完成腾讯文档授权')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.syncLogisticsForm.fileId || !this.syncLogisticsForm.sheetId) {
|
||||
this.$message.warning('请填写文件ID和工作表ID')
|
||||
return
|
||||
}
|
||||
|
||||
// 保存配置到localStorage
|
||||
localStorage.setItem('tendoc_sync_config', JSON.stringify(this.syncLogisticsForm))
|
||||
|
||||
this.syncLogisticsLoading = true
|
||||
try {
|
||||
const params = {
|
||||
accessToken: this.syncLogisticsForm.accessToken,
|
||||
fileId: this.syncLogisticsForm.fileId,
|
||||
sheetId: this.syncLogisticsForm.sheetId,
|
||||
headerRow: this.syncLogisticsForm.headerRow || 1
|
||||
}
|
||||
|
||||
// 如果指定了列位置,则传递
|
||||
if (this.syncLogisticsForm.orderNoColumn != null) {
|
||||
params.orderNoColumn = this.syncLogisticsForm.orderNoColumn
|
||||
}
|
||||
if (this.syncLogisticsForm.logisticsLinkColumn != null) {
|
||||
params.logisticsLinkColumn = this.syncLogisticsForm.logisticsLinkColumn
|
||||
}
|
||||
|
||||
const res = await fillLogisticsByOrderNo(params)
|
||||
|
||||
if (res.code === 200) {
|
||||
const data = res.data || {}
|
||||
this.$message.success(
|
||||
`同步成功!成功填充 ${data.filledCount || 0} 条,跳过 ${data.skippedCount || 0} 条,错误 ${data.errorCount || 0} 条`
|
||||
)
|
||||
this.syncLogisticsDialogVisible = false
|
||||
} else {
|
||||
this.$message.error(res.msg || '同步失败')
|
||||
}
|
||||
} catch (e) {
|
||||
this.$message.error('同步失败,请稍后重试')
|
||||
console.error('同步物流失败', e)
|
||||
} finally {
|
||||
this.syncLogisticsLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user