fix(任务): 编号改为 #序号展示、详情页完整编号可复制、修复详情改列报「看板列不存在」

- 列表/看板任务编号徽标改为 `#序号`(如 #18), 移除不再需要的 codePrefix 透传
- 详情页标题下新增完整任务编号胶囊 (项目编号-序号, 如 ADMIN-18), 点按复制:
  Clipboard API 优先, 非安全上下文/旧 WebView 回退 execCommand, 并提示已复制
- 修复详情页「看板列」切换报错: 0.2.1 本地库列 id 为 uuid 字符串,
  ActionSheet 的 key 恒为字符串, 旧代码 Number(key) 得到 NaN ->
  update 校验失败抛「看板列不存在」。改为字符串比对 (currentCol/勾选标记同步)
- 详情页保存后先就地替换该行再回源刷新
This commit is contained in:
jif2.zhang
2026-10-27 10:06:12 +08:00
parent 317072539d
commit 06e9a3e694
8 changed files with 119 additions and 24 deletions
+5 -4
View File
@@ -1,6 +1,7 @@
import StatusDot from './StatusDot.jsx'
import Avatar from './Avatar.jsx'
import { kindColor } from '../../pages/task/kind.js'
import { taskShortId } from '../../pages/task/date.js'
// 看板卡片 (T-UI-02): 轻量化
// - 标题 + 状态点 (T-ST-09)
@@ -9,11 +10,13 @@ import { kindColor } from '../../pages/task/kind.js'
const MAX_SUB = 3
export default function TaskCard({
task, codePrefix, bindDrag, onClick, onToggleSub, onToggle, onMore, dragging = false, highlight = false,
task, bindDrag, onClick, onToggleSub, onToggle, onMore, dragging = false, highlight = false,
}) {
const children = task.children || []
const shown = children.slice(0, MAX_SUB)
const rest = children.length - shown.length
// 编号只显示 `#序号`; 完整编号 (项目编号-序号) 放详情页 (见 TaskDetail)
const shortId = taskShortId(task)
return (
<div
@@ -47,9 +50,7 @@ export default function TaskCard({
</div>
<div className="bmeta">
{codePrefix && task.number != null && (
<span className="num-tag">{codePrefix}-{task.number}</span>
)}
{shortId && <span className="num-tag">{shortId}</span>}
{task.markDate && (
<span className="date-tag">{task.markDate.slice(5, 10).replace('-', '/')}</span>
)}
+5 -4
View File
@@ -1,6 +1,7 @@
import StatusDot from './StatusDot.jsx'
import Avatar from './Avatar.jsx'
import { kindColor } from '../../pages/task/kind.js'
import { taskShortId } from '../../pages/task/date.js'
const statusLabel = (s) => (s === 'done' ? '完成' : s === 'doing' ? '执行中' : '未开始')
@@ -10,9 +11,11 @@ const statusLabel = (s) => (s === 'done' ? '完成' : s === 'doing' ? '执行中
// 复选框 / ⋯ 是独立控件: pointerdown 不冒泡, 不发起拖动,
// 避免长按行后抬手时合成的 click 落在控件上误触状态切换
export default function TaskRow({
task, codePrefix, onToggle, onClick, onMore, bindDrag, bindDragHandle, dragging = false, dragOver, indent = false, children,
task, onToggle, onClick, onMore, bindDrag, bindDragHandle, dragging = false, dragOver, indent = false, children,
}) {
const done = task.status === 'done'
// 编号只显示 `#序号`; 完整编号 (项目编号-序号) 放详情页 (见 TaskDetail)
const shortId = indent ? null : taskShortId(task)
return (
<>
<div
@@ -52,9 +55,7 @@ export default function TaskRow({
<div className="task-title">{task.title}</div>
{/* 无类型/成员也保留该行, 与有标签的行等高 */}
<div className="task-meta">
{codePrefix && task.number != null && (
<span className="num-tag">{codePrefix}-{task.number}</span>
)}
{shortId && <span className="num-tag">{shortId}</span>}
{task.markDate && (
<span className="date-tag">{task.markDate.slice(5, 10).replace('-', '/')}</span>
)}