diff --git a/README.md b/README.md index eff0f12..872746c 100644 --- a/README.md +++ b/README.md @@ -45,20 +45,20 @@ - ***无需联网使用,全开源*** - ***零配置,无需注册,下载即用*** - ***零污染,无插件依赖*** -- ***精小,打包后仅65M,确包含了所有的办公套件*** +- ***精小,打包后仅65M,却包含了所有的办公套件*** - ***可无限扩展,支持自定义应用*** - ***golang开发后端,低资源消耗和高性能*** - ***支持多平台,Windows、Linux、MacOS*** -- ***只会html和拥有可执行的应用,简单学习一下应用商店配置即可开发出复杂的应用*** +- ***完善的应用商店体系,简单学习一下[应用商店配置](./docs/Store.md)即可开发出复杂的应用*** ## 🚧 开发进程 -- 2024年7月,发布v1.0.0版本,发布后,项目进入第二阶段。 +- 2024年8月1日,发布v1.0.0版本,发布后,项目进入第二阶段。 ## 🏭 第二阶段目标 - [x] 完善的应用商店体系 - [x] 完善开发文档 - [x] 支持远程存储 -- [x] 完成企业客户端 +- [x] 开发更多的商店应用 ## ⚡ 功能说明和预览 diff --git a/docs/Store.md b/docs/Store.md index 48eb763..f9f3df2 100644 --- a/docs/Store.md +++ b/docs/Store.md @@ -1,17 +1,27 @@ -## 应用管理 +## GodoOS应用商店开发教程 + +### 快速开始 +1. 下载[mysql5.7的zip包](https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-winx64.zip),并解压到用户目录.godoos/run/windows/目录下,文件夹命名为mysql5.7 +2. 复制本程序docs/demo/mysql5.7到用户目录.godoos/run/windows/mysql5.7目录下 +3. 打开应用商店,添加应用,选择开发模式,本地路径输入mysql5.7,点击确定 + +### 开发条件 + +1. 会简单的html开发 +2. 熟悉可执行文件的启动流程,然后根据如下的流程配置json文件 ### 如何添加一个应用 -1. 在用户目录.godoos/run下建立一个应用文件夹。 +1. 在用户目录.godoos/run/windows/下建立一个应用文件夹。 2. 一个应用需要包含两个配置文件,在应用根目录下创建`install.json`和`store.json`两个文件。 配置文件格式如下: -- install.json +- install.json [样本](./demo/mysql5.7/install.json) ```json { "name": "", // string, 应用程序名称。 "url": "", // string, 应用程序下载地址。 "webUrl":"", // string, 如何设置,应用程序将显示到桌面。 "isDev": true, // boolean, 是否为开发环境。 - "needDownload": true, // boolean, 是否需要下载。 + "needDownload": true, // boolean, 是否需要下载,本地开发设置为false。 "needInstall": true, // boolean, 是否需要安装。 "version": "1.0.0", // string, 应用程序版本。 "icon": "", // string, 应用程序图标,为可访问的网络地址。 @@ -21,9 +31,9 @@ } ``` -如果不需要后端进程的web应用,store.json可以不用配置。 +- 备注:如果不需要后端进程的web应用,store.json可以不用配置。 -install.json的struct为: +install.json的结构体为: ```json type InstallInfo struct { Name string `json:"name"` // 应用程序名称。重要,必须和应用的目录名称一致。 @@ -42,7 +52,7 @@ type InstallInfo struct { } ``` -- store.json +- store.json [样本](./demo/mysql5.7/store.json) ```json { @@ -50,33 +60,38 @@ type InstallInfo struct { "icon": "mysql.png", // string, 应用程序图标,一般放在应用程序static目录下。 "setting": { "binPath": "{exePath}/bin/mysqld.exe", // string, 重要,必须设置。为启动程序路径。 - "confPath": "{exePath}/my.ini",// string, 重要,必须设置。为配置文件路径。 + "confPath": "{exePath}/my.ini",// string, 可为空。为配置文件路径。 "progressName": "mysqld.exe",// string, 进程名称。如果为单线程可不设置。 "isOn": true // boolean, 是否启动守护进程 }, - "config": { // object, 配置文件。里面的配置可以任意填写,和cmds配合使用。 + "config": { // object, 配置文件。里面的配置可以任意填写,和commands配合使用。可以通过http设置里面的参数。 }, - "cmds": {},// object, 命令集。 + "commands": {},// object, 命令列表集。可供install里的installCmds调用,也可以通过外部http请求调用。 "install": { // object, 安装配置。 - "envs": [],// object[], 环境变量。 - "cmds": []// object[], 启动命令。 + "installEnvs": [],// object[], 环境变量。 + "installCmds": []// object[], 启动命令。可调用命令列表集commands里面的命令。 }, - "start": {// object, 启动配置。 - "envs": [],// object[], 环境变量。 - "cmds": []// object[], 启动命令。 + "start": { + "startEnvs": [], + "startCmds": [// object[], 纯参数命令集。将启动`setting.binPath`,不可调用命令列表集`commands`里面的命令。 + "--defaults-file={exePath}/my.ini" + ] } } ``` + +- 备注:核心的替换参数为`{exePath}`即程序的执行目录。其他`{参数}`对应`store.json`里的`config`。 + store.json的struct为 ```json type StoreInfo struct { - Name string `json:"name"` // 应用程序的名称。 - Icon string `json:"icon"` // 应用程序的图标路径。 - Setting Setting `json:"setting"` // 应用程序的配置信息。 - Config map[string]any `json:"config"` // 应用程序的配置信息映射。 - Cmds map[string][]Cmd `json:"cmds"` // 应用程序的命令集合。 - Install Install `json:"install"` // 安装应用程序的信息。 - Start Install `json:"start"` // 启动应用程序的信息。 + Name string `json:"name"` // 应用程序商店的名称。 + Icon string `json:"icon"` // 应用程序商店的图标路径。 + Setting Setting `json:"setting"` // 应用程序商店的配置信息。 + Config map[string]any `json:"config"` // 应用程序的配置信息映射。 + Commands map[string][]Cmd `json:"commands"` // 应用程序的命令集合。 + Install InstallStruct `json:"install"` // 安装应用程序的信息。 + Start StartStruct `json:"start"` // 启动应用程序的信息。 } ``` Setting的结构体为: @@ -103,12 +118,16 @@ type Cmd struct { Envs []Item `json:"envs"` // 命令执行时的环境变量。 } ``` -Install的struct为: +Install的结构体为: ```json -// Install 描述了安装过程中的环境变量和命令列表。 -type Install struct { - Envs []Item `json:"envs"` // 安装过程中需要的环境变量。 - Cmds []string `json:"cmds"` // 安装过程中需要执行的命令列表。 +// InstallStruct 描述了安装过程中的环境变量和命令列表。 +type InstallStruct struct { + InstallEnvs []Item `json:"installEnvs"` // 安装过程中需要的环境变量。 + InstallCmds []string `json:"installCmds"` // 安装过程中需要执行的命令列表。 +} +type StartStruct struct { + StartEnvs []Item `json:"startEnvs"` // 安装过程中需要的环境变量。 + StartCmds []string `json:"startCmds"` // 安装过程中需要执行的命令列表。 } // Item 是一个通用的键值对结构体,用于表示配置项或环境变量等。 type Item struct { @@ -121,13 +140,13 @@ type Item struct { ### 配置文件`store.json`说明 -1. `install`和`start`配置可以调用`cmds`里的命令。 -2. `cmds`里的命令也可以调用自身的命令。 +1. `install`可以调用`commands`里的命令。 +2. `commands`里的命令也可以调用自身的命令。 3. 所有的命令都可以串联使用。 ### 如何设置配置 1. 在应用目录下建立`static`目录,并创建`index.html`文件。`install.json`中`setting`设置为`true`。 -前端配置样列 +前端配置样列 [样本](./demo/mysql5.7/static/index.html) ```js const postData = { dataDir: dataDir,// 此处对应store.json中的config配置项 @@ -144,17 +163,67 @@ const comp = await fetch('http://localhost:56780/store/setting', { body: JSON.stringify(postData) }); ``` -关键要设置好`name`和`cmdKey`,`cmdKey`对应`store.json`中的`cmds`数组配置项中的`name`,一个数组中又可以配置一系列的命令,可以参考Cmd的结构体 +- 关键要设置好`name`和`cmdKey`,`name`为应用名称,`cmdKey`对应`store.json`中的`commands`对象中的键,一个对象中又可以配置一系列的命令,可以参考Cmd的结构体,样例: +```json +"commands": { + "initData": [ + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--initialize" + ], + "waiting": 1 //为等待的秒数 + }, + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--init-file={exePath}/password.txt" + ], + "waiting": 3, + "kill": true + }, + { + "name": "start" + } + ], + "setting": [ + { + "name": "changeFile", + "tplPath": "{exePath}/my.ini.tpl", + "filePath": "{exePath}/my.ini" + }, + { + "name": "initData" + } + ], +} +``` +- 上述样例中setting又调用了initData命令。 +- post的固定地址为`http://localhost:56780/store/setting` +- 原理是通过`http`请求`/store/setting`接口,将配置信息发送给`store`服务,然后`store`服务会根据配置信息,自动更换配置信息,并启动应用 + +### static目录说明 +1. `index.html`是应用的首页 +2. `static`目录下的在执行install时文件会自动复制到`.godoos/static/`应用目录下 +3. `store.json`如果设置了`icon`,并且`static`目录下存在该文件,则应用图标为该文件。否则为`install.json`中的icon ### 内置应用说明 -- 系列封装了一些用于处理进程控制和文件操作的功能函数,以下是各函数的详细描述: +- 系统封装了一些用于处理进程控制和文件操作的功能函数,以下是各函数的详细描述: 1. `start` 启动应用 2. `stop` 停止应用 3. `restart` 重启应用 4. `exec` 执行命令 必须设置binPath和cmds -5. `writeFile` 写入文件 必须设置filePath和content,以config为依据,对content进行替换 +5. `writeFile` 写入文件 必须设置filePath和content,以config为依据,对content中的`{参数}`进行替换 6. `changeFile` 修改文件 必须设置filePath和tplPath,以config为依据,在模板文件中进行替换 7. `deleteFile` 删除文件 8. `unzip` 解压文件 必须设置filePath和content,content为解压目录 9. `zip` 压缩文件 必须设置filePath和content,filePath为将要压缩的文件夹,content为压缩后的文件名 10. `mkdir` 创建文件夹 必须设置FilePath,FilePath为创建的文件夹路径 +11. `startApp` 启动其他应用,content为应用名 +12. `stopApp` 停止其他应用,content为应用名 + + diff --git a/docs/demo/mysql5.7/install.json b/docs/demo/mysql5.7/install.json new file mode 100644 index 0000000..94a372a --- /dev/null +++ b/docs/demo/mysql5.7/install.json @@ -0,0 +1,13 @@ +{ + "name": "mysql5.7", + "url": "https://gitee.com/ruitao_admin/godoos-mysql5.7/releases/download/mysql5.7/mysql5.7.zip", + "isDev": true, + "needDownload": true, + "needInstall": true, + "version": "5.7.37", + "icon": "https://img0.baidu.com/it/u=1087008535,3349487719&fm=253&fmt=auto&app=138&f=PNG?w=969&h=500", + "checkProgress": true, + "hasRestart": true, + "setting": true, + "isOn": true +} \ No newline at end of file diff --git a/docs/demo/mysql5.7/my.ini b/docs/demo/mysql5.7/my.ini new file mode 100644 index 0000000..b780d45 --- /dev/null +++ b/docs/demo/mysql5.7/my.ini @@ -0,0 +1,26 @@ +[client] +port = 3306 + +[mysql] +no-auto-rehash +default-character-set = utf8 + +[mysqld] +basedir = "" +datadir = "data" +port = 3306 +server_id = 1 +character-set-server = utf8 + +explicit_defaults_for_timestamp = on +skip-ssl + +table_open_cache = 256 + +log_timestamps = SYSTEM + +log-error = "logs/mysql.log" +log_syslog = 0 +[mysqldump] +quick +max_allowed_packet = 512M diff --git a/docs/demo/mysql5.7/my.ini.tpl b/docs/demo/mysql5.7/my.ini.tpl new file mode 100644 index 0000000..6e6385b --- /dev/null +++ b/docs/demo/mysql5.7/my.ini.tpl @@ -0,0 +1,26 @@ +[client] +port = {port} + +[mysql] +no-auto-rehash +default-character-set = utf8 + +[mysqld] +basedir = "{exePath}" +datadir = "{dataDir}" +port = {port} +server_id = 1 +character-set-server = utf8 + +explicit_defaults_for_timestamp = on +skip-ssl + +table_open_cache = 256 + +log_timestamps = SYSTEM + +log-error = "{logDir}/mysql.log" +log_syslog = 0 +[mysqldump] +quick +max_allowed_packet = 512M diff --git a/docs/demo/mysql5.7/password.txt b/docs/demo/mysql5.7/password.txt new file mode 100644 index 0000000..492d052 --- /dev/null +++ b/docs/demo/mysql5.7/password.txt @@ -0,0 +1 @@ +ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; \ No newline at end of file diff --git a/docs/demo/mysql5.7/password.txt.tpl b/docs/demo/mysql5.7/password.txt.tpl new file mode 100644 index 0000000..0f36b5e --- /dev/null +++ b/docs/demo/mysql5.7/password.txt.tpl @@ -0,0 +1 @@ +ALTER USER 'root'@'localhost' IDENTIFIED BY '{password}'; \ No newline at end of file diff --git a/docs/demo/mysql5.7/static/index.html b/docs/demo/mysql5.7/static/index.html new file mode 100644 index 0000000..2cd2a69 --- /dev/null +++ b/docs/demo/mysql5.7/static/index.html @@ -0,0 +1,314 @@ + + + + + + MySQL 设置 + + + + + +
+

