333 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			333 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from flask import Blueprint, request, jsonify, g, current_app
 | ||
| import sqlite3
 | ||
| from datetime import datetime
 | ||
| 
 | ||
| bp = Blueprint('personnel', __name__, url_prefix='/personnel')
 | ||
| 
 | ||
| # 定义全局有效的权限级别
 | ||
| VALID_PERMISSIONS = {'Admin', 'Supervisor', 'Operator'}
 | ||
| 
 | ||
| # 数据库连接
 | ||
| def get_db():
 | ||
|     if 'db' not in g:
 | ||
|         g.db = sqlite3.connect(
 | ||
|             current_app.config['DATABASE'],
 | ||
|             check_same_thread=False
 | ||
|         )
 | ||
|         g.db.row_factory = sqlite3.Row
 | ||
|     return g.db
 | ||
| 
 | ||
| # 关闭数据库连接
 | ||
| @bp.teardown_request
 | ||
| def close_db_connection(exception=None):
 | ||
|     db = g.pop('db', None)
 | ||
|     if db is not None:
 | ||
|         db.close()
 | ||
| 
 | ||
| # 创建表(初始化数据库)
 | ||
| @bp.cli.command('init-db')
 | ||
| def init_db():
 | ||
|     schema = """
 | ||
|     CREATE TABLE IF NOT EXISTS user (
 | ||
|         id INTEGER PRIMARY KEY AUTOINCREMENT,
 | ||
|         username TEXT UNIQUE NOT NULL,
 | ||
|         password TEXT NOT NULL,
 | ||
|         permission_level TEXT NOT NULL CHECK (permission_level IN ('Admin', 'Supervisor', 'Operator')),
 | ||
|         hire_date TEXT NOT NULL,
 | ||
|         email TEXT,
 | ||
|         phone TEXT,
 | ||
|         status TEXT DEFAULT 'Active',
 | ||
|         linked_devices INTEGER DEFAULT 0,
 | ||
|         created_by TEXT,
 | ||
|         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 | ||
|     );
 | ||
| 
 | ||
|     CREATE TABLE IF NOT EXISTS operation_log (
 | ||
|         id INTEGER PRIMARY KEY AUTOINCREMENT,
 | ||
|         user_id INTEGER NOT NULL,
 | ||
|         type TEXT NOT NULL,
 | ||
|         message TEXT NOT NULL,
 | ||
|         details TEXT,
 | ||
|         timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | ||
|         FOREIGN KEY (user_id) REFERENCES user (id)
 | ||
|     );
 | ||
|     """
 | ||
|     with current_app.open_resource('schema.sql', mode='w') as f:
 | ||
|         f.write(schema)
 | ||
|     get_db().executescript(schema)
 | ||
|     print("数据库初始化完成")
 | ||
| 
 | ||
| # 用户列表接口
 | ||
| @bp.route('/users', methods=['GET'])
 | ||
| def get_users():
 | ||
|     try:
 | ||
|         db = get_db()
 | ||
|         cursor = db.cursor()
 | ||
|         query = """
 | ||
|             SELECT 
 | ||
|                 id,
 | ||
|                 username,
 | ||
|                 email,
 | ||
|                 phone,
 | ||
|                 permission_level,
 | ||
|                 DATE(hire_date) AS hire_date,
 | ||
|                 status,
 | ||
|                 linked_devices
 | ||
|             FROM user
 | ||
|             ORDER BY 
 | ||
|                 CASE permission_level 
 | ||
|                     WHEN 'Admin' THEN 1
 | ||
|                     WHEN 'Supervisor' THEN 2
 | ||
|                     WHEN 'Operator' THEN 3
 | ||
|                 END, 
 | ||
|                 hire_date DESC
 | ||
|         """
 | ||
|         filter_permission = request.args.get('filter_permission')
 | ||
|         if filter_permission and filter_permission != 'all':
 | ||
|             cursor.execute(query + " WHERE permission_level = ?", (filter_permission,))
 | ||
|         else:
 | ||
|             cursor.execute(query)
 | ||
|         users = cursor.fetchall()
 | ||
|         return jsonify({
 | ||
|             'code': 200,
 | ||
|             'data': [dict(user) for user in users]
 | ||
|         })
 | ||
|     except sqlite3.Error as e:
 | ||
|         current_app.logger.error(f"获取用户列表错误: {str(e)}")
 | ||
|         return jsonify({'code': 500, 'message': '服务器内部错误'}), 500
 | ||
| 
 | ||
| # 添加用户接口
 | ||
| @bp.route('/users', methods=['POST'])
 | ||
| def add_user():
 | ||
|     data = request.json
 | ||
|     # 明确必填字段(包括 password)
 | ||
|     required_fields = ['username', 'permissionLevel', 'hire_date', 'password']
 | ||
|     for field in required_fields:
 | ||
|         if not data.get(field):
 | ||
