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">
|
<el-table-column label="完成时间" prop="finishTime" width="160">
|
||||||
<template slot-scope="scope">{{ parseTime(scope.row.finishTime) }}</template>
|
<template slot-scope="scope">{{ parseTime(scope.row.finishTime) }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" fixed="right" width="120">
|
<el-table-column label="操作" fixed="right" width="180">
|
||||||
<template slot-scope="scope">
|
<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 type="text" size="mini" style="color: #f56c6c;" @click="handleDelete(scope.row)">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -155,11 +158,102 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</list-layout>
|
</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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listJDOrders, updateJDOrder, delJDOrder } from '@/api/system/jdorder'
|
import { listJDOrders, updateJDOrder, delJDOrder } from '@/api/system/jdorder'
|
||||||
|
import { fillLogisticsByOrderNo, getTencentDocAuthUrl, getTencentDocAccessToken } from '@/api/jarvis/tendoc'
|
||||||
import ListLayout from '@/components/ListLayout'
|
import ListLayout from '@/components/ListLayout'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -189,7 +283,19 @@ export default {
|
|||||||
orderBy: 'create_time',
|
orderBy: 'create_time',
|
||||||
isAsc: 'desc',
|
isAsc: 'desc',
|
||||||
hasFinishTime: false
|
hasFinishTime: false
|
||||||
}
|
},
|
||||||
|
// 同步物流对话框
|
||||||
|
syncLogisticsDialogVisible: false,
|
||||||
|
syncLogisticsLoading: false,
|
||||||
|
syncLogisticsForm: {
|
||||||
|
accessToken: '',
|
||||||
|
fileId: '',
|
||||||
|
sheetId: '',
|
||||||
|
headerRow: 1,
|
||||||
|
orderNoColumn: null,
|
||||||
|
logisticsLinkColumn: null
|
||||||
|
},
|
||||||
|
currentOrder: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -415,6 +521,136 @@ export default {
|
|||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
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