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 }},第 {{ oaSyncProgress.current || 0 }} / {{ oaSyncTotalPage }} 页
+ 当前阶段:{{ oaSyncStageLabel }}
+
+ ,公司 {{ oaSyncProgress.companyIndex || 0 }} / {{ oaSyncProgress.companyTotal }}
+ (oaId={{ oaSyncProgress.companyOaId }})
+
+ ,第 {{ 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;