|             return jsonify({
 | ||
|                 'code': 400,
 | ||
|                 'message': f'缺少必填字段: {field}'
 | ||
|             }), 400
 | ||
| 
 | ||
|     permission = data['permissionLevel']
 | ||
|     if permission not in VALID_PERMISSIONS:  # 修改:使用全局常量
 | ||
|         current_app.logger.error(f"无效权限级别: {data['permissionLevel']}")
 | ||
|         return jsonify({
 | ||
|             'code': 400,
 | ||
|             'message': '权限级别格式错误,请使用Admin、Supervisor或Operator'
 | ||
|         }), 400
 | ||
| 
 | ||
|     try:
 | ||
|         db = get_db()
 | ||
|         cursor = db.cursor()
 | ||
|         # 插入所有字段(包括 email、phone)
 | ||
|         cursor.execute(
 | ||
|             """INSERT INTO user (
 | ||
|                 username, 
 | ||
|                 password, 
 | ||
|                 permission_level, 
 | ||
|                 hire_date, 
 | ||
|                 email, 
 | ||
|                 phone
 | ||
|             ) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(username) DO NOTHING""",
 | ||
|             (
 | ||
|                 data['username'],
 | ||
|                 data['password'],
 | ||
|                 permission,
 | ||
|                 data['hire_date'],
 | ||
|                 data.get('email', ''),  # 允许为空
 | ||
|                 data.get('phone', '')   # 允许为空
 | ||
|             )
 | ||
|         )
 | ||
|         db.commit()
 | ||
| 
 | ||
|         if cursor.rowcount == 0:
 | ||
|             return jsonify({
 | ||
|                 'code': 400,
 | ||
|                 'message': '用户名已存在'
 | ||
|             }), 400
 | ||
| 
 | ||
|         # 记录操作日志
 | ||
|         cursor.execute(
 | ||
|             "INSERT INTO operation_log (user_id, type, message) VALUES (?, ?, ?)",
 | ||
|             (cursor.lastrowid, 'USER_CREATE', f'创建用户 {data["username"]}')
 | ||
|         )
 | ||
|         db.commit()
 | ||
| 
 | ||
|         return jsonify({
 | ||
|             'code': 201,
 | ||
|             'message': '用户创建成功'
 | ||
|         }), 201
 | ||
| 
 | ||
|     except sqlite3.IntegrityError as e:
 | ||
|         if 'CHECK constraint failed' in str(e):
 | ||
|             return jsonify({
 | ||
|                 'code': 400,
 | ||
|                 'message': '权限级别格式错误,请使用Admin、Supervisor或Operator'
 | ||
|             }), 400
 | ||
|         else:
 | ||
|             current_app.logger.error(f"添加用户错误: {str(e)}")
 | ||
|             db.rollback()
 | ||
|             return jsonify({
 | ||
|                 'code': 500,
 | ||
|                 'message': '服务器内部错误'
 | ||
|             }), 500
 | ||
|     except sqlite3.Error as e:
 | ||
|         current_app.logger.error(f"添加用户错误: {str(e)}")
 | ||
|         db.rollback()
 | ||
|         return jsonify({
 | ||
|             'code': 500,
 | ||
|             'message': '服务器内部错误'
 | ||
|         }), 500
 | ||
| 
 | ||
| # 编辑用户接口
 | ||
| @bp.route('/users/<string:username>', methods=['PUT'])
 | ||
| def edit_user(username):
 | ||
|     data = request.json
 | ||
|     db = get_db()
 | ||
|     cursor = db.cursor()
 | ||
|     cursor.execute("SELECT id FROM user WHERE username = ?", (username,))
 | ||
|     user = cursor.fetchone()
 | ||
|     if not user:
 | ||
|         return jsonify({
 | ||
|             'code': 404,
 | ||
|             'message': '用户不存在'
 | ||
|         }), 404
 | ||
| 
 | ||
|     update_fields = []
 | ||
|     params = []
 | ||
| 
 | ||
|     # 处理权限级别
 | ||
|     if 'permissionLevel' in data:
 | ||
|         permission = data['permissionLevel']
 | ||
|         if permission not in VALID_PERMISSIONS:  # 修改:使用全局常量
 | ||
|             return jsonify({
 | ||
|                 'code': 400,
 | ||
|                 'message': '权限级别格式错误,请使用Admin、Supervisor或Operator'
 | ||
|             }), 400
 | ||
|         update_fields.append("permission_level = ?")
 | ||
|         params.append(permission)
 | ||
| 
 | ||
|     # 处理其他字段
 | ||
|     if 'hire_date' in data:
 | ||
|         update_fields.append("hire_date = ?")
 | ||
|         params.append(data['hire_date'])
 | ||
|     if 'linkedDevices' in data:
 | ||
|         update_fields.append("linked_devices = ?")
 | ||
|         params.append(data['linkedDevices'])
 | ||
|     if 'status' in data:
 | ||
