| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // 任务数据访问层
- //
- // 替代之前的 src/mocks/tasks.ts,所有数据落 SQLite(@tauri-apps/plugin-sql)。
- // 数据库名与 src-tauri/src/lib.rs 中的 migration 一致:sqlite:autorecord.db
- //
- // 表结构(migration v1):
- // id TEXT PRIMARY KEY -- uuid 缩短到 12 位
- // url TEXT NOT NULL
- // status INT NOT NULL DEFAULT 0 -- 0=待处理, 1=已完成
- // "desc" TEXT NOT NULL DEFAULT '' -- DESC 是 SQLite 关键字,列名要带引号
- import Database from "@tauri-apps/plugin-sql";
- const DB_URI = "sqlite:autorecord.db";
- /** 任务行结构(与 SQLite 表一一对应) */
- export interface Task {
- /** 任务唯一标识(uuid 截短 12 位) */
- id: string;
- /** 目标网页 url */
- url: string;
- /** 0=待处理(出现在主列表),1=已完成(隐藏) */
- status: number;
- /** 备注(当前导入流程统一留空,后续可补) */
- desc: string;
- }
- let _dbPromise: Promise<Database> | null = null;
- /** 单例:第一次调用时打开 DB,后续复用同一个连接 */
- function getDb(): Promise<Database> {
- if (!_dbPromise) {
- _dbPromise = Database.load(DB_URI);
- }
- return _dbPromise;
- }
- /** 生成 12 位的短 uuid(去掉连字符后取前 12 位) */
- export function genTaskId(): string {
- // crypto.randomUUID 在所有现代 WebView2/WKWebView 上都可用
- return crypto.randomUUID().replace(/-/g, "").slice(0, 12);
- }
- /** 列出所有 status=0 的待处理任务,按 rowid 升序(= 插入顺序) */
- export async function listPendingTasks(): Promise<Task[]> {
- const db = await getDb();
- return await db.select<Task[]>(
- 'SELECT id, url, status, "desc" FROM tasks WHERE status = 0 ORDER BY rowid ASC',
- );
- }
- /** 统计 status=0 的任务数量,供「空表 → 拉起导入窗口」判断 */
- export async function countPendingTasks(): Promise<number> {
- const db = await getDb();
- const rows = await db.select<{ n: number }[]>(
- "SELECT COUNT(*) AS n FROM tasks WHERE status = 0",
- );
- return rows[0]?.n ?? 0;
- }
- /**
- * 批量插入 url(desc 全部留空)。
- * - 自动去除空白行
- * - 自动去除 url 两端空白
- * - id 用 12 位短 uuid
- * 返回实际插入的条数。
- */
- export async function insertTasksFromUrls(rawUrls: string[]): Promise<number> {
- const urls = rawUrls.map((s) => s.trim()).filter((s) => s.length > 0);
- if (urls.length === 0) return 0;
- const db = await getDb();
- // plugin-sql 不直接暴露事务,循环 execute 即可。批量量不大,性能足够。
- for (const url of urls) {
- await db.execute(
- 'INSERT INTO tasks (id, url, status, "desc") VALUES ($1, $2, 0, \'\')',
- [genTaskId(), url],
- );
- }
- return urls.length;
- }
- /** 把指定任务标记为完成(status=1),不再出现在主列表 */
- export async function markTaskDone(id: string): Promise<void> {
- const db = await getDb();
- await db.execute("UPDATE tasks SET status = 1 WHERE id = $1", [id]);
- }
|