소스 검색

移植选品接口

Ohio-HYF 1 년 전
부모
커밋
5879658fb4
46개의 변경된 파일2536개의 추가작업 그리고 36개의 파일을 삭제
  1. 35 0
      db/product.go
  2. 191 0
      db/sectask.go
  3. 29 0
      db/sectask_logistics.go
  4. 177 0
      db/selection.go
  5. 23 0
      db/talent_income.go
  6. 8 29
      go.mod
  7. 90 5
      go.sum
  8. 60 0
      handler/CreateSecTaskLogistics.go
  9. 61 0
      handler/GetSecTaskList.go
  10. 61 0
      handler/PassSecTaskCoop.go
  11. 61 0
      handler/RefuseSecTaskCoop.go
  12. 61 0
      handler/SettleSecTask.go
  13. 60 0
      handler/UpdateSecTaskLogistics.go
  14. 61 0
      handler/selection_create.go
  15. 55 0
      handler/selection_delete.go
  16. 58 0
      handler/selection_detail.go
  17. 68 0
      handler/selection_find_all.go
  18. 61 0
      handler/selection_pay.go
  19. 59 0
      handler/selection_review.go
  20. 59 0
      handler/selection_update.go
  21. 12 0
      model/common_model/selection_condition.go
  22. 20 0
      model/gorm_model/selection_brief_info.go
  23. 20 0
      model/gorm_model/selection_example_info.go
  24. 44 0
      model/gorm_model/selection_task_info.go
  25. 27 0
      model/gorm_model/talent_income.go
  26. 24 0
      model/http_model/CreateSecTaskLogisticsRequest.go
  27. 21 0
      model/http_model/CreateSelectionRequest.go
  28. 13 0
      model/http_model/DeleteSelectionRequest.go
  29. 32 0
      model/http_model/FindAllSelectionRequest.go
  30. 38 0
      model/http_model/GetSecTaskListRequest.go
  31. 19 0
      model/http_model/PassSecTaskCoopRequest.go
  32. 21 0
      model/http_model/PaySelectionRequest.go
  33. 18 0
      model/http_model/RefuseSecTaskCoopRequest.go
  34. 21 0
      model/http_model/ReviewSelectionRequest.go
  35. 26 0
      model/http_model/SelectionDetailRequest.go
  36. 23 0
      model/http_model/SettleSecTaskRequest.go
  37. 25 0
      model/http_model/UpdateSecTaskLogisticsRequest.go
  38. 48 0
      model/http_model/UpdateSelectionRequest.go
  39. 30 0
      pack/sec_task_list.go
  40. 60 0
      pack/selection.go
  41. 14 2
      route/init.go
  42. 188 0
      service/sec_task.go
  43. 106 0
      service/sec_task_logistics.go
  44. 288 0
      service/selection.go
  45. 22 0
      util/structFunc.go
  46. 38 0
      util/uuid.go

+ 35 - 0
db/product.go

@@ -3,6 +3,7 @@ package db
 import (
 	"context"
 	"github.com/caixw/lib.go/conv"
+	"github.com/sirupsen/logrus"
 	"gorm.io/gorm"
 	"strconv"
 	"youngee_m_api/model/gorm_model"
@@ -83,3 +84,37 @@ func UpdateProduct(ctx context.Context, product gorm_model.YounggeeProduct) (*in
 	}
 	return &product.ProductID, nil
 }
+
+func GetProductInfoBySelectionId(ctx context.Context, selectionId string) (*gorm_model.YounggeeProduct, error) {
+	db := GetReadDB(ctx)
+	productId := 0
+	err := db.Model(gorm_model.YounggeeSelectionInfo{}).Select("product_id").Where("selection_id = ?", selectionId).Find(&productId).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	productInfo := gorm_model.YounggeeProduct{}
+	err = db.Model(gorm_model.YounggeeProduct{}).Where("product_id = ?", productId).Find(&productInfo).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	return &productInfo, nil
+}
+
+func GetProductPhotoInfoBySelectionId(ctx context.Context, selectionId string) ([]*gorm_model.YounggeeProductPhoto, error) {
+	db := GetReadDB(ctx)
+	productId := 0
+	err := db.Model(gorm_model.YounggeeSelectionInfo{}).Select("product_id").Where("selection_id = ?", selectionId).Find(&productId).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	var productPhotoInfo []*gorm_model.YounggeeProductPhoto
+	err = db.Model(gorm_model.YounggeeProductPhoto{}).Where("product_id = ?", productId).Find(&productPhotoInfo).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetProductInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	return productPhotoInfo, nil
+}

+ 191 - 0
db/sectask.go

@@ -0,0 +1,191 @@
+package db
+
+import (
+	"context"
+	"errors"
+	"github.com/sirupsen/logrus"
+	"gorm.io/gorm"
+	"strings"
+	"time"
+	"youngee_m_api/model/gorm_model"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/pack"
+)
+
+func GetSecTaskById(ctx context.Context, secTaskId string) (*gorm_model.YounggeeSecTaskInfo, error) {
+	db := GetWriteDB(ctx)
+	secTaskInfo := gorm_model.YounggeeSecTaskInfo{}
+	whereCondition := gorm_model.YounggeeSecTaskInfo{TaskID: secTaskId}
+	result := db.Where(&whereCondition).First(&secTaskInfo)
+	if result.Error != nil {
+		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
+			return nil, nil
+		} else {
+			return nil, result.Error
+		}
+	}
+	return &secTaskInfo, nil
+}
+
+func GetSecTaskList(ctx context.Context, selectionId string, taskStatus int, searchValue string, pageSize, pageNum int64) ([]*http_model.SecTaskInfo, int64, error) {
+	db := GetReadDB(ctx)
+	whereCondition := gorm_model.YounggeeSecTaskInfo{
+		SelectionID: selectionId,
+		TaskStatus:  taskStatus,
+	}
+	db = db.Model(gorm_model.YounggeeSecTaskInfo{}).Where(whereCondition)
+
+	// 查询总数
+	var total int64
+	var secTaskInfoList []*gorm_model.YounggeeSecTaskInfo
+	if err := db.Count(&total).Error; err != nil {
+		logrus.WithContext(ctx).Errorf("[GetSelectionList] error query mysql total, err:%+v", err)
+		return nil, 0, err
+	}
+	// 查询该页数据
+	limit := pageSize
+	offset := pageSize * pageNum // assert pageNum start with 0
+	err := db.Order("create_date desc").Limit(int(limit)).Offset(int(offset)).Find(&secTaskInfoList).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetSelectionList] error query mysql total, err:%+v", err)
+		return nil, 0, err
+	}
+
+	newSecTaskInfoList := pack.GormSecTaskListToHttpSecTaskList(secTaskInfoList)
+	var resSecTaskInfoList []*http_model.SecTaskInfo
+	if searchValue != "" {
+		for _, v := range newSecTaskInfoList {
+			if strings.Contains(v.SelectionId, searchValue) {
+				resSecTaskInfoList = append(resSecTaskInfoList, v)
+			} else if strings.Contains(v.PlatformNickname, searchValue) {
+				resSecTaskInfoList = append(resSecTaskInfoList, v)
+			} else {
+				total--
+			}
+		}
+	} else {
+		resSecTaskInfoList = newSecTaskInfoList
+	}
+	return resSecTaskInfoList, total, nil
+}
+
+func PassSecTaskCoop(ctx context.Context, selectionId string, taskIds []string) (bool, error) {
+	db := GetWriteDB(ctx)
+	// 1. 校验
+	var count int64
+	err := db.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ? AND task_stage = 3", taskIds).Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+	if int64(len(taskIds)) == 0 || count != int64(len(taskIds)) {
+		return false, errors.New("任务id有误")
+	}
+
+	// 2. 查询任务对应达人id(用于生成达人消息)
+	var talentIds []string
+	err = db.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ?", taskIds).Select("talent_id").Find(talentIds).Error
+	if err != nil {
+		return false, err
+	}
+	// 3. 查询任务对应选品名称(用于生成达人消息)
+	var selection gorm_model.YounggeeSelectionInfo
+	err = db.Model(gorm_model.YounggeeSelectionInfo{}).Where("selection_id = ?", selectionId).Find(selection).Error
+	if err != nil {
+		return false, err
+	}
+
+	err = db.Transaction(func(tx *gorm.DB) error {
+		// 2. 修改任务状态和任务阶段
+		// 若选品不提供样品,则直接跳转执行阶段,否则进入发货阶段
+		if selection.SampleMode == 3 {
+			updateData := gorm_model.YounggeeSecTaskInfo{
+				TaskStatus:      2,
+				TaskStage:       6,
+				SelectDate:      time.Now(),
+				LogisticsStatus: 1,
+			}
+			err = tx.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ? AND task_stage = 3", taskIds).Updates(updateData).Error
+			if err != nil {
+				return err
+			}
+		} else {
+			updateData := gorm_model.YounggeeSecTaskInfo{
+				TaskStatus:       2,
+				TaskStage:        8,
+				SelectDate:       time.Now(),
+				LogisticsStatus:  3,
+				AssignmentStatus: 1,
+			}
+			err = tx.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ? AND task_stage = 3", taskIds).Updates(updateData).Error
+			if err != nil {
+				return err
+			}
+		}
+		// 3. 生成达人消息
+		for _, talendId := range talentIds {
+			err = CreateMessage(ctx, 1, 1, talendId, selection.SelectionName)
+			if err != nil {
+				return err
+			}
+		}
+		// 返回 nil 提交事务
+		return nil
+	})
+	if err != nil {
+		return false, err
+	}
+	return true, nil
+}
+
+func RefuseSecTaskCoop(ctx context.Context, taskIds []string) (bool, error) {
+	db := GetWriteDB(ctx)
+	// 1. 校验
+	var count int64
+	err := db.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ? AND task_stage = 3", taskIds).Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+	if count != int64(len(taskIds)) {
+		return false, errors.New("任务id有误")
+	}
+
+	// 查询任务对应达人id
+	var talentIds []string
+	err = db.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ?", taskIds).Select("talent_id").Find(talentIds).Error
+	if err != nil {
+		return false, err
+	}
+
+	err = db.Transaction(func(tx *gorm.DB) error {
+		// 2. 修改任务状态和任务阶段
+		updateData := gorm_model.YounggeeSecTaskInfo{
+			TaskStatus:     3,
+			TaskStage:      5,
+			CompleteDate:   time.Now(),
+			CompleteStatus: 3,
+		}
+		err = tx.Model(gorm_model.YounggeeSecTaskInfo{}).Where("task_id IN ? AND task_stage = 3", taskIds).Updates(updateData).Error
+		if err != nil {
+			return err
+		}
+
+		// 返回 nil 提交事务
+		return nil
+	})
+	if err != nil {
+		return false, err
+	}
+	return true, nil
+}
+
+func UpdateSecTask(ctx context.Context, updateData gorm_model.YounggeeSecTaskInfo) (bool, error) {
+	db := GetWriteDB(ctx)
+	whereCondition := gorm_model.YounggeeSecTaskInfo{
+		TaskID: updateData.TaskID,
+	}
+	err := db.Where(whereCondition).Updates(&updateData).Error
+	if err != nil {
+		return false, err
+	}
+	return true, nil
+}

+ 29 - 0
db/sectask_logistics.go

@@ -0,0 +1,29 @@
+package db
+
+import (
+	"context"
+	"youngee_m_api/model/gorm_model"
+)
+
+func CreateSecTaskLogistics(ctx context.Context, logistics gorm_model.YoungeeTaskLogistics) (*int64, error) {
+	db := GetWriteDB(ctx)
+	err := db.Create(&logistics).Error
+	if err != nil {
+		return nil, err
+	}
+
+	return &logistics.LogisticsID, nil
+}
+
+func UpdateSecTaskLogistics(ctx context.Context, updateData gorm_model.YoungeeTaskLogistics) (*int64, error) {
+	db := GetWriteDB(ctx)
+	whereCondition := gorm_model.YoungeeTaskLogistics{
+		LogisticsID: updateData.LogisticsID,
+	}
+	err := db.Where(whereCondition).Updates(&updateData).Error
+	if err != nil {
+		return nil, err
+	}
+
+	return &updateData.LogisticsID, nil
+}

