调整 用户
This commit is contained in:
+218
-15
@@ -340,6 +340,45 @@
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
v-model="oaSyncVisible"
|
||||
width="480px"
|
||||
append-to-body
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="!oaSyncRunning"
|
||||
:show-close="!oaSyncRunning"
|
||||
class="oa-sync-dialog"
|
||||
@close="closeOaSyncDialog"
|
||||
>
|
||||
<template #header>
|
||||
<span class="dialog-title">{{ oaSyncDialogTitle }}</span>
|
||||
</template>
|
||||
<div class="oa-sync-body">
|
||||
<el-progress
|
||||
:percentage="oaSyncPercent"
|
||||
:status="oaSyncProgressStatus"
|
||||
:stroke-width="12"
|
||||
/>
|
||||
<div class="oa-sync-meta">当前进度:第 {{ oaSyncProgress.current || 0 }} / {{ oaSyncTotalPage }} 页</div>
|
||||
<div class="oa-sync-stats">
|
||||
<div class="oa-sync-stat">
|
||||
<span class="oa-sync-stat__label">同步成功</span>
|
||||
<span class="oa-sync-stat__value oa-sync-stat__value--success">{{ oaSyncProgress.synced }}</span>
|
||||
</div>
|
||||
<div class="oa-sync-stat">
|
||||
<span class="oa-sync-stat__label">跳过</span>
|
||||
<span class="oa-sync-stat__value oa-sync-stat__value--skip">{{ oaSyncProgress.skipped }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button v-if="oaSyncRunning" @click="cancelOaSync">取消</el-button>
|
||||
<el-button v-else type="primary" @click="closeOaSyncDialog">关闭</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 认证日志组件 -->
|
||||
<auth-log ref="authLog" />
|
||||
<!-- 认证锁定配置组件 -->
|
||||
@@ -403,6 +442,18 @@ export default {
|
||||
query: {},
|
||||
loading: true,
|
||||
iamSyncLoading: false,
|
||||
oaSyncVisible: false,
|
||||
oaSyncRunning: false,
|
||||
oaSyncCancelled: false,
|
||||
oaSyncStatus: 'running',
|
||||
oaSyncController: null,
|
||||
oaSyncProgress: {
|
||||
current: 0,
|
||||
size: 50,
|
||||
total: 0,
|
||||
synced: 0,
|
||||
skipped: 0,
|
||||
},
|
||||
page: {
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
@@ -453,6 +504,46 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['userInfo', 'permission']),
|
||||
oaSyncDialogTitle() {
|
||||
if (this.oaSyncStatus === 'done') {
|
||||
return '同步完成';
|
||||
}
|
||||
if (this.oaSyncStatus === 'cancelled') {
|
||||
return '已取消同步';
|
||||
}
|
||||
if (this.oaSyncStatus === 'error') {
|
||||
return '同步失败';
|
||||
}
|
||||
return '同步人员';
|
||||
},
|
||||
oaSyncTotalPage() {
|
||||
const total = Number(this.oaSyncProgress.total) || 0;
|
||||
const size = Number(this.oaSyncProgress.size) || 50;
|
||||
if (total <= 0) {
|
||||
return this.oaSyncProgress.current || 0;
|
||||
}
|
||||
return Math.max(1, Math.ceil(total / size));
|
||||
},
|
||||
oaSyncPercent() {
|
||||
if (this.oaSyncStatus === 'done') {
|
||||
return 100;
|
||||
}
|
||||
const totalPage = this.oaSyncTotalPage;
|
||||
const current = Number(this.oaSyncProgress.current) || 0;
|
||||
if (totalPage <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(100, Math.round((current / totalPage) * 100));
|
||||
},
|
||||
oaSyncProgressStatus() {
|
||||
if (this.oaSyncStatus === 'done') {
|
||||
return 'success';
|
||||
}
|
||||
if (this.oaSyncStatus === 'error') {
|
||||
return 'exception';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
// 所属组织级联配置:checkStrictly 为 false 时只能选择最后一级(叶子节点)
|
||||
deptCascaderProps() {
|
||||
return {
|
||||
@@ -564,23 +655,87 @@ export default {
|
||||
}
|
||||
},
|
||||
handleIamSync() {
|
||||
this.$confirm('确定从IAM同步人员信息?', '提示', {
|
||||
this.$confirm('确定从OA同步人员及组织信息?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
})
|
||||
.then(() => {
|
||||
this.iamSyncLoading = true;
|
||||
return syncIamAccounts();
|
||||
})
|
||||
.then(res => {
|
||||
const count = res?.data?.data ?? 0;
|
||||
this.$message.success(`IAM人员同步完成,共处理${count}条`);
|
||||
}).then(() => {
|
||||
this.startOaSync();
|
||||
});
|
||||
},
|
||||
startOaSync() {
|
||||
this.iamSyncLoading = true;
|
||||
this.oaSyncVisible = true;
|
||||
this.oaSyncRunning = true;
|
||||
this.oaSyncCancelled = false;
|
||||
this.oaSyncStatus = 'running';
|
||||
this.oaSyncController = new AbortController();
|
||||
this.oaSyncProgress = {
|
||||
current: 0,
|
||||
size: 50,
|
||||
total: 0,
|
||||
synced: 0,
|
||||
skipped: 0,
|
||||
};
|
||||
this.runOaSyncPages();
|
||||
},
|
||||
isOaSyncCanceledError(error) {
|
||||
return (
|
||||
this.oaSyncCancelled ||
|
||||
error?.code === 'ERR_CANCELED' ||
|
||||
error?.name === 'CanceledError' ||
|
||||
error?.name === 'AbortError'
|
||||
);
|
||||
},
|
||||
async runOaSyncPages() {
|
||||
const size = 50;
|
||||
let current = 1;
|
||||
try {
|
||||
while (!this.oaSyncCancelled) {
|
||||
const res = await syncIamAccounts(current, size, this.oaSyncController?.signal);
|
||||
const page = res?.data?.data || {};
|
||||
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.finished) {
|
||||
this.oaSyncStatus = 'done';
|
||||
break;
|
||||
}
|
||||
current += 1;
|
||||
}
|
||||
if (this.oaSyncCancelled && this.oaSyncStatus === 'running') {
|
||||
this.oaSyncStatus = 'cancelled';
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.isOaSyncCanceledError(error)) {
|
||||
this.oaSyncStatus = 'cancelled';
|
||||
} else {
|
||||
this.oaSyncStatus = 'error';
|
||||
this.$message.error(error?.message || 'OA人员同步失败');
|
||||
}
|
||||
} finally {
|
||||
this.oaSyncRunning = false;
|
||||
this.iamSyncLoading = false;
|
||||
if (this.oaSyncStatus === 'done' || this.oaSyncStatus === 'cancelled') {
|
||||
this.onLoad(this.page, this.query);
|
||||
})
|
||||
.finally(() => {
|
||||
this.iamSyncLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
cancelOaSync() {
|
||||
if (!this.oaSyncRunning) {
|
||||
return;
|
||||
}
|
||||
this.oaSyncCancelled = true;
|
||||
this.oaSyncController?.abort();
|
||||
},
|
||||
closeOaSyncDialog() {
|
||||
if (this.oaSyncRunning) {
|
||||
this.cancelOaSync();
|
||||
return;
|
||||
}
|
||||
this.oaSyncVisible = false;
|
||||
},
|
||||
handleSetLeader(row) {
|
||||
const tip = row.isLeader === 1 ? '确定取消用户的主管职务?' : '确定设置用户为主管职务?';
|
||||
@@ -1150,14 +1305,16 @@ export default {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.user-edit-dialog .dialog-title {
|
||||
.user-edit-dialog .dialog-title,
|
||||
.oa-sync-dialog .dialog-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.user-edit-dialog .dialog-title::before {
|
||||
.user-edit-dialog .dialog-title::before,
|
||||
.oa-sync-dialog .dialog-title::before {
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
margin-right: 8px;
|
||||
@@ -1165,6 +1322,52 @@ export default {
|
||||
content: '';
|
||||
}
|
||||
|
||||
.oa-sync-body {
|
||||
padding: 8px 4px 0;
|
||||
}
|
||||
|
||||
.oa-sync-meta {
|
||||
margin-top: 12px;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.oa-sync-stats {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.oa-sync-stat {
|
||||
flex: 1;
|
||||
padding: 12px 16px;
|
||||
background: #fafafa;
|
||||
border: 1px solid #eff1f7;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.oa-sync-stat__label {
|
||||
display: block;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.oa-sync-stat__value {
|
||||
display: block;
|
||||
margin-top: 6px;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.oa-sync-stat__value--success {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.oa-sync-stat__value--skip {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.user-edit-dialog .el-form-item {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user