开始
This commit is contained in:
Executable
+297
@@ -0,0 +1,297 @@
|
||||
from flask import jsonify, request, send_file, session, current_app
|
||||
from flask_login import login_required, current_user
|
||||
from scripts.update.zte import LoginClient
|
||||
from scripts.models import db, Device, WorkOrder, Channel
|
||||
from datetime import datetime
|
||||
from sqlalchemy import text, create_engine
|
||||
import hashlib
|
||||
import pymysql
|
||||
import io
|
||||
import os
|
||||
|
||||
|
||||
def init_device_routes(app):
|
||||
@app.route('/sync_offline_devices', methods=['POST'])
|
||||
@login_required
|
||||
def sync_offline_devices():
|
||||
if current_user.role not in ['装维员', '统计员']:
|
||||
app.logger.warning(f'未授权访问:用户 {current_user.name} 尝试同步离线设备')
|
||||
return jsonify({'success': False, 'message': '没有权限执行此操作'})
|
||||
|
||||
try:
|
||||
app.logger.info(f'用户 {current_user.name} 开始同步离线设备')
|
||||
# 从配置中获取数据库连接信息
|
||||
db_config = current_app.config['KEY110_DB']
|
||||
conn = pymysql.connect(**db_config)
|
||||
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 获取所有教学点的状态
|
||||
cursor.execute("""
|
||||
SELECT 教学点名称, 连通状态
|
||||
FROM IP数据
|
||||
""")
|
||||
|
||||
schools = cursor.fetchall()
|
||||
|
||||
# 分别处理在线和离线的教学点
|
||||
offline_school_names = [school[0].strip().replace(' ', ' ') for school in schools if school[1] == '离线']
|
||||
online_school_names = [school[0].strip().replace(' ', ' ') for school in schools if school[1] == '在线']
|
||||
|
||||
# 关闭1key110数据库连接
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
# 处理恢复在线的设备
|
||||
online_devices = Device.query.filter(
|
||||
Device.device_id.in_(online_school_names),
|
||||
Device.is_normal == False # 当前状态为故障的设备
|
||||
).all()
|
||||
|
||||
# 删除恢复在线设备的在途工单
|
||||
recovered_count = 0
|
||||
for device in online_devices:
|
||||
# 查找并删除该设备的在途工单
|
||||
pending_orders = WorkOrder.query.filter_by(
|
||||
device_id=device.device_id,
|
||||
status='待处理'
|
||||
).all()
|
||||
|
||||
for order in pending_orders:
|
||||
db.session.delete(order)
|
||||
recovered_count += 1
|
||||
|
||||
# 更新设备状态为正常
|
||||
device.is_normal = True
|
||||
db.session.add(device)
|
||||
|
||||
# 处理离线设备
|
||||
offline_devices = Device.query.filter(
|
||||
Device.device_id.in_(offline_school_names),
|
||||
Device.in_use == True,
|
||||
Device.is_normal == True
|
||||
).all()
|
||||
|
||||
# 生成工单号
|
||||
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()
|
||||
|
||||
start_number = int(last_work_order.order_id[-4:]) + 1 if last_work_order else 1
|
||||
|
||||
# 创建工单
|
||||
created_count = 0
|
||||
for index, device in enumerate(offline_devices):
|
||||
# 检查是否已有在途工单
|
||||
existing_order = WorkOrder.query.filter_by(
|
||||
device_id=device.device_id,
|
||||
status='待处理'
|
||||
).first()
|
||||
|
||||
if existing_order:
|
||||
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.device_id,
|
||||
dispatch_time=datetime.now(),
|
||||
status='待处理',
|
||||
branch=device.branch
|
||||
)
|
||||
|
||||
db.session.add(work_order)
|
||||
device.is_normal = False
|
||||
db.session.add(device)
|
||||
created_count += 1
|
||||
|
||||
db.session.commit()
|
||||
|
||||
app.logger.info(f'同步完成:创建了 {created_count} 个工单,恢复了 {recovered_count} 个设备')
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'count': created_count
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f'同步离线设备失败:{str(e)}')
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'message': str(e)
|
||||
})
|
||||
|
||||
@app.route('/check_existing_orders', methods=['POST'])
|
||||
@login_required
|
||||
def check_existing_orders():
|
||||
device_ids = request.json.get('device_ids', [])
|
||||
app.logger.info(f'用户 {current_user.name} 检查设备工单状态,设备数量:{len(device_ids)}')
|
||||
|
||||
# 查询设备状态
|
||||
existing_devices = Device.query.filter(
|
||||
Device.device_id.in_(device_ids),
|
||||
Device.is_normal == False # 检查设备是否处于故障状态
|
||||
).with_entities(Device.device_id).all()
|
||||
|
||||
# 提取设备ID列表
|
||||
existing_device_ids = [device.device_id for device in existing_devices]
|
||||
app.logger.info(f'发现 {len(existing_device_ids)} 个设备存在故障工单')
|
||||
|
||||
return jsonify({'existing_devices': existing_device_ids})
|
||||
|
||||
@app.route('/get_captcha', methods=['GET'])
|
||||
def get_captcha():
|
||||
app.logger.info('用户请求验证码')
|
||||
try:
|
||||
client = LoginClient()
|
||||
cid = client.get_captcha()
|
||||
# 将 cid 存储在 session 中供后续使用
|
||||
session['zte_cid'] = cid
|
||||
|
||||
# 读取验证码图片并返回给前端
|
||||
captcha_path = os.path.join(os.path.dirname(os.path.dirname(__file__)),
|
||||
'static', 'captcha.png')
|
||||
with open(captcha_path, "rb") as f:
|
||||
app.logger.info('验证码获取成功')
|
||||
return send_file(
|
||||
io.BytesIO(f.read()),
|
||||
mimetype='image/png'
|
||||
)
|
||||
except Exception as e:
|
||||
app.logger.error(f'获取验证码失败:{str(e)}')
|
||||
return jsonify({'success': False, 'message': '获取验证码失败'})
|
||||
|
||||
@app.route('/sync_camera_step1', methods=['POST'])
|
||||
def sync_camera_step1():
|
||||
try:
|
||||
app.logger.info(f'用户 {current_user.name if current_user else "未登录"} 开始同步摄像头第一步')
|
||||
data = request.get_json()
|
||||
captcha = data.get('captcha')
|
||||
cid = session.get('zte_cid')
|
||||
|
||||
if not captcha or not cid:
|
||||
app.logger.warning('同步摄像头失败:验证码或会话ID缺失')
|
||||
return jsonify({'success': False, 'message': 'Invalid request'})
|
||||
|
||||
client = LoginClient()
|
||||
# 登录
|
||||
app.logger.info('尝试登录中兴平台')
|
||||
login_result = client.login(
|
||||
account="DHDX001",
|
||||
password=hashlib.sha256("Root1234#".encode()).hexdigest(),
|
||||
validcode=captcha,
|
||||
cid=cid
|
||||
)
|
||||
|
||||
if login_result.get("result") != 0:
|
||||
app.logger.warning('登录中兴平台失败:验证码错误')
|
||||
return jsonify({'success': False, 'message': 'INVALID_CAPTCHA'})
|
||||
|
||||
token = login_result.get("token")
|
||||
app.logger.info('登录成功,开始获取在线信息')
|
||||
# 获取在线信息
|
||||
online_info = client.get_online_info(token)
|
||||
|
||||
if online_info.get("result") == 0:
|
||||
rows = online_info.get("rows", [])
|
||||
updated_count = 0
|
||||
offline_count = 0
|
||||
|
||||
app.logger.info(f'获取到 {len(rows)} 个设备信息,开始更新数据库')
|
||||
# 更新 channels 表
|
||||
for row in rows:
|
||||
db.session.execute(
|
||||
text("""
|
||||
INSERT INTO channels (puid, pu_name, status)
|
||||
VALUES (:puid, :pu_name, :status)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
pu_name = :pu_name, status = :status
|
||||
"""),
|
||||
{
|
||||
'puid': row['puid'],
|
||||
'pu_name': row['pu_name'],
|
||||
'status': row['status']
|
||||
}
|
||||
)
|
||||
updated_count += 1
|
||||
if row['status'] != 'online':
|
||||
offline_count += 1
|
||||
|
||||
db.session.commit()
|
||||
app.logger.info(f'数据库更新完成,更新了 {updated_count} 条记录,其中离线设备 {offline_count} 个')
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'updated_count': updated_count,
|
||||
'offline_count': offline_count
|
||||
})
|
||||
|
||||
app.logger.error('获取在线信息失败')
|
||||
return jsonify({'success': False, 'message': 'Failed to get online info'})
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f'同步摄像头步骤1失败:{str(e)}')
|
||||
return jsonify({'success': False, 'message': str(e)})
|
||||
|
||||
@app.route('/sync_camera_step2', methods=['POST'])
|
||||
def sync_camera_step2():
|
||||
try:
|
||||
app.logger.info(f'用户 {current_user.name if current_user else "未登录"} 开始同步摄像头第二步')
|
||||
# 更新设备状态
|
||||
devices = Device.query.filter(
|
||||
Device.puid.isnot(None),
|
||||
Device.in_use == True # 添加这个条件,只检查在用设备
|
||||
).all()
|
||||
app.logger.info(f'查询到 {len(devices)} 个需要同步的设备')
|
||||
offline_devices = []
|
||||
|
||||
for device in devices:
|
||||
channel = db.session.query(Channel).filter_by(puid=device.puid).first()
|
||||
if channel and channel.status != 'online':
|
||||
device.is_normal = 0
|
||||
# 检查是否已有在途工单
|
||||
existing_order = WorkOrder.query.filter_by(
|
||||
device_id=device.device_id,
|
||||
status='待处理'
|
||||
).first()
|
||||
|
||||
if not existing_order: # 只添加没有在途工单的设备
|
||||
offline_devices.append(device)
|
||||
|
||||
db.session.commit()
|
||||
app.logger.info(f'发现 {len(offline_devices)} 个离线设备需要创建工单')
|
||||
|
||||
# 为离线设备创建工单
|
||||
created_count = 0
|
||||
if offline_devices:
|
||||
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()
|
||||
|
||||
start_number = int(last_work_order.order_id[-4:]) + 1 if last_work_order else 1
|
||||
|
||||
for index, device in enumerate(offline_devices):
|
||||
order_id = f"{today}{str(start_number + index).zfill(4)}"
|
||||
work_order = WorkOrder(
|
||||
order_id=order_id,
|
||||
device_id=device.device_id,
|
||||
status='待处理',
|
||||
dispatch_time=datetime.now(),
|
||||
branch=device.branch # 添加支局信息
|
||||
)
|
||||
db.session.add(work_order)
|
||||
created_count += 1
|
||||
|
||||
db.session.commit()
|
||||
app.logger.info(f'成功创建 {created_count} 个工单')
|
||||
|
||||
return jsonify({
|
||||
'success': True,
|
||||
'count': created_count
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f'同步摄像头步骤2失败:{str(e)}')
|
||||
return jsonify({'success': False, 'message': str(e)})
|
||||
Reference in New Issue
Block a user