@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<view class="dishes-item">
|
||||||
|
<!-- 菜品左侧图片区域 -->
|
||||||
|
<view class="dishes-item-left">
|
||||||
|
<image :src="dishes.dish_src" class="dishes-pic"></image>
|
||||||
|
</view>
|
||||||
|
<!-- 菜品右侧信息区域 -->
|
||||||
|
<view class="dishes-item-right">
|
||||||
|
<!-- 菜品标题 -->
|
||||||
|
<view class="dishes-name">{{dishes.dish_name}}</view>
|
||||||
|
<view class="dishes-info-box">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
dishes: {
|
||||||
|
type: Object,
|
||||||
|
default:{},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data: {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.dishes-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 10px 5px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
|
||||||
|
.dishes-item-left {
|
||||||
|
margin-right: 5px;
|
||||||
|
|
||||||
|
.dishes-pic {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dishes-item-right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.dishes-name {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dishes-price {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #c00000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<view class="my-search-container" @click="searchBoxHandler">
|
||||||
|
<!-- 使用 view 组件模拟 input 输入框的样式 -->
|
||||||
|
<view class="my-search-box">
|
||||||
|
<uni-icons type="search" size="17"></uni-icons>
|
||||||
|
<text class="placeholder">搜索</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name:"my-search",
|
||||||
|
props: {
|
||||||
|
// 背景颜色
|
||||||
|
bgcolor: {
|
||||||
|
type: String,
|
||||||
|
default: '#C00000'
|
||||||
|
},
|
||||||
|
// 圆角尺寸
|
||||||
|
radius: {
|
||||||
|
type: Number,
|
||||||
|
// 单位是 px
|
||||||
|
default: 18
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
searchBoxHandler(){
|
||||||
|
// 触发外界通过 @click 绑定的 click 事件处理函数
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.my-search-container {
|
||||||
|
background-color: #c00000;
|
||||||
|
height: 50px;
|
||||||
|
padding: 0 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.my-search-box {
|
||||||
|
height: 36px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 15px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
font-size: 15px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,19 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<view>
|
<view class="my-container">
|
||||||
|
<my-login v-if="!token"></my-login>
|
||||||
|
|
||||||
</view>
|
<my-userinfo v-else></my-userinfo>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
import {mapState} from "vuex"
|
||||||
data() {
|
export default {
|
||||||
return {
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
}
|
computed: {
|
||||||
|
...mapState('m_user',['token'])
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
page,
|
||||||
|
.my-container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 765 B |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 544 B |
After Width: | Height: | Size: 759 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 715 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 672 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 765 B |
After Width: | Height: | Size: 435 B |
After Width: | Height: | Size: 596 B |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 589 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.9 KiB |
@ -0,0 +1,122 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
|
||||||
|
<view class="image_view">
|
||||||
|
<image class='dish_image' :src="dish_image_src"></image>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<text>{{"菜品名称:" + dish_name + '\n'}}</text>
|
||||||
|
<text>{{"菜品位置:" + dish_location + dish_window_name + '\n'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="evaluete">
|
||||||
|
|
||||||
|
<hb-comment ref="hbComment" @add="add" @del="del" @like="like" :deleteTip="'确认删除?'"
|
||||||
|
:cmData="commentData" v-if="commentData"></hb-comment>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<text>{{"评分:\n"}}</text>
|
||||||
|
<uni-rate v-model="value" @change="onChange(e.value)" allow-half="true" size="75" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dish_image_src: '',
|
||||||
|
dish_name: '',
|
||||||
|
dish_label: [],
|
||||||
|
dish_location: '',
|
||||||
|
dish_window_name: '',
|
||||||
|
value: 4,
|
||||||
|
comentData:[],
|
||||||
|
dish_id:''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad(option) {
|
||||||
|
|
||||||
|
//this.getLabels()
|
||||||
|
this.dish_id = JSON.parse(decodeURIComponent(option._id))
|
||||||
|
this.getImage()
|
||||||
|
console.log(this.dish_id )
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getImage() {
|
||||||
|
let that = this
|
||||||
|
uniCloud.callFunction({
|
||||||
|
name: 'getDishes',
|
||||||
|
data: {
|
||||||
|
api: 'getByID',
|
||||||
|
id: this.dish_id
|
||||||
|
},
|
||||||
|
success: function(res) {
|
||||||
|
that.dish_image_src = res.result.data[0].dish_src
|
||||||
|
that.dish_name = res.result.data[0].dish_name
|
||||||
|
that.dish_location =res.result.data[0].location
|
||||||
|
that.dish_window_name =res.result.data[0].window_name
|
||||||
|
console.log(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getLabels() {
|
||||||
|
let that = this
|
||||||
|
uniCloud.callFunction({
|
||||||
|
name: 'getLabels',
|
||||||
|
data: {
|
||||||
|
id: '650e8610a09a9bd68ba734ed'
|
||||||
|
},
|
||||||
|
success: function(res) {
|
||||||
|
that.dish_label = res.result.data[0].labelList
|
||||||
|
console.log(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChange() {
|
||||||
|
this.value = e.value
|
||||||
|
|
||||||
|
},
|
||||||
|
updateScore() {
|
||||||
|
uniCloud.callFunction({
|
||||||
|
name: 'scoreUpdate',
|
||||||
|
data: {
|
||||||
|
//用户信息和获取的评分
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
add(commentReq){
|
||||||
|
console.log(commentReq)
|
||||||
|
},
|
||||||
|
del(commentid){
|
||||||
|
console.log(commentid)
|
||||||
|
},
|
||||||
|
like(commentid){
|
||||||
|
console.log(commentid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.image_view {
|
||||||
|
height: 400rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
padding-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dish_image {
|
||||||
|
display: flex;
|
||||||
|
height: 400rpx;
|
||||||
|
width: 600rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.evaluete{
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<d-search-log @onSearchNameApi="onSearchNameApi"></d-search-log>
|
||||||
|
<view>
|
||||||
|
<view class="serach-list" v-for="(data,i) in dishList" :key="i">
|
||||||
|
|
||||||
|
<view class="dish-item">
|
||||||
|
<image class="dish-image" :src="data[i].dish_src"></image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Vue from 'vue'
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dishList: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async onSearchNameApi(e) {
|
||||||
|
let that = this
|
||||||
|
let data = []
|
||||||
|
uniCloud.callFunction({
|
||||||
|
name: 'getDishes',
|
||||||
|
data: {
|
||||||
|
api: 'getByName',
|
||||||
|
dish_name: e
|
||||||
|
},
|
||||||
|
success: function(res) {
|
||||||
|
|
||||||
|
/*that.dishList.splice(0)
|
||||||
|
data = [res.result.data]
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
Vue.set(that.dishList, i, data[i])
|
||||||
|
}*/
|
||||||
|
|
||||||
|
console.log(res)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.searchbox {
|
||||||
|
width: 500;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-list {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dish_image {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,23 @@
|
|||||||
|
const {
|
||||||
|
createApi
|
||||||
|
} = require('./shared/index')
|
||||||
|
|
||||||
|
let reportDataReceiver, dataStatCron
|
||||||
|
module.exports = {
|
||||||
|
//uni统计数据上报数据接收器初始化
|
||||||
|
initReceiver: (options = {}) => {
|
||||||
|
if(!reportDataReceiver) {
|
||||||
|
reportDataReceiver = require('./stat/receiver')
|
||||||
|
}
|
||||||
|
options.clientType = options.clientType || __ctx__.PLATFORM
|
||||||
|
return createApi(reportDataReceiver, options)
|
||||||
|
},
|
||||||
|
//uni统计数据统计模块初始化
|
||||||
|
initStat: (options = {}) => {
|
||||||
|
if(!dataStatCron) {
|
||||||
|
dataStatCron = require('./stat/stat')
|
||||||
|
}
|
||||||
|
options.clientType = options.clientType || __ctx__.PLATFORM
|
||||||
|
return createApi(dataStatCron, options)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "uni-stat",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "uni-stat",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"uni-config-center": "file:../../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* @class UniCloudError 错误处理模块
|
||||||
|
*/
|
||||||
|
module.exports = class UniCloudError extends Error {
|
||||||
|
constructor (options) {
|
||||||
|
super(options.message)
|
||||||
|
this.errMsg = options.message || ''
|
||||||
|
Object.defineProperties(this, {
|
||||||
|
message: {
|
||||||
|
get () {
|
||||||
|
return `errCode: ${options.code || ''} | errMsg: ` + this.errMsg
|
||||||
|
},
|
||||||
|
set (msg) {
|
||||||
|
this.errMsg = msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
module.exports = {
|
||||||
|
UniCloudError: require('./error'),
|
||||||
|
createApi: require('./create-api'),
|
||||||
|
... require('./utils')
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
module.exports = {
|
||||||
|
DateTime: require('./date'),
|
||||||
|
UniCrypto: require('./uni-crypto')
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* @class AppCrashLogs 原生应用崩溃日志模型
|
||||||
|
* @function clean 原生应用崩溃日志清理函数
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const {
|
||||||
|
DateTime,
|
||||||
|
UniCrypto
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class AppCrashLogs extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'app-crash-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原生应用崩溃日志清理函数
|
||||||
|
* @param {Number} days 保留天数
|
||||||
|
*/
|
||||||
|
async clean(days = 7) {
|
||||||
|
days = Math.max(parseInt(days), 1)
|
||||||
|
console.log('clean app crash 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 app crash log:', res)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
/**
|
||||||
|
* @class Channel 渠道模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const Scenes = require('./scenes')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class Channel extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'app-channels'
|
||||||
|
this.scenes = new Scenes()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取渠道信息
|
||||||
|
* @param {String} appid
|
||||||
|
* @param {String} platformId 平台编号
|
||||||
|
* @param {String} channel 渠道代码
|
||||||
|
*/
|
||||||
|
async getChannel(appid, platformId, channel) {
|
||||||
|
const cacheKey = 'uni-stat-channel-' + appid + '-' + platformId + '-' + channel
|
||||||
|
let channelData = await this.getCache(cacheKey)
|
||||||
|
if (!channelData) {
|
||||||
|
const channelInfo = await this.getCollection(this.tableName).where({
|
||||||
|
appid: appid,
|
||||||
|
platform_id: platformId,
|
||||||
|
channel_code: channel
|
||||||
|
}).limit(1).get()
|
||||||
|
channelData = []
|
||||||
|
if (channelInfo.data.length > 0) {
|
||||||
|
channelData = channelInfo.data[0]
|
||||||
|
if (channelData.channel_name === '') {
|
||||||
|
const scenesName = await this.scenes.getScenesNameByPlatformId(platformId, channel)
|
||||||
|
if (scenesName) {
|
||||||
|
await this.update(this.tableName, {
|
||||||
|
channel_name: scenesName,
|
||||||
|
update_time: new DateTime().getTime()
|
||||||
|
}, {
|
||||||
|
_id: channelData._id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.setCache(cacheKey, channelData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return channelData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取渠道信息没有则进行创建
|
||||||
|
* @param {String} appid
|
||||||
|
* @param {String} platformId
|
||||||
|
* @param {String} channel
|
||||||
|
*/
|
||||||
|
async getChannelAndCreate(appid, platformId, channel) {
|
||||||
|
if (!appid || !platformId) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const channelInfo = await this.getChannel(appid, platformId, channel)
|
||||||
|
if (channelInfo.length === 0) {
|
||||||
|
const thisTime = new DateTime().getTime()
|
||||||
|
const insertParam = {
|
||||||
|
appid: appid,
|
||||||
|
platform_id: platformId,
|
||||||
|
channel_code: channel,
|
||||||
|
channel_name: await this.scenes.getScenesNameByPlatformId(platformId, channel),
|
||||||
|
create_time: thisTime,
|
||||||
|
update_time: thisTime
|
||||||
|
}
|
||||||
|
const res = await this.insert(this.tableName, insertParam)
|
||||||
|
if (res && res.id) {
|
||||||
|
return Object.assign(insertParam, {
|
||||||
|
_id: res.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return channelInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取渠道_id
|
||||||
|
* @param {String} appid
|
||||||
|
* @param {String} platformId
|
||||||
|
* @param {String} channel
|
||||||
|
*/
|
||||||
|
async getChannelId(appid, platformId, channel) {
|
||||||
|
const channelInfo = await this.getChannel(appid, platformId, channel)
|
||||||
|
return channelInfo.length > 0 ? channelInfo._id : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取渠道码或者场景值
|
||||||
|
* @param {Object} params 上报参数
|
||||||
|
*/
|
||||||
|
getChannelCode(params) {
|
||||||
|
//小程序未上报渠道则使用场景值
|
||||||
|
if (params.ch) {
|
||||||
|
return params.ch
|
||||||
|
} else if (params.sc && params.ut.indexOf('mp-') === 0) {
|
||||||
|
return params.sc
|
||||||
|
}
|
||||||
|
return this.scenes.defualtCode
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
/**
|
||||||
|
* @class Device 设备模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const Platform = require('./platform')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class Device extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'opendb-device'
|
||||||
|
this.tablePrefix = false
|
||||||
|
this.cacheKeyPre = 'uni-stat-device-'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过设备编号获取设备信息
|
||||||
|
* @param {Object} deviceId 设备编号
|
||||||
|
*/
|
||||||
|
async getDeviceById(deviceId) {
|
||||||
|
const cacheKey = this.cacheKeyPre + deviceId
|
||||||
|
let deviceData = await this.getCache(cacheKey)
|
||||||
|
if (!deviceData) {
|
||||||
|
const deviceRes = await this.getCollection().where({
|
||||||
|
device_id: deviceId
|
||||||
|
}).get()
|
||||||
|
deviceData = []
|
||||||
|
if (deviceRes.data.length > 0) {
|
||||||
|
deviceData = deviceRes.data[0]
|
||||||
|
await this.setCache(cacheKey, deviceData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deviceData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置设备信息
|
||||||
|
* @param {Object} params 上报参数
|
||||||
|
*/
|
||||||
|
async setDevice(params) {
|
||||||
|
// 设备信息
|
||||||
|
if (!params.did) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Parameter "did" not found'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const deviceData = await this.getDeviceById(params.did)
|
||||||
|
//不存在则添加
|
||||||
|
if(deviceData.length === 0) {
|
||||||
|
return await this.addDevice(params)
|
||||||
|
} else {
|
||||||
|
return await this.updateDevice(params, deviceData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加设备信息
|
||||||
|
* @param {Object} params 上报参数
|
||||||
|
*/
|
||||||
|
async addDevice(params) {
|
||||||
|
const dateTime = new DateTime()
|
||||||
|
const platform = new Platform()
|
||||||
|
const fillParams = {
|
||||||
|
device_id: params.did,
|
||||||
|
appid: params.ak,
|
||||||
|
vendor: params.brand ? params.brand : '',
|
||||||
|
push_clientid: params.cid ? params.cid : '',
|
||||||
|
imei: params.imei ? params.imei : '',
|
||||||
|
oaid: params.oaid ? params.oaid : '',
|
||||||
|
idfa: params.idfa ? params.idfa : '',
|
||||||
|
imsi: params.imsi ? params.imsi : '',
|
||||||
|
model: params.md ? params.md : '',
|
||||||
|
uni_platform: params.up ? params.up : '',
|
||||||
|
os_name: params.on ? params.on : platform.getOsName(params.p),
|
||||||
|
os_version: params.sv ? params.sv : '',
|
||||||
|
os_language: params.lang ? params.lang : '',
|
||||||
|
os_theme: params.ot ? params.ot : '',
|
||||||
|
pixel_ratio: params.pr ? params.pr : '',
|
||||||
|
network_model: params.net ? params.net : '',
|
||||||
|
window_width: params.ww ? params.ww : '',
|
||||||
|
window_height: params.wh ? params.wh : '',
|
||||||
|
screen_width: params.sw ? params.sw : '',
|
||||||
|
screen_height: params.sh ? params.sh : '',
|
||||||
|
rom_name: params.rn ? params.rn : '',
|
||||||
|
rom_version: params.rv ? params.rv : '',
|
||||||
|
location_ip: params.ip ? params.ip : '',
|
||||||
|
location_latitude: params.lat ? parseFloat(params.lat) : 0,
|
||||||
|
location_longitude: params.lng ? parseFloat(params.lng) : 0,
|
||||||
|
location_country: params.cn ? params.cn : '',
|
||||||
|
location_province: params.pn ? params.pn : '',
|
||||||
|
location_city: params.ct ? params.ct : '',
|
||||||
|
create_date: dateTime.getTime(),
|
||||||
|
last_update_date: dateTime.getTime()
|
||||||
|
}
|
||||||
|
const res = await this.insert(this.tableName, fillParams)
|
||||||
|
if (res && res.id) {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: 'success',
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
msg: 'Device data filled error'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改设备信息
|
||||||
|
* @param {Object} params
|
||||||
|
* @param {Object} deviceData
|
||||||
|
*/
|
||||||
|
async updateDevice(params, deviceData) {
|
||||||
|
//最新的参数
|
||||||
|
const dateTime = new DateTime()
|
||||||
|
const platform = new Platform()
|
||||||
|
console.log('device params', params)
|
||||||
|
const newDeviceParams = {
|
||||||
|
appid: params.ak,
|
||||||
|
push_clientid: params.cid ? params.cid : '',
|
||||||
|
imei: params.imei ? params.imei : '',
|
||||||
|
oaid: params.oaid ? params.oaid : '',
|
||||||
|
idfa: params.idfa ? params.idfa : '',
|
||||||
|
imsi: params.imsi ? params.imsi : '',
|
||||||
|
uni_platform: params.up ? params.up : '',
|
||||||
|
os_name: params.on ? params.on : platform.getOsName(params.p),
|
||||||
|
os_version: params.sv ? params.sv : '',
|
||||||
|
os_language: params.lang ? params.lang : '',
|
||||||
|
pixel_ratio: params.pr ? params.pr : '',
|
||||||
|
network_model: params.net ? params.net : '',
|
||||||
|
window_width: params.ww ? params.ww : '',
|
||||||
|
window_height: params.wh ? params.wh : '',
|
||||||
|
screen_width: params.sw ? params.sw : '',
|
||||||
|
screen_height: params.sh ? params.sh : '',
|
||||||
|
rom_name: params.rn ? params.rn : '',
|
||||||
|
rom_version: params.rv ? params.rv : '',
|
||||||
|
location_ip: params.ip ? params.ip : '',
|
||||||
|
location_latitude: params.lat ? parseFloat(params.lat) : '',
|
||||||
|
location_longitude: params.lng ? parseFloat(params.lng) : '',
|
||||||
|
location_country: params.cn ? params.cn : '',
|
||||||
|
location_province: params.pn ? params.pn : '',
|
||||||
|
location_city: params.ct ? params.ct : '',
|
||||||
|
}
|
||||||
|
|
||||||
|
//检查是否有需要更新的数据
|
||||||
|
const updateData = {}
|
||||||
|
for(let key in newDeviceParams) {
|
||||||
|
if(newDeviceParams[key] && newDeviceParams[key] !== deviceData[key]) {
|
||||||
|
updateData[key] = newDeviceParams[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Object.keys(updateData).length) {
|
||||||
|
if(this.debug) {
|
||||||
|
console.log('Device need to update', updateData)
|
||||||
|
}
|
||||||
|
//数据更新
|
||||||
|
updateData.last_update_date = dateTime.getTime()
|
||||||
|
await this.update(this.tableName, updateData, {device_id: params.did})
|
||||||
|
} else {
|
||||||
|
if(this.debug) {
|
||||||
|
console.log('Device not need update', newDeviceParams)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: 'success'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async bindPush(params) {
|
||||||
|
if (!params.cid) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Parameter "cid" not found'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await this.setDevice(params)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
/**
|
||||||
|
* @class ErrorLog 错误日志模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const Platform = require('./platform')
|
||||||
|
const Channel = require('./channel')
|
||||||
|
const {
|
||||||
|
DateTime,
|
||||||
|
UniCrypto
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class ErrorLog extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'error-logs'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误日志数据填充
|
||||||
|
* @param {Object} reportParams 上报参数
|
||||||
|
*/
|
||||||
|
async fill(reportParams) {
|
||||||
|
let params, errorHash, errorCount, cacheKey;
|
||||||
|
const fillParams = []
|
||||||
|
const platform = new Platform()
|
||||||
|
const dateTime = new DateTime()
|
||||||
|
const uniCrypto = new UniCrypto()
|
||||||
|
const channel = new Channel()
|
||||||
|
const {
|
||||||
|
needCheck,
|
||||||
|
checkTime
|
||||||
|
} = this.getConfig('errorCheck')
|
||||||
|
const errorCheckTime = Math.max(checkTime, 1)
|
||||||
|
let spaceId
|
||||||
|
let spaceProvider
|
||||||
|
for (const rk in reportParams) {
|
||||||
|
params = reportParams[rk]
|
||||||
|
errorHash = uniCrypto.md5(params.em)
|
||||||
|
cacheKey = 'error-count-' + errorHash
|
||||||
|
// 校验在指定时间段内是否已存在相同的错误项
|
||||||
|
if (needCheck) {
|
||||||
|
errorCount = await this.getCache(cacheKey)
|
||||||
|
if (!errorCount) {
|
||||||
|
errorCount = await this.getCollection(this.tableName).where({
|
||||||
|
error_hash: errorHash,
|
||||||
|
create_time: {
|
||||||
|
$gte: dateTime.getTime() - errorCheckTime * 60000
|
||||||
|
}
|
||||||
|
}).count()
|
||||||
|
if (errorCount && errorCount.total > 0) {
|
||||||
|
await this.setCache(cacheKey, errorCount, errorCheckTime * 60)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorCount && errorCount.total > 0) {
|
||||||
|
if (this.debug) {
|
||||||
|
console.log('This error have already existsed: ' + params.em)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取云端信息
|
||||||
|
spaceId = null
|
||||||
|
spaceProvider = null
|
||||||
|
if (params.spi) {
|
||||||
|
//云函数调用参数
|
||||||
|
spaceId = params.spi.spaceId
|
||||||
|
spaceProvider = params.spi.provider
|
||||||
|
} else {
|
||||||
|
//云对象调用参数
|
||||||
|
if (params.spid) {
|
||||||
|
spaceId = params.spid
|
||||||
|
}
|
||||||
|
if (params.sppd) {
|
||||||
|
spaceProvider = params.sppd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 填充数据
|
||||||
|
fillParams.push({
|
||||||
|
appid: params.ak,
|
||||||
|
version: params.v ? params.v : '',
|
||||||
|
platform: platform.getPlatformCode(params.ut, params.p),
|
||||||
|
channel: channel.getChannelCode(params),
|
||||||
|
device_id: params.did,
|
||||||
|
uid: params.uid ? params.uid : '',
|
||||||
|
os: params.on ? params.on : platform.getOsName(params.p),
|
||||||
|
ua: params.ua ? params.ua : '',
|
||||||
|
page_url: params.url ? params.url : '',
|
||||||
|
space_id: spaceId ? spaceId : '',
|
||||||
|
space_provider: spaceProvider ? spaceProvider : '',
|
||||||
|
platform_version: params.mpv ? params.mpv : '',
|
||||||
|
error_msg: params.em ? params.em : '',
|
||||||
|
error_hash: errorHash,
|
||||||
|
create_time: dateTime.getTime()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fillParams.length === 0) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Invild param'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await this.insert(this.tableName, fillParams)
|
||||||
|
if (res && res.inserted) {
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: 'success'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
msg: 'Filled error'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误日志清理
|
||||||
|
* @param {Number} days 日志保留天数
|
||||||
|
*/
|
||||||
|
async clean(days) {
|
||||||
|
days = Math.max(parseInt(days), 1)
|
||||||
|
console.log('clean error 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 error log:', res)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* @class StatEvent 事件统计模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class StatEvent extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'events'
|
||||||
|
this.defaultEvent = this.getConfig('event') || {
|
||||||
|
login: '登录',
|
||||||
|
register: '注册',
|
||||||
|
click: '点击',
|
||||||
|
share: '分享',
|
||||||
|
pay_success: '支付成功',
|
||||||
|
pay_fail: '支付失败'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取事件信息
|
||||||
|
* @param {String} appid: DCloud appid
|
||||||
|
* @param {String} eventKey 事件键值
|
||||||
|
*/
|
||||||
|
async getEvent(appid, eventKey) {
|
||||||
|
const cacheKey = 'uni-stat-event-' + appid + '-' + eventKey
|
||||||
|
let eventData = await this.getCache(cacheKey)
|
||||||
|
if (!eventData) {
|
||||||
|
const eventInfo = await this.getCollection(this.tableName).where({
|
||||||
|
appid: appid,
|
||||||
|
event_key: eventKey
|
||||||
|
}).get()
|
||||||
|
eventData = []
|
||||||
|
if (eventInfo.data.length > 0) {
|
||||||
|
eventData = eventInfo.data[0]
|
||||||
|
await this.setCache(cacheKey, eventData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return eventData
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取事件信息不存在则创建
|
||||||
|
* @param {String} appid: DCloud appid
|
||||||
|
* @param {String} eventKey 事件键值
|
||||||
|
*/
|
||||||
|
async getEventAndCreate(appid, eventKey) {
|
||||||
|
const eventInfo = await this.getEvent(appid, eventKey)
|
||||||
|
if (eventInfo.length === 0) {
|
||||||
|
const thisTime = new DateTime().getTime()
|
||||||
|
const insertParam = {
|
||||||
|
appid: appid,
|
||||||
|
event_key: eventKey,
|
||||||
|
event_name: this.defaultEvent[eventKey] ? this.defaultEvent[eventKey] : '',
|
||||||
|
create_time: thisTime,
|
||||||
|
update_time: thisTime
|
||||||
|
}
|
||||||
|
const res = await this.insert(this.tableName, insertParam)
|
||||||
|
|
||||||
|
if (res && res.id) {
|
||||||
|
return Object.assign(insertParam, {
|
||||||
|
_id: res.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventInfo
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
* @class EventLog 事件日志模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const Platform = require('./platform')
|
||||||
|
const Channel = require('./channel')
|
||||||
|
const StatEvent = require('./event')
|
||||||
|
const SessionLog = require('./sessionLog')
|
||||||
|
const ShareLog = require('./shareLog')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class EventLog extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'event-logs'
|
||||||
|
this.sessionLogInfo = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件日志填充
|
||||||
|
* @param {Object} reportParams 上报参数
|
||||||
|
*/
|
||||||
|
async fill(reportParams) {
|
||||||
|
let params;
|
||||||
|
let sessionKey, sessionLogKey;
|
||||||
|
let sessionLogInfo;
|
||||||
|
const sessionData = []
|
||||||
|
const fillParams = []
|
||||||
|
const shareParams = []
|
||||||
|
const sessionLog = new SessionLog()
|
||||||
|
const event = new StatEvent()
|
||||||
|
const platform = new Platform()
|
||||||
|
const dateTime = new DateTime()
|
||||||
|
const channel = new Channel()
|
||||||
|
for (const rk in reportParams) {
|
||||||
|
params = reportParams[rk]
|
||||||
|
|
||||||
|
//暂存下会话数据,减少读库
|
||||||
|
sessionKey = params.ak + params.did + params.p
|
||||||
|
if (!this.sessionLogInfo[sessionKey]) {
|
||||||
|
// 会话日志
|
||||||
|
sessionLogInfo = await sessionLog.getSession(params)
|
||||||
|
if (sessionLogInfo.code) {
|
||||||
|
return sessionLogInfo
|
||||||
|
}
|
||||||
|
if (this.debug) {
|
||||||
|
console.log('sessionLogInfo', JSON.stringify(sessionLogInfo))
|
||||||
|
}
|
||||||
|
this.sessionLogInfo[sessionKey] = sessionLogInfo
|
||||||
|
} else {
|
||||||
|
sessionLogInfo = this.sessionLogInfo[sessionKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会话数据
|
||||||
|
sessionLogKey = sessionLogInfo.data.sessionLogId.toString()
|
||||||
|
if (!sessionData[sessionLogKey]) {
|
||||||
|
sessionData[sessionLogKey] = {
|
||||||
|
eventCount: sessionLogInfo.data.eventCount + 1,
|
||||||
|
addEventCount: 1,
|
||||||
|
uid: sessionLogInfo.data.uid,
|
||||||
|
createTime: sessionLogInfo.data.createTime
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sessionData[sessionLogKey].eventCount++
|
||||||
|
sessionData[sessionLogKey].addEventCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 事件
|
||||||
|
const eventInfo = await event.getEventAndCreate(params.ak, params.e_n)
|
||||||
|
|
||||||
|
// 填充数据
|
||||||
|
fillParams.push({
|
||||||
|
appid: params.ak,
|
||||||
|
version: params.v ? params.v : '',
|
||||||
|
platform: platform.getPlatformCode(params.ut, params.p),
|
||||||
|
channel: channel.getChannelCode(params),
|
||||||
|
device_id: params.did,
|
||||||
|
uid: params.uid ? params.uid : '',
|
||||||
|
session_id: sessionLogInfo.data.sessionLogId,
|
||||||
|
page_id: sessionLogInfo.data.pageId,
|
||||||
|
event_key: eventInfo.event_key,
|
||||||
|
param: params.e_v ? params.e_v : '',
|
||||||
|
// 版本
|
||||||
|
sdk_version: params.mpsdk ? params.mpsdk : '',
|
||||||
|
platform_version: params.mpv ? params.mpv : '',
|
||||||
|
// 设备相关
|
||||||
|
device_os_name: params.on ? params.on : platform.getOsName(params.p),
|
||||||
|
device_os_version: params.sv ? params.sv : '',
|
||||||
|
device_vendor: params.brand ? params.brand : '',
|
||||||
|
device_model: params.md ? params.md : '',
|
||||||
|
device_language: params.lang ? params.lang : '',
|
||||||
|
device_pixel_ratio: params.pr ? params.pr : '',
|
||||||
|
device_window_width: params.ww ? params.ww : '',
|
||||||
|
device_window_height: params.wh ? params.wh : '',
|
||||||
|
device_screen_width: params.sw ? params.sw : '',
|
||||||
|
device_screen_height: params.sh ? params.sh : '',
|
||||||
|
create_time: dateTime.getTime()
|
||||||
|
})
|
||||||
|
// 分享数据
|
||||||
|
if (eventInfo.event_key === 'share') {
|
||||||
|
shareParams.push(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fillParams.length === 0) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Invild param'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shareParams.length > 0) {
|
||||||
|
const shareLog = new ShareLog()
|
||||||
|
await shareLog.fill(shareParams, this.sessionLogInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await this.insert(this.tableName, fillParams)
|
||||||
|
if (res && res.inserted) {
|
||||||
|
for (const sid in sessionData) {
|
||||||
|
await sessionLog.updateSession(sid, sessionData[sid])
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: 'success'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
msg: 'Filled error'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 事件日志清理
|
||||||
|
* @param {Number} days 保留天数
|
||||||
|
*/
|
||||||
|
async clean(days) {
|
||||||
|
days = Math.max(parseInt(days), 1)
|
||||||
|
console.log('clean event 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 event log:', res)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* 基础对外模型
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
BaseMod: require('./base'),
|
||||||
|
SessionLog: require('./sessionLog'),
|
||||||
|
UserSessionLog: require('./userSessionLog'),
|
||||||
|
PageLog: require('./pageLog'),
|
||||||
|
EventLog: require('./eventLog'),
|
||||||
|
ShareLog: require('./shareLog'),
|
||||||
|
ErrorLog: require('./errorLog'),
|
||||||
|
AppCrashLogs: require('./appCrashLogs'),
|
||||||
|
StatResult: require('./statResult'),
|
||||||
|
ActiveUsers: require('./activeUsers'),
|
||||||
|
ActiveDevices: require('./activeDevices'),
|
||||||
|
PageResult: require('./pageResult'),
|
||||||
|
EventResult: require('./eventResult'),
|
||||||
|
ErrorResult: require('./errorResult'),
|
||||||
|
Loyalty: require('./loyalty'),
|
||||||
|
RunErrors: require('./runErrors'),
|
||||||
|
uniPay: require('./uni-pay'),
|
||||||
|
Setting: require('./setting'),
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
/**
|
||||||
|
* @class Page 页面模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const {
|
||||||
|
parseUrl
|
||||||
|
} = require('../../shared')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class Page extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'pages'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取页面信息
|
||||||
|
* @param {String} appid
|
||||||
|
* @param {String} url 页面地址
|
||||||
|
*/
|
||||||
|
async getPage(appid, url) {
|
||||||
|
const cacheKey = 'uni-stat-page-' + appid + '-' + url
|
||||||
|
let pageData = await this.getCache(cacheKey)
|
||||||
|
if (!pageData) {
|
||||||
|
const pageInfo = await this.getCollection(this.tableName).where({
|
||||||
|
appid: appid,
|
||||||
|
path: url
|
||||||
|
}).limit(1).get()
|
||||||
|
pageData = []
|
||||||
|
if (pageInfo.data.length > 0) {
|
||||||
|
pageData = pageInfo.data[0]
|
||||||
|
await this.setCache(cacheKey, pageData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pageData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取页面信息不存在则创建
|
||||||
|
* @param {String} appid
|
||||||
|
* @param {String} url 页面地址
|
||||||
|
* @param {Object} title 页面标题
|
||||||
|
*/
|
||||||
|
async getPageAndCreate(appid, url, title) {
|
||||||
|
//获取url信息
|
||||||
|
const urlInfo = parseUrl(url)
|
||||||
|
if (!urlInfo) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const baseurl = urlInfo.path
|
||||||
|
const pageInfo = await this.getPage(appid, baseurl)
|
||||||
|
//页面不存在则创建
|
||||||
|
if (pageInfo.length === 0) {
|
||||||
|
const thisTime = new DateTime().getTime()
|
||||||
|
const insertParam = {
|
||||||
|
appid: appid,
|
||||||
|
path: baseurl,
|
||||||
|
title: title,
|
||||||
|
page_params: [],
|
||||||
|
create_time: thisTime,
|
||||||
|
update_time: thisTime
|
||||||
|
}
|
||||||
|
const res = await this.insert(this.tableName, insertParam)
|
||||||
|
|
||||||
|
if (res && res.id) {
|
||||||
|
return Object.assign(insertParam, {
|
||||||
|
_id: res.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (!pageInfo.title && title) {
|
||||||
|
const cacheKey = 'uni-stat-page-' + appid + '-' + baseurl
|
||||||
|
await this.clearCache(cacheKey)
|
||||||
|
await this.update(this.tableName, {
|
||||||
|
title: title
|
||||||
|
}, {
|
||||||
|
_id: pageInfo._id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return pageInfo
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
/**
|
||||||
|
* @class PageLog 页面日志模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const Page = require('./page')
|
||||||
|
const Platform = require('./platform')
|
||||||
|
const Channel = require('./channel')
|
||||||
|
const SessionLog = require('./sessionLog')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
const {
|
||||||
|
parseUrl
|
||||||
|
} = require('../../shared')
|
||||||
|
module.exports = class PageLog extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'page-logs'
|
||||||
|
this.sessionLogInfo = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面日志数据填充
|
||||||
|
* @param {Object} reportParams 上报参数
|
||||||
|
*/
|
||||||
|
async fill(reportParams) {
|
||||||
|
let params;
|
||||||
|
let sessionKey
|
||||||
|
let sessionLogKey
|
||||||
|
let sessionLogInfo
|
||||||
|
let pageKey
|
||||||
|
let pageInfo
|
||||||
|
let referPageInfo
|
||||||
|
const sessionData = []
|
||||||
|
const pageData = []
|
||||||
|
const fillParams = []
|
||||||
|
const sessionLog = new SessionLog()
|
||||||
|
const page = new Page()
|
||||||
|
const platform = new Platform()
|
||||||
|
const dateTime = new DateTime()
|
||||||
|
const channel = new Channel()
|
||||||
|
for (const pk in reportParams) {
|
||||||
|
params = reportParams[pk]
|
||||||
|
if (['3', '4'].includes(params.lt) && !params.url && params.urlref) {
|
||||||
|
params.url = params.urlref
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页面信息
|
||||||
|
pageKey = params.ak + params.url
|
||||||
|
if (pageData[pageKey]) {
|
||||||
|
pageInfo = pageData[pageKey]
|
||||||
|
} else {
|
||||||
|
pageInfo = await page.getPageAndCreate(params.ak, params.url, params.ttpj)
|
||||||
|
if (!pageInfo || pageInfo.length === 0) {
|
||||||
|
console.log('Not found this page by param:', JSON.stringify(params))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pageData[pageKey] = pageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会话日志,暂存下会话数据,减少读库
|
||||||
|
sessionKey = params.ak + params.did + params.p
|
||||||
|
if (!this.sessionLogInfo[sessionKey]) {
|
||||||
|
sessionLogInfo = await sessionLog.getSession(params)
|
||||||
|
if (sessionLogInfo.code) {
|
||||||
|
return sessionLogInfo
|
||||||
|
}
|
||||||
|
if (this.debug) {
|
||||||
|
console.log('sessionLogInfo', JSON.stringify(sessionLogInfo))
|
||||||
|
}
|
||||||
|
this.sessionLogInfo[sessionKey] = sessionLogInfo
|
||||||
|
} else {
|
||||||
|
sessionLogInfo = this.sessionLogInfo[sessionKey]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 会话数据
|
||||||
|
sessionLogKey = sessionLogInfo.data.sessionLogId.toString()
|
||||||
|
if (!sessionData[sessionLogKey]) {
|
||||||
|
//临时存储减少查询次数
|
||||||
|
sessionData[sessionLogKey] = {
|
||||||
|
pageCount: sessionLogInfo.data.pageCount + 1,
|
||||||
|
addPageCount: 1,
|
||||||
|
createTime: sessionLogInfo.data.createTime,
|
||||||
|
pageId: pageInfo._id,
|
||||||
|
uid: sessionLogInfo.data.uid
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.debug) {
|
||||||
|
console.log('add sessionData - ' + sessionLogKey, sessionData)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sessionData[sessionLogKey].pageCount += 1
|
||||||
|
sessionData[sessionLogKey].addPageCount += 1
|
||||||
|
sessionData[sessionLogKey].pageId = pageInfo._id
|
||||||
|
|
||||||
|
if (this.debug) {
|
||||||
|
console.log('update sessionData - ' + sessionLogKey, sessionData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上级页面信息
|
||||||
|
pageKey = params.ak + params.urlref
|
||||||
|
if (pageData[pageKey]) {
|
||||||
|
referPageInfo = pageData[pageKey]
|
||||||
|
} else {
|
||||||
|
referPageInfo = await page.getPageAndCreate(params.ak, params.urlref, params.ttpj)
|
||||||
|
if (!referPageInfo || referPageInfo.length === 0) {
|
||||||
|
referPageInfo = {_id:''}
|
||||||
|
}
|
||||||
|
pageData[pageKey] = referPageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
//当前页面url信息
|
||||||
|
const urlInfo = parseUrl(params.url)
|
||||||
|
|
||||||
|
// 填充数据
|
||||||
|
fillParams.push({
|
||||||
|
appid: params.ak,
|
||||||
|
version: params.v ? params.v : '',
|
||||||
|
platform: platform.getPlatformCode(params.ut, params.p),
|
||||||
|
channel: channel.getChannelCode(params),
|
||||||
|
device_id: params.did,
|
||||||
|
uid: params.uid ? params.uid : '',
|
||||||
|
session_id: sessionLogInfo.data.sessionLogId,
|
||||||
|
page_id: pageInfo._id,
|
||||||
|
query_string: urlInfo.query,
|
||||||
|
//上级页面相关
|
||||||
|
previous_page_id: referPageInfo._id,
|
||||||
|
previous_page_duration: params.urlref_ts ? parseInt(params.urlref_ts) : 0,
|
||||||
|
previous_page_is_entry: referPageInfo._id === sessionLogInfo.data.entryPageId ? 1 : 0,
|
||||||
|
create_time: dateTime.getTime()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fillParams.length === 0) {
|
||||||
|
console.log('No page params')
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Invild param'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//日志数据入库
|
||||||
|
const res = await this.insert(this.tableName, fillParams)
|
||||||
|
if (res && res.inserted) {
|
||||||
|
// 更新会话数据
|
||||||
|
const nowTime = dateTime.getTime()
|
||||||
|
for (const sid in sessionData) {
|
||||||
|
await sessionLog.updateSession(sid, sessionData[sid])
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
code: 0,
|
||||||
|
msg: 'success'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
code: 500,
|
||||||
|
msg: 'Filled error'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面日志清理
|
||||||
|
* @param {Number} days 页面日志保留天数
|
||||||
|
*/
|
||||||
|
async clean(days) {
|
||||||
|
days = Math.max(parseInt(days), 1)
|
||||||
|
console.log('clean page 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 page log:', res)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,160 @@
|
|||||||
|
/**
|
||||||
|
* @class Platform 应用平台模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class Platform extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'app-platforms'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台信息
|
||||||
|
* @param {String} platform 平台代码
|
||||||
|
* @param {String} os 系统
|
||||||
|
*/
|
||||||
|
async getPlatform(platform, os) {
|
||||||
|
const cacheKey = 'uni-stat-platform-' + platform + '-' + os
|
||||||
|
let platformData = await this.getCache(cacheKey)
|
||||||
|
if (!platformData) {
|
||||||
|
const platformCode = this.getPlatformCode(platform, os)
|
||||||
|
const platformInfo = await this.getCollection(this.tableName).where({
|
||||||
|
code: platformCode
|
||||||
|
}).limit(1).get()
|
||||||
|
platformData = []
|
||||||
|
if (platformInfo.data.length > 0) {
|
||||||
|
platformData = platformInfo.data[0]
|
||||||
|
await this.setCache(cacheKey, platformData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return platformData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台信息没有则创建
|
||||||
|
* @param {String} platform 平台代码
|
||||||
|
* @param {String} os 系统
|
||||||
|
*/
|
||||||
|
async getPlatformAndCreate(platform, os) {
|
||||||
|
if (!platform) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const platformInfo = await this.getPlatform(platform, os)
|
||||||
|
|
||||||
|
if (platformInfo.length === 0) {
|
||||||
|
const platformCode = this.getPlatformCode(platform, os)
|
||||||
|
const insertParam = {
|
||||||
|
code: platformCode,
|
||||||
|
name: platformCode,
|
||||||
|
create_time: new DateTime().getTime()
|
||||||
|
}
|
||||||
|
const res = await this.insert(this.tableName, insertParam)
|
||||||
|
if (res && res.id) {
|
||||||
|
return Object.assign(insertParam, {
|
||||||
|
_id: res.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return platformInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台代码
|
||||||
|
* @param {String} platform 平台代码
|
||||||
|
* @param {String} os 系统
|
||||||
|
*/
|
||||||
|
getPlatformCode(platform, os) {
|
||||||
|
let platformCode = platform
|
||||||
|
|
||||||
|
//兼容客户端上报参数
|
||||||
|
switch(platform) {
|
||||||
|
//h5|web
|
||||||
|
case 'h5':
|
||||||
|
platformCode = 'web'
|
||||||
|
break
|
||||||
|
//微信小程序
|
||||||
|
case 'wx':
|
||||||
|
platformCode = 'mp-weixin'
|
||||||
|
break
|
||||||
|
//百度小程序
|
||||||
|
case 'bd':
|
||||||
|
platformCode = 'mp-baidu'
|
||||||
|
break
|
||||||
|
//支付宝小程序
|
||||||
|
case 'ali':
|
||||||
|
platformCode = 'mp-alipay'
|
||||||
|
break
|
||||||
|
//字节跳动小程序
|
||||||
|
case 'tt':
|
||||||
|
platformCode = 'mp-toutiao'
|
||||||
|
break
|
||||||
|
//qq小程序
|
||||||
|
case 'qq':
|
||||||
|
platformCode = 'mp-qq'
|
||||||
|
break
|
||||||
|
//快应用联盟
|
||||||
|
case 'qn':
|
||||||
|
platformCode = 'quickapp-webview-union'
|
||||||
|
break
|
||||||
|
//快应用(webview)
|
||||||
|
case 'qw':
|
||||||
|
platformCode = 'quickapp-webview'
|
||||||
|
break
|
||||||
|
//快应用华为
|
||||||
|
case 'qi':
|
||||||
|
platformCode = 'quickapp-webview-huawei'
|
||||||
|
break
|
||||||
|
//360小程序
|
||||||
|
case '360':
|
||||||
|
platformCode = 'mp-360'
|
||||||
|
break
|
||||||
|
//京东小程序
|
||||||
|
case 'jd':
|
||||||
|
platformCode = 'mp-jd'
|
||||||
|
break
|
||||||
|
//钉钉小程序
|
||||||
|
case 'dt':
|
||||||
|
platformCode = 'mp-dingtalk'
|
||||||
|
break
|
||||||
|
//快手小程序
|
||||||
|
case 'ks':
|
||||||
|
platformCode = 'mp-kuaishou'
|
||||||
|
break
|
||||||
|
//飞书小程序
|
||||||
|
case 'lark':
|
||||||
|
platformCode = 'mp-lark'
|
||||||
|
break
|
||||||
|
//原生应用
|
||||||
|
case 'n':
|
||||||
|
case 'app-plus':
|
||||||
|
case 'app':
|
||||||
|
os = this.getOsName(os)
|
||||||
|
if (os === 'ios') {
|
||||||
|
platformCode = 'ios'
|
||||||
|
} else {
|
||||||
|
platformCode = 'android'
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return platformCode
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取系统名称
|
||||||
|
* @param {Object} os系统标识
|
||||||
|
*/
|
||||||
|
getOsName(os) {
|
||||||
|
if(!os) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
//兼容老版上报参数
|
||||||
|
const osSetting = {
|
||||||
|
i: 'ios',
|
||||||
|
a: 'android'
|
||||||
|
}
|
||||||
|
return osSetting[os] ? osSetting[os] : os
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* @class RunErrors 运行错误日志
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
module.exports = class RunErrors extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'run-errors'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建日志
|
||||||
|
* @param {Object} params 参数
|
||||||
|
*/
|
||||||
|
async create(params) {
|
||||||
|
if (!params) return
|
||||||
|
const res = await this.insert(this.tableName, params)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
/**
|
||||||
|
* @class Scenes 场景值模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const Platform = require('./platform')
|
||||||
|
module.exports = class Scenes extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'mp-scenes'
|
||||||
|
this.defualtCode = '1001'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取场景值
|
||||||
|
* @param {String} platform 平台代码
|
||||||
|
* @param {String} code 场景值代码
|
||||||
|
*/
|
||||||
|
async getScenes(platform, code) {
|
||||||
|
const cacheKey = 'uni-stat-scenes-' + platform + '-' + code
|
||||||
|
let scenesData = await this.getCache(cacheKey)
|
||||||
|
if (!scenesData) {
|
||||||
|
const scenesInfo = await this.getCollection(this.tableName).where({
|
||||||
|
platform: platform,
|
||||||
|
scene_code: code
|
||||||
|
}).limit(1).get()
|
||||||
|
scenesData = []
|
||||||
|
if (scenesInfo.data.length > 0) {
|
||||||
|
scenesData = scenesInfo.data[0]
|
||||||
|
await this.setCache(cacheKey, scenesData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scenesData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过平台编号获取场景值
|
||||||
|
* @param {String} platformId 平台编号
|
||||||
|
* @param {String} code 场景值代码
|
||||||
|
*/
|
||||||
|
async getScenesByPlatformId(platformId, code) {
|
||||||
|
const platform = new Platform()
|
||||||
|
let platformInfo = await this.getCollection(platform.tableName).where({
|
||||||
|
_id: platformId
|
||||||
|
}).limit(1).get()
|
||||||
|
let scenesData
|
||||||
|
if (platformInfo.data.length > 0) {
|
||||||
|
platformInfo = platformInfo.data[0]
|
||||||
|
scenesData = await this.getScenes(platformInfo.code, code)
|
||||||
|
} else {
|
||||||
|
scenesData = []
|
||||||
|
}
|
||||||
|
return scenesData
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取场景值名称
|
||||||
|
* @param {String} platform 平台代码
|
||||||
|
* @param {String} code 场景值代码
|
||||||
|
*/
|
||||||
|
async getScenesName(platform, code) {
|
||||||
|
const scenesData = await this.getScenes(platform, code)
|
||||||
|
if (scenesData.length === 0) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
return scenesData.scene_name
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过平台编号获取场景值名称
|
||||||
|
* @param {String} platformId 平台编号
|
||||||
|
* @param {String} code 场景值代码
|
||||||
|
*/
|
||||||
|
async getScenesNameByPlatformId(platformId, code) {
|
||||||
|
const scenesData = await this.getScenesByPlatformId(platformId, code)
|
||||||
|
if (scenesData.length === 0) {
|
||||||
|
return code === this.defualtCode ? '默认' : ''
|
||||||
|
}
|
||||||
|
return scenesData.scene_name
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* 表名
|
||||||
|
*/
|
||||||
|
const dbName = {
|
||||||
|
uniIdUsers: 'uni-id-users', // 支付订单明细表
|
||||||
|
uniPayOrders: 'uni-pay-orders', // 支付订单明细表
|
||||||
|
uniStatPayResult: 'uni-stat-pay-result', // 统计结果存储表
|
||||||
|
uniStatSessionLogs: 'uni-stat-session-logs', // 设备会话日志表(主要用于统计访问设备数)
|
||||||
|
uniStatUserSessionLogs: 'uni-stat-user-session-logs', // 用户会话日志表(主要用于统计访问人数)
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = dbName;
|
@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* 数据库操作
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
uniIdUsers: require('./uniIdUsers'),
|
||||||
|
uniPayOrders: require('./uniPayOrders'),
|
||||||
|
uniStatPayResult: require('./uniStatPayResult'),
|
||||||
|
uniStatSessionLogs: require('./uniStatSessionLogs'),
|
||||||
|
uniStatUserSessionLogs: require('./uniStatUserSessionLogs'),
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* 数据库操作
|
||||||
|
*/
|
||||||
|
const dbName = require("./config");
|
||||||
|
|
||||||
|
let db = uniCloud.database();
|
||||||
|
let _ = db.command;
|
||||||
|
let $ = _.aggregate;
|
||||||
|
|
||||||
|
class Dao {
|
||||||
|
async count(whereJson) {
|
||||||
|
let dbRes = await db.collection(dbName.uniIdUsers).where(whereJson).count()
|
||||||
|
return dbRes && dbRes.total ? dbRes.total : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async countNewUserOrder(obj) {
|
||||||
|
let {
|
||||||
|
whereJson,
|
||||||
|
status
|
||||||
|
} = obj;
|
||||||
|
let dbRes = await db.collection(dbName.uniIdUsers).aggregate()
|
||||||
|
.match(whereJson)
|
||||||
|
.lookup({
|
||||||
|
from: dbName.uniPayOrders,
|
||||||
|
let: {
|
||||||
|
user_id: '$_id',
|
||||||
|
},
|
||||||
|
pipeline: $.pipeline()
|
||||||
|
.match(_.expr($.and([
|
||||||
|
$.eq(['$user_id', '$$user_id']),
|
||||||
|
$.in(['$status', status])
|
||||||
|
])))
|
||||||
|
.limit(1)
|
||||||
|
.done(),
|
||||||
|
as: 'order',
|
||||||
|
})
|
||||||
|
.unwind({
|
||||||
|
path: '$order',
|
||||||
|
})
|
||||||
|
.group({
|
||||||
|
_id: null,
|
||||||
|
count: {
|
||||||
|
$addToSet: '$_id'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.addFields({
|
||||||
|
count: {
|
||||||
|
$size: '$count'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.end()
|
||||||
|
try {
|
||||||
|
return dbRes.data[0].count;
|
||||||
|
} catch (err) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = new Dao();
|
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
* 数据库操作
|
||||||
|
*/
|
||||||
|
const BaseMod = require('../../base');
|
||||||
|
const dbName = require("./config");
|
||||||
|
|
||||||
|
class Dao extends BaseMod {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tablePrefix = false; // 不使用表前缀
|
||||||
|
}
|
||||||
|
|
||||||
|
async group(data) {
|
||||||
|
let {
|
||||||
|
start_time,
|
||||||
|
end_time,
|
||||||
|
status: status_str
|
||||||
|
} = data;
|
||||||
|
let status;
|
||||||
|
if (status_str === "已下单") {
|
||||||
|
|
||||||
|
} else if (status_str === "已付款") {
|
||||||
|
status = {
|
||||||
|
$gt: 0
|
||||||
|
}
|
||||||
|
} else if (status_str === "已退款") {
|
||||||
|
status = {
|
||||||
|
$in: [2, 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const dbRes = await this.aggregate(dbName.uniPayOrders, {
|
||||||
|
match: {
|
||||||
|
create_date: {
|
||||||
|
$gte: start_time,
|
||||||
|
$lte: end_time
|
||||||
|
},
|
||||||
|
status
|
||||||
|
},
|
||||||
|
group: {
|
||||||
|
_id: {
|
||||||
|
appid: '$appid',
|
||||||
|
version: '$stat_data.app_version',
|
||||||
|
platform: '$stat_data.platform',
|
||||||
|
channel: '$stat_data.channel',
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
$first: '$status'
|
||||||
|
},
|
||||||
|
// 支付金额
|
||||||
|
total_fee: {
|
||||||
|
$sum: '$total_fee'
|
||||||
|
},
|
||||||
|
// 退款金额
|
||||||
|
refund_fee: {
|
||||||
|
$sum: '$refund_fee'
|
||||||
|
},
|
||||||
|
// 支付笔数
|
||||||
|
order_count: {
|
||||||
|
$sum: 1
|
||||||
|
},
|
||||||
|
// 支付人数(去重复)
|
||||||
|
user_count: {
|
||||||
|
$addToSet: '$user_id'
|
||||||
|
},
|
||||||
|
// 支付设备数(去重复)
|
||||||
|
device_count: {
|
||||||
|
$addToSet: '$device_id'
|
||||||
|
},
|
||||||
|
|
||||||
|
create_date: {
|
||||||
|
$min: '$create_date'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addFields: {
|
||||||
|
user_count: {
|
||||||
|
$size: '$user_count'
|
||||||
|
},
|
||||||
|
device_count: {
|
||||||
|
$size: '$device_count'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 按创建时间排序
|
||||||
|
sort: {
|
||||||
|
create_date: 1
|
||||||
|
},
|
||||||
|
getAll: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let list = dbRes.data;
|
||||||
|
list.map((item) => {
|
||||||
|
item.status_str = status_str;
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = new Dao();
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 数据库操作
|
||||||
|
*/
|
||||||
|
const BaseMod = require('../../base');
|
||||||
|
const dbName = require("./config");
|
||||||
|
|
||||||
|
class Dao extends BaseMod {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tablePrefix = false; // 不使用表前缀
|
||||||
|
}
|
||||||
|
|
||||||
|
async list(data) {
|
||||||
|
let {
|
||||||
|
whereJson,
|
||||||
|
} = data;
|
||||||
|
const dbRes = await this.getCollection(dbName.uniStatPayResult).where(whereJson).get();
|
||||||
|
return dbRes.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async del(data) {
|
||||||
|
let {
|
||||||
|
whereJson
|
||||||
|
} = data;
|
||||||
|
const dbRes = await this.delete(dbName.uniStatPayResult, whereJson);
|
||||||
|
return dbRes.deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
async adds(saveList) {
|
||||||
|
return await this.batchInsert(dbName.uniStatPayResult, saveList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = new Dao();
|
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* 数据库操作
|
||||||
|
*/
|
||||||
|
const BaseMod = require('../../base');
|
||||||
|
const dbName = require("./config");
|
||||||
|
|
||||||
|
class Dao extends BaseMod {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tablePrefix = false; // 不使用表前缀
|
||||||
|
}
|
||||||
|
|
||||||
|
async group(data) {
|
||||||
|
let {
|
||||||
|
whereJson,
|
||||||
|
} = data;
|
||||||
|
const dbRes = await this.aggregate(dbName.uniStatSessionLogs, {
|
||||||
|
match: whereJson,
|
||||||
|
group: {
|
||||||
|
_id: {
|
||||||
|
appid: '$appid',
|
||||||
|
version: '$version',
|
||||||
|
platform: '$platform',
|
||||||
|
channel: '$channel',
|
||||||
|
},
|
||||||
|
// 设备数(去重复)
|
||||||
|
device_count: {
|
||||||
|
$addToSet: '$device_id'
|
||||||
|
},
|
||||||
|
|
||||||
|
create_time: {
|
||||||
|
$min: '$create_time'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addFields: {
|
||||||
|
device_count: {
|
||||||
|
$size: '$device_count'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 按创建时间排序
|
||||||
|
sort: {
|
||||||
|
create_time: 1
|
||||||
|
},
|
||||||
|
getAll: true
|
||||||
|
});
|
||||||
|
|
||||||
|
return dbRes.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async groupCount(whereJson) {
|
||||||
|
const dbRes = await this.aggregate(dbName.uniStatSessionLogs, {
|
||||||
|
match: whereJson,
|
||||||
|
group: {
|
||||||
|
_id: null,
|
||||||
|
// 设备数(去重复)
|
||||||
|
count: {
|
||||||
|
$addToSet: '$device_id'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addFields: {
|
||||||
|
count: {
|
||||||
|
$size: '$count'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getAll: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
return dbRes.data[0].count;
|
||||||
|
} catch (err) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = new Dao();
|
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* 数据库操作
|
||||||
|
*/
|
||||||
|
const BaseMod = require('../../base');
|
||||||
|
const dbName = require("./config");
|
||||||
|
|
||||||
|
class Dao extends BaseMod {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tablePrefix = false; // 不使用表前缀
|
||||||
|
}
|
||||||
|
|
||||||
|
async group(data) {
|
||||||
|
let {
|
||||||
|
whereJson
|
||||||
|
} = data;
|
||||||
|
const dbRes = await this.aggregate(dbName.uniStatUserSessionLogs, {
|
||||||
|
match: whereJson,
|
||||||
|
group: {
|
||||||
|
_id: {
|
||||||
|
appid: '$appid',
|
||||||
|
version: '$version',
|
||||||
|
platform: '$platform',
|
||||||
|
channel: '$channel',
|
||||||
|
},
|
||||||
|
// 用户数(去重复)
|
||||||
|
user_count: {
|
||||||
|
$addToSet: '$uid'
|
||||||
|
},
|
||||||
|
|
||||||
|
create_time: {
|
||||||
|
$min: '$create_time'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addFields: {
|
||||||
|
user_count: {
|
||||||
|
$size: '$user_count'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 按创建时间排序
|
||||||
|
sort: {
|
||||||
|
create_time: 1
|
||||||
|
},
|
||||||
|
getAll: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let list = dbRes.data;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
async groupCount(whereJson) {
|
||||||
|
const dbRes = await this.aggregate(dbName.uniStatUserSessionLogs, {
|
||||||
|
match: whereJson,
|
||||||
|
group: {
|
||||||
|
_id: null,
|
||||||
|
// 设备数(去重复)
|
||||||
|
count: {
|
||||||
|
$addToSet: '$uid'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
addFields: {
|
||||||
|
count: {
|
||||||
|
$size: '$count'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getAll: true
|
||||||
|
});
|
||||||
|
try {
|
||||||
|
return dbRes.data[0].count;
|
||||||
|
} catch (err) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = new Dao();
|
@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* 基础对外模型
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
PayResult: require('./payResult'),
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
/**
|
||||||
|
* @class Version 应用版本模型
|
||||||
|
*/
|
||||||
|
const BaseMod = require('./base')
|
||||||
|
const {
|
||||||
|
DateTime
|
||||||
|
} = require('../lib')
|
||||||
|
module.exports = class Version extends BaseMod {
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.tableName = 'opendb-app-versions'
|
||||||
|
this.tablePrefix = false
|
||||||
|
this.cacheKeyPre = 'uni-stat-app-version-'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取版本信息
|
||||||
|
* @param {String} appid DCloud-appid
|
||||||
|
* @param {String} platformId 平台编号
|
||||||
|
* @param {String} appVersion 平台版本号
|
||||||
|
*/
|
||||||
|
async getVersion(appid, platform, appVersion) {
|
||||||
|
const cacheKey = this.cacheKeyPre + appid + '-' + platform + '-' + appVersion
|
||||||
|
let versionData = await this.getCache(cacheKey)
|
||||||
|
if (!versionData) {
|
||||||
|
const versionInfo = await this.getCollection(this.tableName).where({
|
||||||
|
appid: appid,
|
||||||
|
uni_platform: platform,
|
||||||
|
type: 'native_app',
|
||||||
|
version: appVersion
|
||||||
|
}).limit(1).get()
|
||||||
|
versionData = []
|
||||||
|
if (versionInfo.data.length > 0) {
|
||||||
|
versionData = versionInfo.data[0]
|
||||||
|
await this.setCache(cacheKey, versionData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return versionData
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取版本信息没有则进行创建
|
||||||
|
* @param {String} appid DCloud-appid
|
||||||
|
* @param {String} platform 平台代码
|
||||||
|
* @param {String} appVersion 平台版本号
|
||||||
|
*/
|
||||||
|
async getVersionAndCreate(appid, platform, appVersion) {
|
||||||
|
const versionInfo = await this.getVersion(appid, platform, appVersion)
|
||||||
|
if (versionInfo.length === 0) {
|
||||||
|
if (appVersion.length > 0 && !appVersion.includes('}')) {
|
||||||
|
const thisTime = new DateTime().getTime()
|
||||||
|
const insertParam = {
|
||||||
|
appid: appid,
|
||||||
|
platform: [],
|
||||||
|
uni_platform: platform,
|
||||||
|
type: 'native_app',
|
||||||
|
version: appVersion,
|
||||||
|
stable_publish: false,
|
||||||
|
create_env: 'uni-stat',
|
||||||
|
create_date: thisTime
|
||||||
|
}
|
||||||
|
const res = await this.insert(this.tableName, insertParam)
|
||||||
|
if (res && res.id) {
|
||||||
|
return Object.assign(insertParam, {
|
||||||
|
_id: res.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return versionInfo
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* @class UniStatReportDataReceiver uni统计上报数据接收器
|
||||||
|
* @function report 上报数据调度处理函数
|
||||||
|
*/
|
||||||
|
const {
|
||||||
|
parseUrlParams
|
||||||
|
} = require('../shared')
|
||||||
|
const SessionLog = require('./mod/sessionLog')
|
||||||
|
const PageLog = require('./mod/pageLog')
|
||||||
|
const EventLog = require('./mod/eventLog')
|
||||||
|
const ErrorLog = require('./mod/errorLog')
|
||||||
|
const Device = require('./mod/device')
|
||||||
|
class UniStatReportDataReceiver {
|
||||||
|
/**
|
||||||
|
* @description 上报数据调度处理函数
|
||||||
|
* @param {Object} params 基础上报参数
|
||||||
|
* @param {Object} context 请求附带的上下文信息
|
||||||
|
*/
|
||||||
|
async report(params, context) {
|
||||||
|
let res = {
|
||||||
|
code: 0,
|
||||||
|
msg: 'success'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params || !params.requests) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Invild params'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON参数解析
|
||||||
|
const requestParam = JSON.parse(params.requests)
|
||||||
|
if (!requestParam || requestParam.length === 0) {
|
||||||
|
return {
|
||||||
|
code: 200,
|
||||||
|
msg: 'Invild params'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 日志填充
|
||||||
|
const sessionParams = []
|
||||||
|
const pageParams = []
|
||||||
|
const eventParams = []
|
||||||
|
const errorParams = []
|
||||||
|
const device = new Device()
|
||||||
|
for (const ri in requestParam) {
|
||||||
|
//参数解析
|
||||||
|
const urlParams = parseUrlParams(requestParam[ri], context)
|
||||||
|
if (!urlParams.ak) {
|
||||||
|
return {
|
||||||
|
code: 201,
|
||||||
|
msg: 'Not found appid'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!urlParams.lt) {
|
||||||
|
return {
|
||||||
|
code: 202,
|
||||||
|
msg: 'Not found this log type'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (parseInt(urlParams.lt)) {
|
||||||
|
// 会话日志
|
||||||
|
case 1: {
|
||||||
|
sessionParams.push(urlParams)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 页面日志
|
||||||
|
case 3:
|
||||||
|
case 11: {
|
||||||
|
pageParams.push(urlParams)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 事件日志
|
||||||
|
case 21: {
|
||||||
|
eventParams.push(urlParams)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// 错误日志
|
||||||
|
case 31: {
|
||||||
|
errorParams.push(urlParams)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
//unipush信息绑定
|
||||||
|
case 101: {
|
||||||
|
res = await device.bindPush(urlParams)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
console.log('Invalid type by param "lt:' + urlParams.lt + '"')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//会话日志填充
|
||||||
|
if (sessionParams.length > 0) {
|
||||||
|
const sessionLog = new SessionLog()
|
||||||
|
res = await sessionLog.batchFill(sessionParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
//页面日志填充
|
||||||
|
if (pageParams.length > 0) {
|
||||||
|
const pageLog = new PageLog()
|
||||||
|
res = await pageLog.fill(pageParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
//事件日志填充
|
||||||
|
if (eventParams.length > 0) {
|
||||||
|
const eventLog = new EventLog()
|
||||||
|
res = await eventLog.fill(eventParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
//错误日志填充
|
||||||
|
if (errorParams.length > 0) {
|
||||||
|
const errorLog = new ErrorLog()
|
||||||
|
res = await errorLog.fill(errorParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = UniStatReportDataReceiver
|
@ -0,0 +1,23 @@
|
|||||||
|
'use strict';
|
||||||
|
exports.main = async (event, context) => {
|
||||||
|
const db = uniCloud.database()
|
||||||
|
|
||||||
|
if (event.api === 'getByID') {
|
||||||
|
const res = await db.collection('dishes').where({
|
||||||
|
_id: event.id
|
||||||
|
}).get()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if (event.api === 'getFloorList') {
|
||||||
|
const res = await db.collection('dishes').skip(4).limit(15).get()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
if (event.api === 'getByName') {
|
||||||
|
const res = await db.collection('dishes').where({
|
||||||
|
dish_name: new RegExp(event.dish_name, 'g')
|
||||||
|
}).get()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
//返回数据给客户端
|
||||||
|
return "请求错误"
|
||||||
|
};
|
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "getDishes",
|
||||||
|
"dependencies": {},
|
||||||
|
"extensions": {
|
||||||
|
"uni-cloud-jql": {}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
'use strict';
|
||||||
|
exports.main = async (event, context) => {
|
||||||
|
const db = uniCloud.database()
|
||||||
|
let labelList = []
|
||||||
|
const res = db.collection('dish-label').where({
|
||||||
|
dish_id:event.id
|
||||||
|
})
|
||||||
|
for(int i = 0;i < res.data.length;i++) {
|
||||||
|
labelList.push(res.data[i].label)
|
||||||
|
}
|
||||||
|
//返回数据给客户端
|
||||||
|
return labelList
|
||||||
|
};
|