379 lines
16 KiB
Python
Executable File
379 lines
16 KiB
Python
Executable File
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():
|
|
allowed_roles = ['装维员', '统计员', '管理员', 'admin']
|
|
if current_user.role not in allowed_roles and current_user.name != 'Admin':
|
|
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/<string:work_order_id>', methods=['GET', 'POST'])
|
|
@login_required
|
|
def receive_detail(work_order_id):
|
|
allowed_roles = ['装维员', '统计员', '管理员', 'admin']
|
|
if current_user.role not in allowed_roles and current_user.name != 'Admin':
|
|
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/<order_id>')
|
|
@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')) |