618 lines
20 KiB
Python
618 lines
20 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
|
||
from log_utils import log_create, log_update, log_delete, log_error
|
||
import uuid
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# 创建蓝图
|
||
enterprise_bp = Blueprint('enterprise', __name__, url_prefix='/api/enterprises')
|
||
|
||
@enterprise_bp.route('/list', methods=['GET'])
|
||
@require_auth
|
||
@require_role('admin')
|
||
def get_enterprises_list():
|
||
"""获取企业列表(平台管理员)"""
|
||
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()
|
||
|
||
# 构建查询条件
|
||
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, phone, 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)
|
||
|
||
logger.info(f"获取企业列表成功,总数: {total}")
|
||
|
||
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')
|
||
def create_enterprise():
|
||
"""创建企业(平台管理员)"""
|
||
try:
|
||
data = request.get_json()
|
||
if not data:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '请求参数错误',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 验证必需字段
|
||
required_fields = ['name', 'short_name', 'phone', 'password']
|
||
for field in required_fields:
|
||
if not data.get(field):
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': f'缺少必需字段: {field}',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 检查手机号是否已存在
|
||
db_manager = get_db_manager()
|
||
check_sql = "SELECT id FROM ai_enterprises WHERE phone = %s"
|
||
existing = db_manager.execute_query(check_sql, (data['phone'],))
|
||
|
||
if existing:
|
||
return jsonify({
|
||
'code': 409,
|
||
'message': '手机号已被使用',
|
||
'data': None
|
||
}), 409
|
||
|
||
# 生成企业唯一标识
|
||
enterprise_id = f"ENT-{datetime.now().strftime('%Y%m%d')}-{str(uuid.uuid4())[:8].upper()}"
|
||
|
||
# 创建企业
|
||
sql = """
|
||
INSERT INTO ai_enterprises
|
||
(enterprise_ID, name, short_name, phone, password, email, status,
|
||
users_total, products_total, articles_total, published_total)
|
||
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||
"""
|
||
from auth_utils import AuthUtils
|
||
hashed_password = AuthUtils.hash_password(data['password'])
|
||
id = db_manager.execute_insert(sql, (
|
||
enterprise_id,
|
||
data['name'],
|
||
data['short_name'],
|
||
data['phone'],
|
||
hashed_password,
|
||
data.get('email', ''),
|
||
'active',
|
||
0, 0, 0, 0
|
||
))
|
||
|
||
logger.info(f"创建企业成功: {data['name']}, ID: {enterprise_id}")
|
||
|
||
# 记录业务日志
|
||
log_create(
|
||
target_type='enterprise',
|
||
target_id=id,
|
||
description=f"创建企业: {data['name']}",
|
||
request_data=data,
|
||
response_data={'id': id, 'enterprise_ID': enterprise_id}
|
||
)
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': '创建成功',
|
||
'data': {
|
||
'id': id,
|
||
'enterprise_ID': enterprise_id,
|
||
'name': data['name']
|
||
},
|
||
'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')
|
||
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
|
||
|
||
# 构建更新字段
|
||
update_fields = []
|
||
params = []
|
||
|
||
if 'name' in data:
|
||
update_fields.append("name = %s")
|
||
params.append(data['name'])
|
||
|
||
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 'password' in data:
|
||
from auth_utils import AuthUtils
|
||
update_fields.append("password = %s")
|
||
params.append(AuthUtils.hash_password(data['password']))
|
||
|
||
if not update_fields:
|
||
return jsonify({
|
||
'code': 400,
|
||
'message': '没有要更新的字段',
|
||
'data': None
|
||
}), 400
|
||
|
||
# 执行更新
|
||
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('/<int:enterprise_id>/status', methods=['PUT'])
|
||
@require_auth
|
||
@require_role('admin')
|
||
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')
|
||
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')
|
||
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('enterprise_admin')
|
||
def get_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
|
||
|
||
db_manager = get_db_manager()
|
||
sql = """
|
||
SELECT id, enterprise_ID, name, short_name, phone, email, status,
|
||
users_total, products_total, articles_total, published_total,
|
||
created_at, updated_at
|
||
FROM ai_enterprises
|
||
WHERE id = %s
|
||
"""
|
||
result = db_manager.execute_query(sql, (enterprise_id,))
|
||
|
||
if not result:
|
||
return jsonify({
|
||
'code': 404,
|
||
'message': '企业不存在',
|
||
'data': None
|
||
}), 404
|
||
|
||
logger.info(f"获取企业信息成功: ID {enterprise_id}")
|
||
|
||
return jsonify({
|
||
'code': 200,
|
||
'message': 'success',
|
||
'data': result[0],
|
||
'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_admin')
|
||
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
|
||
|
||
# 获取当前密码
|
||
db_manager = get_db_manager()
|
||
sql = "SELECT password FROM ai_enterprises WHERE id = %s"
|
||
result = db_manager.execute_query(sql, (enterprise_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
|
||
|
||
# 更新密码
|
||
hashed_new_password = AuthUtils.hash_password(new_password)
|
||
update_sql = "UPDATE ai_enterprises SET password = %s, updated_at = NOW() WHERE id = %s"
|
||
db_manager.execute_update(update_sql, (hashed_new_password, enterprise_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
|