- 后端新增员工同步配置API(获取/保存/测试连接) - employee_sync_service 从数据库读取配置 - 前端系统设置页面添加"员工同步"Tab - 支持配置:数据库主机、端口、库名、用户名、密码、表名 - 保留默认配置用于向后兼容
This commit is contained in:
@@ -92,10 +92,106 @@
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 其他设置(预留) -->
|
||||
<el-tab-pane label="其他设置" name="other" disabled>
|
||||
<!-- 员工同步配置 -->
|
||||
<el-tab-pane label="员工同步" name="employee_sync">
|
||||
<div class="tab-content">
|
||||
<el-empty description="暂无其他设置项" />
|
||||
<el-alert
|
||||
title="员工同步配置说明"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
style="margin-bottom: 20px;"
|
||||
>
|
||||
<template #default>
|
||||
<p>配置外部数据源,系统将自动同步员工信息(姓名、手机号、部门、岗位等)。</p>
|
||||
<p style="margin-top: 8px;">同步的员工将自动创建系统账号,初始密码为 123456。</p>
|
||||
</template>
|
||||
</el-alert>
|
||||
|
||||
<el-form
|
||||
ref="syncFormRef"
|
||||
:model="syncForm"
|
||||
:rules="syncRules"
|
||||
label-width="140px"
|
||||
v-loading="syncLoading"
|
||||
>
|
||||
<el-form-item label="启用自动同步">
|
||||
<el-switch
|
||||
v-model="syncForm.enabled"
|
||||
active-text="已启用"
|
||||
inactive-text="已禁用"
|
||||
/>
|
||||
<span class="form-tip">启用后将每日自动同步员工数据</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-divider content-position="left">数据库连接配置</el-divider>
|
||||
|
||||
<el-form-item label="数据库主机" prop="db_host">
|
||||
<el-input
|
||||
v-model="syncForm.db_host"
|
||||
placeholder="如:192.168.1.100"
|
||||
style="width: 300px;"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="端口" prop="db_port">
|
||||
<el-input-number
|
||||
v-model="syncForm.db_port"
|
||||
:min="1"
|
||||
:max="65535"
|
||||
placeholder="3306"
|
||||
style="width: 150px;"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="数据库名" prop="db_name">
|
||||
<el-input
|
||||
v-model="syncForm.db_name"
|
||||
placeholder="请输入数据库名称"
|
||||
style="width: 300px;"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户名" prop="db_user">
|
||||
<el-input
|
||||
v-model="syncForm.db_user"
|
||||
placeholder="请输入数据库用户名"
|
||||
style="width: 300px;"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="密码" prop="db_password">
|
||||
<el-input
|
||||
v-model="syncForm.db_password"
|
||||
type="password"
|
||||
show-password
|
||||
:placeholder="syncForm.db_password_masked || '请输入数据库密码'"
|
||||
style="width: 300px;"
|
||||
/>
|
||||
<span class="form-tip" v-if="syncForm.db_password_masked && !syncForm.db_password">
|
||||
当前值: {{ syncForm.db_password_masked }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="员工表名" prop="table_name">
|
||||
<el-input
|
||||
v-model="syncForm.table_name"
|
||||
placeholder="v_钉钉员工表"
|
||||
style="width: 300px;"
|
||||
/>
|
||||
<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">
|
||||
测试连接
|
||||
</el-button>
|
||||
<el-button @click="loadSyncConfig">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
@@ -114,6 +210,12 @@ const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const dingtalkFormRef = ref<FormInstance>()
|
||||
|
||||
// 员工同步配置
|
||||
const syncLoading = ref(false)
|
||||
const syncSaving = ref(false)
|
||||
const syncTesting = ref(false)
|
||||
const syncFormRef = ref<FormInstance>()
|
||||
|
||||
// 钉钉配置表单
|
||||
const dingtalkForm = reactive({
|
||||
enabled: false,
|
||||
@@ -124,6 +226,18 @@ const dingtalkForm = reactive({
|
||||
corp_id: '',
|
||||
})
|
||||
|
||||
// 员工同步配置表单
|
||||
const syncForm = reactive({
|
||||
enabled: false,
|
||||
db_host: '',
|
||||
db_port: 3306,
|
||||
db_name: '',
|
||||
db_user: '',
|
||||
db_password: '',
|
||||
db_password_masked: '',
|
||||
table_name: 'v_钉钉员工表',
|
||||
})
|
||||
|
||||
// 表单验证规则
|
||||
const dingtalkRules = reactive<FormRules>({
|
||||
app_key: [
|
||||
@@ -137,6 +251,18 @@ const dingtalkRules = reactive<FormRules>({
|
||||
]
|
||||
})
|
||||
|
||||
const syncRules = reactive<FormRules>({
|
||||
db_host: [
|
||||
{ required: false, message: '请输入数据库主机', trigger: 'blur' }
|
||||
],
|
||||
db_name: [
|
||||
{ required: false, message: '请输入数据库名', trigger: 'blur' }
|
||||
],
|
||||
db_user: [
|
||||
{ required: false, message: '请输入用户名', trigger: 'blur' }
|
||||
]
|
||||
})
|
||||
|
||||
/**
|
||||
* 加载钉钉配置
|
||||
*/
|
||||
@@ -206,9 +332,89 @@ const saveDingtalkConfig = async () => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载员工同步配置
|
||||
*/
|
||||
const loadSyncConfig = async () => {
|
||||
syncLoading.value = true
|
||||
try {
|
||||
const response = await request.get('/api/v1/settings/employee-sync')
|
||||
if (response.code === 200 && response.data) {
|
||||
syncForm.enabled = response.data.enabled || false
|
||||
syncForm.db_host = response.data.db_host || ''
|
||||
syncForm.db_port = response.data.db_port || 3306
|
||||
syncForm.db_name = response.data.db_name || ''
|
||||
syncForm.db_user = response.data.db_user || ''
|
||||
syncForm.db_password = ''
|
||||
syncForm.db_password_masked = response.data.db_password_masked || ''
|
||||
syncForm.table_name = response.data.table_name || 'v_钉钉员工表'
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('加载员工同步配置失败:', error)
|
||||
// 不显示错误提示,可能是表不存在
|
||||
} finally {
|
||||
syncLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存员工同步配置
|
||||
*/
|
||||
const saveSyncConfig = async () => {
|
||||
syncSaving.value = true
|
||||
try {
|
||||
const updateData: any = {
|
||||
enabled: syncForm.enabled,
|
||||
db_host: syncForm.db_host,
|
||||
db_port: syncForm.db_port,
|
||||
db_name: syncForm.db_name,
|
||||
db_user: syncForm.db_user,
|
||||
table_name: syncForm.table_name,
|
||||
}
|
||||
|
||||
if (syncForm.db_password) {
|
||||
updateData.db_password = syncForm.db_password
|
||||
}
|
||||
|
||||
const response = await request.put('/api/v1/settings/employee-sync', updateData)
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('配置保存成功')
|
||||
await loadSyncConfig()
|
||||
} else {
|
||||
ElMessage.error(response.message || '保存失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('保存员工同步配置失败:', error)
|
||||
ElMessage.error('保存配置失败')
|
||||
} finally {
|
||||
syncSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试员工同步数据库连接
|
||||
*/
|
||||
const testSyncConnection = async () => {
|
||||
syncTesting.value = true
|
||||
try {
|
||||
const response = await request.post('/api/v1/settings/employee-sync/test')
|
||||
if (response.code === 200) {
|
||||
ElMessage.success(response.message || '连接成功')
|
||||
} else {
|
||||
ElMessage.error(response.message || '连接失败')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('测试连接失败:', error)
|
||||
ElMessage.error('测试连接失败')
|
||||
} finally {
|
||||
syncTesting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载时获取配置
|
||||
onMounted(() => {
|
||||
loadDingtalkConfig()
|
||||
loadSyncConfig()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user