393 lines
13 KiB
Go
393 lines
13 KiB
Go
package system
|
||
|
||
import (
|
||
"fmt"
|
||
"strconv"
|
||
|
||
"git.echol.cn/loser/st/server/global"
|
||
"git.echol.cn/loser/st/server/model/system"
|
||
"git.echol.cn/loser/st/server/model/system/request"
|
||
)
|
||
|
||
//@author: [piexlmax](https://github.com/piexlmax)
|
||
//@function: CreateSysDictionaryDetail
|
||
//@description: 创建字典详情数据
|
||
//@param: sysDictionaryDetail model.SysDictionaryDetail
|
||
//@return: err error
|
||
|
||
type DictionaryDetailService struct{}
|
||
|
||
var DictionaryDetailServiceApp = new(DictionaryDetailService)
|
||
|
||
func (dictionaryDetailService *DictionaryDetailService) CreateSysDictionaryDetail(sysDictionaryDetail system.SysDictionaryDetail) (err error) {
|
||
// 计算层级和路径
|
||
if sysDictionaryDetail.ParentID != nil {
|
||
var parent system.SysDictionaryDetail
|
||
err = global.GVA_DB.First(&parent, *sysDictionaryDetail.ParentID).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
sysDictionaryDetail.Level = parent.Level + 1
|
||
if parent.Path == "" {
|
||
sysDictionaryDetail.Path = strconv.Itoa(int(parent.ID))
|
||
} else {
|
||
sysDictionaryDetail.Path = parent.Path + "," + strconv.Itoa(int(parent.ID))
|
||
}
|
||
} else {
|
||
sysDictionaryDetail.Level = 0
|
||
sysDictionaryDetail.Path = ""
|
||
}
|
||
|
||
err = global.GVA_DB.Create(&sysDictionaryDetail).Error
|
||
return err
|
||
}
|
||
|
||
//@author: [piexlmax](https://github.com/piexlmax)
|
||
//@function: DeleteSysDictionaryDetail
|
||
//@description: 删除字典详情数据
|
||
//@param: sysDictionaryDetail model.SysDictionaryDetail
|
||
//@return: err error
|
||
|
||
func (dictionaryDetailService *DictionaryDetailService) DeleteSysDictionaryDetail(sysDictionaryDetail system.SysDictionaryDetail) (err error) {
|
||
// 检查是否有子项
|
||
var count int64
|
||
err = global.GVA_DB.Model(&system.SysDictionaryDetail{}).Where("parent_id = ?", sysDictionaryDetail.ID).Count(&count).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if count > 0 {
|
||
return fmt.Errorf("该字典详情下还有子项,无法删除")
|
||
}
|
||
|
||
err = global.GVA_DB.Delete(&sysDictionaryDetail).Error
|
||
return err
|
||
}
|
||
|
||
//@author: [piexlmax](https://github.com/piexlmax)
|
||
//@function: UpdateSysDictionaryDetail
|
||
//@description: 更新字典详情数据
|
||
//@param: sysDictionaryDetail *model.SysDictionaryDetail
|
||
//@return: err error
|
||
|
||
func (dictionaryDetailService *DictionaryDetailService) UpdateSysDictionaryDetail(sysDictionaryDetail *system.SysDictionaryDetail) (err error) {
|
||
// 如果更新了父级ID,需要重新计算层级和路径
|
||
if sysDictionaryDetail.ParentID != nil {
|
||
var parent system.SysDictionaryDetail
|
||
err = global.GVA_DB.First(&parent, *sysDictionaryDetail.ParentID).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 检查循环引用
|
||
if dictionaryDetailService.checkCircularReference(sysDictionaryDetail.ID, *sysDictionaryDetail.ParentID) {
|
||
return fmt.Errorf("不能将字典详情设置为自己或其子项的父级")
|
||
}
|
||
|
||
sysDictionaryDetail.Level = parent.Level + 1
|
||
if parent.Path == "" {
|
||
sysDictionaryDetail.Path = strconv.Itoa(int(parent.ID))
|
||
} else {
|
||
sysDictionaryDetail.Path = parent.Path + "," + strconv.Itoa(int(parent.ID))
|
||
}
|
||
} else {
|
||
sysDictionaryDetail.Level = 0
|
||
sysDictionaryDetail.Path = ""
|
||
}
|
||
|
||
err = global.GVA_DB.Save(sysDictionaryDetail).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 更新所有子项的层级和路径
|
||
return dictionaryDetailService.updateChildrenLevelAndPath(sysDictionaryDetail.ID)
|
||
}
|
||
|
||
// checkCircularReference 检查循环引用
|
||
func (dictionaryDetailService *DictionaryDetailService) checkCircularReference(id, parentID uint) bool {
|
||
if id == parentID {
|
||
return true
|
||
}
|
||
|
||
var parent system.SysDictionaryDetail
|
||
err := global.GVA_DB.First(&parent, parentID).Error
|
||
if err != nil {
|
||
return false
|
||
}
|
||
|
||
if parent.ParentID == nil {
|
||
return false
|
||
}
|
||
|
||
return dictionaryDetailService.checkCircularReference(id, *parent.ParentID)
|
||
}
|
||
|
||
// updateChildrenLevelAndPath 更新子项的层级和路径
|
||
func (dictionaryDetailService *DictionaryDetailService) updateChildrenLevelAndPath(parentID uint) error {
|
||
var children []system.SysDictionaryDetail
|
||
err := global.GVA_DB.Where("parent_id = ?", parentID).Find(&children).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
var parent system.SysDictionaryDetail
|
||
err = global.GVA_DB.First(&parent, parentID).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
for _, child := range children {
|
||
child.Level = parent.Level + 1
|
||
if parent.Path == "" {
|
||
child.Path = strconv.Itoa(int(parent.ID))
|
||
} else {
|
||
child.Path = parent.Path + "," + strconv.Itoa(int(parent.ID))
|
||
}
|
||
|
||
err = global.GVA_DB.Save(&child).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// 递归更新子项的子项
|
||
err = dictionaryDetailService.updateChildrenLevelAndPath(child.ID)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
//@author: [piexlmax](https://github.com/piexlmax)
|
||
//@function: GetSysDictionaryDetail
|
||
//@description: 根据id获取字典详情单条数据
|
||
//@param: id uint
|
||
//@return: sysDictionaryDetail system.SysDictionaryDetail, err error
|
||
|
||
func (dictionaryDetailService *DictionaryDetailService) GetSysDictionaryDetail(id uint) (sysDictionaryDetail system.SysDictionaryDetail, err error) {
|
||
err = global.GVA_DB.Where("id = ?", id).First(&sysDictionaryDetail).Error
|
||
return
|
||
}
|
||
|
||
//@author: [piexlmax](https://github.com/piexlmax)
|
||
//@function: GetSysDictionaryDetailInfoList
|
||
//@description: 分页获取字典详情列表
|
||
//@param: info request.SysDictionaryDetailSearch
|
||
//@return: list interface{}, total int64, err error
|
||
|
||
func (dictionaryDetailService *DictionaryDetailService) GetSysDictionaryDetailInfoList(info request.SysDictionaryDetailSearch) (list interface{}, total int64, err error) {
|
||
limit := info.PageSize
|
||
offset := info.PageSize * (info.Page - 1)
|
||
// 创建db
|
||
db := global.GVA_DB.Model(&system.SysDictionaryDetail{})
|
||
var sysDictionaryDetails []system.SysDictionaryDetail
|
||
// 如果有条件搜索 下方会自动创建搜索语句
|
||
if info.Label != "" {
|
||
db = db.Where("label LIKE ?", "%"+info.Label+"%")
|
||
}
|
||
if info.Value != "" {
|
||
db = db.Where("value = ?", info.Value)
|
||
}
|
||
if info.Status != nil {
|
||
db = db.Where("status = ?", info.Status)
|
||
}
|
||
if info.SysDictionaryID != 0 {
|
||
db = db.Where("sys_dictionary_id = ?", info.SysDictionaryID)
|
||
}
|
||
if info.ParentID != nil {
|
||
db = db.Where("parent_id = ?", *info.ParentID)
|
||
}
|
||
if info.Level != nil {
|
||
db = db.Where("level = ?", *info.Level)
|
||
}
|
||
err = db.Count(&total).Error
|
||
if err != nil {
|
||
return
|
||
}
|
||
err = db.Limit(limit).Offset(offset).Order("sort").Order("id").Find(&sysDictionaryDetails).Error
|
||
return sysDictionaryDetails, total, err
|
||
}
|
||
|
||
// 按照字典id获取字典全部内容的方法
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryList(dictionaryID uint) (list []system.SysDictionaryDetail, err error) {
|
||
var sysDictionaryDetails []system.SysDictionaryDetail
|
||
err = global.GVA_DB.Find(&sysDictionaryDetails, "sys_dictionary_id = ?", dictionaryID).Error
|
||
return sysDictionaryDetails, err
|
||
}
|
||
|
||
// GetDictionaryTreeList 获取字典树形结构列表
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryTreeList(dictionaryID uint) (list []system.SysDictionaryDetail, err error) {
|
||
var sysDictionaryDetails []system.SysDictionaryDetail
|
||
// 只获取顶级项目(parent_id为空)
|
||
err = global.GVA_DB.Where("sys_dictionary_id = ? AND parent_id IS NULL", dictionaryID).Order("sort").Find(&sysDictionaryDetails).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 递归加载子项并设置disabled属性
|
||
for i := range sysDictionaryDetails {
|
||
// 设置disabled属性:当status为false时,disabled为true
|
||
if sysDictionaryDetails[i].Status != nil {
|
||
sysDictionaryDetails[i].Disabled = !*sysDictionaryDetails[i].Status
|
||
} else {
|
||
sysDictionaryDetails[i].Disabled = false // 默认不禁用
|
||
}
|
||
|
||
err = dictionaryDetailService.loadChildren(&sysDictionaryDetails[i])
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
return sysDictionaryDetails, nil
|
||
}
|
||
|
||
// loadChildren 递归加载子项
|
||
func (dictionaryDetailService *DictionaryDetailService) loadChildren(detail *system.SysDictionaryDetail) error {
|
||
var children []system.SysDictionaryDetail
|
||
err := global.GVA_DB.Where("parent_id = ?", detail.ID).Order("sort").Find(&children).Error
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
for i := range children {
|
||
// 设置disabled属性:当status为false时,disabled为true
|
||
if children[i].Status != nil {
|
||
children[i].Disabled = !*children[i].Status
|
||
} else {
|
||
children[i].Disabled = false // 默认不禁用
|
||
}
|
||
|
||
err = dictionaryDetailService.loadChildren(&children[i])
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
detail.Children = children
|
||
return nil
|
||
}
|
||
|
||
// GetDictionaryDetailsByParent 根据父级ID获取字典详情
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryDetailsByParent(req request.GetDictionaryDetailsByParentRequest) (list []system.SysDictionaryDetail, err error) {
|
||
db := global.GVA_DB.Model(&system.SysDictionaryDetail{}).Where("sys_dictionary_id = ?", req.SysDictionaryID)
|
||
|
||
if req.ParentID != nil {
|
||
db = db.Where("parent_id = ?", *req.ParentID)
|
||
} else {
|
||
db = db.Where("parent_id IS NULL")
|
||
}
|
||
|
||
err = db.Order("sort").Find(&list).Error
|
||
if err != nil {
|
||
return list, err
|
||
}
|
||
|
||
// 设置disabled属性
|
||
for i := range list {
|
||
if list[i].Status != nil {
|
||
list[i].Disabled = !*list[i].Status
|
||
} else {
|
||
list[i].Disabled = false // 默认不禁用
|
||
}
|
||
}
|
||
|
||
// 如果需要包含子级数据,使用递归方式加载所有层级的子项
|
||
if req.IncludeChildren {
|
||
for i := range list {
|
||
err = dictionaryDetailService.loadChildren(&list[i])
|
||
if err != nil {
|
||
return list, err
|
||
}
|
||
}
|
||
}
|
||
|
||
return list, err
|
||
}
|
||
|
||
// 按照字典type获取字典全部内容的方法
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryListByType(t string) (list []system.SysDictionaryDetail, err error) {
|
||
var sysDictionaryDetails []system.SysDictionaryDetail
|
||
db := global.GVA_DB.Model(&system.SysDictionaryDetail{}).Joins("JOIN sys_dictionaries ON sys_dictionaries.id = sys_dictionary_details.sys_dictionary_id")
|
||
err = db.Find(&sysDictionaryDetails, "type = ?", t).Error
|
||
return sysDictionaryDetails, err
|
||
}
|
||
|
||
// GetDictionaryTreeListByType 根据字典类型获取树形结构
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryTreeListByType(t string) (list []system.SysDictionaryDetail, err error) {
|
||
var sysDictionaryDetails []system.SysDictionaryDetail
|
||
db := global.GVA_DB.Model(&system.SysDictionaryDetail{}).
|
||
Joins("JOIN sys_dictionaries ON sys_dictionaries.id = sys_dictionary_details.sys_dictionary_id").
|
||
Where("sys_dictionaries.type = ? AND sys_dictionary_details.parent_id IS NULL", t).
|
||
Order("sys_dictionary_details.sort")
|
||
|
||
err = db.Find(&sysDictionaryDetails).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
// 递归加载子项并设置disabled属性
|
||
for i := range sysDictionaryDetails {
|
||
// 设置disabled属性:当status为false时,disabled为true
|
||
if sysDictionaryDetails[i].Status != nil {
|
||
sysDictionaryDetails[i].Disabled = !*sysDictionaryDetails[i].Status
|
||
} else {
|
||
sysDictionaryDetails[i].Disabled = false // 默认不禁用
|
||
}
|
||
|
||
err = dictionaryDetailService.loadChildren(&sysDictionaryDetails[i])
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
}
|
||
|
||
return sysDictionaryDetails, nil
|
||
}
|
||
|
||
// 按照字典id+字典内容value获取单条字典内容
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryInfoByValue(dictionaryID uint, value string) (detail system.SysDictionaryDetail, err error) {
|
||
var sysDictionaryDetail system.SysDictionaryDetail
|
||
err = global.GVA_DB.First(&sysDictionaryDetail, "sys_dictionary_id = ? and value = ?", dictionaryID, value).Error
|
||
return sysDictionaryDetail, err
|
||
}
|
||
|
||
// 按照字典type+字典内容value获取单条字典内容
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryInfoByTypeValue(t string, value string) (detail system.SysDictionaryDetail, err error) {
|
||
var sysDictionaryDetails system.SysDictionaryDetail
|
||
db := global.GVA_DB.Model(&system.SysDictionaryDetail{}).Joins("JOIN sys_dictionaries ON sys_dictionaries.id = sys_dictionary_details.sys_dictionary_id")
|
||
err = db.First(&sysDictionaryDetails, "sys_dictionaries.type = ? and sys_dictionary_details.value = ?", t, value).Error
|
||
return sysDictionaryDetails, err
|
||
}
|
||
|
||
// GetDictionaryPath 获取字典详情的完整路径
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryPath(id uint) (path []system.SysDictionaryDetail, err error) {
|
||
var detail system.SysDictionaryDetail
|
||
err = global.GVA_DB.First(&detail, id).Error
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
path = append(path, detail)
|
||
|
||
if detail.ParentID != nil {
|
||
parentPath, err := dictionaryDetailService.GetDictionaryPath(*detail.ParentID)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
path = append(parentPath, path...)
|
||
}
|
||
|
||
return path, nil
|
||
}
|
||
|
||
// GetDictionaryPathByValue 根据值获取字典详情的完整路径
|
||
func (dictionaryDetailService *DictionaryDetailService) GetDictionaryPathByValue(dictionaryID uint, value string) (path []system.SysDictionaryDetail, err error) {
|
||
detail, err := dictionaryDetailService.GetDictionaryInfoByValue(dictionaryID, value)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return dictionaryDetailService.GetDictionaryPath(detail.ID)
|
||
}
|