+ 177 - 0
db/selection.go

@@ -2,13 +2,19 @@ package db
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"github.com/caixw/lib.go/conv"
 	"github.com/sirupsen/logrus"
+	"gorm.io/gorm"
+	"reflect"
 	"strconv"
+	"strings"
 	"youngee_m_api/consts"
+	"youngee_m_api/model/common_model"
 	"youngee_m_api/model/gorm_model"
 	"youngee_m_api/model/http_model"
+	"youngee_m_api/util"
 )
 
 func SelectionReviewNumber(ctx context.Context) (*http_model.ReviewNums, error) {
@@ -58,3 +64,174 @@ func GetSelectionInfo(ctx context.Context, req *http_model.GetSelectionInfoReque
 	selectionInfoData.Total = strconv.FormatInt(total, 10)
 	return
 }
+
+func CreateSelection(ctx context.Context, selectionInfo gorm_model.YounggeeSelectionInfo) error {
+	db := GetWriteDB(ctx)
+	err := db.Create(&selectionInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func UpdateSelection(ctx context.Context, selectionInfo gorm_model.YounggeeSelectionInfo) error {
+	db := GetWriteDB(ctx)
+	whereCondition := gorm_model.YounggeeSelectionInfo{SelectionID: selectionInfo.SelectionID}
+	err := db.Model(&gorm_model.YounggeeSelectionInfo{}).Where(whereCondition).Updates(selectionInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func DeleteSelection(ctx context.Context, SelectionId string) error {
+	db := GetReadDB(ctx)
+	err := db.Where("selection_id = ?", SelectionId).Delete(&gorm_model.YounggeeSelectionInfo{}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func GetSelectionById(ctx context.Context, selectionId string) (*gorm_model.YounggeeSelectionInfo, error) {
+	db := GetWriteDB(ctx)
+	selectionInfo := gorm_model.YounggeeSelectionInfo{}
+	whereCondition := gorm_model.YounggeeSelectionInfo{SelectionID: selectionId}
+	result := db.Where(&whereCondition).First(&selectionInfo)
+	if result.Error != nil {
+		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
+			return nil, nil
+		} else {
+			return nil, result.Error
+		}
+	}
+	return &selectionInfo, nil
+}
+
+func GetSelectionByEnterpiseIdAndProductId(ctx context.Context, enterpriseId string, productId int) (*gorm_model.YounggeeSelectionInfo, error) {
+	db := GetWriteDB(ctx)
+	selectionInfo := gorm_model.YounggeeSelectionInfo{}
+	whereCondition := gorm_model.YounggeeSelectionInfo{EnterpriseID: enterpriseId, ProductID: productId}
+	result := db.Where(&whereCondition).First(&selectionInfo)
+	if result.Error != nil {
+		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
+			return nil, nil
+		} else {
+			return nil, result.Error
+		}
+	}
+	return &selectionInfo, nil
+}
+
+func GetSelectionList(ctx context.Context, enterpriseID string, pageSize, pageNum int64, conditions *common_model.SelectionConditions) ([]*gorm_model.YounggeeSelectionInfo, int64, error) {
+	db := GetReadDB(ctx)
+	db = db.Debug().Model(gorm_model.YounggeeSelectionInfo{}).Where("enterprise_id = ?", enterpriseID)
+	conditionType := reflect.TypeOf(conditions).Elem()
+	conditionValue := reflect.ValueOf(conditions).Elem()
+	selectionStatus := ""
+	searchValue := ""
+	for i := 0; i < conditionType.NumField(); i++ {
+		field := conditionType.Field(i)
+		tag := field.Tag.Get("condition")
+		value := conditionValue.FieldByName(field.Name)
+		if tag == "selection_status" {
+			selectionStatus = fmt.Sprintf("%v", value.Interface())
+		} else if tag == "search_value" {
+			searchValue = fmt.Sprintf("%v", value.Interface())
+		} else if tag == "submit_at" && value.Interface() != "" {
+			db = db.Where(fmt.Sprintf("submit_at like '%s%%'", value.Interface()))
+		} else if tag == "task_ddl" && value.Interface() != "" {
+			db = db.Where(fmt.Sprintf("task_ddl like '%s%%'", value.Interface()))
+		} else if !util.IsBlank(value) && tag != "task_ddl" && tag != "submit_at" && tag != "search_value" {
+			db = db.Where(fmt.Sprintf("%s = ?", tag), value.Interface())
+		}
+	}
+	// 查询总数
+	var total int64
+	var selectionInfos []*gorm_model.YounggeeSelectionInfo
+	if err := db.Count(&total).Error; err != nil {
+		logrus.WithContext(ctx).Errorf("[GetSelectionList] error query mysql total, err:%+v", err)
+		return nil, 0, err
+	}
+	// 查询该页数据
+	limit := pageSize
+	offset := pageSize * pageNum // assert pageNum start with 0
+	if selectionStatus == "1" {
+		err := db.Order("submit_at desc").Limit(int(limit)).Offset(int(offset)).Find(&selectionInfos).Error
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[GetSelectionList] error query mysql total, err:%+v", err)
+			return nil, 0, err
+		}
+	} else {
+		err := db.Order("task_ddl desc").Limit(int(limit)).Offset(int(offset)).Find(&selectionInfos).Error
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[GetSelectionList] error query mysql total, err:%+v", err)
+			return nil, 0, err
+		}
+	}
+	var newSelectionInfos []*gorm_model.YounggeeSelectionInfo
+	for _, v := range selectionInfos {
+		if searchValue == "" {
+			newSelectionInfos = append(newSelectionInfos, v)
+		} else if strings.Contains(v.SelectionID, searchValue) {
+			newSelectionInfos = append(newSelectionInfos, v)
+		} else if strings.Contains(v.SelectionName, searchValue) {
+			newSelectionInfos = append(newSelectionInfos, v)
+		} else {
+			total--
+		}
+	}
+	return newSelectionInfos, total, nil
+}
+
+func GetSelectionBriefInfo(ctx context.Context, selectionId string) ([]*gorm_model.YounggeeSecBrief, error) {
+	db := GetReadDB(ctx)
+	var selectionBriefInfos []*gorm_model.YounggeeSecBrief
+	err := db.Model(gorm_model.YounggeeSecBrief{}).Where("selection_id = ?", selectionId).Find(&selectionBriefInfos).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetSelectionBriefInfo] error query mysql, err:%+v", err)
+		return nil, err
+	}
+	return selectionBriefInfos, nil
+}
+
+func GetSelectionExampleInfo(ctx context.Context, selectionId string) ([]*gorm_model.YounggeeSecExample, error) {
+	db := GetReadDB(ctx)
+	var selectionExampleInfos []*gorm_model.YounggeeSecExample
+	err := db.Model(gorm_model.YounggeeSecExample{}).Where("selection_id = ?", selectionId).Find(&selectionExampleInfos).Error
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[GetSelectionExampleInfo] error query, err:%+v", err)
+		return nil, err
+	}
+	return selectionExampleInfos, nil
+}
+
+func PaySelection(ctx context.Context, enterpriseId string, payMoney float64, selectionId string) error {
+	db := GetWriteDB(ctx)
+	err := db.Transaction(func(tx *gorm.DB) error {
+		// 1. 冻结账户余额
+		whereCondition := gorm_model.Enterprise{
+			EnterpriseID: enterpriseId,
+		}
+		updateData := map[string]interface{}{
+			"frozen_balance":    gorm.Expr("frozen_balance + ?", payMoney),
+			"available_balance": gorm.Expr("available_balance - ?", payMoney)}
+		if err := tx.Model(gorm_model.Enterprise{}).Where(whereCondition).Updates(updateData).Error; err != nil {
+			return err
+		}
+
+		// 2. 更新选品项目状态
+		whereCondition1 := gorm_model.YounggeeSelectionInfo{SelectionID: selectionId, SelectionStatus: 4}
+		updateData1 := gorm_model.YounggeeSelectionInfo{SelectionStatus: 6}
+		if err := tx.Model(gorm_model.YounggeeSelectionInfo{}).Where(whereCondition1).Updates(updateData1).Error; err != nil {
+			return err
+		}
+
+		// 返回 nil 提交事务
+		return nil
+	})
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 23 - 0
db/talent_income.go

@@ -0,0 +1,23 @@
+package db
+
+import (
+	"context"
+	"gorm.io/gorm"
+	"youngee_m_api/model/gorm_model"
+)
+
+func CreateIncome(ctx context.Context, income gorm_model.YounggeeTalentIncome, tx *gorm.DB) error {
+	if tx != nil {
+		err := tx.Create(&income).Error
+		if err != nil {
+			return err
+		}
+	} else {
+		db := GetWriteDB(ctx)
+		err := db.Create(&income).Error
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 8 - 29
go.mod

@@ -1,6 +1,6 @@
 module youngee_m_api
 
-go 1.17
+go 1.16
 
 require (
 	github.com/caixw/lib.go v0.0.0-20141220110639-1781da9139e0
@@ -13,32 +13,11 @@ require (
 )
 
 require (
-	github.com/cespare/xxhash/v2 v2.1.2 // indirect
-	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
-	github.com/gin-contrib/sse v0.1.0 // indirect
-	github.com/go-playground/locales v0.14.0 // indirect
-	github.com/go-playground/universal-translator v0.18.0 // indirect
-	github.com/go-playground/validator/v10 v10.10.0 // indirect
-	github.com/go-redis/redis/v8 v8.11.5 // indirect
-	github.com/go-sql-driver/mysql v1.6.0 // indirect
-	github.com/goccy/go-json v0.9.7 // indirect
-	github.com/jinzhu/inflection v1.0.0 // indirect
-	github.com/jinzhu/now v1.1.4 // indirect
-	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/leodido/go-urn v1.2.1 // indirect
-	github.com/mattn/go-isatty v0.0.14 // indirect
-	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
-	github.com/modern-go/reflect2 v1.0.2 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
-	github.com/robfig/cron/v3 v3.0.0 // indirect
-	github.com/tidwall/gjson v1.14.3 // indirect
-	github.com/tidwall/match v1.1.1 // indirect
-	github.com/tidwall/pretty v1.2.0 // indirect
-	github.com/ugorji/go/codec v1.2.7 // indirect
-	github.com/wechatpay-apiv3/wechatpay-go v0.2.15 // indirect
-	golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
-	golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
-	golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
-	golang.org/x/text v0.3.6 // indirect
-	google.golang.org/protobuf v1.28.0 // indirect
+	github.com/GUAIK-ORG/go-snowflake v0.0.0-20200116064823-220c4260e85f
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/google/uuid v1.3.0
+	github.com/issue9/conv v1.3.4
+	github.com/robfig/cron/v3 v3.0.0
+	github.com/tidwall/gjson v1.14.3
+	github.com/wechatpay-apiv3/wechatpay-go v0.2.15
 )

+ 90 - 5
go.sum

@@ -1,8 +1,14 @@
+github.com/GUAIK-ORG/go-snowflake v0.0.0-20200116064823-220c4260e85f h1:RDkg3pyE1qGbBpRWmvSN9RNZC5nUrOaEPiEpEb8y2f0=
+github.com/GUAIK-ORG/go-snowflake v0.0.0-20200116064823-220c4260e85f/go.mod h1:zA7AF9RTfpluCfz0omI4t5KCMaWHUMicsZoMccnaT44=
+github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
 github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
 github.com/caixw/lib.go v0.0.0-20141220110639-1781da9139e0 h1:MnIURgMAFAMyxAHu8h2TbnjxMMd7SKVCPyTZz5EfwNA=
 github.com/caixw/lib.go v0.0.0-20141220110639-1781da9139e0/go.mod h1:hQL8hyiiVE/BSo7gh13njx+DpvoPh/yE8/BkKKc62RA=
 github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
 github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/cstockton/go-conv v1.0.0 h1:zj/q/0MpQ/97XfiC9glWiohO8lhgR4TTnHYZifLTv6I=
 github.com/cstockton/go-conv v1.0.0/go.mod h1:HuiHkkRgOA0IoBNPC7ysG7kNpjDYlgM7Kj62yQPxjy4=
@@ -11,6 +17,9 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
+github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
 github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
 github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
@@ -27,12 +36,35 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC
 github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
 github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
 github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
 github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
 github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/issue9/assert/v3 v3.0.4 h1:WsYZQ6PQmM/pGFrbkn5GIXjWeVZHv+wcl2829UTX1Qc=
+github.com/issue9/assert/v3 v3.0.4/go.mod h1:yft/uaskRpwQTyBT3n1zRl91SR1wNlO4fLZHzOa4bdM=
+github.com/issue9/conv v1.3.4 h1:v1j/p1lVNW4u1yrbUxxNCb61iTFnF86s+KAwS65MsBs=
+github.com/issue9/conv v1.3.4/go.mod h1:TXM2DyyJhzZMSwp9cxwFW/OhP5JRVZPMg5XE8OMzwUY=
 github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
 github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
 github.com/jinzhu/now v1.1.4 h1:tHnRBy1i5F2Dh8BAFxqFzxKqqvezXrL2OW1TnX+Mlas=
@@ -55,6 +87,20 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
+github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
+github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
+github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
+github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
+github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
 github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
 github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
 github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@@ -71,9 +117,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -89,29 +135,63 @@ github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0
 github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
 github.com/wechatpay-apiv3/wechatpay-go v0.2.15 h1:WtlAK8GsLwTveS7c5W8Vd1m4rU1cJ0YW6tqBW2BlKH8=
 github.com/wechatpay-apiv3/wechatpay-go v0.2.15/go.mod h1:Ca9wvI7xFoIWiY163q1jzddarQBS+1NE17OM1ZV24nw=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 h1:DzZ89McO9/gWPsQXS/FVKAlG02ZjaQ6AlZRBimEYOd0=
 golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 h1:siQdpVirKtzPhKl3lZWozZraCFObP8S1v6PRp0bLrtU=
 golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
 google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -119,10 +199,15 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

+ 60 - 0
handler/CreateSecTaskLogistics.go

@@ -0,0 +1,60 @@
+package handler
+
+import (
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+)
+
+func WrapCreateSecTaskLogisticsHandler(ctx *gin.Context) {
+	handler := newCreateSecTaskLogisticsHandler(ctx)
+	BaseRun(handler)
+}
+
+type CreateSecTaskLogistics struct {
+	ctx  *gin.Context
+	req  *http_model.CreateSecTaskLogisticsRequest
+	resp *http_model.CommonResponse
+}
+
+func (c CreateSecTaskLogistics) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c CreateSecTaskLogistics) getResponse() interface{} {
+	return c.resp
+}
+
+func (c CreateSecTaskLogistics) getRequest() interface{} {
+	return c.req
+}
+
+func (c CreateSecTaskLogistics) run() {
+	data := http_model.CreateSecTaskLogisticsRequest{}
+	data = *c.req
+	res, err := service.SecLogistics.Create(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[CreateSecTaskLogistics] call CreateSecTaskLogistics err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("CreateSecTaskLogistics fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功添加发货信息"
+	c.resp.Data = res
+}
+
+func (c CreateSecTaskLogistics) checkParam() error {
+	return nil
+}
+
+func newCreateSecTaskLogisticsHandler(ctx *gin.Context) *CreateSecTaskLogistics {
+	return &CreateSecTaskLogistics{
+		ctx:  ctx,
+		req:  http_model.NewCreateSecTaskLogisticsRequest(),
+		resp: http_model.NewCreateSecTaskLogisticsResponse(),
+	}
+}

+ 61 - 0
handler/GetSecTaskList.go

@@ -0,0 +1,61 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapGetSecTaskListHandler(ctx *gin.Context) {
+	handler := newGetSecTaskListHandler(ctx)
+	BaseRun(handler)
+}
+
+type GetSecTaskList struct {
+	ctx  *gin.Context
+	req  *http_model.GetSecTaskListRequest
+	resp *http_model.CommonResponse
+}
+
+func (c GetSecTaskList) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c GetSecTaskList) getResponse() interface{} {
+	return c.resp
+}
+
+func (c GetSecTaskList) getRequest() interface{} {
+	return c.req
+}
+
+func (c GetSecTaskList) run() {
+	data := http_model.GetSecTaskListRequest{}
+	data = *c.req
+	//auth := middleware.GetSessionAuth(c.ctx)
+	//enterpriseID := auth.EnterpriseID
+	res, err := service.SelectionTask.GetList(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[GetSecTaskList] call GetSecTaskList err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("GetSecTaskList fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功查询选品任务"
+	c.resp.Data = res
+}
+
+func (c GetSecTaskList) checkParam() error {
+	return nil
+}
+
+func newGetSecTaskListHandler(ctx *gin.Context) *GetSecTaskList {
+	return &GetSecTaskList{
+		ctx:  ctx,
+		req:  http_model.NewGetSecTaskListRequest(),
+		resp: http_model.NewGetSecTaskListResponse(),
+	}
+}

+ 61 - 0
handler/PassSecTaskCoop.go

@@ -0,0 +1,61 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapPassSecTaskCoopHandler(ctx *gin.Context) {
+	handler := newPassSecTaskCoopHandler(ctx)
+	BaseRun(handler)
+}
+
+type PassSecTaskCoop struct {
+	ctx  *gin.Context
+	req  *http_model.PassSecTaskCoopRequest
+	resp *http_model.CommonResponse
+}
+
+func (c PassSecTaskCoop) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c PassSecTaskCoop) getResponse() interface{} {
+	return c.resp
+}
+
+func (c PassSecTaskCoop) getRequest() interface{} {
+	return c.req
+}
+
+func (c PassSecTaskCoop) run() {
+	data := http_model.PassSecTaskCoopRequest{}
+	data = *c.req
+	//auth := middleware.GetSessionAuth(c.ctx)
+	//enterpriseID := auth.EnterpriseID
+	res, err := service.SelectionTask.PassCoop(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[PassSecTaskCoop] call PassSecTaskCoop err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("PassSecTaskCoop fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功合作选品任务"
+	c.resp.Data = res
+}
+
+func (c PassSecTaskCoop) checkParam() error {
+	return nil
+}
+
+func newPassSecTaskCoopHandler(ctx *gin.Context) *PassSecTaskCoop {
+	return &PassSecTaskCoop{
+		ctx:  ctx,
+		req:  http_model.NewPassSecTaskCoopRequest(),
+		resp: http_model.NewPassSecTaskCoopResponse(),
+	}
+}

+ 61 - 0
handler/RefuseSecTaskCoop.go

@@ -0,0 +1,61 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapRefuseSecTaskCoopHandler(ctx *gin.Context) {
+	handler := newRefuseSecTaskCoopHandler(ctx)
+	BaseRun(handler)
+}
+
+type RefuseSecTaskCoop struct {
+	ctx  *gin.Context
+	req  *http_model.RefuseSecTaskCoopRequest
+	resp *http_model.CommonResponse
+}
+
+func (c RefuseSecTaskCoop) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c RefuseSecTaskCoop) getResponse() interface{} {
+	return c.resp
+}
+
+func (c RefuseSecTaskCoop) getRequest() interface{} {
+	return c.req
+}
+
+func (c RefuseSecTaskCoop) run() {
+	data := http_model.RefuseSecTaskCoopRequest{}
+	data = *c.req
+	//auth := middleware.GetSessionAuth(c.ctx)
+	//enterpriseID := auth.EnterpriseID
+	res, err := service.SelectionTask.RefuseCoop(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[RefuseSecTaskCoop] call RefuseSecTaskCoop err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("RefuseSecTaskCoop fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功拒绝选品任务"
+	c.resp.Data = res
+}
+
+func (c RefuseSecTaskCoop) checkParam() error {
+	return nil
+}
+
+func newRefuseSecTaskCoopHandler(ctx *gin.Context) *RefuseSecTaskCoop {
+	return &RefuseSecTaskCoop{
+		ctx:  ctx,
+		req:  http_model.NewRefuseSecTaskCoopRequest(),
+		resp: http_model.NewRefuseSecTaskCoopResponse(),
+	}
+}

+ 61 - 0
handler/SettleSecTask.go

@@ -0,0 +1,61 @@
+package handler
+
+import (
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+)
+
+func WrapSettleSecTaskHandler(ctx *gin.Context) {
+	handler := newSettleSecTaskHandler(ctx)
+	BaseRun(handler)
+}
+
+type SettleSecTask struct {
+	ctx  *gin.Context
+	req  *http_model.SettleSecTaskRequest
+	resp *http_model.CommonResponse
+}
+
+func (c SettleSecTask) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c SettleSecTask) getResponse() interface{} {
+	return c.resp
+}
+
+func (c SettleSecTask) getRequest() interface{} {
+	return c.req
+}
+
+func (c SettleSecTask) run() {
+	//enterpriseID := middleware.GetSessionAuth(c.ctx).EnterpriseID
+	data := http_model.SettleSecTaskRequest{}
+	data = *c.req
+	res, err := service.SelectionTask.Settle(c.ctx, data.EnterpriseId, data)
+	if err != nil {
+		logrus.Errorf("[SettleSecTask] call SettleSecTask err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("SettleSecTask fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功添加发货信息"
+	c.resp.Data = res
+}
+
+func (c SettleSecTask) checkParam() error {
+	return nil
+}
+
+func newSettleSecTaskHandler(ctx *gin.Context) *SettleSecTask {
+	return &SettleSecTask{
+		ctx:  ctx,
+		req:  http_model.NewSettleSecTaskRequest(),
+		resp: http_model.NewSettleSecTaskResponse(),
+	}
+}

+ 60 - 0
handler/UpdateSecTaskLogistics.go

@@ -0,0 +1,60 @@
+package handler
+
+import (
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+)
+
+func WrapUpdateSecTaskLogisticsHandler(ctx *gin.Context) {
+	handler := newUpdateSecTaskLogisticsHandler(ctx)
+	BaseRun(handler)
+}
+
+type UpdateSecTaskLogistics struct {
+	ctx  *gin.Context
+	req  *http_model.UpdateSecTaskLogisticsRequest
+	resp *http_model.CommonResponse
+}
+
+func (c UpdateSecTaskLogistics) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c UpdateSecTaskLogistics) getResponse() interface{} {
+	return c.resp
+}
+
+func (c UpdateSecTaskLogistics) getRequest() interface{} {
+	return c.req
+}
+
+func (c UpdateSecTaskLogistics) run() {
+	data := http_model.UpdateSecTaskLogisticsRequest{}
+	data = *c.req
+	res, err := service.SecLogistics.Update(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[UpdateSecTaskLogistics] call UpdateSecTaskLogistics err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("UpdateSecTaskLogistics fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功添加发货信息"
+	c.resp.Data = res
+}
+
+func (c UpdateSecTaskLogistics) checkParam() error {
+	return nil
+}
+
+func newUpdateSecTaskLogisticsHandler(ctx *gin.Context) *UpdateSecTaskLogistics {
+	return &UpdateSecTaskLogistics{
+		ctx:  ctx,
+		req:  http_model.NewUpdateSecTaskLogisticsRequest(),
+		resp: http_model.NewUpdateSecTaskLogisticsResponse(),
+	}
+}

+ 61 - 0
handler/selection_create.go

@@ -0,0 +1,61 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapCreateSelectionHandler(ctx *gin.Context) {
+	handler := newCreateSelectionHandler(ctx)
+	BaseRun(handler)
+}
+
+type CreateSelection struct {
+	ctx  *gin.Context
+	req  *http_model.CreateSelectionRequest
+	resp *http_model.CommonResponse
+}
+
+func (c CreateSelection) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c CreateSelection) getResponse() interface{} {
+	return c.resp
+}
+
+func (c CreateSelection) getRequest() interface{} {
+	return c.req
+}
+
+func (c CreateSelection) run() {
+	data := http_model.CreateSelectionRequest{}
+	data = *c.req
+	//auth := middleware.GetSessionAuth(c.ctx)
+	//enterpriseID := auth.EnterpriseID
+	res, err := service.Selection.Create(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[CreateSelection] call CreateSelection err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("CreateSelection fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功创建选品"
+	c.resp.Data = res
+}
+
+func (c CreateSelection) checkParam() error {
+	return nil
+}
+
+func newCreateSelectionHandler(ctx *gin.Context) *CreateSelection {
+	return &CreateSelection{
+		ctx:  ctx,
+		req:  http_model.NewCreateSelectionRequest(),
+		resp: http_model.NewCreateSelectionResponse(),
+	}
+}

+ 55 - 0
handler/selection_delete.go

@@ -0,0 +1,55 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/db"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/util"
+)
+
+func WrapDeleteSelectionHandler(ctx *gin.Context) {
+	handler := NewDeleteSelection(ctx)
+	BaseRun(handler)
+}
+
+type DeleteSelectionHandler struct {
+	ctx  *gin.Context
+	req  *http_model.DeleteSelectionRequest
+	resp *http_model.CommonResponse
+}
+
+func (d DeleteSelectionHandler) getContext() *gin.Context {
+	return d.ctx
+}
+
+func (d DeleteSelectionHandler) getResponse() interface{} {
+	return d.resp
+}
+
+func (d DeleteSelectionHandler) getRequest() interface{} {
+	return d.req
+}
+
+func (d DeleteSelectionHandler) run() {
+	err := db.DeleteSelection(d.ctx, d.req.SelectionId)
+	if err != nil {
+		logrus.WithContext(d.ctx).Errorf("[DeleteSelectionHandler] error DeleteSelection, err:%+v", err)
+		util.HandlerPackErrorResp(d.resp, consts.ErrorInternal, consts.DefaultToast)
+		return
+	}
+	d.resp.Message = "选品删除成功"
+}
+
+func (d DeleteSelectionHandler) checkParam() error {
+	return nil
+}
+
+func NewDeleteSelection(ctx *gin.Context) *DeleteSelectionHandler {
+	return &DeleteSelectionHandler{
+		ctx:  ctx,
+		req:  http_model.NewDeleteSelectionRequest(),
+		resp: http_model.NewDeleteSelectionResponse(),
+	}
+}

+ 58 - 0
handler/selection_detail.go

@@ -0,0 +1,58 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapSelectionDetailHandler(ctx *gin.Context) {
+	handler := newSelectionDetail(ctx)
+	BaseRun(handler)
+}
+
+type SelectionDetailHandler struct {
+	ctx  *gin.Context
+	req  *http_model.SelectionDetailRequest
+	resp *http_model.CommonResponse
+}
+
+func (s SelectionDetailHandler) getContext() *gin.Context {
+	return s.ctx
+}
+
+func (s SelectionDetailHandler) getResponse() interface{} {
+	return s.resp
+}
+
+func (s SelectionDetailHandler) getRequest() interface{} {
+	return s.req
+}
+
+func (s SelectionDetailHandler) run() {
+	//enterpriseID := middleware.GetSessionAuth(s.ctx).EnterpriseID
+	res, err := service.Selection.GetSelectionDetail(s.ctx, s.req.SelectionId, s.req.EnterpriseId)
+	if err != nil {
+		logrus.Errorf("[GetSelectionDetail] call Show err:%+v\n", err)
+		util.HandlerPackErrorResp(s.resp, consts.ErrorInternal, "")
+		logrus.Info("GetSelectionDetail fail,req:%+v", s.req)
+		return
+	}
+	s.resp.Message = "成功查询项目"
+	s.resp.Data = res
+}
+
+func (s SelectionDetailHandler) checkParam() error {
+	return nil
+}
+
+func newSelectionDetail(ctx *gin.Context) *SelectionDetailHandler {
+	return &SelectionDetailHandler{
+		ctx:  ctx,
+		req:  http_model.NewSelectionDetailRequest(),
+		resp: http_model.NewSelectionDetailResponse(),
+	}
+}

+ 68 - 0
handler/selection_find_all.go

@@ -0,0 +1,68 @@
+package handler
+
+import (
+	"errors"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/pack"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapFindAllSelectionHandler(ctx *gin.Context) {
+	handler := newFindAllSelection(ctx)
+	BaseRun(handler)
+}
+
+type FindAllSelectionHandler struct {
+	ctx  *gin.Context
+	req  *http_model.FindAllSelectionRequest
+	resp *http_model.CommonResponse
+}
+
+func (f FindAllSelectionHandler) getContext() *gin.Context {
+	return f.ctx
+}
+
+func (f FindAllSelectionHandler) getResponse() interface{} {
+	return f.resp
+}
+
+func (f FindAllSelectionHandler) getRequest() interface{} {
+	return f.req
+}
+
+func (f FindAllSelectionHandler) run() {
+	//enterpriseID := middleware.GetSessionAuth(f.ctx).EnterpriseID
+	condition := pack.HttpFindAllSelectionRequestToCondition(f.req)
+	data, err := service.Selection.GetAllSelection(f.ctx, f.req.EnterpriseId, f.req.PageSize, f.req.PageNum, condition)
+	if err != nil {
+		logrus.WithContext(f.ctx).Errorf("[FindAllSelectionHandler] error GetAllSelection, err:%+v", err)
+		util.HandlerPackErrorResp(f.resp, consts.ErrorInternal, consts.DefaultToast)
+		return
+	}
+	f.resp.Data = data
+}
+
+func (f FindAllSelectionHandler) checkParam() error {
+	var errs []error
+	if f.req.PageNum < 0 || f.req.PageSize <= 0 {
+		errs = append(errs, errors.New("page param error"))
+	}
+	f.req.PageNum--
+	if len(errs) != 0 {
+		return fmt.Errorf("check param errs:%+v", errs)
+	}
+	return nil
+}
+
+func newFindAllSelection(ctx *gin.Context) *FindAllSelectionHandler {
+	return &FindAllSelectionHandler{
+		ctx:  ctx,
+		req:  http_model.NewFindAllSelectionRequest(),
+		resp: http_model.NewFindAllSelectionResponse(),
+	}
+}

+ 61 - 0
handler/selection_pay.go

@@ -0,0 +1,61 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapPaySelectionHandler(ctx *gin.Context) {
+	handler := newPaySelectionHandler(ctx)
+	BaseRun(handler)
+}
+
+type PaySelection struct {
+	ctx  *gin.Context
+	req  *http_model.PaySelectionRequest
+	resp *http_model.CommonResponse
+}
+
+func (c PaySelection) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c PaySelection) getResponse() interface{} {
+	return c.resp
+}
+
+func (c PaySelection) getRequest() interface{} {
+	return c.req
+}
+
+func (c PaySelection) run() {
+	data := http_model.PaySelectionRequest{}
+	data = *c.req
+	//auth := middleware.GetSessionAuth(c.ctx)
+	//enterpriseID := auth.EnterpriseID
+	res, err := service.Selection.Pay(c.ctx, data, data.EnterpriseId)
+	if err != nil {
+		logrus.Errorf("[PaySelection] call PaySelection err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("PaySelection fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "支付成功"
+	c.resp.Data = res
+}
+
+func (c PaySelection) checkParam() error {
+	return nil
+}
+
+func newPaySelectionHandler(ctx *gin.Context) *PaySelection {
+	return &PaySelection{
+		ctx:  ctx,
+		req:  http_model.NewPaySelectionRequest(),
+		resp: http_model.NewPaySelectionResponse(),
+	}
+}

+ 59 - 0
handler/selection_review.go

@@ -0,0 +1,59 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapReviewSelectionHandler(ctx *gin.Context) {
+	handler := newReviewSelectionHandler(ctx)
+	BaseRun(handler)
+}
+
+type ReviewSelection struct {
+	ctx  *gin.Context
+	req  *http_model.ReviewSelectionRequest
+	resp *http_model.CommonResponse
+}
+
+func (c ReviewSelection) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c ReviewSelection) getResponse() interface{} {
+	return c.resp
+}
+
+func (c ReviewSelection) getRequest() interface{} {
+	return c.req
+}
+
+func (c ReviewSelection) run() {
+	data := http_model.ReviewSelectionRequest{}
+	data = *c.req
+	res, err := service.Selection.Review(c.ctx, data)
+	if err != nil {
+		logrus.Errorf("[ReviewSelection] call ReviewSelection err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("ReviewSelection fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功创建选品"
+	c.resp.Data = res
+}
+
+func (c ReviewSelection) checkParam() error {
+	return nil
+}
+
+func newReviewSelectionHandler(ctx *gin.Context) *ReviewSelection {
+	return &ReviewSelection{
+		ctx:  ctx,
+		req:  http_model.NewReviewSelectionRequest(),
+		resp: http_model.NewReviewSelectionResponse(),
+	}
+}

+ 59 - 0
handler/selection_update.go

@@ -0,0 +1,59 @@
+package handler
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_m_api/consts"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/service"
+	"youngee_m_api/util"
+)
+
+func WrapUpdateSelectionHandler(ctx *gin.Context) {
+	handler := newUpdateSelectionHandler(ctx)
+	BaseRun(handler)
+}
+
+type UpdateSelection struct {
+	ctx  *gin.Context
+	req  *http_model.UpdateSelectionRequest
+	resp *http_model.CommonResponse
+}
+
+func (c UpdateSelection) getContext() *gin.Context {
+	return c.ctx
+}
+
+func (c UpdateSelection) getResponse() interface{} {
+	return c.resp
+}
+
+func (c UpdateSelection) getRequest() interface{} {
+	return c.req
+}
+
+func (c UpdateSelection) run() {
+	data := http_model.UpdateSelectionRequest{}
+	data = *c.req
+	res, err := service.Selection.Update(c.ctx, data, data.EnterpriseId)
+	if err != nil {
+		logrus.Errorf("[UpdateSelection] call UpdateSelection err:%+v\n", err)
+		util.HandlerPackErrorResp(c.resp, consts.ErrorInternal, "")
+		logrus.Info("UpdateSelection fail,req:%+v", c.req)
+		return
+	}
+	c.resp.Message = "成功创建选品"
+	c.resp.Data = res
+}
+
+func (c UpdateSelection) checkParam() error {
+	return nil
+}
+
+func newUpdateSelectionHandler(ctx *gin.Context) *UpdateSelection {
+	return &UpdateSelection{
+		ctx:  ctx,
+		req:  http_model.NewUpdateSelectionRequest(),
+		resp: http_model.NewUpdateSelectionResponse(),
+	}
+}

+ 12 - 0
model/common_model/selection_condition.go

@@ -0,0 +1,12 @@
+package common_model
+
+type SelectionConditions struct {
+	SelectionStatus int8   `condition:"selection_status"` // 选品阶段
+	Platform        int8   `condition:"platform"`         // 社媒平台
+	SampleMode      int8   `condition:"sample_mode"`      // 领样形式
+	ContentType     int8   `condition:"content_type"`     // 内容形式
+	TaskMode        int8   `condition:"task_mode"`        // 任务形式
+	SearchValue     string `condition:"search_value"`     // 项目id或项目名称
+	SubmitAt        string `condition:"submit_at"`        // 提交审核时间
+	TaskDdl         string `condition:"task_ddl"`         // 任务截止时间
+}

+ 20 - 0
model/gorm_model/selection_brief_info.go

@@ -0,0 +1,20 @@
+package gorm_model
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+import (
+	"time"
+)
+
+type YounggeeSecBrief 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 *YounggeeSecBrief) TableName() string {
+	return "younggee_sec_brief"
+}

+ 20 - 0
model/gorm_model/selection_example_info.go

@@ -0,0 +1,20 @@
+package gorm_model
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+import (
+	"time"
+)
+
+type YounggeeSecExample 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 *YounggeeSecExample) TableName() string {
+	return "younggee_sec_example"
+}

+ 44 - 0
model/gorm_model/selection_task_info.go

@@ -0,0 +1,44 @@
+package gorm_model
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+import (
+	"time"
+)
+
+type YounggeeSecTaskInfo struct {
+	ID                     int       `gorm:"column:id;primary_key"`                        // 递增id
+	TaskID                 string    `gorm:"column:task_id"`                               // 选品任务id
+	SelectionID            string    `gorm:"column:selection_id"`                          // 选品id
+	TalentID               string    `gorm:"column:talent_id"`                             // 达人id
+	AccountID              int       `gorm:"column:account_id"`                            // 账号id
+	TalentPlatformInfoSnap string    `gorm:"column:talent_platform_info_snap"`             // 达人平台信息快照
+	TalentPersonalInfoSnap string    `gorm:"column:talent_personal_info_snap"`             // 达人个人信息快照
+	TalentPostAddrSnap     string    `gorm:"column:talent_post_addr_snap"`                 // 收货地址快照
+	TaskReward             string    `gorm:"column:task_reward"`                           //  达人赏金
+	TalentPayment          string    `gorm:"column:talent_payment"`                        // 达人垫付金额
+	IsPayPayment           int       `gorm:"column:is_pay_payment"`                        // 企业是否返样品钱
+	IsPayReward            int       `gorm:"column:is_pay_reward"`                         // 企业是否结算悬赏
+	TaskMode               int       `gorm:"column:task_mode"`                             // 任务形式,1、2分别表示纯佣带货、悬赏任务
+	SampleMode             int       `gorm:"column:sample_mode"`                           // 领样形式,1-3分别表示免费领样、垫付买样、不提供样品
+	TaskStatus             int       `gorm:"column:task_status;default:1"`                 // 任务状态 1待选 2已选 3落选
+	TaskStage              int       `gorm:"column:task_stage"`                            // 任务阶段,详情见info_sec_task_stage表
+	CreateDate             time.Time `gorm:"column:create_date;default:CURRENT_TIMESTAMP"` // 创建时间
+	SelectDate             time.Time `gorm:"column:select_date"`                           // 反选时间
+	DeliveryDate           time.Time `gorm:"column:delivery_date"`                         // 发货时间
+	CompleteDate           time.Time `gorm:"column:complete_date"`                         // 结束时间
+	WithdrawDate           time.Time `gorm:"column:withdraw_date"`                         // 提现时间
+	CompleteStatus         int       `gorm:"column:complete_status;default:1"`             // 结束方式 1未结束 2正常结束 3反选失败
+	LogisticsStatus        int       `gorm:"column:logistics_status;default:1"`            // 发货状态 1 待发货 2已发货 3 已签收
+	AssignmentStatus       uint      `gorm:"column:assignment_status;default:1"`           // 作业上传状态 1-5分别代表待添加、已添加、待修改、已修改、已通过
+	UpdateAt               time.Time `gorm:"column:update_at"`                             // 更新时间
+	WithdrawStatus         int       `gorm:"column:withdraw_status;default:1"`             // 提现状态,1-4分别代表不可提现、可提现、提现中、已提现
+	LeadTeamID             string    `gorm:"column:lead_team_id"`                          // 作为团长的young之团id,对应younggee_talent_team中的team_id字段
+	TeamID                 string    `gorm:"column:team_id"`                               // 作为团员的young之团id,对应younggee_talent_team中的team_id字段
+	TeamIncome             int       `gorm:"column:team_income"`                           // young之团团长现金收益
+	TeamPoint              int       `gorm:"column:team_point"`                            // young之团团长积分收益
+}
+
+func (m *YounggeeSecTaskInfo) TableName() string {
+	return "younggee_sec_task_info"
+}

+ 27 - 0
model/gorm_model/talent_income.go

@@ -0,0 +1,27 @@
+// Code generated by sql2gorm. DO NOT EDIT.
+package gorm_model
+
+import (
+	"time"
+)
+
+type YounggeeTalentIncome struct {
+	ID             int       `gorm:"column:id;primary_key"`  // 递增id
+	TalentID       string    `gorm:"column:talent_id"`       // 达人id,对应youngee_talent_info中id字段
+	ProjectID      string    `gorm:"column:project_id"`      // 项目id
+	SelectionID    string    `gorm:"column:selection_id"`    // 选品id
+	TaskID         string    `gorm:"column:task_id"`         // 任务id
+	SectaskID      string    `gorm:"column:sectask_id"`      // 选品任务id
+	BrandName      string    `gorm:"column:brand_name"`      // 品牌名称
+	TaskName       string    `gorm:"column:task_name"`       // 任务名称
+	TeamID         string    `gorm:"column:team_id"`         // young之团id
+	Income         string    `gorm:"column:income"`          // 收益金额
+	IncomeType     int       `gorm:"column:income_type"`     // 收益类型,1-4分别表示任务收益、开团收益、样品返现、悬赏收益
+	WithdrawStatus int       `gorm:"column:withdraw_status"` // 提现状态,1-3分别表示可提现、提现中、已提现
+	IncomeAt       time.Time `gorm:"column:income_at"`       // 收益产生时间
+	WithdrawAt     time.Time `gorm:"column:withdraw_at"`     // 提现时间
+}
+
+func (m *YounggeeTalentIncome) TableName() string {
+	return "younggee_talent_income"
+}

+ 24 - 0
model/http_model/CreateSecTaskLogisticsRequest.go

@@ -0,0 +1,24 @@
+package http_model
+
+type CreateSecTaskLogisticsRequest struct {
+	TaskID                string `json:"task_id"`                // 任务id
+	CompanyName           string `json:"company_name"`           // 实物商品-物流公司名称
+	LogisticsNumber       string `json:"logistics_number"`       // 实物商品-物流单号
+	ExplorestoreStarttime string `json:"explorestore_starttime"` // 线下探店-探店开始时间
+	ExplorestoreEndtime   string `json:"explorestore_endtime"`   // 线下探店-探店结束时间
+	ExplorestorePeriod    string `json:"explorestore_period"`    // 线下探店-探店持续时间
+	ThingsType            int    `json:"things_type"`            // 产品类型 1:实物, 3:线下探店
+}
+
+type CreateSecTaskLogisticsData struct {
+}
+
+func NewCreateSecTaskLogisticsRequest() *CreateSecTaskLogisticsRequest {
+	return new(CreateSecTaskLogisticsRequest)
+}
+
+func NewCreateSecTaskLogisticsResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(CreateSecTaskLogisticsData)
+	return resp
+}

+ 21 - 0
model/http_model/CreateSelectionRequest.go

@@ -0,0 +1,21 @@
+package http_model
+
+type CreateSelectionRequest struct {
+	EnterpriseId string `json:"enterprise_id"`
+	Platform     string `json:"platform"`
+	ProductId    string `json:"product_id"`
+}
+
+type CreateSelectionData struct {
+	SelectionId string `json:"selection_id"`
+}
+
+func NewCreateSelectionRequest() *CreateSelectionRequest {
+	return new(CreateSelectionRequest)
+}
+
+func NewCreateSelectionResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(CreateSelectionData)
+	return resp
+}

+ 13 - 0
model/http_model/DeleteSelectionRequest.go

@@ -0,0 +1,13 @@
+package http_model
+
+type DeleteSelectionRequest struct {
+	SelectionId string `json:"selection_id"`
+}
+
+func NewDeleteSelectionRequest() *DeleteSelectionRequest {
+	return new(DeleteSelectionRequest)
+}
+
+func NewDeleteSelectionResponse() *CommonResponse {
+	return new(CommonResponse)
+}

+ 32 - 0
model/http_model/FindAllSelectionRequest.go

@@ -0,0 +1,32 @@
+package http_model
+
+import "youngee_m_api/model/gorm_model"
+
+type FindAllSelectionRequest struct {
+	EnterpriseId    string `json:"enterprise_id"`
+	PageSize        int64  `json:"page_size"`
+	PageNum         int64  `json:"page_num"`
+	SelectionStatus int8   `json:"selection_status"` // 选品阶段
+	Platform        int8   `json:"platform"`         // 社媒平台
+	SampleMode      int8   `json:"sample_mode"`      // 领样形式
+	ContentType     int8   `json:"content_type"`     // 内容形式
+	TaskMode        int8   `json:"task_mode"`        // 任务形式
+	SearchValue     string `json:"search_value"`     // 项目id或项目名称
+	SubmitAt        string `json:"submit_at"`        // 提交审核时间
+	TaskDdl         string `json:"task_ddl"`         // 提交审核时间
+}
+
+type SelectionData struct {
+	SelectionInfo []*gorm_model.YounggeeSelectionInfo `json:"selection_info"`
+	Total         string                              `json:"total"`
+}
+
+func NewFindAllSelectionRequest() *FindAllSelectionRequest {
+	return new(FindAllSelectionRequest)
+}
+
+func NewFindAllSelectionResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(SelectionData)
+	return resp
+}

+ 38 - 0
model/http_model/GetSecTaskListRequest.go

@@ -0,0 +1,38 @@
+package http_model
+
+import (
+	"time"
+)
+
+type GetSecTaskListRequest struct {
+	PageSize      int64  `json:"page_size"`
+	PageNum       int64  `json:"page_num"`
+	SelectionId   string `json:"selection_id"`
+	SecTaskStatus int    `json:"sec_task_status"`
+	SearchValue   string `json:"search_value"`
+}
+
+type GetSecTaskListData struct {
+	SecTaskList []*SecTaskInfo `json:"sec_task_list"`
+	Total       string         `json:"total"`
+}
+
+type SecTaskInfo struct {
+	SelectionId        string    `json:"selection_id"`
+	PlatformNickname   string    `json:"platform_nickname"`                            // 帐号昵称
+	FansCount          string    `json:"fans_count"`                                   // 粉丝数
+	HomePageCaptureUrl string    `json:"home_page_capture_url"`                        // 主页截图链接
+	HomePageUrl        string    `json:"home_page_url"`                                // 主页链接
+	CreateDate         time.Time `json:"column:create_date;default:CURRENT_TIMESTAMP"` // 创建时间
+	SelectDate         time.Time `json:"column:select_date"`                           // 反选时间
+}
+
+func NewGetSecTaskListRequest() *GetSecTaskListRequest {
+	return new(GetSecTaskListRequest)
+}
+
+func NewGetSecTaskListResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(GetSecTaskListData)
+	return resp
+}

+ 19 - 0
model/http_model/PassSecTaskCoopRequest.go

@@ -0,0 +1,19 @@
+package http_model
+
+type PassSecTaskCoopRequest struct {
+	SelectionId string   `json:"selection_id"`
+	TaskIds     []string `json:"task_ids"`
+}
+
+type PassSecTaskCoopData struct {
+}
+
+func NewPassSecTaskCoopRequest() *PassSecTaskCoopRequest {
+	return new(PassSecTaskCoopRequest)
+}
+
+func NewPassSecTaskCoopResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(PassSecTaskCoopData)
+	return resp
+}

+ 21 - 0
model/http_model/PaySelectionRequest.go

@@ -0,0 +1,21 @@
+package http_model
+
+type PaySelectionRequest struct {
+	EnterpriseId string  `json:"enterprise_id"`
+	PayMoney     float64 `json:"pay_money"`
+	SelectionId  string  `json:"selection_id"`
+}
+
+type PaySelectionData struct {
+	SelectionId string `json:"selection_id"`
+}
+
+func NewPaySelectionRequest() *PaySelectionRequest {
+	return new(PaySelectionRequest)
+}
+
+func NewPaySelectionResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(PaySelectionData)
+	return resp
+}

+ 18 - 0
model/http_model/RefuseSecTaskCoopRequest.go

@@ -0,0 +1,18 @@
+package http_model
+
+type RefuseSecTaskCoopRequest struct {
+	TaskIds []string `json:"task_ids"`
+}
+
+type RefuseSecTaskCoopData struct {
+}
+
+func NewRefuseSecTaskCoopRequest() *RefuseSecTaskCoopRequest {
+	return new(RefuseSecTaskCoopRequest)
+}
+
+func NewRefuseSecTaskCoopResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(RefuseSecTaskCoopData)
+	return resp
+}

+ 21 - 0
model/http_model/ReviewSelectionRequest.go

@@ -0,0 +1,21 @@
+package http_model
+
+type ReviewSelectionRequest struct {
+	EnterpriseId string `json:"enterprise_id"`
+	SelectionId  string `json:"selection_id"`
+	IsPass       int    `json:"is_pass"`
+}
+
+type ReviewSelectionData struct {
+	SelectionId string `json:"selection_id"`
+}
+
+func NewReviewSelectionRequest() *ReviewSelectionRequest {
+	return new(ReviewSelectionRequest)
+}
+
+func NewReviewSelectionResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(ReviewSelectionData)
+	return resp
+}

+ 26 - 0
model/http_model/SelectionDetailRequest.go

@@ -0,0 +1,26 @@
+package http_model
+
+import "youngee_m_api/model/gorm_model"
+
+type SelectionDetailRequest struct {
+	EnterpriseId string `json:"enterprise_id"`
+	SelectionId  string `json:"selection_id"` // 选品id
+}
+
+type SelectionDetail struct {
+	SelectionInfo    *gorm_model.YounggeeSelectionInfo  // 选品详情
+	SelectionBrief   []*gorm_model.YounggeeSecBrief     // 选品brief列表
+	SelectionExample []*gorm_model.YounggeeSecExample   // 选品示例列表
+	ProductInfo      *gorm_model.YounggeeProduct        // 商品详情
+	ProductPhotoInfo []*gorm_model.YounggeeProductPhoto // 商品图片列表
+}
+
+func NewSelectionDetailRequest() *SelectionDetailRequest {
+	return new(SelectionDetailRequest)
+}
+
+func NewSelectionDetailResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(SelectionDetail)
+	return resp
+}

