From d1e779bbccf21f75c6a1ce21a7093de9d522621d Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Sat, 17 Oct 2026 15:35:20 +0800 Subject: [PATCH] =?UTF-8?q?:zap:=20=E4=BC=98=E5=8C=96=E7=BB=84=E7=BB=87?= =?UTF-8?q?=E5=85=A8=E9=87=8F=E5=90=8C=E6=AD=A5=E6=B5=81=E7=A8=8B=EF=BC=8C?= =?UTF-8?q?=E9=83=A8=E9=97=A8=E6=8C=89=E5=85=AC=E5=8F=B8=E8=BD=AE=E8=AF=A2?= =?UTF-8?q?=E5=B9=B6=E5=8E=BB=E6=8E=89=E7=A1=AE=E8=AE=A4=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- src/api/system/dept.js | 4 +- src/views/system/dept.vue | 121 +++++++++++++++++++++++++++----------- 2 files changed, 90 insertions(+), 35 deletions(-) diff --git a/src/api/system/dept.js b/src/api/system/dept.js index 5a489e0..c7f22de 100644 --- a/src/api/system/dept.js +++ b/src/api/system/dept.js @@ -77,7 +77,8 @@ export const syncOaDepartment = ( size = 20, signal, incremental = false, - modifiedSince + modifiedSince, + companyOaId ) => { return request({ url: '/blade-system/dept/sync-oa-department', @@ -87,6 +88,7 @@ export const syncOaDepartment = ( size, incremental: !!incremental, modifiedSince: modifiedSince || undefined, + companyOaId: companyOaId || undefined, }, timeout: 60000, signal, diff --git a/src/views/system/dept.vue b/src/views/system/dept.vue index 9058af3..c37610a 100644 --- a/src/views/system/dept.vue +++ b/src/views/system/dept.vue @@ -153,7 +153,12 @@ />
当前阶段:{{ oaSyncStageLabel }}
- 当前阶段:{{ oaSyncStageLabel }},第 {{ oaSyncProgress.current || 0 }} / {{ oaSyncTotalPage }} 页 + 当前阶段:{{ oaSyncStageLabel }} + + ,第 {{ oaSyncProgress.current || 0 }} / {{ oaSyncTotalPage }} 页
@@ -257,6 +262,9 @@ export default { synced: 0, skipped: 0, dumpFilePath: '', + companyOaId: '', + companyIndex: 0, + companyTotal: 0, }, parentId: 0, page: { @@ -642,12 +650,18 @@ export default { } const totalPage = this.oaSyncTotalPage; const current = Number(this.oaSyncProgress.current) || 0; - const stageBase = this.oaSyncStage === 'department' ? 50 : 0; - if (totalPage <= 0) { - return stageBase; + if (this.oaSyncStage === 'department') { + const companyTotal = Math.max(1, Number(this.oaSyncProgress.companyTotal) || 1); + const companyIndex = Math.max(1, Number(this.oaSyncProgress.companyIndex) || 1); + const companyBase = ((companyIndex - 1) / companyTotal) * 50; + const pageRatio = totalPage > 0 ? Math.min(1, current / totalPage) : 0; + const companyPagePercent = (pageRatio * 50) / companyTotal; + return Math.min(99, Math.round(50 + companyBase + companyPagePercent)); } - const stagePercent = Math.min(50, Math.round((current / totalPage) * 50)); - return Math.min(99, stageBase + stagePercent); + if (totalPage <= 0) { + return 0; + } + return Math.min(49, Math.round((current / totalPage) * 50)); }, oaSyncProgressStatus() { if (this.oaSyncStatus === 'done') { @@ -661,25 +675,7 @@ export default { }, methods: { handleOaOrgFullSync() { - this.$confirm( - '全量同步将拉取 OA 公司/部门(仅保留二级公司 oaId=2、135 及其子公司与部门);已存在且 OA 更新时间一致的记录会跳过。是否清除后同步?选择“是”将保留顶级「外部组织」与集团锚点(id=1/GWWL),删除其余组织后再同步;选择“否”则直接全量同步。', - '全量同步', - { - confirmButtonText: '是', - cancelButtonText: '否', - distinguishCancelAndClose: true, - closeOnClickModal: false, - type: 'warning', - } - ) - .then(() => { - this.startOaOrgSync({ clearNonTop: true, incremental: false }); - }) - .catch(action => { - if (action === 'cancel') { - this.startOaOrgSync({ clearNonTop: false, incremental: false }); - } - }); + this.startOaOrgSync({ clearNonTop: false, incremental: false }); }, handleOaOrgIncrementalSync() { this.$confirm( @@ -714,6 +710,9 @@ export default { synced: 0, skipped: 0, dumpFilePath: '', + companyOaId: '', + companyIndex: 0, + companyTotal: 0, }; this.runOaOrgSyncPages(); }, @@ -725,6 +724,25 @@ export default { error?.name === 'AbortError' ); }, + applyOaOrgSyncPage(page, current, size) { + this.oaSyncProgress.current = page.current || current; + this.oaSyncProgress.size = page.size || size; + this.oaSyncProgress.total = page.total || 0; + this.oaSyncProgress.synced += page.syncedCount || 0; + this.oaSyncProgress.skipped += page.skippedCount || 0; + if (page.dumpFilePath) { + this.oaSyncProgress.dumpFilePath = page.dumpFilePath; + } + if (page.companyOaId != null) { + this.oaSyncProgress.companyOaId = page.companyOaId || ''; + } + if (page.companyIndex != null) { + this.oaSyncProgress.companyIndex = page.companyIndex || 0; + } + if (page.companyTotal != null) { + this.oaSyncProgress.companyTotal = page.companyTotal || 0; + } + }, async runOaOrgSyncStage(syncApi) { const size = 20; const incremental = this.oaSyncMode === 'incremental'; @@ -742,20 +760,52 @@ export default { if (!modifiedSince && page.modifiedSince) { modifiedSince = page.modifiedSince; } - this.oaSyncProgress.current = page.current || current; - this.oaSyncProgress.size = page.size || size; - this.oaSyncProgress.total = page.total || 0; - this.oaSyncProgress.synced += page.syncedCount || 0; - this.oaSyncProgress.skipped += page.skippedCount || 0; - if (page.dumpFilePath) { - this.oaSyncProgress.dumpFilePath = page.dumpFilePath; - } + this.applyOaOrgSyncPage(page, current, size); if (page.finished) { break; } current += 1; } }, + /** + * 部门阶段:公司同步完成后,按公司 oaId 轮询;当前公司部门拉完后切换下一公司并重置页码 + */ + async runOaOrgDepartmentSyncStage() { + const size = 20; + const incremental = this.oaSyncMode === 'incremental'; + let current = 1; + let modifiedSince = ''; + let companyOaId = ''; + while (!this.oaSyncCancelled) { + const res = await syncOaDepartment( + current, + size, + this.oaSyncController?.signal, + incremental, + modifiedSince, + companyOaId + ); + const page = res?.data?.data || {}; + if (!modifiedSince && page.modifiedSince) { + modifiedSince = page.modifiedSince; + } + if (page.companyOaId) { + companyOaId = page.companyOaId; + } + this.applyOaOrgSyncPage(page, current, size); + if (page.finished) { + break; + } + if (page.companyFinished && page.nextCompanyOaId) { + companyOaId = page.nextCompanyOaId; + current = 1; + this.oaSyncProgress.current = 0; + this.oaSyncProgress.total = 0; + continue; + } + current += 1; + } + }, async runOaOrgSyncPages() { try { if (this.oaSyncClearNonTop) { @@ -775,7 +825,10 @@ export default { this.oaSyncStage = 'department'; this.oaSyncProgress.current = 0; this.oaSyncProgress.total = 0; - await this.runOaOrgSyncStage(syncOaDepartment); + this.oaSyncProgress.companyOaId = ''; + this.oaSyncProgress.companyIndex = 0; + this.oaSyncProgress.companyTotal = 0; + await this.runOaOrgDepartmentSyncStage(); if (this.oaSyncCancelled) { this.oaSyncStatus = 'cancelled'; return;