feat: 新增日程面板、复盘页面与 Agent 读写接口

- 日程:单次/每日/每周/每月重复,JSON 存储,月历按优先级着色圆点 + 悬停提示
- 复盘页:可自定义折线图卡片(SVG) + 每日心得总览(按日期/任务展开)
- Agent 接口:GET /api/agent/overview 读日程+进度,POST /api/agent/schedules 建日程(PPM_API_TOKEN Bearer 鉴权)
- 导出/导入/统计纳入日程与图表;47 项测试全绿
This commit is contained in:
MobKBK
2026-09-04 14:46:41 +08:00
parent 5f50eb54ed
commit 8340d1dbbd
13 changed files with 1027 additions and 19 deletions

View File

@@ -194,12 +194,70 @@ label { display: grid; gap: 6px; font-size: 12px; font-weight: 600; color: #4551
.login-overlay { position: fixed; inset: 0; z-index: 100; background: #eef2ee; display: grid; place-items: center; padding: 20px; }
.login-overlay[hidden] { display: none; }.login-panel { width: min(380px, 100%); background: white; border: 1px solid var(--line); padding: 38px; border-radius: 8px; }.login-panel h1 { margin: 6px 0 28px; font-size: 25px; }.wide-button { width: 100%; margin-top: 16px; }.form-error { color: var(--red); min-height: 18px; font-size: 12px; }
.toast { position: fixed; right: 22px; bottom: 22px; z-index: 200; max-width: min(360px, calc(100vw - 44px)); background: var(--ink); color: white; border-radius: 6px; padding: 11px 15px; transform: translateY(100px); opacity: 0; transition: .2s ease; }.toast.show { transform: translateY(0); opacity: 1; }
@media (max-width: 820px) {
.review-heading { margin-bottom: 20px; }
.review-chart-grid { display: grid; gap: 14px; }
.review-chart-card { border: 1px solid var(--line); background: var(--surface); border-radius: 6px; padding: 16px; }
.review-chart-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 10px; }
.review-chart-head h3 { margin: 0; font-size: 15px; }
.review-chart-head > span { display: flex; gap: 5px; }
.review-chart-head .icon-button { width: 30px; min-height: 30px; font-size: 16px; }
.chart-svg { display: block; width: 100%; height: auto; min-height: 180px; overflow: visible; }
.chart-svg polyline { fill: none; stroke: var(--green); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-svg circle { fill: var(--surface); stroke: var(--green); stroke-width: 1.5; }
.chart-area { fill: rgba(23,107,75,.10); }
.chart-guide { stroke: #e6ebe7; stroke-width: 1; }
.chart-svg text { fill: var(--muted); font-size: 11px; }
.chart-empty { min-height: 180px; display: grid; place-items: center; color: var(--muted); font-size: 13px; }
.review-day { border: 1px solid var(--line); border-radius: 6px; background: var(--surface); margin-bottom: 9px; overflow: hidden; }
.review-day summary { display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; list-style: none; }
.review-day summary::-webkit-details-marker { display: none; }
.review-date-badge { display: grid; place-items: center; min-width: 48px; min-height: 30px; border-radius: 4px; background: var(--green-soft); color: var(--green); font-size: 12px; font-weight: 700; }
.review-day-records { border-top: 1px solid var(--line); padding: 2px 14px 8px 72px; }
.review-note-record { padding: 10px 0; border-bottom: 1px solid #eef2ee; }
.review-note-record:last-child { border-bottom: 0; }
.review-note-record strong { display: block; font-size: 13px; }.review-note-record time { display: block; color: var(--muted); font-size: 11px; margin-top: 3px; }.review-note-record p { margin: 7px 0 0; white-space: pre-wrap; font-size: 13px; line-height: 1.6; }
.chart-dialog { width: min(560px, calc(100vw - 28px)); }
.schedule-actions { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.schedule-actions strong { min-width: 76px; text-align: center; font-size: 14px; }
.schedule-weekdays, .schedule-calendar { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 5px; }
.schedule-weekdays { color: var(--muted); font-size: 11px; text-align: center; margin-bottom: 5px; }
.schedule-date { font-size: 13px; font-weight: 600; }
.schedule-day { min-height: 52px; position: relative; border: 1px solid var(--line); border-radius: 5px; background: var(--surface); color: var(--ink); display: flex; align-items: flex-start; justify-content: flex-start; padding: 7px; transition: .15s ease; }
.schedule-day:hover, .schedule-day.selected { border-color: var(--green); background: var(--green-soft); }
.schedule-day:hover, .schedule-day:focus-visible { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(23,33,26,.08); z-index: 4; }
.schedule-day.today { border-color: var(--green); box-shadow: 0 0 0 1px var(--green); }
.schedule-day.today .schedule-date { font-weight: 800; color: var(--green); }
.schedule-dots { position: absolute; right: 7px; bottom: 7px; display: flex; align-items: flex-end; justify-content: flex-end; gap: 4px; min-height: 9px; max-width: calc(100% - 14px); }
.schedule-dots .dot, .schedule-legend .dot { width: 7px; height: 7px; flex: 0 0 7px; display: block; border-radius: 50%; box-shadow: 0 0 0 1.5px #fff; }
.schedule-dots .dot.priority-1, .schedule-legend .dot.priority-1 { background: #e5484d; }
.schedule-dots .dot.priority-2, .schedule-legend .dot.priority-2 { background: #f76b15; }
.schedule-dots .dot.priority-3, .schedule-legend .dot.priority-3 { background: var(--green); }
.schedule-dots .dot.priority-4, .schedule-legend .dot.priority-4 { background: #8a93a6; }
.schedule-dots .dot.priority-5, .schedule-legend .dot.priority-5 { background: #c6ccd6; }
.schedule-dots-more { color: var(--muted); font-size: 10px; line-height: 9px; white-space: nowrap; }
.schedule-day[data-tooltip]::after { content: attr(data-tooltip); position: absolute; right: 0; bottom: calc(100% + 8px); z-index: 20; display: none; width: max-content; max-width: min(260px, calc(100vw - 28px)); padding: 8px 10px; border-radius: 5px; background: var(--ink); color: #fff; box-shadow: 0 5px 16px rgba(23,33,26,.2); font-size: 11px; font-weight: 400; line-height: 1.5; text-align: left; white-space: pre-line; pointer-events: none; }
.schedule-day[data-tooltip]:hover::after, .schedule-day[data-tooltip]:focus-visible::after { display: block; }
.schedule-legend { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 13px; margin-top: 12px; color: var(--muted); font-size: 11px; }
.schedule-legend-label { margin-right: 2px; font-weight: 600; }
.schedule-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.schedule-list { display: grid; gap: 7px; margin-top: 15px; }
.schedule-item { display: grid; grid-template-columns: 4px 1fr auto auto; gap: 10px; align-items: center; border-top: 1px solid var(--line); padding: 11px 0; }
.schedule-item .priority-bar { height: 36px; }
.schedule-copy { min-width: 0; }
.schedule-copy strong, .schedule-copy small { display: block; }
.schedule-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.schedule-copy small { margin-top: 4px; color: var(--muted); font-size: 11px; }
.schedule-item.completed .schedule-copy strong { text-decoration: line-through; color: var(--muted); }
.schedule-item .icon-button { width: 32px; min-height: 32px; font-size: 16px; }
.schedule-dialog { width: min(620px, calc(100vw - 28px)); }
.schedule-day.blank { border-color: transparent; background: transparent; pointer-events: none; }
@media (max-width: 820px) {
.topbar { padding: 0 12px; }.button.primary { padding-inline: 10px; }
.workspace { display: block; }.sidebar { border-right: 0; border-bottom: 1px solid var(--line); max-height: 41vh; }.main-content { padding: 22px 16px 50px; }
.summary-strip { grid-template-columns: repeat(3, 1fr); }.summary-cell { padding: 15px 10px; }.summary-cell strong { font-size: 20px; }
.overview-row { grid-template-columns: 1fr auto; }.overview-row .progress-track { grid-column: 1 / -1; grid-row: 2; }
.metric-row { grid-template-columns: repeat(2, 1fr); }.remove-metric { grid-column: 2; justify-self: end; }
.review-day-records { padding-left: 14px; }
}
@media (max-width: 520px) {
.brand-button small { display: none; }.top-actions .primary { font-size: 0; width: 42px; }.top-actions .primary::first-letter { font-size: 18px; }