+ 23 - 0
model/http_model/SettleSecTaskRequest.go

@@ -0,0 +1,23 @@
+package http_model
+
+type SettleSecTaskRequest struct {
+	EnterpriseId  string `json:"enterprise_id"`
+	SelectionID   string `json:"selection_id"`    // 选品项目id
+	TaskID        string `json:"task_id"`         // 任务id
+	IsReturnMoney int    `json:"is_return_money"` //是否返回样品钱
+	IsPayReward   int    `json:"is_pay_reward"`   //是否给悬赏金
+	TotalPayMoney string `json:"total_pay_money"` //合计结算金额
+}
+
+type SettleSecTaskData struct {
+}
+
+func NewSettleSecTaskRequest() *SettleSecTaskRequest {
+	return new(SettleSecTaskRequest)
+}
+
+func NewSettleSecTaskResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(SettleSecTaskData)
+	return resp
+}

+ 25 - 0
model/http_model/UpdateSecTaskLogisticsRequest.go

@@ -0,0 +1,25 @@
+package http_model
+
+type UpdateSecTaskLogisticsRequest struct {
+	TaskID                string `json:"task_id"`                // 任务id
+	LogisticsId           int64  `json:"logistics_id"`           // 物流信息id
+	CompanyName           string `json:"company_name"`           // 实物商品-物流公司名称
+	LogisticsNumber       string `json:"logistics_number"`       // 实物商品-物流单号
+	ExplorestoreStarttime string `json:"explorestore_starttime"` // 线下探店-探店开始时间
+	ExplorestoreEndtime   string `json:"explorestore_endtime"`   // 线下探店-探店结束时间
+	ExplorestorePeriod    string `json:"explorestore_period"`    // 线下探店-探店持续时间
+	ThingsType            int    `json:"things_type"`            // 产品类型 1:实物, 3:线下探店
+}
+
+type UpdateSecTaskLogisticsData struct {
+}
+
+func NewUpdateSecTaskLogisticsRequest() *UpdateSecTaskLogisticsRequest {
+	return new(UpdateSecTaskLogisticsRequest)
+}
+
+func NewUpdateSecTaskLogisticsResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(UpdateSecTaskLogisticsData)
+	return resp
+}

