project_info.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. package youngee_task_service
  2. import (
  3. "fmt"
  4. "github.com/gogf/gf/os/glog"
  5. "github.com/gogf/gf/os/gtime"
  6. "github.com/gogf/gf/util/gconv"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. "youngmini_server/app/dao"
  11. "youngmini_server/app/model"
  12. "youngmini_server/app/model/youngee_talent_model"
  13. "youngmini_server/app/service/youngee_talent_service"
  14. "youngmini_server/app/utils"
  15. "github.com/gogf/gf/frame/g"
  16. "github.com/gogf/gf/net/ghttp"
  17. "github.com/wxnacy/wgo/arrays"
  18. )
  19. type projectStatus int
  20. const (
  21. projectStatusCreating = iota + 1
  22. projectStatusReviewing
  23. projectStatusReviewed
  24. projectStatusRecruiting
  25. projectStatusRecruited
  26. projectStatusPaying
  27. projectStatusPaid
  28. projectStatusInvalid
  29. projectStatusInProgress
  30. projectStatusClosed
  31. )
  32. // 获取项目信息列表service
  33. func GetProjectInfoList(r *ghttp.Request) *TalentHttpResult {
  34. fmt.Println("进入种草主页")
  35. pageIndex := r.GetQueryInt("idx", -1)
  36. cntPerPage := r.GetQueryInt("cnt", -1)
  37. platform := r.Get("platform")
  38. projectForm := r.Get("projectform")
  39. feeForm := r.Get("feeform")
  40. searchValue := r.Get("searchvalue")
  41. if pageIndex == -1 || cntPerPage == -1 || cntPerPage == 0 {
  42. return &TalentHttpResult{Code: -1, Msg: "参数错误"}
  43. }
  44. // 如果有稿费形式的过滤条件,则将过滤条件保存于taskModeList
  45. var feeFormList []interface{}
  46. if feeForm != nil {
  47. if reflect.TypeOf(feeForm).Kind() != reflect.Slice {
  48. return &TalentHttpResult{Code: -2, Msg: "搜索条件稿费形式错误"}
  49. }
  50. feeFormList = make([]interface{}, 0)
  51. feeFormList = feeForm.([]interface{})
  52. }
  53. // 如果有任务形式的过滤条件,则将过滤条件保存于taskModeList
  54. var projectFormList []interface{}
  55. if projectForm != nil {
  56. if reflect.TypeOf(projectForm).Kind() != reflect.Slice {
  57. return &TalentHttpResult{Code: -2, Msg: "搜索条件任务形式错误"}
  58. }
  59. projectFormList = make([]interface{}, 0)
  60. projectFormList = projectForm.([]interface{})
  61. }
  62. // 如果有平台的过滤条件,则将平台列表保存于platformList
  63. var platformList []interface{}
  64. if platform != nil {
  65. if reflect.TypeOf(platform).Kind() != reflect.Slice {
  66. return &TalentHttpResult{Code: -2, Msg: "搜索条件平台类型错误"}
  67. }
  68. platformList = make([]interface{}, 0)
  69. platformList = platform.([]interface{})
  70. }
  71. // 构造查询的条件
  72. startId := pageIndex * cntPerPage
  73. // whereStr := fmt.Sprintf("(project_status >= %d and project_status <> %d and project_type = 1)", projectStatusRecruiting, projectStatusInvalid)
  74. whereStr := fmt.Sprintf("(project_status >= %d and fail_reason <> 2 and project_type = 1)", projectStatusRecruiting)
  75. if platformList != nil {
  76. whereStr = whereStr + " and project_platform in ("
  77. for _, v := range platformList {
  78. whereStr += v.(string) + ", "
  79. }
  80. whereStr = whereStr[0 : len(whereStr)-2]
  81. whereStr += ")"
  82. }
  83. if projectFormList != nil {
  84. whereStr += " and project_form in ("
  85. for _, v := range projectFormList {
  86. whereStr += v.(string) + ", "
  87. }
  88. whereStr = whereStr[0 : len(whereStr)-2]
  89. whereStr += ")"
  90. }
  91. if searchValue != nil {
  92. whereStr += " and project_name like '%" + searchValue.(string) + "%'"
  93. }
  94. // 查询所有project
  95. var projectList = []model.ProjectInfo{}
  96. var projectIdList []string
  97. err := g.Model(dao.ProjectInfo.Table).Where(whereStr).Scan(&projectList)
  98. if err != nil {
  99. return &TalentHttpResult{Code: -3, Msg: "查询数据库失败"}
  100. }
  101. fmt.Println("searchValue:", searchValue)
  102. fmt.Println("feeFormList:", feeFormList)
  103. // 筛选出满足稿费形式条件的项目id列表
  104. for _, v := range projectList {
  105. string_slice := strings.Split(v.FeeForm, ",")
  106. // fmt.Println("str:", string_slice)
  107. tmp := 0
  108. for _, w := range feeFormList {
  109. i := arrays.ContainsString(string_slice, w.(string))
  110. if i < 0 {
  111. tmp = 0
  112. break
  113. }
  114. tmp = 1
  115. }
  116. if tmp == 1 {
  117. projectIdList = append(projectIdList, v.ProjectId)
  118. }
  119. }
  120. if projectIdList != nil {
  121. whereStr += " and project_id in ("
  122. for _, v := range projectIdList {
  123. whereStr += v + ", "
  124. }
  125. whereStr = whereStr[0 : len(whereStr)-2]
  126. whereStr += ")"
  127. } else if feeForm != nil {
  128. return &TalentHttpResult{Code: -4, Msg: "has no fullproject", Data: nil}
  129. }
  130. fmt.Println("whereStr: ", whereStr)
  131. // 判断请求页面是否超过最大页面
  132. c, err := g.DB().Model(dao.ProjectInfo.Table).Fields("project_id").Where(whereStr).Count()
  133. if c <= 0 {
  134. return &TalentHttpResult{Code: -4, Msg: "has no fullproject", Data: nil}
  135. }
  136. maxPage := c / cntPerPage
  137. if c%cntPerPage > 0 {
  138. maxPage += 1
  139. }
  140. if pageIndex+1 > maxPage {
  141. return &TalentHttpResult{Code: -5, Msg: "over max page"}
  142. }
  143. var projectInfoList = youngee_talent_model.ProjectInfoList{}
  144. err = g.DB().Model("project_info").WithAll().Where(whereStr).
  145. Order("project_status ASC,recruit_ddl DESC").Limit(startId, cntPerPage).Scan(&projectInfoList.ProjectInfos)
  146. if err != nil {
  147. return &TalentHttpResult{Code: -6, Msg: "查询数据库失败"}
  148. }
  149. // 遍历projectList
  150. for i, project := range projectInfoList.ProjectInfos {
  151. fmt.Println("project.EnterpriseId---", project.EnterpriseId)
  152. //处理浏览量
  153. projectViewKey := "project:view:" + gconv.String(project.ProjectId)
  154. //redis中取浏览量 返回的是gvar.Var类型。 不存咋则为nil。经过viewCount.Int变成0
  155. viewCount, err := g.Redis().DoVar("GET", projectViewKey)
  156. if err != nil {
  157. glog.Error(err)
  158. return &TalentHttpResult{Code: 0, Msg: "Redis error"}
  159. }
  160. projectInfoList.ProjectInfos[i].WatchedNum = viewCount.Int()
  161. // 如果 enterprise_id 有值,查询 Enterprise 信息并关联,服务商的任务不会出现在首页
  162. //if project.EnterpriseId != "" {
  163. // var enterprise *youngee_talent_model.Enterprise
  164. // err := g.DB().Model("enterprise").Where("enterprise_id", project.EnterpriseId).Scan(&enterprise)
  165. // if err != nil {
  166. // fmt.Println("查询失败")
  167. // continue // 如果查询失败,跳过当前 project 继续处理下一个
  168. // }
  169. //
  170. // fmt.Println("查询结果---", enterprise)
  171. //
  172. // // 将查询到的 Enterprise 赋值给 projectInfo 的 Enterprise 字段
  173. // projectInfoList.ProjectInfos[i].Enterprise = enterprise
  174. //}
  175. }
  176. projectInfoList.MaxPage = maxPage
  177. return &TalentHttpResult{Code: 0, Msg: "success", Data: projectInfoList}
  178. }
  179. // 获取单个项目详情service
  180. func GetProjectDetail(r *ghttp.Request) *TalentHttpResult {
  181. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  182. pid := r.GetQueryInt("project_id", 0)
  183. //通过首页进入的详情页,获取服务商id,younggee_supplier表
  184. enterprise_id := r.GetQueryString("enterprise_id", "")
  185. //通过扫服务商码进入的详情页,获取服务商id,younggee_supplier表
  186. supplier_id := r.GetQueryString("supplier_id", "")
  187. fmt.Println("enterprise_id----:", enterprise_id)
  188. fmt.Println("supplier_id----:", supplier_id)
  189. // Redis key
  190. projectViewKey := "project:view:" + strconv.Itoa(pid)
  191. userViewedKey := "user:viewed:" + tid + ":" + strconv.Itoa(pid)
  192. if pid == 0 {
  193. return &TalentHttpResult{Code: -2, Msg: "parse param error"}
  194. }
  195. //在redis中增加浏览量
  196. // Check if the user has already viewed the product
  197. //DoVar方便进行类型转化
  198. viewed, err := g.Redis().DoVar("GET", userViewedKey)
  199. if err != nil {
  200. glog.Error(err)
  201. return &TalentHttpResult{Code: 0, Msg: "Redis error"}
  202. }
  203. if viewed.IsNil() {
  204. // User hasn't viewed this product yet, increase the view count
  205. _, err = g.Redis().Do("INCR", projectViewKey)
  206. if err != nil {
  207. glog.Error(err)
  208. return &TalentHttpResult{Code: 0, Msg: "Redis error"}
  209. }
  210. // Mark the product as viewed by this user
  211. _, err = g.Redis().Do("SET", userViewedKey, true)
  212. if err != nil {
  213. glog.Error(err)
  214. return &TalentHttpResult{Code: 0, Msg: "Redis error"}
  215. }
  216. }
  217. //浏览历史
  218. currentDate := gtime.Now().Format("Ymd")
  219. // 设计 Redis Key
  220. redisBrowseKey := fmt.Sprintf("browseProject:%s:%s", currentDate, tid)
  221. fmt.Println("redis浏览记录的key为——————————", redisBrowseKey)
  222. // 将 project_id 添加到 Redis 中的 SET
  223. _, err = g.Redis().Do("SADD", redisBrowseKey, pid)
  224. if err != nil {
  225. return &TalentHttpResult{Code: 0, Msg: "Redis 存浏览历史数据失败"}
  226. }
  227. // 设置 Key 的过期时间为 7 天
  228. _, err = g.Redis().Do("EXPIRE", redisBrowseKey, 7*24*60*60) // 7 天的秒数
  229. if err != nil {
  230. return &TalentHttpResult{Code: 0, Msg: "Redis 设置过期时间失败"}
  231. }
  232. var ProjectDetail *youngee_talent_model.ProjectDetail
  233. err = g.DB().Model("project_info").WithAll().Where("project_id", pid).Scan(&ProjectDetail)
  234. if err != nil {
  235. return &TalentHttpResult{Code: -3, Msg: err.Error()}
  236. }
  237. if enterprise_id != "" { //project来自商家
  238. var enterprise *youngee_talent_model.Enterprise
  239. err = g.DB().Model("enterprise").WithAll().Where("enterprise_id", enterprise_id).Scan(&enterprise)
  240. if err != nil {
  241. return &TalentHttpResult{Code: -3, Msg: err.Error()}
  242. }
  243. ProjectDetail.Enterprise = enterprise
  244. }
  245. if supplier_id != "" {
  246. // 来自服务商
  247. var younggeeSupplier *youngee_talent_model.YounggeeSupplier
  248. err = g.DB().Model("younggee_supplier").WithAll().Where("supplier_id", supplier_id).Scan(&younggeeSupplier)
  249. if err != nil {
  250. return &TalentHttpResult{Code: -3, Msg: err.Error()}
  251. }
  252. ProjectDetail.YounggeeSupplier = younggeeSupplier
  253. }
  254. return &TalentHttpResult{Code: 0, Msg: "success", Data: ProjectDetail}
  255. }
  256. func SignUpProjKuaishouList(r *ghttp.Request) *TalentHttpResult {
  257. tid, _ := utils.SessionTalentInfo.GetTalentIdFromSession(r)
  258. pid := r.GetQueryString("project_id", 0)
  259. // 定义用于存储查询结果的结构体切片
  260. var results []*youngee_talent_model.KuaishouUserInfo
  261. // 查询此达人下,platform_id 为 8 或 4 的所有数据,并将结果扫描到结构体切片中
  262. err := g.DB().Model(&youngee_talent_model.KuaishouUserInfo{}).
  263. Where("talent_id = ?", tid).
  264. Where("platform_id IN (?, ?)", 4, 8).
  265. Order("open_id ASC, platform_id DESC"). // 按 open_id 排序,确保每组的数据连续,并且 platform_id=4 的数据排在前面
  266. Scan(&results)
  267. if err != nil {
  268. return &TalentHttpResult{Code: 1, Msg: "查询失败", Data: nil}
  269. }
  270. // 创建一个 map,用于记录每个 open_id 对应的记录
  271. //key是openid,value是数组,从而实现一对多
  272. openIdMap := make(map[string][]*youngee_talent_model.KuaishouUserInfo)
  273. // 将查询结果按 open_id 分组
  274. for _, record := range results {
  275. openIdMap[record.OpenId] = append(openIdMap[record.OpenId], record)
  276. }
  277. // 筛选出 open_id 对应两条数据且 platform_id = 4 的记录
  278. var resInfo []*youngee_talent_model.KuaishouUserInfo
  279. for _, records := range openIdMap {
  280. if len(records) == 2 { // 确保有两条数据,排除只有一个 platform_id 的情况
  281. for _, record := range records {
  282. if record.PlatformId == 4 { // 选取 platform_id = 4(电商) 的记录,含有粉丝数就好,因为需要加入橱窗
  283. resInfo = append(resInfo, record)
  284. break
  285. }
  286. }
  287. }
  288. }
  289. // 遍历 resInfo 检查过期和是否报名
  290. for _, record := range resInfo {
  291. // 调用 CheckKuaishouTokenExp 函数,检查 openId 是否过期
  292. expired := youngee_talent_service.CheckKuaishouTokenExp(record.OpenId)
  293. // 将过期检查结果赋值给 expired 属性 ,过期则不能被选中用于加入橱窗
  294. record.Expired = expired
  295. //是否报名
  296. isSignResult, err := g.DB().Model("younggee_task_info").Where("project_id=? AND open_id=? talent_id=?", pid, record.OpenId, tid).One()
  297. // 根据查询结果设置 IsSign 属性
  298. if err != nil || isSignResult.IsEmpty() {
  299. record.IsSign = 0 // 没有查到数据,设置为 0
  300. } else {
  301. record.IsSign = 1 // 查到数据,设置为 1
  302. }
  303. }
  304. return &TalentHttpResult{Code: 0, Msg: "success", Data: resInfo}
  305. }