修改平差时找不到平差按钮就返回。

This commit is contained in:
2026-02-12 17:04:24 +08:00
parent 80fdc75c26
commit fbdbed37f4
8 changed files with 163 additions and 88 deletions

View File

@@ -5,6 +5,7 @@ from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException from selenium.common.exceptions import TimeoutException, NoSuchElementException
import logging import logging
import time import time
from datetime import datetime
from globals.driver_utils import launch_app_manually from globals.driver_utils import launch_app_manually
from page_objects.login_page import LoginPage from page_objects.login_page import LoginPage
@@ -179,12 +180,41 @@ class MoreDownloadPage:
try: try:
# # 获取年份选择器滚轮元素 # # 获取年份选择器滚轮元素
# year_wheel = self.driver.find_element(AppiumBy.ID, "com.bjjw.cjgc:id/wheelView1") # 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 location = month_wheel.location
size = year_wheel.size size = month_wheel.size
# 计算滚轮中心点坐标 # 计算滚轮中心点坐标
center_x = location['x'] + size['width'] // 2 center_x = location['x'] + size['width'] // 2

View File

@@ -5,6 +5,7 @@ import time
import re import re
import os import os
from datetime import datetime from datetime import datetime
from turtle import back
from appium.webdriver.common.appiumby import AppiumBy from appium.webdriver.common.appiumby import AppiumBy
from selenium.common.exceptions import NoSuchElementException, TimeoutException from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait
@@ -866,7 +867,7 @@ class ScreenshotPage:
self.logger.info(f"已点击返回按钮,等待处理返回确认弹窗") self.logger.info(f"已点击返回按钮,等待处理返回确认弹窗")
if not self.handle_confirmation_dialog(device_id): if not self.handle_confirmation_dialog(device_id):
self.logger.error(f"设备 {device_id} 处理返回确认弹窗失败") self.logger.error(f"设备 {device_id} 处理返回确认弹窗失败")
return False # return False
# 3. 验证是否成功返回到上一页面 # 3. 验证是否成功返回到上一页面
@@ -1277,80 +1278,118 @@ class ScreenshotPage:
# global_variable.set_upload_breakpoint_dict({'CDWZQ-2标-龙骨湾右线大桥-0-7号墩-平原': 'L156372', 'CDWZQ-2标-蓝家湾特大 桥-31-31-平原': 'L159206'}) # 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()) breakpoint_names = list(global_variable.get_upload_breakpoint_dict().keys())
processed_breakpoints = [] processed_breakpoints = [] # 创建一个列表,用于记录已处理的断点
# 开始循环处理断点 # 开始循环处理断点
for breakpoint_name in breakpoint_names: # 检测当前页面获取到的标段是否在breakpoint_names
if breakpoint_name in processed_breakpoints: max_scroll_attempts = 100 # 最大滚动尝试次数
continue scroll_count = 0
line_code = global_variable.get_upload_breakpoint_dict()[breakpoint_name] 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 # 检查当前页面的项目是否在breakpoint_names中
if not self.find_keyword(breakpoint_name): for item in current_items:
self.logger.error(f"设备 {device_id} 未找到包含 {breakpoint_name} 的文件名") # 检查项目是否在breakpoint_names中且未处理
continue # 继续处理下一个断点 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} 处理测量弹窗失败") try:
continue 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} 检查平差处理按钮失败") retry_count = 0
self.execute_back_navigation_steps(device_id) while retry_count < max_retry_attempts:
continue self.logger.info(f"开始处理断点 {item} (第 {retry_count + 1} 次尝试)")
# 4. 点击平差处理按钮 # 点击目标项目
if not self.click_adjustment_button(device_id): if not self.click_item_by_text(item):
self.logger.error(f"设备 {device_id} 点击平差处理按钮失败") self.logger.error(f"点击目标断点失败: {item}")
continue retry_count += 1
continue
# 检查是否在测量页面在就重新执行选择断点滑动列表到底部点击最后一个spinner 再下滑一次,点击平差处理按钮平差 if not self.handle_measurement_dialog():
if not self.handle_back_navigation(breakpoint_name, device_id): self.logger.error(f"设备 {device_id} 处理测量弹窗失败")
self.logger.error(f"{breakpoint_name}平差失败,未截图") retry_count += 1
continue 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(): if not self.click_adjustment_button(device_id):
self.logger.error("处理平差结果弹窗失败") self.logger.error(f"设备 {device_id} 点击平差处理按钮失败")
continue retry_count += 1
continue
# # 平差完成,将断点数据保存到上传列表中 # 检查是否在测量页面在就重新执行选择断点滑动列表到底部点击最后一个spinner 再下滑一次,点击平差处理按钮平差
# if not self.add_breakpoint_to_upload_list(breakpoint_name, line_code): if not self.handle_back_navigation(item, device_id):
# self.logger.error(f"设备 {device_id} 保存断点 {breakpoint_name} 到上传列表失败") self.logger.error(f"{item}平差失败,未截图")
# continue retry_count += 1
continue
# # 检查是否在测量页面在就重新执行选择断点滑动列表到底部点击最后一个spinner 再下滑一次,点击平差处理按钮平差 # 检测并处理"是 保留成果"弹窗
# if not self.handle_back_navigation(breakpoint_name, device_id): if not self.handle_adjustment_result_dialog():
# self.logger.error(f"{breakpoint_name}平差失败,未截图") self.logger.error("处理平差结果弹窗失败")
# continue retry_count += 1
continue
# # 检测并处理"是 保留成果"弹窗 # 点击返回按钮并处理弹窗
# if not self.handle_adjustment_result_dialog(): if not self.execute_back_navigation_steps(device_id):
# self.logger.error("处理平差结果弹窗失败") self.logger.error(f"设备 {device_id} 处理返回按钮确认失败")
# continue retry_count += 1
continue
# 成功处理完一个断点,添加到已处理列表
processed_breakpoints.append(item)
self.logger.info(f"成功处理断点: {item}")
break # 跳出重试循环
# 点击返回按钮并处理弹窗 # 检查是否重试次数用完仍未成功
if not self.execute_back_navigation_steps(device_id): if retry_count >= max_retry_attempts:
self.logger.error(f"设备 {device_id} 处理返回按钮确认失败") self.logger.error(f"断点 {item} 经过 {max_retry_attempts} 次重试后仍然失败")
continue
# # 成功处理完一个断点,添加到已处理列表 # 重新获取当前页面项目,因为可能有新的项目加载
# processed_breakpoints.append(breakpoint_name) break
# self.logger.info(f"成功处理断点: {breakpoint_name}") # 向下滑动列表以加载更多项目
if not self.scroll_list(direction="down"):
self.logger.error("向下滑动列表失败")
break
# # 检查是否所有断点都处理完成 # 检查是否到达底部:连续两次获取的项目相同
# if len(processed_breakpoints) == len(breakpoint_names): if current_items == previous_items and len(current_items) > 0:
# self.logger.info(f"设备 {device_id} 平差页面操作执行完成") self.logger.info("连续两次获取的项目相同,已到达列表底部")
# return True break
# else:
# self.logger.warning(f"设备 {device_id} 部分断点处理失败,已成功处理 {len(processed_breakpoints)}/{len(breakpoint_names)} 个断点") # 更新前一次项目集合
# return True previous_items = current_items.copy()
self.logger.warning(f"设备 {device_id} 平差线路到上传页面流程执行完成")
return True 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: except Exception as e:
retry_count += 1 retry_count += 1

