Files
proxy_server/app/admin/service/sms_platform_key.go
hucan cbefd85f25 1、平台多ApiKey支持
2、平台号码跟系统号码对比自动续费
2025-09-11 20:01:00 +08:00

315 lines
8.8 KiB
Go

package service
import (
"errors"
"fmt"
"github.com/go-admin-team/go-admin-core/sdk/service"
"gorm.io/gorm"
"go-admin/app/admin/models"
"go-admin/app/admin/service/dto"
"go-admin/common/actions"
cDto "go-admin/common/dto"
"go-admin/utils/utility"
)
type SmsPlatformKey struct {
service.Service
}
// GetPage 获取SmsPlatformKey列表
func (e *SmsPlatformKey) GetPage(c *dto.SmsPlatformKeyGetPageReq, p *actions.DataPermission, list *[]models.SmsPlatformKey, count *int64) error {
var err error
var data models.SmsPlatformKey
err = e.Orm.Model(&data).
Scopes(
cDto.MakeCondition(c.GetNeedSearch()),
cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
actions.Permission(data.TableName(), p),
).
Find(list).Limit(-1).Offset(-1).
Count(count).Error
if err != nil {
e.Log.Errorf("SmsPlatformKeyService GetPage error:%s \r\n", err)
return err
}
for index := range *list {
(*list)[index].ApiKey = utility.DesensitizeGeneric((*list)[index].ApiKey, 3, 3, '*')
(*list)[index].ApiSecret = utility.DesensitizeGeneric((*list)[index].ApiSecret, 3, 3, '*')
}
return nil
}
// GetRandomKey 随机获取一个密钥
func (e *SmsPlatformKey) GetRandomKey(platformCode string) (*dto.SmsPlatformKeyQueueDto, error) {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.GetRandomKey(platformCode)
}
// GetRoundRobinKey 轮询获取密钥
func (e *SmsPlatformKey) GetRoundRobinKey(platformCode string) (*dto.SmsPlatformKeyQueueDto, error) {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.GetRoundRobinKey(platformCode)
}
// GetQueueLength 获取队列长度
func (e *SmsPlatformKey) GetQueueLength(platformCode string) (int64, error) {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.GetQueueLength(platformCode)
}
// ClearPlatformQueue 清空指定平台的队列
func (e *SmsPlatformKey) ClearPlatformQueue(platformCode string) error {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.ClearPlatformQueue(platformCode)
}
// Get 获取SmsPlatformKey对象
func (e *SmsPlatformKey) Get(d *dto.SmsPlatformKeyGetReq, p *actions.DataPermission, model *models.SmsPlatformKey) error {
var data models.SmsPlatformKey
err := e.Orm.Model(&data).
Scopes(
actions.Permission(data.TableName(), p),
).
First(model, d.GetId()).Error
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
err = errors.New("查看对象不存在或无权查看")
e.Log.Errorf("Service GetSmsPlatformKey error:%s \r\n", err)
return err
}
if err != nil {
e.Log.Errorf("db error:%s", err)
return err
}
return nil
}
// Insert 创建SmsPlatformKey对象
func (e *SmsPlatformKey) Insert(c *dto.SmsPlatformKeyInsertReq) error {
var err error
var data models.SmsPlatformKey
var count int64
c.Generate(&data)
if err := e.Orm.Model(&models.SmsPlatformKey{}).
Where("platform_code = ? and api_key =? and account=?", data.PlatformCode, data.ApiKey, data.Account).
Count(&count).Error; err != nil {
e.Log.Errorf("SmsPlatformKeyService Insert error:%s \r\n", err)
return err
}
if count > 0 {
return errors.New("ApiKey或账号 已存在")
}
err = e.Orm.Create(&data).Error
if err != nil {
e.Log.Errorf("SmsPlatformKeyService Insert error:%s \r\n", err)
return err
}
if err := e.AddQueque(dto.SmsPlatformKeyQueueDto{
PlatformCode: data.PlatformCode,
Account: data.Account,
ApiKey: data.ApiKey,
ApiSecret: data.ApiSecret,
}); err != nil {
e.Log.Errorf("添加队列失败,%v", err)
return err
}
return nil
}
// Update 修改SmsPlatformKey对象
func (e *SmsPlatformKey) Update(c *dto.SmsPlatformKeyUpdateReq, p *actions.DataPermission) error {
var err error
var data = models.SmsPlatformKey{}
var count int64
e.Orm.Scopes(
actions.Permission(data.TableName(), p),
).First(&data, c.GetId())
oldKey := data.ApiKey
oldSecret := data.ApiSecret
oldStatus := data.Status
oldPlatformCode := data.PlatformCode
if err1 := e.Orm.Model(&models.SmsPlatformKey{}).
Where("platform_code = ? and api_key =? and account=? and id != ?",
data.PlatformCode, data.ApiKey, data.Account, data.Id).
Count(&count).Error; err1 != nil {
e.Log.Errorf("SmsPlatformKeyService Insert error:%s \r\n", err1)
return err1
}
if count > 0 {
return errors.New("ApiKey或账号 已存在")
}
c.Generate(&data)
// 如果要将启用状态改为禁用状态,需要检查该平台是否还有其他启用的密钥
if data.Status == 2 {
var remainingCount int64
err1 := e.Orm.Model(&models.SmsPlatformKey{}).
Where("platform_code = ? AND status = ? AND id != ?", oldPlatformCode, 1, c.GetId()).
Count(&remainingCount).Error
if err1 != nil {
e.Log.Errorf("检查平台剩余启用密钥失败: %v", err1)
return errors.New("检查平台剩余启用密钥失败")
}
if remainingCount == 0 {
return fmt.Errorf("平台 %s 至少需要保留一个启用状态的密钥,无法禁用", oldPlatformCode)
}
}
db := e.Orm.Save(&data)
if err = db.Error; err != nil {
e.Log.Errorf("SmsPlatformKeyService Save error:%s \r\n", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权更新该数据")
}
if oldStatus == 1 && data.Status == 2 {
if err := e.RemoveQueque(dto.SmsPlatformKeyQueueDto{
PlatformCode: data.PlatformCode,
Account: data.Account,
ApiKey: data.ApiKey,
ApiSecret: data.ApiSecret,
}, false); err != nil {
e.Log.Errorf("删除失败,%v", err)
return err
}
} else if oldStatus == 2 && data.Status == 1 {
if err := e.AddQueque(dto.SmsPlatformKeyQueueDto{
PlatformCode: data.PlatformCode,
Account: data.Account,
ApiKey: data.ApiKey,
ApiSecret: data.ApiSecret,
}); err != nil {
e.Log.Errorf("添加队列失败,%v", err)
return err
}
} else {
oldQueueData := dto.SmsPlatformKeyQueueDto{
PlatformCode: data.PlatformCode,
Account: data.Account,
ApiKey: oldKey,
ApiSecret: oldSecret,
}
queueData := dto.SmsPlatformKeyQueueDto{
PlatformCode: data.PlatformCode,
Account: data.Account,
ApiKey: data.ApiKey,
ApiSecret: data.ApiSecret,
}
if err := e.Replace(oldQueueData, queueData); err != nil {
e.Log.Errorf("替换队列失败,%v", err)
return err
}
}
return nil
}
// Remove 删除SmsPlatformKey
func (e *SmsPlatformKey) Remove(d *dto.SmsPlatformKeyDeleteReq, p *actions.DataPermission) error {
var data models.SmsPlatformKey
var datas []models.SmsPlatformKey
if err1 := e.Orm.Where("id in (?)", d.GetId()).Find(&datas).Error; err1 != nil {
e.Log.Errorf("Service RemoveSmsPlatformKey error:%s \r\n", err1)
return err1
}
var platformCodes []string
for _, item := range datas {
if utility.ContainsString(platformCodes, item.PlatformCode) {
continue
}
platformCodes = append(platformCodes, item.PlatformCode)
}
err := e.Orm.Transaction(func(tx *gorm.DB) error {
db := tx.Model(&data).
Scopes(
actions.Permission(data.TableName(), p),
).Delete(&data, d.GetId())
var count []string
if err1 := tx.Model(&data).Where("status =1").
Group("platform_code").
Select("platform_code").
Scan(&count).
Error; err1 != nil {
e.Log.Errorf("Service RemoveSmsPlatformKey error:%s \r\n", err1)
return err1
}
for _, item := range platformCodes {
if !utility.ContainsString(count, item) {
return errors.New("删除失败,通道最少需要保留一个可用ApiKey")
}
}
if err := db.Error; err != nil {
e.Log.Errorf("Service RemoveSmsPlatformKey error:%s \r\n", err)
return err
}
if db.RowsAffected == 0 {
return errors.New("无权删除该数据")
}
return nil
})
if err != nil {
return err
}
for _, item := range datas {
queueDta := dto.SmsPlatformKeyQueueDto{
PlatformCode: item.PlatformCode,
Account: data.Account,
ApiKey: item.ApiKey,
ApiSecret: item.ApiSecret,
}
if err := e.RemoveQueque(queueDta, true); err != nil {
e.Log.Errorf("移出队列失败,%v", err)
return errors.New("删除队列失败")
}
}
return nil
}
// InitQueque 初始化Redis缓存队列
func (e *SmsPlatformKey) InitQueque() error {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.InitRedisQueque()
}
// Replace 替换Redis缓存中的密钥
func (e *SmsPlatformKey) Replace(oldEntity dto.SmsPlatformKeyQueueDto, entity dto.SmsPlatformKeyQueueDto) error {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.ReplaceRedisKey(oldEntity, entity)
}
// RemoveQueque 从Redis缓存中移出队列
func (e *SmsPlatformKey) RemoveQueque(entity dto.SmsPlatformKeyQueueDto, shouldDel bool) error {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.RemoveRedisQueque(entity, shouldDel)
}
// AddQueque 添加到Redis缓存队列
func (e *SmsPlatformKey) AddQueque(entity dto.SmsPlatformKeyQueueDto) error {
redisService := NewSmsPlatformKeyRedis(e.Orm, e.Log)
return redisService.AddRedisQueque(entity)
}