stdDoc.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. package servers
  2. import (
  3. . "app.yhyue.com/moapp/jybase/api"
  4. "app.yhyue.com/moapp/jybase/common"
  5. "app.yhyue.com/moapp/jybase/go-xweb/xweb"
  6. "app.yhyue.com/moapp/jybase/redis"
  7. "app.yhyue.com/moapp/jypkg/common/src/qfw/util/jy"
  8. "fmt"
  9. "jy-docs/config"
  10. "jy-docs/public"
  11. "jy-docs/rpc"
  12. "log"
  13. "strings"
  14. )
  15. type StdDoc struct {
  16. *xweb.Action
  17. search xweb.Mapper `xweb:"/search"` //检索文库
  18. indexTag xweb.Mapper `xweb:"/indexTag"` //首页搜索标签
  19. detail xweb.Mapper `xweb:"/detail"` //文库详情
  20. recommend xweb.Mapper `xweb:"/detail/recommend"` //相关推荐
  21. getDoc xweb.Mapper `xweb:"/get(Show|Down)"` //文库在线查看 or 下载
  22. topList xweb.Mapper `xweb:"/topList"` //最新文档&热门下载
  23. activityList xweb.Mapper `xweb:"/activityList"` //活动文库(精品推荐、兑换榜)
  24. docRecommend xweb.Mapper `xweb:"/docRecommend"` // 文库首页 :热门文档推荐、 会员免费 、精选推荐
  25. }
  26. func (stdDoc *StdDoc) Search() {
  27. userId := common.ObjToString(stdDoc.GetSession("userId"))
  28. rData, errMsg := func() (interface{}, error) {
  29. keyWord := strings.TrimSpace(stdDoc.GetString("keyWord")) //关键词
  30. tag := stdDoc.GetString("tag") //标签
  31. sort := stdDoc.GetString("sort") //排序 tSort dSort vSort
  32. pageNumReq, _ := stdDoc.GetInt("num") //页码 从1开始
  33. pageSizeReq, _ := stdDoc.GetInt("size") //每页数量
  34. productType, _ := stdDoc.GetInt("productType") //每页数量
  35. docFileType, _ := stdDoc.GetInt("docFileType") //每页数量
  36. pageNum, pageSize, err := public.PageNumParse(pageNumReq, pageSizeReq, config.JyDocsAppConfig.SearchNumLimit)
  37. if err != nil {
  38. return nil, err
  39. }
  40. if keyWord == "" && tag == "" && productType == 0 {
  41. return nil, fmt.Errorf("检索内容不能为空")
  42. }
  43. if tag == "全部" {
  44. tag = ""
  45. }
  46. if keyWord == "" && (pageNum > 1 || pageSize > 50 || docFileType != 0) { // / 搜索时关键词不能为空 热门推荐 会员免费 精选推荐时关键词可以为空所以再判断一下页数
  47. return nil, fmt.Errorf("参数有误")
  48. }
  49. // 关键词为空说明不是搜索过来的
  50. topKey := fmt.Sprintf("jydoc_searchCache_%s_%d_%s_%d_%d", tag, productType, sort, pageNum, pageSize)
  51. if keyWord == "" {
  52. listCache := redis.Get("other", topKey)
  53. if listCache != nil {
  54. return listCache, nil
  55. }
  56. }
  57. list, total, err := rpc.GetDocQuery(userId, keyWord, tag, pageNum, pageSize, sort, productType, docFileType)
  58. if err != nil {
  59. return nil, err
  60. }
  61. if total > config.JyDocsAppConfig.SearchNumLimit {
  62. total = config.JyDocsAppConfig.SearchNumLimit
  63. }
  64. for i := 0; i < len(list); i++ {
  65. if list[i].Source == public.SourceDd {
  66. list[i].PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, list[i].PreviewImgId)
  67. } else {
  68. list[i].PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, list[i].PreviewImgId)
  69. }
  70. }
  71. rs := map[string]interface{}{
  72. "total": total,
  73. "list": list,
  74. }
  75. // 存缓存
  76. if keyWord == "" && len(list) > 0 {
  77. redis.Put("other", topKey, rs, 60*60*2)
  78. }
  79. return rs, nil
  80. }()
  81. if errMsg != nil {
  82. log.Printf("%s StdDoc search err:%s\n", userId, errMsg.Error())
  83. errMsg = fmt.Errorf("系统繁忙,请稍后再试!")
  84. }
  85. stdDoc.ServeJson(NewResult(rData, errMsg))
  86. }
  87. func (stdDoc *StdDoc) IndexTag() {
  88. tags, err := rpc.GetIndexTags()
  89. stdDoc.ServeJson(NewResult(tags, err))
  90. }
  91. func (stdDoc *StdDoc) Detail() {
  92. userId := common.ObjToString(stdDoc.GetSession("userId"))
  93. rData, errMsg := func() (interface{}, error) {
  94. docId := stdDoc.GetString("docId")
  95. from := stdDoc.GetString("from")
  96. if docId == "" {
  97. return nil, fmt.Errorf("参数异常")
  98. }
  99. if from != "" { //分享赚积分
  100. go public.OpenShareJydoc(from, userId, docId)
  101. }
  102. detail, isBuy, IsCollect, err := rpc.GetDocDetail(userId, docId, false)
  103. if err != nil {
  104. return nil, err
  105. }
  106. //ossId清除
  107. detail.OssPdfId = ""
  108. detail.OssDocId = ""
  109. downloadStatus := 0 // 1- 免费用户下载豆丁免费次数用完
  110. // 如果是会员免费文档 并且不是文库会员 并且没有买过 时免费判断判断有没有超过10篇
  111. if !isBuy && userId != "" && detail.ProductType == public.ProductTypeMemberFree && detail.Source == public.SourceDd {
  112. mData := jy.GetBigVipUserBaseMsg(stdDoc.Session(), *config.Middleground)
  113. if mData != nil && mData.Data != nil {
  114. if mData.Data.Docs.Status <= 0 {
  115. // 免费用户 判断豆丁免费文档下载次数
  116. count, _, err2 := rpc.TodayCount(userId)
  117. if err2 != nil {
  118. return nil, err2
  119. }
  120. if count >= int64(config.JyDocsAppConfig.DocMember.FreeDocLimit) {
  121. downloadStatus = 1
  122. }
  123. }
  124. }
  125. }
  126. go rpc.DocStatistics(userId, docId, rpc.View) //统计下载次数
  127. return map[string]interface{}{
  128. "status": common.If(isBuy, 1, 0),
  129. "collect": common.If(IsCollect, 1, 0),
  130. "detail": detail,
  131. "downloadStatus": downloadStatus,
  132. }, nil
  133. }()
  134. if errMsg != nil {
  135. log.Printf("%s StdDoc detail err:%s\n", userId, errMsg.Error())
  136. }
  137. stdDoc.ServeJson(NewResult(rData, errMsg))
  138. }
  139. func (stdDoc *StdDoc) Recommend() {
  140. userId := common.ObjToString(stdDoc.GetSession("userId"))
  141. rData, errMsg := func() (interface{}, error) {
  142. docId := stdDoc.GetString("docId")
  143. docTag := stdDoc.GetString("docTag")
  144. num, _ := stdDoc.GetInt("num")
  145. num = public.PageRange(num, 1, 10)
  146. if strings.Index(docTag, ",") > -1 {
  147. docTag = strings.Split(docTag, ",")[0]
  148. }
  149. list, _, err := rpc.GetDocQuery(userId, "", docTag, 1, num+1, "dSort", 0, 0)
  150. if err != nil {
  151. return nil, err
  152. }
  153. returnList := []interface{}{}
  154. for _, v := range list {
  155. if docId == v.DocId || len(returnList) >= common.IntAll(num) {
  156. continue
  157. }
  158. v.DocSummary = ""
  159. if v.Source == public.SourceDd {
  160. v.PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, v.PreviewImgId)
  161. } else {
  162. v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
  163. }
  164. returnList = append(returnList, v)
  165. }
  166. return returnList, nil
  167. }()
  168. if errMsg != nil {
  169. log.Printf("%s StdDoc detail err:%s\n", userId, errMsg.Error())
  170. }
  171. stdDoc.ServeJson(NewResult(rData, errMsg))
  172. }
  173. func (stdDoc *StdDoc) GetDoc(sign string) {
  174. //userId := common.ObjToString(stdDoc.GetSession("userId"))
  175. userInfo := public.GetUserBaseInfo(stdDoc.Session())
  176. userId := userInfo.UserId
  177. rData, errMsg := func() (interface{}, error) {
  178. docId := stdDoc.GetString("docId")
  179. if docId == "" {
  180. return nil, fmt.Errorf("参数异常")
  181. }
  182. detail, isBuy, _, err := rpc.GetDocDetail(userId, docId, true)
  183. if err != nil {
  184. return nil, err
  185. }
  186. if !isBuy && !(sign == "Show" && detail.Source == public.SourceJy) {
  187. detail.OssPdfId = ""
  188. detail.OssDocId = ""
  189. return nil, fmt.Errorf("请先兑换文档")
  190. }
  191. fileId := detail.OssPdfId
  192. if sign == "Down" {
  193. fileId = detail.OssDocId
  194. if b, _ := redis.Exists(public.RedisCode, fmt.Sprintf("file_upload_ing_%s", fileId)); b {
  195. return nil, fmt.Errorf("文档正在上传中,请稍后再试")
  196. }
  197. if detail.OssDocId == "" {
  198. // 下载接口
  199. _, err := rpc.PartDocDownload(docId, userInfo.MgoUserId, userInfo.Phone, userInfo.PositionId)
  200. if err != nil {
  201. log.Println("GetDoc PartDocDownload 获取失败")
  202. }
  203. return nil, fmt.Errorf("文档正在上传中,请稍后再试")
  204. }
  205. }
  206. domain := config.JyDocsAppConfig.OssBucket.Std
  207. if detail.Source == int64(public.SourceDd) {
  208. domain = config.JyDocsAppConfig.OssBucket.Docin
  209. }
  210. url, err := rpc.GetFileContext(userId, fileId, domain)
  211. if err != nil {
  212. return nil, err
  213. }
  214. if strings.HasPrefix(url, "http://") {
  215. url = strings.Replace(url, "http://", "https://", 1)
  216. }
  217. return url, nil
  218. }()
  219. if errMsg != nil {
  220. log.Printf("%s StdDoc content err:%s\n", userId, errMsg.Error())
  221. }
  222. stdDoc.ServeJson(NewResult(rData, errMsg))
  223. }
  224. func (stdDoc *StdDoc) TopList() {
  225. userId := common.ObjToString(stdDoc.GetSession("userId"))
  226. rData, errMsg := func() (interface{}, error) {
  227. num, _ := stdDoc.GetInt("num") //返回数量
  228. sign := stdDoc.GetString("sign") //类别
  229. reqSort := ""
  230. if num > 50 {
  231. num = 50
  232. }
  233. if sign == "hot" {
  234. reqSort = "dSort"
  235. } else if sign == "new" {
  236. reqSort = "tSort"
  237. } else {
  238. return nil, fmt.Errorf("未知请求")
  239. }
  240. topKey := fmt.Sprintf("jydoc_indexCache_%s_%d", reqSort, num)
  241. listCache := redis.Get("other", topKey)
  242. if listCache != nil {
  243. return listCache, nil
  244. }
  245. log.Println("flush", topKey)
  246. list, _, err := rpc.GetDocQuery(userId, "", "", 1, num, reqSort, 0, 0)
  247. if err != nil {
  248. return nil, err
  249. }
  250. if len(list) > 0 { //存入redis缓存
  251. for _, v := range list {
  252. if v.Source == public.SourceDd {
  253. v.PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, v.PreviewImgId)
  254. } else {
  255. if v.PreviewImgId != "" && !strings.HasPrefix(v.PreviewImgId, "http") {
  256. v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
  257. }
  258. }
  259. }
  260. redis.Put("other", topKey, list, 60*5)
  261. }
  262. return list, nil
  263. }()
  264. if errMsg != nil {
  265. log.Printf("%s StdDoc topList err:%s\n", userId, errMsg.Error())
  266. }
  267. stdDoc.ServeJson(NewResult(rData, errMsg))
  268. }
  269. func (stdDoc *StdDoc) ActivityList() {
  270. userId := common.ObjToString(stdDoc.GetSession("userId"))
  271. rData, errMsg := func() (interface{}, error) {
  272. code, _ := stdDoc.GetInt("code")
  273. pageNumReq, _ := stdDoc.GetInt("num") //页码 从1开始
  274. pageSizeReq, _ := stdDoc.GetInt("size") //每页数量
  275. pageNum, pageSize, err := public.PageNumParse(pageNumReq, pageSizeReq, 20*10)
  276. if err != nil {
  277. return nil, err
  278. }
  279. //存入redis缓存
  280. list, err := rpc.GeActivityList(userId, code, pageNum, pageSize)
  281. if err != nil {
  282. return nil, err
  283. }
  284. if list != nil && len(list) > 0 {
  285. for i := 0; i < len(list); i++ {
  286. list[i].DocImg = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, list[i].DocImg)
  287. }
  288. }
  289. return list, nil
  290. }()
  291. if errMsg != nil {
  292. log.Printf("%s StdDoc activityList err:%s\n", userId, errMsg.Error())
  293. }
  294. stdDoc.ServeJson(NewResult(rData, errMsg))
  295. }
  296. // 文库推荐
  297. func (stdDoc *StdDoc) DocRecommend() {
  298. userId := common.ObjToString(stdDoc.GetSession("userId"))
  299. rData, errMsg := func() (interface{}, error) {
  300. tag := stdDoc.GetString("tag") //标签
  301. //sort := stdDoc.GetString("sort") //排序 tSort dSort vSort
  302. pageSizeReq, _ := stdDoc.GetInteger("size") //每页数量
  303. productType, _ := stdDoc.GetInteger("productType") // 商品类型 1-会员免费 2-精品文档
  304. if pageSizeReq > 50 {
  305. return nil, fmt.Errorf("数量有误")
  306. }
  307. if (tag == "" && productType == 0) || (tag != "" && productType != 0) {
  308. return nil, fmt.Errorf("不能为空")
  309. }
  310. var regionState int
  311. if tag != "" {
  312. regionState = public.RegionStateHot
  313. tag = public.DocClassInfo[tag]
  314. } else if productType == public.ProductTypeMemberFree {
  315. regionState = public.RegionStateMemberFree
  316. } else if productType == public.ProductTypePremium {
  317. regionState = public.RegionStatePremium
  318. } else {
  319. return nil, fmt.Errorf("参数无效")
  320. }
  321. topKey := fmt.Sprintf("jydoc_RecCache_%d_%s", regionState, tag)
  322. listCache := redis.Get(public.RedisCode, topKey)
  323. if listCache != nil {
  324. list, ok := listCache.([]interface{})
  325. if ok && list != nil && len(list) > 0 {
  326. if len(list) > pageSizeReq {
  327. list = list[:pageSizeReq]
  328. }
  329. return map[string]interface{}{
  330. "total": len(list),
  331. "list": list,
  332. }, nil
  333. }
  334. }
  335. // 查库
  336. list := []map[string]interface{}{}
  337. rs := public.GetRecDoc(regionState, tag)
  338. // 格式化数据
  339. for i := 0; i < len(rs); i++ {
  340. tags := strings.Split(common.ObjToString((rs)[i]["docTags"]), ",")
  341. tmptags := []string{}
  342. subTag := ""
  343. for j := 0; j < len(tags); j++ {
  344. if _, ok := public.DocClassInfo[tags[j]]; ok && len(tmptags) == 0 {
  345. tmptags = append(tmptags, tags[j])
  346. } else {
  347. subTag = tags[j]
  348. }
  349. if subTag != "" && len(tmptags) > 0 {
  350. tmptags = append(tmptags, subTag)
  351. break
  352. }
  353. }
  354. previewImgId := ""
  355. if common.IntAll((rs)[i]["source"]) == public.SourceDd {
  356. previewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, rs[i]["previewImgId"])
  357. } else {
  358. previewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, rs[i]["previewImgId"])
  359. }
  360. doc := map[string]interface{}{
  361. "docId": common.ObjToString((rs)[i]["doc_id"]),
  362. "docName": common.ObjToString((rs)[i]["docName"]),
  363. "docPageSize": common.Int64All((rs)[i]["docPageSize"]),
  364. "docFileSize": common.Int64All((rs)[i]["docFileSize"]),
  365. "downTimes": common.Int64All((rs)[i]["downTimes"]),
  366. "viewTimes": common.Int64All((rs)[i]["viewTimes"]),
  367. "uploadDate": common.ObjToString((rs)[i]["uploadDate"]),
  368. "docSummary": common.ObjToString((rs)[i]["docSummary"]),
  369. "docFileType": public.DocFileType[common.IntAll((rs)[i]["docFileType"])],
  370. "previewImgId": previewImgId,
  371. "productType": common.Int64All((rs)[i]["productType"]),
  372. "source": common.Int64All((rs)[i]["source"]),
  373. "docTags": strings.Join(tmptags, " "),
  374. }
  375. list = append(list, doc)
  376. }
  377. // 存缓存
  378. if len(list) > 0 {
  379. redis.Put(public.RedisCode, topKey, list, 60*60*12)
  380. }
  381. if len(list) > pageSizeReq {
  382. list = list[:pageSizeReq]
  383. }
  384. return map[string]interface{}{
  385. "total": len(list),
  386. "list": list,
  387. }, nil
  388. }()
  389. if errMsg != nil {
  390. log.Printf("%s StdDoc search err:%s\n", userId, errMsg.Error())
  391. }
  392. stdDoc.ServeJson(NewResult(rData, errMsg))
  393. }