feat: 内容数据迁移至数据库,合规审查全链路打通

- 文章 HTML 存储从文件系统迁移至 articles 表,删除 releases 目录
- 合规审查从 DB 读取 HTML,审查结果写回 DB,通过后自动推进至待发布
- 新增 todayCount 筛选按钮,与系统概览统计数据一致
- 全屏预览修复:提升 z-index 超过侧边栏,添加退出全屏/关闭按钮
- 统一 '优化' → '审查' 命名,消除前后端术语不一致
- 调度器创作完成后自动触发审查(生成 → 审查 → 待发布)
- 清理旧备份/调试文件、过期大纲和研究笔记
This commit is contained in:
Yuzhiran Dev
2026-05-13 17:33:56 +08:00
parent bc6a302e59
commit 233e23016c
234 changed files with 5670 additions and 10651 deletions
+101
View File
@@ -0,0 +1,101 @@
"""
侧边栏/底部导航 点击跳转专项测试
统一使用 native click 避免 Playwright strict hit-test 误判
"""
import asyncio
import sys
from playwright.async_api import async_playwright
BASE_URL = "http://localhost:8001"
CREDENTIALS = {"username": "admin", "password": "admin123"}
NAV_ITEMS = [
("系统概览", "/", ""),
("选题管理", "topics.html", ""),
("数据分析", "metrics.html", "more"),
("内容日历", "calendar.html", ""),
("素材库", "assets.html", "more"),
("创作任务", "tasks.html", ""),
("平台配置", "platforms.html", "more"),
("系统日志", "logs.html", "more"),
("系统管理", "admin.html", "more"),
]
def native_click(page, selector):
return page.evaluate(f"""() => {{
const el = document.querySelector('{selector}');
if (!el) return false;
el.click();
return true;
}}""")
async def run_nav_test(viewport, label, is_mobile):
print(f"\n--- {label} ---")
ok, fail = 0, 0
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True, channel="chrome", args=["--no-sandbox"])
page = await browser.new_page(viewport=viewport)
await page.goto(f"{BASE_URL}/login.html", wait_until="networkidle")
await page.wait_for_timeout(500)
await page.locator("input.form-input").nth(0).fill(CREDENTIALS["username"])
await page.locator("input.form-input").nth(1).fill(CREDENTIALS["password"])
await page.click("button.login-btn")
await page.wait_for_timeout(3000)
for name, target, more_group in NAV_ITEMS:
try:
if is_mobile:
sel = f'.mobile-nav-btn[data-page="{target}"]'
clicked = await native_click(page, sel)
if not clicked:
# 打开更多面板后再点
more_sel = "#mobile-more-btn"
await native_click(page, more_sel)
await page.wait_for_timeout(400)
sel = f'.sheet-item[data-page="{target}"]'
clicked = await native_click(page, sel)
if not clicked:
print(f"{name}: 按钮未找到")
continue
else:
sel = f'.sidebar-btn[data-page="{target}"]'
ok2 = await native_click(page, sel)
if not ok2:
print(f"{name}: 按钮未找到")
continue
await page.wait_for_timeout(1500)
matched = target in page.url if target != "/" else page.url.endswith("/") or "index" in page.url
if matched:
print(f"{name} -> {page.url}")
ok += 1
else:
print(f"{name} -> {page.url}")
fail += 1
except Exception as e:
print(f"{name}: {e}")
fail += 1
await browser.close()
return ok, fail
async def main():
pc_ok, pc_fail = await run_nav_test({"width": 1280, "height": 720}, "PC 侧边栏", False)
h5_ok, h5_fail = await run_nav_test({"width": 375, "height": 667}, "H5 底部导航", True)
total_ok = pc_ok + h5_ok
total_fail = pc_fail + h5_fail
print(f"\n{'='*50}")
print(f" 导航测试: PC ✅{pc_ok}{pc_fail} | H5 ✅{h5_ok}{h5_fail} | 总计 ✅{total_ok}{total_fail}")
print(f"{'='*50}")
if total_fail:
sys.exit(1)
if __name__ == "__main__":
asyncio.run(main())