/** * @class UserSessionLog 用户会话日志模型 */ const BaseMod = require('./base') const Platform = require('./platform') const Channel = require('./channel') const { DateTime } = require('../lib') module.exports = class UserSessionLog extends BaseMod { constructor() { super() this.tableName = 'user-session-logs' } /** * 用户会话日志数据填充 * @param {Object} params 上报参数 */ async fill(params) { if (!params.sid) { return { code: 200, msg: 'Not found session log' } } if (!params.uid) { return { code: 200, msg: 'Parameter "uid" not found' } } const dateTime = new DateTime() const platform = new Platform() const channel = new Channel() //获取当前页面信息 if (!params.page_id) { const pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj) if (!pageInfo || pageInfo.length === 0) { return { code: 300, msg: 'Not found this entry page' } } params.page_id = pageInfo._id } const nowTime = dateTime.getTime() const fillParams = { appid: params.ak, version: params.v ? params.v : '', platform: platform.getPlatformCode(params.ut, params.p), channel: channel.getChannelCode(params), session_id: params.sid, uid: params.uid, last_visit_time: nowTime, entry_page_id: params.page_id, exit_page_id: params.page_id, page_count: 0, event_count: 0, duration: 1, is_finish: 0, create_time: nowTime, } const res = await this.insert(this.tableName, fillParams) if (res && res.id) { return { code: 0, msg: 'success' } } else { return { code: 500, msg: 'User session log filled error' } } } /** * 检测用户会话是否有变化,并更新 * @param {Object} params 校验参数 - sid:基础会话编号 uid:用户编号 last_visit_user_id:基础会话中最近一个访问用户的编号 */ async checkUserSession(params) { if (!params.sid) { return { code: 200, msg: 'Not found session log' } } if (!params.uid) { //用户已退出会话 if (params.last_visit_user_id) { if (this.debug) { console.log('user "' + params.last_visit_user_id + '" is exit session :', params.sid) } await this.closeUserSession(params.sid) } } else { //添加用户日志 if (!params.last_visit_user_id) { await this.fill(params) } //用户已切换 else if (params.uid != params.last_visit_user_id) { if (this.debug) { console.log('user "' + params.last_visit_user_id + '" change to "' + params.uid + '" in the session :', params.sid) } //关闭原会话生成新用户对话 await this.closeUserSession(params.sid) await this.fill(params) } } return { code: 0, msg: 'success' } } /** * 关闭用户会话 * @param {String} sid 基础会话编号 */ async closeUserSession(sid) { if (this.debug) { console.log('close user session log by sid:', sid) } return await this.update(this.tableName, { is_finish: 1 }, { session_id: sid, is_finish: 0 }) } /** * 更新会话信息 * @param {String} sid 基础会话编号 * @param {Object} data 更新数据 */ async updateUserSession(sid, data) { const userSession = await this.getCollection(this.tableName).where({ session_id: sid, uid: data.uid, is_finish: 0 }).orderBy('create_time', 'desc').limit(1).get() if (userSession.data.length === 0) { console.log('Not found the user session', { session_id: sid, uid: data.uid, is_finish: 0 }) return { code: 300, msg: 'Not found the user session' } } let nowTime = data.nowTime ? data.nowTime : new DateTime().getTime() const accessTime = nowTime - userSession.data[0].createTime const accessSenconds = accessTime > 1000 ? parseInt(accessTime / 1000) : 1 const updateData = { last_visit_time: nowTime, duration: accessSenconds, } //访问页面数量 if (data.addPageCount) { updateData.page_count = userSession.data[0].page_count + data.addPageCount } //最终访问的页面编号 if (data.pageId) { updateData.exit_page_id = data.pageId } //产生事件次数 if (data.eventCount) { updateData.event_count = userSession.data[0].event_count + data.addEventCount } if (this.debug) { console.log('update user session log by sid-' + sid, updateData) } await this.update(this.tableName, updateData, { _id: userSession.data[0]._id }) return { code: 0, msg: 'success' } } /** * 清理用户会话日志数据 * @param {Object} days 保留天数, 留存统计需要计算30天后留存率,因此至少应保留31天的日志数据 */ async clean(days = 31) { days = Math.max(parseInt(days), 1) console.log('clean user session logs - day:', days) const dateTime = new DateTime() const res = await this.delete(this.tableName, { create_time: { $lt: dateTime.getTimeBySetDays(0 - days) } }) if (!res.code) { console.log('clean user session log:', res) } return res } }