Ver código fonte

任务中心

Ethan 8 meses atrás
pai
commit
54df003dae

+ 31 - 0
app/consts/product_type.go

@@ -0,0 +1,31 @@
+package consts
+
+var productTypeMap = map[int64]string{
+	1:  "3C及电器",
+	2:  "食品饮料",
+	3:  "服装配饰",
+	4:  "医疗",
+	5:  "房地产",
+	6:  "家居建材",
+	7:  "教育培训",
+	8:  "出行旅游",
+	9:  "游戏",
+	10: "互联网平台",
+	11: "汽车",
+	12: "文体娱乐",
+	13: "影视传媒",
+	14: "线下店铺",
+	15: "软件服务",
+	16: "美妆",
+	17: "母婴宠物",
+	18: "日化",
+	19: "其他",
+}
+
+func GetProductType(productType int64) string {
+	toast, contain := productTypeMap[productType]
+	if contain {
+		return toast
+	}
+	return "未知"
+}

+ 7 - 2
app/controller/common.go

@@ -19,7 +19,12 @@ func returnSuccess(c *gin.Context, code int, data interface{}) {
 	c.JSON(200, json)
 }
 
-func returnError(c *gin.Context, code int) {
-	json := &JsonErrStruct{Code: code, Msg: "error"}
+func returnError(c *gin.Context, code int, msg string) {
+	json := &JsonErrStruct{}
+	if msg == "" {
+		json = &JsonErrStruct{Code: code, Msg: "error"}
+	} else {
+		json = &JsonErrStruct{Code: code, Msg: msg}
+	}
 	c.JSON(400, json)
 }

+ 105 - 0
app/controller/task_controller.go

@@ -0,0 +1,105 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/service"
+	"youngee_b_api/app/vo"
+)
+
+type TaskController struct{}
+
+type GetAllProductParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+}
+
+type SelectionDetailParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	SelectionId  string `json:"selection_id"`
+}
+
+// 关联商品-已有商品展示
+func (t TaskController) GetAllProduct(c *gin.Context) {
+	search := &GetAllProductParam{}
+	err := c.BindJSON(&search)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	result, err := service.ProductService{}.GetTaskProducts(search.EnterpriseId)
+	if err != nil {
+		returnError(c, 40000, "error")
+		return
+	}
+	returnSuccess(c, 20000, result)
+	return
+}
+
+// 关联商品-新建商品
+func (t TaskController) CreateProduct(c *gin.Context) {
+	data := &vo.ProductCreateParam{}
+	err := c.BindJSON(data)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	productId, err := service.ProductService{}.CreateProduct(data)
+	returnSuccess(c, 20000, productId)
+}
+
+// 关联商品-完成关联创建带货任务
+func (t TaskController) CreateSelection(c *gin.Context) {
+	data := &vo.SelectionInfoCreateParam{}
+	err := c.BindJSON(data)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	selectionId, err := service.SelectionInfoService{}.CreateSelectionInfo(data)
+	if err != nil {
+		logrus.Errorf("[CreateSelection] call CreateSelection err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	returnSuccess(c, 20000, *selectionId)
+}
+
+// 更新带货任务(样品奖励、补充信息)
+func (t TaskController) UpdateSelection(c *gin.Context) {
+	data := &vo.SelectionInfoUpdateParam{}
+	err := c.BindJSON(data)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	selectionId, err := service.SelectionInfoService{}.UpdateSelectionInfo(data)
+	if err != nil {
+		logrus.Errorf("[UpdateSelection] call UpdateSelection err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	returnSuccess(c, 20000, *selectionId)
+}
+
+// 电商带货任务预览
+func (t TaskController) GetSelectionDetail(c *gin.Context) {
+	data := &SelectionDetailParam{}
+	err := c.BindJSON(data)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+	res, err := service.SelectionInfoService{}.GetSelectionDetail(data.SelectionId, data.EnterpriseId)
+	if err != nil {
+		logrus.Errorf("[GetSelectionDetail] call Show err:%+v\n", err)
+		returnError(c, 40000, "error")
+		return
+	}
+
+	returnSuccess(c, 20000, res)
+}

+ 3 - 3
app/controller/workspace_controller.go

@@ -7,16 +7,16 @@ import (
 
 type WorkspaceController struct{}
 
-type Search struct {
+type GetTakegoodsInfoParam struct {
 	EnterpriseId string `json:"enterprise_id"`
 	DateRange    string `json:"days"`
 }
 
 func (w WorkspaceController) GetTakegoodsInfo(c *gin.Context) {
-	search := &Search{}
+	search := &GetTakegoodsInfoParam{}
 	err := c.BindJSON(&search)
 	if err != nil {
-		returnError(c, 40000)
+		returnError(c, 40000, "error")
 		return
 	}
 	result := service.EnterpriseService{}.GetEnterpriseTakegoodsInfo(search.EnterpriseId, search.DateRange)

+ 34 - 0
app/dao/free_strategy_dao.go

@@ -0,0 +1,34 @@
+package dao
+
+import (
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/entity"
+)
+
+type FreeStrategyDao struct{}
+
+func (d FreeStrategyDao) DeleteFreeStrategyBySelectionId(selectionId string) error {
+	err := Db.Where("selection_id = ?", selectionId).Delete(&entity.FreeStrategy{}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d FreeStrategyDao) CreateFreeStrategy(freeStrategys []entity.FreeStrategy) error {
+	err := Db.Create(&freeStrategys).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d FreeStrategyDao) GetFreeStrategyBySelectionId(selectionId string) ([]*entity.FreeStrategy, error) {
+	var freeStrategys []*entity.FreeStrategy
+	err := Db.Model(entity.FreeStrategy{}).Where("selection_id = ?", selectionId).Find(&freeStrategys).Error
+	if err != nil {
+		logrus.Errorf("[GetFreeStrategyBySelectionId] error query, err:%+v", err)
+		return nil, err
+	}
+	return freeStrategys, nil
+}

+ 56 - 0
app/dao/product_dao.go

@@ -0,0 +1,56 @@
+package dao
+
+import (
+	"errors"
+	"github.com/sirupsen/logrus"
+	"gorm.io/gorm"
+	"youngee_b_api/app/entity"
+)
+
+type ProductDAO struct{}
+
+func (d ProductDAO) GetProductsByEnterpriseID(enterpriseId string) ([]entity.Product, error) {
+	var products []entity.Product
+	err := Db.Where("enterprise_id = ?", enterpriseId).Order("created_at desc").Find(&products).Error
+	if err != nil {
+		return nil, err
+	}
+	return products, nil
+}
+
+func (d ProductDAO) CreateProduct(product entity.Product) (int64, error) {
+	err := Db.Create(&product).Error
+	if err != nil {
+		return 0, err
+	}
+	return product.ProductID, nil
+}
+
+func (d ProductDAO) GetProductByID(productId int64) (*entity.Product, error) {
+	var product entity.Product
+	err := Db.Where("product_id = ?", productId).First(&product).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return nil, nil
+		} else {
+			return nil, err
+		}
+	}
+	return &product, nil
+}
+
+func (d ProductDAO) GetProductBySelectionId(selectionId string) (*entity.Product, error) {
+	productId := 0
+	err := Db.Model(entity.SelectionInfo{}).Select("product_id").Where("selection_id = ?", selectionId).Find(&productId).Error
+	if err != nil {
+		logrus.Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	productInfo := entity.Product{}
+	err = Db.Model(entity.Product{}).Where("product_id = ?", productId).Find(&productInfo).Error
+	if err != nil {
+		logrus.Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	return &productInfo, nil
+}

+ 50 - 0
app/dao/product_photo_dao.go

@@ -0,0 +1,50 @@
+package dao
+
+import (
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/entity"
+)
+
+type ProductPhotoDAO struct{}
+
+func (d ProductPhotoDAO) GetMainPhotoByProductID(productId int64) (string, error) {
+	var productPhoto entity.ProductPhoto
+	err := Db.Where("product_id = ? AND symbol = ?", productId, 1).First(&productPhoto).Error
+	if err != nil {
+		return "", err
+	}
+	return productPhoto.PhotoUrl, nil
+}
+
+func (d ProductPhotoDAO) CreateProductPhoto(productPhotos []entity.ProductPhoto) error {
+	err := Db.Create(&productPhotos).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d ProductPhotoDAO) GetProductPhotoByProductID(productID int64) ([]entity.ProductPhoto, error) {
+	var productPhotos []entity.ProductPhoto
+	err := Db.Where("product_id = ?", productID).Find(&productPhotos).Error
+	if err != nil {
+		return nil, err
+	}
+	return productPhotos, nil
+}
+
+func (d ProductPhotoDAO) GetProductPhotosBySelectionId(selectionId string) ([]*entity.ProductPhoto, error) {
+	productId := 0
+	err := Db.Model(entity.SelectionInfo{}).Select("product_id").Where("selection_id = ?", selectionId).Find(&productId).Error
+	if err != nil {
+		logrus.Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	var productPhotos []*entity.ProductPhoto
+	err = Db.Model(entity.ProductPhoto{}).Where("product_id = ?", productId).Find(&productPhotos).Error
+	if err != nil {
+		logrus.Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	return productPhotos, nil
+}

+ 34 - 0
app/dao/reward_strategy_dao.go

@@ -0,0 +1,34 @@
+package dao
+
+import (
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/entity"
+)
+
+type RewardStrategyDao struct{}
+
+func (d RewardStrategyDao) DeleteRewardStrategyBySelectionId(selectionId string) error {
+	err := Db.Where("selection_id = ?", selectionId).Delete(&entity.RewardStrategy{}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d RewardStrategyDao) CreateRewardStrategy(rewardStrategys []entity.RewardStrategy) error {
+	err := Db.Create(&rewardStrategys).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d RewardStrategyDao) GetRewardStrategyBySelectionId(selectionId string) ([]*entity.RewardStrategy, error) {
+	var rewardStrategys []*entity.RewardStrategy
+	err := Db.Model(entity.RewardStrategy{}).Where("selection_id = ?", selectionId).Find(&rewardStrategys).Error
+	if err != nil {
+		logrus.Errorf("[GetRewardStrategyBySelectionId] error query, err:%+v", err)
+		return nil, err
+	}
+	return rewardStrategys, nil
+}

+ 34 - 0
app/dao/sec_brief_dao.go

@@ -0,0 +1,34 @@
+package dao
+
+import (
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/entity"
+)
+
+type SecBriefDao struct{}
+
+func (p SecBriefDao) DeleteSecBriefBySelectionId(selectionId string) error {
+	err := Db.Where("selection_id = ?", selectionId).Delete(entity.SecBrief{}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p SecBriefDao) CreateSecBrief(briefInfo entity.SecBrief) error {
+	err := Db.Create(&briefInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (p SecBriefDao) GetSelectionBriefInfo(selectionId string) ([]*entity.SecBrief, error) {
+	var selectionBriefInfos []*entity.SecBrief
+	err := Db.Model(entity.SecBrief{}).Where("selection_id = ?", selectionId).Find(&selectionBriefInfos).Error
+	if err != nil {
+		logrus.Errorf("[GetSelectionBriefInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	return selectionBriefInfos, nil
+}

+ 34 - 0
app/dao/sec_example_dao.go

@@ -0,0 +1,34 @@
+package dao
+
+import (
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/entity"
+)
+
+type SecExampleDao struct{}
+
+func (d SecExampleDao) DeleteSecExampleBySelectionId(selectionId string) error {
+	err := Db.Where("selection_id = ?", selectionId).Delete(entity.SecExample{}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d SecExampleDao) CreateSecExample(secExample entity.SecExample) error {
+	err := Db.Create(&secExample).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d SecExampleDao) GetSelectionExampleInfo(selectionId string) ([]*entity.SecExample, error) {
+	var selectionExampleInfos []*entity.SecExample
+	err := Db.Model(entity.SecExample{}).Where("selection_id = ?", selectionId).Find(&selectionExampleInfos).Error
+	if err != nil {
+		logrus.Errorf("[GetSelectionExampleInfo] error query, err:%+v", err)
+		return nil, err
+	}
+	return selectionExampleInfos, nil
+}

+ 36 - 11
app/dao/selection_info_dao.go

@@ -1,29 +1,38 @@
 package dao
 
 import (
+	"errors"
+	"gorm.io/gorm"
 	"time"
 	"youngee_b_api/app/entity"
 )
 
 type SelectionInfoDAO struct{}
 
-func (SelectionInfoDAO) GetSelectionInfoById(id string) (entity.SelectionInfo, error) {
+func (d SelectionInfoDAO) GetSelectionInfoById(selectionId string) (*entity.SelectionInfo, error) {
 	var selectionInfo entity.SelectionInfo
-	err := Db.Where("selection_id = ?", id).First(&selectionInfo).Error
-	return selectionInfo, err
+	err := Db.Where("selection_id = ?", selectionId).First(&selectionInfo).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return nil, nil
+		} else {
+			return nil, err
+		}
+	}
+	return &selectionInfo, err
 }
 
-func (SelectionInfoDAO) UpdateSelectionInfoById(id int, enterpriseId string) {
-	Db.Model(&entity.SelectionInfo{}).Where("id = ?", id).Update("enterprise_id", enterpriseId)
-}
+//func (d SelectionInfoDAO) UpdateSelectionInfoById(id int, enterpriseId string) {
+//	Db.Model(&entity.SelectionInfo{}).Where("id = ?", id).Update("enterprise_id", enterpriseId)
+//}
 
-func (SelectionInfoDAO) DeleteSelectionInfoById(id int) error {
-	err := Db.Delete(&entity.SelectionInfo{}, id).Error
-	return err
-}
+//func (d SelectionInfoDAO) DeleteSelectionInfoById(id int) error {
+//	err := Db.Delete(&entity.SelectionInfo{}, id).Error
+//	return err
+//}
 
 // 根据enterpriseId查询指定某天的所有带货数据
-func (SelectionInfoDAO) GetSelectionInfoListOfDay(enterpriseId string, date time.Time) ([]entity.SelectionInfo, error) {
+func (d SelectionInfoDAO) GetSelectionInfoListOfDay(enterpriseId string, date time.Time) ([]entity.SelectionInfo, error) {
 	var selectionInfos []entity.SelectionInfo
 	// 构建查询
 	query := Db.Model(&entity.SelectionInfo{})
@@ -35,3 +44,19 @@ func (SelectionInfoDAO) GetSelectionInfoListOfDay(enterpriseId string, date time
 	err := query.Find(&selectionInfos).Error
 	return selectionInfos, err
 }
+
+func (d SelectionInfoDAO) CreateSelectionInfo(selectionInfo entity.SelectionInfo) error {
+	err := Db.Omit("task_ddl", "submit_at", "pass_at", "auto_fail_at").Create(&selectionInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d SelectionInfoDAO) UpdateSelectionInfo(selectionInfo entity.SelectionInfo) error {
+	err := Db.Model(&entity.SelectionInfo{}).Where("selection_id = ?", selectionInfo.SelectionID).Updates(selectionInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 19 - 0
app/entity/free_strategy.go

@@ -0,0 +1,19 @@
+package entity
+
+type FreeStrategy struct {
+	FreeStrategyId    int64  `gorm:"column:free_strategy_id;primary_key;AUTO_INCREMENT"` // 免费领样策略id
+	StrategyId        int64  `gorm:"column:strategy_id"`                                 // 策略编号
+	SelectionId       string `gorm:"column:selection_id"`                                // 带货任务id
+	FansNum           int64  `gorm:"column:fans_num"`                                    // 粉丝数量
+	SaleNum           int64  `gorm:"column:sale_num"`                                    // 近30天橱窗销量
+	StrategyStatus    int64  `gorm:"column:strategy_status"`                             // 招募策略状态
+	EnrollNum         int    `gorm:"column:enroll_num"`                                  // 报名数量
+	ChooseNum         int    `gorm:"column:choose_num"`                                  // 已选数量
+	BeforeDeliveryNum int    `gorm:"column:before_delivery_num"`                         // 待发货数量
+	DeliveryNum       int    `gorm:"column:delivery_num"`                                // 已发货数量
+	AfterDeliveryNum  int    `gorm:"column:after_delivery_num"`                          // 已收货数量
+}
+
+func (m *FreeStrategy) TableName() string {
+	return "free_strategy"
+}

+ 27 - 0
app/entity/product.go

@@ -0,0 +1,27 @@
+package entity
+
+import "time"
+
+type Product struct {
+	ProductID           int64     `gorm:"primaryKey;autoIncrement" json:"product_id"` // 商品id
+	ProductName         string    `gorm:"column:product_name"`                        // 商品名称
+	ProductType         int64     `gorm:"column:product_type"`                        // 商品类型
+	ProductCategory     int64     `gorm:"column:product_category"`                    // 商品类目1--20
+	ShopAddress         string    `gorm:"column:shop_address"`                        // 店铺地址,商品类型为线下品牌时需填写
+	ProductPrice        float64   `gorm:"column:product_price"`                       // 商品价值
+	ProductDetail       string    `gorm:"column:product_detail"`                      // 商品详情
+	ProductUrl          string    `gorm:"column:product_url"`                         // 商品链接,可为电商网址、公司官网、大众点评的店铺地址等可以说明商品信息或者品牌信息的线上地址;
+	EnterpriseID        string    `gorm:"column:enterprise_id"`                       // 所属企业id
+	CreatedAt           time.Time `gorm:"column:created_at"`                          // 创建时间
+	UpdatedAt           time.Time `gorm:"column:updated_at"`                          // 更新时间
+	BrandName           string    `gorm:"column:brand_name"`                          // 品牌名称
+	PublicCommission    float64   `gorm:"column:public_commission"`                   // 公开佣金
+	ExclusiveCommission float64   `gorm:"column:exclusive_commission"`                // 专属佣金
+	CommissionPrice     float64   `gorm:"column:commission_price"`                    // 佣金金额
+	KuaishouProductId   int64     `gorm:"column:kuaishou_product_id"`                 // 快手商品ID
+	SalesCount          string    `gorm:"column:sales_count"`                         // 商品30天销量
+}
+
+func (m *Product) TableName() string {
+	return "younggee_product"
+}

+ 16 - 0
app/entity/product_photo.go

@@ -0,0 +1,16 @@
+package entity
+
+import "time"
+
+type ProductPhoto struct {
+	ProductPhotoID int64     `gorm:"column:product_photo_id;primary_key;AUTO_INCREMENT"` // 商品图片id
+	PhotoUrl       string    `gorm:"column:photo_url"`                                   // 图片或视频url
+	PhotoUid       string    `gorm:"column:photo_uid"`
+	Symbol         int64     `gorm:"column:symbol"`     // 图片为主图或详情图标志位,1为主图,2为详情图,3为视频
+	ProductID      int64     `gorm:"column:product_id"` // 所属商品id
+	CreatedAt      time.Time `gorm:"column:created_at"` // 创建时间
+}
+
+func (m *ProductPhoto) TableName() string {
+	return "younggee_product_photo"
+}

+ 14 - 0
app/entity/reward_strategy.go

@@ -0,0 +1,14 @@
+package entity
+
+type RewardStrategy struct {
+	RewardStrategyId int64   `gorm:"column:reward_strategy_id;primary_key;AUTO_INCREMENT"` // 悬赏策略id
+	SelectionId      string  `gorm:"column:selection_id"`                                  // 带货任务id
+	Reward           float64 `gorm:"column:reward"`                                        // 悬赏池总金额
+	SaleActual       int64   `gorm:"column:sale_actual"`                                   // 实际带货销量
+	PerReward        float64 `gorm:"column:per_reward"`                                    // 每人可获得悬赏金
+	StrategyStatus   int64   `gorm:"column:strategy_status"`                               // 悬赏策略状态
+}
+
+func (m *RewardStrategy) TableName() string {
+	return "reward_strategy"
+}

+ 16 - 0
app/entity/sec_brief.go

@@ -0,0 +1,16 @@
+package entity
+
+import "time"
+
+type SecBrief struct {
+	SectionBriefID int       `gorm:"column:section_brief_id;primary_key;AUTO_INCREMENT"` // brief的Id
+	FileUrl        string    `gorm:"column:file_url"`                                    // 文件url
+	FileUid        string    `gorm:"column:file_uid"`                                    // 文件uid
+	SelectionID    string    `gorm:"column:selection_id"`                                // 所属选品id
+	CreatedAt      time.Time `gorm:"column:created_at"`                                  // 创建时间
+	FileName       string    `gorm:"column:file_name"`                                   // 文件名称
+}
+
+func (m *SecBrief) TableName() string {
+	return "younggee_sec_brief"
+}

+ 16 - 0
app/entity/sec_example.go

@@ -0,0 +1,16 @@
+package entity
+
+import "time"
+
+type SecExample struct {
+	ExampleID   int       `gorm:"column:example_id;primary_key;AUTO_INCREMENT"` // 选品示例图id
+	FileUrl     string    `gorm:"column:file_url"`                              // 文件url
+	FileUid     string    `gorm:"column:file_uid"`                              // 文件uid
+	SelectionID string    `gorm:"column:selection_id"`                          // 所属项目id
+	CreatedAt   time.Time `gorm:"column:created_at"`                            // 创建时间
+	FileName    string    `gorm:"column:file_name"`                             // 文件名称
+}
+
+func (m *SecExample) TableName() string {
+	return "younggee_sec_example"
+}

+ 4 - 3
app/entity/selection_info.go

@@ -34,11 +34,12 @@ type SelectionInfo struct {
 	SubmitAt         time.Time  `gorm:"column:submit_at"`                // 提交审核时间
 	PassAt           time.Time  `gorm:"column:pass_at"`                  // 审核通过时间
 	FailReason       int64      `gorm:"column:fail_reason"`              // 失效原因,1、2分别表示逾期未支付、项目存在风险
-	PayAt            time.Time  `gorm:"column:pay_at"`                   // 支付时间
-	FinishAt         time.Time  `gorm:"column:finish_at"`                // 结案时间
+	PayAt            *time.Time `gorm:"column:pay_at"`                   // 支付时间
+	FinishAt         *time.Time `gorm:"column:finish_at"`                // 结案时间
 	IsRead           int64      `gorm:"column:is_read"`                  // 是否已读
 	AutoTaskID       int64      `gorm:"column:auto_task_id"`             // 定时任务id
-	AutoFailAt       *time.Time `gorm:"column:auto_fail_at"`             // 失效自动处理时间
+	AutoFailAt       time.Time  `gorm:"column:auto_fail_at"`             // 失效自动处理时间
+	Status           int64      `gorm:"column:status"`                   // 选品是否删除 2代表删除
 }
 
 func (m *SelectionInfo) TableName() string {

+ 83 - 0
app/service/product_service.go

@@ -0,0 +1,83 @@
+package service
+
+import (
+	"errors"
+	"strconv"
+	"time"
+	"youngee_b_api/app/consts"
+	"youngee_b_api/app/dao"
+	"youngee_b_api/app/entity"
+	"youngee_b_api/app/vo"
+)
+
+type ProductService struct{}
+
+func (p ProductService) GetTaskProducts(enterpriseId string) ([]vo.ReTaskProduct, error) {
+	if enterpriseId == "" {
+		return nil, errors.New("enterpriseId is empty")
+	}
+	products, err := (&dao.ProductDAO{}).GetProductsByEnterpriseID(enterpriseId)
+	if err != nil {
+		// 数据库查询error
+		return nil, err
+	}
+	var reProducts []vo.ReTaskProduct
+	for _, product := range products {
+		photoUrl, e := dao.ProductPhotoDAO{}.GetMainPhotoByProductID(product.ProductID)
+		if e != nil {
+			photoUrl = ""
+		}
+		reProduct := vo.ReTaskProduct{
+			ProductID:     product.ProductID,
+			ProductName:   product.ProductName,
+			ProductType:   consts.GetProductType(product.ProductType),
+			ProductPrice:  product.ProductPrice,
+			ProductDetail: product.ProductDetail,
+			CreatedAt:     product.CreatedAt,
+			BrandName:     product.BrandName,
+			PhotoUrl:      photoUrl,
+		}
+		reProducts = append(reProducts, reProduct)
+	}
+	return reProducts, nil
+}
+
+func (p ProductService) CreateProduct(productCreateParam *vo.ProductCreateParam) (int64, error) {
+	product := entity.Product{
+		ProductName:         productCreateParam.ProductName,
+		ProductType:         productCreateParam.ProductType,
+		ShopAddress:         productCreateParam.ShopAddress,
+		ProductPrice:        productCreateParam.ProductPrice,
+		ProductDetail:       productCreateParam.ProductDetail,
+		ProductUrl:          productCreateParam.ProductUrl,
+		EnterpriseID:        productCreateParam.EnterpriseId,
+		BrandName:           productCreateParam.BrandName,
+		PublicCommission:    productCreateParam.PublicCommission,
+		ExclusiveCommission: productCreateParam.ExclusiveCommission,
+		CommissionPrice:     productCreateParam.CommissionPrice,
+		SalesCount:          strconv.Itoa(int(productCreateParam.MerchantSoldCountThirtyDays)),
+		KuaishouProductId:   productCreateParam.KuaishouProductId,
+	}
+	productID, err := dao.ProductDAO{}.CreateProduct(product)
+	if err != nil {
+		return 0, err
+	}
+	if productCreateParam.ProductPhotos != nil {
+		productPhotos := []entity.ProductPhoto{}
+		for _, photo := range productCreateParam.ProductPhotos {
+			productPhoto := entity.ProductPhoto{
+				PhotoUrl:  photo.PhotoUrl,
+				PhotoUid:  photo.PhotoUid,
+				Symbol:    photo.Symbol,
+				ProductID: productID,
+				CreatedAt: time.Time{},
+			}
+			productPhotos = append(productPhotos, productPhoto)
+		}
+		err = dao.ProductPhotoDAO{}.CreateProductPhoto(productPhotos)
+		if err != nil {
+			return 0, err
+		}
+	}
+	return productID, nil
+}

+ 309 - 18
app/service/selection_info_service.go

@@ -1,46 +1,337 @@
 package service
 
 import (
-	"github.com/gin-gonic/gin"
+	"encoding/json"
+	"errors"
+	"github.com/caixw/lib.go/conv"
 	"github.com/sirupsen/logrus"
-	"youngee_b_api/db"
-	"youngee_b_api/model/http_model"
+	"reflect"
+	"time"
+	"youngee_b_api/app/dao"
+	"youngee_b_api/app/entity"
+	"youngee_b_api/app/util"
+	"youngee_b_api/app/vo"
 )
 
 type SelectionInfoService struct{}
 
-func (s *SelectionInfoService) GetSelectionInfo(ctx *gin.Context, selectionId string) (*http_model.SelectionDetail, error) {
-	selectionDetail := http_model.SelectionDetail{}
-	selectionInfo, err := db.GetSelectionById(ctx, selectionId)
+//func (s *SelectionInfoService) GetSelectionInfo(ctx *gin.Context, selectionId string) (*http_model.SelectionDetail, error) {
+//	selectionDetail := http_model.SelectionDetail{}
+//	selectionInfo, err := db.GetSelectionById(ctx, selectionId)
+//
+//	if err != nil {
+//		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionInfo error,err:%+v", err)
+//		return nil, err
+//	}
+//	selectionBriefInfo, err := db.GetSelectionBriefInfo(ctx, selectionId)
+//	if err != nil {
+//		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionBriefInfo error,err:%+v", err)
+//		return nil, err
+//	}
+//	selectionExampleInfo, err := db.GetSelectionExampleInfo(ctx, selectionId)
+//	if err != nil {
+//		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionExampleInfo error,err:%+v", err)
+//		return nil, err
+//	}
+//	productInfo, err := db.GetProductInfoBySelectionId(ctx, selectionId)
+//	if err != nil {
+//		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetProductInfo error,err:%+v", err)
+//		return nil, err
+//	}
+//	productPhotoInfo, err := db.GetProductPhotoInfoBySelectionId(ctx, selectionId)
+//	if err != nil {
+//		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetProductPhotoInfo error,err:%+v", err)
+//		return nil, err
+//	}
+//	selectionDetail.SelectionBrief = selectionBriefInfo
+//	selectionDetail.SelectionInfo = selectionInfo
+//	selectionDetail.SelectionExample = selectionExampleInfo
+//	selectionDetail.ProductInfo = productInfo
+//	selectionDetail.ProductPhotoInfo = productPhotoInfo
+//	return &selectionDetail, nil
+//}
 
+// 创建带货任务
+func (s SelectionInfoService) CreateSelectionInfo(selection *vo.SelectionInfoCreateParam) (*string, error) {
+	// a) 生成选品id
+	selectionId := util.GetSelectionID()
+	// b) 查找关联商品信息
+	product, err := dao.ProductDAO{}.GetProductByID(conv.MustInt64(selection.ProductId, 0))
 	if err != nil {
-		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionInfo error,err:%+v", err)
 		return nil, err
 	}
-	selectionBriefInfo, err := db.GetSelectionBriefInfo(ctx, selectionId)
+	if product == nil {
+		return nil, errors.New("未找到关联商品")
+	}
+	productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(selection.ProductId)
+	productInfoToJson, _ := json.Marshal(product)
+	productPhotosToJson, _ := json.Marshal(productPhotos)
+	// c) 选品名称
+	selectionName := product.BrandName + "-" + product.ProductName
+	// d)创建选品
+	t := time.Now()
+	newSelection := entity.SelectionInfo{
+		SelectionStatus:  1,
+		SelectionID:      selectionId,
+		SelectionName:    selectionName,
+		ProductID:        selection.ProductId,
+		EnterpriseID:     selection.EnterpriseId,
+		Platform:         selection.Platform,
+		ProductSnap:      string(productInfoToJson),
+		ProductPhotoSnap: string(productPhotosToJson),
+		CreatedAt:        t,
+		UpdatedAt:        t,
+		CommissionRate:   0,
+		EstimatedCost:    0,
+		TaskReward:       0,
+		SettlementAmount: 0,
+	}
+	err = dao.SelectionInfoDAO{}.CreateSelectionInfo(newSelection)
 	if err != nil {
-		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionBriefInfo error,err:%+v", err)
 		return nil, err
 	}
-	selectionExampleInfo, err := db.GetSelectionExampleInfo(ctx, selectionId)
+
+	return &selectionId, nil
+}
+
+// 更新带货任务(样品奖励、补充信息)
+func (s SelectionInfoService) UpdateSelectionInfo(selectionUpdateParam *vo.SelectionInfoUpdateParam) (*string, error) {
+	// 1. 检查该企业id和商品id有无选品
+	selectionID := selectionUpdateParam.SelectionID
+	selectionInfo, err := dao.SelectionInfoDAO{}.GetSelectionInfoById(selectionID)
 	if err != nil {
-		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionExampleInfo error,err:%+v", err)
 		return nil, err
 	}
-	productInfo, err := db.GetProductInfoBySelectionId(ctx, selectionId)
+	if selectionInfo == nil {
+		return nil, errors.New("选品不存在")
+	}
+
+	// 2. 数据准备
+	// a) 查找关联商品信息
+	product, err := dao.ProductDAO{}.GetProductByID(conv.MustInt64(selectionUpdateParam.ProductId, 0))
 	if err != nil {
-		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetProductInfo error,err:%+v", err)
 		return nil, err
 	}
-	productPhotoInfo, err := db.GetProductPhotoInfoBySelectionId(ctx, selectionId)
+	productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(conv.MustInt64(selectionUpdateParam.ProductId, 0))
+	productInfoToJson, _ := json.Marshal(product)
+	productPhotosToJson, _ := json.Marshal(productPhotos)
+	// b) 选品名称
+	selectionName := product.BrandName + "-" + product.ProductName
+	// d) 任务截止时间
+	taskDdl := time.Time{} //赋零值
+	taskDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", selectionUpdateParam.TaskDdl, time.Local)
+	// f) 更新选品状态
+	if selectionUpdateParam.SelectionStatus != 2 && selectionUpdateParam.SelectionStatus != 7 {
+		selectionUpdateParam.SelectionStatus = 1
+	}
+	t := time.Now()
+	updateSelection := entity.SelectionInfo{
+		SelectionID:      selectionUpdateParam.SelectionID,
+		SelectionStatus:  selectionUpdateParam.SelectionStatus,
+		SelectionName:    selectionName,
+		EnterpriseID:     selectionUpdateParam.EnterpriseId,
+		ProductID:        selectionUpdateParam.ProductId,
+		ContentType:      selectionUpdateParam.ContentType,
+		TaskMode:         selectionUpdateParam.TaskMode,
+		Platform:         selectionUpdateParam.Platform,
+		SampleMode:       selectionUpdateParam.SampleMode,
+		ProductUrl:       selectionUpdateParam.ProductUrl,
+		SampleNum:        selectionUpdateParam.SampleNum,
+		RemainNum:        selectionUpdateParam.SampleNum,
+		CommissionRate:   selectionUpdateParam.CommissionRate,
+		TaskReward:       selectionUpdateParam.TaskReward,
+		SettlementAmount: selectionUpdateParam.SettlementAmount,
+		EstimatedCost:    selectionInfo.EstimatedCost,
+		SampleCondition:  selectionUpdateParam.SampleCondition,
+		RewardCondition:  selectionUpdateParam.RewardCondition,
+		TaskDdl:          taskDdl,
+		Detail:           selectionUpdateParam.Detail,
+		ProductSnap:      string(productInfoToJson),
+		ProductPhotoSnap: string(productPhotosToJson),
+		CreatedAt:        selectionInfo.CreatedAt,
+		UpdatedAt:        t,
+	}
+	if selectionUpdateParam.SelectionStatus == 2 {
+		updateSelection.SubmitAt = t
+	}
+	if selectionUpdateParam.Status == 1 {
+		updateSelection.Status = 1
+	}
+	// 合并传入参数和数据表中原记录,若传入参数字段值为空,则将字段赋值为原记录中值
+	result := util.MergeStructValue(&updateSelection, selectionInfo)
+	// 利用反射机制将interface类型转换为结构体类型
+	v := reflect.ValueOf(&result).Elem()
+	if v.Kind() == reflect.Struct {
+		updateSelection = v.Interface().(entity.SelectionInfo)
+		//fmt.Println(p)
+	}
+	// c) 计算预估成本(如果有)
+	/*
+		var estimatedCost float64
+		if conv.MustInt(updateSelection.TaskMode, 0) == 1 {
+			estimatedCost = conv.MustFloat64(updateSelection.TaskReward, 0) * conv.MustFloat64(updateSelection.SampleNum, 0)
+		}
+		estimatedCostToString, _ := conv.String(estimatedCost)
+		updateSelection.EstimatedCost = estimatedCostToString
+	*/
+	// 3. 更新选品
+	err = dao.SelectionInfoDAO{}.UpdateSelectionInfo(updateSelection)
 	if err != nil {
-		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetProductPhotoInfo error,err:%+v", err)
 		return nil, err
 	}
-	selectionDetail.SelectionBrief = selectionBriefInfo
+
+	// 4. 更新选品brief和示例(带货任务补充信息)
+	if selectionUpdateParam.SecBrief != nil {
+		// 删除已有brief
+		err = dao.SecBriefDao{}.DeleteSecBriefBySelectionId(selectionInfo.SelectionID)
+		if err != nil {
+			return nil, err
+		}
+		// 插入新的brief
+		for _, v := range selectionUpdateParam.SecBrief {
+			brief := entity.SecBrief{
+				SelectionID: selectionInfo.SelectionID,
+				FileUid:     v.PhotoUid,
+				FileName:    v.Name,
+				FileUrl:     v.PhotoUrl,
+				CreatedAt:   time.Now(),
+			}
+			err = dao.SecBriefDao{}.CreateSecBrief(brief)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	if selectionUpdateParam.SecExample != nil {
+		// 删除已有示例
+		err = dao.SecExampleDao{}.DeleteSecExampleBySelectionId(selectionInfo.SelectionID)
+		if err != nil {
+			return nil, err
+		}
+		// 插入新的示例
+		for _, v := range selectionUpdateParam.SecExample {
+			secExample := entity.SecExample{
+				SelectionID: selectionInfo.SelectionID,
+				FileUid:     v.PhotoUid,
+				FileName:    v.Name,
+				FileUrl:     v.PhotoUrl,
+				CreatedAt:   time.Now(),
+			}
+			err = dao.SecExampleDao{}.CreateSecExample(secExample)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	println("更新带货任务的免费领样策略")
+	// 更新带货任务的免费领样策略
+	if selectionUpdateParam.FreeStrategys != nil {
+		// 1. 删除已有的免费领样策略
+		err = dao.FreeStrategyDao{}.DeleteFreeStrategyBySelectionId(selectionUpdateParam.SelectionID)
+		if err != nil {
+			return nil, err
+		}
+		// 2. 接收并创建新的免费领样策略
+		if selectionUpdateParam.SampleMode == 1 {
+			var frees []entity.FreeStrategy
+			for _, v := range selectionUpdateParam.FreeStrategys {
+				free := entity.FreeStrategy{
+					SelectionId:    selectionInfo.SelectionID,
+					StrategyId:     v.StrategyId,
+					FansNum:        v.FansNum,
+					SaleNum:        v.SaleNum,
+					StrategyStatus: 1,
+					EnrollNum:      0,
+					ChooseNum:      0,
+				}
+				frees = append(frees, free)
+			}
+			err = dao.FreeStrategyDao{}.CreateFreeStrategy(frees)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	println("更新带货任务的悬赏策略")
+	// 更新带货任务的悬赏策略
+	if selectionUpdateParam.RewardStrategys != nil {
+		// 1. 删除已有的悬赏策略
+		err = dao.RewardStrategyDao{}.DeleteRewardStrategyBySelectionId(selectionUpdateParam.SelectionID)
+		if err != nil {
+			return nil, err
+		}
+		if selectionUpdateParam.TaskMode == 1 {
+			var rewards []entity.RewardStrategy
+			for _, v := range selectionUpdateParam.RewardStrategys {
+				reward := entity.RewardStrategy{
+					SelectionId:    selectionInfo.SelectionID,
+					Reward:         v.Reward,
+					SaleActual:     v.SaleActual,
+					PerReward:      v.PerReward,
+					StrategyStatus: 1,
+				}
+				rewards = append(rewards, reward)
+			}
+			err = dao.RewardStrategyDao{}.CreateRewardStrategy(rewards)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	return &updateSelection.SelectionID, nil
+}
+
+// 电商带货任务预览
+func (s SelectionInfoService) GetSelectionDetail(selectionId string, enterpriseId string) (*vo.ReSelectionDetail, error) {
+	selectionDetail := vo.ReSelectionDetail{}
+	selectionInfo, err := dao.SelectionInfoDAO{}.GetSelectionInfoById(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetSelectionInfo error,err:%+v", err)
+		return nil, err
+	}
+	selectionBriefInfos, err := dao.SecBriefDao{}.GetSelectionBriefInfo(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetSelectionBriefInfo error,err:%+v", err)
+		return nil, err
+	}
+	selectionExamples, err := dao.SecExampleDao{}.GetSelectionExampleInfo(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetSelectionExampleInfo error,err:%+v", err)
+		return nil, err
+	}
+	productInfo, err := dao.ProductDAO{}.GetProductBySelectionId(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetProductInfo error,err:%+v", err)
+		return nil, err
+	}
+	productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotosBySelectionId(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetProductPhotoInfo error,err:%+v", err)
+		return nil, err
+	}
+	// 查找免费领样策略
+	freeStrategys, err := dao.FreeStrategyDao{}.GetFreeStrategyBySelectionId(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetFreeStrategy error,err:%+v", err)
+		return nil, err
+	}
+	// 查找悬赏策略
+	rewardStrategys, err := dao.RewardStrategyDao{}.GetRewardStrategyBySelectionId(selectionId)
+	if err != nil {
+		logrus.Errorf("[selectionDB service] call GetRewardStrategy error,err:%+v", err)
+		return nil, err
+	}
+
+	selectionDetail.SelectionBriefs = selectionBriefInfos
 	selectionDetail.SelectionInfo = selectionInfo
-	selectionDetail.SelectionExample = selectionExampleInfo
+	selectionDetail.SelectionExamples = selectionExamples
 	selectionDetail.ProductInfo = productInfo
-	selectionDetail.ProductPhotoInfo = productPhotoInfo
+	selectionDetail.ProductPhotos = productPhotos
+	selectionDetail.FreeStrategys = freeStrategys
+	selectionDetail.RewardStrategys = rewardStrategys
 	return &selectionDetail, nil
 }

+ 16 - 0
app/util/encoding.go

@@ -0,0 +1,16 @@
+package util
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+)
+
+func MD5(keys ...string) string {
+	finalKey := ""
+	for _, key := range keys {
+		finalKey += key
+	}
+	s := md5.New()
+	s.Write([]byte(finalKey))
+	return hex.EncodeToString(s.Sum(nil))
+}

+ 26 - 0
app/util/resp.go

@@ -0,0 +1,26 @@
+package util
+
+import (
+	"net/http"
+	"youngee_b_api/consts"
+	"youngee_b_api/model/http_model"
+
+	"github.com/gin-gonic/gin"
+)
+
+func PackErrorResp(c *gin.Context, status int32) {
+	resp := http_model.CommonResponse{
+		Status:  status,
+		Message: consts.GetErrorToast(status),
+		Data:    nil,
+	}
+	c.JSON(http.StatusOK, resp)
+}
+func HandlerPackErrorResp(resp *http_model.CommonResponse, status int32, message string) {
+	resp.Status = status
+	if message != consts.DefaultToast {
+		resp.Message = message
+	} else {
+		resp.Message = consts.GetErrorToast(status)
+	}
+}

+ 25 - 0
app/util/structFunc.go

@@ -0,0 +1,25 @@
+package util
+
+import (
+	"fmt"
+	"reflect"
+)
+
+/*
+	合并两个结构体的值,遍历结构体s1,若s1中某字段值为空,则将s2该字段的值赋给s1,否则不变
+	参数:interface{} -> &struct, 结构体指针
+	返回值:interface{} -> &struct, 结构体指针
+*/
+func MergeStructValue(s1 interface{}, s2 interface{}) interface{} {
+	v1 := reflect.ValueOf(s1).Elem()
+	v2 := reflect.ValueOf(s2).Elem()
+	for i := 0; i < v1.NumField(); i++ {
+		field := v1.Field(i)
+		name := v1.Type().Field(i).Name
+		if field.Interface() == reflect.Zero(field.Type()).Interface() {
+			fmt.Printf("%+v %+v", name, v1.Kind() == reflect.Ptr)
+			v1.FieldByName(name).Set(v2.FieldByName(name))
+		}
+	}
+	return v1
+}

+ 129 - 0
app/util/type.go

@@ -0,0 +1,129 @@
+package util
+
+import (
+	"fmt"
+	"math/rand"
+	"reflect"
+	"time"
+)
+
+// IsNull 判断是否为空字符串
+func IsNull(s string) string {
+	if s == "" {
+		return "0"
+	}
+	return s
+}
+
+// IsBlank 判断 reflect.Value 是否为空
+func IsBlank(value reflect.Value) bool {
+	switch value.Kind() {
+	case reflect.String:
+		return value.Len() == 0
+	case reflect.Bool:
+		return !value.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return value.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return value.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return value.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		return value.IsNil()
+	}
+	return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
+}
+
+func GetNumString(num int64) string {
+	if num < 10000 {
+		return fmt.Sprintf("%v.00", num)
+	} else if num >= 10000 && num < 100000000 {
+		mean := float32(num) / float32(10000)
+		str := fmt.Sprintf("%.1f", mean)
+		return str + "万"
+	} else {
+		mean := float32(num) / float32(100000000)
+		str := fmt.Sprintf("%.1f", mean)
+		return str + "亿"
+	}
+}
+
+func GetTimePoionter(t *time.Time) time.Time {
+	if t == nil {
+		return time.Now()
+	} else {
+		return *t
+	}
+}
+
+func GetRandomString(l int) string {
+	str := "0123456789"
+	bytes := []byte(str)
+	var result []byte
+	r := rand.New(rand.NewSource(time.Now().UnixNano()))
+	for i := 0; i < l; i++ {
+		result = append(result, bytes[r.Intn(len(bytes))])
+	}
+	return string(result)
+}
+
+func GetDayNum(inputType string, inputData int) (int, error) {
+	result := 0
+	switch inputType {
+	case "year":
+		if inputData < 1 {
+			fmt.Println("年份错误!")
+			break
+		}
+		result = inputData
+	case "month":
+		months := []int{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}
+		if (inputData <= 12) && (inputData < 0) {
+			fmt.Println("月份错误!")
+			break
+		}
+		result = months[inputData-1]
+	case "day":
+		if (inputData < 0) && (inputData > 31) {
+			fmt.Println("日期错误!")
+			break
+		}
+		result = inputData
+	default:
+		return 0, fmt.Errorf("输入参数非法:%s", inputType)
+	}
+	return result, nil
+}
+
+// RemoveRepByMap 通过map主键唯一的特性过滤重复元素
+func RemoveRepByMap(slc []int64) []int64 {
+	if len(slc) == 0 {
+		return slc
+	}
+	var result []int64
+	tempMap := map[int64]byte{} // 存放不重复主键
+	for _, e := range slc {
+		l := len(tempMap)
+		tempMap[e] = 0
+		if len(tempMap) != l { // 加入map后,map长度变化,则元素不重复
+			result = append(result, e)
+		}
+	}
+	return result
+}
+
+func RemoveStrRepByMap(slc []string) []string {
+	if len(slc) == 0 {
+		return slc
+	}
+	var result []string
+	tempMap := map[string]byte{} // 存放不重复主键
+	for _, e := range slc {
+		l := len(tempMap)
+		tempMap[e] = 0
+		if len(tempMap) != l { // 加入map后,map长度变化,则元素不重复
+			result = append(result, e)
+		}
+	}
+	return result
+}

+ 38 - 0
app/util/uuid.go

@@ -0,0 +1,38 @@
+package util
+
+import (
+	"github.com/GUAIK-ORG/go-snowflake/snowflake"
+	"github.com/google/uuid"
+	"github.com/issue9/conv"
+	"math/rand"
+	"time"
+)
+
+var snowflakeInstance *snowflake.Snowflake
+
+func init() {
+	s, err := snowflake.NewSnowflake(int64(0), int64(0))
+	if err != nil {
+		panic(err)
+	}
+	snowflakeInstance = s
+}
+func GetUUID() string {
+	return uuid.New().String()
+}
+func GetSnowflakeID() int64 {
+	return snowflakeInstance.NextVal()
+}
+
+func GetSelectionID() string {
+	rand.Seed(time.Now().UnixNano())
+	td := conv.MustString(time.Now().Day())
+	for {
+		if len(td) == 3 {
+			break
+		}
+		td = "0" + td
+	}
+	selectionId := conv.MustString(time.Now().Year())[2:] + td + conv.MustString(rand.Intn(100000-10000)+10000)
+	return selectionId
+}

+ 24 - 0
app/vo/product_create_param.go

@@ -0,0 +1,24 @@
+package vo
+
+type ProductPhoto struct {
+	PhotoUrl string `json:"photo_url"` // 图片或视频url
+	PhotoUid string `json:"photo_uid"`
+	Symbol   int64  `json:"symbol"` // 图片为主图或详情图标志位,1为主图,2为轮播图,3为轮播视频. 4为详情图. 5为详情视频
+}
+
+type ProductCreateParam struct {
+	EnterpriseId                string         `json:"enterprise_id"`                   // 要绑定的企业id
+	ProductName                 string         `json:"product_name"`                    // 商品名称
+	ProductType                 int64          `json:"product_type"`                    // 商品类型
+	ShopAddress                 string         `json:"shop_address"`                    // 店铺地址,商品类型为线下品牌时需填写
+	ProductDetail               string         `json:"product_detail"`                  // 商品详细
+	ProductPrice                float64        `json:"product_price"`                   // 商品价值
+	ProductPhotos               []ProductPhoto `json:"product_photos"`                  // 商品图片列表
+	ProductUrl                  string         `json:"product_url"`                     // 商品链接,可为电商网址、公司官网、大众点评的店铺地址等可以说明商品信息或者品牌信息的线上地址;
+	BrandName                   string         `json:"brand_name"`                      // 品牌名称
+	PublicCommission            float64        `json:"public_commission"`               // 公开佣金
+	ExclusiveCommission         float64        `json:"exclusive_commission"`            // 专属佣金
+	CommissionPrice             float64        `json:"commission_price"`                // 佣金金额
+	MerchantSoldCountThirtyDays int64          `json:"merchant_sold_count_thirty_days"` // 商品30天销量
+	KuaishouProductId           int64          `json:"kuaishou_product_id"`             // 快手商品ID
+}

+ 0 - 18
app/vo/re_enterprise.go

@@ -1,18 +0,0 @@
-package vo
-
-import "time"
-
-type ReEnterprise struct {
-	EnterpriseID     string    `gorm:"column:enterprise_id"`     // 企业id,用户ID的生成规则为:1(企业用户代码)+分秒数字+四位随机数字
-	Industry         int64     `gorm:"column:industry"`          // 行业,1-14分别代表能源、化工、材料、机械设备/军工、企业服务/造纸印刷、运输设备、旅游酒店、媒体/信息通信服务、批发/零售、消费品、卫生保健/医疗、金融、建材/建筑/房地产、公共事业
-	BusinessName     string    `gorm:"column:business_name"`     // 公司或组织名称
-	UserID           int64     `gorm:"column:user_id"`           // 对应用户id
-	Balance          float64   `gorm:"column:balance"`           // 账户余额
-	FrozenBalance    float64   `gorm:"column:frozen_balance"`    // 冻结余额
-	AvailableBalance float64   `gorm:"column:available_balance"` // 可用余额
-	BillableAmount   float64   `gorm:"column:billable_amount"`   // 可开票金额
-	Invoicing        float64   `gorm:"column:invoicing"`         // 开票中金额
-	Recharging       float64   `gorm:"column:recharging"`        // 充值中金额
-	CreatedAt        time.Time `gorm:"column:created_at"`        // 创建时间
-	UpdatedAt        time.Time `gorm:"column:updated_at"`        // 更新时间
-}

+ 15 - 0
app/vo/re_selection_detail.go

@@ -0,0 +1,15 @@
+package vo
+
+import (
+	"youngee_b_api/app/entity"
+)
+
+type ReSelectionDetail struct {
+	SelectionInfo     *entity.SelectionInfo    // 选品详情
+	SelectionBriefs   []*entity.SecBrief       // 选品brief列表
+	SelectionExamples []*entity.SecExample     // 选品示例列表
+	ProductInfo       *entity.Product          // 商品详情
+	ProductPhotos     []*entity.ProductPhoto   // 商品图片列表
+	FreeStrategys     []*entity.FreeStrategy   // 免费领样策略
+	RewardStrategys   []*entity.RewardStrategy // 悬赏策略
+}

+ 14 - 0
app/vo/re_task_product.go

@@ -0,0 +1,14 @@
+package vo
+
+import "time"
+
+type ReTaskProduct struct {
+	ProductID     int64     `json:"product_id"`
+	ProductName   string    `json:"product_name"`
+	ProductType   string    `json:"product_type"`
+	ProductPrice  float64   `json:"product_price"`
+	ProductDetail string    `json:"product_detail"`
+	CreatedAt     time.Time `json:"created_at"`
+	BrandName     string    `json:"brand_name"`
+	PhotoUrl      string    `json:"photo_url"`
+}

+ 7 - 0
app/vo/selection_info_create_param.go

@@ -0,0 +1,7 @@
+package vo
+
+type SelectionInfoCreateParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	Platform     int64  `json:"platform"`
+	ProductId    int64  `json:"product_id"`
+}

+ 53 - 0
app/vo/selection_info_update_param.go

@@ -0,0 +1,53 @@
+package vo
+
+type SelectionInfoUpdateParam struct {
+	EnterpriseId     string                  `json:"enterprise_id"`
+	SelectionID      string                  `json:"selection_id"` // 选品id
+	SelectionStatus  int64                   `json:"selection_status"`
+	Platform         int64                   `json:"platform"`
+	ProductId        int64                   `json:"product_id"`
+	ContentType      int64                   `json:"content_type"`
+	TaskMode         int64                   `json:"task_mode"`
+	SampleNum        int64                   `json:"sample_num"`  // 样品数量
+	RemainNum        int64                   `json:"remain_num"`  // 剩余数量
+	TaskReward       float64                 `json:"task_reward"` // 任务悬赏
+	TaskDdl          string                  `json:"task_ddl"`
+	SampleMode       int64                   `json:"sample_mode"`
+	CommissionRate   float64                 `json:"commission_rate"`
+	ProductUrl       string                  `json:"product_url"`
+	SampleCondition  string                  `json:"sample_condition"`
+	RewardCondition  string                  `json:"reward_condition"` // 返现悬赏条件
+	SecBrief         []*SecBriefInfo         `json:"sec_brief"`
+	SecExample       []*SecExampleInfo       `json:"sec_example"`
+	Detail           string                  `json:"detail"`
+	SettlementAmount float64                 `json:"settlement_amount"`
+	FreeStrategys    []UpdateFreeStrategys   `json:"free_strategys"`   // 免费领样策略
+	RewardStrategys  []UpdateRewardStrategys `json:"reward_strategys"` // 悬赏策略
+	Status           int64                   `json:"status"`           // 是否删除
+}
+
+type SecBriefInfo struct {
+	PhotoUrl string `json:"photo_url"`
+	PhotoUid string `json:"photo_uid"`
+	Name     string `json:"name"`
+}
+
+type SecExampleInfo struct {
+	PhotoUrl string `json:"photo_url"`
+	PhotoUid string `json:"photo_uid"`
+	Name     string `json:"name"`
+}
+
+type UpdateFreeStrategys struct {
+	StrategyId int64 `json:"strategy_id"` // 策略编号
+	FansNum    int64 `json:"fans_num"`    // 粉丝数目
+	SaleNum    int64 `json:"sale_num"`    // 近30天橱窗销量
+	EnrollNum  int64 `json:"enroll_num"`  // 报名人数
+	ChooseNum  int64 `json:"choose_num"`  // 已选人数
+}
+
+type UpdateRewardStrategys struct {
+	Reward     float64 `json:"reward"`      // 悬赏池总金额
+	SaleActual int64   `json:"sale_actual"` // 实际带货销量
+	PerReward  float64 `json:"per_reward"`  // 每人可获得悬赏金
+}

+ 13 - 2
route/init.go

@@ -161,10 +161,21 @@ func InitRoute(r *gin.Engine) {
 	}
 
 	// 工作台相关接口
-	workspace := r.Group("/youngee/business/workspace")
+	workspace := r.Group("/youngee/b/workspace")
 	{
 		workspace.Use(middleware.LoginAuthMiddleware)
-		workspace.POST("/takegoods", controller.WorkspaceController{}.GetTakegoodsInfo)
+		workspace.POST("/takegoods", controller.WorkspaceController{}.GetTakegoodsInfo) //工作台数据概览
+	}
+	// 任务中心相关接口
+	task := r.Group("/youngee/b/task")
+	{
+		task.Use(middleware.LoginAuthMiddleware)
+		task.POST("/product/findAll", controller.TaskController{}.GetAllProduct)       // 关联商品-已有商品展示
+		task.POST("/product/create", controller.TaskController{}.CreateProduct)        // 关联商品-新建商品
+		task.POST("/selection/create", controller.TaskController{}.CreateSelection)    // 关联商品-完成关联创建带货任务
+		task.POST("/selection/update", controller.TaskController{}.UpdateSelection)    // 更新带货任务(样品奖励、补充信息)
+		task.POST("/selection/detail", controller.TaskController{}.GetSelectionDetail) // 电商带货任务预览
+
 	}
 
 }