+ 48 - 0
model/http_model/UpdateSelectionRequest.go

@@ -0,0 +1,48 @@
+package http_model
+
+type UpdateSelectionRequest struct {
+	EnterpriseId    string            `json:"enterprise_id"`
+	SelectionID     string            `json:"selection_id"` // 选品项目id
+	Platform        string            `json:"platform"`
+	ProductId       int               `json:"product_id"`
+	ContentType     int               `json:"content_type"`
+	TaskMode        int               `json:"task_mode"`
+	SampleNum       int               `json:"sample_num"`  // 样品数量
+	RemainNum       int               `json:"remain_num"`  // 剩余数量
+	TaskReward      float64           `json:"task_reward"` // 任务悬赏
+	TaskDdl         string            `json:"task_ddl"`
+	SampleMode      int               `json:"sample_mode"`
+	CommissionRate  int               `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"`
+}
+
+type SecBriefInfo struct {
+	FileUrl  string `json:"file_url"`
+	FileUid  string `json:"file_uid"`
+	FileName string `json:"file_name"`
+}
+
+type SecExampleInfo struct {
+	FileUrl  string `json:"file_url"`
+	FileUid  string `json:"file_uid"`
+	FileName string `json:"file_name"`
+}
+
+type UpdateSelectionData struct {
+	SelectionId string `json:"selection_id"`
+}
+
+func NewUpdateSelectionRequest() *UpdateSelectionRequest {
+	return new(UpdateSelectionRequest)
+}
+
+func NewUpdateSelectionResponse() *CommonResponse {
+	resp := new(CommonResponse)
+	resp.Data = new(UpdateSelectionData)
+	return resp
+}

