Skip to content

Commit

Permalink
Merge pull request #2 from JxQg/jxq_dev
Browse files Browse the repository at this point in the history
新增订阅节点排序功能
  • Loading branch information
JxQg authored Jan 16, 2025
2 parents ded6268 + 74aa5b2 commit ca4ae27
Show file tree
Hide file tree
Showing 9 changed files with 280 additions and 34 deletions.
51 changes: 51 additions & 0 deletions api/sub.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"github.com/goccy/go-json"
"strconv"
"strings"
"sublink/models"
Expand Down Expand Up @@ -179,3 +180,53 @@ func SubDel(c *gin.Context) {
"msg": "删除成功",
})
}

// 更新节点排序
func SubUpdateSort(c *gin.Context) {
var nodeSorts []models.SubscriptionNodes

subIDStr := c.PostForm("subId")
if subIDStr == "" {
c.JSON(400, gin.H{
"msg": "订阅ID不能为空",
})
return
}

subID, err := strconv.Atoi(subIDStr)
if err != nil {
c.JSON(400, gin.H{
"msg": "无效的订阅ID",
})
return
}

// 获取节点排序数据
nodesData := c.PostForm("nodes")
if nodesData == "" {
c.JSON(400, gin.H{
"msg": "节点数据不能为空",
})
return
}

// 解析节点排序数据
if err := json.Unmarshal([]byte(nodesData), &nodeSorts); err != nil {
c.JSON(400, gin.H{
"msg": "解析节点数据失败",
})
return
}
sn := &models.SubscriptionNodes{}
if err := sn.UpdateNodesWithSort(subID, nodeSorts); err != nil {
c.JSON(500, gin.H{
"msg": "更新排序失败",
})
return
}

c.JSON(200, gin.H{
"code": "00000",
"msg": "排序更新成功",
})
}
8 changes: 8 additions & 0 deletions models/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,13 @@ func (node *Node) List() ([]Node, error) {

// 删除节点
func (node *Node) Del() error {
// 删除节点排序信息
sn := &SubscriptionNodes{}
err := sn.DeleteNodeSortByNodeID(node.ID)
if err != nil {
return err
}

// 删除节点
return DB.Delete(node).Error
}
5 changes: 3 additions & 2 deletions models/sqlite.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package models

import (
"errors"
"log"
"os"

Expand Down Expand Up @@ -30,13 +31,13 @@ func InitSqlite() {
log.Println("数据库已经初始化,无需重复初始化")
return
}
err = db.AutoMigrate(&User{}, &Subcription{}, &Node{}, &SubLogs{})
err = db.AutoMigrate(&User{}, &Subcription{}, &Node{}, &SubLogs{}, &SubscriptionNodes{})
if err != nil {
log.Println("数据表迁移失败")
}
// 初始化用户数据
err = db.First(&User{}).Error
if err == gorm.ErrRecordNotFound {
if errors.Is(err, gorm.ErrRecordNotFound) {
admin := &User{
Username: "admin",
Password: "123456",
Expand Down
92 changes: 82 additions & 10 deletions models/subcription.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package models

import (
"sort"
)

type Subcription struct {
ID int
Name string
Expand All @@ -26,21 +30,50 @@ func (sub *Subcription) Update() error {

// 更新节点列表建立多对多关系
func (sub *Subcription) UpdateNodes() error {
return DB.Model(sub).Association("Nodes").Replace(sub.Nodes)
tx := DB.Begin()

// 清除旧的节点排序信息
err := tx.Model(&SubscriptionNodes{}).Where("subscription_id = ?", sub.ID).Delete(&SubscriptionNodes{}).Error
if err != nil {
tx.Rollback()
return err
}

// 更新节点列表并建立多对多关系
err = tx.Model(sub).Association("Nodes").Replace(sub.Nodes)
if err != nil {
tx.Rollback()
return err
}

// 保存新的节点排序信息
for i, node := range sub.Nodes {
subscriptionNode := SubscriptionNodes{
SubscriptionID: sub.ID,
NodeID: node.ID,
Sort: i + 1,
}
err = tx.Create(&subscriptionNode).Error
if err != nil {
tx.Rollback()
return err
}
}

return tx.Commit().Error
}

// 查找订阅
func (sub *Subcription) Find() error {
return DB.Where("id = ? or name = ?", sub.ID, sub.Name).First(sub).Error
if err := DB.Where("id = ? or name = ?", sub.ID, sub.Name).First(sub).Error; err != nil {
return err
}
return sub.loadNodesSorted()
}

// 读取订阅
func (sub *Subcription) GetSub() error {
// err := DB.Find(sub).Error
// if err != nil {
// return err
// }
return DB.Model(sub).Association("Nodes").Find(&sub.Nodes)
return sub.loadNodesSorted()
}

// 订阅列表
Expand All @@ -51,8 +84,12 @@ func (sub *Subcription) List() ([]Subcription, error) {
return nil, err
}
for i := range subs {
DB.Model(&subs[i]).Association("Nodes").Find(&subs[i].Nodes)
DB.Model(&subs[i]).Association("SubLogs").Find(&subs[i].SubLogs)
if err := subs[i].loadNodesSorted(); err != nil {
return nil, err
}
if logsErr := DB.Model(&subs[i]).Association("SubLogs").Find(&subs[i].SubLogs); logsErr != nil {
return nil, logsErr
}
}
return subs, nil
}
Expand All @@ -63,9 +100,44 @@ func (sub *Subcription) IPlogUpdate() error {

// 删除订阅
func (sub *Subcription) Del() error {
err := DB.Model(sub).Association("Nodes").Clear()
// 清空关联订阅的节点排序信息
sn := &SubscriptionNodes{}
err := sn.DeleteNodesBySubscriptionID(sub.ID)
if err != nil {
return err
}

// 删除订阅
return DB.Delete(sub).Error
}

// 加载排序后的节点列表
func (sub *Subcription) loadNodesSorted() error {
var subscriptionNodes []SubscriptionNodes
if err := DB.Where("subscription_id = ?", sub.ID).Find(&subscriptionNodes).Error; err != nil {
return err
}

nodeIDToSort := make(map[int]int)
for _, sn := range subscriptionNodes {
nodeIDToSort[sn.NodeID] = sn.Sort
}

if err := DB.Model(sub).Association("Nodes").Find(&sub.Nodes); err != nil {
return err
}

sort.Slice(sub.Nodes, func(i, j int) bool {
sortI, okI := nodeIDToSort[sub.Nodes[i].ID]
sortJ, okJ := nodeIDToSort[sub.Nodes[j].ID]
if !okI {
sortI = int(^uint(0) >> 1)
}
if !okJ {
sortJ = int(^uint(0) >> 1)
}
return sortI < sortJ
})

return nil
}
33 changes: 33 additions & 0 deletions models/subscriptionNodes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package models

type SubscriptionNodes struct {
SubscriptionID int `gorm:"primaryKey"`
NodeID int `gorm:"primaryKey"`
Sort int `gorm:"default:0"`
}

// 更新节点列表建立多对多关系并更新排序
func (sn *SubscriptionNodes) UpdateNodesWithSort(subID int, nodeSorts []SubscriptionNodes) error {
for _, node := range nodeSorts {
subNode := SubscriptionNodes{
SubscriptionID: subID,
NodeID: node.NodeID,
Sort: node.Sort, // 使用传入的排序字段
}
// 使用 Save 方法进行插入或更新
if err := DB.Save(&subNode).Error; err != nil {
return err
}
}
return nil
}

// 根据订阅ID删除关联的节点排序信息的方法
func (sn *SubscriptionNodes) DeleteNodesBySubscriptionID(subID int) error {
return DB.Where("subscription_id = ?", subID).Delete(&SubscriptionNodes{}).Error
}

// 根据节点ID删除节点排序信息的方法
func (sn *SubscriptionNodes) DeleteNodeSortByNodeID(nodeID int) error {
return DB.Where("node_id = ?", nodeID).Delete(&SubscriptionNodes{}).Error
}
2 changes: 1 addition & 1 deletion routers/subcription.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ func Subcription(r *gin.Engine) {
SubcriptionGroup.DELETE("/delete", api.SubDel)
SubcriptionGroup.GET("/get", api.SubGet)
SubcriptionGroup.POST("/update", api.SubUpdate)
SubcriptionGroup.POST("/sort", api.SubUpdateSort)
}

}
2 changes: 2 additions & 0 deletions webs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,15 @@
"vue": "^3.4.21",
"vue-i18n": "9.9.1",
"vue-router": "^4.3.0",
"vuedraggable": "^4.1.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@commitlint/cli": "^18.6.1",
"@commitlint/config-conventional": "^18.6.3",
"@iconify-json/ep": "^1.1.15",
"@types/lodash": "^4.17.0",
"@types/md5": "^2.3.5",
"@types/node": "^20.11.30",
"@types/nprogress": "^0.2.3",
"@types/path-browserify": "^1.0.2",
Expand Down
13 changes: 12 additions & 1 deletion webs/src/api/subcription/subs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,15 @@ export function UpdateSub(data: any){
"Content-Type": "multipart/form-data",
},
});
}
}

export function UpdateSubSort(data: any) {
return request({
url: "/api/v1/subcription/sort",
method: "post",
data,
headers: {
"Content-Type": "multipart/form-data",
},
});
}
Loading

0 comments on commit ca4ae27

Please sign in to comment.