Skip to content

Commit 2b9a73e

Browse files
committed
fix: 修复相册及资源关联表同步问题
1 parent 6fc1751 commit 2b9a73e

File tree

5 files changed

+74
-24
lines changed

5 files changed

+74
-24
lines changed

app/composables/repositories/useAssetTagRepository.ts

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -77,45 +77,70 @@ export function useAssetTagRepository() {
7777
)
7878
}, '删除相册失败')
7979

80-
// 获取标签下的资源
80+
// 获取标签下的资源(支持 UUID 和 ID 关联)
8181
const getAssetsByTag = (tagId: number) =>
8282
runAsync(() => select<Asset[]>(
83-
`SELECT a.*
83+
`SELECT DISTINCT a.*
8484
FROM assets a
85-
JOIN asset_tag_relations r ON a.id = r.asset_id
86-
WHERE r.tag_id = ? AND a.deleted_at IS NULL AND r.deleted_at IS NULL
85+
LEFT JOIN asset_tag_relations r ON (
86+
(r.asset_uuid IS NOT NULL AND a.uuid = r.asset_uuid) OR
87+
(r.asset_uuid IS NULL AND a.id = r.asset_id)
88+
)
89+
WHERE r.tag_id = ?
90+
AND a.deleted_at IS NULL
91+
AND r.deleted_at IS NULL
8792
ORDER BY r.created_at DESC`,
8893
[tagId],
8994
), '获取相册资源失败')
9095

91-
// 将资源添加到标签
96+
// 将资源添加到标签(使用 UUID 支持跨设备同步)
9297
const addAssetsToTag = (assetIds: number[], tagId: number) =>
9398
runAsync(async () => {
9499
const now = new Date().toISOString()
95100
const version = -Date.now()
96101

97-
// 批量插入或忽略(如果已存在)
98-
// SQLite 不支持一次性插入多个 VALUES 且带 WHERE NOT EXISTS 这种复杂逻辑简单写
99-
// 这里用循环处理,虽然不是极致性能,但对于相册操作足够了
102+
// 1. 获取相册的 UUID
103+
const tagResult = await select<Array<{ uuid: string }>>(
104+
'SELECT uuid FROM asset_tags WHERE id = ?',
105+
[tagId],
106+
)
107+
const tagUuid = tagResult[0]?.uuid
108+
if (!tagUuid) {
109+
throw new Error('相册不存在')
110+
}
111+
100112
for (const assetId of assetIds) {
101-
const uuid = generateUUID()
102-
// 使用 INSERT OR IGNORE 避免重复关联
113+
// 2. 获取资源的 UUID,如果没有则创建一个
114+
let assetResult = await select<Array<{ uuid: string | null }>>(
115+
'SELECT uuid FROM assets WHERE id = ?',
116+
[assetId],
117+
)
118+
let assetUuid = assetResult[0]?.uuid
119+
120+
// 如果旧资源没有 UUID,自动生成一个
121+
if (!assetUuid || assetUuid.trim() === '') {
122+
assetUuid = generateUUID()
123+
await execute(
124+
'UPDATE assets SET uuid = ?, updated_at = ?, version = ? WHERE id = ?',
125+
[assetUuid, now, version, assetId],
126+
)
127+
}
128+
129+
// 3. 创建关联记录(同时保存 ID 和 UUID)
130+
const relationUuid = generateUUID()
103131
await execute(
104132
`INSERT OR IGNORE INTO asset_tag_relations
105-
(uuid, asset_id, tag_id, version, updated_at)
106-
VALUES (?, ?, ?, ?, ?)`,
107-
[uuid, assetId, tagId, version, now],
133+
(uuid, asset_id, tag_id, asset_uuid, tag_uuid, version, updated_at)
134+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
135+
[relationUuid, assetId, tagId, assetUuid, tagUuid, version, now],
108136
)
109137

110-
// 如果是软删除过的记录,需要恢复
111-
// 这里简化处理:先尝试插入,如果没插入(因为唯一约束),则尝试更新 deleted_at = NULL
112-
// 但由于 UNIQUE(asset_id, tag_id) 约束,INSERT OR IGNORE 会忽略冲突
113-
// 所以我们需要额外检查是否需要"复活"关系
138+
// 4. 如果是软删除过的记录,需要恢复
114139
await execute(
115140
`UPDATE asset_tag_relations
116-
SET deleted_at = NULL, version = ?, updated_at = ?
117-
WHERE asset_id = ? AND tag_id = ? AND deleted_at IS NOT NULL`,
118-
[version, now, assetId, tagId],
141+
SET deleted_at = NULL, asset_uuid = ?, tag_uuid = ?, version = ?, updated_at = ?
142+
WHERE asset_id = ? AND tag_id = ? AND deleted_at IS NOT NULL`,
143+
[assetUuid, tagUuid, version, now, assetId, tagId],
119144
)
120145
}
121146
}, '添加资源到相册失败')