|         update_fields.append("status = ?")
 | ||
|         params.append(data['status'])
 | ||
|     if 'email' in data:
 | ||
|         update_fields.append("email = ?")
 | ||
|         params.append(data['email'])
 | ||
|     if 'phone' in data:
 | ||
|         update_fields.append("phone = ?")
 | ||
|         params.append(data['phone'])
 | ||
|     if 'password' in data:  # 允许修改密码
 | ||
|         update_fields.append("password = ?")
 | ||
|         params.append(data['password'])
 | ||
| 
 | ||
|     if not update_fields:
 | ||
|         return jsonify({
 | ||
|             'code': 400,
 | ||
|             'message': '未提供更新字段'
 | ||
|         }), 400
 | ||
| 
 | ||
|     params.append(username)
 | ||
|     query = f"UPDATE user SET {', '.join(update_fields)} WHERE username = ?"
 | ||
|     try:
 | ||
|         cursor.execute(query, params)
 | ||
|         db.commit()
 | ||
| 
 | ||
|         # 记录操作日志
 | ||
|         cursor.execute(
 | ||
|             "INSERT INTO operation_log (user_id, type, message) VALUES (?, ?, ?)",
 | ||
|             (user['id'], 'USER_UPDATE', f'更新用户 {username}')
 | ||
|         )
 | ||
|         db.commit()
 | ||
| 
 | ||
|         return jsonify({
 | ||
|             'code': 200,
 | ||
|             'message': '更新成功'
 | ||
|         }), 200
 | ||
| 
 | ||
|     except sqlite3.Error as e:
 | ||
|         current_app.logger.error(f"编辑用户错误: {str(e)}")
 | ||
|         db.rollback()
 | ||
|         return jsonify({
 | ||
|             'code': 500,
 | ||
|             'message': '服务器内部错误'
 | ||
|         }), 500
 | ||
| 
 | ||
| # 删除用户接口
 | ||
| @bp.route('/users/<string:username>', methods=['DELETE'])
 | ||
| def delete_user(username):
 | ||
|     db = get_db()
 | ||
|     cursor = db.cursor()
 | ||
|     cursor.execute("SELECT id FROM user WHERE username = ?", (username,))
 | ||
|     user = cursor.fetchone()
 | ||
|     if not user:
 | ||
|         return jsonify({
 | ||
|             'code': 404,
 | ||
|             'message': '用户不存在'
 | ||
|         }), 404
 | ||
| 
 | ||
|     if username == 'root':
 | ||
|         return jsonify({
 | ||
|             'code': 403,
 | ||
|             'message': '禁止删除root用户'
 | ||
|         }), 403
 | ||
| 
 | ||
|     try:
 | ||
|         cursor.execute("DELETE FROM user WHERE username = ?", (username,))
 | ||
|         db.commit()
 | ||
| 
 | ||
|         # 记录操作日志
 | ||
|         cursor.execute(
 | ||
|             "INSERT INTO operation_log (user_id, type, message) VALUES (?, ?, ?)",
 | ||
|             (user['id'], 'USER_DELETE', f'删除用户 {username}')
 | ||
|         )
 | ||
|         db.commit()
 | ||
| 
 | ||
|         return jsonify({
 | ||
|             'code': 200,
 | ||
|             'message': '用户删除成功'
 | ||
|         }), 200
 | ||
| 
 | ||
|     except sqlite3.Error as e:
 | ||
|         current_app.logger.error(f"删除用户错误: {str(e)}")
 | ||
|         db.rollback()
 | ||
|         return jsonify({
 | ||
|             'code': 500,
 | ||
|             'message': '服务器内部错误'
 | ||
|         }), 500
 | ||
| 
 | ||
| # 操作日志接口
 | ||
| @bp.route('/logs', methods=['GET'])
 | ||
| def get_logs():
 | ||
|     try:
 | ||
|         db = get_db()
 | ||
|         cursor = db.cursor()
 | ||
|         query = """
 | ||
|             SELECT 
 | ||
|                 id,
 | ||
|                 strftime('%Y-%m-%d %H:%M:%S', timestamp) AS timestamp,
 | ||
|                 type,
 | ||
|                 message,
 | ||
|                 (SELECT username FROM user WHERE id = user_id) AS user
 | ||
|             FROM operation_log
 | ||
|             ORDER BY timestamp DESC  -- 按时间降序排列
 | ||
|         """
 | ||
|         cursor.execute(query)
 | ||
|         logs = cursor.fetchall()
 | ||
|         return jsonify({
 | ||
|             'code': 200,
 | ||
|             'data': [dict(log) for log in logs]
 | ||
|         })
 | ||
|     except sqlite3.Error as e:
 | ||
|         current_app.logger.error(f"获取日志错误: {str(e)}")
 | ||
|         return jsonify({
 | ||
|             'code': 500,
 | ||
|             'message': '服务器内部错误'
 | ||
|         }), 500 | 
