Files
ai_wht_B/ver_25122119/employee_routes.py
“shengyudong” 5a384b694e 2026-1-6
2026-01-06 14:18:39 +08:00

312 lines
11 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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'"]
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)
# 转换布尔值
for emp in employees:
emp['is_bound_xhs'] = bool(emp.get('is_bound_xhs', 0))
# 格式化日期时间字段
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']
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'
"""
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