python-qlv-helper 0.7.2__py3-none-any.whl → 0.9.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_qlv_helper-0.7.2.dist-info → python_qlv_helper-0.9.3.dist-info}/METADATA +5 -5
- {python_qlv_helper-0.7.2.dist-info → python_qlv_helper-0.9.3.dist-info}/RECORD +9 -9
- qlv_helper/controller/order_detail.py +191 -254
- qlv_helper/controller/order_table.py +5 -12
- qlv_helper/http/order_page.py +127 -43
- qlv_helper/po/order_detail_page.py +29 -1
- {python_qlv_helper-0.7.2.dist-info → python_qlv_helper-0.9.3.dist-info}/WHEEL +0 -0
- {python_qlv_helper-0.7.2.dist-info → python_qlv_helper-0.9.3.dist-info}/licenses/LICENSE +0 -0
- {python_qlv_helper-0.7.2.dist-info → python_qlv_helper-0.9.3.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python_qlv_helper
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.3
|
|
4
4
|
Summary: qlv helper python package
|
|
5
5
|
Author-email: ckf10000 <ckf10000@sina.com>
|
|
6
6
|
License: Apache License
|
|
@@ -216,10 +216,10 @@ Requires-Dist: ddddocr==1.5.6; python_version >= "3.12"
|
|
|
216
216
|
Requires-Dist: aiohttp==3.13.2; python_version >= "3.12"
|
|
217
217
|
Requires-Dist: beautifulsoup4==4.14.2; python_version >= "3.12"
|
|
218
218
|
Requires-Dist: airtest==1.3.6; python_version >= "3.12"
|
|
219
|
-
Requires-Dist: python_http_helper>=0.2.
|
|
220
|
-
Requires-Dist: python_playwright_helper>=0.3
|
|
221
|
-
Requires-Dist: python_ocr_helper>=0.0.
|
|
222
|
-
Requires-Dist: flight_helper>=0.
|
|
219
|
+
Requires-Dist: python_http_helper>=0.2.1; python_version >= "3.12"
|
|
220
|
+
Requires-Dist: python_playwright_helper>=0.4.3; python_version >= "3.12"
|
|
221
|
+
Requires-Dist: python_ocr_helper>=0.0.2; python_version >= "3.12"
|
|
222
|
+
Requires-Dist: flight_helper>=0.3.6
|
|
223
223
|
Dynamic: license-file
|
|
224
224
|
|
|
225
225
|
# qlv-helper
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
python_qlv_helper-0.
|
|
1
|
+
python_qlv_helper-0.9.3.dist-info/licenses/LICENSE,sha256=WtjCEwlcVzkh1ziO35P2qfVEkLjr87Flro7xlHz3CEY,11556
|
|
2
2
|
qlv_helper/__init__.py,sha256=5DCc5JhfdsgtIuFWgkxPOW5VVKZ8RPikQLGIuyZX6_Y,465
|
|
3
3
|
qlv_helper/config/__init__.py,sha256=0pKLgui-sC6yMNBBuuTTLkUGhPybiJQSTKTbi66alvg,465
|
|
4
4
|
qlv_helper/config/custom_exception.py,sha256=uYme0iseQt_dP-Y6-hZ_H2OA2OQR0Kp5PmmZvhEZlEc,805
|
|
@@ -6,19 +6,19 @@ qlv_helper/config/url_const.py,sha256=EoLHOtlO3Ob2WSMMv6TBrl7eJCfJCB844dwmD_k86B
|
|
|
6
6
|
qlv_helper/controller/__init__.py,sha256=cOJA0xMIytv17oICzPYqWLaSy-Ro2Ceeti0hHhsUj6Y,468
|
|
7
7
|
qlv_helper/controller/domestic_activity_order.py,sha256=MlmsDVsMBWq2h4Yjh1rhO372Z3p8tu2-4IZGP-nkfr8,1136
|
|
8
8
|
qlv_helper/controller/main_page.py,sha256=p_-nXAIptNrx1SUgma7oPB-cqFFHYdCNvXCfsesIQFc,1855
|
|
9
|
-
qlv_helper/controller/order_detail.py,sha256=
|
|
10
|
-
qlv_helper/controller/order_table.py,sha256=
|
|
9
|
+
qlv_helper/controller/order_detail.py,sha256=bDmA_v0CummPlKKfxTry6-SaH6qfZ4LekqnK38Rq2CA,22114
|
|
10
|
+
qlv_helper/controller/order_table.py,sha256=bVVCM2oJF4q43fdJN5aBYbpwzW2rcL0bMoCP90ZIvtY,15144
|
|
11
11
|
qlv_helper/controller/user_login.py,sha256=oXO1otTGuK3_r07fKdncQE3Is2w-kiI-mWmJyFvsVyE,5915
|
|
12
12
|
qlv_helper/controller/wechat_login.py,sha256=0u9H6tJiQO28nT5AG2Ot7EWFmpBqFJD_9dd12snsJIQ,2196
|
|
13
13
|
qlv_helper/http/__init__.py,sha256=yDh1xi_o7ohXqDAzLu62qCWIGk4_aD1dhnUaCon3klM,484
|
|
14
14
|
qlv_helper/http/main_page.py,sha256=LTpwrG8H_NqwCa3185irgcGd6JQkChAk7HQsDM-TNTI,1519
|
|
15
|
-
qlv_helper/http/order_page.py,sha256=
|
|
15
|
+
qlv_helper/http/order_page.py,sha256=aaghRwvC2Px5OgQh8Lc4-Q1eQWbXE-lYM2iLdm7qbSw,24987
|
|
16
16
|
qlv_helper/http/order_table_page.py,sha256=IaXn5wjqPi1aRXHz0kucdHEdZswUWAZfECC13y57y8k,14440
|
|
17
17
|
qlv_helper/po/__init__.py,sha256=eDr06o0eYapBsYpOhA11bbxzs2F0dsuDjOKmxk_2HVE,480
|
|
18
18
|
qlv_helper/po/domestic_activity_order_page.py,sha256=El63U0GI2PU9WGIkGxPgCE1Fp1yCsw2v1H6cZhSaG4c,8509
|
|
19
19
|
qlv_helper/po/login_page.py,sha256=JbapNFwGCei3K3mpfhte1TVNeqzG7yHsCtp5KiKv_6g,4271
|
|
20
20
|
qlv_helper/po/main_page.py,sha256=0_tqZILZnLS6y3chg9ERTHDtg86pW0aIQ1vNuPFLVG8,1752
|
|
21
|
-
qlv_helper/po/order_detail_page.py,sha256=
|
|
21
|
+
qlv_helper/po/order_detail_page.py,sha256=f3PZF1Sm5Xdc9qRQDDKSq08L6PM-o4Vkchu32sZytfA,15545
|
|
22
22
|
qlv_helper/po/wechat_auth_page.py,sha256=a4YZlM5JOS0l3CNJm_oJFBhZY7AbNOpdIwilSjAO5bY,3171
|
|
23
23
|
qlv_helper/utils/__init__.py,sha256=rGzBkUf1tslG4WRPQjVWTVuwWG76pkckuKO_6K4sEus,465
|
|
24
24
|
qlv_helper/utils/browser_utils.py,sha256=mKoqSEz1vFrVemp9cgI4R5UhA4k7i0Cd9cWsIXJZ6E4,986
|
|
@@ -30,7 +30,7 @@ qlv_helper/utils/po_utils.py,sha256=SwQKL58HERGG2Weou_AwY_TQoYSvgi0gvaVCJBput_k,
|
|
|
30
30
|
qlv_helper/utils/stealth_browser.py,sha256=srNOYJOboYo30TvW5OP5TaVpg4jgHm9GxqmYnuwcUQU,3140
|
|
31
31
|
qlv_helper/utils/type_utils.py,sha256=S5FXUje2mbDuq27LU05WymxNu1VGOLBUV3tuqcx51dE,3792
|
|
32
32
|
qlv_helper/utils/windows_utils.py,sha256=Cvedsk1c2ujgPNVxszz8XWANkvEr8G9kne6povtZRU4,2866
|
|
33
|
-
python_qlv_helper-0.
|
|
34
|
-
python_qlv_helper-0.
|
|
35
|
-
python_qlv_helper-0.
|
|
36
|
-
python_qlv_helper-0.
|
|
33
|
+
python_qlv_helper-0.9.3.dist-info/METADATA,sha256=GVMfOfy40GcPrKIH_pLtFCW3vzPD6b2sZH-yd4XbnW4,14825
|
|
34
|
+
python_qlv_helper-0.9.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
35
|
+
python_qlv_helper-0.9.3.dist-info/top_level.txt,sha256=0pYdhD8SfBcC57LzLYGHY7cwwPqdqAkB1twysCJh5OA,11
|
|
36
|
+
python_qlv_helper-0.9.3.dist-info/RECORD,,
|
|
@@ -13,12 +13,19 @@ import aiohttp
|
|
|
13
13
|
import asyncio
|
|
14
14
|
from logging import Logger
|
|
15
15
|
from datetime import datetime
|
|
16
|
+
from typing import Dict, Any, List, Optional
|
|
16
17
|
import qlv_helper.config.url_const as url_const
|
|
17
|
-
from typing import Dict, Any, List, cast, Optional
|
|
18
18
|
from qlv_helper.po.order_detail_page import OrderDetailPage
|
|
19
|
+
from flight_helper.utils.exception_utils import UserNotLoginError
|
|
19
20
|
from flight_helper.models.dto.procurement import FillProcurementInputDTO
|
|
21
|
+
from flight_helper.utils.exception_utils import RelationOrderConflictError, LockedOrderFailedError
|
|
20
22
|
from qlv_helper.http.order_page import parser_order_info, get_order_page_html, parser_order_flight_table, \
|
|
21
|
-
|
|
23
|
+
fill_procurement_dto_with_http as _fill_procurement_dto_with_http, fill_remark_with_http as _fill_remark_with_http, \
|
|
24
|
+
update_policy_with_http as _update_policy_with_http, unlock_order_with_http as _unlock_order_with_http, \
|
|
25
|
+
forced_unlock_order_with_http as _forced_unlock_order_with_http, locked_order_with_http as _locked_order_with_http, \
|
|
26
|
+
fill_itinerary_with_http as _fill_itinerary_with_http, \
|
|
27
|
+
kick_out_activity_order_with_http as _kick_out_activity_order_with_http, \
|
|
28
|
+
kick_out_activity_orders_with_http as _kick_out_activity_orders_with_http
|
|
22
29
|
from playwright.async_api import Page, Locator, Error as PlaywrightError, TimeoutError as PlaywrightTimeoutError
|
|
23
30
|
|
|
24
31
|
|
|
@@ -57,9 +64,14 @@ async def open_order_detail_page(
|
|
|
57
64
|
logger.info(f"即将劲旅订单详情页面,页面URL<{order_detail_url}>")
|
|
58
65
|
|
|
59
66
|
try:
|
|
67
|
+
message: str = await order_detail_po.get_message_content(timeout=1)
|
|
68
|
+
if "关联订单" in message:
|
|
69
|
+
raise RelationOrderConflictError(message)
|
|
60
70
|
confirm_btn = await order_detail_po.get_message_notice_dialog_confirm_btn(timeout=1)
|
|
61
71
|
await confirm_btn.click(button="left")
|
|
62
72
|
logger.info("订单详情页面,消息提醒弹框,【确认】按钮点击完成")
|
|
73
|
+
except (RelationOrderConflictError,):
|
|
74
|
+
raise
|
|
63
75
|
except (PlaywrightTimeoutError, PlaywrightError, RuntimeError, Exception):
|
|
64
76
|
pass
|
|
65
77
|
return order_detail_po
|
|
@@ -77,6 +89,58 @@ async def add_custom_remark(*, logger: Logger, page: OrderDetailPage, remark: st
|
|
|
77
89
|
logger.info(f"订单详情页面,日志记录栏,【保存备注】按钮点击完成")
|
|
78
90
|
|
|
79
91
|
|
|
92
|
+
async def add_custom_remark_with_http(
|
|
93
|
+
*, order_id: int, remark: str, domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
94
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
95
|
+
) -> Dict[str, Any]:
|
|
96
|
+
return await _fill_remark_with_http(
|
|
97
|
+
remark=remark, order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=timeout,
|
|
98
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
async def update_order_policy_with_http(
|
|
103
|
+
*, order_id: int, policy_name: str, domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
104
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, old_policy_name: Optional[str] = None,
|
|
105
|
+
playwright_state: Dict[str, Any] = None
|
|
106
|
+
) -> Dict[str, Any]:
|
|
107
|
+
return await _update_policy_with_http(
|
|
108
|
+
policy_name=policy_name, order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry,
|
|
109
|
+
timeout=timeout, enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state,
|
|
110
|
+
old_policy_name=old_policy_name
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
async def locked_order_with_http(
|
|
115
|
+
*, order_id: int, domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
116
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
117
|
+
) -> Dict[str, Any]:
|
|
118
|
+
return await _locked_order_with_http(
|
|
119
|
+
order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=timeout,
|
|
120
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
async def unlock_order_with_http(
|
|
125
|
+
*, order_id: int, domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
126
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
127
|
+
) -> Dict[str, Any]:
|
|
128
|
+
return await _unlock_order_with_http(
|
|
129
|
+
order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=timeout,
|
|
130
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
async def forced_unlock_order_with_http(
|
|
135
|
+
*, order_id: int, domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
136
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
137
|
+
) -> Dict[str, Any]:
|
|
138
|
+
return await _forced_unlock_order_with_http(
|
|
139
|
+
order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=timeout,
|
|
140
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
|
|
80
144
|
async def update_order_policy(
|
|
81
145
|
*, page: OrderDetailPage, logger: Logger, policy: str, order_id: int, timeout: float = 5.0
|
|
82
146
|
) -> None:
|
|
@@ -93,6 +157,13 @@ async def order_unlock(
|
|
|
93
157
|
*, logger: Logger, page: OrderDetailPage, remark: str, order_id: int, is_force: bool = False,
|
|
94
158
|
qlv_user_id: Optional[str] = None, timeout: float = 5.0
|
|
95
159
|
) -> None:
|
|
160
|
+
try:
|
|
161
|
+
confirm_btn = await page.get_message_notice_dialog_confirm_btn(timeout=3)
|
|
162
|
+
await confirm_btn.click(button="left")
|
|
163
|
+
logger.info("订单详情页面,消息提醒弹框,【确认】按钮点击完成")
|
|
164
|
+
await asyncio.sleep(2)
|
|
165
|
+
except (Exception,):
|
|
166
|
+
pass
|
|
96
167
|
# 1. 获取订单操作锁的状态
|
|
97
168
|
lock_state, lock_btn = await page.get_order_lock_state_btn(timeout=timeout)
|
|
98
169
|
if "强制解锁" in lock_state:
|
|
@@ -101,7 +172,7 @@ async def order_unlock(
|
|
|
101
172
|
await lock_btn.click(button="left")
|
|
102
173
|
logger.info(f"订单详情页面,用户操作【{lock_state}】按钮点击完成")
|
|
103
174
|
try:
|
|
104
|
-
confirm_btn = await page.get_message_notice_dialog_confirm_btn(timeout=
|
|
175
|
+
confirm_btn = await page.get_message_notice_dialog_confirm_btn(timeout=5)
|
|
105
176
|
await confirm_btn.click(button="left")
|
|
106
177
|
logger.info("订单详情页面,强制解锁弹框确认,【确认】按钮点击完成")
|
|
107
178
|
await asyncio.sleep(2)
|
|
@@ -115,10 +186,27 @@ async def order_unlock(
|
|
|
115
186
|
return
|
|
116
187
|
elif "操作" in lock_state:
|
|
117
188
|
await lock_btn.click(button="left")
|
|
118
|
-
|
|
119
|
-
|
|
189
|
+
logger.info(f"订单详情页面,日志记录栏,【{lock_state}】按钮点击完成")
|
|
190
|
+
try:
|
|
191
|
+
confirm_btn = await page.get_message_notice_dialog_confirm_btn(timeout=3)
|
|
192
|
+
await confirm_btn.click(button="left")
|
|
193
|
+
logger.info("订单详情页面,消息提醒弹框,【确认】按钮点击完成")
|
|
194
|
+
await asyncio.sleep(2)
|
|
195
|
+
except (Exception,):
|
|
196
|
+
pass
|
|
120
197
|
lock_state, lock_btn = await page.get_order_lock_state_btn(timeout=timeout)
|
|
121
|
-
logger.info(f"
|
|
198
|
+
logger.info(f"订单详情页面,页面刷新后,【{lock_state}】按钮获取完成")
|
|
199
|
+
if "操作" in lock_state:
|
|
200
|
+
await lock_btn.click(button="left")
|
|
201
|
+
logger.info(f"订单详情页面,日志记录栏,【{lock_state}】按钮点击完成")
|
|
202
|
+
try:
|
|
203
|
+
confirm_btn = await page.get_message_notice_dialog_confirm_btn(timeout=3)
|
|
204
|
+
await confirm_btn.click(button="left")
|
|
205
|
+
logger.info("订单详情页面,消息提醒弹框,【确认】按钮点击完成")
|
|
206
|
+
await asyncio.sleep(2)
|
|
207
|
+
except (Exception,):
|
|
208
|
+
pass
|
|
209
|
+
lock_state, lock_btn = await page.get_order_lock_state_btn(timeout=timeout)
|
|
122
210
|
if remark:
|
|
123
211
|
# 2. 添加解锁备注
|
|
124
212
|
await add_custom_remark(logger=logger, page=page, remark=remark, timeout=timeout)
|
|
@@ -155,11 +243,19 @@ async def order_locked(
|
|
|
155
243
|
# 2. 点击【锁定|操作】按钮
|
|
156
244
|
await lock_btn.click(button="left")
|
|
157
245
|
logger.info(f"订单详情页面,日志记录栏,【{lock_state}】按钮点击完成")
|
|
246
|
+
try:
|
|
247
|
+
confirm_btn = await page.get_message_notice_dialog_confirm_btn(timeout=1)
|
|
248
|
+
await confirm_btn.click(button="left")
|
|
249
|
+
logger.info("订单详情页面,强制解锁弹框确认,【确认】按钮点击完成")
|
|
250
|
+
await asyncio.sleep(2)
|
|
251
|
+
except (PlaywrightTimeoutError, PlaywrightError, RuntimeError, Exception):
|
|
252
|
+
pass
|
|
158
253
|
|
|
159
254
|
|
|
160
255
|
async def first_open_page_order_locked(
|
|
161
256
|
*, logger: Logger, page: Page, protocol: str, domain: str, order_id: int, is_force: bool = False,
|
|
162
|
-
qlv_user_id: Optional[str] = None, timeout: float = 5.0,
|
|
257
|
+
qlv_user_id: Optional[str] = None, timeout: float = 5.0, retry: int = 1, enable_log: bool = True,
|
|
258
|
+
cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None, **kwargs
|
|
163
259
|
) -> OrderDetailPage:
|
|
164
260
|
# 1. 打开页面
|
|
165
261
|
order_detail_po = await open_order_detail_page(
|
|
@@ -167,141 +263,30 @@ async def first_open_page_order_locked(
|
|
|
167
263
|
)
|
|
168
264
|
|
|
169
265
|
# 2. 锁定订单
|
|
170
|
-
await order_locked(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
)
|
|
174
|
-
return order_detail_po
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
async def first_open_page_order_unlock(
|
|
178
|
-
*, logger: Logger, page: Page, protocol: str, domain: str, order_id: int, is_force: bool = False,
|
|
179
|
-
qlv_user_id: Optional[str] = None, timeout: float = 5.0, remark: Optional[str] = None, **kwargs
|
|
180
|
-
) -> OrderDetailPage:
|
|
181
|
-
# 1. 打开页面
|
|
182
|
-
order_detail_po = await open_order_detail_page(
|
|
183
|
-
page=page, logger=logger, protocol=protocol, domain=domain, order_id=order_id, timeout=timeout
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
# 2. 解锁订单
|
|
187
|
-
await order_unlock(
|
|
188
|
-
logger=logger, page=order_detail_po, order_id=order_id, timeout=timeout, is_force=is_force,
|
|
189
|
-
qlv_user_id=qlv_user_id, remark=remark
|
|
190
|
-
)
|
|
191
|
-
return order_detail_po
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
async def fill_procurement_info(
|
|
195
|
-
*, logger: Logger, page: OrderDetailPage, order_id: int, out_ticket_platform_type: str, purchase_amount: float,
|
|
196
|
-
out_ticket_platform: str, out_ticket_account: str, purchase_account_type: str, purchase_account: str,
|
|
197
|
-
ceair_user_id: str, ceair_password: str, payment_id: str, platform_order_id: str, timeout: float = 5.0
|
|
198
|
-
) -> None:
|
|
199
|
-
# 1. 出票地类型选择【out_ticket_platform_type】
|
|
200
|
-
out_ticket_platform_type_dropdown = await page.get_out_ticket_platform_type_dropdown(timeout=timeout)
|
|
201
|
-
await out_ticket_platform_type_dropdown.select_option(label=out_ticket_platform_type)
|
|
202
|
-
# await out_ticket_platform_type_dropdown.click(button="left")
|
|
203
|
-
# out_ticket_platform_type_select_option = await page.get_out_ticket_platform_type_select_option(
|
|
204
|
-
# select_option=out_ticket_platform_type, timeout=timeout
|
|
205
|
-
# )
|
|
206
|
-
# await out_ticket_platform_type_select_option.click(button="left")
|
|
207
|
-
logger.info(f"订单详情页面,采购信息栏,出票地类型选择<{out_ticket_platform_type}>已完成")
|
|
208
|
-
await asyncio.sleep(1)
|
|
209
|
-
|
|
210
|
-
# 2. 出票平台选择【out_ticket_platform】
|
|
211
|
-
out_ticket_platform_dropdown = await page.get_out_ticket_platform_dropdown(timeout=timeout)
|
|
212
|
-
await out_ticket_platform_dropdown.select_option(label=out_ticket_platform)
|
|
213
|
-
# await out_ticket_platform_dropdown.click(button="left")
|
|
214
|
-
# out_ticket_platform_select_option = await page.get_out_ticket_platform_select_option(
|
|
215
|
-
# select_option=out_ticket_platform, timeout=timeout
|
|
266
|
+
# await order_locked(
|
|
267
|
+
# logger=logger, page=order_detail_po, order_id=order_id, timeout=timeout, is_force=is_force,
|
|
268
|
+
# qlv_user_id=qlv_user_id
|
|
216
269
|
# )
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
# 3. 出票账号选择【out_ticket_account】
|
|
222
|
-
out_ticket_account_dropdown = await page.get_out_ticket_account_dropdown(timeout=timeout)
|
|
223
|
-
await out_ticket_account_dropdown.select_option(label=out_ticket_account)
|
|
224
|
-
# await out_ticket_account_dropdown.click(button="left")
|
|
225
|
-
# out_ticket_account_select_option = await page.get_out_ticket_account_select_option(
|
|
226
|
-
# select_option=out_ticket_account, timeout=timeout
|
|
227
|
-
# )
|
|
228
|
-
# await out_ticket_account_select_option.click(button="left")
|
|
229
|
-
logger.info(f"订单详情页面,采购信息栏,出票账号选择<{out_ticket_account}>已完成")
|
|
230
|
-
await asyncio.sleep(1)
|
|
231
|
-
|
|
232
|
-
# 4. 采购账号类型选择【purchase_account_type】
|
|
233
|
-
purchase_account_type_dropdown = await page.get_purchase_account_type_dropdown(timeout=timeout)
|
|
234
|
-
await purchase_account_type_dropdown.select_option(label=purchase_account_type)
|
|
235
|
-
# await purchase_account_type_dropdown.click(button="left")
|
|
236
|
-
# purchase_account_type_select_option = await page.get_purchase_account_type_select_option(
|
|
237
|
-
# select_option=purchase_account_type, timeout=timeout
|
|
238
|
-
# )
|
|
239
|
-
# await purchase_account_type_select_option.click(button="left")
|
|
240
|
-
logger.info(f"订单详情页面,采购信息栏,采购账号类型选择<{purchase_account_type}>已完成")
|
|
241
|
-
await asyncio.sleep(1)
|
|
242
|
-
|
|
243
|
-
# 5. 采购账号选择【purchase_account】
|
|
244
|
-
purchase_account_dropdown = await page.get_purchase_account_dropdown(timeout=timeout)
|
|
245
|
-
await purchase_account_dropdown.select_option(label=purchase_account)
|
|
246
|
-
# await purchase_account_dropdown.click(button="left")
|
|
247
|
-
# purchase_account_select_option = await page.get_purchase_account_select_option(
|
|
248
|
-
# select_option=purchase_account, timeout=timeout
|
|
249
|
-
# )
|
|
250
|
-
# await purchase_account_select_option.click(button="left")
|
|
251
|
-
logger.info(f"订单详情页面,采购信息栏,采购账号选择<{purchase_account}>已完成")
|
|
252
|
-
await asyncio.sleep(1)
|
|
253
|
-
|
|
254
|
-
# 6. 填写采购金额
|
|
255
|
-
purchase_amount_input = await page.get_purchase_amount_input(timeout=timeout)
|
|
256
|
-
await purchase_amount_input.fill(value=str(purchase_amount))
|
|
257
|
-
logger.info(f"订单详情页面,采购信息栏,采购金额<{purchase_amount}>输入完成")
|
|
258
|
-
|
|
259
|
-
# 7. 填写备注
|
|
260
|
-
remark_input = await page.get_remark_input(timeout=timeout)
|
|
261
|
-
value = f"{ceair_user_id}/{ceair_password}"
|
|
262
|
-
await remark_input.fill(value=value)
|
|
263
|
-
logger.info(f"订单详情页面,采购信息栏,备注<{value}>输入完成")
|
|
264
|
-
|
|
265
|
-
# 8. 填写对账标识
|
|
266
|
-
main_check_input = await page.get_main_check_input(timeout=timeout)
|
|
267
|
-
await main_check_input.fill(value=payment_id)
|
|
268
|
-
logger.info(f"订单详情页面,采购信息栏,对账标识<{payment_id}>输入完成")
|
|
269
|
-
|
|
270
|
-
# 9. 填写官网订单号
|
|
271
|
-
air_comp_order_id_input = await page.get_air_comp_order_id_input(timeout=timeout)
|
|
272
|
-
await air_comp_order_id_input.fill(value=platform_order_id)
|
|
273
|
-
logger.info(f"订单详情页面,采购信息栏,官网订单号<{platform_order_id}>输入完成")
|
|
274
|
-
|
|
275
|
-
# 10. 点击【保存采购】按钮
|
|
276
|
-
procurement_info_save_btn = await page.get_procurement_info_save_btn(timeout=timeout)
|
|
277
|
-
await procurement_info_save_btn.click(button="left")
|
|
278
|
-
logger.info(f"订单详情页面,采购信息栏,【保存采购】按钮点击完成")
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
async def first_open_page_fill_procurement_info(
|
|
282
|
-
*, logger: Logger, page: Page, order_id: int, protocol: str, domain: str, out_ticket_platform_type: str,
|
|
283
|
-
purchase_amount: float, out_ticket_platform: str, out_ticket_account: str, purchase_account_type: str,
|
|
284
|
-
purchase_account: str, ceair_user_id: str, ceair_password: str, payment_id: str, platform_order_id: str,
|
|
285
|
-
is_force: bool = False, qlv_user_id: Optional[str] = None, timeout: float = 5.0, **kwargs: Any
|
|
286
|
-
) -> OrderDetailPage:
|
|
287
|
-
# 1. 打开页面
|
|
288
|
-
order_detail_po = await open_order_detail_page(
|
|
289
|
-
page=page, logger=logger, protocol=protocol, domain=domain, order_id=order_id, timeout=timeout
|
|
290
|
-
)
|
|
291
|
-
|
|
292
|
-
# 2. 锁定订单
|
|
293
|
-
await order_locked(
|
|
294
|
-
logger=logger, page=order_detail_po, order_id=order_id, is_force=is_force, timeout=timeout,
|
|
295
|
-
qlv_user_id=qlv_user_id
|
|
296
|
-
)
|
|
297
|
-
|
|
298
|
-
# 3. 回填采购信息
|
|
299
|
-
await fill_procurement_info(
|
|
300
|
-
out_ticket_platform_type=out_ticket_platform_type, out_ticket_account=out_ticket_account, payment_id=payment_id,
|
|
301
|
-
purchase_amount=purchase_amount, out_ticket_platform=out_ticket_platform, purchase_account=purchase_account,
|
|
302
|
-
purchase_account_type=purchase_account_type, ceair_user_id=ceair_user_id, ceair_password=ceair_password,
|
|
303
|
-
platform_order_id=platform_order_id, timeout=timeout, logger=logger, page=order_detail_po, order_id=order_id
|
|
270
|
+
response = await _locked_order_with_http(
|
|
271
|
+
order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=int(timeout),
|
|
272
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
304
273
|
)
|
|
274
|
+
message = response.get("message")
|
|
275
|
+
if message == "订单出票":
|
|
276
|
+
logger.info(f"订单<{order_id}>,被用户<{qlv_user_id}>锁单成功")
|
|
277
|
+
else:
|
|
278
|
+
msg: str = "锁单失败"
|
|
279
|
+
if message == "强旅系统":
|
|
280
|
+
if response.get("data").find("用户登陆") != -1:
|
|
281
|
+
raise UserNotLoginError(f"{msg},用户<{qlv_user_id}>未登录劲旅系统")
|
|
282
|
+
else:
|
|
283
|
+
msg = msg + "," + response.get("data") if len(
|
|
284
|
+
response.get("data")
|
|
285
|
+
) < 100 else response.get("data")[:100]
|
|
286
|
+
raise RuntimeError(msg)
|
|
287
|
+
elif message == "操作提示":
|
|
288
|
+
msg = msg + f",原因:{response.get('data')}"
|
|
289
|
+
raise LockedOrderFailedError(msg)
|
|
305
290
|
return order_detail_po
|
|
306
291
|
|
|
307
292
|
|
|
@@ -321,26 +306,23 @@ async def fill_itinerary(
|
|
|
321
306
|
raise RuntimeError(
|
|
322
307
|
f"传递回填票号的乘客证件信息<{kwargs_passengers}>与订单实际乘客信息<{current_passengers}>不一致"
|
|
323
308
|
)
|
|
324
|
-
passenger_itinerary_locator = cast(Locator, None)
|
|
325
309
|
for passenger_locator in passenger_itinerary_locators:
|
|
326
310
|
current_passenger = passenger_locator.get("username")
|
|
327
311
|
passenger_itinerary = passengers_itinerary.get(current_passenger)
|
|
328
312
|
if passenger_itinerary:
|
|
329
313
|
passenger_itinerary_locator: Locator = passenger_locator.get("locator")
|
|
330
314
|
await passenger_itinerary_locator.fill(value=passenger_itinerary)
|
|
315
|
+
await passenger_itinerary_locator.press("Enter")
|
|
331
316
|
logger.info(f"订单<{order_id}>,乘客<{current_passenger}>的票号<{passenger_itinerary}>填写完成")
|
|
317
|
+
await asyncio.sleep(1)
|
|
332
318
|
else:
|
|
333
319
|
logger.warning(f"订单<{order_id}>,乘客<{current_passenger}>的票号没有获取到,本次回填跳过,等待下一次")
|
|
334
|
-
if passenger_itinerary_locator:
|
|
335
|
-
await passenger_itinerary_locator.press("Enter")
|
|
336
|
-
logger.info(f"订单<{order_id}>,本次的票号回填完成")
|
|
337
|
-
else:
|
|
338
|
-
raise RuntimeError(f"回填票号过程异常,回填失败")
|
|
339
320
|
|
|
340
321
|
|
|
341
322
|
async def first_open_page_fill_itinerary(
|
|
342
|
-
*, page: Page, logger: Logger, protocol: str, domain: str, order_id: int,
|
|
343
|
-
passengers_itinerary: Dict[str, Any], timeout: float = 20.0,
|
|
323
|
+
*, page: Page, logger: Logger, protocol: str, domain: str, order_id: int, retry: int = 1,
|
|
324
|
+
enable_log: bool = True, passengers_itinerary: Dict[str, Any], timeout: float = 20.0,
|
|
325
|
+
cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None, **kwargs: Any
|
|
344
326
|
) -> OrderDetailPage:
|
|
345
327
|
# 1. 开发页面
|
|
346
328
|
order_detail_po = await open_order_detail_page(
|
|
@@ -353,25 +335,35 @@ async def first_open_page_fill_itinerary(
|
|
|
353
335
|
passengers_itinerary=passengers_itinerary
|
|
354
336
|
)
|
|
355
337
|
logger.info(f"订单<{order_id}>,票号回填流程结束")
|
|
356
|
-
await order_unlock(logger=logger, page=order_detail_po, order_id=order_id, timeout=timeout, remark="")
|
|
357
|
-
logger.info(f"订单<{order_id}>,订单解锁成功")
|
|
358
|
-
return order_detail_po
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
async def first_open_page_update_policy(
|
|
362
|
-
*, page: Page, logger: Logger, protocol: str, domain: str, order_id: int, policy: str, timeout: float = 20.0,
|
|
363
|
-
**kwargs: Any
|
|
364
|
-
) -> OrderDetailPage:
|
|
365
|
-
# 1. 打开页面
|
|
366
|
-
order_detail_po = await open_order_detail_page(
|
|
367
|
-
page=page, logger=logger, protocol=protocol, domain=domain, order_id=order_id, timeout=timeout
|
|
368
|
-
)
|
|
369
|
-
|
|
370
|
-
# 2. 更新订单政策代码
|
|
371
|
-
await update_order_policy(
|
|
372
|
-
logger=logger, page=order_detail_po, order_id=order_id, timeout=timeout, policy=policy
|
|
373
|
-
)
|
|
374
338
|
|
|
339
|
+
# 3. 解锁订单
|
|
340
|
+
# await order_unlock(
|
|
341
|
+
# logger=logger, page=order_detail_po, order_id=order_id, timeout=timeout, is_force=True, remark=""
|
|
342
|
+
# )
|
|
343
|
+
msg: str = f"订单<{order_id}>,"
|
|
344
|
+
try:
|
|
345
|
+
response = await forced_unlock_order_with_http(
|
|
346
|
+
retry=retry, timeout=int(timeout), enable_log=enable_log, cookie_jar=cookie_jar,
|
|
347
|
+
playwright_state=playwright_state, order_id=order_id, domain=domain, protocol=protocol
|
|
348
|
+
)
|
|
349
|
+
if response.get("data") == "1":
|
|
350
|
+
logger.info(f"{msg}强制解锁成功")
|
|
351
|
+
except Exception as e:
|
|
352
|
+
logger.error(f"{msg}强制解锁失败,原因:{e}")
|
|
353
|
+
try:
|
|
354
|
+
response = await unlock_order_with_http(
|
|
355
|
+
retry=retry, timeout=int(timeout), enable_log=enable_log, cookie_jar=cookie_jar,
|
|
356
|
+
playwright_state=playwright_state, order_id=order_id, domain=domain, protocol=protocol
|
|
357
|
+
)
|
|
358
|
+
if response.get("data") == "OK":
|
|
359
|
+
logger.info(f"{msg}解锁成功")
|
|
360
|
+
else:
|
|
361
|
+
if response.get('data'):
|
|
362
|
+
logger.error(f"{msg}解锁失败,原因:{response.get('data')}")
|
|
363
|
+
else:
|
|
364
|
+
logger.error(f"{msg}解锁失败,原因:{response}")
|
|
365
|
+
except Exception as e:
|
|
366
|
+
logger.error(f"{msg}解锁失败,原因:{e}")
|
|
375
367
|
return order_detail_po
|
|
376
368
|
|
|
377
369
|
|
|
@@ -379,7 +371,7 @@ async def first_open_page_my_order_unlock(
|
|
|
379
371
|
*, page: Page, logger: Logger, protocol: str, domain: str, order_id: int, qlv_user_id: str,
|
|
380
372
|
policy: Optional[str] = None, remark: Optional[str] = None, timeout: float = 20.0, is_force: bool = False,
|
|
381
373
|
**kwargs: Any
|
|
382
|
-
) ->
|
|
374
|
+
) -> None:
|
|
383
375
|
# 1. 打开页面
|
|
384
376
|
order_detail_po = await open_order_detail_page(
|
|
385
377
|
page=page, logger=logger, protocol=protocol, domain=domain, order_id=order_id, timeout=timeout
|
|
@@ -391,56 +383,10 @@ async def first_open_page_my_order_unlock(
|
|
|
391
383
|
logger=logger, page=order_detail_po, order_id=order_id, timeout=timeout, policy=policy
|
|
392
384
|
)
|
|
393
385
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
# 4. 获取订单操作锁的状态
|
|
399
|
-
lock_state, lock_btn = await order_detail_po.get_order_lock_state_btn(timeout=timeout)
|
|
400
|
-
if "强制解锁" in lock_state:
|
|
401
|
-
if is_force is False:
|
|
402
|
-
logger.warning(f"订单<{order_id}>,非本账号<{qlv_user_id}>的锁单,暂不处理,即将跳过")
|
|
403
|
-
return order_detail_po
|
|
404
|
-
await lock_btn.click(button="left")
|
|
405
|
-
logger.info(f"订单详情页面,用户操作【{lock_state}】按钮点击完成")
|
|
406
|
-
try:
|
|
407
|
-
confirm_btn = await order_detail_po.get_message_notice_dialog_confirm_btn(timeout=1)
|
|
408
|
-
await confirm_btn.click(button="left")
|
|
409
|
-
logger.info("订单详情页面,强制解锁弹框确认,【确认】按钮点击完成")
|
|
410
|
-
await asyncio.sleep(2)
|
|
411
|
-
except (PlaywrightTimeoutError, PlaywrightError, RuntimeError, Exception):
|
|
412
|
-
pass
|
|
413
|
-
logger.warning(f"订单<{order_id}>,已被用户<{qlv_user_id or '无记录'}>强制解锁")
|
|
414
|
-
# 再次获取订单操作锁的状态
|
|
415
|
-
lock_state, lock_btn = await order_detail_po.get_order_lock_state_btn(timeout=timeout)
|
|
416
|
-
elif "锁定" in lock_state:
|
|
417
|
-
logger.info(f"订单<{order_id}>,处于无锁状态,无需解锁处理")
|
|
418
|
-
return order_detail_po
|
|
419
|
-
elif "操作" in lock_state:
|
|
420
|
-
await lock_btn.click(button="left")
|
|
421
|
-
await asyncio.sleep(2)
|
|
422
|
-
lock_state_temp = lock_state
|
|
423
|
-
lock_state, lock_btn = await order_detail_po.get_order_lock_state_btn(timeout=timeout)
|
|
424
|
-
logger.info(f"订单详情页面,日志记录栏,【{lock_state_temp}】按钮点击完成")
|
|
425
|
-
|
|
426
|
-
# 5. 点击【解锁返回】按钮
|
|
427
|
-
await lock_btn.click(button="left")
|
|
428
|
-
await asyncio.sleep(2)
|
|
429
|
-
logger.info(f"订单详情页面,日志记录栏,【{lock_state}】按钮点击完成")
|
|
430
|
-
return order_detail_po
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
async def fill_procurement_with_http(
|
|
434
|
-
*, order_id: int, qlv_domain: str, amount: float, pre_order_id: str, platform_user_id: str, user_password: str,
|
|
435
|
-
passengers: List[str], fids: str, pids: List[str], transaction_id: str, qlv_protocol: str = "http",
|
|
436
|
-
retry: int = 1, timeout: int = 5, enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None,
|
|
437
|
-
playwright_state: Dict[str, Any] = None, data_list: Optional[List[Dict[str, Any]]] = None, **kwargs: Any
|
|
438
|
-
) -> Dict[str, Any]:
|
|
439
|
-
return await fill_procurement_info_with_http(
|
|
440
|
-
order_id=order_id, qlv_domain=qlv_domain, amount=amount, pre_order_id=pre_order_id,
|
|
441
|
-
platform_user_id=platform_user_id, user_password=user_password, passengers=passengers, fids=fids, pids=pids,
|
|
442
|
-
transaction_id=transaction_id, qlv_protocol=qlv_protocol, retry=retry, timeout=timeout, enable_log=enable_log,
|
|
443
|
-
cookie_jar=cookie_jar, playwright_state=playwright_state, data_list=data_list
|
|
386
|
+
# 3. 获取订单操作锁的状态
|
|
387
|
+
await order_unlock(
|
|
388
|
+
logger=logger, page=order_detail_po, remark=remark, order_id=order_id, is_force=is_force,
|
|
389
|
+
qlv_user_id=qlv_user_id, timeout=timeout
|
|
444
390
|
)
|
|
445
391
|
|
|
446
392
|
|
|
@@ -449,48 +395,39 @@ async def fill_procurement_with_http_callback(
|
|
|
449
395
|
cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None,
|
|
450
396
|
data_list: Optional[List[Dict[str, Any]]] = None, **kwargs: Any
|
|
451
397
|
) -> Dict[str, Any]:
|
|
452
|
-
return await
|
|
398
|
+
return await _fill_procurement_dto_with_http(
|
|
453
399
|
fill_procurement_dto=fill_procurement_dto, retry=retry, timeout=timeout, enable_log=enable_log,
|
|
454
400
|
cookie_jar=cookie_jar, playwright_state=playwright_state, data_list=data_list
|
|
455
401
|
)
|
|
456
402
|
|
|
457
403
|
|
|
458
404
|
async def fill_itinerary_with_http(
|
|
459
|
-
*,
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
) ->
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
405
|
+
*, order_id: int, qlv_domain: str, pid: str, tid: str, transaction_id: str, itinerary_id: str, retry: int = 1,
|
|
406
|
+
qlv_protocol: str = "http", timeout: int = 5, enable_log: bool = True, data: Optional[str] = None,
|
|
407
|
+
cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None, **kwargs: Any
|
|
408
|
+
) -> Dict[str, Any]:
|
|
409
|
+
return await _fill_itinerary_with_http(
|
|
410
|
+
order_id=order_id, qlv_domain=qlv_domain, pid=pid, tid=tid, transaction_id=transaction_id, data=data,
|
|
411
|
+
itinerary_id=itinerary_id, retry=retry, qlv_protocol=qlv_protocol, timeout=timeout, enable_log=enable_log,
|
|
412
|
+
cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
466
413
|
)
|
|
467
414
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
logger.info(f"订单<{order_id}>,乘客<{p_name}>票号<{itinerary_id}>回填成功")
|
|
488
|
-
else:
|
|
489
|
-
logger.warning(
|
|
490
|
-
f'订单<{order_id}>,乘客<{p_name}>票号<{itinerary_id}>回填失败:{response.get("data")}')
|
|
491
|
-
flag = False
|
|
492
|
-
except (Exception,):
|
|
493
|
-
flag = False
|
|
494
|
-
return flag
|
|
495
|
-
else:
|
|
496
|
-
raise EnvironmentError("还未填写采购信息,暂时不能回填票号")
|
|
415
|
+
|
|
416
|
+
async def kick_out_activity_order_with_http(
|
|
417
|
+
*, order_id: int, domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
418
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
419
|
+
) -> Dict[str, Any]:
|
|
420
|
+
return await _kick_out_activity_order_with_http(
|
|
421
|
+
order_id=order_id, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=timeout,
|
|
422
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
async def kick_out_activity_orders_with_http(
|
|
427
|
+
*, order_ids: List[int], domain: str, protocol: str = "http", retry: int = 1, timeout: int = 5,
|
|
428
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
429
|
+
) -> Dict[str, Any]:
|
|
430
|
+
return await _kick_out_activity_orders_with_http(
|
|
431
|
+
order_ids=order_ids, qlv_domain=domain, qlv_protocol=protocol, retry=retry, timeout=timeout,
|
|
432
|
+
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state
|
|
433
|
+
)
|
|
@@ -53,9 +53,10 @@ async def _get_paginated_order_table(
|
|
|
53
53
|
response = await fetch_page_fn(
|
|
54
54
|
domain=domain, protocol=protocol, retry=retry, timeout=timeout,
|
|
55
55
|
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state,
|
|
56
|
-
order_http_client=order_http_client, is_end=
|
|
56
|
+
order_http_client=order_http_client, is_end=False
|
|
57
57
|
)
|
|
58
58
|
if response.get("code") != 200:
|
|
59
|
+
await order_http_client.close()
|
|
59
60
|
return response
|
|
60
61
|
|
|
61
62
|
html = response["data"]
|
|
@@ -73,6 +74,7 @@ async def _get_paginated_order_table(
|
|
|
73
74
|
"pages": 1
|
|
74
75
|
})
|
|
75
76
|
response["data"] = pagination_info
|
|
77
|
+
await order_http_client.close()
|
|
76
78
|
return response
|
|
77
79
|
|
|
78
80
|
# --- 3. 多页:并发抓取第 2~pages 页 ---
|
|
@@ -82,7 +84,7 @@ async def _get_paginated_order_table(
|
|
|
82
84
|
resp = await fetch_page_fn(
|
|
83
85
|
domain=domain, protocol=protocol, retry=retry, timeout=timeout,
|
|
84
86
|
enable_log=enable_log, cookie_jar=cookie_jar, playwright_state=playwright_state,
|
|
85
|
-
order_http_client=client, current_page=page, pages=pages, is_end=
|
|
87
|
+
order_http_client=client, current_page=page, pages=pages, is_end=False
|
|
86
88
|
)
|
|
87
89
|
if resp.get("code") == 200:
|
|
88
90
|
return parse_order_table(html=resp["data"], table_state=table_state)
|
|
@@ -90,16 +92,6 @@ async def _get_paginated_order_table(
|
|
|
90
92
|
return list() # 抓取失败则返回空,不影响整体
|
|
91
93
|
return list()
|
|
92
94
|
|
|
93
|
-
# 🔥 并发:一口气抓全部分页
|
|
94
|
-
order_http_client = HttpClientFactory(
|
|
95
|
-
protocol=protocol if protocol == "http" else "https",
|
|
96
|
-
domain=domain,
|
|
97
|
-
timeout=timeout,
|
|
98
|
-
retry=retry,
|
|
99
|
-
enable_log=enable_log,
|
|
100
|
-
cookie_jar=cookie_jar,
|
|
101
|
-
playwright_state=playwright_state
|
|
102
|
-
)
|
|
103
95
|
tasks = [fetch_page(client=order_http_client, page=page) for page in range(2, pages + 1)]
|
|
104
96
|
results = await asyncio.gather(*tasks)
|
|
105
97
|
|
|
@@ -116,6 +108,7 @@ async def _get_paginated_order_table(
|
|
|
116
108
|
"pages": 1
|
|
117
109
|
})
|
|
118
110
|
response["data"] = pagination_info
|
|
111
|
+
await order_http_client.close()
|
|
119
112
|
return response
|
|
120
113
|
|
|
121
114
|
|
qlv_helper/http/order_page.py
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import re
|
|
13
13
|
import json
|
|
14
14
|
import aiohttp
|
|
15
|
+
from random import random
|
|
15
16
|
from datetime import datetime
|
|
16
17
|
from urllib.parse import quote
|
|
17
18
|
from bs4 import BeautifulSoup, Tag
|
|
@@ -44,46 +45,6 @@ async def get_order_page_html(
|
|
|
44
45
|
)
|
|
45
46
|
|
|
46
47
|
|
|
47
|
-
async def fill_procurement_info_with_http(
|
|
48
|
-
*, order_id: int, qlv_domain: str, amount: float, pre_order_id: str, platform_user_id: str, user_password: str,
|
|
49
|
-
passengers: List[str], fids: str, pids: List[str], transaction_id: str, qlv_protocol: str = "http",
|
|
50
|
-
retry: int = 1, timeout: int = 5, enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None,
|
|
51
|
-
playwright_state: Dict[str, Any] = None, data_list: Optional[List[Dict[str, Any]]] = None
|
|
52
|
-
) -> Dict[str, Any]:
|
|
53
|
-
client = HttpClientFactory(
|
|
54
|
-
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, enable_log=enable_log, retry=retry,
|
|
55
|
-
cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
headers = {
|
|
59
|
-
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
60
|
-
"Referer": f"{qlv_protocol}://{qlv_domain}/OrderProcessing/NewTicket/{order_id}?&r={datetime.now().strftime("%Y%m%d%H%M%S")}",
|
|
61
|
-
}
|
|
62
|
-
if data_list:
|
|
63
|
-
data = data_list
|
|
64
|
-
else:
|
|
65
|
-
remark = f"{platform_user_id}/{user_password}"
|
|
66
|
-
pName = "," + ",".join(passengers) + ","
|
|
67
|
-
pids = ",".join(pids)
|
|
68
|
-
data = [
|
|
69
|
-
{"tradingDat": datetime.now().strftime("%Y-%m-%d %H:%M"), "outTktPF": "G航司官网", "outTktLoginCode": "",
|
|
70
|
-
"typeName": "VCC", "accountID": "8", "accountName": "VCC", "transactionAmount": f"{amount}",
|
|
71
|
-
"mainCheckNumber": "", "airCoOrderID": f"{pre_order_id}", "QuotaResultAmount": "0.00",
|
|
72
|
-
"remark": f"{quote(remark)}", "flightIdx": ",1,", "pName": f"{pName}", "orderID": f"{order_id}",
|
|
73
|
-
"businessTypeName": "机票", "tradingItems": "机票支出", "actualAmount": 0, "pType": "成人",
|
|
74
|
-
"fids": f"{fids}", "pids": f"{pids}", "iscandel": "true", "isbatch": "false",
|
|
75
|
-
"MainCheckNumberValus": f"{transaction_id}",
|
|
76
|
-
"OfficeNo": "", "PriceStdActual": "0.00", "ReturnAmount": "0.0000", "OffsetReturnAmount": "0.00",
|
|
77
|
-
"profitRemark": "", "preSaleType": "", "ErrorType": "", "OutTktPFTypeID": "34", "OutTicketAccount": "",
|
|
78
|
-
"OutTicketAccountID": "", "OutTicketPWD": "", "OutTicketTel": "", "OutTicketPNR": ""}
|
|
79
|
-
]
|
|
80
|
-
data = f"list={json.dumps(data)}&isPayAll=true&delTransactionids=&OutTicketLossType&OutTicketLossRemark="
|
|
81
|
-
return await client.request(
|
|
82
|
-
method="POST", url="/OrderProcessing/PurchaseInfoSave",
|
|
83
|
-
headers=headers, is_end=True, data=data.encode("utf-8")
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
|
|
87
48
|
async def fill_procurement_dto_with_http(
|
|
88
49
|
*, fill_procurement_dto: FillProcurementInputDTO, retry: int = 1, timeout: int = 5, enable_log: bool = True,
|
|
89
50
|
cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None,
|
|
@@ -138,9 +99,96 @@ async def fill_procurement_dto_with_http(
|
|
|
138
99
|
)
|
|
139
100
|
|
|
140
101
|
|
|
141
|
-
async def
|
|
102
|
+
async def fill_remark_with_http(
|
|
103
|
+
*, remark: str, order_id: int, qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
104
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
105
|
+
) -> Dict[str, Any]:
|
|
106
|
+
client = HttpClientFactory(
|
|
107
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
108
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
headers = {
|
|
112
|
+
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
|
113
|
+
}
|
|
114
|
+
data = f"orderid={order_id}&remark={remark}"
|
|
115
|
+
return await client.request(
|
|
116
|
+
method="POST", url="/JPOrderCommon/SaveFreeRemark", headers=headers, is_end=True, data=data.encode("utf-8")
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
async def update_policy_with_http(
|
|
121
|
+
*, policy_name: str, order_id: int, qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
122
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, old_policy_name: Optional[str] = None,
|
|
123
|
+
playwright_state: Dict[str, Any] = None,
|
|
124
|
+
) -> Dict[str, Any]:
|
|
125
|
+
client = HttpClientFactory(
|
|
126
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
127
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
headers = {
|
|
131
|
+
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
|
132
|
+
}
|
|
133
|
+
data = f"OrderID={order_id}&PolicyName={policy_name}&OldPolicyName="
|
|
134
|
+
if old_policy_name is not None:
|
|
135
|
+
data = f"{data}{old_policy_name}"
|
|
136
|
+
return await client.request(
|
|
137
|
+
method="POST", url="/OrderProcessing/EditPolicyName", headers=headers, is_end=True, data=data.encode("utf-8")
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
async def locked_order_with_http(
|
|
142
|
+
*, order_id: int, qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
143
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
144
|
+
) -> Dict[str, Any]:
|
|
145
|
+
client = HttpClientFactory(
|
|
146
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
147
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
result = await client.request(method="GET", url=f"/OrderProcessing/Ticket/{order_id}", is_end=True)
|
|
151
|
+
if "操作提示" in result.get("message", ""):
|
|
152
|
+
soup = BeautifulSoup(result.get("data"), 'html.parser')
|
|
153
|
+
h3_tag = soup.find('h3')
|
|
154
|
+
if h3_tag:
|
|
155
|
+
text = h3_tag.get_text(strip=True)
|
|
156
|
+
if text:
|
|
157
|
+
result["data"] = text
|
|
158
|
+
return result
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
async def unlock_order_with_http(
|
|
162
|
+
*, order_id: int, qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
163
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
164
|
+
) -> Dict[str, Any]:
|
|
165
|
+
client = HttpClientFactory(
|
|
166
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
167
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return await client.request(
|
|
171
|
+
method="GET", url=f"/OrderProcessing/UnLock/{order_id}?s={random()}", is_end=True
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
async def forced_unlock_order_with_http(
|
|
176
|
+
*, order_id: int, qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
177
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
178
|
+
) -> Dict[str, Any]:
|
|
179
|
+
client = HttpClientFactory(
|
|
180
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
181
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
return await client.request(
|
|
185
|
+
method="GET", url=f"/OrderProcessing/UnLockForce/{order_id}?s={random()}", is_end=True
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async def fill_itinerary_with_http(
|
|
142
190
|
*, order_id: int, qlv_domain: str, pid: str, tid: str, transaction_id: str, itinerary_id: str, retry: int = 1,
|
|
143
|
-
qlv_protocol: str = "http", timeout: int = 5, enable_log: bool = True,
|
|
191
|
+
qlv_protocol: str = "http", timeout: int = 5, enable_log: bool = True, data: Optional[str] = None,
|
|
144
192
|
cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
145
193
|
) -> Dict[str, Any]:
|
|
146
194
|
client = HttpClientFactory(
|
|
@@ -152,13 +200,49 @@ async def fill_itinerary_info_with_http(
|
|
|
152
200
|
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
|
153
201
|
"Referer": f"{qlv_protocol}://{qlv_domain}/OrderProcessing/NewTicket_show/{order_id}?&r={datetime.now().strftime("%Y%m%d%H%M%S")}",
|
|
154
202
|
}
|
|
155
|
-
|
|
203
|
+
if not data:
|
|
204
|
+
data = f"OrderID={order_id}&OrderPID={pid}&OrderTID={tid}&TicketNo={itinerary_id}&ZJTransactionID={transaction_id}"
|
|
156
205
|
return await client.request(
|
|
157
206
|
method="POST", url="/OrderProcessing/TicketNoSave",
|
|
158
207
|
headers=headers, is_end=True, data=data.encode("utf-8")
|
|
159
208
|
)
|
|
160
209
|
|
|
161
210
|
|
|
211
|
+
async def kick_out_activity_order_with_http(
|
|
212
|
+
*, order_id: int, qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
213
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
214
|
+
) -> Dict[str, Any]:
|
|
215
|
+
client = HttpClientFactory(
|
|
216
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
217
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
218
|
+
)
|
|
219
|
+
headers = {
|
|
220
|
+
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
|
221
|
+
}
|
|
222
|
+
data = f"ID={order_id}"
|
|
223
|
+
return await client.request(
|
|
224
|
+
method="POST", url=f"/OrderList/KickOutActivityOrders", is_end=True, data=data.encode("utf-8"), headers=headers
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
async def kick_out_activity_orders_with_http(
|
|
229
|
+
*, order_ids: List[int], qlv_protocol: str, qlv_domain: str, retry: int = 1, timeout: int = 5,
|
|
230
|
+
enable_log: bool = True, cookie_jar: Optional[aiohttp.CookieJar] = None, playwright_state: Dict[str, Any] = None
|
|
231
|
+
) -> Dict[str, Any]:
|
|
232
|
+
client = HttpClientFactory(
|
|
233
|
+
protocol=qlv_protocol, domain=qlv_domain, timeout=timeout, retry=retry,
|
|
234
|
+
enable_log=enable_log, cookie_jar=cookie_jar or aiohttp.CookieJar(), playwright_state=playwright_state
|
|
235
|
+
)
|
|
236
|
+
headers = {
|
|
237
|
+
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
|
238
|
+
}
|
|
239
|
+
order_ids_str = ",".join(str(id) for id in order_ids) + ","
|
|
240
|
+
data = f"OrderIDS={order_ids_str}"
|
|
241
|
+
return await client.request(
|
|
242
|
+
method="POST", url=f"/OrderList/YJTCActivityOrders", is_end=True, data=data.encode("utf-8"), headers=headers
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
|
|
162
246
|
def order_info_static_headers() -> OrderedDict[str, str]:
|
|
163
247
|
return OrderedDict([
|
|
164
248
|
("receipted_ota", "OTA实收"), # 0
|
|
@@ -263,7 +263,7 @@ class OrderDetailPage(BasePo):
|
|
|
263
263
|
:return: (是否存在, 错误信息|元素对象)
|
|
264
264
|
"""
|
|
265
265
|
selector: str = '//a[@id="alertMsg_btnConfirm"]/cite'
|
|
266
|
-
return await self.get_locator(selector=selector, timeout=timeout)
|
|
266
|
+
return await self.get_locator(selector=selector, timeout=timeout, strict=False)
|
|
267
267
|
|
|
268
268
|
async def get_policy_input(self, timeout: float = 5.0) -> Locator:
|
|
269
269
|
"""
|
|
@@ -290,3 +290,31 @@ class OrderDetailPage(BasePo):
|
|
|
290
290
|
if transaction_id:
|
|
291
291
|
transaction_ids.append(transaction_id.strip())
|
|
292
292
|
return transaction_ids
|
|
293
|
+
|
|
294
|
+
async def get_relation_order_detail_link(self, timeout: float = 5.0) -> Locator:
|
|
295
|
+
"""
|
|
296
|
+
获取关联订单的详情链接
|
|
297
|
+
:param timeout: 超时时间
|
|
298
|
+
:return:
|
|
299
|
+
"""
|
|
300
|
+
selector: str = 'xpath=//span[contains(text(), "关联订单")]/../a'
|
|
301
|
+
return await self.get_locator(selector=selector, timeout=timeout)
|
|
302
|
+
|
|
303
|
+
async def get_message_alert(self, timeout: float = 5.0) -> Locator:
|
|
304
|
+
"""
|
|
305
|
+
获取详情页面消息弹框
|
|
306
|
+
:param timeout: 超时时长
|
|
307
|
+
:return:
|
|
308
|
+
"""
|
|
309
|
+
selector: str = 'xpath=//a[@id="alertMsg_btnConfirm"]/cite/../..'
|
|
310
|
+
return await self.get_locator(selector=selector, timeout=timeout)
|
|
311
|
+
|
|
312
|
+
async def get_message_content(self, timeout: float = 5.0) -> str:
|
|
313
|
+
"""
|
|
314
|
+
获取详情页面消息弹框
|
|
315
|
+
:param timeout: 超时时长
|
|
316
|
+
:return:
|
|
317
|
+
"""
|
|
318
|
+
selector: str = 'xpath=//a[@id="alertMsg_btnConfirm"]/cite/../../p'
|
|
319
|
+
locator = await self.get_locator(selector=selector, timeout=timeout)
|
|
320
|
+
return (await locator.inner_text()).strip()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|