136.创建硬币使用记录展示页面,展示硬币列表数据
/uniCloud-alipay/database/wallpaper-activity-coin.schema.json
添加ip字段

/uniCloud-alipay/cloudfunctions/admin-data-record/index.obj.js
coinRecord方法
async coinRecord({ size = 5, current = 1, dataRange = [] } = {}) {
size = Math.min(100, size);
let skip = (current - 1) * size;
let wre = dataRange.length ?
`createTime >= ${dayjs(dataRange[0]).startOf("day").valueOf()} &&
createTime<=${dayjs(dataRange[1]).endOf("day").valueOf()}` : {};
const dbJQL = uniCloud.databaseForJQL({
clientInfo: this.getClientInfo()
})
let coinTemp = dbJQL.collection("wallpaper-activity-coin")
.where(wre)
.orderBy("createTime desc")
.skip(skip)
.limit(size)
.getTemp();
let userTemp = dbJQL.collection("uni-id-users")
.field("_id,nickname")
.getTemp();
let res = await dbJQL.collection(coinTemp, userTemp)
.field(`
createTime,
dayGet,
total,
ip,
record,
user_id.nickname as nickname
`)
.get({ getCount: true })
let data = res.data.map(item => {
return {
...item,
nickname: item.nickname[0]
}
})
return { ...res, data };
},
新建coin-record

按照日期选择展示范围内的数据
uni-datetime-picker 日期选择器 | uni-app官网

<script setup>
/**
* 导入Vue和dayjs相关依赖
* ref: Vue的响应式引用API
* dayjs: 处理日期的库
*/
import { ref } from 'vue';
import dayjs from "dayjs"
/**
* 导入uniCloud云函数对象
* 用于与后端云函数进行数据交互
*/
const dataCloudObj = uniCloud.importObject("admin-data-record", { customUI: true });
// 弹出框引用
const popup = ref(null);
// 列表数据
const listData = ref([]);
// 记录列表数据
const recordList = ref([]);
// 请求参数
const params = ref({
current: 1, // 当前页码
total: 0, // 总记录数
size: 20, // 每页显示数量
dataRange: [] // 日期范围
});
// 默认日期范围(当前时间往前推6个月)
const deftData = ref([
dayjs().subtract(6, "M").startOf("day").valueOf(),
dayjs().endOf("day").valueOf()
]);
/**
* 获取数据函数
* 从后端获取硬币记录数据
*/
const getData = async () => {
let { errCode, data = [], count = 0 } = await dataCloudObj.coinRecord(params.value);
listData.value = data
params.value.total = count
}
/**
* 处理链接点击事件
* @param {number} index - 当前点击的记录索引
*/
const handleLink = (index) => {
recordList.value = listData.value[index].record
popup.value.open();
}
/**
* 分页改变事件处理
* @param {Object} e - 分页事件对象
*/
const pageChange = (e) => {
params.value.current = e.current;
getData();
}
/**
* 日期改变事件处理
*/
const dataChange = () => {
getData();
}
getData(); // 初始加载数据
</script>
<template>
<!-- 主容器 -->
<view class="coin">
<!-- 自定义头部 -->
<custom-head-top>
<!-- 左侧标题 -->
<template #left>
硬币记录
</template>
<!-- 右侧日期选择器 -->
<template #right>
<uni-datetime-picker style="width: 300px;" :start="deftData[0]" :end="deftData[1]" @change="dataChange"
v-model="params.dataRange" type="daterange" />
</template>
</custom-head-top>
<!-- 主要内容区域 -->
<view class="main">
<!-- 表格组件 -->
<uni-table class="table" ref="tableRef" border stripe emptyText="暂无更多数据">
<!-- 表头 -->
<uni-tr>
<uni-th align="left">用户名</uni-th>
<uni-th align="left">积分</uni-th>
<uni-th align="left">每日领币</uni-th>
<uni-th align="left">操作记录</uni-th>
<uni-th align="left">IP</uni-th>
<uni-th align="left">创建时间</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="item,index in listData" :key="item._id">
<uni-td>{{item.nickname}}</uni-td>
<uni-td>{{item.total}}</uni-td>
<uni-td>
<uni-tag v-if="item.dayGet" text="已领取" type="primary" size="mini" />
<uni-tag v-else text="未领取" type="default" size="mini" inverted />
</uni-td>
<uni-td>
<view class="link" @click="handleLink(index)">{{item.record.length}}条记录</view>
</uni-td>
<uni-td>{{item.ip || '-'}}</uni-td>
<uni-td>{{dayjs(item.createTime).format("YYYY-MM-DD HH:mm:ss")}}</uni-td>
</uni-tr>
</uni-table>
</view>
<!-- 分页组件 -->
<view class="paging">
<uni-pagination :current="params.current" :total="params.total" :page-size="params.size" :show-icon="true"
@change="pageChange" />
</view>
</view>
<!-- 记录详情弹窗 -->
<uni-popup ref="popup">
<view class="recordPop">
<!-- 可滚动区域 -->
<scroll-view scroll-y style="max-height: 600px;">
<!-- 记录列表 -->
<uni-list border-full>
<uni-list-item :title="item.desc" :note="dayjs(item.time).format('YYYY-MM-DD HH:mm:ss')"
:rightText="item.score+''" v-for="item,index in recordList" :key="index" />
</uni-list>
</scroll-view>
</view>
</uni-popup>
</template>
<style lang="scss" scoped>
.main {
padding: 20px;
.table {
.link {
text-decoration: underline;
color: var(--primary-color);
cursor: pointer;
}
}
}
.recordPop {
width: 600px;
min-height: 400px;
background: #fff;
border-radius: 10px;
background: #fff;
padding: 30px;
}
// 深度选择器样式调整
:deep(.uni-date-range--x) {
right: 0;
}
:deep(.uni-popper__arrow) {
left: 80%;
}
</style>
添加二级菜单


