Files
iotlcm/app/server/internal/logic/app/app_customer.go
T

864 lines
28 KiB
Go

package app
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"
"git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
)
const (
appCustomerTypeAll = "all"
appCustomerTypeEnterprise = "enterprise"
appCustomerTypeTerminal = "terminal"
)
type appCustomerCardStat struct {
PackageStatus int `orm:"package_status"`
PackageStatusCounts []model.AppCustomerStatusCount
BossCardStatus int `orm:"boss_card_status"`
CardStatusCounts []model.AppCustomerStatusCount
DeptId int64 `orm:"dept_id"`
TerminalId int64 `orm:"terminal_id"`
CardCount int `orm:"card_count"`
NormalCardCount int `orm:"normal_card_count"`
}
type appTerminalCustomerIdRow struct {
TerminalId int64 `orm:"terminal_id"`
}
func (s *sAppUser) CustomerList(ctx context.Context, param *model.AppCustomerListParam) (items []*model.AppCustomerModel, total int, summary *model.AppCustomerSummary, err error) {
if param == nil {
param = &model.AppCustomerListParam{}
}
user, err := appCurrentUser(ctx)
if err != nil {
return nil, 0, nil, err
}
if err = appEnsureEnterpriseCustomerScope(ctx, user); err != nil {
return nil, 0, nil, err
}
if param.Page <= 0 {
param.Page = 1
}
if param.PageSize <= 0 {
param.PageSize = 20
}
if param.PageSize > 200 {
param.PageSize = 200
}
customerType := appNormalizeCustomerType(param.CustomerType)
if customerType == appCustomerTypeTerminal {
return nil, 0, nil, gerror.New("暂不支持查看终端客户")
}
list, err := s.enterpriseCustomerList(ctx, user, param)
if err != nil {
return nil, 0, nil, err
}
total = len(list)
summary = appCustomerSummary(list)
items = appCustomerPage(list, param.Page, param.PageSize)
if len(items) == 0 {
return items, total, summary, nil
}
deptIds := make([]int64, 0, len(items))
for _, item := range items {
deptIds = append(deptIds, item.CustomerId)
}
stats, err := appCardStatsByDept(ctx, user.TenantId, deptIds)
if err != nil {
return nil, 0, nil, err
}
for _, item := range items {
if stat := stats[item.CustomerId]; stat != nil {
item.CardCount = stat.CardCount
item.NormalCardCount = stat.NormalCardCount
item.CardStatusCounts = stat.CardStatusCounts
item.PackageStatusCounts = stat.PackageStatusCounts
}
}
return items, total, summary, nil
}
func appCustomerPage(items []*model.AppCustomerModel, page, pageSize int) []*model.AppCustomerModel {
if page <= 0 || pageSize <= 0 || len(items) == 0 || page > (len(items)-1)/pageSize+1 {
return []*model.AppCustomerModel{}
}
start := (page - 1) * pageSize
remaining := len(items) - start
if remaining < pageSize {
return items[start:]
}
return items[start : start+pageSize]
}
func appCustomerSummary(items []*model.AppCustomerModel) *model.AppCustomerSummary {
summary := &model.AppCustomerSummary{}
for _, item := range items {
if item == nil {
continue
}
summary.Total++
if item.Status == consts.SysDeptStatusNormal {
summary.NormalCount++
}
if item.RealNameStatus != "已录入实名资料" {
summary.PendingProfileCount++
}
}
return summary
}
func (s *sAppUser) CustomerDetail(ctx context.Context, param *model.AppCustomerDetailParam) (*model.AppCustomerDetailModel, error) {
if param == nil {
param = &model.AppCustomerDetailParam{}
}
user, err := appCurrentUser(ctx)
if err != nil {
return nil, err
}
if err = appEnsureEnterpriseCustomerScope(ctx, user); err != nil {
return nil, err
}
customerType := appNormalizeCustomerType(param.CustomerType)
switch customerType {
case appCustomerTypeEnterprise:
return s.enterpriseCustomerDetail(ctx, user, param.CustomerId)
case appCustomerTypeTerminal:
return nil, gerror.New("暂不支持查看终端客户")
default:
return nil, gerror.New("客户类型不正确")
}
}
func (s *sAppUser) enterpriseCustomerList(ctx context.Context, user *entity.SysUser, param *model.AppCustomerListParam) ([]*model.AppCustomerModel, error) {
depts, err := appEnterpriseAuthorizedCustomerDepts(ctx, user)
if err != nil {
return nil, err
}
depts = appFilterEnterpriseDepts(depts, strings.TrimSpace(param.Keyword), strings.TrimSpace(param.Status))
deptIds := appDeptIds(depts)
profiles, err := appEnterpriseProfileMap(ctx, user.TenantId, deptIds)
if err != nil {
return nil, err
}
list := make([]*model.AppCustomerModel, 0, len(depts))
for _, dept := range depts {
profile := profiles[dept.DeptId]
item := appEnterpriseCustomerModel(dept, profile, 0, nil)
list = append(list, item)
}
return list, nil
}
func (s *sAppUser) enterpriseCustomerDetail(ctx context.Context, user *entity.SysUser, deptId int64) (*model.AppCustomerDetailModel, error) {
dept, err := appLoadCustomerDept(ctx, user.TenantId, deptId)
if err != nil {
return nil, err
}
if dept == nil || dept.DeptId == 0 || dept.DeptType != 1 {
return nil, gerror.New("企业客户不存在")
}
visible, err := appEnterpriseCustomerDeptVisible(ctx, user, dept.DeptId)
if err != nil {
return nil, err
}
if !visible {
return nil, gerror.New("企业客户不在当前企业可查看范围内")
}
profile, err := appEnterpriseProfileByDeptId(ctx, user.TenantId, dept.DeptId)
if err != nil {
return nil, err
}
stats, err := appCardStatsByDept(ctx, user.TenantId, []int64{dept.DeptId})
if err != nil {
return nil, err
}
item := appEnterpriseCustomerModel(dept, profile, 0, stats[dept.DeptId])
return &model.AppCustomerDetailModel{
AppCustomerModel: *item,
EnterpriseProfile: appEnterpriseProfileModel(dept, profile),
}, nil
}
func (s *sAppUser) terminalCustomerList(ctx context.Context, user *entity.SysUser, param *model.AppCustomerListParam) ([]*model.AppCustomerModel, error) {
visibleDeptIds, err := appVisibleCustomerDeptIds(ctx, user)
if err != nil {
return nil, err
}
terminalIds, err := appTerminalIdsByVisibleCards(ctx, user.TenantId, visibleDeptIds)
if err != nil {
return nil, err
}
if len(terminalIds) == 0 {
return []*model.AppCustomerModel{}, nil
}
terminals, err := appTerminalMap(ctx, user.TenantId, terminalIds)
if err != nil {
return nil, err
}
stats, err := appCardStatsByTerminal(ctx, user.TenantId, visibleDeptIds)
if err != nil {
return nil, err
}
keyword := strings.TrimSpace(param.Keyword)
status := strings.TrimSpace(param.Status)
list := make([]*model.AppCustomerModel, 0, len(terminals))
for _, terminalId := range terminalIds {
terminal := terminals[terminalId]
if terminal == nil || terminal.TerminalId == 0 {
continue
}
if status != "" && strings.TrimSpace(terminal.Status) != status {
continue
}
if keyword != "" && !appTerminalMatchesKeyword(terminal, keyword) {
continue
}
item := appTerminalCustomerModel(terminal, stats[terminal.TerminalId])
list = append(list, item)
}
return list, nil
}
func (s *sAppUser) terminalCustomerDetail(ctx context.Context, user *entity.SysUser, terminalId int64) (*model.AppCustomerDetailModel, error) {
visibleDeptIds, err := appVisibleCustomerDeptIds(ctx, user)
if err != nil {
return nil, err
}
visible, err := appTerminalHasVisibleCard(ctx, user.TenantId, terminalId, visibleDeptIds)
if err != nil {
return nil, err
}
if !visible {
return nil, gerror.New("终端客户不在当前企业可查看范围内")
}
terminals, err := appTerminalMap(ctx, user.TenantId, []int64{terminalId})
if err != nil {
return nil, err
}
terminal := terminals[terminalId]
if terminal == nil || terminal.TerminalId == 0 {
return nil, gerror.New("终端客户不存在")
}
stats, err := appCardStatsByTerminal(ctx, user.TenantId, visibleDeptIds)
if err != nil {
return nil, err
}
item := appTerminalCustomerModel(terminal, stats[terminal.TerminalId])
return &model.AppCustomerDetailModel{
AppCustomerModel: *item,
TerminalProfile: appTerminalProfileModel(terminal),
}, nil
}
func appEnsureEnterpriseCustomerScope(ctx context.Context, user *entity.SysUser) error {
if user == nil {
return gerror.New("登录已过期")
}
if appIsTerminalUser(ctx, user) {
return gerror.New("终端用户不能查看客户管理")
}
if user.DeptId <= 0 {
return gerror.New("当前账号未绑定企业,不能查看客户管理")
}
return nil
}
func appNormalizeCustomerType(customerType string) string {
switch strings.TrimSpace(customerType) {
case appCustomerTypeEnterprise:
return appCustomerTypeEnterprise
case appCustomerTypeTerminal:
return appCustomerTypeTerminal
default:
return appCustomerTypeAll
}
}
func appDirectChildDepts(ctx context.Context, user *entity.SysUser) ([]*entity.SysDept, error) {
var rows []*entity.SysDept
err := dao.SysDept.Ctx(ctx).
Where(dao.SysDept.Columns().TenantId, user.TenantId).
Where(dao.SysDept.Columns().ParentId, user.DeptId).
Where(dao.SysDept.Columns().DeptType, 1).
WhereNull(dao.SysDept.Columns().DeletedAt).
OrderAsc(dao.SysDept.Columns().OrderNum).
OrderAsc(dao.SysDept.Columns().DeptId).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询直属下级企业客户失败")
}
return rows, nil
}
func appEnterpriseDirectCustomerDepts(ctx context.Context, user *entity.SysUser) ([]*entity.SysDept, error) {
rows, err := appDirectChildDepts(ctx, user)
if err != nil {
return nil, err
}
excludeIds, err := appEnterpriseCustomerExcludedDeptIds(ctx, user.TenantId, user.DeptId)
if err != nil {
return nil, err
}
result := make([]*entity.SysDept, 0, len(rows))
for _, row := range rows {
if row == nil || row.DeptId <= 0 {
continue
}
if _, excluded := excludeIds[row.DeptId]; excluded {
continue
}
result = append(result, row)
}
return appFilterDeptsByEnterpriseDataScope(ctx, user, result)
}
func appEnterpriseSubCustomerDepts(ctx context.Context, user *entity.SysUser) ([]*entity.SysDept, error) {
if user == nil || user.DeptId <= 0 {
return []*entity.SysDept{}, nil
}
visibleIds, err := appEnterpriseDeptAndSubIds(ctx, user.TenantId, user.DeptId)
if err != nil {
return nil, err
}
excludeIds, err := appEnterpriseCustomerExcludedDeptIds(ctx, user.TenantId, user.DeptId)
if err != nil {
return nil, err
}
deptIds := make([]int64, 0, len(visibleIds))
for _, deptId := range visibleIds {
if deptId <= 0 || deptId == user.DeptId {
continue
}
if _, excluded := excludeIds[deptId]; excluded {
continue
}
deptIds = append(deptIds, deptId)
}
if len(deptIds) == 0 {
return []*entity.SysDept{}, nil
}
var rows []*entity.SysDept
err = dao.SysDept.Ctx(ctx).
Where(dao.SysDept.Columns().TenantId, user.TenantId).
WhereIn(dao.SysDept.Columns().DeptId, deptIds).
WhereNull(dao.SysDept.Columns().DeletedAt).
OrderAsc(dao.SysDept.Columns().ParentId).
OrderAsc(dao.SysDept.Columns().OrderNum).
OrderAsc(dao.SysDept.Columns().DeptId).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询下级企业客户失败")
}
return rows, nil
}
func appEnterpriseCustomerQuery(ctx context.Context, user *entity.SysUser) (*gdb.Model, error) {
scope, err := appResolveEnterpriseDataScope(ctx, user)
if err != nil {
return nil, err
}
mod := dao.SysDept.Ctx(ctx).
Where(dao.SysDept.Columns().TenantId, user.TenantId).
Where(dao.SysDept.Columns().DeptType, 1)
if scope.Configured {
if !scope.All {
if len(scope.DeptIds) == 0 {
return mod.Where("1 = 0"), nil
}
mod = mod.WhereIn(dao.SysDept.Columns().DeptId, scope.DeptIds)
}
} else {
ids, err := appEnterpriseDeptAndSubIds(ctx, user.TenantId, user.DeptId)
if err != nil {
return nil, err
}
mod = mod.WhereIn(dao.SysDept.Columns().DeptId, ids)
}
excluded, err := appEnterpriseCustomerExcludedDeptIds(ctx, user.TenantId, user.DeptId)
if err != nil {
return nil, err
}
excludedIds := []int64{user.DeptId}
for id := range excluded {
excludedIds = append(excludedIds, id)
}
mod = mod.WhereNotIn(dao.SysDept.Columns().DeptId, excludedIds)
return mod, nil
}
func appEnterpriseAuthorizedCustomerDepts(ctx context.Context, user *entity.SysUser) ([]*entity.SysDept, error) {
mod, err := appEnterpriseCustomerQuery(ctx, user)
if err != nil {
return nil, err
}
var rows []*entity.SysDept
err = mod.OrderAsc(dao.SysDept.Columns().OrderNum).
OrderAsc(dao.SysDept.Columns().DeptId).Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询授权企业客户失败")
}
return rows, nil
}
func appEnterpriseCustomerDeptVisible(ctx context.Context, user *entity.SysUser, deptId int64) (bool, error) {
if user == nil || user.DeptId <= 0 || deptId <= 0 {
return false, nil
}
mod, err := appEnterpriseCustomerQuery(ctx, user)
if err != nil {
return false, err
}
count, err := mod.Where(dao.SysDept.Columns().DeptId, deptId).Count()
if err != nil {
return false, gerror.Wrap(err, "校验企业客户范围失败")
}
return count > 0, nil
}
func appEnterpriseCustomerExcludedDeptIds(ctx context.Context, tenantId string, currentDeptId int64) (map[int64]struct{}, error) {
excludeIds := make(map[int64]struct{})
registerDeptId := appRegisterDeptOrDefault(ctx, tenantId)
if registerDeptId <= 0 {
return excludeIds, nil
}
registerDeptIds, err := appEnterpriseDeptAndSubIds(ctx, tenantId, registerDeptId)
if err != nil {
return nil, err
}
for _, deptId := range registerDeptIds {
if deptId == currentDeptId {
return excludeIds, nil
}
}
for _, deptId := range registerDeptIds {
if deptId > 0 {
excludeIds[deptId] = struct{}{}
}
}
return excludeIds, nil
}
func appVisibleCustomerDeptIds(ctx context.Context, user *entity.SysUser) ([]int64, error) {
children, err := appEnterpriseSubCustomerDepts(ctx, user)
if err != nil {
return nil, err
}
ids := make([]int64, 0, len(children)+1)
ids = append(ids, user.DeptId)
for _, child := range children {
if child != nil && child.DeptId > 0 {
ids = append(ids, child.DeptId)
}
}
depts := make([]*entity.SysDept, 0, len(ids))
for _, deptId := range ids {
depts = append(depts, &entity.SysDept{DeptId: deptId})
}
filtered, err := appFilterDeptsByEnterpriseDataScope(ctx, user, depts)
if err != nil {
return nil, err
}
return appDeptIds(filtered), nil
}
func appFilterEnterpriseDepts(depts []*entity.SysDept, keyword string, status string) []*entity.SysDept {
result := make([]*entity.SysDept, 0, len(depts))
for _, dept := range depts {
if dept == nil || dept.DeptId == 0 {
continue
}
if status != "" && strings.TrimSpace(dept.Status) != status {
continue
}
if keyword != "" && !appDeptMatchesKeyword(dept, keyword) {
continue
}
result = append(result, dept)
}
return result
}
func appDeptMatchesKeyword(dept *entity.SysDept, keyword string) bool {
if dept == nil {
return false
}
fields := []string{
dept.DeptName,
dept.DeptKey,
dept.Phone,
dept.Email,
dept.CreditCode,
strconv.FormatInt(dept.DeptId, 10),
}
for _, field := range fields {
if strings.Contains(strings.TrimSpace(field), keyword) {
return true
}
}
return false
}
func appTerminalMatchesKeyword(terminal *entity.TTerminal, keyword string) bool {
if terminal == nil {
return false
}
fields := []string{
terminal.TerminalName,
terminal.Phone,
terminal.Email,
terminal.FullName,
terminal.CreditCode,
strconv.FormatInt(terminal.TerminalId, 10),
}
for _, field := range fields {
if strings.Contains(strings.TrimSpace(field), keyword) {
return true
}
}
return false
}
func appDeptIds(depts []*entity.SysDept) []int64 {
ids := make([]int64, 0, len(depts))
for _, dept := range depts {
if dept != nil && dept.DeptId > 0 {
ids = append(ids, dept.DeptId)
}
}
return ids
}
func appAccumulateCustomerStatusCount(counts []model.AppCustomerStatusCount, status, count int) []model.AppCustomerStatusCount {
for index := range counts {
if counts[index].Status == status {
counts[index].Count += count
return counts
}
}
return append(counts, model.AppCustomerStatusCount{Status: status, Count: count})
}
func appCardStatsByDept(ctx context.Context, tenantId string, deptIds []int64) (map[int64]*appCustomerCardStat, error) {
result := make(map[int64]*appCustomerCardStat)
if len(deptIds) == 0 {
return result, nil
}
var rows []*appCustomerCardStat
cardTable := dao.TSimCardInfo.Table()
normalCountExpr := "SUM(CASE WHEN " + cardTable + "." + dao.TSimCardInfo.Columns().BossCardStatus + " = " + strconv.Itoa(consts.V3ApiSimBossCardStatusActivated) +
" AND " + cardTable + "." + dao.TSimCardInfo.Columns().PackageStatus + " <> " + strconv.Itoa(consts.PackageStatusExpired) + " THEN 1 ELSE 0 END) AS normal_card_count"
err := dao.TSimCardInfo.Ctx(ctx).
Fields(cardTable+"."+dao.TSimCardInfo.Columns().DeptId+" AS dept_id").
Fields("COUNT(1) AS card_count").
Fields(normalCountExpr).
Fields("COALESCE("+cardTable+"."+dao.TSimCardInfo.Columns().BossCardStatus+", 0) AS boss_card_status").
Fields("COALESCE("+cardTable+"."+dao.TSimCardInfo.Columns().PackageStatus+", -1) AS package_status").
Where(cardTable+"."+dao.TSimCardInfo.Columns().TenantId, tenantId).
WhereIn(cardTable+"."+dao.TSimCardInfo.Columns().DeptId, deptIds).
Group(cardTable + "." + dao.TSimCardInfo.Columns().DeptId + ", COALESCE(" + cardTable + "." + dao.TSimCardInfo.Columns().BossCardStatus + ", 0), COALESCE(" + cardTable + "." + dao.TSimCardInfo.Columns().PackageStatus + ", -1)").
OrderAsc("boss_card_status").
OrderAsc("package_status").
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "统计企业客户卡数量失败")
}
for _, row := range rows {
if row != nil {
stat := result[row.DeptId]
if stat == nil {
stat = &appCustomerCardStat{DeptId: row.DeptId}
result[row.DeptId] = stat
}
stat.CardCount += row.CardCount
stat.NormalCardCount += row.NormalCardCount
stat.CardStatusCounts = appAccumulateCustomerStatusCount(stat.CardStatusCounts, row.BossCardStatus, row.CardCount)
stat.PackageStatusCounts = appAccumulateCustomerStatusCount(stat.PackageStatusCounts, row.PackageStatus, row.CardCount)
}
}
return result, nil
}
func appCardStatsByTerminal(ctx context.Context, tenantId string, visibleDeptIds []int64) (map[int64]*appCustomerCardStat, error) {
result := make(map[int64]*appCustomerCardStat)
if len(visibleDeptIds) == 0 {
return result, nil
}
bindTable := dao.TSimTerminal.Table()
cardTable := dao.TSimCardInfo.Table()
var rows []*appCustomerCardStat
normalCountExpr := "SUM(CASE WHEN " + cardTable + "." + dao.TSimCardInfo.Columns().BossCardStatus + " = " + strconv.Itoa(consts.V3ApiSimBossCardStatusActivated) +
" AND " + cardTable + "." + dao.TSimCardInfo.Columns().PackageStatus + " <> " + strconv.Itoa(consts.PackageStatusExpired) + " THEN 1 ELSE 0 END) AS normal_card_count"
err := dao.TSimTerminal.Ctx(ctx).
Fields(bindTable+"."+dao.TSimTerminal.Columns().TerminalId+" AS terminal_id").
Fields("COUNT(DISTINCT "+bindTable+"."+dao.TSimTerminal.Columns().Iccid+") AS card_count").
Fields(normalCountExpr).
InnerJoin(cardTable, cardTable+"."+dao.TSimCardInfo.Columns().Iccid+"="+bindTable+"."+dao.TSimTerminal.Columns().Iccid+" AND "+cardTable+"."+dao.TSimCardInfo.Columns().TenantId+"="+bindTable+"."+dao.TSimTerminal.Columns().TenantId).
Where(bindTable+"."+dao.TSimTerminal.Columns().TenantId, tenantId).
WhereIn(cardTable+"."+dao.TSimCardInfo.Columns().DeptId, visibleDeptIds).
Group(bindTable + "." + dao.TSimTerminal.Columns().TerminalId).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "统计终端客户卡数量失败")
}
for _, row := range rows {
if row != nil {
result[row.TerminalId] = row
}
}
return result, nil
}
func appAgentBalanceMap(ctx context.Context, tenantId string, deptIds []int64) (map[int64]float64, error) {
result := make(map[int64]float64)
if len(deptIds) == 0 {
return result, nil
}
var rows []*entity.TAgentBalance
err := dao.TAgentBalance.Ctx(ctx).
Where(dao.TAgentBalance.Columns().TenantId, tenantId).
WhereIn(dao.TAgentBalance.Columns().DeptId, deptIds).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询企业客户余额失败")
}
for _, row := range rows {
if row != nil {
result[row.DeptId] = appRoundAmount(row.Balance)
}
}
return result, nil
}
func appEnterpriseProfileMap(ctx context.Context, tenantId string, deptIds []int64) (map[int64]*entity.TAgentEnterprise, error) {
result := make(map[int64]*entity.TAgentEnterprise)
if len(deptIds) == 0 {
return result, nil
}
var rows []*entity.TAgentEnterprise
err := dao.TAgentEnterprise.Ctx(ctx).
Where(dao.TAgentEnterprise.Columns().TenantId, tenantId).
WhereIn(dao.TAgentEnterprise.Columns().DeptId, deptIds).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询企业客户实名资料失败")
}
for _, row := range rows {
if row != nil {
result[row.DeptId] = row
}
}
return result, nil
}
func appEnterpriseProfileByDeptId(ctx context.Context, tenantId string, deptId int64) (*entity.TAgentEnterprise, error) {
var profile *entity.TAgentEnterprise
err := dao.TAgentEnterprise.Ctx(ctx).
Where(dao.TAgentEnterprise.Columns().TenantId, tenantId).
Where(dao.TAgentEnterprise.Columns().DeptId, deptId).
Limit(1).
Scan(&profile)
if err != nil {
return nil, gerror.Wrap(err, "查询企业客户实名资料失败")
}
return profile, nil
}
func appTerminalIdsByVisibleCards(ctx context.Context, tenantId string, visibleDeptIds []int64) ([]int64, error) {
if len(visibleDeptIds) == 0 {
return []int64{}, nil
}
bindTable := dao.TSimTerminal.Table()
cardTable := dao.TSimCardInfo.Table()
var rows []*appTerminalCustomerIdRow
err := dao.TSimTerminal.Ctx(ctx).
Fields(bindTable+"."+dao.TSimTerminal.Columns().TerminalId+" AS terminal_id").
InnerJoin(cardTable, cardTable+"."+dao.TSimCardInfo.Columns().Iccid+"="+bindTable+"."+dao.TSimTerminal.Columns().Iccid+" AND "+cardTable+"."+dao.TSimCardInfo.Columns().TenantId+"="+bindTable+"."+dao.TSimTerminal.Columns().TenantId).
Where(bindTable+"."+dao.TSimTerminal.Columns().TenantId, tenantId).
WhereIn(cardTable+"."+dao.TSimCardInfo.Columns().DeptId, visibleDeptIds).
Group(bindTable + "." + dao.TSimTerminal.Columns().TerminalId).
OrderAsc(bindTable + "." + dao.TSimTerminal.Columns().TerminalId).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询终端客户范围失败")
}
ids := make([]int64, 0, len(rows))
for _, row := range rows {
if row != nil && row.TerminalId > 0 {
ids = append(ids, row.TerminalId)
}
}
return ids, nil
}
func appTerminalMap(ctx context.Context, tenantId string, terminalIds []int64) (map[int64]*entity.TTerminal, error) {
result := make(map[int64]*entity.TTerminal)
if len(terminalIds) == 0 {
return result, nil
}
var rows []*entity.TTerminal
err := dao.TTerminal.Ctx(ctx).
Where(dao.TTerminal.Columns().TenantId, tenantId).
WhereIn(dao.TTerminal.Columns().TerminalId, terminalIds).
Scan(&rows)
if err != nil {
return nil, gerror.Wrap(err, "查询终端客户资料失败")
}
for _, row := range rows {
if row != nil {
result[row.TerminalId] = row
}
}
return result, nil
}
func appTerminalHasVisibleCard(ctx context.Context, tenantId string, terminalId int64, visibleDeptIds []int64) (bool, error) {
if terminalId <= 0 || len(visibleDeptIds) == 0 {
return false, nil
}
bindTable := dao.TSimTerminal.Table()
cardTable := dao.TSimCardInfo.Table()
count, err := dao.TSimTerminal.Ctx(ctx).
InnerJoin(cardTable, cardTable+"."+dao.TSimCardInfo.Columns().Iccid+"="+bindTable+"."+dao.TSimTerminal.Columns().Iccid+" AND "+cardTable+"."+dao.TSimCardInfo.Columns().TenantId+"="+bindTable+"."+dao.TSimTerminal.Columns().TenantId).
Where(bindTable+"."+dao.TSimTerminal.Columns().TenantId, tenantId).
Where(bindTable+"."+dao.TSimTerminal.Columns().TerminalId, terminalId).
WhereIn(cardTable+"."+dao.TSimCardInfo.Columns().DeptId, visibleDeptIds).
Count()
if err != nil {
return false, gerror.Wrap(err, "校验终端客户范围失败")
}
return count > 0, nil
}
func appLoadCustomerDept(ctx context.Context, tenantId string, deptId int64) (*entity.SysDept, error) {
var dept *entity.SysDept
err := dao.SysDept.Ctx(ctx).
Where(dao.SysDept.Columns().TenantId, tenantId).
Where(dao.SysDept.Columns().DeptId, deptId).
Limit(1).
Scan(&dept)
if err != nil {
return nil, gerror.Wrap(err, "查询企业客户失败")
}
return dept, nil
}
func appEnterpriseCustomerModel(dept *entity.SysDept, profile *entity.TAgentEnterprise, balance float64, stat *appCustomerCardStat) *model.AppCustomerModel {
item := &model.AppCustomerModel{
CustomerType: appCustomerTypeEnterprise,
CustomerTypeName: "企业客户",
CustomerId: dept.DeptId,
DeptId: dept.DeptId,
ParentDeptId: dept.ParentId,
CustomerCode: strings.TrimSpace(dept.DeptKey),
CustomerName: strings.TrimSpace(dept.DeptName),
DeptCategory: strings.TrimSpace(dept.DeptCategory),
Phone: appMaskPhone(dept.Phone),
Email: appMaskEmail(dept.Email),
Status: strings.TrimSpace(dept.Status),
StatusText: appDeptStatusText(dept.Status),
Balance: balance,
Address: appMaskAddress(dept.Address),
CreatedAt: appProfileDate(dept.CreatedAt),
}
if profile != nil {
item.FullName = strings.TrimSpace(profile.FullName)
item.RealNameStatus = appRealNameStatus(profile.FullName, profile.LegalPersonName, profile.LegalPersonIdCard)
} else {
item.RealNameStatus = "实名资料待完善"
}
if stat != nil {
item.CardCount = stat.CardCount
item.NormalCardCount = stat.NormalCardCount
item.CardStatusCounts = stat.CardStatusCounts
item.PackageStatusCounts = stat.PackageStatusCounts
}
return item
}
func appTerminalCustomerModel(terminal *entity.TTerminal, stat *appCustomerCardStat) *model.AppCustomerModel {
item := &model.AppCustomerModel{
CustomerType: appCustomerTypeTerminal,
CustomerTypeName: "终端客户",
CustomerId: terminal.TerminalId,
TerminalId: terminal.TerminalId,
CustomerName: strings.TrimSpace(terminal.TerminalName),
Phone: appMaskPhone(terminal.Phone),
Email: appMaskEmail(terminal.Email),
Status: strings.TrimSpace(terminal.Status),
StatusText: appTerminalStatusText(terminal.Status),
RealNameStatus: appRealNameStatus(terminal.FullName, terminal.LegalPersonName, terminal.LegalPersonIdCard),
Balance: appRoundAmount(terminal.Balance),
Address: appMaskAddress(terminal.Address),
FullName: strings.TrimSpace(terminal.FullName),
CreatedAt: appProfileDate(terminal.CreatedAt),
}
if item.CustomerName == "" {
item.CustomerName = item.FullName
}
if item.CustomerName == "" {
item.CustomerName = "终端客户" + strconv.FormatInt(terminal.TerminalId, 10)
}
if stat != nil {
item.CardCount = stat.CardCount
item.NormalCardCount = stat.NormalCardCount
item.CardStatusCounts = stat.CardStatusCounts
item.PackageStatusCounts = stat.PackageStatusCounts
}
return item
}
func appEnterpriseProfileModel(dept *entity.SysDept, enterprise *entity.TAgentEnterprise) *model.AppEnterpriseProfileModel {
if dept == nil || dept.DeptId == 0 {
return nil
}
profile := &model.AppEnterpriseProfileModel{
DeptId: dept.DeptId,
DeptName: strings.TrimSpace(dept.DeptName),
DeptKey: strings.TrimSpace(dept.DeptKey),
Phone: appMaskPhone(dept.Phone),
Email: appMaskEmail(dept.Email),
StatusText: appDeptStatusText(dept.Status),
CreditCode: appMaskCreditCode(dept.CreditCode),
AreaCode: strings.TrimSpace(dept.AreaCode),
Address: appMaskAddress(dept.Address),
FullName: strings.TrimSpace(dept.DeptName),
RealNameStatus: "实名资料待完善",
}
if enterprise != nil && enterprise.Id > 0 {
profile.FullName = appFirstNotEmpty(enterprise.FullName, dept.DeptName)
profile.Industry = strings.TrimSpace(enterprise.Industry)
profile.CompanyType = strings.TrimSpace(enterprise.CompanyType)
profile.EstablishTime = appProfileDate(enterprise.EstablishTime)
profile.RealNameStatus = appRealNameStatus(enterprise.FullName, enterprise.LegalPersonName, enterprise.LegalPersonIdCard)
}
return profile
}
func appDeptStatusText(status string) string {
switch strings.TrimSpace(status) {
case consts.SysDeptStatusNormal:
return "正常"
case consts.SysDeptStatusDisable:
return "停用"
case "":
return "未设置"
default:
return "未知"
}
}