from flask import Blueprint, current_app, request, jsonify from sqlalchemy.exc import IntegrityError from app.models import User, Role, UserRole # 导入模型类 from app.utils import encrypt_password # 导入密码加密工具 from app import db from flask_jwt_extended import jwt_required, get_jwt_identity # 导入JWT相关工具 auth_bp = Blueprint("auth", __name__) @auth_bp.route("/create-user", methods=["POST"]) # @jwt_required() # 需要有效Token才能创建用户 def create_user(): """ { "username": "new_user", "password": "securePass123", "role_ids": [1, 3] // 要分配的角色ID列表 } """ data = request.get_json() # print(data) if not data or "username" not in data or "password" not in data: return jsonify({"error": "缺少用户名或密码"}), 400 # 1. 验证用户名唯一性 existing_user = User.query.filter_by(username=data["username"]).first() if existing_user: return jsonify({"error": "用户名已存在"}), 409 # 2. 获取当前操作者 # current_user_id = get_jwt_identity() current_user_id = 1 print("current_user_id", current_user_id) current_user = User.query.get(int(current_user_id)) current_user_id = 1 # if not current_user: # return jsonify({"error": "无效的操作者"}), 401 # 3. 密码复杂度验证 password = data["password"] if len(password) < 4 or not any(c.isdigit() for c in password): return jsonify({"error": "密码需至少4位且包含数字"}), 400 # 4. 验证角色(新增部分) role_ids = data.get("role_ids", []) valid_roles = [] if role_ids: valid_roles = Role.query.filter(Role.id.in_(role_ids)).all() if len(valid_roles) != len(role_ids): return jsonify({"error": "包含无效的角色ID"}), 400 try: # 5. 创建新用户 new_user = User( username=data["username"], password=encrypt_password(data["password"]), status=data.get("status", 1), created_by=current_user_id, email=data.get("email"), avatar=data.get("avatar"), region=data.get("region"), phone=data.get("phone"), brief=data.get("brief"), third_party_account=data.get("third_party_account"), position=data.get("position"), department=data.get("department"), label=data.get("label"), ) db.session.add(new_user) db.session.flush() # 获取新用户ID但不提交事务 # 6. 分配角色(新增核心功能) for role in valid_roles: user_role = UserRole( user_id=new_user.id, role_id=role.id, created_by=current_user_id ) db.session.add(user_role) db.session.commit() # 7. 构造响应数据(包含角色信息) response_data = { "id": new_user.id, "username": new_user.username, "created_at": new_user.created_at.isoformat(), "created_by": new_user.created_by, "roles": [ {"id": r.id, "name": r.name} for r in valid_roles ], # 新增角色信息 } # 8. 记录操作日志(新增角色信息) current_app.logger.info( f"用户创建成功: {new_user.username} (ID:{new_user.id}) " f"操作者: {current_user.username} (ID:{current_user_id}) " f"分配角色: {[r.name for r in valid_roles]}" # 记录分配的角色 ) return jsonify(response_data), 201 except Exception as e: db.session.rollback() current_app.logger.error(f"用户创建失败: {str(e)}") return jsonify({"error": "服务器内部错误"}), 500 # 2.修改用户 @auth_bp.route("/update-user", methods=["POST"]) def update_user(): """ 修改用户信息(支持更新所有字段,包括新增字段) 请求体示例: { "user_id":"12345", "username": "new_username", # 可选:修改用户名 "password": "new_password", # 可选:修改密码(明文) "status": 1, # 可选:修改状态 "updated_by": 1, # 更新人ID // 新增可选字段(需要更新的字段才传入) "email": "new@example.com", "phone": "+86 13987654321", "department": "产品部", "position": "产品经理", "label": "产品,管理" } """ data = request.get_json() user_id = data["user_id"] user = User.query.get(user_id) if not user: return jsonify({"code": 404, "message": f"用户ID {user_id} 不存在"}), 404 try: # 基础字段更新(原有逻辑保留) if "username" in data and data["username"]: user.username = data["username"] if "password" in data and data["password"]: user.password = encrypt_password(data["password"]) if "status" in data: user.status = data["status"] if "updated_by" in data: user.updated_by = data["updated_by"] # 新增字段更新(按需更新,仅处理传入的字段) if "email" in data: user.email = data["email"] if "avatar" in data: user.avatar = data["avatar"] if "region" in data: user.region = data["region"] if "phone" in data: user.phone = data["phone"] if "brief" in data: user.brief = data["brief"] if "third_party_account" in data: user.third_party_account = data["third_party_account"] if "position" in data: user.position = data["position"] if "department" in data: user.department = data["department"] if "label" in data: user.label = data["label"] db.session.commit() # 返回更新结果(包含核心字段和新增关键字段) return jsonify( { "code": 200, "message": "用户信息更新成功", "data": { "user_id": user.id, "username": user.username, "email": user.email, "phone": user.phone, "department": user.department, "updated_at": user.updated_at.strftime("%Y-%m-%d %H:%M:%S"), }, } ) except IntegrityError: db.session.rollback() return ( jsonify({"code": 409, "message": f'用户名"{data["username"]}"已存在'}), 409, ) except Exception as e: db.session.rollback() return jsonify({"code": 500, "message": f"更新失败:{str(e)}"}), 500 # 3. 创建角色 @auth_bp.route("/roles", methods=["POST"]) def create_role(): """ 创建新角色 请求体示例: { "name": "admin", # 角色名称(唯一) "description": "系统管理员", "status": 1, "created_by": 1 # 创建人ID } """ data = request.get_json() if not data.get("name"): return jsonify({"code": 400, "message": "角色名称不能为空"}), 400 try: new_role = Role( name=data["name"], description=data.get("description"), status=data.get("status", 1), created_by=data.get("created_by"), updated_by=data.get("created_by"), ) db.session.add(new_role) db.session.commit() return jsonify( { "code": 200, "message": "角色创建成功", "data": {"role_id": new_role.id, "name": new_role.name}, } ) except IntegrityError: db.session.rollback() return jsonify({"code": 409, "message": f'角色"{data["name"]}"已存在'}), 409 except Exception as e: db.session.rollback() return jsonify({"code": 500, "message": f"创建失败:{str(e)}"}), 500 # 4. 修改角色 @auth_bp.route("/roles/", methods=["PUT"]) def update_role(role_id): """ 修改角色信息 请求体示例: { "name": "super_admin", # 可选:修改角色名称 "description": "超级管理员", # 可选:修改描述 "status": 1, # 可选:修改状态(1-启用,0-禁用) "updated_by": 1 # 更新人ID } """ data = request.get_json() role = Role.query.get(role_id) if not role: return jsonify({"code": 404, "message": f"角色ID {role_id} 不存在"}), 404 try: if "name" in data and data["name"]: role.name = data["name"] if "description" in data: role.description = data["description"] if "status" in data: role.status = data["status"] if "updated_by" in data: role.updated_by = data["updated_by"] db.session.commit() return jsonify( { "code": 200, "message": "角色信息更新成功", "data": {"role_id": role.id, "name": role.name}, } ) except IntegrityError: db.session.rollback() return jsonify({"code": 409, "message": f'角色"{data["name"]}"已存在'}), 409 except Exception as e: db.session.rollback() return jsonify({"code": 500, "message": f"更新失败:{str(e)}"}), 500 # 5. 给用户分配角色(补充功能:用户-角色关联) @auth_bp.route("/user-roles", methods=["POST"]) def assign_role_to_user(): """ 给用户分配角色(多对多关联) 请求体示例: { "user_id": 1, "role_id": 2, "created_by": 1 # 操作人ID } """ data = request.get_json() user_id = data.get("user_id") role_id = data.get("role_id") # 校验用户和角色是否存在 if not User.query.get(user_id): return jsonify({"code": 404, "message": f"用户ID {user_id} 不存在"}), 404 if not Role.query.get(role_id): return jsonify({"code": 404, "message": f"角色ID {role_id} 不存在"}), 404 try: # 检查是否已关联 existing = UserRole.query.filter_by(user_id=user_id, role_id=role_id).first() if existing: return ( jsonify( {"code": 409, "message": f"用户ID {user_id} 已拥有角色ID {role_id}"} ), 409, ) # 创建关联 user_role = UserRole( user_id=user_id, role_id=role_id, created_by=data.get("created_by") ) db.session.add(user_role) db.session.commit() return jsonify({"code": 200, "message": "角色分配成功"}) except Exception as e: db.session.rollback() return jsonify({"code": 500, "message": f"分配失败:{str(e)}"}), 500