This commit is contained in:
Leo
2026-01-15 19:50:23 +08:00
parent 09cb3c2862
commit 04dd5396ac

View File

@@ -1,9 +1,13 @@
<template>
<div class="tendoc-config">
<div class="config-container">
<!-- 左侧配置表单 -->
<div class="config-left">
<!-- 授权状态 -->
<el-card class="auth-card" style="margin-bottom: 20px;">
<div slot="header">
<span><i class="el-icon-key"></i> 授权状态</span>
<el-card class="config-section">
<div slot="header" class="section-header">
<i class="el-icon-key"></i>
<span>授权状态</span>
</div>
<div class="auth-status">
<el-tag v-if="config.hasAccessToken" type="success" size="medium">
@@ -38,10 +42,11 @@
</div>
</el-card>
<!-- 自动写入配置 -->
<el-card>
<div slot="header">
<span><i class="el-icon-setting"></i> H-TF订单自动写入配置</span>
<!-- 文档配置表单 -->
<el-card class="config-section">
<div slot="header" class="section-header">
<i class="el-icon-document"></i>
<span>H-TF订单自动写入配置</span>
<el-tag v-if="config.isConfigured" type="success" size="mini" style="margin-left: 10px;">
<i class="el-icon-success"></i> 已配置
</el-tag>
@@ -49,14 +54,12 @@
<i class="el-icon-warning"></i> 未配置
</el-tag>
</div>
<el-form ref="form" :model="form" :rules="rules" label-width="120px" size="small">
<el-form ref="form" :model="form" :rules="rules" label-width="100px" size="small">
<el-form-item label="文件ID" prop="fileId">
<el-input
v-model="form.fileId"
placeholder="例如DUW50RUprWXh2TGJK"
clearable
style="width: 400px;"
>
<el-button
slot="append"
@@ -74,7 +77,7 @@
v-if="sheetList.length > 0"
v-model="form.sheetId"
placeholder="请选择工作表"
style="width: 400px;"
style="width: 100%;"
clearable
>
<el-option
@@ -92,35 +95,28 @@
v-model="form.sheetId"
placeholder="例如BB08J2"
clearable
style="width: 400px;"
/>
</el-form-item>
<el-row :gutter="20">
<el-row :gutter="10">
<el-col :span="12">
<el-form-item label="表头行号" prop="headerRow">
<el-input-number
v-model="form.headerRow"
:min="1"
:max="100"
controls-position="right"
style="width: 100%;"
/>
<div style="color: #909399; font-size: 12px; margin-top: 5px;">
表头所在的行号从1开始
</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="数据起始行" prop="startRow">
<el-form-item label="起始行" prop="startRow">
<el-input-number
v-model="form.startRow"
:min="1"
:max="10000"
controls-position="right"
style="width: 100%;"
/>
<div style="color: #909399; font-size: 12px; margin-top: 5px;">
数据开始的行号从1开始
</div>
</el-form-item>
</el-col>
</el-row>
@@ -141,8 +137,89 @@
</el-form-item>
</el-form>
</el-card>
</div>
<!-- 操作日志对话框 -->
<!-- 右侧状态信息 -->
<div class="config-right">
<!-- 配置状态提示 -->
<el-card class="status-card-wrapper">
<div class="status-card" :class="config.isConfigured ? 'success' : 'warning'">
<div class="status-icon" :class="config.isConfigured ? 'success' : 'warning'">
<i :class="config.isConfigured ? 'el-icon-success' : 'el-icon-warning'"></i>
</div>
<div class="status-text">
<div class="status-title">{{ config.isConfigured ? '配置完成' : '配置未完成' }}</div>
<div class="status-desc">{{ config.hint || (config.isConfigured ? 'H-TF订单将自动写入腾讯文档' : '请完成配置') }}</div>
</div>
</div>
</el-card>
<!-- 同步进度 -->
<el-card v-if="config.progressHint || config.currentProgress" class="progress-card-wrapper">
<div slot="header" class="card-header">
<i class="el-icon-data-line"></i>
<span>同步进度</span>
</div>
<div class="progress-content">
<div v-if="config.currentProgress" class="progress-detail">
<div class="progress-item">
<span class="label">当前进度</span>
<span class="value"> {{ config.currentProgress }} </span>
</div>
<div class="progress-item">
<span class="label">下次同步</span>
<span class="value">
<template v-if="config.currentProgress <= (form.startRow + 49)">
{{ form.startRow }}
</template>
<template v-else-if="config.currentProgress > (form.startRow + 100)">
{{ config.currentProgress - 100 }}
</template>
<template v-else>
{{ form.startRow }}
</template>
</span>
</div>
<div class="progress-hint">
<i class="el-icon-info"></i>
系统自动回溯检查防止遗漏
</div>
</div>
<div v-else class="no-progress">
{{ config.progressHint || '暂无同步进度' }}
</div>
</div>
</el-card>
<!-- 快速帮助 -->
<el-card class="help-card-wrapper">
<div slot="header" class="card-header">
<i class="el-icon-question"></i>
<span>配置说明</span>
</div>
<div class="help-content">
<div class="help-item">
<i class="el-icon-check"></i>
<span>文件ID从腾讯文档URL中获取</span>
</div>
<div class="help-item">
<i class="el-icon-check"></i>
<span>点击"获取工作表"自动加载</span>
</div>
<div class="help-item">
<i class="el-icon-check"></i>
<span>表头行号默认为第2行</span>
</div>
<div class="help-item">
<i class="el-icon-check"></i>
<span>数据起始行默认为第3行</span>
</div>
</div>
</el-card>
</div>
</div>
<!-- 操作日志查看对话框 -->
<tencent-doc-operation-logs
v-model="showOperationLogs"
:file-id="form.fileId"
@@ -158,8 +235,7 @@ import {
testAutoWriteConfig,
clearAutoWriteConfig,
getDocSheetList,
getTencentDocAuthUrl,
getTokenStatus
getTencentDocAuthUrl
} from '@/api/jarvis/tendoc'
import TencentDocOperationLogs from '@/views/system/jdorder/components/TencentDocOperationLogs'
@@ -176,8 +252,12 @@ export default {
accessTokenStatus: '未授权',
fileId: '',
sheetId: '',
appId: '',
apiBaseUrl: '',
isConfigured: false,
hint: ''
hint: '',
progressHint: '',
currentProgress: null
},
form: {
fileId: '',
@@ -224,8 +304,10 @@ export default {
this.config = res.data
this.form.fileId = res.data.fileId || ''
this.form.sheetId = res.data.sheetId || ''
// 确保 headerRow 和 startRow 是数字类型
this.form.headerRow = parseInt(res.data.headerRow) || 2
this.form.startRow = parseInt(res.data.startRow) || 3
console.log('配置加载成功 - headerRow:', this.form.headerRow, 'startRow:', this.form.startRow)
}
} catch (e) {
this.$message.error('加载配置失败:' + (e.message || '未知错误'))
@@ -320,12 +402,21 @@ export default {
if (res.code === 200) {
this.$message.success(`配置保存成功!表头第${this.form.headerRow}行,数据从第${this.form.startRow}行开始`)
console.log('配置保存成功 - 保存的值:', {
fileId: this.form.fileId,
sheetId: this.form.sheetId,
headerRow: this.form.headerRow,
startRow: this.form.startRow
})
// 延迟重新加载配置,确保后端已保存
setTimeout(() => {
this.loadConfig()
}, 500)
} else {
this.$message.error('保存配置失败:' + (res.msg || '未知错误'))
this.$message.error('保存失败:' + (res.msg || '未知错误'))
}
} catch (e) {
this.$message.error('保存配置失败:' + (e.message || '未知错误'))
this.$message.error('保存失败:' + (e.message || '未知错误'))
} finally {
this.saveLoading = false
}
@@ -337,64 +428,108 @@ export default {
this.testLoading = true
try {
const res = await testAutoWriteConfig()
if (res.code === 200) {
this.$message.success('配置测试通过!')
this.$alert(
'<pre style="text-align: left; max-height: 400px; overflow: auto;">' +
JSON.stringify(res.data, null, 2) +
'</pre>',
'测试成功',
{
dangerouslyUseHTMLString: true,
confirmButtonText: '确定',
type: 'success'
}
)
} else {
this.$message.error('配置测试失败:' + (res.msg || '未知错误'))
this.$message.error('测试失败:' + (res.msg || '未知错误'))
}
} catch (e) {
this.$message.error('配置测试失败:' + (e.message || '未知错误'))
this.$message.error('测试失败:' + (e.message || '未知错误'))
} finally {
this.testLoading = false
}
},
/** 清除配置 */
handleClear() {
this.$confirm('确定要清除配置吗?此操作不可恢复!', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
this.clearLoading = true
async handleClear() {
try {
await this.$confirm('确定要清除配置吗?这不会清除授权令牌。', '提示', {
type: 'warning'
})
this.clearLoading = true
const res = await clearAutoWriteConfig()
if (res.code === 200) {
this.$message.success('配置已清除')
this.form = {
fileId: '',
sheetId: '',
headerRow: 2,
startRow: 3
}
this.form.fileId = ''
this.form.sheetId = ''
this.form.startRow = 3
this.sheetList = []
this.loadConfig()
} else {
this.$message.error('清除配置失败:' + (res.msg || '未知错误'))
this.$message.error('清除失败:' + (res.msg || '未知错误'))
}
} catch (e) {
this.$message.error('清除配置失败:' + (e.message || '未知错误'))
if (e !== 'cancel') {
this.$message.error('清除失败:' + (e.message || '未知错误'))
}
} finally {
this.clearLoading = false
}
})
}
}
}
</script>
<style scoped>
.tendoc-config {
padding: 0;
/* 容器布局 */
.config-container {
display: flex;
gap: 20px;
min-height: 400px;
}
.auth-card {
margin-bottom: 20px;
.config-left {
flex: 1;
display: flex;
flex-direction: column;
gap: 15px;
}
.config-right {
width: 300px;
display: flex;
flex-direction: column;
gap: 15px;
}
/* 配置区块 */
.config-section {
background: #f5f7fa;
border-radius: 6px;
}
.section-header {
display: flex;
align-items: center;
font-size: 14px;
font-weight: 500;
color: #303133;
}
.section-header i {
margin-right: 6px;
font-size: 16px;
color: #409eff;
}
/* 授权状态 */
.auth-status {
display: flex;
align-items: center;
gap: 10px;
}
.config-hint {
@@ -402,5 +537,197 @@ export default {
color: #909399;
font-size: 12px;
}
</style>
/* 状态卡片 */
.status-card-wrapper {
padding: 0;
border: none;
box-shadow: none;
}
.status-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 8px;
padding: 20px;
color: white;
display: flex;
align-items: center;
gap: 15px;
box-shadow: 0 2px 12px rgba(102, 126, 234, 0.3);
}
.status-card.warning {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}
.status-icon {
width: 48px;
height: 48px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
flex-shrink: 0;
}
.status-icon.success {
background: rgba(103, 194, 58, 0.2);
}
.status-icon.warning {
background: rgba(230, 162, 60, 0.2);
}
.status-text {
flex: 1;
}
.status-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 5px;
}
.status-desc {
font-size: 12px;
opacity: 0.9;
line-height: 1.5;
}
/* 进度卡片 */
.progress-card-wrapper {
padding: 0;
border: none;
box-shadow: none;
}
.progress-card-wrapper >>> .el-card__body {
padding: 0;
}
.card-header {
background: #f5f7fa;
padding: 12px 15px;
font-size: 14px;
font-weight: 500;
color: #303133;
display: flex;
align-items: center;
border-bottom: 1px solid #e4e7ed;
}
.card-header i {
margin-right: 6px;
color: #409eff;
}
.progress-content {
padding: 15px;
}
.progress-detail {
display: flex;
flex-direction: column;
gap: 10px;
}
.progress-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
background: #f0f9ff;
border-radius: 4px;
border-left: 3px solid #409eff;
}
.progress-item .label {
font-size: 13px;
color: #606266;
}
.progress-item .value {
font-size: 14px;
font-weight: 500;
color: #303133;
}
.progress-hint {
font-size: 12px;
color: #909399;
padding: 8px 12px;
background: #fef0f0;
border-radius: 4px;
border-left: 3px solid #f56c6c;
display: flex;
align-items: center;
gap: 5px;
}
.no-progress {
font-size: 13px;
color: #909399;
text-align: center;
padding: 10px;
}
/* 帮助卡片 */
.help-card-wrapper {
padding: 0;
border: none;
box-shadow: none;
}
.help-card-wrapper >>> .el-card__body {
padding: 0;
}
.help-content {
padding: 15px;
display: flex;
flex-direction: column;
gap: 10px;
}
.help-item {
display: flex;
align-items: flex-start;
gap: 8px;
font-size: 13px;
color: #606266;
line-height: 1.6;
}
.help-item i {
color: #67c23a;
margin-top: 2px;
flex-shrink: 0;
}
/* Element UI 覆盖样式 */
.config-section >>> .el-form-item {
margin-bottom: 18px;
}
.config-section >>> .el-form-item__label {
font-weight: 500;
color: #606266;
}
.config-section >>> .el-input-number {
width: 100%;
}
/* 响应式调整 */
@media (max-width: 1200px) {
.config-container {
flex-direction: column;
}
.config-right {
width: 100%;
}
}
</style>