Files
iboard/docs/V0.2/任务模块/任务模块界面设计.html
T
jif2.zhang 0cdbfb434f
Docker Build and Push / build-image (push) Successful in 4m8s
feat(V0.2): 任务模块界面调整 —— 首屏/项目管理/底部安全距离
按 2026-10-24 评审的 5 条调整实现 (需求 T-VW-08~10 / T-PJ-11/12 / T-UI-11):

首屏 (T-VW-08/09):
- /task 改为「上=最近项目条(3 个+更多入口), 下=当前项目任务管理」
- 完整项目列表迁至 /task/list, 从「更多项目」进入; /task/:pid 保留供深链

最近项目排序 (T-VW-10):
- 卡片长按 300ms 拖动换位, 结果存设备端 prefs.recentOrder
- 顺序 = 手动排序 > 最近访问(recentIds) > 列表序, 归档项目不展示

项目管理 (T-PJ-11/12):
- 新增 ProjectManage: 成员 / 看板列 / 项目信息 三分区统一入口
- 项目信息含 改名 / 归档切换 / 删除(个人项目隐藏) / 退出(仅创建人)
- 项目页头部只留「项目管理 + 新增」, 移除散置的成员/列设置按钮

底部安全距离 (T-UI-11):
- 任务详情 / 人员选择 / 拷贝弹层 padding-bottom = 安全区 + 20px
- 小屏下弹层 maxHeight + 内部滚动, 底部按钮完整可见

已验证: 97 文件语法 0 错误、相对导入 0 缺失
2026-10-24 20:32:44 +08:00

