refactor: 首次运行为空列表并简化存储初始化
- 移除 seed-data 模块,首次运行改为持久化空任务列表 - 简化 initializeStore(),将 tasksInitialized 处理集中到 store 层 - 移除 loadTasksData() 写入 tasksInitialized 的副作用 - 已归一化的任务数据跳过多余的 localStorage 回写 - 为旧版安装补写 tasksInitialized;首次写入失败时下次访问重试 - 补充存储兼容性测试并更新 README
This commit is contained in:
+2
-3
@@ -12,7 +12,6 @@ import {
|
||||
setTimelineExpanded,
|
||||
updateTaskCounts,
|
||||
} from './render.js';
|
||||
import { createSeedTasks } from './seed-data.js';
|
||||
import {
|
||||
getShowHidden,
|
||||
getTasks,
|
||||
@@ -24,7 +23,7 @@ import {
|
||||
togglePin,
|
||||
wasCorrupted,
|
||||
} from './store.js';
|
||||
import { consumeStorageWriteFailure, isInitialized } from './storage.js';
|
||||
import { consumeStorageWriteFailure } from './storage.js';
|
||||
import { addTimelineEntry, deleteTimelineEntry, updateTimelineEntry } from './timeline.js';
|
||||
import { isHiddenTask } from './utils.js';
|
||||
|
||||
@@ -256,7 +255,7 @@ function bind() {
|
||||
});
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initializeStore(createSeedTasks(), isInitialized());
|
||||
initializeStore();
|
||||
applyTranslations();
|
||||
renderAllTasks();
|
||||
bind();
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
export function createSeedTasks(now = new Date()) {
|
||||
const createdDate = now.toISOString();
|
||||
return [
|
||||
{
|
||||
id: 1,
|
||||
title: '所有设备相机参数标准化',
|
||||
description: '完成所有生产设备的相机参数标准化工作,确保图像采集的一致性和可靠性。',
|
||||
progressNotes: '目前已完成大部分设备的参数标准化工作,仅剩DieBond贴片相机待确认参数配置。',
|
||||
status: 'inProgress',
|
||||
progress: 90,
|
||||
assignee: '技术团队',
|
||||
collaborators: [],
|
||||
dueDate: '2025-02-15',
|
||||
createdDate,
|
||||
language: 'zh',
|
||||
priority: 'high',
|
||||
isPinned: false,
|
||||
timeline: [],
|
||||
isHidden: false,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'DieBond设备照明优化',
|
||||
description:
|
||||
'定制组合光源:同轴光+环形光,采购更窄、更亮的侧面光源,以解决支架白边问题,提升图像质量。',
|
||||
progressNotes:
|
||||
'配置方案已与供应商确认,技术参数符合要求。供应商承诺2025年7月4日发货,目前正在生产中。',
|
||||
status: 'inProgress',
|
||||
progress: 60,
|
||||
assignee: '硬件团队',
|
||||
collaborators: ['供应商'],
|
||||
dueDate: '2025-07-04',
|
||||
createdDate,
|
||||
language: 'zh',
|
||||
priority: 'medium',
|
||||
isPinned: true,
|
||||
timeline: [],
|
||||
isHidden: false,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: 'DieBond和ClipBond软件界面中英文翻译更新',
|
||||
description: '完成DieBond和ClipBond设备软件界面的中英文翻译工作,支持多语言操作环境。',
|
||||
progressNotes:
|
||||
'SG-TATA GUI 的中英文翻译已完成。未来更新杨杰的代码后,需要重新进行翻译(任务量很少)。',
|
||||
status: 'inProgress',
|
||||
progress: 80,
|
||||
assignee: '杨杰',
|
||||
collaborators: ['翻译团队'],
|
||||
dueDate: '2025-02-28',
|
||||
createdDate,
|
||||
language: 'zh',
|
||||
priority: 'medium',
|
||||
isPinned: false,
|
||||
timeline: [],
|
||||
isHidden: false,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '所有设备相机手册',
|
||||
description: '编写所有设备相机的操作手册,包括校准流程、位置引导方法、检测标准等技术文档。',
|
||||
progressNotes: '任务刚启动,正在收集各设备的相机技术规格和操作要求。',
|
||||
status: 'todo',
|
||||
progress: 0,
|
||||
assignee: '技术文档组',
|
||||
collaborators: [],
|
||||
dueDate: '2025-03-31',
|
||||
createdDate,
|
||||
language: 'zh',
|
||||
priority: 'low',
|
||||
isPinned: false,
|
||||
timeline: [],
|
||||
isHidden: false,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '开发 TaTa SECS/GEM & Map 软件',
|
||||
description:
|
||||
'开发符合SEMI标准的SECS/GEM通信协议软件,实现设备与MES系统的标准化通信,包括Map数据管理功能。',
|
||||
progressNotes: '需求分析阶段,正在梳理SECS/GEM协议规范和技术架构设计。',
|
||||
status: 'todo',
|
||||
progress: 0,
|
||||
assignee: '软件开发组',
|
||||
collaborators: ['系统架构师'],
|
||||
dueDate: '2025-06-30',
|
||||
createdDate,
|
||||
language: 'zh',
|
||||
priority: 'high',
|
||||
isPinned: false,
|
||||
timeline: [],
|
||||
isHidden: false,
|
||||
},
|
||||
];
|
||||
}
|
||||
+6
-5
@@ -36,16 +36,17 @@ function writeJson(key, value) {
|
||||
}
|
||||
export function loadTasksData() {
|
||||
const { value: raw, available } = readRaw(STORAGE_KEYS.tasks);
|
||||
if (!available) return { tasks: [], corrupted: false, exists: false, available: false };
|
||||
if (raw === null) return { tasks: [], corrupted: false, exists: false, available: true };
|
||||
writeRaw(STORAGE_KEYS.initialized, 'true');
|
||||
if (!available)
|
||||
return { tasks: [], corrupted: false, exists: false, available: false, raw: null };
|
||||
if (raw === null)
|
||||
return { tasks: [], corrupted: false, exists: false, available: true, raw: null };
|
||||
try {
|
||||
const tasks = JSON.parse(raw);
|
||||
if (!Array.isArray(tasks)) throw new TypeError('Tasks must be an array');
|
||||
return { tasks, corrupted: false, exists: true, available: true };
|
||||
return { tasks, corrupted: false, exists: true, available: true, raw };
|
||||
} catch {
|
||||
writeRaw(STORAGE_KEYS.corruptedBackup, raw);
|
||||
return { tasks: [], corrupted: true, exists: true, available: true };
|
||||
return { tasks: [], corrupted: true, exists: true, available: true, raw };
|
||||
}
|
||||
}
|
||||
export const saveTasksData = (tasks) => writeJson(STORAGE_KEYS.tasks, tasks);
|
||||
|
||||
+8
-6
@@ -2,6 +2,7 @@ import { DEFAULT_SORT_ORDERS, HIDEABLE_STATUSES, SORT_VALUES, STATUSES } from '.
|
||||
import { normalizeSortOrders, normalizeTask, normalizeTasks } from './task-model.js';
|
||||
import { generateUniqueId } from './utils.js';
|
||||
import {
|
||||
isInitialized,
|
||||
loadShowHiddenData,
|
||||
loadSortOrdersData,
|
||||
loadTasksData,
|
||||
@@ -16,15 +17,16 @@ let sortOrders = { ...DEFAULT_SORT_ORDERS };
|
||||
let showHidden = Object.fromEntries(HIDEABLE_STATUSES.map((status) => [status, false]));
|
||||
let corrupted = false;
|
||||
const persistTasks = () => saveTasksData(tasks);
|
||||
export function initializeStore(seedTasks, initialized) {
|
||||
export function initializeStore() {
|
||||
const loaded = loadTasksData();
|
||||
corrupted = loaded.corrupted;
|
||||
tasks = normalizeTasks(loaded.tasks);
|
||||
if (loaded.exists && !loaded.corrupted) persistTasks();
|
||||
if (!initialized && !loaded.exists) {
|
||||
tasks = normalizeTasks(seedTasks);
|
||||
persistTasks();
|
||||
markInitialized();
|
||||
if (loaded.available && !loaded.corrupted) {
|
||||
// normalizeTask 以 { ...input } 展开、保留原 key 顺序,故本应用写入的数据可用字符串
|
||||
// 相等判断“无需回写”;未归一化的旧版数据必然不等,会被归一化后回写。
|
||||
const unchanged = loaded.exists && loaded.raw === JSON.stringify(tasks);
|
||||
const writeOk = unchanged || persistTasks();
|
||||
if (!isInitialized() && (loaded.exists || writeOk)) markInitialized();
|
||||
}
|
||||
sortOrders = { ...DEFAULT_SORT_ORDERS, ...normalizeSortOrders(loadSortOrdersData()) };
|
||||
showHidden = Object.fromEntries(
|
||||
|
||||
Reference in New Issue
Block a user