stdDoc.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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. }
  84. stdDoc.ServeJson(NewResult(rData, errMsg))
  85. }
  86. func (stdDoc *StdDoc) IndexTag() {
  87. tags, err := rpc.GetIndexTags()
  88. stdDoc.ServeJson(NewResult(tags, err))
  89. }
  90. func (stdDoc *StdDoc) Detail() {
  91. userId := common.ObjToString(stdDoc.GetSession("userId"))
  92. rData, errMsg := func() (interface{}, error) {
  93. docId := stdDoc.GetString("docId")
  94. from := stdDoc.GetString("from")
  95. if docId == "" {
  96. return nil, fmt.Errorf("参数异常")
  97. }
  98. if from != "" { //分享赚积分
  99. go public.OpenShareJydoc(from, userId, docId)
  100. }
  101. detail, isBuy, IsCollect, err := rpc.GetDocDetail(userId, docId, false)
  102. if err != nil {
  103. return nil, err
  104. }
  105. //ossId清除
  106. detail.OssPdfId = ""
  107. detail.OssDocId = ""
  108. downloadStatus := 0 // 1- 免费用户下载豆丁免费次数用完
  109. // 如果是会员免费文档 并且不是文库会员 并且没有买过 时免费判断判断有没有超过10篇
  110. if !isBuy && userId != "" && detail.ProductType == public.ProductTypeMemberFree && detail.Source == public.SourceDd {
  111. mData := jy.GetBigVipUserBaseMsg(stdDoc.Session(), *config.Middleground)
  112. if mData != nil && mData.Data != nil {
  113. if mData.Data.Docs.Status <= 0 {
  114. // 免费用户 判断豆丁免费文档下载次数
  115. count, _, err2 := rpc.TodayCount(userId)
  116. if err2 != nil {
  117. return nil, err2
  118. }
  119. if count >= int64(config.JyDocsAppConfig.DocMember.FreeDocLimit) {
  120. downloadStatus = 1
  121. }
  122. }
  123. }
  124. }
  125. go rpc.DocStatistics(userId, docId, rpc.View) //统计下载次数
  126. return map[string]interface{}{
  127. "status": common.If(isBuy, 1, 0),
  128. "collect": common.If(IsCollect, 1, 0),
  129. "detail": detail,
  130. "downloadStatus": downloadStatus,
  131. }, nil
  132. }()
  133. if errMsg != nil {
  134. log.Printf("%s StdDoc detail err:%s\n", userId, errMsg.Error())
  135. }
  136. stdDoc.ServeJson(NewResult(rData, errMsg))
  137. }
  138. func (stdDoc *StdDoc) Recommend() {
  139. userId := common.ObjToString(stdDoc.GetSession("userId"))
  140. rData, errMsg := func() (interface{}, error) {
  141. docId := stdDoc.GetString("docId")
  142. docTag := stdDoc.GetString("docTag")
  143. num, _ := stdDoc.GetInt("num")
  144. num = public.PageRange(num, 1, 10)
  145. if strings.Index(docTag, ",") > -1 {
  146. docTag = strings.Split(docTag, ",")[0]
  147. }
  148. list, _, err := rpc.GetDocQuery(userId, "", docTag, 1, num+1, "dSort", 0, 0)
  149. if err != nil {
  150. return nil, err
  151. }
  152. returnList := []interface{}{}
  153. for _, v := range list {
  154. if docId == v.DocId || len(returnList) >= common.IntAll(num) {
  155. continue
  156. }
  157. v.DocSummary = ""
  158. if v.Source == public.SourceDd {
  159. v.PreviewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, v.PreviewImgId)
  160. } else {
  161. v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
  162. }
  163. returnList = append(returnList, v)
  164. }
  165. return returnList, nil
  166. }()
  167. if errMsg != nil {
  168. log.Printf("%s StdDoc detail err:%s\n", userId, errMsg.Error())
  169. }
  170. stdDoc.ServeJson(NewResult(rData, errMsg))
  171. }
  172. func (stdDoc *StdDoc) GetDoc(sign string) {
  173. //userId := common.ObjToString(stdDoc.GetSession("userId"))
  174. userInfo := public.GetUserBaseInfo(stdDoc.Session())
  175. userId := userInfo.UserId
  176. rData, errMsg := func() (interface{}, error) {
  177. docId := stdDoc.GetString("docId")
  178. if docId == "" {
  179. return nil, fmt.Errorf("参数异常")
  180. }
  181. detail, isBuy, _, err := rpc.GetDocDetail(userId, docId, false)
  182. if err != nil {
  183. return nil, err
  184. }
  185. if !isBuy {
  186. return nil, fmt.Errorf("请先兑换文档")
  187. }
  188. fileId := detail.OssPdfId
  189. if sign == "Down" {
  190. fileId = detail.OssDocId
  191. if b, _ := redis.Exists(public.RedisCode, fmt.Sprintf("file_upload_ing_%s", fileId)); b {
  192. return nil, fmt.Errorf("文档正在上传中,请稍后再试")
  193. }
  194. if detail.OssDocId == "" {
  195. // 下载接口
  196. _, err := rpc.PartDocDownload(docId, userInfo.MgoUserId, userInfo.Phone, userInfo.PositionId)
  197. if err != nil {
  198. log.Println("GetDoc PartDocDownload 获取失败")
  199. }
  200. return nil, fmt.Errorf("文档正在上传中,请稍后再试")
  201. }
  202. }
  203. domain := config.JyDocsAppConfig.OssBucket.Std
  204. if detail.Source == int64(public.SourceDd) {
  205. domain = config.JyDocsAppConfig.OssBucket.Docin
  206. }
  207. url, err := rpc.GetFileContext(userId, fileId, domain)
  208. if err != nil {
  209. return nil, err
  210. }
  211. if strings.HasPrefix(url, "http://") {
  212. url = strings.Replace(url, "http://", "https://", 1)
  213. }
  214. return url, nil
  215. }()
  216. if errMsg != nil {
  217. log.Printf("%s StdDoc content err:%s\n", userId, errMsg.Error())
  218. }
  219. stdDoc.ServeJson(NewResult(rData, errMsg))
  220. }
  221. func (stdDoc *StdDoc) TopList() {
  222. userId := common.ObjToString(stdDoc.GetSession("userId"))
  223. rData, errMsg := func() (interface{}, error) {
  224. num, _ := stdDoc.GetInt("num") //返回数量
  225. sign := stdDoc.GetString("sign") //类别
  226. reqSort := ""
  227. if num > 50 {
  228. num = 50
  229. }
  230. if sign == "hot" {
  231. reqSort = "dSort"
  232. } else if sign == "new" {
  233. reqSort = "tSort"
  234. } else {
  235. return nil, fmt.Errorf("未知请求")
  236. }
  237. topKey := fmt.Sprintf("jydoc_indexCache_%s_%d", reqSort, num)
  238. listCache := redis.Get("other", topKey)
  239. if listCache != nil {
  240. return listCache, nil
  241. }
  242. log.Println("flush", topKey)
  243. list, _, err := rpc.GetDocQuery(userId, "", "", 1, num, reqSort, 0, 0)
  244. if err != nil {
  245. return nil, err
  246. }
  247. if len(list) > 0 { //存入redis缓存
  248. for _, v := range list {
  249. if v.PreviewImgId != "" && !strings.HasPrefix(v.PreviewImgId, "http") {
  250. v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
  251. }
  252. }
  253. redis.Put("other", topKey, list, 60*5)
  254. }
  255. return list, nil
  256. }()
  257. if errMsg != nil {
  258. log.Printf("%s StdDoc topList err:%s\n", userId, errMsg.Error())
  259. }
  260. stdDoc.ServeJson(NewResult(rData, errMsg))
  261. }
  262. func (stdDoc *StdDoc) ActivityList() {
  263. userId := common.ObjToString(stdDoc.GetSession("userId"))
  264. rData, errMsg := func() (interface{}, error) {
  265. code, _ := stdDoc.GetInt("code")
  266. pageNumReq, _ := stdDoc.GetInt("num") //页码 从1开始
  267. pageSizeReq, _ := stdDoc.GetInt("size") //每页数量
  268. pageNum, pageSize, err := public.PageNumParse(pageNumReq, pageSizeReq, 20*10)
  269. if err != nil {
  270. return nil, err
  271. }
  272. //存入redis缓存
  273. list, err := rpc.GeActivityList(userId, code, pageNum, pageSize)
  274. if err != nil {
  275. return nil, err
  276. }
  277. if list != nil && len(list) > 0 {
  278. for i := 0; i < len(list); i++ {
  279. list[i].DocImg = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, list[i].DocImg)
  280. }
  281. }
  282. return list, nil
  283. }()
  284. if errMsg != nil {
  285. log.Printf("%s StdDoc activityList err:%s\n", userId, errMsg.Error())
  286. }
  287. stdDoc.ServeJson(NewResult(rData, errMsg))
  288. }
  289. // 文库推荐
  290. func (stdDoc *StdDoc) DocRecommend() {
  291. userId := common.ObjToString(stdDoc.GetSession("userId"))
  292. rData, errMsg := func() (interface{}, error) {
  293. tag := stdDoc.GetString("tag") //标签
  294. //sort := stdDoc.GetString("sort") //排序 tSort dSort vSort
  295. pageSizeReq, _ := stdDoc.GetInteger("size") //每页数量
  296. productType, _ := stdDoc.GetInteger("productType") // 商品类型 1-会员免费 2-精品文档
  297. if pageSizeReq > 50 {
  298. return nil, fmt.Errorf("数量有误")
  299. }
  300. if (tag == "" && productType == 0) || (tag != "" && productType != 0) {
  301. return nil, fmt.Errorf("不能为空")
  302. }
  303. var regionState int
  304. if tag != "" {
  305. regionState = public.RegionStateHot
  306. tag = public.DocClassInfo[tag]
  307. } else if productType == public.ProductTypeMemberFree {
  308. regionState = public.RegionStateMemberFree
  309. } else if productType == public.ProductTypePremium {
  310. regionState = public.RegionStatePremium
  311. } else {
  312. return nil, fmt.Errorf("参数无效")
  313. }
  314. topKey := fmt.Sprintf("jydoc_RecCache_%d_%s", regionState, tag)
  315. listCache := redis.Get("other", topKey)
  316. if listCache != nil {
  317. list, ok := listCache.([]interface{})
  318. if ok && list != nil && len(list) > 0 {
  319. if len(list) > pageSizeReq {
  320. list = list[:pageSizeReq]
  321. }
  322. return map[string]interface{}{
  323. "total": len(list),
  324. "list": list,
  325. }, nil
  326. }
  327. }
  328. // 查库
  329. list := []map[string]interface{}{}
  330. rs := public.GetRecDoc(regionState, tag)
  331. // 格式化数据
  332. for i := 0; i < len(rs); i++ {
  333. tags := strings.Split(common.ObjToString((rs)[i]["docTags"]), ",")
  334. tmptags := []string{}
  335. subTag := ""
  336. for j := 0; j < len(tags); j++ {
  337. if _, ok := public.DocClassInfo[tags[j]]; ok && len(tmptags) == 0 {
  338. tmptags = append(tmptags, tags[j])
  339. } else {
  340. subTag = tags[j]
  341. }
  342. if subTag != "" && len(tmptags) > 0 {
  343. tmptags = append(tmptags, subTag)
  344. break
  345. }
  346. }
  347. previewImgId := ""
  348. if common.IntAll((rs)[i]["source"]) == public.SourceDd {
  349. previewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, rs[i]["previewImgId"])
  350. } else {
  351. previewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, rs[i]["previewImgId"])
  352. }
  353. doc := map[string]interface{}{
  354. "docId": common.ObjToString((rs)[i]["id"]),
  355. "docName": common.ObjToString((rs)[i]["docName"]),
  356. "docPageSize": common.Int64All((rs)[i]["docPageSize"]),
  357. "docFileSize": common.Int64All((rs)[i]["docFileSize"]),
  358. "downTimes": common.Int64All((rs)[i]["downTimes"]),
  359. "viewTimes": common.Int64All((rs)[i]["(rs)[i]iewTimes"]),
  360. "uploadDate": common.ObjToString((rs)[i]["uploadDate"]),
  361. "docSummary": common.ObjToString((rs)[i]["docSummary"]),
  362. "docFileType": public.DocFileType[common.IntAll((rs)[i]["docFileType"])],
  363. "previewImgId": previewImgId,
  364. "productType": common.Int64All((rs)[i]["productType"]),
  365. "source": common.Int64All((rs)[i]["source"]),
  366. "docTags": strings.Join(tmptags, " "),
  367. }
  368. list = append(list, doc)
  369. }
  370. // 存缓存
  371. if len(list) > 0 {
  372. redis.Put("other", topKey, list, 60*60*2)
  373. }
  374. if len(list) > pageSizeReq {
  375. list = list[:pageSizeReq]
  376. }
  377. return map[string]interface{}{
  378. "total": len(list),
  379. "list": list,
  380. }, nil
  381. }()
  382. if errMsg != nil {
  383. log.Printf("%s StdDoc search err:%s\n", userId, errMsg.Error())
  384. }
  385. stdDoc.ServeJson(NewResult(rData, errMsg))
  386. }