package appidentity import ( "context" "strconv" "strings" "git.5iot.com/iotlcm-public/iotlcm-app/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-app/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity" "github.com/gogf/gf/v2/errors/gerror" ) type TerminalUserConfig struct { DeptId int64 RoleId int64 } func IsTerminalUser(ctx context.Context, user *entity.SysUser) (bool, error) { if user == nil || user.UserId <= 0 { return false, nil } cfg, err := LoadTerminalUserConfig(ctx, user.TenantId) if err != nil { return false, err } if cfg == nil { return false, nil } hasRole, err := userHasRole(ctx, user.UserId, cfg.RoleId) if err != nil { return false, err } return hasRole, nil } func IsTerminalUserId(ctx context.Context, userId int64) (bool, error) { if userId <= 0 { return false, nil } var user *entity.SysUser if err := dao.SysUser.Ctx(ctx). Where(dao.SysUser.Columns().UserId, userId). WhereNull(dao.SysUser.Columns().DeletedAt). Limit(1). Scan(&user); err != nil { return false, gerror.Wrap(err, "查询小程序用户身份失败") } if user == nil || user.UserId <= 0 { return false, nil } return IsTerminalUser(ctx, user) } func LoadTerminalUserConfig(ctx context.Context, tenantId string) (*TerminalUserConfig, error) { tenantId = strings.TrimSpace(tenantId) if tenantId == "" { tenantId = consts.DefaultSystemTenantCode } deptValue, err := tenantConfigValue(ctx, tenantId, consts.ConfigKeyAppRegisterDeptId) if err != nil { return nil, gerror.Wrap(err, "读取小程序所属组织配置失败") } roleValue, err := tenantConfigValue(ctx, tenantId, consts.ConfigKeyAppRegisterRoleId) if err != nil { return nil, gerror.Wrap(err, "读取小程序角色配置失败") } deptValue = strings.TrimSpace(deptValue) roleValue = strings.TrimSpace(roleValue) if roleValue == "" { return nil, nil } roleId, err := positiveConfigId(roleValue, "小程序角色ID") if err != nil { return nil, err } deptId := int64(0) if deptValue != "" { deptId, err = positiveConfigId(deptValue, "小程序所属组织ID") if err != nil { return nil, err } } return &TerminalUserConfig{ DeptId: deptId, RoleId: roleId, }, nil } func tenantConfigValue(ctx context.Context, tenantId string, key string) (string, error) { var config *entity.SysConfig if err := dao.SysConfig.Ctx(ctx). Where(dao.SysConfig.Columns().TenantId, tenantId). Where(dao.SysConfig.Columns().ConfigKey, key). OrderDesc(dao.SysConfig.Columns().ConfigId). Limit(1). Scan(&config); err != nil { return "", err } if config == nil || config.ConfigId == 0 { return "", nil } return strings.TrimSpace(config.ConfigValue), nil } func positiveConfigId(value string, label string) (int64, error) { id, err := strconv.ParseInt(strings.TrimSpace(value), 10, 64) if err != nil || id <= 0 { return 0, gerror.Newf("%s配置不正确", label) } return id, nil } func userHasRole(ctx context.Context, userId int64, roleId int64) (bool, error) { if userId <= 0 || roleId <= 0 { return false, nil } count, err := dao.SysUserRole.Ctx(ctx). Where(dao.SysUserRole.Columns().UserId, userId). Where(dao.SysUserRole.Columns().RoleId, roleId). Count() if err != nil { return false, gerror.Wrap(err, "校验小程序角色失败") } return count > 0, nil } func userInTerminalDept(ctx context.Context, user *entity.SysUser, terminalDeptId int64) (bool, error) { if user == nil || user.DeptId <= 0 || terminalDeptId <= 0 { return false, nil } if user.DeptId == terminalDeptId { return true, nil } deptIds, err := deptAndSubIds(ctx, user.TenantId, terminalDeptId) if err != nil { return false, err } for _, deptId := range deptIds { if deptId == user.DeptId { return true, nil } } return false, nil } func deptAndSubIds(ctx context.Context, tenantId string, rootDeptId int64) ([]int64, error) { if rootDeptId <= 0 { return []int64{}, nil } tenantId = strings.TrimSpace(tenantId) if tenantId == "" { tenantId = consts.DefaultSystemTenantCode } seen := map[int64]struct{}{ rootDeptId: {}, } result := []int64{rootDeptId} level := []int64{rootDeptId} for len(level) > 0 { var rows []*entity.SysDept err := dao.SysDept.Ctx(ctx). Fields(dao.SysDept.Columns().DeptId). Where(dao.SysDept.Columns().TenantId, tenantId). WhereIn(dao.SysDept.Columns().ParentId, level). WhereNull(dao.SysDept.Columns().DeletedAt). Scan(&rows) if err != nil { return nil, gerror.Wrap(err, "查询小程序所属组织下级失败") } nextLevel := make([]int64, 0, len(rows)) for _, row := range rows { if row == nil || row.DeptId <= 0 { continue } if _, ok := seen[row.DeptId]; ok { continue } seen[row.DeptId] = struct{}{} result = append(result, row.DeptId) nextLevel = append(nextLevel, row.DeptId) } level = nextLevel } return result, nil }