- 后端新增员工同步配置API(获取/保存/测试连接) - employee_sync_service 从数据库读取配置 - 前端系统设置页面添加"员工同步"Tab - 支持配置:数据库主机、端口、库名、用户名、密码、表名 - 保留默认配置用于向后兼容
This commit is contained in:
@@ -40,6 +40,17 @@ class DingtalkConfigResponse(BaseModel):
|
|||||||
enabled: bool = False
|
enabled: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeeSyncConfigUpdate(BaseModel):
|
||||||
|
"""员工同步配置更新请求"""
|
||||||
|
db_host: Optional[str] = Field(None, description="数据库主机")
|
||||||
|
db_port: Optional[int] = Field(None, description="数据库端口")
|
||||||
|
db_name: Optional[str] = Field(None, description="数据库名")
|
||||||
|
db_user: Optional[str] = Field(None, description="数据库用户名")
|
||||||
|
db_password: Optional[str] = Field(None, description="数据库密码")
|
||||||
|
table_name: Optional[str] = Field(None, description="员工表/视图名称")
|
||||||
|
enabled: Optional[bool] = Field(None, description="是否启用自动同步")
|
||||||
|
|
||||||
|
|
||||||
# ============================================
|
# ============================================
|
||||||
# 辅助函数
|
# 辅助函数
|
||||||
# ============================================
|
# ============================================
|
||||||
@@ -277,6 +288,163 @@ async def update_dingtalk_config(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/employee-sync", response_model=ResponseModel)
|
||||||
|
async def get_employee_sync_config(
|
||||||
|
current_user: User = Depends(get_current_active_user),
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> ResponseModel:
|
||||||
|
"""
|
||||||
|
获取员工同步配置
|
||||||
|
|
||||||
|
仅限管理员访问
|
||||||
|
"""
|
||||||
|
check_admin_permission(current_user)
|
||||||
|
|
||||||
|
tenant_id = await get_or_create_tenant_id(db)
|
||||||
|
|
||||||
|
# 获取配置
|
||||||
|
db_host = await get_system_config(db, tenant_id, 'employee_sync', 'DB_HOST')
|
||||||
|
db_port = await get_system_config(db, tenant_id, 'employee_sync', 'DB_PORT')
|
||||||
|
db_name = await get_system_config(db, tenant_id, 'employee_sync', 'DB_NAME')
|
||||||
|
db_user = await get_system_config(db, tenant_id, 'employee_sync', 'DB_USER')
|
||||||
|
db_password = await get_system_config(db, tenant_id, 'employee_sync', 'DB_PASSWORD')
|
||||||
|
table_name = await get_system_config(db, tenant_id, 'employee_sync', 'TABLE_NAME')
|
||||||
|
enabled = await get_feature_switch(db, tenant_id, 'employee_sync')
|
||||||
|
|
||||||
|
# 脱敏处理密码
|
||||||
|
password_masked = None
|
||||||
|
if db_password:
|
||||||
|
if len(db_password) > 4:
|
||||||
|
password_masked = '****' + db_password[-2:]
|
||||||
|
else:
|
||||||
|
password_masked = '****'
|
||||||
|
|
||||||
|
return ResponseModel(
|
||||||
|
message="获取成功",
|
||||||
|
data={
|
||||||
|
"db_host": db_host,
|
||||||
|
"db_port": int(db_port) if db_port else None,
|
||||||
|
"db_name": db_name,
|
||||||
|
"db_user": db_user,
|
||||||
|
"db_password_masked": password_masked,
|
||||||
|
"table_name": table_name or "v_钉钉员工表",
|
||||||
|
"enabled": enabled,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.put("/employee-sync", response_model=ResponseModel)
|
||||||
|
async def update_employee_sync_config(
|
||||||
|
config: EmployeeSyncConfigUpdate,
|
||||||
|
current_user: User = Depends(get_current_active_user),
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> ResponseModel:
|
||||||
|
"""
|
||||||
|
更新员工同步配置
|
||||||
|
|
||||||
|
仅限管理员访问
|
||||||
|
"""
|
||||||
|
check_admin_permission(current_user)
|
||||||
|
|
||||||
|
tenant_id = await get_or_create_tenant_id(db)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if config.db_host is not None:
|
||||||
|
await set_system_config(db, tenant_id, 'employee_sync', 'DB_HOST', config.db_host)
|
||||||
|
|
||||||
|
if config.db_port is not None:
|
||||||
|
await set_system_config(db, tenant_id, 'employee_sync', 'DB_PORT', str(config.db_port))
|
||||||
|
|
||||||
|
if config.db_name is not None:
|
||||||
|
await set_system_config(db, tenant_id, 'employee_sync', 'DB_NAME', config.db_name)
|
||||||
|
|
||||||
|
if config.db_user is not None:
|
||||||
|
await set_system_config(db, tenant_id, 'employee_sync', 'DB_USER', config.db_user)
|
||||||
|
|
||||||
|
if config.db_password is not None:
|
||||||
|
await set_system_config(db, tenant_id, 'employee_sync', 'DB_PASSWORD', config.db_password)
|
||||||
|
|
||||||
|
if config.table_name is not None:
|
||||||
|
await set_system_config(db, tenant_id, 'employee_sync', 'TABLE_NAME', config.table_name)
|
||||||
|
|
||||||
|
if config.enabled is not None:
|
||||||
|
await set_feature_switch(db, tenant_id, 'employee_sync', config.enabled)
|
||||||
|
|
||||||
|
await db.commit()
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"员工同步配置已更新",
|
||||||
|
user_id=current_user.id,
|
||||||
|
username=current_user.username,
|
||||||
|
)
|
||||||
|
|
||||||
|
return ResponseModel(message="配置已保存")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
await db.rollback()
|
||||||
|
logger.error(f"更新员工同步配置失败: {str(e)}")
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||||
|
detail="保存配置失败"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/employee-sync/test", response_model=ResponseModel)
|
||||||
|
async def test_employee_sync_connection(
|
||||||
|
current_user: User = Depends(get_current_active_user),
|
||||||
|
db: AsyncSession = Depends(get_db),
|
||||||
|
) -> ResponseModel:
|
||||||
|
"""
|
||||||
|
测试员工同步数据库连接
|
||||||
|
|
||||||
|
仅限管理员访问
|
||||||
|
"""
|
||||||
|
check_admin_permission(current_user)
|
||||||
|
|
||||||
|
tenant_id = await get_or_create_tenant_id(db)
|
||||||
|
|
||||||
|
# 获取配置
|
||||||
|
db_host = await get_system_config(db, tenant_id, 'employee_sync', 'DB_HOST')
|
||||||
|
db_port = await get_system_config(db, tenant_id, 'employee_sync', 'DB_PORT')
|
||||||
|
db_name = await get_system_config(db, tenant_id, 'employee_sync', 'DB_NAME')
|
||||||
|
db_user = await get_system_config(db, tenant_id, 'employee_sync', 'DB_USER')
|
||||||
|
db_password = await get_system_config(db, tenant_id, 'employee_sync', 'DB_PASSWORD')
|
||||||
|
table_name = await get_system_config(db, tenant_id, 'employee_sync', 'TABLE_NAME') or "v_钉钉员工表"
|
||||||
|
|
||||||
|
if not all([db_host, db_port, db_name, db_user, db_password]):
|
||||||
|
return ResponseModel(
|
||||||
|
code=400,
|
||||||
|
message="配置不完整,请先填写所有数据库连接信息"
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from sqlalchemy.ext.asyncio import create_async_engine
|
||||||
|
|
||||||
|
# 构建连接URL
|
||||||
|
db_url = f"mysql+aiomysql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}?charset=utf8mb4"
|
||||||
|
|
||||||
|
engine = create_async_engine(db_url, echo=False, pool_pre_ping=True)
|
||||||
|
|
||||||
|
async with engine.connect() as conn:
|
||||||
|
# 测试查询员工表
|
||||||
|
result = await conn.execute(text(f"SELECT COUNT(*) FROM {table_name}"))
|
||||||
|
count = result.scalar()
|
||||||
|
|
||||||
|
await engine.dispose()
|
||||||
|
|
||||||
|
return ResponseModel(
|
||||||
|
message=f"连接成功!员工表共有 {count} 条记录",
|
||||||
|
data={"employee_count": count}
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"测试连接失败: {str(e)}")
|
||||||
|
return ResponseModel(
|
||||||
|
code=500,
|
||||||
|
message=f"连接失败: {str(e)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/all", response_model=ResponseModel)
|
@router.get("/all", response_model=ResponseModel)
|
||||||
async def get_all_settings(
|
async def get_all_settings(
|
||||||
current_user: User = Depends(get_current_active_user),
|
current_user: User = Depends(get_current_active_user),
|
||||||
@@ -295,12 +463,20 @@ async def get_all_settings(
|
|||||||
dingtalk_enabled = await get_feature_switch(db, tenant_id, 'dingtalk_login')
|
dingtalk_enabled = await get_feature_switch(db, tenant_id, 'dingtalk_login')
|
||||||
dingtalk_corp_id = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_CORP_ID')
|
dingtalk_corp_id = await get_system_config(db, tenant_id, 'dingtalk', 'DINGTALK_CORP_ID')
|
||||||
|
|
||||||
|
# 员工同步配置状态
|
||||||
|
employee_sync_enabled = await get_feature_switch(db, tenant_id, 'employee_sync')
|
||||||
|
employee_sync_host = await get_system_config(db, tenant_id, 'employee_sync', 'DB_HOST')
|
||||||
|
|
||||||
return ResponseModel(
|
return ResponseModel(
|
||||||
message="获取成功",
|
message="获取成功",
|
||||||
data={
|
data={
|
||||||
"dingtalk": {
|
"dingtalk": {
|
||||||
"enabled": dingtalk_enabled,
|
"enabled": dingtalk_enabled,
|
||||||
"configured": bool(dingtalk_corp_id), # 是否已配置
|
"configured": bool(dingtalk_corp_id),
|
||||||
|
},
|
||||||
|
"employee_sync": {
|
||||||
|
"enabled": employee_sync_enabled,
|
||||||
|
"configured": bool(employee_sync_host),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -23,17 +23,59 @@ logger = get_logger(__name__)
|
|||||||
class EmployeeSyncService:
|
class EmployeeSyncService:
|
||||||
"""员工同步服务"""
|
"""员工同步服务"""
|
||||||
|
|
||||||
# 外部数据库连接配置
|
# 默认外部数据库连接配置(向后兼容)
|
||||||
EXTERNAL_DB_URL = "mysql+aiomysql://neuron_new:NWxGM6CQoMLKyEszXhfuLBIIo1QbeK@120.77.144.233:29613/neuron_new?charset=utf8mb4"
|
DEFAULT_DB_URL = "mysql+aiomysql://neuron_new:NWxGM6CQoMLKyEszXhfuLBIIo1QbeK@120.77.144.233:29613/neuron_new?charset=utf8mb4"
|
||||||
|
DEFAULT_TABLE_NAME = "v_钉钉员工表"
|
||||||
|
|
||||||
def __init__(self, db: AsyncSession):
|
def __init__(self, db: AsyncSession, tenant_id: int = 1):
|
||||||
self.db = db
|
self.db = db
|
||||||
|
self.tenant_id = tenant_id
|
||||||
self.external_engine = None
|
self.external_engine = None
|
||||||
|
self.table_name = self.DEFAULT_TABLE_NAME
|
||||||
|
self._db_url = None
|
||||||
|
|
||||||
|
async def _get_config_from_db(self) -> tuple:
|
||||||
|
"""从数据库获取员工同步配置"""
|
||||||
|
result = await self.db.execute(
|
||||||
|
text("""
|
||||||
|
SELECT config_key, config_value
|
||||||
|
FROM tenant_configs
|
||||||
|
WHERE tenant_id = :tenant_id AND config_group = 'employee_sync'
|
||||||
|
"""),
|
||||||
|
{"tenant_id": self.tenant_id}
|
||||||
|
)
|
||||||
|
rows = result.fetchall()
|
||||||
|
|
||||||
|
config = {}
|
||||||
|
for key, value in rows:
|
||||||
|
config[key] = value
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
async def _build_db_url(self) -> str:
|
||||||
|
"""构建数据库连接URL"""
|
||||||
|
config = await self._get_config_from_db()
|
||||||
|
|
||||||
|
db_host = config.get('DB_HOST')
|
||||||
|
db_port = config.get('DB_PORT')
|
||||||
|
db_name = config.get('DB_NAME')
|
||||||
|
db_user = config.get('DB_USER')
|
||||||
|
db_password = config.get('DB_PASSWORD')
|
||||||
|
self.table_name = config.get('TABLE_NAME') or self.DEFAULT_TABLE_NAME
|
||||||
|
|
||||||
|
# 如果配置完整,使用配置的URL
|
||||||
|
if all([db_host, db_port, db_name, db_user, db_password]):
|
||||||
|
return f"mysql+aiomysql://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}?charset=utf8mb4"
|
||||||
|
|
||||||
|
# 否则使用默认配置
|
||||||
|
logger.warning(f"租户 {self.tenant_id} 未配置员工同步数据库,使用默认配置")
|
||||||
|
return self.DEFAULT_DB_URL
|
||||||
|
|
||||||
async def __aenter__(self):
|
async def __aenter__(self):
|
||||||
"""异步上下文管理器入口"""
|
"""异步上下文管理器入口"""
|
||||||
|
self._db_url = await self._build_db_url()
|
||||||
self.external_engine = create_async_engine(
|
self.external_engine = create_async_engine(
|
||||||
self.EXTERNAL_DB_URL,
|
self._db_url,
|
||||||
echo=False,
|
echo=False,
|
||||||
pool_pre_ping=True,
|
pool_pre_ping=True,
|
||||||
pool_recycle=3600
|
pool_recycle=3600
|
||||||
@@ -52,9 +94,9 @@ class EmployeeSyncService:
|
|||||||
Returns:
|
Returns:
|
||||||
员工数据列表
|
员工数据列表
|
||||||
"""
|
"""
|
||||||
logger.info("开始从钉钉员工表获取数据...")
|
logger.info(f"开始从员工表 {self.table_name} 获取数据...")
|
||||||
|
|
||||||
query = """
|
query = f"""
|
||||||
SELECT
|
SELECT
|
||||||
员工姓名,
|
员工姓名,
|
||||||
手机号,
|
手机号,
|
||||||
@@ -67,7 +109,7 @@ class EmployeeSyncService:
|
|||||||
钉钉用户ID,
|
钉钉用户ID,
|
||||||
入职日期,
|
入职日期,
|
||||||
工作地点
|
工作地点
|
||||||
FROM v_钉钉员工表
|
FROM {self.table_name}
|
||||||
WHERE 是否在职 = 1
|
WHERE 是否在职 = 1
|
||||||
ORDER BY 员工姓名
|
ORDER BY 员工姓名
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -92,10 +92,106 @@
|
|||||||
</div>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
<!-- 其他设置(预留) -->
|
<!-- 员工同步配置 -->
|
||||||
<el-tab-pane label="其他设置" name="other" disabled>
|
<el-tab-pane label="员工同步" name="employee_sync">
|
||||||
<div class="tab-content">
|
<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>
|
</div>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
@@ -114,6 +210,12 @@ const loading = ref(false)
|
|||||||
const saving = ref(false)
|
const saving = ref(false)
|
||||||
const dingtalkFormRef = ref<FormInstance>()
|
const dingtalkFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
|
// 员工同步配置
|
||||||
|
const syncLoading = ref(false)
|
||||||
|
const syncSaving = ref(false)
|
||||||
|
const syncTesting = ref(false)
|
||||||
|
const syncFormRef = ref<FormInstance>()
|
||||||
|
|
||||||
// 钉钉配置表单
|
// 钉钉配置表单
|
||||||
const dingtalkForm = reactive({
|
const dingtalkForm = reactive({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
@@ -124,6 +226,18 @@ const dingtalkForm = reactive({
|
|||||||
corp_id: '',
|
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>({
|
const dingtalkRules = reactive<FormRules>({
|
||||||
app_key: [
|
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(() => {
|
onMounted(() => {
|
||||||
loadDingtalkConfig()
|
loadDingtalkConfig()
|
||||||
|
loadSyncConfig()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user