فهرست منبع

Merge branch 'refs/heads/develop' into develop-ljl

# Conflicts:
#	model/gorm_model/info_auto_task.go
#	model/gorm_model/project.go
#	model/gorm_model/project_task.go
lin-jim-leon 7 ماه پیش
والد
کامیت
9b434f3214
69فایلهای تغییر یافته به همراه3334 افزوده شده و 166 حذف شده
  1. 28 0
      app/consts/error_code.go
  2. 27 0
      app/consts/invoice_enums.go
  3. 20 0
      app/consts/platform_icon.go
  4. 95 0
      app/consts/project_enums.go
  5. 6 0
      app/consts/session.go
  6. 90 0
      app/controller/cooperation_controller.go
  7. 182 15
      app/controller/finance_controller.go
  8. 37 1
      app/controller/task_controller.go
  9. 27 1
      app/dao/enterprise_dao.go
  10. 68 0
      app/dao/enterprise_supplier_cooperate_dao.go
  11. 49 0
      app/dao/invoice_info_dao.go
  12. 120 0
      app/dao/invoice_record_dao.go
  13. 43 1
      app/dao/project_dao.go
  14. 90 1
      app/dao/recharge_record_dao.go
  15. 71 0
      app/dao/s_project_dao.go
  16. 39 2
      app/dao/selection_info_dao.go
  17. 46 0
      app/dao/supplier_dao.go
  18. 24 0
      app/entity/enterprise_supplier_cooperate.go
  19. 19 0
      app/entity/invoice_address.go
  20. 24 0
      app/entity/invoice_info.go
  21. 33 0
      app/entity/invoice_record.go
  22. 2 0
      app/entity/project.go
  23. 6 3
      app/entity/recharge_record.go
  24. 2 0
      app/entity/recruit_strategy.go
  25. 27 0
      app/entity/s_project.go
  26. 2 0
      app/entity/selection_info.go
  27. 20 0
      app/entity/supplier.go
  28. 2 2
      app/schedule/auto_task1.go
  29. 55 0
      app/schedule/auto_task2.go
  30. 324 0
      app/service/cooperation_service.go
  31. 8 8
      app/service/default_service.go
  32. 305 0
      app/service/invoice_service.go
  33. 20 14
      app/service/project_service.go
  34. 272 16
      app/service/recharge_service.go
  35. 1 0
      app/service/selection_info_service.go
  36. 8 2
      app/util/uuid.go
  37. 8 0
      app/vo/balance_param.go
  38. 25 0
      app/vo/invoice_bill_param.go
  39. 14 0
      app/vo/invoice_default_param.go
  40. 11 6
      app/vo/pay_wx_param.go
  41. 1 1
      app/vo/project_update_param.go
  42. 7 0
      app/vo/re_balance_show.go
  43. 13 0
      app/vo/re_billable_info.go
  44. 17 0
      app/vo/re_frozen_info.go
  45. 11 0
      app/vo/re_invoice_info.go
  46. 14 0
      app/vo/re_invoice_record.go
  47. 1 0
      app/vo/re_project_task_preview.go
  48. 13 0
      app/vo/re_recharge_info.go
  49. 6 0
      app/vo/re_recharge_show.go
  50. 11 0
      app/vo/re_supplier_confirming_info.go
  51. 13 0
      app/vo/re_supplier_pool_info.go
  52. 12 0
      app/vo/re_supplier_preview.go
  53. 13 0
      app/vo/re_supplier_target_task.go
  54. 9 0
      app/vo/recharge_param.go
  55. 43 0
      app/vo/supplier_search_param.go
  56. 24 5
      config/pro.yaml
  57. 2 2
      consts/invoice.go
  58. 12 0
      db/auto_default.go
  59. 724 0
      db/auto_task.go
  60. 2 24
      go.mod
  61. 14 5
      main.go
  62. 2 1
      model/gorm_model/info_auto_task.go
  63. 0 1
      model/gorm_model/project.go
  64. 1 0
      model/gorm_model/project_task.go
  65. 21 24
      model/gorm_model/recruit_strategy.go
  66. 0 2
      model/gorm_model/sketch.go
  67. 35 15
      route/init.go
  68. 62 14
      service/autoTask.go
  69. 1 0
      service/logistics.go

+ 28 - 0
app/consts/error_code.go

@@ -0,0 +1,28 @@
+package consts
+
+import "github.com/go-redis/redis/v8"
+
+var RedisNil = redis.Nil
+var errorCodeToastMap = map[int32]string{}
+
+const DefaultToast = ""
+
+const ErrorSuccess int32 = 0
+const ErrorNotLogin int32 = 4001
+const ErrorParamCheck int32 = 5001
+const ErrorInternal int32 = 5001
+
+func init() {
+	errorCodeToastMap[ErrorSuccess] = "请求成功"
+	errorCodeToastMap[ErrorNotLogin] = "请登录后操作"
+	errorCodeToastMap[ErrorParamCheck] = "参数有误"
+	errorCodeToastMap[ErrorInternal] = "网络错误"
+}
+
+func GetErrorToast(errorCode int32) string {
+	toast, contain := errorCodeToastMap[errorCode]
+	if contain {
+		return toast
+	}
+	return "网络错误,请稍后再试"
+}

+ 27 - 0
app/consts/invoice_enums.go

@@ -0,0 +1,27 @@
+package consts
+
+var HeadTypeMap = map[int64]string{
+	1: "企业",
+	2: "个人",
+}
+
+func GetHeadType(HeadType int64) string {
+	toast, contain := HeadTypeMap[HeadType]
+	if contain {
+		return toast
+	}
+	return "未知"
+}
+
+var InvoiceTypeMap = map[int64]string{
+	1: "数电普票",
+	2: "数电专票",
+}
+
+func GetInvoiceType(InvoiceType int64) string {
+	toast, contain := InvoiceTypeMap[InvoiceType]
+	if contain {
+		return toast
+	}
+	return "未知"
+}

+ 20 - 0
app/consts/platform_icon.go

@@ -0,0 +1,20 @@
+package consts
+
+var platformIconMap = map[int]string{
+	0: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/platformlogo/redbook.png",
+	1: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/platformlogo/redbook.png",
+	2: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/pingtai2.png",
+	3: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/lQLPDhrXwll1_OojIrB54K2_gW0cQQGOvh1TQE8B_34_35.png",
+	4: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/lQLPDhrXwll1_NcjI7AD0T3viYtxQwGOvh1SwG0A_35_35.png",
+	5: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/lQLPDhrXwll1_N8lJbAnowYY8vg2EwGOvh1MQAcA_37_37.png",
+	6: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/lQLPDhrXwll1_NomJrBzk2H1dD_6NwGOvh1TQE8A_38_38.png",
+	7: "https://horastar.obs.cn-east-3.myhuaweicloud.com/talent/lQLPDhrXwll1_OglJrDwCzIdgTtsKQGOvh1TAG0A_38_37.png",
+}
+
+func GetPaltformIcon(platformId int) string {
+	icon, contain := platformIconMap[platformId]
+	if contain {
+		return icon
+	}
+	return ""
+}

+ 95 - 0
app/consts/project_enums.go

@@ -0,0 +1,95 @@
+package consts
+
+var projectStatusMap = map[int64]string{
+	1:  "创建中",
+	2:  "待审核",
+	3:  "审核通过",
+	4:  "招募中",
+	5:  "招募完毕",
+	6:  "待支付",
+	7:  "已支付",
+	8:  "失效",
+	9:  "执行中",
+	10: "已结案",
+}
+
+func GetProjectStatus(status int64) string {
+	toast, contain := projectStatusMap[status]
+	if contain {
+		return toast
+	}
+	return "未知"
+}
+
+var ProjectPlatformMap = map[int64]string{
+	1: "红book",
+	2: "抖音",
+	3: "微博",
+	4: "快手",
+	5: "b站",
+	6: "大众点评",
+	7: "知乎",
+}
+
+func GetProjectPlatform(status int64) string {
+	toast, contain := ProjectPlatformMap[status]
+	if contain {
+		return toast
+	}
+	return "未知"
+}
+
+var ProjectFormMap = map[int64]string{
+	1: "实体商品寄拍",
+	2: "虚拟产品测评",
+	3: "线下探店打卡",
+	4: "素材微原创",
+}
+
+func GetProjectForm(status int64) string {
+	toast, contain := ProjectFormMap[status]
+	if contain {
+		return toast
+	}
+	return "未知"
+}
+
+var ProjectContentTypeMap = map[int64]string{
+	1: "图文",
+	2: "视频",
+}
+
+func GetProjectContentType(status int64) string {
+	toast, contain := ProjectContentTypeMap[status]
+	if contain {
+		return toast
+	}
+	return "未知"
+}
+
+var ProjectTypeMap = map[int64]string{
+	1: "全流程项目",
+	2: "专项执行项目",
+}
+
+func GetProjectType(projectType int64) string {
+	toast, contain := ProjectTypeMap[projectType]
+	if contain {
+		return toast
+	}
+	return "未知"
+}
+
+var RechargeMethod = map[int64]string{
+	1: "对公转账",
+	2: "支付宝",
+	3: "微信",
+}
+
+func GetRechargeMethod(method int64) string {
+	toast, contain := RechargeMethod[method]
+	if contain {
+		return toast
+	}
+	return "未知"
+}

+ 6 - 0
app/consts/session.go

@@ -0,0 +1,6 @@
+package consts
+
+const SessionAuthSchema = "session_auth"
+const SessionRedisPrefix = "b_user:"
+const AuthSalt = "fa2tg4y"
+const BRole = "3"

+ 90 - 0
app/controller/cooperation_controller.go

