feat(B批收尾): B1门禁可信/B7-1菜单环防护/B2空值守卫/B7-2分页/B7-3字段清洗/B3空态/B4索引key/B5-3 comment三集合选A新建schema(漂移清零)/B6清理+admin配置+changelog
This commit is contained in:
+430
-423
@@ -1,423 +1,430 @@
|
||||
<template>
|
||||
<view class="fix-top-window">
|
||||
<view class="uni-header">
|
||||
<uni-stat-breadcrumb class="uni-stat-breadcrumb-on-phone" />
|
||||
<view class="uni-group">
|
||||
<view class="uni-sub-title hide-on-phone"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-container">
|
||||
<!-- 提示条1:初始化db_init.json -->
|
||||
<uni-notice-bar v-if="showdbInit" showGetMore showIcon class="mb-m pointer" text="检测到您未初始化db_init.json,请先右键uniCloud/database/db_init.json文件,执行初始化云数据库,否则左侧无法显示菜单等数据" background-color="#fef0f0" color="#f56c6c" @click="toAddAppId" />
|
||||
<!-- 提示条2:添加应用 -->
|
||||
<uni-notice-bar v-if="showAddAppId" showGetMore showIcon class="mb-m pointer" text="检测到您还未添加应用,点击前往应用管理添加" @click="toAddAppId" />
|
||||
<!-- 提示条3:暂无数据,需开通统计功能 -->
|
||||
<uni-notice-bar v-if="!deviceTableData.length && !userTableData.length && !query.platform_id && complete" showGetMore showIcon class="mb-m pointer"
|
||||
text="暂无数据, 统计相关功能需开通 uni 统计后才能使用, 如未开通, 点击查看具体流程" @click="navTo('https://uniapp.dcloud.io/uni-stat-v2.html')" />
|
||||
|
||||
<view class="uni-stat--x mb-m">
|
||||
<!-- 平台选择标签 -->
|
||||
<uni-stat-tabs label="平台选择" type="boldLine" mode="platform" v-model="query.platform_id" />
|
||||
</view>
|
||||
<view class="uni-stat--x p-m">
|
||||
<view class="uni-stat-card-header">设备概览</view>
|
||||
<!-- 设备概览表格 -->
|
||||
<uni-table :loading="loading" border stripe emptyText="暂无数据">
|
||||
<uni-tr>
|
||||
<block v-for="(mapper, index) in deviceTableFields" :key="index">
|
||||
<!-- 表头列 -->
|
||||
<uni-th v-if="mapper.title" :key="index" align="center">
|
||||
{{mapper.title}}
|
||||
</uni-th>
|
||||
</block>
|
||||
</uni-tr>
|
||||
<uni-tr v-for="(item ,i) in deviceTableData" :key="i">
|
||||
<block v-for="(mapper, index) in deviceTableFields" :key="index">
|
||||
<uni-td v-if="mapper.field === 'appid'" align="center">
|
||||
<view v-if="item.appid" @click="navTo('/pages/uni-stat/device/overview/overview', item.appid)" class="link-btn-color">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</view>
|
||||
<view v-else @click="navTo('/pages/system/app/add')" class="link-btn-color">
|
||||
需添加此应用的 appid
|
||||
</view>
|
||||
</uni-td>
|
||||
<uni-td v-else :key="index" align="center">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</uni-td>
|
||||
</block>
|
||||
</uni-tr>
|
||||
</uni-table>
|
||||
</view>
|
||||
<view class="uni-stat--x p-m">
|
||||
<view class="uni-stat-card-header">注册用户概览</view>
|
||||
<!-- 注册用户概览表格 -->
|
||||
<uni-table :loading="loading" border stripe emptyText="暂无数据">
|
||||
<uni-tr>
|
||||
<block v-for="(mapper, index) in userTableFields" :key="index">
|
||||
<uni-th v-if="mapper.title" :key="index" align="center">
|
||||
{{mapper.title}}
|
||||
</uni-th>
|
||||
</block>
|
||||
</uni-tr>
|
||||
<uni-tr v-for="(item ,i) in userTableData" :key="i">
|
||||
<block v-for="(mapper, index) in userTableFields" :key="index">
|
||||
<uni-td v-if="mapper.field === 'appid'" align="center">
|
||||
<view v-if="item.appid" @click="navTo('/pages/uni-stat/user/overview/overview', item.appid)" class="link-btn-color">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</view>
|
||||
<view v-else @click="navTo('/pages/system/app/add')" class="link-btn-color">
|
||||
需添加此应用的 appid
|
||||
</view>
|
||||
</uni-td>
|
||||
<uni-td v-else :key="index" align="center">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</uni-td>
|
||||
</block>
|
||||
</uni-tr>
|
||||
</uni-table>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- #ifndef H5 -->
|
||||
<fix-window />
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
stringifyQuery,
|
||||
stringifyField,
|
||||
stringifyGroupField,
|
||||
getTimeOfSomeDayAgo,
|
||||
division,
|
||||
format,
|
||||
parseDateTime,
|
||||
getFieldTotal,
|
||||
debounce
|
||||
} from '@/js_sdk/uni-stat/util.js'
|
||||
|
||||
import {
|
||||
deviceFeildsMap,
|
||||
userFeildsMap
|
||||
} from './fieldsMap.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
platform_id: '',
|
||||
start_time: [getTimeOfSomeDayAgo(1), new Date().getTime()]
|
||||
},
|
||||
deviceTableData: [],
|
||||
userTableData: [],
|
||||
// panelData: panelOption,
|
||||
// 每页数据量
|
||||
pageSize: 10,
|
||||
// 当前页
|
||||
pageCurrent: 1,
|
||||
// 数据总量
|
||||
total: 0,
|
||||
loading: false,
|
||||
complete: false,
|
||||
statSetting: {
|
||||
mode: "",
|
||||
day: 7
|
||||
},
|
||||
statModeList: [
|
||||
{ "value": "open", "text": "开启" },
|
||||
{ "value": "close", "text": "关闭" },
|
||||
{ "value": "auto", "text": "节能" },
|
||||
],
|
||||
showAddAppId: false,
|
||||
showdbInit: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// 创建一个防抖函数,延迟执行getAllData方法
|
||||
this.debounceGet = debounce(() => {
|
||||
this.getAllData(this.queryStr);
|
||||
}, 300);
|
||||
|
||||
// 执行防抖函数
|
||||
this.debounceGet();
|
||||
|
||||
// 检查appId
|
||||
this.checkAppId();
|
||||
|
||||
this.checkdbInit();
|
||||
},
|
||||
|
||||
watch: {
|
||||
query: {
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
// 监听query对象的变化,并在变化时执行防抖函数
|
||||
this.debounceGet(this.queryStr);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
queryStr() {
|
||||
// 默认查询条件
|
||||
const defQuery = `(dimension == "hour" || dimension == "day")`;
|
||||
// 将query对象转换为查询字符串并与默认查询条件合并
|
||||
return stringifyQuery(this.query) + ' && ' + defQuery;
|
||||
},
|
||||
|
||||
deviceTableFields() {
|
||||
// 返回设备表格的字段映射
|
||||
return this.tableFieldsMap(deviceFeildsMap);
|
||||
},
|
||||
|
||||
userTableFields() {
|
||||
// 返回用户表格的字段映射
|
||||
return this.tableFieldsMap(userFeildsMap);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getAllData(queryStr) {
|
||||
// 获取设备数据
|
||||
this.getApps(this.queryStr, deviceFeildsMap, 'device');
|
||||
// 获取用户数据
|
||||
this.getApps(this.queryStr, userFeildsMap, 'user');
|
||||
},
|
||||
|
||||
tableFieldsMap(fieldsMap) {
|
||||
let tableFields = [];
|
||||
const today = [];
|
||||
const yesterday = [];
|
||||
const other = [];
|
||||
|
||||
for (const mapper of fieldsMap) {
|
||||
if (mapper.field) {
|
||||
if (mapper.hasOwnProperty('value')) {
|
||||
// 如果字段映射中有'value'属性,则根据映射生成今天和昨天的字段
|
||||
const t = JSON.parse(JSON.stringify(mapper));
|
||||
const y = JSON.parse(JSON.stringify(mapper));
|
||||
|
||||
if (mapper.field !== 'total_users' && mapper.field !== 'total_devices') {
|
||||
t.title = '今日' + mapper.title;
|
||||
t.field = mapper.field + '_value';
|
||||
y.title = '昨日' + mapper.title;
|
||||
y.field = mapper.field + '_contrast';
|
||||
|
||||
today.push(t);
|
||||
yesterday.push(y);
|
||||
} else {
|
||||
t.field = mapper.field + '_value';
|
||||
other.push(t);
|
||||
}
|
||||
} else {
|
||||
// 将其他字段直接添加到tableFields中
|
||||
tableFields.push(mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按顺序合并所有的字段
|
||||
tableFields = [...tableFields, ...today, ...yesterday, ...other];
|
||||
|
||||
return tableFields;
|
||||
},
|
||||
|
||||
|
||||
getApps(query, fieldsMap, type = "device") {
|
||||
this.loading = true
|
||||
const db = uniCloud.database()
|
||||
const appDaily = db.collection('uni-stat-result').where(query).getTemp();
|
||||
const appList = db.collection('opendb-app-list').getTemp()
|
||||
db.collection(appDaily, appList)
|
||||
.field(
|
||||
`${stringifyField(fieldsMap, '', 'value')},stat_date,appid,dimension`
|
||||
)
|
||||
.groupBy(`appid,dimension,stat_date`)
|
||||
.groupField(stringifyGroupField(fieldsMap, '', 'value'))
|
||||
.orderBy(`appid`, 'desc')
|
||||
.get()
|
||||
.then((res) => {
|
||||
let {
|
||||
data
|
||||
} = res.result
|
||||
//console.log('data: ', data)
|
||||
this[`${type}TableData`] = []
|
||||
if (!data.length) return
|
||||
let appids = [],
|
||||
todays = [],
|
||||
yesterdays = [],
|
||||
isToday = parseDateTime(getTimeOfSomeDayAgo(0), '', ''),
|
||||
isYesterday = parseDateTime(getTimeOfSomeDayAgo(1), '', '')
|
||||
for (const item of data) {
|
||||
const {
|
||||
appid,
|
||||
name
|
||||
} = item.appid && item.appid[0] || {}
|
||||
item.appid = appid
|
||||
item.name = name
|
||||
|
||||
if (appids.indexOf(item.appid) < 0) {
|
||||
appids.push(item.appid)
|
||||
}
|
||||
if (item.dimension === 'hour' && item.stat_date === isToday) {
|
||||
todays.push(item)
|
||||
}
|
||||
if (item.dimension === 'day' && item.stat_date === isYesterday) {
|
||||
yesterdays.push(item)
|
||||
}
|
||||
}
|
||||
const keys = fieldsMap.map(f => f.field).filter(Boolean)
|
||||
for (const appid of appids) {
|
||||
const rowData = {}
|
||||
const t = todays.find(item => item.appid === appid)
|
||||
const y = yesterdays.find(item => item.appid === appid)
|
||||
for (const key of keys) {
|
||||
if (key === 'appid' || key === 'name') {
|
||||
rowData[key] = t && t[key]
|
||||
} else {
|
||||
const value = t && t[key]
|
||||
const contrast = y && y[key]
|
||||
rowData[key + '_value'] = format(value)
|
||||
rowData[key + '_contrast'] = format(contrast)
|
||||
}
|
||||
}
|
||||
if (appid) {
|
||||
rowData[`total_${type}s_value`] = "获取中...";
|
||||
}
|
||||
this[`${type}TableData`].push(rowData);
|
||||
if (appid) {
|
||||
// total_users 不准确,置空后由 getFieldTotal 处理, appid 不存在时暂不处理
|
||||
t[`total_${type}s`] = 0
|
||||
const query = JSON.parse(JSON.stringify(this.query))
|
||||
query.start_time = [getTimeOfSomeDayAgo(0), new Date().getTime()]
|
||||
query.appid = appid
|
||||
getFieldTotal.call(this, query, `total_${type}s`).then(total => {
|
||||
this[`${type}TableData`].find(item => item.appid === appid)[
|
||||
`total_${type}s_value`] = total
|
||||
})
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
// err.message 错误信息
|
||||
// err.code 错误码
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
this.complete = true;
|
||||
})
|
||||
},
|
||||
|
||||
navTo(url, id) {
|
||||
if (url.indexOf('http') > -1) {
|
||||
// 如果url中包含'http',则在新窗口中打开该链接
|
||||
window.open(url);
|
||||
} else {
|
||||
if (id) {
|
||||
// 如果有提供id参数,则将其添加到url中作为查询参数
|
||||
url = `${url}?appid=${id}`;
|
||||
}
|
||||
// 使用uni.navigateTo方法进行页面跳转
|
||||
uni.navigateTo({
|
||||
url
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
toUrl(url) {
|
||||
// #ifdef H5
|
||||
// 在新窗口中打开url链接(仅适用于H5平台)
|
||||
window.open(url, "_blank");
|
||||
// #endif
|
||||
},
|
||||
|
||||
toAddAppId() {
|
||||
// 隐藏添加App ID的标识
|
||||
this.showAddAppId = false;
|
||||
// 使用uni.navigateTo方法进行页面跳转到指定路径
|
||||
uni.navigateTo({
|
||||
url: "/pages/system/app/list",
|
||||
events: {
|
||||
// 注册事件,用于在目标页面刷新数据后执行回调
|
||||
refreshData: () => {
|
||||
this.checkAppId();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async checkAppId() {
|
||||
// 获取uniCloud数据库的实例
|
||||
const db = uniCloud.database();
|
||||
// 查询'opendb-app-list'集合的数据数量
|
||||
let res = await db.collection('opendb-app-list').count();
|
||||
// 如果查询结果为空或total为0,则显示添加App ID的标识
|
||||
this.showAddAppId = (!res.result || res.result.total === 0) ? true : false;
|
||||
},
|
||||
|
||||
async checkdbInit(){
|
||||
// 获取uniCloud数据库的实例
|
||||
const db = uniCloud.database();
|
||||
// 查询'opendb-app-list'集合的数据数量
|
||||
let res = await db.collection('opendb-admin-menus').count();
|
||||
// 如果查询结果为空或total为0,则显示添加App ID的标识
|
||||
this.showdbInit = (!res.result || res.result.total === 0) ? true : false;
|
||||
if (this.showdbInit) {
|
||||
uni.showModal({
|
||||
title: "重要提示",
|
||||
content: `检测到您未初始化数据库,请先右键uni-admin项目根目下的 uniCloud/database 目录,执行初始化云数据库,否则左侧无法显示菜单等数据`,
|
||||
showCancel: false,
|
||||
confirmText: "我知道了"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-stat-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.uni-table-scroll {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.link-btn-color {
|
||||
color: #007AFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.uni-stat-text {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.uni-radio-cell {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.uni-stat-tooltip-s {
|
||||
width: 400px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.uni-a {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="fix-top-window">
|
||||
<view class="uni-header">
|
||||
<uni-stat-breadcrumb class="uni-stat-breadcrumb-on-phone" />
|
||||
<view class="uni-group">
|
||||
<view class="uni-sub-title hide-on-phone"></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-container">
|
||||
<!-- 提示条1:初始化db_init.json -->
|
||||
<uni-notice-bar v-if="showdbInit" showGetMore showIcon class="mb-m pointer" text="检测到您未初始化db_init.json,请先右键uniCloud/database/db_init.json文件,执行初始化云数据库,否则左侧无法显示菜单等数据" background-color="#fef0f0" color="#f56c6c" @click="toAddAppId" />
|
||||
<!-- 提示条2:添加应用 -->
|
||||
<uni-notice-bar v-if="showAddAppId" showGetMore showIcon class="mb-m pointer" text="检测到您还未添加应用,点击前往应用管理添加" @click="toAddAppId" />
|
||||
<!-- 提示条3:暂无数据,需开通统计功能 -->
|
||||
<uni-notice-bar v-if="!deviceTableData.length && !userTableData.length && !query.platform_id && complete" showGetMore showIcon class="mb-m pointer"
|
||||
text="暂无数据, 统计相关功能需开通 uni 统计后才能使用, 如未开通, 点击查看具体流程" @click="navTo('https://uniapp.dcloud.io/uni-stat-v2.html')" />
|
||||
|
||||
<view class="uni-stat--x mb-m">
|
||||
<!-- 平台选择标签 -->
|
||||
<uni-stat-tabs label="平台选择" type="boldLine" mode="platform" v-model="query.platform_id" />
|
||||
</view>
|
||||
<view class="uni-stat--x p-m">
|
||||
<view class="uni-stat-card-header">设备概览</view>
|
||||
<!-- 设备概览表格 -->
|
||||
<uni-table :loading="loading" border stripe :emptyText="deviceError || '暂无数据'">
|
||||
<uni-tr>
|
||||
<block v-for="(mapper, index) in deviceTableFields" :key="index">
|
||||
<!-- 表头列 -->
|
||||
<uni-th v-if="mapper.title" :key="index" align="center">
|
||||
{{mapper.title}}
|
||||
</uni-th>
|
||||
</block>
|
||||
</uni-tr>
|
||||
<uni-tr v-for="(item ,i) in deviceTableData" :key="i">
|
||||
<block v-for="(mapper, index) in deviceTableFields" :key="index">
|
||||
<uni-td v-if="mapper.field === 'appid'" align="center">
|
||||
<view v-if="item.appid" @click="navTo('/pages/uni-stat/device/overview/overview', item.appid)" class="link-btn-color">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</view>
|
||||
<view v-else @click="navTo('/pages/system/app/add')" class="link-btn-color">
|
||||
需添加此应用的 appid
|
||||
</view>
|
||||
</uni-td>
|
||||
<uni-td v-else :key="index" align="center">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</uni-td>
|
||||
</block>
|
||||
</uni-tr>
|
||||
</uni-table>
|
||||
</view>
|
||||
<view class="uni-stat--x p-m">
|
||||
<view class="uni-stat-card-header">注册用户概览</view>
|
||||
<!-- 注册用户概览表格 -->
|
||||
<uni-table :loading="loading" border stripe :emptyText="userError || '暂无数据'">
|
||||
<uni-tr>
|
||||
<block v-for="(mapper, index) in userTableFields" :key="index">
|
||||
<uni-th v-if="mapper.title" :key="index" align="center">
|
||||
{{mapper.title}}
|
||||
</uni-th>
|
||||
</block>
|
||||
</uni-tr>
|
||||
<uni-tr v-for="(item ,i) in userTableData" :key="i">
|
||||
<block v-for="(mapper, index) in userTableFields" :key="index">
|
||||
<uni-td v-if="mapper.field === 'appid'" align="center">
|
||||
<view v-if="item.appid" @click="navTo('/pages/uni-stat/user/overview/overview', item.appid)" class="link-btn-color">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</view>
|
||||
<view v-else @click="navTo('/pages/system/app/add')" class="link-btn-color">
|
||||
需添加此应用的 appid
|
||||
</view>
|
||||
</uni-td>
|
||||
<uni-td v-else :key="index" align="center">
|
||||
{{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
|
||||
</uni-td>
|
||||
</block>
|
||||
</uni-tr>
|
||||
</uni-table>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- #ifndef H5 -->
|
||||
<fix-window />
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
stringifyQuery,
|
||||
stringifyField,
|
||||
stringifyGroupField,
|
||||
getTimeOfSomeDayAgo,
|
||||
division,
|
||||
format,
|
||||
parseDateTime,
|
||||
getFieldTotal,
|
||||
debounce
|
||||
} from '@/js_sdk/uni-stat/util.js'
|
||||
|
||||
import {
|
||||
deviceFeildsMap,
|
||||
userFeildsMap
|
||||
} from './fieldsMap.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query: {
|
||||
platform_id: '',
|
||||
start_time: [getTimeOfSomeDayAgo(1), new Date().getTime()]
|
||||
},
|
||||
deviceTableData: [],
|
||||
userTableData: [],
|
||||
deviceError: '',
|
||||
userError: '',
|
||||
// panelData: panelOption,
|
||||
// 每页数据量
|
||||
pageSize: 10,
|
||||
// 当前页
|
||||
pageCurrent: 1,
|
||||
// 数据总量
|
||||
total: 0,
|
||||
loading: false,
|
||||
complete: false,
|
||||
statSetting: {
|
||||
mode: "",
|
||||
day: 7
|
||||
},
|
||||
statModeList: [
|
||||
{ "value": "open", "text": "开启" },
|
||||
{ "value": "close", "text": "关闭" },
|
||||
{ "value": "auto", "text": "节能" },
|
||||
],
|
||||
showAddAppId: false,
|
||||
showdbInit: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// 创建一个防抖函数,延迟执行getAllData方法
|
||||
this.debounceGet = debounce(() => {
|
||||
this.getAllData(this.queryStr);
|
||||
}, 300);
|
||||
|
||||
// 执行防抖函数
|
||||
this.debounceGet();
|
||||
|
||||
// 检查appId
|
||||
this.checkAppId();
|
||||
|
||||
this.checkdbInit();
|
||||
},
|
||||
|
||||
watch: {
|
||||
query: {
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
// 监听query对象的变化,并在变化时执行防抖函数
|
||||
this.debounceGet(this.queryStr);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
queryStr() {
|
||||
// 默认查询条件
|
||||
const defQuery = `(dimension == "hour" || dimension == "day")`;
|
||||
// 将query对象转换为查询字符串并与默认查询条件合并
|
||||
return stringifyQuery(this.query) + ' && ' + defQuery;
|
||||
},
|
||||
|
||||
deviceTableFields() {
|
||||
// 返回设备表格的字段映射
|
||||
return this.tableFieldsMap(deviceFeildsMap);
|
||||
},
|
||||
|
||||
userTableFields() {
|
||||
// 返回用户表格的字段映射
|
||||
return this.tableFieldsMap(userFeildsMap);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getAllData(queryStr) {
|
||||
// 获取设备数据
|
||||
this.getApps(this.queryStr, deviceFeildsMap, 'device');
|
||||
// 获取用户数据
|
||||
this.getApps(this.queryStr, userFeildsMap, 'user');
|
||||
},
|
||||
|
||||
tableFieldsMap(fieldsMap) {
|
||||
let tableFields = [];
|
||||
const today = [];
|
||||
const yesterday = [];
|
||||
const other = [];
|
||||
|
||||
for (const mapper of fieldsMap) {
|
||||
if (mapper.field) {
|
||||
if (mapper.hasOwnProperty('value')) {
|
||||
// 如果字段映射中有'value'属性,则根据映射生成今天和昨天的字段
|
||||
const t = JSON.parse(JSON.stringify(mapper));
|
||||
const y = JSON.parse(JSON.stringify(mapper));
|
||||
|
||||
if (mapper.field !== 'total_users' && mapper.field !== 'total_devices') {
|
||||
t.title = '今日' + mapper.title;
|
||||
t.field = mapper.field + '_value';
|
||||
y.title = '昨日' + mapper.title;
|
||||
y.field = mapper.field + '_contrast';
|
||||
|
||||
today.push(t);
|
||||
yesterday.push(y);
|
||||
} else {
|
||||
t.field = mapper.field + '_value';
|
||||
other.push(t);
|
||||
}
|
||||
} else {
|
||||
// 将其他字段直接添加到tableFields中
|
||||
tableFields.push(mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 按顺序合并所有的字段
|
||||
tableFields = [...tableFields, ...today, ...yesterday, ...other];
|
||||
|
||||
return tableFields;
|
||||
},
|
||||
|
||||
|
||||
getApps(query, fieldsMap, type = "device") {
|
||||
this.loading = true
|
||||
this[`${type}Error`] = ''
|
||||
const db = uniCloud.database()
|
||||
const appDaily = db.collection('uni-stat-result').where(query).getTemp();
|
||||
const appList = db.collection('opendb-app-list').getTemp()
|
||||
db.collection(appDaily, appList)
|
||||
.field(
|
||||
`${stringifyField(fieldsMap, '', 'value')},stat_date,appid,dimension`
|
||||
)
|
||||
.groupBy(`appid,dimension,stat_date`)
|
||||
.groupField(stringifyGroupField(fieldsMap, '', 'value'))
|
||||
.orderBy(`appid`, 'desc')
|
||||
.get()
|
||||
.then((res) => {
|
||||
const data = res.result && Array.isArray(res.result.data) ? res.result.data : []
|
||||
//console.log('data: ', data)
|
||||
this[`${type}TableData`] = []
|
||||
if (!data.length) return
|
||||
let appids = [],
|
||||
todays = [],
|
||||
yesterdays = [],
|
||||
isToday = parseDateTime(getTimeOfSomeDayAgo(0), '', ''),
|
||||
isYesterday = parseDateTime(getTimeOfSomeDayAgo(1), '', '')
|
||||
for (const item of data) {
|
||||
const {
|
||||
appid,
|
||||
name
|
||||
} = item.appid && item.appid[0] || {}
|
||||
item.appid = appid
|
||||
item.name = name
|
||||
|
||||
if (appids.indexOf(item.appid) < 0) {
|
||||
appids.push(item.appid)
|
||||
}
|
||||
if (item.dimension === 'hour' && item.stat_date === isToday) {
|
||||
todays.push(item)
|
||||
}
|
||||
if (item.dimension === 'day' && item.stat_date === isYesterday) {
|
||||
yesterdays.push(item)
|
||||
}
|
||||
}
|
||||
const keys = fieldsMap.map(f => f.field).filter(Boolean)
|
||||
for (const appid of appids) {
|
||||
const rowData = {}
|
||||
const t = todays.find(item => item.appid === appid) || {}
|
||||
const y = yesterdays.find(item => item.appid === appid) || {}
|
||||
for (const key of keys) {
|
||||
if (key === 'appid' || key === 'name') {
|
||||
rowData[key] = t && t[key]
|
||||
} else {
|
||||
const value = t && t[key]
|
||||
const contrast = y && y[key]
|
||||
rowData[key + '_value'] = format(value)
|
||||
rowData[key + '_contrast'] = format(contrast)
|
||||
}
|
||||
}
|
||||
if (appid) {
|
||||
rowData[`total_${type}s_value`] = "获取中...";
|
||||
}
|
||||
this[`${type}TableData`].push(rowData);
|
||||
if (appid) {
|
||||
// total_users 不准确,置空后由 getFieldTotal 处理, appid 不存在时暂不处理
|
||||
t[`total_${type}s`] = 0
|
||||
const query = JSON.parse(JSON.stringify(this.query))
|
||||
query.start_time = [getTimeOfSomeDayAgo(0), new Date().getTime()]
|
||||
query.appid = appid
|
||||
getFieldTotal.call(this, query, `total_${type}s`).then(total => {
|
||||
this[`${type}TableData`].find(item => item.appid === appid)[
|
||||
`total_${type}s_value`] = total
|
||||
})
|
||||
}
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
this[`${type}TableData`] = []
|
||||
this[`${type}Error`] = err && err.message ? err.message : '统计数据加载失败'
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
this.complete = true;
|
||||
})
|
||||
},
|
||||
|
||||
navTo(url, id) {
|
||||
if (url.indexOf('http') > -1) {
|
||||
// 如果url中包含'http',则在新窗口中打开该链接
|
||||
window.open(url);
|
||||
} else {
|
||||
if (id) {
|
||||
// 如果有提供id参数,则将其添加到url中作为查询参数
|
||||
url = `${url}?appid=${id}`;
|
||||
}
|
||||
// 使用uni.navigateTo方法进行页面跳转
|
||||
uni.navigateTo({
|
||||
url
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
toUrl(url) {
|
||||
// #ifdef H5
|
||||
// 在新窗口中打开url链接(仅适用于H5平台)
|
||||
window.open(url, "_blank");
|
||||
// #endif
|
||||
},
|
||||
|
||||
toAddAppId() {
|
||||
// 隐藏添加App ID的标识
|
||||
this.showAddAppId = false;
|
||||
// 使用uni.navigateTo方法进行页面跳转到指定路径
|
||||
uni.navigateTo({
|
||||
url: "/pages/system/app/list",
|
||||
events: {
|
||||
// 注册事件,用于在目标页面刷新数据后执行回调
|
||||
refreshData: () => {
|
||||
this.checkAppId();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async checkAppId() {
|
||||
try {
|
||||
const db = uniCloud.database();
|
||||
const res = await db.collection('opendb-app-list').count();
|
||||
this.showAddAppId = !res.result || res.result.total === 0;
|
||||
} catch (error) {
|
||||
this.showAddAppId = false;
|
||||
console.error('[index_info] check app failed', error);
|
||||
}
|
||||
},
|
||||
|
||||
async checkdbInit() {
|
||||
try {
|
||||
const db = uniCloud.database();
|
||||
const res = await db.collection('opendb-admin-menus').count();
|
||||
this.showdbInit = !res.result || res.result.total === 0;
|
||||
} catch (error) {
|
||||
this.showdbInit = false;
|
||||
console.error('[index_info] check database failed', error);
|
||||
}
|
||||
if (this.showdbInit) {
|
||||
uni.showModal({
|
||||
title: "重要提示",
|
||||
content: `检测到您未初始化数据库,请先右键uni-admin项目根目下的 uniCloud/database 目录,执行初始化云数据库,否则左侧无法显示菜单等数据`,
|
||||
showCancel: false,
|
||||
confirmText: "我知道了"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-stat-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
padding: 10px 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.uni-table-scroll {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.link-btn-color {
|
||||
color: #007AFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.uni-stat-text {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.uni-radio-cell {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.uni-stat-tooltip-s {
|
||||
width: 400px;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.uni-a {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user