stdDoc.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  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, false)
  183. if err != nil {
  184. return nil, err
  185. }
  186. if !isBuy {
  187. return nil, fmt.Errorf("请先兑换文档")
  188. }
  189. fileId := detail.OssPdfId
  190. if sign == "Down" {
  191. fileId = detail.OssDocId
  192. if b, _ := redis.Exists(public.RedisCode, fmt.Sprintf("file_upload_ing_%s", fileId)); b {
  193. return nil, fmt.Errorf("文档正在上传中,请稍后再试")
  194. }
  195. if detail.OssDocId == "" {
  196. // 下载接口
  197. _, err := rpc.PartDocDownload(docId, userInfo.MgoUserId, userInfo.Phone, userInfo.PositionId)
  198. if err != nil {
  199. log.Println("GetDoc PartDocDownload 获取失败")
  200. }
  201. return nil, fmt.Errorf("文档正在上传中,请稍后再试")
  202. }
  203. }
  204. domain := config.JyDocsAppConfig.OssBucket.Std
  205. if detail.Source == int64(public.SourceDd) {
  206. domain = config.JyDocsAppConfig.OssBucket.Docin
  207. }
  208. url, err := rpc.GetFileContext(userId, fileId, domain)
  209. if err != nil {
  210. return nil, err
  211. }
  212. if strings.HasPrefix(url, "http://") {
  213. url = strings.Replace(url, "http://", "https://", 1)
  214. }
  215. return url, nil
  216. }()
  217. if errMsg != nil {
  218. log.Printf("%s StdDoc content err:%s\n", userId, errMsg.Error())
  219. }
  220. stdDoc.ServeJson(NewResult(rData, errMsg))
  221. }
  222. func (stdDoc *StdDoc) TopList() {
  223. userId := common.ObjToString(stdDoc.GetSession("userId"))
  224. rData, errMsg := func() (interface{}, error) {
  225. num, _ := stdDoc.GetInt("num") //返回数量
  226. sign := stdDoc.GetString("sign") //类别
  227. reqSort := ""
  228. if num > 50 {
  229. num = 50
  230. }
  231. if sign == "hot" {
  232. reqSort = "dSort"
  233. } else if sign == "new" {
  234. reqSort = "tSort"
  235. } else {
  236. return nil, fmt.Errorf("未知请求")
  237. }
  238. topKey := fmt.Sprintf("jydoc_indexCache_%s_%d", reqSort, num)
  239. listCache := redis.Get("other", topKey)
  240. if listCache != nil {
  241. return listCache, nil
  242. }
  243. log.Println("flush", topKey)
  244. list, _, err := rpc.GetDocQuery(userId, "", "", 1, num, reqSort, 0, 0)
  245. if err != nil {
  246. return nil, err
  247. }
  248. if len(list) > 0 { //存入redis缓存
  249. for _, v := range list {
  250. if v.PreviewImgId != "" && !strings.HasPrefix(v.PreviewImgId, "http") {
  251. v.PreviewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, v.PreviewImgId)
  252. }
  253. }
  254. redis.Put("other", topKey, list, 60*5)
  255. }
  256. return list, nil
  257. }()
  258. if errMsg != nil {
  259. log.Printf("%s StdDoc topList err:%s\n", userId, errMsg.Error())
  260. }
  261. stdDoc.ServeJson(NewResult(rData, errMsg))
  262. }
  263. func (stdDoc *StdDoc) ActivityList() {
  264. userId := common.ObjToString(stdDoc.GetSession("userId"))
  265. rData, errMsg := func() (interface{}, error) {
  266. code, _ := stdDoc.GetInt("code")
  267. pageNumReq, _ := stdDoc.GetInt("num") //页码 从1开始
  268. pageSizeReq, _ := stdDoc.GetInt("size") //每页数量
  269. pageNum, pageSize, err := public.PageNumParse(pageNumReq, pageSizeReq, 20*10)
  270. if err != nil {
  271. return nil, err
  272. }
  273. //存入redis缓存
  274. list, err := rpc.GeActivityList(userId, code, pageNum, pageSize)
  275. if err != nil {
  276. return nil, err
  277. }
  278. if list != nil && len(list) > 0 {
  279. for i := 0; i < len(list); i++ {
  280. list[i].DocImg = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, list[i].DocImg)
  281. }
  282. }
  283. return list, nil
  284. }()
  285. if errMsg != nil {
  286. log.Printf("%s StdDoc activityList err:%s\n", userId, errMsg.Error())
  287. }
  288. stdDoc.ServeJson(NewResult(rData, errMsg))
  289. }
  290. // 文库推荐
  291. func (stdDoc *StdDoc) DocRecommend() {
  292. userId := common.ObjToString(stdDoc.GetSession("userId"))
  293. rData, errMsg := func() (interface{}, error) {
  294. tag := stdDoc.GetString("tag") //标签
  295. //sort := stdDoc.GetString("sort") //排序 tSort dSort vSort
  296. pageSizeReq, _ := stdDoc.GetInteger("size") //每页数量
  297. productType, _ := stdDoc.GetInteger("productType") // 商品类型 1-会员免费 2-精品文档
  298. if pageSizeReq > 50 {
  299. return nil, fmt.Errorf("数量有误")
  300. }
  301. if (tag == "" && productType == 0) || (tag != "" && productType != 0) {
  302. return nil, fmt.Errorf("不能为空")
  303. }
  304. var regionState int
  305. if tag != "" {
  306. regionState = public.RegionStateHot
  307. tag = public.DocClassInfo[tag]
  308. } else if productType == public.ProductTypeMemberFree {
  309. regionState = public.RegionStateMemberFree
  310. } else if productType == public.ProductTypePremium {
  311. regionState = public.RegionStatePremium
  312. } else {
  313. return nil, fmt.Errorf("参数无效")
  314. }
  315. topKey := fmt.Sprintf("jydoc_RecCache_%d_%s", regionState, tag)
  316. listCache := redis.Get(public.RedisCode, topKey)
  317. if listCache != nil {
  318. list, ok := listCache.([]interface{})
  319. if ok && list != nil && len(list) > 0 {
  320. if len(list) > pageSizeReq {
  321. list = list[:pageSizeReq]
  322. }
  323. return map[string]interface{}{
  324. "total": len(list),
  325. "list": list,
  326. }, nil
  327. }
  328. }
  329. // 查库
  330. list := []map[string]interface{}{}
  331. rs := public.GetRecDoc(regionState, tag)
  332. // 格式化数据
  333. for i := 0; i < len(rs); i++ {
  334. tags := strings.Split(common.ObjToString((rs)[i]["docTags"]), ",")
  335. tmptags := []string{}
  336. subTag := ""
  337. for j := 0; j < len(tags); j++ {
  338. if _, ok := public.DocClassInfo[tags[j]]; ok && len(tmptags) == 0 {
  339. tmptags = append(tmptags, tags[j])
  340. } else {
  341. subTag = tags[j]
  342. }
  343. if subTag != "" && len(tmptags) > 0 {
  344. tmptags = append(tmptags, subTag)
  345. break
  346. }
  347. }
  348. previewImgId := ""
  349. if common.IntAll((rs)[i]["source"]) == public.SourceDd {
  350. previewImgId = fmt.Sprintf(config.JyDocsAppConfig.DoudingImg, rs[i]["previewImgId"])
  351. } else {
  352. previewImgId = fmt.Sprintf("https://%s.%s/%s", config.JyDocsAppConfig.OssBucket.Priv, config.JyDocsAppConfig.OssAdmin, rs[i]["previewImgId"])
  353. }
  354. doc := map[string]interface{}{
  355. "docId": common.ObjToString((rs)[i]["doc_id"]),
  356. "docName": common.ObjToString((rs)[i]["docName"]),
  357. "docPageSize": common.Int64All((rs)[i]["docPageSize"]),
  358. "docFileSize": common.Int64All((rs)[i]["docFileSize"]),
  359. "downTimes": common.Int64All((rs)[i]["downTimes"]),
  360. "viewTimes": common.Int64All((rs)[i]["viewTimes"]),
  361. "uploadDate": common.ObjToString((rs)[i]["uploadDate"]),
  362. "docSummary": common.ObjToString((rs)[i]["docSummary"]),
  363. "docFileType": public.DocFileType[common.IntAll((rs)[i]["docFileType"])],
  364. "previewImgId": previewImgId,
  365. "productType": common.Int64All((rs)[i]["productType"]),
  366. "source": common.Int64All((rs)[i]["source"]),
  367. "docTags": strings.Join(tmptags, " "),
  368. }
  369. list = append(list, doc)
  370. }
  371. // 存缓存
  372. if len(list) > 0 {
  373. redis.Put(public.RedisCode, topKey, list, 60*60*12)
  374. }
  375. if len(list) > pageSizeReq {
  376. list = list[:pageSizeReq]
  377. }
  378. return map[string]interface{}{
  379. "total": len(list),
  380. "list": list,
  381. }, nil
  382. }()
  383. if errMsg != nil {
  384. log.Printf("%s StdDoc search err:%s\n", userId, errMsg.Error())
  385. }
  386. stdDoc.ServeJson(NewResult(rData, errMsg))
  387. }