116.进入下载和评分页面共用同一个云对象方法
点击事件


userHistoryList
/uniCloud-alipay/cloudfunctions/client-user-action/index.obj.js

117.联表查询并field过滤壁纸表内的字段
/uniCloud-alipay/cloudfunctions/client-user-action/index.obj.js



118.完成壁纸下载和评分列表的数据展示及客户端已知bug的修改
完成壁纸下载和评分列表的壁纸信息数据展示
/uniCloud-alipay/cloudfunctions/client-user-action/index.obj.js



修改bug




119.在后台管理展示所有用户的下载评分记录

<template>
<view class="download">
<custom-head-top>
<template #left>
下载记录
</template>
<template #right>
<uni-data-select style="width: 200px;" ref="selectRef" @change="classifyChange" collection="xxm-bizhi-classify"
field="_id as value, name as text,sort"
:where="`enable == true`"
orderby="sort asc"
v-model="params.classid"
></uni-data-select>
</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" >IP地址</uni-th>
<uni-th align="left" >下载时间</uni-th>
</uni-tr>
<uni-tr v-for="item in listData" :key="item._id">
<uni-td class="thumb">
<image @click="previewImg(item.picurl)" :src="getSmallImg(item.picurl)" mode="aspectFill"></image>
</uni-td>
<uni-td>{{item.classname}}</uni-td>
<uni-td>{{item.nickname}} </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>
</template>
<script setup>
import {onMounted, ref} from "vue";
import dayjs from "dayjs"
import { getSmallImg } from '@/utils/tools';
import { routerTo, showModal, showToast,previewImg } from '@/utils/common';
const listData = ref([]);
const selectValue = ref("");
const selectRef = ref(null);
const params = ref({
current:1,
total:0,
size:15,
classid:""
})
//切换分类
const classifyChange = (e)=>{
params.value.classid = e
params.value.current = 1
getData();
}
//切换分页
const pageChange = (e)=>{
params.value.current = e.current;
getData();
}
//获取数据
const getData = async()=>{
// let {errCode,errMsg,data,count} = await 云对象.方法名();
listData.value = data
params.value.total = count
console.log(data);
}
//删除分类选择的缓存
onMounted(()=>{
selectRef.value.clearVal();
})
</script>
<style lang="scss" scoped>
.main{
padding:20px;
}
</style>

<template>
<view class="download">
<custom-head-top>
<template #left>
评分记录
</template>
<template #right>
<uni-data-select style="width: 200px;" ref="selectRef" @change="classifyChange" collection="xxm-bizhi-classify"
field="_id as value, name as text,sort"
:where="`enable == true`"
orderby="sort asc"
v-model="params.classid"
></uni-data-select>
</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 in listData" :key="item._id">
<uni-td class="thumb">
<image @click="previewImg(item.picurl)" :src="getSmallImg(item.picurl)" mode="aspectFill"></image>
</uni-td>
<uni-td>{{item.classname}}</uni-td>
<uni-td class="score">
<uni-rate class="uni-rate" :disabled="true"
disabledColor="#F7E7CE" size="16" :value="item.userScore" />
<text class="text">{{item.userScore}}</text>
</uni-td>
<uni-td>{{item.nickname}} </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>
</template>
<script setup>
import {onMounted, ref} from "vue";
import dayjs from "dayjs"
import { getSmallImg } from '@/utils/tools';
import { routerTo, showModal, showToast,previewImg } from '@/utils/common';
const dataCloudObj = uniCloud.importObject("admin-data-record");
const listData = ref([]);
const selectValue = ref("");
const selectRef = ref(null);
const params = ref({
current:1,
total:0,
size:10,
classid:"",
type:"score"
})
//切换分类
const classifyChange = (e)=>{
params.value.classid = e
params.value.current = 1
getData();
}
//切换分页
const pageChange = (e)=>{
params.value.current = e.current;
getData();
}
//获取数据
const getData = async()=>{
try{
let {data,errCode,count} = await dataCloudObj.recordList(params.value);
listData.value = data
params.value.total = count
console.log(data);
}catch(err){
console.log(err);
}
}
//删除分类选择的缓存
onMounted(()=>{
selectRef.value.clearVal();
})
</script>
<style lang="scss" scoped>
.main{
padding:20px;
.table{
.thumb{
image{
width: 45px;
height: 100px;
}
}
.score{
.uni-rate{ display: inline-block;}
.text{padding-left:5px;}
}
}
}
</style>
菜单管理

一级菜单

二级菜单
下载记录

评分记录

新建云对象

module.exports = {
_before: function() { // 通用预处理器
},
// 获取记录列表
async recordList({ size = 5, current = 1, classid = "", type = "" } = {}) {
if (!type) return { errCode: 400, errMsg: "type必填" };
// 限制最大查询数量
size = Math.min(100, size);
let skip = (current - 1) * size
// 构建查询条件
let where = {}
// 根据类型选择表名
let tablename = (type == 'download') ? 'wallpaper-download' : (type == 'score') ? 'wallpaper-score' :
"";
if (classid) where.classid = classid
const dbJQL = uniCloud.databaseForJQL({
clientInfo: this.getClientInfo()
})
// 构建主表查询模板
let tableTemp = dbJQL.collection(tablename)
.where(where)
.orderBy("createTime desc")
.skip(skip)
.limit(size)
.getTemp();
// 构建关联表查询模板
let classTemp = dbJQL.collection("wallpaper-classify")
.field("_id,name")
.getTemp();
let picTemp = dbJQL.collection("wallpaper-piclist")
.field(`
_id,
picurl
`).getTemp();
let userTemp = dbJQL.collection("uni-id-users")
.field("_id,nickname")
.getTemp();
// 执行联合查询
let res = await dbJQL.collection(tableTemp, picTemp, classTemp, userTemp)
.field(`
userScore,
ip,
user_id.nickname as nickname,
createTime,
classid.name as classname,
picid.picurl as picurl
`)
.get({ getCount: true });
// 处理关联字段数组
let data = res.data.map(item => ({
...item,
classname: item.classname[0],
nickname: item.nickname[0],
picurl: item.picurl[0]
}))
return { ...res, data };
},
}
下载记录
/pages/data/download-record
数据显示


