326 lines
11 KiB
Python
326 lines
11 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
员工管理接口
|
||
"""
|
||
|
||
from flask import Blueprint, request, jsonify
|
||
import logging
|
||
from datetime import datetime
|
||
from auth_utils import require_auth, require_role, AuthUtils
|
||
from database_config import get_db_manager, format_datetime_fields
|
||
from log_utils import log_create, log_update, log_delete, log_error, log_operation
|
||
|
||
logger = logging.getLogger('article_server')
|
||
|
||
# 创建蓝图
|
||
employee_bp = Blueprint('employee', __name__, url_prefix='/api/employees')
|
||
|
||
@employee_bp.route('/list', methods=['GET'])
|
||
@require_auth
|
||
def get_employees_list():
|
||
"""获取员工列表"""
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 获取查询参数
|
||
page = int(request.args.get('page', 1))
|
||
page_size = int(request.args.get('pageSize', 20))
|
||
keyword = request.args.get('keyword', '').strip()
|
||
status = request.args.get('status', '').strip()
|
||
is_bound_xhs = request.args.get('isBoundXHS', '').strip()
|
||
|
||
# 构建查询条件(使用表别名以避免字段歧义)
|
||
where_conditions = ["u.enterprise_id = %s", "u.status != 'deleted'", "u.role != 'enterprise'"]
|
||
params = [enterprise_id]
|
||
|
||
if keyword:
|
||
where_conditions.append("(u.real_name LIKE %s OR u.username LIKE %s OR u.phone LIKE %s)")
|
||
keyword_pattern = f"%{keyword}%"
|
||
params.extend([keyword_pattern, keyword_pattern, keyword_pattern])
|
||
|
||
if status:
|
||
where_conditions.append("u.status = %s")
|
||
params.append(status)
|
||
|
||
if is_bound_xhs:
|
||
bound_value = 1 if is_bound_xhs.lower() == 'true' else 0
|
||
where_conditions.append("u.is_bound_xhs = %s")
|
||
params.append(bound_value)
|
||
|
||
where_clause = " AND ".join(where_conditions)
|
||
|
||
# 计算偏移量
|
||
offset = (page - 1) * page_size
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 查询总数
|
||
count_sql = f"SELECT COUNT(*) as total FROM ai_users u WHERE {where_clause}"
|
||
count_result = db_manager.execute_query(count_sql, params)
|
||
total = count_result[0]['total']
|
||
|
||
# 查询员工列表
|
||
# 从ai_authors表获取xhs_account字段以优化性能
|
||
sql = f"""
|
||
SELECT u.id, u.enterprise_id, u.real_name as name, u.username, u.phone, u.role, u.department,
|
||
u.is_bound_xhs, a.xhs_account, u.status, u.created_at, u.updated_at
|
||
FROM ai_users u
|
||
LEFT JOIN ai_authors a ON u.id = a.created_user_id AND a.status = 'active'
|
||
WHERE {where_clause}
|
||
ORDER BY u.created_at DESC
|
||
LIMIT %s OFFSET %s
|
||
"""
|
||
params.extend([page_size, offset])
|
||
employees = db_manager.execute_query(sql, params)
|
||
|
||
# 角色名称映射
|
||
role_name_map = {
|
||
'enterprise': '企业',
|
||
'admin': '管理员',
|
||
'editor': '编辑',
|
||
'reviewer': '审核',
|
||
'publisher': '发布',
|
||
'each_title_reviewer': 'title审核',
|
||
'employee': '员工',
|
||
'teamleader': '组长',
|
||
'supervisor': '主管'
|
||
}
|
||
|
||
# 转换布尔值并添加role_name
|
||
for emp in employees:
|
||
emp['is_bound_xhs'] = bool(emp.get('is_bound_xhs', 0))
|
||
emp['role_name'] = role_name_map.get(emp.get('role', ''), emp.get('role', ''))
|
||
|
||
# 格式化日期时间字段
|
||
employees = format_datetime_fields(employees)
|
||
|
||
logger.info(f"获取员工列表成功,总数: {total}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': 'success',
|
||
'data': {
|
||
'total': total,
|
||
'list': employees
|
||
},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[获取员工列表] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@employee_bp.route('/add', methods=['POST'])
|
||
@require_auth
|
||
@require_role('enterprise')
|
||
def add_employee():
|
||
"""添加员工"""
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '请求参数错误',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 验证必需字段
|
||
required_fields = ['name', 'phone', 'password', 'role']
|
||
for field in required_fields:
|
||
if not data.get(field):
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': f'缺少必需字段: {field}',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 验证角色
|
||
valid_roles = ['editor', 'reviewer', 'publisher', 'each_title_reviewer','employee','teamleader','supervisor']
|
||
if data['role'] not in valid_roles:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无效的角色',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 检查手机号是否已存在
|
||
db_manager = get_db_manager()
|
||
check_sql = "SELECT id FROM ai_users WHERE phone = %s AND enterprise_id = %s"
|
||
existing = db_manager.execute_query(check_sql, (data['phone'], enterprise_id))
|
||
|
||
if existing:
|
||
return jsonify({
|
||
'code': 409,
|
||
'message': '手机号已被使用',
|
||
'data': None
|
||
}), 409
|
||
|
||
# 创建员工
|
||
# xhs_phone, xhs_account, bound_at字段已迁移到ai_authors表,不再在ai_users表中存储
|
||
sql = """
|
||
INSERT INTO ai_users
|
||
(enterprise_id, enterprise_name, username, real_name, phone, password, role, department, status, is_bound_xhs)
|
||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||
"""
|
||
hashed_password = AuthUtils.hash_password(data['password'])
|
||
# 获取企业名称
|
||
ent_sql = "SELECT name FROM ai_enterprises WHERE id = %s"
|
||
ent_result = db_manager.execute_query(ent_sql, (enterprise_id,))
|
||
enterprise_name = ent_result[0]['name'] if ent_result else ''
|
||
|
||
user_id = db_manager.execute_insert(sql, (
|
||
enterprise_id,
|
||
enterprise_name,
|
||
data['phone'], # 使用手机号作为username
|
||
data['name'], # real_name
|
||
data['phone'],
|
||
hashed_password,
|
||
data['role'],
|
||
data.get('department', ''),
|
||
'active',
|
||
0 # is_bound_xhs
|
||
))
|
||
|
||
# 更新企业员工总数
|
||
update_sql = "UPDATE ai_enterprises SET users_total = users_total + 1 WHERE id = %s"
|
||
db_manager.execute_update(update_sql, (enterprise_id,))
|
||
|
||
logger.info(f"添加员工成功: {data['name']}, ID: {user_id}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '添加成功',
|
||
'data': {'id': user_id},
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[添加员工] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@employee_bp.route('/<int:employee_id>', methods=['DELETE'])
|
||
@require_auth
|
||
@require_role('enterprise')
|
||
def delete_employee(employee_id):
|
||
"""删除员工"""
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
# 检查员工是否存在且属于当前企业
|
||
check_sql = "SELECT id, real_name FROM ai_users WHERE id = %s AND enterprise_id = %s AND status != 'deleted'"
|
||
existing = db_manager.execute_query(check_sql, (employee_id, enterprise_id))
|
||
|
||
if not existing:
|
||
return jsonify({
|
||
'code': 404,
|
||
'message': '员工不存在',
|
||
'data': None
|
||
}), 404
|
||
|
||
# 软删除员工
|
||
sql = "UPDATE ai_users SET status = 'deleted', updated_at = NOW() WHERE id = %s"
|
||
db_manager.execute_update(sql, (employee_id,))
|
||
|
||
# 更新企业员工总数
|
||
update_sql = "UPDATE ai_enterprises SET users_total = users_total - 1 WHERE id = %s"
|
||
db_manager.execute_update(update_sql, (enterprise_id,))
|
||
|
||
logger.info(f"删除员工成功: {existing[0]['real_name']}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '删除成功',
|
||
'data': None,
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[删除员工] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|
||
|
||
@employee_bp.route('/stats', methods=['GET'])
|
||
@require_auth
|
||
def get_employees_stats():
|
||
"""获取员工统计"""
|
||
try:
|
||
current_user = AuthUtils.get_current_user()
|
||
enterprise_id = current_user.get('enterprise_id')
|
||
|
||
if not enterprise_id:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '无法获取企业ID',
|
||
'data': None
|
||
}), 400
|
||
|
||
db_manager = get_db_manager()
|
||
|
||
sql = """
|
||
SELECT
|
||
COUNT(*) as total_count,
|
||
SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active_count,
|
||
SUM(CASE WHEN is_bound_xhs = 1 THEN 1 ELSE 0 END) as bound_xhs_count
|
||
FROM ai_users
|
||
WHERE enterprise_id = %s AND status != 'deleted' AND role != 'enterprise'
|
||
"""
|
||
result = db_manager.execute_query(sql, (enterprise_id,))
|
||
stats = result[0] if result else {}
|
||
|
||
logger.info("获取员工统计成功")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': 'success',
|
||
'data': stats,
|
||
'timestamp': int(datetime.now().timestamp() * 1000)
|
||
})
|
||
|
||
except Exception as e:
|
||
logger.error(f"[获取员工统计] 处理请求时发生错误: {str(e)}", exc_info=True)
|
||
return jsonify({
|
||
'code': 500,
|
||
'message': '服务器内部错误',
|
||
'data': None
|
||
}), 500
|