package task import ( "archive/zip" "bytes" "fmt" util "github.com/alibabacloud-go/tea-utils/service" "github.com/alibabacloud-go/tea/tea" "image" "image/jpeg" "image/png" "io" "io/fs" "io/ioutil" "net/http" "net/url" "os" path2 "path" "path/filepath" "recook/internal/back" "recook/internal/dbc" "recook/internal/libs/weibo" "recook/internal/static_path" "recook/internal/v2/model/recook/goods" "recook/internal/v2/model/search_ali" "recook/tools" "strconv" "strings" mysql2 "git.oa00.com/go/mysql" "github.com/corona10/goimagehash" "github.com/gin-gonic/gin" "golang.org/x/text/encoding/simplifiedchinese" "golang.org/x/text/transform" "gorm.io/gorm" ) type Goods struct { } type Base struct { goods.RecookGoodsInfoModel Photo goods.RecookGoodsMainPhotoModel `gorm:"foreignKey:goods_id"` } const MaxDistance = 5 func (g *Goods) ZipSync(c *gin.Context) { file, err := c.FormFile("upload") if err != nil { c.String(http.StatusBadRequest, "请求失败1") return } f, err := file.Open() if err != nil { c.String(http.StatusBadRequest, "请求失败2") return } zipReader, err := zip.NewReader(f, file.Size) if err != nil { c.String(http.StatusBadRequest, "请求失败3") return } for _, v := range zipReader.File { if v.FileInfo().IsDir() { continue } decodeName := "" if v.Flags == 0 { i := bytes.NewReader([]byte(v.Name)) decoder := transform.NewReader(i, simplifiedchinese.GB18030.NewDecoder()) content, _ := ioutil.ReadAll(decoder) decodeName = string(content) } else { decodeName = v.Name } decodeName = strings.Split(decodeName, "/")[1] name := path2.Base(decodeName) ext := path2.Ext(decodeName) pathName := filepath.Join(static_path.Dir.Root, static_path.Dir.Photo, tools.MD5(name)+ext) content, _ := v.Open() b, _ := io.ReadAll(content) if err = os.WriteFile(pathName, b, fs.ModePerm); err != nil { c.String(http.StatusBadRequest, "请求失败3") break } brandName := decodeName[0 : len(decodeName)-len(ext)] var brand goods.RecookGoodsBrandModel mysql2.Db.First(&brand, "name = ? AND created_at > '2021-08-26'", brandName) if brand.Id == 0 { continue } brand.LogoUrl = filepath.Join(static_path.Dir.Photo, tools.MD5(name)+ext) mysql2.Db.Save(&brand) } c.String(http.StatusBadRequest, "请求成功") } func (g *Goods) WeiboSync(c *gin.Context) { go func() { for p := 1; p <= 20; p++ { v := url.Values{} v.Set("containerid", "107603"+"5918987931") v.Set("page", strconv.Itoa(p)) data, err := weibo.GetJson(v) if err != nil { return } weibo.ParsePage(data) } }() c.JSON(200, gin.H{ "status": "success", }) return } // Update 更新相关 func (g *Goods) Update(c *gin.Context) { var data []Base mysql2.Db.Preload("Photo", func(db *gorm.DB) *gorm.DB { return db.Where("is_master = 1").Where("url <> ''") }).Find(&data, "publish_status = 1") fmt.Println(len(data)) var temp []goods.Associate for _, v := range data { if v.Photo.Hash == "" { continue } o, err := goimagehash.ImageHashFromString(v.Photo.Hash) if err != nil { back.Fail(c, "err 1: "+err.Error()) return } fmt.Println(len(data)) for _, j := range data { if j.SecondCategoryID != v.SecondCategoryID || j.Id == v.Id || j.Photo.Hash == "" { continue } b, err := goimagehash.ImageHashFromString(j.Photo.Hash) if err != nil { back.Fail(c, "err 2: "+err.Error()) return } distance, err := o.Distance(b) if err != nil { back.Fail(c, "err 3: "+err.Error()) return } fmt.Println(distance) if distance <= MaxDistance { temp = append(temp, goods.Associate{ GoodsID: v.Id, OtherGoodsID: j.Id, Distance: distance, }) } } } if err := mysql2.Db.Transaction(func(tx *gorm.DB) error { if err := tx.Where("1 = 1").Delete(&goods.Associate{}).Error; err != nil { return err } var t []goods.Associate fmt.Println("temp:", temp) for _, v := range temp { t = append(t, v) if len(t) == 100 { fmt.Println("新建相似表:", len(t)) if err := tx.Create(&t).Error; err != nil { return err } t = []goods.Associate{} } } if len(t) > 0 { fmt.Println("新建相似表:", len(t)) if err := tx.Create(&t).Error; err != nil { return err } } return nil }); err != nil { back.Fail(c, err.Error()) return } back.Suc(c, "操作完成", nil) } func CalHash(model goods.RecookGoodsMainPhotoModel) (string, error) { uri := filepath.Join(static_path.Dir.Root, model.Url) file, _ := os.Open(uri) defer file.Close() var img image.Image if strings.HasSuffix(uri, "png") { img1, err := png.Decode(file) if err != nil { return "", err } img = img1 fmt.Println("img:", img) } else if strings.HasSuffix(uri, "jpg") || strings.HasSuffix(uri, "jpeg") { img1, err := jpeg.Decode(file) if err != nil { return "", err } img = img1 fmt.Println("img:", img) } else { return "", nil } if img == nil { model.Hash = "" return "", nil } hash, err := goimagehash.DifferenceHash(img) if err != nil { return "", err } model.Hash = hash.ToString() fmt.Println("hash:", hash.ToString()) dbc.DB.Table(model.TableName()).Where("id=?", model.Id).Updates(model) return hash.ToString(), nil } func (g *Goods) Sync(c *gin.Context) { b := c.Query("brand") go SyncAllSku(b) c.String(200, "suc") } func (g *Goods) Fix(c *gin.Context) { go SyncJDImage() c.String(200, "suc") } func (g *Goods) AttrSync(c *gin.Context) { go AttrSync() c.String(200, "suc") } func (g *Goods) Publish(c *gin.Context) { go func() { var gs []goods.RecookGoodsInfoModel mysql2.Db.Find(&gs) for _, v := range gs { var gsk []goods.RecookGoodsSkuModel mysql2.Db.Find(&gsk, "goods_id = ?", v.Id) if len(gsk) == 0 { continue } flag := 1 price := 1 for _, j := range gsk { if j.Inventory != 0 { flag = 0 } if j.DiscountPrice.IsZero() { price = 0 } } if flag == 0 && price == 1 { mysql2.Db.Table((&goods.RecookGoodsInfoModel{}).TableName()). Where("id = ?", v.Id).Update("publish_status", 1) } if flag == 1 { mysql2.Db.Table((&goods.RecookGoodsInfoModel{}).TableName()). Where("id = ?", v.Id).Update("publish_status", 0) } } }() c.String(200, "suc") } func (g *Goods) OpenSearch(c *gin.Context) { go func() { page := 0 size := 1000 for { var gs []goods.RecookGoodsInfoModel mysql2.Db.Offset(page * size).Limit(size).Find(&gs) if len(gs) == 0 { break } config := &search_ali.Config{ Endpoint: tea.String(search_ali.EndPoint), AccessKeyId: tea.String(search_ali.AccessKeyId), AccessKeySecret: tea.String(search_ali.AccessKeySecret), } client, _clientErr := search_ali.NewClient(config) // 如果 NewClient 过程中出现异常. 则 返回 _clientErr 且输出 错误信息. if _clientErr != nil { fmt.Println(_clientErr) return } runTime := &util.RuntimeOptions{ ConnectTimeout: tea.Int(5000), ReadTimeout: tea.Int(10000), Autoretry: tea.Bool(false), IgnoreSSL: tea.Bool(false), MaxIdleConns: tea.Int(50), } requestBody := make([]search_ali.Res, 0) for _, v := range gs { cmd := search_ali.ADD if v.PublishStatus == 0 { cmd = search_ali.DELETE } requestBody = append(requestBody, search_ali.Res{ Cmd: cmd, Fields: search_ali.F{ ID: v.Id, GoodsName: v.GoodsName, }, }) } fmt.Println("request len:", len(requestBody)) // 发送请求的方法调用. r1, rr := client.Request( tea.String("POST"), tea.String("/v3/openapi/apps/"+search_ali.App+"/"+search_ali.Table+"/actions/bulk"), nil, nil, requestBody, runTime) page += 1 if rr != nil{ fmt.Println(rr.Error()) continue } fmt.Println(r1) } }() c.String(200, "sync") }