diff --git a/daily_report/static/report-hero.png b/daily_report/static/report-hero.png new file mode 100644 index 0000000..0560770 Binary files /dev/null and b/daily_report/static/report-hero.png differ diff --git a/daily_report/static/styles.css b/daily_report/static/styles.css index f94f648..8776021 100644 --- a/daily_report/static/styles.css +++ b/daily_report/static/styles.css @@ -2,11 +2,14 @@ body { margin: 0; font-family: Arial, "Microsoft YaHei", sans-serif; - background: #f6f7f9; + background: + radial-gradient(circle at 18% 10%, rgba(255, 204, 116, 0.32), transparent 28%), + radial-gradient(circle at 86% 4%, rgba(91, 190, 226, 0.22), transparent 26%), + linear-gradient(180deg, #fff8ed 0%, #f6f7fb 42%, #f6f7f9 100%); color: #1f2937; } -.shell { width: min(1120px, calc(100% - 32px)); margin: 32px auto; } -.narrow { width: min(720px, calc(100% - 32px)); } +.shell { width: min(1120px, calc(100% - 32px)); margin: 28px auto; } +.narrow { width: min(780px, calc(100% - 32px)); } .topbar { display: flex; justify-content: space-between; gap: 16px; align-items: center; } h1 { margin: 0 0 8px; font-size: 28px; } h2 { font-size: 18px; } @@ -17,6 +20,50 @@ p { color: #5b6472; } border-radius: 8px; padding: 16px; } +.submit-hero { + min-height: 178px; + display: grid; + grid-template-columns: minmax(0, 1fr) 230px; + gap: 20px; + align-items: center; + margin-bottom: 18px; + padding: 24px 28px; + border: 1px solid #f3d49a; + border-radius: 18px; + background: + linear-gradient(135deg, rgba(255, 248, 225, 0.96), rgba(230, 246, 255, 0.96)), + #fff; + box-shadow: 0 18px 45px rgba(39, 45, 58, 0.08); + overflow: hidden; +} +.submit-hero-copy { min-width: 0; } +.hero-kicker { + display: inline-flex; + margin: 0 0 8px; + padding: 4px 10px; + border-radius: 999px; + background: #fff7d6; + color: #9a5b00; + font-size: 13px; + font-weight: 700; +} +.submit-hero h1 { + margin: 0 0 8px; + font-size: 32px; +} +.submit-hero p { + max-width: 420px; + margin: 0; +} +.submit-hero-image { + width: 230px; + max-width: 100%; + justify-self: end; + filter: drop-shadow(0 12px 16px rgba(31, 41, 55, 0.14)); +} +form.panel, .history-panel, .previous-plan { + box-shadow: 0 14px 34px rgba(39, 45, 58, 0.06); +} form { display: grid; gap: 14px; } label { display: grid; gap: 6px; font-weight: 600; } input, textarea, button { @@ -90,11 +137,18 @@ button { justify-content: center; } .add-item { + width: auto; + min-width: 92px; + padding: 0 12px; border: 1px solid #2563eb; background: #fff; color: #2563eb; - font-size: 22px; - line-height: 1; + font-size: 14px; + font-weight: 700; +} +.add-item::after { + content: " 添加一条"; + font-size: 13px; } .remove-item { border: 1px solid #e5e7eb; @@ -173,4 +227,12 @@ pre { @media (max-width: 760px) { .topbar, .stats, .history-head, .report-head { display: grid; } .filters, .report-grid { grid-template-columns: 1fr; } + .submit-hero { + grid-template-columns: 1fr; + padding: 20px; + } + .submit-hero-image { + width: 180px; + justify-self: center; + } } diff --git a/daily_report/web.py b/daily_report/web.py index 8b592fa..1d66748 100644 --- a/daily_report/web.py +++ b/daily_report/web.py @@ -60,7 +60,14 @@ def submit_page(current_date: str, session: dict[str, str] | None = None) -> byt "每日报告", f"""
-

每日工作汇报

+
+
+

今日收尾小站

+

每日工作汇报

+

把今天的进展、明天的计划和需要协助的地方简单记下来。

+
+ +
{identity_html} @@ -506,7 +513,14 @@ class DailyReportHandler(BaseHTTPRequestHandler): if not file_path.exists(): self._json(404, {"error": "not found"}) return - content_type = "application/javascript; charset=utf-8" if file_path.suffix == ".js" else "text/css; charset=utf-8" + content_types = { + ".css": "text/css; charset=utf-8", + ".js": "application/javascript; charset=utf-8", + ".png": "image/png", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + } + content_type = content_types.get(file_path.suffix.lower(), "application/octet-stream") self._send(200, file_path.read_bytes(), content_type) diff --git a/tests/test_web.py b/tests/test_web.py index f2e72b2..d86783f 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -66,6 +66,7 @@ class WebTest(unittest.TestCase): status, submit = get(f"{base_url}/submit") self.assertEqual(status, 200) self.assertIn("每日工作汇报", submit) + self.assertIn("/static/report-hero.png", submit) self.assertIn("今日状态", submit) self.assertIn('data-list="today_done"', submit) self.assertIn('data-add-list="today_done"', submit) @@ -85,6 +86,10 @@ class WebTest(unittest.TestCase): status, manager = get_with_cookie(f"{base_url}/manager", admin_cookie()) self.assertEqual(status, 200) self.assertIn("日报浏览", manager) + + with urllib.request.urlopen(f"{base_url}/static/report-hero.png", timeout=5) as response: + self.assertEqual(response.status, 200) + self.assertEqual(response.headers["content-type"], "image/png") finally: server.shutdown() server.server_close()