- 移除员工同步独立的 API 凭证配置 - 复用 dingtalk 配置组的 CorpId、AppKey、AppSecret - 简化前端界面,只保留开关和测试连接
This commit is contained in:
@@ -41,10 +41,7 @@ class DingtalkConfigResponse(BaseModel):
|
||||
|
||||
|
||||
class EmployeeSyncConfigUpdate(BaseModel):
|
||||
"""员工同步配置更新请求(钉钉 API 方式)"""
|
||||
corp_id: Optional[str] = Field(None, description="钉钉企业 CorpId")
|
||||
client_id: Optional[str] = Field(None, description="应用 ClientId (AppKey)")
|
||||
client_secret: Optional[str] = Field(None, description="应用 ClientSecret (AppSecret)")
|
||||
"""员工同步配置更新请求(复用钉钉免密登录配置)"""
|
||||
enabled: Optional[bool] = Field(None, description="是否启用自动同步")
|
||||
|
||||
|
||||
@@ -291,7 +288,7 @@ async def get_employee_sync_config(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> ResponseModel:
|
||||
"""
|
||||
获取员工同步配置(钉钉 API 方式)
|
||||
获取员工同步配置(复用钉钉免密登录配置)
|
||||
|
||||
仅限管理员访问
|
||||
"""
|
||||
@@ -299,31 +296,22 @@ async def get_employee_sync_config(
|
||||
|
||||
tenant_id = await get_or_create_tenant_id(db)
|
||||
|
||||
# 从数据库获取钉钉 API 配置
|
||||
corp_id = await get_system_config(db, tenant_id, 'employee_sync', 'CORP_ID')
|
||||
client_id = await get_system_config(db, tenant_id, 'employee_sync', 'CLIENT_ID')
|
||||
client_secret = await get_system_config(db, tenant_id, 'employee_sync', 'CLIENT_SECRET')
|
||||
# 从 dingtalk 配置组读取(与免密登录共用)
|
||||
corp_id = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_CORP_ID')
|
||||
app_key = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_APP_KEY')
|
||||
app_secret = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_APP_SECRET')
|
||||
enabled = await get_feature_switch(db, tenant_id, 'employee_sync')
|
||||
dingtalk_enabled = await get_feature_switch(db, tenant_id, 'dingtalk_login')
|
||||
|
||||
# 脱敏处理 client_secret
|
||||
client_secret_masked = None
|
||||
if client_secret:
|
||||
if len(client_secret) > 8:
|
||||
client_secret_masked = client_secret[:4] + '****' + client_secret[-4:]
|
||||
else:
|
||||
client_secret_masked = '****'
|
||||
|
||||
# 检查配置是否完整
|
||||
configured = bool(corp_id and client_id and client_secret)
|
||||
# 检查钉钉配置是否完整
|
||||
configured = bool(corp_id and app_key and app_secret)
|
||||
|
||||
return ResponseModel(
|
||||
message="获取成功",
|
||||
data={
|
||||
"corp_id": corp_id,
|
||||
"client_id": client_id,
|
||||
"client_secret_masked": client_secret_masked,
|
||||
"enabled": enabled,
|
||||
"configured": configured,
|
||||
"dingtalk_enabled": dingtalk_enabled, # 免密登录是否启用
|
||||
}
|
||||
)
|
||||
|
||||
@@ -335,7 +323,7 @@ async def update_employee_sync_config(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> ResponseModel:
|
||||
"""
|
||||
更新员工同步配置(钉钉 API 方式)
|
||||
更新员工同步配置(仅开关,API 凭证复用钉钉免密登录)
|
||||
|
||||
仅限管理员访问
|
||||
"""
|
||||
@@ -344,15 +332,6 @@ async def update_employee_sync_config(
|
||||
tenant_id = await get_or_create_tenant_id(db)
|
||||
|
||||
try:
|
||||
if config.corp_id is not None:
|
||||
await set_system_config(db, tenant_id, 'employee_sync', 'CORP_ID', config.corp_id)
|
||||
|
||||
if config.client_id is not None:
|
||||
await set_system_config(db, tenant_id, 'employee_sync', 'CLIENT_ID', config.client_id)
|
||||
|
||||
if config.client_secret is not None:
|
||||
await set_system_config(db, tenant_id, 'employee_sync', 'CLIENT_SECRET', config.client_secret)
|
||||
|
||||
if config.enabled is not None:
|
||||
await set_feature_switch(db, tenant_id, 'employee_sync', config.enabled)
|
||||
|
||||
@@ -381,7 +360,7 @@ async def test_employee_sync_connection(
|
||||
db: AsyncSession = Depends(get_db),
|
||||
) -> ResponseModel:
|
||||
"""
|
||||
测试钉钉 API 连接
|
||||
测试钉钉 API 连接(复用免密登录配置)
|
||||
|
||||
仅限管理员访问
|
||||
"""
|
||||
@@ -389,15 +368,15 @@ async def test_employee_sync_connection(
|
||||
|
||||
tenant_id = await get_or_create_tenant_id(db)
|
||||
|
||||
# 获取钉钉配置
|
||||
corp_id = await get_system_config(db, tenant_id, 'employee_sync', 'CORP_ID')
|
||||
client_id = await get_system_config(db, tenant_id, 'employee_sync', 'CLIENT_ID')
|
||||
client_secret = await get_system_config(db, tenant_id, 'employee_sync', 'CLIENT_SECRET')
|
||||
# 从 dingtalk 配置组读取(与免密登录共用)
|
||||
corp_id = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_CORP_ID')
|
||||
client_id = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_APP_KEY')
|
||||
client_secret = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_APP_SECRET')
|
||||
|
||||
if not all([corp_id, client_id, client_secret]):
|
||||
return ResponseModel(
|
||||
code=400,
|
||||
message="钉钉 API 配置不完整,请先填写 CorpId、ClientId、ClientSecret"
|
||||
message="请先在「钉钉免密登录」页签配置 CorpId、AppKey、AppSecret"
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -29,17 +29,18 @@ class EmployeeSyncService:
|
||||
self._dingtalk_config = None
|
||||
|
||||
async def _get_dingtalk_config(self) -> Dict[str, str]:
|
||||
"""从数据库获取钉钉 API 配置"""
|
||||
"""从数据库获取钉钉 API 配置(复用免密登录配置)"""
|
||||
if self._dingtalk_config:
|
||||
return self._dingtalk_config
|
||||
|
||||
try:
|
||||
# 从 dingtalk 配置组读取(与免密登录共用)
|
||||
result = await self.db.execute(
|
||||
text("""
|
||||
SELECT config_key, config_value
|
||||
FROM tenant_configs
|
||||
WHERE tenant_id = :tenant_id
|
||||
AND config_group = 'employee_sync'
|
||||
AND config_group = 'dingtalk'
|
||||
"""),
|
||||
{"tenant_id": self.tenant_id}
|
||||
)
|
||||
@@ -47,7 +48,13 @@ class EmployeeSyncService:
|
||||
|
||||
config = {}
|
||||
for key, value in rows:
|
||||
config[key] = value
|
||||
# 转换 key 名称以匹配 DingTalkService 需要的格式
|
||||
if key == 'DINGTALK_CORP_ID':
|
||||
config['CORP_ID'] = value
|
||||
elif key == 'DINGTALK_APP_KEY':
|
||||
config['CLIENT_ID'] = value
|
||||
elif key == 'DINGTALK_APP_SECRET':
|
||||
config['CLIENT_SECRET'] = value
|
||||
|
||||
self._dingtalk_config = config
|
||||
return config
|
||||
|
||||
@@ -105,13 +105,13 @@
|
||||
<template #default>
|
||||
<p>通过钉钉开放 API 自动同步组织架构和员工信息(姓名、手机号、部门、岗位等)。</p>
|
||||
<p style="margin-top: 8px;">同步的员工将自动创建系统账号,初始密码为 123456。</p>
|
||||
<p style="margin-top: 8px; color: #E6A23C;">注意:员工同步复用「钉钉免密登录」的 API 凭证配置。</p>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
||||
<el-form
|
||||
ref="syncFormRef"
|
||||
:model="syncForm"
|
||||
:rules="syncRules"
|
||||
label-width="140px"
|
||||
v-loading="syncLoading"
|
||||
>
|
||||
@@ -124,50 +124,20 @@
|
||||
<span class="form-tip">启用后将每日自动从钉钉同步员工数据</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">钉钉应用配置</el-divider>
|
||||
|
||||
<el-form-item label="企业 CorpId" prop="corp_id">
|
||||
<el-input
|
||||
v-model="syncForm.corp_id"
|
||||
placeholder="请输入钉钉企业 CorpId"
|
||||
style="width: 350px;"
|
||||
/>
|
||||
<span class="form-tip">在钉钉管理后台-设置中查看</span>
|
||||
</el-form-item>
|
||||
|
||||
<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-form-item label="钉钉 API 状态">
|
||||
<el-tag :type="syncForm.configured ? 'success' : 'warning'">
|
||||
{{ syncForm.configured ? '已配置' : '未配置' }}
|
||||
</el-tag>
|
||||
<span class="form-tip" v-if="!syncForm.configured">
|
||||
请先在「钉钉免密登录」页签配置 API 凭证
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="saveSyncConfig" :loading="syncSaving">
|
||||
保存配置
|
||||
</el-button>
|
||||
<el-button @click="testSyncConnection" :loading="syncTesting">
|
||||
<el-button @click="testSyncConnection" :loading="syncTesting" :disabled="!syncForm.configured">
|
||||
测试连接
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
@@ -206,14 +176,10 @@ const dingtalkForm = reactive({
|
||||
corp_id: '',
|
||||
})
|
||||
|
||||
// 员工同步配置表单(钉钉 API 方式)
|
||||
// 员工同步配置表单(复用钉钉免密登录配置)
|
||||
const syncForm = reactive({
|
||||
enabled: false,
|
||||
corp_id: '',
|
||||
client_id: '',
|
||||
client_secret: '',
|
||||
client_secret_masked: '',
|
||||
configured: false,
|
||||
configured: false, // 钉钉 API 是否已配置
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
@@ -229,14 +195,7 @@ const dingtalkRules = reactive<FormRules>({
|
||||
]
|
||||
})
|
||||
|
||||
const syncRules = reactive<FormRules>({
|
||||
corp_id: [
|
||||
{ required: false, message: '请输入企业 CorpId', trigger: 'blur' }
|
||||
],
|
||||
client_id: [
|
||||
{ required: false, message: '请输入应用 ClientId', trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
const syncRules = reactive<FormRules>({})
|
||||
|
||||
/**
|
||||
* 加载钉钉配置
|
||||
@@ -308,7 +267,7 @@ const saveDingtalkConfig = async () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载员工同步配置(钉钉 API 方式)
|
||||
* 加载员工同步配置(复用钉钉免密登录配置)
|
||||
*/
|
||||
const loadSyncConfig = async () => {
|
||||
syncLoading.value = true
|
||||
@@ -316,10 +275,6 @@ 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.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) {
|
||||
@@ -330,23 +285,14 @@ const loadSyncConfig = async () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存员工同步配置(钉钉 API 方式)
|
||||
* 保存员工同步配置(仅开关)
|
||||
*/
|
||||
const saveSyncConfig = async () => {
|
||||
syncSaving.value = true
|
||||
try {
|
||||
const updateData: any = {
|
||||
const response = await request.put('/api/v1/settings/employee-sync', {
|
||||
enabled: syncForm.enabled,
|
||||
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)
|
||||
})
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('配置保存成功')
|
||||
await loadSyncConfig()
|
||||
|
||||
Reference in New Issue
Block a user