|
@@ -3,12 +3,16 @@ package Account
|
|
|
import (
|
|
import (
|
|
|
"ColdVerify_server/lib"
|
|
"ColdVerify_server/lib"
|
|
|
"ColdVerify_server/logs"
|
|
"ColdVerify_server/logs"
|
|
|
|
|
+ "errors"
|
|
|
|
|
+ "log"
|
|
|
|
|
+ "strconv"
|
|
|
|
|
+ "strings"
|
|
|
|
|
+ "time"
|
|
|
|
|
+
|
|
|
"github.com/beego/beego/v2/adapter/orm"
|
|
"github.com/beego/beego/v2/adapter/orm"
|
|
|
orm2 "github.com/beego/beego/v2/client/orm"
|
|
orm2 "github.com/beego/beego/v2/client/orm"
|
|
|
_ "github.com/go-sql-driver/mysql"
|
|
_ "github.com/go-sql-driver/mysql"
|
|
|
uuid "github.com/satori/go.uuid"
|
|
uuid "github.com/satori/go.uuid"
|
|
|
- "log"
|
|
|
|
|
- "time"
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
type User struct {
|
|
type User struct {
|
|
@@ -16,21 +20,27 @@ type User struct {
|
|
|
T_Distributor_id string `orm:"size(256);null"` // 分销商id
|
|
T_Distributor_id string `orm:"size(256);null"` // 分销商id
|
|
|
T_uuid string `orm:"size(256);null"` //
|
|
T_uuid string `orm:"size(256);null"` //
|
|
|
//T_power int `orm:"size(2);default(0)"` // 权限
|
|
//T_power int `orm:"size(2);default(0)"` // 权限
|
|
|
- T_name string `orm:"size(256);null"` // 某某公司名称
|
|
|
|
|
- T_pass string `orm:"size(256);null"` // 密码 MD5
|
|
|
|
|
- T_passstr string `orm:"size(256);null"` // 密码明文
|
|
|
|
|
|
|
+ T_name string `orm:"size(256);null"` // 某某公司名称
|
|
|
|
|
+ T_pass string `orm:"size(256);null"` // 密码 MD5
|
|
|
|
|
+ T_passstr string `orm:"size(256);null"` // 密码明文
|
|
|
|
|
+ T_pid int `orm:"size(11);default(0)"` // 父级ID
|
|
|
|
|
+ T_path string `orm:"size(1000);null"` // 路径,如:1/2/3
|
|
|
|
|
+
|
|
|
T_Show int `orm:"size(200);default(1)"` // 0隐藏 1公开
|
|
T_Show int `orm:"size(200);default(1)"` // 0隐藏 1公开
|
|
|
T_State int `orm:"size(200);default(1)"` // 0删除 1正常
|
|
T_State int `orm:"size(200);default(1)"` // 0删除 1正常
|
|
|
CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now 每次 model 保存时都会对时间自动更新
|
|
CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now 每次 model 保存时都会对时间自动更新
|
|
|
UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"` //auto_now_add 第一次保存时才设置时间
|
|
UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"` //auto_now_add 第一次保存时才设置时间
|
|
|
}
|
|
}
|
|
|
type User_R struct {
|
|
type User_R struct {
|
|
|
|
|
+ Id int // ID
|
|
|
T_uuid string //
|
|
T_uuid string //
|
|
|
T_Distributor_id string //
|
|
T_Distributor_id string //
|
|
|
T_Distributor_name string //
|
|
T_Distributor_name string //
|
|
|
//T_power int // 权限
|
|
//T_power int // 权限
|
|
|
T_name string // 某某公司名称
|
|
T_name string // 某某公司名称
|
|
|
T_passstr string // 密码明文
|
|
T_passstr string // 密码明文
|
|
|
|
|
+ T_pid int // 父级ID
|
|
|
|
|
+ T_path string // 路径
|
|
|
T_Show int // 0 1
|
|
T_Show int // 0 1
|
|
|
T_State int // 0 1
|
|
T_State int // 0 1
|
|
|
}
|
|
}
|
|
@@ -47,6 +57,7 @@ func init() {
|
|
|
|
|
|
|
|
// -------------------------------------------------------------
|
|
// -------------------------------------------------------------
|
|
|
func UserToUser_R(T User, distributorMap map[string]string) (T_r User_R) {
|
|
func UserToUser_R(T User, distributorMap map[string]string) (T_r User_R) {
|
|
|
|
|
+ T_r.Id = T.Id
|
|
|
T_r.T_uuid = T.T_uuid
|
|
T_r.T_uuid = T.T_uuid
|
|
|
T_r.T_Distributor_id = T.T_Distributor_id
|
|
T_r.T_Distributor_id = T.T_Distributor_id
|
|
|
T_Distributor_name, ok := distributorMap[T.T_Distributor_id]
|
|
T_Distributor_name, ok := distributorMap[T.T_Distributor_id]
|
|
@@ -57,6 +68,8 @@ func UserToUser_R(T User, distributorMap map[string]string) (T_r User_R) {
|
|
|
//T_r.T_power = T.T_power
|
|
//T_r.T_power = T.T_power
|
|
|
T_r.T_name = T.T_name
|
|
T_r.T_name = T.T_name
|
|
|
T_r.T_passstr = T.T_passstr
|
|
T_r.T_passstr = T.T_passstr
|
|
|
|
|
+ T_r.T_pid = T.T_pid
|
|
|
|
|
+ T_r.T_path = T.T_path
|
|
|
T_r.T_Show = T.T_Show
|
|
T_r.T_Show = T.T_Show
|
|
|
T_r.T_State = T.T_State
|
|
T_r.T_State = T.T_State
|
|
|
|
|
|
|
@@ -88,7 +101,7 @@ func Read_User_verification(T_user string, T_pass string) (error, User) {
|
|
|
func Read_User_ById(id int) (r User, is bool) {
|
|
func Read_User_ById(id int) (r User, is bool) {
|
|
|
o := orm.NewOrm()
|
|
o := orm.NewOrm()
|
|
|
r = User{Id: id, T_State: 1}
|
|
r = User{Id: id, T_State: 1}
|
|
|
- err := o.Read(&r, "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
|
|
|
|
|
|
|
+ err := o.Read(&r, "Id", "T_State") // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
|
|
|
if err != nil {
|
|
if err != nil {
|
|
|
logs.Error(lib.FuncName(), err)
|
|
logs.Error(lib.FuncName(), err)
|
|
|
return r, false
|
|
return r, false
|
|
@@ -195,7 +208,19 @@ func Read_User_List(T_Distributor_id string, T_name string, page int, page_z int
|
|
|
offset = int64((page - 1) * page_z)
|
|
offset = int64((page - 1) * page_z)
|
|
|
}
|
|
}
|
|
|
cond := orm.NewCondition()
|
|
cond := orm.NewCondition()
|
|
|
- cond1 := cond.And("T_State", 1).AndCond(cond.Or("T_name__icontains", T_name))
|
|
|
|
|
|
|
+ cond1 := cond.And("T_State", 1)
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有名称搜索,获取包含所有子公司的ID列表
|
|
|
|
|
+ if len(T_name) > 0 {
|
|
|
|
|
+ userIds, err := GetUserIdsByNameWithChildren(T_Distributor_id, T_name)
|
|
|
|
|
+ if err == nil && len(userIds) > 0 {
|
|
|
|
|
+ cond1 = cond1.And("Id__in", userIds)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有匹配结果,使用原来的模糊搜索
|
|
|
|
|
+ cond1 = cond1.And("T_name__icontains", T_name)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if len(T_Distributor_id) > 0 {
|
|
if len(T_Distributor_id) > 0 {
|
|
|
cond1 = cond1.And("T_Distributor_id", T_Distributor_id)
|
|
cond1 = cond1.And("T_Distributor_id", T_Distributor_id)
|
|
|
}
|
|
}
|
|
@@ -288,3 +313,331 @@ func Read_User_T_uuid_ListByT_name(T_name string) (list []string) {
|
|
|
|
|
|
|
|
return list
|
|
return list
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// 树形结构相关函数
|
|
|
|
|
+
|
|
|
|
|
+// 根据公司名称获取公司ID列表(包含所有子公司)
|
|
|
|
|
+func GetUserIdsByNameWithChildren(T_Distributor_id string, T_name string) ([]int, error) {
|
|
|
|
|
+ if T_name == "" {
|
|
|
|
|
+ return nil, nil
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+ var matchedUsers []User
|
|
|
|
|
+ qs := o.QueryTable(new(User))
|
|
|
|
|
+
|
|
|
|
|
+ cond := orm.NewCondition()
|
|
|
|
|
+ cond1 := cond.And("T_State", 1).And("T_name__icontains", T_name)
|
|
|
|
|
+ if len(T_Distributor_id) > 0 {
|
|
|
|
|
+ cond1 = cond1.And("T_Distributor_id", T_Distributor_id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _, err := qs.SetCond((*orm2.Condition)(cond1)).All(&matchedUsers)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 收集所有匹配的公司ID及其子公司ID
|
|
|
|
|
+ userIds := make([]int, 0)
|
|
|
|
|
+ for _, user := range matchedUsers {
|
|
|
|
|
+ userIds = append(userIds, user.Id)
|
|
|
|
|
+ // 获取所有子公司ID
|
|
|
|
|
+ childIds, err := getChildUserIds(o, user.Id)
|
|
|
|
|
+ if err == nil {
|
|
|
|
|
+ userIds = append(userIds, childIds...)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return userIds, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 递归获取所有子公司ID
|
|
|
|
|
+func getChildUserIds(o orm.Ormer, parentId int) ([]int, error) {
|
|
|
|
|
+ var children []User
|
|
|
|
|
+ _, err := o.QueryTable(new(User)).Filter("T_pid", parentId).Filter("T_State", 1).All(&children)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ childIds := make([]int, 0)
|
|
|
|
|
+ for _, child := range children {
|
|
|
|
|
+ childIds = append(childIds, child.Id)
|
|
|
|
|
+ // 递归获取子公司的子公司
|
|
|
|
|
+ subChildIds, err := getChildUserIds(o, child.Id)
|
|
|
|
|
+ if err == nil {
|
|
|
|
|
+ childIds = append(childIds, subChildIds...)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return childIds, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取所有用户用于构建树形结构
|
|
|
|
|
+func Read_User_Tree_List(T_Distributor_id string, distributorMap map[string]string) ([]User_R, error) {
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+ var r []User
|
|
|
|
|
+ qs := o.QueryTable(new(User))
|
|
|
|
|
+
|
|
|
|
|
+ cond := orm.NewCondition()
|
|
|
|
|
+ cond1 := cond.And("T_State", 1)
|
|
|
|
|
+ if len(T_Distributor_id) > 0 {
|
|
|
|
|
+ cond1 = cond1.And("T_Distributor_id", T_Distributor_id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _, err := qs.SetCond((*orm2.Condition)(cond1)).OrderBy("T_pid", "Id").All(&r)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 转换
|
|
|
|
|
+ var User_r []User_R
|
|
|
|
|
+ for _, v := range r {
|
|
|
|
|
+ User_r = append(User_r, UserToUser_R(v, distributorMap))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return User_r, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 获取指定公司的所有子公司(用于树形展示的过滤)
|
|
|
|
|
+func Read_User_Tree_List_WithFilter(T_Distributor_id string, T_name string, distributorMap map[string]string) ([]User_R, error) {
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+ var r []User
|
|
|
|
|
+ qs := o.QueryTable(new(User))
|
|
|
|
|
+
|
|
|
|
|
+ cond := orm.NewCondition()
|
|
|
|
|
+ cond1 := cond.And("T_State", 1)
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有名称搜索,获取包含所有子公司的ID列表
|
|
|
|
|
+ if len(T_name) > 0 {
|
|
|
|
|
+ userIds, err := GetUserIdsByNameWithChildren(T_Distributor_id, T_name)
|
|
|
|
|
+ if err == nil && len(userIds) > 0 {
|
|
|
|
|
+ cond1 = cond1.And("Id__in", userIds)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有匹配结果,返回空列表
|
|
|
|
|
+ return []User_R{}, nil
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if len(T_Distributor_id) > 0 {
|
|
|
|
|
+ cond1 = cond1.And("T_Distributor_id", T_Distributor_id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ _, err := qs.SetCond((*orm2.Condition)(cond1)).OrderBy("T_pid", "Id").All(&r)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 转换
|
|
|
|
|
+ var User_r []User_R
|
|
|
|
|
+ for _, v := range r {
|
|
|
|
|
+ User_r = append(User_r, UserToUser_R(v, distributorMap))
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return User_r, nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 构建树形结构
|
|
|
|
|
+type UserTreeNode struct {
|
|
|
|
|
+ User_R
|
|
|
|
|
+ Children []UserTreeNode `json:"children"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 内部使用的指针版本
|
|
|
|
|
+type userTreeNodePtr struct {
|
|
|
|
|
+ User_R
|
|
|
|
|
+ Children []*userTreeNodePtr
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func BuildUserTree(users []User_R) []UserTreeNode {
|
|
|
|
|
+ // 创建ID到节点的映射(使用指针以便修改)
|
|
|
|
|
+ nodeMap := make(map[int]*userTreeNodePtr)
|
|
|
|
|
+ var rootNodes []*userTreeNodePtr
|
|
|
|
|
+
|
|
|
|
|
+ // 首先创建所有节点
|
|
|
|
|
+ for i := range users {
|
|
|
|
|
+ node := &userTreeNodePtr{
|
|
|
|
|
+ User_R: users[i],
|
|
|
|
|
+ Children: make([]*userTreeNodePtr, 0),
|
|
|
|
|
+ }
|
|
|
|
|
+ nodeMap[users[i].Id] = node
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 然后建立父子关系(使用指针)
|
|
|
|
|
+ for i := range users {
|
|
|
|
|
+ node := nodeMap[users[i].Id]
|
|
|
|
|
+ if users[i].T_pid == 0 {
|
|
|
|
|
+ // 根节点
|
|
|
|
|
+ rootNodes = append(rootNodes, node)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 子节点 - 将指针添加到父节点的Children
|
|
|
|
|
+ if parent, exists := nodeMap[users[i].T_pid]; exists {
|
|
|
|
|
+ parent.Children = append(parent.Children, node)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 递归转换为值类型返回
|
|
|
|
|
+ result := make([]UserTreeNode, len(rootNodes))
|
|
|
|
|
+ for i, node := range rootNodes {
|
|
|
|
|
+ result[i] = convertNodeToValue(node)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return result
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 递归将指针类型的节点树转换为值类型
|
|
|
|
|
+func convertNodeToValue(node *userTreeNodePtr) UserTreeNode {
|
|
|
|
|
+ valueNode := UserTreeNode{
|
|
|
|
|
+ User_R: node.User_R,
|
|
|
|
|
+ Children: make([]UserTreeNode, len(node.Children)),
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 递归转换所有子节点
|
|
|
|
|
+ for i, child := range node.Children {
|
|
|
|
|
+ valueNode.Children[i] = convertNodeToValue(child)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return valueNode
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 更新用户路径
|
|
|
|
|
+func UpdateUserPath(userId int) error {
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+
|
|
|
|
|
+ // 获取当前用户
|
|
|
|
|
+ var user User
|
|
|
|
|
+ err := o.QueryTable(new(User)).Filter("Id", userId).One(&user)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建路径
|
|
|
|
|
+ var path string
|
|
|
|
|
+ if user.T_pid == 0 {
|
|
|
|
|
+ path = strconv.Itoa(userId)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 获取父级路径
|
|
|
|
|
+ var parent User
|
|
|
|
|
+ err = o.QueryTable(new(User)).Filter("Id", user.T_pid).One(&parent)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if parent.T_path != "" {
|
|
|
|
|
+ path = parent.T_path + "/" + strconv.Itoa(userId)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ path = strconv.Itoa(user.T_pid) + "/" + strconv.Itoa(userId)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新当前用户路径
|
|
|
|
|
+ user.T_path = path
|
|
|
|
|
+ _, err = o.Update(&user, "T_path")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 递归更新所有子节点的路径
|
|
|
|
|
+ return updateChildrenPath(o, userId)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 递归更新子节点路径
|
|
|
|
|
+func updateChildrenPath(o orm.Ormer, parentId int) error {
|
|
|
|
|
+ var children []User
|
|
|
|
|
+ _, err := o.QueryTable(new(User)).Filter("T_pid", parentId).All(&children)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for _, child := range children {
|
|
|
|
|
+ // 获取父级路径
|
|
|
|
|
+ var parent User
|
|
|
|
|
+ err = o.QueryTable(new(User)).Filter("Id", child.T_pid).One(&parent)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 构建新的路径
|
|
|
|
|
+ var newPath string
|
|
|
|
|
+ if parent.T_path != "" {
|
|
|
|
|
+ newPath = parent.T_path + "/" + strconv.Itoa(child.Id)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ newPath = strconv.Itoa(child.T_pid) + "/" + strconv.Itoa(child.Id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新子节点路径
|
|
|
|
|
+ child.T_path = newPath
|
|
|
|
|
+ _, err = o.Update(&child, "T_path")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 递归更新子节点的子节点
|
|
|
|
|
+ updateChildrenPath(o, child.Id)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return nil
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 移动公司到另一个公司下面
|
|
|
|
|
+func MoveUserToParent(userId int, newParentId int) error {
|
|
|
|
|
+ o := orm.NewOrm()
|
|
|
|
|
+
|
|
|
|
|
+ // 获取要移动的用户
|
|
|
|
|
+ var user User
|
|
|
|
|
+ err := o.QueryTable(new(User)).Filter("Id", userId).One(&user)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查新父级是否存在(如果newParentId不为0)
|
|
|
|
|
+
|
|
|
|
|
+ if newParentId != 0 {
|
|
|
|
|
+ var parent User
|
|
|
|
|
+ err = o.QueryTable(new(User)).Filter("Id", newParentId).Filter("T_State", 1).One(&parent)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+ if user.T_Distributor_id != parent.T_Distributor_id {
|
|
|
|
|
+ return errors.New("不能将公司移动到不同经销商下面")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否会造成循环引用
|
|
|
|
|
+ if newParentId != 0 {
|
|
|
|
|
+ if isCircularReference(o, userId, newParentId) {
|
|
|
|
|
+ return errors.New("不能将公司移动到其子级公司下面")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新父级ID
|
|
|
|
|
+ user.T_pid = newParentId
|
|
|
|
|
+ _, err = o.Update(&user, "T_pid")
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新路径
|
|
|
|
|
+ return UpdateUserPath(userId)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 检查是否会造成循环引用
|
|
|
|
|
+func isCircularReference(o orm.Ormer, userId int, newParentId int) bool {
|
|
|
|
|
+ // 获取新父级的路径
|
|
|
|
|
+ var parent User
|
|
|
|
|
+ err := o.QueryTable(new(User)).Filter("Id", newParentId).One(&parent)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return false
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果新父级的路径包含当前用户ID,则会造成循环引用
|
|
|
|
|
+ if parent.T_path != "" {
|
|
|
|
|
+ pathParts := strings.Split(parent.T_path, "/")
|
|
|
|
|
+ for _, part := range pathParts {
|
|
|
|
|
+ if part == strconv.Itoa(userId) {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return false
|
|
|
|
|
+}
|