This commit is contained in:
2025-11-05 22:47:11 +08:00
parent df9085baa4
commit 364276d85b
2 changed files with 61 additions and 78 deletions

View File

@@ -35,6 +35,23 @@ export function fillLogisticsByOrderNo(data) {
}) })
} }
// 获取token状态
export function getTokenStatus() {
return request({
url: '/jarvis/tendoc/tokenStatus',
method: 'get'
})
}
// 设置token用于首次授权
export function setToken(data) {
return request({
url: '/jarvis/tendoc/setToken',
method: 'post',
data
})
}
// 追加单个订单物流信息 // 追加单个订单物流信息
export function appendLogistics(data) { export function appendLogistics(data) {
return request({ return request({

View File

@@ -278,22 +278,20 @@
width="600px" width="600px"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<el-form :model="syncLogisticsForm" label-width="140px"> <el-alert
<el-form-item label="访问令牌"> v-if="tokenStatusChecked && !tokenValid"
<el-input title="访问令牌未配置或已过期"
v-model="syncLogisticsForm.accessToken" type="warning"
placeholder="点击下方按钮获取授权" :closable="false"
style="width: 100%" style="margin-bottom: 20px;"
/>
<el-button
type="primary"
size="small"
style="margin-top: 8px;"
@click="handleAuthorize"
> >
获取授权 <template slot="default">
</el-button> <p>请先完成授权并保存访问令牌</p>
</el-form-item> <p>获取授权URL后完成授权从回调页面复制access_token和refresh_token然后调用设置token接口保存</p>
</template>
</el-alert>
<el-form :model="syncLogisticsForm" label-width="140px">
<el-form-item label="文件ID" required> <el-form-item label="文件ID" required>
<el-input <el-input
v-model="syncLogisticsForm.fileId" v-model="syncLogisticsForm.fileId"
@@ -342,7 +340,7 @@
</el-form-item> </el-form-item>
<el-form-item label="说明"> <el-form-item label="说明">
<div style="font-size: 12px; color: #666; line-height: 1.6;"> <div style="font-size: 12px; color: #666; line-height: 1.6;">
<p>1. 首次使用需要点击"获取授权"按钮完成腾讯文档授权</p> <p>1. 系统会自动使用后端保存的访问令牌无需手动输入</p>
<p>2. 文件ID和工作表ID可以从腾讯文档URL中获取</p> <p>2. 文件ID和工作表ID可以从腾讯文档URL中获取</p>
<p>3. 系统会自动从上次处理的最大行数-100开始读取避免重复处理历史数据</p> <p>3. 系统会自动从上次处理的最大行数-100开始读取避免重复处理历史数据</p>
<p>4. 配置会自动保存下次使用时无需重新填写</p> <p>4. 配置会自动保存下次使用时无需重新填写</p>
@@ -355,6 +353,7 @@
type="primary" type="primary"
:loading="syncLogisticsLoading" :loading="syncLogisticsLoading"
@click="handleSyncLogisticsSubmit" @click="handleSyncLogisticsSubmit"
:disabled="tokenStatusChecked && !tokenValid"
> >
开始同步 开始同步
</el-button> </el-button>
@@ -365,7 +364,7 @@
<script> <script>
import { listJDOrders, updateJDOrder, delJDOrder, fetchLogisticsManually } from '@/api/system/jdorder' import { listJDOrders, updateJDOrder, delJDOrder, fetchLogisticsManually } from '@/api/system/jdorder'
import { fillLogisticsByOrderNo, getTencentDocAuthUrl, getTencentDocAccessToken } from '@/api/jarvis/tendoc' import { fillLogisticsByOrderNo, getTokenStatus } from '@/api/jarvis/tendoc'
import ListLayout from '@/components/ListLayout' import ListLayout from '@/components/ListLayout'
export default { export default {
@@ -400,7 +399,6 @@ export default {
syncLogisticsDialogVisible: false, syncLogisticsDialogVisible: false,
syncLogisticsLoading: false, syncLogisticsLoading: false,
syncLogisticsForm: { syncLogisticsForm: {
accessToken: '',
fileId: '', fileId: '',
sheetId: '', sheetId: '',
headerRow: 1, headerRow: 1,
@@ -408,6 +406,8 @@ export default {
logisticsLinkColumn: null logisticsLinkColumn: null
}, },
currentOrder: null, currentOrder: null,
tokenValid: false,
tokenStatusChecked: false,
// 获取物流信息对话框 // 获取物流信息对话框
fetchLogisticsDialogVisible: false, fetchLogisticsDialogVisible: false,
fetchLogisticsLoading: false, fetchLogisticsLoading: false,
@@ -640,7 +640,7 @@ export default {
}, },
/** 同步物流到腾讯文档 */ /** 同步物流到腾讯文档 */
handleSyncLogistics(row) { async handleSyncLogistics(row) {
// 检查是否有物流链接 // 检查是否有物流链接
if (!row.logisticsLink || !row.logisticsLink.trim()) { if (!row.logisticsLink || !row.logisticsLink.trim()) {
this.$message.warning('该订单暂无物流链接,无法同步') this.$message.warning('该订单暂无物流链接,无法同步')
@@ -649,6 +649,8 @@ export default {
this.currentOrder = row this.currentOrder = row
this.syncLogisticsDialogVisible = true this.syncLogisticsDialogVisible = true
this.tokenStatusChecked = false
this.tokenValid = false
// 从localStorage获取之前保存的配置 // 从localStorage获取之前保存的配置
const savedConfig = localStorage.getItem('tendoc_sync_config') const savedConfig = localStorage.getItem('tendoc_sync_config')
@@ -664,74 +666,31 @@ export default {
} }
} }
// 检查是否有访问令牌,如果没有则引导授权 // 检查后端token状态
if (!this.syncLogisticsForm.accessToken) { await this.checkTokenStatus()
this.handleAuthorize()
}
}, },
/** 腾讯文档授权 */ /** 检查后端token状态 */
async handleAuthorize() { async checkTokenStatus() {
try { try {
const res = await getTencentDocAuthUrl() const res = await getTokenStatus()
if (res.code === 200 && res.data) { if (res.code === 200 && res.data) {
// 打开授权页面 this.tokenValid = res.data.hasToken === true
const authUrl = res.data
const width = 600
const height = 700
const left = (window.screen.width - width) / 2
const top = (window.screen.height - height) / 2
// 监听来自授权回调页面的消息
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`
)
// 如果窗口关闭检查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('授权成功,访问令牌已自动保存')
}
}
}, 1000)
this.$message.info('请在授权页面完成授权,授权成功后会自动保存访问令牌')
} else { } else {
this.$message.error(res.msg || '获取授权URL失败') this.tokenValid = false
} }
} catch (e) { } catch (e) {
this.$message.error('授权失败,请稍后重试') console.error('检查token状态失败', e)
console.error('授权失败', e) this.tokenValid = false
} finally {
this.tokenStatusChecked = true
} }
}, },
/** 同步物流链接 */ /** 同步物流链接 */
async handleSyncLogisticsSubmit() { async handleSyncLogisticsSubmit() {
if (!this.syncLogisticsForm.accessToken) { if (!this.tokenValid) {
this.$message.warning('请先完成腾讯文档授权') this.$message.warning('访问令牌无效请先完成授权并保存token')
return return
} }
@@ -740,13 +699,20 @@ export default {
return return
} }
// 保存配置到localStorage // 保存配置到localStorage不包含accessToken
localStorage.setItem('tendoc_sync_config', JSON.stringify(this.syncLogisticsForm)) const configToSave = {
fileId: this.syncLogisticsForm.fileId,
sheetId: this.syncLogisticsForm.sheetId,
headerRow: this.syncLogisticsForm.headerRow,
orderNoColumn: this.syncLogisticsForm.orderNoColumn,
logisticsLinkColumn: this.syncLogisticsForm.logisticsLinkColumn
}
localStorage.setItem('tendoc_sync_config', JSON.stringify(configToSave))
this.syncLogisticsLoading = true this.syncLogisticsLoading = true
try { try {
const params = { const params = {
accessToken: this.syncLogisticsForm.accessToken, // 不再传递accessToken,后端自动获取
fileId: this.syncLogisticsForm.fileId, fileId: this.syncLogisticsForm.fileId,
sheetId: this.syncLogisticsForm.sheetId, sheetId: this.syncLogisticsForm.sheetId,
headerRow: this.syncLogisticsForm.headerRow || 1 headerRow: this.syncLogisticsForm.headerRow || 1