From 996ba6bd9d6e8e80e6d43ce567267573f9ef45be Mon Sep 17 00:00:00 2001 From: fm453 <1280880631@qq.com> Date: Tue, 17 Sep 2024 01:56:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E4=BB=B6=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E8=AF=BB=E5=86=99=E6=93=8D=E4=BD=9C=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E3=80=81sqlite=E6=95=B0=E6=8D=AE=E5=BA=93=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .electron-vite/preloads.ts | 2 + .electron-vite/rollup.config.ts | 10 +- .electron-vite/vite.config.mts | 14 +- CHANGELOG.md | 11 + env/DEL-env | 14 - env/DEL-env.development | 23 - env/DEL-env.production | 25 - env/DEL-env.test | 25 - env/dev.env | 7 +- env/prod.env | 13 +- package.json | 1 + src/main/db/index.ts | 34 ++ src/main/db/sqlite.db | Bin 0 -> 12288 bytes src/main/db/sqliteDb.ts | 78 +++ src/main/handle/dbHandle.ts | 16 + src/main/handle/fileHandle.ts | 25 + src/main/hook/dataFileHook.ts | 33 ++ src/main/index.ts | 1 + src/main/ipc.ts | 18 +- src/main/services/ipcMain.ts | 7 +- src/renderer/index.html | 4 +- src/renderer/main-geeker.ts | 4 +- src/renderer/main-multi-themes.ts | 6 +- src/renderer/main-notheme.ts | 2 +- src/renderer/main-single-theme.ts | 2 +- .../themes/geeker/api/modules/login.ts | 6 +- .../geeker/layouts/components/Main/index.vue | 12 +- .../themes/geeker/views/home/index.vue | 21 +- src/renderer/utils/ipcRenderer.ts | 2 +- src/renderer/views/LandingPage.vue | 29 +- yarn.lock | 515 +++++++++++++++++- 31 files changed, 804 insertions(+), 156 deletions(-) delete mode 100644 env/DEL-env delete mode 100644 env/DEL-env.development delete mode 100644 env/DEL-env.production delete mode 100644 env/DEL-env.test create mode 100644 src/main/db/index.ts create mode 100644 src/main/db/sqlite.db create mode 100644 src/main/db/sqliteDb.ts create mode 100644 src/main/handle/dbHandle.ts create mode 100644 src/main/handle/fileHandle.ts create mode 100644 src/main/hook/dataFileHook.ts diff --git a/.electron-vite/preloads.ts b/.electron-vite/preloads.ts index 274fc0c..7cd8bf0 100644 --- a/.electron-vite/preloads.ts +++ b/.electron-vite/preloads.ts @@ -14,6 +14,8 @@ export const preloads = { "path-browserify", "unocss", "node", + "md5", + "sqlite3", "element-plus/es/components/form/style/css", "element-plus/es/components/form-item/style/css", "element-plus/es/components/button/style/css", diff --git a/.electron-vite/rollup.config.ts b/.electron-vite/rollup.config.ts index 0561053..0a87fee 100644 --- a/.electron-vite/rollup.config.ts +++ b/.electron-vite/rollup.config.ts @@ -1,14 +1,15 @@ import path from "path"; -import { nodeResolve } from "@rollup/plugin-node-resolve"; -import { builtinModules } from "module"; +import {nodeResolve} from "@rollup/plugin-node-resolve"; +import {builtinModules} from "module"; import commonjs from "@rollup/plugin-commonjs"; import replace from "@rollup/plugin-replace"; import alias from "@rollup/plugin-alias"; import json from "@rollup/plugin-json"; import esbuild from "rollup-plugin-esbuild"; import obfuscator from "rollup-plugin-obfuscator"; -import { defineConfig } from "rollup"; -import { getConfig } from "./utils"; +import {defineConfig} from "rollup"; +import {getConfig} from "./utils"; + const config = getConfig(); export default (env = "production", type = "main") => { @@ -87,6 +88,7 @@ export default (env = "production", type = "main") => { "ref-struct-napi", "semver", "glob", + "sqlite3", ], }); }; diff --git a/.electron-vite/vite.config.mts b/.electron-vite/vite.config.mts index 162b5c7..a6db321 100644 --- a/.electron-vite/vite.config.mts +++ b/.electron-vite/vite.config.mts @@ -1,5 +1,5 @@ import {join} from "path"; -import {UserConfig, ConfigEnv, loadEnv, defineConfig} from "vite"; +import {defineConfig} from "vite"; import vuePlugin from "@vitejs/plugin-vue"; import vueJsx from "@vitejs/plugin-vue-jsx"; import viteIkarosTools from "./plugin/vite-ikaros-tools"; @@ -30,13 +30,13 @@ import UnoCSS from "unocss/vite"; * 需要预加载的资源 */ import {preloads} from "./preloads"; +import pkg from "../package.json"; function resolve(dir: string) { return join(__dirname, "..", dir); } const config = getConfig(); -import pkg from "../package.json"; /** 平台的名称、版本、运行所需的`node`版本、依赖、构建时间的类型提示 */ const __APP_INFO__ = { @@ -95,7 +95,7 @@ export default defineConfig({ javascriptEnabled: true, additionalData: ` @use "@themeDefault/styles/variables.scss" as *; - // @use "@themeGeeker/styles/var.scss" as *; + @use "@themeGeeker/styles/var.scss" as *; `, }, }, @@ -164,14 +164,6 @@ export default defineConfig({ symbolId: "icon-[dir]-[name]", }), - // node({ - // // 默认情况下,`node` 插件会重写 `process` 和全局变量。 - // // 如果你不想要这个行为,可以将 `mock` 设置为 `false`。 - // mock: true, - // - // // 如果你想要包括一些特定的Node.js全局变量,可以在 `additional` 中指定。 - // additional: ['process', 'fs', 'path'] - // }) ], optimizeDeps: preloads, }); diff --git a/CHANGELOG.md b/CHANGELOG.md index d0eb4a1..aa69062 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,18 @@ +# 2024.09.16 + +- 添加sqlite3使用,用法演示放在home/index页面 + +# 2024.09.15 + +- 增加文件读写功能,可用于动态数据保存。用法演示目前放在home/index页面内 + # 2024.09.14 - 新增一套主题geeker, - 优化了主题目录别名写法,减少让切换主题时需要修改的东西,现在只需要在index.html页面里修改主题名称指向即可。(修改缓存值) - 增加需要preload加载的具体内容,减少页面闪屏。 +- 演示echarts相关的需要调整一下样式,容易出现页面显示高度异常。 + - 解释:样式读取绑定了挂载元素ID(主入口页index.html中#app),如果修改了挂载ID的,就会异常。 + - 数据大屏亦是如此。 # 2024.09.07 diff --git a/env/DEL-env b/env/DEL-env deleted file mode 100644 index 6b945d5..0000000 --- a/env/DEL-env +++ /dev/null @@ -1,14 +0,0 @@ -# title -VITE_GLOB_APP_TITLE = Geeker Admin - -# 本地运行端口号 -VITE_PORT = 8848 - -# 启动时自动打开浏览器 -VITE_OPEN = true - -# 开启 devTools 调试 -VITE_DEVTOOLS = false - -# 打包后是否生成包分析文件 -VITE_REPORT = false diff --git a/env/DEL-env.development b/env/DEL-env.development deleted file mode 100644 index 6a08604..0000000 --- a/env/DEL-env.development +++ /dev/null @@ -1,23 +0,0 @@ -# 本地环境 -VITE_USER_NODE_ENV = development - -# 公共基础路径 -VITE_PUBLIC_PATH = / - -# 路由模式 -# Optional: hash | history -VITE_ROUTER_MODE = hash - -# 打包时是否删除 console -VITE_DROP_CONSOLE = true - -# 是否开启 VitePWA -VITE_PWA = false - -# 开发环境接口地址 -VITE_API_URL = /api - -# 开发环境跨域代理,支持配置多个 -VITE_PROXY = [["/api","https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e"]] -# VITE_PROXY = [["/api","https://www.fastmock.site/mock/f81e8333c1a9276214bcdbc170d9e0a0"]] -# VITE_PROXY = [["/api-easymock","https://mock.mengxuegu.com"],["/api-fastmock","https://www.fastmock.site"]] diff --git a/env/DEL-env.production b/env/DEL-env.production deleted file mode 100644 index 64f00b6..0000000 --- a/env/DEL-env.production +++ /dev/null @@ -1,25 +0,0 @@ -# 线上环境 -VITE_USER_NODE_ENV=production - -# 公共基础路径 -VITE_PUBLIC_PATH=/ - -# 路由模式 -# Optional: hash | history -VITE_ROUTER_MODE=hash - -# 是否启用 gzip 或 brotli 压缩打包,如果需要多个压缩规则,可以使用 “,” 分隔 -# Optional: gzip | brotli | none -VITE_BUILD_COMPRESS = none - -# 打包压缩后是否删除源文件 -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false - -# 打包时是否删除 console -VITE_DROP_CONSOLE = true - -# 是否开启 VitePWA -VITE_PWA = true - -# 线上环境接口地址 -VITE_API_URL="https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e" diff --git a/env/DEL-env.test b/env/DEL-env.test deleted file mode 100644 index 17dbebd..0000000 --- a/env/DEL-env.test +++ /dev/null @@ -1,25 +0,0 @@ -# 测试环境 -VITE_USER_NODE_ENV = test - -# 公共基础路径 -VITE_PUBLIC_PATH = / - -# 路由模式 -# Optional: hash | history -VITE_ROUTER_MODE = hash - -# 是否启用 gzip 或 brotli 压缩打包,如果需要多个压缩规则,可以使用 “,” 分隔 -# Optional: gzip | brotli | none -VITE_BUILD_COMPRESS = none - -# 打包压缩后是否删除源文件 -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false - -# 打包时是否删除 console -VITE_DROP_CONSOLE = true - -# 是否开启 VitePWA -VITE_PWA = false - -# 测试环境接口地址 -VITE_API_URL = "https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e" diff --git a/env/dev.env b/env/dev.env index 1ac0cb6..a25c02e 100644 --- a/env/dev.env +++ b/env/dev.env @@ -12,7 +12,7 @@ REMOTE_SERVER=false # 以下是配合geeker主题做的配置 # title -VITE_GLOB_APP_TITLE=Geeker Admin +VITE_GLOB_APP_TITLE=Hi-Sass-Frame # 本地环境 VITE_USER_NODE_ENV=development @@ -20,7 +20,7 @@ VITE_USER_NODE_ENV=development # 公共基础路径 VITE_PUBLIC_PATH=/ -# 路由模式 +# 路由模式(electron中只能用hash模式) # Optional: hash | history VITE_ROUTER_MODE=hash @@ -33,6 +33,3 @@ VITE_PWA=false # 开发环境接口地址 #VITE_API_URL=/api VITE_API_URL=https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e - -# 开发环境跨域代理,支持配置多个 -VITE_PROXY=[["/api","https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e"]] diff --git a/env/prod.env b/env/prod.env index 681b184..774eee7 100644 --- a/env/prod.env +++ b/env/prod.env @@ -11,28 +11,31 @@ REMOTE_API_URL='http://api.frame.sass.hiluker.cn' REMOTE_SERVER=false # 以下是配合geeker主题做的配置 +# title +VITE_GLOB_APP_TITLE=Hi-Sass-Frame + # 线上环境 VITE_USER_NODE_ENV=production # 公共基础路径 VITE_PUBLIC_PATH=/ -# 路由模式 +# 路由模式(electron中只能用hash模式) # Optional: hash | history VITE_ROUTER_MODE=hash # 是否启用 gzip 或 brotli 压缩打包,如果需要多个压缩规则,可以使用 “,” 分隔 # Optional: gzip | brotli | none -VITE_BUILD_COMPRESS = none +VITE_BUILD_COMPRESS=none # 打包压缩后是否删除源文件 -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false +VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE=false # 打包时是否删除 console -VITE_DROP_CONSOLE = true +VITE_DROP_CONSOLE=true # 是否开启 VitePWA -VITE_PWA = true +VITE_PWA=true # 线上环境接口地址 VITE_API_URL="https://mock.mengxuegu.com/mock/629d727e6163854a32e8307e" diff --git a/package.json b/package.json index 4b2ef9d..0d55779 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,7 @@ "semver": "^7.6.3", "sockjs-client": "^1.6.1", "sortablejs": "^1.15.3", + "sqlite3": "^5.1.7", "stompjs": "^2.3.3", "unocss": "^0.62.3", "uuid": "^10.0.0", diff --git a/src/main/db/index.ts b/src/main/db/index.ts new file mode 100644 index 0000000..377e96c --- /dev/null +++ b/src/main/db/index.ts @@ -0,0 +1,34 @@ +import {SqliteDb} from './sqliteDb'; + +const db = new SqliteDb(); + +export async function run(sql, params) { + try { + return await db.run(sql, params); + } catch (err) { + throw err; + } +} + +export async function checkTable(tableName: string) { + return await db.table_exists('lorem').then((exists) => { + return exists; + }) +} + +export function close() { + return db.close(); +} + +export default { + run, + checkTable, + close +} +// const db = new SqliteDb; +// db.table_exists('lorem').then((exists) => { +// console.log('数据表lorem检查存在:',exists); +// }); +// const sql = "SELECT name FROM sqlite_master WHERE type='table' AND name=?"; +// const params = ['testSqlite']; +// db.run(sql,params); diff --git a/src/main/db/sqlite.db b/src/main/db/sqlite.db new file mode 100644 index 0000000000000000000000000000000000000000..e6b1c2fa4bce918b4495d24258ae00b024319ce7 GIT binary patch literal 12288 zcmeI0PiPZC7{zBdHTqdQU;WoL)<2tCHC}9z-Td=pEei%(P?LjD5UL~)NQ`Y)Pl6{Y zdK5esJPIBKkA)r;j|Go{N5Nykqm!&JS+S)jFZP>ZH!m-5XV_m(Z)&&aTVca(c2_z} zq3fw}Wm)RF>nf$H=1Q0g!!}|BU(BZ!)4R#4y87hBnEBP_=ZZg>n+zc!1cZPP5CTF# z2nYcoAOwVf5D)_UmB5^xbkb?77B1ayH^RnhSX*wJRz6gTxjVsZJ#g!@H|7I(=)0NL z!)Dj52Y2gNd@JcVj#ce1((bM_I{lmd$D@5K{#37N5He}AMi`{ztKcjCd-sbQ8 zmACjKZ}5A5%j@PuV2z*hGBOSwfOq9QV=}{UoPcCGR&O>JR?Ef^0>@NMEP9flt0~zoCbP{g7|I=}}d-s20WaIsx#^B~@ j*#Bu1ZoK~!!7bAv$aw#!B;0uarxCc`&i$V(1hT&X#Y7s) literal 0 HcmV?d00001 diff --git a/src/main/db/sqliteDb.ts b/src/main/db/sqliteDb.ts new file mode 100644 index 0000000..4660a1b --- /dev/null +++ b/src/main/db/sqliteDb.ts @@ -0,0 +1,78 @@ +//sqlite相关操作 +import {app} from "electron"; +import path from "path"; +import {Database} from "sqlite3"; + +const dataPath = path.join(app.getPath('userData'), 'db'); +const dbPath = process.env.NODE_ENV === 'production' ? dataPath : 'src/main/db'; + +export class SqliteDb { + db; + + constructor() { + this.db = new Database(dbPath + "/sqlite.db"); + } + + /** + * 测试数据库,添加一张表、写入点内容 + */ + test() { + this.db.serialize(() => { + this.db.run("CREATE TABLE testSqlite (info TEXT)"); + + const stmt = this.db.prepare("INSERT INTO testSqlite VALUES (?)"); + for (let i = 0; i < 10; i++) { + stmt.run("Ipsum " + i); + } + stmt.finalize(); + + this.db.each("SELECT rowid AS id, info FROM testSqlite", (err: any, row: any) => { + console.log(row.id + ": " + row.info); + }); + }); + this.db.close(); + } + + /** + * 检查数据表是否存在 + */ + table_exists(tableName: string): Promise { + const sql = "SELECT name FROM sqlite_master WHERE type='table' AND name=?"; + const params = [tableName]; + let mydb = this.db; + return new Promise((resolve, reject) => { + mydb.get(sql, params, (err: any, row: any) => { + console.log('查表执行结果:', err, row) + if (err) { + reject(err); + resolve(false); + } else { + resolve(true); + } + }) + }) + } + + /** + * 执行sql,异步执行的 + */ + async run(sql: string, params: string[]) { + let promise = new Promise((resolve, reject) => { + this.db.get(sql, params, (err: any, row: any) => { + console.log('SQL语句执行结果:', err, row) + if (err) reject(err); + resolve(row); + }); + }); + let res = await promise; + // console.log(res); + return res; + } + + /** + * 关闭数据库 + */ + close() { + this.db.close(); + } +} diff --git a/src/main/handle/dbHandle.ts b/src/main/handle/dbHandle.ts new file mode 100644 index 0000000..74ffe6c --- /dev/null +++ b/src/main/handle/dbHandle.ts @@ -0,0 +1,16 @@ +import mydb from '../db'; +import {IpcChannel} from "../ipc"; + +export function useDbHandle() { + return { + [IpcChannel.SqlRun]: async (event, args) => { + let sql = args.sql, params = args.params || []; + try { + return await mydb.run(sql, params); + } catch (error) { + console.error(error); + return false; + } + }, + } +} diff --git a/src/main/handle/fileHandle.ts b/src/main/handle/fileHandle.ts new file mode 100644 index 0000000..59d8c8e --- /dev/null +++ b/src/main/handle/fileHandle.ts @@ -0,0 +1,25 @@ +import {IpcChannel, IpcMainHandle} from "../ipc"; + +import {createLocalFile, loadLocalFile} from "../hook/dataFileHook"; + +export function useFileHandle(): Pick { + return { + [IpcChannel.FileRead]: (event, args) => { + // console.log(args); + let filename = args.filename; + let data = loadLocalFile(filename); + return {data: data}; + }, + [IpcChannel.FileWrite]: (event, args) => { + // console.log(args); + let filename = args.filename, + data = args.data; + return createLocalFile(filename, data).then((r) => { + return r; + }).catch(err => { + // console.log(err); + return false; + }); + }, + } +} diff --git a/src/main/hook/dataFileHook.ts b/src/main/hook/dataFileHook.ts new file mode 100644 index 0000000..25c7214 --- /dev/null +++ b/src/main/hook/dataFileHook.ts @@ -0,0 +1,33 @@ +// 将数据以文件形式保存 +import path from "path"; +import * as fs from "node:fs"; + +//创建目录,测试中的表现:使用递归创建(允许多级目录),否则必须逐级创建 +function checkFolder(folderPath) { + if (!fs.existsSync(folderPath)) { + fs.mkdirSync(folderPath, {recursive: true}); + } +} + +// const folderPath = path.join(app.getPath('userData'), '/datas/files'); +let folderPath = path.join(__dirname, 'datas/files/'); + +export function createLocalFile(fileName: string, data: any) { + checkFolder(folderPath); + // 确定文件路径 + const filePath = path.join(folderPath, fileName); + + // 使用fs.writeFile (异步)创建文件,如果文件已存在则会被覆盖 + return fs.promises.writeFile(filePath, data, {flag: 'w'}).then(() => { + console.log(`文件已创建成功:${filePath}`); + return true; + }).catch((err) => { + console.log(err); + return false; + }); +} + +export function loadLocalFile(fileName: string) { + const filePath = path.join(folderPath, fileName); + return fs.readFileSync(filePath, 'utf8'); +} diff --git a/src/main/index.ts b/src/main/index.ts index e984a01..79df942 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -23,6 +23,7 @@ function onAppReady() { server.StartServer().then((r) => { console.log('内置服务器已启动'); }) + } } diff --git a/src/main/ipc.ts b/src/main/ipc.ts index b873dde..d31eaea 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -235,9 +235,18 @@ export const enum IpcChannel { */ CheckShowOnMyComputer = "check-show-on-my-computer", /** - * 自定义Mock模拟网络请求-By fm453 + * 文件写入数据 */ - Mocker = "get-mock-data", + FileWrite = "file-write", + /** + * 读取文件 + */ + FileRead = "file-read", + + /** + * 执行sqlite语句 + */ + SqlRun = "sqlite-run", } type IpcMainEvent = { @@ -344,6 +353,9 @@ type IpcMainEvent = { >; [IpcChannel.CheckShowOnMyComputer]: IpcMainEventListener; [IpcChannel.SetShowOnMyComputer]: IpcMainEventListener; + [IpcChannel.FileWrite]: IpcMainEventListener<{ filename: string, data: any }, boolean>; + [IpcChannel.FileRead]: IpcMainEventListener<{ filename: string }, { data: any }>; + [IpcChannel.SqlRun]: IpcMainEventListener<{ sql: string, params: string[] }, any>; }; type IpcRenderderEvent = { @@ -386,6 +398,8 @@ type IpcRenderderEvent = { bvWebContentsId: number; }>; [IpcChannel.BrowserTabMouseup]: IpcRendererEventListener; + // [IpcChannel.FileWrite]: IpcRendererEventListener; + // [IpcChannel.FileRead]: IpcRendererEventListener; }; export type IpcMainHandle = { diff --git a/src/main/services/ipcMain.ts b/src/main/services/ipcMain.ts index 4834926..43f353b 100644 --- a/src/main/services/ipcMain.ts +++ b/src/main/services/ipcMain.ts @@ -1,14 +1,19 @@ import {ipcMain} from "electron"; -import {usePrintHandle} from "../handle/printHandle"; import {useBrowserHandle} from "../handle/browserHandle"; +import {useDbHandle} from "../handle/dbHandle"; +import {useFileHandle} from "../handle/fileHandle"; import {useMainHandle} from "../handle/mainHandle"; +import {usePrintHandle} from "../handle/printHandle"; import {useUpdateHandle} from "../handle/updateHandle"; import {useServerHandle} from "../handle/serverHandle"; + import {IpcMainHandle} from "../ipc"; const ipcMainHandle: IpcMainHandle = { ...useMainHandle(), ...useBrowserHandle(), + ...useDbHandle(), + ...useFileHandle(), ...usePrintHandle(), ...useServerHandle(), ...useUpdateHandle(), diff --git a/src/renderer/index.html b/src/renderer/index.html index 949e666..b30aae0 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -9,9 +9,9 @@ -
+
+