|
|
package goods
|
|
|
|
|
|
import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"log"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
"recook/internal/back"
|
|
|
"recook/internal/dbc"
|
|
|
"recook/internal/model/goods"
|
|
|
"recook/internal/model/vend"
|
|
|
"recook/internal/static_path"
|
|
|
"recook/tools"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
"time"
|
|
|
"unicode/utf8"
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
"github.com/shopspring/decimal"
|
|
|
)
|
|
|
|
|
|
type attrsParam struct {
|
|
|
Name string `json:"name" validate:"required,numeric"`
|
|
|
Children []string `json:"children" validate:"required,numeric"`
|
|
|
}
|
|
|
|
|
|
type skuParam struct {
|
|
|
CombineValue string `json:"combineValue" validate:"required"`
|
|
|
PicURL string `json:"picUrl" validate:"required"`
|
|
|
Code string `json:"code"`
|
|
|
PurchasePrice float64 `json:"purchasePrice" validate:"required"`
|
|
|
OriginalPrice float64 `json:"originalPrice" validate:"required"`
|
|
|
DiscountPrice float64 `json:"discountPrice" validate:"required"` // 折扣价
|
|
|
CommissionRate float64 `json:"commissionRate" validate:"required"` // 佣金
|
|
|
Inventory uint `json:"inventory" validate:"required"` // 库存量 可以直接补货
|
|
|
SalesVolumeInc uint `json:"salesVolumeInc"`
|
|
|
Coupon float64 `json:"coupon"`
|
|
|
GoodsNum string `json:"goodsNum"`
|
|
|
BmSkuId string `json:"bm_sku_id"` //舶茂的skuid
|
|
|
BmShopId string ` json:"bm_shop_id"` //舶茂的商家id
|
|
|
}
|
|
|
|
|
|
type photoParam struct {
|
|
|
IsMaster uint `json:"isMaster" validate:"required"`
|
|
|
OrderNo uint `json:"orderNo" validate:"required"`
|
|
|
Name string `json:"name"`
|
|
|
Width uint `json:"width" validate:"required"`
|
|
|
Height uint `json:"height" validate:"required"`
|
|
|
URL string `json:"url" validate:"required"`
|
|
|
Type int
|
|
|
}
|
|
|
|
|
|
type promotionPhotoParam struct {
|
|
|
Width uint `json:"width"`
|
|
|
Height uint `json:"height"`
|
|
|
URL string `json:"url"`
|
|
|
}
|
|
|
|
|
|
type createGoodsAbstractParam struct {
|
|
|
ID uint `json:"id"`
|
|
|
BrandID uint `json:"brandID" validate:"required,numeric"`
|
|
|
VendorID uint `json:"vendorId"`
|
|
|
GoodsName string `json:"goodsName" validate:"required"`
|
|
|
Description string `json:"description"`
|
|
|
Material string `json:"material"`
|
|
|
CategoryID uint `json:"categoryID" validate:"required"`
|
|
|
PublishStatus uint `json:"publishStatus"`
|
|
|
Weight float64 `json:"weight"`
|
|
|
FreightID uint `json:"freightId" validate:"required"`
|
|
|
IsJoinTeamPerformance uint `json:"isJoinTeamPerformance" validate:"oneof=0 1"`
|
|
|
Attributes []attrsParam `json:"attributes" validate:"required"`
|
|
|
Sku []skuParam `json:"sku" validate:"required"`
|
|
|
MainPictures []photoParam `json:"mainPictures" validate:"required"`
|
|
|
DetailPictures []photoParam `json:"detailPictures" validate:"required"`
|
|
|
QualityPictures []photoParam `json:"qualityPictures"`
|
|
|
OtherPictures []photoParam `json:"otherPictures""`
|
|
|
PromotionPicture promotionPhotoParam `json:"promotionPicture"`
|
|
|
VideoPath string `json:"videoPath"`
|
|
|
}
|
|
|
|
|
|
func CreateGoods(c *gin.Context) {
|
|
|
var p createGoodsAbstractParam
|
|
|
if err := tools.Params(&p, c); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if err := checkParam(&p); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var cate goods.Category
|
|
|
if err := dbc.DB.First(&cate, "id=?", p.CategoryID).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
if cate.ParentId == 0 {
|
|
|
back.Err(c, "必须指定子类目")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var brand goods.Brand
|
|
|
if err := dbc.DB.First(&brand, "id = ?", p.BrandID).Error; err != nil {
|
|
|
back.Err(c, "品牌不存在")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var goodsInfo goods.Information
|
|
|
tx := dbc.DB.Begin()
|
|
|
{
|
|
|
goodsInfo = goods.Information{
|
|
|
BrandID: p.BrandID,
|
|
|
VendorID: p.VendorID,
|
|
|
GoodsName: p.GoodsName,
|
|
|
Description: p.Description,
|
|
|
Material: p.Material,
|
|
|
FirstCategoryID: cate.ParentId,
|
|
|
SecondCategoryID: cate.ID,
|
|
|
PublishStatus: p.PublishStatus,
|
|
|
Weight: decimal.NewFromFloat(p.Weight),
|
|
|
FreightID: p.FreightID,
|
|
|
IsJoinTeamPerformance: p.IsJoinTeamPerformance,
|
|
|
Hash: tools.GenerateGoodsHashSign(),
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&goodsInfo).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// ---------------------------更新商品品牌属性---------------------------------
|
|
|
if err := tx.Model(&brand).Update(goods.Brand{GoodsCount: brand.GoodsCount + 1}).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// ---------------------------存储属性---------------------------------
|
|
|
/*存储attrs*/
|
|
|
attrsValueMap := map[string]uint{}
|
|
|
for _, v1 := range p.Attributes {
|
|
|
for _, v2 := range v1.Children {
|
|
|
|
|
|
attr := goods.Attribute{
|
|
|
GoodsID: goodsInfo.ID,
|
|
|
Name: v1.Name,
|
|
|
Value: v2,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&attr).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
attrsValueMap[attr.Value] = attr.ID
|
|
|
}
|
|
|
}
|
|
|
// ------------------------------存储sku------------------------------
|
|
|
|
|
|
/*存储组合*/
|
|
|
for _, v := range p.Sku {
|
|
|
array := strings.Split(v.CombineValue, ",")
|
|
|
combineIDs := make([]string, 0, 0)
|
|
|
combineNames := make([]string, 0, 0)
|
|
|
for _, v := range array {
|
|
|
idStr := strconv.Itoa(int(attrsValueMap[v]))
|
|
|
combineIDs = append(combineIDs, idStr)
|
|
|
combineNames = append(combineNames, v)
|
|
|
}
|
|
|
|
|
|
sku := goods.Sku{
|
|
|
GoodsID: goodsInfo.ID,
|
|
|
Name: strings.Join(combineNames, "+"),
|
|
|
CombineID: strings.Join(combineIDs, ","),
|
|
|
PicURL: v.PicURL,
|
|
|
Code: v.Code,
|
|
|
PurchasePrice: decimal.NewFromFloat(v.PurchasePrice).Truncate(2),
|
|
|
OriginalPrice: decimal.NewFromFloat(v.OriginalPrice).Truncate(2),
|
|
|
DiscountPrice: decimal.NewFromFloat(v.DiscountPrice).Truncate(2),
|
|
|
Commission: decimal.NewFromFloat(v.CommissionRate).Mul(decimal.NewFromFloat(v.DiscountPrice)).Truncate(2),
|
|
|
CommissionRate: decimal.NewFromFloat(v.CommissionRate).Truncate(2),
|
|
|
SalesVolume: 0,
|
|
|
Inventory: v.Inventory,
|
|
|
Coupon: decimal.NewFromFloat(v.Coupon).Truncate(2),
|
|
|
GoodsNum: v.GoodsNum,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&sku).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// -----------------------------存储主图-------------------------------
|
|
|
for _, v := range p.MainPictures {
|
|
|
mainPicturePath := filepath.Join(static_path.Dir.Root, v.URL)
|
|
|
_, err := os.Stat(mainPicturePath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
mp := goods.MainPhoto{
|
|
|
GoodsID: goodsInfo.ID,
|
|
|
URL: v.URL,
|
|
|
IsMaster: v.IsMaster,
|
|
|
OrderNo: v.OrderNo,
|
|
|
Width: v.Width,
|
|
|
Height: v.Height,
|
|
|
Name: v.Name,
|
|
|
}
|
|
|
err = tx.Create(&mp).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// -----------------------------存储详情图-------------------------------
|
|
|
for _, v := range p.DetailPictures {
|
|
|
detailPicturePath := filepath.Join(static_path.Dir.Root, v.URL)
|
|
|
_, err := os.Stat(detailPicturePath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
dp := goods.DetailPhoto{
|
|
|
GoodsID: goodsInfo.ID,
|
|
|
URL: v.URL,
|
|
|
OrderNo: v.OrderNo,
|
|
|
Width: v.Width,
|
|
|
Height: v.Height,
|
|
|
Name: v.Name,
|
|
|
}
|
|
|
err = tx.Create(&dp).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ------------------------存储活动图片---------------------------
|
|
|
if len(p.PromotionPicture.URL) > 0 {
|
|
|
promotionPhoto := goods.PromotionPhoto{
|
|
|
GoodsID: goodsInfo.ID,
|
|
|
URL: p.PromotionPicture.URL,
|
|
|
Width: p.PromotionPicture.Width,
|
|
|
Height: p.PromotionPicture.Height,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&promotionPhoto).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ------------------------存储视频------------------------------
|
|
|
if len(p.VideoPath) > 0 {
|
|
|
videoPath := filepath.Join(static_path.Dir.Root, p.VideoPath)
|
|
|
fileInfo, err := os.Stat(videoPath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
fileSize := fileInfo.Size()
|
|
|
|
|
|
duration, err := tools.ParseVideoDuration(videoPath)
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error()+"视频解析失败")
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
v := goods.Video{
|
|
|
GoodsID: goodsInfo.ID,
|
|
|
Thumbnail: tools.GenerateVideoThumbnail(p.VideoPath),
|
|
|
URL: p.VideoPath,
|
|
|
Duration: uint(duration),
|
|
|
Size: float64(fileSize)/(1<<20) + 0.005,
|
|
|
}
|
|
|
|
|
|
err = tx.Create(&v).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
tx.Commit()
|
|
|
|
|
|
back.Suc(c, "操作成功", &goodsInfo)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
校验商品参数合法性
|
|
|
*/
|
|
|
func checkParam(p *createGoodsAbstractParam) error {
|
|
|
if utf8.RuneCountInString(p.GoodsName) > 35 {
|
|
|
return errors.New("商品名称不超过35个字符")
|
|
|
}
|
|
|
if utf8.RuneCountInString(p.GoodsName) < 5 {
|
|
|
log.Println(p.GoodsName)
|
|
|
return errors.New("商品名称符不少于5个字")
|
|
|
}
|
|
|
|
|
|
if len(p.Attributes) == 0 {
|
|
|
return errors.New("商品属性未填写")
|
|
|
}
|
|
|
|
|
|
if len(p.Attributes) > 3 {
|
|
|
return errors.New("商品属性不超过3个")
|
|
|
}
|
|
|
|
|
|
if len(p.MainPictures) < 1 {
|
|
|
return errors.New("商品主要图片至少一张")
|
|
|
}
|
|
|
|
|
|
if len(p.MainPictures) > 5 {
|
|
|
return errors.New("商品主要图片不超过5张")
|
|
|
}
|
|
|
|
|
|
if len(p.DetailPictures) < 1 {
|
|
|
return errors.New("商品详情图片至少一张")
|
|
|
}
|
|
|
|
|
|
if len(p.DetailPictures) > 30 {
|
|
|
return errors.New("商品详情图片不超过30张")
|
|
|
}
|
|
|
|
|
|
valueMap := map[string]int{}
|
|
|
titleMap := map[string]int{}
|
|
|
|
|
|
/*
|
|
|
sku 标题不可一样 用titleMap检测
|
|
|
每个标题下的子项目不超过20个
|
|
|
每个子项目的数值也不能相同,valueMap去检测
|
|
|
把所有子项目的数值保存到valueMap
|
|
|
*/
|
|
|
for _, v1 := range p.Attributes {
|
|
|
if utf8.RuneCountInString(v1.Name) > 10 {
|
|
|
return errors.New("商品具体属性长度不超过10个字符")
|
|
|
}
|
|
|
if _, ok := titleMap[v1.Name]; ok {
|
|
|
return errors.New("SKU中标题不可重复")
|
|
|
}
|
|
|
titleMap[v1.Name] = 1
|
|
|
|
|
|
if len(v1.Children) > 20 {
|
|
|
return errors.New("商品具体属性描述个数不超过20个")
|
|
|
}
|
|
|
for _, v2 := range v1.Children {
|
|
|
if _, ok := valueMap[v2]; ok {
|
|
|
return errors.New("SKU中名称不可重复")
|
|
|
}
|
|
|
valueMap[v2] = 1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
检测价格
|
|
|
检测折扣价
|
|
|
|
|
|
将sku中的组合名称分解成数组 校验每个组合名称是否都在valueMap中
|
|
|
|
|
|
*/
|
|
|
for _, v1 := range p.Sku {
|
|
|
if v1.OriginalPrice < 1.0 {
|
|
|
return errors.New("最少1.0元")
|
|
|
}
|
|
|
if v1.Inventory < 0 {
|
|
|
return errors.New("库存至少0件")
|
|
|
}
|
|
|
|
|
|
array := strings.Split(v1.CombineValue, ",")
|
|
|
|
|
|
for _, v2 := range array {
|
|
|
if _, ok := valueMap[v2]; !ok {
|
|
|
return errors.New("组合名称与属性无法匹配")
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
//这边做供应商那边的新品提报
|
|
|
func CreateByGys(c *gin.Context) {
|
|
|
gys_token := c.Request.Header.Get("X-Recook-GYSToken")
|
|
|
gysId, _ := dbc.Rds.Get(gys_token).Result()
|
|
|
myGysId, _ := strconv.Atoi(gysId)
|
|
|
|
|
|
if myGysId <= 0 {
|
|
|
back.Err(c, "供应商ID不存在")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var p createGoodsAbstractParam
|
|
|
if err := tools.Params(&p, c); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
fmt.Println("--------------------")
|
|
|
fmt.Println(p.ID)
|
|
|
fmt.Println("--------------------")
|
|
|
if err := checkParam(&p); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var cate goods.Category
|
|
|
if err := dbc.DB.First(&cate, "id=?", p.CategoryID).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
if cate.ParentId == 0 {
|
|
|
back.Err(c, "必须指定子类目")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var brand vend.GysEnterpriseBrand
|
|
|
if err := dbc.DB.First(&brand, "id = ?", p.BrandID).Error; err != nil {
|
|
|
back.Err(c, "品牌不存在")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
//获取主品牌
|
|
|
var mainBrand goods.Brand
|
|
|
dbc.DB.First(&mainBrand, "name=?", brand.Name)
|
|
|
|
|
|
var gysGoodsInfo vend.GysGoodsInfo
|
|
|
var gysGoodsInfoHave vend.GysGoodsInfo
|
|
|
tx := dbc.DB.Begin()
|
|
|
//这边不能直接插入到goods表,要插入到gys里面去
|
|
|
|
|
|
{
|
|
|
|
|
|
tx.First(&gysGoodsInfoHave, "id=?", p.ID)
|
|
|
if gysGoodsInfoHave.ID > 0 {
|
|
|
//这边删除老的关联属性,插入新的属性
|
|
|
//gysGoodsInfo
|
|
|
//GysAttribute
|
|
|
//GysGoodsSku
|
|
|
//GysGoodsMainPhoto
|
|
|
//GysGoodsDetailPhoto
|
|
|
//GysGoodsPromotionPhoto
|
|
|
//GysGoodsVideo
|
|
|
tx.Where("goods_id=?", p.ID).Delete(vend.GysAttribute{})
|
|
|
tx.Where("goods_id=?", p.ID).Delete(vend.GysGoodsSku{})
|
|
|
tx.Where("goods_id=?", p.ID).Delete(vend.GysGoodsMainPhoto{})
|
|
|
tx.Where("goods_id=?", p.ID).Delete(vend.GysGoodsDetailPhoto{})
|
|
|
tx.Where("goods_id=?", p.ID).Delete(vend.GysGoodsPromotionPhoto{})
|
|
|
tx.Where("goods_id=?", p.ID).Delete(vend.GysGoodsVideo{})
|
|
|
|
|
|
//更新
|
|
|
tx.Model(&gysGoodsInfoHave).Updates(vend.GysGoodsInfo{
|
|
|
Brand: p.BrandID,
|
|
|
UserID: uint(myGysId),
|
|
|
Title: p.GoodsName,
|
|
|
ViceTitle: p.Description,
|
|
|
Material: p.Material,
|
|
|
FirstCategoryId: cate.ParentId,
|
|
|
SecondCategoryId: cate.ID,
|
|
|
PublishStatus: int(p.PublishStatus), //老的这边0下架,1上架//新的商品状态(1。草稿箱,2。待审核,3.审核失败,4.审核通过,5.下架)
|
|
|
Weight: decimal.NewFromFloat(p.Weight),
|
|
|
Freight: p.FreightID,
|
|
|
Hash: tools.GenerateGoodsHashSign(),
|
|
|
CreatedAts: strconv.FormatInt(time.Now().Unix(), 10),
|
|
|
UpdatedAts: strconv.FormatInt(time.Now().Unix(), 10),
|
|
|
MainBranid: mainBrand.ID,
|
|
|
GcStatus: 1,
|
|
|
QcStatus: 1,
|
|
|
})
|
|
|
gysGoodsInfo = gysGoodsInfoHave
|
|
|
|
|
|
} else {
|
|
|
gysGoodsInfo = vend.GysGoodsInfo{
|
|
|
Brand: p.BrandID,
|
|
|
UserID: uint(myGysId),
|
|
|
Title: p.GoodsName,
|
|
|
ViceTitle: p.Description,
|
|
|
Material: p.Material,
|
|
|
FirstCategoryId: cate.ParentId,
|
|
|
SecondCategoryId: cate.ID,
|
|
|
PublishStatus: int(p.PublishStatus), //老的这边0下架,1上架//新的商品状态(1。草稿箱,2。待审核,3.审核失败,4.审核通过,5.下架)
|
|
|
Weight: decimal.NewFromFloat(p.Weight),
|
|
|
Freight: p.FreightID,
|
|
|
Hash: tools.GenerateGoodsHashSign(),
|
|
|
CreatedAts: strconv.FormatInt(time.Now().Unix(), 10),
|
|
|
UpdatedAts: strconv.FormatInt(time.Now().Unix(), 10),
|
|
|
MainBranid: mainBrand.ID,
|
|
|
GcStatus: 1,
|
|
|
QcStatus: 1,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&gysGoodsInfo).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ---------------------------存储属性---------------------------------
|
|
|
/*存储attrs*/
|
|
|
attrsValueMap := map[string]uint{}
|
|
|
for _, v1 := range p.Attributes {
|
|
|
for _, v2 := range v1.Children {
|
|
|
|
|
|
attr := vend.GysAttribute{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Name: v1.Name,
|
|
|
Value: v2,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&attr).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
attrsValueMap[attr.Value] = attr.ID
|
|
|
}
|
|
|
}
|
|
|
// ------------------------------存储sku------------------------------
|
|
|
|
|
|
/*存储组合*/
|
|
|
for _, v := range p.Sku {
|
|
|
array := strings.Split(v.CombineValue, ",")
|
|
|
combineIDs := make([]string, 0, 0)
|
|
|
combineNames := make([]string, 0, 0)
|
|
|
for _, v := range array {
|
|
|
idStr := strconv.Itoa(int(attrsValueMap[v]))
|
|
|
combineIDs = append(combineIDs, idStr)
|
|
|
combineNames = append(combineNames, v)
|
|
|
}
|
|
|
|
|
|
sku := vend.GysGoodsSku{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Name: strings.Join(combineNames, "+"),
|
|
|
CombineId: strings.Join(combineIDs, ","),
|
|
|
PicUrl: v.PicURL,
|
|
|
Code: v.Code,
|
|
|
PurchasePrice: float32(v.PurchasePrice),
|
|
|
OriginalPrice: float32(v.OriginalPrice),
|
|
|
DiscountPrice: float32(v.DiscountPrice),
|
|
|
CommissionRate: decimal.NewFromFloat(v.CommissionRate).Truncate(2),
|
|
|
Inventory: v.Inventory,
|
|
|
Coupon: v.Coupon,
|
|
|
GoodsNum: v.GoodsNum,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&sku).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// -----------------------------存储主图-------------------------------
|
|
|
for _, v := range p.MainPictures {
|
|
|
mainPicturePath := filepath.Join(static_path.Dir.Root, v.URL)
|
|
|
_, err := os.Stat(mainPicturePath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
mp := vend.GysGoodsMainPhoto{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Url: v.URL,
|
|
|
IsMaster: v.IsMaster,
|
|
|
OrderNo: v.OrderNo,
|
|
|
Width: v.Width,
|
|
|
Height: v.Height,
|
|
|
Name: v.Name,
|
|
|
}
|
|
|
err = tx.Create(&mp).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// -----------------------------存储详情图-------------------------------
|
|
|
for _, v := range p.DetailPictures {
|
|
|
detailPicturePath := filepath.Join(static_path.Dir.Root, v.URL)
|
|
|
_, err := os.Stat(detailPicturePath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
dp := vend.GysGoodsDetailPhoto{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Url: v.URL,
|
|
|
OrderNo: v.OrderNo,
|
|
|
Width: v.Width,
|
|
|
Height: v.Height,
|
|
|
Name: v.Name,
|
|
|
}
|
|
|
err = tx.Create(&dp).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//---------------资质部分
|
|
|
// type=1 资质报告,2其他资质
|
|
|
for _, v := range p.QualityPictures {
|
|
|
detailPicturePath := filepath.Join(static_path.Dir.Root, v.URL)
|
|
|
_, err := os.Stat(detailPicturePath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
dp := vend.GysGoodsDetailPhoto{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Url: v.URL,
|
|
|
OrderNo: v.OrderNo,
|
|
|
Width: v.Width,
|
|
|
Height: v.Height,
|
|
|
Name: v.Name,
|
|
|
Type: 1,
|
|
|
}
|
|
|
err = tx.Create(&dp).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
for _, v := range p.OtherPictures {
|
|
|
detailPicturePath := filepath.Join(static_path.Dir.Root, v.URL)
|
|
|
_, err := os.Stat(detailPicturePath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
dp := vend.GysGoodsDetailPhoto{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Url: v.URL,
|
|
|
OrderNo: v.OrderNo,
|
|
|
Width: v.Width,
|
|
|
Height: v.Height,
|
|
|
Name: v.Name,
|
|
|
Type: 2,
|
|
|
}
|
|
|
err = tx.Create(&dp).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ------------------------存储活动图片---------------------------
|
|
|
if len(p.PromotionPicture.URL) > 0 {
|
|
|
promotionPhoto := vend.GysGoodsPromotionPhoto{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Url: p.PromotionPicture.URL,
|
|
|
Width: p.PromotionPicture.Width,
|
|
|
Height: p.PromotionPicture.Height,
|
|
|
}
|
|
|
|
|
|
if err := tx.Create(&promotionPhoto).Error; err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ------------------------存储视频------------------------------
|
|
|
if len(p.VideoPath) > 0 {
|
|
|
videoPath := filepath.Join(static_path.Dir.Root, p.VideoPath)
|
|
|
fileInfo, err := os.Stat(videoPath)
|
|
|
if err != nil && os.IsNotExist(err) {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
fileSize := fileInfo.Size()
|
|
|
|
|
|
duration, err := tools.ParseVideoDuration(videoPath)
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error()+"视频解析失败")
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
|
|
|
v := vend.GysGoodsVideo{
|
|
|
GoodsId: gysGoodsInfo.ID,
|
|
|
Thumbnail: tools.GenerateVideoThumbnail(p.VideoPath),
|
|
|
Url: p.VideoPath,
|
|
|
Duration: uint(duration),
|
|
|
Size: float64(fileSize)/(1<<20) + 0.005,
|
|
|
}
|
|
|
|
|
|
err = tx.Create(&v).Error
|
|
|
if err != nil {
|
|
|
back.Err(c, err.Error())
|
|
|
tx.Rollback()
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
tx.Commit()
|
|
|
|
|
|
back.Suc(c, "操作成功", &gysGoodsInfo)
|
|
|
}
|
|
|
func MyDecimal(value float64) float64 {
|
|
|
value, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", value), 64)
|
|
|
return value
|
|
|
}
|
|
|
|
|
|
type GysGoodsListPem struct {
|
|
|
Page int //从1开始传
|
|
|
}
|
|
|
|
|
|
//新品提报的列表
|
|
|
func GysGoodsList(c *gin.Context) {
|
|
|
var p GysGoodsListPem
|
|
|
|
|
|
err := tools.Params(&p, c)
|
|
|
if err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
if p.Page <= 0 {
|
|
|
p.Page = 1
|
|
|
}
|
|
|
|
|
|
//获取供应商
|
|
|
gys_token := c.Request.Header.Get("X-Recook-GYSToken")
|
|
|
gysId, _ := dbc.Rds.Get(gys_token).Result()
|
|
|
myGysId, _ := strconv.Atoi(gysId)
|
|
|
|
|
|
if myGysId <= 0 {
|
|
|
back.Fail(c, "供应商id不存在")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
var gysGoods []vend.GysGoodsInfo
|
|
|
dbc.DB.Limit(10).Offset((p.Page-1)*10).Find(&gysGoods, "user_id=? and publish_status!=4", myGysId)
|
|
|
|
|
|
total := 0
|
|
|
dbc.DB.Model(&vend.GysGoodsInfo{}).Where("user_id=?", myGysId).Count(&total)
|
|
|
for key, item := range gysGoods {
|
|
|
//获取品牌
|
|
|
var gysBrand vend.GysEnterpriseBrand
|
|
|
dbc.DB.First(&gysBrand, "id=?", item.Brand)
|
|
|
gysGoods[key].GysBrandName = gysBrand
|
|
|
|
|
|
//获取商品主图
|
|
|
var gysMainPhoto vend.GysGoodsMainPhoto
|
|
|
dbc.DB.First(&gysMainPhoto, "goods_id=? and is_master=1", item.ID)
|
|
|
gysGoods[key].GysMainPhoto = gysMainPhoto.Url
|
|
|
|
|
|
//获取shang商品状态
|
|
|
gysGoods[key].GysGoodsStatusTxt = GetGoodsStatus(item.PublishStatus)
|
|
|
}
|
|
|
|
|
|
back.Suc(c, "", gin.H{
|
|
|
"gysGoods": gysGoods,
|
|
|
"total": total,
|
|
|
})
|
|
|
return
|
|
|
}
|
|
|
|
|
|
//供应商商品状态
|
|
|
func GetGoodsStatus(status int) (statusTxt string) {
|
|
|
|
|
|
if status == 1 {
|
|
|
statusTxt = "仓库中"
|
|
|
} else if status == 2 {
|
|
|
statusTxt = "待审核"
|
|
|
} else if status == 3 {
|
|
|
statusTxt = "驳回"
|
|
|
} else if status == 4 {
|
|
|
statusTxt = "已上架"
|
|
|
} else if status == 5 {
|
|
|
statusTxt = "停售"
|
|
|
} else if status == 6 {
|
|
|
statusTxt = "待审核"
|
|
|
} else if status == 7 {
|
|
|
statusTxt = "待审核"
|
|
|
} else {
|
|
|
statusTxt = ""
|
|
|
}
|
|
|
return statusTxt
|
|
|
}
|
|
|
|
|
|
type GysToPublishPem struct {
|
|
|
GoodsId uint `json:"goods_id"`
|
|
|
}
|
|
|
|
|
|
//供应商递交审核
|
|
|
func GysToPublish(c *gin.Context) {
|
|
|
var p GysToPublishPem
|
|
|
err := tools.Params(&p, c)
|
|
|
if err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
//判断这个产品是不是自己的
|
|
|
gys_token := c.Request.Header.Get("X-Recook-GYSToken")
|
|
|
gysId, _ := dbc.Rds.Get(gys_token).Result()
|
|
|
myGysId, _ := strconv.Atoi(gysId)
|
|
|
var gysGoods vend.GysGoodsInfo
|
|
|
dbc.DB.First(&gysGoods, "id=? and user_id=?", p.GoodsId, myGysId)
|
|
|
if gysGoods.ID <= 0 {
|
|
|
back.Fail(c, "该产品不是您发布的,无权提报")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if gysGoods.PublishStatus != 1 {
|
|
|
back.Fail(c, "当前产品状态不支持提报!")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
//继续提报
|
|
|
dbc.DB.Model(&gysGoods).Updates(vend.GysGoodsInfo{
|
|
|
PublishStatus: 2,
|
|
|
UpdatedAts: strconv.FormatInt(time.Now().Unix(), 10),
|
|
|
})
|
|
|
back.Suc(c, "", nil)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
type GysToLowPem struct {
|
|
|
GoodsId uint `json:"goods_id"`
|
|
|
}
|
|
|
|
|
|
//供应商撤销审核
|
|
|
func GysToLow(c *gin.Context) {
|
|
|
var p GysToPublishPem
|
|
|
err := tools.Params(&p, c)
|
|
|
if err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
}
|
|
|
//判断这个产品是不是自己的
|
|
|
gys_token := c.Request.Header.Get("X-Recook-GYSToken")
|
|
|
gysId, _ := dbc.Rds.Get(gys_token).Result()
|
|
|
myGysId, _ := strconv.Atoi(gysId)
|
|
|
var gysGoods vend.GysGoodsInfo
|
|
|
dbc.DB.First(&gysGoods, "id=? and user_id=?", p.GoodsId, myGysId)
|
|
|
if gysGoods.ID <= 0 {
|
|
|
back.Fail(c, "该产品不是您发布的,无权提报")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
if gysGoods.PublishStatus != 2 {
|
|
|
back.Fail(c, "当前产品状态不支持撤销!")
|
|
|
return
|
|
|
}
|
|
|
dbc.DB.Model(&gysGoods).Updates(vend.GysGoodsInfo{
|
|
|
PublishStatus: 1,
|
|
|
})
|
|
|
back.Suc(c, "", nil)
|
|
|
return
|
|
|
|
|
|
}
|