from flask import render_template, request, redirect, url_for, flash, jsonify from flask_login import login_required, current_user from scripts.models import db, Device, WorkOrder, WorkOrderHandling from datetime import datetime import os from utils.file_utils import allowed_file, compress_image from utils.lzmx import send_lzmx_message from config import Config def init_work_order_routes(app): # 添加获取支局列表的辅助函数 def get_branches(): branches = db.session.query(Device.branch).distinct().all() return [branch[0] for branch in branches if branch[0]] # 派单平台路由 @app.route('/dispatch', methods=['GET', 'POST']) @login_required def dispatch(): if current_user.role not in ['装维员', '统计员']: flash('您没有权限访问此页面') return redirect(url_for('statistics')) # 处理 POST 请求 if request.method == 'POST': device_ids = request.form.getlist('device_ids') if not device_ids: flash('请选择至少一个设备') return redirect(url_for('dispatch')) today = datetime.now().strftime('%Y%m%d') last_work_order = WorkOrder.query.filter(WorkOrder.order_id.like(f'{today}%')).order_by(WorkOrder.order_id.desc()).first() # 获取起始编号 if last_work_order: last_number = int(last_work_order.order_id[-4:]) start_number = last_number + 1 else: start_number = 1 # 为每个设备生成唯一的工单号 for index, device_id in enumerate(device_ids): device = db.session.get(Device, device_id) if not device: continue current_number = start_number + index new_number = f"{today}{str(current_number).zfill(4)}" work_order = WorkOrder( order_id=new_number, device_id=device_id, dispatch_time=datetime.now(), status='待处理', branch=device.branch ) db.session.add(work_order) device.is_normal = False db.session.add(device) db.session.commit() flash('派单成功') return redirect(url_for('dispatch')) # 处理 GET 请求 # 获取分页参数 page = request.args.get('page', 1, type=int) per_page = request.args.get('per_page', 50, type=int) # 从请求参数中获取每页显示数量 # 获取搜索词和筛选条件 search = request.args.get('search', '') selected_town = request.args.get('town', '') selected_branch = request.args.get('branch', '') towns = db.session.query(Device.town).distinct().all() towns = [town[0] for town in towns if town[0]] branches = db.session.query(Device.branch).distinct().all() branches = [branch[0] for branch in branches if branch[0]] query = Device.query if search: query = query.filter( (Device.device_id.contains(search)) | (Device.town.contains(search)) | (Device.branch.contains(search)) | (Device.unit_name.contains(search)) | (Device.project_type.contains(search)) | (Device.device_type.contains(search)) | (Device.remark.contains(search)) ) if selected_town: query = query.filter(Device.town == selected_town) if selected_branch: query = query.filter(Device.branch == selected_branch) # 分页时使用从请求获取的 per_page 参数 devices = query.filter_by(in_use=True).paginate(page=page, per_page=per_page) return render_template('dispatch.html', devices=devices, towns=towns, branches=branches) @app.route('/update_device_remark', methods=['POST']) @login_required def update_device_remark(): try: data = request.get_json() device_id = data.get('device_id') remark = data.get('remark', '') device = Device.query.get(device_id) if not device: return jsonify({'success': False, 'message': '设备不存在'}) device.remark = remark db.session.commit() return jsonify({'success': True}) except Exception as e: return jsonify({'success': False, 'message': str(e)}) # 接单平台路由 @app.route('/receive') @login_required def receive(): page = request.args.get('page', 1, type=int) per_page = request.args.get('per_page', 50, type=int) branch = request.args.get('branch', '') device_type = request.args.get('device_type', '') project_type = request.args.get('project_type', '') # 基础查询,直接join Device表 query = WorkOrder.query.join(Device).filter(WorkOrder.status == '待处理') # 根据用户权限筛选工单 if current_user.branch != '交付中心': query = query.filter(Device.branch == current_user.branch) # 应用分支筛选(仅交付中心可用) if branch and current_user.branch == '交付中心': query = query.filter(Device.branch == branch) # 应用设备类型筛选 if device_type: query = query.filter(Device.device_type == device_type) # 应用项目类型筛选 if project_type: query = query.filter(Device.project_type == project_type) # 获取总数统计(使用相同的筛选条件) total_orders = query.count() # 获取各支局统计 branch_stats = {} if current_user.branch == '交付中心': branch_counts = db.session.query( Device.branch, db.func.count(WorkOrder.order_id) ).join(WorkOrder, WorkOrder.device_id == Device.device_id ).filter(WorkOrder.status == '待处理' ).group_by(Device.branch).all() branch_stats = dict(branch_counts) # 获取筛选选项 - 修正查询方向 device_types_query = db.session.query(Device.device_type).distinct().filter( Device.device_id.in_( db.session.query(WorkOrder.device_id).filter(WorkOrder.status == '待处理') ) ) project_types_query = db.session.query(Device.project_type).distinct().filter( Device.device_id.in_( db.session.query(WorkOrder.device_id).filter(WorkOrder.status == '待处理') ) ) # 根据用户权限进一步筛选选项 if current_user.branch != '交付中心': device_types_query = device_types_query.filter(Device.branch == current_user.branch) project_types_query = project_types_query.filter(Device.branch == current_user.branch) elif branch: device_types_query = device_types_query.filter(Device.branch == branch) project_types_query = project_types_query.filter(Device.branch == branch) device_types = [dt[0] for dt in device_types_query.all() if dt[0]] project_types = [pt[0] for pt in project_types_query.all() if pt[0]] # 获取设备类型统计 device_type_stats = {} if device_types: device_type_counts = db.session.query( Device.device_type, db.func.count(WorkOrder.order_id) ).join(WorkOrder, WorkOrder.device_id == Device.device_id ).filter(WorkOrder.status == '待处理') # 应用同样的权限筛选 if current_user.branch != '交付中心': device_type_counts = device_type_counts.filter(Device.branch == current_user.branch) elif branch: device_type_counts = device_type_counts.filter(Device.branch == branch) device_type_counts = device_type_counts.group_by(Device.device_type).all() device_type_stats = dict(device_type_counts) # 获取项目类型统计 project_type_stats = {} if project_types: project_type_counts = db.session.query( Device.project_type, db.func.count(WorkOrder.order_id) ).join(WorkOrder, WorkOrder.device_id == Device.device_id ).filter(WorkOrder.status == '待处理') # 应用同样的权限筛选 if current_user.branch != '交付中心': project_type_counts = project_type_counts.filter(Device.branch == current_user.branch) elif branch: project_type_counts = project_type_counts.filter(Device.branch == branch) project_type_counts = project_type_counts.group_by(Device.project_type).all() project_type_stats = dict(project_type_counts) # 获取分页数据 work_orders = query.paginate(page=page, per_page=per_page) # 计算派单时长 for work_order in work_orders.items: dispatch_time = work_order.dispatch_time now = datetime.now() delta = now - dispatch_time work_order.duration = f"{delta.days}天{delta.seconds // 3600}小时{(delta.seconds % 3600) // 60}分钟" return render_template('receive.html', work_orders=work_orders, total_orders=total_orders, branch_stats=branch_stats, device_type_stats=device_type_stats, project_type_stats=project_type_stats, show_filter=current_user.branch == '交付中心', # 只有交付中心可以看到筛选 branches=get_branches() if current_user.branch == '交付中心' else [], # 只有交付中心可以看到支局列表 selected_branch=branch, device_types=device_types, project_types=project_types ) @app.route('/recall_all_orders', methods=['POST']) @login_required def recall_all_orders(): try: # 获取所有在途工单 orders = WorkOrder.query.filter_by(status='待处理').all() count = len(orders) # 恢复设备状态并删除工单 for order in orders: # 恢复设备状态 device = Device.query.get(order.device_id) if device: device.is_normal = True db.session.add(device) # 直接删除工单 db.session.delete(order) db.session.commit() return jsonify({ 'success': True, 'count': count }) except Exception as e: return jsonify({ 'success': False, 'message': str(e) }) # 处理工单 @app.route('/receive/', methods=['GET', 'POST']) @login_required def receive_detail(work_order_id): if current_user.role not in ['装维员', '统计员']: flash('您没有权限访问此页面') return redirect(url_for('statistics')) work_order = WorkOrder.query.get_or_404(work_order_id) device = Device.query.filter_by(device_id=work_order.device_id).first() if request.method == 'POST': photo_paths = [] if 'photo' in request.files: files = request.files.getlist('photo') if len(files) > 5: flash('最多只能上传5张图片') return redirect(url_for('receive_detail', work_order_id=work_order_id)) for file in files: if file and allowed_file(file.filename, Config.ALLOWED_EXTENSIONS): # 修改这里 filename = f"{datetime.now().strftime('%Y%m%d%H%M%S')}_{file.filename}" file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) file.save(file_path) compress_image(file_path) photo_paths.append(filename) # 创建处理工单信息 handling_info = WorkOrderHandling( order_id=work_order.order_id, device_id=work_order.device_id, branch=device.branch if device else None, restore_time=datetime.now(), fault_type=request.form['fault_type'], contact_person=request.form['contact_person'], contact_phone=request.form['contact_phone'], handler=request.form['handler'], handle_description=request.form['handle_description'], photo_paths=','.join(photo_paths) if photo_paths else None, distance_from_branch=request.form['distance_from_branch'], remark=request.form.get('remark', '') ) # 更新工单状态为已处理 work_order.status = '已处理' # 更新设备状态为正常 if device: device.is_normal = True # 将所有更改添加到会话 db.session.add(handling_info) db.session.add(work_order) if device: db.session.add(device) # 一次性提交所有更改 db.session.commit() # 发送量子密信通知 send_lzmx_message( Config.LZMX_WEBHOOK_URL, # 修改这里 request.form['handler'], work_order.device_id, request.form['fault_type'], request.form['distance_from_branch'], datetime.now() ) flash('工单处理成功') return redirect(url_for('receive')) return render_template('receive_detail.html', work_order=work_order, device=device) @app.route('/recall_order/') @login_required def recall_order(order_id): # 检查用户权限 if current_user.role != '统计员': flash('没有权限执行此操作') return redirect(url_for('receive')) # 获取工单 work_order = WorkOrder.query.get_or_404(order_id) # 更新设备状态 device = Device.query.get(work_order.device_id) if device: device.is_normal = True db.session.add(device) # 删除工单 db.session.delete(work_order) db.session.commit() flash('工单已成功追回') return redirect(url_for('receive'))