修改平差时找不到平差按钮就返回。
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -5,6 +5,7 @@ from selenium.webdriver.support import expected_conditions as EC
|
||||
from selenium.common.exceptions import TimeoutException, NoSuchElementException
|
||||
import logging
|
||||
import time
|
||||
from datetime import datetime
|
||||
from globals.driver_utils import launch_app_manually
|
||||
from page_objects.login_page import LoginPage
|
||||
|
||||
@@ -179,12 +180,41 @@ class MoreDownloadPage:
|
||||
try:
|
||||
# # 获取年份选择器滚轮元素
|
||||
# year_wheel = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/wheelView1")
|
||||
# 获取当前日期
|
||||
current_date = datetime.now()
|
||||
current_month = current_date.month
|
||||
|
||||
# 检查月份是否小于等于3
|
||||
if current_month <= 3:
|
||||
self.logger.info(f"当前月份为{current_month}月,需要滑动年份选择器")
|
||||
|
||||
# 获取年份选择器滚轮元素
|
||||
year_wheel = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/wheelView1")
|
||||
|
||||
# 获取滚轮的位置和尺寸
|
||||
location = year_wheel.location
|
||||
size = year_wheel.size
|
||||
|
||||
# 计算滚轮中心点坐标
|
||||
center_x = location['x'] + size['width'] // 2
|
||||
center_y = location['y'] + size['height'] // 2
|
||||
|
||||
# 计算滑动距离 - 滚轮高度的1/5
|
||||
swipe_distance = size['height'] // 5
|
||||
|
||||
# 滑动一次年份选择器
|
||||
# 执行滑动操作 - 从中心向上滑动1/5高度
|
||||
self.driver.swipe(center_x, center_y - swipe_distance, center_x, center_y, 500)
|
||||
|
||||
self.logger.info("已滑动一次年份选择器")
|
||||
else:
|
||||
self.logger.info(f"当前月份为{current_month}月,不需要滑动年份选择器")
|
||||
# 获取月份选择器滚轮元素
|
||||
year_wheel = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/wheelView2")
|
||||
month_wheel = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/wheelView2")
|
||||
|
||||
# 获取滚轮的位置和尺寸
|
||||
location = year_wheel.location
|
||||
size = year_wheel.size
|
||||
location = month_wheel.location
|
||||
size = month_wheel.size
|
||||
|
||||
# 计算滚轮中心点坐标
|
||||
center_x = location['x'] + size['width'] // 2
|
||||
|
||||
@@ -5,6 +5,7 @@ import time
|
||||
import re
|
||||
import os
|
||||
from datetime import datetime
|
||||
from turtle import back
|
||||
from appium.webdriver.common.appiumby import AppiumBy
|
||||
from selenium.common.exceptions import NoSuchElementException, TimeoutException
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
@@ -866,7 +867,7 @@ class ScreenshotPage:
|
||||
self.logger.info(f"已点击返回按钮,等待处理返回确认弹窗")
|
||||
if not self.handle_confirmation_dialog(device_id):
|
||||
self.logger.error(f"设备 {device_id} 处理返回确认弹窗失败")
|
||||
return False
|
||||
# return False
|
||||
|
||||
|
||||
# 3. 验证是否成功返回到上一页面
|
||||
@@ -1277,80 +1278,118 @@ class ScreenshotPage:
|
||||
# global_variable.set_upload_breakpoint_dict({'CDWZQ-2标-龙骨湾右线大桥-0-7号墩-平原': 'L156372', 'CDWZQ-2标-蓝家湾特大 桥-31-31-平原': 'L159206'})
|
||||
|
||||
breakpoint_names = list(global_variable.get_upload_breakpoint_dict().keys())
|
||||
processed_breakpoints = []
|
||||
processed_breakpoints = [] # 创建一个列表,用于记录已处理的断点
|
||||
|
||||
# 开始循环处理断点
|
||||
for breakpoint_name in breakpoint_names:
|
||||
if breakpoint_name in processed_breakpoints:
|
||||
continue
|
||||
line_code = global_variable.get_upload_breakpoint_dict()[breakpoint_name]
|
||||
# 检测当前页面获取到的标段是否在breakpoint_names中
|
||||
max_scroll_attempts = 100 # 最大滚动尝试次数
|
||||
scroll_count = 0
|
||||
previous_items = set() # 记录前一次获取的项目集合,用于检测是否到达边界
|
||||
found_any = False # 标记是否找到并处理了任何断点
|
||||
max_retry_attempts = 3 # 每个断点的最大重试次数
|
||||
|
||||
self.logger.info(f"开始处理要平差的断点 {breakpoint_name}")
|
||||
while scroll_count < max_scroll_attempts:
|
||||
# 获取当前页面中的所有项目
|
||||
current_items = self.get_current_items()
|
||||
self.logger.info(f"当前页面找到 {len(current_items)} 个项目")
|
||||
|
||||
# 把断点名称给find_keyword
|
||||
if not self.find_keyword(breakpoint_name):
|
||||
self.logger.error(f"设备 {device_id} 未找到包含 {breakpoint_name} 的文件名")
|
||||
continue # 继续处理下一个断点
|
||||
# 检查当前页面的项目是否在breakpoint_names中
|
||||
for item in current_items:
|
||||
# 检查项目是否在breakpoint_names中且未处理
|
||||
if item in breakpoint_names and item not in processed_breakpoints:
|
||||
self.logger.info(f"找到目标断点: {item}")
|
||||
found_any = True
|
||||
|
||||
if not self.handle_measurement_dialog():
|
||||
self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
|
||||
continue
|
||||
# 获取线路编码
|
||||
try:
|
||||
line_code = global_variable.get_upload_breakpoint_dict()[item]
|
||||
except KeyError:
|
||||
self.logger.error(f"未找到断点 {item} 的线路编码")
|
||||
continue
|
||||
|
||||
if not self.check_apply_btn():
|
||||
self.logger.error(f"设备 {device_id} 检查平差处理按钮失败")
|
||||
self.execute_back_navigation_steps(device_id)
|
||||
continue
|
||||
# 重试处理断点
|
||||
retry_count = 0
|
||||
while retry_count < max_retry_attempts:
|
||||
self.logger.info(f"开始处理断点 {item} (第 {retry_count + 1} 次尝试)")
|
||||
|
||||
# 4. 点击平差处理按钮
|
||||
if not self.click_adjustment_button(device_id):
|
||||
self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
|
||||
continue
|
||||
# 点击目标项目
|
||||
if not self.click_item_by_text(item):
|
||||
self.logger.error(f"点击目标断点失败: {item}")
|
||||
retry_count += 1
|
||||
continue
|
||||
|
||||
# 检查是否在测量页面,在就重新执行选择断点,滑动列表到底部,点击最后一个spinner, 再下滑一次,点击平差处理按钮平差
|
||||
if not self.handle_back_navigation(breakpoint_name, device_id):
|
||||
self.logger.error(f"{breakpoint_name}平差失败,未截图")
|
||||
continue
|
||||
if not self.handle_measurement_dialog():
|
||||
self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
|
||||
retry_count += 1
|
||||
continue
|
||||
|
||||
if not self.check_apply_btn():
|
||||
retry_count += 1
|
||||
self.driver.back()
|
||||
self.logger.info(f"设备 {device_id} 检查平差处理按钮失败,已点击手机系统返回按钮")
|
||||
break
|
||||
|
||||
# 检测并处理"是 保留成果"弹窗
|
||||
if not self.handle_adjustment_result_dialog():
|
||||
self.logger.error("处理平差结果弹窗失败")
|
||||
continue
|
||||
# 点击平差处理按钮
|
||||
if not self.click_adjustment_button(device_id):
|
||||
self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
|
||||
retry_count += 1
|
||||
continue
|
||||
|
||||
# # 平差完成,将断点数据保存到上传列表中
|
||||
# if not self.add_breakpoint_to_upload_list(breakpoint_name, line_code):
|
||||
# self.logger.error(f"设备 {device_id} 保存断点 {breakpoint_name} 到上传列表失败")
|
||||
# continue
|
||||
# 检查是否在测量页面,在就重新执行选择断点,滑动列表到底部,点击最后一个spinner, 再下滑一次,点击平差处理按钮平差
|
||||
if not self.handle_back_navigation(item, device_id):
|
||||
self.logger.error(f"{item}平差失败,未截图")
|
||||
retry_count += 1
|
||||
continue
|
||||
|
||||
# # 检查是否在测量页面,在就重新执行选择断点,滑动列表到底部,点击最后一个spinner, 再下滑一次,点击平差处理按钮平差
|
||||
# if not self.handle_back_navigation(breakpoint_name, device_id):
|
||||
# self.logger.error(f"{breakpoint_name}平差失败,未截图")
|
||||
# continue
|
||||
# 检测并处理"是 保留成果"弹窗
|
||||
if not self.handle_adjustment_result_dialog():
|
||||
self.logger.error("处理平差结果弹窗失败")
|
||||
retry_count += 1
|
||||
continue
|
||||
|
||||
# # 检测并处理"是 保留成果"弹窗
|
||||
# if not self.handle_adjustment_result_dialog():
|
||||
# self.logger.error("处理平差结果弹窗失败")
|
||||
# continue
|
||||
# 点击返回按钮并处理弹窗
|
||||
if not self.execute_back_navigation_steps(device_id):
|
||||
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
|
||||
retry_count += 1
|
||||
continue
|
||||
|
||||
# 成功处理完一个断点,添加到已处理列表
|
||||
processed_breakpoints.append(item)
|
||||
self.logger.info(f"成功处理断点: {item}")
|
||||
break # 跳出重试循环
|
||||
|
||||
# 点击返回按钮并处理弹窗
|
||||
if not self.execute_back_navigation_steps(device_id):
|
||||
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
|
||||
continue
|
||||
# 检查是否重试次数用完仍未成功
|
||||
if retry_count >= max_retry_attempts:
|
||||
self.logger.error(f"断点 {item} 经过 {max_retry_attempts} 次重试后仍然失败")
|
||||
|
||||
# # 成功处理完一个断点,添加到已处理列表
|
||||
# processed_breakpoints.append(breakpoint_name)
|
||||
# self.logger.info(f"成功处理断点: {breakpoint_name}")
|
||||
# 重新获取当前页面项目,因为可能有新的项目加载
|
||||
break
|
||||
# 向下滑动列表以加载更多项目
|
||||
if not self.scroll_list(direction="down"):
|
||||
self.logger.error("向下滑动列表失败")
|
||||
break
|
||||
|
||||
# # 检查是否所有断点都处理完成
|
||||
# if len(processed_breakpoints) == len(breakpoint_names):
|
||||
# self.logger.info(f"设备 {device_id} 平差页面操作执行完成")
|
||||
# return True
|
||||
# else:
|
||||
# self.logger.warning(f"设备 {device_id} 部分断点处理失败,已成功处理 {len(processed_breakpoints)}/{len(breakpoint_names)} 个断点")
|
||||
# return True
|
||||
self.logger.warning(f"设备 {device_id} 平差线路到上传页面流程执行完成")
|
||||
return True
|
||||
# 检查是否到达底部:连续两次获取的项目相同
|
||||
if current_items == previous_items and len(current_items) > 0:
|
||||
self.logger.info("连续两次获取的项目相同,已到达列表底部")
|
||||
break
|
||||
|
||||
# 更新前一次项目集合
|
||||
previous_items = current_items.copy()
|
||||
|
||||
scroll_count += 1
|
||||
self.logger.info(f"第 {scroll_count} 次向下滑动,继续查找...")
|
||||
|
||||
# 检查是否所有断点都处理完成
|
||||
if len(processed_breakpoints) == len(breakpoint_names):
|
||||
self.logger.info(f"设备 {device_id} 平差页面操作执行完成")
|
||||
return True
|
||||
elif found_any:
|
||||
self.logger.warning(f"设备 {device_id} 部分断点处理完成,已成功处理 {len(processed_breakpoints)}/{len(breakpoint_names)} 个断点")
|
||||
return True
|
||||
else:
|
||||
self.logger.warning(f"设备 {device_id} 未找到任何目标断点")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
retry_count += 1
|
||||
|
||||
35
scheduler.py
35
scheduler.py
@@ -152,23 +152,28 @@ def get_combined_tasks():
|
||||
|
||||
def run_task(address, target_time, username):
|
||||
"""
|
||||
单个执行线程:锁定状态 -> 等待 -> 执行 -> 完成
|
||||
单个执行线程:检查时间 -> 锁定状态 -> 执行 -> 完成
|
||||
"""
|
||||
# 1. 尝试将状态从 ok 改为 running (锁定任务)
|
||||
# 如果此时文件状态已被其他逻辑修改,则放弃执行,防止重复
|
||||
if not update_file_status(username, "ok", "running"):
|
||||
return f"⏭️ {username} 状态已变更,跳过执行。"
|
||||
|
||||
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
|
||||
print(f"📅 [任务检查] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
|
||||
|
||||
try:
|
||||
# 2. 计算并执行等待逻辑
|
||||
# 1. 检查当前时间是否到达计划时间
|
||||
target_dt = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S")
|
||||
wait_secs = (target_dt - datetime.now()).total_seconds()
|
||||
current_dt = datetime.now()
|
||||
|
||||
if wait_secs > 0:
|
||||
print(f"⏳ {username} 距离执行还有 {int(wait_secs)} 秒...")
|
||||
time.sleep(wait_secs)
|
||||
# 如果当前时间还未到达计划时间,直接返回,等待下次轮询
|
||||
if current_dt < target_dt:
|
||||
time_diff = int((target_dt - current_dt).total_seconds())
|
||||
print(f"⏰ {username} 计划时间未到,距离执行还有 {time_diff} 秒,等待下次轮询")
|
||||
return f"⏰ {username} 计划时间未到,等待下次轮询"
|
||||
|
||||
# 2. 开始执行前,尝试将状态从 ok 改为 running (锁定任务)
|
||||
# 如果此时文件状态已被其他逻辑修改,则放弃执行,防止重复
|
||||
print(f"🔒 [准备锁定] 尝试锁定任务状态: {username}")
|
||||
if not update_file_status(username, "ok", "running"):
|
||||
return f"⏭️ {username} 状态已变更,跳过执行。"
|
||||
|
||||
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
|
||||
|
||||
# 3. 调用 main.py 中的自动化逻辑
|
||||
print(f"▶️ [正在执行] {username} 开始自动化操作...")
|
||||
@@ -181,7 +186,11 @@ def run_task(address, target_time, username):
|
||||
|
||||
except Exception as e:
|
||||
# 如果中间报错,将状态改为 error 方便排查
|
||||
update_file_status(username, "running", "error")
|
||||
# 只有在状态已经改为 running 的情况下才需要改为 error
|
||||
try:
|
||||
update_file_status(username, "running", "error")
|
||||
except:
|
||||
pass
|
||||
return f"❌ {username} 执行异常: {str(e)}"
|
||||
|
||||
def monitor_center():
|
||||
|
||||
@@ -1,4 +1 @@
|
||||
CZSCZQ-13A-二工区-沙马大桥-1#墩身-山区
|
||||
CZSCZQ-13A-二工区-沙马大桥-2#墩身-山区
|
||||
CZSCZQ-13A-二工区-沙马大桥-6#墩-山区
|
||||
CZSCZQ-13A-二工区-沙马大桥-7#墩-山区
|
||||
SJSG-7标-跨沿江高速特大桥-85#-89#-墩身-平原
|
||||
|
||||
Reference in New Issue
Block a user