feat(board): 展示任务时间,并修正已完成任务的逾期基准
时间展示(ADR-008): - 详情抽屉新增只读「时间」区块:创建 / 更新常驻,完成时间缺失时标注「未完成」,归档任务追加归档时间;时间不进入草稿与 dirty 判定 - 已完成卡片在元信息行右侧显示「完成于 M月D日」,卡片根元素 title 汇总创建 / 完成 / 归档时间(精确到分钟) - 回收站条目补创建时间,删掉内联 formatTime,统一走 @/utils/date - date.ts 新增 formatDateTime(YYYY-MM-DD HH:mm)与 formatCompactDate(同年 M月D日 / 跨年带年份),空值与非法时间戳返回 null 逾期基准修复: - 新增 formatDueDateForTask:未完成任务仍以「今天」推算;已完成任务改以「完成日」推算,19 号截止、19 号当天完成的任务不会在 20 号显示「逾期 1 天」,完成时确实超期则定格为「逾期 N 天完成」,不再随日期增长 - 新增 localDateOf:completedAt 存 UTC 时间戳,按本地时区取日期,避免跨日偏差 - TaskCard 改用 dueLabel computed 取代模板内直接调用 formatDueDate;颜色仍由 isOverdue 决定,已完成卡片保持中性色 测试:date / TaskCard 补时间格式化与逾期基准用例(当天完成、提前完成、完成时超期定格、缺 completedAt、跨年),全量 728 单测通过;vue-tsc 与 eslint 干净。
This commit is contained in:
@@ -81,11 +81,32 @@ describe('截止日期', () => {
|
||||
|
||||
it('已完成任务不再标记逾期', () => {
|
||||
const yesterday = dayjs().subtract(2, 'day').format('YYYY-MM-DD')
|
||||
const wrapper = mountCard({ dueDate: yesterday, status: 'done' })
|
||||
const completedAt = dayjs().subtract(1, 'day').hour(10).minute(0).toISOString()
|
||||
const wrapper = mountCard({ dueDate: yesterday, status: 'done', completedAt })
|
||||
const badge = wrapper.findAll('span').find((node) => node.text().includes('逾期'))
|
||||
expect(badge?.text()).toBe('逾期 1 天完成')
|
||||
expect(badge?.classes().join(' ')).not.toContain('rose')
|
||||
})
|
||||
|
||||
it('当天完成的任务第二天不再显示逾期天数', () => {
|
||||
// 复现:19 号截止、19 号完成,20 号查看时曾显示「逾期 1 天」
|
||||
const dueDate = dayjs().subtract(1, 'day').format('YYYY-MM-DD')
|
||||
const completedAt = dayjs().subtract(1, 'day').hour(10).minute(0).toISOString()
|
||||
const wrapper = mountCard({ dueDate, status: 'done', completedAt })
|
||||
|
||||
expect(wrapper.text()).not.toContain('逾期')
|
||||
expect(wrapper.text()).toContain('原定')
|
||||
expect(wrapper.text()).toMatch(/原定 \d+月\d+日/)
|
||||
})
|
||||
|
||||
it('完成时已超期的任务显示「逾期 N 天完成」,不再随日期增长', () => {
|
||||
const dueDate = dayjs().subtract(3, 'day').format('YYYY-MM-DD')
|
||||
const completedAt = dayjs().subtract(2, 'day').hour(9).minute(0).toISOString()
|
||||
const wrapper = mountCard({ dueDate, status: 'done', completedAt })
|
||||
|
||||
expect(wrapper.text()).toContain('逾期 1 天完成')
|
||||
})
|
||||
|
||||
it('今天到期显示「今天」', () => {
|
||||
expect(mountCard({ dueDate: dayjs().format('YYYY-MM-DD') }).text()).toContain('今天')
|
||||
})
|
||||
@@ -105,6 +126,36 @@ describe('已完成样式', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('时间信息', () => {
|
||||
it('已完成卡片显示完成日期', () => {
|
||||
const completedAt = new Date(2026, 9, 18, 10, 20).toISOString()
|
||||
const wrapper = mountCard({ status: 'done', completedAt })
|
||||
expect(wrapper.text()).toContain('完成于')
|
||||
expect(wrapper.text()).toContain('10月18日')
|
||||
})
|
||||
|
||||
it('未完成卡片不显示完成时间', () => {
|
||||
expect(mountCard({ completedAt: null }).text()).not.toContain('完成于')
|
||||
})
|
||||
|
||||
it('卡片 title 暴露完整创建与完成时间', () => {
|
||||
const createdAt = new Date(2026, 9, 18, 10, 8).toISOString()
|
||||
const completedAt = new Date(2026, 9, 18, 10, 20).toISOString()
|
||||
const title = mountCard({ status: 'done', createdAt, completedAt })
|
||||
.find('article')
|
||||
.attributes('title')
|
||||
|
||||
expect(title).toContain('创建于 2026-10-18 10:08')
|
||||
expect(title).toContain('完成于 2026-10-18 10:20')
|
||||
})
|
||||
|
||||
it('归档任务在 title 中补充归档时间', () => {
|
||||
const archivedAt = new Date(2026, 9, 19, 8, 0).toISOString()
|
||||
const title = mountCard({ archivedAt }).find('article').attributes('title')
|
||||
expect(title).toContain('归档于 2026-10-19 08:00')
|
||||
})
|
||||
})
|
||||
|
||||
describe('标签展示', () => {
|
||||
it('最多显示 3 个标签', () => {
|
||||
const wrapper = mountCard({ tags: ['a', 'b', 'c', 'd', 'e'] })
|
||||
|
||||
Reference in New Issue
Block a user