Skip to content

Commit 017b3ea

Browse files
committed
重构为使用 Dexie 管理数据库
1 parent 94a9ac5 commit 017b3ea

File tree

13 files changed

+1285
-762
lines changed

13 files changed

+1285
-762
lines changed

apps/InfoFlow/components/RuleExecutionRecords.vue

Lines changed: 422 additions & 284 deletions
Large diffs are not rendered by default.

apps/InfoFlow/components/RulesManagement.vue

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,25 @@
7777
:rows="pageSize"
7878
:totalRecords="totalRecords"
7979
:rowsPerPageOptions="[10, 20, 50]"
80+
:lazy="true"
8081
@page="handlePageChange"
8182
responsiveLayout="scroll"
82-
stripedRows
8383
v-model:expandedRows="expandedRows"
84-
dataKey="id">
84+
dataKey="id"
85+
:rowStyle="getRowStyle">
8586
<Column :expander="true" headerStyle="width: 3rem" />
8687
<Column field="name" header="规则名称" class="min-w-[150px] whitespace-nowrap">
8788
<template #body="slotProps">
88-
<div>
89-
<div class="font-medium">{{ slotProps.data.name }}</div>
90-
<div class="text-sm text-gray-600">{{ slotProps.data.description }}</div>
89+
<div class="flex items-center gap-2">
90+
<div
91+
v-if="hasUnreadExecutions(slotProps.data.id)"
92+
class="w-2 h-2 rounded-full bg-blue-500"
93+
title="有未读的执行记录">
94+
</div>
95+
<div>
96+
<div class="font-medium">{{ slotProps.data.name }}</div>
97+
<div class="text-sm text-gray-600">{{ slotProps.data.description }}</div>
98+
</div>
9199
</div>
92100
</template>
93101
</Column>
@@ -518,6 +526,13 @@ return document.title;"
518526
return format(new Date(date), 'MM-dd HH:mm');
519527
};
520528
529+
// 检测规则是否有未读的执行记录
530+
const ruleUnreadStatus = ref<Record<string, boolean>>({});
531+
532+
const hasUnreadExecutions = (ruleId: string) => {
533+
return ruleUnreadStatus.value[ruleId] || false;
534+
};
535+
521536
// Methods
522537
const loadRules = async () => {
523538
loading.value = true;
@@ -533,6 +548,9 @@ return document.title;"
533548
534549
rules.value = result.rules;
535550
totalRecords.value = result.total;
551+
552+
// 检查每个规则的未读执行记录状态
553+
await checkRulesUnreadStatus();
536554
} finally {
537555
loading.value = false;
538556
}
@@ -546,12 +564,52 @@ return document.title;"
546564
}
547565
};
548566
567+
const checkRulesUnreadStatus = async () => {
568+
try {
569+
// 重置未读状态
570+
ruleUnreadStatus.value = {};
571+
572+
// 并行检查每个规则的未读状态
573+
const checkPromises = rules.value.map(async (rule: Rule) => {
574+
const hasUnread = await rulesManager.hasUnreadExecutions(rule.id);
575+
return { ruleId: rule.id, hasUnread };
576+
});
577+
578+
const results = await Promise.all(checkPromises);
579+
580+
// 设置未读状态
581+
for (const result of results) {
582+
ruleUnreadStatus.value[result.ruleId] = result.hasUnread;
583+
}
584+
} catch (error) {
585+
console.error('Failed to check rules unread status:', error);
586+
}
587+
};
588+
549589
const handlePageChange = (event: any) => {
550590
currentPage.value = event.page + 1;
551591
pageSize.value = event.rows;
552592
loadRules();
553593
};
554594
595+
const getRowStyle = (rule: Rule) => {
596+
const hasUnread = hasUnreadExecutions(rule.id);
597+
598+
if (hasUnread) {
599+
return {
600+
backgroundColor: '#ffffff',
601+
borderLeft: '3px solid #3b82f6',
602+
fontWeight: '500',
603+
cursor: 'pointer',
604+
};
605+
} else {
606+
return {
607+
backgroundColor: '#f8fafc',
608+
cursor: 'pointer',
609+
};
610+
}
611+
};
612+
555613
const handleSearch = () => {
556614
currentPage.value = 1;
557615
loadRules();
Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import { browser, defineBackground } from '#imports';
22
import { infoFlowGetMessenger } from '@/services/InfoFlowGet/messageProtocol';
33
import { runInfoFlowGet } from '@/services/InfoFlowGet/runInfoFlowGet';
4-
import { openExtensionDatabase, registerConfigsService } from '@/storage/indexdbAdapter';
5-
import { openInfoFlowRulesDatabase, registerRulesService } from '@/storage/rulesService';
4+
import { registerConfigsService } from '@/storage/indexdbAdapter';
5+
import { registerRulesService } from '@/storage/rulesService';
66
import {
7-
openInfoFlowTaskExecutionDatabase,
87
registerTaskExecutionService,
98
} from '@/storage/taskExecutionService';
109

@@ -15,12 +14,8 @@ export default defineBackground(() => {
1514
return runInfoFlowGet(msg.data);
1615
});
1716

18-
const db = openExtensionDatabase();
19-
registerConfigsService(db);
17+
registerConfigsService();
18+
registerRulesService();
2019

21-
const InfoFlowRulesDB = openInfoFlowRulesDatabase();
22-
registerRulesService(InfoFlowRulesDB);
23-
24-
const taskDB = openInfoFlowTaskExecutionDatabase();
25-
registerTaskExecutionService(taskDB);
20+
registerTaskExecutionService();
2621
});

