From ba143138d1c6983dbcd7d26dbcc2966383272ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B4=BE=E5=90=8C=E5=AD=A6?= Date: Fri, 24 Oct 2025 15:10:23 +0800 Subject: [PATCH] =?UTF-8?q?add:=E6=B7=BB=E5=8A=A0sqlite=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E6=BF=80=E6=B4=BB=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/config/config.default.ts | 8 +- electron/controller/activateRecord.ts | 26 ++ electron/jobs/example/timer.ts | 12 +- electron/preload/index.ts | 3 + electron/service/database/activateRecord.ts | 129 ++++++ electron/service/database/basedb.ts | 52 +++ frontend/src/api/index.ts | 10 +- frontend/src/assets/global.less | 1 - frontend/src/components/global/iconFont.ts | 22 -- frontend/src/components/global/index.ts | 7 +- frontend/src/layouts/AppSider.vue | 75 ++-- frontend/src/router/routerMap.ts | 12 +- frontend/src/views/activate/ActiveForm.vue | 299 ++++++++++++++ frontend/src/views/activate/index.vue | 411 +++++++++----------- package.json | 4 +- 15 files changed, 758 insertions(+), 313 deletions(-) create mode 100644 electron/controller/activateRecord.ts create mode 100644 electron/service/database/activateRecord.ts create mode 100644 electron/service/database/basedb.ts delete mode 100644 frontend/src/components/global/iconFont.ts create mode 100644 frontend/src/views/activate/ActiveForm.vue diff --git a/electron/config/config.default.ts b/electron/config/config.default.ts index 4988ab4..12bdf83 100644 --- a/electron/config/config.default.ts +++ b/electron/config/config.default.ts @@ -8,10 +8,10 @@ const config: () => AppConfig = () => { singleLock: true, windowsOption: { title: 'PQS9100工具箱', // 软件标题 - width: 980, // 软件窗口宽度 - height: 650, // 软件窗口高度 - minWidth: 800, // 软件窗口最小宽度 - minHeight: 650, // 软件窗口最小高度 + width: 1366, // 软件窗口宽度 + height: 768, // 软件窗口高度 + minWidth: 1366, // 软件窗口最小宽度 + minHeight: 768, // 软件窗口最小高度 autoHideMenuBar: true, // 默认不显示菜单栏, webPreferences: { webSecurity: true, diff --git a/electron/controller/activateRecord.ts b/electron/controller/activateRecord.ts new file mode 100644 index 0000000..8089f44 --- /dev/null +++ b/electron/controller/activateRecord.ts @@ -0,0 +1,26 @@ +import {activateRecordService} from "../service/database/activateRecord"; + +class ActivateRecordController { + + async list(args: { macAddress: string, modules: string[] }): Promise { + const {macAddress, modules} = args + return activateRecordService.list(macAddress, modules) + } + + async save(args: { + macAddress: string, + applicationCode: string, + modules: string[], + activationCode: string, + createTime: string, + remark: string + }): Promise { + const { modules} = args + return activateRecordService.save({...args, module : modules.join(',')}) + } + +} + +ActivateRecordController.toString = () => '[class ActivateRecordController]'; + +export default ActivateRecordController; diff --git a/electron/jobs/example/timer.ts b/electron/jobs/example/timer.ts index 0a12c8d..f34c9b9 100644 --- a/electron/jobs/example/timer.ts +++ b/electron/jobs/example/timer.ts @@ -1,9 +1,9 @@ -import { logger } from 'ee-core/log'; -import { isChildJob, exit } from 'ee-core/ps'; -import { childMessage } from 'ee-core/message'; -import { welcome } from './hello'; -import { UserService } from '../../service/job/user'; -import { sqlitedbService } from '../../service/database/sqlitedb'; +import {logger} from 'ee-core/log'; +import {exit, isChildJob} from 'ee-core/ps'; +import {childMessage} from 'ee-core/message'; +import {welcome} from './hello'; +import {UserService} from '../../service/job/user'; +import {sqlitedbService} from '../../service/database/activateRecord'; /** * example - TimerJob diff --git a/electron/preload/index.ts b/electron/preload/index.ts index 9b9bf54..6b46d58 100644 --- a/electron/preload/index.ts +++ b/electron/preload/index.ts @@ -6,6 +6,7 @@ import {logger} from 'ee-core/log'; import {trayService} from '../service/os/tray'; import {securityService} from '../service/os/security'; import {autoUpdaterService} from '../service/os/auto_updater'; +import {activateRecordService} from '../service/database/activateRecord'; function preload(): void { // Example feature module, optional to use and modify @@ -13,6 +14,8 @@ function preload(): void { trayService.create(); securityService.create(); autoUpdaterService.create(); + + activateRecordService.init(); } /** diff --git a/electron/service/database/activateRecord.ts b/electron/service/database/activateRecord.ts new file mode 100644 index 0000000..341dee0 --- /dev/null +++ b/electron/service/database/activateRecord.ts @@ -0,0 +1,129 @@ +import {BasedbService} from './basedb'; + +/** + * sqlite数据存储 + * @class + */ +class ActivateRecordService extends BasedbService { + tableName: string; + + constructor() { + const options = { + dbname: 'pqs9100-tool.db', + } + super(options); + this.tableName = 'activate_record'; + } + + /* + * 初始化表 + */ + init(): void { + this._init(); + + // 检查表是否存在 + const masterStmt = this.db.prepare('SELECT * FROM sqlite_master WHERE type=? AND name = ?'); + let tableExists = masterStmt.get('table', this.tableName); + if (!tableExists) { + // 创建表 + const create_table_sql = + `CREATE TABLE ${this.tableName} + ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + macAddress CHAR(50) NOT NULL, + applicationCode CHAR(2000) NOT NULL, + module CHAR(200) NOT NULL, + activationCode CHAR(2000) NOT NULL, + createTime CHAR(32) NOT NULL, + remark CHAR(120) NULL + );` + this.db.exec(create_table_sql); + } + } + + /* + * 增 data (sqlite) + */ + async save(data: { + macAddress: string; + applicationCode: string; + module: string; + activationCode: string; + createTime: string; + remark: string; + }) { + const insert = this.db.prepare(`INSERT INTO ${this.tableName} (macAddress, applicationCode, module, activationCode, createTime, remark) + VALUES (@macAddress, @applicationCode, @module, @activationCode, @createTime, @remark)`); + insert.run(data); + return true; + } + + /* + * 删 data + */ + async removeById(name: string = ''): Promise { + const remove = this.db.prepare(`DELETE + FROM ${this.tableName} + WHERE id = ?`); + remove.run(name); + return true; + } + + /* + * 查list data (sqlite) + */ + async list(macAddress: string = '', modules: string[] = []): Promise { + let condition = '' + if (macAddress) { + condition += ` AND macAddress = '${macAddress}'` + } + if (modules.length > 0) { + const moduleConditions = modules.map(module => `module LIKE '%${module}%'`).join(' OR '); + condition += ` AND (${moduleConditions})`; + } + const select = this.db.prepare(`SELECT * + FROM ${this.tableName} + WHERE 1 = 1 ${condition} + order by id desc`); + return select.all(); + } + + /* + * all Test data (sqlite) + */ + async getAllTestDataSqlite(): Promise { + const selectAllUser = this.db.prepare(`SELECT * + FROM ${this.tableName} `); + const allUser = selectAllUser.all(); + return allUser; + } + + /* + * get data dir (sqlite) + */ + async getDataDir(): Promise { + const dir = this.storage.getDbDir(); + return dir; + } + + /* + * set custom data dir (sqlite) + */ + async setCustomDataDir(dir: string): Promise { + if (dir.length == 0) { + return; + } + + this.changeDataDir(dir); + this.init(); + return; + } +} + +ActivateRecordService.toString = () => '[class ActivateRecordService]'; +const activateRecordService = new ActivateRecordService(); + +export { + ActivateRecordService, + activateRecordService +}; diff --git a/electron/service/database/basedb.ts b/electron/service/database/basedb.ts new file mode 100644 index 0000000..bc515a6 --- /dev/null +++ b/electron/service/database/basedb.ts @@ -0,0 +1,52 @@ +import {type Database, SqliteStorage} from 'ee-core/storage'; +import {getDataDir} from 'ee-core/ps'; +import path from 'path'; + +/** + * sqlite数据存储 + * @class + */ +class BasedbService { + dbname: string; + db!: Database; + storage!: SqliteStorage; + + constructor(options: { dbname: string }) { + const { dbname } = options; + this.dbname = dbname; + + } + + /* + * 初始化 + */ + protected _init(): void { + // 定义数据文件 + const dbFile = path.join(getDataDir(), "db", this.dbname); + const sqliteOptions = { + timeout: 6000, + verbose: console.log + } + this.storage = new SqliteStorage(dbFile, sqliteOptions); + this.db = this.storage.db; + } + + /* + * change data dir (sqlite) + */ + changeDataDir(dir: string): void { + // the absolute path of the db file + const dbFile = path.join(dir, this.dbname); + const sqliteOptions = { + timeout: 6000, + verbose: console.log + } + this.storage = new SqliteStorage(dbFile, sqliteOptions); + this.db = this.storage.db; + } +} +BasedbService.toString = () => '[class BasedbService]'; + +export { + BasedbService, +} \ No newline at end of file diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index a395175..1c3c315 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -1,12 +1,12 @@ - /** * Definition of communication channel between main process and rendering process * format:controller/filename/method * Definition of communication channels between main process and rendering process */ const ipcApiRoute = { - example: { - test: 'controller/example/test', + activateRecord: { + list: 'controller/activateRecord/list', + save: 'controller/activateRecord/save', }, framework: { checkForUpdater: 'controller/framework/checkForUpdater', @@ -28,7 +28,7 @@ const ipcApiRoute = { createPoolNotice: 'controller/framework/createPoolNotice', someJobByPool: 'controller/framework/someJobByPool', hello: 'controller/framework/hello', - openSoftware: 'controller/framework/openSoftware', + openSoftware: 'controller/framework/openSoftware', }, // os @@ -78,7 +78,7 @@ const specialIpcRoute = { } export { - ipcApiRoute, + ipcApiRoute, specialIpcRoute } diff --git a/frontend/src/assets/global.less b/frontend/src/assets/global.less index c019968..a34544b 100644 --- a/frontend/src/assets/global.less +++ b/frontend/src/assets/global.less @@ -2,7 +2,6 @@ font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - text-align: center; color: #2c3e50; width: 100vw; height: 100vh; diff --git a/frontend/src/components/global/iconFont.ts b/frontend/src/components/global/iconFont.ts deleted file mode 100644 index 6c675dc..0000000 --- a/frontend/src/components/global/iconFont.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { createFromIconfontCN } from '@ant-design/icons-vue' -import { h, VNode } from 'vue' - -const IconFont = createFromIconfontCN({ - scriptUrl: 'https://at.alicdn.com/t/font_2456157_4ovzopz659q.js', - extraCommonProps: { - type: 'icon-fengche', - style: { - fontSize: '18px', - }, - }, -}) - -interface Props { - type?: string; -} - -const DynamicIconFont = (props: Props): VNode => { - return h(IconFont, { type: props.type || 'icon-fengche' }) -} - -export default DynamicIconFont diff --git a/frontend/src/components/global/index.ts b/frontend/src/components/global/index.ts index 3c7401f..1540960 100644 --- a/frontend/src/components/global/index.ts +++ b/frontend/src/components/global/index.ts @@ -1,5 +1,3 @@ -import iconFont from './iconFont'; - // Use import.meta.globEager to dynamically import all .vue files in the directory const modules: { [key: string]: { default: any } } = import.meta.glob('./*.vue', { eager: true }); @@ -12,8 +10,7 @@ Object.keys(modules).forEach(file => { // Combine the dynamically imported components with the iconFont component const globalComponents = { - ...map, - iconFont, + ...map }; -export default globalComponents; \ No newline at end of file +export default globalComponents; diff --git a/frontend/src/layouts/AppSider.vue b/frontend/src/layouts/AppSider.vue index 228a9e7..b775e4f 100644 --- a/frontend/src/layouts/AppSider.vue +++ b/frontend/src/layouts/AppSider.vue @@ -1,34 +1,34 @@ - diff --git a/frontend/src/router/routerMap.ts b/frontend/src/router/routerMap.ts index 30900bf..16659d9 100644 --- a/frontend/src/router/routerMap.ts +++ b/frontend/src/router/routerMap.ts @@ -1,9 +1,6 @@ -/** - * 基础路由 - * @type { *[] } - */ +import {RouteRecordRaw} from 'vue-router' -const constantRouterMap = [ +const routerMap: RouteRecordRaw[] = [ { path: '/', component: () => import('@/layouts/AppSider.vue'), @@ -11,11 +8,10 @@ const constantRouterMap = [ { path: '/activate', name: 'Activate', - component: () => import('@/views/activate/index.vue'), - props: { id: 'activate' } + component: () => import('@/views/activate/index.vue') } ] }, ] -export default constantRouterMap +export default routerMap diff --git a/frontend/src/views/activate/ActiveForm.vue b/frontend/src/views/activate/ActiveForm.vue new file mode 100644 index 0000000..179e3d7 --- /dev/null +++ b/frontend/src/views/activate/ActiveForm.vue @@ -0,0 +1,299 @@ + + + diff --git a/frontend/src/views/activate/index.vue b/frontend/src/views/activate/index.vue index 9342f14..8fa49be 100644 --- a/frontend/src/views/activate/index.vue +++ b/frontend/src/views/activate/index.vue @@ -1,221 +1,203 @@ + diff --git a/package.json b/package.json index ff2c29a..59b8a2d 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "build-electron": "ee-bin build --cmds=electron", "encrypt": "ee-bin encrypt", "icon": "ee-bin icon", + "re-sqlite": "electron-rebuild -f -w better-sqlite3", "build-w": "ee-bin build --cmds=win64", "build-we": "ee-bin build --cmds=win_e", "build-m": "ee-bin build --cmds=mac", @@ -32,6 +33,7 @@ "author": "njcn", "devDependencies": { "@electron/rebuild": "^3.7.1", + "@types/better-sqlite3": "^7.6.12", "@types/node": "^20.16.0", "cross-env": "^7.0.3", "debug": "^4.4.0", @@ -42,7 +44,7 @@ "typescript": "^5.4.2" }, "dependencies": { - "axios": "^1.7.9", + "better-sqlite3": "^11.7.0", "dayjs": "^1.11.13", "ee-core": "^4.1.5", "electron-updater": "^6.3.8"