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.

335 lines
12 KiB

package service
import (
"errors"
"fmt"
"time"
"shop-api/global"
"shop-api/model"
"shop-api/model/request"
"shop-api/utils"
"gorm.io/gorm"
)
func GetMissionDetail(uuid string, id uint) (error, model.MissionDetail) {
var (
err error
result model.MissionDetail
)
err = global.MG_DB.Model(&model.Mission{}).
Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,status,create_by").
Where("id = ?", id).Preload("Goods", func(db *gorm.DB) *gorm.DB {
return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
}).First(&result).Error
if err != nil {
return err, result
}
if result.HireType == 1 { // 1:固定佣金
result.HireMoneyExpect = utils.FormatFloatToString(result.HireMoney)
} else { // 2:比例抽成
if result.Goods.PriceMin == result.Goods.PriceMax {
result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin * (result.HireRatio / 100))
} else {
result.HireMoneyExpect = utils.FormatFloatToString(result.Goods.PriceMin*(result.HireRatio/100)) + "-" + utils.FormatFloatToString(result.Goods.PriceMax*(result.HireRatio/100))
}
}
if result.CreateBy != "" {
_, result.Store = GetSellerStoreInfo(result.CreateBy)
}
result.CollectStatus = getMissionCollectStatus(uuid, result.ID)
return nil, result
}
func GetMissionList(uuid string, info request.SearchMission) (err error, list interface{}, total int64) {
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.MG_DB.Model(&model.Mission{}).Joins("INNER JOIN tb_goods ON tb_goods.id = mission.goods_id").
Where("mission.`status` = 2 AND mission.goods_status = 1 AND tb_goods.stock > 0")
err = db.Count(&total).Error
var res []model.MissionDetail
err = db.Select("mission.id,mission.title,mission.goods_id,mission.goods_status,mission.num,mission.hire_type,mission.hire_money,mission.hire_ratio,mission.start_time,mission.end_time,mission.`status`,mission.create_by").
Preload("Goods", func(db *gorm.DB) *gorm.DB {
return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
}).Limit(limit).Offset(offset).Order("id desc").Find(&res).Error
if err != nil {
return err, nil, 0
}
var (
ids []uint
uuids []string
)
for i := 0; i < len(res); i++ {
if res[i].HireType == 1 { // 1:固定佣金
res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].HireMoney)
} else { // 2:比例抽成
if res[i].Goods.PriceMin == res[i].Goods.PriceMax {
// res[i].HireMoneyExpect = fmt.Sprintf("%v", res[i].Goods.PriceMin*(res[i].HireRatio/100))
res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin * (res[i].HireRatio / 100))
} else {
res[i].HireMoneyExpect = utils.FormatFloatToString(res[i].Goods.PriceMin*(res[i].HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Goods.PriceMax*(res[i].HireRatio/100))
}
}
if res[i].CreateBy != "" {
uuids = append(uuids, res[i].CreateBy)
}
ids = append(ids, res[i].ID)
}
if len(ids) != 0 {
statusMap := getMissionCollectStatusMap(uuid, ids)
for i := 0; i < len(res); i++ {
if val, ok := statusMap[res[i].ID]; ok {
res[i].CollectStatus = val
}
}
}
if len(uuids) != 0 {
_, storeMap := getSellerStoreInfoMap(uuids)
for i := 0; i < len(res); i++ {
if val, ok := storeMap[res[i].CreateBy]; ok {
res[i].Store = val
}
}
}
return err, res, total
}
func GetMissionClaim(uuid string, id uint) (err error, res model.MissionClaimDetail) {
err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, id).
Select("id,mission_id,claim_no,achieve_num,`status`,created_at,updated_at").
Preload("Order", func(db *gorm.DB) *gorm.DB {
return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number")
}).
Preload("Mission", func(db *gorm.DB) *gorm.DB {
return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`,create_by").
Preload("Goods", func(db *gorm.DB) *gorm.DB {
return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
})
}).Preload("Works").First(&res).Error
if err != nil {
return
}
if res.Mission.CreateBy != "" {
_, res.Mission.Store = GetSellerStoreInfo(res.Mission.CreateBy)
}
if res.Mission.HireType == 1 { // 1:固定佣金
res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.HireMoney)
} else { // 2:比例抽成
if res.Mission.Goods.PriceMin == res.Mission.Goods.PriceMax {
res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.Goods.PriceMin * (res.Mission.HireRatio / 100))
} else {
res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Mission.Goods.PriceMin*(res.Mission.HireRatio/100)) + "-" + utils.FormatFloatToString(res.Mission.Goods.PriceMax*(res.Mission.HireRatio/100))
}
}
if res.Mission.ID != 0 {
res.Mission.CollectStatus = getMissionCollectStatus(uuid, res.Mission.ID)
}
res.SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res.Mission.Goods.ID) + "&spu_no=" + res.Mission.Goods.SpuNo + "&claim_no=" + res.ClaimNo
return
}
func GetMissionClaimList(uuid string, info request.SearchMissionClaim) (err error, list interface{}, total int64) {
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
db := global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ?", uuid)
err = db.Count(&total).Error
var res []model.MissionClaimDetail
err = db.Select("id,mission_id,claim_no,achieve_num,`status`,created_at,updated_at").Preload("Order", func(db *gorm.DB) *gorm.DB {
return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number")
}).Preload("Mission", func(db *gorm.DB) *gorm.DB {
return db.Select("id,title,goods_id,goods_status,num,hire_type,hire_money,hire_ratio,start_time,end_time,`status`").
Preload("Goods", func(db *gorm.DB) *gorm.DB {
return db.Select("id,spu_no,title,title_eng,images,tags,retail_price,price_min,price_max").Unscoped()
})
}).Order("id DESC").Limit(limit).Offset(offset).Find(&res).Error
if err != nil {
return err, nil, 0
}
var (
ids []uint
uuids []string
)
for i := 0; i < len(res); i++ {
if res[i].Mission.CreateBy != "" {
uuids = append(uuids, res[i].Mission.CreateBy)
}
if res[i].Mission.HireType == 1 { // 1:固定佣金
res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.HireMoney)
} else { // 2:比例抽成
if res[i].Mission.Goods.PriceMin == res[i].Mission.Goods.PriceMax {
res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.Goods.PriceMin * (res[i].Mission.HireRatio / 100))
} else {
res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Mission.Goods.PriceMin*(res[i].Mission.HireRatio/100)) + "-" + utils.FormatFloatToString(res[i].Mission.Goods.PriceMax*(res[i].Mission.HireRatio/100))
}
}
if res[i].Mission.ID != 0 {
ids = append(ids, res[i].Mission.ID)
}
}
if len(ids) != 0 {
statusMap := getMissionCollectStatusMap(uuid, ids)
for i := 0; i < len(res); i++ {
res[i].Mission.CollectStatus = statusMap[res[i].ID]
}
}
if len(uuids) != 0 {
_, storeMap := getSellerStoreInfoMap(uuids)
for i := 0; i < len(res); i++ {
if val, ok := storeMap[res[i].Mission.CreateBy]; ok {
res[i].Mission.Store = val
}
}
}
return err, res, total
}
func ClaimMission(uuid string, info request.ClaimMission) (err error, id uint) {
var mission model.Mission
if global.MG_DB.Model(&model.Mission{}).Where("id = ?", info.MissionId).First(&mission).Error != nil {
return errors.New("抱歉,未找到任务信息"), 0
}
if mission.Status != 2 || mission.GoodsStatus != 1 {
return errors.New("抱歉,当前任务不可领取"), 0
}
now := time.Now().UTC().Unix()
if mission.StartTime.Unix() > now || mission.EndTime.Unix() < now {
return errors.New("抱歉,不在任务领取时间内"), 0
}
var address model.Address
if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, info.MissionId).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册
return errors.New("不可重复领取"), 0
}
if global.MG_DB.Model(&model.Address{}).Where("user_id = ? AND id = ?", uuid, info.AddressId).First(&address).Error != nil {
return errors.New("抱歉,未找到地址信息"), 0
}
var (
missionClaim model.MissionClaim
missionClaimOrder model.MissionClaimOrder
missionClaimOrderGoods model.MissionClaimOrderGoods
missionClaimAddress model.MissionClaimAddress
)
tx := global.MG_DB.Begin()
missionClaim.MissionId = info.MissionId
missionClaim.ClaimNo = utils.GetInvitationLowerLen(20)
missionClaim.AchieveNum = 0
missionClaim.CreateBy = uuid
missionClaim.Status = 1
err = tx.Model(&model.MissionClaim{}).Create(&missionClaim).Error
if err != nil {
tx.Rollback()
return
}
// 任务领取人数+1
err = tx.Model(&model.Mission{}).Where("id = ?", info.MissionId).UpdateColumn("claim_num", gorm.Expr("`claim_num` + 1")).Error
if err != nil {
tx.Rollback()
return
}
// 创建任务订单
var (
goods model.TbGoods
goodsSpec model.TbGoodsSpecs
)
err = tx.Model(&model.TbGoods{}).Where("online = 'on' AND spu_no = ?", info.SpuNo).First(&goods).Error
if err != nil {
tx.Rollback()
err = errors.New("未找到商品信息")
return
}
err = tx.Model(&model.TbGoodsSpecs{}).Where("status = 1 AND goods_id = ? AND sku_no = ?", goods.ID, info.SkuNo).First(&goodsSpec).Error
if err != nil {
tx.Rollback()
err = errors.New("未找到商品规格信息")
return
}
missionClaimOrder.OrderID = Generate()
missionClaimOrder.MissionClaimId = missionClaim.ID
missionClaimOrder.SpuNo = info.SpuNo
missionClaimOrder.SkuNo = info.SkuNo
missionClaimOrder.Number = 1
missionClaimOrder.CreateBy = uuid
missionClaimOrder.Status = 2 // 待发货
err = tx.Model(&model.MissionClaimOrder{}).Create(&missionClaimOrder).Error
if err != nil {
tx.Rollback()
err = errors.New("创建任务订单失败")
return
}
missionClaimOrderGoods.OrderID = missionClaimOrder.OrderID
missionClaimOrderGoods.SkuNo = info.SkuNo
missionClaimOrderGoods.Title = goods.Title
missionClaimOrderGoods.Image = goodsSpec.Image
missionClaimOrderGoods.Specs = goodsSpec.Specs
missionClaimOrderGoods.Price = goodsSpec.Price
err = tx.Model(&model.MissionClaimOrderGoods{}).Create(&missionClaimOrderGoods).Error
if err != nil {
tx.Rollback()
err = errors.New("创建任务订单失败")
return
}
// 创建任务收获地址
missionClaimAddress.Address = address
missionClaimAddress.ID = 0
missionClaimAddress.AddressId = address.ID
missionClaimAddress.MissionClaimId = missionClaim.ID
missionClaimAddress.OrderID = missionClaimOrder.OrderID
err = tx.Model(&model.MissionClaimAddress{}).Create(&missionClaimAddress).Error
if err != nil {
tx.Rollback()
return
}
tx.Commit()
id = missionClaim.ID
return
}
func SubmitClaimMissionWorks(uuid string, info request.ClaimMissionWorksList) (err error) {
err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&model.MissionClaim{}).Error
if err != nil {
err = errors.New("not found mission claim record")
return err
}
tx := global.MG_DB.Begin()
for i := 0; i < len(info.Works); i++ {
var works model.MissionClaimWorks
works.Type = info.Works[i].Type
works.Homepage = info.Works[i].Homepage
works.Image = info.Works[i].Image
if info.Works[i].ID != 0 {
if info.Works[i].Homepage == "" {
err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Delete(&model.MissionClaimWorks{}).Error
if err != nil {
tx.Rollback()
return err
}
} else {
err = tx.Model(&model.MissionClaimWorks{}).Where("id = ?", info.Works[i].ID).Select("Type", "Homepage", "Image").Updates(&works).Error
if err != nil {
tx.Rollback()
return err
}
}
} else {
works.MissionClaimId = info.MissionClaimId
err = tx.Model(&model.MissionClaimWorks{}).Create(&works).Error
if err != nil {
tx.Rollback()
return err
}
}
}
err = tx.Model(&model.MissionClaim{}).Where("id = ? AND status = 2", info.MissionClaimId).UpdateColumn("status", 3).Error
if err != nil {
tx.Rollback()
return err
}
tx.Commit()
return nil
}
func GetMissionBonus(req *request.MissionCode) interface{} {
var bonus model.MissionBonus
global.MG_DB.Model(&model.Bill{}).Select("sum(bill.price) total").Joins("inner join `order` b on bill.order_id=b.order_id and b.code=?", req.Code).Where("bill.status=2 and bill.type=1").Scan(&bonus)
return bonus
}