From 6e224e285fb7e1eb14c9eceee3fe345a86ea9d65 Mon Sep 17 00:00:00 2001
From: 12914 <12914@example.com>
Date: Sun, 6 Sep 2026 20:05:19 +0800
Subject: [PATCH] =?UTF-8?q?chore(uni-admin):=20=E5=90=8C=E6=AD=A5=E5=AE=98?=
=?UTF-8?q?=E6=96=B9=202.5.1=20=E6=A1=86=E6=9E=B6=E6=96=87=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
来源: gitee.com/dcloud/uni-admin master (2.5.1, 2025-04-24)。含 uni-stat-tabs 组件更新、uni-id-users/uni-id-log validator、uni-stat 页面修复、菜单初始数据与 DB schema 更新;版本号对齐 2.5.1。
---
components/uni-stat-tabs/uni-stat-tabs.vue | 135 +++-
js_sdk/validator/uni-id-log.js | 172 +----
js_sdk/validator/uni-id-users.js | 593 ++++++------------
package.json | 2 +-
pages/system/menu/originalMenuList.json | 2 +-
.../uni-stat/device/comparison/comparison.vue | 65 +-
pages/uni-stat/device/overview/overview.vue | 2 +-
pages/uni-stat/pay-order/list/list.vue | 8 +
pages/uni-stat/user/trend/fieldsMap.js | 19 +-
.../opendb-admin-menus.init_data.json | 2 +-
.../database/opendb-app-list.schema.json | 2 +-
.../uni-stat-app-channels.schema.json | 2 +-
.../database/uni-stat-result.schema.json | 2 +-
13 files changed, 388 insertions(+), 618 deletions(-)
diff --git a/components/uni-stat-tabs/uni-stat-tabs.vue b/components/uni-stat-tabs/uni-stat-tabs.vue
index b8915c6..3cf479b 100644
--- a/components/uni-stat-tabs/uni-stat-tabs.vue
+++ b/components/uni-stat-tabs/uni-stat-tabs.vue
@@ -6,27 +6,47 @@
:class="[`uni-stat--tab-item-${type}`]">
{{placeholder}}
-
-
- {{item.name}}
-
-
-
- {{item.name}}
-
-
-
- {{item.tooltip}}
-
-
-
-
-
+
+
+
+
+ {{item.name}}
+
+
+
+ {{item.name}}
+
+
+
+ {{item.tooltip}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -39,7 +59,12 @@
return {
currentTab: 0,
renderTabs: [],
- cacheKey: "uni-admin-statTabsData"
+ cacheKey: "uni-admin-statTabsData",
+ customCheck:[],
+ costomList:[{
+ "value": 0,
+ "text": "微信小程序",
+ }]
};
},
props: {
@@ -96,6 +121,10 @@
default: () => {
return []
}
+ },
+ costom: {
+ type: Boolean,
+ default: false
}
},
created() {
@@ -204,6 +233,13 @@
}
this.setCache(platforms);
this.renderTabs = platforms
+ this.costomList = []
+ this.renderTabs.forEach(item=>{
+ if(item.name !== '全部') {
+ this.costomList.push(item)
+ }
+ })
+ console.log(this.costomList);
})
},
setAllItem(platforms, _id = '', name = '全部') {
@@ -269,7 +305,6 @@
.uni-stat {
&--tab {
-
&-item {
white-space: nowrap;
font-size: 14px;
@@ -355,7 +390,63 @@
display: none;
}
/* #endif */
+
}
/* #endif */
+
+
+ .costom-box {
+ display:flex;
+ align-items: center;
+ margin-left: 20px;
+ height: auto;
+ width: auto;
+ .coston-inner {
+ position: relative;
+ .costom-dialog {
+ position: absolute;
+ top: 40px;
+ right: 0;
+ border: 1px #eee solid;
+ box-sizing: border-box;
+ width: 200px;
+ border-radius: 5px;
+ background-color: #fff;
+ box-shadow: 0 0 5px 0px rgba(0, 0, 0, 0.1);
+
+ // z-index: 10;
+ &::before {
+ content: '';
+ position: absolute;
+ right: 40px;
+ top: -5px;
+ width: 10px;
+ height: 10px;
+ transform: rotate(45deg);
+ // border: 1px red solid;
+ z-index: 0;
+ background-color: #fff;
+ box-shadow: 0 0 5px 1px rgba(0, 0, 0, 0.1);
+ }
+ .costom-dialog-inner {
+ position: relative;
+ padding: 15px;
+ width: 100%;
+ height: 100%;
+ background-color: #fff;
+ box-sizing: border-box;
+ z-index: 2;
+ }
+ .costom-dialog-bottom {
+ margin-top: 20px;
+ display: flex;
+ align-items: center;
+ }
+ }
+ }
+ }
+
+
+
diff --git a/js_sdk/validator/uni-id-log.js b/js_sdk/validator/uni-id-log.js
index 586ac1a..dd4ee2c 100644
--- a/js_sdk/validator/uni-id-log.js
+++ b/js_sdk/validator/uni-id-log.js
@@ -1,16 +1,21 @@
-// 表单校验规则由 schema2code 生成,不建议直接修改校验规则,而建议通过 schema2code 生成, 详情: https://uniapp.dcloud.net.cn/uniCloud/schema
+// 校验规则由 schema 生成,请不要直接修改当前文件,如果需要请在uniCloud控制台修改schema
+// uniCloud: https://unicloud.dcloud.net.cn/
-const validator = {
- "create_date": {
+
+export default {
+ "user_name": {
"rules": [
{
- "format": "timestamp"
+ "format": "string"
}
]
},
- "device_uuid": {
+ "content": {
"rules": [
+ {
+ "required": true
+ },
{
"format": "string"
}
@@ -23,164 +28,11 @@ const validator = {
}
]
},
- "state": {
+ "create_date": {
"rules": [
{
- "format": "int"
- }
- ]
- },
- "type": {
- "rules": [
- {
- "format": "string"
- },
- {
- "range": [
- {
- "value": "logout",
- "text": "logout"
- },
- {
- "value": "login",
- "text": "login"
- },
- {
- "value": "register",
- "text": "register"
- },
- {
- "value": "reset-pwd",
- "text": "reset-pwd"
- },
- {
- "value": "bind-mobile",
- "text": "bind-mobile"
- },
- {
- "value": "bind-weixin",
- "text": "bind-weixin"
- },
- {
- "value": "bind-qq",
- "text": "bind-qq"
- },
- {
- "value": "bind-apple",
- "text": "bind-apple"
- },
- {
- "value": "bind-alipay",
- "text": "bind-alipay"
- }
- ]
- }
- ]
- },
- "ua": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "user_id": {
- "rules": [
- {
- "required": true
- },
- {
- "format": "string"
- }
- ]
- },
- "username": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "email": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "mobile": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "appid": {
- "rules": [
- {
- "format": "string"
+ "format": "timestamp"
}
]
}
}
-
-const enumConverter = {
- "type_valuetotext": {
- "logout": "logout",
- "login": "login",
- "register": "register",
- "reset-pwd": "reset-pwd",
- "bind-mobile": "bind-mobile",
- "bind-weixin": "bind-weixin",
- "bind-qq": "bind-qq",
- "bind-apple": "bind-apple",
- "bind-alipay": "bind-alipay"
- }
-}
-
-function filterToWhere(filter, command) {
- let where = {}
- for (let field in filter) {
- let { type, value } = filter[field]
- switch (type) {
- case "search":
- if (typeof value === 'string' && value.length) {
- where[field] = new RegExp(value)
- }
- break;
- case "select":
- if (value.length) {
- let selectValue = []
- for (let s of value) {
- selectValue.push(command.eq(s))
- }
- where[field] = command.or(selectValue)
- }
- break;
- case "range":
- if (value.length) {
- let gt = value[0]
- let lt = value[1]
- where[field] = command.and([command.gte(gt), command.lte(lt)])
- }
- break;
- case "date":
- if (value.length) {
- let [s, e] = value
- let startDate = new Date(s)
- let endDate = new Date(e)
- where[field] = command.and([command.gte(startDate), command.lte(endDate)])
- }
- break;
- case "timestamp":
- if (value.length) {
- let [startDate, endDate] = value
- where[field] = command.and([command.gte(startDate), command.lte(endDate)])
- }
- break;
- }
- }
- return where
-}
-
-export { validator, enumConverter, filterToWhere }
diff --git a/js_sdk/validator/uni-id-users.js b/js_sdk/validator/uni-id-users.js
index 5a45f5d..a8a8d4f 100644
--- a/js_sdk/validator/uni-id-users.js
+++ b/js_sdk/validator/uni-id-users.js
@@ -2,425 +2,190 @@
const validator = {
- "ali_openid": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "apple_openid": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "avatar": {
- "rules": [
- {
- "format": "string"
- }
- ],
- "title": "头像地址",
- "label": "头像地址"
- },
- "avatar_file": {
- "rules": [
- {
- "format": "file"
- }
- ],
- "title": "头像文件",
- "label": "头像文件"
- },
- "comment": {
- "rules": [
- {
- "format": "string"
- }
- ],
- "title": "备注",
- "label": "备注"
- },
- "dcloud_appid": {
- "rules": [
- {
- "format": "array"
- }
- ]
- },
- "department_id": {
- "rules": [
- {
- "format": "array"
- }
- ],
- "title": "部门",
- "label": "部门"
- },
- "email": {
- "rules": [
- {
- "format": "string"
- },
- {
- "format": "email"
- }
- ],
- "title": "邮箱",
- "label": "邮箱"
- },
- "email_confirmed": {
- "rules": [
- {
- "format": "int"
- },
- {
- "range": [
- {
- "text": "未验证",
- "value": 0
- },
- {
- "text": "已验证",
- "value": 1
- }
- ]
- }
- ],
- "title": "邮箱验证状态",
- "defaultValue": 0,
- "label": "邮箱验证状态"
- },
- "gender": {
- "rules": [
- {
- "format": "int"
- },
- {
- "range": [
- {
- "text": "未知",
- "value": 0
- },
- {
- "text": "男",
- "value": 1
- },
- {
- "text": "女",
- "value": 2
- }
- ]
- }
- ],
- "title": "性别",
- "defaultValue": 0,
- "label": "性别"
- },
- "invite_time": {
- "rules": [
- {
- "format": "timestamp"
- }
- ]
- },
- "inviter_uid": {
- "rules": [
- {
- "format": "array"
- }
- ]
- },
- "last_login_date": {
- "rules": [
- {
- "format": "timestamp"
- }
- ]
- },
- "last_login_ip": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "mobile": {
- "rules": [
- {
- "format": "string"
- },
- {
- "pattern": "^\\+?[0-9-]{3,20}$"
- }
- ],
- "title": "手机号码",
- "label": "手机号码"
- },
- "mobile_confirmed": {
- "rules": [
- {
- "format": "int"
- },
- {
- "range": [
- {
- "text": "未验证",
- "value": 0
- },
- {
- "text": "已验证",
- "value": 1
- }
- ]
- }
- ],
- "title": "手机号验证状态",
- "defaultValue": 0,
- "label": "手机号验证状态"
- },
- "my_invite_code": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "nickname": {
- "rules": [
- {
- "format": "string"
- }
- ],
- "title": "昵称",
- "label": "昵称"
- },
- "password": {
- "rules": [
- {
- "format": "password"
- }
- ],
- "title": "密码",
- "label": "密码"
- },
- "password_secret_version": {
- "rules": [
- {
- "format": "int"
- }
- ],
- "title": "passwordSecret",
- "label": "passwordSecret"
- },
- "realname_auth": {
- "rules": [
- {
- "format": "object"
- }
- ]
- },
- "register_date": {
- "rules": [
- {
- "format": "timestamp"
- }
- ]
- },
- "register_ip": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "role": {
- "rules": [
- {
- "format": "array"
- }
- ],
- "title": "角色",
- "label": "角色"
- },
- "tags": {
- "rules": [
- {
- "format": "array"
- }
- ],
- "title": "标签",
- "label": "标签"
- },
- "score": {
- "rules": [
- {
- "format": "int"
- }
- ]
- },
- "status": {
- "rules": [
- {
- "format": "int"
- },
- {
- "range": [
- {
- "text": "正常",
- "value": 0
- },
- {
- "text": "禁用",
- "value": 1
- },
- {
- "text": "审核中",
- "value": 2
- },
- {
- "text": "审核拒绝",
- "value": 3
- },
- {
- "text": "已注销",
- "value": 4
- }
- ]
- }
- ],
- "title": "用户状态",
- "defaultValue": 0,
- "label": "用户状态"
- },
- "token": {
- "rules": [
- {
- "format": "array"
- }
- ]
- },
- "username": {
- "rules": [
- {
- "format": "string"
- }
- ],
- "title": "用户名",
- "label": "用户名"
- },
- "wx_openid": {
- "rules": [
- {
- "format": "object"
- }
- ]
- },
- "wx_unionid": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "qq_openid": {
- "rules": [
- {
- "format": "object"
- }
- ]
- },
- "qq_unionid": {
- "rules": [
- {
- "format": "string"
- }
- ]
- },
- "third_party": {
- "rules": [
- {
- "format": "object"
- }
- ]
- },
- "identities": {
- "rules": [
- {
- "format": "array"
- }
- ]
- }
+ "username": {
+ "rules": [{
+ "required": true,
+ "errorMessage": '请输入用户名',
+ },
+ {
+ "minLength": 3,
+ "maxLength": 32,
+ "errorMessage": '用户名长度在 {minLength} 到 {maxLength} 个字符',
+ },
+ {
+ validateFunction: function(rule, value, data, callback) {
+ // console.log(value);
+ if (/^1\d{10}$/.test(value) || /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) {
+ callback('用户名不能是:手机号或邮箱')
+ };
+ if (/^\d+$/.test(value)) {
+ callback('用户名不能为纯数字')
+ };
+ if(/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(value)){
+ callback('用户名不能包含中文')
+ }
+ return true
+ }
+ }
+ ],
+ "label": "用户名"
+ },
+ "nickname": {
+ "rules": [{
+ minLength: 3,
+ maxLength: 32,
+ errorMessage: '昵称长度在 {minLength} 到 {maxLength} 个字符',
+ },
+ {
+ validateFunction: function(rule, value, data, callback) {
+ // console.log(value);
+ if (/^1\d{10}$/.test(value) || /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) {
+ callback('昵称不能是:手机号或邮箱')
+ };
+ if (/^\d+$/.test(value)) {
+ callback('昵称不能为纯数字')
+ };
+ // if(/[\u4E00-\u9FA5\uF900-\uFA2D]{1,}/.test(value)){
+ // callback('昵称不能包含中文')
+ // }
+ return true
+ }
+ }
+ ],
+ "label": "昵称"
+ },
+ "password": {
+ "rules": [{
+ "required": true,
+ },
+ {
+ "format": "password"
+ },
+ {
+ "minLength": 6
+ }
+ ],
+ "label": "密码"
+ },
+ "mobile": {
+ "rules": [{
+ "format": "string"
+ },
+ {
+ "pattern": "^\\+?[0-9-]{3,20}$"
+ }
+ ],
+ "label": "手机号码"
+ },
+ "status": {
+ "rules": [{
+ "format": "int"
+ },
+ {
+ "range": [{
+ "text": "正常",
+ "value": 0
+ },
+ {
+ "text": "禁用",
+ "value": 1
+ },
+ {
+ "text": "审核中",
+ "value": 2
+ },
+ {
+ "text": "审核拒绝",
+ "value": 3
+ }
+ ]
+ }
+ ],
+ "defaultValue": 0,
+ "label": "用户状态"
+ },
+ "email": {
+ "rules": [{
+ "format": "string"
+ },
+ {
+ "format": "email"
+ }
+ ],
+ "label": "邮箱"
+ },
+ "role": {
+ "rules": [{
+ "format": "array"
+ }],
+ "label": "角色"
+ },
+ "last_login_date": {
+ "rules": [{
+ "format": "timestamp"
+ }]
+ }
}
const enumConverter = {
- "email_confirmed_valuetotext": {
- "0": "未验证",
- "1": "已验证"
- },
- "gender_valuetotext": {
- "0": "未知",
- "1": "男",
- "2": "女"
- },
- "mobile_confirmed_valuetotext": {
- "0": "未验证",
- "1": "已验证"
- },
- "status_valuetotext": {
- "0": "正常",
- "1": "禁用",
- "2": "审核中",
- "3": "审核拒绝",
- "4": "已注销"
- }
+ "status_valuetotext": {
+ "0": "正常",
+ "1": "禁用",
+ "2": "审核中",
+ "3": "审核拒绝"
+ }
}
function filterToWhere(filter, command) {
- let where = {}
- for (let field in filter) {
- let { type, value } = filter[field]
- switch (type) {
- case "search":
- if (typeof value === 'string' && value.length) {
- where[field] = new RegExp(value)
- }
- break;
- case "select":
- if (value.length) {
- let selectValue = []
- for (let s of value) {
- selectValue.push(command.eq(s))
- }
- where[field] = command.or(selectValue)
- }
- break;
- case "range":
- if (value.length) {
- let gt = value[0]
- let lt = value[1]
- where[field] = command.and([command.gte(gt), command.lte(lt)])
- }
- break;
- case "date":
- if (value.length) {
- let [s, e] = value
- let startDate = new Date(s)
- let endDate = new Date(e)
- where[field] = command.and([command.gte(startDate), command.lte(endDate)])
- }
- break;
- case "timestamp":
- if (value.length) {
- let [startDate, endDate] = value
- where[field] = command.and([command.gte(startDate), command.lte(endDate)])
- }
- break;
- }
- }
- return where
+ let where = {}
+ for (let field in filter) {
+ let {
+ type,
+ value
+ } = filter[field]
+ switch (type) {
+ case "search":
+ if (typeof value === 'string' && value.length) {
+ where[field] = new RegExp(value)
+ }
+ break;
+ case "select":
+ if (value.length) {
+ let selectValue = []
+ for (let s of value) {
+ selectValue.push(command.eq(s))
+ }
+ where[field] = command.or(selectValue)
+ }
+ break;
+ case "range":
+ if (value.length) {
+ let gt = value[0]
+ let lt = value[1]
+ where[field] = command.and([command.gte(gt), command.lte(lt)])
+ }
+ break;
+ case "date":
+ if (value.length) {
+ let [s, e] = value
+ let startDate = new Date(s)
+ let endDate = new Date(e)
+ where[field] = command.and([command.gte(startDate), command.lte(endDate)])
+ }
+ break;
+ case "timestamp":
+ if (value.length) {
+ let [startDate, endDate] = value
+ where[field] = command.and([command.gte(startDate), command.lte(endDate)])
+ }
+ break;
+ }
+ }
+ return where
}
-export { validator, enumConverter, filterToWhere }
+export {
+ validator,
+ enumConverter,
+ filterToWhere
+}
diff --git a/package.json b/package.json
index 61a4c15..75b6c81 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "uni-admin 基础框架(原名 uniCloud admin)",
"id": "uni-template-admin",
"displayName": "uni-admin 基础框架",
- "version": "2.4.25",
+ "version": "2.5.1",
"description": "基于uni-app & uniCloud的后台管理项目模板(管理后台开发必备神器)",
"main": "main.js",
"scripts": {
diff --git a/pages/system/menu/originalMenuList.json b/pages/system/menu/originalMenuList.json
index 11a66fa..a85e72a 100644
--- a/pages/system/menu/originalMenuList.json
+++ b/pages/system/menu/originalMenuList.json
@@ -373,7 +373,7 @@
"permission": [],
"enable": true,
"menu_id": "uni-stat-error-js",
- "name": "js报错",
+ "name": "代码错误",
"icon": "",
"url": "/pages/uni-stat/error/js/js",
"sort": 2171,
diff --git a/pages/uni-stat/device/comparison/comparison.vue b/pages/uni-stat/device/comparison/comparison.vue
index 80dd338..23f58e4 100644
--- a/pages/uni-stat/device/comparison/comparison.vue
+++ b/pages/uni-stat/device/comparison/comparison.vue
@@ -21,9 +21,11 @@
-
- {{chartsData[index].title}}
-
+
+ {{chartsData[index].title}}
+
+
+
@@ -47,6 +49,33 @@
export default {
data() {
return {
+ eopts:{
+ // color: ["#91CB74","#1890FF","#FAC858","#EE6666","#73C0DE","#3CA272","#FC8452","#9A60B4","#ea7ccc"],
+ grid:{
+ left: 100,
+ right: 100,
+ bottom:50
+ },
+ xAxis:{
+ boundaryGap: true,
+ axisTick:{
+ alignWithLabel:true,
+ interval:0
+ },
+ axisLabel :{
+ interval:0,
+ rotate:-30,
+ align:'left'
+ }
+
+ },
+ extra: {
+ column: {
+ type:'group',
+ width: 120,
+ }
+ }
+ },
query: {
dimension: "day",
appid: '',
@@ -165,6 +194,7 @@
if (type === 'day') {
options.unshift({
+ type:"",
field: `day_total_devices`,
title: `总设备数对比`,
series: [{
@@ -176,22 +206,28 @@
this[goal] = options
const platformsData = res.result.data
const platforms = {}
+ let categories = []
platformsData.forEach(p => {
platforms[p._id] = p.name
+ categories.push(p.name)
})
for (const chart of this[goal]) {
- const pie = chart.series[0].data
+ let pie = chart.series[0].data
+ chart.categories = categories
const p = JSON.parse(JSON.stringify(platforms))
+ let total = 0
+ let tableList = []
for (const item of data) {
for (const key in item) {
if (chart.field === key) {
const id = item.platform_id
const slice = {
name: p[id],
- value: item[key]
+ value: item[key],
}
- pie.push(slice)
+ total += item[key]
+ tableList.push(slice)
delete p[id]
}
}
@@ -201,8 +237,18 @@
name: p[key],
value: 0
}
- pie.push(slice)
+ tableList.push(slice)
}
+ // 计算总数
+ tableList.map(item=>{
+ item.total = total
+ return item
+ })
+
+ categories.forEach(v=>{
+ const item = tableList.find(i=>i.name === v)
+ chart.series[0].data.push(item)
+ })
}
})
}
@@ -217,4 +263,9 @@
padding: 10px;
height: 420px;
}
+
+ .charts-box {
+ display: flex;
+ flex-direction: column;
+ }
diff --git a/pages/uni-stat/device/overview/overview.vue b/pages/uni-stat/device/overview/overview.vue
index 7881d39..6009c98 100644
--- a/pages/uni-stat/device/overview/overview.vue
+++ b/pages/uni-stat/device/overview/overview.vue
@@ -16,7 +16,7 @@
-
+
diff --git a/pages/uni-stat/pay-order/list/list.vue b/pages/uni-stat/pay-order/list/list.vue
index 1178504..8911f77 100644
--- a/pages/uni-stat/pay-order/list/list.vue
+++ b/pages/uni-stat/pay-order/list/list.vue
@@ -16,6 +16,9 @@
+
+
+