添加样式


120.搭建动态全局配置项页面
新建页面

菜单管理

/pages/system/config/config
<template>
<view class="config">
<custom-head-top>
<template #left>
项目配置
</template>
<template #right>
<button type="primary" size="mini" :plain="!btnType" @click="editAndSubmit">
<template v-if="btnType">
<uni-icons type="paperplane-filled" size="14" color="#fff"></uni-icons>
提交
</template>
<template v-else>
<uni-icons type="compose" size="14" color="#007AFF"></uni-icons>
编辑
</template>
</button>
</template>
</custom-head-top>
<view class="main" :class="!btnType?'readonly':''">
<view class="container">
<uni-forms ref="formRef" :modelValue="formData"
label-align="right" :label-width="120">
<uni-forms-item label="LOGO" name="logo">
<select-one-img v-model:formData="formData" :width="100"
ratio="1 / 1" :maxImgSize="500"></select-one-img>
</uni-forms-item>
<uni-forms-item label="项目名称" name="brand">
<uni-easyinput type="text" v-model="formData.brand"
placeholder="请输入项目名称" />
</uni-forms-item>
<uni-forms-item label="是否开启广告" name="checkedAd">
<switch :checked="formData.checkedAd" class="switchStyle" @change="checkedAdChange"/>
</uni-forms-item>
<uni-forms-item label="激励视频ID" name="rewardedVideo"
v-if="formData.checkedAd">
<uni-easyinput type="text" v-model="formData.rewardedVideo"
placeholder="请输入激励视频ID" />
</uni-forms-item>
<uni-forms-item label="视频卡片ID" name="cardVideo"
v-if="formData.checkedAd">
<uni-easyinput type="text" v-model="formData.cardVideo"
placeholder="请输入视频卡片ID" />
</uni-forms-item>
<uni-forms-item label="每日领币数" name="dayCoin"
v-if="formData.checkedAd">
<uni-easyinput type="text" v-model.number="formData.dayCoin"
placeholder="请输入每日领币数" />
</uni-forms-item>
<uni-forms-item label="看广告得币" name="adCoin"
v-if="formData.checkedAd">
<uni-easyinput type="text" v-model.number="formData.adCoin"
placeholder="请输入看广告得币数" />
</uni-forms-item>
<uni-forms-item label="硬币规则" name="ruleCoin"
v-if="formData.checkedAd">
<uni-easyinput type="textarea" v-model="formData.ruleCoin"
placeholder="请输入硬币使用规则" maxlength="300"/>
</uni-forms-item>
<uni-forms-item label="搜索热词" name="hots">
<uni-easyinput type="text" v-model="formData.hots"
placeholder="请输入搜索热词用逗号,隔开" />
</uni-forms-item>
<uni-forms-item label="版权信息" name="copyright">
<uni-easyinput type="textarea" v-model="formData.copyright"
placeholder="请输入版权信息" />
</uni-forms-item>
<uni-forms-item label="服务协议" name="service">
<uni-easyinput type="textarea" v-model="formData.service"
placeholder="请输入服务协议" autoHeight maxlength="1000"/>
</uni-forms-item>
<uni-forms-item label="隐私政策" name="privacy">
<uni-easyinput type="textarea" v-model="formData.privacy"
placeholder="请输入隐私政策" autoHeight maxlength="1000"/>
</uni-forms-item>
</uni-forms>
</view>
</view>
</view>
</template>
<script setup>
import { computed, ref } from 'vue';
const btnType = ref(0); //0是编辑 1是提交
const btnName = computed(()=>btnType.value?'提交':'编辑');
const formRef = ref(null);
const formData = ref({
logo:"",
brand:"",
checkedAd:false,
rewardedVideo:"",//激励视频id
cardVideo:"",//视频卡片广告
dayCoin:10, //每日领币
adCoin:30, //看广告获得币
ruleCoin:"", //硬币规则说明
hots:"",//搜索热词
copyright:"",
service:"",
privacy:""
})
//是否加入广告开关
const checkedAdChange = (e)=>{
formData.value.checkedAd = e.detail.value;
}
const editAndSubmit = ()=>{
if(btnType.value){
console.log(formData.value);
console.log("提交");
}else{
console.log("编辑");
}
btnType.value = btnType.value ? 0 : 1;
}
</script>
<style lang="scss" scoped>
.main{
padding:20px;
.container{
margin:0 auto;
min-height: 200px;
max-width: 1000px;
:deep(.uni-forms-item){
margin-top: 32px;
}
:deep(.uni-forms-item__content){
display: flex;
align-items: center;
}
}
}
.readonly{
pointer-events: none;
opacity: 0.7;
user-select: none;
}
</style>
