from flask import request, jsonify, current_app from datetime import datetime from app import db from app.models import Ticket, Product from . import api_bp from .decorators import require_login, require_admin from app.utils.logger import log_operation @api_bp.route('/tickets', methods=['GET']) @require_login def get_tickets(): """获取工单列表""" try: page = request.args.get('page', 1, type=int) per_page = min(request.args.get('per_page', 20, type=int), 100) status = request.args.get('status', type=int) priority = request.args.get('priority', type=int) product_id = request.args.get('product_id') # 修复:确保参数名与前端一致 keyword = request.args.get('keyword', '').strip() query = Ticket.query if status is not None: query = query.filter_by(status=status) if priority is not None: query = query.filter_by(priority=priority) if product_id: query = query.filter_by(product_id=product_id) if keyword: query = query.filter(Ticket.title.like(f'%{keyword}%')) query = query.order_by(Ticket.create_time.desc()) pagination = query.paginate(page=page, per_page=per_page, error_out=False) tickets = [ticket.to_dict() for ticket in pagination.items] return jsonify({ 'success': True, 'data': { 'tickets': tickets, 'pagination': { 'page': page, 'per_page': per_page, 'total': pagination.total, 'pages': pagination.pages } } }) except Exception as e: current_app.logger.error(f"获取工单列表失败: {str(e)}") return jsonify({'success': False, 'message': '服务器内部错误'}), 500 @api_bp.route('/tickets', methods=['POST']) def create_ticket(): """创建工单(用户接口)""" try: data = request.get_json() if not data: return jsonify({'success': False, 'message': '请求数据为空'}), 400 title = data.get('title', '').strip() product_id = data.get('product_id') description = data.get('description', '').strip() if not all([title, product_id, description]): return jsonify({'success': False, 'message': '缺少必要参数'}), 400 # 验证产品存在 product = Product.query.filter_by(product_id=product_id).first() if not product: return jsonify({'success': False, 'message': '产品不存在'}), 404 ticket = Ticket( title=title, product_id=product_id, software_version=data.get('software_version'), machine_code=data.get('machine_code'), license_key=data.get('license_key'), description=description, priority=data.get('priority', 1) ) db.session.add(ticket) db.session.commit() # 记录操作日志 log_operation('CREATE_TICKET', 'TICKET', ticket.ticket_id, { 'title': ticket.title, 'product_id': ticket.product_id }) return jsonify({ 'success': True, 'message': '工单创建成功', 'data': ticket.to_dict() }) except Exception as e: db.session.rollback() current_app.logger.error(f"创建工单失败: {str(e)}") return jsonify({'success': False, 'message': '服务器内部错误'}), 500 @api_bp.route('/tickets/batch/status', methods=['PUT']) @require_login def batch_update_ticket_status(): """批量更新工单状态""" try: data = request.get_json() if not data or 'ticket_ids' not in data or 'status' not in data: return jsonify({ 'success': False, 'message': '请求数据为空或缺少ticket_ids/status字段' }), 400 ticket_ids = data['ticket_ids'] status = data['status'] remark = data.get('remark', '') if not isinstance(ticket_ids, list) or len(ticket_ids) == 0: return jsonify({ 'success': False, 'message': 'ticket_ids必须是非空列表' }), 400 if status not in [0, 1, 2, 3]: return jsonify({ 'success': False, 'message': 'status必须是0(待处理)、1(处理中)、2(已解决)或3(已关闭)' }), 400 # 查找所有要更新的工单 tickets = Ticket.query.filter(Ticket.ticket_id.in_(ticket_ids)).all() if len(tickets) != len(ticket_ids): found_ids = [t.ticket_id for t in tickets] missing_ids = [tid for tid in ticket_ids if tid not in found_ids] return jsonify({ 'success': False, 'message': f'以下工单不存在: {", ".join(map(str, missing_ids))}' }), 404 # 批量更新工单状态 for ticket in tickets: ticket.update_status(status, remark) # 记录操作日志 ticket_ids = [ticket.ticket_id for ticket in tickets] log_operation('BATCH_UPDATE_TICKET_STATUS', 'TICKET', None, { 'ticket_ids': ticket_ids, 'status': status, 'count': len(tickets) }) status_names = {0: '待处理', 1: '处理中', 2: '已解决', 3: '已关闭'} status_name = status_names.get(status, '未知') return jsonify({ 'success': True, 'message': f'成功将 {len(tickets)} 个工单状态更新为{status_name}' }) except Exception as e: db.session.rollback() current_app.logger.error(f"批量更新工单状态失败: {str(e)}") return jsonify({ 'success': False, 'message': '服务器内部错误' }), 500