fix: align admin behavior and Kratos integrations
This commit is contained in:
+127
-35
@@ -62,6 +62,47 @@ func (r *settingsRepo) CreateDictionary(ctx context.Context, v *biz.Dictionary)
|
||||
v.ID = po.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *settingsRepo) ImportDictionary(ctx context.Context, dictionary *biz.Dictionary, details []*biz.DictionaryDetail) error {
|
||||
return r.data.gormDB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
po := dictionaryPO{Name: dictionary.Name, Type: dictionary.Type, Status: dictionary.Status, Desc: dictionary.Desc, ParentID: dictionary.ParentID}
|
||||
if err := tx.Create(&po).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
dictionary.ID = po.ID
|
||||
idMap := make(map[uint]uint, len(details))
|
||||
created := make(map[uint]uint, len(details))
|
||||
for index, item := range details {
|
||||
// Incomplete detail rows are ignored to preserve import behavior.
|
||||
if item.Label == "" || item.Value == "" {
|
||||
continue
|
||||
}
|
||||
oldID := item.ID
|
||||
detail := dictionaryDetailPO{Label: item.Label, Value: item.Value, Extend: item.Extend, Status: item.Status, Sort: item.Sort, DictionaryID: po.ID, Level: item.Level, Path: item.Path}
|
||||
if err := tx.Create(&detail).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
created[uint(index)] = detail.ID
|
||||
if oldID > 0 {
|
||||
idMap[oldID] = detail.ID
|
||||
}
|
||||
}
|
||||
for index, item := range details {
|
||||
if item.ID == 0 || item.ParentID == nil || *item.ParentID == 0 {
|
||||
continue
|
||||
}
|
||||
newID, exists := created[uint(index)]
|
||||
newParentID, parentExists := idMap[*item.ParentID]
|
||||
if !exists || !parentExists {
|
||||
continue
|
||||
}
|
||||
if err := tx.Model(&dictionaryDetailPO{}).Where("id = ?", newID).Update("parent_id", newParentID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
func (r *settingsRepo) UpdateDictionary(ctx context.Context, v *biz.Dictionary) error {
|
||||
return r.data.gormDB.WithContext(ctx).Model(&dictionaryPO{}).Where("id = ?", v.ID).Updates(map[string]any{"name": v.Name, "type": v.Type, "status": v.Status, "desc": v.Desc, "parent_id": v.ParentID}).Error
|
||||
}
|
||||
@@ -80,51 +121,98 @@ func (r *settingsRepo) DeleteDictionary(ctx context.Context, id uint) error {
|
||||
return tx.Delete(&dictionaryPO{}, id).Error
|
||||
})
|
||||
}
|
||||
func (r *settingsRepo) FindDictionary(ctx context.Context, id uint, typ string, details bool) (*biz.Dictionary, error) {
|
||||
func (r *settingsRepo) FindDictionary(ctx context.Context, id uint, typ string, status *bool, details bool) (*biz.Dictionary, error) {
|
||||
var po dictionaryPO
|
||||
db := r.data.gormDB.WithContext(ctx)
|
||||
var err error
|
||||
if id != 0 {
|
||||
err = db.First(&po, id).Error
|
||||
} else {
|
||||
err = db.Where("type = ?", typ).First(&po).Error
|
||||
active := true
|
||||
if status != nil {
|
||||
active = *status
|
||||
}
|
||||
err := db.Where("(type = ? OR id = ?) AND status = ?", typ, id, active).First(&po).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := dictionaryFromPO(po)
|
||||
if details {
|
||||
out.Details, _, err = r.ListDictionaryDetails(ctx, 1, 10000, out.ID, "", "")
|
||||
out.Details, _, err = r.ListDictionaryDetails(ctx, 0, 0, biz.DictionaryDetailFilter{DictionaryID: out.ID})
|
||||
if err == nil {
|
||||
filtered := out.Details[:0]
|
||||
for _, item := range out.Details {
|
||||
if item.Status {
|
||||
filtered = append(filtered, item)
|
||||
}
|
||||
}
|
||||
out.Details = filtered
|
||||
}
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (r *settingsRepo) ExportDictionary(ctx context.Context, id uint) (*biz.Dictionary, error) {
|
||||
var po dictionaryPO
|
||||
if err := r.data.gormDB.WithContext(ctx).First(&po, id).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value := dictionaryFromPO(po)
|
||||
details, _, err := r.ListDictionaryDetails(ctx, 0, 0, biz.DictionaryDetailFilter{DictionaryID: id})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value.Details = details
|
||||
return value, nil
|
||||
}
|
||||
func (r *settingsRepo) ListDictionaries(ctx context.Context, page, size int, name, typ string, details bool) ([]*biz.Dictionary, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
db := r.data.gormDB.WithContext(ctx).Model(&dictionaryPO{})
|
||||
if name != "" {
|
||||
db = db.Where("name LIKE ?", "%"+name+"%")
|
||||
}
|
||||
if typ != "" {
|
||||
db = db.Where("type LIKE ?", "%"+typ+"%")
|
||||
like := "%" + name + "%"
|
||||
db = db.Where("name LIKE ? OR type LIKE ?", like, like)
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []dictionaryPO
|
||||
if err := db.Order("id desc").Offset((page - 1) * size).Limit(size).Find(&pos).Error; err != nil {
|
||||
if err := applyPagination(db.Order("id"), page, size, 0).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
parentIDs := make([]uint, 0, len(pos))
|
||||
dictionaryIDs := make([]uint, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
parentIDs = append(parentIDs, po.ID)
|
||||
dictionaryIDs = append(dictionaryIDs, po.ID)
|
||||
}
|
||||
childrenByParent := make(map[uint][]dictionaryPO)
|
||||
if len(parentIDs) > 0 {
|
||||
var children []dictionaryPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("parent_id IN ?", parentIDs).Order("id").Find(&children).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
for _, child := range children {
|
||||
if child.ParentID != nil {
|
||||
childrenByParent[*child.ParentID] = append(childrenByParent[*child.ParentID], child)
|
||||
}
|
||||
}
|
||||
}
|
||||
detailsByDictionary := make(map[uint][]dictionaryDetailPO)
|
||||
if details && len(dictionaryIDs) > 0 {
|
||||
var values []dictionaryDetailPO
|
||||
if err := r.data.gormDB.WithContext(ctx).Where("sys_dictionary_id IN ?", dictionaryIDs).Order("sort").Find(&values).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
for _, value := range values {
|
||||
detailsByDictionary[value.DictionaryID] = append(detailsByDictionary[value.DictionaryID], value)
|
||||
}
|
||||
}
|
||||
out := make([]*biz.Dictionary, 0, len(pos))
|
||||
for _, po := range pos {
|
||||
v := dictionaryFromPO(po)
|
||||
for _, child := range childrenByParent[po.ID] {
|
||||
v.Children = append(v.Children, dictionaryFromPO(child))
|
||||
}
|
||||
if details {
|
||||
v.Details, _, _ = r.ListDictionaryDetails(ctx, 1, 10000, v.ID, "", "")
|
||||
for _, detail := range detailsByDictionary[v.ID] {
|
||||
v.Details = append(v.Details, detailFromPO(detail))
|
||||
}
|
||||
}
|
||||
out = append(out, v)
|
||||
}
|
||||
@@ -197,29 +285,32 @@ func (r *settingsRepo) FindDictionaryDetail(ctx context.Context, id uint) (*biz.
|
||||
}
|
||||
return detailFromPO(po), nil
|
||||
}
|
||||
func (r *settingsRepo) ListDictionaryDetails(ctx context.Context, page, size int, dictionaryID uint, label, value string) ([]*biz.DictionaryDetail, int64, error) {
|
||||
if page < 1 {
|
||||
page = 1
|
||||
}
|
||||
if size < 1 {
|
||||
size = 10
|
||||
}
|
||||
func (r *settingsRepo) ListDictionaryDetails(ctx context.Context, page, size int, filter biz.DictionaryDetailFilter) ([]*biz.DictionaryDetail, int64, error) {
|
||||
db := r.data.gormDB.WithContext(ctx).Model(&dictionaryDetailPO{})
|
||||
if dictionaryID != 0 {
|
||||
db = db.Where("sys_dictionary_id = ?", dictionaryID)
|
||||
if filter.DictionaryID != 0 {
|
||||
db = db.Where("sys_dictionary_id = ?", filter.DictionaryID)
|
||||
}
|
||||
if label != "" {
|
||||
db = db.Where("label LIKE ?", "%"+label+"%")
|
||||
if filter.Label != "" {
|
||||
db = db.Where("label LIKE ?", "%"+filter.Label+"%")
|
||||
}
|
||||
if value != "" {
|
||||
db = db.Where("value LIKE ?", "%"+value+"%")
|
||||
if filter.Value != "" {
|
||||
db = db.Where("value = ?", filter.Value)
|
||||
}
|
||||
if filter.Status != nil {
|
||||
db = db.Where("status = ?", *filter.Status)
|
||||
}
|
||||
if filter.ParentID != nil {
|
||||
db = db.Where("parent_id = ?", *filter.ParentID)
|
||||
}
|
||||
if filter.Level != nil {
|
||||
db = db.Where("level = ?", *filter.Level)
|
||||
}
|
||||
var total int64
|
||||
if err := db.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var pos []dictionaryDetailPO
|
||||
if err := db.Order("sort,id").Offset((page - 1) * size).Limit(size).Find(&pos).Error; err != nil {
|
||||
if err := applyPagination(db.Order("sort,id"), page, size, 100).Find(&pos).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out := make([]*biz.DictionaryDetail, 0, len(pos))
|
||||
@@ -230,13 +321,14 @@ func (r *settingsRepo) ListDictionaryDetails(ctx context.Context, page, size int
|
||||
}
|
||||
func (r *settingsRepo) DictionaryDetailTree(ctx context.Context, dictionaryID uint, typ string) ([]*biz.DictionaryDetail, error) {
|
||||
if dictionaryID == 0 {
|
||||
dictionary, err := r.FindDictionary(ctx, 0, typ, false)
|
||||
active := true
|
||||
dictionary, err := r.FindDictionary(ctx, 0, typ, &active, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dictionaryID = dictionary.ID
|
||||
}
|
||||
items, _, err := r.ListDictionaryDetails(ctx, 1, 100000, dictionaryID, "", "")
|
||||
items, _, err := r.ListDictionaryDetails(ctx, 0, 0, biz.DictionaryDetailFilter{DictionaryID: dictionaryID})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user