"""管理后台路由(A5 + A6) 用户管理、角色管理、LLM 配置、Prompt 管理 """ from flask import Blueprint, request, jsonify from insurance.admin.service import AdminService from insurance.middleware.auth_middleware import jwt_required, admin_required, super_admin_required, permission_required admin_bp = Blueprint("admin", __name__) admin_service = AdminService() # ---- 用户管理(A5)---- @admin_bp.route("/users", methods=["GET"]) @permission_required("user_manage") def list_users(): """用户列表。""" params = { "page": request.args.get("page", 1, type=int), "page_size": request.args.get("page_size", 20, type=int), "role": request.args.get("role", ""), "department": request.args.get("department", ""), } result = admin_service.list_users(params) return jsonify(result) @admin_bp.route("/users", methods=["POST"]) @permission_required("user_manage") def create_user(): """新增用户。""" data = request.get_json() result = admin_service.create_user(data) return jsonify(result) @admin_bp.route("/users/", methods=["PUT"]) @permission_required("user_manage") def update_user(user_id): """编辑用户。""" data = request.get_json() result = admin_service.update_user(user_id, data) return jsonify(result) @admin_bp.route("/users/", methods=["DELETE"]) @permission_required("user_manage") def delete_user(user_id): """停用用户。""" result = admin_service.delete_user(user_id) return jsonify(result) @admin_bp.route("/users/batch-import", methods=["POST"]) @permission_required("user_manage") def batch_import_users(): """批量导入用户。""" file = request.files.get("file") if not file: return jsonify({"code": 1001, "message": "请选择文件", "data": None}), 400 result = admin_service.batch_import_users(file) return jsonify(result) @admin_bp.route("/users/sync-to-dify", methods=["POST"]) @permission_required("user_manage") def sync_users_to_dify(): """手动同步所有用户到 Dify。""" result = admin_service.sync_all_users_to_dify() return jsonify(result) # ---- 企微群配置 ---- @admin_bp.route("/wecom-groups", methods=["GET"]) @permission_required("config_manage") def list_wecom_groups(): """企微群配置列表。""" params = { "page": request.args.get("page", 1, type=int), "page_size": request.args.get("page_size", 20, type=int), "status": request.args.get("status", ""), "keyword": request.args.get("keyword", ""), } result = admin_service.list_wecom_groups(params) return jsonify(result) @admin_bp.route("/wecom-groups/", methods=["PUT"]) @permission_required("config_manage") def update_wecom_group(group_id): """更新企微群配置。""" data = request.get_json() or {} result = admin_service.update_wecom_group(group_id, data) return jsonify(result) # ---- 角色管理(A5)---- @admin_bp.route("/roles", methods=["GET"]) @permission_required("user_manage") def list_roles(): """角色列表。""" result = admin_service.list_roles() return jsonify(result) @admin_bp.route("/roles", methods=["POST"]) @permission_required("user_manage") def create_role(): """新建角色。""" data = request.get_json() result = admin_service.create_role(data) return jsonify(result) @admin_bp.route("/roles/", methods=["PUT"]) @permission_required("user_manage") def update_role(role_id): """更新角色权限。""" data = request.get_json() result = admin_service.update_role(role_id, data) return jsonify(result) @admin_bp.route("/roles/", methods=["DELETE"]) @permission_required("user_manage") def delete_role(role_id): """删除自定义角色。""" result = admin_service.delete_role(role_id) return jsonify(result) @admin_bp.route("/permissions/me", methods=["GET"]) @jwt_required def get_my_permissions(): """获取当前用户的权限列表。""" from insurance.middleware.auth_middleware import get_user_permissions role_name = request.user_role or "" perms = get_user_permissions(role_name) return jsonify({"code": 0, "data": {"role": role_name, "permissions": perms}}) # ---- LLM 配置(A6)---- @admin_bp.route("/llm-configs", methods=["GET"]) @permission_required("config_manage") def list_llm_configs(): """LLM 配置列表。""" result = admin_service.list_llm_configs() return jsonify(result) @admin_bp.route("/llm-configs", methods=["POST"]) @permission_required("config_manage") def create_llm_config(): """新建 LLM 配置。""" data = request.get_json() result = admin_service.create_llm_config(data) return jsonify(result) @admin_bp.route("/llm-configs/", methods=["PUT"]) @permission_required("config_manage") def update_llm_config(config_id): """更新 LLM 配置。""" data = request.get_json() result = admin_service.update_llm_config(config_id, data) return jsonify(result) @admin_bp.route("/llm-configs//ping", methods=["POST"]) @permission_required("config_manage") def ping_llm(config_id): """测试模型连通性。""" result = admin_service.ping_llm(config_id) return jsonify(result) # ---- Prompt 管理(A6)---- @admin_bp.route("/prompts", methods=["GET"]) @permission_required("kb_manage") def list_prompts(): """Prompt 列表。""" result = admin_service.list_prompts() return jsonify(result) @admin_bp.route("/prompts/", methods=["GET"]) @permission_required("kb_manage") def get_prompt(prompt_id): """获取单个 Prompt 详情。""" result = admin_service.get_prompt(prompt_id) return jsonify(result) @admin_bp.route("/prompts", methods=["POST"]) @permission_required("kb_manage") def save_prompt(): """新建/更新 Prompt(自动创建版本快照)。""" data = request.get_json() result = admin_service.save_prompt(data) return jsonify(result) @admin_bp.route("/prompts/", methods=["DELETE"]) @permission_required("kb_manage") def delete_prompt(prompt_id): """删除 Prompt。""" result = admin_service.delete_prompt(prompt_id) return jsonify(result) @admin_bp.route("/prompts//versions", methods=["GET"]) @permission_required("kb_manage") def get_prompt_versions(prompt_id): """获取 Prompt 版本历史。""" result = admin_service.get_prompt_versions(prompt_id) return jsonify(result) @admin_bp.route("/prompts//rollback", methods=["POST"]) @permission_required("kb_manage") def rollback_prompt(prompt_id): """回滚到指定版本。""" data = request.get_json() version = data.get("version") if not version: return jsonify({"code": 1001, "message": "版本号不能为空", "data": None}), 400 result = admin_service.rollback_prompt(prompt_id, version) return jsonify(result) @admin_bp.route("/prompts/test", methods=["POST"]) @permission_required("kb_manage") def test_prompt(): """即时测试 Prompt 效果。""" data = request.get_json() result = admin_service.test_prompt(data) return jsonify(result) # ---- 方案模板管理 ---- from insurance.admin.template_service import TemplateService template_service = TemplateService() @admin_bp.route("/templates", methods=["GET"]) @permission_required("kb_manage") def list_templates(): """模板列表。""" params = { "page": request.args.get("page", 1, type=int), "page_size": request.args.get("page_size", 20, type=int), "insurance_type": request.args.get("insurance_type", ""), } result = template_service.list_templates(params) return jsonify(result) @admin_bp.route("/templates/", methods=["GET"]) @permission_required("kb_manage") def get_template(template_id): """获取模板详情。""" result = template_service.get_template(template_id) return jsonify(result) @admin_bp.route("/templates", methods=["POST"]) @permission_required("kb_manage") def create_template(): """创建模板。""" data = request.get_json() result = template_service.create_template(data) return jsonify(result) @admin_bp.route("/templates/", methods=["PUT"]) @permission_required("kb_manage") def update_template(template_id): """更新模板。""" data = request.get_json() result = template_service.update_template(template_id, data) return jsonify(result) @admin_bp.route("/templates/", methods=["DELETE"]) @permission_required("kb_manage") def delete_template(template_id): """删除模板。""" result = template_service.delete_template(template_id) return jsonify(result) @admin_bp.route("/templates/upload", methods=["POST"]) @permission_required("kb_manage") def upload_template(): """上传模板文件。""" file = request.files.get("file") data = { "name": request.form.get("name", ""), "description": request.form.get("description", ""), "insurance_type": request.form.get("insurance_type", ""), } result = template_service.upload_template(file, data) return jsonify(result) # ---- 通知告警配置 ---- from insurance.admin.notification_service import NotificationService notification_service = NotificationService() # ---- 部门/分组管理 ---- from insurance.admin.department_service import DepartmentService department_service = DepartmentService() @admin_bp.route("/departments", methods=["GET"]) @permission_required("user_manage") def list_departments(): """部门列表。""" result = department_service.list_departments() return jsonify(result) @admin_bp.route("/departments/tree", methods=["GET"]) @permission_required("user_manage") def get_department_tree(): """部门树形结构。""" result = department_service.get_department_tree() return jsonify(result) @admin_bp.route("/departments", methods=["POST"]) @permission_required("user_manage") def create_department(): """创建部门。""" data = request.get_json() result = department_service.create_department(data) return jsonify(result) @admin_bp.route("/departments/", methods=["PUT"]) @permission_required("user_manage") def update_department(dept_id): """更新部门。""" data = request.get_json() result = department_service.update_department(dept_id, data) return jsonify(result) @admin_bp.route("/departments/", methods=["DELETE"]) @permission_required("user_manage") def delete_department(dept_id): """删除部门。""" result = department_service.delete_department(dept_id) return jsonify(result) @admin_bp.route("/notification-channels", methods=["GET"]) @permission_required("config_manage") def list_notification_channels(): """通知渠道列表。""" result = notification_service.list_channels() return jsonify(result) @admin_bp.route("/notification-channels", methods=["POST"]) @permission_required("config_manage") def create_notification_channel(): """创建通知渠道。""" data = request.get_json() result = notification_service.create_channel(data) return jsonify(result) @admin_bp.route("/notification-channels/", methods=["PUT"]) @permission_required("config_manage") def update_notification_channel(channel_id): """更新通知渠道。""" data = request.get_json() result = notification_service.update_channel(channel_id, data) return jsonify(result) @admin_bp.route("/notification-channels/", methods=["DELETE"]) @permission_required("config_manage") def delete_notification_channel(channel_id): """删除通知渠道。""" result = notification_service.delete_channel(channel_id) return jsonify(result) @admin_bp.route("/notification-channels//test", methods=["POST"]) @permission_required("config_manage") def test_notification_channel(channel_id): """测试通知渠道。""" result = notification_service.test_channel(channel_id) return jsonify(result) @admin_bp.route("/alert-rules", methods=["GET"]) @permission_required("config_manage") def list_alert_rules(): """告警规则列表。""" result = notification_service.list_rules() return jsonify(result) @admin_bp.route("/alert-rules", methods=["POST"]) @permission_required("config_manage") def create_alert_rule(): """创建告警规则。""" data = request.get_json() result = notification_service.create_rule(data) return jsonify(result) @admin_bp.route("/alert-rules/", methods=["PUT"]) @permission_required("config_manage") def update_alert_rule(rule_id): """更新告警规则。""" data = request.get_json() result = notification_service.update_rule(rule_id, data) return jsonify(result) @admin_bp.route("/alert-rules/", methods=["DELETE"]) @permission_required("config_manage") def delete_alert_rule(rule_id): """删除告警规则。""" result = notification_service.delete_rule(rule_id) return jsonify(result) # ---- 日志查询(A7)—— 路径 /admin/logs/*,挂在 admin_bp 下 ---- from insurance.stats.service import StatsService stats_service = StatsService() @admin_bp.route("/logs/chat", methods=["GET"]) @permission_required("log_view") def chat_logs(): """问答记录查询。""" params = { "page": request.args.get("page", 1, type=int), "page_size": request.args.get("page_size", 50, type=int), "user_id": request.args.get("user_id", ""), "start_date": request.args.get("start_date", ""), "end_date": request.args.get("end_date", ""), "keyword": request.args.get("keyword", ""), "rating": request.args.get("rating", ""), } result = stats_service.get_chat_logs(params) return jsonify(result) @admin_bp.route("/logs/chat/export", methods=["GET"]) @permission_required("log_view") def export_chat_logs(): """导出对话记录为 CSV。""" from flask import Response params = { "user_id": request.args.get("user_id", ""), "start_date": request.args.get("start_date", ""), "end_date": request.args.get("end_date", ""), "keyword": request.args.get("keyword", ""), "rating": request.args.get("rating", ""), } csv_data = stats_service.export_chat_logs(params) return Response( csv_data, content_type="text/csv", headers={"Content-Disposition": "attachment; filename=chat_logs.csv"}, ) @admin_bp.route("/logs/system", methods=["GET"]) @permission_required("log_view") def system_logs(): """系统操作日志查询。""" params = { "page": request.args.get("page", 1, type=int), "page_size": request.args.get("page_size", 50, type=int), "action": request.args.get("action", ""), "user_id": request.args.get("user_id", ""), } result = stats_service.get_system_logs(params) return jsonify(result)