@@ -0,0 +1,90 @@
+package controller
+
+import (
+	"github.com/gin-gonic/gin"
+	"github.com/sirupsen/logrus"
+	"youngee_b_api/app/service"
+	"youngee_b_api/app/vo"
+)
+
+type CooperationController struct{}
+
+// 服务商端链接
+func (o CooperationController) GetSupplierLink(c *gin.Context) {
+	supplierLink := "服务商端链接"
+	resultMap := make(map[string]string)
+	resultMap["supplierLink"] = supplierLink
+	returnSuccess(c, 20000, resultMap)
+}
+
+// 服务商搜索
+func (o CooperationController) SearchSupplier(c *gin.Context) {
+	param := &vo.SupplierSearchParam{}
+	err := c.BindJSON(param)
+	if err != nil || "" == param.FieldName {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	reSupplierPreviews, err := service.CooperationService{}.SearchSupplier(param)
+	if err != nil {
+		logrus.Errorf("[SearchSupplier] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, reSupplierPreviews)
+}
+
+// 服务商入库批量邀请
+func (o CooperationController) InviteSupplier(c *gin.Context) {
+	param := &vo.SupplierInviteParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	err1 := service.CooperationService{}.InviteSupplier(param)
+	if err1 != nil {
+		logrus.Errorf("[InviteSupplier] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, nil)
+}
+
+// 在库服务商列表
+func (o CooperationController) GetEnterprisePoolList(c *gin.Context) {
+	param := &vo.SupplierSearchInPoolParam{}
+	err := c.BindJSON(param)
+	if err != nil || "" == param.EnterpriseId {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err1 := service.CooperationService{}.GetEnterprisePoolList(param)
+	if err1 != nil {
+		logrus.Errorf("[GetEnterprisePoolList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, result)
+}
+
+// 服务商邀请待确认列表
+func (o CooperationController) GetSupplierConfirmingList(c *gin.Context) {
+	param := &vo.SupplierConfirmingParam{}
+	err := c.BindJSON(param)
+	if err != nil || "" == param.EnterpriseId {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err1 := service.CooperationService{}.GetSupplierConfirmingList(param)
+	if err1 != nil {
+		logrus.Errorf("[GetSupplierConfirmingList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, result)
+}

+ 182 - 15
app/controller/finance_controller.go

@@ -1,7 +1,6 @@
 package controller
 
 import (
-	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/sirupsen/logrus"
 	"youngee_b_api/app/service"
@@ -12,7 +11,7 @@ import (
 type FinanceController struct{}
 
 // 充值管理——对公转账
-func (t FinanceController) TransferToPublic(c *gin.Context) {
+func (f FinanceController) TransferToPublic(c *gin.Context) {
 	param := &vo.RechargeTransferParam{}
 	err := c.BindJSON(param)
 	if err != nil {
@@ -32,7 +31,7 @@ func (t FinanceController) TransferToPublic(c *gin.Context) {
 }
 
 // 获取微信支付CodeUrl
-func (t FinanceController) GetCodeUrl(c *gin.Context) {
+func (f FinanceController) GetCodeUrl(c *gin.Context) {
 	param := &vo.GetCodeUrlParam{}
 	err := c.BindJSON(param)
 	if err != nil {
@@ -40,23 +39,23 @@ func (t FinanceController) GetCodeUrl(c *gin.Context) {
 		returnError(c, 40000, "参数错误")
 		return
 	}
-	tradeId := util.GetRandomString(32)
-	fmt.Println("amount:", param.Amount)
-	codeUrl, err := service.RechargeService{}.NativeApiServicePrepay(tradeId, param.Amount)
+	tradeId := util.GenerateDateRelatedUUID(16)
+	codeUrl, timeExpire, err := service.RechargeService{}.NativeApiServicePrepay(param.EnterpriseId, param.SubAccountId, tradeId, param.Amount)
 	if err != nil {
 		logrus.Errorf("[GetCodeUrl] call Show err:%+v\n", err)
-		returnError(c, 40000, "error")
+		returnError(c, 40000, err.Error())
 		return
 	}
-	reCodeUrl := new(vo.ReCodeUrl)
-	reCodeUrl.CodeUrl = codeUrl
-	reCodeUrl.TradeId = tradeId
-
+	reCodeUrl := vo.ReCodeUrl{
+		CodeUrl:    codeUrl,
+		TradeId:    tradeId,
+		TimeExpire: timeExpire.Format("2006-01-02 15:04:05"),
+	}
 	returnSuccess(c, 20000, reCodeUrl)
 }
 
 // 根据交易id查询微信是否扫码付款
-func (t FinanceController) QueryOrderByTradeId(c *gin.Context) {
+func (f FinanceController) QueryOrderByTradeId(c *gin.Context) {
 	param := &vo.QueryOrderByTradeIdParam{}
 	err := c.BindJSON(param)
 	if err != nil {
@@ -64,11 +63,179 @@ func (t FinanceController) QueryOrderByTradeId(c *gin.Context) {
 		returnError(c, 40000, "参数错误")
 		return
 	}
-	tradeState, err := service.RechargeService{}.QueryOrderByTradeId(param.TradeId)
+	tradeState, err := service.RechargeService{}.QueryOrderByTradeId(param.EnterpriseId, param.SubAccountId, param.TradeId)
 	if err != nil {
 		logrus.Errorf("[QueryOrderByTradeId] call Show err:%+v\n", err)
-		returnError(c, 40000, "error")
+		returnError(c, 40000, err.Error())
+		return
+	}
+	resultMap := make(map[string]string)
+	resultMap["tradeState"] = tradeState
+	returnSuccess(c, 20000, resultMap)
+}
+
+// 余额管理——总金额、可用余额、冻结金额
+func (f FinanceController) ShowBalance(c *gin.Context) {
+	param := &vo.BalanceParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	reBalanceShow, err := service.RechargeService{}.ShowBalance(param)
+	if err != nil {
+		logrus.Errorf("[ShowBalance] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, reBalanceShow)
+}
+
+// 余额管理——冻结记录
+func (f FinanceController) FrozenInfoList(c *gin.Context) {
+	param := &vo.BalanceParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err := service.RechargeService{}.FrozenInfoList(param)
+	if err != nil {
+		logrus.Errorf("[FrozenInfoList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, result)
+}
+
+// 充值管理——累计充值金额、确认中金额
+func (f FinanceController) ShowRecharge(c *gin.Context) {
+	param := &vo.RechargeParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	reRechargeShow, err := service.RechargeService{}.ShowRecharge(param)
+	if err != nil {
+		logrus.Errorf("[ShowRecharge] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, reRechargeShow)
+}
+
+// 充值管理——充值记录
+func (f FinanceController) RechargeInfoList(c *gin.Context) {
+	param := &vo.RechargeParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err := service.RechargeService{}.RechargeInfoList(param)
+	if err != nil {
+		logrus.Errorf("[RechargeInfoList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, result)
+}
+
+// 设置默认开票抬头
+func (f FinanceController) UpdateInvoiceDefault(c *gin.Context) {
+	param := &vo.InvoiceDefaultParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	invoiceId, err := service.InvoiceService{}.UpdateInvoiceDefault(param)
+	if err != nil {
+		logrus.Errorf("[UpdateInvoiceDefault] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	resultMap := make(map[string]int64)
+	resultMap["invoiceId"] = *invoiceId
+	returnSuccess(c, 20000, resultMap)
+}
+
+// 获取默认开票抬头
+func (f FinanceController) GetInvoiceDefault(c *gin.Context) {
+	param := &vo.InvoiceDefaultParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	reInvoiceInfo, err := service.InvoiceService{}.GetInvoiceDefault(param)
+	if err != nil {
+		logrus.Errorf("[GetInvoiceDefault] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, reInvoiceInfo)
+}
+
+// 确认开票
+func (f FinanceController) BillInvoice(c *gin.Context) {
+	param := &vo.InvoiceBillParam{}
+	err := c.BindJSON(param)
+	if err != nil || len(param.TaskIds) != 3 {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	billingId, err := service.InvoiceService{}.BillInvoice(param)
+	if err != nil {
+		logrus.Errorf("[BillInvoice] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	resultMap := make(map[string]string)
+	resultMap["billingId"] = *billingId
+	returnSuccess(c, 20000, resultMap)
+}
+
+// 开票记录
+func (f FinanceController) GetBillList(c *gin.Context) {
+	param := &vo.InvoiceBillListParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err := service.InvoiceService{}.GetBillList(param)
+	if err != nil {
+		logrus.Errorf("[GetBillList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, result)
+}
+
+// 可开票账单
+func (f FinanceController) GetBillableList(c *gin.Context) {
+	param := &vo.InvoiceBillListParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err := service.InvoiceService{}.GetBillableList(param)
+	if err != nil {
+		logrus.Errorf("[GetBillableList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
 		return
 	}
-	returnSuccess(c, 20000, tradeState)
+	returnSuccess(c, 20000, result)
 }

+ 37 - 1
app/controller/task_controller.go

@@ -332,7 +332,7 @@ func (t TaskController) ProjectToReview(c *gin.Context) {
 	returnSuccess(c, 20000, resultMap)
 }
 
-// 公开种草任务列表
+// 种草任务列表
 func (t TaskController) ProjectTaskList(c *gin.Context) {
 	param := &vo.ProjectSearchParam{}
 	err := c.BindJSON(param)
@@ -524,3 +524,39 @@ func (t TaskController) CancelTalentList(c *gin.Context) {
 	resultMap["taskIds"] = param.TaskIds
 	returnSuccess(c, 20000, resultMap)
 }
+
+// 服务商合作-服务商列表
+func (o TaskController) GetSupplierInTargetTaskList(c *gin.Context) {
+	param := &vo.SupplierSearchInTargetTaskParam{}
+	err := c.BindJSON(param)
+	if err != nil || "" == param.EnterpriseId {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	result, err1 := service.CooperationService{}.GetSupplierInTargetTaskList(param)
+	if err1 != nil {
+		logrus.Errorf("[GetSuplierList] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, result)
+}
+
+// 服务商合作-邀约合作
+func (o TaskController) InviteSupplier(c *gin.Context) {
+	param := &vo.SupplierInviteInTargetTaskParam{}
+	err := c.BindJSON(param)
+	if err != nil {
+		logrus.Errorf("Request bind err:%+v\n", err)
+		returnError(c, 40000, "参数错误")
+		return
+	}
+	err1 := service.CooperationService{}.InviteSupplierInTargetTask(param)
+	if err1 != nil {
+		logrus.Errorf("[InviteSupplier] call Show err:%+v\n", err)
+		returnError(c, 40000, err.Error())
+		return
+	}
+	returnSuccess(c, 20000, nil)
+}

+ 27 - 1
app/dao/enterprise_dao.go

@@ -4,6 +4,15 @@ import "youngee_b_api/app/entity"
 
 type EnterpriseDao struct{}
 
+func (d EnterpriseDao) GetEnterpriseInfo(enterpriseId string) (*entity.Enterprise, error) {
+	var enterprise entity.Enterprise
+	err := Db.Debug().Model(&entity.Enterprise{}).Where("enterprise_id = ?", enterpriseId).First(&enterprise).Error
+	if err != nil {
+		return nil, err
+	}
+	return &enterprise, nil
+}
+
 func (d EnterpriseDao) GetEnterprise(enterpriseId string) (*entity.Enterprise, error) {
 	var enterprise entity.Enterprise
 	err := Db.Model(&entity.Enterprise{}).Where("enterprise_id = ?", enterpriseId).Select("business_name, user_id").First(&enterprise).Error
@@ -15,9 +24,26 @@ func (d EnterpriseDao) GetEnterprise(enterpriseId string) (*entity.Enterprise, e
 
 func (d EnterpriseDao) GetEnterprisePhone(enterpriseId string) (string, error) {
 	var phone string
-	err := Db.Model(&entity.Enterprise{}).Where("enterprise_id = ?", enterpriseId).Select("phone").First(&phone).Error
+	err := Db.Debug().Model(&entity.Enterprise{}).Where("enterprise_id = ?", enterpriseId).Select("phone").First(&phone).Error
 	if err != nil {
 		return "", err
 	}
 	return phone, nil
 }
+
+// 更新账户余额
+func (d EnterpriseDao) UpdateEnterpriseBalance(enterpriseId string, balance float64) (*string, error) {
+	var enterprise entity.Enterprise
+	var err error
+	err = Db.Debug().Model(&entity.Enterprise{}).Where("enterprise_id = ?", enterpriseId).First(&enterprise).Error
+	if err != nil {
+		return nil, err
+	}
+	enterprise.Balance += balance
+	enterprise.AvailableBalance += balance
+	err = Db.Debug().Model(&entity.Enterprise{}).Where("enterprise_id = ?", enterpriseId).Updates(enterprise).Error
+	if err != nil {
+		return nil, err
+	}
+	return &enterpriseId, nil
+}

+ 68 - 0
app/dao/enterprise_supplier_cooperate_dao.go

@@ -0,0 +1,68 @@
+package dao
+
+import (
+	"gorm.io/gorm"
+	"youngee_b_api/app/entity"
+)
+
+type EnterpriseSupplierCooperateDao struct{}
+
+// 检查给定的服务商是否在该商家库中
+func (d EnterpriseSupplierCooperateDao) EnterpriseDatabaseCheck(enterpriseId string, supplierId int64) (bool, error) {
+	var count int64
+	err := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND supplier_id = ? AND cooperate_status != 2", enterpriseId, supplierId).Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+	return count > 0, nil
+}
+
+// 批量插入数据
+func (d EnterpriseSupplierCooperateDao) InsertBatch(records []*entity.EnterpriseSupplierCooperate) error {
+	result := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Omit("agree_time", "reject_time").Create(&records)
+	return result.Error
+}
+
+// 获取指定商家的服务商库
+func (d EnterpriseSupplierCooperateDao) GetSupplierByEnterprise(enterpriseId string, page int, pageSize int) ([]*entity.EnterpriseSupplierCooperate, int64, error) {
+	var enterpriseSupplierCooperates []*entity.EnterpriseSupplierCooperate
+	var total int64
+	offset := (page - 1) * pageSize
+	query := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND cooperate_status = 2", enterpriseId)
+	query.Count(&total)
+	query = query.Select("supplier_id, cooperate_num, upload_talent_num, cooperate_talent_num, b_operator, b_operator_type, agree_time")
+	err := query.Order("agree_time desc").Offset(offset).Limit(pageSize).Find(&enterpriseSupplierCooperates).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return enterpriseSupplierCooperates, total, nil
+}
+
+// 获取指定商家的某个服务商数据
+func (d EnterpriseSupplierCooperateDao) GetDataByEnterpriseAndSupplier(enterpriseId string, supplierId int64) (*entity.EnterpriseSupplierCooperate, error) {
+	var enterpriseSupplierCooperate *entity.EnterpriseSupplierCooperate
+	query := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND supplier_id = ?", enterpriseId, supplierId)
+	query = query.Select("supplier_id, cooperate_num, upload_talent_num, cooperate_talent_num, b_operator, b_operator_type")
+	err := query.Find(&enterpriseSupplierCooperate).Error
+	if err != nil && err != gorm.ErrRecordNotFound {
+		return nil, err
+	}
+	return enterpriseSupplierCooperate, nil
+}
+
+// 获取邀请待确认的服务商
+func (d EnterpriseSupplierCooperateDao) GetSupplierConfirmingList(enterpriseId string, page int, pageSize int) ([]*entity.EnterpriseSupplierCooperate, int64, error) {
+	var enterpriseSupplierCooperates []*entity.EnterpriseSupplierCooperate
+	var total int64
+	offset := (page - 1) * pageSize
+	query := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND cooperate_status = 1", enterpriseId)
+	query.Count(&total)
+	query = query.Select("supplier_id,  b_operator, b_operator_type, cooperate_status, create_time")
+	err := query.Order("create_time desc").Offset(offset).Limit(pageSize).Find(&enterpriseSupplierCooperates).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return enterpriseSupplierCooperates, total, nil
+}

+ 49 - 0
app/dao/invoice_info_dao.go

@@ -0,0 +1,49 @@
+package dao
+
+import (
+	"gorm.io/gorm"
+	"youngee_b_api/app/entity"
+)
+
+type InvoiceInfoDao struct{}
+
+func (d InvoiceInfoDao) Select(invoiceId int64) (*entity.InvoiceInfo, error) {
+	var invoiceInfo entity.InvoiceInfo
+	err := Db.Debug().Model(&entity.InvoiceInfo{}).Where("invoice_id = ?", invoiceId).Find(&invoiceInfo).Error
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			return &invoiceInfo, nil
+		}
+		return nil, err
+	}
+	return &invoiceInfo, nil
+}
+
+func (d InvoiceInfoDao) Delete(invoiceId int64) error {
+	var invoiceInfo entity.InvoiceInfo
+	err := Db.Debug().Model(&entity.InvoiceInfo{}).Where("invoice_id = ?", invoiceId).Delete(&invoiceInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d InvoiceInfoDao) SelectDefault(enterpriseId string, invoiceType int64, isDefault int64) (*entity.InvoiceInfo, error) {
+	var invoiceInfo entity.InvoiceInfo
+	err := Db.Debug().Model(&entity.InvoiceInfo{}).Where("enterprise_id = ? AND invoice_type = ? AND is_default = ?", enterpriseId, invoiceType, isDefault).Find(&invoiceInfo).Error
+	if err != nil {
+		if err == gorm.ErrRecordNotFound {
+			return &invoiceInfo, nil
+		}
+		return nil, err
+	}
+	return &invoiceInfo, nil
+}
+
+func (d InvoiceInfoDao) Insert(invoiceInfo *entity.InvoiceInfo) error {
+	err := Db.Debug().Model(&entity.InvoiceInfo{}).Create(invoiceInfo).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 120 - 0
app/dao/invoice_record_dao.go

@@ -0,0 +1,120 @@
+package dao
+
+import (
+	"errors"
+	"youngee_b_api/app/entity"
+)
+
+type InvoiceRecordDao struct{}
+
+func (d InvoiceRecordDao) Insert(invoiceRecord *entity.InvoiceRecord) error {
+	err := Db.Debug().Model(&entity.InvoiceRecord{}).Omit("billing_at").Create(invoiceRecord).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// 开票记录
+func (d InvoiceRecordDao) GetBillList(enterpriseId string, subAccountId int64, status int64, page int, pageSize int) ([]*entity.InvoiceRecord, int64, error) {
+	invoiceRecords := []*entity.InvoiceRecord{}
+	var total int64
+	query := Db.Debug().Model(&entity.InvoiceRecord{}).Where("status = ?", status)
+	if subAccountId == 0 {
+		if enterpriseId == "" {
+			return invoiceRecords, 0, errors.New("enterpriseId is empty")
+		}
+		query = query.Where("enterprise_id = ?", enterpriseId)
+	} else {
+		query = query.Where("sub_account_id = ?", subAccountId)
+	}
+	query.Count(&total)
+	query = query.Select("billing_id, enterprise_id, sub_account_id, invoice_amount, invoice_body, invoice_type, task_ids, status, submit_at, billing_at, invoice_url")
+	offset := (page - 1) * pageSize
+	var err error
+	if status == 1 {
+		err = query.Order("submit_at desc").Offset(offset).Limit(pageSize).Find(&invoiceRecords).Error
+	} else if status == 2 {
+		err = query.Order("billing_at desc").Offset(offset).Limit(pageSize).Find(&invoiceRecords).Error
+	}
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return invoiceRecords, total, nil
+}
+
+// 可开票账单——电商带货
+func (d InvoiceRecordDao) GetBillableSelectionList(enterpriseId string, subAccountId int64, page int, pageSize int) ([]*entity.SelectionInfo, int64, error) {
+	billableSelections := []*entity.SelectionInfo{}
+	var total int64
+	query := Db.Debug().Model(&entity.SelectionInfo{}).Where("selection_status = ? AND invoice_status = ?", 8, 0)
+	if subAccountId == 0 {
+		if enterpriseId == "" {
+			return billableSelections, 0, errors.New("enterpriseId is empty")
+		}
+		query = query.Where("enterprise_id = ?", enterpriseId)
+	} else {
+		query = query.Where("sub_account_id = ?", subAccountId)
+	}
+	query.Count(&total)
+	query = query.Select("selection_id, enterprise_id, sub_account_id, product_id, platform, settlement_amount")
+	//offset := (page - 1) * pageSize
+	//err := query.Order("finish_at desc").Offset(offset).Limit(pageSize).Find(&invoiceRecords).Error
+	err := query.Order("finish_at desc").Find(&billableSelections).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return billableSelections, total, nil
+}
+
+// 可开票账单——品牌种草
+func (d InvoiceRecordDao) GetBillableProjectList(enterpriseId string, subAccountId int64, page int, pageSize int) ([]*entity.Project, int64, error) {
+	billableProjects := []*entity.Project{}
+	var total int64
+	query := Db.Debug().Model(&entity.Project{}).Where("project_status = ? AND invoice_status = ?", 10, 0)
+	if subAccountId == 0 {
+		if enterpriseId == "" {
+			return billableProjects, 0, errors.New("enterpriseId is empty")
+		}
+		query = query.Where("enterprise_id = ?", enterpriseId)
+	} else {
+		query = query.Where("sub_account_id = ?", subAccountId)
+	}
+	query.Count(&total)
+	query = query.Select("project_id, enterprise_id, sub_account_id, product_id, project_platform, settlement_amount")
+	//offset := (page - 1) * pageSize
+	//err := query.Order("finish_at desc").Offset(offset).Limit(pageSize).Find(&invoiceRecords).Error
+	err := query.Order("finish_at desc").Find(&billableProjects).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return billableProjects, total, nil
+}
+
+// 可开票账单——本地生活
+//func (d InvoiceRecordDao) GetBillableProjectList(enterpriseId string, subAccountId int64, page int, pageSize int) ([]*entity.Project, int64, error) {
+//	billableProjects := []*entity.Project{}
+//	var total int64
+//	query := Db.Debug().Model(&entity.Project{}).Where("project_status = ? AND invoice_status = ?", 10, 0)
+//	if subAccountId == 0 {
+//		if enterpriseId == "" {
+//			return billableProjects, 0, errors.New("enterpriseId is empty")
+//		}
+//		query = query.Where("enterprise_id = ?", enterpriseId)
+//	} else {
+//		query = query.Where("sub_account_id = ?", subAccountId)
+//	}
+//	query.Count(&total)
+//	query = query.Select("project_id, enterprise_id, sub_account_id, product_id, project_platform, settlement_amount")
+//	//offset := (page - 1) * pageSize
+//	//err := query.Order("finish_at desc").Offset(offset).Limit(pageSize).Find(&invoiceRecords).Error
+//	err := query.Order("finish_at desc").Find(&billableProjects).Error
+//	if err != nil {
+//		return nil, 0, err
+//	}
+//
+//	return billableProjects, total, nil
+//}

+ 43 - 1
app/dao/project_dao.go

@@ -67,6 +67,15 @@ func (d ProjectDAO) UpdateProject(project entity.Project) error {
 	return nil
 }
 
+// 更新开票状态字段
+func (d ProjectDAO) UpdateInvoiceStatus(projectIDs []string) error {
+	err := Db.Debug().Model(&entity.Project{}).Where("project_id IN ?", projectIDs).Updates(entity.Project{InvoiceStatus: 1}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
 // 获取种草任务列表
 func (d ProjectDAO) GetProjectPreviews(param *vo.ProjectSearchParam) ([]vo.ReProjectTaskPreview, int64, error) {
 	var reProjectTaskPreviews []vo.ReProjectTaskPreview
@@ -98,7 +107,7 @@ func (d ProjectDAO) GetProjectPreviews(param *vo.ProjectSearchParam) ([]vo.RePro
 		query = query.Where("content_type = ?", param.ContentType)
 	}
 	query.Count(&total)
-	query = query.Select("enterprise_id, sub_account_id, project_id, project_platform, project_status, estimated_cost, project_form, content_type, need_review, need_quality, need_calculate, product_id")
+	query = query.Select("enterprise_id, sub_account_id, project_id, project_platform, project_status, estimated_cost, project_form, content_type, need_review, need_quality, need_calculate, product_id, tools")
 	offset := (param.Page - 1) * param.PageSize
 	if err := query.Order("created_at asc").Offset(offset).Limit(param.PageSize).Find(&projects).Error; err != nil {
 		return nil, 0, err
@@ -117,6 +126,7 @@ func (d ProjectDAO) GetProjectPreviews(param *vo.ProjectSearchParam) ([]vo.RePro
 			NeedQuality:     project.NeedQuality,
 			NeedCalculate:   project.NeedCalculate,
 			ProductId:       project.ProductID,
+			Tools:           project.Tools,
 		}
 		reProjectTaskPreviews = append(reProjectTaskPreviews, reProjectTaskPreview)
 	}
@@ -276,3 +286,35 @@ func (d ProjectDAO) GetProjectTargetList(param *vo.DefaultSearchParam) ([]vo.ReT
 
 	return reTaskDefaultTargets, total, nil
 }
+
+// 获取品牌种草冻结中的任务
+func (d ProjectDAO) GetProjectFrozenList(enterpriseId string) ([]*entity.Project, error) {
+	var projects []*entity.Project
+	query := Db.Debug().Model(entity.Project{})
+	query.Select("project_id, product_id, enterprise_id, sub_account_id, project_platform, payment_amount, pay_at") // 冻结金额:payment_amount
+	err := query.Where(fmt.Sprintf("enterprise_id = ? AND (project_status between 7 and 8) "), enterpriseId).Find(&projects).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return projects, nil
+		} else {
+			return nil, err
+		}
+	}
+	return projects, nil
+}
+
+// 获取品牌种草冻结解除的任务
+func (d ProjectDAO) GetProjectFrozenCancelList(enterpriseId string) ([]*entity.Project, error) {
+	var projects []*entity.Project
+	query := Db.Debug().Model(entity.Project{})
+	query.Select("project_id, product_id, enterprise_id, sub_account_id, project_platform, settlement_amount, pay_at") // 解冻金额:settlement_amount
+	err := query.Where(fmt.Sprintf("enterprise_id = ? AND (project_status between 9 and 10) "), enterpriseId).Find(&projects).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return projects, nil
+		} else {
+			return nil, err
+		}
+	}
+	return projects, nil
+}

+ 90 - 1
app/dao/recharge_record_dao.go

@@ -1,6 +1,10 @@
 package dao
 
-import "youngee_b_api/app/entity"
+import (
+	"time"
+	"youngee_b_api/app/entity"
+	"youngee_b_api/app/vo"
+)
 
 type RechargeRecordDao struct{}
 
@@ -11,3 +15,88 @@ func (d RechargeRecordDao) Insert(rechargeRecord *entity.RechargeRecord) error {
 	}
 	return nil
 }
+
+// 获取指定企业id的累计充值金额、充值确认中金额
+func (d RechargeRecordDao) GetRechargeAmount(enterpriseId string, status int64) (float64, error) {
+	var totalAmount float64
+	query := Db.Debug().Model(&entity.RechargeRecord{})
+	err := query.Where("enterprise_id = ? AND status = ?", enterpriseId, status).Select("SUM(recharge_amount)").Scan(&totalAmount).Error
+	if err != nil {
+		return 0, err
+	}
+	return totalAmount, nil
+}
+
+// 获取指定企业id的充值记录
+func (d RechargeRecordDao) RechargeInfoList(param *vo.RechargeParam) ([]entity.RechargeRecord, int64, error) {
+	rechargeRecords := []entity.RechargeRecord{}
+	var total int64
+	query := Db.Debug().Model(&entity.RechargeRecord{}).Where("enterprise_id = ? AND status = ?", param.EnterpriseId, param.RechargeState)
+	query.Count(&total)
+	query = query.Select("recharge_id, recharge_amount, transfer_voucher_url, recharge_method, commit_at, confirm_at, refuse_at, fail_reason, enterprise_id, sub_account_id")
+	offset := (param.Page - 1) * param.PageSize
+	var err error
+	if param.RechargeState == 1 {
+		err = query.Order("commit_at desc").Offset(offset).Limit(param.PageSize).Find(&rechargeRecords).Error
+	} else if param.RechargeState == 2 {
+		err = query.Order("confirm_at desc").Offset(offset).Limit(param.PageSize).Find(&rechargeRecords).Error
+	} else if param.RechargeState == 3 {
+		err = query.Order("refuse_at desc").Offset(offset).Limit(param.PageSize).Find(&rechargeRecords).Error
+	}
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return rechargeRecords, total, nil
+}
+
+// 更新充值状态
+func (d RechargeRecordDao) UpdateRechargeStatus(rechargeId string, status int64, t time.Time) error {
+	rechargeRecord := entity.RechargeRecord{
+		Status: status,
+	}
+	if status == 2 {
+		rechargeRecord.InvoiceStatus = 1
+		rechargeRecord.ConfirmAt = t
+	}
+	if status == 3 {
+		rechargeRecord.FailReason = "微信支付失败"
+		rechargeRecord.RefuseAt = t
+	}
+	err = Db.Debug().Model(&entity.RechargeRecord{}).Where("recharge_id = ?", rechargeId).Updates(rechargeRecord).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+// 查找微信充值中超时且状态为充值未确认的记录
+func (d RechargeRecordDao) GetWXRechargeByStatusList(status int64) ([]*entity.RechargeRecord, error) {
+	now := time.Now()
+	var rechargeRecords []*entity.RechargeRecord
+	err := Db.Debug().Model(&entity.RechargeRecord{}).Where("recharge_method = ? AND status = ? AND refuse_at < ?", 2, status, now).Find(&rechargeRecords).Error
+	if err != nil {
+		return nil, err
+	}
+	return rechargeRecords, nil
+}
+
+// 批量更新指定id的充值记录状态
+func (d RechargeRecordDao) UpdateRechargeFailedList(noPayIds []int64) error {
+	err := Db.Debug().Model(&entity.RechargeRecord{}).Where("id IN ?", noPayIds).Updates(entity.RechargeRecord{Status: 3, FailReason: "微信支付失败"}).Error
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+//// 更新所有充值记录中微信支付超时的记录
+//func (d RechargeRecordDao) UpdateRechargeFailedList() error {
+//	now := time.Now()
+//	err := Db.Debug().Model(&entity.RechargeRecord{}).Where("recharge_method = ? AND status = ? AND refuse_at < ?", 2, 1, now).
+//		Updates(map[string]interface{}{"status": 3, "fail_reason": "微信支付失败"}).Error
+//	if err != nil {
+//		return err
+//	}
+//	return nil
+//}

+ 71 - 0
app/dao/s_project_dao.go

@@ -0,0 +1,71 @@
+package dao
+
+import (
+	"youngee_b_api/app/entity"
+)
+
+type SProjectDao struct{}
+
+// 插入数据
+func (d SProjectDao) Insert(record *entity.SProjectInfo) error {
+	result := Db.Debug().Model(&entity.SProjectInfo{}).Create(&record)
+	return result.Error
+}
+
+// 根据种草id、邀约状态返回数据列表
+func (d SProjectDao) GetSProjectByStatus(projectId string, status int64, page int, pageSize int) ([]*entity.SProjectInfo, int64, error) {
+	var sProjectInfos []*entity.SProjectInfo
+	var total int64
+	offset := (page - 1) * pageSize
+	query := Db.Debug().Model(&entity.SProjectInfo{}).Where("project_id = ? AND s_project_status = ?", projectId, status)
+	query.Count(&total)
+	query = query.Select("supplier_id,  b_operator, b_operator_type")
+	err := query.Order("create_time desc").Offset(offset).Limit(pageSize).Find(&sProjectInfos).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return sProjectInfos, total, nil
+}
+
+// 检查给定的服务商是否在该商家库中
+func (d SupplierDao) EnterpriseDatabaseCheck(enterpriseId string, supplierId int64) (bool, error) {
+	var count int64
+	err := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND supplier_id = ? AND cooperate_status != 2", enterpriseId, supplierId).Count(&count).Error
+	if err != nil {
+		return false, err
+	}
+	return count > 0, nil
+}
+
+// 获取指定商家的服务商库
+func (d SupplierDao) GetSupplierByEnterprise(enterpriseId string, page int, pageSize int) ([]*entity.EnterpriseSupplierCooperate, int64, error) {
+	var enterpriseSupplierCooperates []*entity.EnterpriseSupplierCooperate
+	var total int64
+	offset := (page - 1) * pageSize
+	query := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND cooperate_status = 2", enterpriseId)
+	query.Count(&total)
+	query = query.Select("supplier_id, cooperate_num, upload_talent_num, cooperate_talent_num, b_operator, b_operator_type, agree_time")
+	err := query.Order("agree_time desc").Offset(offset).Limit(pageSize).Find(&enterpriseSupplierCooperates).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return enterpriseSupplierCooperates, total, nil
+}
+
+// 获取邀请待确认的服务商
+func (d SupplierDao) GetSupplierConfirmingList(enterpriseId string, page int, pageSize int) ([]*entity.EnterpriseSupplierCooperate, int64, error) {
+	var enterpriseSupplierCooperates []*entity.EnterpriseSupplierCooperate
+	var total int64
+	offset := (page - 1) * pageSize
+	query := Db.Debug().Model(&entity.EnterpriseSupplierCooperate{}).Where("enterprise_id = ? AND cooperate_status = 1", enterpriseId)
+	query.Count(&total)
+	query = query.Select("supplier_id,  b_operator, b_operator_type, cooperate_status, create_time")
+	err := query.Order("create_time desc").Offset(offset).Limit(pageSize).Find(&enterpriseSupplierCooperates).Error
+	if err != nil {
+		return nil, 0, err
+	}
+
+	return enterpriseSupplierCooperates, total, nil
+}

+ 39 - 2
app/dao/selection_info_dao.go

@@ -49,13 +49,19 @@ func (d SelectionInfoDAO) CreateSelectionInfo(selectionInfo entity.SelectionInfo
 
 // 更新带货任务
 func (d SelectionInfoDAO) UpdateSelectionInfo(selectionInfo entity.SelectionInfo) error {
-	err := Db.Model(&entity.SelectionInfo{}).Where("selection_id = ?", selectionInfo.SelectionID).Updates(selectionInfo).Error
+	err := Db.Debug().Model(&entity.SelectionInfo{}).Where("selection_id = ?", selectionInfo.SelectionID).Updates(selectionInfo).Error
 	if err != nil {
 		return err
 	}
 	return nil
 }
 
+// 更新开票状态字段
+func (d SelectionInfoDAO) UpdateInvoiceStatus(selectionIDs []string) error {
+	err := Db.Model(&entity.SelectionInfo{}).Where("selection_id IN ?", selectionIDs).Updates(entity.SelectionInfo{InvoiceStatus: 1}).Error
+	return err
+}
+
 // 获取带货任务列表
 func (d SelectionInfoDAO) GetSelectionPreviews(param *vo.SelectionSearchParam) ([]vo.ReSelectionTaskPreview, int64, error) {
 	var reSelectionTaskPreviews []vo.ReSelectionTaskPreview
@@ -168,7 +174,6 @@ func (d SelectionInfoDAO) GetSelectionDraftList(param *vo.SelectionDraftParam) (
 
 // 获取电商带货悬赏任务中全部指定状态值的项目
 func (d SelectionInfoDAO) GetSelectionInfoList(value int64, fieldName string) ([]*entity.SelectionInfo, error) {
-	fmt.Println("Db", Db)
 	var selectionInfos []*entity.SelectionInfo
 	err := Db.Model(entity.SelectionInfo{}).Where(fmt.Sprintf("task_mode = ? AND %s = ? ", fieldName), 1, value).Find(&selectionInfos).Error
 	if err != nil {
@@ -176,3 +181,35 @@ func (d SelectionInfoDAO) GetSelectionInfoList(value int64, fieldName string) ([
 	}
 	return selectionInfos, nil
 }
+
+// 获取电商带货冻结中的任务
+func (d SelectionInfoDAO) GetSelectionFrozenList(enterpriseId string) ([]*entity.SelectionInfo, error) {
+	var selectionInfos []*entity.SelectionInfo
+	query := Db.Debug().Model(entity.SelectionInfo{})
+	query.Select("selection_id, product_id, enterprise_id, sub_account_id, platform, estimated_cost, pay_at") // 冻结金额:estimated_cost
+	err := query.Where(fmt.Sprintf("enterprise_id = ? AND (selection_status between 5 and 6) "), enterpriseId).Find(&selectionInfos).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return selectionInfos, nil
+		} else {
+			return nil, err
+		}
+	}
+	return selectionInfos, nil
+}
+
+// 获取电商带货冻结解除的任务
+func (d SelectionInfoDAO) GetSelectionFrozenCancelList(enterpriseId string) ([]*entity.SelectionInfo, error) {
+	var selectionInfos []*entity.SelectionInfo
+	query := Db.Debug().Model(entity.SelectionInfo{})
+	query.Select("selection_id, product_id, enterprise_id, sub_account_id, platform, settlement_amount, pay_at") // 解冻金额:settlement_amount
+	err := query.Where(fmt.Sprintf("enterprise_id = ? AND (selection_status between 7 and 8) "), enterpriseId).Find(&selectionInfos).Error
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return selectionInfos, nil
+		} else {
+			return nil, err
+		}
+	}
+	return selectionInfos, nil
+}

+ 46 - 0
app/dao/supplier_dao.go

@@ -0,0 +1,46 @@
+package dao
+
+import (
+	"gorm.io/gorm"
+	"strconv"
+	"youngee_b_api/app/entity"
+)
+
+type SupplierDao struct{}
+
+func (d SupplierDao) GetSupplierInfoById(supplierId int64) (*entity.Supplier, error) {
+	var supplier entity.Supplier
+	err := Db.Debug().Model(&entity.Supplier{}).Where("supplier_id = ?", supplierId).First(&supplier).Error
+	if err != nil && err != gorm.ErrRecordNotFound {
+		return nil, err
+	}
+	return &supplier, nil
+}
+
+// 根据服务商名称/认证名搜索
+func (d SupplierDao) GetSuppliersByMsg(fieldName string) ([]*entity.Supplier, error) {
+	var suppliers []*entity.Supplier
+	supplierId, err := strconv.ParseInt(fieldName, 10, 64)
+	if err == nil {
+		err1 := Db.Debug().Model(&entity.Supplier{}).Where("supplier_id = ? AND supplier_type != 0", supplierId).First(&suppliers).Error
+		if err1 != nil && err1 != gorm.ErrRecordNotFound {
+			return nil, err1
+		}
+	} else {
+		err1 := Db.Debug().Model(&entity.Supplier{}).Where("supplier_name = ? OR company_name = ? OR name = ? AND supplier_type != 0", fieldName, fieldName, fieldName).Find(&suppliers).Error
+		if err1 != nil {
+			return nil, err
+		}
+	}
+
+	return suppliers, nil
+}
+
+func (d SupplierDao) GetSupplierPhone(supplierId int64) (string, error) {
+	var phone string
+	err := Db.Debug().Model(&entity.Supplier{}).Where("supplier_id = ?", supplierId).Select("phone_number").First(&phone).Error
+	if err != nil && err != gorm.ErrRecordNotFound {
+		return "", err
+	}
+	return phone, nil
+}

+ 24 - 0
app/entity/enterprise_supplier_cooperate.go

@@ -0,0 +1,24 @@
+package entity
+
+import "time"
+
+type EnterpriseSupplierCooperate struct {
+	CooperateId        int64     `gorm:"column:cooperate_id;primary_key;AUTO_INCREMENT"` // 合作表主键ID
+	EnterpriseId       string    `gorm:"column:enterprise_id"`                           // 商家ID
+	SupplierId         int64     `gorm:"column:supplier_id"`                             // 服务商ID
+	CooperateNum       int64     `gorm:"column:cooperate_num"`                           // 受邀合作次数
+	UploadTalentNum    int64     `gorm:"column:upload_talent_num"`                       // 提报达人数量
+	CooperateTalentNum int64     `gorm:"column:cooperate_talent_num"`                    // 合作达人人数
+	SOperator          int64     `gorm:"column:s_operator"`                              // 服务商同意/拒绝邀约操作人
+	SOperatorType      int64     `gorm:"column:s_operator_type"`                         // 服务商操作人类型:1主账号,2子账号
+	BOperator          string    `gorm:"column:b_operator"`                              // 商家发起入库邀约人
+	BOperatorType      int64     `gorm:"column:b_operator_type"`                         // 商家发起入库邀约人类型:1主账号,2子账号
+	CooperateStatus    int64     `gorm:"column:cooperate_status"`                        // 邀约状态:1待同意,2已同意,3已拒绝
+	CreateTime         time.Time `gorm:"column:create_time"`                             // 合作邀约时间
+	AgreeTime          time.Time `gorm:"column:agree_time"`                              // 同意邀约时间
+	RejectTime         time.Time `gorm:"column:reject_time"`                             // 拒绝邀约时间
+}
+
+func (m *EnterpriseSupplierCooperate) TableName() string {
+	return "enterprise_supplier_cooperate"
+}

+ 19 - 0
app/entity/invoice_address.go

@@ -0,0 +1,19 @@
+package entity
+
+import "time"
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+type YounggeeInvoiceAddress struct {
+	AddressID    int64     `gorm:"column:address_id;primary_key;AUTO_INCREMENT"` // 发票收件地址id
+	EnterpriseID string    `gorm:"column:enterprise_id;NOT NULL"`                // 企业id
+	Name         string    `gorm:"column:name;NOT NULL"`                         // 收件人姓名
+	RegionCode   string    `gorm:"column:region_code;NOT NULL"`                  // 所在地区编码
+	Address      string    `gorm:"column:address;NOT NULL"`                      // 详细地址
+	Phone        string    `gorm:"column:phone;NOT NULL"`                        // 手机号码
+	UpdateAt     time.Time `gorm:"column:update_at;NOT NULL"`                    // 创建时间
+}
+
+func (m *YounggeeInvoiceAddress) TableName() string {
+	return "younggee_invoice_address"
+}

+ 24 - 0
app/entity/invoice_info.go

@@ -0,0 +1,24 @@
+package entity
+
+import "time"
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+type InvoiceInfo struct {
+	InvoiceID         int64     `gorm:"column:invoice_id;primary_key;AUTO_INCREMENT"` // 发票信息id
+	EnterpriseID      string    `gorm:"column:enterprise_id;NOT NULL"`                // 企业id
+	InvoiceType       int64     `gorm:"column:invoice_type;NOT NULL"`                 // 发票类型
+	HeadType          string    `gorm:"column:head_type;NOT NULL"`                    // 抬头类型
+	InvoiceHeader     string    `gorm:"column:invoice_header;NOT NULL"`               // 发票抬头
+	TaxCode           string    `gorm:"column:tax_code;NOT NULL"`                     // 税务登记证号/统一社会信用代码
+	RegisteredAddress string    `gorm:"column:registered_address;NOT NULL"`           // 企业注册地址
+	RegisteredPhone   string    `gorm:"column:registered_phone;NOT NULL"`             // 企业注册电话
+	Bank              string    `gorm:"column:bank;NOT NULL"`                         // 开户银行
+	BankCardNumber    string    `gorm:"column:bank_card_number;NOT NULL"`             // 开户银行账号
+	IsDefault         int64     `gorm:"column:is_default;NOT NULL"`                   // 1默认抬头
+	UpdateAt          time.Time `gorm:"column:update_at;NOT NULL"`                    // 更新时间
+}
+
+func (m *InvoiceInfo) TableName() string {
+	return "younggee_invoice_info"
+}

+ 33 - 0
app/entity/invoice_record.go

@@ -0,0 +1,33 @@
+package entity
+
+import (
+	"time"
+)
+
+// Code generated by sql2gorm. DO NOT EDIT.
+
+type InvoiceRecord struct {
+	Id                int64     `gorm:"column:id;NOT NULL;primary_key;AUTO_INCREMENT"` // 自增ID
+	BillingId         string    `gorm:"column:billing_id;NOT NULL;unique_key"`         // 开票订单ID
+	EnterpriseID      string    `gorm:"column:enterprise_id;NOT NULL"`                 // 企业id
+	SubAccountId      int64     `gorm:"column:sub_account_id;NOT NULL"`                // 子账号id
+	InvoiceAmount     float64   `gorm:"column:invoice_amount;NOT NULL"`                // 开票金额
+	InvoiceBody       string    `gorm:"column:invoice_body;NOT NULL"`                  // 开票方信息
+	InvoiceContent    string    `gorm:"column:invoice_content;NOT NULL"`               // 发票内容
+	InvoiceType       int64     `gorm:"column:invoice_type;NOT NULL"`                  // 发票类型
+	InvoiceHeader     string    `gorm:"column:invoice_header;NOT NULL"`                // 发票抬头
+	TaxCode           string    `gorm:"column:tax_code;NOT NULL"`                      // 税务登记证号/统一社会信用代码
+	RegisteredAddress string    `gorm:"column:registered_address;NOT NULL"`            // 企业注册地址
+	RegisteredPhone   string    `gorm:"column:registered_phone;NOT NULL"`              // 企业注册电话
+	Bank              string    `gorm:"column:bank;NOT NULL"`                          // 开户银行
+	BankCardNumber    string    `gorm:"column:bank_card_number;NOT NULL"`              // 开户银行账号
+	Status            int64     `gorm:"column:status;NOT NULL"`                        // 开票状态:1 为待开票,2为已开票
+	SubmitAt          time.Time `gorm:"column:submit_at;NOT NULL"`                     // 申请提交时间
+	BillingAt         time.Time `gorm:"column:billing_at;NOT NULL"`                    // 开票时间
+	TaskIds           string    `gorm:"column:task_ids;NOT NULL"`                      // 账单列表
+	InvoiceUrl        string    `gorm:"column:invoice_url;NOT NULL"`                   // 发票
+}
+
+func (m *InvoiceRecord) TableName() string {
+	return "younggee_invoice_record"
+}

+ 2 - 0
app/entity/project.go

@@ -21,6 +21,7 @@ type Project struct {
 	EnterpriseID      string    `gorm:"column:enterprise_id"`                  // 所属企业id
 	SubAccountId      int64     `gorm:"column:sub_account_id"`                 // 子账号id
 	ProductID         int64     `gorm:"column:product_id"`                     // 关联商品id
+	ProductCategory   string    `gorm:"column:product_category"`               // 商品类目1--20
 	CreatedAt         time.Time `gorm:"column:created_at"`                     // 创建时间
 	UpdatedAt         time.Time `gorm:"column:updated_at"`                     // 修改时间
 	FeeForm           string    `gorm:"column:fee_form"`                       // 稿费形式列表
@@ -47,6 +48,7 @@ type Project struct {
 	OperatorType      int64     `gorm:"column:operator_type"`                  // 创建者类型,1商家主账号,2商家子账号
 	TotalRecruitNum   int64     `gorm:"column:total_recruit_num"`              // 各策略招募人数总和
 	Tools             string    `gorm:"column:tools"`                          // 工具选择,1邀约招募 2结算账单 3样品物流 4审稿工具 5作品审查 6数据巡检(,分隔)
+	InvoiceStatus     int64     `gorm:"column:invoice_status"`                 // 开票状态(1开票中 2已开票)
 }
 
 func (m *Project) TableName() string {

+ 6 - 3
app/entity/recharge_record.go

@@ -3,9 +3,10 @@ package entity
 import "time"
 
 type RechargeRecord struct {
-	RechargeID         string    `gorm:"column:recharge_id;primary_key"`       // 充值订单ID
-	EnterpriseID       string    `gorm:"column:enterprise_id;NOT NULL"`        // 企业id
-	SubAccountId       int64     `gorm:"column:sub_account_id;NOT NULL"`       // 子账号id
+	ID                 int64     `gorm:"column:id;primary_key;column:id"`
+	RechargeID         string    `gorm:"column:recharge_id;unique_key"` // 充值订单ID
+	EnterpriseID       string    `gorm:"column:enterprise_id;NOT NULL"` // 企业id
+	SubAccountId       int64     `gorm:"column:sub_account_id;NOT NULL"`
 	RechargeAmount     float64   `gorm:"column:recharge_amount;NOT NULL"`      // 充值金额
 	TransferVoucherUrl string    `gorm:"column:transfer_voucher_url;NOT NULL"` // 转账凭证图片链接
 	Phone              string    `gorm:"column:phone;NOT NULL"`                // 联系方式
@@ -14,6 +15,8 @@ type RechargeRecord struct {
 	InvoiceStatus      int       `gorm:"column:invoice_status;NOT NULL"`       // 开票状态:1为可开票,2为待开票,3为已开票
 	CommitAt           time.Time `gorm:"column:commit_at;NOT NULL"`            // 充值申请提交时间
 	ConfirmAt          time.Time `gorm:"column:confirm_at"`                    // 充值确认时间
+	FailReason         string    `gorm:"column:fail_reason;NOT NULL"`          // 失败原因
+	RefuseAt           time.Time `gorm:"column:refuse_at;NOT NULL"`            // 充值失败时间
 }
 
 func (m *RechargeRecord) TableName() string {

+ 2 - 0
app/entity/recruit_strategy.go

@@ -12,6 +12,7 @@ type RecruitStrategy struct {
 	TOffer            float64 `gorm:"column:t_offer"`                                        // 达人所见报价
 	ProjectID         string  `gorm:"column:project_id"`                                     // 所属项目id
 	ServiceCharge     float64 `gorm:"column:service_charge"`                                 // 平台服务费,稿费形式为产品置换时必填
+	ServiceRate       float64 `gorm:"column:service_rate"`                                   // 服务费率
 	SelectedNumber    int64   `gorm:"column:selected_number;default:0"`                      // 已选数量,被企业选择的达人数量
 	WaitingNumber     int64   `gorm:"column:waiting_number;default:0"`                       // 待发货
 	DeliveredNumber   int64   `gorm:"column:delivered_number;default:0"`                     // 已发货
@@ -25,6 +26,7 @@ type RecruitStrategy struct {
 	CommentNumber     int64   `gorm:"column:comment_number;default:0"`                       // 总评论数
 	FinishNumber      int64   `gorm:"column:finish_number;default:0"`                        // 结案数量
 	TotalOffer        float64 `gorm:"column:total_offer;default:0"`                          // 支付合计
+	StrategyType      int64   `gorm:"column:strategy_type;default:0"`                        // 策略类型,1为商家设置,2为服务商设置
 }
 
 func (m *RecruitStrategy) TableName() string {

+ 27 - 0
app/entity/s_project.go

@@ -0,0 +1,27 @@
+package entity
+
+import "time"
+
+// 服务商加入商单的种草任务
+type SProjectInfo struct {
+	SProjectId          int64     `gorm:"column:s_project_id;primary_key;AUTO_INCREMENT"` // 服务商加入商单后的种草任务ID
+	ProjectId           string    `gorm:"column:project_id;"`                             // 被服务商加入商单的原种草任务ID
+	ShareCode           string    `gorm:"column:share_code"`                              // 分享码URL
+	SupplierId          int64     `gorm:"column:supplier_id"`                             // 所属服务商ID
+	ApplyNum            int64     `gorm:"column:apply_num;default:0;NOT NULL"`            // 报名人数
+	RecruitNum          int64     `gorm:"column:recruit_num;default:0;NOT NULL"`          // 已招募人数
+	SettleNum           int64     `gorm:"column:settle_num;default:0;NOT NULL"`           // 已结算人数
+	SubAccountId        int64     `gorm:"column:sub_account_id"`                          // 所属子账号ID
+	ServiceCharge       float64   `gorm:"column:service_charge"`                          // 服务商预估可赚服务费
+	ServiceChargeActual float64   `gorm:"column:service_charge_actual"`                   // 服务商实际可赚服务费
+	OperatorType        int64     `gorm:"column:operator_type"`                           // 添加商单操作人类型,1为服务商主账号,2为服务商子账号
+	SProjectStatus      int64     `gorm:"column:s_project_status"`                        // 服务商种草任务状态,1待确认,2已确认,3已拒绝
+	StrategyStatus      int64     `gorm:"column:strategy_status"`                         // 定向种草任务是否替换招募策略
+	BOperator           string    `gorm:"column:b_operator"`                              // 商家发起入库邀约人
+	BOperatorType       int64     `gorm:"column:b_operator_type"`                         // 商家发起入库邀约人类型:1主账号,2子账号
+	CreateTime          time.Time `gorm:"column:create_time;default:0;NOT NULL"`
+}
+
+func (m *SProjectInfo) TableName() string {
+	return "younggee_s_project_info"
+}

+ 2 - 0
app/entity/selection_info.go

@@ -12,6 +12,7 @@ type SelectionInfo struct {
 	EnterpriseID     string    `gorm:"column:enterprise_id"`            // 所属企业id
 	SubAccountId     int64     `gorm:"column:sub_account_id"`           // 子账号id
 	ProductID        int64     `gorm:"column:product_id"`               // 关联商品id
+	ProductCategory  string    `gorm:"column:product_category"`         // 商品类目1--20
 	SelectionStatus  int64     `gorm:"column:selection_status"`         // 选品项目状态,1-8分别代表创建中、待审核、审核通过、待支付、已支付、执行中、失效、已结案
 	Platform         int64     `gorm:"column:platform"`                 // 项目平台,1-7分别代表小红书、抖音、微博、快手、b站、大众点评、知乎
 	SampleNum        int64     `gorm:"column:sample_num"`               // 样品数量
@@ -43,6 +44,7 @@ type SelectionInfo struct {
 	Status           int64     `gorm:"column:status"`                   // 选品是否删除 2代表删除
 	EnrollNum        int64     `gorm:"column:enroll_num"`               // 报名数量
 	ChooseNum        int64     `gorm:"column:choose_num"`               // 已选数量
+	InvoiceStatus    int64     `gorm:"column:invoice_status"`           // 开票状态(1开票中 2已开票)
 }
 
 func (m *SelectionInfo) TableName() string {

+ 20 - 0
app/entity/supplier.go

@@ -0,0 +1,20 @@
+package entity
+
+type Supplier struct {
+	SupplierID      int64  `gorm:"column:supplier_id"`      // 服务商ID
+	SupplierName    string `gorm:"column:supplier_name"`    // 服务商名称
+	PhoneNumber     string `gorm:"column:phone_number"`     // 手机号
+	BusinessLicense string `gorm:"column:business_license"` // 营业执照url
+	USCI            string `gorm:"column:usci"`             // 统一社会信用代码
+	CompanyName     string `gorm:"column:company_name"`     // 公司名称
+	IDFront         string `gorm:"column:id_front"`         // 身份证人像面url
+	IDBack          string `gorm:"column:id_back"`          // 身份证国徽面url
+	IDNumber        string `gorm:"column:id_number"`        // 身份证号
+	Name            string `gorm:"column:name"`             // 姓名
+	UserID          int64  `gorm:"column:user_id"`          // 用户表中的用户ID
+	SupplierType    int64  `gorm:"column:supplier_type"`    // 服务商用户类型,1为个人PR,2为机构
+}
+
+func (Supplier) TableName() string {
+	return "younggee_supplier"
+}

+ 2 - 2
app/schedule/auto_task.go → app/schedule/auto_task1.go

@@ -10,10 +10,10 @@ import (
 	"youngee_b_api/app/entity"
 )
 
-func AutoTask() error {
+func AutoTask1() error {
 	// 新建一个定时任务对象
 	crontab := cron.New(cron.WithSeconds()) // 精确到秒
-	spec := "0 0 */5 * * ?"                 //cron表达式,每10h一次
+	spec := "0 */5 * * * ?"                 //cron表达式,每5分钟一次
 	// "0 0 12 * * ?" 每天中午12点执行
 
 	// 添加定时任务

+ 55 - 0
app/schedule/auto_task2.go

@@ -0,0 +1,55 @@
+package schedule
+
+import (
+	"github.com/robfig/cron/v3"
+	"github.com/sirupsen/logrus"
+	"log"
+	"time"
+	"youngee_b_api/app/dao"
+	"youngee_b_api/app/service"
+)
+
+func AutoTask2() error {
+	// 新建一个定时任务对象
+	crontab := cron.New(cron.WithSeconds()) // 精确到秒
+	spec := "0 */2 * * * ?"                 //cron表达式
+
+	// 定时任务  检查微信支付是否充值成功
+	_, err1 := crontab.AddFunc(spec, AutoCheckWXRechargeTask)
+	if err1 != nil {
+		return err1
+	}
+
+	// 启动定时器
+	crontab.Start()
+	// 定时任务是另起协程执行的,这里使用 select 简单阻塞.需要根据实际情况进行控制
+	//select {} //阻塞主线程停止
+	return nil
+}
+
+// 定时任务  检查微信支付是否充值成功
+func AutoCheckWXRechargeTask() {
+	log.Println("AutoCheckWXRechargeTask running Start, Time :", time.Now())
+	rechargeRecords, err := dao.RechargeRecordDao{}.GetWXRechargeByStatusList(1)
+	if err != nil {
+		log.Println("GetWXRechargeByStatusList", err)
+	}
+	var rechargeId string
+	var noPayIds []int64
+	for _, rechargeRecord := range rechargeRecords {
+		rechargeId = rechargeRecord.RechargeID
+		tradeState, err := service.RechargeService{}.QueryOrderByTradeId(rechargeRecord.EnterpriseID, rechargeRecord.SubAccountId, rechargeId)
+		if err != nil {
+			logrus.Errorf("AutoCheckWXRechargeTask [QueryOrderByTradeId] call Show err:%+v\n", err)
+		}
+		// 支付成功的状态会在方法里更新,未支付的需要单独更新
+		if "NOTPAY" == tradeState {
+			noPayIds = append(noPayIds, rechargeRecord.ID)
+		}
+	}
+	err2 := dao.RechargeRecordDao{}.UpdateRechargeFailedList(noPayIds)
+	if err2 != nil {
+		log.Println("UpdateRechargeFailedList", err2)
+	}
+	log.Println("AutoCheckWXRechargeTask running End, Time :", time.Now())
+}

+ 324 - 0
app/service/cooperation_service.go

@@ -0,0 +1,324 @@
+package service
+
+import (
+	"fmt"
+	"strconv"
+	"time"
+	"youngee_b_api/app/dao"
+	"youngee_b_api/app/entity"
+	"youngee_b_api/app/vo"
+)
+
+type CooperationService struct{}
+
+// 服务商搜索
+func (s CooperationService) SearchSupplier(param *vo.SupplierSearchParam) ([]*vo.ReSupplierPreview, error) {
+	var reSupplierPreviews []*vo.ReSupplierPreview
+	suppliers, err := dao.SupplierDao{}.GetSuppliersByMsg(param.FieldName)
+	if err != nil {
+		return reSupplierPreviews, err
+	}
+	for _, supplier := range suppliers {
+		// 判断该服务商是否已在商家库
+		exist, _ := dao.EnterpriseSupplierCooperateDao{}.EnterpriseDatabaseCheck(param.EnterpriseId, supplier.SupplierID)
+		reSupplierPreview := &vo.ReSupplierPreview{
+			SupplierId:   supplier.SupplierID,
+			HeadUrl:      "",
+			SupplierName: supplier.SupplierName,
+			SupplierType: supplier.SupplierType,
+			CompanyName:  supplier.CompanyName,
+			Name:         supplier.Name,
+			Existence:    exist,
+		}
+		reSupplierPreviews = append(reSupplierPreviews, reSupplierPreview)
+	}
+	return reSupplierPreviews, nil
+}
+
+// 服务商入库批量邀请
+func (s CooperationService) InviteSupplier(param *vo.SupplierInviteParam) error {
+	// 要求传入的服务商都是未在该商家库的
+	var records []*entity.EnterpriseSupplierCooperate
+	for _, supplierId := range param.SupplierIds {
+		record := &entity.EnterpriseSupplierCooperate{
+			EnterpriseId:    param.EnterpriseId,
+			SupplierId:      supplierId,
+			CooperateNum:    1,
+			CooperateStatus: 1,
+			CreateTime:      time.Now(),
+		}
+		if param.SubAccountId == 0 {
+			record.BOperator = param.EnterpriseId
+			record.BOperatorType = 1
+		} else {
+			record.BOperator = strconv.Itoa(int(param.SubAccountId))
+			record.BOperatorType = 2
+		}
+		records = append(records, record)
+	}
+	err := dao.EnterpriseSupplierCooperateDao{}.InsertBatch(records)
+
+	return err
+}
+
+// 在库服务商列表
+func (s CooperationService) GetEnterprisePoolList(param *vo.SupplierSearchInPoolParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	var reSupplierPoolInfos []*vo.ReSupplierPoolInfo
+	var enterpriseOperator string
+	enterpriseSupplierCooperates, total, _ := dao.EnterpriseSupplierCooperateDao{}.GetSupplierByEnterprise(param.EnterpriseId, param.Page, param.PageSize)
+	for _, enterpriseSupplierCooperate := range enterpriseSupplierCooperates {
+		// 获取商家操作人姓名
+		bOperator := enterpriseSupplierCooperate.BOperator
+		if enterpriseSupplierCooperate.BOperatorType == 1 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(bOperator)
+			if err == nil && enterprise != nil {
+				enterpriseOperator = enterprise.BusinessName
+			}
+		} else if enterpriseSupplierCooperate.BOperatorType == 2 {
+			subAccountId, err := strconv.ParseInt(bOperator, 10, 64)
+			if err != nil {
+				fmt.Println("GetEnterprisePoolList==subAccountId 转换出错:", err)
+			} else {
+				subAccount, err := dao.SubAccountDao{}.GetSubAccount(subAccountId)
+				if err == nil && subAccount != nil {
+					enterpriseOperator = subAccount.SubAccountName
+				}
+			}
+		}
+		supplier, err := dao.SupplierDao{}.GetSupplierInfoById(enterpriseSupplierCooperate.SupplierId)
+		if err != nil {
+			continue
+		}
+		supplierPreview := &vo.ReSupplierPreview{
+			SupplierId:   supplier.SupplierID,
+			HeadUrl:      "",
+			SupplierName: supplier.SupplierName,
+			SupplierType: supplier.SupplierType,
+			CompanyName:  supplier.CompanyName,
+			Name:         supplier.Name,
+			Existence:    true,
+		}
+		reSupplierPoolInfo := &vo.ReSupplierPoolInfo{
+			SupplierPreview:    supplierPreview,
+			PhoneNumber:        supplier.PhoneNumber,
+			WechatId:           "",
+			WechatUrl:          "",
+			CooperateNum:       enterpriseSupplierCooperate.CooperateNum,
+			UploadTalentNum:    enterpriseSupplierCooperate.UploadTalentNum,
+			CooperateTalentNum: enterpriseSupplierCooperate.CooperateTalentNum,
+			AgreeTime:          enterpriseSupplierCooperate.AgreeTime.Format("2006-01-02 15:04:05"),
+			EnterpriseOperator: enterpriseOperator,
+		}
+		reSupplierPoolInfos = append(reSupplierPoolInfos, reSupplierPoolInfo)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reSupplierPoolInfos,
+	}
+	return result, nil
+}
+
+// 服务商邀请待确认列表
+func (s CooperationService) GetSupplierConfirmingList(param *vo.SupplierConfirmingParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	var reSupplierConfirmingInfos []*vo.ReSupplierConfirmingInfo
+	var enterpriseOperator string
+	enterpriseSupplierCooperates, total, _ := dao.EnterpriseSupplierCooperateDao{}.GetSupplierConfirmingList(param.EnterpriseId, param.Page, param.PageSize)
+	for _, enterpriseSupplierCooperate := range enterpriseSupplierCooperates {
+		// 获取商家操作人姓名
+		bOperator := enterpriseSupplierCooperate.BOperator
+		if enterpriseSupplierCooperate.BOperatorType == 1 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(bOperator)
+			if err == nil && enterprise != nil {
+				enterpriseOperator = enterprise.BusinessName
+			}
+		} else if enterpriseSupplierCooperate.BOperatorType == 2 {
+			subAccountId, err := strconv.ParseInt(bOperator, 10, 64)
+			if err != nil {
+				fmt.Println("GetSupplierConfirmingList==subAccountId 转换出错:", err)
+			} else {
+				subAccount, err := dao.SubAccountDao{}.GetSubAccount(subAccountId)
+				if err == nil && subAccount != nil {
+					enterpriseOperator = subAccount.SubAccountName
+				}
+			}
+		}
+		supplier, err := dao.SupplierDao{}.GetSupplierInfoById(enterpriseSupplierCooperate.SupplierId)
+		var supplierPreview *vo.ReSupplierPreview
+		var phoneNumber string
+		if err == nil {
+			supplierPreview = &vo.ReSupplierPreview{
+				SupplierId:   supplier.SupplierID,
+				HeadUrl:      "",
+				SupplierName: supplier.SupplierName,
+				SupplierType: supplier.SupplierType,
+				CompanyName:  supplier.CompanyName,
+				Name:         supplier.Name,
+			}
+			phoneNumber = supplier.PhoneNumber
+		}
+		reSupplierConfirmingInfo := &vo.ReSupplierConfirmingInfo{
+			SupplierPreview:    supplierPreview,
+			PhoneNumber:        phoneNumber,
+			WechatId:           "",
+			WechatUrl:          "",
+			CreateTime:         enterpriseSupplierCooperate.CreateTime.Format("2006-01-02 15:04:05"),
+			Status:             enterpriseSupplierCooperate.CooperateStatus,
+			EnterpriseOperator: enterpriseOperator,
+		}
+		reSupplierConfirmingInfos = append(reSupplierConfirmingInfos, reSupplierConfirmingInfo)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reSupplierConfirmingInfos,
+	}
+	return result, nil
+}
+
+// 服务商合作-服务商列表
+func (s CooperationService) GetSupplierInTargetTaskList(param *vo.SupplierSearchInTargetTaskParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var reSupplierTargetTasks []*vo.ReSupplierTargetTask
+	var total int64
+	result := vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reSupplierTargetTasks,
+	}
+	var enterpriseSupplierCooperates []*entity.EnterpriseSupplierCooperate
+	var sProjectInfos []*entity.SProjectInfo
+	var enterpriseOperator string
+	if param.Status == 1 { // 可邀约
+		enterpriseSupplierCooperates, total, _ = dao.EnterpriseSupplierCooperateDao{}.GetSupplierByEnterprise(param.EnterpriseId, param.Page, param.PageSize)
+	} else if param.Status == 2 { // 邀约中
+		if param.TaskType == 2 {
+			// 品牌种草
+			sProjectInfos, total, _ = dao.SProjectDao{}.GetSProjectByStatus(param.TaskId, 1, param.Page, param.PageSize)
+		} else if param.TaskType == 3 {
+			// 本地生活
+
+		}
+	} else if param.Status == 3 { // 合作中
+		if param.TaskType == 2 {
+			// 品牌种草
+			sProjectInfos, total, _ = dao.SProjectDao{}.GetSProjectByStatus(param.TaskId, 2, param.Page, param.PageSize)
+		} else if param.TaskType == 3 {
+			// 本地生活
+
+		}
+	}
+	if enterpriseSupplierCooperates == nil {
+		if param.TaskType == 2 { // 种草
+			for _, sProjectInfo := range sProjectInfos {
+				supplierId := sProjectInfo.SupplierId
+				enterpriseSupplierCooperate, err1 := dao.EnterpriseSupplierCooperateDao{}.GetDataByEnterpriseAndSupplier(param.EnterpriseId, supplierId)
+				if err1 != nil {
+					return result, err1
+				}
+				enterpriseSupplierCooperates = append(enterpriseSupplierCooperates, enterpriseSupplierCooperate)
+			}
+		} else if param.TaskType == 3 {
+			// 本地生活
+
+		}
+	}
+	for _, enterpriseSupplierCooperate := range enterpriseSupplierCooperates {
+		// 获取商家操作人姓名
+		bOperator := enterpriseSupplierCooperate.BOperator
+		if enterpriseSupplierCooperate.BOperatorType == 1 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(bOperator)
+			if err == nil && enterprise != nil {
+				enterpriseOperator = enterprise.BusinessName
+			}
+		} else if enterpriseSupplierCooperate.BOperatorType == 2 {
+			subAccountId, err := strconv.ParseInt(bOperator, 10, 64)
+			if err != nil {
+				fmt.Println("GetEnterprisePoolList==subAccountId 转换出错:", err)
+			} else {
+				subAccount, err := dao.SubAccountDao{}.GetSubAccount(subAccountId)
+				if err == nil && subAccount != nil {
+					enterpriseOperator = subAccount.SubAccountName
+				}
+			}
+		}
+		supplier, err := dao.SupplierDao{}.GetSupplierInfoById(enterpriseSupplierCooperate.SupplierId)
+		var supplierPreview *vo.ReSupplierPreview
+		var phoneNumber string
+		if err == nil {
+			supplierPreview = &vo.ReSupplierPreview{
+				SupplierId:   supplier.SupplierID,
+				HeadUrl:      "",
+				SupplierName: supplier.SupplierName,
+				SupplierType: supplier.SupplierType,
+				CompanyName:  supplier.CompanyName,
+				Name:         supplier.Name,
+				Existence:    true,
+			}
+			phoneNumber = supplier.PhoneNumber
+		}
+		reSupplierTargetTask := &vo.ReSupplierTargetTask{
+			SupplierPreview:    supplierPreview,
+			PhoneNumber:        phoneNumber,
+			WechatId:           "",
+			WechatUrl:          "",
+			CooperateNum:       enterpriseSupplierCooperate.CooperateNum,
+			UploadTalentNum:    enterpriseSupplierCooperate.UploadTalentNum,
+			CooperateTalentNum: enterpriseSupplierCooperate.CooperateTalentNum,
+			EnterpriseOperator: enterpriseOperator,
+			Status:             param.Status,
+		}
+		reSupplierTargetTasks = append(reSupplierTargetTasks, reSupplierTargetTask)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reSupplierTargetTasks,
+	}
+	return result, nil
+}
+
+// 服务商合作-邀约合作
+func (s CooperationService) InviteSupplierInTargetTask(param *vo.SupplierInviteInTargetTaskParam) error {
+	var sProjectInfo entity.SProjectInfo
+	if param.TaskType == 2 {
+		sProjectInfo.ProjectId = param.TaskId
+		sProjectInfo.SupplierId = param.SupplierId
+		sProjectInfo.SProjectStatus = 1
+		sProjectInfo.CreateTime = time.Now()
+		if param.SubAccountId == 0 {
+			sProjectInfo.BOperator = param.EnterpriseId
+			sProjectInfo.BOperatorType = 1
+		} else {
+			sProjectInfo.BOperator = strconv.Itoa(int(param.SubAccountId))
+			sProjectInfo.BOperatorType = 2
+		}
+	} else if param.TaskType == 3 {
+		// 本地生活
+	}
+	err := dao.SProjectDao{}.Insert(&sProjectInfo)
+	return err
+}

+ 8 - 8
app/service/default_service.go

@@ -12,10 +12,10 @@ type DefaultService struct{}
 
 // 违约管理——违约公开任务列表
 func (s DefaultService) GetPublicDefaultList(param *vo.DefaultSearchParam) (vo.ResultVO, error) {
-	if param.Page == 0 {
+	if param.Page <= 0 {
 		param.Page = 1
 	}
-	if param.PageSize == 0 {
+	if param.PageSize <= 0 {
 		param.PageSize = 10
 	}
 	var result vo.ResultVO
@@ -74,10 +74,10 @@ func (s DefaultService) GetPublicDefaultList(param *vo.DefaultSearchParam) (vo.R
 
 // 违约管理——违约定向任务列表
 func (s DefaultService) GetTargetDefaultList(param *vo.DefaultSearchParam) (vo.ResultVO, error) {
-	if param.Page == 0 {
+	if param.Page <= 0 {
 		param.Page = 1
 	}
-	if param.PageSize == 0 {
+	if param.PageSize <= 0 {
 		param.PageSize = 10
 	}
 	var result vo.ResultVO
@@ -128,10 +128,10 @@ func (s DefaultService) GetTargetDefaultList(param *vo.DefaultSearchParam) (vo.R
 
 // 违约管理——公开任务-违约达人列表
 func (s DefaultService) GetPublicDefaultTalentList(param *vo.DefaultSearchParam) (vo.ResultVO, error) {
-	if param.Page == 0 {
+	if param.Page <= 0 {
 		param.Page = 1
 	}
-	if param.PageSize == 0 {
+	if param.PageSize <= 0 {
 		param.PageSize = 10
 	}
 	var result vo.ResultVO
@@ -235,10 +235,10 @@ func (s DefaultService) GetPublicDefaultTalentList(param *vo.DefaultSearchParam)
 
 // 违约管理——定向任务-违约达人列表
 func (s DefaultService) GetTargetDefaultTalentList(param *vo.DefaultSearchParam) (vo.ResultVO, error) {
-	if param.Page == 0 {
+	if param.Page <= 0 {
 		param.Page = 1
 	}
-	if param.PageSize == 0 {
+	if param.PageSize <= 0 {
 		param.PageSize = 10
 	}
 	var result vo.ResultVO

+ 305 - 0
app/service/invoice_service.go

@@ -0,0 +1,305 @@
+package service
+
+import (
+	"encoding/json"
+	"fmt"
+	"time"
+	"youngee_b_api/app/consts"
+	"youngee_b_api/app/dao"
+	"youngee_b_api/app/entity"
+	"youngee_b_api/app/util"
+	"youngee_b_api/app/vo"
+)
+
+type InvoiceService struct{}
+
+// 设置默认开票抬头
+func (s InvoiceService) UpdateInvoiceDefault(param *vo.InvoiceDefaultParam) (*int64, error) {
+	var err error
+	invoiceInfo, err := dao.InvoiceInfoDao{}.SelectDefault(param.EnterpriseId, param.InvoiceType, 1)
+	if err != nil {
+		return nil, err
+	}
+	if invoiceInfo != nil && invoiceInfo.InvoiceID != 0 {
+		err := dao.InvoiceInfoDao{}.Delete(invoiceInfo.InvoiceID)
+		if err != nil {
+			return nil, err
+		}
+	}
+	if param.HeadType == 0 {
+		param.HeadType = 1
+	}
+	invoiceInfoAdd := entity.InvoiceInfo{
+		EnterpriseID:      param.EnterpriseId,
+		InvoiceType:       param.InvoiceType,
+		HeadType:          consts.GetHeadType(param.HeadType),
+		InvoiceHeader:     param.InvoiceHead,
+		TaxCode:           param.TaxCode,
+		RegisteredAddress: param.RegisteredAddress,
+		RegisteredPhone:   param.RegisteredPhone,
+		Bank:              param.Bank,
+		BankCardNumber:    param.BankCardNumber,
+		IsDefault:         1,
+		UpdateAt:          time.Now(),
+	}
+	err = dao.InvoiceInfoDao{}.Insert(&invoiceInfoAdd)
+	if err != nil {
+		return nil, err
+	}
+
+	return &invoiceInfoAdd.InvoiceID, nil
+}
+
+// 获取默认开票抬头
+func (s InvoiceService) GetInvoiceDefault(param *vo.InvoiceDefaultParam) (*vo.ReInvoiceInfo, error) {
+	invoiceInfo, err := dao.InvoiceInfoDao{}.SelectDefault(param.EnterpriseId, param.InvoiceType, 1)
+	if err != nil {
+		return nil, err
+	}
+	reInvoiceInfo := &vo.ReInvoiceInfo{
+		InvoiceHeader:     invoiceInfo.InvoiceHeader,
+		TaxCode:           invoiceInfo.TaxCode,
+		RegisteredAddress: invoiceInfo.RegisteredAddress,
+		RegisteredPhone:   invoiceInfo.RegisteredPhone,
+		Bank:              invoiceInfo.Bank,
+		BankCardNumber:    invoiceInfo.BankCardNumber,
+		IsDefault:         invoiceInfo.IsDefault,
+	}
+	return reInvoiceInfo, nil
+}
+
+// 确认开票
+func (s InvoiceService) BillInvoice(param *vo.InvoiceBillParam) (*string, error) {
+	var err error
+	billingId := util.GenerateDateRelatedUUID(16)
+	taskIds := param.TaskIds
+	// 将二维数组转换为 JSON 字符串
+	jsonData, _ := json.Marshal(taskIds)
+	// 将 []byte 转换为 string
+	taskIdsString := string(jsonData)
+	invoiceRecordAdd := entity.InvoiceRecord{
+		BillingId:         billingId,
+		EnterpriseID:      param.EnterpriseId,
+		SubAccountId:      param.SubAccountId,
+		InvoiceAmount:     param.InvoiceAmount,
+		InvoiceBody:       param.InvoiceBody,
+		InvoiceContent:    param.InvoiceContent,
+		InvoiceType:       param.InvoiceType,
+		InvoiceHeader:     param.InvoiceHead,
+		TaxCode:           param.TaxCode,
+		RegisteredAddress: param.RegisteredAddress,
+		RegisteredPhone:   param.RegisteredPhone,
+		Bank:              param.Bank,
+		BankCardNumber:    param.BankCardNumber,
+		TaskIds:           taskIdsString,
+		Status:            1,
+		SubmitAt:          time.Now(),
+	}
+	err = dao.InvoiceRecordDao{}.Insert(&invoiceRecordAdd)
+	if err != nil {
+		return nil, err
+	}
+	// 更新选品表的开票状态字段
+	// 电商带货
+	err = dao.SelectionInfoDAO{}.UpdateInvoiceStatus(taskIds[0])
+	if err != nil {
+		return nil, err
+	}
+	// 品牌种草
+	err = dao.ProjectDAO{}.UpdateInvoiceStatus(taskIds[1])
+	if err != nil {
+		return nil, err
+	}
+	// 本地生活
+
+	return &billingId, nil
+}
+
+// 开票记录
+func (s InvoiceService) GetBillList(param *vo.InvoiceBillListParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	var reInvoiceRecords []*vo.ReInvoiceRecord
+	invoiceRecords, total, _ := dao.InvoiceRecordDao{}.GetBillList(param.EnterpriseId, param.SubAccountId, param.BillStatus, param.Page, param.PageSize)
+	//if err != nil {
+	//	result = vo.ResultVO{
+	//		Page:     param.Page,
+	//		PageSize: param.PageSize,
+	//		Total:    total,
+	//		Data:     reInvoiceRecords,
+	//	}
+	//	return result, err
+	//}
+	for _, invoiceRecord := range invoiceRecords {
+		var creatorName string
+		if invoiceRecord.SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(invoiceRecord.EnterpriseID)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(invoiceRecord.SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		var taskNumber int
+		// 将 JSON 字符串解码为二维数组
+		var arrayData [3][]string
+		err := json.Unmarshal([]byte(invoiceRecord.TaskIds), &arrayData)
+		if err != nil {
+			fmt.Println("Error unmarshaling JSON:", err)
+			return result, err
+		}
+		for _, array := range arrayData {
+			taskNumber += len(array)
+		}
+		reInvoiceRecord := &vo.ReInvoiceRecord{
+			BillingId:     invoiceRecord.BillingId,
+			InvoiceAmount: invoiceRecord.InvoiceAmount,
+			CreatorName:   creatorName,
+			SubmitAt:      invoiceRecord.SubmitAt.Format("2006-01-02 15:04:05"),
+			InvoiceBody:   invoiceRecord.InvoiceBody,
+			InvoiceType:   invoiceRecord.InvoiceType,
+			Status:        invoiceRecord.Status,
+			TaskNumber:    int64(taskNumber),
+			InvoiceUrl:    invoiceRecord.InvoiceUrl,
+		}
+		if param.BillStatus == 2 {
+			reInvoiceRecord.BillingAt = invoiceRecord.BillingAt.Format("2006-01-02 15:04:05")
+		}
+		reInvoiceRecords = append(reInvoiceRecords, reInvoiceRecord)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reInvoiceRecords,
+	}
+	return result, nil
+}
+
+// 可开票账单
+func (s InvoiceService) GetBillableList(param *vo.InvoiceBillListParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	var reBillableInfos []*vo.ReBillableInfo
+	var billableSelections []*entity.SelectionInfo
+	var billableProjects []*entity.Project
+	// 电商带货
+	billableSelections, _, _ = dao.InvoiceRecordDao{}.GetBillableSelectionList(param.EnterpriseId, param.SubAccountId, param.Page, param.PageSize)
+	// 品牌种草
+	billableProjects, _, _ = dao.InvoiceRecordDao{}.GetBillableProjectList(param.EnterpriseId, param.SubAccountId, param.Page, param.PageSize)
+	// 本地生活
+
+	// 汇总结果
+	for _, billableSelection := range billableSelections {
+		// 获取商品详情字段
+		var creatorName string
+		var productName string
+		var productPrice float64
+		var mainImage string
+		if billableSelection.SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(billableSelection.EnterpriseID)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(billableSelection.SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		product, err := dao.ProductDAO{}.GetProductByID(billableSelection.ProductID)
+		if err == nil && product != nil {
+			productName = product.ProductName
+			productPrice = product.ProductPrice
+		}
+		mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(billableSelection.ProductID)
+		// 电商带货汇总
+		reBillableInfo := &vo.ReBillableInfo{
+			ProductId:      billableSelection.ProductID,
+			MainImage:      mainImage,
+			ProductName:    productName,
+			ProductPrice:   productPrice,
+			Platform:       billableSelection.Platform,
+			CreatorName:    creatorName,
+			TaskType:       "电商带货",
+			BillableAmount: billableSelection.SettlementAmount,
+			TaskId:         billableSelection.SelectionID,
+		}
+		reBillableInfos = append(reBillableInfos, reBillableInfo)
+	}
+	for _, billableProject := range billableProjects {
+		// 获取商品详情字段
+		var creatorName string
+		var productName string
+		var productPrice float64
+		var mainImage string
+		if billableProject.SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(billableProject.EnterpriseID)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(billableProject.SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		product, err := dao.ProductDAO{}.GetProductByID(billableProject.ProductID)
+		if err == nil && product != nil {
+			productName = product.ProductName
+			productPrice = product.ProductPrice
+		}
+		mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(billableProject.ProductID)
+		// 品牌种草汇总
+		reBillableInfo := &vo.ReBillableInfo{
+			ProductId:      billableProject.ProductID,
+			MainImage:      mainImage,
+			ProductName:    productName,
+			ProductPrice:   productPrice,
+			Platform:       billableProject.ProjectPlatform,
+			CreatorName:    creatorName,
+			TaskType:       "品牌种草",
+			BillableAmount: billableProject.SettlementAmount,
+			TaskId:         billableProject.ProjectId,
+		}
+		reBillableInfos = append(reBillableInfos, reBillableInfo)
+	}
+	// 本地生活
+
+	startIndex := (param.Page - 1) * param.PageSize
+	endIndex := startIndex + param.PageSize
+
+	// 分页
+	if startIndex >= len(reBillableInfos) {
+		result = vo.ResultVO{
+			Page:     param.Page,
+			PageSize: param.PageSize,
+			Total:    int64(len(reBillableInfos)),
+			Data:     nil,
+		}
+		return result, nil
+	}
+	if endIndex > len(reBillableInfos) {
+		endIndex = len(reBillableInfos)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    int64(len(reBillableInfos)),
+		Data:     reBillableInfos[startIndex:endIndex],
+	}
+	return result, nil
+}

+ 20 - 14
app/service/project_service.go

@@ -44,19 +44,21 @@ func (s ProjectService) CreateProject(param *vo.ProjectCreateParam) (*string, er
 	infoAutoDefault = dao.InfoAutoDefaultDao{}.GetAutoDefaultLast(param.EnterpriseId)
 	t := time.Now()
 	newProject := entity.Project{
-		ProjectStatus:    1,
-		ProjectType:      param.ProjectType,
-		ProjectId:        projectId,
-		ProductID:        param.ProductId,
-		EnterpriseID:     param.EnterpriseId,
-		SubAccountId:     param.SubAccountId,
-		ProjectPlatform:  param.Platform,
-		OperatorType:     operatorType,
-		ProductSnap:      string(productInfoToJson),
-		ProductPhotoSnap: string(productPhotosToJson),
-		CreatedAt:        t,
-		AutoTaskID:       infoAutoTask.AutoTaskID,
-		AutoDefaultID:    infoAutoDefault.AutoDefaultID,
+		ProjectStatus:     1,
+		ProjectType:       param.ProjectType,
+		ProjectId:         projectId,
+		ProductID:         param.ProductId,
+		ProductCategory:   product.ProductCategory,
+		EnterpriseID:      param.EnterpriseId,
+		SubAccountId:      param.SubAccountId,
+		ProjectPlatform:   param.Platform,
+		OperatorType:      operatorType,
+		ProductSnap:       string(productInfoToJson),
+		ProductPhotoSnap:  string(productPhotosToJson),
+		CreatedAt:         t,
+		AutoTaskID:        infoAutoTask.AutoTaskID,
+		AutoDefaultID:     infoAutoDefault.AutoDefaultID,
+		ServiceChargeRate: param.ServiceChargeRate,
 	}
 	if param.ProjectType == 1 {
 		newProject.ServiceChargeRate = param.ServiceChargeRate
@@ -100,6 +102,8 @@ func (s ProjectService) UpdateProject(projectUpdateParam *vo.ProjectUpdateParam)
 					FollowersUp:   strategy.FollowersUp,
 					RecruitNumber: strategy.RecruitNumber,
 					ProjectID:     project.ProjectId,
+					StrategyType:  1,
+					ServiceRate:   project.ServiceChargeRate,
 				}
 				totalRecruitNum += strategy.RecruitNumber
 				if strategy.FeeForm == 2 {
@@ -253,6 +257,8 @@ func (s ProjectService) UpdateProjectTarget(projectUpdateParam *vo.ProjectUpdate
 					FollowersUp:   strategy.FollowersUp,
 					RecruitNumber: strategy.RecruitNumber,
 					ProjectID:     project.ProjectId,
+					StrategyType:  1,
+					ServiceRate:   project.ServiceChargeRate,
 				}
 				totalRecruitNum += strategy.RecruitNumber
 				if strategy.FeeForm == 2 {
@@ -487,7 +493,7 @@ func (s ProjectService) ProjectToReview(projectUpdateParam *vo.ProjectUpdatePara
 	return &projectId, nil
 }
 
-// 公开种草任务列表
+// 种草任务列表
 func (s ProjectService) GetProjectTaskList(param *vo.ProjectSearchParam) (vo.ResultVO, error) {
 	if param.Page == 0 {
 		param.Page = 1

+ 272 - 16
app/service/recharge_service.go

@@ -2,13 +2,14 @@ package service
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	log "github.com/sirupsen/logrus"
 	"github.com/wechatpay-apiv3/wechatpay-go/core"
 	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
 	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/native"
 	"github.com/wechatpay-apiv3/wechatpay-go/utils"
-	"strconv"
+	"gorm.io/gorm"
 	"time"
 	"youngee_b_api/app/dao"
 	"youngee_b_api/app/entity"
@@ -22,22 +23,24 @@ type RechargeService struct{}
 func (s RechargeService) TransferToPublic(param *vo.RechargeTransferParam) (*string, error) {
 	var rechargeId string
 	var phone string
-	if param.SubAccountId == 0 {
-		rechargeId = util.MakeRechargeId(param.EnterpriseId)
-		phone, _ = dao.EnterpriseDao{}.GetEnterprisePhone(param.EnterpriseId)
-	} else {
-		rechargeId = util.MakeRechargeId(strconv.FormatInt(param.SubAccountId, 10))
-		phone, _ = dao.SubAccountDao{}.GetSubAccountPhone(param.SubAccountId)
-	}
+	//if param.SubAccountId == 0 {
+	//	rechargeId = util.MakeRechargeId(param.EnterpriseId)
+	//	phone, _ = dao.EnterpriseDao{}.GetEnterprisePhone(param.EnterpriseId)
+	//} else {
+	//	rechargeId = util.MakeRechargeId(strconv.FormatInt(param.SubAccountId, 10))
+	//	phone, _ = dao.SubAccountDao{}.GetSubAccountPhone(param.SubAccountId)
+	//}
+	rechargeId = util.GenerateDateRelatedUUID(16)
+	phone, _ = dao.EnterpriseDao{}.GetEnterprisePhone(param.EnterpriseId)
 	rechargeRecord := entity.RechargeRecord{
 		RechargeID:         rechargeId,
 		EnterpriseID:       param.EnterpriseId,
+		SubAccountId:       param.SubAccountId,
 		RechargeAmount:     param.Amount,
 		TransferVoucherUrl: param.TransferVoucherUrl,
 		Phone:              phone,
 		RechargeMethod:     1,
 		Status:             1,
-		InvoiceStatus:      1,
 		CommitAt:           time.Now(),
 	}
 	err := dao.RechargeRecordDao{}.Insert(&rechargeRecord)
@@ -47,13 +50,13 @@ func (s RechargeService) TransferToPublic(param *vo.RechargeTransferParam) (*str
 	return &rechargeId, nil
 }
 
-func (s RechargeService) NativeApiServicePrepay(tradeId string, amount int64) (codeUrl string, err error) {
+// 获取微信支付CodeUrl
+func (s RechargeService) NativeApiServicePrepay(enterpriseId string, subAccountId int64, tradeId string, amount int64) (string, *time.Time, error) {
 	var (
 		mchID                      string = "1615933939"                               // 商户号
 		mchCertificateSerialNumber string = "33DDFEC51BF5412F663B9B56510FD567B625FC68" // 商户证书序列号
 		mchAPIv3Key                string = "V10987654321younggee12345678910V"         // 商户APIv3密钥,用于加密和解密平台证书
 	)
-	fmt.Println("充值的金额为:", amount)
 
 	// 使用 utils 提供的函数从本地文件中加载商户私钥
 	mchPrivateKey, err := utils.LoadPrivateKeyWithPath("./apiclient_key.pem") // 商户私钥,用于生成请求的签名
@@ -74,13 +77,14 @@ func (s RechargeService) NativeApiServicePrepay(tradeId string, amount int64) (c
 	// 采用 Native 支付方式
 	svc := native.NativeApiService{Client: client}
 	// 发送请求
+	timeExpire := time.Now().Add(5 * time.Minute)
 	resp, result, err := svc.Prepay(ctx,
 		native.PrepayRequest{
 			Appid:         core.String("wxac396a3be7a16844"),
 			Mchid:         core.String("1615933939"),
 			Description:   core.String("样叽微信支付充值"),
 			OutTradeNo:    core.String(tradeId),
-			TimeExpire:    core.Time(time.Now().Add(10 * time.Minute)),
+			TimeExpire:    core.Time(timeExpire),
 			Attach:        core.String("微信支付充值"),
 			NotifyUrl:     core.String("https://www.weixin.qq.com/wxpay/pay.php"),
 			SupportFapiao: core.Bool(true),
@@ -94,16 +98,37 @@ func (s RechargeService) NativeApiServicePrepay(tradeId string, amount int64) (c
 	if err != nil {
 		// 处理错误
 		log.Printf("call Prepay err:%s", err)
-		return "", err
+		return "", nil, err
 	} else {
 		// 处理返回结果
 		log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
 		log.Println("codeUrl:", *resp.CodeUrl)
 	}
-	return *resp.CodeUrl, nil
+
+	// 生成充值记录
+	phone, _ := dao.EnterpriseDao{}.GetEnterprisePhone(enterpriseId)
+	rechargeRecord := entity.RechargeRecord{
+		RechargeID:     tradeId,
+		EnterpriseID:   enterpriseId,
+		SubAccountId:   subAccountId,
+		RechargeAmount: float64(amount) / 100,
+		Phone:          phone,
+		RechargeMethod: 2,
+		Status:         1,
+		CommitAt:       time.Now(),
+		RefuseAt:       timeExpire,
+	}
+	err = dao.RechargeRecordDao{}.Insert(&rechargeRecord)
+	if err != nil {
+		return "", nil, err
+	}
+
+	return *resp.CodeUrl, &timeExpire, nil
 }
 
-func (s RechargeService) QueryOrderByTradeId(tradeId string) (tradeState string, err error) {
+// 根据交易id查询微信是否扫码付款
+// https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_2.shtml
+func (s RechargeService) QueryOrderByTradeId(enterpriseId string, subAccountId int64, tradeId string) (tradeState string, err error) {
 	var (
 		mchID                      string = "1615933939"                               // 商户号
 		mchCertificateSerialNumber string = "33DDFEC51BF5412F663B9B56510FD567B625FC68" // 商户证书序列号
@@ -142,6 +167,237 @@ func (s RechargeService) QueryOrderByTradeId(tradeId string) (tradeState string,
 		// 处理返回结果
 		log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
 	}
-	fmt.Printf("支付状态 %+v\n", *resp.TradeState)
+
+	// 更新充值记录/账户金额相关信息
+	if "SUCCESS" == *resp.TradeState {
+		payTime := resp.SuccessTime
+		t, _ := time.Parse("2006-01-02 15:04:05", *payTime)
+		err = dao.RechargeRecordDao{}.UpdateRechargeStatus(tradeId, 2, t)
+		amount := float64(*resp.Amount.Total) / 100
+		_, err = dao.EnterpriseDao{}.UpdateEnterpriseBalance(enterpriseId, amount)
+	} else if "CLOSED" == *resp.TradeState {
+		err = dao.RechargeRecordDao{}.UpdateRechargeStatus(tradeId, 3, time.Now())
+	}
+
 	return *resp.TradeState, nil
 }
+
+// 余额管理——总金额、可用余额、冻结金额
+func (s RechargeService) ShowBalance(param *vo.BalanceParam) (*vo.ReBalanceShow, error) {
+	reBalanceShow := new(vo.ReBalanceShow)
+	enterprise, err := dao.EnterpriseDao{}.GetEnterpriseInfo(param.EnterpriseId)
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return reBalanceShow, nil
+		} else {
+			return nil, err
+		}
+	}
+	reBalanceShow.TotalBalance = enterprise.Balance
+	reBalanceShow.AvailBalance = enterprise.AvailableBalance
+	reBalanceShow.FrozenBalance = enterprise.FrozenBalance
+	return reBalanceShow, nil
+}
+
+// 余额管理——冻结记录
+func (s RechargeService) FrozenInfoList(param *vo.BalanceParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	var reBalanceShows []*vo.ReFrozenInfo
+	var selectionInfos []*entity.SelectionInfo
+	var projects []*entity.Project
+	if param.FrozenState == 1 {
+		// 电商带货
+		selectionInfos, _ = dao.SelectionInfoDAO{}.GetSelectionFrozenList(param.EnterpriseId)
+		// 品牌种草
+		projects, _ = dao.ProjectDAO{}.GetProjectFrozenList(param.EnterpriseId)
+		// 本地生活
+
+	} else {
+		// 电商带货
+		selectionInfos, _ = dao.SelectionInfoDAO{}.GetSelectionFrozenCancelList(param.EnterpriseId)
+		// 品牌种草
+		projects, _ = dao.ProjectDAO{}.GetProjectFrozenCancelList(param.EnterpriseId)
+		// 本地生活
+
+	}
+	// 汇总结果
+	for _, selection := range selectionInfos {
+		// 获取商品详情字段
+		var creatorName string
+		var productName string
+		var productPrice float64
+		var mainImage string
+		if selection.SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(selection.EnterpriseID)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(selection.SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		product, err := dao.ProductDAO{}.GetProductByID(selection.ProductID)
+		if err == nil && product != nil {
+			productName = product.ProductName
+			productPrice = product.ProductPrice
+		}
+		mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(selection.ProductID)
+		// 电商带货汇总
+		reBalanceShow := &vo.ReFrozenInfo{
+			ProductId:     selection.ProductID,
+			MainImage:     mainImage,
+			ProductName:   productName,
+			ProductPrice:  productPrice,
+			Platform:      selection.Platform,
+			CreatorName:   creatorName,
+			TaskType:      "电商带货",
+			FrozenBalance: selection.EstimatedCost,
+			FrozenTime:    selection.PayAt.Format("2006-01-02 15:04:05"),
+			EnterpriseId:  selection.EnterpriseID,
+			SubAccountId:  selection.SubAccountId,
+			TaskId:        selection.SelectionID,
+		}
+		if param.FrozenState == 2 {
+			reBalanceShow.FrozenCancelBalance = selection.SettlementAmount
+		}
+		reBalanceShows = append(reBalanceShows, reBalanceShow)
+	}
+	for _, project := range projects {
+		// 获取商品详情字段
+		var creatorName string
+		var productName string
+		var productPrice float64
+		var mainImage string
+		if project.SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(project.EnterpriseID)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(project.SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		product, err := dao.ProductDAO{}.GetProductByID(project.ProductID)
+		if err == nil && product != nil {
+			productName = product.ProductName
+			productPrice = product.ProductPrice
+		}
+		mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(project.ProductID)
+		// 电商带货汇总
+		reBalanceShow := &vo.ReFrozenInfo{
+			ProductId:     project.ProductID,
+			MainImage:     mainImage,
+			ProductName:   productName,
+			ProductPrice:  productPrice,
+			Platform:      project.ProjectPlatform,
+			CreatorName:   creatorName,
+			TaskType:      "品牌种草",
+			FrozenBalance: project.PaymentAmount,
+			FrozenTime:    project.PayAt.Format("2006-01-02 15:04:05"),
+			EnterpriseId:  project.EnterpriseID,
+			SubAccountId:  project.SubAccountId,
+			TaskId:        project.ProjectId,
+		}
+		if param.FrozenState == 2 {
+			reBalanceShow.FrozenCancelBalance = project.SettlementAmount
+		}
+		reBalanceShows = append(reBalanceShows, reBalanceShow)
+	}
+
+	startIndex := (param.Page - 1) * param.PageSize
+	endIndex := startIndex + param.PageSize
+
+	// 分页
+	if startIndex >= len(reBalanceShows) {
+		result = vo.ResultVO{
+			Page:     param.Page,
+			PageSize: param.PageSize,
+			Total:    int64(len(reBalanceShows)),
+			Data:     nil,
+		}
+		return result, nil
+	}
+	if endIndex > len(reBalanceShows) {
+		endIndex = len(reBalanceShows)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    int64(len(reBalanceShows)),
+		Data:     reBalanceShows[startIndex:endIndex],
+	}
+	return result, nil
+}
+
+// 充值管理——累计充值金额、确认中金额
+func (s RechargeService) ShowRecharge(param *vo.RechargeParam) (*vo.ReRechargeShow, error) {
+	reRechargeShow := new(vo.ReRechargeShow)
+	confirmingRecharge, _ := dao.RechargeRecordDao{}.GetRechargeAmount(param.EnterpriseId, 1)
+	totalRecharge, _ := dao.RechargeRecordDao{}.GetRechargeAmount(param.EnterpriseId, 2)
+	reRechargeShow.ConfirmingRecharge = confirmingRecharge
+	reRechargeShow.TotalRecharge = totalRecharge
+	return reRechargeShow, nil
+}
+
+// 充值管理——充值记录
+func (s RechargeService) RechargeInfoList(param *vo.RechargeParam) (vo.ResultVO, error) {
+	if param.Page <= 0 {
+		param.Page = 1
+	}
+	if param.PageSize <= 0 {
+		param.PageSize = 10
+	}
+	var result vo.ResultVO
+	var reRechargeInfos []*vo.ReRechargeInfo
+	rechargeRecords, total, err := dao.RechargeRecordDao{}.RechargeInfoList(param)
+	if err != nil {
+		return result, err
+	}
+	for _, rechargeRecord := range rechargeRecords {
+		var creatorName string
+		if rechargeRecord.SubAccountId == 0 {
+			enterprise, err := dao.EnterpriseDao{}.GetEnterprise(rechargeRecord.EnterpriseID)
+			if err == nil && enterprise != nil {
+				creatorName = enterprise.BusinessName
+			}
+		} else {
+			subAccount, err := dao.SubAccountDao{}.GetSubAccount(rechargeRecord.SubAccountId)
+			if err == nil && subAccount != nil {
+				creatorName = subAccount.SubAccountName
+			}
+		}
+		reRechargeInfo := &vo.ReRechargeInfo{
+			RechargeId:         rechargeRecord.RechargeID,
+			CreatorName:        creatorName,
+			RechargeAmount:     rechargeRecord.RechargeAmount,
+			RechargeMethod:     rechargeRecord.RechargeMethod,
+			TransferVoucherUrl: rechargeRecord.TransferVoucherUrl,
+		}
+		if param.RechargeState == 1 {
+			reRechargeInfo.CommitAt = rechargeRecord.CommitAt.Format("2006-01-02 15:04:05")
+		} else if param.RechargeState == 2 {
+			reRechargeInfo.ConfirmAt = rechargeRecord.ConfirmAt.Format("2006-01-02 15:04:05")
+		} else if param.RechargeState == 3 {
+			reRechargeInfo.RefuseAt = rechargeRecord.RefuseAt.Format("2006-01-02 15:04:05")
+			reRechargeInfo.FailReason = rechargeRecord.FailReason
+		}
+		reRechargeInfos = append(reRechargeInfos, reRechargeInfo)
+	}
+	result = vo.ResultVO{
+		Page:     param.Page,
+		PageSize: param.PageSize,
+		Total:    total,
+		Data:     reRechargeInfos,
+	}
+	return result, nil
+}

+ 1 - 0
app/service/selection_info_service.go

@@ -76,6 +76,7 @@ func (s SelectionInfoService) CreateSelectionInfo(param *vo.SelectionInfoCreateP
 		SelectionStatus:  1,
 		SelectionID:      selectionId,
 		ProductID:        param.ProductId,
+		ProductCategory:  product.ProductCategory,
 		EnterpriseID:     param.EnterpriseId,
 		SubAccountId:     param.SubAccountId,
 		Platform:         param.Platform,

+ 8 - 2
app/util/uuid.go

@@ -53,7 +53,7 @@ func GetProjectID() string {
 	return selectionId
 }
 
-func MakeRechargeId(EnterpriseID string) string {
+func MakeRechargeId(enterpriseID string) string {
 	// 1、年月日
 	year := time.Now().Year()
 	month := time.Now().Month()
@@ -71,7 +71,7 @@ func MakeRechargeId(EnterpriseID string) string {
 		sum += 1
 	}
 	last := ""
-	rechargeIdPrefix := "8" + EnterpriseID[len(EnterpriseID)-2:] + conv.MustString(sum)
+	rechargeIdPrefix := "8" + enterpriseID[len(enterpriseID)-2:] + conv.MustString(sum)
 	var rechargeIdLast string
 	err := dao.Db.Model(entity.RechargeRecord{}).Select("recharge_id").Where("recharge_id like ?", rechargeIdPrefix+"%").
 		Last(&rechargeIdLast).Error
@@ -89,3 +89,9 @@ func MakeRechargeId(EnterpriseID string) string {
 	}
 	return rechargeIdPrefix + last
 }
+
+func GenerateDateRelatedUUID(num int64) string {
+	date := time.Now().Format("20060102") // 获取当前日期
+	u := uuid.New()
+	return date + u.String()[:(num-8)]
+}

+ 8 - 0
app/vo/balance_param.go

@@ -0,0 +1,8 @@
+package vo
+
+type BalanceParam struct {
+	EnterpriseId string `json:"enterprise_id"` // 企业id
+	FrozenState  int64  `json:"frozen_state"`  // 冻结状态(1冻结中 2冻结解除)
+	Page         int    `json:"page"`
+	PageSize     int    `json:"page_size"`
+}

+ 25 - 0
app/vo/invoice_bill_param.go

@@ -0,0 +1,25 @@
+package vo
+
+type InvoiceBillParam struct {
+	EnterpriseId      string     `json:"enterprise_id"`
+	SubAccountId      int64      `json:"sub_account_id"`
+	InvoiceAmount     float64    `json:"invoice_amount"`     // 开票金额
+	InvoiceBody       string     `json:"invoice_body"`       // 开票方信息
+	InvoiceContent    string     `json:"invoice_content"`    // 发票内容
+	InvoiceType       int64      `json:"invoice_type"`       // 发票类型(1数电普票 2数电专票)
+	InvoiceHead       string     `json:"invoice_head"`       // 发票抬头(企业名称)
+	TaxCode           string     `json:"tax_code"`           // 企业税号
+	RegisteredAddress string     `json:"registered_address"` // 企业注册地址
+	RegisteredPhone   string     `json:"registered_phone"`   // 企业注册电话
+	Bank              string     `json:"bank"`               // 开户银行
+	BankCardNumber    string     `json:"bank_card_number"`   // 银行账号
+	TaskIds           [][]string `json:"task_ids"`           // 账单列表
+}
+
+type InvoiceBillListParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	SubAccountId int64  `json:"sub_account_id"`
+	BillStatus   int64  `json:"bill_status"` // 开票状态:1开票中 2已开票
+	Page         int    `json:"page"`
+	PageSize     int    `json:"page_size"`
+}

+ 14 - 0
app/vo/invoice_default_param.go

@@ -0,0 +1,14 @@
+package vo
+
+type InvoiceDefaultParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	HeadType     int64  `json:"head_type"`    // 抬头类型(1企业 2个人)
+	InvoiceType  int64  `json:"invoice_type"` // 发票类型(1数电普票 2数电专票)
+	InvoiceHead  string `json:"invoice_head"` //发票抬头(企业名称)
+	TaxCode      string `json:"tax_code"`     // 企业税号
+
+	RegisteredAddress string `json:"registered_address"` // 企业注册地址
+	RegisteredPhone   string `json:"registered_phone"`   // 企业注册电话
+	Bank              string `json:"bank"`               // 开户银行
+	BankCardNumber    string `json:"bank_card_number"`   // 银行账号
+}

+ 11 - 6
app/vo/pay_wx_param.go

@@ -1,14 +1,19 @@
 package vo
 
 type GetCodeUrlParam struct {
-	Amount int64 `json:"amount"`
+	EnterpriseId string `json:"enterprise_id"` // 企业id
+	SubAccountId int64  `json:"sub_account_id"`
+	Amount       int64  `json:"amount"` // 金额(分)
 }
 
-type ReCodeUrl struct {
-	CodeUrl string `json:"code_url"`
-	TradeId string `json:"trade_id"`
+type QueryOrderByTradeIdParam struct {
+	EnterpriseId string `json:"enterprise_id"` // 企业id
+	SubAccountId int64  `json:"sub_account_id"`
+	TradeId      string `json:"trade_id"`
 }
 
-type QueryOrderByTradeIdParam struct {
-	TradeId string `json:"trade_id"`
+type ReCodeUrl struct {
+	CodeUrl    string `json:"codeUrl"`
+	TradeId    string `json:"tradeId"`
+	TimeExpire string `json:"timeExpire"`
 }

+ 1 - 1
app/vo/project_update_param.go

@@ -13,7 +13,7 @@ type ProjectUpdateParam struct {
 	RecruitDdl        string                  `json:"recruit_ddl"`       // 招募截止时间
 	RecruitStrategys  []CreateRecruitStrategy `json:"recruit_strategys"` // 招募策略
 
-	ProjectForm     int64                  `json:"project_form"`   // 项目形式,1-4分别代表实体商品寄拍、虚拟产品测评、线下探店打卡、素材微原创
+	ProjectForm     int64                  `json:"project_form"`   // 项目形式,1-3分别代表商品寄拍、素材分发、虚拟产品测评
 	ContentType     int64                  `json:"content_type"`   // 内容形式,1代表图文,2代表视频
 	ProjectDetail   string                 `json:"project_detail"` // 项目详情
 	Tools           string                 `json:"tools"`          // 工具选择 1邀约招募 2结算账单 3样品物流 4审稿工具 5作品审查 6数据巡检(,分隔)

+ 7 - 0
app/vo/re_balance_show.go

@@ -0,0 +1,7 @@
+package vo
+
+type ReBalanceShow struct {
+	TotalBalance  float64 `json:"totalBalance"`  // 总金额
+	AvailBalance  float64 `json:"availBalance"`  // 可用余额
+	FrozenBalance float64 `json:"frozenBalance"` // 冻结金额
+}

+ 13 - 0
app/vo/re_billable_info.go

@@ -0,0 +1,13 @@
+package vo
+
+type ReBillableInfo struct {
+	ProductId      int64   `json:"productId"`
+	MainImage      string  `json:"mainImage"`
+	ProductName    string  `json:"productName"`
+	ProductPrice   float64 `json:"productPrice"`
+	Platform       int64   `json:"platform"`
+	CreatorName    string  `json:"creatorName"`
+	TaskType       string  `json:"taskType"` // 任务类型
+	BillableAmount float64 `json:"billableAmount"`
+	TaskId         string  `json:"taskId"`
+}

+ 17 - 0
app/vo/re_frozen_info.go

@@ -0,0 +1,17 @@
+package vo
+
+type ReFrozenInfo struct {
+	ProductId           int64   `json:"productId"`
+	MainImage           string  `json:"mainImage"`
+	ProductName         string  `json:"productName"`
+	ProductPrice        float64 `json:"productPrice"`
+	Platform            int64   `json:"platform"`
+	CreatorName         string  `json:"creatorName"`
+	TaskType            string  `json:"taskType"` // 任务类型
+	FrozenBalance       float64 `json:"frozenBalance"`
+	FrozenCancelBalance float64 `json:"frozenCancelBalance"`
+	FrozenTime          string  `json:"frozenTime"`
+	EnterpriseId        string  `json:"enterpriseId"`
+	SubAccountId        int64   `json:"subAccountId"`
+	TaskId              string  `json:"taskId"`
+}

+ 11 - 0
app/vo/re_invoice_info.go

@@ -0,0 +1,11 @@
+package vo
+
+type ReInvoiceInfo struct {
+	InvoiceHeader     string `json:"invoiceHeader"`     // 发票抬头
+	TaxCode           string `json:"taxCode"`           // 税务登记证号/统一社会信用代码
+	RegisteredAddress string `json:"registeredAddress"` // 企业注册地址
+	RegisteredPhone   string `json:"registeredPhone"`   // 企业注册电话
+	Bank              string `json:"bank"`              // 开户银行
+	BankCardNumber    string `json:"bankCardNumber"`    // 开户银行账号
+	IsDefault         int64  `json:"isDefault"`         // 1默认抬头
+}

+ 14 - 0
app/vo/re_invoice_record.go

@@ -0,0 +1,14 @@
+package vo
+
+type ReInvoiceRecord struct {
+	BillingId     string  `json:"billingId"`
+	InvoiceAmount float64 `json:"invoiceAmount"`
+	CreatorName   string  `json:"creatorName"`
+	SubmitAt      string  `json:"submitAt"`
+	BillingAt     string  `json:"billingAt"`
+	InvoiceBody   string  `json:"invoiceBody"`
+	InvoiceType   int64   `json:"invoiceType"`
+	Status        int64   `json:"status"`
+	TaskNumber    int64   `json:"taskNumber"`
+	InvoiceUrl    string  `json:"invoiceUrl"`
+}

+ 1 - 0
app/vo/re_project_task_preview.go

@@ -20,4 +20,5 @@ type ReProjectTaskPreview struct {
 	CreatorName     string  `json:"creatorName"`
 	ProjectType     int64   `json:"projectType"`
 	CreatedAt       string  `json:"createdAt"`
+	Tools           string  `json:"tools"`
 }

+ 13 - 0
app/vo/re_recharge_info.go

@@ -0,0 +1,13 @@
+package vo
+
+type ReRechargeInfo struct {
+	RechargeId         string  `json:"rechargeId"`
+	CreatorName        string  `json:"creatorName"`
+	RechargeAmount     float64 `json:"rechargeAmount"`
+	RechargeMethod     int64   `json:"rechargeMethod"` // 1对公转账 2微信支付
+	TransferVoucherUrl string  `json:"transferVoucherUrl"`
+	CommitAt           string  `json:"commitAt"`   // 充值申请提交时间
+	ConfirmAt          string  `json:"confirmAt"`  // 充值确认时间
+	RefuseAt           string  `json:"refuseAt"`   // 充值失败时间
+	FailReason         string  `json:"failReason"` // 失败原因
+}

+ 6 - 0
app/vo/re_recharge_show.go

@@ -0,0 +1,6 @@
+package vo
+
+type ReRechargeShow struct {
+	TotalRecharge      float64 `json:"totalRecharge"`      // 累计充值金额
+	ConfirmingRecharge float64 `json:"rechargeConfirming"` // 充值确认中金额
+}

+ 11 - 0
app/vo/re_supplier_confirming_info.go

@@ -0,0 +1,11 @@
+package vo
+
+type ReSupplierConfirmingInfo struct {
+	SupplierPreview    *ReSupplierPreview `json:"supplierPreview"`
+	PhoneNumber        string             `json:"phoneNumber"`        // 手机号
+	WechatId           string             `json:"wechatId"`           // 微信号
+	WechatUrl          string             `json:"wechatUrl"`          // 微信二维码
+	CreateTime         string             `json:"agreeTime"`          // 邀请时间
+	EnterpriseOperator string             `json:"enterpriseOperator"` // 邀请操作人
+	Status             int64              `json:"status"`             // 状态
+}

+ 13 - 0
app/vo/re_supplier_pool_info.go

@@ -0,0 +1,13 @@
+package vo
+
+type ReSupplierPoolInfo struct {
+	SupplierPreview    *ReSupplierPreview `json:"supplierPreview"`
+	PhoneNumber        string             `json:"phoneNumber"`        // 手机号
+	WechatId           string             `json:"wechatId"`           // 微信号
+	WechatUrl          string             `json:"wechatUrl"`          // 微信二维码
+	CooperateNum       int64              `json:"cooperateNum"`       // 受邀合作次数
+	UploadTalentNum    int64              `json:"uploadTalentNum"`    // 提报达人数
+	CooperateTalentNum int64              `json:"cooperateTalentNum"` // 合作达人数
+	AgreeTime          string             `json:"agreeTime"`          // 入库时间
+	EnterpriseOperator string             `json:"enterpriseOperator"` // 邀请操作人
+}

+ 12 - 0
app/vo/re_supplier_preview.go

@@ -0,0 +1,12 @@
+package vo
+
+type ReSupplierPreview struct {
+	SupplierId   int64  `json:"supplierId"`
+	HeadUrl      string `json:"headUrl"`
+	SupplierName string `json:"supplierName"` // 服务商名称
+	SupplierType int64  `json:"supplierType"` // 服务商类型,1为个人PR,2为机构
+	CompanyName  string `json:"companyName"`  // 公司名称
+	Name         string `json:"name"`         // 个人姓名
+
+	Existence bool `json:"existence"` // 已在库
+}

+ 13 - 0
app/vo/re_supplier_target_task.go

@@ -0,0 +1,13 @@
+package vo
+
+type ReSupplierTargetTask struct {
+	SupplierPreview    *ReSupplierPreview `json:"supplierPreview"`
+	PhoneNumber        string             `json:"phoneNumber"`        // 手机号
+	WechatId           string             `json:"wechatId"`           // 微信号
+	WechatUrl          string             `json:"wechatUrl"`          // 微信二维码
+	CooperateNum       int64              `json:"cooperateNum"`       // 受邀合作次数
+	UploadTalentNum    int64              `json:"uploadTalentNum"`    // 提报达人数
+	CooperateTalentNum int64              `json:"cooperateTalentNum"` // 合作达人数
+	EnterpriseOperator string             `json:"enterpriseOperator"` // 邀请操作人
+	Status             int64              `json:"status"`             // 状态:1可邀约 2邀约中 3合作中
+}

+ 9 - 0
app/vo/recharge_param.go

@@ -0,0 +1,9 @@
+package vo
+
+type RechargeParam struct {
+	EnterpriseId  string `json:"enterprise_id"` // 企业id
+	SubAccountId  int64  `json:"sub_account_id"`
+	RechargeState int64  `json:"recharge_state"` // 充值状态(1充值待确认 2已充值 3充值失败)
+	Page          int    `json:"page"`
+	PageSize      int    `json:"page_size"`
+}

+ 43 - 0
app/vo/supplier_search_param.go

@@ -0,0 +1,43 @@
+package vo
+
+type SupplierSearchParam struct {
+	FieldName    string `json:"field_name"`
+	EnterpriseId string `json:"enterprise_id"`
+	SubAccountId int64  `json:"sub_account_id"`
+}
+
+type SupplierInviteParam struct {
+	SupplierIds  []int64 `json:"supplier_ids"`
+	EnterpriseId string  `json:"enterprise_id"`
+	SubAccountId int64   `json:"sub_account_id"`
+}
+
+type SupplierSearchInPoolParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	Page         int    `json:"page"`
+	PageSize     int    `json:"page_size"`
+}
+
+type SupplierConfirmingParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	Page         int    `json:"page"`
+	PageSize     int    `json:"page_size"`
+}
+
+type SupplierSearchInTargetTaskParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	SubAccountId int64  `json:"sub_account_id"`
+	TaskType     int64  `json:"task_type"` // 任务类型:2品牌种草 3本地生活
+	TaskId       string `json:"task_id"`
+	Status       int64  `json:"status"` // 1可邀约 2邀约中 3合作中
+	Page         int    `json:"page"`
+	PageSize     int    `json:"page_size"`
+}
+
+type SupplierInviteInTargetTaskParam struct {
+	EnterpriseId string `json:"enterprise_id"`
+	SubAccountId int64  `json:"sub_account_id"`
+	TaskType     int64  `json:"task_type"` // 任务类型:2品牌种草 3本地生活
+	TaskId       string `json:"task_id"`
+	SupplierId   int64  `json:"supplier_id"`
+}

+ 24 - 5
config/pro.yaml

@@ -1,8 +1,27 @@
+# mysql:
+#   host: 192.168.0.165
+#   port: 3306
+#   user: test
+#   password: testDB_123
+#   database: youngmini
+#
+# redis:
+#   host: 139.9.53.143
+#   port: 6379
+#   auth: younggeeRedis_123
+#   database: 1
+#
+# server:
+#   host: 0.0.0.0
+#   port: 8388
+#   session:
+#     ttl: -1 #minute
+
 mysql:
-  host: 192.168.0.165
+  host: 139.9.53.143
   port: 3306
-  user: test
-  password: testDB_123
+  user: talent
+  password: talentDB_123
   database: youngmini
 
 redis:
@@ -10,9 +29,9 @@ redis:
   port: 6379
   auth: younggeeRedis_123
   database: 1
-  
+
 server:
   host: 0.0.0.0
   port: 8388
   session:
-    ttl: -1 #minute
+    ttl: -1 # minute

+ 2 - 2
consts/invoice.go

@@ -14,8 +14,8 @@ func GetHeadType(HeadType string) string {
 }
 
 var InvoiceTypeMap = map[string]string{
-	"1": "增值税专用发票",
-	"2": "增值税普通发票",
+	"1": "数电普票",
+	"2": "数电专票",
 }
 
 func GetInvoiceType(InvoiceType string) string {

+ 12 - 0
db/auto_default.go

@@ -19,3 +19,15 @@ func GetLastAutoDefaultID() (int, error) {
 	//fmt.Printf("auto task %+v %+v", result, LastTask)
 	return LastDefault.AutoDefaultID, nil
 }
+
+// GetLastAutoDefaultIDByEnterpriseId 根据enterpriseId查找违约扣款Id
+func GetLastAutoDefaultIDByEnterpriseId(enterpriseId string) (int, error) {
+	db := GetReadDB(context.Background())
+	LastDefault := gorm_model.InfoAutoDefaultHandle{}
+	autoDefaultIErr := db.Model(gorm_model.InfoAutoDefaultHandle{}).Where("enterprise_id = ?", enterpriseId).Find(&LastDefault).Error
+	if autoDefaultIErr != nil {
+		log.Println("DB GetLastAutoDefaultID:", autoDefaultIErr)
+		return 0, autoDefaultIErr
+	}
+	return LastDefault.AutoDefaultID, nil
+}

+ 724 - 0
db/auto_task.go

@@ -2,6 +2,7 @@ package db
 
 import (
 	"context"
+	"fmt"
 	"github.com/issue9/conv"
 	"time"
 	"youngee_b_api/model/gorm_model"
@@ -144,3 +145,726 @@ func AutoCompleteSelection() error {
 
 	return nil
 }
+
+// GetAutoDraftDefaultTask 品牌种草-商品寄拍 初稿超时违约
+func GetAutoDraftDefaultTask() error {
+	fmt.Println("GetAutoDraftDefaultInPicTask Running")
+	db := GetReadDB(context.Background())
+
+	// 1. 根据种草任务形式取出对应的Project
+	var projectInfos []*gorm_model.ProjectInfo
+	projectInfoErr := db.Model(gorm_model.ProjectInfo{}).Where("project_type = ? AND project_form = ? ", 1, 1).Find(&projectInfos).Error
+	if projectInfoErr != nil {
+		return projectInfoErr
+	}
+
+	// 2. 构建查询map
+	var projectIds []string
+	projectIdToAutoTaskIdMap := map[string]int{}    // 项目id 对 定时任务id 的map
+	projectIdToAutoDefaultIdMap := map[string]int{} // 项目id 对 违约扣款设置id 的map
+	taskIdToFeeFormMap := make(map[string]int)      // taskId 对 稿费形式的 map
+	TaskIdToProjectId := make(map[string]string)    // taskId 对 项目id的 map
+	var taskNeedModIds []string                     // 首次提交初稿的任务记录id
+	var submitTaskNeedModIds []string               // 修改后提交初稿的任务记录id
+	for _, projectInfo := range projectInfos {
+		projectIds = append(projectIds, projectInfo.ProjectID)
+		projectIdToAutoTaskIdMap[projectInfo.ProjectID] = int(projectInfo.AutoTaskID)
+		projectIdToAutoDefaultIdMap[projectInfo.ProjectID] = int(projectInfo.AutoDefaultID)
+	}
+	for _, projectId := range projectIds {
+		db1 := GetReadDB(context.Background())
+		var taskInfos []gorm_model.YoungeeTaskInfo
+		db1.Model(gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = ? AND task_stage = ? AND cur_default_type = ? AND logistics_status = 3", projectId, 2, 9, 0).Find(&taskInfos)
+		for _, taskInfo := range taskInfos {
+			TaskIdToProjectId[taskInfo.TaskID] = projectId
+			taskNeedMod := gorm_model.YoungeeTaskInfo{}
+			db2 := GetReadDB(context.Background())
+
+			// 保存所有满足物流状态为 3 且 初稿上传状态为 1或 3 的任务记录的id
+			db2.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskInfo.TaskID).First(&taskNeedMod)
+			taskIdToFeeFormMap[taskInfo.TaskID] = taskInfo.FeeForm
+			if taskNeedMod.TaskStage == 9 && taskNeedMod.SketchStatus == 1 {
+				taskNeedModIds = append(taskNeedModIds, taskInfo.TaskID)
+			}
+			if taskNeedMod.TaskStage == 9 && taskNeedMod.SketchStatus == 3 {
+				submitTaskNeedModIds = append(submitTaskNeedModIds, taskInfo.TaskID)
+			}
+		}
+	}
+
+	// 3. 对初次初稿未上传的操作
+	for _, taskNeedModId := range taskNeedModIds {
+		// 获取taskId对应的autoTaskId
+		autoTaskId := projectIdToAutoTaskIdMap[TaskIdToProjectId[taskNeedModId]]
+
+		// 根据autoTaskId去查找对应的初稿违约小时数
+		dbStart := GetReadDB(context.Background())
+		var DraftDefaultInPic int32
+		dbStart.Model(gorm_model.InfoAutoTask{}).Select("draft_default").Where("auto_task_id = ?", autoTaskId).First(&DraftDefaultInPic)
+
+		// 根据taskId查询taskInfo
+		db3 := GetReadDB(context.Background())
+		taskLogisticNeedMod := gorm_model.YoungeeTaskInfo{}
+		db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).First(&taskLogisticNeedMod)
+
+		// 获取task对应的autoDefaultId 并取出违约扣款比例
+		autoDefaultHandle := gorm_model.InfoAutoDefaultHandle{}
+		db6 := GetReadDB(context.Background())
+		db6.Model(gorm_model.InfoAutoDefaultHandle{}).Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[TaskIdToProjectId[taskNeedModId]]).Find(&autoDefaultHandle)
+
+		var sketchDefaultRate int
+		var sketchErrRate int
+		// 稿费形式为产品置换
+		if taskIdToFeeFormMap[taskNeedModId] == 1 {
+			sketchDefaultRate = autoDefaultHandle.SketchReplaceTimeOut
+			sketchErrRate = autoDefaultHandle.SketchReplaceNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("sketch_replace_time_out", "sketch_replace_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[TaskIdToProjectId[taskNeedModId]]).Find(&autoDefaultHandle)
+		} else {
+			// 稿费形式为其他
+			sketchDefaultRate = autoDefaultHandle.SketchOtherTimeOut
+			sketchErrRate = autoDefaultHandle.SketchOtherNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("sketch_other_time_out", "sketch_other_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[TaskIdToProjectId[taskNeedModId]]).Find(&sketchDefaultRate, &sketchErrRate)
+		}
+
+		//	若无违约自动处理时间 则添加初稿违约自动处理时间
+		if taskLogisticNeedMod.TaskID != "" && taskLogisticNeedMod.SketchMissingTime.IsZero() {
+			dd, _ := time.ParseDuration(conv.MustString(DraftDefaultInPic, "") + "h")
+			db4 := GetReadDB(context.Background())
+			t := taskLogisticNeedMod.SignedTime.Add(dd)
+			db4.Where("task_id = ?", taskNeedModId).Updates(&gorm_model.YoungeeTaskInfo{
+				SketchMissingTime: t,
+			})
+			taskLogisticNeedMod.SketchMissingTime = t
+			fmt.Println("已添加 品牌种草-商品寄拍-初次初稿未上传 初稿违约自动处理时间")
+			fmt.Println(sketchDefaultRate, sketchErrRate)
+		}
+
+		// 判断是否超时违约
+		if taskLogisticNeedMod.TaskID != "" && taskLogisticNeedMod.SketchMissingTime.Sub(time.Now()) <= 0 {
+			fmt.Println("taskId: ", taskLogisticNeedMod.TaskID, "超时违约触发")
+			taskInfo := gorm_model.YoungeeTaskInfo{}
+			dbt := GetReadDB(context.Background())
+			err2 := dbt.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskLogisticNeedMod.TaskID).Find(&taskInfo).Error
+			if err2 != nil {
+				return err2
+			}
+
+			// 计算违约扣款后的达人所得
+			settleAmount := taskInfo.DraftFee * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+sketchDefaultRate+taskInfo.ScriptBreakRate)/100)
+			if settleAmount <= 0 {
+				settleAmount = 0.0
+			}
+
+			// 计算违约扣款后的服务商所得
+			realServiceCharge := taskInfo.ServiceCharge * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+sketchDefaultRate+taskInfo.ScriptBreakRate)/100)
+			if realServiceCharge <= 0 {
+				realServiceCharge = 0.0
+			}
+
+			// 计算企业需要实际支付金额
+			realPayment := settleAmount + realServiceCharge
+			if realPayment <= 0 {
+				realPayment = 0.0
+			}
+
+			db8 := GetReadDB(context.Background())
+			fmt.Println("待更新的taskId: ", taskLogisticNeedMod.TaskID)
+			db8.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskLogisticNeedMod.TaskID).Updates(
+				map[string]interface{}{
+					"sketch_missing_status": 1,
+					"cur_default_type":      3,
+					"sketch_break_rate":     sketchDefaultRate,
+					"settle_amount":         settleAmount,
+					"err_break_rate":        sketchErrRate,
+					"real_service_charge":   realServiceCharge,
+					"real_payment":          realPayment,
+				})
+			createTaskLogErr := CreateTaskLog(context.Background(), taskLogisticNeedMod.TaskID, "初稿逾期")
+			if createTaskLogErr != nil {
+				log.WithContext(context.Background()).Errorf("[operate db] call CreateTaskLog error,err:%+v", createTaskLogErr)
+			}
+			createMessageByTaskIdErr := CreateMessageByTaskId(context.Background(), 22, 4, taskLogisticNeedMod.TaskID)
+			if createMessageByTaskIdErr != nil {
+				log.WithContext(context.Background()).Errorf("[operate db] call CreateMessageByTaskId error,err:%+v", createMessageByTaskIdErr)
+			}
+			fmt.Println("已创建 品牌种草-商品寄拍-初次初稿未上传 初稿违约记录")
+		}
+	}
+
+	// 4. 判断应该修改后上传的任务
+	for _, submitTaskNeedModId := range submitTaskNeedModIds {
+
+		// 获取 autoTaskId 及其对应的限制时间
+		db2 := GetReadDB(context.Background())
+		var DraftDefaultInMv int32
+		db2.Model(&gorm_model.InfoAutoTask{}).Select("draft_default").Where("auto_task_id = ?", projectIdToAutoTaskIdMap[TaskIdToProjectId[submitTaskNeedModId]]).First(&DraftDefaultInMv)
+		dd, _ := time.ParseDuration(conv.MustString(DraftDefaultInMv, "") + "h")
+
+		// 查询违约扣款比例
+		autoDefaultHandle := gorm_model.InfoAutoDefaultHandle{}
+		db6 := GetReadDB(context.Background())
+		db6.Model(gorm_model.InfoAutoDefaultHandle{}).Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[TaskIdToProjectId[submitTaskNeedModId]]).Find(&autoDefaultHandle)
+
+		var sketchDefaultRate int
+		var sketchErrRate int
+		if taskIdToFeeFormMap[submitTaskNeedModId] == 1 {
+			sketchDefaultRate = autoDefaultHandle.SketchReplaceTimeOut
+			sketchErrRate = autoDefaultHandle.SketchReplaceNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("sketch_replace_time_out", "sketch_replace_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[TaskIdToProjectId[submitTaskNeedModId]]).Find(&sketchDefaultRate, &sketchErrRate)
+		} else {
+			sketchDefaultRate = autoDefaultHandle.SketchOtherTimeOut
+			sketchErrRate = autoDefaultHandle.SketchOtherNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("sketch_other_time_out", "sketch_other_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[TaskIdToProjectId[submitTaskNeedModId]]).Find(&sketchDefaultRate, &sketchErrRate)
+		}
+
+		//	添加初稿违约自动处理时间
+		db1 := GetReadDB(context.Background())
+		var taskSketchInfo gorm_model.YounggeeSketchInfo
+		db1.Model(gorm_model.YounggeeSketchInfo{}).Where("task_id = ? and is_review = 1", submitTaskNeedModId).Order("reject_at desc").First(&taskSketchInfo)
+		if taskSketchInfo.AutoSketchBreakAt.IsZero() {
+			err4 := db1.Where("task_id = ?", submitTaskNeedModId).Updates(&gorm_model.YounggeeSketchInfo{AutoSketchBreakAt: taskSketchInfo.RejectAt.Add(dd)}).Error
+			if err4 != nil {
+				return err4
+			}
+			taskSketchInfo.AutoSketchBreakAt = taskSketchInfo.RejectAt.Add(dd)
+			fmt.Println("已添加 品牌种草-商品寄拍-修改后上传初稿未上传自动处理时间")
+		}
+
+		// 判断是否违约
+		if taskSketchInfo.TaskID != "" && taskSketchInfo.AutoSketchBreakAt.Sub(time.Now()) <= 0 {
+			db4 := GetReadDB(context.Background())
+			err1 := db4.Model(gorm_model.YoungeeContractInfo{}).Create(&gorm_model.YoungeeContractInfo{
+				TaskID: submitTaskNeedModId, ProjectID: TaskIdToProjectId[submitTaskNeedModId], BreakType: 2, BreakAt: time.Now(), DefaultStatus: 1}).Error
+			if err1 != nil {
+				return err1
+			}
+			taskInfo := gorm_model.YoungeeTaskInfo{}
+			dbt := GetReadDB(context.Background())
+			err2 := dbt.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Find(&taskInfo).Error
+			if err2 != nil {
+				return err2
+			}
+
+			// 计算违约扣款后的达人所得
+			settleAmount := taskInfo.DraftFee * (1.0 - float64(sketchDefaultRate+taskInfo.DataBreakRate+taskInfo.LinkBreakRate+taskInfo.ScriptBreakRate)/100)
+			if settleAmount <= 0 {
+				settleAmount = 0.
+			}
+
+			// 计算违约扣款后的服务商所得
+			realServiceCharge := taskInfo.ServiceCharge * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+sketchDefaultRate+taskInfo.ScriptBreakRate)/100)
+			if realServiceCharge <= 0 {
+				realServiceCharge = 0.0
+			}
+
+			// 计算企业需要实际支付金额
+			realPayment := settleAmount + realServiceCharge
+			if realPayment <= 0 {
+				realPayment = 0.0
+			}
+
+			db3 := GetReadDB(context.Background())
+			err2 = db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Updates(
+				map[string]interface{}{
+					"sketch_missing_status": 1,
+					"cur_default_type":      3,
+					"sketch_break_rate":     sketchDefaultRate,
+					"settle_amount":         settleAmount,
+					"err_break_rate":        sketchErrRate,
+					"real_service_charge":   realServiceCharge,
+					"real_payment":          realPayment,
+				}).Error
+			if err2 != nil {
+				return err2
+			}
+			createTaskLogErr := CreateTaskLog(context.Background(), submitTaskNeedModId, "初稿逾期")
+			if createTaskLogErr != nil {
+				log.WithContext(context.Background()).Errorf("[operate db] call CreateTaskLog error,err:%+v", createTaskLogErr)
+			}
+			createMessageByTaskIdErr := CreateMessageByTaskId(context.Background(), 22, 4, submitTaskNeedModId)
+			if createMessageByTaskIdErr != nil {
+				log.WithContext(context.Background()).Errorf("[operate db] call CreateMessageByTaskId error,err:%+v", createMessageByTaskIdErr)
+			}
+			fmt.Println("创建已提交初稿的初稿违约记录")
+		}
+	}
+	return nil
+}
+
+// GetAutoLinkDefaultTask 品牌种草 链接超时违约
+func GetAutoLinkDefaultTask() error {
+
+	// 1. 筛选出可能链接超时违约的子任务,首次/修改
+	db := GetReadDB(context.Background())
+	var projectInfos []*gorm_model.ProjectInfo
+	err := db.Model(gorm_model.ProjectInfo{}).Where("project_type = ?", 1).Find(&projectInfos).Error
+	if err != nil {
+		return err
+	}
+	var projectIds []string
+	// 任务id 对 项目id 的map
+	taskIdToProjectIdMap := map[string]string{}
+	// 项目id 对 定时任务id 的map
+	projectIdToAutoTaskIdMap := map[string]int{}
+	// 项目id 对 违约定时任务id 的map
+	projectIdToAutoDefaultIdMap := map[string]int{}
+	var taskIds []string
+	// taskId 对 稿费形式的 map
+	taskIdToFeeFormMap := make(map[string]int)
+	for _, projectInfo := range projectInfos {
+		projectIds = append(projectIds, projectInfo.ProjectID)
+		projectIdToAutoTaskIdMap[projectInfo.ProjectID] = int(projectInfo.AutoTaskID)
+		projectIdToAutoDefaultIdMap[projectInfo.ProjectID] = int(projectInfo.AutoDefaultID)
+
+		var taskInfos []*gorm_model.YoungeeTaskInfo
+		db1 := GetReadDB(context.Background())
+		db1.Model(&gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = ? AND task_stage = ? AND cur_default_type = ? ", projectInfo.ProjectID, 2, 11, 0).Find(&taskInfos)
+		for _, taskInfo := range taskInfos {
+			taskIdToProjectIdMap[taskInfo.TaskID] = projectInfo.ProjectID
+			taskIds = append(taskIds, taskInfo.TaskID)
+			taskIdToFeeFormMap[taskInfo.TaskID] = taskInfo.FeeForm
+		}
+	}
+	// 首次提交链接的任务记录id
+	var taskNeedModIds []string
+	// 已提交链接的任务记录id
+	var submitTaskNeedModIds []string
+	for _, taskId := range taskIds {
+		var taskInfo gorm_model.YoungeeTaskInfo
+		db3 := GetReadDB(context.Background())
+		// 保存所有链接上传状态为 1  且任务状态为12 的任务记录的id
+		db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskId).First(&taskInfo)
+		if taskInfo.LinkStatus == 1 && taskInfo.TaskStage == 11 {
+			taskNeedModIds = append(taskNeedModIds, taskId)
+		}
+		// 保存所有链接上传状态为 3  且任务状态为12 的任务记录的id
+		if taskInfo.LinkStatus == 3 && taskInfo.TaskStage == 11 {
+			submitTaskNeedModIds = append(submitTaskNeedModIds, taskId)
+		}
+	}
+
+	// 2. 对于需要初次上传链接但是未上传的子任务
+	for _, taskNeedModId := range taskNeedModIds {
+		db2 := GetReadDB(context.Background())
+		var linkBreach int32
+		db2.Model(&gorm_model.InfoAutoTask{}).Select("link_breach").Where("auto_task_id = ?", projectIdToAutoTaskIdMap[taskIdToProjectIdMap[taskNeedModId]]).First(&linkBreach)
+		dd, _ := time.ParseDuration(conv.MustString(linkBreach, "") + "h")
+
+		autoDefaultHandle := gorm_model.InfoAutoDefaultHandle{}
+		db6 := GetReadDB(context.Background())
+		db6.Model(gorm_model.InfoAutoDefaultHandle{}).Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[taskNeedModId]]).Find(&autoDefaultHandle)
+
+		var linkDefaultRate int
+		var linkErrRate int
+		if taskIdToFeeFormMap[taskNeedModId] == 1 {
+			linkDefaultRate = autoDefaultHandle.LinkReplaceTimeOut
+			linkErrRate = autoDefaultHandle.LinkReplaceNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("link_replace_time_out", "link_replace_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[taskNeedModId]]).Find(&linkDefaultRate, &linkErrRate)
+		} else {
+			linkDefaultRate = autoDefaultHandle.LinkOtherTimeOut
+			linkErrRate = autoDefaultHandle.LinkOtherNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("link_other_time_out", "link_other_not_uploadsg").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[taskNeedModId]]).Find(&linkDefaultRate, &linkErrRate)
+		}
+		db1 := GetReadDB(context.Background())
+		var taskSketchInfo gorm_model.YounggeeSketchInfo
+		db1.Model(gorm_model.YounggeeSketchInfo{}).Where("task_id = ? AND is_ok = ?", taskNeedModId, 1).Find(&taskSketchInfo)
+		dbTask := GetReadDB(context.Background())
+		var taskInfoCurr gorm_model.YoungeeTaskInfo
+		dbTask.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).Find(&taskInfoCurr)
+		if taskInfoCurr.LinkMissingTime.IsZero() {
+			// db1.Where("task_id = ?", taskNeedModId).Updates(&gorm_model.YounggeeSketchInfo{AutoLinkBreakAt: taskSketchInfo.AgreeAt.Add(dd)})
+			dbTask.Where("task_id = ?", taskNeedModId).Updates(&gorm_model.YoungeeTaskInfo{LinkMissingTime: taskSketchInfo.AgreeAt.Add(dd)})
+			fmt.Println("已添加链接违约自动处理时间")
+		} else {
+			if taskInfoCurr.TaskID != "" && taskInfoCurr.LinkMissingTime.Sub(time.Now()) <= 0 {
+				//db4 := GetReadDB(context.Background())
+				//err1 := db4.Model(gorm_model.YoungeeContractInfo{}).Create(&gorm_model.YoungeeContractInfo{
+				//	TaskID: taskNeedModId, ProjectID: taskIdToProjectIdMap[taskNeedModId], BreakType: 3, BreakAt: time.Now(), DefaultStatus: 1}).Error
+				//if err1 != nil {
+				//	return err1
+				//}
+				taskInfo := gorm_model.YoungeeTaskInfo{}
+				dbt := GetReadDB(context.Background())
+				err2 := dbt.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).Find(&taskInfo).Error
+				if err2 != nil {
+					return err2
+				}
+				// 达人实际所得
+				settleAmount := taskInfo.DraftFee * (1.0 - float64(linkDefaultRate+taskInfo.DataBreakRate+taskInfo.SketchBreakRate+taskInfo.ScriptBreakRate)/100)
+				if settleAmount <= 0 {
+					settleAmount = 0.0
+				}
+				// 服务商实际所得
+				realServiceCharge := taskInfo.ServiceCharge * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+linkDefaultRate+taskInfo.ScriptBreakRate)/100)
+				if realServiceCharge <= 0 {
+					realServiceCharge = 0.0
+				}
+				// 企业实际支付
+				realPayment := settleAmount + realServiceCharge
+				if realPayment <= 0 {
+					realPayment = 0.0
+				}
+				db3 := GetReadDB(context.Background())
+				err2 = db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).Updates(
+					map[string]interface{}{
+						"link_missing_status": 1,
+						"cur_default_type":    5,
+						"link_break_rate":     linkDefaultRate,
+						"settle_amount":       settleAmount,
+						"real_service_charge": realServiceCharge,
+						"err_break_rate":      linkErrRate,
+						"real_payment":        realPayment,
+					}).Error
+				if err2 != nil {
+					return err2
+				}
+				err = CreateTaskLog(context.Background(), taskNeedModId, "链接逾期")
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateTaskLog error,err:%+v", err)
+				}
+				err = CreateMessageByTaskId(context.Background(), 23, 4, taskNeedModId)
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateMessageByTaskId error,err:%+v", err)
+				}
+				fmt.Println("已创建链接违约记录")
+			}
+		}
+	}
+
+	// 3. 对于需要修改后上传的链接
+	for _, submitTaskNeedModId := range submitTaskNeedModIds {
+		db2 := GetReadDB(context.Background())
+		var LinkBreach int32
+		db2.Model(&gorm_model.InfoAutoTask{}).Select("link_breach").Where("auto_task_id = ?", projectIdToAutoTaskIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).First(&LinkBreach)
+		dd, _ := time.ParseDuration(conv.MustString(LinkBreach, "") + "h")
+
+		autoDefaultHandle := gorm_model.InfoAutoDefaultHandle{}
+		db6 := GetReadDB(context.Background())
+		db6.Model(gorm_model.InfoAutoDefaultHandle{}).Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).Find(&autoDefaultHandle)
+
+		var linkDefaultRate int
+		var linkErrRate int
+		if taskIdToFeeFormMap[submitTaskNeedModId] == 1 {
+			linkDefaultRate = autoDefaultHandle.LinkReplaceTimeOut
+			linkErrRate = autoDefaultHandle.LinkReplaceNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("link_replace_time_out", "link_replace_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).Find(&linkDefaultRate, &linkErrRate)
+		} else {
+			linkDefaultRate = autoDefaultHandle.LinkOtherTimeOut
+			linkErrRate = autoDefaultHandle.LinkOtherNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("link_other_time_out", "link_other_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).Find(&linkDefaultRate, &linkErrRate)
+		}
+		db1 := GetReadDB(context.Background())
+		var taskLinkInfo gorm_model.YounggeeLinkInfo
+		db1.Model(gorm_model.YounggeeLinkInfo{}).Where("task_id = ?", submitTaskNeedModId).Order("reject_at desc").First(&taskLinkInfo)
+		dbTask := GetReadDB(context.Background())
+		var taskInfoCurr gorm_model.YoungeeTaskInfo
+		dbTask.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Find(&taskInfoCurr)
+		if taskLinkInfo.AutoLinkBreakAt.IsZero() {
+			err4 := db1.Where("task_id = ?", submitTaskNeedModId).Updates(&gorm_model.YounggeeLinkInfo{AutoLinkBreakAt: taskLinkInfo.RejectAt.Add(dd)}).Error
+			if err4 != nil {
+				return err4
+			}
+			taskInfoCurrErr := dbTask.Where("task_id = ?", submitTaskNeedModId).Updates(&gorm_model.YoungeeTaskInfo{LinkMissingTime: taskLinkInfo.RejectAt.Add(dd)}).Error
+			if taskInfoCurrErr != nil {
+				return taskInfoCurrErr
+			}
+			fmt.Println("已添加链接违约自动处理时间")
+		} else {
+			if taskLinkInfo.TaskID != "" && taskLinkInfo.AutoLinkBreakAt.Sub(time.Now()) <= 0 {
+				//db4 := GetReadDB(context.Background())
+				//err1 := db4.Model(gorm_model.YoungeeContractInfo{}).Create(&gorm_model.YoungeeContractInfo{
+				//	TaskID: submitTaskNeedModId, ProjectID: taskIdToProjectIdMap[submitTaskNeedModId], BreakType: 3, BreakAt: time.Now(), DefaultStatus: 1}).Error
+				//if err1 != nil {
+				//	return err1
+				//}
+				taskInfo := gorm_model.YoungeeTaskInfo{}
+				dbt := GetReadDB(context.Background())
+				err2 := dbt.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Find(&taskInfo).Error
+				if err2 != nil {
+					return err2
+				}
+				// 达人实际所得
+				settleAmount := taskInfo.DraftFee * (1.0 - float64(linkDefaultRate+taskInfo.DataBreakRate+taskInfo.SketchBreakRate+taskInfo.ScriptBreakRate)/100)
+				if settleAmount <= 0 {
+					settleAmount = 0.0
+				}
+				// 服务商实际所得
+				realServiceCharge := taskInfo.ServiceCharge * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+linkDefaultRate+taskInfo.ScriptBreakRate)/100)
+				if realServiceCharge <= 0 {
+					realServiceCharge = 0.0
+				}
+				// 企业实际支付
+				realPayment := settleAmount + realServiceCharge
+				if realPayment <= 0 {
+					realPayment = 0.0
+				}
+				db3 := GetReadDB(context.Background())
+				err2 = db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Updates(
+					map[string]interface{}{
+						"link_missing_status": 1,
+						"cur_default_type":    5,
+						"link_break_rate":     linkDefaultRate,
+						"settle_amount":       settleAmount,
+						"real_service_charge": realServiceCharge,
+						"err_break_rate":      linkErrRate,
+						"real_payment":        realPayment,
+					}).Error
+				if err2 != nil {
+					return err2
+				}
+				err = CreateTaskLog(context.Background(), submitTaskNeedModId, "链接逾期")
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateTaskLog error,err:%+v", err)
+				}
+				err = CreateMessageByTaskId(context.Background(), 23, 4, submitTaskNeedModId)
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateMessageByTaskId error,err:%+v", err)
+				}
+				fmt.Println("创建已提交链接的链接违约记录")
+			}
+		}
+	}
+	return nil
+}
+
+// GetAutoCaseCloseDefaultTask 品牌种草 数据超时违约
+func GetAutoCaseCloseDefaultTask() error {
+
+	// 1. 筛选出可能数据违约的种草子任务 待上传/待修改
+	db := GetReadDB(context.Background())
+	var projectInfos []*gorm_model.ProjectInfo
+	err := db.Model(gorm_model.ProjectInfo{}).Where("project_type = ?", 1).Find(&projectInfos).Error
+	if err != nil {
+		return err
+	}
+	var projectIds []string
+	// 任务id 对 项目id 的map
+	taskIdToProjectIdMap := map[string]string{}
+	// 项目id 对 定时任务id 的map
+	projectIdToAutoTaskIdMap := map[string]int{}
+	// 项目id 对 违约定时任务id 的map
+	projectIdToAutoDefaultIdMap := map[string]int{}
+	var taskIds []string
+	for _, projectInfo := range projectInfos {
+		projectIds = append(projectIds, projectInfo.ProjectID)
+		projectIdToAutoTaskIdMap[projectInfo.ProjectID] = int(projectInfo.AutoTaskID)
+		projectIdToAutoDefaultIdMap[projectInfo.ProjectID] = int(projectInfo.AutoDefaultID)
+		var taskInfos []string
+		db1 := GetReadDB(context.Background())
+		db1.Select("task_id").Model(&gorm_model.YoungeeTaskInfo{}).Where("project_id = ? AND task_status = ? AND task_stage = ? AND cur_default_type = ? ", projectInfo.ProjectID, 2, 13, 0).Find(&taskInfos)
+		for _, taskInfo := range taskInfos {
+			taskIdToProjectIdMap[taskInfo] = projectInfo.ProjectID
+			taskIds = append(taskIds, taskInfo)
+		}
+	}
+	// 首次提交链接的任务记录id
+	var taskNeedModIds []string
+	// 已提交链接的任务记录id
+	var submitTaskNeedModIds []string
+	// taskId 对 稿费形式的 map
+	taskIdToFeeFormMap := make(map[string]int)
+	for _, taskId := range taskIds {
+		var taskInfo gorm_model.YoungeeTaskInfo
+		db3 := GetReadDB(context.Background())
+		// 保存所有数据上传状态为 1  且任务状态为14 的任务记录的id
+		db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskId).First(&taskInfo)
+		if taskInfo.DataStatus == 1 && taskInfo.TaskStage == 13 {
+			taskNeedModIds = append(taskNeedModIds, taskId)
+		}
+		// 保存所有数据上传状态为 3  且任务状态为14 的任务记录的id
+		if taskInfo.DataStatus == 3 && taskInfo.TaskStage == 13 {
+			submitTaskNeedModIds = append(submitTaskNeedModIds, taskId)
+		}
+		taskIdToFeeFormMap[taskId] = taskInfo.FeeForm
+	}
+
+	// 2. 对待上传数据的子任务判断
+	for _, taskNeedModId := range taskNeedModIds {
+		db2 := GetReadDB(context.Background())
+		var CaseCloseDefault int32
+		db2.Model(&gorm_model.InfoAutoTask{}).Select("case_close_default").Where("auto_task_id = ?", projectIdToAutoTaskIdMap[taskIdToProjectIdMap[taskNeedModId]]).First(&CaseCloseDefault)
+		dd, _ := time.ParseDuration(conv.MustString(CaseCloseDefault, "") + "h")
+
+		autoDefaultHandle := gorm_model.InfoAutoDefaultHandle{}
+		db6 := GetReadDB(context.Background())
+		db6.Model(gorm_model.InfoAutoDefaultHandle{}).Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[taskNeedModId]]).Find(&autoDefaultHandle)
+
+		var dataDefaultRate int
+		var dataErrRate int
+		if taskIdToFeeFormMap[taskNeedModId] == 1 {
+			dataDefaultRate = autoDefaultHandle.DataReplaceTimeOut
+			dataErrRate = autoDefaultHandle.DataReplaceNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("data_replace_time_out", "data_replace_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[taskNeedModId]]).Find(&dataDefaultRate, &dataErrRate)
+		} else {
+			dataDefaultRate = autoDefaultHandle.DataOtherTimeOut
+			dataErrRate = autoDefaultHandle.DataOtherNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("data_other_time_out", "data_other_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[taskNeedModId]]).Find(&dataDefaultRate, &dataErrRate)
+		}
+		//fmt.Println("dataDefaultRate:", dataDefaultRate)
+		db1 := GetReadDB(context.Background())
+		var taskLinkInfo gorm_model.YounggeeLinkInfo
+		db1.Model(gorm_model.YounggeeLinkInfo{}).Where("task_id = ? AND is_ok = ?", taskNeedModId, 1).Find(&taskLinkInfo)
+		dbTask := GetReadDB(context.Background())
+		var taskInfoCurr gorm_model.YoungeeTaskInfo
+		dbTask.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).Find(&taskInfoCurr)
+		if taskInfoCurr.DataMissingTime.IsZero() {
+			db1.Where("task_id = ?", taskNeedModId).Updates(&gorm_model.YounggeeLinkInfo{AutoDataBreakAt: taskLinkInfo.AgreeAt.Add(dd)})
+			dbTask.Where("task_id = ?", taskNeedModId).Updates(&gorm_model.YoungeeTaskInfo{DataMissingTime: taskLinkInfo.AgreeAt.Add(dd)})
+			fmt.Println("已添加数据违约自动处理时间")
+		} else {
+			if taskInfoCurr.TaskID != "" && taskInfoCurr.DataMissingTime.Sub(time.Now()) <= 0 {
+				//db4 := GetReadDB(context.Background())
+				//err1 := db4.Model(gorm_model.YoungeeContractInfo{}).Create(&gorm_model.YoungeeContractInfo{
+				//	TaskID: taskNeedModId, ProjectID: taskIdToProjectIdMap[taskNeedModId], BreakType: 4, BreakAt: time.Now(), DefaultStatus: 1}).Error
+				//if err1 != nil {
+				//	return err1
+				//}
+				taskInfo := gorm_model.YoungeeTaskInfo{}
+				dbt := GetReadDB(context.Background())
+				err2 := dbt.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).Find(&taskInfo).Error
+				if err2 != nil {
+					return err2
+				}
+				// 达人实际所得
+				settleAmount := taskInfo.DraftFee * (1.0 - float64(dataDefaultRate+taskInfo.DataBreakRate+taskInfo.SketchBreakRate+taskInfo.ScriptBreakRate)/100)
+				if settleAmount <= 0 {
+					settleAmount = 0.0
+				}
+				// 服务商实际所得
+				realServiceCharge := taskInfo.ServiceCharge * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+dataDefaultRate+taskInfo.ScriptBreakRate)/100)
+				if realServiceCharge <= 0 {
+					realServiceCharge = 0.0
+				}
+				// 企业实际支付
+				realPayment := settleAmount + realServiceCharge
+				if realPayment <= 0 {
+					realPayment = 0.0
+				}
+				fmt.Println("settleAmount: ", settleAmount)
+				db3 := GetReadDB(context.Background())
+				err2 = db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", taskNeedModId).Updates(
+					map[string]interface{}{
+						"data_missing_status": 1,
+						"cur_default_type":    7,
+						"sketch_break_rate":   dataDefaultRate,
+						"settle_amount":       settleAmount,
+						"err_break_rate":      dataErrRate,
+						"real_payment":        realPayment,
+						"real_service_charge": realServiceCharge,
+					}).Error
+				if err2 != nil {
+					return err2
+				}
+				err = CreateTaskLog(context.Background(), taskNeedModId, "数据逾期")
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateTaskLog error,err:%+v", err)
+				}
+				err = CreateMessageByTaskId(context.Background(), 24, 4, taskNeedModId)
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateMessageByTaskId error,err:%+v", err)
+				}
+				fmt.Println("已创建数据违约记录")
+			}
+		}
+	}
+
+	// 3. 针对待修改的子任务
+	for _, submitTaskNeedModId := range submitTaskNeedModIds {
+		db2 := GetReadDB(context.Background())
+		var LinkBreach int32
+		db2.Model(&gorm_model.InfoAutoTask{}).Select("case_close_default").Where("auto_task_id = ?", projectIdToAutoTaskIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).First(&LinkBreach)
+		dd, _ := time.ParseDuration(conv.MustString(LinkBreach, "") + "h")
+
+		autoDefaultHandle := gorm_model.InfoAutoDefaultHandle{}
+		db6 := GetReadDB(context.Background())
+		db6.Model(gorm_model.InfoAutoDefaultHandle{}).Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).Find(&autoDefaultHandle)
+
+		var dataDefaultRate int
+		var dataErrRate int
+		if taskIdToFeeFormMap[submitTaskNeedModId] == 1 {
+			dataDefaultRate = autoDefaultHandle.DataReplaceTimeOut
+			dataErrRate = autoDefaultHandle.DataReplaceNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("data_replace_time_out", "data_replace_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).Find(&dataDefaultRate, &dataErrRate)
+		} else {
+			dataDefaultRate = autoDefaultHandle.DataOtherTimeOut
+			dataErrRate = autoDefaultHandle.DataOtherNotUpload
+			// db6 := GetReadDB(context.Background())
+			// db6.Model(gorm_model.InfoAutoDefaultHandle{}).Select("data_other_time_out", "data_other_not_upload").Where("auto_default_id = ?", projectIdToAutoDefaultIdMap[taskIdToProjectIdMap[submitTaskNeedModId]]).Find(&dataDefaultRate, &dataErrRate)
+		}
+		db1 := GetReadDB(context.Background())
+		var taskDataInfo gorm_model.YounggeeDataInfo
+		db1.Model(gorm_model.YounggeeDataInfo{}).Where("task_id = ? and is_review = 1", submitTaskNeedModId).Order("reject_at desc").First(&taskDataInfo)
+		if taskDataInfo.AutoDataBreakAt.IsZero() {
+			err4 := db1.Where("task_id = ?", submitTaskNeedModId).Updates(&gorm_model.YounggeeDataInfo{AutoDataBreakAt: taskDataInfo.RejectAt.Add(dd)}).Error
+			if err4 != nil {
+				return err4
+			}
+			fmt.Println("已添加数据违约自动处理时间")
+		} else {
+			if taskDataInfo.TaskID != "" && taskDataInfo.AutoDataBreakAt.Sub(time.Now()) <= 0 {
+				db4 := GetReadDB(context.Background())
+				err1 := db4.Model(gorm_model.YoungeeContractInfo{}).Create(&gorm_model.YoungeeContractInfo{
+					TaskID: submitTaskNeedModId, ProjectID: taskIdToProjectIdMap[submitTaskNeedModId], BreakType: 4, BreakAt: time.Now(), DefaultStatus: 1}).Error
+				if err1 != nil {
+					return err1
+				}
+				taskInfo := gorm_model.YoungeeTaskInfo{}
+				dbt := GetReadDB(context.Background())
+				err2 := dbt.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Find(&taskInfo).Error
+				if err2 != nil {
+					return err2
+				}
+				// 达人实际所得
+				settleAmount := taskInfo.DraftFee * (1.0 - float64(dataDefaultRate+taskInfo.DataBreakRate+taskInfo.SketchBreakRate+taskInfo.ScriptBreakRate)/100)
+				if settleAmount <= 0 {
+					settleAmount = 0.0
+				}
+				// 服务商实际所得
+				realServiceCharge := taskInfo.ServiceCharge * (1.0 - float64(taskInfo.LinkBreakRate+taskInfo.DataBreakRate+dataDefaultRate+taskInfo.ScriptBreakRate)/100)
+				if realServiceCharge <= 0 {
+					realServiceCharge = 0.0
+				}
+				// 企业实际支付
+				realPayment := settleAmount + realServiceCharge
+				if realPayment <= 0 {
+					realPayment = 0.0
+				}
+				db3 := GetReadDB(context.Background())
+				err2 = db3.Model(gorm_model.YoungeeTaskInfo{}).Where("task_id = ?", submitTaskNeedModId).Updates(
+					map[string]interface{}{
+						"data_missing_status": 1,
+						"cur_default_type":    7,
+						"sketch_break_rate":   dataDefaultRate,
+						"settle_amount":       settleAmount,
+						"err_break_rate":      dataErrRate,
+						"real_payment":        realPayment,
+						"real_service_charge": realServiceCharge,
+					}).Error
+				if err2 != nil {
+					return err2
+				}
+				err = CreateTaskLog(context.Background(), submitTaskNeedModId, "数据逾期")
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateTaskLog error,err:%+v", err)
+				}
+				err = CreateMessageByTaskId(context.Background(), 24, 4, submitTaskNeedModId)
+				if err != nil {
+					log.WithContext(context.Background()).Errorf("[operate db] call CreateMessageByTaskId error,err:%+v", err)
+				}
+				fmt.Println("创建已提交数据的数据违约记录")
+			}
+		}
+	}
+	return nil
+}

+ 2 - 24
go.mod

@@ -11,22 +11,15 @@ require (
 )
 
 require (
-	github.com/BurntSushi/toml v0.3.1 // indirect
 	github.com/KyleBanks/depth v1.2.1 // indirect
 	github.com/PuerkitoBio/purell v1.1.1 // indirect
 	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
 	github.com/agiledragon/gomonkey v2.0.2+incompatible // indirect
 	github.com/agiledragon/gomonkey/v2 v2.3.1 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
-	github.com/chzyer/logex v1.1.10 // indirect
-	github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect
-	github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
-	github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
-	github.com/creack/pty v1.1.9 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/fsnotify/fsnotify v1.4.9 // indirect
-	github.com/ghodss/yaml v1.0.0 // indirect
 	github.com/gin-contrib/gzip v0.0.3 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
 	github.com/go-openapi/jsonpointer v0.19.5 // indirect
@@ -36,27 +29,18 @@ require (
 	github.com/go-playground/locales v0.14.0 // indirect
 	github.com/go-playground/universal-translator v0.18.0 // indirect
 	github.com/go-sql-driver/mysql v1.6.0 // indirect
-	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
 	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/go-cmp v0.5.5 // indirect
-	github.com/google/gofuzz v1.0.0 // indirect
-	github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
-	github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 // indirect
-	github.com/hpcloud/tail v1.0.0 // indirect
 	github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.117 // indirect
-	github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 // indirect
 	github.com/issue9/assert/v2 v2.0.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
-	github.com/jtolds/gls v4.20.0+incompatible // indirect
 	github.com/kr/pretty v0.3.0 // indirect
-	github.com/kr/pty v1.1.1 // indirect
 	github.com/kr/text v0.2.0 // indirect
 	github.com/leodido/go-urn v1.2.1 // indirect
 	github.com/lin-jim-leon/kuaishou v0.3.0 // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
-	github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
 	github.com/nxadm/tail v1.4.8 // indirect
 	github.com/onsi/ginkgo v1.16.5 // indirect
 	github.com/onsi/ginkgo/v2 v2.0.0 // indirect
@@ -64,28 +48,23 @@ require (
 	github.com/otiai10/copy v1.7.0 // indirect
 	github.com/otiai10/curr v1.0.0 // indirect
 	github.com/otiai10/mint v1.3.3 // indirect
-	github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/rogpeppe/go-internal v1.8.0 // indirect
-	github.com/russross/blackfriday/v2 v2.0.1 // indirect
-	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
-	github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
-	github.com/smartystreets/goconvey v1.6.4 // indirect
-	github.com/stretchr/objx v0.5.0 // indirect
 	github.com/stretchr/testify v1.8.4 // indirect
 	github.com/tidwall/match v1.1.1 // indirect
 	github.com/tidwall/pretty v1.2.0 // indirect
 	github.com/tjfoc/gmsm v1.4.1 // indirect
 	github.com/ugorji/go/codec v1.2.7 // indirect
+	go.mongodb.org/mongo-driver v1.12.0 // indirect
 	github.com/urfave/cli/v2 v2.3.0 // indirect
 	github.com/yuin/goldmark v1.4.13 // indirect
 	go.mongodb.org/mongo-driver v1.12.0 // indirect
 	golang.org/x/mod v0.8.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/term v0.20.0 // indirect
 	golang.org/x/text v0.15.0 // indirect
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/errgo.v2 v2.1.0 // indirect
 	gopkg.in/fsnotify.v1 v1.4.7 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
@@ -111,7 +90,6 @@ require (
 	github.com/swaggo/gin-swagger v1.4.1
 	github.com/swaggo/swag v1.8.1
 	github.com/tidwall/gjson v1.14.1
-	github.com/ugorji/go v1.2.7 // indirect
 	github.com/wechatpay-apiv3/wechatpay-go v0.2.15
 	golang.org/x/crypto v0.23.0 // indirect
 	golang.org/x/net v0.21.0 // indirect

+ 14 - 5
main.go

@@ -3,6 +3,8 @@ package main
 import (
 	"fmt"
 	"github.com/gin-gonic/gin"
+	log "github.com/sirupsen/logrus"
+	"youngee_b_api/app/schedule"
 	"youngee_b_api/config"
 	_ "youngee_b_api/docs"
 	"youngee_b_api/route"
@@ -18,10 +20,17 @@ func main() {
 	service.SMTPMailServiceIstance.Init(mailConfig)
 
 	addr := fmt.Sprintf("%v:%v", config.Host, config.Port)
-	//err := service.AutoTask()
-	//err := schedule.AutoTask()
-	//if err != nil {
-	//	log.Println("service AutoTask error:", err)
-	//}
+	err := service.AutoTask()
+	if err != nil {
+		log.Println("service AutoTask error:", err)
+	}
+	err1 := schedule.AutoTask1()
+	if err1 != nil {
+		log.Println("schedule AutoTask1 error:", err1)
+	}
+	err2 := schedule.AutoTask2()
+	if err2 != nil {
+		log.Println("schedule AutoTask2 error:", err2)
+	}
 	r.Run(addr) // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
 }

+ 2 - 1
model/gorm_model/info_auto_task.go

@@ -16,7 +16,8 @@ type InfoAutoTask struct {
 	ScriptDefault     int `gorm:"column:script_default"`                          // 脚本违约自动处理
 	LinkBreach        int `gorm:"column:link_breach"`                             // 链接违约自动处理
 	CaseCloseDefault  int `gorm:"column:case_close_default"`                      // 数据违约时间
-	DraftDefault      int `gorm:"column:draft_default;NOT NULL"`                  // 初稿违约时间
+	DraftDefault      int `gorm:"column:draft_default;NOT NULL"`
+	EnterpriseId     string `gorm:"column:enterprise_id"`//   企业ID
 }
 
 func (m *InfoAutoTask) TableName() string {

+ 0 - 1
model/gorm_model/project.go

@@ -1,4 +1,3 @@
-// Code generated by sql2gorm. DO NOT EDIT.
 package gorm_model
 
 import (

+ 1 - 0
model/gorm_model/project_task.go

@@ -24,6 +24,7 @@ type YoungeeTaskInfo struct {
 	DataBreakRate          int       `gorm:"column:data_break_rate;default:0;NOT NULL"`   // 数据上传超时违约扣款比例,百分之
 	FeeForm                int       `gorm:"column:fee_form;NOT NULL"`                    // 稿费形式,1,2,3分别代表产品置换、固定稿费、自报价
 	ServiceCharge          float64   `gorm:"column:service_charge"`                       // 服务费
+	RealServiceCharge      float64   `gorm:"column:real_service_charge"`                  // 服务商实际所得服务费(扣除违约)
 	ServiceRate            int       `gorm:"column:service_rate"`                         // 服务费率,千分之
 	TaskStatus             int       `gorm:"column:task_status;default:1;NOT NULL"`       // 任务状态 1待选 2已选 3落选
 	TaskStage              int       `gorm:"column:task_stage;NOT NULL"`                  // 任务阶段,详情见info_task_stage表

+ 21 - 24
model/gorm_model/recruit_strategy.go

@@ -1,34 +1,31 @@
-// Code generated by sql2gorm. DO NOT EDIT.
 package gorm_model
 
-
 type RecruitStrategy struct {
-	RecruitStrategyID int64    `gorm:"column:recruit_strategy_id;primary_key;AUTO_INCREMENT"` // 招募策略id
-	FeeForm           int64    `gorm:"column:fee_form"`                                       // 稿费形式,1-3分别代表产品置换、固定稿费、自报价
-	StrategyID        int64    `gorm:"column:strategy_id"`                                    // 策略id
-	FollowersLow      int64    `gorm:"column:followers_low"`                                  // 达人粉丝数下限
-	FollowersUp       int64    `gorm:"column:followers_up"`                                   // 达人粉丝数上限
-	RecruitNumber     int64    `gorm:"column:recruit_number"`                                 // 招募数量
+	RecruitStrategyID int64   `gorm:"column:recruit_strategy_id;primary_key;AUTO_INCREMENT"` // 招募策略id
+	FeeForm           int64   `gorm:"column:fee_form"`                                       // 稿费形式,1-3分别代表产品置换、固定稿费、自报价
+	StrategyID        int64   `gorm:"column:strategy_id"`                                    // 策略id
+	FollowersLow      int64   `gorm:"column:followers_low"`                                  // 达人粉丝数下限
+	FollowersUp       int64   `gorm:"column:followers_up"`                                   // 达人粉丝数上限
+	RecruitNumber     int64   `gorm:"column:recruit_number"`                                 // 招募数量
 	Offer             float64 `gorm:"column:offer"`                                          // 报价
 	TOffer            float64 `gorm:"column:t_offer"`                                        // 达人所见报价
-	ProjectID         string   `gorm:"column:project_id"`                                     // 所属项目id
-	ServiceCharge     float64    `gorm:"column:service_charge"`                                 // 平台服务费,稿费形式为产品置换时必填
-	SelectedNumber    int64    `gorm:"column:selected_number;default:0"`                      // 已选数量,被企业选择的达人数量
-	WaitingNumber     int64    `gorm:"column:waiting_number;default:0"`                       // 待发货
-	DeliveredNumber   int64    `gorm:"column:delivered_number;default:0"`                     // 已发货
-	SignedNumber      int64    `gorm:"column:signed_number;default:0"`                        // 已签收
-	MaxOffer          int64    `gorm:"column:max_offer;default:0"`                            // 报价上限
-	MinOffer          int64    `gorm:"column:min_offer;default:0"`                            // 报价下限
-	FanNumber         int64    `gorm:"column:fan_number;default:0"`                           // 总粉丝量
-	PlayNumber        int64    `gorm:"column:play_number;default:0"`                          // 总播放量
-	LikeNumber        int64    `gorm:"column:like_number;default:0"`                          // 总点赞数
-	CollectNumber     int64    `gorm:"column:collect_number;default:0"`                       // 总收藏量
-	CommentNumber     int64    `gorm:"column:comment_number;default:0"`                       // 总评论数
-	FinishNumber      int64    `gorm:"column:finish_number;default:0"`                        // 结案数量
-	TotalOffer        float64    `gorm:"column:total_offer;default:0"`                          // 支付合计
+	ProjectID         string  `gorm:"column:project_id"`                                     // 所属项目id
+	ServiceCharge     float64 `gorm:"column:service_charge"`                                 // 平台服务费,稿费形式为产品置换时必填
+	SelectedNumber    int64   `gorm:"column:selected_number;default:0"`                      // 已选数量,被企业选择的达人数量
+	WaitingNumber     int64   `gorm:"column:waiting_number;default:0"`                       // 待发货
+	DeliveredNumber   int64   `gorm:"column:delivered_number;default:0"`                     // 已发货
+	SignedNumber      int64   `gorm:"column:signed_number;default:0"`                        // 已签收
+	MaxOffer          int64   `gorm:"column:max_offer;default:0"`                            // 报价上限
+	MinOffer          int64   `gorm:"column:min_offer;default:0"`                            // 报价下限
+	FanNumber         int64   `gorm:"column:fan_number;default:0"`                           // 总粉丝量
+	PlayNumber        int64   `gorm:"column:play_number;default:0"`                          // 总播放量
+	LikeNumber        int64   `gorm:"column:like_number;default:0"`                          // 总点赞数
+	CollectNumber     int64   `gorm:"column:collect_number;default:0"`                       // 总收藏量
+	CommentNumber     int64   `gorm:"column:comment_number;default:0"`                       // 总评论数
+	FinishNumber      int64   `gorm:"column:finish_number;default:0"`                        // 结案数量
+	TotalOffer        float64 `gorm:"column:total_offer;default:0"`                          // 支付合计
 }
 
 func (m *RecruitStrategy) TableName() string {
 	return "recruit_strategy"
 }
-

+ 0 - 2
model/gorm_model/sketch.go

@@ -1,7 +1,5 @@
 package gorm_model
 
-// Code generated by sql2gorm. DO NOT EDIT.
-
 import (
 	"time"
 )

+ 35 - 15
route/init.go

@@ -1,6 +1,8 @@
 package route
 
 import (
+	swaggerFiles "github.com/swaggo/files"
+	ginSwagger "github.com/swaggo/gin-swagger"
 	"youngee_b_api/app/controller"
 	"youngee_b_api/handler"
 	"youngee_b_api/middleware"
@@ -11,14 +13,14 @@ import (
 )
 
 func InitRoute(r *gin.Engine) {
-	//r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
-	//r.POST("/register", handler.WrapRegisterHandler)                 // 商家主账号注册
-	//r.POST("/addNewSubAccount", handler.WrapAddNewSubAccountHandler) // 商家子账号注册
-	//r.POST("/addNewJob", handler.WrapaddNewJobHandler)               // 商家新增岗位
-	//r.POST("/updateJob", handler.WrapupdateJobHandler)               // 商家修改岗位
-	//r.POST("/deleteJob", handler.WrapdeleteJobHandler)               // 商家删除岗位
-	//r.POST("/sendCode", handler.WrapSendCodeHandler)                 // 发送登录验证码
-	//r.POST("/login", handler.WrapCodeLoginHandler)                   // 商家登录
+	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
+	r.POST("/register", handler.WrapRegisterHandler)                 // 商家主账号注册
+	r.POST("/addNewSubAccount", handler.WrapAddNewSubAccountHandler) // 商家子账号注册
+	r.POST("/addNewJob", handler.WrapaddNewJobHandler)               // 商家新增岗位
+	r.POST("/updateJob", handler.WrapupdateJobHandler)               // 商家修改岗位
+	r.POST("/deleteJob", handler.WrapdeleteJobHandler)               // 商家删除岗位
+	r.POST("/sendCode", handler.WrapSendCodeHandler)                 // 发送登录验证码
+	r.POST("/login", handler.WrapCodeLoginHandler)                   // 商家登录
 	r.GET("/test/ping", func(c *gin.Context) {
 		resp := http_model.CommonResponse{
 			Status:  0,
@@ -147,7 +149,7 @@ func InitRoute(r *gin.Engine) {
 		s.POST("/selection/task/list", handler.WrapGetSecTaskListHandler)                     // 查询选品的任务列表(确定、发货、结算)
 		s.POST("/selection/task/coop/pass", handler.WrapPassSecTaskCoopHandler)               // 同意任务合作
 		s.POST("/selection/task/coop/refuse", handler.WrapRefuseSecTaskCoopHandler)           // 拒绝任务合作
-		s.POST("/selection/task/logistics/create", handler.WrapCreateSecTaskLogisticsHandler) // 上传物流信息
+		s.POST("/selection/task/logistics/create", handler.WrapCreateSecTaskLogisticsHandler) // 上传物流信息 **
 		s.POST("/selection/task/logistics/update", handler.WrapUpdateSecTaskLogisticsHandler) // 修改物流信息
 		s.POST("/selection/task/settle", handler.WrapSettleSecTaskHandler)                    // 结算
 		s.POST("/selection/getAllSelection", handler.WrapGetAllSelectionHandler)              // 查询选品广场选品列表
@@ -180,7 +182,7 @@ func InitRoute(r *gin.Engine) {
 		task.POST("/project/target/update", controller.TaskController{}.UpdateProjectTarget) // 更新定向种草任务
 		task.POST("/project/detail", controller.TaskController{}.GetProjectDetail)           // 品牌种草任务预览
 		task.POST("/project/toReview", controller.TaskController{}.ProjectToReview)          // 种草提交审核
-		task.POST("/project/task/list", controller.TaskController{}.ProjectTaskList)         // 公开种草任务列表
+		task.POST("/project/task/list", controller.TaskController{}.ProjectTaskList)         // 种草任务列表
 		task.POST("/project/del", controller.TaskController{}.ProjectDel)                    // 删除种草任务
 
 		task.POST("/project/getTasklist", handler.WrapGetTaskListHandler)            //招募中选达人列表/查名单
@@ -223,19 +225,37 @@ func InitRoute(r *gin.Engine) {
 		task.POST("/default/talent/cancel", controller.TaskController{}.CancelTalent)                    // 违约管理——达人解约
 		task.POST("/default/talent/cancel/list", controller.TaskController{}.CancelTalentList)           // 违约管理——达人批量解约
 
+		// 服务商合作
+		task.POST("/supplier/list", controller.TaskController{}.GetSupplierInTargetTaskList) // 服务商合作-服务商列表
+		task.POST("/supplier/invite", controller.TaskController{}.InviteSupplier)            // 服务商合作-邀约合作
 	}
 	// 财务结算相关接口
 	finance := r.Group("/youngee/b/finance")
 	{
 		finance.Use(middleware.LoginAuthMiddleware)
-		// 余额管理——总金额、可用余额、冻结金额
-		// 余额管理——冻结记录
-		// 充值管理——累计充值金额、确认中金额
-		// 充值管理——充值记录
-		// YG官方汇款账号
 		finance.POST("/recharge/transferToPublic", controller.FinanceController{}.TransferToPublic)  // 充值管理——对公转账
 		finance.POST("/pay/getCodeUrl", controller.FinanceController{}.GetCodeUrl)                   // 获取微信支付codeURL
 		finance.POST("/pay/queryOrderByTradeId", controller.FinanceController{}.QueryOrderByTradeId) // 根据交易id查询微信是否扫码付款
+		finance.POST("/balance/show", controller.FinanceController{}.ShowBalance)                    // 余额管理——总金额、可用余额、冻结金额
+		finance.POST("/balance/frozen/info", controller.FinanceController{}.FrozenInfoList)          // 余额管理——冻结记录
+		finance.POST("/recharge/show", controller.FinanceController{}.ShowRecharge)                  // 充值管理——累计充值金额、确认中金额
+		finance.POST("/recharge/info", controller.FinanceController{}.RechargeInfoList)              // 充值管理——充值记录
+		// YG官方汇款账号
+		finance.POST("/invoice/default/update", controller.FinanceController{}.UpdateInvoiceDefault) // 设置默认开票抬头
+		finance.POST("/invoice/default/get", controller.FinanceController{}.GetInvoiceDefault)       // 获取默认开票抬头
+		finance.POST("/invoice/bill", controller.FinanceController{}.BillInvoice)                    // 确认开票
+		finance.POST("/invoice/list/bill", controller.FinanceController{}.GetBillList)               // 开票记录
+		finance.POST("/invoice/list/billable", controller.FinanceController{}.GetBillableList)       // 可开票账单
+	}
+	// 推广合作-服务商相关接口
+	cooperation := r.Group("/youngee/b/cooperation/supplier")
+	{
+		cooperation.Use(middleware.LoginAuthMiddleware)
+		cooperation.POST("/link", controller.CooperationController{}.GetSupplierLink)                 // 服务商端链接
+		cooperation.POST("/search", controller.CooperationController{}.SearchSupplier)                // 服务商搜索
+		cooperation.POST("/invite", controller.CooperationController{}.InviteSupplier)                // 服务商入库批量邀请
+		cooperation.POST("/inPool", controller.CooperationController{}.GetEnterprisePoolList)         // 在库服务商列表
+		cooperation.POST("/confirming", controller.CooperationController{}.GetSupplierConfirmingList) // 邀请待确认服务商列表
 	}
 
 }

+ 62 - 14
service/autoTask.go

@@ -1,6 +1,7 @@
 package service
 
 import (
+	"fmt"
 	"github.com/robfig/cron/v3"
 	log "github.com/sirupsen/logrus"
 	"time"
@@ -9,24 +10,44 @@ import (
 
 func AutoTask() error {
 	c := cron.New(cron.WithSeconds())
-	spec := "0 */30 * * * ?" //cron表达式,每半小时执行一次
-	//spec := "0 */1 * * * ?" //cron表达式,每1分钟一次
+	//spec := "0 */30 * * * ?" //cron表达式,每半小时执行一次
+	spec := "0 */2 * * * ?" //cron表达式,每1分钟一次
 	//spec := "*/10 * * * * ?" //cron表达式,每10秒一次
-	_, err1 := c.AddFunc(spec, AutoTaskUpdateStatus)
-	if err1 != nil {
-		log.Println("service [AutoTaskUpdateStatus] error:", err1)
-		return err1
+
+	/*
+		_, err1 := c.AddFunc(spec, AutoTaskUpdateStatus)
+		if err1 != nil {
+			log.Println("service [AutoTaskUpdateStatus] error:", err1)
+			return err1
+		}
+		_, err2 := c.AddFunc("@midnight", AutoTaskUpdateApplyTimes)
+		if err2 != nil {
+			log.Println("service [AutoTaskUpdateApplyTimes] error:", err2)
+			return err2
+		}
+		_, err3 := c.AddFunc(spec, AutoTaskCompleteSelection)
+		if err3 != nil {
+			log.Println("service [AutoTaskCompleteSecTask] error:", err2)
+			return err3
+		}
+
+	*/
+	_, err4 := c.AddFunc(spec, GetAutoDraftDefaultTask)
+	if err4 != nil {
+		log.Println("service [GetAutoDraftDefaultTask] error:", err4)
+		return err4
 	}
-	_, err2 := c.AddFunc("@midnight", AutoTaskUpdateApplyTimes)
-	if err2 != nil {
-		log.Println("service [AutoTaskUpdateApplyTimes] error:", err2)
-		return err2
+	_, err5 := c.AddFunc(spec, GetAutoLinkDefaultTask)
+	if err5 != nil {
+		log.Println("service [GetAutoLinkDefaultTask] error:", err4)
+		return err5
 	}
-	_, err3 := c.AddFunc(spec, AutoTaskCompleteSelection)
-	if err3 != nil {
-		log.Println("service [AutoTaskCompleteSecTask] error:", err2)
-		return err3
+	_, err6 := c.AddFunc(spec, GetAutoCaseCloseDefaultTask)
+	if err6 != nil {
+		log.Println("service [GetAutoCaseCloseDefaultTask] error:", err4)
+		return err6
 	}
+	fmt.Println(spec)
 	c.Start()
 	return nil
 }
@@ -54,3 +75,30 @@ func AutoTaskCompleteSelection() {
 		log.Println("AutoUpdateApplyTimes error : ", err)
 	}
 }
+
+// GetAutoDraftDefaultTask 初稿超时违约
+func GetAutoDraftDefaultTask() {
+	err := db.GetAutoDraftDefaultTask()
+	log.Println("GetAutoDraftDefaultInPicTask is running ,Time :", time.Now())
+	if err != nil {
+		log.Println("GetAutoDraftDefaultInPicTask error : ", err)
+	}
+}
+
+// GetAutoLinkDefaultTask 链接超时违约
+func GetAutoLinkDefaultTask() {
+	err := db.GetAutoLinkDefaultTask()
+	log.Println("GetAutoLinkDefaultTask is running ,Time :", time.Now())
+	if err != nil {
+		log.Println("GetAutoDraftDefaultInPicTask error : ", err)
+	}
+}
+
+// GetAutoCaseCloseDefaultTask 数据超时违约
+func GetAutoCaseCloseDefaultTask() {
+	err := db.GetAutoCaseCloseDefaultTask()
+	log.Println("GetAutoCaseCloseDefaultTask is running ,Time :", time.Now())
+	if err != nil {
+		log.Println("GetAutoCaseCloseDefaultTask error : ", err)
+	}
+}

+ 1 - 0
service/logistics.go

@@ -222,6 +222,7 @@ func (*logistics) SignForReceipt(ctx *gin.Context, data http_model.SignForReceip
 	return nil
 }
 
+// **
 func (l *logistics) CreateSpecialLogistics(ctx context.Context, newLogistics http_model.CreateSpecialLogisticsRequest) (*http_model.SpecialLogisticsData, error) {
 	ThingsType := newLogistics.ThingsType
 	Logistics := gorm_model.YoungeeTaskLogistics{