apps/InfoFlow/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
"@webext-core/messaging": "^2.3.0",
2626
"@webext-core/proxy-service": "^1.2.1",
2727
"date-fns": "^4.1.0",
28+
"dexie": "^4.2.0",
2829
"fast-equals": "^5.2.2",
29-
"idb": "^8.0.3",
3030
"primeicons": "^7.0.0",
3131
"primevue": "^4.3.7",
3232
"superjson": "^2.2.2",
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import Dexie, { Table } from 'dexie';
2+
3+
// 定义配置项类型
4+
export interface ConfigItem {
5+
key: string;
6+
data: any;
7+
}
8+
9+
// 创建 Dexie 数据库
10+
class ConfigDatabase extends Dexie {
11+
configs!: Table<ConfigItem, string>;
12+
13+
constructor() {
14+
super('infoFlowConfigDB');
15+
16+
// 定义数据库架构 - Dexie 会自动处理版本和索引
17+
this.version(1).stores({
18+
configs: 'key, data'
19+
});
20+
}
21+
}
22+
23+
// 创建数据库实例
24+
const db = new ConfigDatabase();
25+
26+
// 配置服务
27+
export class ConfigService {
28+
// 获取所有配置
29+
async getAll(): Promise<ConfigItem[]> {
30+
return await db.configs.toArray();
31+
}
32+
33+
// 更新或插入配置
34+
async upsert(info: ConfigItem): Promise<void> {
35+
await db.configs.put(info);
36+
}
37+
38+
// 获取配置项
39+
async getItem(key: string): Promise<any> {
40+
const result = await db.configs.get(key);
41+
return result?.data;
42+
}
43+
44+
// 设置配置项
45+
async setItem(key: string, data: any): Promise<void> {
46+
await db.configs.put({ key, data });
47+
}
48+
49+
// 删除配置项
50+
async deleteItem(key: string): Promise<void> {
51+
await db.configs.delete(key);
52+
}
53+
54+
// 重置数据库
55+
async reset(): Promise<void> {
56+
await db.delete();
57+
await db.open();
58+
}
59+
}
60+
61+
// 创建服务实例
62+
export const configService = new ConfigService();

apps/InfoFlow/storage/indexdbAdapter.ts

Lines changed: 23 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,40 @@
1-
import { DBSchema, IDBPDatabase, openDB } from 'idb';
1+
import Dexie, { Table } from 'dexie';
22
import { defineProxyService } from '@webext-core/proxy-service';
33
import type { StorageAdapter, VersionedStorage } from './storageAdapter';
4-
interface ExtensionDatabaseSchema extends DBSchema {
5-
configs: {
6-
key: string;
7-
value: { data: any; key: string };
8-
};
4+
5+
interface ConfigItem {
6+
key: string;
7+
data: any;
98
}
109

11-
export type ExtensionDatabase = IDBPDatabase<ExtensionDatabaseSchema>;
10+
class ConfigDatabase extends Dexie {
11+
configs!: Table<ConfigItem, string>;
1212

13-
/**
14-
* 这里创建的数据可以在background 中运行,能够通过检查 popup 中的存储查看 indexdb 数据库。
15-
*/
16-
export function openExtensionDatabase(): Promise<ExtensionDatabase> {
17-
return openDB<ExtensionDatabaseSchema>('infoFlow', 3, {
18-
upgrade(database) {
19-
database.createObjectStore('configs', {
20-
/** 这里定义的key是插入和查询都需要的 */ keyPath: 'key',
21-
});
22-
},
23-
});
13+
constructor() {
14+
super('infoFlowConfigDB');
15+
16+
this.version(1).stores({
17+
configs: 'key, data'
18+
});
19+
}
2420
}
2521

26-
function createConfigsService(_db: Promise<ExtensionDatabase>) {
22+
const db = new ConfigDatabase();
23+
24+
function createConfigsService() {
2725
return {
2826
async getAll() {
29-
const db = await _db;
30-
return await db.getAll('configs');
27+
return await db.configs.toArray();
3128
},
32-
async upsert(info: ExtensionDatabaseSchema['configs']['value']) {
33-
const db = await _db;
34-
await db.put('configs', info);
29+
async upsert(info: ConfigItem) {
30+
await db.configs.put(info);
3531
},
3632
async getItem(key: string) {
37-
const db = await _db;
38-
return await db.get('configs', key);
33+
const result = await db.configs.get(key);
34+
return result?.data;
3935
},
4036
async setItem(key: string, data: any) {
41-
const db = await _db;
42-
return await db.put('configs', { key, data });
37+
await db.configs.put({ key, data });
4338
},
4439
};
4540
}

0 commit comments

Comments
 (0)