package label import ( "context" "encoding/json" "entgo.io/ent/dialect/sql" "strings" "time" "wechat-api/ent" "wechat-api/ent/label" "wechat-api/internal/svc" "wechat-api/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type LabelImportLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewLabelImportLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LabelImportLogic { return &LabelImportLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx} } func (l *LabelImportLogic) LabelImport(req *types.LabelImportReq) (resp *types.LabelImportResp, err error) { // todo: add your logic here and delete this line organizationId := l.ctx.Value("organizationId").(uint64) contentString := req.Content contentList := splitContent(contentString) existingLabels, err := l.svcCtx.DB.Label.Query(). Where( label.NameIn(contentList...), label.OrganizationID(organizationId), ). Select(label.FieldName). All(l.ctx) if err != nil { return nil, err } //var toInsert []string 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) continue } if !existMap[tag] { labelCreates = append(labelCreates, l.svcCtx.DB.Label.Create(). SetName(tag). SetType(*req.Type). SetStatus(1). SetOrganizationID(organizationId). SetFrom(1). SetMode(1). SetConditions(`{}`). SetCreatedAt(time.Now()). SetUpdatedAt(time.Now()), ) } inserted = append(inserted, tag) insertNames = append(insertNames, tag) // 新增:记录本次尝试插入的标签 } if len(labelCreates) > 0 { err := l.svcCtx.DB.Label.CreateBulk(labelCreates...). OnConflict(sql.ConflictColumns(label.FieldName, label.FieldOrganizationID)). DoNothing(). Exec(l.ctx) if err != nil { 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"}, Data: types.LabelImportInfo{ 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 }