+ 30 - 0
pack/sec_task_list.go

@@ -0,0 +1,30 @@
+package pack
+
+import (
+	"github.com/tidwall/gjson"
+	"youngee_m_api/model/gorm_model"
+	"youngee_m_api/model/http_model"
+
+	"github.com/caixw/lib.go/conv"
+)
+
+func GormSecTaskListToHttpSecTaskList(secTaskList []*gorm_model.YounggeeSecTaskInfo) []*http_model.SecTaskInfo {
+	var resTaskTaskList []*http_model.SecTaskInfo
+	for _, secTask := range secTaskList {
+		secTaskH := GormSecTaskToHttpSecTask(secTask)
+		resTaskTaskList = append(resTaskTaskList, secTaskH)
+	}
+	return resTaskTaskList
+}
+
+func GormSecTaskToHttpSecTask(secTask *gorm_model.YounggeeSecTaskInfo) *http_model.SecTaskInfo {
+	TalentPlatformInfoSnap := secTask.TalentPlatformInfoSnap
+	return &http_model.SecTaskInfo{
+		PlatformNickname:   conv.MustString(gjson.Get(TalentPlatformInfoSnap, "platform_nickname"), ""),
+		FansCount:          conv.MustString(gjson.Get(TalentPlatformInfoSnap, "fans_count"), ""),
+		HomePageCaptureUrl: conv.MustString(gjson.Get(TalentPlatformInfoSnap, "home_page_capture_url"), ""),
+		HomePageUrl:        conv.MustString(gjson.Get(TalentPlatformInfoSnap, "home_page_url"), ""),
+		CreateDate:         secTask.CreateDate,
+		SelectDate:         secTask.SelectDate,
+	}
+}

