You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

173 line
5.0 KiB

  1. package service
  2. import (
  3. "errors"
  4. "strings"
  5. "github.com/QuantumNous/new-api/common"
  6. "github.com/QuantumNous/new-api/constant"
  7. "github.com/QuantumNous/new-api/model"
  8. "gorm.io/gorm"
  9. )
  10. type VideoAssetFamily string
  11. const (
  12. VideoAssetFamilySeedance VideoAssetFamily = "seedance"
  13. VideoAssetFamilyKling VideoAssetFamily = "kling"
  14. )
  15. func VideoAssetChannelTypesForFamily(family VideoAssetFamily) []int {
  16. switch family {
  17. case VideoAssetFamilySeedance:
  18. return []int{
  19. constant.ChannelTypeDoubaoVideoCompatibleAiping,
  20. constant.ChannelTypeDoubaoVideoCompatibleTianyiYun,
  21. constant.ChannelTypeChinaMobileSeedance,
  22. }
  23. case VideoAssetFamilyKling:
  24. return []int{
  25. constant.ChannelTypeKlingAiping,
  26. }
  27. default:
  28. return nil
  29. }
  30. }
  31. func VideoAssetFamilyForChannelType(channelType int) (VideoAssetFamily, bool) {
  32. for _, family := range []VideoAssetFamily{VideoAssetFamilySeedance, VideoAssetFamilyKling} {
  33. if channelTypeAllowed(channelType, VideoAssetChannelTypesForFamily(family)) {
  34. return family, true
  35. }
  36. }
  37. return "", false
  38. }
  39. func GetBoundVideoAssetChannelForModel(userId int, tokenGroup string, modelName string, family VideoAssetFamily) (*model.Channel, error) {
  40. bindings, err := model.GetUserAssetChannelsByTypes(userId, VideoAssetChannelTypesForFamily(family), tokenGroup)
  41. if err != nil {
  42. return nil, err
  43. }
  44. for _, binding := range bindings {
  45. channel, err := model.CacheGetChannel(binding.ChannelId)
  46. if err != nil {
  47. if errors.Is(err, gorm.ErrRecordNotFound) || common.MemoryCacheEnabled {
  48. continue
  49. }
  50. return nil, err
  51. }
  52. if IsUsableVideoAssetChannelForFamily(channel, tokenGroup, modelName, family) {
  53. return channel, nil
  54. }
  55. }
  56. return nil, nil
  57. }
  58. func ResolveVideoAssetChannelForModel(userId int, tokenGroup string, modelName string, family VideoAssetFamily) (*model.Channel, error) {
  59. channel, err := GetBoundVideoAssetChannelForModel(userId, tokenGroup, modelName, family)
  60. if err != nil {
  61. return nil, err
  62. }
  63. if channel != nil {
  64. return channel, nil
  65. }
  66. channel, err = autoMatchVideoAssetChannelForModel(tokenGroup, modelName, family)
  67. if err != nil {
  68. return nil, err
  69. }
  70. if channel == nil {
  71. return nil, nil
  72. }
  73. if err = BindVideoAssetChannel(userId, tokenGroup, channel, family); err != nil {
  74. return nil, err
  75. }
  76. return channel, nil
  77. }
  78. func BindVideoAssetChannel(userId int, tokenGroup string, channel *model.Channel, family VideoAssetFamily) error {
  79. if channel == nil {
  80. return nil
  81. }
  82. channelTypes := VideoAssetChannelTypesForFamily(family)
  83. if len(channelTypes) == 0 || !channelTypeAllowed(channel.Type, channelTypes) {
  84. return nil
  85. }
  86. otherTypes := make([]int, 0, len(channelTypes))
  87. for _, channelType := range channelTypes {
  88. if channelType != channel.Type {
  89. otherTypes = append(otherTypes, channelType)
  90. }
  91. }
  92. return model.DB.Transaction(func(tx *gorm.DB) error {
  93. if err := model.DeleteUserAssetChannelsByTypesWithTx(tx, userId, otherTypes, tokenGroup); err != nil {
  94. return err
  95. }
  96. return model.BindUserAssetChannelWithTx(tx, userId, channel.Type, tokenGroup, channel.Id)
  97. })
  98. }
  99. func HasVideoAssetChannelForGroupModel(tokenGroup string, modelName string, family VideoAssetFamily) bool {
  100. tokenGroup = strings.TrimSpace(tokenGroup)
  101. modelName = strings.TrimSpace(modelName)
  102. if tokenGroup == "" || modelName == "" {
  103. return false
  104. }
  105. channel, err := autoMatchVideoAssetChannelForModel(tokenGroup, modelName, family)
  106. return err == nil && channel != nil
  107. }
  108. func autoMatchVideoAssetChannelForModel(tokenGroup string, modelName string, family VideoAssetFamily) (*model.Channel, error) {
  109. for _, channelType := range VideoAssetChannelTypesForFamily(family) {
  110. for startIdx := 0; ; startIdx += DoubaoAssetChannelPageSize {
  111. candidates, err := model.GetChannelsByType(startIdx, DoubaoAssetChannelPageSize, true, channelType)
  112. if err != nil {
  113. return nil, err
  114. }
  115. for _, candidate := range candidates {
  116. if candidate == nil || !MatchDoubaoAssetGroup(candidate.GetGroups(), tokenGroup) {
  117. continue
  118. }
  119. channel, err := model.CacheGetChannel(candidate.Id)
  120. if err != nil {
  121. if errors.Is(err, gorm.ErrRecordNotFound) || common.MemoryCacheEnabled {
  122. continue
  123. }
  124. return nil, err
  125. }
  126. if IsUsableVideoAssetChannelForFamily(channel, tokenGroup, modelName, family) {
  127. return channel, nil
  128. }
  129. }
  130. if len(candidates) < DoubaoAssetChannelPageSize {
  131. break
  132. }
  133. }
  134. }
  135. return nil, nil
  136. }
  137. func IsUsableVideoAssetChannelForFamily(channel *model.Channel, tokenGroup string, modelName string, family VideoAssetFamily) bool {
  138. if channel == nil {
  139. return false
  140. }
  141. channelTypes := VideoAssetChannelTypesForFamily(family)
  142. if len(channelTypes) == 0 || !channelTypeAllowed(channel.Type, channelTypes) {
  143. return false
  144. }
  145. if channel.Status != common.ChannelStatusEnabled {
  146. return false
  147. }
  148. if strings.TrimSpace(channel.Key) == "" || len(channel.GetKeys()) == 0 {
  149. return false
  150. }
  151. if !MatchDoubaoAssetGroup(channel.GetGroups(), tokenGroup) {
  152. return false
  153. }
  154. modelName = strings.TrimSpace(modelName)
  155. if modelName == "" {
  156. return true
  157. }
  158. return model.IsChannelEnabledForGroupModel(tokenGroup, modelName, channel.Id)
  159. }