mirror of
https://github.com/hslr-s/sun-panel.git
synced 2025-12-20 01:21:07 +08:00
[后端] 增加应用分组
This commit is contained in:
@@ -16,7 +16,7 @@ COPY . /build
|
||||
RUN pnpm run build
|
||||
|
||||
# build backend
|
||||
FROM golang:1.19 as server_image
|
||||
FROM golang:1.20 as server_image
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
|
||||
@@ -4,4 +4,5 @@ type ApiPanel struct {
|
||||
ItemIcon ItemIcon
|
||||
UserConfig UserConfig
|
||||
UsersApi UsersApi
|
||||
ItemIconGroup ItemIconGroup
|
||||
}
|
||||
|
||||
89
service/api/api_v1/panel/ItemIconGroup.go
Normal file
89
service/api/api_v1/panel/ItemIconGroup.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package panel
|
||||
|
||||
import (
|
||||
"sun-panel/api/api_v1/common/apiData/commonApiStructs"
|
||||
"sun-panel/api/api_v1/common/apiReturn"
|
||||
"sun-panel/api/api_v1/common/base"
|
||||
"sun-panel/global"
|
||||
"sun-panel/models"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
type ItemIconGroup struct {
|
||||
}
|
||||
|
||||
func (a *ItemIconGroup) Edit(c *gin.Context) {
|
||||
userInfo, _ := base.GetCurrentUserInfo(c)
|
||||
req := models.ItemIconGroup{}
|
||||
|
||||
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
|
||||
apiReturn.ErrorParamFomat(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
req.UserId = userInfo.ID
|
||||
|
||||
if req.ID != 0 {
|
||||
// 修改
|
||||
global.Db.Model(&models.ItemIconGroup{}).
|
||||
Select("IconJson", "Icon", "Title", "Url", "LanUrl", "Description", "OpenMethod", "Sort", "GroupId", "UserId").
|
||||
Where("id=?", req.ID).Updates(&req)
|
||||
} else {
|
||||
// 创建
|
||||
global.Db.Create(&req)
|
||||
}
|
||||
|
||||
apiReturn.SuccessData(c, req)
|
||||
}
|
||||
|
||||
func (a *ItemIconGroup) GetList(c *gin.Context) {
|
||||
|
||||
userInfo, _ := base.GetCurrentUserInfo(c)
|
||||
groups := []models.ItemIconGroup{}
|
||||
|
||||
if err := global.Db.Order("sort ,created_at").Where("user_id=?", userInfo.ID).Find(&groups, "user_id=?", 1, userInfo.ID).Error; err != nil {
|
||||
apiReturn.ErrorDatabase(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 判断分组是否为空,为空将自动创建默认分组
|
||||
if len(groups) == 0 {
|
||||
defaultGroup := models.ItemIconGroup{
|
||||
Title: "APP",
|
||||
UserId: userInfo.ID,
|
||||
Icon: "material-symbols:folder-outline"}
|
||||
if err := global.Db.Create(&defaultGroup).Error; err != nil {
|
||||
apiReturn.ErrorDatabase(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 并将当前账号下所有无分组的图标更新到当前组
|
||||
if err := global.Db.Model(&models.ItemIcon{}).Where("user_id=?", userInfo.ID).Update("item_icon_group_id", defaultGroup.ID).Error; err != nil {
|
||||
apiReturn.ErrorDatabase(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
groups = append(groups, defaultGroup)
|
||||
}
|
||||
|
||||
apiReturn.SuccessListData(c, groups, 0)
|
||||
}
|
||||
|
||||
func (a *ItemIconGroup) Deletes(c *gin.Context) {
|
||||
req := commonApiStructs.RequestDeleteIds[uint]{}
|
||||
|
||||
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
|
||||
apiReturn.ErrorParamFomat(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
userInfo, _ := base.GetCurrentUserInfo(c)
|
||||
if err := global.Db.Delete(&models.ItemIconGroup{}, "id in ? AND user_id=?", req.Ids, userInfo.ID).Error; err != nil {
|
||||
apiReturn.ErrorDatabase(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
apiReturn.Success(c)
|
||||
}
|
||||
@@ -25,8 +25,7 @@ func (a *ItemIcon) Edit(c *gin.Context) {
|
||||
}
|
||||
|
||||
req.UserId = userInfo.ID
|
||||
req.GroupId = 1
|
||||
req.Sort = 1
|
||||
req.Sort = 9999
|
||||
|
||||
// json转字符串
|
||||
if j, err := json.Marshal(req.Icon); err == nil {
|
||||
@@ -87,7 +86,7 @@ func (a *ItemIcon) GetListByGroupId(c *gin.Context) {
|
||||
userInfo, _ := base.GetCurrentUserInfo(c)
|
||||
itemIcons := []models.ItemIcon{}
|
||||
|
||||
if err := global.Db.Order("sort ,created_at DESC").Where("user_id=?", userInfo.ID).Find(&itemIcons, "group_id = ? AND user_id=?", 1, userInfo.ID).Error; err != nil {
|
||||
if err := global.Db.Order("sort ,created_at").Where("user_id=?", userInfo.ID).Find(&itemIcons, "group_id = ? AND user_id=?", 1, userInfo.ID).Error; err != nil {
|
||||
apiReturn.ErrorDatabase(c, err.Error())
|
||||
return
|
||||
}
|
||||
@@ -108,7 +107,7 @@ func (a *ItemIcon) Deletes(c *gin.Context) {
|
||||
}
|
||||
|
||||
userInfo, _ := base.GetCurrentUserInfo(c)
|
||||
if err := global.Db.Debug().Delete(&models.ItemIcon{}, "id in ? AND user_id=?", req.Ids, userInfo.ID).Error; err != nil {
|
||||
if err := global.Db.Delete(&models.ItemIcon{}, "id in ? AND user_id=?", req.Ids, userInfo.ID).Error; err != nil {
|
||||
apiReturn.ErrorDatabase(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ func CreateDatabase(driver string, db *gorm.DB) error {
|
||||
&models.ItemIcon{},
|
||||
&models.UserConfig{},
|
||||
&models.File{},
|
||||
&models.ItemIconGroup{},
|
||||
)
|
||||
|
||||
return err
|
||||
|
||||
@@ -12,7 +12,7 @@ type ItemIcon struct {
|
||||
Description string `gorm:"type:varchar(1000)" json:"description"`
|
||||
OpenMethod int `gorm:"type:tinyint(1)" json:"openMethod"`
|
||||
Sort int `gorm:"type:int(11)" json:"sort"`
|
||||
GroupId int `json:"groupId"` // 为以后分组做准备
|
||||
ItemIconGroupId int `json:"itemIconGroupId"`
|
||||
UserId uint `json:"userId"`
|
||||
User User `json:"user"`
|
||||
}
|
||||
|
||||
11
service/models/itemIconGroup.go
Normal file
11
service/models/itemIconGroup.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
type ItemIconGroup struct {
|
||||
BaseModel
|
||||
Icon string `json:"icon"`
|
||||
Title string `gorm:"type:varchar(50)" json:"title"`
|
||||
Description string `gorm:"type:varchar(1000)" json:"description"`
|
||||
Sort int `gorm:"type:int(11)" json:"sort"`
|
||||
UserId uint `json:"userId"`
|
||||
User User `json:"user"`
|
||||
}
|
||||
@@ -6,4 +6,5 @@ func Init(routerGroup *gin.RouterGroup) {
|
||||
InitItemIcon(routerGroup)
|
||||
InitUserConfig(routerGroup)
|
||||
InitUsersRouter(routerGroup)
|
||||
InitItemIconGroup(routerGroup)
|
||||
}
|
||||
|
||||
18
service/router/panel/itemIconGroup.go
Normal file
18
service/router/panel/itemIconGroup.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package panel
|
||||
|
||||
import (
|
||||
"sun-panel/api/api_v1"
|
||||
"sun-panel/api/api_v1/middleware"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func InitItemIconGroup(router *gin.RouterGroup) {
|
||||
itemIconGroup := api_v1.ApiGroupApp.ApiPanel.ItemIconGroup
|
||||
r := router.Group("", middleware.LoginInterceptor)
|
||||
{
|
||||
r.POST("/panel/itemIconGroup/edit", itemIconGroup.Edit)
|
||||
r.POST("/panel/itemIconGroup/getList", itemIconGroup.GetList)
|
||||
r.POST("/panel/itemIconGroup/deletes", itemIconGroup.Deletes)
|
||||
}
|
||||
}
|
||||
@@ -231,6 +231,7 @@ onMounted(() => {
|
||||
:animation="300"
|
||||
class="mx-auto mt-4 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:12 gap-5"
|
||||
@end="handleEndDrag"
|
||||
filter=".not-drag"
|
||||
>
|
||||
<div v-for="item, index in items" :key="index" @contextmenu="(e) => handleContextMenu(e, item)">
|
||||
<div
|
||||
@@ -254,6 +255,28 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="not-drag">
|
||||
<div
|
||||
class="w-full rounded-2xl cursor-pointer transition-all duration-200 hover:shadow-[0_0_20px_10px_rgba(0,0,0,0.2)] bg-[#2a2a2a6b] flex"
|
||||
@click="handleAddAppClick"
|
||||
>
|
||||
<ItemIcon :item-icon="{ itemType: 3, text: 'subway:add', bgColor: '#00000000' }" />
|
||||
<div class="text-white m-[8px]" :style="{ color: panelState.panelConfig.iconTextColor }">
|
||||
<div>
|
||||
<NEllipsis>
|
||||
添加图标
|
||||
</NEllipsis>
|
||||
</div>
|
||||
|
||||
<div class="text text-xs">
|
||||
<NEllipsis>
|
||||
新增一个新的图标
|
||||
</NEllipsis>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</vuedraggable>
|
||||
<!-- <NGrid :x-gap="15" :y-gap="15" item-responsive cols="1 200:1 400:2 600:3 800:4 1000:5 1200:6">
|
||||
<NGridItem v-for="(item, index) in items" :key="index">
|
||||
@@ -314,6 +337,7 @@ onMounted(() => {
|
||||
item-key="id"
|
||||
:animation="300"
|
||||
class="mx-auto mt-4 grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 lg:grid-cols-10 xl:12 gap-5"
|
||||
filter=".not-drag"
|
||||
>
|
||||
<div v-for="item, index in items" :key="index" @contextmenu="(e) => handleContextMenu(e, item)">
|
||||
<div
|
||||
@@ -326,6 +350,16 @@ onMounted(() => {
|
||||
<span>{{ item.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="not-drag">
|
||||
<div class="w-[70px] h-[70px] mx-auto rounded-2xl cursor-pointer transition-all duration-200 hover:shadow-[0_0_20px_10px_rgba(0,0,0,0.2)]" @click="handleAddAppClick">
|
||||
<ItemIcon :item-icon="{ itemType: 3, text: 'subway:add', bgColor: '#343434' }" />
|
||||
</div>
|
||||
<div class="text-center app-icon-text-shadow cursor-pointer mt-[2px]" :style="{ color: panelState.panelConfig.iconTextColor }" @click="handleAddAppClick">
|
||||
添加图标
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</vuedraggable>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user