export json

This commit is contained in:
Julian Freeman
2026-03-22 19:24:01 -04:00
parent b32d5ddbd3
commit facce53aba

View File

@@ -350,52 +350,37 @@ const isTagSelectOpen = ref(false);
const isExportModalOpen = ref(false); const isExportModalOpen = ref(false);
const exportStartDate = ref(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toLocaleDateString('sv')); const exportStartDate = ref(new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toLocaleDateString('sv'));
const exportEndDate = ref(currentDate.value); const exportEndDate = ref(currentDate.value);
const exportSelectedTags = ref<number[]>([]);
const toggleExportTag = (tagId: number) => {
if (exportSelectedTags.value.includes(tagId)) {
exportSelectedTags.value = exportSelectedTags.value.filter(id => id !== tagId);
} else {
exportSelectedTags.value.push(tagId);
}
};
const selectAllTags = () => {
exportSelectedTags.value = tags.value.map(t => t.id);
};
const openExportModal = () => { const openExportModal = () => {
exportEndDate.value = currentDate.value; exportEndDate.value = currentDate.value;
selectAllTags();
isExportModalOpen.value = true; isExportModalOpen.value = true;
}; };
const handleExport = async () => { const handleExport = async () => {
try { try {
const events: DBEvent[] = await invoke("get_events_range", { startDate: exportStartDate.value, endDate: exportEndDate.value }); const events: DBEvent[] = await invoke("get_events_range", { startDate: exportStartDate.value, endDate: exportEndDate.value });
const filteredEvents = events.filter(e => exportSelectedTags.value.includes(e.main_tag_id) || (e.sub_tag_id && exportSelectedTags.value.includes(e.sub_tag_id)));
if (filteredEvents.length === 0) { if (events.length === 0) {
showToast("所选范围内没有找到匹配的记录", "error"); showToast("所选范围内没有找到记录", "error");
return; return;
} }
const savePath = await save({ const savePath = await save({
filters: [{ name: "CSV 逗号分隔值文件", extensions: ["csv"] }], filters: [{ name: "JSON 文件", extensions: ["json"] }],
defaultPath: `ChronoSnap_Export_${exportStartDate.value}_${exportEndDate.value}.csv` defaultPath: `ChronoSnap_Export_${exportStartDate.value}_${exportEndDate.value}.json`
}); });
if (savePath) { if (savePath) {
let csvContent = "日期,开始时间,结束时间,主标签,副标签,事件内容\n"; const exportData = events.map(e => ({
for (const e of filteredEvents) { date: e.date,
const start = logicalMinutesToTime(e.start_minute); start_time: logicalMinutesToTime(e.start_minute),
const end = logicalMinutesToTime(e.end_minute); end_time: logicalMinutesToTime(e.end_minute),
const mainTag = getTagName(e.main_tag_id); main_tag: getTagName(e.main_tag_id),
const subTag = getTagName(e.sub_tag_id); sub_tag: getTagName(e.sub_tag_id),
const content = `"${e.content.replace(/"/g, '""')}"`; content: e.content
csvContent += `${e.date},${start},${end},${mainTag},${subTag},${content}\n`; }));
}
await writeTextFile(savePath, "\uFEFF" + csvContent); await writeTextFile(savePath, JSON.stringify(exportData, null, 2));
isExportModalOpen.value = false; isExportModalOpen.value = false;
showToast("导出成功"); showToast("导出成功");
} }
@@ -628,17 +613,8 @@ const handleExport = async () => {
<input type="date" v-model="exportEndDate" class="flex-1 bg-[#F2F2F7] rounded-xl px-4 py-2.5 text-sm outline-none border border-transparent focus:border-[#007AFF] transition-all" /> <input type="date" v-model="exportEndDate" class="flex-1 bg-[#F2F2F7] rounded-xl px-4 py-2.5 text-sm outline-none border border-transparent focus:border-[#007AFF] transition-all" />
</div> </div>
</div> </div>
<div class="space-y-2">
<div class="flex justify-between items-end">
<label class="text-[10px] font-bold text-[#86868B]">包含的标签</label>
<button @click="selectAllTags" class="text-[10px] font-bold text-[#007AFF] hover:underline">全选</button>
</div>
<div class="flex flex-wrap gap-2 max-h-40 overflow-y-auto p-1 no-scrollbar">
<button v-for="tag in tags" :key="tag.id" @click="toggleExportTag(tag.id)" class="px-3 py-1.5 rounded-lg text-[10px] font-medium border-2 transition-all" :style="{ backgroundColor: exportSelectedTags.includes(tag.id) ? tag.color : 'transparent', borderColor: tag.color, color: exportSelectedTags.includes(tag.id) ? 'white' : tag.color }">{{ tag.name }}</button>
</div>
</div>
</div> </div>
<button @click="handleExport" :disabled="!exportStartDate || !exportEndDate || exportSelectedTags.length === 0" class="w-full bg-[#007AFF] text-white py-4 rounded-2xl font-bold shadow-lg shadow-[#007AFF]/20 active:scale-95 transition-all disabled:opacity-50 disabled:active:scale-100">导出为 CSV</button> <button @click="handleExport" :disabled="!exportStartDate || !exportEndDate" class="w-full bg-[#007AFF] text-white py-4 rounded-2xl font-bold shadow-lg shadow-[#007AFF]/20 active:scale-95 transition-all disabled:opacity-50 disabled:active:scale-100">导出为 JSON</button>
</div> </div>
</div> </div>
</div> </div>