浏览代码

refact: 数据库重构

kindring 3 月之前
父节点
当前提交
c9b49fb1a9

+ 2 - 1
src/apis/ApiAction.ts

@@ -8,5 +8,6 @@ export enum Magnet_Actions {
 export enum Music_Actions {
   play_list_fetch = 'play_list_fetch',
   scan_music_select = 'scan_music_select',
-  scan_music_add = 'scan_music_add'
+  scan_music_add = 'scan_music_add',
+  scan_settings = 'scan_settings',
 }

+ 26 - 15
src/common/db/db.ts

@@ -3,39 +3,50 @@ import fs from "fs-extra";
 import path from "path";
 import os from "os";
 
-let dbInstance: Knex | null = null;
-if (!dbInstance) {
-    // let dbPath = process.env.APPDATA || (process.platform == "darwin" ? process.env.HOME + "/Library/Preferences" : process.env.HOME + "/.local/share");
+// 用于存放所有的db文件
+export const dbFiles: { [key: string]: Knex} = {
+
+}
+
+function createDbFile (dbFileName: string): string {
     let userPath = path.join(os.homedir(), '/fc-ele/');
-    // dbPath = path.join(dbPath, "fc-ele/db.db");
-    userPath = path.join(userPath, "fc-ele/db.db");
-    console.log(userPath);
+    userPath = path.join(userPath, `fc-ele/${dbFileName}`);
     let dbIsExist = fs.existsSync(userPath);
     if (!dbIsExist) {
-        let resourceDbPath = path.join(process.execPath, "../resources/db.db");
+        let resourceDbPath = path.join(process.execPath, `../resources/${dbFileName}`);
         // 判断初始文件是否存在
         let resourceDbIsExist = fs.existsSync(resourceDbPath);
         if (!resourceDbIsExist) {
             console.log("base db not find");
             fs.ensureFile(resourceDbPath);
             // 创建初始文件
-            dbInstance = knex({
+            let dbInstance = knex({
                 client: "better-sqlite3",
                 connection: { filename: resourceDbPath },
                 useNullAsDefault: true,
             });
+            // 关闭数据库连接
+            dbInstance.destroy();
         }
         // 复制初始文件到用户目录
-        fs.copy(resourceDbPath, userPath).catch((err) => {
-            console.log(err);
-        });
+        fs.copySync(resourceDbPath, userPath)
     }
-    // 连接数据库
+    return userPath;
+}
+
+export function loadDb (dbFileName: string) : Knex | null
+{
+    let dbInstance: Knex | null = dbFiles[dbFileName];
+    if (dbInstance)
+    {
+        return dbInstance;
+    }
+    let dbPath = createDbFile(dbFileName);
     dbInstance = knex({
         client: "better-sqlite3",
-        connection: { filename: userPath },
+        connection: { filename: dbPath },
         useNullAsDefault: true,
     });
+    dbFiles[dbFileName] = dbInstance;
+    return dbInstance;
 }
-
-export let db = dbInstance;

+ 291 - 0
src/common/db/db_music.ts

@@ -0,0 +1,291 @@
+import Logger from "@/util/logger.ts";
+import { loadDb} from "@/common/db/db.ts";
+import {handle, PromiseResult} from "@/util/promiseHandle.ts";
+import {AppDbName} from "@/types/appConfig.ts";
+import {Knex} from "knex";
+import {MusicScanSetting, MusicTableName} from "@/types/musicType.ts";
+
+let logger = Logger.logger('music_db', 'info');
+
+async function _initScanConfigTable(db : Knex): PromiseResult<boolean> {
+    let [err, hasTable] = await handle(
+        db.schema.hasTable(MusicTableName.music_scan_setting)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[音频扫描库] ${err.message}`)
+        return [new Error('音频扫描库初始化失败'), false]
+    }
+    if (hasTable) {
+        return [null, true];
+    }
+    let [createErr, _res] = await handle(db?.schema.createTable('scanConfig', (table) => {
+        // 初始化扫描配置
+        logger.error(`[初始化音频扫描库]`)
+        table.string('name')
+        table.string('path')
+        table.boolean('scanSubDir')
+        table.boolean('isFileRepeat')
+    }))
+    if (createErr) {
+        createErr = createErr as Error;
+        logger.error(`[初始化磁贴表失败] ${createErr.message}`)
+        return [createErr, false];
+    }
+    logger.info('[初始化音频扫描配置成功]')
+    return [null, true];
+}
+
+async function _initPlayListTable(db : Knex): PromiseResult<boolean> {
+    let [err, hasTable] = await handle(
+        db.schema.hasTable(MusicTableName.music_scan_setting)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[歌单初始化] ${err.message}`)
+        return [new Error('歌单初始化'), false]
+    }
+    if (hasTable) {
+        return [null, true];
+    }
+    let [createErr, _res] = await handle(
+        db.schema.createTable(MusicTableName.music_play_list, (table) => {
+            logger.error(`[初始化音频播放列表库]`)
+            table.increments('id').primary()
+            table.string('name')
+            table.string('icon')
+            table.string('cover')
+            table.string('description')
+            table.integer('playCount')
+            table.integer('trackCount')
+            table.integer('createTime')
+            table.boolean('isTagSearch')
+            table.integer('lastPlayTime')
+            table.boolean('isSync')
+            table.boolean('isPublic')
+            table.boolean('isLike')
+        }))
+    if (createErr) {
+        createErr = createErr as Error;
+        logger.error(`[初始化歌单失败] ${createErr.message}`)
+        return [createErr, false];
+    }
+    // 添加默认歌单
+    await db.insert({
+        name: '我的喜爱',
+        icon: 'favorite',
+        cover: 'favorite',
+        description: '我的喜爱',
+        playCount: 0,
+        trackCount: 0,
+        createTime: Date.now(),
+        isTagSearch: false,
+        lastPlayTime: Date.now(),
+        isSync: false,
+        isPublic: false,
+        isLike: true,
+    }).into(MusicTableName.music_play_list)
+    logger.info('[初始化我的喜爱歌单成功]')
+
+    return [null, true];
+}
+
+async function _initSongsTable(db : Knex): PromiseResult<boolean>
+{
+    let [err, hasTable] = await handle(
+        db.schema.hasTable(MusicTableName.music_songs)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[音频表初始化] ${err.message}`)
+        return [new Error('音频表初始化'), false]
+    }
+    if (hasTable) {
+        return [null, true];
+    }
+    let [createErr, _res] = await handle(
+        db.schema.createTable(MusicTableName.music_songs, (table) => {
+            logger.error(`[初始化音频库]`)
+            table.increments('id').primary()
+            table.string('name')
+            table.string('artists')
+            table.string('album')
+            table.string('cover')
+            table.integer('duration')
+            table.boolean('isLike')
+            table.string('origin')
+            table.integer('type')
+            table.boolean('isLocal')
+            table.string('filePath')
+            table.string('lyricPath')
+            table.string('tags')
+            table.integer('playCount')
+        }))
+    if (createErr) {
+        createErr = createErr as Error;
+        logger.error(`[初始化音频库失败] ${createErr.message}`)
+        return [createErr, false];
+    }
+    logger.info('[初始化音频库成功]')
+    return [null, true];
+}
+
+async function _initPlaylistSongs(db : Knex): PromiseResult<boolean>
+{
+    let [err, hasTable] = await handle(
+        db.schema.hasTable(MusicTableName.music_play_list_songs)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[歌单歌曲表初始化] ${err.message}`)
+        return [new Error('歌单歌曲表初始化'), false]
+    }
+    if (hasTable) {
+        return [null, true];
+    }
+    let [createErr, _res] = await handle(
+        db.schema.createTable(MusicTableName.music_play_list_songs, (table) => {
+            logger.error(`[初始化歌单歌曲库]`)
+            table.increments('id').primary()
+            table.integer('musicId')
+            table.integer('playListId')
+            table.integer('order')
+        }))
+    if (createErr) {
+        createErr = createErr as Error;
+        logger.error(`[初始化歌单歌曲库失败] ${createErr.message}`)
+        return [createErr, false];
+    }
+    logger.info('[初始化歌单歌曲库成功]')
+    return [null, true];
+}
+
+
+export async function initMusicData() : PromiseResult<boolean>
+{
+    let db = loadDb(AppDbName.music_db)
+    if(!db){
+        logger.error('数据库初始化失败')
+        return [new Error('音乐数据库初始化失败'), false]
+    }
+    let [err, res] = await _initScanConfigTable(db);
+    if (err) {
+        err = err as Error;
+        logger.error(`[初始化扫描库失败] ${err.message}`)
+        return [err, false];
+    }
+    [err, res] = await _initPlayListTable(db);
+    if (err) {
+        err = err as Error;
+        logger.error(`[初始化播放列表库失败] ${err.message}`)
+        return [err, false];
+    }
+    [err, res] = await _initSongsTable(db);
+    if (err) {
+        err = err as Error;
+        logger.error(`[初始化音频库失败] ${err.message}`)
+        return [err, false];
+    }
+    [err, res] = await _initPlaylistSongs(db);
+    if (err) {
+        err = err as Error;
+        logger.error(`[初始化歌单歌曲库失败] ${err.message}`)
+        return [err, false];
+    }
+
+
+    logger.info('[初始化音频库成功]')
+    return [null, res]
+}
+
+
+
+// 根据扫描地址获取扫描配置
+export async function getScanConfigByPath(path: string) : PromiseResult<MusicScanSetting[]>
+{
+    let db = loadDb(AppDbName.music_db)
+    if(!db){
+        logger.error('数据库初始化失败')
+        return [new Error('音乐数据库初始化失败'), null]
+    }
+    let [err, res] = await handle(
+        db.select('name', 'path', 'scanSubDir', 'isFileRepeat')
+            .from(MusicTableName.music_scan_setting)
+            .where('path', path)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[获取扫描配置失败] ${err.message}`)
+        return [err, null];
+    }
+    return [null, res as MusicScanSetting[]];
+}
+
+export async function getScanConfig() : PromiseResult<MusicScanSetting[]>
+{
+    let db = loadDb(AppDbName.music_db)
+    if(!db){
+        logger.error('数据库初始化失败')
+        return [new Error('音乐数据库初始化失败'), null]
+    }
+    let [err, res] = await handle(
+        db.select('name', 'path', 'scanSubDir', 'isFileRepeat')
+            .from(MusicTableName.music_scan_setting)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[获取扫描配置失败] ${err.message}`)
+        return [err, null];
+    }
+    return [null, res as MusicScanSetting[]];
+}
+
+export async function addScanConfig(scanConfig: MusicScanSetting) : PromiseResult<boolean>
+{
+    let db = loadDb(AppDbName.music_db)
+    if(!db){
+        logger.error('数据库初始化失败')
+        return [new Error('音乐数据库初始化失败'), false]
+    }
+    let [err, _res] = await handle(
+        db.insert(scanConfig).into(MusicTableName.music_scan_setting)
+    )
+    if (err) {
+        err = err as Error;
+        logger.error(`[添加扫描配置失败] ${err.message}`)
+        return [err, false];
+    }
+    return [null, true];
+}
+
+export async function updateScanConfig(scanConfig: MusicScanSetting) : PromiseResult<boolean>
+{
+    let db = loadDb(AppDbName.music_db)
+    if(!db){
+        logger.error('数据库初始化失败')
+        return [new Error('音乐数据库初始化失败'), false]
+    }
+    let [err, _res] = await handle(
+        db.update(scanConfig).into(MusicTableName.music_scan_setting)
+    )
+    if (err) {
+        err = err as Error;
+    }
+    return [err, true];
+}
+
+export async function deleteScanConfig(path: string) : PromiseResult<boolean>
+{
+    let db = loadDb(AppDbName.music_db)
+    if(!db){
+        logger.error('数据库初始化失败')
+        return [new Error('音乐数据库初始化失败'), false]
+    }
+    let [err, _res] = await handle(
+        db.delete().from(MusicTableName.music_scan_setting).where('path', path)
+    )
+    if (err) {
+        err= err as Error;
+    }
+    return [err, true];
+}

+ 53 - 18
src/common/db/magnetDb.ts

@@ -1,23 +1,25 @@
-import {db} from "./db.ts"
+import {loadDb} from "./db.ts"
 import {SavedMagnet} from "@/types/magnetType.ts";
 import Logger from "@/util/logger.ts";
-import {handle} from "@/util/promiseHandle.ts";
+import {handle, PromiseResult} from "@/util/promiseHandle.ts";
+import {AppDbName} from "@/types/appConfig.ts";
 let logger = Logger.logger('magnet_db', 'info');
-export async function initMagnetData() {
+export async function initMagnetData() : Promise<[Error | null, boolean]> {
     console.log('初始化磁贴数据库')
+    let db = loadDb(AppDbName.magnet_db)
     // 1. 判断数据表是否存在
     if(!db){
         logger.error('数据库初始化失败')
-        throw new Error('数据库初始化失败')
+        return [new Error('数据库初始化失败'),false];
     }
     let [err, hasTable] =  await handle(db.schema.hasTable('magnets'))
     if (err) {
         err = err as Error;
         logger.error(`[数据库初始化失败] ${err.message}`)
-        throw new Error('数据库初始化失败')
+        return [err, false];
     }
     if (hasTable) {
-        return false;
+        return [null, false];
     }
     let [createErr, _res] =  await handle(db?.schema.createTable('magnets', (table) => {
         logger.error(`[初始化磁贴表]`)
@@ -26,20 +28,22 @@ export async function initMagnetData() {
         table.integer('y')
         table.string('type')
         table.string('size')
+
     }))
     if (createErr) {
         createErr = createErr as Error;
         logger.error(`[初始化磁贴表失败] ${createErr.message}`)
-        throw new Error('数据库初始化失败')
+        return [createErr, false];
     }
     logger.info('[初始化磁贴表成功]')
-    return true;
+    return [null, true];
 }
 initMagnetData()
 
 
 
 export function findMagnetById(id: string) {
+    let db = loadDb(AppDbName.magnet_db)
     return db?.select(
         'id',
         'x',
@@ -49,19 +53,34 @@ export function findMagnetById(id: string) {
     ).from('magnets').where('id', id)
 }
 
-export function getMagnetList(): Promise<SavedMagnet[]> {
-    return db?.select(
+export async function getMagnetList(): Promise<[Error | null, SavedMagnet[]]> {
+    let db = loadDb(AppDbName.magnet_db)
+    if (!db) {
+        return [new Error('数据库初始化失败'), []];
+    }
+    let [err, savedMagnet] = await handle(db?.select(
         'id',
         'x',
         'y',
         'type',
         'size'
-    ).from('magnets')
+    ).from('magnets'))
+    if (err) {
+        err = err as Error;
+        logger.error(`[获取磁贴列表失败] ${err.message}`)
+        return [err, []];
+    }
+    return [err, savedMagnet as SavedMagnet[]];
 }
 
 // 批量更改
-export function changeMagnets(magnetList: SavedMagnet[]) {
-    return db?.transaction(async (trx) => {
+export async function changeMagnets(magnetList: SavedMagnet[]): PromiseResult<boolean> {
+    let db = loadDb(AppDbName.magnet_db)
+    if (!db) {
+        return [new Error('数据库初始化失败'), false];
+    }
+    let transaction = await db.transaction(async (trx) => {
+        let flag = true
         for (const magnet of magnetList) {
             let changeMagnet = {
                 id: magnet.id,
@@ -72,11 +91,20 @@ export function changeMagnets(magnetList: SavedMagnet[]) {
             }
             await trx('magnets').where('id', changeMagnet.id).update(changeMagnet)
         }
+        return flag;
     })
+
+
+
+    return [null, transaction]
 }
 
 // 新增数据
-export  function addMagnet(magnet: SavedMagnet) {
+export async function addMagnet(magnet: SavedMagnet) : PromiseResult<boolean> {
+    let db = loadDb(AppDbName.magnet_db)
+    if (!db) {
+        return [new Error('数据库初始化失败'), false];
+    }
     // id 字段移除
     let addMagnet = {
         size: magnet.size,
@@ -84,14 +112,21 @@ export  function addMagnet(magnet: SavedMagnet) {
         x: magnet.x,
         y: magnet.y,
     }
-    return db?.insert(addMagnet).into('magnets')
+    db.insert(addMagnet).into('magnets')
+    return [null, true]
 
 }
 
 // 删除数据
-export  function db_deleteMagnet(magnetId: string) {
-    console.log(`删除磁贴: ${magnetId}`)
-    return db?.delete().from('magnets').where('id', magnetId)
+export async function db_deleteMagnet(magnetId: string): PromiseResult<boolean> {
+    // console.log(`删除磁贴: ${magnetId}`)
+    let db = loadDb(AppDbName.magnet_db)
+    if (!db) {
+        return [new Error('数据库初始化失败'), false];
+    }
+    logger.info(`删除磁贴: ${magnetId}`)
+    db?.delete().from('magnets').where('id', magnetId)
+    return [null, true]
 }
 
 

+ 3 - 3
src/components/music/dialog/addScan.vue

@@ -2,7 +2,7 @@
 import {defineComponent, ref} from "vue";
 import KuiInput from "@/components/public/kui/kui-input.vue";
 import message from "@/components/public/kui/message";
-import {selectScanDir} from "@/apis/musicControl.ts";
+import {addScanDir, selectScanDir} from "@/apis/musicControl.ts";
 import KuiCheckbox from "@/components/public/kui/kui-checkbox.vue";
 import {MusicScanSetting} from "@/types/musicType.ts";
 
@@ -39,7 +39,7 @@ async function selectPathHandle() {
 async function submitHandle() {
   let param: MusicScanSetting = {
     name: name.value,
-    dirPath: dirPath.value,
+    path: dirPath.value,
     scanSubDir: scanSubDir.value,
     isFileRepeat: isFileRepeat.value
   }
@@ -50,7 +50,7 @@ async function submitHandle() {
   }
   if (!param.name)
   {
-    param.name = param.dirPath;
+    param.name = param.path;
   }
   let responseData = await addScanDir(param);
   if (responseData.code === 0) {

+ 12 - 3
src/main/control/api_router.ts

@@ -1,9 +1,9 @@
 import {ApiType, ErrorCode, RequestData, ResponseData} from "@/types/apiTypes.ts";
 import {Magnet_Actions, Music_Actions} from "@/apis/ApiAction.ts";
 import {c_fetchMagnetList, c_magnet_batch_update, c_magnet_delete} from "@/main/control/magnet/magnet.ts";
-import {c_fetchPlayList, c_scanMusicSelect} from "@/main/control/magnet/music.ts";
+import {c_fetchPlayList, c_scanMusicAdd, c_scanMusicSelect, c_scanSettings} from "@/main/control/magnet/music.ts";
 
-export async function apiRouter(requestData: RequestData){
+export async function apiRouter(requestData: RequestData<any>){
     // 生成callId
     let responseData: ResponseData<any>
     switch (requestData.action)
@@ -18,11 +18,20 @@ export async function apiRouter(requestData: RequestData){
             responseData = await c_magnet_delete(requestData);
             break;
         case Music_Actions.play_list_fetch:
-            responseData = await c_fetchPlayList();
+            responseData = await c_fetchPlayList(requestData);
             break;
         case Music_Actions.scan_music_select:
             responseData = await c_scanMusicSelect(requestData);
             break;
+        case Music_Actions.scan_music_add:
+            responseData = await c_scanMusicSelect(requestData);
+            break;
+        case Music_Actions.scan_settings:
+            responseData = await c_scanSettings(requestData);
+            break;
+        case Music_Actions.scan_music_add:
+            responseData = await c_scanMusicAdd(requestData);
+            break;
         default:
             responseData = {
                 type: ApiType.res,

+ 5 - 5
src/main/control/magnet/magnet.ts

@@ -6,7 +6,7 @@ import Logger from "@/util/logger.ts";
 
 let logger = Logger.logger('magnet_control', 'info');
 
-export async function c_fetchMagnetList(requestData: RequestData){
+export async function c_fetchMagnetList(requestData: RequestData<null>){
     let [err, result] = await handle(getMagnetList());
     let responseData: ResponseData<any>
     if (err) {
@@ -34,10 +34,10 @@ export async function c_fetchMagnetList(requestData: RequestData){
 }
 
 
-export async function c_magnet_batch_update(requestData: RequestData){
+export async function c_magnet_batch_update(requestData: RequestData<ChangeSaveMagnet[]>){
     let responseData: ResponseData<any>
     // 区分出新增的项和原本就有的项
-    let saveMagnets: ChangeSaveMagnet[] = requestData.data as ChangeSaveMagnet[];
+    let saveMagnets: ChangeSaveMagnet[] = requestData.data ;
     // 分类
     let addMagnets: SavedMagnet[] = []
     let updateMagnets: SavedMagnet[] = []
@@ -84,9 +84,9 @@ export async function c_magnet_batch_update(requestData: RequestData){
 }
 
 
-export async function c_magnet_delete(requestData: RequestData){
+export async function c_magnet_delete(requestData: RequestData<{magnetId: string}>){
     let responseData: ResponseData<any>
-    let data = requestData.data as {magnetId: string};
+    let data = requestData.data;
     if (!data.magnetId) {
         responseData = {
             type: ApiType.res,

+ 45 - 13
src/main/control/magnet/music.ts

@@ -1,9 +1,15 @@
 import {dialog} from "electron"
 import {ApiType, ErrorCode, RequestData, ResponseData} from "@/types/apiTypes.ts";
 import Logger from "@/util/logger.ts";
+import {MusicScanSetting} from "@/types/musicType.ts";
+import {addScanConfig, getScanConfig, getScanConfigByPath} from "@/common/db/db_music.ts";
+import {ResType} from "@/util/promiseHandle.ts";
+import {t_gen_res, t_res_ok} from "@/main/tools/ipcRouter.ts";
 let logger = Logger.logger('music', 'info');
 
-export async function c_fetchPlayList(requestData: RequestData)
+
+
+export async function c_fetchPlayList(requestData: RequestData<null>)
 {
     let responseData: ResponseData<any>
     responseData = {
@@ -14,32 +20,58 @@ export async function c_fetchPlayList(requestData: RequestData)
         msg: '暂无歌单',
         data: [],
     }
+
     return responseData;
 }
 
 
-export async function c_scanMusicSelect(requestData: RequestData): Promise<ResponseData<string>>
+export async function c_scanMusicSelect(requestData: RequestData<string>): Promise<ResponseData<string>>
 {
     let defaultPath = requestData.data;
-    let responseData: ResponseData<any>
     logger.info(`select scan dir`);
     let result = await dialog.showOpenDialog({
         defaultPath: defaultPath,
         properties: ['openDirectory'],
-        multiSelections: false,
         title: '请选择扫描目录'
     })
-    console.log(result)
     logger.info(`scan dir ${result.filePaths[0]}`);
 
-    responseData = {
-        type: ApiType.res,
-        code: ErrorCode.success,
-        callId: requestData.callId,
-        action: requestData.action,
-        msg: '',
-        data: result.filePaths[0],
-    }
+    return t_res_ok(requestData, result.filePaths[0]);
+}
+
 
+// 获取扫描设置列表
+export async function c_scanSettings(requestData: RequestData<null>) : Promise<ResponseData<MusicScanSetting[]>>
+{
+    let responseData: ResponseData<any>
+    let [err, scanSettingList] = await getScanConfig();
+    if (err) {
+        logger.error(`[获取扫描设置列表失败] ${err.message}`)
+        return t_gen_res(requestData, ErrorCode.db, '获取扫描设置列表失败', [])
+    }
+    responseData = t_gen_res(requestData, ErrorCode.success, '', scanSettingList)
     return responseData;
 }
+export async function c_scanMusicAdd(requestData: RequestData<MusicScanSetting>) : Promise<ResponseData<boolean>>
+{
+    let scanSetting: MusicScanSetting = requestData.data;
+    let res: ResType<any> = false;
+    // 判断路径是否重复
+    let [err, scanSettingList] = await getScanConfigByPath(scanSetting.path)
+    if (err) {
+        logger.error(`[获取扫描设置列表失败] ${err.message}`)
+        return t_gen_res(requestData, ErrorCode.db, '获取扫描设置列表失败', false);
+    }
+    scanSettingList = scanSettingList as MusicScanSetting[];
+    if (scanSettingList.length> 0) {
+        logger.error(`[扫描路径重复] ${scanSetting.path}`)
+        return t_gen_res(requestData, ErrorCode.params, '扫描路径重复', false);
+    }
+    [err, res] = await addScanConfig(scanSetting);
+    if (err) {
+        logger.error(`[添加扫描设置失败] ${err.message}`)
+        return t_gen_res(requestData, ErrorCode.db, '添加扫描设置失败', false)
+    }
+    res = res as boolean;
+    return t_res_ok(requestData,  res)
+}

+ 20 - 2
src/main/tools/ipcRouter.ts

@@ -1,5 +1,5 @@
 import {apiRouter} from "@/main/control/api_router.ts";
-import {NotifyData, RequestData, ResponseData} from "@/types/apiTypes.ts";
+import {ApiType, ErrorCode, NotifyData, RequestData, ResponseData} from "@/types/apiTypes.ts";
 import AppControl from "@/main/AppControl.ts";
 import Logger from "@/util/logger.ts";
 import {actionMap} from "@/tools/IpcCmd.ts";
@@ -44,7 +44,7 @@ const sendToMain = sendDataByType.bind(null, 'main')
  * 处理窗口发来的api请求
  * @param requestData
  */
-export async function ipcRouter(requestData: RequestData): Promise<boolean>
+export async function ipcRouter(requestData: RequestData<any>): Promise<boolean>
 {
     let signId = requestData.signId;
     let responseData: ResponseData<any> = await apiRouter(requestData)
@@ -57,3 +57,21 @@ export async function ipcRouter(requestData: RequestData): Promise<boolean>
     }
 }
 
+export function t_gen_res(requestData: RequestData<any>, code: number, msg: string, data: any): ResponseData<any>
+{
+    let responseData: ResponseData<any> = {
+        type: ApiType.res,
+        code: code,
+        callId: requestData.callId,
+        action: requestData.action,
+        msg: msg,
+        data: data
+    }
+    return responseData;
+}
+
+export function t_res_ok(requestData: RequestData<any>, data: any): ResponseData<any>
+{
+    return t_gen_res(requestData, ErrorCode.success, '', data);
+}
+

+ 2 - 2
src/types/apiTypes.ts

@@ -25,14 +25,14 @@ export enum ApiType {
 
 
 // 请求参数
-export interface RequestData
+export interface RequestData<T>
 {
     type: ApiType.req;
     signId: string;
     callId: string;
     // 请求的具体操作
     action: string;
-    data: any;
+    data: T;
     // 超时时间, 单位毫秒
     timeout: number;
 }

+ 8 - 0
src/types/appConfig.ts

@@ -67,3 +67,11 @@ export interface registerWindowData {
     type: string;
 }
 
+
+export enum AppDbName
+{
+    magnet_db = 'magnet.db',
+    music_db = 'music.db',
+}
+
+

+ 16 - 1
src/types/musicType.ts

@@ -11,7 +11,7 @@ export interface PlayList {
     lastPlayTime: number;  // 上次播放时间 时间戳
     isSync: boolean; // 是否参与跨设备同步
     isPublic: boolean; // 是否公开
-    isLike: boolean; // 是否为默认收藏歌单
+    isLike: boolean; // 是否为默认收藏歌单, 默认歌单不允许编辑信息
 }
 
 export enum MusicType{
@@ -35,6 +35,13 @@ export interface MusicInfo {
     tags: string[]; // 歌曲标签
     playCount: number;  // 播放次数
 }
+// 歌单音频信息
+export interface PlayListMusicInfo {
+    id: string;
+    musicId: string;
+    playListId: string;
+    order: number;
+}
 
 
 export interface MusicSearchInfo {
@@ -51,3 +58,11 @@ export interface MusicScanSetting {
 }
 
 
+export enum MusicTableName
+{
+    music_play_list = 'music_play_list',// 歌单表
+    music_scan_setting = 'music_scan_setting',// 扫描配置
+    music_songs = 'music_songs',// 歌曲表
+    music_play_list_songs = 'music_play_list_songs',// 歌单歌曲表
+}
+

+ 2 - 1
src/util/promiseHandle.ts

@@ -1,4 +1,5 @@
-export type handleResult<T> = [Error | null | any, T | null | undefined]
+export type ResType<T> = T | null | undefined
+export type handleResult<T> = [Error | null | any, ResType<T>]
 export type PromiseResult<T> = Promise<handleResult<T>>
 export function handle<T>(promise: Promise<T>): PromiseResult<T> {
     return new Promise<[Error | T | null , T | null | undefined]>(resolve => {