diff --git a/backend/app/service/app_utils.go b/backend/app/service/app_utils.go index c0ff8ad33..6ccc33889 100644 --- a/backend/app/service/app_utils.go +++ b/backend/app/service/app_utils.go @@ -1107,11 +1107,7 @@ func handleLocalAppDetail(versionDir string, appDetail *model.AppDetail) error { return buserr.WithMap(constant.ErrFileParseApp, map[string]interface{}{"name": "data.yml", "err": err.Error()}, err) } - additionalProperties, ok := dataMap["additionalProperties"].(map[string]interface{}) - if !ok { - return buserr.WithName(constant.ErrAppParamKey, "additionalProperties") - } - + additionalProperties, _ := dataMap["additionalProperties"].(map[string]interface{}) formFieldsInterface, ok := additionalProperties["formFields"] if ok { formFields, ok := formFieldsInterface.([]interface{}) diff --git a/backend/app/service/runtime.go b/backend/app/service/runtime.go index b1ed2a0db..638c87875 100644 --- a/backend/app/service/runtime.go +++ b/backend/app/service/runtime.go @@ -83,7 +83,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e if exist != nil { return nil, buserr.New(constant.ErrImageExist) } - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: if !fileOp.Stat(create.CodeDir) { return nil, buserr.New(constant.ErrPathNotFound) } @@ -113,7 +113,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e } appVersionDir := filepath.Join(app.GetAppResourcePath(), appDetail.Version) - if !fileOp.Stat(appVersionDir) || appDetail.Update { + if !fileOp.Stat(appVersionDir) { if err = downloadApp(app, appDetail, nil); err != nil { return nil, err } @@ -133,7 +133,7 @@ func (r *RuntimeService) Create(create request.RuntimeCreate) (*model.Runtime, e if err = handlePHP(create, runtime, fileOp, appVersionDir); err != nil { return nil, err } - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: runtime.Port = create.Port if err = handleNodeAndJava(create, runtime, fileOp, appVersionDir); err != nil { return nil, err @@ -217,7 +217,7 @@ func (r *RuntimeService) Delete(runtimeDelete request.RuntimeDelete) error { global.LOG.Errorf("delete image id [%s] error %v", imageID, err) } } - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: if out, err := compose.Down(runtime.GetComposePath()); err != nil && !runtimeDelete.ForceDelete { if out != "" { return errors.New(out) @@ -300,7 +300,7 @@ func (r *RuntimeService) Get(id uint) (*response.RuntimeDTO, error) { } } res.AppParams = appParams - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: res.Params = make(map[string]interface{}) envs, err := gotenv.Unmarshal(runtime.Env) if err != nil { @@ -361,7 +361,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error { if exist != nil { return buserr.New(constant.ErrImageExist) } - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: if runtime.Port != req.Port { if err = checkPortExist(req.Port); err != nil { return err @@ -441,7 +441,7 @@ func (r *RuntimeService) Update(req request.RuntimeUpdate) error { return err } go buildRuntime(runtime, imageID, req.Rebuild) - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: runtime.Version = req.Version runtime.CodeDir = req.CodeDir runtime.Port = req.Port @@ -613,7 +613,7 @@ func (r *RuntimeService) SyncRuntimeStatus() error { return err } for _, runtime := range runtimes { - if runtime.Type == constant.RuntimeNode || runtime.Type == constant.RuntimeJava || runtime.Type == constant.RuntimeGo { + if runtime.Type != constant.RuntimePHP { _ = SyncRuntimeContainerStatus(&runtime) } } diff --git a/backend/app/service/runtime_utils.go b/backend/app/service/runtime_utils.go index ecb43abbf..d1bbf6633 100644 --- a/backend/app/service/runtime_utils.go +++ b/backend/app/service/runtime_utils.go @@ -354,6 +354,14 @@ func handleParams(create request.RuntimeCreate, projectDir string) (composeConte if err != nil { return } + case constant.RuntimeDoNet: + create.Params["CODE_DIR"] = create.CodeDir + create.Params["DONET_VERSION"] = create.Version + create.Params["PANEL_APP_PORT_HTTP"] = create.Port + composeContent, err = handleCompose(env, composeContent, create, projectDir) + if err != nil { + return + } } newMap := make(map[string]string) @@ -400,7 +408,7 @@ func handleCompose(env gotenv.Env, composeContent []byte, create request.Runtime ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${JAVA_APP_PORT}") case constant.RuntimeGo: ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${GO_APP_PORT}") - case constant.RuntimePython: + case constant.RuntimePython, constant.RuntimeDoNet: ports = append(ports, "${HOST_IP}:${PANEL_APP_PORT_HTTP}:${APP_PORT}") } diff --git a/backend/app/service/website.go b/backend/app/service/website.go index b55ee8a86..4bf21ccb0 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -352,7 +352,7 @@ func (w WebsiteService) CreateWebsite(create request.WebsiteCreate) (err error) } website.Proxy = proxy } - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: website.Proxy = fmt.Sprintf("127.0.0.1:%d", runtime.Port) } } diff --git a/backend/app/service/website_utils.go b/backend/app/service/website_utils.go index 88e256273..14e2125a2 100644 --- a/backend/app/service/website_utils.go +++ b/backend/app/service/website_utils.go @@ -277,7 +277,7 @@ func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, a server.UpdateRoot(rootIndex) server.UpdatePHPProxy([]string{website.Proxy}, "") } - case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython: + case constant.RuntimeNode, constant.RuntimeJava, constant.RuntimeGo, constant.RuntimePython, constant.RuntimeDoNet: proxy := fmt.Sprintf("http://127.0.0.1:%d", runtime.Port) server.UpdateRootProxy([]string{proxy}) } diff --git a/backend/constant/common.go b/backend/constant/common.go index f9f0b33aa..8707b6389 100644 --- a/backend/constant/common.go +++ b/backend/constant/common.go @@ -99,6 +99,7 @@ var WebUrlMap = map[string]struct{}{ "/websites/runtimes/net": {}, "/websites/runtimes/go": {}, "/websites/runtimes/python": {}, + "/websites/runtimes/donet": {}, "/login": {}, diff --git a/backend/constant/runtime.go b/backend/constant/runtime.go index 558948703..cc4e89881 100644 --- a/backend/constant/runtime.go +++ b/backend/constant/runtime.go @@ -19,6 +19,7 @@ const ( RuntimeJava = "java" RuntimeGo = "go" RuntimePython = "python" + RuntimeDoNet = "donet" RuntimeProxyUnix = "unix" RuntimeProxyTcp = "tcp" diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts index 2de099497..85cc15381 100644 --- a/frontend/src/lang/modules/en.ts +++ b/frontend/src/lang/modules/en.ts @@ -2428,6 +2428,7 @@ const message = { goDirHelper: 'The directory must contain go files or binary files, subdirectories are also acceptable', pythonHelper: 'Please fill in the complete startup command, for example: pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000', + donetHelper: 'Please fill in the complete startup comman, for example: dotnet MyWebApp.dll', }, process: { pid: 'Process ID', diff --git a/frontend/src/lang/modules/tw.ts b/frontend/src/lang/modules/tw.ts index 71fe21f8d..c2dda6f19 100644 --- a/frontend/src/lang/modules/tw.ts +++ b/frontend/src/lang/modules/tw.ts @@ -2247,6 +2247,7 @@ const message = { goDirHelper: '目錄中要包含 go 文件或者二進制文件,子目錄中包含也可', pythonHelper: '請填入完整啟動指令,例如:pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000', + donetHelper: '請填入完整啟動指令,例如 dotnet MyWebApp.dll', }, process: { pid: '進程ID', diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index d8538ddf0..1285a2317 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -2249,6 +2249,7 @@ const message = { goDirHelper: '目录中要包含 go 文件或者二进制文件,子目录中包含也可', pythonHelper: '请填写完整启动命令,例如:pip install -r requirements.txt && python manage.py runserver 0.0.0.0:5000', + donetHelper: '请填写完整启动命令,例如 dotnet MyWebApp.dll', }, process: { pid: '进程ID', diff --git a/frontend/src/routers/modules/website.ts b/frontend/src/routers/modules/website.ts index 4571b23a6..945990dbf 100644 --- a/frontend/src/routers/modules/website.ts +++ b/frontend/src/routers/modules/website.ts @@ -88,6 +88,16 @@ const webSiteRouter = { requiresAuth: false, }, }, + { + path: '/websites/runtimes/donet', + name: 'doNet', + hidden: true, + component: () => import('@/views/website/runtime/donet/index.vue'), + meta: { + activeMenu: '/websites/runtimes/php', + requiresAuth: false, + }, + }, ], }; diff --git a/frontend/src/views/app-store/apps/index.vue b/frontend/src/views/app-store/apps/index.vue index 8ae80e3e2..b397c618d 100644 --- a/frontend/src/views/app-store/apps/index.vue +++ b/frontend/src/views/app-store/apps/index.vue @@ -237,6 +237,7 @@ const openInstall = (app: App.App) => { case 'java': case 'go': case 'python': + case 'donet': router.push({ path: '/websites/runtimes/' + app.type }); break; default: diff --git a/frontend/src/views/app-store/detail/index.vue b/frontend/src/views/app-store/detail/index.vue index c3fb4cb97..0498116d0 100644 --- a/frontend/src/views/app-store/detail/index.vue +++ b/frontend/src/views/app-store/detail/index.vue @@ -146,6 +146,7 @@ const openInstall = () => { case 'java': case 'go': case 'python': + case 'donet': router.push({ path: '/websites/runtimes/' + app.value.type }); break; default: diff --git a/frontend/src/views/home/app/index.vue b/frontend/src/views/home/app/index.vue index e7eccf217..e5f4c7417 100644 --- a/frontend/src/views/home/app/index.vue +++ b/frontend/src/views/home/app/index.vue @@ -67,10 +67,12 @@ const acceptParams = (): void => { const goInstall = (key: string, type: string) => { switch (type) { case 'php': - router.push({ path: '/websites/runtimes/php' }); - break; case 'node': - router.push({ path: '/websites/runtimes/node' }); + case 'java': + case 'go': + case 'python': + case 'donet': + router.push({ path: '/websites/runtimes/' + type }); break; default: router.push({ name: 'AppAll', query: { install: key } }); diff --git a/frontend/src/views/website/runtime/donet/index.vue b/frontend/src/views/website/runtime/donet/index.vue new file mode 100644 index 000000000..a376dfab3 --- /dev/null +++ b/frontend/src/views/website/runtime/donet/index.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/frontend/src/views/website/runtime/donet/operate/index.vue b/frontend/src/views/website/runtime/donet/operate/index.vue new file mode 100644 index 000000000..1a6755a44 --- /dev/null +++ b/frontend/src/views/website/runtime/donet/operate/index.vue @@ -0,0 +1,394 @@ + + + diff --git a/frontend/src/views/website/runtime/index.vue b/frontend/src/views/website/runtime/index.vue index 2fa8d18df..f44c36598 100644 --- a/frontend/src/views/website/runtime/index.vue +++ b/frontend/src/views/website/runtime/index.vue @@ -29,5 +29,9 @@ const buttons = [ label: 'Python', path: '/websites/runtimes/python', }, + { + label: '.NET', + path: '/websites/runtimes/donet', + }, ];