diff --git a/docs/Store.md b/docs/Store.md
index f9f3df2..19a404a 100644
--- a/docs/Store.md
+++ b/docs/Store.md
@@ -20,7 +20,7 @@
"name": "", // string, 应用程序名称。
"url": "", // string, 应用程序下载地址。
"webUrl":"", // string, 如何设置,应用程序将显示到桌面。
- "isDev": true, // boolean, 是否为开发环境。
+ "isDev": true, // boolean, 是否为开发环境。如果设置为true将不会下载数据。
"needDownload": true, // boolean, 是否需要下载,本地开发设置为false。
"needInstall": true, // boolean, 是否需要安装。
"version": "1.0.0", // string, 应用程序版本。
@@ -73,9 +73,11 @@ type InstallInfo struct {
},
"start": {
"startEnvs": [],
+ "beforeCmds": [],// 启动前需要执行的命令列表。可调用命令列表集commands里面的命令。
"startCmds": [// object[], 纯参数命令集。将启动`setting.binPath`,不可调用命令列表集`commands`里面的命令。
"--defaults-file={exePath}/my.ini"
- ]
+ ],
+ "AfterCmds": []// 启动后需要执行的命令列表。可调用命令列表集commands里面的命令。
}
}
```
@@ -114,7 +116,7 @@ type Cmd struct {
TplPath string `json:"tplPath,omitempty"` // 命令的模板路径。
Cmds []string `json:"cmds,omitempty"` // 要执行的子命令列表。
Waiting int `json:"waiting"` // 等待的时间。
- Kill bool `json:"kill"` // 标志位,表示是否需要终止之前的命令。如果setting中设置了progressName会优先杀死整个进程
+ Kill bool `json:"kill"` // 标志位,表示是否需要终止之前的命令。如果设置了`content`中的进程名,则优先以进程名字杀死进程
Envs []Item `json:"envs"` // 命令执行时的环境变量。
}
```
@@ -126,8 +128,10 @@ type InstallStruct struct {
InstallCmds []string `json:"installCmds"` // 安装过程中需要执行的命令列表。
}
type StartStruct struct {
- StartEnvs []Item `json:"startEnvs"` // 安装过程中需要的环境变量。
- StartCmds []string `json:"startCmds"` // 安装过程中需要执行的命令列表。
+ StartEnvs []Item `json:"startEnvs"` // 启动过程中需要的环境变量。
+ BeforeCmds []string `json:"beforeCmds"` // 启动前需要执行的命令列表。可调用命令列表集commands里面的命令。
+ StartCmds []string `json:"startCmds"` // 启动过程中需要执行的命令列表。
+ AfterCmds []string `json:"afterCmds"` // 启动后需要执行的命令列表。可调用命令列表集commands里面的命令。
}
// Item 是一个通用的键值对结构体,用于表示配置项或环境变量等。
type Item struct {
@@ -184,6 +188,7 @@ const comp = await fetch('http://localhost:56780/store/setting', {
"--init-file={exePath}/password.txt"
],
"waiting": 3,
+ "content": "mysqld.exe",
"kill": true
},
{
@@ -226,4 +231,7 @@ const comp = await fetch('http://localhost:56780/store/setting', {
11. `startApp` 启动其他应用,content为应用名
12. `stopApp` 停止其他应用,content为应用名
+### 进阶操作
+1. 下载[mysql8.0](https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip)
+2. 参考demo下的mysql8.0目录,尝试自己制作安装包
diff --git a/docs/demo/mysql5.7/install.json b/docs/demo/mysql5.7/install.json
index 94a372a..b3dc8db 100644
--- a/docs/demo/mysql5.7/install.json
+++ b/docs/demo/mysql5.7/install.json
@@ -1,10 +1,10 @@
{
"name": "mysql5.7",
- "url": "https://gitee.com/ruitao_admin/godoos-mysql5.7/releases/download/mysql5.7/mysql5.7.zip",
+ "url": "https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-winx64.zip",
"isDev": true,
"needDownload": true,
"needInstall": true,
- "version": "5.7.37",
+ "version": "5.7.44",
"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,
diff --git a/docs/demo/mysql5.7/store.json b/docs/demo/mysql5.7/store.json
index fc7dfe9..bb6e1e7 100644
--- a/docs/demo/mysql5.7/store.json
+++ b/docs/demo/mysql5.7/store.json
@@ -1,5 +1,4 @@
{
- "name": "mysql5.7",
"icon": "mysql.png",
"setting": {
"binPath": "{exePath}/bin/mysqld.exe",
@@ -32,6 +31,7 @@
"--init-file={exePath}/password.txt"
],
"waiting": 3,
+ "content": "mysqld.exe",
"kill": true
},
{
@@ -65,6 +65,7 @@
"--init-file={exePath}/password.txt"
],
"waiting": 3,
+ "content": "mysqld.exe",
"kill": true
}
]
diff --git a/docs/demo/mysql8.0/install.json b/docs/demo/mysql8.0/install.json
new file mode 100644
index 0000000..b9ca128
--- /dev/null
+++ b/docs/demo/mysql8.0/install.json
@@ -0,0 +1,13 @@
+{
+ "name": "mysql8.0",
+ "url": "https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip",
+ "isDev": true,
+ "needDownload": true,
+ "needInstall": true,
+ "version": "8.0.39",
+ "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/mysql8.0/my.ini.tpl b/docs/demo/mysql8.0/my.ini.tpl
new file mode 100644
index 0000000..07a36a4
--- /dev/null
+++ b/docs/demo/mysql8.0/my.ini.tpl
@@ -0,0 +1,29 @@
+[client]
+port = 3306
+
+[mysql]
+no-auto-rehash
+default-character-set = utf8mb4
+
+[mysqld]
+basedir = "{exePath}"
+datadir = "{dataDir}"
+port = {port}
+server_id = 1
+character-set-server = utf8mb4
+
+default_authentication_plugin = mysql_native_password
+
+explicit_defaults_for_timestamp = on
+tls-version = ''
+skip-mysqlx
+
+table_open_cache = 256
+
+log_timestamps = SYSTEM
+
+log-error = "{logDir}/mysql.log"
+
+[mysqldump]
+quick
+max_allowed_packet = 512M
diff --git a/docs/demo/nginx/store.json b/docs/demo/nginx/store.json
new file mode 100644
index 0000000..9e63304
--- /dev/null
+++ b/docs/demo/nginx/store.json
@@ -0,0 +1,14 @@
+{
+ "name": "nginx",
+ "icon": "nginx.png",
+ "setting": {
+ "binPath": "{exePath}/nginx.exe",
+ "progressName":"nginx.exe"
+ },
+ "start": {
+ "startCmds": [
+ "-p",
+ "{exePath}"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/docs/demo/redis5.0/store.json b/docs/demo/redis5.0/store.json
new file mode 100644
index 0000000..740ea8d
--- /dev/null
+++ b/docs/demo/redis5.0/store.json
@@ -0,0 +1,12 @@
+{
+ "name": "redis5.0",
+ "icon": "redis.png",
+ "setting": {
+ "binPath": "{exePath}/redis-server.exe"
+ },
+ "start": {
+ "startCmds": [
+ "{exePath}/redis.windows.conf"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/components/store/AddApp.vue b/frontend/src/components/store/AddApp.vue
index d2456ba..c612619 100644
--- a/frontend/src/components/store/AddApp.vue
+++ b/frontend/src/components/store/AddApp.vue
@@ -2,9 +2,12 @@
import { ref, defineProps } from "vue";
import { OpenDirDialog } from "@/util/goutil";
import { getSystemKey, parseJson } from "@/system/config";
-const apiUrl = getSystemKey("apiUrl");
+import { useStoreStore } from "@/stores/store";
import { notifySuccess, notifyError } from "@/util/msg";
import { t } from "@/i18n";
+const apiUrl = getSystemKey("apiUrl");
+const store = useStoreStore()
+const fileInput = ref()
const props = defineProps({
install: {
type: Function,
@@ -22,10 +25,10 @@ const addType = [
'name': '远程下载',
'type': 'download'
},
- // {
- // 'name': '本地导入',
- // 'type': 'local'
- // },
+ {
+ 'name': '本地导入',
+ 'type': 'local'
+ },
{
'name': '开发模式',
'type': 'dev'
@@ -76,7 +79,27 @@ async function addAppByDownload() {
}
}
async function addAppByImport() {
-
+ fileInput.value.click()
+}
+async function upload(e: any) {
+ const file = e.target.files[0];
+ if (file) {
+ const formData = new FormData();
+ formData.append('files', file);
+ const completion = await fetch(apiUrl + '/store/upload', {
+ method: 'POST',
+ body: formData
+ })
+ if (!completion.ok) {
+ notifyError(t("store.importError"))
+ return
+ }
+ const item = await completion.json()
+ //console.log(item)
+ if(item.data){
+ await installPlugin(item.data)
+ }
+ }
}
async function addAppByDev() {
if(formData.value.devPath && formData.value.devPath != ""){
@@ -91,8 +114,9 @@ async function installPlugin(pluginName: string) {
}
const item = await completion.json()
//console.log(item)
- item.isOut = true
+ item.data.isOut = true
await props.install(item.data)
+ store.changeCate(0, 'hots')
}
@@ -112,7 +136,8 @@ async function installPlugin(pluginName: string) {
添加
- 导入
+
+ 导入压缩包
diff --git a/frontend/src/components/store/Store.vue b/frontend/src/components/store/Store.vue
index eae0764..f56719d 100644
--- a/frontend/src/components/store/Store.vue
+++ b/frontend/src/components/store/Store.vue
@@ -19,9 +19,10 @@ function setCache() {
}, 1000);
}
async function install(item: any) {
+ //console.log(item)
if (item.isOut) {
item.progress = 0
- const flag = store.addOutList(item)
+ const flag = await store.addOutList(item)
if(!flag){
notifyError(t("store.installError"))
}
@@ -48,7 +49,7 @@ async function install(item: any) {
}
if (item.webUrl) {
- sys.fs.writeFile(
+ await sys.fs.writeFile(
`${sys._options.userLocation}Desktop/${item.name}.url`,
`link::url::${item.webUrl}::${item.icon}`
);
@@ -61,6 +62,12 @@ async function install(item: any) {
}
async function uninstall(item: any) {
+ if (item.webUrl) {
+ await sys.fs.unlink(`${sys._options.userLocation}Desktop/${item.name}.url`);
+ }
+
+ delete store.installedList[store.installedList.indexOf(item.name)];
+ setCache();
if (item.needInstall) {
item.progress = 0
const completion = await fetch(store.apiUrl + '/store/uninstall?name=' + item.name)
@@ -74,10 +81,7 @@ async function uninstall(item: any) {
return
}
}
- sys.fs.unlink(`${sys._options.userLocation}Desktop/${item.name}.url`);
notifySuccess(t("store.uninstallSuccess"))
- delete store.installedList[store.installedList.indexOf(item.name)];
- setCache();
}
async function download(item: any) {
//console.log(item)
diff --git a/frontend/src/stores/store.ts b/frontend/src/stores/store.ts
index f813c77..2e78704 100644
--- a/frontend/src/stores/store.ts
+++ b/frontend/src/stores/store.ts
@@ -25,8 +25,8 @@ export const useStoreStore = defineStore('storeStore', () => {
}
let list:any = await res.json()
//console.log(data)
- if (outList.value.length > 0 && currentCate.value == 'hots') {
- const names = list.value.map((item : any) => item.name)
+ if (outList.value.length > 0 && currentCate.value == 'hots' && list && list.length > 0) {
+ const names = list.map((item : any) => item.name)
const adds:any = []
outList.value.forEach((item : any) => {
if (!names.includes(item.name)) {
@@ -40,7 +40,9 @@ export const useStoreStore = defineStore('storeStore', () => {
isready.value = true;
}
async function addOutList(item:any) {
+ console.log(item)
const has = outList.value.find((i:any) => i.name === item.name)
+ console.log(has)
if(!has) {
item.isOut = true
outList.value.push(item)
diff --git a/godo/store/cmds.go b/godo/store/cmds.go
index 67f80b6..85bafd5 100644
--- a/godo/store/cmds.go
+++ b/godo/store/cmds.go
@@ -21,6 +21,15 @@ func runStart(storeInfo StoreInfo) error {
if err != nil {
return fmt.Errorf("failed to set start environment variable %s: %w", storeInfo.Name, err)
}
+ if len(storeInfo.Start.BeforeCmds) > 0 {
+ for _, cmdKey := range storeInfo.Start.BeforeCmds {
+ if _, ok := storeInfo.Commands[cmdKey]; ok {
+ // 如果命令存在,你可以进一步处理 cmds
+ RunCmds(storeInfo, cmdKey)
+ }
+ }
+
+ }
binPath := storeInfo.Setting.BinPath
if !libs.PathExists(binPath) {
return fmt.Errorf("script file %s does not exist", storeInfo.Setting.BinPath)
@@ -49,7 +58,15 @@ func runStart(storeInfo StoreInfo) error {
}
}(cmd)
+ if len(storeInfo.Start.AfterCmds) > 0 {
+ for _, cmdKey := range storeInfo.Start.AfterCmds {
+ if _, ok := storeInfo.Commands[cmdKey]; ok {
+ // 如果命令存在,你可以进一步处理 cmds
+ RunCmds(storeInfo, cmdKey)
+ }
+ }
+ }
return nil
}
func RunStartApp(appName string) error {
@@ -89,9 +106,9 @@ func runExec(storeInfo StoreInfo, cmdParam Cmd) error {
time.Sleep(time.Second * time.Duration(cmdParam.Waiting))
}
if cmdParam.Kill {
- if storeInfo.Setting.ProgressName != "" {
- if err := KillProcessByName(storeInfo.Setting.ProgressName); err != nil {
- log.Printf("failed to kill process %s: %s", storeInfo.Setting.ProgressName, err.Error())
+ if cmdParam.Content != "" {
+ if err := KillProcessByName(cmdParam.Content); err != nil {
+ log.Printf("failed to kill process %s: %s", cmdParam.Content, err.Error())
}
} else {
if err := cmd.Process.Kill(); err != nil {
diff --git a/godo/store/map.go b/godo/store/map.go
deleted file mode 100644
index 0204a97..0000000
--- a/godo/store/map.go
+++ /dev/null
@@ -1,8 +0,0 @@
-package store
-
-type ProcessInfo struct {
- Port string
- PingPath string // 增加ping或健康检查路径
-}
-
-var ProcessInfoMap = map[string]ProcessInfo{}
diff --git a/godo/store/types.go b/godo/store/types.go
index 7458541..3f2bb49 100644
--- a/godo/store/types.go
+++ b/godo/store/types.go
@@ -65,6 +65,8 @@ type InstallStruct struct {
InstallCmds []string `json:"installCmds"` // 安装过程中需要执行的命令列表。
}
type StartStruct struct {
- StartEnvs []Item `json:"startEnvs"` // 安装过程中需要的环境变量。
- StartCmds []string `json:"startCmds"` // 安装过程中需要执行的命令列表。
+ StartEnvs []Item `json:"startEnvs"` // 启动过程中需要的环境变量。
+ BeforeCmds []string `json:"beforeCmds"` // 启动前需要执行的命令列表。
+ StartCmds []string `json:"startCmds"` // 启动过程中需要执行的命令列表。
+ AfterCmds []string `json:"afterCmds"` // 启动后需要执行的命令列表。
}