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.
778 lines
26 KiB
778 lines
26 KiB
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"pure/initialize/api"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/spf13/cast"
|
|
"gorm.io/gorm"
|
|
|
|
"pure/global"
|
|
"pure/model"
|
|
"pure/model/request"
|
|
"pure/model/response"
|
|
"pure/utils"
|
|
)
|
|
|
|
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,has_sample,has_video,claim_stock,claim_days,claim_demands,video_channel_ids,description,claim_num,sample_num").
|
|
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,stock,sales").Preload("Specs", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("id,goods_id,specs,stock,sku_no,price,image,goods_no,code").Unscoped()
|
|
}).Unscoped()
|
|
}).First(&result).Error
|
|
|
|
if err != nil {
|
|
return err, result
|
|
}
|
|
|
|
if result.VideoChannelIds != "" {
|
|
channelLabels := FormatDictLabels(model.ReleaseChannelCode, strings.Split(result.VideoChannelIds, ","))
|
|
result.ReleaseChannels = strings.Join(channelLabels, "、")
|
|
}
|
|
claimExcept := GetMissionStatusExcept(result, uuid)
|
|
result.ClaimStatusExcept = claimExcept
|
|
trs := utils.InterTranslate(claimExcept, "zh", "en")
|
|
if trs != "" {
|
|
result.ClaimStatusExceptEng = trs
|
|
}
|
|
|
|
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)
|
|
//
|
|
result.GoodsUrl = global.MG_CONFIG.Tools.CustomerUrl + `/CommodityDetails?id=` + cast.ToString(result.GoodsId)
|
|
err = getSpecs(&result.Goods)
|
|
return nil, result
|
|
}
|
|
|
|
func getSpecs(goods *model.TbGoodsSpecsView) (err error) {
|
|
attributeValues := make(map[uint]*model.TbAttributeValueJson)
|
|
for i := 0; i < len(goods.Specs); i++ {
|
|
err = json.Unmarshal([]byte(goods.Specs[i].Specs), &goods.Specs[i].Attributes)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if i == 0 {
|
|
var attributes []uint
|
|
for j := 0; j < len(goods.Specs[i].Attributes); j++ {
|
|
attributes = append(attributes, goods.Specs[i].Attributes[j].AttributeId)
|
|
}
|
|
orderSql := "FIELD(id"
|
|
for _, attribute := range attributes {
|
|
orderSql += fmt.Sprintf(",'%v'", attribute)
|
|
}
|
|
orderSql += ")"
|
|
err = global.MG_DB.Model(&model.TbAttribute{}).Select("id,`name`").Where("id IN (?)", attributes).Order(orderSql).Find(&goods.Attributes).Error
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
for _, attribute := range goods.Specs[i].Attributes {
|
|
if _, ok := attributeValues[attribute.AttributeId]; ok {
|
|
if !strings.Contains(attributeValues[attribute.AttributeId].Str, attribute.Value) {
|
|
attributeValues[attribute.AttributeId].Str += attribute.Value + ","
|
|
attributeValues[attribute.AttributeId].Items = append(attributeValues[attribute.AttributeId].Items, model.TbAttributeValueItem{
|
|
Id: attribute.ValueId, Name: attribute.Value, Image: goods.Specs[i].Image})
|
|
}
|
|
} else {
|
|
attributeValues[attribute.AttributeId] = &model.TbAttributeValueJson{Items: []model.TbAttributeValueItem{{
|
|
Id: attribute.ValueId, Name: attribute.Value, Image: goods.Specs[i].Image}}, Str: attribute.Value + ","}
|
|
}
|
|
}
|
|
}
|
|
for i := 0; i < len(goods.Attributes); i++ {
|
|
if val, ok := attributeValues[goods.Attributes[i].ID]; ok {
|
|
goods.Attributes[i].Values = val.Items
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func GetMissionList(uuid string, info request.SearchMission) (err error, list any, 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.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,case when mission.status = 2 then 900000000 when mission.status = 1 then 500000000+mission.id else mission.id end as sort_value").
|
|
// 分段排序逻辑:进行中--结束时间正序,未开始--id倒序,已结束--id倒序
|
|
Preload("Goods", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("tb_goods.id,tb_goods.spu_no,title,title_eng,tb_goods.images,tb_goods.tags,retail_price,price_min,price_max").Unscoped()
|
|
}).Limit(limit).Offset(offset).Order("sort_value desc").Order("end_time asc").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, claimNo string) (err error, result model.MissionClaim) {
|
|
err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND claim_no = ?", uuid, claimNo).First(&result).Error
|
|
return
|
|
}
|
|
|
|
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,expire_at,finished,email").
|
|
Preload("Order", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number,send_time").
|
|
Preload("OrderGoods", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("order_id,price,sku_no,title,image,specs,id")
|
|
})
|
|
}).
|
|
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,claim_days").
|
|
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").
|
|
Preload("Video", func(db *gorm.DB) *gorm.DB {
|
|
return db.Where("status in (1,2)").Order("id desc").Limit(1)
|
|
}).First(&res).Error
|
|
if err != nil {
|
|
return
|
|
}
|
|
res.Video.CreateTime = res.Video.CreatedAt
|
|
|
|
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:比例抽成
|
|
res.Mission.HireMoneyExpect = utils.FormatFloatToString(res.Order.OrderGoods.Price * (res.Mission.HireRatio / 100))
|
|
}
|
|
if res.Mission.ID != 0 {
|
|
res.Mission.CollectStatus = getMissionCollectStatus(uuid, res.Mission.ID)
|
|
}
|
|
res.StatusExcept = GetMissionClaimStatusExcept(res)
|
|
|
|
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 MergeMissionClaimList(uuid string, info request.SearchMissionClaim) (err error, list []model.MissionClaimDetail, total int64) {
|
|
// 进行中与已结束分段查询,在此处合并
|
|
db := global.MG_DB.Model(&model.MissionClaim{}).Joins("inner join mission on mission.id = mission_claim.mission_id").
|
|
Where("mission_claim.create_by = ?", uuid)
|
|
if info.HireType != 0 {
|
|
db = db.Where("mission.hire_type = ?", info.HireType)
|
|
}
|
|
|
|
//是否
|
|
if info.VideoUpload == 1 {
|
|
var delIds []uint
|
|
var claimVideos []model.MissionClaimVideo
|
|
err = global.MG_DB.Model(&model.MissionClaimVideo{}).
|
|
Select("id,mission_id,status,create_by,mission_claim_id").
|
|
Where("status in (1,2) and create_by = ?", uuid).
|
|
Find(&claimVideos).Error
|
|
for _, c := range claimVideos {
|
|
if c.MissionClaimId != 0 {
|
|
delIds = append(delIds, c.MissionClaimId)
|
|
}
|
|
}
|
|
info.ExcludeIds = delIds
|
|
db.Where("mission_claim.id not in (?)", info.ExcludeIds)
|
|
}
|
|
|
|
err = db.Count(&total).Error
|
|
var (
|
|
partTotal int64
|
|
partOffset int
|
|
limit int
|
|
offset int
|
|
newPage int
|
|
endedList []model.MissionClaimDetail
|
|
)
|
|
limit = info.PageSize
|
|
offset = info.PageSize * (info.Page - 1)
|
|
// 查询进行中的数据
|
|
info.MissionStatus = 2
|
|
err, list, partTotal = GetMissionClaimList(uuid, info, offset, limit)
|
|
if len(list) < limit {
|
|
// 查询已结束的数据补齐
|
|
info.MissionStatus = 3
|
|
// 进行中总页数
|
|
newPage = info.Page - int(math.Ceil(float64(partTotal)/float64(limit)))
|
|
partOffset = int(partTotal) % limit
|
|
if len(list) > 0 {
|
|
limit = info.PageSize - len(list)
|
|
offset = 0
|
|
} else {
|
|
limit = info.PageSize
|
|
offset = info.PageSize*newPage - partOffset
|
|
}
|
|
|
|
err, endedList, partTotal = GetMissionClaimList(uuid, info, offset, limit)
|
|
list = append(list, endedList...)
|
|
}
|
|
|
|
return err, list, total
|
|
}
|
|
|
|
func GetMissionClaimList(uuid string, info request.SearchMissionClaim, offset, limit int) (err error, list []model.MissionClaimDetail, total int64) {
|
|
db := global.MG_DB.Model(&model.MissionClaim{}).Where("mission_claim.create_by = ?", uuid)
|
|
|
|
var res []model.MissionClaimDetail
|
|
|
|
db = db.Joins("inner join mission on mission.id = mission_claim.mission_id").
|
|
Select("mission_claim.id,mission_claim.mission_id,mission_claim.claim_no,mission_claim.achieve_num,mission_claim.`status`,mission_claim.created_at,mission_claim.updated_at,mission_claim.expire_at,mission_claim.finished").Preload("Order", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("order_id,mission_claim_id,`status`,courier,courier_url,courier_number").
|
|
Preload("OrderGoods", func(db *gorm.DB) *gorm.DB {
|
|
return db.Select("order_id,sku_no,title,specs,image,price").Unscoped()
|
|
})
|
|
}).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()
|
|
})
|
|
})
|
|
|
|
if info.HireType != 0 {
|
|
db = db.Where("mission.hire_type = ?", info.HireType)
|
|
}
|
|
|
|
if len(info.ExcludeIds) != 0 {
|
|
db.Where("mission_claim.id not in (?)", info.ExcludeIds)
|
|
}
|
|
|
|
if info.MissionStatus == 2 {
|
|
db = db.Where("mission.status = 2").Order("mission_claim.expire_at asc")
|
|
} else {
|
|
db = db.Where("mission.status != 2")
|
|
}
|
|
|
|
err = db.Count(&total).Error
|
|
err = db.Order("mission_claim.id DESC").Limit(limit).Offset(offset).Find(&res).Error
|
|
|
|
if err != nil {
|
|
return err, nil, 0
|
|
}
|
|
var (
|
|
ids []uint
|
|
uuids []string
|
|
resList []response.MissionClaimView
|
|
)
|
|
for i := 0; i < len(res); i++ {
|
|
var vMissionClaim response.MissionClaimView
|
|
|
|
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:比例抽成
|
|
res[i].Mission.HireMoneyExpect = utils.FormatFloatToString(res[i].Order.OrderGoods.Price * (res[i].Mission.HireRatio / 100))
|
|
}
|
|
res[i].SpreadUrl = global.MG_CONFIG.Tools.CustomerUrl + "/CommodityDetails?id=" + fmt.Sprintf("%v", res[i].Mission.Goods.ID) + "&spu_no=" + res[i].Mission.Goods.SpuNo + "&claim_no=" + res[i].ClaimNo
|
|
|
|
if res[i].Mission.ID != 0 {
|
|
ids = append(ids, res[i].Mission.ID)
|
|
}
|
|
vRes := res[i]
|
|
vMissionClaim.MissionId = vRes.MissionId
|
|
vMissionClaim = response.MissionClaimView{
|
|
ID: vRes.ID,
|
|
ClaimNo: vRes.ClaimNo,
|
|
MissionId: vRes.MissionId,
|
|
AchieveNum: vRes.AchieveNum,
|
|
Status: vRes.Status,
|
|
SpreadUrl: vRes.SpreadUrl,
|
|
HireType: vRes.Mission.HireType,
|
|
HireMoneyExpect: vRes.Mission.HireMoneyExpect,
|
|
EndTime: vRes.Mission.EndTime,
|
|
ExpireAt: vRes.ExpireAt,
|
|
CollectStatus: false,
|
|
Goods: response.MissionGoodsView{
|
|
GoodsId: vRes.Mission.GoodsId,
|
|
SkuNo: vRes.Order.OrderGoods.SkuNo,
|
|
Title: vRes.Order.OrderGoods.Title,
|
|
Images: vRes.Order.OrderGoods.Image,
|
|
Price: vRes.Order.OrderGoods.Price,
|
|
SpuNo: vRes.Mission.Goods.SpuNo,
|
|
TitleEng: vRes.Mission.Goods.TitleEng,
|
|
},
|
|
}
|
|
|
|
resList = append(resList, vMissionClaim)
|
|
}
|
|
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
|
|
//查询网红是否被禁用
|
|
var user model.User
|
|
err = global.MG_DB.Model(&model.User{}).Where("uuid = ?", uuid).First(&user).Error
|
|
if err != nil {
|
|
return errors.New("未找到用户信息"), 0
|
|
}
|
|
if user.IDForbidden {
|
|
return errors.New("账号已被禁用"), 0
|
|
}
|
|
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
|
|
}
|
|
|
|
if mission.HireType == 1 && mission.ClaimStock <= mission.ClaimNum {
|
|
return errors.New("可接人数已满额"), 0
|
|
}
|
|
|
|
if mission.HireType == 2 {
|
|
var total int64
|
|
global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ? and hire_type = 2", uuid, mission.ID).Count(&total)
|
|
if total >= 10 {
|
|
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
|
|
expireDate := time.Now().AddDate(0, 0, mission.ClaimDays)
|
|
missionClaim.ExpireAt = expireDate
|
|
missionClaim.Email = info.Email //邮箱
|
|
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
|
|
}
|
|
|
|
_, seller := GetSellerStoreInfo(mission.CreateBy)
|
|
|
|
if mission.HireType == 1 {
|
|
// 固定佣金任务锁定商家营销账户
|
|
var wallet model.Wallet
|
|
err = global.MG_DB.Model(&model.Wallet{}).Where("platform = 'seller' AND user_id = ?", seller.StoreNo).First(&wallet).Error
|
|
if err != nil {
|
|
return
|
|
}
|
|
var billFund model.BillFund
|
|
billFund.UserID = mission.CreateBy
|
|
billFund.TransactionType = 1
|
|
billFund.TransactionId = "MB" + Generate() // mission-bill
|
|
billFund.Title = ""
|
|
billFund.Price = mission.HireMoney
|
|
billFund.Balance = wallet.Fund
|
|
billFund.Platform = "seller"
|
|
billFund.RelatedId = missionClaim.ClaimNo
|
|
billFund.Status = 1
|
|
err = tx.Model(&model.BillFund{}).Create(&billFund).Error
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return
|
|
}
|
|
}
|
|
tx.Commit()
|
|
id = missionClaim.ID
|
|
|
|
//给商家发送邮件
|
|
go func(uid string, mission model.Mission, email string) {
|
|
_, user := GetUserDetail(uid)
|
|
body := fmt.Sprintf("您好,%s已被%s已接单,请及时回复网红疑问,促进网红完成任务", mission.Title, user.NickName)
|
|
global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
|
|
To: []string{email},
|
|
Subject: "网红接任务",
|
|
Body: body,
|
|
})
|
|
}(uuid, mission, seller.Email)
|
|
|
|
//给网红发送邮件
|
|
if mission.HasVideo == 1 && mission.VideoUrl != "" {
|
|
go func(mission model.Mission, email string, files string) {
|
|
subject := fmt.Sprintf("任务《%s》素材已发送", mission.Title)
|
|
body := "嗨,您接任务的素材已发送到邮箱,请查看,尽快完成任务。"
|
|
global.EMAIL_CLIENT.SendEmail(context.Background(), &api.SendRequest{
|
|
To: []string{email},
|
|
Subject: subject,
|
|
Body: body,
|
|
Files: []string{files},
|
|
})
|
|
}(mission, info.Email, mission.VideoUrl)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func SubmitClaimMissionWorks(uuid string, info request.ClaimMissionWorksList) (err error) {
|
|
var (
|
|
missionClaim model.MissionClaim
|
|
)
|
|
|
|
err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&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
|
|
works.VideoUrl = info.Works[i].VideoUrl
|
|
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", "VideoUrl").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
|
|
}
|
|
}
|
|
}
|
|
claimStatus := 3 // 推广中
|
|
err = tx.Model(&model.MissionClaim{}).Where("id = ? AND status = 2", info.MissionClaimId).UpdateColumn("status", claimStatus).Error
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
tx.Commit()
|
|
return nil
|
|
}
|
|
|
|
func SubmitClaimMissionVideo(uuid string, info request.ClaimMissionVideo) (err error) {
|
|
var (
|
|
mission model.Mission
|
|
missionClaim model.MissionClaim
|
|
claimVideo model.MissionClaimVideo
|
|
achieveNum int64
|
|
)
|
|
|
|
err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND id = ?", uuid, info.MissionClaimId).First(&missionClaim).Error
|
|
if err != nil {
|
|
err = errors.New("not found mission claim record")
|
|
return err
|
|
}
|
|
err = global.MG_DB.Model(&model.Mission{}).Where("id = ?", missionClaim.MissionId).First(&mission).Error
|
|
if err != nil {
|
|
err = errors.New("not found mission record")
|
|
return err
|
|
}
|
|
|
|
// 判断有无审核通过和待审核的
|
|
err = global.MG_DB.Model(&model.MissionClaimVideo{}).Where("mission_claim_id = ? and status in (1,2)", info.MissionClaimId).First(&model.MissionClaimVideo{}).Error
|
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return errors.New("不能重复上传")
|
|
}
|
|
if info.SourceType == 2 {
|
|
global.MG_DB.Model(&model.MissionClaimVideo{}).Where("create_by = ? and source_type = 2 and status in (1,2)", uuid).Count(&achieveNum)
|
|
}
|
|
|
|
tx := global.MG_DB.Begin()
|
|
claimVideo.MissionClaimId = info.MissionClaimId
|
|
claimVideo.VideoUrl = info.VideoUrl
|
|
claimVideo.Cover = info.Cover
|
|
claimVideo.Status = 1 // 待审核
|
|
claimVideo.SourceType = info.SourceType // 来源类型
|
|
claimVideo.MissionId = missionClaim.MissionId // 任务ID
|
|
claimVideo.CreateBy = uuid // 创建者ID
|
|
claimVideo.Width = info.Width //宽度
|
|
claimVideo.Height = info.Height //高度
|
|
err = tx.Model(&model.MissionClaimVideo{}).Create(&claimVideo).Error
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
// 完成平台任务奖励
|
|
if info.SourceType == 2 {
|
|
err = AddSysMissionReward(request.AddSysMissionReward{
|
|
Type: 1,
|
|
RelationId: strconv.Itoa(int(claimVideo.ID)),
|
|
AchieveNum: achieveNum + 1,
|
|
CreateBy: uuid,
|
|
}, tx)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
}
|
|
tx.Commit()
|
|
return nil
|
|
}
|
|
|
|
// 查询任务奖金
|
|
func GetMissionBonus(code string) model.MissionBonus {
|
|
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=?", code).Where("bill.status=2 and bill.type=1").Scan(&bonus)
|
|
return bonus
|
|
}
|
|
|
|
func GetMissionStatusExcept(mission model.MissionDetail, uuid string) (except string) {
|
|
if mission.Status != 2 {
|
|
except = "当前时间,任务不可接"
|
|
return except
|
|
}
|
|
if mission.HireType == 1 && mission.ClaimStock <= mission.ClaimNum {
|
|
except = "可接人数已满额"
|
|
return except
|
|
}
|
|
|
|
if !errors.Is(global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ?", uuid, mission.ID).First(&model.MissionClaim{}).Error, gorm.ErrRecordNotFound) { // 判断email是否注册
|
|
return "任务已接"
|
|
}
|
|
|
|
if mission.HireType == 2 {
|
|
var total int64
|
|
global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ? AND mission_id = ? and hire_type = 2", uuid, mission.ID).Count(&total)
|
|
if total >= 10 {
|
|
return "进行中任务已达上限"
|
|
}
|
|
}
|
|
|
|
if mission.GoodsStatus != 1 {
|
|
except = "商品已下架,任务不可接"
|
|
return except
|
|
}
|
|
|
|
//费用待发放
|
|
|
|
//费用已发放
|
|
|
|
return ""
|
|
}
|
|
|
|
func GetMissionBonusAndSales(missionId uint) (model.MissionBonus, int64, int64) {
|
|
var (
|
|
claimList []model.MissionClaim
|
|
codes []string
|
|
achieveNums int64
|
|
bonus model.MissionBonus
|
|
claimNum int64
|
|
)
|
|
global.MG_DB.Model(&model.MissionClaim{}).Where("mission_id = ?", missionId).Find(&claimList)
|
|
for _, vClaim := range claimList {
|
|
codes = append(codes, vClaim.ClaimNo)
|
|
achieveNums += vClaim.AchieveNum
|
|
}
|
|
claimNum = int64(len(claimList))
|
|
|
|
global.MG_DB.Model(&model.Bill{}).Joins("INNER JOIN `order` ON `order`.order_id = bill.order_id").
|
|
Select("SUM(bill.price) total,COUNT(DISTINCT bill.user_id) user_total").Where("bill.status=2 and bill.type=1 and `order`.`code` IN (?)", codes).Scan(&bonus)
|
|
return bonus, achieveNums, claimNum
|
|
}
|
|
|
|
func getMissionClaimRewardUnfinished(uuid string) (error, float64) {
|
|
var (
|
|
err error
|
|
result float64
|
|
)
|
|
err = global.MG_DB.Model(&model.MissionClaim{}).Where("create_by = ?", uuid).Select("SUM(reward_unfinished) as reward_unfinished").Scan(&result).Error
|
|
return err, result
|
|
}
|
|
|
|
func GetMissionClaimStatusExcept(res model.MissionClaimDetail) string {
|
|
var (
|
|
statusExcept string
|
|
)
|
|
switch res.Status {
|
|
//状态 1:已领取待发货 2:已发货 3:已收货推广中
|
|
case 1:
|
|
statusExcept = "等待样品发货"
|
|
case 2:
|
|
statusExcept = "等待链接上传"
|
|
if res.Mission.HireType == 1 {
|
|
if res.Video.ID == 0 {
|
|
statusExcept = "等待视频上传"
|
|
} else {
|
|
switch res.Video.Status {
|
|
case 1:
|
|
statusExcept = "等待视频审核"
|
|
case 2:
|
|
|
|
case 3:
|
|
statusExcept = "视频审核不通过"
|
|
}
|
|
}
|
|
}
|
|
case 3:
|
|
statusExcept = "链接已上传"
|
|
//todo 查看奖励发放状态
|
|
if res.Mission.HireType == 1 {
|
|
switch res.Video.RewardStatus {
|
|
case 1:
|
|
statusExcept = "费用待发放"
|
|
case 2:
|
|
statusExcept = "费用已发放"
|
|
}
|
|
}
|
|
}
|
|
|
|
return statusExcept
|
|
}
|
|
|