From 26039cc19d43ffc1db53d23c74b86c41ccc140af Mon Sep 17 00:00:00 2001 From: zhengkunwang223 Date: Sun, 4 Dec 2022 17:45:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=89=E8=A3=85=E7=BD=91=E7=AB=99?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/website.go | 15 ++++- backend/app/dto/website.go | 11 ++++ backend/app/repo/app_install.go | 2 +- backend/app/service/app_install.go | 5 ++ backend/app/service/website.go | 49 +++++++++++++++ backend/constant/errs.go | 2 +- backend/i18n/lang/en.yaml | 1 + backend/i18n/lang/zh.yaml | 1 + backend/router/ro_website.go | 1 + frontend/src/api/interface/website.ts | 11 ++++ frontend/src/api/modules/website.ts | 4 ++ frontend/src/lang/modules/zh.ts | 3 + .../src/views/website/website/check/index.vue | 61 +++++++++++++++++++ .../views/website/website/create/index.vue | 26 +++++--- 14 files changed, 181 insertions(+), 11 deletions(-) create mode 100644 frontend/src/views/website/website/check/index.vue diff --git a/backend/app/api/v1/website.go b/backend/app/api/v1/website.go index c995abe72..c221b7cc5 100644 --- a/backend/app/api/v1/website.go +++ b/backend/app/api/v1/website.go @@ -2,7 +2,6 @@ package v1 import ( "errors" - "github.com/1Panel-dev/1Panel/backend/app/api/v1/helper" "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/constant" @@ -255,3 +254,17 @@ func (b *BaseApi) UpdateHTTPSConfig(c *gin.Context) { } helper.SuccessWithData(c, res) } + +func (b *BaseApi) CreateWebsiteCheck(c *gin.Context) { + var req dto.WebsiteInstallCheckReq + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + data, err := websiteService.PreInstallCheck(req) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, data) +} diff --git a/backend/app/dto/website.go b/backend/app/dto/website.go index 35f3320a1..553e74468 100644 --- a/backend/app/dto/website.go +++ b/backend/app/dto/website.go @@ -110,3 +110,14 @@ type WebsiteNginxConfig struct { Enable bool `json:"enable"` Params []NginxParam `json:"params"` } + +type WebsitePreInstallCheck struct { + Name string `json:"name"` + Status string `json:"status"` + Version string `json:"version"` + AppName string `json:"appName"` +} + +type WebsiteInstallCheckReq struct { + InstallIds []uint `json:"InstallIds"` +} diff --git a/backend/app/repo/app_install.go b/backend/app/repo/app_install.go index 5b18be938..d015d4631 100644 --- a/backend/app/repo/app_install.go +++ b/backend/app/repo/app_install.go @@ -112,7 +112,7 @@ type RootInfo struct { Version string `json:"version"` } -func (u *AppInstallRepo) LoadBaseInfoByKey(key string) (*RootInfo, error) { +func (a *AppInstallRepo) LoadBaseInfoByKey(key string) (*RootInfo, error) { var ( app model.App appInstall model.AppInstall diff --git a/backend/app/service/app_install.go b/backend/app/service/app_install.go index 2232b288c..5088e5ab8 100644 --- a/backend/app/service/app_install.go +++ b/backend/app/service/app_install.go @@ -48,6 +48,7 @@ func (a AppInstallService) Page(req dto.AppInstalledRequest) (int64, []dto.AppIn } func (a AppInstallService) CheckExist(key string) (*dto.CheckInstalled, error) { + res := &dto.CheckInstalled{ IsExist: false, } @@ -60,6 +61,10 @@ func (a AppInstallService) CheckExist(key string) (*dto.CheckInstalled, error) { if reflect.DeepEqual(appInstall, model.AppInstall{}) { return res, nil } + if err := syncById(appInstall.ID); err != nil { + return nil, err + } + res.ContainerName = appInstall.ContainerName res.Name = appInstall.Name res.Version = appInstall.Version diff --git a/backend/app/service/website.go b/backend/app/service/website.go index 131eda91b..fef7d7586 100644 --- a/backend/app/service/website.go +++ b/backend/app/service/website.go @@ -511,6 +511,55 @@ func (w WebsiteService) OpWebsiteHTTPS(req dto.WebsiteHTTPSOp) (dto.WebsiteHTTPS return res, nil } +func (w WebsiteService) PreInstallCheck(req dto.WebsiteInstallCheckReq) ([]dto.WebsitePreInstallCheck, error) { + var ( + res []dto.WebsitePreInstallCheck + checkIds []uint + showErr = false + ) + + app, err := appRepo.GetFirst(appRepo.WithKey("nginx")) + if err != nil { + return nil, err + } + appInstall, _ := appInstallRepo.GetFirst(appInstallRepo.WithAppId(app.ID)) + if reflect.DeepEqual(appInstall, model.AppInstall{}) { + res = append(res, dto.WebsitePreInstallCheck{ + Name: appInstall.Name, + AppName: app.Name, + Status: buserr.WithMessage(constant.ErrNotInstall, app.Name, nil).Error(), + Version: appInstall.Version, + }) + showErr = true + } else { + checkIds = append(req.InstallIds, appInstall.ID) + } + for _, id := range checkIds { + if err := syncById(id); err != nil { + return nil, err + } + } + if len(checkIds) > 0 { + installList, _ := appInstallRepo.GetBy(commonRepo.WithIdsIn(checkIds)) + for _, install := range installList { + res = append(res, dto.WebsitePreInstallCheck{ + Name: install.Name, + Status: install.Status, + Version: install.Version, + AppName: install.App.Name, + }) + if install.Status != constant.StatusRunning { + showErr = true + } + } + } + if showErr { + return res, nil + } else { + return nil, nil + } +} + type WebSiteInfo struct { WebsiteName string `json:"websiteName"` WebsiteType string `json:"websiteType"` diff --git a/backend/constant/errs.go b/backend/constant/errs.go index 84f0e695e..bd2dea298 100644 --- a/backend/constant/errs.go +++ b/backend/constant/errs.go @@ -51,10 +51,10 @@ var ( ErrAppRequired = "ErrAppRequired" ErrFileCanNotRead = "ErrFileCanNotRead" ErrFileToLarge = "ErrFileToLarge" + ErrNotInstall = "ErrNotInstall" ) //website - var ( ErrDomainIsExist = "ErrDomainIsExist" ErrAliasIsExist = "ErrAliasIsExist" diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml index 0dbcaf6ee..3f8ae2429 100644 --- a/backend/i18n/lang/en.yaml +++ b/backend/i18n/lang/en.yaml @@ -22,6 +22,7 @@ ErrNameIsExist: "Name is already exist" ErrPortInUsed: "{{ .detail }} port already in use" ErrAppLimit: "App exceeds install limit" ErrAppRequired: "{{ .detail }} app is required" +ErrNotInstall: "App not installed" #file diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml index b35fc806a..faf06934c 100644 --- a/backend/i18n/lang/zh.yaml +++ b/backend/i18n/lang/zh.yaml @@ -22,6 +22,7 @@ ErrNameIsExist: "名称已存在" ErrPortInUsed: "{{ .detail }} 端口已被占用!" ErrAppLimit: "应用超出安装数量限制" ErrAppRequired: "请先安装 {{ .detail }} 应用" +ErrNotInstall: "应用未安装" #file diff --git a/backend/router/ro_website.go b/backend/router/ro_website.go index b898e6a24..3a02b15b6 100644 --- a/backend/router/ro_website.go +++ b/backend/router/ro_website.go @@ -16,6 +16,7 @@ func (a *WebsiteRouter) InitWebsiteRouter(Router *gin.RouterGroup) { baseApi := v1.ApiGroupApp.BaseApi { groupRouter.POST("", baseApi.CreateWebsite) + groupRouter.POST("/check", baseApi.CreateWebsiteCheck) groupRouter.GET("/options", baseApi.GetWebsiteOptions) groupRouter.POST("/backup/:domain", baseApi.BackupWebsite) groupRouter.POST("/recover", baseApi.RecoverWebsite) diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 66122eb4f..20fd3a4db 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -201,4 +201,15 @@ export namespace WebSite { enable: boolean; SSL: SSL; } + + export interface CheckReq { + installIds?: number[]; + } + + export interface CheckRes { + name: string; + status: string; + version: string; + appName: string; + } } diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index f9dcbe1a5..1dfb39f4b 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -144,3 +144,7 @@ export const GetHTTPSConfig = (id: number) => { export const UpdateHTTPSConfig = (req: WebSite.HTTPSReq) => { return http.post(`/websites/${req.websiteId}/https`, req); }; + +export const PreCheck = (req: WebSite.CheckReq) => { + return http.post(`/websites/check`, req); +}; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 20bc3f089..db170171f 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -712,6 +712,7 @@ export default { }, app: { app: '应用', + installName: '安装名称', installed: '已安装', all: '全部', version: '版本', @@ -826,6 +827,8 @@ export default { protocol: '协议', setDefault: '设为默认', default: '默认', + deleteHelper: '相关应用状态不正常,请检查', + toApp: '去已安装列表', }, nginx: { serverNamesHashBucketSizeHelper: '服务器名字的hash表大小', diff --git a/frontend/src/views/website/website/check/index.vue b/frontend/src/views/website/website/check/index.vue new file mode 100644 index 000000000..ad212bdce --- /dev/null +++ b/frontend/src/views/website/website/check/index.vue @@ -0,0 +1,61 @@ + + diff --git a/frontend/src/views/website/website/create/index.vue b/frontend/src/views/website/website/create/index.vue index 297325a7d..82b5f211b 100644 --- a/frontend/src/views/website/website/create/index.vue +++ b/frontend/src/views/website/website/create/index.vue @@ -115,6 +115,7 @@ + @@ -122,12 +123,13 @@ import { App } from '@/api/interface/app'; import { WebSite } from '@/api/interface/website'; import { GetApp, GetAppDetail, SearchApp, GetAppInstalled } from '@/api/modules/app'; -import { CreateWebsite, ListGroups } from '@/api/modules/website'; +import { CreateWebsite, ListGroups, PreCheck } from '@/api/modules/website'; import { Rules } from '@/global/form-rules'; import i18n from '@/lang'; import { ElDialog, ElForm, FormInstance, ElMessage } from 'element-plus'; import { reactive, ref } from 'vue'; import Params from '@/views/app-store/detail/params/index.vue'; +import Check from '../check/index.vue'; const websiteForm = ref(); const website = ref({ @@ -175,6 +177,7 @@ let appVersions = ref([]); let appDetail = ref(); let appParams = ref(); let paramKey = ref(1); +let preCheckRef = ref(); const em = defineEmits(['close']); @@ -248,14 +251,21 @@ const submit = async (formEl: FormInstance | undefined) => { return; } loading.value = true; - CreateWebsite(website.value) - .then(() => { - ElMessage.success(i18n.global.t('commons.msg.createSuccess')); - handleClose(); - }) - .finally(() => { + PreCheck({}).then((res) => { + if (res.data) { loading.value = false; - }); + preCheckRef.value.acceptParams({ items: res.data }); + } else { + CreateWebsite(website.value) + .then(() => { + ElMessage.success(i18n.global.t('commons.msg.createSuccess')); + handleClose(); + }) + .finally(() => { + loading.value = false; + }); + } + }); }); };