From ac930ec63e54b4848db34769c72ebf9a1fd43887 Mon Sep 17 00:00:00 2001 From: admin9webs Date: Fri, 10 Jul 2026 16:10:51 +0800 Subject: [PATCH] Add archived/tongtool-order-remark --- .../archived/tongtool-order-remark/SKILL.md | 180 ++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 skills/archived/tongtool-order-remark/SKILL.md diff --git a/skills/archived/tongtool-order-remark/SKILL.md b/skills/archived/tongtool-order-remark/SKILL.md new file mode 100644 index 0000000..889624e --- /dev/null +++ b/skills/archived/tongtool-order-remark/SKILL.md @@ -0,0 +1,180 @@ +--- +name: tongtool-order-remark +description: Log into Tongtool ERP, search for a specific order by ID, and add a remark. +--- + +# Tongtool Order Remark Automation + +This skill automates the process of logging into the Tongtool ERP system, navigating to a specific order using global search, and adding a custom remark to the order details. + +## Dependencies + +- Python 3 +- `DrissionPage` +- `ddddocr` +- `requests` + +## The Script + +This script performs the following steps: +1. Opens a headless Chromium browser using DrissionPage (Crucial: 1920x1080 window size). +2. Navigates to the Tongtool login page (`passport.tongtool.com`). +3. Uses `ddddocr` to solve the captcha and logs in. +4. Navigates to the ERP dashboard to initialize the session. +5. Uses the global search URL to jump directly to the target order's detail page. +6. Clicks the "Add Remark" button (`#addOrderRemark`). +7. robustly injects the desired remark into the text area using JS events. +8. Clicks the "Save" button to apply the remark using `by_js=True`. + +```python +from DrissionPage import ChromiumPage, ChromiumOptions +import ddddocr, requests, json, time, os + +def add_order_remark(order_id: str, note_text: str, user: str = 'ozonezsjgw@163.com', pwd: str = '111111'): + co = ChromiumOptions() + # Path to playwright Chromium + co.set_browser_path('/home/ubuntu/.cache/ms-playwright/chromium-1217/chrome-linux64/chrome') + co.set_argument('--no-sandbox') + co.set_argument('--disable-dev-shm-usage') + # CRITICAL: Use a large window size to ensure the responsive UI displays the detail pane and action buttons + co.set_argument('--window-size=1920,1080') + co.headless() + co.auto_port() + + driver = ChromiumPage(co) + + # Helper: Fix ddddocr misrecognitions + def correct_ocr(raw_code): + cleaned = ''.join(c for c in raw_code if c.isascii() and c.isalnum()) + return cleaned.translate(str.maketrans('oliOSsZz', '01105522')) + + # Helper: Close layui popups that block interaction + def nuke_popups(page): + try: + page.run_js(""" + document.querySelectorAll('.layui-layer-shade, .layui-layer, .modal, .overlay, .jclose-blue, .close, [title="关闭"], .layui-layer-close').forEach(el => { try { el.remove(); } catch(e){} }); + """) + except: pass + + # Login function with retry mechanism + def login(driver, user, pwd, max_retry=5): + for attempt in range(max_retry): + driver.get('https://passport.tongtool.com/') + time.sleep(3) + driver.ele('css:input[name="username"]').input(user) + driver.ele('css:input[name="password"]').input(pwd) + + img = driver.ele('css:img.pic-yzm') + if not img: + time.sleep(2) + continue + + src = img.attr('src') + cookies = {c['name']: c['value'] for c in driver.cookies()} + + try: + resp = requests.get(src, cookies=cookies, timeout=10) + raw = ddddocr.DdddOcr(show_ad=False).classification(resp.content) + code = correct_ocr(raw) + if len(code) < 4: + continue + driver.ele('css:input[name="captcha"]').input(code) + driver.ele('css:button.btn-primary').click() + time.sleep(5) + except Exception as e: + print(f"Login request failed: {e}") + continue + + for _ in range(5): + if 'member' in driver.url or 'dashboard' in driver.url or 'yijiety' in driver.url: + return True + time.sleep(2) + + if 'passport' in driver.url: + body = driver.ele('tag:body').text + if '验证码输入错误' in body: + continue # Retry loop + elif '密码' in body and '错误' in body: + print("Wrong password") + return False + return False + + print("Attempting login...") + success = login(driver, user, pwd) + if not success: + print("Login failed after max retries.") + driver.quit() + return False + print("Login successful.") + + # Enter ERP to set session completely + driver.get("https://yijiety.tongtool.com/dashboard/homepage/index.htm") + time.sleep(8) + nuke_popups(driver) + + # Navigate to the specific order using global search + print(f"Navigating to order: {order_id}") + search_url = ( + f"https://yijiety.tongtool.com/search/order.htm" + f"?search_text_value={order_id}" + f"&search_mark=salesRecordNumber" + f"&source=global" + ) + driver.get(search_url) + time.sleep(12) + nuke_popups(driver) + + # Attempt to add the remark + remark_added = False + btn = driver.ele('css:#addOrderRemark') + if btn: + a_tag = btn.ele('tag:a') + if a_tag: + a_tag.click(by_js=True) + time.sleep(3) + textarea = driver.ele('tag:textarea') + if textarea: + print("Writing remark robustly...") + # MUST use JS dispatch for layui to detect the model change + js = f""" + var ta = document.querySelector('textarea'); + if(ta) {{ + ta.value = '{note_text}'; + ta.dispatchEvent(new Event('input', {{bubbles: true}})); + ta.dispatchEvent(new Event('change', {{bubbles: true}})); + }} + """ + driver.run_js(js) + time.sleep(1) + + for a in driver.eles('tag:a'): + if a.text.strip() == '保存': + a.click(by_js=True) + time.sleep(3) + print("Remark saved successfully!") + remark_added = True + break + else: + print("Could not find the text area for the remark.") + else: + print("Could not find clickable element inside the remark button.") + else: + print("Could not find the remark button (#addOrderRemark) on the page.") + + driver.quit() + return remark_added + +if __name__ == '__main__': + # Usage Example: + order_id = "16Ezyhbg-PO-211-05103794125430842" + custom_note = "Testing Order Remark Automation" + add_order_remark(order_id, custom_note) +``` + +## Pitfalls + +* **Window Size Requirement (CRITICAL):** It is critical to set a large window size (e.g., `--window-size=1920,1080`). The global search page uses a responsive grid. Without a wide window, the details pane (containing the remark button and other actions) may not be exposed or rendered in the DOM natively. +* **JS Event Dispatching for Textareas (CRITICAL):** Using `textarea.input('text')` often fails to update the underlying layui/Vue model, resulting in a blank note being saved. Always use `driver.run_js` to set `value` and dispatch `input` and `change` events natively. +* **JS Click for Save:** The save dialog anchor should be clicked with `by_js=True` (`a.click(by_js=True)`) because overlapping layui shades often block standard WebDriver clicks. +* **CSS Selector for Remark Button:** The button has a specific ID. You must use `driver.ele('css:#addOrderRemark')`, and then click the `` tag nested inside it. +* **Popups Blocking Interaction:** Tongtool frequently shows `layui` popups (announcements) that cover the screen. Ensure the aggressive `nuke_popups` function is called before interacting. \ No newline at end of file