app/config/sync-tables.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export const SYNC_TABLES: Record<string, SyncableTable> = {
6464
asset_tag_relations: {
6565
name: 'asset_tag_relations',
6666
primaryKey: 'uuid',
67-
fields: ['uuid', 'asset_id', 'tag_id', 'created_at', 'updated_at', 'deleted_at', 'version'],
67+
fields: ['uuid', 'asset_uuid', 'tag_uuid', 'created_at', 'updated_at', 'deleted_at', 'version'],
6868
jsonFields: [],
6969
hasVersion: true,
7070
hasSoftDelete: true,

app/pages/write/article/[id].vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,9 @@ const checkWxDraftWorkflow = async () => {
191191
const extractImageUrls = (markdown: string): string[] => {
192192
const urls: string[] = []
193193
194-
// 匹配 ![alt](url) 格式
195-
const markdownImageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g
194+
// 匹配 ![alt](url) 或 ![alt](url "title") 格式
195+
// 只抓取 URL 部分,忽略可选的 title 描述
196+
const markdownImageRegex = /!\[([^\]]*)\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g
196197
let match = markdownImageRegex.exec(markdown)
197198
while (match !== null) {
198199
if (match[2]) {

src-tauri/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,30 @@ pub fn run() {
919919
",
920920
kind: MigrationKind::Up,
921921
},
922+
Migration {
923+
version: 8,
924+
description: "Add UUID fields to asset_tag_relations for cross-device sync",
925+
sql: "
926+
-- 添加 UUID 字段用于跨设备同步
927+
ALTER TABLE asset_tag_relations ADD COLUMN asset_uuid TEXT;
928+
ALTER TABLE asset_tag_relations ADD COLUMN tag_uuid TEXT;
929+
930+
-- 为 UUID 字段创建索引
931+
CREATE INDEX IF NOT EXISTS idx_asset_tag_relations_asset_uuid ON asset_tag_relations(asset_uuid);
932+
CREATE INDEX IF NOT EXISTS idx_asset_tag_relations_tag_uuid ON asset_tag_relations(tag_uuid);
933+
934+
-- 为现有数据填充 UUID(从 assets 和 asset_tags 表关联获取)
935+
UPDATE asset_tag_relations
936+
SET asset_uuid = (
937+
SELECT uuid FROM assets WHERE assets.id = asset_tag_relations.asset_id
938+
),
939+
tag_uuid = (
940+
SELECT uuid FROM asset_tags WHERE asset_tags.id = asset_tag_relations.tag_id
941+
)
942+
WHERE asset_uuid IS NULL OR tag_uuid IS NULL;
943+
",
944+
kind: MigrationKind::Up,
945+
},
922946
],
923947
)
924948
.build(),

src-tauri/src/sync_engine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub const SYNC_TABLES: &[TableConfig] = &[
5959
TableConfig {
6060
name: "asset_tag_relations",
6161
primary_key: "uuid",
62-
fields: &["uuid", "asset_id", "tag_id", "created_at", "updated_at", "deleted_at", "version"],
62+
fields: &["uuid", "asset_uuid", "tag_uuid", "created_at", "updated_at", "deleted_at", "version"],
6363
json_fields: &[],
6464
},
6565
TableConfig {

0 commit comments

Comments
 (0)