235 lines
7.2 KiB
Go
235 lines
7.2 KiB
Go
package data
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"kra/internal/biz"
|
|
)
|
|
|
|
type versionPO struct {
|
|
ID uint `gorm:"primaryKey"`
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
|
Name string `gorm:"column:version_name"`
|
|
Code string `gorm:"column:version_code"`
|
|
Description string
|
|
Data string `gorm:"column:version_data;type:text"`
|
|
}
|
|
|
|
func (versionPO) TableName() string { return "sys_versions" }
|
|
|
|
type versionRepo struct{ data *Data }
|
|
|
|
func NewVersionRepo(data *Data) biz.VersionRepo { return &versionRepo{data: data} }
|
|
func versionFromPO(v versionPO) *biz.Version {
|
|
return &biz.Version{ID: v.ID, CreatedAt: v.CreatedAt, UpdatedAt: v.UpdatedAt, Name: v.Name, Code: v.Code, Description: v.Description, Data: v.Data}
|
|
}
|
|
func (r *versionRepo) CreateVersion(ctx context.Context, v *biz.Version) error {
|
|
po := versionPO{Name: v.Name, Code: v.Code, Description: v.Description, Data: v.Data}
|
|
if err := r.data.gormDB.WithContext(ctx).Create(&po).Error; err != nil {
|
|
return err
|
|
}
|
|
v.ID = po.ID
|
|
return nil
|
|
}
|
|
func (r *versionRepo) DeleteVersions(ctx context.Context, ids []uint) error {
|
|
return r.data.gormDB.WithContext(ctx).Delete(&versionPO{}, ids).Error
|
|
}
|
|
func (r *versionRepo) FindVersion(ctx context.Context, id uint) (*biz.Version, error) {
|
|
var po versionPO
|
|
if err := r.data.gormDB.WithContext(ctx).First(&po, id).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
return versionFromPO(po), nil
|
|
}
|
|
func (r *versionRepo) ListVersions(ctx context.Context, page, size int, name, code string, createdAtRange []*time.Time) ([]*biz.Version, int64, error) {
|
|
db := r.data.gormDB.WithContext(ctx).Model(&versionPO{})
|
|
if len(createdAtRange) == 2 && createdAtRange[0] != nil && createdAtRange[1] != nil {
|
|
db = db.Where("created_at BETWEEN ? AND ?", createdAtRange[0], createdAtRange[1])
|
|
}
|
|
if name != "" {
|
|
db = db.Where("version_name LIKE ?", "%"+name+"%")
|
|
}
|
|
if code != "" {
|
|
db = db.Where("version_code = ?", code)
|
|
}
|
|
var total int64
|
|
if err := db.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
var pos []versionPO
|
|
if err := applyPagination(db, page, size, 100).Find(&pos).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
out := make([]*biz.Version, 0, len(pos))
|
|
for _, po := range pos {
|
|
out = append(out, versionFromPO(po))
|
|
}
|
|
return out, total, nil
|
|
}
|
|
func (r *versionRepo) BuildVersionBundle(ctx context.Context, menuIDs, apiIDs, dictIDs []uint) (*biz.VersionBundle, error) {
|
|
bundle := &biz.VersionBundle{}
|
|
var menus []menuPO
|
|
if len(menuIDs) > 0 {
|
|
if err := r.data.gormDB.WithContext(ctx).Where("id IN ?", menuIDs).Order("sort,id").Find(&menus).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
byID := map[uint]*biz.Menu{}
|
|
for _, po := range menus {
|
|
v := menuFromPO(po)
|
|
v.Children = []*biz.Menu{}
|
|
var btns []menuButtonPO
|
|
_ = r.data.gormDB.WithContext(ctx).Where("sys_base_menu_id = ?", po.ID).Find(&btns).Error
|
|
for _, btn := range btns {
|
|
v.Buttons = append(v.Buttons, &biz.MenuButton{Name: btn.Name, Description: btn.Description})
|
|
}
|
|
byID[po.ID] = v
|
|
}
|
|
if len(menuIDs) > 0 {
|
|
var parameters []menuParameterPO
|
|
if err := r.data.gormDB.WithContext(ctx).Where("sys_base_menu_id IN ?", menuIDs).Find(¶meters).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
for _, parameter := range parameters {
|
|
if menu := byID[parameter.MenuID]; menu != nil {
|
|
menu.Parameters = append(menu.Parameters, &biz.MenuParameter{Type: parameter.Type, Key: parameter.Key, Value: parameter.Value})
|
|
}
|
|
}
|
|
}
|
|
for _, po := range menus {
|
|
v := byID[po.ID]
|
|
if parent := byID[po.ParentID]; parent != nil {
|
|
parent.Children = append(parent.Children, v)
|
|
} else if po.ParentID == 0 {
|
|
bundle.Menus = append(bundle.Menus, v)
|
|
}
|
|
}
|
|
var cleanMenu func(*biz.Menu)
|
|
cleanMenu = func(menu *biz.Menu) {
|
|
menu.ID = 0
|
|
menu.ParentID = 0
|
|
for _, button := range menu.Buttons {
|
|
button.ID = 0
|
|
button.MenuID = 0
|
|
button.AuthorityID = 0
|
|
}
|
|
for _, parameter := range menu.Parameters {
|
|
parameter.ID = 0
|
|
parameter.MenuID = 0
|
|
}
|
|
for _, child := range menu.Children {
|
|
cleanMenu(child)
|
|
}
|
|
}
|
|
for _, menu := range bundle.Menus {
|
|
cleanMenu(menu)
|
|
}
|
|
var apis []apiPO
|
|
if len(apiIDs) > 0 {
|
|
if err := r.data.gormDB.WithContext(ctx).Where("id IN ?", apiIDs).Find(&apis).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
for _, po := range apis {
|
|
v := apiFromPO(po)
|
|
v.ID = 0
|
|
bundle.APIs = append(bundle.APIs, v)
|
|
}
|
|
var dictionaries []dictionaryPO
|
|
if len(dictIDs) > 0 {
|
|
if err := r.data.gormDB.WithContext(ctx).Where("id IN ?", dictIDs).Find(&dictionaries).Error; err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
settings := &settingsRepo{data: r.data}
|
|
for _, po := range dictionaries {
|
|
v := dictionaryFromPO(po)
|
|
v.ID = 0
|
|
details, _, err := settings.ListDictionaryDetails(ctx, 0, 0, biz.DictionaryDetailFilter{DictionaryID: po.ID})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, d := range details {
|
|
d.ID = 0
|
|
d.DictionaryID = 0
|
|
d.ParentID = nil
|
|
d.Path = ""
|
|
d.Level = 0
|
|
}
|
|
v.Details = details
|
|
bundle.Dictionaries = append(bundle.Dictionaries, v)
|
|
}
|
|
return bundle, nil
|
|
}
|
|
func (r *versionRepo) ImportVersionBundle(ctx context.Context, b *biz.VersionBundle) error {
|
|
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
|
var addMenus func([]*biz.Menu, uint) error
|
|
addMenus = func(items []*biz.Menu, parent uint) error {
|
|
for _, item := range items {
|
|
var existing menuPO
|
|
err := tx.Where("name = ? AND path = ?", item.Name, item.Path).First(&existing).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
po := menuToPO(item)
|
|
po.ID = 0
|
|
po.ParentID = parent
|
|
if err = tx.Create(&po).Error; err != nil {
|
|
return err
|
|
}
|
|
existing = po
|
|
for _, button := range item.Buttons {
|
|
if err = tx.Create(&menuButtonPO{Name: button.Name, Description: button.Description, MenuID: po.ID}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
for _, parameter := range item.Parameters {
|
|
if err = tx.Create(&menuParameterPO{MenuID: po.ID, Type: parameter.Type, Key: parameter.Key, Value: parameter.Value}).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
if err = addMenus(item.Children, existing.ID); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
if err := addMenus(b.Menus, 0); err != nil {
|
|
return err
|
|
}
|
|
for _, item := range b.APIs {
|
|
po := apiPO{Path: item.Path, Description: item.Description, APIGroup: item.APIGroup, Method: strings.ToUpper(item.Method)}
|
|
if err := tx.Where("path = ? AND method = ?", po.Path, po.Method).FirstOrCreate(&po).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
for _, item := range b.Dictionaries {
|
|
var count int64
|
|
if err := tx.Model(&dictionaryPO{}).Where("type = ?", item.Type).Count(&count).Error; err != nil {
|
|
return err
|
|
}
|
|
if count > 0 {
|
|
continue
|
|
}
|
|
po := dictionaryPO{Name: item.Name, Type: item.Type, Status: item.Status, Desc: item.Desc}
|
|
if err := tx.Create(&po).Error; err != nil {
|
|
return err
|
|
}
|
|
for _, detail := range item.Details {
|
|
d := dictionaryDetailPO{Label: detail.Label, Value: detail.Value, Extend: detail.Extend, Status: detail.Status, Sort: detail.Sort, DictionaryID: po.ID}
|
|
if err := tx.Create(&d).Error; err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|