You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

646 lines
15 KiB

package goods
import (
"os"
"path/filepath"
"recook/internal/api/manage/excel"
"recook/internal/back"
"recook/internal/dbc"
"recook/internal/model/freight"
"recook/internal/model/goods"
"recook/internal/static_path"
"recook/tools"
"strconv"
"unicode/utf8"
"github.com/360EntSecGroup-Skylar/excelize/v2"
"github.com/gin-gonic/gin"
"github.com/jinzhu/gorm"
"github.com/shopspring/decimal"
)
type updatePromotionPhotoParam struct {
GoodsID uint `json:"goodsID" validate:"required"`
Width uint `json:"width" validate:"required"`
Height uint `json:"height" validate:"required"`
URL string `json:"url" validate:"required"`
}
type updateGoodsPhotosParam struct {
UserID uint `json:"userId" validate:"required"`
GoodsID uint `json:"goodsId" validate:"required"`
PhotoPaths []string `json:"photoPaths" validate:"required"`
}
type updateGoodsVideoParam struct {
UserID uint `json:"user_id" validate:"required"`
GoodsID uint `json:"goods_id" validate:"required"`
VideoPath string `json:"video_path" validate:"required"`
}
type deleteGoodsVideoParam struct {
GoodsID uint `json:"goods_id" validate:"required"`
}
type updateGoodsAbstractParam struct {
UserId uint `json:"user_id" validate:"required"`
GoodsId uint `json:"goods_id" validate:"required"`
UpdateField uint `json:"update_field" validate:"required"`
Value interface{} `json:"value" validate:"required"`
}
type changeGoodsPhotoParam struct {
UserId uint `json:"user_id" validate:"required"`
GoodsId uint `json:"goods_id" validate:"required"`
OriginPath string `json:"origin_path" validate:"required"`
ChangePath string `json:"change_path" validate:"required"`
Width uint `json:"width" validate:"required"`
Height uint `json:"height" validate:"required"`
}
func UpdateGoodsAbstractInfo(c *gin.Context) {
var p updateGoodsAbstractParam
if err := tools.Params(&p, c); err != nil {
back.Fail(c, err.Error())
return
}
var info goods.Information
if err := dbc.DB.First(&info, "id = ?", p.GoodsId).Error; err != nil {
back.Fail(c, err.Error())
return
}
if p.UpdateField == 1 {
v := p.Value.(string)
if utf8.RuneCountInString(v) > 35 {
back.Fail(c, "商品名称不超过35个字符")
return
}
if utf8.RuneCountInString(v) < 5 {
back.Fail(c, "商品名称符不少于5个字")
return
}
if err := dbc.DB.Model(&info).Updates(goods.Information{GoodsName: v}).Error; err != nil {
back.Err(c, err.Error())
return
}
back.Suc(c, "", nil)
} else if p.UpdateField == 2 {
v := p.Value.(string)
if utf8.RuneCountInString(v) > 30 {
back.Fail(c, "商品描述不超过30个字符")
return
}
if err := dbc.DB.Model(&info).Updates(map[string]interface{}{"description": v}).Error; err != nil {
back.Err(c, err.Error())
return
}
back.Suc(c, "", nil)
} else if p.UpdateField == 3 {
} else if p.UpdateField == 4 {
} else if p.UpdateField == 5 {
v := p.Value.(float64)
if v < 0 {
back.Fail(c, "参数错误")
return
}
if v > 1000 {
back.Fail(c, "最大支持1000")
return
}
if err := dbc.DB.Model(&info).Updates(map[string]interface{}{"weight": v}).Error; err != nil {
back.Err(c, err.Error())
return
}
back.Suc(c, "", nil)
} else {
back.Fail(c, "参数错误")
}
}
func UpdateGoodsPromotionPhoto(c *gin.Context) {
var p updatePromotionPhotoParam
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var photo goods.PromotionPhoto
err = dbc.DB.First(&photo, "goods_id = ?", p.GoodsID).Error
if err != nil && gorm.IsRecordNotFoundError(err) == false {
back.Err(c, err.Error())
return
}
if gorm.IsRecordNotFoundError(err) {
photo = goods.PromotionPhoto{
GoodsID: p.GoodsID,
URL: p.URL,
Width: p.Width,
Height: p.Height,
}
err = dbc.DB.Create(&photo).Error
if err != nil {
back.Fail(c, err.Error())
return
}
} else {
err = dbc.DB.Model(&photo).Updates(goods.PromotionPhoto{
URL: p.URL,
Width: p.Width,
Height: p.Height,
}).Error
if err != nil {
back.Fail(c, err.Error())
return
}
}
back.Suc(c, "操作成功", nil)
}
/*
更新商品详情图片顺序
*/
func UpdateDetailPhotoOrder(c *gin.Context) {
var p updateGoodsPhotosParam
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var arr []goods.DetailPhoto
err = dbc.DB.Find(&arr, "goods_id = ?", p.GoodsID).Error
if err != nil {
back.Fail(c, err.Error())
return
}
// 先验证。不要走数据库
for _, v1 := range arr {
// 遍历找到该图的顺序
var odr = -1
for j, v2 := range p.PhotoPaths {
if v1.URL == v2 {
odr = j
break
}
}
if odr == -1 {
back.Fail(c, "参数不正确,不能完全匹配")
return
}
}
tx := dbc.DB.Begin()
{
for i, v1 := range arr {
// 遍历找到该图的顺序
for j, v2 := range p.PhotoPaths {
if v1.URL == v2 {
err = tx.Model(&(arr[i])).Updates(map[string]interface{}{
"order_no": j,
}).Error
if err != nil {
back.Fail(c, err.Error())
tx.Rollback()
return
}
break
}
}
}
}
tx.Commit()
back.Suc(c, "操作成功", nil)
}
/*
更新商品主图顺序
*/
func UpdateMainPhotoOrder(c *gin.Context) {
var p updateGoodsPhotosParam
if err := tools.Params(&p, c); err != nil {
back.Fail(c, err.Error())
return
}
var photos []goods.MainPhoto
if err := dbc.DB.Find(&photos, "goods_id = ?", p.GoodsID).Error; err != nil {
back.Fail(c, err.Error())
return
}
// 先验证。不要走数据库
for _, v1 := range photos {
// 遍历找到该图的顺序
var odr = -1
for j, v2 := range p.PhotoPaths {
if v1.URL == v2 {
odr = j
break
}
}
if odr == -1 {
back.Fail(c, "参数不正确,不能完全匹配")
return
}
}
tx := dbc.DB.Begin()
{
for i1, v1 := range p.PhotoPaths {
isMaster := 0
if i1 == 0 {
isMaster = 1
}
for _, v2 := range photos {
if v1 == v2.URL {
if err := tx.Model(&v2).Updates(map[string]interface{}{
"order_no": i1,
"is_master": isMaster,
}).Error; err != nil {
back.Fail(c, err.Error())
tx.Rollback()
return
}
break
}
}
}
}
tx.Commit()
back.Suc(c, "操作成功", nil)
}
func ChangeGoodsMainPhoto(c *gin.Context) {
var p changeGoodsPhotoParam
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var mp goods.MainPhoto
err = dbc.DB.First(&mp, "url = ?", p.OriginPath).Error
if err != nil {
back.Fail(c, "不存在该图")
return
}
if mp.GoodsID != p.GoodsId {
back.Fail(c, "商品参数异常")
return
}
err = dbc.DB.Model(&mp).Updates(goods.MainPhoto{URL: p.ChangePath, Width: p.Width, Height: p.Height}).Error
if err != nil {
back.Fail(c, err.Error())
return
}
back.Suc(c, "", nil)
}
func ChangeGoodsDetailPhoto(c *gin.Context) {
var p changeGoodsPhotoParam
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var dp goods.DetailPhoto
err = dbc.DB.First(&dp, "url = ?", p.OriginPath).Error
if err != nil {
back.Fail(c, "不存在该图")
return
}
if dp.GoodsID != p.GoodsId {
back.Fail(c, "商品参数异常")
return
}
err = dbc.DB.Model(&dp).Updates(goods.MainPhoto{URL: p.ChangePath, Width: p.Width, Height: p.Height}).Error
if err != nil {
back.Fail(c, err.Error())
return
}
back.Suc(c, "", nil)
}
func DeletedGoodsVideo(c *gin.Context) {
var p deleteGoodsVideoParam
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var video goods.Video
err = dbc.DB.First(&video, "goods_id = ?", p.GoodsID).Error
if err != nil && !gorm.IsRecordNotFoundError(err) {
back.Err(c, err.Error())
return
}
if video.ID > 0 { // 更换
if video.GoodsID != p.GoodsID {
back.Err(c, "商品与视频无法匹配")
return
}
dbc.DB.Where("goods_id = ?", p.GoodsID).Delete(&video)
}
back.Suc(c, "", nil)
}
func UpdateGoodsVideo(c *gin.Context) {
var p updateGoodsVideoParam
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var video goods.Video
err = dbc.DB.First(&video, "goods_id = ?", p.GoodsID).Error
if err != nil && !gorm.IsRecordNotFoundError(err) {
back.Err(c, err.Error())
return
}
videoPath := filepath.Join(static_path.Dir.Root, p.VideoPath)
fileInfo, err := os.Stat(videoPath)
if err != nil && os.IsNotExist(err) {
back.Fail(c, "不存在该视频文件")
return
}
fileSize := fileInfo.Size()
duration, err := tools.ParseVideoDuration(videoPath)
if err != nil {
back.Err(c, err.Error()+"视频解析失败")
return
}
if video.ID > 0 { // 更换
if video.GoodsID != p.GoodsID {
back.Err(c, "商品与视频无法匹配")
return
}
dbc.DB.Model(&video).Updates(goods.Video{
URL: p.VideoPath,
Thumbnail: tools.GenerateVideoThumbnail(p.VideoPath),
Duration: uint(duration),
Size: float64(fileSize)/(1<<20) + 0.005,
})
} else {
video = goods.Video{
GoodsID: p.GoodsID,
URL: p.VideoPath,
Thumbnail: tools.GenerateVideoThumbnail(p.VideoPath),
Duration: uint(duration),
Size: float64(fileSize)/(1<<20) + 0.005,
}
err = dbc.DB.Create(&video).Error
if err != nil {
back.Err(c, err.Error())
return
}
}
back.Suc(c, "", nil)
}
type updateStatus struct {
UserID uint `json:"userId" validate:"required"`
GoodsID uint `json:"goodsId" validate:"required"`
Status uint `json:"status" validate:"oneof=0 1"`
}
func UpdateGoodsPublishStatus(c *gin.Context) {
var p updateStatus
err := tools.Params(&p, c)
if err != nil {
back.Fail(c, err.Error())
return
}
var goodsInfo goods.Information
dbc.DB.First(&goodsInfo, p.GoodsID)
if goodsInfo.PublishStatus != p.Status {
if err = dbc.DB.Model(&goodsInfo).Updates(map[string]interface{}{
"publish_status": p.Status,
"hash": tools.GenerateGoodsHashSign(),
}).Error; err != nil {
back.Err(c, err.Error())
return
}
}
back.Suc(c, "", nil)
}
type freightParam struct {
GoodsID uint `json:"goodsId"`
FreightID uint `json:"freightId"`
}
// 更换运费模版
func UpdateGoodsFreight(c *gin.Context) {
var p freightParam
if err := tools.Params(&p, c); err != nil {
back.Fail(c, err.Error())
return
}
var goodsInfo goods.Information
dbc.DB.First(&goodsInfo, p.GoodsID)
if err := dbc.DB.Model(&goodsInfo).Updates(goods.Information{
FreightID: p.FreightID,
}).Error; err != nil {
back.Err(c, err.Error())
return
}
back.Suc(c, "", &goodsInfo)
}
// 更改商品信息
type updateGoodsInfoParam struct {
GoodsID uint `json:"goodsId" validate:"required"`
VendorID uint `json:"vendorId"`
GoodsName string `json:"goodsName" validate:"required"`
Description string `json:"description" `
Material string `json:"material" `
FirstCategoryID uint `json:"firstCategoryId" validate:"required"`
SecondCategoryID uint `json:"secondCategoryId" validate:"required"`
PublishStatus uint `json:"publishStatus"`
Weight decimal.Decimal `json:"weight"`
FreightID uint `json:"freightId" validate:"required"`
IsJoinTeamPerformance uint `json:"isJoinTeamPerformance"` // 是否参与团队业绩计算
}
func UpdateGoodsInfo(c *gin.Context) {
var p updateGoodsInfoParam
if err := tools.Params(&p, c); err != nil {
back.Fail(c, err.Error())
return
}
var secCate goods.Category
dbc.DB.First(&secCate, "id = ? AND parent_id = ?", p.SecondCategoryID, p.FirstCategoryID)
if secCate.ID == 0 {
back.Fail(c, "类目参数错误")
return
}
var goodsInfo goods.Information
dbc.DB.First(&goodsInfo, p.GoodsID)
if err := dbc.DB.Model(&goodsInfo).Updates(map[string]interface{}{
"vendor_id": p.VendorID,
"goods_name": p.GoodsName,
"description": p.Description,
"material": p.Material,
"first_category_id": p.FirstCategoryID,
"second_category_id": p.SecondCategoryID,
//"publish_status": p.PublishStatus,
"freight_id": p.FreightID,
"weight": p.Weight.Round(2),
"is_join_team_performance": p.IsJoinTeamPerformance,
}).Error; err != nil {
back.Err(c, err.Error())
return
}
back.Suc(c, "", &goodsInfo)
}
func UpdateCoupon(c *gin.Context) {
file, err := c.FormFile("excel")
if err != nil {
back.Fail(c, err.Error())
return
}
name := filepath.Join(static_path.Dir.Excel, file.Filename)
dst := filepath.Join(static_path.Dir.Root, name)
err = c.SaveUploadedFile(file, dst)
if err != nil {
back.Err(c, err.Error())
return
}
exl, err := excelize.OpenFile(dst)
if err != nil {
back.Err(c, err.Error())
return
}
allRows, _ := exl.GetRows(excel.SheetName) // 获取所有的行
if len(allRows) < 2 {
back.Suc(c, "", nil)
return
}
tx := dbc.DB.Begin()
{
for _, r := range allRows[1:] {
if r[0] == "" || r[1] == "" {
continue
}
skuDetail := goods.Sku{}
err := tx.Where("code = ?", r[0]).First(&skuDetail).Error
if err != nil {
back.Err(c, err.Error()+"skuCode:"+r[0])
tx.Rollback()
return
} else {
purchasePrice, err := decimal.NewFromString(r[1])
discountPrice, err := decimal.NewFromString(r[2])
coupon, err := decimal.NewFromString(r[3])
originalPrice := discountPrice.Add(coupon)
commissionRate, err := decimal.NewFromString(r[5])
commission := discountPrice.Mul(commissionRate)
inventory, err := strconv.Atoi(r[7])
goodsNum := string(r[8])
if err != nil {
back.Err(c, err.Error()+"skuCode:"+r[0])
tx.Rollback()
return
}
skuDetail.PurchasePrice = purchasePrice
skuDetail.CommissionRate = commissionRate
skuDetail.DiscountPrice = discountPrice
skuDetail.Commission = commission
skuDetail.Inventory = uint(inventory)
skuDetail.Coupon = coupon
skuDetail.OriginalPrice = originalPrice
skuDetail.GoodsNum = goodsNum
if err = tx.Save(&skuDetail).Error; err != nil {
back.Err(c, err.Error())
tx.Rollback()
return
}
}
}
}
tx.Commit()
back.Suc(c, "", nil)
}
type FreightByCategoryPem struct {
CategoryId int `json:"category_id"`
FreightId uint `json:"freight_id"`
}
//根据产品类目修改运费模板
func FreightByCategory(c *gin.Context) {
var p FreightByCategoryPem
if err := tools.Params(&p, c); err != nil {
back.Fail(c, err.Error())
return
}
//判断品牌是否存在
var categoryData goods.Category
dbc.DB.First(&categoryData, "id=?", p.CategoryId)
if categoryData.ID <= 0 {
back.Fail(c, "品牌不存在")
return
}
//判断运费模板是否存在
var freightData freight.Information
dbc.DB.First(&freightData, "id=?", p.FreightId)
if freightData.ID <= 0 {
back.Fail(c, "运费模板不存在")
return
}
//正式修改运费模板,这边根据分类还没确定
var goodsData goods.Information
dbc.DB.Model(&goodsData).Where("").Updates(goods.Information{
FreightID: p.FreightId,
})
back.Suc(c, "", nil)
return
}
type FreightByBrandPem struct {
BrandId int `json:"brand_id"`
FreightId uint `json:"freight_id"`
}
//根据产品品牌修改运费模板
func FreightByBrand(c *gin.Context) {
}