userSessionLog.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. /**
  2. * @class UserSessionLog 用户会话日志模型
  3. */
  4. const BaseMod = require('./base')
  5. const Platform = require('./platform')
  6. const Channel = require('./channel')
  7. const {
  8. DateTime
  9. } = require('../lib')
  10. module.exports = class UserSessionLog extends BaseMod {
  11. constructor() {
  12. super()
  13. this.tableName = 'user-session-logs'
  14. }
  15. /**
  16. * 用户会话日志数据填充
  17. * @param {Object} params 上报参数
  18. */
  19. async fill(params) {
  20. if (!params.sid) {
  21. return {
  22. code: 200,
  23. msg: 'Not found session log'
  24. }
  25. }
  26. if (!params.uid) {
  27. return {
  28. code: 200,
  29. msg: 'Parameter "uid" not found'
  30. }
  31. }
  32. const dateTime = new DateTime()
  33. const platform = new Platform()
  34. const channel = new Channel()
  35. //获取当前页面信息
  36. if (!params.page_id) {
  37. const pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj)
  38. if (!pageInfo || pageInfo.length === 0) {
  39. return {
  40. code: 300,
  41. msg: 'Not found this entry page'
  42. }
  43. }
  44. params.page_id = pageInfo._id
  45. }
  46. const nowTime = dateTime.getTime()
  47. const fillParams = {
  48. appid: params.ak,
  49. version: params.v ? params.v : '',
  50. platform: platform.getPlatformCode(params.ut, params.p),
  51. channel: channel.getChannelCode(params),
  52. session_id: params.sid,
  53. uid: params.uid,
  54. last_visit_time: nowTime,
  55. entry_page_id: params.page_id,
  56. exit_page_id: params.page_id,
  57. page_count: 0,
  58. event_count: 0,
  59. duration: 1,
  60. is_finish: 0,
  61. create_time: nowTime,
  62. }
  63. const res = await this.insert(this.tableName, fillParams)
  64. if (res && res.id) {
  65. return {
  66. code: 0,
  67. msg: 'success'
  68. }
  69. } else {
  70. return {
  71. code: 500,
  72. msg: 'User session log filled error'
  73. }
  74. }
  75. }
  76. /**
  77. * 检测用户会话是否有变化,并更新
  78. * @param {Object} params 校验参数 - sid:基础会话编号 uid:用户编号 last_visit_user_id:基础会话中最近一个访问用户的编号
  79. */
  80. async checkUserSession(params) {
  81. if (!params.sid) {
  82. return {
  83. code: 200,
  84. msg: 'Not found session log'
  85. }
  86. }
  87. if (!params.uid) {
  88. //用户已退出会话
  89. if (params.last_visit_user_id) {
  90. if (this.debug) {
  91. console.log('user "' + params.last_visit_user_id + '" is exit session :', params.sid)
  92. }
  93. await this.closeUserSession(params.sid)
  94. }
  95. } else {
  96. //添加用户日志
  97. if (!params.last_visit_user_id) {
  98. await this.fill(params)
  99. }
  100. //用户已切换
  101. else if (params.uid != params.last_visit_user_id) {
  102. if (this.debug) {
  103. console.log('user "' + params.last_visit_user_id + '" change to "' + params.uid +
  104. '" in the session :', params.sid)
  105. }
  106. //关闭原会话生成新用户对话
  107. await this.closeUserSession(params.sid)
  108. await this.fill(params)
  109. }
  110. }
  111. return {
  112. code: 0,
  113. msg: 'success'
  114. }
  115. }
  116. /**
  117. * 关闭用户会话
  118. * @param {String} sid 基础会话编号
  119. */
  120. async closeUserSession(sid) {
  121. if (this.debug) {
  122. console.log('close user session log by sid:', sid)
  123. }
  124. return await this.update(this.tableName, {
  125. is_finish: 1
  126. }, {
  127. session_id: sid,
  128. is_finish: 0
  129. })
  130. }
  131. /**
  132. * 更新会话信息
  133. * @param {String} sid 基础会话编号
  134. * @param {Object} data 更新数据
  135. */
  136. async updateUserSession(sid, data) {
  137. const userSession = await this.getCollection(this.tableName).where({
  138. session_id: sid,
  139. uid: data.uid,
  140. is_finish: 0
  141. }).orderBy('create_time', 'desc').limit(1).get()
  142. if (userSession.data.length === 0) {
  143. console.log('Not found the user session', {
  144. session_id: sid,
  145. uid: data.uid,
  146. is_finish: 0
  147. })
  148. return {
  149. code: 300,
  150. msg: 'Not found the user session'
  151. }
  152. }
  153. let nowTime = data.nowTime ? data.nowTime : new DateTime().getTime()
  154. const accessTime = nowTime - userSession.data[0].createTime
  155. const accessSenconds = accessTime > 1000 ? parseInt(accessTime / 1000) : 1
  156. const updateData = {
  157. last_visit_time: nowTime,
  158. duration: accessSenconds,
  159. }
  160. //访问页面数量
  161. if (data.addPageCount) {
  162. updateData.page_count = userSession.data[0].page_count + data.addPageCount
  163. }
  164. //最终访问的页面编号
  165. if (data.pageId) {
  166. updateData.exit_page_id = data.pageId
  167. }
  168. //产生事件次数
  169. if (data.eventCount) {
  170. updateData.event_count = userSession.data[0].event_count + data.addEventCount
  171. }
  172. if (this.debug) {
  173. console.log('update user session log by sid-' + sid, updateData)
  174. }
  175. await this.update(this.tableName, updateData, {
  176. _id: userSession.data[0]._id
  177. })
  178. return {
  179. code: 0,
  180. msg: 'success'
  181. }
  182. }
  183. /**
  184. * 清理用户会话日志数据
  185. * @param {Object} days 保留天数, 留存统计需要计算30天后留存率,因此至少应保留31天的日志数据
  186. */
  187. async clean(days = 31) {
  188. days = Math.max(parseInt(days), 1)
  189. console.log('clean user session logs - day:', days)
  190. const dateTime = new DateTime()
  191. const res = await this.delete(this.tableName, {
  192. create_time: {
  193. $lt: dateTime.getTimeBySetDays(0 - days)
  194. }
  195. })
  196. if (!res.code) {
  197. console.log('clean user session log:', res)
  198. }
  199. return res
  200. }
  201. }