MySQL 设置

+
+ + +
+
+ + + + + + + + + + +
+
+ + + + +
+
+ + + + + \ No newline at end of file diff --git a/docs/demo/mysql5.7/static/mysql.png b/docs/demo/mysql5.7/static/mysql.png new file mode 100644 index 0000000..0804c78 Binary files /dev/null and b/docs/demo/mysql5.7/static/mysql.png differ diff --git a/docs/demo/mysql5.7/store.json b/docs/demo/mysql5.7/store.json new file mode 100644 index 0000000..fc7dfe9 --- /dev/null +++ b/docs/demo/mysql5.7/store.json @@ -0,0 +1,84 @@ +{ + "name": "mysql5.7", + "icon": "mysql.png", + "setting": { + "binPath": "{exePath}/bin/mysqld.exe", + "confPath": "{exePath}/my.ini", + "progressName": "mysqld.exe", + "isOn": true + }, + "config": { + "password": "root", + "port": 3306, + "dataDir": "{exePath}/data", + "logDir": "{exePath}/logs" + }, + "commands": { + "initData": [ + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--initialize" + ], + "waiting": 1 + }, + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--init-file={exePath}/password.txt" + ], + "waiting": 3, + "kill": true + }, + { + "name": "start" + } + ], + "setting": [ + { + "name": "changeFile", + "tplPath": "{exePath}/my.ini.tpl", + "filePath": "{exePath}/my.ini" + }, + { + "name": "initData" + } + ], + "changePassword": [ + { + "name": "changeFile", + "tplPath": "{exePath}/password.txt.tpl", + "filePath": "{exePath}/password.txt" + }, + { + "name": "stop" + }, + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--init-file={exePath}/password.txt" + ], + "waiting": 3, + "kill": true + } + ] + }, + "install": { + "installEnvs": [], + "installCmds": [ + "initData" + ] + }, + "start": { + "startEnvs": [], + "startCmds": [ + "--defaults-file={exePath}/my.ini" + ] + } +} \ No newline at end of file diff --git a/docs/img/baiban.png b/docs/img/baiban.png deleted file mode 100644 index 595ebe9..0000000 Binary files a/docs/img/baiban.png and /dev/null differ diff --git a/docs/img/cal.png b/docs/img/cal.png deleted file mode 100644 index 2a54ded..0000000 Binary files a/docs/img/cal.png and /dev/null differ diff --git a/docs/img/doc.png b/docs/img/doc.png deleted file mode 100644 index 8e25a8a..0000000 Binary files a/docs/img/doc.png and /dev/null differ diff --git a/docs/img/excel.png b/docs/img/excel.png deleted file mode 100644 index 119558e..0000000 Binary files a/docs/img/excel.png and /dev/null differ diff --git a/docs/img/file.png b/docs/img/file.png deleted file mode 100644 index 383d8f5..0000000 Binary files a/docs/img/file.png and /dev/null differ diff --git a/docs/img/fileeditor.png b/docs/img/fileeditor.png deleted file mode 100644 index 39ab7c4..0000000 Binary files a/docs/img/fileeditor.png and /dev/null differ diff --git a/docs/img/gant.png b/docs/img/gant.png deleted file mode 100644 index b2ab688..0000000 Binary files a/docs/img/gant.png and /dev/null differ diff --git a/docs/img/home.png b/docs/img/home.png deleted file mode 100644 index ecc9123..0000000 Binary files a/docs/img/home.png and /dev/null differ diff --git a/docs/img/ie.png b/docs/img/ie.png deleted file mode 100644 index 3e42277..0000000 Binary files a/docs/img/ie.png and /dev/null differ diff --git a/docs/img/kanban.png b/docs/img/kanban.png deleted file mode 100644 index ff9ce4f..0000000 Binary files a/docs/img/kanban.png and /dev/null differ diff --git a/docs/img/localchat.png b/docs/img/localchat.png deleted file mode 100644 index 8d242ac..0000000 Binary files a/docs/img/localchat.png and /dev/null differ diff --git a/docs/img/markdown.png b/docs/img/markdown.png deleted file mode 100644 index 9fb37e9..0000000 Binary files a/docs/img/markdown.png and /dev/null differ diff --git a/docs/img/mind.png b/docs/img/mind.png deleted file mode 100644 index bab3931..0000000 Binary files a/docs/img/mind.png and /dev/null differ diff --git a/docs/img/pic.png b/docs/img/pic.png deleted file mode 100644 index e583739..0000000 Binary files a/docs/img/pic.png and /dev/null differ diff --git a/docs/img/ppt.png b/docs/img/ppt.png deleted file mode 100644 index d99527d..0000000 Binary files a/docs/img/ppt.png and /dev/null differ diff --git a/docs/img/rili.png b/docs/img/rili.png deleted file mode 100644 index 848f50e..0000000 Binary files a/docs/img/rili.png and /dev/null differ diff --git a/docs/img/setting-store.png b/docs/img/setting-store.png deleted file mode 100644 index d8fcead..0000000 Binary files a/docs/img/setting-store.png and /dev/null differ diff --git a/frontend/src/components/desktop/Upgrade.vue b/frontend/src/components/desktop/Upgrade.vue index 5e158bd..adbb4f9 100644 --- a/frontend/src/components/desktop/Upgrade.vue +++ b/frontend/src/components/desktop/Upgrade.vue @@ -15,9 +15,9 @@
- GodoOS {{ $t('upgrade.msg') }} + GodoOS {{ upgradeStore.upgradeDesc }}
- + CHANGELOG.md
diff --git a/frontend/src/stores/upgrade.ts b/frontend/src/stores/upgrade.ts index 46af8b3..4b405de 100644 --- a/frontend/src/stores/upgrade.ts +++ b/frontend/src/stores/upgrade.ts @@ -3,12 +3,14 @@ import { ref } from "vue"; import { getSystemKey, setSystemKey, parseJson, getSystemConfig } from '@/system/config' import { RestartApp } from '@/util/goutil'; import { ElMessage } from 'element-plus' +import { t } from '@/i18n'; export const useUpgradeStore = defineStore('upgradeStore', () => { const hasUpgrade = ref(false); const hasNotice = ref(false); const hasAd = ref(false); const updateUrl = ref(''); const versionTag = ref(0) + const upgradeDesc = ref('') const currentVersion = ref(0) const progress = ref(0) const noticeList:any = ref([]) @@ -21,6 +23,7 @@ export const useUpgradeStore = defineStore('upgradeStore', () => { const releaseData = await releaseRes.json() versionTag.value = releaseData.version if(versionTag.value > config.version){ + upgradeDesc.value = releaseData.desc ?? t('upgrade.msg') hasUpgrade.value = true updateUrl.value = releaseData.url } @@ -78,6 +81,7 @@ export const useUpgradeStore = defineStore('upgradeStore', () => { hasNotice, hasAd, versionTag, + upgradeDesc, updateUrl, noticeList, adList, diff --git a/godo/store/cmds.go b/godo/store/cmds.go index 1f7e4e6..67f80b6 100644 --- a/godo/store/cmds.go +++ b/godo/store/cmds.go @@ -15,19 +15,21 @@ import ( func runStop(storeInfo StoreInfo) error { return StopCmd(storeInfo.Name) } + func runStart(storeInfo StoreInfo) error { - err := SetEnvs(storeInfo.Start.Envs) + err := SetEnvs(storeInfo.Start.StartEnvs) if err != nil { return fmt.Errorf("failed to set start environment variable %s: %w", storeInfo.Name, err) } - if !libs.PathExists(storeInfo.Setting.BinPath) { + binPath := storeInfo.Setting.BinPath + if !libs.PathExists(binPath) { return fmt.Errorf("script file %s does not exist", storeInfo.Setting.BinPath) } var cmd *exec.Cmd - if len(storeInfo.Start.Cmds) > 0 { - cmd = exec.Command(storeInfo.Setting.BinPath, storeInfo.Start.Cmds...) + if len(storeInfo.Start.StartCmds) > 0 { + cmd = exec.Command(binPath, storeInfo.Start.StartCmds...) } else { - cmd = exec.Command(storeInfo.Setting.BinPath) + cmd = exec.Command(binPath) } if runtime.GOOS == "windows" { // 在Windows上,通过设置CreationFlags来隐藏窗口 @@ -50,6 +52,12 @@ func runStart(storeInfo StoreInfo) error { return nil } +func RunStartApp(appName string) error { + return ExecuteScript(appName) +} +func RunStopApp(appName string) error { + return StopCmd(appName) +} func runRestart(storeInfo StoreInfo) error { err := runStop(storeInfo) if err != nil { diff --git a/godo/store/install.go b/godo/store/install.go index 063c111..9c2eb10 100644 --- a/godo/store/install.go +++ b/godo/store/install.go @@ -192,13 +192,13 @@ func convertValueToString(value any) string { } func InstallStore(storeInfo StoreInfo) error { - err := SetEnvs(storeInfo.Install.Envs) + err := SetEnvs(storeInfo.Install.InstallEnvs) if err != nil { return fmt.Errorf("failed to set install environment variable %s: %w", storeInfo.Name, err) } - if len(storeInfo.Install.Cmds) > 0 { - for _, cmdKey := range storeInfo.Install.Cmds { - if _, ok := storeInfo.Cmds[cmdKey]; ok { + if len(storeInfo.Install.InstallCmds) > 0 { + for _, cmdKey := range storeInfo.Install.InstallCmds { + if _, ok := storeInfo.Commands[cmdKey]; ok { // 如果命令存在,你可以进一步处理 cmds RunCmds(storeInfo, cmdKey) } @@ -214,6 +214,12 @@ func RunCmd(storeInfo StoreInfo, cmd Cmd) error { if cmd.Name == "start" { runStart(storeInfo) } + if cmd.Name == "startApp" { + RunStartApp(cmd.Content) + } + if cmd.Name == "stopApp" { + RunStopApp(cmd.Content) + } if cmd.Name == "restart" { runRestart(storeInfo) } @@ -259,9 +265,9 @@ func RunCmd(storeInfo StoreInfo, cmd Cmd) error { return nil } func RunCmds(storeInfo StoreInfo, cmdKey string) error { - cmds := storeInfo.Cmds[cmdKey] + cmds := storeInfo.Commands[cmdKey] for _, cmd := range cmds { - if _, ok := storeInfo.Cmds[cmd.Name]; ok { + if _, ok := storeInfo.Commands[cmd.Name]; ok { RunCmds(storeInfo, cmd.Name) } else { RunCmd(storeInfo, cmd) @@ -333,21 +339,24 @@ func replacePlaceholdersInCmds(storeInfo *StoreInfo) { // 遍历Config中的所有键值对 for key, value := range storeInfo.Config { // 遍历Cmds中的所有命令组 - for cmdGroupName, cmds := range storeInfo.Cmds { + for cmdGroupName, cmds := range storeInfo.Commands { // 遍历每个命令组中的所有Cmd for i, cmd := range cmds { - strValue := convertValueToString(value) - // 使用正则表达式替换Content中的占位符 - storeInfo.Cmds[cmdGroupName][i].Content = pattern.ReplaceAllStringFunc( - cmd.Content, - func(match string) string { - // 检查占位符是否与Config中的键匹配 - if strings.Trim(match, "{}") == key { - return strValue - } - return match - }, - ) + if cmd.Content != "" { + strValue := convertValueToString(value) + // 使用正则表达式替换Content中的占位符 + storeInfo.Commands[cmdGroupName][i].Content = pattern.ReplaceAllStringFunc( + cmd.Content, + func(match string) string { + // 检查占位符是否与Config中的键匹配 + if strings.Trim(match, "{}") == key { + return strValue + } + return match + }, + ) + } + } } } diff --git a/godo/store/store.go b/godo/store/store.go index 11dd50a..cc3b009 100644 --- a/godo/store/store.go +++ b/godo/store/store.go @@ -89,12 +89,13 @@ func StoreSettingHandler(w http.ResponseWriter, r *http.Request) { storeInfo.Config[k] = v // 如果k存在,则更新;如果不存在,则新增 } } + replacePlaceholdersInCmds(&storeInfo) err = SaveInfoFile(storeInfo) if err != nil { libs.ErrorMsg(w, "the store info.json is error: "+err.Error()) return } - _, ok := storeInfo.Cmds[cmdKey] + _, ok := storeInfo.Commands[cmdKey] if !ok { libs.ErrorMsg(w, "cmdKey is not found") return diff --git a/godo/store/types.go b/godo/store/types.go index 604fa5a..7458541 100644 --- a/godo/store/types.go +++ b/godo/store/types.go @@ -21,13 +21,13 @@ type InstallInfo struct { // StoreInfo 维护了应用程序商店的信息。 // 包含应用程序的名称、图标、配置信息等。 type StoreInfo struct { - Name string `json:"name"` // 应用程序商店的名称。 - Icon string `json:"icon"` // 应用程序商店的图标路径。 - Setting Setting `json:"setting"` // 应用程序商店的配置信息。 - Config map[string]any `json:"config"` // 应用程序的配置信息映射。 - Cmds map[string][]Cmd `json:"cmds"` // 应用程序的命令集合。 - Install Install `json:"install"` // 安装应用程序的信息。 - Start Install `json:"start"` // 启动应用程序的信息。 + Name string `json:"name"` // 应用程序商店的名称。 + Icon string `json:"icon"` // 应用程序商店的图标路径。 + Setting Setting `json:"setting"` // 应用程序商店的配置信息。 + Config map[string]any `json:"config"` // 应用程序的配置信息映射。 + Commands map[string][]Cmd `json:"commands"` // 应用程序的命令集合。 + Install InstallStruct `json:"install"` // 安装应用程序的信息。 + Start StartStruct `json:"start"` // 启动应用程序的信息。 } // Setting 描述了应用程序的设置信息。 @@ -60,7 +60,11 @@ type Cmd struct { } // Install 描述了安装过程中的环境变量和命令列表。 -type Install struct { - Envs []Item `json:"envs"` // 安装过程中需要的环境变量。 - Cmds []string `json:"cmds"` // 安装过程中需要执行的命令列表。 +type InstallStruct struct { + InstallEnvs []Item `json:"installEnvs"` // 安装过程中需要的环境变量。 + InstallCmds []string `json:"installCmds"` // 安装过程中需要执行的命令列表。 +} +type StartStruct struct { + StartEnvs []Item `json:"startEnvs"` // 安装过程中需要的环境变量。 + StartCmds []string `json:"startCmds"` // 安装过程中需要执行的命令列表。 }