View File

@@ -152,23 +152,28 @@ def get_combined_tasks():
def run_task(address, target_time, username): def run_task(address, target_time, username):
""" """
单个执行线程:锁定状态 -> 等待 -> 执行 -> 完成 单个执行线程:检查时间 -> 锁定状态 -> 执行 -> 完成
""" """
# 1. 尝试将状态从 ok 改为 running (锁定任务) print(f"📅 [任务检查] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
# 如果此时文件状态已被其他逻辑修改,则放弃执行,防止重复
if not update_file_status(username, "ok", "running"):
return f"⏭️ {username} 状态已变更,跳过执行。"
print(f"🚀 [任务锁定] 设备: {address} | 用户: {username} | 计划时间: {target_time}")
try: try:
# 2. 计算并执行等待逻辑 # 1. 检查当前时间是否到达计划时间
target_dt = datetime.strptime(target_time, "%Y-%m-%d %H:%M:%S") 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)} 秒...") if current_dt < target_dt:
time.sleep(wait_secs) 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 中的自动化逻辑 # 3. 调用 main.py 中的自动化逻辑
print(f"▶️ [正在执行] {username} 开始自动化操作...") print(f"▶️ [正在执行] {username} 开始自动化操作...")
@@ -181,7 +186,11 @@ def run_task(address, target_time, username):
except Exception as e: except Exception as e:
# 如果中间报错,将状态改为 error 方便排查 # 如果中间报错,将状态改为 error 方便排查
update_file_status(username, "running", "error") # 只有在状态已经改为 running 的情况下才需要改为 error
try:
update_file_status(username, "running", "error")
except:
pass
return f"{username} 执行异常: {str(e)}" return f"{username} 执行异常: {str(e)}"
def monitor_center(): def monitor_center():

View File

@@ -1,4 +1 @@
CZSCZQ-13A-二工区-沙马大桥-1#墩身-山区 SJSG-7标-跨沿江高速特大桥-85#-89#-墩身-平原
CZSCZQ-13A-二工区-沙马大桥-2#墩身-山区
CZSCZQ-13A-二工区-沙马大桥-6#墩-山区
CZSCZQ-13A-二工区-沙马大桥-7#墩-山区