+ 60 - 0
pack/selection.go

@@ -0,0 +1,60 @@
+package pack
+
+import (
+	"youngee_m_api/model/common_model"
+	"youngee_m_api/model/gorm_model"
+	"youngee_m_api/model/http_model"
+)
+
+func HttpFindAllSelectionRequestToCondition(req *http_model.FindAllSelectionRequest) *common_model.SelectionConditions {
+	return &common_model.SelectionConditions{
+		SelectionStatus: req.SelectionStatus,
+		Platform:        req.Platform,
+		SampleMode:      req.SampleMode,
+		ContentType:     req.ContentType,
+		TaskMode:        req.TaskMode,
+		SearchValue:     req.SearchValue,
+		SubmitAt:        req.SubmitAt,
+		TaskDdl:         req.TaskDdl,
+	}
+}
+
+func MGormSelectionToHttpSelectionPreview(gormSelectionInfos []*gorm_model.YounggeeSelectionInfo) []*gorm_model.YounggeeSelectionInfo {
+	var httpSelectionPreviews []*gorm_model.YounggeeSelectionInfo
+	for _, gormSelectionInfo := range gormSelectionInfos {
+		gormSelectionInfo := GormSelectionToHttpSelectionPreview(gormSelectionInfo)
+		httpSelectionPreviews = append(httpSelectionPreviews, gormSelectionInfo)
+	}
+	return httpSelectionPreviews
+}
+
+func GormSelectionToHttpSelectionPreview(selectionInfo *gorm_model.YounggeeSelectionInfo) *gorm_model.YounggeeSelectionInfo {
+	return &gorm_model.YounggeeSelectionInfo{
+		SelectionID:      selectionInfo.SelectionID,
+		SelectionName:    selectionInfo.SelectionName,
+		EnterpriseID:     selectionInfo.EnterpriseID,
+		ProductID:        selectionInfo.ProductID,
+		ContentType:      selectionInfo.ContentType,
+		SelectionStatus:  selectionInfo.SelectionStatus,
+		Platform:         selectionInfo.Platform,
+		ProductUrl:       selectionInfo.ProductUrl,
+		RemainNum:        selectionInfo.RemainNum,
+		EstimatedCost:    selectionInfo.EstimatedCost,
+		TaskReward:       selectionInfo.TaskReward,
+		SampleCondition:  selectionInfo.SampleCondition,
+		RewardCondition:  selectionInfo.RewardCondition,
+		SettlementAmount: selectionInfo.SettlementAmount,
+		TaskDdl:          selectionInfo.TaskDdl,
+		Detail:           selectionInfo.Detail,
+		ProductSnap:      selectionInfo.ProductSnap,
+		ProductPhotoSnap: selectionInfo.ProductPhotoSnap,
+		CreatedAt:        selectionInfo.CreatedAt,
+		UpdatedAt:        selectionInfo.UpdatedAt,
+		SubmitAt:         selectionInfo.SubmitAt,
+		PassAt:           selectionInfo.PassAt,
+		FailReason:       selectionInfo.FailReason,
+		PayAt:            selectionInfo.PayAt,
+		FinishAt:         selectionInfo.FinishAt,
+		IsRead:           selectionInfo.IsRead,
+	}
+}

+ 14 - 2
route/init.go

