2025-11-11 21:39:12 +08:00
|
|
|
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
|
2025-11-13 16:51:51 +08:00
|
|
|
from .decorators import require_admin
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
@api_bp.route('/tickets', methods=['GET'])
|
|
|
|
|
@require_admin
|
|
|
|
|
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)
|
2025-11-12 15:11:05 +08:00
|
|
|
product_id = request.args.get('product_id') # 修复:确保参数名与前端一致
|
2025-11-11 21:39:12 +08:00
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
|
|
|
|
return jsonify({
|
|
|
|
|
'success': True,
|
|
|
|
|
'message': '工单创建成功',
|
|
|
|
|
'data': ticket.to_dict()
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
db.session.rollback()
|
|
|
|
|
current_app.logger.error(f"创建工单失败: {str(e)}")
|
2025-11-12 15:11:05 +08:00
|
|
|
return jsonify({'success': False, 'message': '服务器内部错误'}), 500
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@api_bp.route('/tickets/batch/status', methods=['PUT'])
|
|
|
|
|
@require_admin
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
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': '服务器内部错误'
|
2025-11-13 16:51:51 +08:00
|
|
|
}), 500
|