label_import_logic.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package label
  2. import (
  3. "context"
  4. "encoding/json"
  5. "entgo.io/ent/dialect/sql"
  6. "strings"
  7. "time"
  8. "wechat-api/ent"
  9. "wechat-api/ent/label"
  10. "wechat-api/internal/svc"
  11. "wechat-api/internal/types"
  12. "github.com/zeromicro/go-zero/core/logx"
  13. )
  14. type LabelImportLogic struct {
  15. logx.Logger
  16. ctx context.Context
  17. svcCtx *svc.ServiceContext
  18. }
  19. func NewLabelImportLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LabelImportLogic {
  20. return &LabelImportLogic{
  21. Logger: logx.WithContext(ctx),
  22. ctx: ctx,
  23. svcCtx: svcCtx}
  24. }
  25. func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.LabelImportResp, err error) {
  26. // todo: add your logic here and delete this line
  27. organizationId := l.ctx.Value("organizationId").(uint64)
  28. contentString := req.Content
  29. contentList := splitContent(contentString)
  30. existingLabels, err := l.svcCtx.DB.Label.Query().
  31. Where(
  32. label.NameIn(contentList...),
  33. label.OrganizationID(organizationId),
  34. ).
  35. Select(label.FieldName).
  36. All(l.ctx)
  37. if err != nil {
  38. return nil, err
  39. }
  40. //var toInsert []string
  41. existMap := make(map[string]bool, len(existingLabels))
  42. for _, tag := range existingLabels {
  43. existMap[tag.Name] = true
  44. }
  45. labelCreates := make([]*ent.LabelCreate, 0)
  46. inserted := make([]string, 0)
  47. existed := make([]string, 0)
  48. failed := make([]string, 0)
  49. insertNames := make([]string, 0) // 新增:用于失败时记录哪些尝试插入的标签
  50. for _, tag := range contentList {
  51. if existMap[tag] {
  52. existed = append(existed, tag)
  53. continue
  54. }
  55. if !existMap[tag] {
  56. labelCreates = append(labelCreates, l.svcCtx.DB.Label.Create().
  57. SetName(tag).
  58. SetType(*req.Type).
  59. SetStatus(1).
  60. SetOrganizationID(organizationId).
  61. SetFrom(1).
  62. SetMode(1).
  63. SetConditions(`{}`).
  64. SetCreatedAt(time.Now()).
  65. SetUpdatedAt(time.Now()),
  66. )
  67. }
  68. inserted = append(inserted, tag)
  69. insertNames = append(insertNames, tag) // 新增:记录本次尝试插入的标签
  70. }
  71. if len(labelCreates) > 0 {
  72. err := l.svcCtx.DB.Label.CreateBulk(labelCreates...).
  73. OnConflict(sql.ConflictColumns(label.FieldName, label.FieldOrganizationID)).
  74. DoNothing().
  75. Exec(l.ctx)
  76. if err != nil {
  77. failed = insertNames
  78. jsonBad, _ := json.Marshal(insertNames)
  79. logx.Errorf("标签批量插入失败:%v,失败数据:%s", err, string(jsonBad))
  80. //return nil, err
  81. }
  82. }
  83. return &types.LabelImportResp{
  84. BaseDataInfo: types.BaseDataInfo{Code: 0, Msg: "success"},
  85. Data: types.LabelImportInfo{
  86. Inserted: nonEmptySlice(inserted),
  87. Existed: nonEmptySlice(existed),
  88. Failed: nonEmptySlice(failed),
  89. },
  90. }, nil
  91. }
  92. // 去重 & 切分内容:
  93. func splitContent(content string) []string {
  94. // 先统一换行符为 \n
  95. content = strings.ReplaceAll(content, "\r\n", "\n")
  96. content = strings.ReplaceAll(content, "\r", "\n")
  97. // 再按 \n 分割
  98. lines := strings.Split(content, "\n")
  99. // 去除每行空格,并过滤空行
  100. unique := make(map[string]struct{})
  101. for _, line := range lines {
  102. tag := strings.TrimSpace(line)
  103. if tag != "" {
  104. unique[tag] = struct{}{}
  105. }
  106. }
  107. result := make([]string, 0, len(unique))
  108. for tag := range unique {
  109. result = append(result, tag)
  110. }
  111. return result
  112. }
  113. func nonEmptySlice(s []string) []string {
  114. if len(s) == 0 {
  115. return []string{}
  116. }
  117. return s
  118. }