project_service.go 17 KB

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