137.使用grid网格布局做响应式栅格布局
创建页面

新建二级菜单

<template>
<view class="index">
<custom-head-top>
<template #left>
数据概览
</template>
<template #right>
<uni-datetime-picker v-model="dataRange" @change="dateChange" type="daterange" style="width: 300px" :start="dataDeft[0]" :end="dataDeft[1]"/>
</template>
</custom-head-top>
<view class="main">
<view class="grid">
<view class="section">
<uni-card title="使用量" margin="0" :is-shadow="false">
<view class="box">
<view class="icon">
<uni-icons type="eye-filled" size="40" color="#9A60B4"></uni-icons>
</view>
<view class="text">
<view class="big">2345<text class="unit">次</text></view>
<view class="small">数据库请求次数</view>
</view>
</view>
</uni-card>
</view>
<view class="section">
<uni-card title="使用人数" margin="0" :is-shadow="false">
<view class="box">
<view class="icon">
<uni-icons type="person-filled" size="40" color="#1890FF"></uni-icons>
</view>
<view class="text">
<view class="big">8899<text class="unit">人</text></view>
<view class="small">IP用户量统计</view>
</view>
</view>
</uni-card>
</view>
<view class="section">
<uni-card title="壁纸总量" margin="0" :is-shadow="false">
<view class="box">
<view class="icon">
<uni-icons type="cloud-download-filled" size="40" color="#91CB74"></uni-icons>
</view>
<view class="text">
<view class="big">189<text class="unit">张</text></view>
<view class="small">系统内壁纸总数</view>
</view>
</view>
</uni-card>
</view>
<view class="section">
<uni-card title="上传量" margin="0" :is-shadow="false">
<view class="box">
<view class="icon">
<uni-icons type="upload-filled" size="40" color="#FC8452"></uni-icons>
</view>
<view class="text">
<view class="big">12<text class="unit">张</text></view>
<view class="small">上传图片量</view>
</view>
</view>
</uni-card>
</view>
<view class="section">
<uni-card title="使用趋势图" margin="0" :is-shadow="false">
折线图
</uni-card>
</view>
<view class="section">
<uni-card title="分类喜好度" margin="0" :is-shadow="false">
饼形图
</uni-card>
</view>
<view class="section">
<uni-card title="下载Top5" margin="0" :is-shadow="false">
<view style="padding:30px 0">
<uni-load-more status="loading" :showText="false"></uni-load-more>
</view>
柱形图
</uni-card>
</view>
<view class="section">
<uni-card title="下载Top5" margin="0" :is-shadow="false">
<view style="padding:30px 0">
<uni-load-more status="loading" :showText="false"></uni-load-more>
</view>
柱形图
</uni-card>
</view>
</view>
</view>
</view>
</template>
<script setup>
import dayjs from "dayjs";
import {onMounted, ref} from "vue";
import { showToast } from "../../utils/common";
const dataDeft = ref([dayjs().subtract(6, 'M').startOf('day').valueOf(),
dayjs().endOf('day').valueOf()]);
const dataRange = ref([])
const dateChange = (e)=>{
getData();
}
const getData = ()=>{
}
getData();
</script>
<style lang="scss" scoped>
:deep(.uni-date-range--x){
right:0;
}
.main{
padding:20px;
.grid{
display: grid;
grid-template-columns: repeat(24,1fr);
gap:20px;
.section{
grid-column: span 6;
.box{
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
padding:30px 0;
.text{
.big{
font-weight: bolder;
color:#333;
font-size: 25px;
padding:10px 0 2px;
.unit{
font-size: 14px;
}
}
.small{
font-size: 12px;
color:#999;
}
}
}
}
.section:nth-child(5){
grid-column: span 16;
}
.section:nth-child(6){
grid-column: span 8;
}
.section:nth-child(7){
grid-column: span 12;
}
.section:nth-child(8){
grid-column: span 12;
}
}
}
@media (max-width:992px){
.main{
.grid{
.section{
grid-column: span 24 !important;
}
}
}
}
</style>

