2026-1-6
This commit is contained in:
298
release/39/auth_routes.py
Normal file
298
release/39/auth_routes.py
Normal file
@@ -0,0 +1,298 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
认证接口
|
||||
"""
|
||||
|
||||
from flask import Blueprint, request, jsonify
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from auth_utils import 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')
|
||||
|
||||
# 创建蓝图
|
||||
auth_bp = Blueprint('auth', __name__, url_prefix='/api/auth')
|
||||
|
||||
@auth_bp.route('/login', methods=['POST'])
|
||||
def login():
|
||||
"""统一登录接口(支持企业主和员工)"""
|
||||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||||
logger.info(f"[用户登录] 开始处理登录请求, IP: {client_ip}")
|
||||
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
logger.warning(f"[用户登录] 请求参数为空, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '请求参数错误',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 支持手机号或用户名登录
|
||||
phone = data.get('phone')
|
||||
username = data.get('username')
|
||||
password = data.get('password')
|
||||
|
||||
login_account = phone or username
|
||||
logger.info(f"[用户登录] 收到登录请求, 账号: {login_account}, IP: {client_ip}")
|
||||
|
||||
if not login_account or not password:
|
||||
logger.warning(f"[用户登录] 账号或密码为空, 账号: {login_account}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '账号和密码不能为空',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 第一步:先在 ai_users 表查询用户
|
||||
# 从ai_authors表获取xhs_account字段以优化性能
|
||||
logger.info(f"[用户登录] 开始在ai_users表查询用户, 账号: {login_account}")
|
||||
db_manager = get_db_manager()
|
||||
|
||||
# 支持手机号或用户名登录
|
||||
sql = """
|
||||
SELECT u.id, u.enterprise_id, u.enterprise_name, u.username, u.phone, u.password,
|
||||
u.real_name, u.role, u.status, u.is_bound_xhs, a.xhs_account
|
||||
FROM ai_users u
|
||||
LEFT JOIN ai_authors a ON u.id = a.created_user_id AND a.status = 'active'
|
||||
WHERE (u.phone = %s OR u.username = %s) AND u.status = 'active'
|
||||
"""
|
||||
result = db_manager.execute_query(sql, (login_account, login_account))
|
||||
|
||||
if not result:
|
||||
logger.warning(f"[用户登录失败] 用户不存在或已禁用: {login_account}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 401,
|
||||
'message': '账号或密码错误',
|
||||
'data': None
|
||||
}), 401
|
||||
|
||||
user = result[0]
|
||||
logger.info(f"[用户登录] 查询到用户信息, 用户名: {user['username']}, 角色: {user['role']}, 企业: {user['enterprise_name']}, 企业ID: {user['enterprise_id']}")
|
||||
|
||||
# 验证密码
|
||||
logger.info(f"[用户登录] 开始验证密码, 账号: {login_account}")
|
||||
if not AuthUtils.verify_password(password, user['password']):
|
||||
logger.warning(f"[用户登录失败] 密码错误: {login_account}, 用户名: {user['username']}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 401,
|
||||
'message': '账号或密码错误',
|
||||
'data': None
|
||||
}), 401
|
||||
|
||||
logger.info(f"[用户登录] 密码验证成功, 用户名: {user['username']}, 角色: {user['role']}")
|
||||
|
||||
# 如果是企业角色,获取企业详细信息
|
||||
enterprise_info = None
|
||||
if user['role'] == 'enterprise' and user['enterprise_id']:
|
||||
logger.info(f"[用户登录] 检测到企业角色, 开始获取企业详细信息, 企业ID: {user['enterprise_id']}")
|
||||
enterprise_sql = """
|
||||
SELECT id, enterprise_ID, name, short_name, email, status,
|
||||
users_total, products_total, articles_total, published_total
|
||||
FROM ai_enterprises
|
||||
WHERE id = %s AND status = 'active'
|
||||
"""
|
||||
enterprise_result = db_manager.execute_query(enterprise_sql, (user['enterprise_id'],))
|
||||
|
||||
if enterprise_result:
|
||||
enterprise_info = enterprise_result[0]
|
||||
logger.info(f"[用户登录] 获取企业信息成功, 企业名称: {enterprise_info['name']}, 企业编号: {enterprise_info['enterprise_ID']}")
|
||||
else:
|
||||
logger.warning(f"[用户登录] 企业信息不存在或已禁用, 企业ID: {user['enterprise_id']}")
|
||||
|
||||
# 生成token
|
||||
logger.info(f"[用户登录] 开始生成token, 用户ID: {user['id']}, 角色: {user['role']}")
|
||||
token = AuthUtils.generate_token(
|
||||
user['id'],
|
||||
user['phone'] or user['username'],
|
||||
user['role'],
|
||||
user['enterprise_id']
|
||||
)
|
||||
|
||||
# 构造返回数据
|
||||
user_info = {
|
||||
'id': user['id'],
|
||||
'name': user['real_name'] or user['username'],
|
||||
'username': user['username'],
|
||||
'phone': user['phone'],
|
||||
'role': user['role'],
|
||||
'enterpriseId': user['enterprise_id'],
|
||||
'enterpriseName': user['enterprise_name'],
|
||||
'isBoundXHS': bool(user.get('is_bound_xhs', 0)),
|
||||
'xhsAccount': user.get('xhs_account', '')
|
||||
}
|
||||
|
||||
# 如果是企业角色且有企业信息,添加企业详细信息
|
||||
if enterprise_info:
|
||||
user_info.update({
|
||||
'enterpriseCode': enterprise_info['enterprise_ID'],
|
||||
'enterpriseShortName': enterprise_info['short_name'],
|
||||
'enterpriseEmail': enterprise_info['email'],
|
||||
'enterprisePhone': user['phone'], # 企业管理员的手机号从user表获取
|
||||
'usersTotal': enterprise_info['users_total'],
|
||||
'productsTotal': enterprise_info['products_total'],
|
||||
'articlesTotal': enterprise_info['articles_total'],
|
||||
'publishedTotal': enterprise_info['published_total']
|
||||
})
|
||||
|
||||
logger.info(f"[用户登录成功] Token生成成功, 用户: {user['username']}, 角色: {user['role']}, 企业: {user['enterprise_name']}, IP: {client_ip}")
|
||||
|
||||
# 返回用户信息和token
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'message': '登录成功',
|
||||
'data': {
|
||||
'token': token,
|
||||
'userInfo': user_info
|
||||
},
|
||||
'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
|
||||
|
||||
@auth_bp.route('/employee/login', methods=['POST'])
|
||||
def employee_login():
|
||||
"""员工登录"""
|
||||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||||
logger.info(f"[员工登录] 开始处理员工登录请求, IP: {client_ip}")
|
||||
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
logger.warning(f"[员工登录] 请求参数为空, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '请求参数错误',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
phone = data.get('phone')
|
||||
password = data.get('password')
|
||||
|
||||
logger.info(f"[员工登录] 收到登录请求, 手机号: {phone}, IP: {client_ip}")
|
||||
|
||||
if not phone or not password:
|
||||
logger.warning(f"[员工登录] 手机号或密码为空, 手机号: {phone}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '手机号和密码不能为空',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 查询员工用户
|
||||
# 从ai_authors表获取xhs_account字段以优化性能
|
||||
logger.info(f"[员工登录] 开始查询员工信息, 手机号: {phone}")
|
||||
db_manager = get_db_manager()
|
||||
sql = """
|
||||
SELECT u.id, u.enterprise_id, u.real_name, u.phone, u.password, u.role, u.status,
|
||||
u.is_bound_xhs, a.xhs_account,
|
||||
e.name as enterprise_name
|
||||
FROM ai_users u
|
||||
LEFT JOIN ai_enterprises e ON u.enterprise_id = e.id
|
||||
LEFT JOIN ai_authors a ON u.id = a.created_user_id AND a.status = 'active'
|
||||
WHERE u.phone = %s
|
||||
"""
|
||||
result = db_manager.execute_query(sql, (phone,))
|
||||
|
||||
if not result:
|
||||
logger.warning(f"[员工登录失败] 用户不存在: {phone}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 401,
|
||||
'message': '手机号或密码错误',
|
||||
'data': None
|
||||
}), 401
|
||||
|
||||
user = result[0]
|
||||
logger.info(f"[员工登录] 查询到员工信息, 姓名: {user['real_name']}, 角色: {user['role']}, 企业: {user['enterprise_name']}, 状态: {user['status']}, 绑定小红书: {user.get('is_bound_xhs', 0)}")
|
||||
|
||||
# 检查用户状态
|
||||
if user['status'] != 'active':
|
||||
logger.warning(f"[员工登录失败] 用户状态异常: {phone}, 状态: {user['status']}, 姓名: {user['real_name']}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 403,
|
||||
'message': '用户已被禁用',
|
||||
'data': None
|
||||
}), 403
|
||||
|
||||
# 验证密码
|
||||
logger.info(f"[员工登录] 开始验证密码, 手机号: {phone}, 姓名: {user['real_name']}")
|
||||
if not AuthUtils.verify_password(password, user['password']):
|
||||
logger.warning(f"[员工登录失败] 密码错误: {phone}, 姓名: {user['real_name']}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 401,
|
||||
'message': '手机号或密码错误',
|
||||
'data': None
|
||||
}), 401
|
||||
|
||||
# 生成token
|
||||
logger.info(f"[员工登录] 密码验证成功, 开始生成token, 姓名: {user['real_name']}, 角色: {user['role']}, 企业: {user['enterprise_name']}")
|
||||
token = AuthUtils.generate_token(user['id'], phone, user['role'], user['enterprise_id'])
|
||||
|
||||
logger.info(f"[员工登录成功] Token生成成功, 姓名: {user['real_name']}, 手机号: {phone}, 角色: {user['role']}, 企业: {user['enterprise_name']}, IP: {client_ip}")
|
||||
|
||||
# 返回用户信息和token
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'message': '登录成功',
|
||||
'data': {
|
||||
'token': token,
|
||||
'userInfo': {
|
||||
'id': user['id'],
|
||||
'name': user['real_name'],
|
||||
'phone': user['phone'],
|
||||
'role': user['role'],
|
||||
'enterpriseId': user['enterprise_id'],
|
||||
'enterpriseName': user['enterprise_name'],
|
||||
'isBoundXHS': bool(user.get('is_bound_xhs', 0)),
|
||||
'xhsAccount': user.get('xhs_account', '')
|
||||
}
|
||||
},
|
||||
'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
|
||||
|
||||
@auth_bp.route('/logout', methods=['POST'])
|
||||
def logout():
|
||||
"""用户登出"""
|
||||
try:
|
||||
# 记录登出日志
|
||||
auth_header = request.headers.get('Authorization')
|
||||
if auth_header:
|
||||
parts = auth_header.split()
|
||||
if len(parts) == 2:
|
||||
token = parts[1]
|
||||
payload = AuthUtils.verify_token(token)
|
||||
if payload:
|
||||
logger.info(f"[登出成功] 用户ID: {payload.get('user_id')}")
|
||||
|
||||
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
|
||||
325
release/39/employee_routes.py
Normal file
325
release/39/employee_routes.py
Normal file
@@ -0,0 +1,325 @@
|
||||
#!/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
|
||||
712
release/39/enterprise_routes.py
Normal file
712
release/39/enterprise_routes.py
Normal file
@@ -0,0 +1,712 @@
|
||||
#!/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
|
||||
import uuid
|
||||
|
||||
logger = logging.getLogger('article_server')
|
||||
|
||||
# 创建蓝图
|
||||
enterprise_bp = Blueprint('enterprise', __name__, url_prefix='/api/enterprises')
|
||||
|
||||
@enterprise_bp.route('/list', methods=['GET'])
|
||||
@require_auth
|
||||
@require_role('admin', 'enterprise')
|
||||
def get_enterprises_list():
|
||||
"""获取企业列表(平台管理员)"""
|
||||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||||
logger.info(f"[获取企业列表] 开始处理请求, IP: {client_ip}")
|
||||
|
||||
try:
|
||||
# 获取查询参数
|
||||
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()
|
||||
|
||||
logger.info(f"[获取企业列表] 查询参数: page={page}, pageSize={page_size}, keyword={keyword}, status={status}, IP: {client_ip}")
|
||||
|
||||
# 构建查询条件
|
||||
where_conditions = ["1=1"]
|
||||
params = []
|
||||
|
||||
if keyword:
|
||||
where_conditions.append("(name LIKE %s OR short_name LIKE %s OR phone LIKE %s)")
|
||||
keyword_pattern = f"%{keyword}%"
|
||||
params.extend([keyword_pattern, keyword_pattern, keyword_pattern])
|
||||
|
||||
if status:
|
||||
where_conditions.append("status = %s")
|
||||
params.append(status)
|
||||
|
||||
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_enterprises WHERE {where_clause}"
|
||||
count_result = db_manager.execute_query(count_sql, params)
|
||||
total = count_result[0]['total']
|
||||
|
||||
# 查询企业列表
|
||||
sql = f"""
|
||||
SELECT id, enterprise_ID, name, short_name, email, status,
|
||||
users_total, products_total, articles_total, published_total,
|
||||
created_at, updated_at
|
||||
FROM ai_enterprises
|
||||
WHERE {where_clause}
|
||||
ORDER BY created_at DESC
|
||||
LIMIT %s OFFSET %s
|
||||
"""
|
||||
params.extend([page_size, offset])
|
||||
enterprises = db_manager.execute_query(sql, params)
|
||||
|
||||
# 为每个企业查询管理员手机号(从ai_users表)
|
||||
for enterprise in enterprises:
|
||||
phone_sql = """
|
||||
SELECT phone
|
||||
FROM ai_users
|
||||
WHERE enterprise_id = %s AND role = 'enterprise' AND is_enterprise = 1 AND status = 'active'
|
||||
LIMIT 1
|
||||
"""
|
||||
phone_result = db_manager.execute_query(phone_sql, (enterprise['id'],))
|
||||
enterprise['phone'] = phone_result[0]['phone'] if phone_result and phone_result[0].get('phone') else ''
|
||||
|
||||
# 格式化日期时间字段
|
||||
enterprises = format_datetime_fields(enterprises)
|
||||
|
||||
logger.info(f"[获取企业列表] 查询成功, 总数: {total}, 当前页: {page}, 每页: {page_size}, 返回数量: {len(enterprises)}, IP: {client_ip}")
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'message': 'success',
|
||||
'data': {
|
||||
'total': total,
|
||||
'list': enterprises
|
||||
},
|
||||
'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
|
||||
|
||||
@enterprise_bp.route('/create', methods=['POST'])
|
||||
@require_auth
|
||||
@require_role('admin', 'enterprise')
|
||||
def create_enterprise():
|
||||
"""创建企业(平台管理员)"""
|
||||
client_ip = request.environ.get('HTTP_X_FORWARDED_FOR', request.environ.get('REMOTE_ADDR', '未知'))
|
||||
logger.info(f"[创建企业] 开始处理创建企业请求, IP: {client_ip}")
|
||||
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
logger.warning(f"[创建企业] 请求参数为空, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '请求参数错误',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
logger.info(f"[创建企业] 收到创建请求, 企业名称: {data.get('name')}, 简称: {data.get('short_name')}, 手机号: {data.get('phone')}, IP: {client_ip}")
|
||||
|
||||
# 验证必需字段
|
||||
required_fields = ['name', 'short_name', 'phone', 'password']
|
||||
for field in required_fields:
|
||||
if not data.get(field):
|
||||
logger.warning(f"[创建企业] 缺少必需字段: {field}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': f'缺少必需字段: {field}',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
db_manager = get_db_manager()
|
||||
|
||||
# ✅ 检查手机号是否已存在(ai_users表中role='enterprise'的记录)
|
||||
logger.info(f"[创建企业] 检查ai_users表中企业角色手机号是否已存在: {data['phone']}")
|
||||
check_user_sql = "SELECT id FROM ai_users WHERE phone = %s AND role = 'enterprise' AND is_enterprise = 1"
|
||||
existing_user = db_manager.execute_query(check_user_sql, (data['phone'],))
|
||||
|
||||
if existing_user:
|
||||
logger.warning(f"[创建企业] ai_users表中企业角色手机号已存在: {data['phone']}, IP: {client_ip}")
|
||||
return jsonify({
|
||||
'code': 409,
|
||||
'message': '手机号已被使用',
|
||||
'data': None
|
||||
}), 409
|
||||
|
||||
# 生成企业唯一标识
|
||||
enterprise_id_str = f"ENT-{datetime.now().strftime('%Y%m%d')}-{str(uuid.uuid4())[:8].upper()}"
|
||||
logger.info(f"[创建企业] 生成企业ID: {enterprise_id_str}, 企业名称: {data['name']}")
|
||||
|
||||
# 加密密码
|
||||
from auth_utils import AuthUtils
|
||||
hashed_password = AuthUtils.hash_password(data['password'])
|
||||
|
||||
# ✅ (1)创建企业(ai_enterprises表)
|
||||
logger.info(f"[创建企业] 开始插入ai_enterprises表, 企业ID: {enterprise_id_str}, 名称: {data['name']}")
|
||||
enterprise_sql = """
|
||||
INSERT INTO ai_enterprises
|
||||
(enterprise_ID, name, short_name, icon, email, website, address, status,
|
||||
users_total, products_total, published_total, articles_total, released_month_total, linked_to_xhs_num)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
"""
|
||||
|
||||
enterprise_db_id = db_manager.execute_insert(enterprise_sql, (
|
||||
enterprise_id_str,
|
||||
data['name'],
|
||||
data['short_name'],
|
||||
data.get('icon', ''),
|
||||
data.get('email', ''),
|
||||
data.get('website', ''),
|
||||
data.get('address', ''),
|
||||
'active',
|
||||
0, 0, 0, 0, 0, 0
|
||||
))
|
||||
|
||||
logger.info(f"[创建企业] ai_enterprises表插入成功, 数据库ID: {enterprise_db_id}, 企业ID: {enterprise_id_str}")
|
||||
|
||||
# ✅ (2)创建企业管理员用户(ai_users表)
|
||||
logger.info(f"[创建企业] 开始创建企业管理员用户, 手机号: {data['phone']}, 角色: enterprise")
|
||||
user_sql = """
|
||||
INSERT INTO ai_users
|
||||
(enterprise_id, enterprise_name, username, password, real_name, email, phone,
|
||||
department, role, status, is_enterprise)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||
"""
|
||||
|
||||
# 用户名使用手机号
|
||||
username = data['phone']
|
||||
|
||||
user_db_id = db_manager.execute_insert(user_sql, (
|
||||
enterprise_db_id, # enterprise_id
|
||||
data['name'], # enterprise_name
|
||||
username, # username (使用手机号)
|
||||
hashed_password, # password (使用传入的密码)
|
||||
data.get('real_name', data['short_name']), # real_name
|
||||
data.get('email', ''), # email
|
||||
data['phone'], # phone
|
||||
data.get('department', ''), # department
|
||||
'enterprise', # role (✅ 角色为enterprise)
|
||||
'active', # status
|
||||
1
|
||||
))
|
||||
|
||||
logger.info(f"[创建企业] ai_users表插入成功, 用户ID: {user_db_id}, 用户名: {username}, 角色: enterprise")
|
||||
|
||||
logger.info(f"[创建企业] 企业创建成功, 企业DB_ID: {enterprise_db_id}, 企业ID: {enterprise_id_str}, 名称: {data['name']}, 管理员用户ID: {user_db_id}, IP: {client_ip}")
|
||||
|
||||
# 记录业务日志
|
||||
log_create(
|
||||
target_type='enterprise',
|
||||
target_id=enterprise_db_id,
|
||||
description=f"创建企业: {data['name']}, 同时创建企业管理员用户",
|
||||
request_data={**data, 'password': '***'}, # 隐藏密码
|
||||
response_data={'enterprise_id': enterprise_db_id, 'enterprise_ID': enterprise_id_str, 'user_id': user_db_id}
|
||||
)
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'message': '创建成功',
|
||||
'data': {
|
||||
'id': enterprise_db_id,
|
||||
'enterprise_ID': enterprise_id_str,
|
||||
'name': data['name'],
|
||||
'user_id': user_db_id,
|
||||
'username': username
|
||||
},
|
||||
'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
|
||||
|
||||
@enterprise_bp.route('/<int:enterprise_id>', methods=['PUT'])
|
||||
@require_auth
|
||||
@require_role('admin', 'enterprise')
|
||||
def update_enterprise(enterprise_id):
|
||||
"""更新企业信息(平台管理员)"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '请求参数错误',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 检查企业是否存在
|
||||
db_manager = get_db_manager()
|
||||
check_sql = "SELECT id FROM ai_enterprises WHERE id = %s"
|
||||
existing = db_manager.execute_query(check_sql, (enterprise_id,))
|
||||
|
||||
if not existing:
|
||||
return jsonify({
|
||||
'code': 404,
|
||||
'message': '企业不存在',
|
||||
'data': None
|
||||
}), 404
|
||||
|
||||
# 构建更新字段
|
||||
enterprise_update_fields = []
|
||||
enterprise_params = []
|
||||
user_password = None
|
||||
|
||||
if 'name' in data:
|
||||
enterprise_update_fields.append("name = %s")
|
||||
enterprise_params.append(data['name'])
|
||||
|
||||
if 'short_name' in data:
|
||||
enterprise_update_fields.append("short_name = %s")
|
||||
enterprise_params.append(data['short_name'])
|
||||
|
||||
if 'email' in data:
|
||||
enterprise_update_fields.append("email = %s")
|
||||
enterprise_params.append(data['email'])
|
||||
|
||||
if 'password' in data:
|
||||
from auth_utils import AuthUtils
|
||||
user_password = AuthUtils.hash_password(data['password'])
|
||||
|
||||
if not enterprise_update_fields and not user_password:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '没有要更新的字段',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 执行更新企业表
|
||||
if enterprise_update_fields:
|
||||
enterprise_params.append(enterprise_id)
|
||||
sql = f"UPDATE ai_enterprises SET {', '.join(enterprise_update_fields)}, updated_at = NOW() WHERE id = %s"
|
||||
db_manager.execute_update(sql, enterprise_params)
|
||||
|
||||
# 如果有密码更新,更新ai_users表中的企业管理员密码
|
||||
if user_password:
|
||||
user_update_sql = "UPDATE ai_users SET password = %s, updated_at = NOW() WHERE enterprise_id = %s AND role = 'enterprise'"
|
||||
db_manager.execute_update(user_update_sql, (user_password, enterprise_id))
|
||||
|
||||
logger.info(f"更新企业成功: ID {enterprise_id}")
|
||||
|
||||
# 记录业务日志
|
||||
log_update(
|
||||
target_type='enterprise',
|
||||
target_id=enterprise_id,
|
||||
description=f"更新企业信息",
|
||||
request_data=data
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
@enterprise_bp.route('/<int:enterprise_id>/status', methods=['PUT'])
|
||||
@require_auth
|
||||
@require_role('admin', 'enterprise')
|
||||
def toggle_enterprise_status(enterprise_id):
|
||||
"""切换企业状态(平台管理员)"""
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data or 'status' not in data:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '缺少status参数',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
status = data['status']
|
||||
if status not in ['active', 'disabled']:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '状态值无效',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
db_manager = get_db_manager()
|
||||
sql = "UPDATE ai_enterprises SET status = %s, updated_at = NOW() WHERE id = %s"
|
||||
affected = db_manager.execute_update(sql, (status, enterprise_id))
|
||||
|
||||
if affected == 0:
|
||||
return jsonify({
|
||||
'code': 404,
|
||||
'message': '企业不存在',
|
||||
'data': None
|
||||
}), 404
|
||||
|
||||
logger.info(f"切换企业状态成功: ID {enterprise_id}, 状态: {status}")
|
||||
|
||||
# 记录业务日志
|
||||
log_update(
|
||||
target_type='enterprise',
|
||||
target_id=enterprise_id,
|
||||
description=f"切换企业状态: {status}",
|
||||
request_data=data
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
@enterprise_bp.route('/<int:enterprise_id>', methods=['DELETE'])
|
||||
@require_auth
|
||||
@require_role('admin', 'enterprise')
|
||||
def delete_enterprise(enterprise_id):
|
||||
"""删除企业(平台管理员)"""
|
||||
try:
|
||||
db_manager = get_db_manager()
|
||||
|
||||
# 检查企业是否存在
|
||||
check_sql = "SELECT id, name FROM ai_enterprises WHERE id = %s"
|
||||
existing = db_manager.execute_query(check_sql, (enterprise_id,))
|
||||
|
||||
if not existing:
|
||||
return jsonify({
|
||||
'code': 404,
|
||||
'message': '企业不存在',
|
||||
'data': None
|
||||
}), 404
|
||||
|
||||
# 物理删除企业(API文档要求)
|
||||
sql = "DELETE FROM ai_enterprises WHERE id = %s"
|
||||
db_manager.execute_update(sql, (enterprise_id,))
|
||||
|
||||
logger.info(f"删除企业成功: {existing[0]['name']}")
|
||||
|
||||
# 记录业务日志
|
||||
log_delete(
|
||||
target_type='enterprise',
|
||||
target_id=enterprise_id,
|
||||
description=f"删除企业: {existing[0]['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
|
||||
|
||||
@enterprise_bp.route('/stats', methods=['GET'])
|
||||
@require_auth
|
||||
@require_role('admin', 'enterprise')
|
||||
def get_enterprises_stats():
|
||||
"""获取企业统计(平台管理员)"""
|
||||
try:
|
||||
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 status = 'disabled' THEN 1 ELSE 0 END) as disabled_count,
|
||||
SUM(users_total) as total_users,
|
||||
SUM(products_total) as total_products,
|
||||
SUM(articles_total) as total_articles,
|
||||
SUM(published_total) as total_published
|
||||
FROM ai_enterprises
|
||||
WHERE status != 'deleted'
|
||||
"""
|
||||
result = db_manager.execute_query(sql)
|
||||
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
|
||||
|
||||
# 企业管理员接口
|
||||
@enterprise_bp.route('/info', methods=['GET'])
|
||||
@require_auth
|
||||
@require_role('admin','editor','reviewer','publisher','each_title_reviewer','enterprise')
|
||||
def get_enterprise_info():
|
||||
"""获取企业信息(企业管理员,包含密码字段)"""
|
||||
try:
|
||||
current_user = AuthUtils.get_current_user()
|
||||
enterprise_id = current_user.get('enterprise_id')
|
||||
user_id = current_user.get('user_id')
|
||||
|
||||
if not enterprise_id:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '无法获取企业ID',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
db_manager = get_db_manager()
|
||||
|
||||
# 查询企业信息
|
||||
enterprise_sql = """
|
||||
SELECT id, enterprise_ID, name, short_name, email, status,
|
||||
users_total, products_total, articles_total, published_total,
|
||||
created_at, updated_at
|
||||
FROM ai_enterprises
|
||||
WHERE id = %s
|
||||
"""
|
||||
enterprise_result = db_manager.execute_query(enterprise_sql, (enterprise_id,))
|
||||
|
||||
if not enterprise_result:
|
||||
return jsonify({
|
||||
'code': 404,
|
||||
'message': '企业不存在',
|
||||
'data': None
|
||||
}), 404
|
||||
|
||||
# 格式化日期时间字段
|
||||
enterprise_info = format_datetime_fields(enterprise_result[0])
|
||||
|
||||
# 查询企业管理员的手机号(从ai_users表)
|
||||
user_sql = """
|
||||
SELECT phone
|
||||
FROM ai_users
|
||||
WHERE enterprise_id = %s AND role = 'enterprise' AND is_enterprise = 1 AND status = 'active'
|
||||
LIMIT 1
|
||||
"""
|
||||
user_result = db_manager.execute_query(user_sql, (enterprise_id,))
|
||||
|
||||
# 添加phone字段到企业信息中
|
||||
if user_result and user_result[0].get('phone'):
|
||||
enterprise_info['phone'] = user_result[0]['phone']
|
||||
else:
|
||||
enterprise_info['phone'] = ''
|
||||
|
||||
logger.info(f"获取企业信息成功(含密码): ID {enterprise_id}")
|
||||
|
||||
return jsonify({
|
||||
'code': 200,
|
||||
'message': 'success',
|
||||
'data': enterprise_info,
|
||||
'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
|
||||
|
||||
@enterprise_bp.route('/info', methods=['PUT'])
|
||||
@require_auth
|
||||
@require_role('enterprise', 'admin')
|
||||
def update_enterprise_info():
|
||||
"""更新企业信息(企业管理员)"""
|
||||
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
|
||||
|
||||
# 构建更新字段(企业管理员只能更新部分字段)
|
||||
update_fields = []
|
||||
params = []
|
||||
|
||||
if 'short_name' in data:
|
||||
update_fields.append("short_name = %s")
|
||||
params.append(data['short_name'])
|
||||
|
||||
if 'email' in data:
|
||||
update_fields.append("email = %s")
|
||||
params.append(data['email'])
|
||||
|
||||
if not update_fields:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '没有要更新的字段',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
db_manager = get_db_manager()
|
||||
params.append(enterprise_id)
|
||||
sql = f"UPDATE ai_enterprises SET {', '.join(update_fields)}, updated_at = NOW() WHERE id = %s"
|
||||
db_manager.execute_update(sql, params)
|
||||
|
||||
logger.info(f"企业管理员更新企业信息成功: ID {enterprise_id}")
|
||||
|
||||
# 记录业务日志
|
||||
log_update(
|
||||
target_type='enterprise',
|
||||
target_id=enterprise_id,
|
||||
description=f"更新企业信息(企业管理员)",
|
||||
request_data=data
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
@enterprise_bp.route('/change-password', methods=['PUT'])
|
||||
@require_auth
|
||||
@require_role('enterprise')
|
||||
def change_password():
|
||||
"""修改企业密码(企业管理员)"""
|
||||
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
|
||||
|
||||
old_password = data.get('old_password')
|
||||
new_password = data.get('new_password')
|
||||
|
||||
if not old_password or not new_password:
|
||||
return jsonify({
|
||||
'code': 400,
|
||||
'message': '旧密码和新密码不能为空',
|
||||
'data': None
|
||||
}), 400
|
||||
|
||||
# 获取当前密码(从ai_users表查询企业管理员账号)
|
||||
db_manager = get_db_manager()
|
||||
user_id = current_user.get('user_id')
|
||||
sql = "SELECT password FROM ai_users WHERE id = %s AND role = 'enterprise'"
|
||||
result = db_manager.execute_query(sql, (user_id,))
|
||||
|
||||
if not result:
|
||||
return jsonify({
|
||||
'code': 404,
|
||||
'message': '用户不存在',
|
||||
'data': None
|
||||
}), 404
|
||||
|
||||
current_password = result[0]['password']
|
||||
|
||||
# 验证旧密码
|
||||
if not AuthUtils.verify_password(old_password, current_password):
|
||||
logger.warning(f"企业修改密码失败 - 旧密码错误: 企业ID {enterprise_id}")
|
||||
return jsonify({
|
||||
'code': 401,
|
||||
'message': '旧密码错误',
|
||||
'data': None
|
||||
}), 401
|
||||
|
||||
# 更新密码(更新ai_users表中的企业管理员密码)
|
||||
hashed_new_password = AuthUtils.hash_password(new_password)
|
||||
update_sql = "UPDATE ai_users SET password = %s, updated_at = NOW() WHERE id = %s AND role = 'enterprise'"
|
||||
db_manager.execute_update(update_sql, (hashed_new_password, user_id))
|
||||
|
||||
logger.info(f"企业修改密码成功: ID {enterprise_id}")
|
||||
|
||||
# 记录业务日志
|
||||
log_update(
|
||||
target_type='enterprise',
|
||||
target_id=enterprise_id,
|
||||
description=f"修改企业密码",
|
||||
request_data={'old_password': '***', 'new_password': '***'} # 隐藏密码
|
||||
)
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user