Commit 0dc572c3 authored by wushanjing's avatar wushanjing

修复手工录单区服选择校验

parent 17a340be
......@@ -4283,6 +4283,7 @@ class WanzhangguiOrderPage(TenantAuthPage):
self.select_first_available_if_placeholder(frame, "区")
self.select_first_available_if_placeholder(frame, "服")
self.select_service_project(frame)
self.ensure_game_region_service_selected(frame)
self.align_order_type_with_service_project(frame)
self.select_sales_customer(frame)
......@@ -4298,6 +4299,7 @@ class WanzhangguiOrderPage(TenantAuthPage):
self.fill_input_by_placeholder(frame, "小时", order.service_hours)
self.fill_input_by_placeholder(frame, "请输入订单内容", order.order_title)
self.fill_number_by_placeholder(frame, "请输入价格", order.receive_price)
self.ensure_game_region_service_selected(frame)
self.fill_sub_order_row(frame, order)
def fill_required_fields_after_submit_without_dispatch(self, frame: Frame, order: ManualOrderData) -> None:
......@@ -4306,6 +4308,7 @@ class WanzhangguiOrderPage(TenantAuthPage):
self.fill_input_by_placeholder(frame, "小时", order.service_hours)
self.fill_input_by_placeholder(frame, "请输入订单内容", order.order_title)
self.fill_number_by_placeholder(frame, "请输入价格", order.receive_price)
self.ensure_game_region_service_selected(frame)
def assert_order_in_pending_accept_status(self, frame: Frame, order: ManualOrderData) -> None:
self.search_order_by_best_identity(
......@@ -5134,6 +5137,126 @@ class WanzhangguiOrderPage(TenantAuthPage):
if clicked:
self.page.wait_for_timeout(800)
def ensure_game_region_service_selected(self, frame: Frame) -> None:
for _ in range(3):
status = self.manual_order_game_region_service_status(frame)
missing = status.get("missing", [])
if not missing:
return
for field in missing:
self.select_manual_order_game_region_field(frame, str(field))
self.page.wait_for_timeout(800)
status = self.manual_order_game_region_service_status(frame)
assert not status.get("missing"), (
f"手工录单游戏/区/服/服务项目选择未生效;status={status}; "
f"validation_messages={self.modal_validation_messages(frame)}"
)
def manual_order_game_region_service_status(self, frame: Frame) -> dict:
return dict(
frame.evaluate(
"""() => {
const invalid = text => {
const value = String(text || '').replace(/\\s+/g, '').trim();
return !value ||
/^\\d+$/.test(value) ||
value.includes('请选择') ||
value.includes('游戏') ||
value === '区' ||
value === '服' ||
value.includes('服务项目');
};
const modal = Array.from(document.querySelectorAll('.ant-modal'))
.filter(el => {
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
}).pop();
if (!modal) return { ok: false, missing: ['modal'], reason: 'no visible modal' };
const selectors = Array.from(modal.querySelectorAll('.ant-select-selector'))
.map((el, index) => ({
index,
text: (el.innerText || el.textContent || '').trim(),
r: el.getBoundingClientRect(),
}))
.filter(item => item.r.width > 0 && item.r.height > 0)
.sort((a, b) => a.r.y - b.r.y || a.r.x - b.r.x);
const byY = new Map();
for (const item of selectors) {
const key = Math.round(item.r.y / 8) * 8;
byY.set(key, [...(byY.get(key) || []), item]);
}
const rows = Array.from(byY.values()).map(items => items.sort((a, b) => a.r.x - b.r.x));
const row = rows.find(items => {
if (items.length < 4) return false;
const text = items.map(item => item.text).join('|');
return /王者|安卓|国服|游戏|服务项目|区|服/.test(text);
});
if (!row) {
return {
ok: false,
missing: ['游戏', '区', '服', '服务项目'],
selectors: selectors.map(item => `${item.index}:${item.text}`),
};
}
const fields = ['游戏', '区', '服', '服务项目'];
const values = {};
const missing = [];
for (let i = 0; i < fields.length; i += 1) {
const value = row[i]?.text || '';
values[fields[i]] = value;
if (!row[i] || invalid(value)) missing.push(fields[i]);
}
return { ok: missing.length === 0, missing, values, row: row.map(item => `${item.index}:${item.text}`) };
}"""
)
)
def select_manual_order_game_region_field(self, frame: Frame, field: str) -> bool:
opened = frame.evaluate(
"""field => {
const modal = Array.from(document.querySelectorAll('.ant-modal'))
.filter(el => {
const r = el.getBoundingClientRect();
return r.width > 0 && r.height > 0;
}).pop();
if (!modal) return { ok: false, reason: 'no visible modal' };
const selectors = Array.from(modal.querySelectorAll('.ant-select-selector'))
.map((el, index) => ({
el,
index,
text: (el.innerText || el.textContent || '').trim(),
r: el.getBoundingClientRect(),
}))
.filter(item => item.r.width > 0 && item.r.height > 0)
.sort((a, b) => a.r.y - b.r.y || a.r.x - b.r.x);
const byY = new Map();
for (const item of selectors) {
const key = Math.round(item.r.y / 8) * 8;
byY.set(key, [...(byY.get(key) || []), item]);
}
const rows = Array.from(byY.values()).map(items => items.sort((a, b) => a.r.x - b.r.x));
const row = rows.find(items => {
if (items.length < 4) return false;
const text = items.map(item => item.text).join('|');
return /王者|安卓|国服|游戏|服务项目|区|服/.test(text);
});
if (!row) return { ok: false, reason: 'game row not found', selectors: selectors.map(item => `${item.index}:${item.text}`) };
const index = { '游戏': 0, '区': 1, '服': 2, '服务项目': 3 }[field];
const selector = row[index];
if (!selector) return { ok: false, reason: `selector not found: ${field}`, row: row.map(item => item.text) };
selector.el.click();
return { ok: true, index: selector.index, before: selector.text };
}""",
field,
)
if not opened.get("ok"):
return False
self.page.wait_for_timeout(1000)
clicked = self.click_first_visible_dropdown_option(frame)
if clicked:
self.page.wait_for_timeout(800)
return clicked
def visible_dropdown_options(self, frame: Frame) -> list[str]:
options = frame.evaluate(
"""() => Array.from(document.querySelectorAll(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment