project_service.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. package service
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "github.com/issue9/conv"
  6. "github.com/sirupsen/logrus"
  7. "reflect"
  8. "time"
  9. "youngee_b_api/app/dao"
  10. "youngee_b_api/app/entity"
  11. "youngee_b_api/app/util"
  12. "youngee_b_api/app/vo"
  13. )
  14. type ProjectService struct{}
  15. // 创建种草任务
  16. func (s ProjectService) CreateProject(param *vo.ProjectCreateParam) (*string, error) {
  17. // a) 生成种草项目id
  18. projectId := util.GetProjectID()
  19. // b) 查找关联商品信息
  20. product, err := dao.ProductDAO{}.GetProductByID(conv.MustInt64(param.ProductId, 0))
  21. if err != nil {
  22. return nil, err
  23. }
  24. if product == nil {
  25. return nil, errors.New("未找到关联商品")
  26. }
  27. productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(param.ProductId)
  28. productInfoToJson, _ := json.Marshal(product)
  29. productPhotosToJson, _ := json.Marshal(productPhotos)
  30. // d)创建种草任务
  31. t := time.Now()
  32. newProject := entity.Project{
  33. ProjectStatus: 1,
  34. ProjectType: param.ProjectType,
  35. ProjectId: projectId,
  36. ProductID: param.ProductId,
  37. EnterpriseID: param.EnterpriseId,
  38. SubAccountId: param.SubAccountId,
  39. ProjectPlatform: param.Platform,
  40. ProductSnap: string(productInfoToJson),
  41. ProductPhotoSnap: string(productPhotosToJson),
  42. CreatedAt: t,
  43. UpdatedAt: t,
  44. EstimatedCost: 0,
  45. SettlementAmount: 0,
  46. }
  47. err = dao.ProjectDAO{}.CreateProject(newProject)
  48. if err != nil {
  49. return nil, err
  50. }
  51. return &projectId, nil
  52. }
  53. // 更新公开种草任务(招募要求、执行要求)
  54. func (s ProjectService) UpdateProject(projectUpdateParam *vo.ProjectUpdateParam) (*string, error) {
  55. // 1. 检查该企业id和商品id有无种草任务
  56. projectID := projectUpdateParam.ProjectID
  57. project, err := dao.ProjectDAO{}.GetProjectById(projectID)
  58. if err != nil {
  59. return nil, err
  60. }
  61. if project == nil {
  62. return nil, errors.New("种草项目不存在")
  63. }
  64. // 2. 数据准备
  65. // a) 查找关联商品信息
  66. product, err := dao.ProductDAO{}.GetProductByID(project.ProductID)
  67. if err != nil {
  68. return nil, err
  69. }
  70. productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(project.ProductID)
  71. productInfoToJson, _ := json.Marshal(product)
  72. productPhotosToJson, _ := json.Marshal(productPhotos)
  73. // d) 任务截止时间
  74. recruitDdl := time.Time{} //赋零值
  75. recruitDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", projectUpdateParam.RecruitDdl, time.Local)
  76. // f) 更新选品状态
  77. if projectUpdateParam.ProjectStatus != 2 && projectUpdateParam.ProjectStatus != 8 {
  78. projectUpdateParam.ProjectStatus = 1
  79. }
  80. t := time.Now()
  81. updateProject := entity.Project{
  82. EnterpriseID: projectUpdateParam.EnterpriseId,
  83. SubAccountId: projectUpdateParam.SubAccountId,
  84. ProjectId: projectUpdateParam.ProjectID,
  85. ProjectType: projectUpdateParam.ProjectType,
  86. ProjectStatus: projectUpdateParam.ProjectStatus,
  87. ProjectName: projectUpdateParam.ProjectName,
  88. ProductID: projectUpdateParam.ProductId,
  89. TalentType: projectUpdateParam.TalentType,
  90. RecruitDdl: recruitDdl,
  91. ProductSnap: string(productInfoToJson),
  92. ProductPhotoSnap: string(productPhotosToJson),
  93. CreatedAt: project.CreatedAt,
  94. UpdatedAt: t,
  95. ProjectForm: projectUpdateParam.ProjectForm,
  96. ContentType: projectUpdateParam.ContentType,
  97. ProjectDetail: projectUpdateParam.ProjectDetail,
  98. }
  99. if projectUpdateParam.ProjectStatus == 2 {
  100. updateProject.SubmitAt = t
  101. }
  102. // 合并传入参数和数据表中原记录,若传入参数字段值为空,则将字段赋值为原记录中值
  103. result := util.MergeStructValue(&updateProject, project)
  104. // 利用反射机制将interface类型转换为结构体类型
  105. v := reflect.ValueOf(&result).Elem()
  106. if v.Kind() == reflect.Struct {
  107. updateProject = v.Interface().(entity.Project)
  108. //fmt.Println(p)
  109. }
  110. // c) 计算预估成本(如果有)
  111. /*
  112. var estimatedCost float64
  113. if conv.MustInt(updateSelection.TaskMode, 0) == 1 {
  114. estimatedCost = conv.MustFloat64(updateSelection.TaskReward, 0) * conv.MustFloat64(updateSelection.SampleNum, 0)
  115. }
  116. estimatedCostToString, _ := conv.String(estimatedCost)
  117. updateSelection.EstimatedCost = estimatedCostToString
  118. */
  119. // 3. 更新选品
  120. err = dao.ProjectDAO{}.UpdateProject(updateProject)
  121. if err != nil {
  122. return nil, err
  123. }
  124. // 4. 更新选品brief和示例(种草任务补充信息)
  125. if projectUpdateParam.ProjectBrief != nil {
  126. // 删除已有brief
  127. err = dao.ProjectBriefDao{}.DeleteSecBriefBySelectionId(project.ProjectId)
  128. if err != nil {
  129. return nil, err
  130. }
  131. // 插入新的brief
  132. for _, v := range projectUpdateParam.ProjectBrief {
  133. brief := entity.ProjectBrief{
  134. ProjectID: project.ProjectId,
  135. FileUid: v.FileUid,
  136. FileName: v.Name,
  137. FileUrl: v.FileUrl,
  138. CreatedAt: time.Now(),
  139. }
  140. err = dao.ProjectBriefDao{}.CreateProjectBrief(brief)
  141. if err != nil {
  142. return nil, err
  143. }
  144. }
  145. }
  146. if projectUpdateParam.ProjectMaterial != nil {
  147. // 删除已有示例
  148. err = dao.ProjectMaterialDao{}.DeleteProjectMaterialByProjectId(project.ProjectId)
  149. if err != nil {
  150. return nil, err
  151. }
  152. // 插入新的示例
  153. for _, v := range projectUpdateParam.ProjectMaterial {
  154. projectMaterial := entity.ProjectMaterial{
  155. ProjectID: project.ProjectId,
  156. FileUid: v.FileUid,
  157. FileName: v.Name,
  158. FileUrl: v.FileUrl,
  159. CreatedAt: time.Now(),
  160. }
  161. err = dao.ProjectMaterialDao{}.CreateProjectMaterial(projectMaterial)
  162. if err != nil {
  163. return nil, err
  164. }
  165. }
  166. }
  167. println("更新种草任务的招募策略")
  168. // 更新种草任务的招募策略
  169. if projectUpdateParam.RecruitStrategys != nil {
  170. // 1. 删除已有的招募策略
  171. err = dao.RecruitStrategyDao{}.DeleteRecruitStrategyByProjectID(projectUpdateParam.ProjectID)
  172. if err != nil {
  173. return nil, err
  174. }
  175. // 2. 接收并创建新的招募策略
  176. if len(projectUpdateParam.RecruitStrategys) != 0 {
  177. var recruits []entity.RecruitStrategy
  178. for _, strategy := range projectUpdateParam.RecruitStrategys {
  179. // 查询对应定价策略
  180. pricingStrategy, err := dao.InfoPricingStrategylDao{}.GetPricingStrategy(strategy.FollowersLow, strategy.FollowersUp, strategy.FeeForm, project.ProjectPlatform)
  181. if err != nil {
  182. return nil, err
  183. }
  184. // 根据定价策略计算达人所见报价
  185. if strategy.FeeForm == 2 {
  186. strategy.TOffer = strategy.Offer * (1 - conv.MustFloat64(pricingStrategy.ServiceRate)/1000)
  187. }
  188. recruitStrategy := entity.RecruitStrategy{
  189. FeeForm: conv.MustInt64(strategy.FeeForm),
  190. StrategyID: conv.MustInt64(strategy.StrategyID),
  191. FollowersLow: conv.MustInt64(strategy.FollowersLow),
  192. FollowersUp: conv.MustInt64(strategy.FollowersUp),
  193. RecruitNumber: conv.MustInt64(strategy.RecruitNumber),
  194. ServiceCharge: strategy.ServiceCharge,
  195. Offer: strategy.Offer,
  196. TOffer: strategy.TOffer,
  197. ProjectID: project.ProjectId,
  198. }
  199. //fmt.Printf("Offer:\t %+v", Strategy.Offer)
  200. recruits = append(recruits, recruitStrategy)
  201. }
  202. err = dao.RecruitStrategyDao{}.CreateRecruitStrategy(recruits)
  203. if err != nil {
  204. return nil, err
  205. }
  206. }
  207. }
  208. return &updateProject.ProjectId, nil
  209. }
  210. // 更新定向种草任务(招募要求、执行要求)
  211. func (s ProjectService) UpdateProjectTarget(projectUpdateParam *vo.ProjectUpdateParam) (*string, error) {
  212. // 1. 检查该企业id和商品id有无种草任务
  213. projectID := projectUpdateParam.ProjectID
  214. project, err := dao.ProjectDAO{}.GetProjectById(projectID)
  215. if err != nil {
  216. return nil, err
  217. }
  218. if project == nil {
  219. return nil, errors.New("种草项目不存在")
  220. }
  221. // 2. 数据准备
  222. // a) 查找关联商品信息
  223. product, err := dao.ProductDAO{}.GetProductByID(project.ProductID)
  224. if err != nil {
  225. return nil, err
  226. }
  227. productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(project.ProductID)
  228. productInfoToJson, _ := json.Marshal(product)
  229. productPhotosToJson, _ := json.Marshal(productPhotos)
  230. // d) 任务截止时间
  231. recruitDdl := time.Time{} //赋零值
  232. recruitDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", projectUpdateParam.RecruitDdl, time.Local)
  233. // f) 更新选品状态
  234. if projectUpdateParam.ProjectStatus != 2 && projectUpdateParam.ProjectStatus != 8 {
  235. projectUpdateParam.ProjectStatus = 1
  236. }
  237. t := time.Now()
  238. updateProject := entity.Project{
  239. EnterpriseID: projectUpdateParam.EnterpriseId,
  240. SubAccountId: projectUpdateParam.SubAccountId,
  241. ProjectId: projectUpdateParam.ProjectID,
  242. ProjectType: projectUpdateParam.ProjectType,
  243. ProjectStatus: projectUpdateParam.ProjectStatus,
  244. ProjectName: projectUpdateParam.ProjectName,
  245. ProductID: projectUpdateParam.ProductId,
  246. TalentType: projectUpdateParam.TalentType,
  247. RecruitDdl: recruitDdl,
  248. ProductSnap: string(productInfoToJson),
  249. ProductPhotoSnap: string(productPhotosToJson),
  250. CreatedAt: project.CreatedAt,
  251. UpdatedAt: t,
  252. ProjectForm: projectUpdateParam.ProjectForm,
  253. ContentType: projectUpdateParam.ContentType,
  254. ProjectDetail: projectUpdateParam.ProjectDetail,
  255. }
  256. if projectUpdateParam.ProjectStatus == 2 {
  257. updateProject.SubmitAt = t
  258. }
  259. // 合并传入参数和数据表中原记录,若传入参数字段值为空,则将字段赋值为原记录中值
  260. result := util.MergeStructValue(&updateProject, project)
  261. // 利用反射机制将interface类型转换为结构体类型
  262. v := reflect.ValueOf(&result).Elem()
  263. if v.Kind() == reflect.Struct {
  264. updateProject = v.Interface().(entity.Project)
  265. //fmt.Println(p)
  266. }
  267. // c) 计算预估成本(如果有)
  268. /*
  269. var estimatedCost float64
  270. if conv.MustInt(updateSelection.TaskMode, 0) == 1 {
  271. estimatedCost = conv.MustFloat64(updateSelection.TaskReward, 0) * conv.MustFloat64(updateSelection.SampleNum, 0)
  272. }
  273. estimatedCostToString, _ := conv.String(estimatedCost)
  274. updateSelection.EstimatedCost = estimatedCostToString
  275. */
  276. // 3. 更新选品
  277. err = dao.ProjectDAO{}.UpdateProject(updateProject)
  278. if err != nil {
  279. return nil, err
  280. }
  281. // 4. 更新选品brief和示例(种草任务补充信息)
  282. if projectUpdateParam.ProjectBrief != nil {
  283. // 删除已有brief
  284. err = dao.ProjectBriefDao{}.DeleteSecBriefBySelectionId(project.ProjectId)
  285. if err != nil {
  286. return nil, err
  287. }
  288. // 插入新的brief
  289. for _, v := range projectUpdateParam.ProjectBrief {
  290. brief := entity.ProjectBrief{
  291. ProjectID: project.ProjectId,
  292. FileUid: v.FileUid,
  293. FileName: v.Name,
  294. FileUrl: v.FileUrl,
  295. CreatedAt: time.Now(),
  296. }
  297. err = dao.ProjectBriefDao{}.CreateProjectBrief(brief)
  298. if err != nil {
  299. return nil, err
  300. }
  301. }
  302. }
  303. if projectUpdateParam.ProjectMaterial != nil {
  304. // 删除已有示例
  305. err = dao.ProjectMaterialDao{}.DeleteProjectMaterialByProjectId(project.ProjectId)
  306. if err != nil {
  307. return nil, err
  308. }
  309. // 插入新的示例
  310. for _, v := range projectUpdateParam.ProjectMaterial {
  311. projectMaterial := entity.ProjectMaterial{
  312. ProjectID: project.ProjectId,
  313. FileUid: v.FileUid,
  314. FileName: v.Name,
  315. FileUrl: v.FileUrl,
  316. CreatedAt: time.Now(),
  317. }
  318. err = dao.ProjectMaterialDao{}.CreateProjectMaterial(projectMaterial)
  319. if err != nil {
  320. return nil, err
  321. }
  322. }
  323. }
  324. println("更新种草任务的招募策略")
  325. // 更新种草任务的招募策略
  326. if projectUpdateParam.RecruitStrategys != nil {
  327. // 1. 删除已有的招募策略
  328. err = dao.RecruitStrategyDao{}.DeleteRecruitStrategyByProjectID(projectUpdateParam.ProjectID)
  329. if err != nil {
  330. return nil, err
  331. }
  332. // 2. 接收并创建新的招募策略
  333. if len(projectUpdateParam.RecruitStrategys) != 0 {
  334. var recruits []entity.RecruitStrategy
  335. for _, strategy := range projectUpdateParam.RecruitStrategys {
  336. //// 查询对应定价策略
  337. //pricingStrategy, err := dao.InfoPricingStrategylDao{}.GetPricingStrategy(strategy.FollowersLow, strategy.FollowersUp, strategy.FeeForm, project.ProjectPlatform)
  338. //if err != nil {
  339. // return nil, err
  340. //}
  341. //// 根据定价策略计算达人所见报价
  342. //if strategy.FeeForm == 2 {
  343. // strategy.TOffer = strategy.Offer * (1 - conv.MustFloat64(pricingStrategy.ServiceRate)/1000)
  344. //}
  345. recruitStrategy := entity.RecruitStrategy{
  346. FeeForm: conv.MustInt64(strategy.FeeForm),
  347. StrategyID: conv.MustInt64(strategy.StrategyID),
  348. FollowersLow: conv.MustInt64(strategy.FollowersLow),
  349. FollowersUp: conv.MustInt64(strategy.FollowersUp),
  350. //ServiceCharge: strategy.ServiceCharge,
  351. Offer: strategy.Offer,
  352. //TOffer: strategy.TOffer,
  353. ProjectID: project.ProjectId,
  354. }
  355. //fmt.Printf("Offer:\t %+v", Strategy.Offer)
  356. recruits = append(recruits, recruitStrategy)
  357. }
  358. err = dao.RecruitStrategyDao{}.CreateRecruitStrategy(recruits)
  359. if err != nil {
  360. return nil, err
  361. }
  362. }
  363. }
  364. return &updateProject.ProjectId, nil
  365. }
  366. // 种草任务预览
  367. func (s ProjectService) GetProjectDetail(projectId string) (*vo.ReProjectDetail, error) {
  368. projectDetail := vo.ReProjectDetail{}
  369. project, err := dao.ProjectDAO{}.GetProjectById(projectId)
  370. if err != nil {
  371. logrus.Errorf("[projectDB service] call GetProject error,err:%+v", err)
  372. return nil, err
  373. }
  374. projectBriefInfos, err := dao.ProjectBriefDao{}.GetProjectBriefInfo(projectId)
  375. if err != nil {
  376. logrus.Errorf("[projectDB service] call GetProjectBriefInfo error,err:%+v", err)
  377. return nil, err
  378. }
  379. projectMaterials, err := dao.ProjectMaterialDao{}.GetProjectMaterialInfo(projectId)
  380. if err != nil {
  381. logrus.Errorf("[projectDB service] call GetprojectMaterialInfo error,err:%+v", err)
  382. return nil, err
  383. }
  384. productInfo, err := dao.ProductDAO{}.GetProductByProjectId(projectId)
  385. if err != nil {
  386. logrus.Errorf("[projectDB service] call GetProductInfo error,err:%+v", err)
  387. return nil, err
  388. }
  389. productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotosByProjectId(projectId)
  390. if err != nil {
  391. logrus.Errorf("[projectDB service] call GetProductPhotoInfo error,err:%+v", err)
  392. return nil, err
  393. }
  394. // 查找招募策略
  395. recruitStrategys, err := dao.RecruitStrategyDao{}.GetRecruitStrategyByProjectId(projectId)
  396. if err != nil {
  397. logrus.Errorf("[projectDB service] call GetRecruitStrategy error,err:%+v", err)
  398. return nil, err
  399. }
  400. projectDetail.ProjectBriefs = projectBriefInfos
  401. projectDetail.Project = project
  402. projectDetail.ProjectMaterials = projectMaterials
  403. projectDetail.ProductInfo = productInfo
  404. projectDetail.ProductPhotos = productPhotos
  405. projectDetail.RecruitStrategys = recruitStrategys
  406. return &projectDetail, nil
  407. }