package packagecustomer import ( "context" "strings" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" ) type packageRow struct { PackageCode string `orm:"package_code"` PackageName string `orm:"package_name"` } func SyncDeptPackagesByDept(ctx context.Context, tenantId string, deptId int64, userId int64) error { tenantId = strings.TrimSpace(tenantId) if tenantId == "" { return gerror.New("tenantId is empty") } if deptId <= 0 { return gerror.New("deptId is empty") } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { dept, err := lockDept(ctx, tx, tenantId, deptId) if err != nil { return err } packages, err := loadDeptPackages(ctx, tx, tenantId, dept) if err != nil { return err } return rebuildDeptPackages(ctx, tx, tenantId, dept, userId, packages) }) } func lockDept(ctx context.Context, tx gdb.TX, tenantId string, deptId int64) (*entity.SysDept, error) { var dept *entity.SysDept err := tx.Ctx(ctx).Model(dao.SysDept.Table()). Where(dao.SysDept.Columns().TenantId, tenantId). Where(dao.SysDept.Columns().DeptId, deptId). WhereNull(dao.SysDept.Columns().DeletedAt). LockUpdate(). Limit(1). Scan(&dept) if err != nil { return nil, gerror.Wrap(err, "load package customer sync dept failed") } if dept == nil || dept.DeptId <= 0 { return nil, gerror.New("package customer sync dept not found") } return dept, nil } func loadDeptPackages(ctx context.Context, tx gdb.TX, tenantId string, dept *entity.SysDept) ([]packageRow, error) { if deptIsTop(dept) { var packages []packageRow err := tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()). Fields(dao.TSimFlowPackageInfo.Columns().PackageCode, dao.TSimFlowPackageInfo.Columns().PackageName). Where(dao.TSimFlowPackageInfo.Columns().TenantId, tenantId). Scan(&packages) if err != nil { return nil, gerror.Wrap(err, "load top dept packages failed") } return packages, nil } cardTable := dao.TSimCardInfo.Table() pkgTable := dao.TSimFlowPackageInfo.Table() var packages []packageRow err := tx.Ctx(ctx).Model(dao.TSimCardInfo.Table()). LeftJoin(pkgTable, cardTable+"."+dao.TSimCardInfo.Columns().CurrentPackageCode+" = "+pkgTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode). Fields( "DISTINCT "+cardTable+"."+dao.TSimCardInfo.Columns().CurrentPackageCode+" AS package_code", pkgTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName+" AS package_name", ). Where(cardTable+"."+dao.TSimCardInfo.Columns().TenantId, tenantId). Where(cardTable+"."+dao.TSimCardInfo.Columns().DeptId, dept.DeptId). Where(pkgTable+"."+dao.TSimFlowPackageInfo.Columns().TenantId, tenantId). Where(cardTable+"."+dao.TSimCardInfo.Columns().CurrentPackageCode+" IS NOT NULL"). Where(cardTable+"."+dao.TSimCardInfo.Columns().CurrentPackageCode+" <> ?", ""). Where(pkgTable + "." + dao.TSimFlowPackageInfo.Columns().PackageCode + " IS NOT NULL"). Scan(&packages) if err != nil { return nil, gerror.Wrap(err, "load dept packages failed") } return packages, nil } func rebuildDeptPackages(ctx context.Context, tx gdb.TX, tenantId string, dept *entity.SysDept, userId int64, packages []packageRow) error { if _, err := tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()). Where(dao.TPackageCustomer.Columns().TenantId, tenantId). Where(dao.TPackageCustomer.Columns().DeptId, dept.DeptId). Delete(); err != nil { return gerror.Wrap(err, "clear dept package customer relation failed") } now := gtime.Now() rows := make([]do.TPackageCustomer, 0, len(packages)) seen := make(map[string]struct{}, len(packages)) for _, item := range packages { packageCode := strings.TrimSpace(item.PackageCode) if packageCode == "" { continue } if _, ok := seen[packageCode]; ok { continue } seen[packageCode] = struct{}{} rows = append(rows, do.TPackageCustomer{ PackageCode: packageCode, PackageName: strings.TrimSpace(item.PackageName), DeptId: dept.DeptId, DeptName: strings.TrimSpace(dept.DeptName), TenantId: tenantId, CreatedDept: dept.DeptId, CreatedBy: userId, CreatedAt: now, UpdatedBy: userId, UpdatedAt: now, }) } if len(rows) == 0 { return nil } if _, err := tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()).Data(rows).Insert(); err != nil { return gerror.Wrap(err, "insert dept package customer relation failed") } return nil } func deptIsTop(dept *entity.SysDept) bool { if dept == nil { return false } return dept.ParentId == 0 || strings.Trim(dept.Ancestors, ",") == "0" }