فهرست منبع

标签批量导入

lichangdong 1 روز پیش
والد
کامیت
6b1607cf73
3فایلهای تغییر یافته به همراه54 افزوده شده و 34 حذف شده
  1. 4 4
      desc/wechat/label.api
  2. 46 26
      internal/logic/label/label_import_logic.go
  3. 4 4
      internal/types/types.go

+ 4 - 4
desc/wechat/label.api

@@ -79,7 +79,7 @@ type (
     labelImportReq {
         Type  *int `json:"type,optional" validate:"required,gt=0"`
         // Label information | Label数据
-        Content string `json:"content,optional" validate:"required,contains=,,excludes=,"`
+        Content string `json:"content,optional" validate:"required"`
     }
 
     LabelImportResp struct {
@@ -88,9 +88,9 @@ type (
     }
 
     LabelImportInfo struct {
-        Inserted []string `json:"inserted,omitempty"` // 插入成功的标签
-        Existed  []string `json:"existed,omitempty"`  // 已存在的标签
-        Failed   []string `json:"failed,omitempty"`   // 插入失败的标签(预留)
+        Inserted []string `json:"inserted"` // 插入成功的标签
+        Existed  []string `json:"existed"`  // 已存在的标签
+        Failed   []string `json:"failed"`   // 插入失败的标签(预留)
     }
 )
 

+ 46 - 26
internal/logic/label/label_import_logic.go

@@ -2,6 +2,7 @@ package label
 
 import (
 	"context"
+	"encoding/json"
 	"entgo.io/ent/dialect/sql"
 	"strings"
 	"time"
@@ -30,22 +31,7 @@ func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.L
 	// todo: add your logic here and delete this line
 	organizationId := l.ctx.Value("organizationId").(uint64)
 	contentString := req.Content
-	// contentString := "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34
-	//逗号分隔contentString
-	contents := strings.Split(contentString, ",")
-	//查找已经存在的标签
-
-	uniqueContents := make(map[string]struct{})
-	for _, tag := range contents {
-		tag = strings.TrimSpace(tag)
-		if tag != "" {
-			uniqueContents[tag] = struct{}{}
-		}
-	}
-	contentList := make([]string, 0, len(uniqueContents))
-	for tag := range uniqueContents {
-		contentList = append(contentList, tag)
-	}
+	contentList := splitContent(contentString)
 	existingLabels, err := l.svcCtx.DB.Label.Query().
 		Where(
 			label.NameIn(contentList...),
@@ -57,13 +43,15 @@ func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.L
 		return nil, err
 	}
 	//var toInsert []string
-	existMap := make(map[string]bool)
+	existMap := make(map[string]bool, len(existingLabels))
 	for _, tag := range existingLabels {
 		existMap[tag.Name] = true
 	}
 	labelCreates := make([]*ent.LabelCreate, 0)
 	inserted := make([]string, 0)
 	existed := make([]string, 0)
+	failed := make([]string, 0)
+	insertNames := make([]string, 0) // 新增:用于失败时记录哪些尝试插入的标签
 	for _, tag := range contentList {
 		if existMap[tag] {
 			existed = append(existed, tag)
@@ -75,7 +63,7 @@ func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.L
 				SetType(*req.Type).
 				SetStatus(1).
 				SetOrganizationID(organizationId).
-				SetFrom(2).
+				SetFrom(1).
 				SetMode(1).
 				SetConditions(`{}`).
 				SetCreatedAt(time.Now()).
@@ -83,6 +71,7 @@ func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.L
 			)
 		}
 		inserted = append(inserted, tag)
+		insertNames = append(insertNames, tag) // 新增:记录本次尝试插入的标签
 	}
 	if len(labelCreates) > 0 {
 		err := l.svcCtx.DB.Label.CreateBulk(labelCreates...).
@@ -90,18 +79,49 @@ func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.L
 			DoNothing().
 			Exec(l.ctx)
 		if err != nil {
-			logx.Error("label 批量插入失败", labelCreates)
-			return nil, err
+			failed = insertNames
+			jsonBad, _ := json.Marshal(insertNames)
+			logx.Errorf("标签批量插入失败:%v,失败数据:%s", err, string(jsonBad))
+			//return nil, err
 		}
 	}
 	return &types.LabelImportResp{
-		BaseDataInfo: types.BaseDataInfo{
-			Code: 0,
-			Msg:  "success",
-		},
+		BaseDataInfo: types.BaseDataInfo{Code: 0, Msg: "success"},
 		Data: types.LabelImportInfo{
-			Inserted: inserted,
-			Existed:  existed,
+			Inserted: nonEmptySlice(inserted),
+			Existed:  nonEmptySlice(existed),
+			Failed:   nonEmptySlice(failed),
 		},
 	}, nil
 }
+
+// 去重 & 切分内容:
+func splitContent(content string) []string {
+	// 先统一换行符为 \n
+	content = strings.ReplaceAll(content, "\r\n", "\n")
+	content = strings.ReplaceAll(content, "\r", "\n")
+
+	// 再按 \n 分割
+	lines := strings.Split(content, "\n")
+
+	// 去除每行空格,并过滤空行
+	unique := make(map[string]struct{})
+	for _, line := range lines {
+		tag := strings.TrimSpace(line)
+		if tag != "" {
+			unique[tag] = struct{}{}
+		}
+	}
+	result := make([]string, 0, len(unique))
+	for tag := range unique {
+		result = append(result, tag)
+	}
+	return result
+}
+
+func nonEmptySlice(s []string) []string {
+	if len(s) == 0 {
+		return []string{}
+	}
+	return s
+}

+ 4 - 4
internal/types/types.go

@@ -1279,7 +1279,7 @@ type LabelImportReq struct {
 	Type *int `json:"type,optional" validate:"required,gt=0"`
 	// Label information | Label数据
 	// required : true
-	Content string `json:"content,optional" validate:"required,contains=,,excludes=,"`
+	Content string `json:"content,optional" validate:"required"`
 }
 
 // swagger:model LabelImportResp
@@ -1290,9 +1290,9 @@ type LabelImportResp struct {
 
 // swagger:model LabelImportInfo
 type LabelImportInfo struct {
-	Inserted []string `json:"inserted,omitempty"` // 插入成功的标签
-	Existed  []string `json:"existed,omitempty"`  // 已存在的标签
-	Failed   []string `json:"failed,omitempty"`   // 插入失败的标签(预留)
+	Inserted []string `json:"inserted"` // 插入成功的标签
+	Existed  []string `json:"existed"`  // 已存在的标签
+	Failed   []string `json:"failed"`   // 插入失败的标签(预留)
 }
 
 // The data of label tagging information | LabelTagging信息