138.云对象常用的API调用方法获取客户端信息
新建数据集合Schema文件

// 文档教程: https://uniapp.dcloud.net.cn/uniCloud/schema
{
"bsonType": "object",
"required": [],
"permission": {
"read": true,
"create": true,
"update": true,
"delete": true
},
"properties": {
"_id": {
"description": "ID,系统自动生成"
},
"user_id": {
"description": "用户id",
"bsonType": "string",
"foreignKey": "uni-id-users._id"
},
"ip": {
"description": "操作者ip地址",
"bsonType": "string",
"defaultValue": {
"$env": "clientIP"
}
},
"methodName": {
"description": "调用的方法名",
"bsonType": "string"
},
"params": {
"description": "请求参数",
"bsonType": "string"
},
"functionName": {
"description": "云对象名称",
"bsonType": "string"
},
"uniPlatform": {
"description": "平台名称",
"bsonType": "string"
},
"createTime": {
"description": "产生时间",
"bsonType": "timestamp",
"defaultValue": {
"$env": "now"
}
}
}
}

139.获取客户端token解析checkToken用户角色信息
管理公共模块或扩展库依赖




// 解构获取客户端IP和平台信息
let clientInfo = this.getClientInfo()
let { clientIP, uniPlatform } = clientInfo
const methodName = this.getMethodName()
const params = this.getParams()
const token = this.getUniIdToken()
this.uniID = uniID.createInstance({ //仓
clientInfo
})
let { uid = '' } = await this.uniID.checkToken(token)
console.log(res)
140.创建云函数公用模块将使用量数据统计封装统计入库
封装方法
/uniCloud-alipay/cloudfunctions/common/custom-utils/index.js
async useRecord(that) {
let clientInfo = that.getClientInfo()
let { clientIP, uniPlatform } = clientInfo
const methodName = that.getMethodName()
const params = that.getParams()
// const token = that.getUniIdToken()
// let uniIDins = uniID.createInstance( {
// //创建uni-id实例,其上方法同uniID
// clientInfo
// )
// let { uid = '' } = await uniIDins.checkToken(token)
const dbJQL = uniCloud.databaseForJQL({
clientInfo
})
dbJQL.collection("wallpaper-data-usage").add({
ip: clientIP,
uniPlatform,
methodName,
params: JSON.stringify(params),
functionName
})
}
管理本云函数的扩展库/公共模块依赖


补充,名称


