123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322 |
- /**
- * @class PageResult 页面详情结果统计模型,既页面内容统计模型
- */
- const BaseMod = require('./base')
- const Platform = require('./platform')
- const Channel = require('./channel')
- const Version = require('./version')
- const SessionLog = require('./sessionLog')
- const PageLog = require('./pageLog')
- const ShareLog = require('./shareLog')
- const {
- DateTime
- } = require('../lib')
- module.exports = class PageResult extends BaseMod {
- constructor() {
- super()
- this.tableName = 'page-detail-result'
- this.platforms = []
- this.channels = []
- this.versions = []
- }
- /**
- * 数据统计
- * @param {String} type 统计类型 hour:实时统计 day:按天统计,week:按周统计 month:按月统计
- * @param {Date|Time} date 指定日期或时间戳
- * @param {Boolean} reset 是否重置,为ture时会重置该批次数据
- */
- async stat(type, date, reset) {
- if(!this.getConfig('pageDetailStat')) {
- return {
- code: 1001,
- msg: 'The page detail module not opened'
- }
- }
- //允许的类型
- const allowedType = ['day']
- if (!allowedType.includes(type)) {
- return {
- code: 1002,
- msg: 'This type is not allowed'
- }
- }
- this.fillType = type
- //获取当前统计的时间范围
- const dateTime = new DateTime()
- const dateDimension = dateTime.getTimeDimensionByType(type, -1, date)
- this.startTime = dateDimension.startTime
- this.endTime = dateDimension.endTime
- if (this.debug) {
- console.log('dimension time', this.startTime + '--' + this.endTime)
- }
- // 查看当前时间段日志是否已存在,防止重复执行
- if (!reset) {
- const checkRes = await this.getCollection(this.tableName).where({
- start_time: this.startTime,
- end_time: this.endTime
- }).get()
- if (checkRes.data.length > 0) {
- console.error('This page detail stat log have exists')
- return {
- code: 1003,
- msg: 'This page detail stat log have existed'
- }
- }
- } else {
- const delRes = await this.delete(this.tableName, {
- start_time: this.startTime,
- end_time: this.endTime
- })
- console.log('Delete old data result:', JSON.stringify(delRes))
- }
- // 数据获取
- this.pageLog = new PageLog()
- const statRes = await this.aggregate(this.pageLog.tableName, {
- match: {
- create_time: {
- $gte: this.startTime,
- $lte: this.endTime
- },
- page_detail_id: {
- $exists: true
- }
- },
- group: {
- _id: {
- appid: '$appid',
- version: '$version',
- platform: '$platform',
- channel: '$channel',
- page_detail_id: '$page_detail_id'
- },
- page_id: {
- $first: '$page_id'
- },
- visit_times: {
- $sum: 1
- }
- },
- sort: {
- visit_times: 1
- },
- getAll: true
- })
- let res = {
- code: 0,
- msg: 'success'
- }
- if (this.debug) {
- console.log('Page detail statRes', JSON.stringify(statRes.data))
- }
- if (statRes.data.length > 0) {
- this.fillData = []
- //获取填充数据
- for (const pdd of statRes.data) {
- try {
- await this.fill(pdd)
- } catch (e) {
- console.error('Page detail result data filled error', e, pdd)
- }
- }
- //数据批量入库
- if (this.fillData.length > 0) {
- res = await this.batchInsert(this.tableName, this.fillData)
- }
- }
- return res
- }
- /**
- * 页面详情(内容)统计数据填充
- * @param {Object} data 统计数据
- */
- async fill(data) {
- // 平台信息
- let platformInfo = null
- if (this.platforms && this.platforms[data._id.platform]) {
- //暂存下数据,减少读库
- platformInfo = this.platforms[data._id.platform]
- } else {
- const platform = new Platform()
- platformInfo = await platform.getPlatformAndCreate(data._id.platform, null)
- if (!platformInfo || platformInfo.length === 0) {
- platformInfo._id = ''
- }
- this.platforms[data._id.platform] = platformInfo
- if (this.debug) {
- console.log('platformInfo', JSON.stringify(platformInfo))
- }
- }
- // 渠道信息
- let channelInfo = null
- const channelKey = data._id.appid + '_' + platformInfo._id + '_' + data._id.channel
- if (this.channels && this.channels[channelKey]) {
- channelInfo = this.channels[channelKey]
- } else {
- const channel = new Channel()
- channelInfo = await channel.getChannelAndCreate(data._id.appid, platformInfo._id, data._id.channel)
- if (!channelInfo || channelInfo.length === 0) {
- channelInfo._id = ''
- }
- this.channels[channelKey] = channelInfo
- if (this.debug) {
- console.log('channelInfo', JSON.stringify(channelInfo))
- }
- }
- // 版本信息
- let versionInfo = null
- const versionKey = data._id.appid + '_' + data._id.platform + '_' + data._id.version
- if (this.versions && this.versions[versionKey]) {
- versionInfo = this.versions[versionKey]
- } else {
- const version = new Version()
- versionInfo = await version.getVersionAndCreate(data._id.appid, data._id.platform, data._id.version)
- if (!versionInfo || versionInfo.length === 0) {
- versionInfo._id = ''
- }
- this.versions[versionKey] = versionInfo
- if (this.debug) {
- console.log('versionInfo', JSON.stringify(versionInfo))
- }
- }
- const matchCondition = data._id
- Object.assign(matchCondition, {
- create_time: {
- $gte: this.startTime,
- $lte: this.endTime
- }
- })
- if (this.debug) {
- console.log('matchCondition', JSON.stringify(matchCondition))
- }
- // 当前页面详情访问设备数
- const statPageDetailDeviceRes = await this.aggregate(this.pageLog.tableName, {
- match: matchCondition,
- group: [{
- _id: {
- device_id: '$device_id'
- }
- }, {
- _id: {},
- total_devices: {
- $sum: 1
- }
- }]
- })
- let pageDetailVisitDevices = 0
- if (statPageDetailDeviceRes.data.length > 0) {
- pageDetailVisitDevices = statPageDetailDeviceRes.data[0].total_devices
- }
- //当前页面详情访问人数
- const statPageDetailUserRes = await this.aggregate(this.pageLog.tableName, {
- match: {
- ...matchCondition,
- uid: {
- $ne: ''
- }
- },
- group: [{
- _id: {
- uid: '$uid'
- }
- }, {
- _id: {},
- total_users: {
- $sum: 1
- }
- }]
- })
- let pageDetailVisitUsers = 0
- if (statPageDetailUserRes.data.length > 0) {
- pageDetailVisitUsers = statPageDetailUserRes.data[0].total_users
- }
- // 访问时长
- const statPageDetailDurationRes = await this.aggregate(this.pageLog.tableName, {
- match: {
- appid: data._id.appid,
- version: data._id.version,
- platform: data._id.platform,
- channel: data._id.channel,
- previous_page_detail_id: data._id.page_detail_id,
- create_time: {
- $gte: this.startTime,
- $lte: this.endTime
- }
- },
- group: {
- _id: {},
- total_duration: {
- $sum: '$previous_page_duration'
- }
- }
- })
- let totalDuration = 0
- if (statPageDetailDurationRes.data.length > 0) {
- totalDuration = statPageDetailDurationRes.data[0].total_duration
- }
- // 分享次数
- const shareLog = new ShareLog()
- const statShareRes = await this.aggregate(shareLog.tableName, {
- match: {
- appid: data._id.appid,
- version: data._id.version,
- platform: data._id.platform,
- channel: data._id.channel,
- page_detail_id: data._id.page_detail_id,
- create_time: {
- $gte: this.startTime,
- $lte: this.endTime
- }
- },
- group: {
- _id: {},
- share_count: {
- $sum: 1
- }
- }
- })
- let shareCount = 0
- if (statShareRes.data.length > 0) {
- shareCount = statShareRes.data[0].share_count
- }
- // 数据填充
- const datetime = new DateTime()
- const insertParams = {
- appid: data._id.appid,
- platform_id: platformInfo._id,
- channel_id: channelInfo._id,
- version_id: versionInfo._id,
- page_id: data.page_id,
- page_detail_id: data._id.page_detail_id,
- visit_times: data.visit_times,
- visit_devices: pageDetailVisitDevices,
- visit_users: pageDetailVisitUsers,
- duration: totalDuration > 0 ? totalDuration : 1,
- share_count: shareCount,
- dimension: this.fillType,
- stat_date: datetime.getDate('Ymd', this.startTime),
- start_time: this.startTime,
- end_time: this.endTime
- }
- this.fillData.push(insertParams)
- return insertParams
- }
- }
|