@@ -191,7 +191,19 @@ func InitRoute(r *gin.Engine) {
 	s := r.Group("/youngee/m/selection")
 	{
 		s.Use(middleware.LoginAuthMiddleware)
-		s.GET("/reviewnumber", handler.WrapSelectionReviewNumberHandler) //查询选品待审核的数量
-
+		s.GET("/reviewnumber", handler.WrapSelectionReviewNumberHandler)            //查询选品待审核的数量
+		s.POST("/delete", handler.WrapDeleteSelectionHandler)                       //删除选品
+		s.POST("/findAll", handler.WrapFindAllSelectionHandler)                     //选品列表
+		s.POST("/detail", handler.WrapSelectionDetailHandler)                       //选品详情
+		s.POST("/create", handler.WrapCreateSelectionHandler)                       // 创建选品
+		s.POST("/update", handler.WrapUpdateSelectionHandler)                       // 更新选品
+		s.POST("/update", handler.WrapReviewSelectionHandler)                       // 选品审核通过
+		s.POST("/pay", handler.WrapPaySelectionHandler)                             // 支付选品项目
+		s.POST("/task/list", handler.WrapGetSecTaskListHandler)                     // 查询选品的任务列表
+		s.POST("/task/coop/pass", handler.WrapPassSecTaskCoopHandler)               // 同意任务合作
+		s.POST("/task/coop/refuse", handler.WrapRefuseSecTaskCoopHandler)           // 拒绝任务合作
+		s.POST("/task/logistics/create", handler.WrapCreateSecTaskLogisticsHandler) // 上传物流信息
+		s.POST("/task/logistics/update", handler.WrapUpdateSecTaskLogisticsHandler) // 修改物流信息
+		s.POST("/task/settle", handler.WrapSettleSecTaskHandler)                    // 结算
 	}
 }

+ 188 - 0
service/sec_task.go

@@ -0,0 +1,188 @@
+package service
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/issue9/conv"
+	"github.com/sirupsen/logrus"
+	"strconv"
+	"time"
+	"youngee_m_api/db"
+	"youngee_m_api/model/gorm_model"
+	"youngee_m_api/model/http_model"
+)
+
+var SelectionTask *selectionTask
+
+type selectionTask struct {
+}
+
+func (*selectionTask) GetList(ctx context.Context, request http_model.GetSecTaskListRequest) (*http_model.GetSecTaskListData, error) {
+	secTaskList, total, err := db.GetSecTaskList(ctx, request.SelectionId, request.SecTaskStatus, request.SearchValue, request.PageSize, request.PageNum)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetAllSelection error,err:%+v", err)
+		return nil, err
+	}
+
+	selectionListData := http_model.GetSecTaskListData{
+		Total:       conv.MustString(total, ""),
+		SecTaskList: secTaskList,
+	}
+
+	return &selectionListData, nil
+}
+
+func (*selectionTask) PassCoop(ctx context.Context, request http_model.PassSecTaskCoopRequest) (*http_model.PassSecTaskCoopData, error) {
+
+	_, err := db.PassSecTaskCoop(ctx, request.SelectionId, request.TaskIds)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call PassCoop error,err:%+v", err)
+		return nil, err
+	}
+
+	selectionListData := http_model.PassSecTaskCoopData{}
+
+	return &selectionListData, nil
+}
+
+func (*selectionTask) RefuseCoop(ctx context.Context, request http_model.RefuseSecTaskCoopRequest) (*http_model.RefuseSecTaskCoopData, error) {
+
+	_, err := db.RefuseSecTaskCoop(ctx, request.TaskIds)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call RefuseCoop error,err:%+v", err)
+		return nil, err
+	}
+
+	selectionListData := http_model.RefuseSecTaskCoopData{}
+
+	return &selectionListData, nil
+}
+
+func (*selectionTask) Settle(ctx context.Context, entersizeId string, request http_model.SettleSecTaskRequest) (*http_model.SettleSecTaskData, error) {
+	// 1. 解析request data
+	var returnMoney float64 = 0.0
+	var rewardMoney float64 = 0.0
+	payMoney, err := strconv.ParseFloat(request.TotalPayMoney, 64)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err)
+		return nil, err
+	}
+	// 2. 校验:任务是否正常(处于待结算阶段);企业账户可用余额是否充足;若返现则校验达人是否垫付买样;若有悬赏金额则校验是否为悬赏任务
+	// 1) 校验企业账户余额是否充足
+	entersize, err := db.GetEnterpriseByEnterpriseID(ctx, entersizeId)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetEnterpriseByEnterpriseID error,err:%+v", err)
+		return nil, err
+	}
+	if entersize.AvailableBalance < payMoney {
+		return nil, errors.New("账户余额不足")
+	}
+	// 2) 若返现则校验达人是否垫付买样;若有悬赏金额则校验是否为悬赏任务
+	selection, err := db.GetSelectionById(ctx, request.SelectionID)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSelectionById error,err:%+v", err)
+		return nil, err
+	}
+	if selection.SampleMode != 2 && request.IsReturnMoney == 1 {
+		return nil, errors.New("免费领养任务不能返样品钱")
+	}
+	if selection.TaskMode != 1 && request.IsPayReward == 1 {
+		return nil, errors.New("非悬赏任务不能支付悬赏")
+	}
+	// 3) 校验任务是否处于待结算阶段
+	secTask, err := db.GetSecTaskById(ctx, request.TaskID)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call GetSecTaskById error,err:%+v", err)
+		return nil, err
+	}
+	if secTask.TaskStage != 9 && secTask.TaskStatus != 2 {
+		return nil, errors.New("该任务暂不可结算")
+	}
+
+	var product gorm_model.YounggeeProduct
+	if err = json.Unmarshal([]byte(selection.ProductSnap), &product); err != nil {
+		fmt.Println("Error:", err)
+		return nil, err
+	}
+	// 4) 校验结算金额计算是否正确
+	if request.IsReturnMoney == 1 {
+		returnMoney = product.ProductPrice
+	}
+	if request.IsPayReward == 1 {
+		rewardMoney, err = strconv.ParseFloat(selection.TaskReward, 64)
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[sectask_service service] call strconv.ParseFloat() error,err:%+v", err)
+			return nil, err
+		}
+	}
+	if rewardMoney+returnMoney != payMoney {
+		return nil, errors.New("结算金额有误")
+	}
+	// 3. 扣除企业账户余额
+	_, err = db.UpdateEnterpriseBalance(ctx, entersizeId, 0, -payMoney, payMoney)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateEnterpriseBalance error,err:%+v", err)
+		return nil, err
+	}
+
+	// 4. 更新选品任务阶段
+	updateSecTaskData := gorm_model.YounggeeSecTaskInfo{
+		TaskID:           request.TaskID,
+		TaskStage:        10,
+		AssignmentStatus: 5,
+		CompleteDate:     time.Now(),
+	}
+	_, err = db.UpdateSecTask(ctx, updateSecTaskData)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask_service service] call UpdateSecTask error,err:%+v", err)
+		return nil, err
+	}
+	// 5. 添加任务日志和达人消息
+	// 6. 创建选品收益记录
+	// 返现收益
+	if request.IsReturnMoney == 1 {
+		income := gorm_model.YounggeeTalentIncome{
+			TalentID:       secTask.TalentID,
+			SelectionID:    secTask.SelectionID,
+			SectaskID:      secTask.TaskID,
+			BrandName:      product.BrandName,
+			TaskName:       selection.SelectionName,
+			Income:         strconv.FormatFloat(returnMoney, 'f', 10, 32),
+			IncomeType:     1,
+			WithdrawStatus: 1,
+			IncomeAt:       time.Now(),
+		}
+		err = db.CreateIncome(ctx, income, nil)
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err)
+			return nil, err
+		}
+	}
+	// 悬赏收益
+	if request.IsPayReward == 1 {
+		income := gorm_model.YounggeeTalentIncome{
+			TalentID:       secTask.TalentID,
+			SelectionID:    secTask.SelectionID,
+			SectaskID:      secTask.TaskID,
+			BrandName:      product.BrandName,
+			TaskName:       selection.SelectionName,
+			Income:         strconv.FormatFloat(rewardMoney, 'f', 10, 32),
+			IncomeType:     1,
+			WithdrawStatus: 1,
+			IncomeAt:       time.Now(),
+		}
+		err = db.CreateIncome(ctx, income, nil)
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[sectask_service service] call CreateIncome error,err:%+v", err)
+			return nil, err
+		}
+	}
+
+	// 7. 若有young之团存在,则为young之团创建收益
+
+	settleSecTaskData := http_model.SettleSecTaskData{}
+
+	return &settleSecTaskData, nil
+}

+ 106 - 0
service/sec_task_logistics.go

@@ -0,0 +1,106 @@
+package service
+
+import (
+	"context"
+	"github.com/sirupsen/logrus"
+	"time"
+	"youngee_m_api/db"
+	"youngee_m_api/model/gorm_model"
+	"youngee_m_api/model/http_model"
+)
+
+var SecLogistics *secLogistics
+
+type secLogistics struct {
+}
+
+func (*secLogistics) Create(ctx context.Context, request http_model.CreateSecTaskLogisticsRequest) (*http_model.CreateSecTaskLogisticsData, error) {
+	ThingsType := request.ThingsType
+	newLogistics := gorm_model.YoungeeTaskLogistics{
+		TaskID:                request.TaskID,
+		ThingsType:            int64(ThingsType),
+		ExplorestoreStarttime: time.Now(),
+		ExplorestoreEndtime:   time.Now(),
+		DeliveryTime:          time.Now(),
+	}
+	//实物
+	if ThingsType == 1 {
+		newLogistics.CompanyName = request.CompanyName
+		newLogistics.LogisticsNumber = request.LogisticsNumber
+		newLogistics.DeliveryTime = time.Now()
+	} else if ThingsType == 3 {
+		ExplorestoreStarttime, _ := time.ParseInLocation("2006-01-02 15:04:05", request.ExplorestoreStarttime, time.Local)
+		ExplorestoreEndtime, _ := time.ParseInLocation("2006-01-02 15:04:05", request.ExplorestoreEndtime, time.Local)
+		newLogistics.ExplorestoreStarttime = ExplorestoreStarttime
+		newLogistics.ExplorestoreEndtime = ExplorestoreEndtime
+	}
+
+	_, err := db.CreateSecTaskLogistics(ctx, newLogistics)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[newLogistics service] call CreatenewLogistics error,err:%+v", err)
+		return nil, err
+	}
+
+	// 修改task_info中发货时间、任务阶段
+	updatdSecTask := gorm_model.YounggeeSecTaskInfo{
+		TaskID:          request.TaskID,
+		LogisticsStatus: 2,
+		TaskStage:       7,
+		DeliveryDate:    time.Now(),
+	}
+	_, err = db.UpdateSecTask(ctx, updatdSecTask)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[sectask logistics service] call UpdateSecTask error,err:%+v", err)
+		return nil, err
+	}
+
+	// 记录任务日志-发货
+	err = db.CreateTaskLog(ctx, newLogistics.TaskID, "发货时间")
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[newLogistics service] call CreateTaskLog error,err:%+v", err)
+		return nil, err
+	}
+
+	err = db.CreateMessageByTaskId(ctx, 8, 2, newLogistics.TaskID)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[newLogistics service] call CreateMessageByTaskId error,err:%+v", err)
+		return nil, err
+	}
+
+	data := http_model.CreateSecTaskLogisticsData{}
+
+	return &data, nil
+}
+
+func (*secLogistics) Update(ctx context.Context, request http_model.UpdateSecTaskLogisticsRequest) (*http_model.UpdateSecTaskLogisticsData, error) {
+	ThingsType := request.ThingsType
+	newLogistics := gorm_model.YoungeeTaskLogistics{
+		LogisticsID:           request.LogisticsId,
+		TaskID:                request.TaskID,
+		ThingsType:            int64(ThingsType),
+		ExplorestoreStarttime: time.Now(),
+		ExplorestoreEndtime:   time.Now(),
+		DeliveryTime:          time.Now(),
+	}
+	//实物
+	if ThingsType == 1 {
+		newLogistics.CompanyName = request.CompanyName
+		newLogistics.LogisticsNumber = request.LogisticsNumber
+		newLogistics.DeliveryTime = time.Now()
+	} else if ThingsType == 3 {
+		ExplorestoreStarttime, _ := time.ParseInLocation("2006-01-02 15:04:05", request.ExplorestoreStarttime, time.Local)
+		ExplorestoreEndtime, _ := time.ParseInLocation("2006-01-02 15:04:05", request.ExplorestoreEndtime, time.Local)
+		newLogistics.ExplorestoreStarttime = ExplorestoreStarttime
+		newLogistics.ExplorestoreEndtime = ExplorestoreEndtime
+	}
+
+	_, err := db.UpdateSecTaskLogistics(ctx, newLogistics)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[newLogistics service] call UpdatenewLogistics error,err:%+v", err)
+		return nil, err
+	}
+
+	data := http_model.UpdateSecTaskLogisticsData{}
+
+	return &data, nil
+}

