Private
Public Access
1
0

新增:Markdown编辑器/数据库优化/安全修复

- Markdown 编辑器:实时预览、PDF 导出、独立查看器
- 数据库优化:动态连接池、查询缓存、Redis Pipeline
- 窗口置顶功能
- 文件系统增强:右键菜单、编辑器集成、收藏夹重构
- 安全修复:XSS 防护、路径穿越、HTML 注入
- 代码质量:正则预编译、缓存锁优化、死代码清理
This commit is contained in:
2026-03-31 09:18:06 +08:00
parent 5f94ccf13b
commit e5dbe89a6f
59 changed files with 5289 additions and 1316 deletions

View File

@@ -66,8 +66,8 @@ export function useFavoriteFiles(storageKey, options = {}) {
return
}
favoriteFiles.value.sort((a, b) => {
const timeA = a.created_at || 0
const timeB = b.created_at || 0
const timeA = a.addedAt || 0
const timeB = b.addedAt || 0
return timeB - timeA // 倒序:最新的在上面
})
}
@@ -106,8 +106,8 @@ export function useFavoriteFiles(storageKey, options = {}) {
favoriteFiles.value.push({
path: item.path,
name: item.name,
is_dir: item.is_dir || false,
created_at: Date.now(), // 添加时间戳(用于 getSortedFavorites
isDir: item.isDir || false,
addedAt: Date.now(),
})
save(favoriteFiles.value) // 直接保存,不重新排序(新项目添加到末尾)
@@ -201,8 +201,8 @@ export function useFavoriteFiles(storageKey, options = {}) {
const getSortedFavorites = (order = 'desc') => {
const sorted = [...favoriteFiles.value]
sorted.sort((a, b) => {
const timeA = a.created_at || 0
const timeB = b.created_at || 0
const timeA = a.addedAt || 0
const timeB = b.addedAt || 0
return order === 'desc' ? timeB - timeA : timeA - timeB
})
return sorted
@@ -255,9 +255,27 @@ export function useFavoriteFiles(storageKey, options = {}) {
return true
}
// 组件挂载时加载数据(不自动排序,保持用户拖拽的顺序
// 旧字段名 → 新字段名迁移(一次性,迁移后自动回写
const migrateFieldNames = (list) => {
if (!Array.isArray(list)) return
const map = { is_dir: 'isDir', created_at: 'addedAt' }
let changed = false
list.forEach(item => {
for (const [old, newKey] of Object.entries(map)) {
if (old in item) {
if (!(newKey in item)) item[newKey] = item[old]
delete item[old]
changed = true
}
}
})
if (changed) save(list)
}
// 组件挂载时加载数据并迁移旧字段
onMounted(() => {
load()
migrateFieldNames(favoriteFiles.value)
})
return {

View File

@@ -1,34 +0,0 @@
/**
* LocalStorage composable
* 通用的 localStorage 操作
*/
import { watch, type Ref } from 'vue'
export function useLocalStorage<T>(
key: string,
defaultValue: T,
storage: Storage = localStorage
): [Ref<T>, (value: T) => void, () => void] {
const stored = storage.getItem(key)
const value = ref<T>(stored ? JSON.parse(stored) : defaultValue)
const setValue = (newValue: T) => {
value.value = newValue
}
const clearValue = () => {
value.value = defaultValue
storage.removeItem(key)
}
watch(value, (newValue) => {
try {
storage.setItem(key, JSON.stringify(newValue))
} catch (e) {
console.warn(`Failed to save ${key} to localStorage:`, e)
}
}, { deep: true })
return [value, setValue, clearValue]
}