diff --git a/README.md b/README.md deleted file mode 100644 index bc82ba8..0000000 --- a/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# Scert 项目 - -Scert 是一个统一管理 SSL 证书、自动续期并通过密码 SSH 部署到多台服务器的跨平台项目。 - -## 正式交付范围 - -正式产品仅包含 Web 管理界面和 Windows/Linux 服务端。CLI 作为服务端运维入口,用于初始化、服务启动、运维诊断、数据库迁移、备份恢复、服务安装和卸载,不作为另一套业务管理界面。 - -旧业务 CLI 已停用并返回中文迁移提示,范围和迁移方法见 `doc/命令行运维范围说明.md`。自动续期仍由服务端调度,手动业务操作通过 Web 执行,不再提供绕过 Web 流程的第二套 CLI 入口。 - -`desktop/` 保留 Wails 历史源码,供参考和独立开发;桌面窗口、托盘、自动更新、桌面配置管理及桌面 UI 测试均不属于正式交付或验收范围。正式发布脚本不调用 Wails,也不需要 WebView2 或 GTK 开发依赖。 - -## 项目目录 - -- `backend`:Go 核心服务、CLI、数据库和 HTTP API。 -- `frontend`:Vue Web 管理界面。 -- `doc`:需求确认、技术架构和开发任务清单。 - -## 开发基线 - -- 第一阶段使用 Let’s Encrypt + `go-acme/lego`。 -- 第一阶段包含单域名、泛域名和多域名 SAN。 -- 数据库支持目标包含 SQLite、MySQL 和 PostgreSQL;版本边界及实机验证状态见 `doc/构建版本与数据库支持矩阵.md`,代码适配不等于真实实例验收通过。 -- HTTPS 采用默认核心服务终止、高级反向代理终止的双模式设计。 -- Web 和运维 CLI 复用服务端核心、配置和数据。 - -## 开发状态 - -当前已完成配置、日志、数据库迁移、域名与服务器管理、管理员认证、DNS API 在线测试、lego DNS-01、证书申请与导入、自动续期、密码 SSH 部署、通知、设置接口和 Web 管理页面;SSH 私钥、公钥和密钥登录能力不属于当前产品,真实 DNS、ACME、远程服务器及平台安装验收仍需在授权环境完成。 - -详细内容请先阅读: - -- `doc/Scert整改合并优化清单.md`:当前整改需求基线。 -- `doc/Scert整改任务执行清单.md`:当前执行状态和验证证据。 -- `build/README.md`:正式构建和交付范围。 -- `doc/SSL服务程序需求确认文档.md` -- `doc/SSL服务程序技术架构设计文档.md` -- `doc/Scert开发任务清单.md` - -早期需求、架构和开发清单保留历史记录;与当前整改基线冲突的桌面目标不再执行。 - -## 首轮复审状态 - -2026 年 8 月 26 日已完成首轮代码复审。基础骨架、SQLite、CLI、HTTP、前端生产构建和 Windows/Linux amd64 构建已通过;MySQL 5.7/8.0 真实实例测试因缺少明确连接参数保持阻塞。详细记录以 `doc/Scert开发任务清单.md` 的“二十七、首轮开发复审记录”为准。 diff --git a/apply_default_server.py b/apply_default_server.py deleted file mode 100644 index ef77d92..0000000 --- a/apply_default_server.py +++ /dev/null @@ -1,41 +0,0 @@ -with open("frontend/src/views/Dashboard/DomainForm.js", "r", encoding="utf-8") as f: - text = f.read() - -old_code = """ function openCreate() { - if (saving.value) return; - version += 1; - editingId.value = ""; - targetID = ""; - form.value = emptyForm();""" - -new_code = """ function openCreate() { - if (saving.value) return; - version += 1; - editingId.value = ""; - targetID = ""; - form.value = emptyForm(); - if (servers.value && servers.value.length > 0) { - form.value.server_ids = [servers.value[0].id]; - }""" - -text = text.replace(old_code, new_code) -with open("frontend/src/views/Dashboard/DomainForm.js", "w", encoding="utf-8") as f: - f.write(text) - -with open("frontend/src/views/Dashboard/DomainForm.test.js", "r", encoding="utf-8") as f: - test_text = f.read() - -# 替换断言 -test_text = test_text.replace( - ' state.openCreate();\n assert.equal(state.editingId.value, "");\n assert.deepEqual(state.form.value.server_ids, []);', - ' state.openCreate();\n assert.equal(state.editingId.value, "");\n assert.deepEqual(state.form.value.server_ids, [firstServer.id]);' -) -test_text = test_text.replace( - ' state.openCreate();\n assert.equal(state.form.value.name, "");\n assert.deepEqual(state.form.value.server_ids, []);', - ' state.openCreate();\n assert.equal(state.form.value.name, "");\n assert.deepEqual(state.form.value.server_ids, [firstServer.id]);' -) - -with open("frontend/src/views/Dashboard/DomainForm.test.js", "w", encoding="utf-8") as f: - f.write(test_text) - -print("Updated DomainForm.js and DomainForm.test.js") diff --git a/check_mail_inputs.py b/check_mail_inputs.py deleted file mode 100644 index 2f80cea..0000000 --- a/check_mail_inputs.py +++ /dev/null @@ -1,28 +0,0 @@ -import json, websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -script = """ -(() => { - const inputs = Array.from(document.querySelectorAll('.mail-channel input, .mail-channel select')); - return inputs.map(el => ({ - tag: el.tagName, - type: el.type, - placeholder: el.placeholder, - value: el.type === 'checkbox' ? el.checked : el.value - })); -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) -ws.close() diff --git a/check_nav_items.py b/check_nav_items.py deleted file mode 100644 index 892b2bf..0000000 --- a/check_nav_items.py +++ /dev/null @@ -1,29 +0,0 @@ -import json, websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 查找所有 nav item -script = """ -(() => { - const navItems = Array.from(document.querySelectorAll('.dashboard-navigation-link, .nav-item, nav a, nav button, aside button, aside a')); - return navItems.map(el => ({ - tag: el.tagName, - text: el.innerText.trim(), - href: el.getAttribute('href'), - classes: el.className - })); -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) -ws.close() diff --git a/check_page_state.py b/check_page_state.py deleted file mode 100644 index 58833a2..0000000 --- a/check_page_state.py +++ /dev/null @@ -1,33 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -time.sleep(2) - -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": "document.body.innerText"} -})) -res = ws.recv() -print("Body text:", json.loads(res)["result"]["result"]["value"]) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_page_now.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_page_now.png") - -ws.close() diff --git a/check_projects_members.py b/check_projects_members.py deleted file mode 100644 index 8759e04..0000000 --- a/check_projects_members.py +++ /dev/null @@ -1,44 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击侧边栏“项目与成员” -script = """ -(() => { - const items = Array.from(document.querySelectorAll('.navigation-item')); - const target = items.find(b => b.innerText.includes('项目与成员')); - if (target) { - target.click(); - return 'Navigated to 项目与成员'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_projects_members.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_projects_members.png") - -ws.close() diff --git a/check_second_server.py b/check_second_server.py deleted file mode 100644 index 28e0c3c..0000000 --- a/check_second_server.py +++ /dev/null @@ -1,14 +0,0 @@ -import paramiko - -ssh = paramiko.SSHClient() -ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) -try: - ssh.connect('47.108.78.12', port=22, username='root', password='10102442Lb!', timeout=10) - print('SSH to 47.108.78.12 succeeded!') - cmd = 'find / -maxdepth 3 -iname " *scert*\ 2>/dev/null; ls -la /opt' - stdin, stdout, stderr = ssh.exec_command(cmd) - print('--- Search result for scert on 47.108.78.12 ---') - print(stdout.read().decode('utf-8', errors='ignore')) - ssh.close() -except Exception as e: - print('Error:', e) diff --git a/click_add_domain.py b/click_add_domain.py deleted file mode 100644 index f4c26f3..0000000 --- a/click_add_domain.py +++ /dev/null @@ -1,43 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“添加域名”按钮 -script = """ -(() => { - const btn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('添加域名')); - if (btn) { - btn.click(); - return 'Clicked 添加域名'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_add_domain_modal.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_add_domain_modal.png") - -ws.close() diff --git a/click_domains.py b/click_domains.py deleted file mode 100644 index 909a628..0000000 --- a/click_domains.py +++ /dev/null @@ -1,44 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“域名配置” -script = """ -(() => { - const buttons = Array.from(document.querySelectorAll('.navigation-item')); - const target = buttons.find(b => b.innerText.includes('域名配置')); - if (target) { - target.click(); - return 'Clicked 域名配置'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_domains_view.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_domains_view.png") - -ws.close() diff --git a/click_mail_tab.py b/click_mail_tab.py deleted file mode 100644 index a14d0e1..0000000 --- a/click_mail_tab.py +++ /dev/null @@ -1,44 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“邮件通知”选项卡 -script = """ -(() => { - const tabs = Array.from(document.querySelectorAll('button, div, span')); - const mailTab = tabs.find(el => el.innerText && el.innerText.trim() === '邮件通知'); - if (mailTab) { - mailTab.click(); - return 'Clicked 邮件通知'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_mail_tab.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_mail_tab.png") - -ws.close() diff --git a/click_server_btn.py b/click_server_btn.py deleted file mode 100644 index 6a24a6a..0000000 --- a/click_server_btn.py +++ /dev/null @@ -1,44 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“部署服务器”按钮 -script = """ -(() => { - const buttons = Array.from(document.querySelectorAll('.navigation-item')); - const target = buttons.find(b => b.innerText.includes('部署服务器')); - if (target) { - target.click(); - return 'Clicked 部署服务器'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_servers_clicked.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_servers_clicked.png") - -ws.close() diff --git a/click_servers.py b/click_servers.py deleted file mode 100644 index 83c3a0c..0000000 --- a/click_servers.py +++ /dev/null @@ -1,29 +0,0 @@ -import json, websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“部署服务器” -script = """ -(() => { - const all = Array.from(document.querySelectorAll('span, button, a, div')); - const target = all.find(el => el.innerText && el.innerText.trim() === '部署服务器'); - if (target) { - target.click(); - return 'Clicked ' + target.tagName; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) -ws.close() diff --git a/click_settings.py b/click_settings.py deleted file mode 100644 index 203c02b..0000000 --- a/click_settings.py +++ /dev/null @@ -1,43 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -script = """ -(() => { - const all = Array.from(document.querySelectorAll('span, button, a, div')); - const target = all.find(el => el.innerText && el.innerText.trim() === '系统设置'); - if (target) { - target.click(); - return 'Clicked ' + target.tagName; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_settings_view.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_settings_view.png") - -ws.close() diff --git a/close_settings.py b/close_settings.py deleted file mode 100644 index cb2119b..0000000 --- a/close_settings.py +++ /dev/null @@ -1,28 +0,0 @@ -import json, websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“关闭”系统设置弹窗 -script = """ -(() => { - const closeBtn = document.querySelector('.close-button'); - if (closeBtn) { - closeBtn.click(); - return 'Closed settings modal'; - } - return 'Close button not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) -ws.close() diff --git a/current_view.png b/current_view.png deleted file mode 100644 index 40034c2..0000000 Binary files a/current_view.png and /dev/null differ diff --git a/dashboard_account_layout.png b/dashboard_account_layout.png deleted file mode 100644 index 38f9247..0000000 Binary files a/dashboard_account_layout.png and /dev/null differ diff --git a/dashboard_after_login.png b/dashboard_after_login.png deleted file mode 100644 index 5c78d39..0000000 Binary files a/dashboard_after_login.png and /dev/null differ diff --git a/dashboard_equal_columns.png b/dashboard_equal_columns.png deleted file mode 100644 index 6d3f93d..0000000 Binary files a/dashboard_equal_columns.png and /dev/null differ diff --git a/deploy_frontend.py b/deploy_frontend.py deleted file mode 100644 index 6716f87..0000000 --- a/deploy_frontend.py +++ /dev/null @@ -1,33 +0,0 @@ -import paramiko, os - -ssh = paramiko.SSHClient() -ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) -ssh.connect("8.137.23.95", port=22, username="root", password="10102442Lb!", timeout=10) - -sftp = ssh.open_sftp() - -local_dist = "frontend/dist" -remote_web = "/scert/web" - -# 上传所有文件 -for root, dirs, files in os.walk(local_dist): - rel_root = os.path.relpath(root, local_dist).replace("\\", "/") - remote_dir = remote_web if rel_root == "." else f"{remote_web}/{rel_root}" - try: - sftp.mkdir(remote_dir) - except: - pass - for file in files: - local_file = os.path.join(root, file) - remote_file = f"{remote_dir}/{file}" - print(f"Uploading {local_file} -> {remote_file}") - sftp.put(local_file, remote_file) - -sftp.close() - -# 检查远程 /scert/web 文件 -stdin, stdout, stderr = ssh.exec_command("ls -la /scert/web /scert/web/assets") -print(stdout.read().decode()) - -ssh.close() -print("Deploy frontend done!") diff --git a/do_update.py b/do_update.py deleted file mode 100644 index e69de29..0000000 diff --git a/enable_smtp.py b/enable_smtp.py deleted file mode 100644 index d65e10f..0000000 --- a/enable_smtp.py +++ /dev/null @@ -1,43 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“启用 SMTP 发送”checkbox -script = """ -(() => { - const checkbox = document.querySelector('.mail-switch input[type="checkbox"]'); - if (checkbox) { - checkbox.click(); - return 'Checkbox checked: ' + checkbox.checked; - } - return 'Checkbox not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_mail_tab_enabled.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_mail_tab_enabled.png") - -ws.close() diff --git a/find_settings.py b/find_settings.py deleted file mode 100644 index 22741a9..0000000 --- a/find_settings.py +++ /dev/null @@ -1,27 +0,0 @@ -import json, websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -script = """ -(() => { - const all = Array.from(document.querySelectorAll('*')); - return all.filter(el => el.children.length === 0 && el.innerText && el.innerText.includes('系统设置')).map(el => ({ - tag: el.tagName, - className: el.className, - text: el.innerText - })); -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) -ws.close() diff --git a/fix_test.py b/fix_test.py deleted file mode 100644 index fdd2006..0000000 --- a/fix_test.py +++ /dev/null @@ -1,12 +0,0 @@ -with open("frontend/src/views/Dashboard/DomainForm.test.js", "r", encoding="utf-8") as f: - test_text = f.read() - -test_text = test_text.replace( - ' assert.equal(state.editingId.value, "");\n assert.deepEqual(state.form.value.server_ids, []);\n assert.equal(state.domainBindingsLoading.value, false);', - ' assert.equal(state.editingId.value, "");\n assert.deepEqual(state.form.value.server_ids, [firstServer.id]);\n assert.equal(state.domainBindingsLoading.value, false);' -) - -with open("frontend/src/views/Dashboard/DomainForm.test.js", "w", encoding="utf-8") as f: - f.write(test_text) - -print("Updated DomainForm.test.js line 241") diff --git a/live_screen.png b/live_screen.png deleted file mode 100644 index 0321e0b..0000000 Binary files a/live_screen.png and /dev/null differ diff --git a/login_and_open_add_domain.py b/login_and_open_add_domain.py deleted file mode 100644 index ea94805..0000000 --- a/login_and_open_add_domain.py +++ /dev/null @@ -1,94 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 自动填写登录表单并登录 xuans / 10102442Lb! (备用 12345678a) -login_script = """ -(() => { - const inputs = Array.from(document.querySelectorAll('input')); - const userInput = inputs.find(i => i.placeholder && i.placeholder.includes('用户名') || i.type === 'text'); - const pwdInput = inputs.find(i => i.type === 'password'); - const submitBtn = document.querySelector('button[type="submit"]') || Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('登录')); - - if (userInput && pwdInput && submitBtn) { - userInput.value = 'xuans'; - userInput.dispatchEvent(new Event('input', { bubbles: true })); - pwdInput.value = '10102442Lb!'; - pwdInput.dispatchEvent(new Event('input', { bubbles: true })); - submitBtn.click(); - return 'Submitting login...'; - } - return 'Login elements not found'; -})() -""" - -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": login_script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(2) - -# 查看是否进入控制台并点击“域名配置” -nav_script = """ -(() => { - const items = Array.from(document.querySelectorAll('.navigation-item, button')); - const target = items.find(b => b.innerText.includes('域名配置')); - if (target) { - target.click(); - return 'Navigated to 域名配置'; - } - return 'Not in dashboard yet: ' + document.body.innerText.slice(0, 100); -})() -""" -ws.send(json.dumps({ - "id": 2, - "method": "Runtime.evaluate", - "params": {"expression": nav_script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 点击“添加域名” -add_script = """ -(() => { - const btn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('添加域名')); - if (btn) { - btn.click(); - return 'Clicked 添加域名'; - } - return '添加域名 not found'; -})() -""" -ws.send(json.dumps({ - "id": 3, - "method": "Runtime.evaluate", - "params": {"expression": add_script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 截图保存 -ws.send(json.dumps({ - "id": 4, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_add_domain_default_checked.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_add_domain_default_checked.png") - -ws.close() diff --git a/login_page.png b/login_page.png deleted file mode 100644 index 6d3f93d..0000000 Binary files a/login_page.png and /dev/null differ diff --git a/login_pwd2.py b/login_pwd2.py deleted file mode 100644 index 78f814f..0000000 --- a/login_pwd2.py +++ /dev/null @@ -1,48 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 使用 12345678a 尝试登录 -login_script = """ -(() => { - const inputs = Array.from(document.querySelectorAll('input')); - const userInput = inputs.find(i => i.placeholder && i.placeholder.includes('用户名') || i.type === 'text'); - const pwdInput = inputs.find(i => i.type === 'password'); - const submitBtn = document.querySelector('button[type="submit"]') || Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('登录')); - - if (userInput && pwdInput && submitBtn) { - userInput.value = 'xuans'; - userInput.dispatchEvent(new Event('input', { bubbles: true })); - pwdInput.value = '12345678a'; - pwdInput.dispatchEvent(new Event('input', { bubbles: true })); - submitBtn.click(); - return 'Submitting login with 12345678a...'; - } - return 'Login elements not found'; -})() -""" - -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": login_script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(2) - -ws.send(json.dumps({ - "id": 2, - "method": "Runtime.evaluate", - "params": {"expression": "document.body.innerText.slice(0, 150)", "returnByValue": True} -})) -print(ws.recv()) - -ws.close() diff --git a/mail_settings_ready.png b/mail_settings_ready.png deleted file mode 100644 index 3e72750..0000000 Binary files a/mail_settings_ready.png and /dev/null differ diff --git a/mail_settings_tab.png b/mail_settings_tab.png deleted file mode 100644 index 3e72750..0000000 Binary files a/mail_settings_tab.png and /dev/null differ diff --git a/mail_settings_view.png b/mail_settings_view.png deleted file mode 100644 index dcdc753..0000000 Binary files a/mail_settings_view.png and /dev/null differ diff --git a/mark_done.py b/mark_done.py deleted file mode 100644 index 887c2e8..0000000 --- a/mark_done.py +++ /dev/null @@ -1,21 +0,0 @@ -with open("doc/Scert整改任务执行清单.md", "r", encoding="utf-8") as f: - text = f.read() - -text = text.replace( - "- [ ] 部署静态产物至第一台服务器(8.137.23.95)并在 Chrome MCP 验证实机新建域名弹窗默认勾选效果。\n- [ ] 提交并双重推送 Git 远端仓库。", - "- [✓] 部署静态产物至第一台服务器(8.137.23.95)并在 Chrome MCP 验证实机新建域名弹窗默认勾选效果。\n- [✓] 提交并双重推送 Git 远端仓库。" -) -with open("doc/Scert整改任务执行清单.md", "w", encoding="utf-8") as f: - f.write(text) - -with open("doc/Scert整改合并优化清单.md", "r", encoding="utf-8") as f: - text_m = f.read() - -text_m = text_m.replace( - "- [ ] 部署静态产物至第一台服务器(8.137.23.95)并在 Chrome MCP 验证实机新建域名弹窗默认勾选效果。\n- [ ] 提交并双重推送 Git 远端仓库。", - "- [✓] 部署静态产物至第一台服务器(8.137.23.95)并在 Chrome MCP 验证实机新建域名弹窗默认勾选效果。\n- [✓] 提交并双重推送 Git 远端仓库。" -) -with open("doc/Scert整改合并优化清单.md", "w", encoding="utf-8") as f: - f.write(text_m) - -print("Marked status as completed in execution lists.") diff --git a/mcp_add_domain_default_checked.png b/mcp_add_domain_default_checked.png deleted file mode 100644 index 8a5c61c..0000000 Binary files a/mcp_add_domain_default_checked.png and /dev/null differ diff --git a/mcp_add_domain_modal.png b/mcp_add_domain_modal.png deleted file mode 100644 index 5e7d2d7..0000000 Binary files a/mcp_add_domain_modal.png and /dev/null differ diff --git a/mcp_add_domain_verified.png b/mcp_add_domain_verified.png deleted file mode 100644 index 9469de0..0000000 Binary files a/mcp_add_domain_verified.png and /dev/null differ diff --git a/mcp_domains_view.png b/mcp_domains_view.png deleted file mode 100644 index c0f0e4f..0000000 Binary files a/mcp_domains_view.png and /dev/null differ diff --git a/mcp_mail_tab.png b/mcp_mail_tab.png deleted file mode 100644 index 3e72750..0000000 Binary files a/mcp_mail_tab.png and /dev/null differ diff --git a/mcp_mail_tab_enabled.png b/mcp_mail_tab_enabled.png deleted file mode 100644 index 01154c1..0000000 Binary files a/mcp_mail_tab_enabled.png and /dev/null differ diff --git a/mcp_page_now.png b/mcp_page_now.png deleted file mode 100644 index d4d339a..0000000 Binary files a/mcp_page_now.png and /dev/null differ diff --git a/mcp_projects_members.png b/mcp_projects_members.png deleted file mode 100644 index 40034c2..0000000 Binary files a/mcp_projects_members.png and /dev/null differ diff --git a/mcp_servers_clicked.png b/mcp_servers_clicked.png deleted file mode 100644 index 9d65428..0000000 Binary files a/mcp_servers_clicked.png and /dev/null differ diff --git a/mcp_servers_view.png b/mcp_servers_view.png deleted file mode 100644 index d4d339a..0000000 Binary files a/mcp_servers_view.png and /dev/null differ diff --git a/mcp_settings_view.png b/mcp_settings_view.png deleted file mode 100644 index fe89fb7..0000000 Binary files a/mcp_settings_view.png and /dev/null differ diff --git a/mcp_verified.png b/mcp_verified.png index 3e72750..81e1a12 100644 Binary files a/mcp_verified.png and b/mcp_verified.png differ diff --git a/nav_to_settings.py b/nav_to_settings.py deleted file mode 100644 index e0911a0..0000000 --- a/nav_to_settings.py +++ /dev/null @@ -1,45 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击“系统设置” -script = """ -(() => { - const items = Array.from(document.querySelectorAll('.dashboard-navigation-item')); - const settingsItem = items.find(el => el.innerText.includes('系统设置')); - if (settingsItem) { - settingsItem.click(); - return 'Clicked 系统设置'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 截图保存 -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_settings_view.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_settings_view.png") - -ws.close() diff --git a/scert_preview_1.png b/scert_preview_1.png deleted file mode 100644 index 400e217..0000000 Binary files a/scert_preview_1.png and /dev/null differ diff --git a/scert_preview_active_dashboard.png b/scert_preview_active_dashboard.png deleted file mode 100644 index 0321e0b..0000000 Binary files a/scert_preview_active_dashboard.png and /dev/null differ diff --git a/scert_preview_current.png b/scert_preview_current.png deleted file mode 100644 index 9469de0..0000000 Binary files a/scert_preview_current.png and /dev/null differ diff --git a/scert_preview_current_2.png b/scert_preview_current_2.png deleted file mode 100644 index b0f5184..0000000 Binary files a/scert_preview_current_2.png and /dev/null differ diff --git a/scert_preview_dashboard_logged_in.png b/scert_preview_dashboard_logged_in.png deleted file mode 100644 index 03219f4..0000000 Binary files a/scert_preview_dashboard_logged_in.png and /dev/null differ diff --git a/scert_preview_login.png b/scert_preview_login.png deleted file mode 100644 index 9469de0..0000000 Binary files a/scert_preview_login.png and /dev/null differ diff --git a/scert_preview_odacm.png b/scert_preview_odacm.png deleted file mode 100644 index 9469de0..0000000 Binary files a/scert_preview_odacm.png and /dev/null differ diff --git a/scert_real_current.png b/scert_real_current.png deleted file mode 100644 index 0321e0b..0000000 Binary files a/scert_real_current.png and /dev/null differ diff --git a/settings_view.png b/settings_view.png deleted file mode 100644 index 2e964eb..0000000 Binary files a/settings_view.png and /dev/null differ diff --git a/sidebar_cropped.png b/sidebar_cropped.png deleted file mode 100644 index 6d0aef8..0000000 Binary files a/sidebar_cropped.png and /dev/null differ diff --git a/sidebar_dashboard_view.png b/sidebar_dashboard_view.png deleted file mode 100644 index 9b5eac2..0000000 Binary files a/sidebar_dashboard_view.png and /dev/null differ diff --git a/sidebar_detail.png b/sidebar_detail.png deleted file mode 100644 index 50212b2..0000000 Binary files a/sidebar_detail.png and /dev/null differ diff --git a/snap_servers.py b/snap_servers.py deleted file mode 100644 index 4384d43..0000000 --- a/snap_servers.py +++ /dev/null @@ -1,25 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 1, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_servers_view.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_servers_view.png") - -ws.close() diff --git a/test_cdp.py b/test_cdp.py deleted file mode 100644 index 8c11a27..0000000 --- a/test_cdp.py +++ /dev/null @@ -1,37 +0,0 @@ -import json, base64, time -import websocket -import urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] -print("Connecting to ws_url:", ws_url) - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": "document.title + ' | ' + window.location.href"} -})) - -msg = ws.recv() -print("Eval result:", msg) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) - -msg2 = ws.recv() -data = json.loads(msg2) -if "result" in data and "data" in data["result"]: - with open("mcp_verified.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot captured successfully!") -else: - print("Response:", msg2[:200]) - -ws.close() diff --git a/test_default_server_mcp.py b/test_default_server_mcp.py deleted file mode 100644 index 4ed7ba3..0000000 --- a/test_default_server_mcp.py +++ /dev/null @@ -1,59 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 清除缓存并刷新页面 -ws.send(json.dumps({ - "id": 1, - "method": "Network.clearBrowserCache" -})) -print(ws.recv()) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.reload", - "params": {"ignoreCache": True} -})) -print(ws.recv()) - -time.sleep(2) - -# 点击“添加域名” -script = """ -(() => { - const btn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('添加域名')); - if (btn) { - btn.click(); - return 'Clicked 添加域名'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 3, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -ws.send(json.dumps({ - "id": 4, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_add_domain_default_checked.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_add_domain_default_checked.png") - -ws.close() diff --git a/test_mcp_conn.py b/test_mcp_conn.py deleted file mode 100644 index 67df475..0000000 --- a/test_mcp_conn.py +++ /dev/null @@ -1,36 +0,0 @@ -import json, base64 -import websocket -import urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] -print("Connecting to ws_url:", ws_url) - -ws = websocket.create_connection(ws_url) - -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": "document.title + ' | ' + window.location.href"} -})) -res = ws.recv() -print("Page status:", res) - -ws.send(json.dumps({ - "id": 2, - "method": "Page.captureScreenshot" -})) - -while True: - msg = ws.recv() - data = json.loads(msg) - if data.get("id") == 2: - img_data = base64.b64decode(data["result"]["data"]) - with open("mcp_check_screenshot.png", "wb") as f: - f.write(img_data) - print("Screenshot saved to mcp_check_screenshot.png") - break - -ws.close() diff --git a/test_nav.py b/test_nav.py deleted file mode 100644 index 825ba27..0000000 --- a/test_nav.py +++ /dev/null @@ -1,26 +0,0 @@ -import json, websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击侧边栏的“系统设置”或切换视图查看 -script = """ -(() => { - const navItems = Array.from(document.querySelectorAll('.dashboard-navigation-item, .nav-item, button')); - return navItems.map(item => item.innerText.trim()).filter(Boolean); -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script, "returnByValue": True} -})) - -res = ws.recv() -print("Nav elements:", res) -ws.close() diff --git a/test_open_add_domain.py b/test_open_add_domain.py deleted file mode 100644 index 02edddb..0000000 --- a/test_open_add_domain.py +++ /dev/null @@ -1,65 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击侧边栏“域名配置” -nav_script = """ -(() => { - const items = Array.from(document.querySelectorAll('.navigation-item')); - const target = items.find(b => b.innerText.includes('域名配置')); - if (target) { - target.click(); - return 'Navigated to 域名配置'; - } - return '域名配置 not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": nav_script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 点击“添加域名” -add_script = """ -(() => { - const btn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('添加域名')); - if (btn) { - btn.click(); - return 'Clicked 添加域名'; - } - return '添加域名 not found'; -})() -""" -ws.send(json.dumps({ - "id": 2, - "method": "Runtime.evaluate", - "params": {"expression": add_script, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 截图保存 -ws.send(json.dumps({ - "id": 3, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_add_domain_default_checked.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_add_domain_default_checked.png") - -ws.close() diff --git a/update_doc.py b/update_doc.py deleted file mode 100644 index 289b0ff..0000000 --- a/update_doc.py +++ /dev/null @@ -1,32 +0,0 @@ -import sys - -with open("doc/Scert整改任务执行清单.md", "r", encoding="utf-8") as f: - text = f.read() - -target = """## 2026年10月18日 侧边栏底部SSL证书管理字样清理与侧边栏左右5px自适应布局 - -- [x] 清理 DashboardNavigation.vue 底部“SSL 证书管理”角标及冗余 CSS -- [x] 优化侧边栏及账号卡片等宽自适应布局,侧边栏以卡片宽度左右各留 5px 内边距(padding: 2px 5px) -- [x] 统一第一行版本号格式为 Vx.x.x(如 V1.52.1) -- [x] 运行前端单元测试 356 项全量验证通过 -- [x] 编译并成功部署前端产物至第一台服务器(8.137.23.95) -- [x] 双重推送远程仓库并持续汇报进度""" - -addition = """## 2026年10月18日 新建托管域名默认勾选第一台生产测试服务器 - -- [x] 修改 DomainForm.js 中 openCreate 逻辑,新建域名时如果已有配置服务器,默认将第一台服务器关联勾选(server_ids = [servers[0].id])。 -- [x] 同步更新 DomainForm.test.js 对应场景断言,确保单元测试与新建默认勾选逻辑严密契合。 -- [x] 前端自动化单元测试 356 项全量通过(356 pass)。 -- [x] 完成前端生产环境打包构建(vite build)生成新静态资源产物。 -- [ ] 部署静态产物至第一台服务器(8.137.23.95)并在 Chrome MCP 验证实机新建域名弹窗默认勾选效果。 -- [ ] 提交并双重推送 Git 远端仓库。 - -""" + target - -if target in text: - text = text.replace(target, addition, 1) - with open("doc/Scert整改任务执行清单.md", "w", encoding="utf-8") as f: - f.write(text) - print("Updated Scert整改任务执行清单.md") -else: - print("Target not found in Scert整改任务执行清单.md") diff --git a/update_doc_merge.py b/update_doc_merge.py deleted file mode 100644 index cefe66f..0000000 --- a/update_doc_merge.py +++ /dev/null @@ -1,25 +0,0 @@ -import sys - -with open("doc/Scert整改合并优化清单.md", "r", encoding="utf-8") as f: - text = f.read() - -target = """## 2026年10月17日 邮件模板美化与Linux生产主服务热部署""" - -addition = """## 2026年10月18日 新建托管域名默认勾选第一台生产测试服务器 - -- [x] 修改 DomainForm.js 中 openCreate 逻辑,新建域名时如果已有配置服务器,默认将第一台服务器关联勾选(server_ids = [servers[0].id])。 -- [x] 同步更新 DomainForm.test.js 对应场景断言,确保单元测试与新建默认勾选逻辑严密契合。 -- [x] 前端自动化单元测试 356 项全量通过(356 pass)。 -- [x] 完成前端生产环境打包构建(vite build)生成新静态资源产物。 -- [ ] 部署静态产物至第一台服务器(8.137.23.95)并在 Chrome MCP 验证实机新建域名弹窗默认勾选效果。 -- [ ] 提交并双重推送 Git 远端仓库。 - -""" + target - -if target in text: - text = text.replace(target, addition, 1) - with open("doc/Scert整改合并优化清单.md", "w", encoding="utf-8") as f: - f.write(text) - print("Updated Scert整改合并优化清单.md") -else: - print("Target not found in Scert整改合并优化清单.md") diff --git a/update_domain_form.py b/update_domain_form.py deleted file mode 100644 index 2b9472e..0000000 --- a/update_domain_form.py +++ /dev/null @@ -1,29 +0,0 @@ -import sys - -with open("frontend/src/views/Dashboard/DomainForm.js", "r", encoding="utf-8") as f: - text = f.read() - -old_open_create = """ function openCreate() { - if (saving.value) return; - version += 1; - editingId.value = ""; - targetID = ""; - form.value = emptyForm();""" - -new_open_create = """ function openCreate() { - if (saving.value) return; - version += 1; - editingId.value = ""; - targetID = ""; - form.value = emptyForm(); - if (servers.value && servers.value.length > 0) { - form.value.server_ids = [servers.value[0].id]; - }""" - -if old_open_create in text: - text = text.replace(old_open_create, new_open_create, 1) - with open("frontend/src/views/Dashboard/DomainForm.js", "w", encoding="utf-8") as f: - f.write(text) - print("DomainForm.js updated successfully!") -else: - print("old_open_create not matched!") diff --git a/verify_domain_default.py b/verify_domain_default.py deleted file mode 100644 index dba62af..0000000 --- a/verify_domain_default.py +++ /dev/null @@ -1,65 +0,0 @@ -import json, base64, time -import websocket, urllib.request - -resp = urllib.request.urlopen("http://127.0.0.1:9222/json/list") -pages = json.loads(resp.read().decode("utf-8")) -page = next(p for p in pages if p.get("type") == "page" and "odacm.cn" in p.get("url")) -ws_url = page["webSocketDebuggerUrl"] - -ws = websocket.WebSocket() -ws.connect(ws_url, timeout=5) - -# 点击侧边栏“域名配置” -script_click_tab = """ -(() => { - const buttons = Array.from(document.querySelectorAll('.navigation-item')); - const target = buttons.find(b => b.innerText.includes('域名配置')); - if (target) { - target.click(); - return 'Clicked 域名配置'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 1, - "method": "Runtime.evaluate", - "params": {"expression": script_click_tab, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 点击“添加域名” -script_click_add = """ -(() => { - const btn = Array.from(document.querySelectorAll('button')).find(b => b.innerText.includes('添加域名')); - if (btn) { - btn.click(); - return 'Clicked 添加域名'; - } - return 'Not found'; -})() -""" -ws.send(json.dumps({ - "id": 2, - "method": "Runtime.evaluate", - "params": {"expression": script_click_add, "returnByValue": True} -})) -print(ws.recv()) - -time.sleep(1) - -# 截图保存 -ws.send(json.dumps({ - "id": 3, - "method": "Page.captureScreenshot" -})) -msg = ws.recv() -data = json.loads(msg) -if "result" in data and "data" in data["result"]: - with open("mcp_add_domain_verified.png", "wb") as f: - f.write(base64.b64decode(data["result"]["data"])) - print("Screenshot saved to mcp_add_domain_verified.png") - -ws.close()