+ 288 - 0
service/selection.go

@@ -0,0 +1,288 @@
+package service
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"reflect"
+	"time"
+	"youngee_m_api/db"
+	"youngee_m_api/model/common_model"
+	"youngee_m_api/model/gorm_model"
+	"youngee_m_api/model/http_model"
+	"youngee_m_api/pack"
+	"youngee_m_api/util"
+
+	"github.com/caixw/lib.go/conv"
+)
+
+var Selection *selection
+
+type selection struct {
+}
+
+func (*selection) Create(ctx context.Context, request http_model.CreateSelectionRequest) (*http_model.CreateSelectionData, error) {
+	enterpriseId := request.EnterpriseId
+	// 1. 检查该企业id和商品id有无选品
+	//selectionInfo, err := db.GetSelectionByEnterpiseIdAndProductId(ctx, enterpriseId, conv.MustInt(request.ProductId, 0))
+	//if err != nil {
+	//	return nil, err
+	//}
+	//if selectionInfo != nil {
+	//	return nil, errors.New("该商品下选品已存在")
+	//}
+
+	// 2. 数据准备
+	// a) 生成选品id
+	selectionId := util.GetSelectionID()
+	// b) 查找关联商品信息
+	product, err := db.GetProductByID(ctx, conv.MustInt64(request.ProductId, 0))
+	if err != nil {
+		return nil, err
+	}
+	productPhotos, err := db.GetProductPhotoByProductID(ctx, conv.MustInt64(request.ProductId, 0))
+	productInfoToJson, _ := json.Marshal(product)
+	productPhotosToJson, _ := json.Marshal(productPhotos)
+	// c) 选品名称
+	selectionName := product.BrandName + "-" + product.ProductName
+
+	// 3. 创建选品
+	taskDdl := time.Time{} //赋零值
+	taskDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", "2026-01-01 08:00:00", time.Local)
+	newSelection := gorm_model.YounggeeSelectionInfo{
+		SelectionID:      selectionId,
+		SelectionName:    selectionName,
+		ProductID:        conv.MustInt(request.ProductId, 0),
+		EnterpriseID:     enterpriseId,
+		Platform:         conv.MustInt(request.Platform, 0),
+		ProductSnap:      string(productInfoToJson),
+		ProductPhotoSnap: string(productPhotosToJson),
+		CreatedAt:        time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
+		SubmitAt:         time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
+		PassAt:           time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
+		PayAt:            time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
+		FinishAt:         time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC),
+		TaskDdl:          taskDdl,
+		EstimatedCost:    "0",
+		TaskReward:       "0",
+		SettlementAmount: "0",
+	}
+	//Selection := gorm_model.YounggeeSelectionInfo{}
+	err = db.CreateSelection(ctx, newSelection)
+	if err != nil {
+		return nil, err
+	}
+
+	res := &http_model.CreateSelectionData{
+		SelectionId: selectionId,
+	}
+	return res, nil
+}
+
+func (*selection) Update(ctx context.Context, request http_model.UpdateSelectionRequest, enterpriseId string) (*http_model.UpdateSelectionData, error) {
+	// 1. 检查该企业id和商品id有无选品
+	selectionInfo, err := db.GetSelectionByEnterpiseIdAndProductId(ctx, enterpriseId, conv.MustInt(request.ProductId, 0))
+	if err != nil {
+		return nil, err
+	}
+	if selectionInfo == nil {
+		return nil, errors.New("选品不存在")
+	}
+
+	// 2. 数据准备
+	// a) 查找关联商品信息
+	product, err := db.GetProductByID(ctx, conv.MustInt64(request.ProductId, 0))
+	if err != nil {
+		return nil, err
+	}
+	productPhotos, err := db.GetProductPhotoByProductID(ctx, conv.MustInt64(request.ProductId, 0))
+	productInfoToJson, _ := json.Marshal(product)
+	productPhotosToJson, _ := json.Marshal(productPhotos)
+	// b) 选品名称
+	selectionName := product.BrandName + "-" + product.ProductName
+	// c) 计算预估成本(如果有)
+	var estimatedCost float64
+	if conv.MustInt(request.TaskMode, 0) == 1 {
+		estimatedCost = conv.MustFloat64(request.TaskReward, 0) * conv.MustFloat64(request.SampleNum, 0)
+	}
+	estimatedCostToString, _ := conv.String(estimatedCost)
+	// d) 任务截止时间
+	taskDdl := time.Time{} //赋零值
+
+	taskDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", request.TaskDdl, time.Local)
+
+	updateSelection := gorm_model.YounggeeSelectionInfo{
+		SelectionID:      request.SelectionID,
+		SelectionName:    selectionName,
+		EnterpriseID:     enterpriseId,
+		ProductID:        conv.MustInt(request.ProductId, 0),
+		ContentType:      conv.MustInt(request.ContentType, 0),
+		SelectionStatus:  1,
+		TaskMode:         conv.MustInt(request.TaskMode, 0),
+		Platform:         conv.MustInt(request.Platform, 0),
+		SampleMode:       conv.MustInt(request.SampleMode, 0),
+		ProductUrl:       request.ProductUrl,
+		SampleNum:        conv.MustInt(request.SampleNum, 0),
+		RemainNum:        conv.MustInt(request.SampleNum, 0),
+		CommissionRate:   conv.MustInt(request.CommissionRate, 0),
+		EstimatedCost:    estimatedCostToString,
+		SampleCondition:  request.SampleCondition,
+		RewardCondition:  request.RewardCondition,
+		TaskDdl:          taskDdl,
+		Detail:           request.Detail,
+		ProductSnap:      string(productInfoToJson),
+		ProductPhotoSnap: string(productPhotosToJson),
+		CreatedAt:        selectionInfo.CreatedAt,
+		UpdatedAt:        time.Now(),
+		SubmitAt:         time.Now(),
+	}
+	// 合并传入参数和数据表中原记录,若传入参数字段值为空,则将字段赋值为原记录中值
+	result := util.MergeStructValue(&updateSelection, &selectionInfo)
+	// 利用反射机制将interface类型转换为结构体类型
+	v := reflect.ValueOf(result).Elem()
+	if v.Kind() == reflect.Struct {
+		updateSelection = v.Interface().(gorm_model.YounggeeSelectionInfo)
+		//fmt.Println(p)
+	}
+
+	// 3. 更新选品
+	err = db.UpdateSelection(ctx, updateSelection)
+	if err != nil {
+		return nil, err
+	}
+
+	res := &http_model.UpdateSelectionData{
+		SelectionId: updateSelection.SelectionID,
+	}
+	return res, nil
+}
+
+func (*selection) Pay(ctx context.Context, request http_model.PaySelectionRequest, enterpriseId string) (*http_model.PaySelectionData, error) {
+	// 校验
+	// 1. 账户余额是否足够
+	enterprise, err := db.GetEnterpriseByEnterpriseID(ctx, enterpriseId)
+	if err != nil {
+		return nil, err
+	}
+	if enterprise.AvailableBalance < request.PayMoney {
+		return nil, errors.New("账户余额不足")
+	}
+	// 2. 选品项目状态是否正确
+	selectionInfo, err := db.GetSelectionById(ctx, request.SelectionId)
+	if err != nil {
+		return nil, err
+	}
+	if selectionInfo == nil {
+		return nil, errors.New("选品不存在")
+	}
+	if selectionInfo.SelectionStatus != 4 {
+		return nil, errors.New("选品状态有误")
+	}
+
+	// 支付
+	err = db.PaySelection(ctx, enterpriseId, request.PayMoney, request.SelectionId)
+	if err != nil {
+		return nil, err
+	}
+
+	res := &http_model.PaySelectionData{
+		SelectionId: request.SelectionId,
+	}
+	return res, nil
+}
+
+func (s *selection) GetAllSelection(ctx context.Context, enterpriseID string, pageSize, pageNum int64, conditions *common_model.SelectionConditions) (*http_model.SelectionData, error) {
+	SelectionList, total, err := db.GetSelectionList(ctx, enterpriseID, pageSize, pageNum, conditions)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetAllSelection error,err:%+v", err)
+		return nil, err
+	}
+	SelectionListData := new(http_model.SelectionData)
+	SelectionListData.SelectionInfo = pack.MGormSelectionToHttpSelectionPreview(SelectionList)
+	SelectionListData.Total = conv.MustString(total, "")
+	return SelectionListData, nil
+}
+
+func (s *selection) GetSelectionDetail(ctx *gin.Context, selectionId string, enterpriseId 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 (*selection) Review(ctx context.Context, request http_model.ReviewSelectionRequest) (*http_model.ReviewSelectionData, error) {
+	// 根据选品id查询选品信息
+	selectionInfo, err := db.GetSelectionById(ctx, request.SelectionId)
+	if err != nil {
+		logrus.WithContext(ctx).Errorf("[selectionDB service] call GetSelectionById error,err:%+v", err)
+		return nil, err
+	}
+
+	// 计算预估成本
+	var estimatedCost float64 = 0.0
+	var estimatedCostToString string = ""
+	if conv.MustInt(selectionInfo.TaskMode, 0) == 1 {
+		estimatedCost = conv.MustFloat64(selectionInfo.TaskReward, 0) * conv.MustFloat64(selectionInfo.SampleNum, 0)
+		estimatedCostToString, _ = conv.String(estimatedCost)
+	}
+
+	// 若审核通过则更新选品阶段为待支付,否则更新为失效并赋值失效原因
+	if request.IsPass == 1 {
+		updateSelection := gorm_model.YounggeeSelectionInfo{
+			SelectionID:     request.SelectionId,
+			SelectionStatus: 4,
+			PassAt:          time.Now(),
+			EstimatedCost:   estimatedCostToString,
+		}
+		err = db.UpdateSelection(ctx, updateSelection)
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[selectionDB service] call UpdateSelection error,err:%+v", err)
+			return nil, err
+		}
+	} else {
+		updateSelection := gorm_model.YounggeeSelectionInfo{
+			SelectionID:     request.SelectionId,
+			SelectionStatus: 7,
+			FailReason:      2,
+			PassAt:          time.Now(),
+			EstimatedCost:   estimatedCostToString,
+		}
+		err = db.UpdateSelection(ctx, updateSelection)
+		if err != nil {
+			logrus.WithContext(ctx).Errorf("[selectionDB service] call UpdateSelection error,err:%+v", err)
+			return nil, err
+		}
+	}
+	res := &http_model.ReviewSelectionData{}
+	return res, nil
+}

+ 22 - 0
util/structFunc.go

@@ -0,0 +1,22 @@
+package util
+
+import "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() {
+			v1.FieldByName(name).Set(v2.FieldByName(name))
+		}
+	}
+
+	return v1
+}

+ 38 - 0
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
+}