project_service.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  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. var operatorType int64
  32. if param.SubAccountId == 0 {
  33. operatorType = 1
  34. } else {
  35. operatorType = 2
  36. }
  37. t := time.Now()
  38. newProject := entity.Project{
  39. ProjectStatus: 1,
  40. ProjectType: param.ProjectType,
  41. ProjectId: projectId,
  42. ProductID: param.ProductId,
  43. EnterpriseID: param.EnterpriseId,
  44. SubAccountId: param.SubAccountId,
  45. ProjectPlatform: param.Platform,
  46. OperatorType: operatorType,
  47. ProductSnap: string(productInfoToJson),
  48. ProductPhotoSnap: string(productPhotosToJson),
  49. CreatedAt: t,
  50. }
  51. if param.ProjectType == 1 {
  52. newProject.ServiceChargeRate = param.ServiceChargeRate
  53. }
  54. err = dao.ProjectDAO{}.CreateProject(newProject)
  55. if err != nil {
  56. return nil, err
  57. }
  58. return &projectId, nil
  59. }
  60. // 更新公开种草任务(招募要求、执行要求)
  61. func (s ProjectService) UpdateProject(projectUpdateParam *vo.ProjectUpdateParam) (*string, error) {
  62. // 1. 检查该企业id和商品id有无种草任务
  63. projectID := projectUpdateParam.ProjectID
  64. project, err := dao.ProjectDAO{}.GetProjectById(projectID)
  65. if err != nil {
  66. return nil, err
  67. }
  68. if project == nil {
  69. return nil, errors.New("种草项目不存在")
  70. }
  71. println("更新公开种草任务的招募策略")
  72. // 更新公开种草任务的招募策略
  73. var totalRecruitNum int64
  74. if projectUpdateParam.RecruitStrategys != nil {
  75. // 1. 删除已有的招募策略
  76. err = dao.RecruitStrategyDao{}.DeleteRecruitStrategyByProjectID(projectUpdateParam.ProjectID)
  77. if err != nil {
  78. return nil, err
  79. }
  80. // 2. 接收并创建新的招募策略
  81. if len(projectUpdateParam.RecruitStrategys) != 0 {
  82. var recruits []entity.RecruitStrategy
  83. for _, strategy := range projectUpdateParam.RecruitStrategys {
  84. recruitStrategy := entity.RecruitStrategy{
  85. FeeForm: strategy.FeeForm,
  86. StrategyID: strategy.StrategyID,
  87. FollowersLow: strategy.FollowersLow,
  88. FollowersUp: strategy.FollowersUp,
  89. RecruitNumber: strategy.RecruitNumber,
  90. ProjectID: project.ProjectId,
  91. }
  92. totalRecruitNum += strategy.RecruitNumber
  93. if strategy.FeeForm == 2 {
  94. recruitStrategy.Offer = strategy.Offer
  95. recruitStrategy.ServiceCharge = strategy.Offer * projectUpdateParam.ServiceChargeRate
  96. recruitStrategy.TOffer = strategy.Offer * (1 - projectUpdateParam.ServiceChargeRate)
  97. }
  98. recruits = append(recruits, recruitStrategy)
  99. }
  100. err = dao.RecruitStrategyDao{}.CreateRecruitStrategy(recruits)
  101. if err != nil {
  102. return nil, err
  103. }
  104. }
  105. }
  106. // 2. 数据准备
  107. // a) 查找关联商品信息
  108. product, err := dao.ProductDAO{}.GetProductByID(project.ProductID)
  109. if err != nil {
  110. return nil, err
  111. }
  112. productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(project.ProductID)
  113. productInfoToJson, _ := json.Marshal(product)
  114. productPhotosToJson, _ := json.Marshal(productPhotos)
  115. // d) 任务截止时间
  116. recruitDdl := time.Time{} //赋零值
  117. recruitDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", projectUpdateParam.RecruitDdl, time.Local)
  118. // f) 更新选品状态
  119. if projectUpdateParam.ProjectStatus != 2 && projectUpdateParam.ProjectStatus != 8 {
  120. projectUpdateParam.ProjectStatus = 1
  121. }
  122. t := time.Now()
  123. updateProject := entity.Project{
  124. EnterpriseID: projectUpdateParam.EnterpriseId,
  125. SubAccountId: projectUpdateParam.SubAccountId,
  126. ProjectId: projectUpdateParam.ProjectID,
  127. ProjectType: projectUpdateParam.ProjectType,
  128. ProjectStatus: projectUpdateParam.ProjectStatus,
  129. ProjectName: projectUpdateParam.ProjectName,
  130. ProductID: projectUpdateParam.ProductId,
  131. TalentType: projectUpdateParam.TalentType,
  132. RecruitDdl: recruitDdl,
  133. ProductSnap: string(productInfoToJson),
  134. ProductPhotoSnap: string(productPhotosToJson),
  135. UpdatedAt: t,
  136. ProjectForm: projectUpdateParam.ProjectForm,
  137. ContentType: projectUpdateParam.ContentType,
  138. ProjectDetail: projectUpdateParam.ProjectDetail,
  139. }
  140. if projectUpdateParam.ProjectStatus == 2 {
  141. updateProject.SubmitAt = t
  142. }
  143. // 合并传入参数和数据表中原记录,若传入参数字段值为空,则将字段赋值为原记录中值
  144. result := util.MergeStructValue(&updateProject, project)
  145. // 利用反射机制将interface类型转换为结构体类型
  146. v := reflect.ValueOf(&result).Elem()
  147. if v.Kind() == reflect.Struct {
  148. updateProject = v.Interface().(entity.Project)
  149. //fmt.Println(p)
  150. }
  151. // c) 计算预估成本(如果有)
  152. /*
  153. var estimatedCost float64
  154. if conv.MustInt(updateSelection.TaskMode, 0) == 1 {
  155. estimatedCost = conv.MustFloat64(updateSelection.TaskReward, 0) * conv.MustFloat64(updateSelection.SampleNum, 0)
  156. }
  157. estimatedCostToString, _ := conv.String(estimatedCost)
  158. updateSelection.EstimatedCost = estimatedCostToString
  159. */
  160. // 3. 更新选品
  161. err = dao.ProjectDAO{}.UpdateProject(updateProject)
  162. if err != nil {
  163. return nil, err
  164. }
  165. // 4. 更新选品brief和示例(种草任务补充信息)
  166. if projectUpdateParam.ProjectBrief != nil {
  167. // 删除已有brief
  168. err = dao.ProjectBriefDao{}.DeleteSecBriefBySelectionId(project.ProjectId)
  169. if err != nil {
  170. return nil, err
  171. }
  172. // 插入新的brief
  173. for _, v := range projectUpdateParam.ProjectBrief {
  174. brief := entity.ProjectBrief{
  175. ProjectID: project.ProjectId,
  176. FileUid: v.FileUid,
  177. FileName: v.Name,
  178. FileUrl: v.FileUrl,
  179. CreatedAt: time.Now(),
  180. }
  181. err = dao.ProjectBriefDao{}.CreateProjectBrief(brief)
  182. if err != nil {
  183. return nil, err
  184. }
  185. }
  186. }
  187. if projectUpdateParam.ProjectMaterial != nil {
  188. // 删除已有示例
  189. err = dao.ProjectMaterialDao{}.DeleteProjectMaterialByProjectId(project.ProjectId)
  190. if err != nil {
  191. return nil, err
  192. }
  193. // 插入新的示例
  194. for _, v := range projectUpdateParam.ProjectMaterial {
  195. projectMaterial := entity.ProjectMaterial{
  196. ProjectID: project.ProjectId,
  197. FileUid: v.FileUid,
  198. FileName: v.Name,
  199. FileUrl: v.FileUrl,
  200. CreatedAt: time.Now(),
  201. }
  202. err = dao.ProjectMaterialDao{}.CreateProjectMaterial(projectMaterial)
  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. println("更新定向种草任务的招募策略")
  222. // 更新定向种草任务的招募策略
  223. var totalRecruitNum int64
  224. if projectUpdateParam.RecruitStrategys != nil {
  225. // 1. 删除已有的招募策略
  226. err = dao.RecruitStrategyDao{}.DeleteRecruitStrategyByProjectID(projectUpdateParam.ProjectID)
  227. if err != nil {
  228. return nil, err
  229. }
  230. // 2. 接收并创建新的招募策略
  231. if len(projectUpdateParam.RecruitStrategys) != 0 {
  232. var recruits []entity.RecruitStrategy
  233. for _, strategy := range projectUpdateParam.RecruitStrategys {
  234. recruitStrategy := entity.RecruitStrategy{
  235. FeeForm: strategy.FeeForm,
  236. StrategyID: strategy.StrategyID,
  237. FollowersLow: strategy.FollowersLow,
  238. FollowersUp: strategy.FollowersUp,
  239. RecruitNumber: strategy.RecruitNumber,
  240. ProjectID: project.ProjectId,
  241. }
  242. totalRecruitNum += strategy.RecruitNumber
  243. if strategy.FeeForm == 2 {
  244. recruitStrategy.Offer = strategy.Offer // 报价
  245. }
  246. recruits = append(recruits, recruitStrategy)
  247. }
  248. err = dao.RecruitStrategyDao{}.CreateRecruitStrategy(recruits)
  249. if err != nil {
  250. return nil, err
  251. }
  252. }
  253. }
  254. // 2. 数据准备
  255. // a) 查找关联商品信息
  256. product, err := dao.ProductDAO{}.GetProductByID(project.ProductID)
  257. if err != nil {
  258. return nil, err
  259. }
  260. productPhotos, err := dao.ProductPhotoDAO{}.GetProductPhotoByProductID(project.ProductID)
  261. productInfoToJson, _ := json.Marshal(product)
  262. productPhotosToJson, _ := json.Marshal(productPhotos)
  263. // d) 任务截止时间
  264. recruitDdl := time.Time{} //赋零值
  265. recruitDdl, _ = time.ParseInLocation("2006-01-02 15:04:05", projectUpdateParam.RecruitDdl, time.Local)
  266. // f) 更新选品状态
  267. if projectUpdateParam.ProjectStatus != 2 && projectUpdateParam.ProjectStatus != 8 {
  268. projectUpdateParam.ProjectStatus = 1
  269. }
  270. t := time.Now()
  271. updateProject := entity.Project{
  272. EnterpriseID: projectUpdateParam.EnterpriseId,
  273. SubAccountId: projectUpdateParam.SubAccountId,
  274. ProjectId: projectUpdateParam.ProjectID,
  275. ProjectType: projectUpdateParam.ProjectType,
  276. ProjectStatus: projectUpdateParam.ProjectStatus,
  277. ProjectName: projectUpdateParam.ProjectName,
  278. ProductID: projectUpdateParam.ProductId,
  279. TalentType: projectUpdateParam.TalentType,
  280. RecruitDdl: recruitDdl,
  281. ProductSnap: string(productInfoToJson),
  282. ProductPhotoSnap: string(productPhotosToJson),
  283. CreatedAt: project.CreatedAt,
  284. UpdatedAt: t,
  285. ProjectForm: projectUpdateParam.ProjectForm,
  286. ContentType: projectUpdateParam.ContentType,
  287. ProjectDetail: projectUpdateParam.ProjectDetail,
  288. Tools: projectUpdateParam.Tools,
  289. }
  290. if projectUpdateParam.ProjectStatus == 2 {
  291. updateProject.SubmitAt = t
  292. }
  293. // 合并传入参数和数据表中原记录,若传入参数字段值为空,则将字段赋值为原记录中值
  294. result := util.MergeStructValue(&updateProject, project)
  295. // 利用反射机制将interface类型转换为结构体类型
  296. v := reflect.ValueOf(&result).Elem()
  297. if v.Kind() == reflect.Struct {
  298. updateProject = v.Interface().(entity.Project)
  299. //fmt.Println(p)
  300. }
  301. // c) 计算预估成本(如果有)
  302. /*
  303. var estimatedCost float64
  304. if conv.MustInt(updateSelection.TaskMode, 0) == 1 {
  305. estimatedCost = conv.MustFloat64(updateSelection.TaskReward, 0) * conv.MustFloat64(updateSelection.SampleNum, 0)
  306. }
  307. estimatedCostToString, _ := conv.String(estimatedCost)
  308. updateSelection.EstimatedCost = estimatedCostToString
  309. */
  310. // 3. 更新选品
  311. err = dao.ProjectDAO{}.UpdateProject(updateProject)
  312. if err != nil {
  313. return nil, err
  314. }
  315. // 4. 更新选品brief和示例(种草任务补充信息)
  316. if projectUpdateParam.ProjectBrief != nil {
  317. // 删除已有brief
  318. err = dao.ProjectBriefDao{}.DeleteSecBriefBySelectionId(project.ProjectId)
  319. if err != nil {
  320. return nil, err
  321. }
  322. // 插入新的brief
  323. for _, v := range projectUpdateParam.ProjectBrief {
  324. brief := entity.ProjectBrief{
  325. ProjectID: project.ProjectId,
  326. FileUid: v.FileUid,
  327. FileName: v.Name,
  328. FileUrl: v.FileUrl,
  329. CreatedAt: time.Now(),
  330. }
  331. err = dao.ProjectBriefDao{}.CreateProjectBrief(brief)
  332. if err != nil {
  333. return nil, err
  334. }
  335. }
  336. }
  337. if projectUpdateParam.ProjectMaterial != nil {
  338. // 删除已有示例
  339. err = dao.ProjectMaterialDao{}.DeleteProjectMaterialByProjectId(project.ProjectId)
  340. if err != nil {
  341. return nil, err
  342. }
  343. // 插入新的示例
  344. for _, v := range projectUpdateParam.ProjectMaterial {
  345. projectMaterial := entity.ProjectMaterial{
  346. ProjectID: project.ProjectId,
  347. FileUid: v.FileUid,
  348. FileName: v.Name,
  349. FileUrl: v.FileUrl,
  350. CreatedAt: time.Now(),
  351. }
  352. err = dao.ProjectMaterialDao{}.CreateProjectMaterial(projectMaterial)
  353. if err != nil {
  354. return nil, err
  355. }
  356. }
  357. }
  358. return &updateProject.ProjectId, nil
  359. }
  360. // 种草任务预览
  361. func (s ProjectService) GetProjectDetail(projectId string) (*vo.ReProjectDetail, error) {
  362. reProjectDetail := vo.ReProjectDetail{}
  363. project, err := dao.ProjectDAO{}.GetProjectById(projectId)
  364. if err != nil {
  365. logrus.Errorf("[projectDB service] call GetProject error,err:%+v", err)
  366. return nil, err
  367. }
  368. // 系统信息
  369. reProjectDetail.ProjectId = projectId
  370. reProjectDetail.ProjectStatus = project.ProjectStatus
  371. reProjectDetail.ProjectPlatform = project.ProjectPlatform
  372. reProjectDetail.CreatedAt = project.CreatedAt
  373. reProjectDetail.EstimatedCost = project.EstimatedCost
  374. reProjectDetail.ServiceChargeRate = project.ServiceChargeRate
  375. var creatorName, phone string
  376. if project.SubAccountId == 0 {
  377. enterprise, err := dao.EnterpriseDao{}.GetEnterprise(project.EnterpriseID)
  378. if err == nil && enterprise != nil {
  379. creatorName = enterprise.BusinessName
  380. phone, err = dao.UserDao{}.GetPhoneByUserId(enterprise.UserId)
  381. }
  382. } else {
  383. subAccount, err := dao.SubAccountDao{}.GetSubAccount(project.SubAccountId)
  384. if err == nil && subAccount != nil {
  385. creatorName = subAccount.SubAccountName
  386. phone, err = dao.UserDao{}.GetPhoneByUserId(subAccount.UserId)
  387. }
  388. }
  389. reProjectDetail.CreatorName = creatorName
  390. reProjectDetail.Phone = phone
  391. // 关联商品
  392. var reProduct vo.ReTaskProduct
  393. product, err := dao.ProductDAO{}.GetProductByID(project.ProductID)
  394. if err == nil {
  395. photoUrl, e := dao.ProductPhotoDAO{}.GetMainPhotoByProductID(product.ProductID)
  396. if e != nil {
  397. photoUrl = ""
  398. }
  399. reProduct = vo.ReTaskProduct{
  400. ProductID: product.ProductID,
  401. ProductName: product.ProductName,
  402. ProductType: product.ProductType,
  403. ProductCategory: product.ProductCategory,
  404. ProductPrice: product.ProductPrice,
  405. ProductDetail: product.ProductDetail,
  406. CreatedAt: product.CreatedAt,
  407. PhotoUrl: photoUrl,
  408. }
  409. }
  410. reProjectDetail.ProductInfo = &reProduct
  411. // 招募要求
  412. reProjectDetail.TalentType = project.TalentType
  413. reProjectDetail.RecruitDdl = project.RecruitDdl
  414. reProjectDetail.ProjectForm = project.ProjectForm
  415. reProjectDetail.ContentType = project.ContentType
  416. reProjectDetail.ProjectDetail = project.ProjectDetail
  417. var recruitStrategysPreviews []*vo.RecruitStrategyPreview
  418. recruitStrategys, err := dao.RecruitStrategyDao{}.GetRecruitStrategyByProjectId(projectId)
  419. if err != nil {
  420. logrus.Errorf("[projectDB service] call GetRecruitStrategy error,err:%+v", err)
  421. return nil, err
  422. }
  423. for _, recruitStrategy := range recruitStrategys {
  424. recruitStrategysPreview := &vo.RecruitStrategyPreview{
  425. StrategyId: recruitStrategy.StrategyID,
  426. FeeForm: recruitStrategy.FeeForm,
  427. FollowersLow: recruitStrategy.FollowersLow,
  428. FollowersUp: recruitStrategy.FollowersUp,
  429. RecruitNumber: recruitStrategy.RecruitNumber,
  430. Offer: recruitStrategy.Offer,
  431. TOffer: recruitStrategy.TOffer,
  432. ServiceCharge: recruitStrategy.ServiceCharge,
  433. SelectedNumber: recruitStrategy.SelectedNumber,
  434. TotalOffer: recruitStrategy.TotalOffer,
  435. }
  436. recruitStrategysPreviews = append(recruitStrategysPreviews, recruitStrategysPreview)
  437. }
  438. reProjectDetail.RecruitStrategys = recruitStrategysPreviews
  439. // 执行要求
  440. projectBriefInfos, err := dao.ProjectBriefDao{}.GetProjectBriefInfo(projectId)
  441. if err != nil {
  442. logrus.Errorf("[projectDB service] call GetProjectBriefInfo error,err:%+v", err)
  443. return nil, err
  444. }
  445. projectMaterials, err := dao.ProjectMaterialDao{}.GetProjectMaterialInfo(projectId)
  446. if err != nil {
  447. logrus.Errorf("[projectDB service] call GetprojectMaterialInfo error,err:%+v", err)
  448. return nil, err
  449. }
  450. reProjectDetail.ProjectBriefs = projectBriefInfos
  451. reProjectDetail.ProjectMaterials = projectMaterials
  452. reProjectDetail.Tools = project.Tools
  453. return &reProjectDetail, nil
  454. }
  455. // 公开种草任务列表
  456. func (s ProjectService) GetProjectTaskList(param *vo.ProjectSearchParam) (vo.ResultVO, error) {
  457. if param.Page == 0 {
  458. param.Page = 1
  459. }
  460. if param.PageSize == 0 {
  461. param.PageSize = 10
  462. }
  463. var result vo.ResultVO
  464. reProjectTaskPreviews, total, err := (&dao.ProjectDAO{}).GetProjectPreviews(param)
  465. if err != nil {
  466. return result, err
  467. }
  468. for i := range reProjectTaskPreviews {
  469. var creatorName string
  470. var productName string
  471. var productPrice float64
  472. var mainImage string
  473. if reProjectTaskPreviews[i].SubAccountId == 0 {
  474. enterprise, err := dao.EnterpriseDao{}.GetEnterprise(reProjectTaskPreviews[i].EnterpriseId)
  475. if err == nil && enterprise != nil {
  476. creatorName = enterprise.BusinessName
  477. }
  478. } else {
  479. subAccount, err := dao.SubAccountDao{}.GetSubAccount(reProjectTaskPreviews[i].SubAccountId)
  480. if err == nil && subAccount != nil {
  481. creatorName = subAccount.SubAccountName
  482. }
  483. }
  484. product, err := dao.ProductDAO{}.GetProductByID(reProjectTaskPreviews[i].ProductId)
  485. if err == nil && product != nil {
  486. productName = product.ProductName
  487. productPrice = product.ProductPrice
  488. }
  489. mainImage, err = dao.ProductPhotoDAO{}.GetMainPhotoByProductID(reProjectTaskPreviews[i].ProductId)
  490. reProjectTaskPreviews[i].CreatorName = creatorName
  491. reProjectTaskPreviews[i].ProductName = productName
  492. reProjectTaskPreviews[i].ProductPrice = productPrice
  493. reProjectTaskPreviews[i].MainImage = mainImage
  494. }
  495. result = vo.ResultVO{
  496. Page: param.Page,
  497. PageSize: param.PageSize,
  498. Total: total,
  499. Data: reProjectTaskPreviews,
  500. }
  501. return result, nil
  502. }
  503. // 删除种草任务
  504. func (s ProjectService) DeleteProject(projectId string) (*string, error) {
  505. res, err := dao.ProjectDAO{}.DeleteProject(projectId)
  506. if err != nil {
  507. logrus.Errorf("[projectDB service] call DeleteProject error,err:%+v", err)
  508. return res, err
  509. }
  510. return res, nil
  511. }