diff --git a/backend/app/api/v1/website_group.go b/backend/app/api/v1/website_group.go index ed71ae22c..9f0d04144 100644 --- a/backend/app/api/v1/website_group.go +++ b/backend/app/api/v1/website_group.go @@ -5,10 +5,10 @@ import ( "github.com/1Panel-dev/1Panel/backend/app/dto" "github.com/1Panel-dev/1Panel/backend/constant" "github.com/gin-gonic/gin" + "strconv" ) func (b *BaseApi) GetWebGroups(c *gin.Context) { - list, err := websiteGroupService.GetGroups() if err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) @@ -18,16 +18,46 @@ func (b *BaseApi) GetWebGroups(c *gin.Context) { } func (b *BaseApi) CreateWebGroup(c *gin.Context) { - var req dto.WebSiteGroupCreate if err := c.ShouldBindJSON(&req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) return } - if err := websiteGroupService.CreateGroup(req); err != nil { helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) return } helper.SuccessWithData(c, nil) } + +func (b *BaseApi) UpdateWebGroup(c *gin.Context) { + var req dto.WebSiteGroupUpdate + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + if err := websiteGroupService.UpdateGroup(req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, nil) +} + +func (b *BaseApi) DeleteWebGroup(c *gin.Context) { + + groupId := c.Param("groupId") + if groupId == "" { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, nil) + return + } + id, err := strconv.Atoi(groupId) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + if err := websiteGroupService.DeleteGroup(uint(id)); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, nil) +} diff --git a/backend/router/ro_website_group.go b/backend/router/ro_website_group.go index 4f3895e73..d67bcf4b1 100644 --- a/backend/router/ro_website_group.go +++ b/backend/router/ro_website_group.go @@ -16,6 +16,8 @@ func (a *WebsiteGroupRouter) InitWebsiteGroupRouter(Router *gin.RouterGroup) { baseApi := v1.ApiGroupApp.BaseApi { groupRouter.GET("", baseApi.GetWebGroups) - //groupRouter.GET("", baseApi.GetGroups) + groupRouter.POST("", baseApi.CreateWebGroup) + groupRouter.PUT("", baseApi.UpdateWebGroup) + groupRouter.DELETE("/:groupId", baseApi.DeleteWebGroup) } } diff --git a/frontend/src/api/interface/website.ts b/frontend/src/api/interface/website.ts index 8284c17ff..c39d238de 100644 --- a/frontend/src/api/interface/website.ts +++ b/frontend/src/api/interface/website.ts @@ -46,4 +46,9 @@ export namespace WebSite { name: string; default: boolean; } + + export interface GroupOp { + name: string; + id?: number; + } } diff --git a/frontend/src/api/modules/website.ts b/frontend/src/api/modules/website.ts index 6ab76ce61..c2449efc7 100644 --- a/frontend/src/api/modules/website.ts +++ b/frontend/src/api/modules/website.ts @@ -6,10 +6,6 @@ export const SearchWebSites = (req: WebSite.WebSiteSearch) => { return http.post>(`/websites/search`, req); }; -export const ListGroups = () => { - return http.get(`/websites/groups`); -}; - export const CreateWebsite = (req: WebSite.WebSiteCreateReq) => { return http.post(`/websites`, req); }; @@ -17,3 +13,19 @@ export const CreateWebsite = (req: WebSite.WebSiteCreateReq) => { export const DeleteWebsite = (req: WebSite.WebSiteDel) => { return http.post(`/websites/del`, req); }; + +export const ListGroups = () => { + return http.get(`/websites/groups`); +}; + +export const CreateGroup = (req: WebSite.GroupOp) => { + return http.post(`/websites/groups`, req); +}; + +export const UpdateGroup = (req: WebSite.GroupOp) => { + return http.put(`/websites/groups`, req); +}; + +export const DeleteGroup = (id: number) => { + return http.delete(`/websites/groups/${id}`); +}; diff --git a/frontend/src/global/form-rules.ts b/frontend/src/global/form-rules.ts index c0e98dafa..c78dc2fda 100644 --- a/frontend/src/global/form-rules.ts +++ b/frontend/src/global/form-rules.ts @@ -44,6 +44,7 @@ const checkName = (rule: any, value: any, callback: any) => { interface CommonRule { requiredInput: FormItemRule; requiredSelect: FormItemRule; + requiredSelectBusiness: FormItemRule; name: FormItemRule; password: FormItemRule; email: FormItemRule; @@ -63,6 +64,14 @@ export const Rules: CommonRule = { message: i18n.global.t('commons.rule.requiredSelect'), trigger: 'change', }, + requiredSelectBusiness: { + required: true, + min: 1, + max: 65535, + type: 'number', + message: i18n.global.t('commons.rule.requiredSelect'), + trigger: 'change', + }, name: { required: true, validator: checkName, diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 9e5e1b83e..83f5f35c6 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -673,12 +673,14 @@ export default { alias: '代号', remark: '备注', group: '分组', + groupSetting: '分组管理', app: '应用', - app_new: '新装应用', - app_installed: '已装应用', + appNew: '新装应用', + appInstalled: '已装应用', create: '创建网站', delete: '删除网站', deleteApp: '删除应用', deleteBackup: '删除备份', + domain: '域名', }, }; diff --git a/frontend/src/views/website/project/create/index.vue b/frontend/src/views/website/project/create/index.vue index 3c9b85a3c..f33ed059a 100644 --- a/frontend/src/views/website/project/create/index.vue +++ b/frontend/src/views/website/project/create/index.vue @@ -21,16 +21,16 @@ - {{ $t('website.app_installed') }} + {{ $t('website.appInstalled') }} - {{ $t('website.app_new') }} + {{ $t('website.appNew') }} @@ -125,13 +125,13 @@ const website = ref({ remark: '', domains: [], appType: 'installed', - appInstallID: null, + appInstallID: 0, webSiteGroupID: 1, otherDomains: '', appinstall: { - appID: null, + appID: 0, name: '', - appDetailID: null, + appDetailID: 0, params: {}, version: '', }, @@ -140,12 +140,12 @@ let rules = ref({ primaryDomain: [Rules.requiredInput], alias: [Rules.requiredInput], type: [Rules.requiredInput], - webSiteGroupID: [Rules.requiredInput], - appInstallID: [Rules.requiredInput], + webSiteGroupID: [Rules.requiredSelectBusiness], + appInstallID: [Rules.requiredSelectBusiness], appType: [Rules.requiredInput], appinstall: { name: [Rules.requiredInput], - appID: [Rules.requiredInput], + appID: [Rules.requiredSelectBusiness], params: {}, }, }); diff --git a/frontend/src/views/website/project/group/index.vue b/frontend/src/views/website/project/group/index.vue new file mode 100644 index 000000000..e2cf7d443 --- /dev/null +++ b/frontend/src/views/website/project/group/index.vue @@ -0,0 +1,107 @@ + + diff --git a/frontend/src/views/website/project/index.vue b/frontend/src/views/website/project/index.vue index d0c566e99..a4fbe44b1 100644 --- a/frontend/src/views/website/project/index.vue +++ b/frontend/src/views/website/project/index.vue @@ -2,7 +2,8 @@ @@ -25,6 +26,7 @@ + @@ -32,15 +34,18 @@ import LayoutContent from '@/layout/layout-content.vue'; import ComplexTable from '@/components/complex-table/index.vue'; import { onMounted, reactive, ref } from '@vue/runtime-core'; -import router from '@/routers'; import CreateWebSite from './create/index.vue'; import DeleteWebsite from './delete/index.vue'; +import WebSiteGroup from './group/index.vue'; import { SearchWebSites } from '@/api/modules/website'; -import i18n from '@/lang'; import { WebSite } from '@/api/interface/website'; +import i18n from '@/lang'; +import router from '@/routers'; + const createRef = ref(); const deleteRef = ref(); +const groupRef = ref(); const paginationConfig = reactive({ currentPage: 1, @@ -86,6 +91,10 @@ const openCreate = () => { createRef.value.acceptParams(); }; +const openGroup = () => { + groupRef.value.acceptParams(); +}; + onMounted(() => { search(); });