feat: 员工同步改为钉钉开放API方式
All checks were successful
continuous-integration/drone/push Build is passing

- 新增 dingtalk_service.py 调用钉钉开放API
- 支持获取 Access Token、部门列表、员工列表
- employee_sync_service 改为从钉钉API获取员工
- 前端配置界面支持配置 CorpId、ClientId、ClientSecret
- 移除外部数据库表依赖
This commit is contained in:
yuliang_guo
2026-01-31 17:25:44 +08:00
parent cabc3c3442
commit 7be1ac1787
4 changed files with 441 additions and 145 deletions

View File

@@ -103,7 +103,7 @@
style="margin-bottom: 20px;"
>
<template #default>
<p>系统将从钉钉员工数据源自动同步员工信息姓名手机号部门岗位等</p>
<p>通过钉钉开放 API 自动同步组织架构和员工信息姓名手机号部门岗位等</p>
<p style="margin-top: 8px;">同步的员工将自动创建系统账号初始密码为 123456</p>
</template>
</el-alert>
@@ -111,6 +111,7 @@
<el-form
ref="syncFormRef"
:model="syncForm"
:rules="syncRules"
label-width="140px"
v-loading="syncLoading"
>
@@ -120,30 +121,53 @@
active-text="已启用"
inactive-text="已禁用"
/>
<span class="form-tip">启用后将每日自动同步员工数据</span>
<span class="form-tip">启用后将每日自动从钉钉同步员工数据</span>
</el-form-item>
<el-form-item label="员工表名" prop="table_name">
<el-divider content-position="left">钉钉应用配置</el-divider>
<el-form-item label="企业 CorpId" prop="corp_id">
<el-input
v-model="syncForm.table_name"
placeholder="v_钉钉员工表"
style="width: 300px;"
v-model="syncForm.corp_id"
placeholder="请输入钉钉企业 CorpId"
style="width: 350px;"
/>
<span class="form-tip">视图需包含员工姓名手机号所属部门职位钉钉用户ID等字段</span>
<span class="form-tip">在钉钉管理后台-设置中查看</span>
</el-form-item>
<el-form-item label="数据源状态">
<el-form-item label="应用 ClientId" prop="client_id">
<el-input
v-model="syncForm.client_id"
placeholder="请输入应用 ClientId (AppKey)"
style="width: 350px;"
/>
<span class="form-tip">钉钉开发者后台-应用凭证</span>
</el-form-item>
<el-form-item label="应用 ClientSecret" prop="client_secret">
<el-input
v-model="syncForm.client_secret"
type="password"
show-password
:placeholder="syncForm.client_secret_masked || '请输入应用 ClientSecret'"
style="width: 350px;"
/>
<span class="form-tip" v-if="syncForm.client_secret_masked && !syncForm.client_secret">
当前值: {{ syncForm.client_secret_masked }}
</span>
</el-form-item>
<el-form-item label="配置状态">
<el-tag :type="syncForm.configured ? 'success' : 'warning'">
{{ syncForm.configured ? '已配置' : '未配置' }}
</el-tag>
<span class="form-tip">数据源由系统管理员在后台配置</span>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="saveSyncConfig" :loading="syncSaving">
保存配置
</el-button>
<el-button @click="testSyncConnection" :loading="syncTesting" :disabled="!syncForm.configured">
<el-button @click="testSyncConnection" :loading="syncTesting">
测试连接
</el-button>
</el-form-item>
@@ -182,11 +206,14 @@ const dingtalkForm = reactive({
corp_id: '',
})
// 员工同步配置表单
// 员工同步配置表单(钉钉 API 方式)
const syncForm = reactive({
enabled: false,
table_name: 'v_钉钉员工表',
configured: false, // 数据源是否已配置
corp_id: '',
client_id: '',
client_secret: '',
client_secret_masked: '',
configured: false,
})
// 表单验证规则
@@ -202,7 +229,14 @@ const dingtalkRules = reactive<FormRules>({
]
})
const syncRules = reactive<FormRules>({})
const syncRules = reactive<FormRules>({
corp_id: [
{ required: false, message: '请输入企业 CorpId', trigger: 'blur' }
],
client_id: [
{ required: false, message: '请输入应用 ClientId', trigger: 'blur' }
]
})
/**
* 加载钉钉配置
@@ -274,7 +308,7 @@ const saveDingtalkConfig = async () => {
}
/**
* 加载员工同步配置
* 加载员工同步配置(钉钉 API 方式)
*/
const loadSyncConfig = async () => {
syncLoading.value = true
@@ -282,7 +316,10 @@ const loadSyncConfig = async () => {
const response = await request.get('/api/v1/settings/employee-sync')
if (response.code === 200 && response.data) {
syncForm.enabled = response.data.enabled || false
syncForm.table_name = response.data.table_name || 'v_钉钉员工表'
syncForm.corp_id = response.data.corp_id || ''
syncForm.client_id = response.data.client_id || ''
syncForm.client_secret = ''
syncForm.client_secret_masked = response.data.client_secret_masked || ''
syncForm.configured = response.data.configured || false
}
} catch (error: any) {
@@ -293,14 +330,20 @@ const loadSyncConfig = async () => {
}
/**
* 保存员工同步配置
* 保存员工同步配置(钉钉 API 方式)
*/
const saveSyncConfig = async () => {
syncSaving.value = true
try {
const updateData = {
const updateData: any = {
enabled: syncForm.enabled,
table_name: syncForm.table_name,
corp_id: syncForm.corp_id,
client_id: syncForm.client_id,
}
// 只有输入了新密码才传递
if (syncForm.client_secret) {
updateData.client_secret = syncForm.client_secret
}
const response = await request.put('/api/v1/settings/employee-sync', updateData)