1433 lines
87 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>iBoard V0.2 界面设计 · 任务模块</title>
<style>
:root{
--bg:#f0f2f5; --page:#ffffff; --card:#ffffff;
--text:#333333; --muted:#666666; --weak:#999999; --line:#eeeeee;
--primary:#1677ff; --success:#00b578; --warn:#ffc53d; --over:#a855f7;
--danger:#ff3141; --orange:#ff8f1f; --teal:#14b8a6; --pink:#f43f9e;
--nav-h:45px; --tab-h:72px;
}
*{box-sizing:border-box;margin:0;padding:0}
body{
background:var(--bg); color:#1f2328; font-size:14px; line-height:1.6;
font-family:-apple-system,BlinkMacSystemFont,'Segoe UI','PingFang SC','Hiragino Sans GB','Microsoft YaHei',Roboto,sans-serif;
-webkit-font-smoothing:antialiased;
}
.wrap{max-width:1400px;margin:0 auto;padding:36px 24px 72px}
.doc-head{border-bottom:1px solid #e3e6ea;padding-bottom:20px;margin-bottom:28px}
.doc-head h1{font-size:26px;font-weight:700;letter-spacing:.5px}
.doc-head p{color:var(--muted);font-size:13px;margin-top:6px}
.meta{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}
.meta span{font-size:12px;background:#fff;border:1px solid #e3e6ea;border-radius:999px;padding:3px 12px;color:var(--muted)}
h2{font-size:19px;font-weight:700;margin:40px 0 6px;display:flex;align-items:center;gap:10px}
h2::before{content:"";width:4px;height:17px;background:var(--primary);border-radius:2px}
h2 .sub{font-size:12px;font-weight:400;color:var(--weak)}
h3{font-size:15px;font-weight:700;margin:22px 0 10px;color:#24292f}
p.desc{color:var(--muted);font-size:13px;margin-bottom:16px}
table{width:100%;border-collapse:collapse;background:#fff;border:1px solid #e6e8eb;border-radius:10px;overflow:hidden;font-size:12.5px}
th{background:#f7f8fa;text-align:left;font-weight:600;color:var(--muted);padding:9px 12px;border-bottom:1px solid #e6e8eb}
td{padding:9px 12px;border-bottom:1px solid var(--line);vertical-align:top}
tr:last-child td{border-bottom:none}
code{background:#f4f5f7;border-radius:4px;padding:1px 5px;font-size:11.5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;color:#c7254e}
.note{background:#fff;border-left:3px solid var(--primary);border-radius:0 8px 8px 0;padding:11px 14px;font-size:12.5px;color:var(--muted)}
/* ---------- 设计规范 ---------- */
.tokens{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:18px}
.panel{background:#fff;border:1px solid #e6e8eb;border-radius:12px;padding:16px 18px}
.panel h4{font-size:13px;color:var(--muted);font-weight:600;margin-bottom:12px;letter-spacing:.4px}
.swatches{display:flex;flex-wrap:wrap;gap:10px}
.sw{width:88px;text-align:center}
.sw i{display:block;height:44px;border-radius:8px;border:1px solid rgba(0,0,0,.06)}
.sw b{display:block;font-size:11px;font-weight:600;margin-top:5px}
.sw em{display:block;font-size:10px;font-style:normal;color:var(--weak)}
.kv{display:grid;grid-template-columns:96px 1fr;gap:6px 12px;font-size:12px}
.kv span{color:var(--weak)}
.kv b{font-weight:600}
.type-row{display:flex;align-items:baseline;gap:12px;padding:6px 0;border-bottom:1px dashed var(--line);font-size:12px}
.type-row:last-child{border-bottom:none}
.type-row em{font-style:normal;color:var(--weak);width:132px;flex-shrink:0}
/* ---------- 手机 ---------- */
.stage{display:grid;grid-template-columns:repeat(auto-fit,minmax(420px,1fr));gap:30px 26px;justify-items:center}
.shot{width:420px}
.phone{
width:420px;height:820px;background:var(--page);position:relative;overflow:hidden;
border:1px solid #d8dde3;border-radius:22px;box-shadow:0 10px 24px rgba(15,23,42,.08);
display:flex;flex-direction:column;
}
.phone::after{content:"";position:absolute;top:8px;left:50%;transform:translateX(-50%);width:118px;height:20px;background:#111827;border-radius:12px;opacity:.9}
.navbar{height:var(--nav-h);margin-top:28px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
font-size:17px;font-weight:600;border-bottom:1px solid var(--line);background:#fff}
.navbar-sm{height:23px;margin-top:28px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
font-size:12px;font-weight:600;letter-spacing:1px;color:var(--primary);background:var(--bg)}
.navbar-sub{height:44px;flex-shrink:0;display:flex;align-items:center;gap:10px;padding:0 14px;background:#fff;border-bottom:1px solid var(--line)}
.navbar-sub .back{font-size:18px;color:var(--muted);line-height:1}
.navbar-sub .title{font-size:16px;font-weight:700}
.navbar-sub .right{margin-left:auto;display:flex;gap:8px}
.body{flex:1;min-height:0;overflow:hidden;background:var(--bg);padding:0 0 8px}
.body.scroll{overflow-y:auto}
.tabbar{height:var(--tab-h);flex-shrink:0;background:#fff;border-top:1px solid var(--line);
display:flex;align-items:flex-start;padding-top:7px}
.tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;color:var(--weak);font-size:11px}
.tab.on{color:var(--primary)}
.tab svg{width:23px;height:23px}
.caption{margin-top:10px;background:#fff;border:1px solid #e6e8eb;border-radius:10px;padding:10px 14px}
.caption b{font-size:13px}
.caption p{font-size:12px;color:var(--muted);margin-top:3px}
.tag{display:inline-block;font-size:11px;color:var(--primary);background:#f0f5ff;border-radius:4px;padding:1px 6px;margin-left:6px}
.tag.grey{color:var(--muted);background:#f2f3f5}
/* ---------- 通用组件 ---------- */
.mini-btn{font-size:11px;border:1px solid var(--primary);color:var(--primary);border-radius:999px;padding:3px 10px;background:#fff;white-space:nowrap}
.mini-btn.solid{background:var(--primary);color:#fff;border-color:var(--primary)}
.mini-btn.grey{border-color:#dcdcdc;color:var(--muted)}
.seg{display:flex;background:#f2f3f5;border-radius:8px;padding:3px}
.seg div{flex:1;text-align:center;font-size:13px;padding:5px 0;border-radius:6px;color:var(--muted)}
.seg div.on{background:#fff;color:var(--text);font-weight:600;box-shadow:0 1px 2px rgba(0,0,0,.06)}
.link{font-size:12px;color:var(--primary)}
.link.danger{color:var(--danger)}
/* 状态点:未开始 / 执行中 / 完成 */
.sdot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.sdot.todo{background:#c9ced6}
.sdot.doing{background:var(--primary)}
.sdot.done{background:var(--success)}
.sdot.pill{width:auto;height:auto;border-radius:999px;font-size:10px;padding:1px 6px;color:#fff;line-height:14px}
.sdot.pill.todo{background:#a8b0ba} .sdot.pill.doing{background:var(--primary)} .sdot.pill.done{background:var(--success)}
/* ---------- 首屏 · 最近项目条 (T-VW-08/10) ---------- */
.rp-bar { display: flex; gap: 8px; padding: 10px 12px 6px; overflow-x: auto; flex-shrink: 0; }
.rp-card {
flex: 0 0 96px; background: #fff; border-radius: 10px; padding: 9px 10px;
box-shadow: 0 1px 2px rgba(0,0,0,.04); cursor: pointer; position: relative;
border: 1.5px solid transparent;
}
.rp-card.on { border-color: var(--primary); background: #f5f9ff; }
.rp-card .rp-ico {
width: 26px; height: 26px; border-radius: 7px; color: #fff; font-size: 11px;
font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.rp-card .rp-name { font-size: 12px; font-weight: 600; margin-top: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-card .rp-meta { font-size: 9.5px; color: var(--weak); margin-top: 1px; }
.rp-card .rp-grip { position: absolute; top: 5px; right: 6px; color: #d3d8de; font-size: 10px; letter-spacing: -1px; }
.rp-more {
flex: 0 0 auto; align-self: stretch; display: flex; flex-direction: column; align-items: center;
justify-content: center; gap: 3px; color: var(--muted); font-size: 10.5px; cursor: pointer; padding: 0 6px;
}
.rp-more .rp-more-ico { width: 30px; height: 30px; border-radius: 50%; background: #f2f3f5; color: #9aa1aa; display: flex; align-items: center; justify-content: center; font-size: 14px; }
.rp-drag-tip { font-size: 9.5px; color: var(--weak); padding: 0 14px 2px; }
/* ---------- 项目列表 ---------- */
.proj-head{padding:12px 14px 8px;display:flex;align-items:center}
.proj-head b{font-size:18px;font-weight:700}
.proj-head .right{margin-left:auto;display:flex;gap:6px}
.proj-group{font-size:11px;color:var(--weak);letter-spacing:.5px;padding:10px 16px 6px}
.proj-item{display:flex;align-items:center;gap:12px;background:#fff;border-radius:10px;padding:13px 14px;margin:0 12px 8px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.proj-item .pico{width:34px;height:34px;border-radius:9px;display:flex;align-items:center;justify-content:center;color:#fff;font-size:14px;font-weight:700;flex-shrink:0}
.proj-item .pmain{flex:1;min-width:0}
.proj-item .ptitle{font-size:14.5px;font-weight:600;display:flex;align-items:center;gap:6px}
.proj-item .psub{font-size:11.5px;color:var(--muted);margin-top:2px}
.proj-item .pcount{font-size:11px;color:var(--weak);text-align:right;flex-shrink:0}
.badge{font-size:10px;color:#ad6800;background:#fff7e6;border-radius:4px;padding:0 5px;font-weight:400}
/* ---------- 列表视图 ---------- */
.pv-head{padding:10px 14px 8px;display:flex;align-items:center;gap:10px;background:var(--bg)}
.pv-head .seg{flex:0 0 112px}
.pv-head .right{margin-left:auto;display:flex;gap:6px}
.filter-bar{display:flex;gap:6px;padding:0 14px 8px;overflow:hidden}
.fchip{font-size:11px;color:var(--muted);background:#fff;border:1px solid #e6e8eb;border-radius:999px;padding:2px 9px;white-space:nowrap}
.fchip.on{color:var(--primary);border-color:var(--primary);background:#f0f5ff}
.group-title{display:flex;align-items:center;gap:7px;padding:12px 16px 6px;font-size:12px;color:var(--muted);font-weight:600}
.group-title::before{content:"";width:3px;height:12px;border-radius:2px;background:var(--primary)}
.group-title .cnt{color:var(--weak);font-weight:400}
.task-row{display:flex;align-items:flex-start;gap:9px;background:#fff;border-radius:9px;padding:10px 12px;margin:0 12px 7px;box-shadow:0 1px 2px rgba(0,0,0,.04)}
.task-row.done{background:#fafbfa}
.task-row .box{width:19px;height:19px;border-radius:50%;border:1.5px solid #d0d0d0;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px}
.task-row.done .box{background:var(--success);border-color:var(--success)}
.box svg{opacity:0} .task-row.done .box svg{opacity:1}
.task-main{flex:1;min-width:0}
.task-title{font-size:14px;display:flex;align-items:center;gap:6px}
.task-row.done .task-title{color:#a0a0a0;text-decoration:line-through}
.task-meta{display:flex;align-items:center;gap:8px;margin-top:4px;font-size:11px;color:var(--weak);flex-wrap:wrap}
.task-meta .col{color:var(--primary);background:#f0f5ff;border-radius:4px;padding:0 5px}
.task-meta .assignee{color:var(--text);font-size:12px;font-weight:600}
.task-meta .members{font-size:10.5px;color:var(--weak)}
.task-right{display:flex;align-items:center;gap:6px;flex-shrink:0;margin-top:1px}
.more{color:#c2c7cf;font-size:16px;line-height:1;padding:0 2px}
.sub-row{display:flex;align-items:center;gap:8px;background:#fff;border-radius:8px;padding:8px 12px 8px 30px;margin:-2px 12px 7px 26px;
box-shadow:0 1px 2px rgba(0,0,0,.03);position:relative}
.sub-row::before{content:"";position:absolute;left:14px;top:0;bottom:0;width:1px;background:#e9ecf0}
.sub-row .box{width:16px;height:16px;border-radius:50%;border:1.5px solid #d0d0d0;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.sub-row.done .box{background:var(--success);border-color:var(--success)}
.sub-row .box svg{opacity:0} .sub-row.done .box svg{opacity:1}
.sub-title{flex:1;font-size:13px;color:#444}
.sub-row.done .sub-title{color:#a8a8a8;text-decoration:line-through}
.collapse{font-size:11px;color:var(--primary);padding:4px 0 8px 30px;margin:0 12px}
/* ---------- 看板视图 ---------- */
.board-wrap{display:flex;gap:10px;padding:4px 12px 8px;overflow-x:auto;overflow-y:hidden;height:100%}
.bcol{flex:0 0 186px;display:flex;flex-direction:column;min-height:0}
.bcol-head{display:flex;align-items:center;gap:5px;padding:2px 2px 7px}
.bcol-name{font-size:12px;font-weight:700;color:#3d4450;letter-spacing:.3px}
.bcol-cnt{font-size:11px;color:var(--weak);background:#e8ebef;border-radius:999px;padding:0 6px;line-height:15px}
.bcol-bind{font-size:10px;color:var(--primary);background:#f0f5ff;border-radius:4px;padding:0 4px;margin-left:auto}
.bcol-bind.off{color:var(--weak);background:#f2f3f5}
.bcol-body{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:7px;padding-bottom:8px}
.bcard{background:#fff;border-radius:8px;padding:9px 10px;box-shadow:0 1px 2px rgba(0,0,0,.05)}
.bcard .brow1{display:flex;align-items:flex-start;gap:6px}
.bcard .btitle{flex:1;font-size:12.5px;font-weight:600;line-height:1.45}
.bcard .bmeta{display:flex;align-items:center;gap:6px;margin-top:6px;font-size:10.5px;color:var(--weak)}
.bcard .bassignee{font-size:11px;font-weight:600;color:#4a5160}
.bcard .bmembers{font-size:10px;color:#a7adb6}
.bsub{display:flex;align-items:center;gap:5px;margin-top:5px;padding-top:5px;border-top:1px dashed #eef0f3;font-size:11px;color:#5a616b}
.bsub .sbox{width:13px;height:13px;border-radius:50%;border:1.3px solid #d0d0d0;flex-shrink:0}
.bsub.done .sbox{background:var(--success);border-color:var(--success)}
.bsub .stitle{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bsub.done .stitle{color:#a8a8a8;text-decoration:line-through}
.bsub .sdot{width:6px;height:6px}
.bmore{color:var(--weak);font-size:10px;margin-left:2px}
.badd{background:rgba(255,255,255,.6);border:1px dashed #d5dae1;border-radius:8px;padding:8px;text-align:center;font-size:11.5px;color:var(--weak)}
.bcol.dragover .bcol-body{background:#eaf2ff;border-radius:8px;outline:1.5px dashed var(--primary)}
.dragging{opacity:.55;transform:scale(.97) rotate(-1deg);box-shadow:0 8px 18px rgba(15,23,42,.16)}
/* ---------- 设置 / 弹窗 ---------- */
.set-row{display:flex;align-items:center;gap:10px;background:#fff;padding:12px 14px;margin-bottom:1px}
.set-row .sname{font-size:13.5px;font-weight:600;width:64px;flex-shrink:0}
.set-row .sctrl{flex:1;display:flex;align-items:center;gap:6px;justify-content:flex-end;flex-wrap:wrap}
.set-hint{font-size:11px;color:var(--weak);padding:8px 14px 14px;line-height:1.7}
.drop{border:1px solid var(--line);border-radius:7px;padding:4px 9px;font-size:12px;color:var(--text);background:#fff;min-width:92px;display:flex;align-items:center;gap:6px}
.drop .cv{margin-left:auto;font-size:9px;color:var(--weak)}
.drop.off{color:var(--weak);background:#f7f8fa}
.sw-toggle{width:38px;height:21px;border-radius:999px;background:#dfe3e8;position:relative;flex-shrink:0}
.sw-toggle::after{content:"";position:absolute;top:2px;left:2px;width:17px;height:17px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.15)}
.sw-toggle.on{background:var(--primary)}
.sw-toggle.on::after{left:19px}
.mask{position:absolute;inset:28px 0 0 0;background:rgba(0,0,0,.45);z-index:9}
.sheet{position:absolute;left:0;right:0;bottom:0;background:#fff;border-radius:12px 12px 0 0;padding:16px 16px calc(env(safe-area-inset-bottom, 0px) + 20px);z-index:10;max-height:640px;overflow:hidden}
.sheet-title{font-size:16px;font-weight:700;margin-bottom:4px}
.sheet-sub{font-size:11.5px;color:var(--weak);margin-bottom:14px}
.field{margin-bottom:13px}
.field label{display:block;font-size:12px;color:var(--muted);margin-bottom:6px}
.inp{border:1px solid var(--line);border-radius:8px;padding:8px 10px;font-size:14px;background:#fff;color:var(--text);display:block;width:100%}
.inp.ph{color:#b8bcc4}
.section-h{font-size:11px;color:var(--weak);letter-spacing:.5px;margin:14px 0 8px;display:flex;align-items:center;gap:6px}
.section-h::after{content:"";flex:1;height:1px;background:var(--line)}
.extras-head{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:600;padding:9px 10px;background:#f7f8fa;border-radius:8px}
.extras-head .cv{margin-left:auto;color:var(--weak);font-size:10px}
.extra-row{display:flex;gap:8px;margin-top:8px}
.extra-row .k{flex:0 0 86px}
.extra-row .v{flex:1}
.btn-primary{display:block;text-align:center;background:var(--primary);color:#fff;border-radius:8px;padding:10px 0;font-size:15px;font-weight:600;margin-top:18px}
.btn-ghost{display:block;text-align:center;border:1px solid var(--line);border-radius:8px;padding:9px 0;font-size:15px;color:var(--muted);margin-top:8px;background:#fff}
.btn-danger{display:block;text-align:center;border:1px solid var(--danger);border-radius:8px;padding:9px 0;font-size:15px;color:var(--danger);margin-top:8px;background:#fff}
.pick-row{display:flex;align-items:center;gap:10px;padding:10px 4px;border-bottom:1px solid var(--line)}
.pick-row:last-child{border-bottom:none}
.avatar{width:26px;height:26px;border-radius:50%;background:#dfe6f0;color:#5a6a80;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.avatar.sm{width:20px;height:20px;font-size:9.5px}
.pick-row .pn{flex:1;font-size:13.5px}
.ck{width:18px;height:18px;border-radius:50%;border:1.5px solid #d0d0d0;flex-shrink:0}
.ck.on{background:var(--primary);border-color:var(--primary);position:relative}
.ck.on::after{content:"";position:absolute;left:5px;top:3px;width:4px;height:8px;border:solid #fff;border-width:0 1.5px 1.5px 0;transform:rotate(45deg)}
/* 空态 */
.empty{text-align:center;padding:70px 20px;color:var(--weak)}
.empty .ico{width:64px;height:64px;margin:0 auto 12px;border-radius:50%;background:#f2f3f5;display:flex;align-items:center;justify-content:center;color:#c4c8ce;font-size:30px}
.empty p{font-size:13px;margin-bottom:12px}
.empty .mini-btn.solid{display:inline-block;padding:6px 18px;font-size:13px}
/* 骨架屏 */
.skel{background:#fff;border-radius:9px;padding:12px;margin:0 12px 8px}
.skel i{display:block;height:10px;border-radius:5px;background:linear-gradient(90deg,#eef0f3 25%,#f6f7f9 37%,#eef0f3 63%);background-size:400% 100%;animation:sk 1.2s ease infinite}
.skel i+i{margin-top:8px;width:60%}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}
/* 退场动画示意 */
.leaving{opacity:.35;transform:scale(.96);filter:grayscale(.5)}
.toast{position:absolute;left:50%;bottom:96px;transform:translateX(-50%);background:rgba(0,0,0,.78);color:#fff;font-size:12px;border-radius:8px;padding:8px 14px;white-space:nowrap;z-index:12}
.hl{outline:2px solid var(--primary);outline-offset:1px;border-radius:8px}
</style>
</head>
<body>
<div class="wrap">
<div class="doc-head">
<h1>iBoard V0.2 界面设计 · 任务模块</h1>
<p>轻量任务 / 项目管理 —— 列表与看板双视图 · 列-状态绑定 · 按列保留选项 · 一级子任务</p>
<div class="meta">
<span>版本 V0.2</span><span>视口 420 × 820</span><span>移动端优先</span>
<span>风格沿用《界面设计.html》</span><span>需求编号 T-*</span>
</div>
</div>
<h2>1 设计规范 <span class="sub">沿用主文档 token,仅新增任务模块语义色</span></h2>
<p class="desc">任务模块不引入新主色,全部复用 V0.2 既有色板;只在「任务状态」「列绑定」两处新增语义映射。</p>
<div class="tokens">
<div class="panel">
<h4>主色 / 语义色</h4>
<div class="swatches">
<div class="sw"><i style="background:#1677ff"></i><b>Primary</b><em>#1677ff</em></div>
<div class="sw"><i style="background:#00b578"></i><b>Success</b><em>#00b578</em></div>
<div class="sw"><i style="background:#ffc53d"></i><b>Warn</b><em>#ffc53d</em></div>
<div class="sw"><i style="background:#ff3141"></i><b>Danger</b><em>#ff3141</em></div>
<div class="sw"><i style="background:#c9ced6"></i><b>Idle</b><em>#c9ced6</em></div>
</div>
</div>
<div class="panel">
<h4>任务状态映射</h4>
<div class="type-row"><em><span class="sdot todo"></span> 未开始 todo</em><span>灰点 #c9ced6,与「空闲/未启用」同色</span></div>
<div class="type-row"><em><span class="sdot doing"></span> 执行中 doing</em><span>主色点 #1677ff,与选中态一致</span></div>
<div class="type-row"><em><span class="sdot done"></span> 完成 done</em><span>成功绿 #00b578,勾选态一致</span></div>
</div>
<div class="panel">
<h4>尺寸 / 间距</h4>
<div class="kv">
<span>页面边距</span><b>12px</b>
<span>卡片圆角</span><b>8~10px</b>
<span>看板列宽</span><b>186px(固定,横向滚动)</b>
<span>列表行高</span><b>≈ 58px(含子任务元信息)</b>
<span>子任务缩进</span><b>28px + 层级线 1px</b>
<span>点击热区</span><b>≥ 44 × 44px</b>
<span>标题字号</span><b>14px / 600(列表)· 12.5px / 600(卡片)</b>
<span>负责人</span><b>12px / 600(突出)</b>
<span>任务成员</span><b>10.5px / 400 · #999(弱化)</b>
</div>
</div>
<div class="panel">
<h4>布局约定</h4>
<div class="type-row"><em>TabBar</em><span>5 项:打卡 / <b>任务</b> / 宏观 / 监控 / 我(任务在打卡之后,T-PM-06)</span></div>
<div class="type-row"><em>头部</em><span>项目页用 <code>navbar-sub</code>(44px,左返回 + 标题 + 右侧操作)</span></div>
<div class="type-row"><em>视图切换</em><span>列表 / 看板 用 <code>seg</code> 分段,切换不刷新</span></div>
<div class="type-row"><em>看板</em><span>列横向滚动,列体纵向滚动,两轴分离</span></div>
</div>
</div>
<h2>2 任务首屏 <span class="sub">最近项目条(可排序)+ 当前项目任务管理 · 更多进项目列表</span></h2>
<p class="desc">首屏<b>上部</b>为最近使用的 3 个项目卡片 + 「更多项目」入口(T-VW-08),卡片可长按拖动排序(T-VW-10,设备端记忆);<b>下部</b>直接是当前选中项目的任务管理视图(T-VW-09,默认上次访问的项目),不必先进项目列表。完整项目列表从「更多项目」进入。</p>
<div class="stage">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="body" style="display:flex;flex-direction:column">
<!-- 上: 最近项目条 -->
<div class="rp-bar">
<div class="rp-card">
<div class="rp-ico" style="background:#1677ff">张</div>
<div class="rp-name">张三的任务</div>
<div class="rp-meta">12 个任务</div>
<div class="rp-grip">⠿</div>
</div>
<div class="rp-card on">
<div class="rp-ico" style="background:#00b578">APP</div>
<div class="rp-name">APP 改版</div>
<div class="rp-meta">28 个任务</div>
<div class="rp-grip">⠿</div>
</div>
<div class="rp-card">
<div class="rp-ico" style="background:#ff8f1f">二</div>
<div class="rp-name">APP 二期</div>
<div class="rp-meta">9 个任务</div>
<div class="rp-grip">⠿</div>
</div>
<div class="rp-more">
<div class="rp-more-ico">▤</div>
更多项目
</div>
</div>
<div class="rp-drag-tip">长按卡片可调整顺序(本机记忆)</div>
<!-- 下: 当前项目的任务管理 -->
<div class="navbar-sub" style="margin-top:4px">
<span class="title">APP 改版</span>
<div class="right">
<div class="mini-btn">项目管理</div>
<div class="mini-btn solid">+ 新增</div>
</div>
</div>
<div class="pv-head">
<div class="seg"><div class="on">列表</div><div>看板</div></div>
<div class="right"><div class="mini-btn grey">过滤</div></div>
</div>
<div style="flex:1;min-height:0;overflow:hidden;padding-bottom:4px">
<div class="task-row" style="margin:0 12px 7px">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">登录接口返回 500</div>
<div class="task-meta">
<span class="sdot doing"></span><span>执行中</span>
<span class="col">Doing</span>
<span class="assignee">张三</span>
<span class="members">+ 李四、王五</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="task-row" style="margin:0 12px 7px">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">首页改版视觉走查</div>
<div class="task-meta">
<span class="sdot doing"></span><span>执行中</span>
<span class="col">Doing</span>
<span class="assignee">李四</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="task-row done" style="margin:0 12px 7px">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">需求评审</div>
<div class="task-meta">
<span class="sdot done"></span><span>完成</span>
<span class="col">Done</span>
<span class="assignee">王五</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>任务首屏(T-VW-08/09)</b>
<p>上:最近 3 个项目卡片,当前项目主色描边高亮;长按「⠿」拖动排序(T-VW-10,设备端)。下:当前项目的任务管理,默认上次访问的项目。项目页头部仅保留<b>「项目管理」+「+ 新增」</b>两个入口(T-PJ-11)。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">我的项目</span>
<div class="right">
<div class="mini-btn solid">+ 新建</div>
</div>
</div>
<div class="body scroll">
<div class="proj-item" style="margin-top:8px">
<div class="pico" style="background:#1677ff">张</div>
<div class="pmain">
<div class="ptitle">张三的任务 <span class="badge">个人</span></div>
<div class="psub">12 个任务 · 3 个进行中</div>
</div>
<div class="pcount">›</div>
</div>
<div class="proj-group">协作项目(3)</div>
<div class="proj-item">
<div class="pico" style="background:#00b578">APP</div>
<div class="pmain">
<div class="ptitle">APP 改版</div>
<div class="psub">28 个任务 · 4 人 · 6 个子任务</div>
</div>
<div class="pcount">›</div>
</div>
<div class="proj-item">
<div class="pico" style="background:#ff8f1f">二期</div>
<div class="pmain">
<div class="ptitle">APP 二期</div>
<div class="psub">9 个任务 · 2 人</div>
</div>
<div class="pcount">›</div>
</div>
<div class="proj-item">
<div class="pico" style="background:#a855f7">运</div>
<div class="pmain">
<div class="ptitle">运维排期</div>
<div class="psub">5 个任务 · 1 人</div>
</div>
<div class="pcount">›</div>
</div>
<div class="proj-group">已归档(1)</div>
<div class="proj-item" style="opacity:.65">
<div class="pico" style="background:#a8b0ba">旧</div>
<div class="pmain">
<div class="ptitle">2025 遗留</div>
<div class="psub">已归档 · 14 个任务</div>
</div>
<div class="pcount">›</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>我的项目列表(从「更多项目」进入)</b>
<p>完整项目列表:个人默认项目带「个人」徽标、无删除入口;归档项目降透明分组。选择项目后返回首屏并切换当前项目(T-VW-09)。</p>
</div>
</div>
</div>
<h2>3 列表视图 <span class="sub">Todoist 风格 · 一级子任务缩进折叠</span></h2>
<p class="desc">默认视图(T-VW-05)。子任务缩进 28px 并带层级线(T-ST-04),可折叠(T-ST-05);已完成任务按<b>所属列</b>的保留选项隐藏(T-FL-11)。</p>
<div class="stage">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right">
<div class="mini-btn">项目管理</div>
<div class="mini-btn solid">+ 新增</div>
</div>
</div>
<div class="body scroll">
<div class="pv-head">
<div class="seg"><div class="on">列表</div><div>看板</div></div>
<div class="right"><div class="mini-btn grey">过滤</div></div>
</div>
<div class="group-title">Doing <span class="cnt">2</span></div>
<div class="task-row">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">登录接口返回 500</div>
<div class="task-meta">
<span class="sdot doing"></span><span>执行中</span>
<span class="col">Doing</span>
<span class="assignee">张三</span>
<span class="members">+ 李四、王五</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="sub-row">
<div class="box"><svg viewBox="0 0 14 14" width="10" height="10"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<span class="sub-title">复现环境搭建</span>
<span class="sdot done pill">完成</span>
</div>
<div class="sub-row">
<div class="box"><svg viewBox="0 0 14 14" width="10" height="10"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<span class="sub-title">补单元测试</span>
<span class="sdot doing pill">执行中</span>
</div>
<div class="collapse">收起 2 个子任务 ⌃</div>
<div class="task-row">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">首页改版视觉走查</div>
<div class="task-meta">
<span class="sdot doing"></span><span>执行中</span>
<span class="col">Doing</span>
<span class="assignee">李四</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="collapse">展开 1 个子任务 ⌄</div>
<div class="group-title">Plan <span class="cnt">1</span></div>
<div class="task-row">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">接入埋点上报</div>
<div class="task-meta">
<span class="sdot todo"></span><span>未开始</span>
<span class="col">Plan</span>
<span class="assignee">未指派</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="group-title">Done <span class="cnt">1</span></div>
<div class="task-row done">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">需求评审</div>
<div class="task-meta">
<span class="sdot done"></span><span>完成</span>
<span class="col">Done</span>
<span class="assignee">王五</span>
</div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div style="height:6px"></div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>列表视图</b>
<p>按看板列分组显示(列名可关闭)。负责人 12px/600 突出,任务成员 10.5px 弱化并置于下方(T-AS-01/02)。子任务带<b>独立状态小标记</b>(T-ST-09),可与父任务不一致。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body scroll">
<div class="pv-head">
<div class="seg"><div class="on">列表</div><div>看板</div></div>
<div class="right"><div class="mini-btn grey">过滤</div></div>
</div>
<div class="group-title">Done <span class="cnt">3</span></div>
<div class="task-row done">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">接口联调</div>
<div class="task-meta"><span class="sdot done"></span><span>完成于 今天</span><span class="col">Done</span><span class="assignee">张三</span></div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<!-- 正在退场:保留选项跨日触发,当场淡出并重排 -->
<div class="task-row done leaving" style="position:relative">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">旧任务 · 超出保留期</div>
<div class="task-meta"><span class="sdot done"></span><span>完成于 昨天</span><span class="col">Done</span></div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="task-row done">
<div class="box"><svg viewBox="0 0 14 14" width="11" height="11"><path d="M2.5 7.2l3 3 6-6.4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round"/></svg></div>
<div class="task-main">
<div class="task-title">修复打包脚本</div>
<div class="task-meta"><span class="sdot done"></span><span>完成于 今天</span><span class="col">Done</span><span class="assignee">李四</span></div>
</div>
<div class="task-right"><span class="more">›</span></div>
</div>
<div class="toast">已隐藏 1 条超出保留期的任务</div>
<div class="note" style="margin:16px 12px 0">
<b>退场动画(T-EX-18)</b><br>
跨日 / 跨周 / 跨月边界到点后,超出所属列保留选项(如「当天」)的已完成任务:透明度与高度在 <b>240ms</b> 内收缩至 0 → 移除节点 → 其余条目平滑重排。不做整页刷新。
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>保留选项 · 当场消失</b>
<p>该列保留选项为「当天」,昨日完成的任务在跨日后进入退场态并移除,其余任务重排(T-FL-05/09、T-EX-18)。</p>
</div>
</div>
</div>
<h2>4 看板视图 <span class="sub">列-状态绑定 · 卡片内嵌子任务 · 长按拖拽</span></h2>
<p class="desc">列头显示列名、数量与绑定标记(<span class="tag">↔ 完成</span> 表示该列绑定「完成」状态,<span class="tag grey">未绑定</span> 表示不参与状态联动)。</p>
<div class="stage">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body" style="padding-top:8px">
<div class="pv-head" style="padding-bottom:6px">
<div class="seg"><div>列表</div><div class="on">看板</div></div>
<div class="right"><div class="mini-btn grey">过滤</div></div>
</div>
<div class="board-wrap" style="height:calc(100% - 44px)">
<!-- Plan -->
<div class="bcol">
<div class="bcol-head">
<span class="bcol-name">Plan</span><span class="bcol-cnt">2</span>
<span class="bcol-bind">↔ 未开始</span>
</div>
<div class="bcol-body">
<div class="bcard">
<div class="brow1"><span class="btitle">接入埋点上报</span><span class="sdot todo"></span></div>
<div class="bmeta"><span class="bassignee">未指派</span></div>
</div>
<div class="bcard">
<div class="brow1"><span class="btitle">整理 0.3 需求清单</span><span class="sdot todo"></span></div>
<div class="bmeta"><span class="bassignee">张三</span><span class="bmembers">+ 王五</span></div>
<div class="bsub"><span class="sbox"></span><span class="stitle">收集各方诉求</span><span class="sdot todo"></span></div>
</div>
<div class="badd">+ 添加任务</div>
</div>
</div>
<!-- Doing 拖拽目标高亮 -->
<div class="bcol dragover">
<div class="bcol-head">
<span class="bcol-name">Doing</span><span class="bcol-cnt">2</span>
<span class="bcol-bind">↔ 执行中</span>
</div>
<div class="bcol-body">
<div class="bcard dragging">
<div class="brow1"><span class="btitle">登录接口返回 500</span><span class="sdot doing"></span></div>
<div class="bmeta"><span class="bassignee">张三</span><span class="bmembers">+ 李四、王五</span></div>
</div>
<div class="bcard">
<div class="brow1"><span class="btitle">首页改版视觉走查</span><span class="sdot doing"></span></div>
<div class="bmeta"><span class="bassignee">李四</span></div>
<div class="bsub"><span class="sbox"></span><span class="stitle">确认色板与字号</span><span class="sdot done"></span></div>
<div class="bsub"><span class="sbox"></span><span class="stitle">产出走查清单</span><span class="sdot doing"></span></div>
<div class="bmore">+1 个子任务</div>
</div>
<div class="badd">+ 添加任务</div>
</div>
</div>
<!-- Action 不绑定 -->
<div class="bcol">
<div class="bcol-head">
<span class="bcol-name">Action</span><span class="bcol-cnt">1</span>
<span class="bcol-bind off">未绑定</span>
</div>
<div class="bcol-body">
<div class="bcard">
<div class="brow1"><span class="btitle">待产品确认的 3 个问题</span><span class="sdot doing"></span></div>
<div class="bmeta"><span class="bassignee">王五</span></div>
</div>
<div class="badd">+ 添加任务</div>
</div>
</div>
<!-- Done -->
<div class="bcol">
<div class="bcol-head">
<span class="bcol-name">Done</span><span class="bcol-cnt">1</span>
<span class="bcol-bind">↔ 完成</span>
</div>
<div class="bcol-body">
<div class="bcard">
<div class="brow1"><span class="btitle">需求评审</span><span class="sdot done"></span></div>
<div class="bmeta"><span class="bassignee">王五</span></div>
<div class="bsub done"><span class="sbox"></span><span class="stitle">会前材料准备</span><span class="sdot done"></span></div>
</div>
<div class="badd">+ 添加任务</div>
</div>
</div>
</div>
<div class="toast">拖入 Doing,状态将改为「执行中」</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>看板视图 + 拖拽中</b>
<p>卡片轻量化(T-UI-02):标题 + 状态点 + 负责人(小字)+ 成员(更弱)+ 子任务摘要。拖拽中卡片半透明抬起,目标列蓝色虚线高亮。<b>子任务内嵌展示并可勾选</b>(T-ST-06/07),带自身状态点(T-ST-09)。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body" style="padding-top:8px">
<div class="pv-head" style="padding-bottom:6px">
<div class="seg"><div>列表</div><div class="on">看板</div></div>
<div class="right"><div class="mini-btn grey">过滤</div></div>
</div>
<div class="board-wrap" style="height:calc(100% - 44px)">
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Plan</span><span class="bcol-cnt">1</span><span class="bcol-bind">↔ 未开始</span></div>
<div class="bcol-body">
<div class="bcard">
<div class="brow1"><span class="btitle">接入埋点上报</span><span class="sdot todo"></span></div>
<div class="bmeta"><span class="bassignee">未指派</span></div>
</div>
</div>
</div>
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Doing</span><span class="bcol-cnt">1</span><span class="bcol-bind">↔ 执行中</span></div>
<div class="bcol-body">
<!-- 拖拽落点:另一张卡片上 → 降为该卡片的子任务 -->
<div class="bcard" style="margin-bottom:7px"><span class="btitle" style="font-size:12.5px">首页改版视觉走查</span></div>
<div class="bcard hl" style="position:relative">
<div class="brow1"><span class="btitle">登录接口返回 500</span><span class="sdot doing"></span></div>
<div class="bmeta"><span class="bassignee">张三</span></div>
<div class="bcard" style="border:1.5px dashed var(--primary);background:#f5f9ff;box-shadow:none;margin-top:6px;padding:5px 7px">
<span style="font-size:11px;color:var(--primary)">松手 → 成为子任务</span>
</div>
</div>
</div>
</div>
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Action</span><span class="bcol-cnt">0</span><span class="bcol-bind off">未绑定</span></div>
<div class="bcol-body"><div class="badd">+ 添加任务</div></div>
</div>
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Done</span><span class="bcol-cnt">1</span><span class="bcol-bind">↔ 完成</span></div>
<div class="bcol-body">
<div class="bcard">
<div class="brow1"><span class="btitle">需求评审</span><span class="sdot done"></span></div>
<div class="bmeta"><span class="bassignee">王五</span></div>
</div>
</div>
</div>
</div>
<div class="toast">仅支持一级子任务</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>拖拽降为子任务(T-ST-12)</b>
<p>长按卡片拖到<b>另一张卡片</b>上松手即成为其一级子任务。目标本身是子任务、或被拖任务已有子任务,均拒绝并 Toast「仅支持一级子任务」(T-ST-13/14)。</p>
</div>
</div>
</div>
<h2>5 列设置 <span class="sub">列管理 + 状态绑定 + 保留选项</span></h2>
<p class="desc">本模块的配置中枢:每列一行,包含<b>重命名</b>、<b>状态绑定</b>(T-BD-02)与<b>保留选项</b>(T-FL-02)。列可拖动排序(T-COL-05)、增删(T-COL-02/04),数量 1~10。</p>
<div class="stage">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">列设置</span>
<div class="right"><div class="mini-btn solid">保存</div></div>
</div>
<div class="body scroll">
<div class="set-hint" style="padding-top:12px">
拖动左侧手柄调整列顺序;顺序决定「改状态时自动归位」的目标列(取第一个匹配列)。
</div>
<div class="set-row">
<span style="color:#c2c7cf">≡</span>
<span class="sname">Plan</span>
<div class="sctrl">
<div class="drop">未开始 <span class="cv">▾</span></div>
</div>
</div>
<div class="set-row">
<span style="color:#c2c7cf">≡</span>
<span class="sname">Doing</span>
<div class="sctrl">
<div class="drop">执行中 <span class="cv">▾</span></div>
</div>
</div>
<div class="set-row">
<span style="color:#c2c7cf">≡</span>
<span class="sname">Action</span>
<div class="sctrl">
<div class="drop off">不绑定状态 <span class="cv">▾</span></div>
</div>
</div>
<div class="set-row">
<span style="color:#c2c7cf">≡</span>
<span class="sname">Done</span>
<div class="sctrl">
<div class="drop">完成 <span class="cv">▾</span></div>
</div>
</div>
<div style="padding:12px 14px">
<div class="mini-btn" style="display:inline-block;padding:6px 14px;font-size:12px">+ 新增列</div>
<div class="mini-btn grey" style="display:inline-block;padding:6px 14px;font-size:12px;margin-left:6px">删除列</div>
</div>
<div class="section-h" style="margin:6px 14px 8px">已完成任务保留</div>
<div class="set-row">
<span class="sname" style="width:82px">Plan</span>
<div class="sctrl"><div class="drop">永久显示 <span class="cv">▾</span></div></div>
</div>
<div class="set-row">
<span class="sname" style="width:82px">Doing</span>
<div class="sctrl"><div class="drop">本月 <span class="cv">▾</span></div></div>
</div>
<div class="set-row">
<span class="sname" style="width:82px">Action</span>
<div class="sctrl"><div class="drop">3 天 <span class="cv">▾</span></div></div>
</div>
<div class="set-row">
<span class="sname" style="width:82px">Done</span>
<div class="sctrl"><div class="drop">当天 <span class="cv">▾</span></div></div>
</div>
<div class="set-hint">
保留选项:<b>永不显示 / 当天 / 3 天 / 本周 / 本月 / 永久显示</b>。<br>
仅影响已完成任务;未完成任务始终展示。列表与看板按同一规则过滤。
</div>
<div style="padding:0 14px 20px">
<div class="btn-primary">保存</div>
<div class="btn-ghost">取消</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>列设置</b>
<p>上半区是「列 → 状态」绑定,下半区是「列 → 保留选项」。<code>Action</code> 显示为「不绑定状态」灰态;保存后看板与列表即时生效,不批量改写已有任务(T-BD-11/12)。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body" style="padding-top:8px">
<div class="pv-head" style="padding-bottom:6px">
<div class="seg"><div>列表</div><div class="on">看板</div></div>
<div class="right"><div class="mini-btn grey">过滤</div></div>
</div>
<div class="board-wrap" style="height:calc(100% - 44px)">
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Plan</span><span class="bcol-cnt">0</span><span class="bcol-bind">↔ 未开始</span></div>
<div class="bcol-body"><div class="badd">+ 添加任务</div></div>
</div>
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Doing</span><span class="bcol-cnt">0</span><span class="bcol-bind">↔ 执行中</span></div>
<div class="bcol-body"><div class="badd">+ 添加任务</div></div>
</div>
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Action</span><span class="bcol-cnt">1</span><span class="bcol-bind off">未绑定</span></div>
<div class="bcol-body">
<div class="bcard hl">
<div class="brow1"><span class="btitle">待产品确认的 3 个问题</span><span class="sdot done"></span></div>
<div class="bmeta"><span class="bassignee">王五</span><span class="bmembers">+ 李四</span></div>
</div>
</div>
</div>
<div class="bcol">
<div class="bcol-head"><span class="bcol-name">Done</span><span class="bcol-cnt">0</span><span class="bcol-bind">↔ 完成</span></div>
<div class="bcol-body"><div class="badd">+ 添加任务</div></div>
</div>
</div>
<div class="toast">状态已改为「完成」,Action 未绑定完成,任务保留在原列</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>自动归位 · 无匹配列</b>
<p>任务在未绑定的 <code>Action</code> 中被勾成「完成」。若其他列绑定了「完成」→ 自动移入第一个匹配列;<b>若全部列都未绑定「完成」→ 不移动</b>,保留在原列(T-BD-14/16)。此屏即后者。</p>
</div>
</div>
</div>
<h2>6 任务详情 <span class="sub">字段 + 扩展信息卡片(默认收起)</span></h2>
<p class="desc">底部弹层。源码等扩展信息放在<b>可折叠卡片</b>内,默认收起、全部非必填(T-TK-04~07),不占用主字段空间。</p>
<div class="stage">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body" style="position:relative">
<div class="mask"></div>
<div class="sheet">
<div class="sheet-title">登录接口返回 500</div>
<div class="sheet-sub">APP 改版 · Doing · 执行中 · 创建于 10-22</div>
<div class="field">
<label>标题</label>
<div class="inp">登录接口返回 500</div>
</div>
<div class="field">
<label>描述</label>
<div class="inp ph">补充说明…</div>
</div>
<div class="field">
<label>状态</label>
<div class="seg"><div>未开始</div><div class="on">执行中</div><div>完成</div></div>
</div>
<div class="field">
<label>负责人</label>
<div class="pick-row" style="padding:6px 0">
<div class="avatar">张</div>
<span class="pn">张三</span>
<span class="link">更换</span>
</div>
</div>
<div class="field">
<label>任务成员</label>
<div class="pick-row" style="padding:6px 0">
<div class="avatar sm">李</div><div class="avatar sm" style="margin-left:-8px">王</div>
<span class="pn" style="font-size:12px;color:var(--weak)">李四、王五</span>
<span class="link">编辑</span>
</div>
</div>
<!-- 扩展信息卡片:默认收起 -->
<div class="extras-head">
<span>▸</span><span>扩展信息</span>
<span class="tag">2</span>
<span class="cv">默认收起 · 全部非必填</span>
</div>
<div style="margin-top:12px">
<div class="btn-primary">保存</div>
</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>详情(扩展信息收起)</b>
<p>负责人默认填入创建者本人,可清空为「未指派」(T-TK-09/10)。扩展信息卡片默认收起,右侧标出条目数。弹层底部预留 <b>安全区 + 20px</b>(T-UI-11):删除按钮不被手势条遮挡,小屏下弹层内部滚动、底部按钮始终完整可见。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body" style="position:relative">
<div class="mask"></div>
<div class="sheet" style="padding-bottom:8px">
<div class="sheet-title">登录接口返回 500</div>
<div class="sheet-sub">APP 改版 · Doing · 执行中</div>
<div class="field">
<label>负责人</label>
<div class="pick-row" style="padding:6px 0">
<div class="avatar">张</div>
<span class="pn">张三</span>
<span class="link">更换</span>
</div>
</div>
<div class="extras-head">
<span>▾</span><span>扩展信息</span>
<span class="tag">2</span>
<span class="cv">可自由增删条目</span>
</div>
<div class="extra-row">
<div class="inp k">仓库</div>
<div class="inp v">gitlab/app-web</div>
</div>
<div class="extra-row">
<div class="inp k">分支</div>
<div class="inp v">fix/login-500</div>
</div>
<div class="extra-row">
<div class="inp k">相关链接</div>
<div class="inp v" style="color:var(--primary)">https://…/issues/128</div>
</div>
<div style="margin-top:10px">
<span class="link">+ 添加一条</span>
</div>
<div class="section-h">子任务 <span class="tag">2</span></div>
<div class="pick-row">
<span class="ck on"></span>
<span class="pn">复现环境搭建</span>
<span class="sdot done pill">完成</span>
</div>
<div class="pick-row">
<span class="ck"></span>
<span class="pn">补单元测试</span>
<span class="sdot doing pill">执行中</span>
</div>
<div class="pick-row" style="border-bottom:none">
<span style="color:#c2c7cf;font-size:16px">+</span>
<span class="pn" style="color:var(--weak);font-size:13px">添加子任务</span>
</div>
<div class="btn-primary" style="margin-top:12px">保存</div>
<div class="btn-danger">删除任务<span style="font-size:11px;font-weight:400">(将一并删除 2 条子任务)</span></div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>详情(扩展信息展开)</b>
<p>扩展条目为<b>任意名称 + 值</b>,不限固定字段(T-TK-05),值可为文本或链接。子任务在此可增删改,状态与父任务互相独立(T-ST-03)。删除任务会提示级联条数(T-EX-07)。</p>
</div>
</div>
</div>
<h2>7 项目管理 · 成员与跨项目拷贝 <span class="sub">统一入口:成员 / 列设置 / 项目信息</span></h2>
<p class="desc">项目页头部的「项目管理」进入统一管理页(T-PJ-11),含<b>成员</b>、<b>列设置</b>、<b>项目信息</b>三个分区;负责人与任务成员只能从<b>当前项目成员</b>中选择(T-AS-03/04);跨项目操作是<b>拷贝</b>(T-CP-01)。</p>
<div class="stage">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">项目管理 · APP 改版</span>
</div>
<div class="body scroll">
<div class="set-hint" style="padding-top:12px">
项目内所有成员权限均等、全读写(T-PM-02);以下配置对全体成员即时生效。
</div>
<div class="section-h" style="margin:6px 14px 8px">成员(4)</div>
<div class="set-row" style="padding:12px 14px">
<div class="avatar">张</div>
<span class="pn" style="flex:1;font-size:13.5px">张三 <span class="tag grey" style="margin-left:6px">创建人</span></span>
<span class="link">管理 ›</span>
</div>
<div class="section-h" style="margin:14px 14px 8px">看板列</div>
<div class="set-row" style="padding:12px 14px">
<span class="pn" style="flex:1;font-size:13px;color:var(--muted)">Plan · Doing · Action · Done</span>
<span class="link">列设置 ›</span>
</div>
<div class="section-h" style="margin:14px 14px 8px">项目信息</div>
<div class="set-row" style="padding:12px 14px">
<span class="pn" style="flex:1;font-size:13.5px">项目名称</span>
<span style="font-size:12.5px;color:var(--muted)">APP 改版</span>
</div>
<div class="set-row" style="padding:12px 14px">
<span class="pn" style="flex:1;font-size:13.5px">归档项目</span>
<span class="link">归档</span>
</div>
<div class="set-row" style="padding:12px 14px">
<span class="pn" style="flex:1;font-size:13.5px;color:var(--danger)">删除项目</span>
<span class="link danger">删除</span>
</div>
<div class="set-hint">
个人默认项目不出现「删除项目」;退出项目仅创建人可见(T-PJ-07)。删除与退出均有二次确认。
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>项目管理(T-PJ-11/12)</b>
<p>三分区:成员(增删)、列设置(进入第 5 节的列设置页)、项目信息(改名 / 归档 / 删除 / 退出)。项目页头部不再散置成员与列设置入口。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn solid">+ 添加</div></div>
</div>
<div class="body scroll">
<div class="set-hint" style="padding-top:12px">
项目内所有成员<b>权限均等、全读写</b>;负责人与成员只是信息标记,不影响权限(T-AS-07、T-PM-02)。
</div>
<div class="set-row" style="padding:12px 14px">
<div class="avatar">张</div>
<span class="pn" style="flex:1;font-size:13.5px">张三 <span class="tag grey">创建人</span></span>
<span class="link" style="color:var(--weak)">退出</span>
</div>
<div class="set-row" style="padding:12px 14px">
<div class="avatar">李</div>
<span class="pn" style="flex:1;font-size:13.5px">李四</span>
<span class="link danger">移除</span>
</div>
<div class="set-row" style="padding:12px 14px">
<div class="avatar">王</div>
<span class="pn" style="flex:1;font-size:13.5px">王五</span>
<span class="link danger">移除</span>
</div>
<div class="set-row" style="padding:12px 14px;opacity:.7">
<div class="avatar" style="background:#f2f3f5;color:#b6bcc4">赵</div>
<span class="pn" style="flex:1;font-size:13.5px">赵六 <span class="badge">已退出</span></span>
<span class="link" style="color:var(--weak)">—</span>
</div>
<div class="note" style="margin:14px 12px 0">
成员被移出项目后,其担任的负责人 / 成员标记<b>保留历史</b>并显示「已退出」灰标,不清空、不报错(T-EX-06)。
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>项目成员</b>
<p>创建人可主动退出(T-PJ-07);成员清空后项目静默保留、前端不报错(T-PJ-08、T-EX-11)。</p>
</div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span>
<span class="title">APP 改版</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body" style="position:relative">
<div class="mask"></div>
<div class="sheet" style="padding-bottom:8px">
<div class="sheet-title">跨项目拷贝</div>
<div class="sheet-sub">将「登录接口返回 500」复制到另一个项目;源任务保持不变</div>
<div class="field">
<label>目标项目</label>
<div class="drop" style="width:100%">APP 二期 <span class="cv">▾</span></div>
</div>
<div class="field">
<label>将会复制</label>
<div style="font-size:12.5px;color:var(--muted);line-height:1.9">
标题、描述、状态、看板列、标签<br>
负责人与任务成员(仅保留目标项目成员)<br>
<b>2 条子任务</b> · <b>2 条扩展信息</b>
</div>
</div>
<div class="field">
<label>人员处理</label>
<div style="font-size:12px;color:var(--orange);background:#fff7e6;border-radius:8px;padding:8px 10px;line-height:1.7">
王五 不是「APP 二期」的成员,拷贝后将<b>不保留</b>其任务成员标记。
</div>
</div>
<div class="btn-primary">确认拷贝</div>
<div class="btn-ghost">取消</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption">
<b>拷贝确认</b>
<p>明确列出复制内容与被丢弃的人员(T-EX-08),避免静默丢数据。拷贝后新旧任务<b>完全独立</b>(T-CP-05)。</p>
</div>
</div>
</div>
<h2>8 交互与状态 <span class="sub">长按拖拽 · 三态 · 边界</span></h2>
<h3>8.1 拖拽与落点</h3>
<table>
<tr><th style="width:150px">操作</th><th>落点</th><th>结果</th></tr>
<tr><td>长按卡片 ≥ 300ms</td><td>—</td><td>卡片抬起(缩 0.97 + 倾斜 1°),进入拖拽态,锁定滚动</td></tr>
<tr><td>拖到另一列空白</td><td>列体</td><td>换列;目标列<b>绑定状态则状态跟随</b>,<b>未绑定则保留原状态</b>(T-BD-07)</td></tr>
<tr><td>拖到另一张卡片上</td><td>顶层任务卡</td><td>降为该任务的一级子任务;<b>原列与状态保持不变</b>(T-ST-15)</td></tr>
<tr><td>拖到子任务 / 自身 / 后代</td><td>非法落点</td><td>拒绝并 Toast,卡片回弹(T-ST-13、T-EX-15)</td></tr>
<tr><td>被拖任务有子任务</td><td>任何卡片</td><td>拒绝,避免二级嵌套(T-ST-14)</td></tr>
<tr><td>无需拖拽时</td><td>卡片「⋯」</td><td>「移动到列 / 移动到子任务」等价入口(T-UI-07)</td></tr>
</table>
<h3>8.2 三态与反馈</h3>
<div class="stage" style="margin-top:8px">
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span><span class="title">APP 二期</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body">
<div class="pv-head"><div class="seg"><div class="on">列表</div><div>看板</div></div></div>
<div class="skel"><i></i><i></i></div>
<div class="skel"><i></i><i></i></div>
<div class="skel"><i></i><i></i></div>
<div class="skel"><i></i><i></i></div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption"><b>加载态(T-UI-09)</b><p>骨架屏,避免白屏与布局跳动。</p></div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span><span class="title">APP 二期</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body">
<div class="pv-head"><div class="seg"><div class="on">列表</div><div>看板</div></div></div>
<div class="empty" style="padding-top:120px">
<div class="ico">✓</div>
<p>这个项目还没有任务</p>
<div class="mini-btn solid">创建第一个任务</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption"><b>空态(T-UI-08)</b><p>带明确 CTA;某列因保留选项隐藏全部已完成任务时,展示该列空态而非报错(T-EX-10)。</p></div>
</div>
<div class="shot">
<div class="phone">
<div class="navbar-sm">任务</div>
<div class="navbar-sub">
<span class="back">‹</span><span class="title">APP 二期</span>
<div class="right"><div class="mini-btn">项目管理</div><div class="mini-btn solid">+ 新增</div></div>
</div>
<div class="body">
<div class="pv-head"><div class="seg"><div class="on">列表</div><div>看板</div></div></div>
<div class="empty" style="padding-top:110px">
<div class="ico" style="background:#fff1f0;color:#ff7875">!</div>
<p>数据加载失败,请检查网络</p>
<div class="mini-btn solid">重试</div>
</div>
</div>
<div class="tabbar">
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="9"/><path d="M8 12h8M12 8v8"/></svg>打卡</div>
<div class="tab on"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="4" y="5" width="16" height="15" rx="2"/><path d="M8 10h8M8 14h5"/><path d="M9 5V3M15 5V3"/></svg>任务</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M4 19V9M10 19V5M16 19v-7M22 19H2"/></svg>宏观</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M3 13h4l2-5 3 10 2-5h7"/></svg>监控</div>
<div class="tab"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="8" r="3.2"/><path d="M5 20c1.2-4 4-6 7-6s5.8 2 7 6"/></svg>我</div>
</div>
</div>
<div class="caption"><b>异常态(T-UI-10)</b><p>乐观更新失败时回滚并 Toast,可重试(T-EX-02)。</p></div>
</div>
</div>
<h2>9 需求点对照 <span class="sub">界面稿 ↔ 需求编号</span></h2>
<table>
<tr><th style="width:120px">界面</th><th>对应需求点</th></tr>
<tr><td>2 任务首屏</td><td><code>T-VW-08/09/10</code>、<code>T-VW-03~07</code>、<code>T-PM-06/07</code>、<code>T-PJ-11</code>(头部入口)</td></tr>
<tr><td>2′ 我的项目列表</td><td><code>T-PJ-01~10</code>、<code>T-UI-08</code></td></tr>
<tr><td>3 列表视图</td><td><code>T-VW-01/02</code>、<code>T-ST-04/05/09</code>、<code>T-AS-01/02</code>、<code>T-FL-11</code>、<code>T-TK-12</code></td></tr>
<tr><td>3′ 保留退场</td><td><code>T-FL-05/09</code>、<code>T-EX-18</code></td></tr>
<tr><td>4 看板视图</td><td><code>T-BD-01~16</code>、<code>T-UI-02/07</code>、<code>T-ST-06/07/09</code>、<code>T-ST-12~15</code></td></tr>
<tr><td>5 列设置</td><td><code>T-COL-01~10</code>、<code>T-BD-02/09/10</code>、<code>T-FL-01~15</code></td></tr>
<tr><td>5′ 自动归位</td><td><code>T-BD-14/16</code>、<code>T-EX-04/05</code></td></tr>
<tr><td>6 任务详情</td><td><code>T-TK-01~13</code>、<code>T-ST-03</code>、<code>T-AS-05</code>、<code>T-EX-07</code>、<code>T-UI-11</code>(底部安全距离)</td></tr>
<tr><td>7 项目管理 / 成员 / 拷贝</td><td><code>T-PJ-11/12</code>、<code>T-AS-03/04/06/07</code>、<code>T-PM-01~05</code>、<code>T-CP-01~09</code>、<code>T-EX-06/08</code></td></tr>
<tr><td>8 三态</td><td><code>T-UI-08/09/10</code>、<code>T-EX-02/10</code></td></tr>
</table>
<h2>10 适配与可达性</h2>
<table>
<tr><th style="width:120px">项</th><th>约定</th></tr>
<tr><td>视口</td><td>设计稿 420×820;375~430px 内元素不换行、不裁切;底部 TabBar <b>5 项</b>每项 ≥ 44px 可点宽度</td></tr>
<tr><td>安全区</td><td>TabBar 使用 antd-mobile <code>safeArea</code>,页面底部留出 <code>tabbar-h + safe-bottom</code></td></tr>
<tr><td>看板宽度</td><td>列宽固定 186px,超出横向滚动;列头吸顶,列体独立纵向滚动</td></tr>
<tr><td>触控</td><td>长按 300ms 进入拖拽;点击热区 ≥ 44×44;拖拽中禁用页面滚动</td></tr>
<tr><td>动效</td><td>退场 240ms、拖动抬起 150ms、Toast 2s 自动消失;均 <code>pointer-events:none</code> 不阻塞后续操作</td></tr>
<tr><td>大字号</td><td>任务标题超长换行不截断(卡片内最多 2 行省略);列名 ≤ 12 字</td></tr>
<tr><td>深色模式</td><td>V0.2 沿用现有浅色主题,暂不适配</td></tr>
<tr><td>数量上限</td><td>看板列 <b>1~10</b>(上限待确认);扩展信息条目建议 ≤ 20</td></tr>
</table>
<p class="note" style="margin-top:26px">本文档为静态设计稿,不含脚本逻辑;实现对应 <code>src/pages/task/*.jsx</code>、<code>src/components/task/*.jsx</code> 与样式段(<code>src/styles/globals.css</code> 的 <code>.task-*</code>)。接口与数据口径见《任务模块设计文档-框架设计.md》《任务模块功能设计.md》与《任务模块数据库设计文档.md》。</p>
</div>
</body>
</html>