diff --git a/inventory-backend/app/api/v1/auth.py b/inventory-backend/app/api/v1/auth.py index 0b981ad..c5aafc6 100644 --- a/inventory-backend/app/api/v1/auth.py +++ b/inventory-backend/app/api/v1/auth.py @@ -19,12 +19,6 @@ def login(): # 调用 Service 层逻辑 result = AuthService.login(data) - # [关键修复] - # 前端 store 代码写的是: token.value = res.data.access_token - # 所以我们这里不能把 access_token 包裹在 data 字段里, - # 而是应该直接合并返回,或者让前端去 data.data 里面取。 - # 为了不改前端,我们这里做解构返回: - response_data = { 'msg': '登录成功', 'access_token': result.get('access_token'), @@ -34,34 +28,51 @@ def login(): return jsonify(response_data), 200 except ValueError as ve: - # 捕获已知的业务错误(如密码错误、用户不存在) return jsonify({'msg': str(ve)}), 401 except Exception as e: - # [关键修复] 打印详细报错到控制台,方便排查 500 错误 - # (例如数据库连接失败、表不存在等) current_app.logger.error(f"Login Failed Error: {str(e)}") - # 生产环境不建议直接把 error 返回给前端,但调试阶段很有用 return jsonify({'msg': f'服务器内部错误: {str(e)}'}), 500 -# 新增:创建用户 (替代了原来的注册) @auth_bp.route('/user/create', methods=['POST']) -@jwt_required() # 必须携带 Token +@jwt_required() def create_user(): try: data = request.get_json() - - # 从 Token 中获取当前操作人的角色 claims = get_jwt() operator_role = claims.get('role') - # 增加一个简单的权限判断(可选) - if operator_role not in ['super_admin', 'supervisor']: - return jsonify({'msg': '权限不足,无法创建用户'}), 403 - result = AuthService.create_user(data, operator_role) return jsonify({'msg': '用户创建成功', 'data': result}), 201 except Exception as e: current_app.logger.error(f"User Create Failed: {str(e)}") + return jsonify({'msg': str(e)}), 400 + + +# [新增] 获取用户列表 +@auth_bp.route('/users', methods=['GET']) +@jwt_required() +def get_users(): + try: + # 这里可以添加分页逻辑,目前先返回所有 + users = AuthService.get_all_users() + return jsonify({'msg': '获取成功', 'data': users}), 200 + except Exception as e: + current_app.logger.error(f"Get Users Failed: {str(e)}") + return jsonify({'msg': '获取用户列表失败'}), 500 + + +# [新增] 删除用户 +@auth_bp.route('/user/', methods=['DELETE']) +@jwt_required() +def delete_user(user_id): + try: + claims = get_jwt() + operator_role = claims.get('role') + + AuthService.delete_user(user_id, operator_role) + return jsonify({'msg': '删除成功'}), 200 + except Exception as e: + current_app.logger.error(f"Delete User Failed: {str(e)}") return jsonify({'msg': str(e)}), 400 \ No newline at end of file diff --git a/inventory-backend/app/models/system.py b/inventory-backend/app/models/system.py index f4ce720..40b5a45 100644 --- a/inventory-backend/app/models/system.py +++ b/inventory-backend/app/models/system.py @@ -8,11 +8,13 @@ class SysUser(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(100), nullable=False) + # 注意:如果允许邮箱为空,建议去掉 unique=True 或者在数据库层面处理空字符串 email = db.Column(db.String(100), unique=True) department = db.Column(db.String(100)) role = db.Column(db.String(50)) status = db.Column(db.String(20), default='active') password_hash = db.Column(db.Text) + created_at = db.Column(db.DateTime, default=datetime.now) # 新增创建时间 def set_password(self, password): """生成加密密码""" @@ -30,7 +32,8 @@ class SysUser(db.Model): 'email': self.email, 'department': self.department, 'role': self.role, - 'status': self.status + 'status': self.status, + 'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else '' } class SysLog(db.Model): diff --git a/inventory-backend/app/services/auth_service.py b/inventory-backend/app/services/auth_service.py index 40fe7ee..82e2b6b 100644 --- a/inventory-backend/app/services/auth_service.py +++ b/inventory-backend/app/services/auth_service.py @@ -1,8 +1,7 @@ # app/services/auth_service.py from app.models.system import SysUser from app.extensions import db -from flask_jwt_extended import create_access_token, get_jwt_identity, get_jwt -from werkzeug.security import check_password_hash +from flask_jwt_extended import create_access_token from app.utils.constants import UserRole @@ -46,8 +45,7 @@ class AuthService: user_id = user.id user_info = user.to_dict() - # 3. 生成 Token,将角色写入 claims (关键步骤:用于后期权限控制) - # identity 存 ID,additional_claims 存角色 + # 3. 生成 Token access_token = create_access_token( identity=user_id, additional_claims={'role': user_role, 'username': username} @@ -62,8 +60,6 @@ class AuthService: def create_user(data, operator_role): """ 创建新用户 (仅限管理员使用) - :param data: 新用户数据 - :param operator_role: 当前操作人的角色 (从 Token 获取) """ # 简单权限控制:只有超级管理员或主管可以创建用户 if operator_role not in [UserRole.SUPER_ADMIN, UserRole.SUPERVISOR]: @@ -75,14 +71,18 @@ class AuthService: # 默认角色处理 role = data.get('role') - # 验证角色是否合法 valid_roles = [v for k, v in UserRole.__dict__.items() if not k.startswith('__')] if role not in valid_roles: raise Exception(f"角色无效,可选角色: {valid_roles}") + # 处理 Email 为空的情况,避免违反 Unique 约束 (视数据库设置而定,这里简单处理为空串) + email = data.get('email', '') + if email and SysUser.query.filter_by(email=email).first(): + raise Exception("邮箱已被使用") + new_user = SysUser( username=data.get('username'), - email=data.get('email', ''), # 允许为空 + email=email, department=data.get('department', ''), role=role, status='active' @@ -92,4 +92,24 @@ class AuthService: db.session.add(new_user) db.session.commit() - return new_user.to_dict() \ No newline at end of file + return new_user.to_dict() + + @staticmethod + def get_all_users(): + """获取所有系统用户""" + users = SysUser.query.order_by(SysUser.id.desc()).all() + return [user.to_dict() for user in users] + + @staticmethod + def delete_user(user_id, operator_role): + """删除用户""" + if operator_role not in [UserRole.SUPER_ADMIN, UserRole.SUPERVISOR]: + raise Exception("权限不足") + + user = SysUser.query.get(user_id) + if not user: + raise Exception("用户不存在") + + db.session.delete(user) + db.session.commit() + return True \ No newline at end of file diff --git a/inventory-web/src/api/auth.ts b/inventory-web/src/api/auth.ts index 496d79c..32de91f 100644 --- a/inventory-web/src/api/auth.ts +++ b/inventory-web/src/api/auth.ts @@ -1,31 +1,43 @@ import request from '@/utils/request' -// 登录 (兼容 IRIS 超级管理员和普通用户) +// 登录 export function login(data: any) { return request({ - // 【修改】去掉开头的 /api,因为 request.ts 的 baseURL 已经包含了 /api - // 最终请求地址会自动拼接为:/api/v1/auth/login url: '/v1/auth/login', method: 'post', data }) } -// 创建用户 (管理员专用接口) +// 创建用户 (管理员专用) export function createUser(data: any) { return request({ - // 【修改】去掉开头的 /api url: '/v1/auth/user/create', method: 'post', data }) } -// 获取用户信息 (用于页面刷新后拉取最新权限) +// 获取当前登录用户信息 export function getUserInfo() { return request({ - // 【修改】去掉开头的 /api url: '/v1/auth/me', method: 'get' }) +} + +// [新增] 获取所有用户列表 +export function getUserList() { + return request({ + url: '/v1/auth/users', + method: 'get' + }) +} + +// [新增] 删除用户 +export function deleteUser(id: number) { + return request({ + url: `/v1/auth/user/${id}`, + method: 'delete' + }) } \ No newline at end of file diff --git a/inventory-web/src/views/system/UserCreate.vue b/inventory-web/src/views/system/UserCreate.vue index 6df0eca..a5966d1 100644 --- a/inventory-web/src/views/system/UserCreate.vue +++ b/inventory-web/src/views/system/UserCreate.vue @@ -3,67 +3,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - + + - - - - - - - + + + + + + + -
注意:超级管理员无法通过此界面创建,请联系开发人员。
- - - 创建账号 - 重置 -
- + + +
\ No newline at end of file