feat(mp, web, calendar): 新增微信收藏夹与日历批量生成功能
- 新增微信小程序版个人收藏夹全套功能,包含聚合首页、收藏列表、编辑、详情页面与配套后端API - 新增web版时光助手门户与个人收藏夹工具,支持与小程序共享后端数据 - 优化日历提醒工具:替换本地bootstrap资源为公共CDN版本,新增批量生成循环提醒的前端界面与后端逻辑,新增数据库batch_id字段,更新鉴权配置文件 - 补充项目配置、站点地图、调试诊断脚本等配套文件 - 完善各模块的页面配置与样式文件
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
const Database = require('better-sqlite3')
|
||||
const path = require('path')
|
||||
const { bindRoutes: bindPersonalCollectRoutes } = require('./kits/personal_collect')
|
||||
|
||||
const CORE_DB_PATH = path.join(process.cwd(), 'data', 'mp_time_assistant_core.db')
|
||||
|
||||
let db = null
|
||||
|
||||
const KIT_META = [
|
||||
{
|
||||
id: 'personal_collect',
|
||||
name: '微信收藏夹',
|
||||
description: '聊天图片、文件收藏管理,标签搜索,软删除可追溯。',
|
||||
},
|
||||
]
|
||||
|
||||
const nowIso = () => new Date().toISOString()
|
||||
|
||||
const getDb = () => {
|
||||
if (db) return db
|
||||
db = new Database(CORE_DB_PATH)
|
||||
db.pragma('journal_mode = WAL')
|
||||
db.exec(`CREATE TABLE IF NOT EXISTS core_state (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
active_kit TEXT,
|
||||
updated_at TEXT NOT NULL
|
||||
);`)
|
||||
db.prepare(`
|
||||
INSERT OR IGNORE INTO core_state (id, active_kit, updated_at)
|
||||
VALUES (1, NULL, ?)
|
||||
`).run(nowIso())
|
||||
return db
|
||||
}
|
||||
|
||||
const getStateRow = () => {
|
||||
const row = getDb().prepare(`SELECT * FROM core_state WHERE id = 1 LIMIT 1`).get()
|
||||
if (!row) {
|
||||
getDb().prepare(`
|
||||
INSERT INTO core_state (id, active_kit, updated_at)
|
||||
VALUES (1, NULL, ?)
|
||||
`).run(nowIso())
|
||||
return getStateRow()
|
||||
}
|
||||
return row
|
||||
}
|
||||
|
||||
const setActiveKit = kitId => {
|
||||
getDb().prepare(`UPDATE core_state SET active_kit = ?, updated_at = ? WHERE id = 1`).run(kitId || null, nowIso())
|
||||
}
|
||||
|
||||
const serializeState = () => {
|
||||
const row = getStateRow()
|
||||
return {
|
||||
ok: true,
|
||||
activeKit: row.active_kit || null,
|
||||
}
|
||||
}
|
||||
|
||||
const bindRoutes = app => {
|
||||
getDb()
|
||||
|
||||
app.get('/api/mp_time_assistant/meta', (req, res) => {
|
||||
res.json({
|
||||
ok: true,
|
||||
appName: 'MpTimeAssistant',
|
||||
appNameZh: 'MilesYang时光助手',
|
||||
kits: KIT_META,
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/api/mp_time_assistant/state', (req, res) => {
|
||||
res.json(serializeState())
|
||||
})
|
||||
|
||||
app.put('/api/mp_time_assistant/state/active-kit', (req, res) => {
|
||||
try {
|
||||
const raw = String(req.body && req.body.kitId || '').trim()
|
||||
const nextKit = raw || null
|
||||
if (nextKit && !KIT_META.find(item => item.id === nextKit)) {
|
||||
return res.status(400).json({ ok: false, error: 'unknown kit id' })
|
||||
}
|
||||
setActiveKit(nextKit)
|
||||
return res.json({ ok: true, activeKit: nextKit })
|
||||
} catch (e) {
|
||||
return res.status(500).json({ ok: false, error: String(e.message || e) })
|
||||
}
|
||||
})
|
||||
|
||||
bindPersonalCollectRoutes(app)
|
||||
}
|
||||
|
||||
module.exports = { bindRoutes }
|
||||
Reference in New Issue
Block a user