userDoc.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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. "encoding/json"
  7. "errors"
  8. "fmt"
  9. "jy-docs/config"
  10. "jy-docs/public"
  11. "jy-docs/rpc"
  12. "log"
  13. "time"
  14. )
  15. type UserDoc struct {
  16. *xweb.Action
  17. userList xweb.Mapper `xweb:"/user/list"` //用户列表
  18. collectAdd xweb.Mapper `xweb:"/user/collect/add"` //收藏文库
  19. collectRemove xweb.Mapper `xweb:"/user/collect/remove"` //取消收藏
  20. docBuy xweb.Mapper `xweb:"/user/buy"` //文库购买
  21. info xweb.Mapper `xweb:"/user/info"` //文库会员信息
  22. }
  23. // 用户文库列表
  24. func (userDoc *UserDoc) UserList() {
  25. userId := common.ObjToString(userDoc.GetSession("userId"))
  26. rData, errMsg := func() (interface{}, error) {
  27. pageNumReq, _ := userDoc.GetInt("num")
  28. pageSizeReq, _ := userDoc.GetInt("size")
  29. sign, _ := userDoc.GetInt("sign") // 0兑换的 1收藏的 2回收站的
  30. pageNum, pageSize, _ := public.PageNumParse(pageNumReq, pageSizeReq, -1)
  31. if sign < 0 || sign > 2 {
  32. return nil, fmt.Errorf("请求参数异常")
  33. }
  34. collectList, total, err := rpc.GetUserDocs(userId, pageNum, pageSize, sign)
  35. if err != nil {
  36. return nil, err
  37. }
  38. return map[string]interface{}{
  39. "total": total,
  40. "list": collectList,
  41. }, nil
  42. }()
  43. if errMsg != nil {
  44. log.Printf("%s UserDoc collectList err:%s\n", userId, errMsg.Error())
  45. }
  46. userDoc.ServeJson(NewResult(rData, errMsg))
  47. }
  48. func (userDoc *UserDoc) CollectAdd() {
  49. userId := common.ObjToString(userDoc.GetSession("userId"))
  50. rData, errMsg := func() (interface{}, error) {
  51. docId := userDoc.GetString("docId")
  52. if docId == "" {
  53. return nil, fmt.Errorf("参数异常")
  54. }
  55. err := rpc.SetUserCollect(userId, docId)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return "success", nil
  60. }()
  61. if errMsg != nil {
  62. log.Printf("%s UserDoc collectAdd err:%s\n", userId, errMsg.Error())
  63. }
  64. userDoc.ServeJson(NewResult(rData, errMsg))
  65. }
  66. func (userDoc *UserDoc) CollectRemove() {
  67. userId := common.ObjToString(userDoc.GetSession("userId"))
  68. rData, errMsg := func() (interface{}, error) {
  69. docId := userDoc.GetString("docId")
  70. if docId == "" {
  71. return nil, fmt.Errorf("参数异常")
  72. }
  73. err := rpc.DelUserCollect(userId, docId)
  74. if err != nil {
  75. return nil, err
  76. }
  77. return "success", nil
  78. }()
  79. if errMsg != nil {
  80. log.Printf("%s UserDoc collectRemove err:%s\n", userId, errMsg.Error())
  81. }
  82. userDoc.ServeJson(NewResult(rData, errMsg))
  83. }
  84. func (userDoc *UserDoc) DocBuy() {
  85. // 加用户锁
  86. userInfo := public.GetUserBaseInfo(userDoc.Session())
  87. userId := userInfo.UserId
  88. pLock := public.GetNewDocBuyLock(fmt.Sprintf("%s", userId))
  89. pLock.Lock()
  90. defer pLock.Unlock()
  91. rData, errMsg := func() (interface{}, error) {
  92. docId := userDoc.GetString("docId")
  93. phone := userDoc.GetString("phone")
  94. payType, _ := userDoc.GetInt("payType") // 0-正常下载 1-原价下载 2-使用一次免费下载机会(会员免费文档 留资)
  95. if docId == "" {
  96. return nil, fmt.Errorf("参数异常")
  97. }
  98. var userPoint, docPoint int64 = 0, 0
  99. var err error
  100. usePoint := true // 是否消耗剑鱼币 会员免费文档且当天100篇以内的或者使用免费下载机会的 不用扣积分
  101. useSLTimes := false // 使用留资机会的下载次数
  102. //查询文档所需积分及文档类型
  103. docInfo, isBuy, _, err := rpc.GetDocDetail(userId, docId)
  104. if err != nil {
  105. return nil, err
  106. }
  107. if isBuy {
  108. return nil, fmt.Errorf("已兑换,请勿重复操作")
  109. }
  110. // 获取用户身份
  111. docMember, err := getDocMemberStatus(userId)
  112. if err != nil {
  113. return nil, err
  114. }
  115. docMemberStatus := docMember["docMemberStatus"].(bool)
  116. freeDownload := docMember["free_download"].(int)
  117. if docMemberStatus {
  118. // 会员
  119. switch payType {
  120. case public.PayTypeNormal:
  121. if docInfo.ProductType == public.ProductTypeMemberFree {
  122. // 如果是会员免费 判断是否超出进入下载次数
  123. // 获取今日下载次数
  124. count, err2 := rpc.TodayCount(userId)
  125. if err2 != nil {
  126. return nil, err2
  127. }
  128. if int(count) >= config.JyDocsAppConfig.DocMember.Times {
  129. return map[string]interface{}{
  130. "status": public.StatusMemberFreeExhaust,
  131. }, nil
  132. }
  133. // 没有超过下载次数 下一步应该到转存 不用扣剑鱼币
  134. usePoint = false
  135. } else {
  136. // 精品文档
  137. docPoint = docInfo.DocMemberPrice // 会员价
  138. }
  139. case public.PayTypeFullPrice:
  140. docPoint = docInfo.Price
  141. default:
  142. return nil, errors.New("payType类型不匹配")
  143. }
  144. } else {
  145. switch payType {
  146. case public.PayTypeFreeSL:
  147. if freeDownload != public.FreeDownloadHasFreeTimes || docInfo.ProductType != public.ProductTypeMemberFree {
  148. return nil, fmt.Errorf("没有免费下载机会")
  149. }
  150. usePoint = false // 免费下载的不扣剑鱼币
  151. useSLTimes = true // 后边要处理该字段
  152. case public.PayTypeFullPrice:
  153. docPoint = docInfo.Price // 原价下的
  154. default:
  155. return nil, errors.New("payType类型不匹配")
  156. }
  157. }
  158. var serialNumber string
  159. if usePoint { // 扣积分
  160. //查询用户剩余积分
  161. userPoint, err = rpc.GetUserPointValue(userId)
  162. if err != nil {
  163. return nil, err
  164. }
  165. //积分够调扣积分
  166. if userPoint < docPoint {
  167. return nil, fmt.Errorf("剩余积分不足")
  168. }
  169. bytes, err := json.Marshal(map[string]interface{}{
  170. "name": docInfo.DocName,
  171. "summary": docInfo.DocSummary,
  172. "img": docInfo.PreviewImgId,
  173. "fType": docInfo.DocFileType,
  174. })
  175. if err != nil {
  176. return nil, fmt.Errorf("文库异常")
  177. }
  178. serialNumber, err = rpc.SpendUserPoint(userId, docInfo.DocId, string(bytes), docPoint)
  179. if err != nil {
  180. return nil, err
  181. }
  182. }
  183. // 没有ossdocId 说明是还没有下过的 需要先获得地址
  184. if docInfo.OssDocId == "" {
  185. // 如果是精品 则需要先调购买接口
  186. if docInfo.ProductType == public.ProductTypePremium {
  187. _, err2 := rpc.PartUserBuy(docId, userInfo.MgoUserId, userInfo.Phone, userInfo.PositionId)
  188. if err2 != nil {
  189. return nil, fmt.Errorf("获取失败")
  190. }
  191. }
  192. // 如果是免费则直接调
  193. _, err := rpc.PartDocDownload(docId, userInfo.MgoUserId, userInfo.Phone, userInfo.PositionId)
  194. if err != nil {
  195. return nil, fmt.Errorf("获取失败")
  196. }
  197. }
  198. //转存文库
  199. err = rpc.PayDoc(userId, docId)
  200. if err != nil {
  201. return nil, err
  202. }
  203. if useSLTimes {
  204. public.Compatible.Update(userId, map[string]interface{}{
  205. "$set": M{
  206. "i_doc_free_download": 1,
  207. },
  208. })
  209. }
  210. //手机号采集
  211. go func() {
  212. if phone != "" {
  213. public.MQFW.Save("user_msg", map[string]interface{}{
  214. "s_userId": userId,
  215. "s_phone": phone,
  216. "i_phoneCheck": -1, //未验证
  217. "i_time": time.Now().Unix(),
  218. "s_source": "jydoc",
  219. })
  220. }
  221. rpc.DocStatistics(userId, docId, rpc.Down)
  222. }()
  223. return map[string]interface{}{
  224. "code": serialNumber,
  225. "balance": userPoint - docPoint,
  226. "payTime": time.Now().Unix(),
  227. "payWay": "剑鱼币",
  228. }, nil
  229. }()
  230. if errMsg != nil {
  231. log.Printf("%s UserDoc docBuy err:%s\n", userId, errMsg.Error())
  232. }
  233. userDoc.ServeJson(NewResult(rData, errMsg))
  234. }
  235. // Info 剑鱼文库会员信息
  236. func (userDoc *UserDoc) Info() {
  237. userId := common.ObjToString(userDoc.GetSession("userId"))
  238. rData, errMsg := func() (interface{}, error) {
  239. if userId == "" {
  240. return map[string]interface{}{
  241. "docMemberStatus": false,
  242. "startTime": 0,
  243. "endTime": 0,
  244. "free_download": public.FreeDownloadNoSL,
  245. }, nil
  246. }
  247. return getDocMemberStatus(userId)
  248. }()
  249. if errMsg != nil {
  250. log.Printf("%s UserDoc Info err:%s\n", userId, errMsg.Error())
  251. }
  252. userDoc.ServeJson(NewResult(rData, errMsg))
  253. }
  254. func getDocMemberStatus(userId string) (map[string]interface{}, error) {
  255. mData := public.Compatible.Select(userId, `{"i_doc_status":1,"l_doc_endtime":1,"l_doc_starttime":1,"i_doc_free_download":1}`)
  256. if mData != nil && len(*mData) > 0 {
  257. vipStatus := common.IntAll((*mData)["i_doc_status"])
  258. free_download := common.IntAll((*mData)["i_doc_free_download"])
  259. if free_download == 0 && vipStatus <= 0 { // 不是文库会员时再查 没有使用过一次免费下载机会
  260. // 查留资
  261. count := public.MQFW.Count("saleLeads", map[string]interface{}{"userid": userId, "source": map[string]interface{}{"$in": config.JyDocsAppConfig.DocMember.Source}})
  262. if count > 0 {
  263. free_download = public.FreeDownloadHasFreeTimes
  264. } else {
  265. free_download = public.FreeDownloadNoSL
  266. }
  267. }
  268. return map[string]interface{}{
  269. "docMemberStatus": vipStatus > 0,
  270. "startTime": (*mData)["l_doc_starttime"],
  271. "endTime": (*mData)["l_doc_endtime"],
  272. "free_download": free_download,
  273. }, nil
  274. }
  275. return nil, errors.New("获取文库会员状态失败")
  276. }