Files
admin-go/internal/app/system/logic/moduleTenant/module_tenant.go

191 lines
6.5 KiB
Go
Raw Normal View History

2026-03-18 10:19:42 +08:00
/*
* @desc:模块租户关系处理
* @company:云南奇讯科技有限公司
* @Author: system
* @Date: 2026/1/6
*/
package moduleTenant
import (
"context"
"fmt"
"time"
2026-06-10 15:37:11 +08:00
"gitea.redpowerfuture.com/red-future/common/beans"
"gitea.redpowerfuture.com/red-future/common/http"
"gitea.redpowerfuture.com/red-future/common/utils"
2026-03-18 10:19:42 +08:00
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"github.com/tiger1103/gfast/v3/api/v1/system"
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
"github.com/tiger1103/gfast/v3/internal/app/system/service"
"github.com/tiger1103/gfast/v3/library/liberr"
)
func init() {
service.RegisterModuleTenant(New())
}
type sModuleTenant struct {
}
func New() *sModuleTenant {
return &sModuleTenant{}
}
// Add 添加模块租户关系
func (s *sModuleTenant) Add(ctx context.Context, req *system.ModuleTenantAddReq) (err error) {
err = g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
err = g.Try(ctx, func(ctx context.Context) {
// 获取用户信息
var getUserInfo *beans.User
getUserInfo, err = utils.GetUserInfo(ctx)
liberr.ErrIsNil(ctx, err, "获取用户信息失败")
// 获取sku信息
assetSukRes := new(system.AssetSku)
// 获取当前请求的 headers 并传递到下游
headers := make(map[string]string)
if r := g.RequestFromCtx(ctx); r != nil {
for k, v := range r.Request.Header {
if len(v) > 0 {
headers[k] = v[0]
}
}
}
if err = http.Get(ctx, "asset/sku/getAssetSkuModule", headers, &assetSukRes,
"id", req.AssetSkuId,
); err != nil {
return
}
liberr.ErrIsNil(ctx, err, "获取资产sku信息失败")
if assetSukRes.ExpireAt != nil {
liberr.ErrIsNil(ctx, err, "sku到期时间不能为空")
}
// 获取模块key
var moduleKey string
// 遍历 map 的所有键值对
for key, value := range beans.ModuleAssetId {
if value == assetSukRes.AssetId {
2026-03-18 10:19:42 +08:00
moduleKey = key
break
}
}
// 检查是否已存在相同的模块租户关系
var moduleTenant *entity.ModuleTenant
moduleTenant, err = s.GetByModuleKeyAndTenantId(ctx, moduleKey, gconv.Uint64(getUserInfo.TenantId))
liberr.ErrIsNil(ctx, err, "检查模块租户关系失败")
if moduleTenant != nil {
now := gtime.Now()
if moduleTenant.ExpireAt != nil && !moduleTenant.ExpireAt.Before(now) {
// 使用原到期时间 + SKU到期时间
duration := assetSukRes.ExpireAt.Sub(gtime.Now())
assetSukRes.ExpireAt = moduleTenant.ExpireAt.Add(duration)
}
// 更新模块租户关系
_, err = dao.ModuleTenant.Ctx(ctx).TX(tx).WherePri(moduleTenant.Id).Update(do.ModuleTenant{
UpdateBy: getUserInfo.UserName,
ExpireAt: assetSukRes.ExpireAt,
})
return
}
// 设置认证状态
certificationStatus := consts.CertificationStatusPass
if req.TenantModuleType == beans.TenantModuleTypeSupplier {
certificationStatus = consts.CertificationStatusUnverified
}
// 添加模块租户关系
_, err = dao.ModuleTenant.Ctx(ctx).TX(tx).InsertAndGetId(do.ModuleTenant{
CreateBy: getUserInfo.UserName,
UpdateBy: getUserInfo.UserName,
ModuleKey: moduleKey,
AssetId: assetSukRes.AssetId,
AssetSkuId: req.AssetSkuId,
2026-03-18 10:19:42 +08:00
TenantId: getUserInfo.TenantId,
TenantModuleType: req.TenantModuleType,
CertificationStatus: certificationStatus,
ExpireAt: assetSukRes.ExpireAt,
})
liberr.ErrIsNil(ctx, err, "添加模块租户关系失败")
// 设置缓存
_, err = s.AddRedisByTenantId(ctx, &system.AddRedisByTenantIdReq{
TenantId: getUserInfo.TenantId,
})
liberr.ErrIsNil(ctx, err, "设置缓存失败")
})
return err
})
return
}
// Check 检查模块开通状态
func (s *sModuleTenant) Check(ctx context.Context, req *system.ModuleTenantCheckReq) (res *system.ModuleTenantCheckRes, err error) {
err = g.Try(ctx, func(ctx context.Context) {
res = new(system.ModuleTenantCheckRes)
// 查询模块租户关系
moduleTenant, err := s.GetByModuleKeyAndTenantId(ctx, req.ModuleKey, req.TenantId)
liberr.ErrIsNil(ctx, err, "查询模块租户关系失败")
// 判断状态
if g.IsEmpty(moduleTenant) {
// 没有记录,未开通
res.Message = "您未开通此功能模块,请开通后再使用"
res.Status = false
} else {
_, err = s.AddRedisByTenantId(ctx, &system.AddRedisByTenantIdReq{
TenantId: req.TenantId,
})
liberr.ErrIsNil(ctx, err, "设置缓存失败")
// 有记录,检查是否到期
now := gtime.Now()
if moduleTenant.ExpireAt != nil && moduleTenant.ExpireAt.Before(now) {
res.Message = "功能模块已到期,请续期后再使用"
res.Status = false
} else {
res.Status = true
if moduleTenant.CertificationStatus == consts.CertificationStatusPass {
res.Message = "已开通"
res.CertificationStatus = true
} else {
keyValue := consts.GetCertificationStatusKeyValue(moduleTenant.CertificationStatus)
res.Message = fmt.Sprintf("功能模块认证状态:%s", keyValue.Value)
res.CertificationStatus = false
}
}
}
})
return
}
// GetByModuleKeyAndTenantId 根据模块Key和租户ID获取模块租户关系
func (s *sModuleTenant) GetByModuleKeyAndTenantId(ctx context.Context, moduleKey string, tenantId uint64) (moduleTenant *entity.ModuleTenant, err error) {
err = g.Try(ctx, func(ctx context.Context) {
err = dao.ModuleTenant.Ctx(ctx).
Where(dao.ModuleTenant.Columns().ModuleKey, moduleKey).
Where(dao.ModuleTenant.Columns().TenantId, tenantId).
Scan(&moduleTenant)
liberr.ErrIsNil(ctx, err, "获取模块租户关系失败")
})
return
}
// AddRedisByTenantId 根据租户ID获取模块租户关系存到redis
func (s *sModuleTenant) AddRedisByTenantId(ctx context.Context, req *system.AddRedisByTenantIdReq) (res *system.AddRedisByTenantIdRes, err error) {
res = new(system.AddRedisByTenantIdRes)
//从数据库获取
err = dao.ModuleTenant.Ctx(ctx).
Where(dao.ModuleTenant.Columns().TenantId, req.TenantId).
Scan(&res.List)
liberr.ErrIsNil(ctx, err, "获取模块租户关系失败")
if !g.IsEmpty(res.List) {
err = g.Redis().SetEX(ctx, fmt.Sprintf("module_tenant:tenantId-%d", gconv.Int(req.TenantId)), res.List, gconv.Int64(time.Minute*1))
liberr.ErrIsNil(ctx, err, "设置缓存失败")
}
return
}