增加app模板和代码生成
@@ -8,6 +8,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "docs"
|
"path": "docs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "x_admin_app"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -42,12 +42,14 @@
|
|||||||
|
|
||||||
<uv-back-top :scroll-top="scrollTop"></uv-back-top>
|
<uv-back-top :scroll-top="scrollTop"></uv-back-top>
|
||||||
|
|
||||||
|
<uv-empty v-if="pager.loading =='nomore'&&pager.lists.length == 0" marginTop="150" mode="data"></uv-empty>
|
||||||
<uv-loading-page
|
<uv-loading-page
|
||||||
:loading="pager.pageNo == 1 && pager.loading == 'loading'"
|
:loading="pager.pageNo == 1 && pager.loading == 'loading'"
|
||||||
loading-text="加载中..."
|
loading-text="加载中..."
|
||||||
font-size="24rpx"
|
font-size="24rpx"
|
||||||
></uv-loading-page>
|
></uv-loading-page>
|
||||||
<uv-load-more
|
<uv-load-more
|
||||||
|
v-if="pager.lists.length > 0"
|
||||||
:status="pager.loading"
|
:status="pager.loading"
|
||||||
:loading-text="pager.loadingText"
|
:loading-text="pager.loadingText"
|
||||||
:loadmore-text="pager.loadmoreText"
|
:loadmore-text="pager.loadmoreText"
|
||||||
|
@@ -0,0 +1,34 @@
|
|||||||
|
// 请将pages里的数据手动合并到根目录下pages.json中
|
||||||
|
{
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/{{{ .ModuleName }}}/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "{{{.FunctionName}}}",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"onReachBottomDistance": 100,
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/{{{ .ModuleName }}}/details",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "{{{.FunctionName}}}详情",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/{{{ .ModuleName }}}/edit",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "编辑{{{.FunctionName}}}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/{{{ .ModuleName }}}/search",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "搜索{{{.FunctionName}}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@@ -8,7 +8,9 @@
|
|||||||
<x-date-range v-model:startTime="form.{{{ (toCamelCase .GoField) }}}Start"
|
<x-date-range v-model:startTime="form.{{{ (toCamelCase .GoField) }}}Start"
|
||||||
v-model:endTime="form.{{{ (toCamelCase .GoField) }}}End"></x-date-range>
|
v-model:endTime="form.{{{ (toCamelCase .GoField) }}}End"></x-date-range>
|
||||||
{{{- else if or (eq .HtmlType "select") (eq .HtmlType "radio") }}}
|
{{{- else if or (eq .HtmlType "select") (eq .HtmlType "radio") }}}
|
||||||
|
{{{- if ne .DictType "" }}}
|
||||||
<x-picker v-model="form.{{{ (toCamelCase .GoField) }}}" valueKey="value" labelKey="name" :columns="dictData.{{{ .DictType }}}"></x-picker>
|
<x-picker v-model="form.{{{ (toCamelCase .GoField) }}}" valueKey="value" labelKey="name" :columns="dictData.{{{ .DictType }}}"></x-picker>
|
||||||
|
{{{- end }}}
|
||||||
{{{- else if eq .HtmlType "input" }}}
|
{{{- else if eq .HtmlType "input" }}}
|
||||||
<uv-input v-model="form.{{{ (toCamelCase .GoField) }}}"> </uv-input>
|
<uv-input v-model="form.{{{ (toCamelCase .GoField) }}}"> </uv-input>
|
||||||
{{{- end }}}
|
{{{- end }}}
|
||||||
@@ -68,7 +70,7 @@ const { dictData } = useDictData([{{{- range .DictFields }}}'{{{ . }}}'{{{- if n
|
|||||||
return toast("请输入查询条件");
|
return toast("请输入查询条件");
|
||||||
}
|
}
|
||||||
|
|
||||||
toPath("/pages/equipment/equipment", search);
|
toPath("/pages/{{{ .ModuleName }}}/index", search);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -170,6 +170,7 @@ func (tu templateUtil) GetTemplatePaths(genTpl string) []string {
|
|||||||
"uniapp/index.vue.tpl",
|
"uniapp/index.vue.tpl",
|
||||||
"uniapp/details.vue.tpl",
|
"uniapp/details.vue.tpl",
|
||||||
"uniapp/search.vue.tpl",
|
"uniapp/search.vue.tpl",
|
||||||
|
"uniapp/pages.json.tpl",
|
||||||
}
|
}
|
||||||
if genTpl == GenConstants.TplCrud {
|
if genTpl == GenConstants.TplCrud {
|
||||||
tplPaths = append(tplPaths, "vue/index.vue.tpl")
|
tplPaths = append(tplPaths, "vue/index.vue.tpl")
|
||||||
@@ -223,11 +224,12 @@ func (tu templateUtil) GetFilePaths(tplCodeMap map[string]string, ModuleName str
|
|||||||
"vue/index.vue.tpl": strings.Join([]string{"admin/src/views/", ModuleName, "/index.vue"}, ""), // "admin/src/views/%s/index.vue",
|
"vue/index.vue.tpl": strings.Join([]string{"admin/src/views/", ModuleName, "/index.vue"}, ""), // "admin/src/views/%s/index.vue",
|
||||||
"vue/index-tree.vue.tpl": strings.Join([]string{"admin/src/views/", ModuleName, "/index-tree.vue"}, ""), // "admin/src/views/%s/index-tree.vue",
|
"vue/index-tree.vue.tpl": strings.Join([]string{"admin/src/views/", ModuleName, "/index-tree.vue"}, ""), // "admin/src/views/%s/index-tree.vue",
|
||||||
|
|
||||||
"uniapp/api.ts.tpl": strings.Join([]string{"uniapp/api/", ModuleName, ".ts"}, ""),
|
"uniapp/api.ts.tpl": strings.Join([]string{"x_admin_app/api/", ModuleName, ".ts"}, ""),
|
||||||
"uniapp/edit.vue.tpl": strings.Join([]string{"uniapp/pages/", ModuleName, "/edit.vue"}, ""),
|
"uniapp/edit.vue.tpl": strings.Join([]string{"x_admin_app/pages/", ModuleName, "/edit.vue"}, ""),
|
||||||
"uniapp/index.vue.tpl": strings.Join([]string{"uniapp/pages/", ModuleName, "/index.vue"}, ""),
|
"uniapp/index.vue.tpl": strings.Join([]string{"x_admin_app/pages/", ModuleName, "/index.vue"}, ""),
|
||||||
"uniapp/search.vue.tpl": strings.Join([]string{"uniapp/pages/", ModuleName, "/search.vue"}, ""),
|
"uniapp/search.vue.tpl": strings.Join([]string{"x_admin_app/pages/", ModuleName, "/search.vue"}, ""),
|
||||||
"uniapp/details.vue.tpl": strings.Join([]string{"uniapp/pages/", ModuleName, "/details.vue"}, ""),
|
"uniapp/details.vue.tpl": strings.Join([]string{"x_admin_app/pages/", ModuleName, "/details.vue"}, ""),
|
||||||
|
"uniapp/pages.json.tpl": strings.Join([]string{"x_admin_app/pages/", ModuleName, "/pages.json"}, ""),
|
||||||
}
|
}
|
||||||
filePath := make(map[string]string)
|
filePath := make(map[string]string)
|
||||||
for tplPath, tplCode := range tplCodeMap {
|
for tplPath, tplCode := range tplCodeMap {
|
||||||
|
@@ -4,9 +4,13 @@ import "x_admin/core"
|
|||||||
|
|
||||||
//MonitorProjectListReq 错误项目列表参数
|
//MonitorProjectListReq 错误项目列表参数
|
||||||
type MonitorProjectListReq struct {
|
type MonitorProjectListReq struct {
|
||||||
ProjectKey string `form:"projectKey"` // 项目uuid
|
ProjectKey string `form:"projectKey"` // 项目uuid
|
||||||
ProjectName string `form:"projectName"` // 项目名称
|
ProjectName string `form:"projectName"` // 项目名称
|
||||||
ProjectType string `form:"projectType"` // 项目类型go java web node php 等
|
ProjectType string `form:"projectType"` // 项目类型go java web node php 等
|
||||||
|
CreateTimeStart string `form:"createTimeStart"` // 开始创建时间
|
||||||
|
CreateTimeEnd string `form:"createTimeEnd"` // 结束创建时间
|
||||||
|
UpdateTimeStart string `form:"updateTimeStart"` // 开始更新时间
|
||||||
|
UpdateTimeEnd string `form:"updateTimeEnd"` // 结束更新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
//MonitorProjectDetailReq 错误项目详情参数
|
//MonitorProjectDetailReq 错误项目详情参数
|
||||||
|
@@ -49,6 +49,18 @@ func (service monitorProjectService) List(page request.PageReq, listReq MonitorP
|
|||||||
if listReq.ProjectType != "" {
|
if listReq.ProjectType != "" {
|
||||||
dbModel = dbModel.Where("project_type = ?", listReq.ProjectType)
|
dbModel = dbModel.Where("project_type = ?", listReq.ProjectType)
|
||||||
}
|
}
|
||||||
|
if listReq.CreateTimeStart != "" {
|
||||||
|
dbModel = dbModel.Where("create_time >= ?", listReq.CreateTimeStart)
|
||||||
|
}
|
||||||
|
if listReq.CreateTimeEnd != "" {
|
||||||
|
dbModel = dbModel.Where("create_time <= ?", listReq.CreateTimeEnd)
|
||||||
|
}
|
||||||
|
if listReq.UpdateTimeStart != "" {
|
||||||
|
dbModel = dbModel.Where("update_time >= ?", listReq.UpdateTimeStart)
|
||||||
|
}
|
||||||
|
if listReq.UpdateTimeEnd != "" {
|
||||||
|
dbModel = dbModel.Where("update_time <= ?", listReq.UpdateTimeEnd)
|
||||||
|
}
|
||||||
dbModel = dbModel.Where("is_delete = ?", 0)
|
dbModel = dbModel.Where("is_delete = ?", 0)
|
||||||
// 总数
|
// 总数
|
||||||
var count int64
|
var count int64
|
||||||
|
25
x_admin_app/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
package-lock.json
|
||||||
|
tests/**/coverage/
|
||||||
|
pnpm-lock.yaml
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
stats.html
|
||||||
|
.vscode/*
|
||||||
|
!/.vscode/settings.json
|
||||||
|
|
||||||
|
release
|
||||||
|
dist-electron
|
||||||
|
unpackage/*
|
||||||
|
!unpackage/res
|
||||||
|
HBuilderConfigTemp.json
|
20
x_admin_app/.hbuilderx/launch.json
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"version" : "1.0",
|
||||||
|
"configurations" : [
|
||||||
|
{
|
||||||
|
"playground" : "custom",
|
||||||
|
"type" : "uni-app:app-android"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"app-plus" :
|
||||||
|
{
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"mp-weixin" :
|
||||||
|
{
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"type" : "uniCloud"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
x_admin_app/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"dcloudio",
|
||||||
|
"fota",
|
||||||
|
"IMEI",
|
||||||
|
"loadmore",
|
||||||
|
"nomore",
|
||||||
|
"pinia",
|
||||||
|
"realname"
|
||||||
|
]
|
||||||
|
}
|
62
x_admin_app/App.vue
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
<script>
|
||||||
|
import {
|
||||||
|
useUserStore
|
||||||
|
} from "@/stores/user";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
onLaunch: function() {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
userStore
|
||||||
|
.getInfo()
|
||||||
|
.then((res) => {
|
||||||
|
console.log("userInfo", res);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: "/pages/login/login",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onShow: function() {},
|
||||||
|
onHide: function() {},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#app {
|
||||||
|
/* 解决app上uv-sticky浮动的问题 ,估计又修复了先注释掉*/
|
||||||
|
/* height: auto; */
|
||||||
|
}
|
||||||
|
button:after {
|
||||||
|
border: 0 !important;
|
||||||
|
}
|
||||||
|
/*每个页面公共css */
|
||||||
|
.h100 {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex_1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search {
|
||||||
|
padding: 5rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
52
x_admin_app/HBuilderConfig.json
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
//项目名字或项目绝对路径
|
||||||
|
"project": "x_admin_app",
|
||||||
|
//打包平台 默认值android 值有"android","ios" 如果要打多个逗号隔开打包平台
|
||||||
|
"platform": "android",
|
||||||
|
//是否使用自定义基座 默认值false true自定义基座 false自定义证书
|
||||||
|
"iscustom": false,
|
||||||
|
//打包方式是否为安心打包默认值false,true安心打包,false传统打包
|
||||||
|
"safemode": true,
|
||||||
|
//android打包参数
|
||||||
|
"android": {
|
||||||
|
//安卓包名
|
||||||
|
"packagename": "uni.UNIFB29F21",
|
||||||
|
//安卓打包类型 默认值0 0 使用自有证书 1 使用公共证书 2 使用老版证书
|
||||||
|
"androidpacktype": "3",
|
||||||
|
//安卓使用自有证书自有打包证书参数
|
||||||
|
//安卓打包证书别名,自有证书打包填写的参数
|
||||||
|
"certalias": "",
|
||||||
|
//安卓打包证书文件路径,自有证书打包填写的参数
|
||||||
|
"certfile": "",
|
||||||
|
//安卓打包证书密码,自有证书打包填写的参数
|
||||||
|
"certpassword": "",
|
||||||
|
//安卓平台要打的渠道包 取值有"google","yyb","360","huawei","xiaomi","oppo","vivo",如果要打多个逗号隔开
|
||||||
|
"channels": ""
|
||||||
|
},
|
||||||
|
//ios打包参数
|
||||||
|
"ios": {
|
||||||
|
//ios appid
|
||||||
|
"bundle": "uni.UNIFB29F21",
|
||||||
|
//ios打包支持的设备类型 默认值iPhone 值有"iPhone","iPad" 如果要打多个逗号隔开打包平台
|
||||||
|
"supporteddevice": "iPhone,iPad",
|
||||||
|
//iOS打包是否打越狱包,只有值为true时打越狱包,false打正式包
|
||||||
|
"isprisonbreak": false,
|
||||||
|
|
||||||
|
//iOS使用自定义证书打包的profile文件路径
|
||||||
|
"profile": "",
|
||||||
|
//iOS使用自定义证书打包的p12文件路径
|
||||||
|
"certfile": "",
|
||||||
|
//iOS使用自定义证书打包的证书密码
|
||||||
|
"certpassword": ""
|
||||||
|
},
|
||||||
|
//是否混淆 true混淆 false关闭
|
||||||
|
"isconfusion": false,
|
||||||
|
//开屏广告 true打开 false关闭
|
||||||
|
"splashads": false,
|
||||||
|
//悬浮红包广告true打开 false关闭
|
||||||
|
"rpads": false,
|
||||||
|
//push广告 true打开 false关闭
|
||||||
|
"pushads": false,
|
||||||
|
//加入换量联盟 true加入 false不加入
|
||||||
|
"exchange": false
|
||||||
|
}
|
3
x_admin_app/androidPrivacy.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"prompt" : "template"
|
||||||
|
}
|
57
x_admin_app/api/monitor_project.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import { request } from '@/utils/request'
|
||||||
|
|
||||||
|
|
||||||
|
// 监控项目列表
|
||||||
|
export function monitor_project_list(params?: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor_project/list',
|
||||||
|
method: 'GET',
|
||||||
|
data: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 监控项目列表-所有
|
||||||
|
export function monitor_project_list_all(params?: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor_project/listAll',
|
||||||
|
method: 'GET',
|
||||||
|
data: params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控项目详情
|
||||||
|
export function monitor_project_detail(id: number | string) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor_project/detail',
|
||||||
|
method: 'GET',
|
||||||
|
data: { id }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控项目新增
|
||||||
|
export function monitor_project_add(data: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor_project/add',
|
||||||
|
method: "POST",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控项目编辑
|
||||||
|
export function monitor_project_edit(data: Record<string, any>) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor_project/edit',
|
||||||
|
method: "POST",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控项目删除
|
||||||
|
export function monitor_project_delete(id: number | string) {
|
||||||
|
return request({
|
||||||
|
url: '/monitor_project/del',
|
||||||
|
method: "POST",
|
||||||
|
data:{
|
||||||
|
id
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
29
x_admin_app/api/user.js
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import {request} from '@/utils/request';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function login(data) {
|
||||||
|
return request({
|
||||||
|
url: '/system/login',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getInfo(token) {
|
||||||
|
return request({
|
||||||
|
url: '/system/admin/self',
|
||||||
|
method: 'GET',
|
||||||
|
data: {
|
||||||
|
token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logout() {
|
||||||
|
return request({
|
||||||
|
url: '/system/logout',
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
39
x_admin_app/components/LoadMore/LoadMore.vue
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<uv-load-more
|
||||||
|
:status="props.status"
|
||||||
|
:loading-text="props.loadingText"
|
||||||
|
:loadmore-text="props.loadmoreText"
|
||||||
|
:nomore-text="props.nomoreText"
|
||||||
|
@loadmore="loadmore"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { onReady, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
import { ref, defineEmits,defineModel } from "vue";
|
||||||
|
|
||||||
|
var pager = defineModel();
|
||||||
|
|
||||||
|
const emits = defineEmits(["loadmore"]);
|
||||||
|
const props = defineProps({
|
||||||
|
status: {
|
||||||
|
type: String,
|
||||||
|
default: "loadmore",
|
||||||
|
},
|
||||||
|
loadingText: {
|
||||||
|
type: String,
|
||||||
|
default: "努力加载中",
|
||||||
|
},
|
||||||
|
loadmoreText: {
|
||||||
|
type: String,
|
||||||
|
default: "轻轻上拉",
|
||||||
|
},
|
||||||
|
nomoreText: {
|
||||||
|
type: String,
|
||||||
|
default: "实在没有了",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
function loadmore(e) {
|
||||||
|
emits("loadmore", e);
|
||||||
|
}
|
||||||
|
</script>
|
11
x_admin_app/components/verifition/utils/ase.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
/**
|
||||||
|
* @word 要加密的内容
|
||||||
|
* @keyWord String 服务器随机返回的关键字
|
||||||
|
* */
|
||||||
|
export function aesEncrypt(word,keyWord="XwKsGlMcdPMEhR1B"){
|
||||||
|
var key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||||
|
var srcs = CryptoJS.enc.Utf8.parse(word);
|
||||||
|
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
|
||||||
|
return encrypted.toString();
|
||||||
|
}
|
20
x_admin_app/components/verifition/utils/request.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
// let baseUrl = "https://captcha.anji-plus.com/captcha-api"
|
||||||
|
import env from "@/utils/env";
|
||||||
|
let baseUrl =env.baseUrl+'/api/common';
|
||||||
|
|
||||||
|
export const myRequest = (option={})=>{
|
||||||
|
return new Promise((reslove,reject)=>{
|
||||||
|
uni.request({
|
||||||
|
url: baseUrl + option.url,
|
||||||
|
data :option.data,
|
||||||
|
method:option.method || "GET",
|
||||||
|
success: (result) => {
|
||||||
|
reslove(result)
|
||||||
|
},
|
||||||
|
fail:(error)=>{
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
489
x_admin_app/components/verifition/verify.vue
Normal file
554
x_admin_app/components/verifition/verifyPoint/verifyPoint.vue
Normal file
671
x_admin_app/components/verifition/verifySlider/verifySlider.vue
Normal file
114
x_admin_app/components/x-card/x-card.vue
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<template>
|
||||||
|
<view class="x-card" :style="{ marginBottom: bottom + 'px' }">
|
||||||
|
<view class="x-card-image" v-if="icon">
|
||||||
|
<uv-image width="100%" :src="icon" mode="widthFix"></uv-image>
|
||||||
|
</view>
|
||||||
|
<view class="x-card-title" v-if="title">
|
||||||
|
<text>{{ title }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="x-card-content" v-if="content">
|
||||||
|
<slot name="contentSlot">
|
||||||
|
<text>{{ content }}</text>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view class="x-card-bottom" v-if="btnText">
|
||||||
|
<slot name="btnSlot">
|
||||||
|
<button :open-type="openType" @click="btnClick">{{ btnText }}</button>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
default: "",
|
||||||
|
type: [String, Number],
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
default: "",
|
||||||
|
type: [String, Number],
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
default: "",
|
||||||
|
type: [String, Number],
|
||||||
|
},
|
||||||
|
btnText: {
|
||||||
|
default: "",
|
||||||
|
type: [String, Number],
|
||||||
|
},
|
||||||
|
openType: {
|
||||||
|
default: "",
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
bottom: {
|
||||||
|
default: "0",
|
||||||
|
type: [String, Number],
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
default: "",
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
methods: {
|
||||||
|
btnClick() {
|
||||||
|
if (this.url) {
|
||||||
|
this.$toPath(this.url, {
|
||||||
|
// id: item.id
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$emit("btnClick");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.x-card {
|
||||||
|
background-color: white;
|
||||||
|
margin:0 10rpx;
|
||||||
|
padding: 10px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
// margin-bottom: 10px;
|
||||||
|
|
||||||
|
.x-card-image {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
.x-card-title {
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 32rpx;
|
||||||
|
// color: #aaaaaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-card-content {
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 26rpx;
|
||||||
|
// color: #aaaaaa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-card-bottom {
|
||||||
|
padding-top: 20rpx;
|
||||||
|
button {
|
||||||
|
margin: 0;
|
||||||
|
padding: 16rpx 16rpx;
|
||||||
|
line-height: 1;
|
||||||
|
border: 0;
|
||||||
|
font-size: 24rpx;
|
||||||
|
background-color: rgba(111, 148, 205, 1);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
46
x_admin_app/components/x-date-range/x-date-range.vue
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<uv-input
|
||||||
|
:modelValue="title"
|
||||||
|
:readonly="true"
|
||||||
|
placeholder="请选择时间"
|
||||||
|
@click="calendarsRef.open()"
|
||||||
|
>
|
||||||
|
</uv-input>
|
||||||
|
<uv-calendars
|
||||||
|
ref="calendarsRef"
|
||||||
|
mode="range"
|
||||||
|
:date="[props.startTime, props.endTime]"
|
||||||
|
@confirm="Confirm"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from "vue";
|
||||||
|
|
||||||
|
const emit = defineEmits(["update:startTime", "update:endTime"]);
|
||||||
|
const props = defineProps({
|
||||||
|
startTime: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
endTime: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let calendarsRef = ref(null);
|
||||||
|
function Confirm(e) {
|
||||||
|
console.log(e);
|
||||||
|
emit("update:startTime", e.range.before);
|
||||||
|
emit("update:endTime", e.range.after);
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = computed(() => {
|
||||||
|
if (!props.startTime || !props.endTime) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return props.startTime + "-" + props.endTime;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
106
x_admin_app/components/x-list/x-list.vue
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<template >
|
||||||
|
<view class="x-list" :style="{marginBottom:bottom+'px'}">
|
||||||
|
|
||||||
|
<view class="x-list-left" v-if="icon">
|
||||||
|
<uv-image width="24px" height="24px" :src="icon" mode="widthFix"></uv-image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="x-list-content">
|
||||||
|
<view v-if="title">{{title}}</view>
|
||||||
|
<text v-if="des">{{des}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="x-list-right" v-if="btnText">
|
||||||
|
<slot name="right">
|
||||||
|
<button :open-type="openType" @click="btnClick">{{btnText}}</button>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props:{
|
||||||
|
icon:{
|
||||||
|
default:"",
|
||||||
|
type:String
|
||||||
|
},
|
||||||
|
title:{
|
||||||
|
default:"",
|
||||||
|
type:String
|
||||||
|
},
|
||||||
|
des:{
|
||||||
|
default:"",
|
||||||
|
type:String
|
||||||
|
},
|
||||||
|
btnText:{
|
||||||
|
default:"",
|
||||||
|
type:String
|
||||||
|
},
|
||||||
|
openType:{
|
||||||
|
default:"",
|
||||||
|
type:String
|
||||||
|
},
|
||||||
|
bottom:{
|
||||||
|
default:"0",
|
||||||
|
type:[String,Number]
|
||||||
|
},
|
||||||
|
url:{
|
||||||
|
default:"",
|
||||||
|
type:String
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
btnClick(){
|
||||||
|
if(this.url){
|
||||||
|
this.$toPath(this.url, {
|
||||||
|
// id: item.id
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$emit('btnClick')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.x-list {
|
||||||
|
display: flex;
|
||||||
|
// justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
padding: 10px 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
// margin-bottom: 10px;
|
||||||
|
|
||||||
|
.x-list-content {
|
||||||
|
font-size: 16px;
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 10px;
|
||||||
|
|
||||||
|
text {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #AAAAAA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.x-list-right {
|
||||||
|
button {
|
||||||
|
margin: 0;
|
||||||
|
padding: 6px 8px;
|
||||||
|
line-height: 1;
|
||||||
|
border: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
background-color: rgba(111, 148, 205, 1);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
108
x_admin_app/components/x-picker/x-picker.vue
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
<template>
|
||||||
|
<uv-input
|
||||||
|
:modelValue="selectItem?.[props.labelKey]"
|
||||||
|
placeholder="请选择"
|
||||||
|
readonly
|
||||||
|
@click="openPicker"
|
||||||
|
>
|
||||||
|
</uv-input>
|
||||||
|
|
||||||
|
<uv-picker
|
||||||
|
ref="picker"
|
||||||
|
:columns="columns"
|
||||||
|
:keyName="props.labelKey"
|
||||||
|
:defaultIndex="pickerIndex"
|
||||||
|
@confirm="handleConfirm"
|
||||||
|
></uv-picker>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
defineModel,
|
||||||
|
|
||||||
|
onMounted,
|
||||||
|
computed,
|
||||||
|
watch,
|
||||||
|
} from "vue";
|
||||||
|
const props = defineProps({
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
labelKey: {
|
||||||
|
type: String,
|
||||||
|
default: "label",
|
||||||
|
},
|
||||||
|
valueKey: {
|
||||||
|
type: String,
|
||||||
|
default: "id",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const columns = computed(() => {
|
||||||
|
return [props.columns];
|
||||||
|
});
|
||||||
|
const picker = ref(null);
|
||||||
|
|
||||||
|
const model = defineModel();
|
||||||
|
const pickerIndex = ref([0]);
|
||||||
|
|
||||||
|
const selectItem = ref({});
|
||||||
|
|
||||||
|
function openPicker() {
|
||||||
|
picker.value.open();
|
||||||
|
}
|
||||||
|
function handleConfirm(e) {
|
||||||
|
// debugger;
|
||||||
|
if (e.value[0]!==undefined) {
|
||||||
|
model.value = e.value[0][props.valueKey];
|
||||||
|
selectItem.value = e.value[0];
|
||||||
|
}else{
|
||||||
|
model.value = null;
|
||||||
|
selectItem.value = {};
|
||||||
|
console.log('handleConfirm没有数据',e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function updateSelectItem() {
|
||||||
|
console.log("updateSelectItem", model.value, props.columns);
|
||||||
|
if (!model.value) {
|
||||||
|
pickerIndex.value = [0];
|
||||||
|
selectItem.value = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(props.columns.length==0){
|
||||||
|
pickerIndex.value = [0];
|
||||||
|
selectItem.value = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let find=false
|
||||||
|
for (let index = 0; index < props.columns.length; index++) {
|
||||||
|
const item = props.columns[index];
|
||||||
|
if (model.value == item[props.valueKey]) {
|
||||||
|
selectItem.value = item;
|
||||||
|
pickerIndex.value = [index];
|
||||||
|
find=true
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!find){
|
||||||
|
selectItem.value = {};
|
||||||
|
pickerIndex.value = [0];
|
||||||
|
model.value = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
console.log("onMounted");
|
||||||
|
updateSelectItem();
|
||||||
|
});
|
||||||
|
watch(
|
||||||
|
() => [model.value, props.columns],
|
||||||
|
(newVal) => {
|
||||||
|
console.log("watch", newVal);
|
||||||
|
updateSelectItem();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
55
x_admin_app/hooks/useDictOptions.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { request } from "@/utils/request";
|
||||||
|
import { reactive, toRaw } from "vue";
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
[propName: string]: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDictOptions<T = any>(options: Options) {
|
||||||
|
const optionsData: any = reactive({});
|
||||||
|
const optionsKey = Object.keys(options);
|
||||||
|
|
||||||
|
const apiLists = optionsKey.map((key) => {
|
||||||
|
const path = options[key];
|
||||||
|
optionsData[key] = [];
|
||||||
|
return () =>request({
|
||||||
|
url: path,
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const refresh = async () => {
|
||||||
|
const res = await Promise.allSettled<Promise<any>>(
|
||||||
|
apiLists.map((api) => api())
|
||||||
|
);
|
||||||
|
console.log(res);
|
||||||
|
|
||||||
|
res.forEach((item, index) => {
|
||||||
|
const key = optionsKey[index];
|
||||||
|
if (item.status == "fulfilled") {
|
||||||
|
const data = item.value;
|
||||||
|
optionsData[key] = data.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
refresh();
|
||||||
|
return {
|
||||||
|
optionsData: optionsData as T,
|
||||||
|
refresh,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDictData<T = any>(dict: string[]) {
|
||||||
|
const options: Options = {};
|
||||||
|
for (const type of dict) {
|
||||||
|
options[type] = `/setting/dict/data/all?dictType=${type}`
|
||||||
|
}
|
||||||
|
const { optionsData } = useDictOptions<T>(options);
|
||||||
|
console.log('optionsData',optionsData);
|
||||||
|
|
||||||
|
return {
|
||||||
|
dictData: optionsData as T,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// export function useAllList<T = any>(options: Options) {}
|
106
x_admin_app/hooks/usePaging.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { reactive, toRaw } from "vue";
|
||||||
|
import { toast } from "@/utils/utils";
|
||||||
|
|
||||||
|
// 分页钩子函数
|
||||||
|
interface Options {
|
||||||
|
pageNo?: number;
|
||||||
|
pageSize?: number;
|
||||||
|
loadingText?: string;
|
||||||
|
loadmoreText?: string;
|
||||||
|
nomoreText?: string;
|
||||||
|
|
||||||
|
fetchFun: (_arg: any) => Promise<any>;
|
||||||
|
params?: Record<any, any>;
|
||||||
|
firstStatus?: string; //loadmore - 加载前,loading - 加载中,nomore - 没有数据
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePaging(options: Options) {
|
||||||
|
const {
|
||||||
|
pageNo = 1,
|
||||||
|
pageSize = 30,
|
||||||
|
loadingText = "努力加载中",
|
||||||
|
loadmoreText = "继续加载",
|
||||||
|
nomoreText = "没有数据了",
|
||||||
|
fetchFun,
|
||||||
|
params = {},
|
||||||
|
firstStatus = "loadmore",
|
||||||
|
} = options;
|
||||||
|
// 记录分页初始参数
|
||||||
|
const paramsInit: Record<any, any> = Object.assign({}, toRaw(params));
|
||||||
|
// 分页数据
|
||||||
|
const pager = reactive({
|
||||||
|
pageNo,
|
||||||
|
pageSize,
|
||||||
|
loadingText,
|
||||||
|
loadmoreText,
|
||||||
|
nomoreText,
|
||||||
|
loading: firstStatus,
|
||||||
|
count: 0,
|
||||||
|
lists: [] as any[],
|
||||||
|
});
|
||||||
|
// 请求分页接口
|
||||||
|
const getLists = () => {
|
||||||
|
pager.loading = "loading";
|
||||||
|
return fetchFun({
|
||||||
|
pageNo: pager.pageNo,
|
||||||
|
pageSize: pager.pageSize,
|
||||||
|
...params,
|
||||||
|
})
|
||||||
|
.then((res: any) => {
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
|
||||||
|
if (res.code == 200) {
|
||||||
|
pager.count = res?.data?.count;
|
||||||
|
var list = res?.data?.lists || [];
|
||||||
|
|
||||||
|
pager.lists.push(...list);
|
||||||
|
|
||||||
|
if (res?.data?.lists?.length < pager.pageSize) {
|
||||||
|
pager.loading = "nomore";
|
||||||
|
} else {
|
||||||
|
pager.loading = "loadmore";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
pager.loading = "loadmore";
|
||||||
|
}
|
||||||
|
return Promise.resolve(res);
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
toast(err.message);
|
||||||
|
pager.loading = "nomore";
|
||||||
|
return Promise.reject(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 下一页
|
||||||
|
const NextPage = () => {
|
||||||
|
if (pager.loading === "nomore") {
|
||||||
|
toast("没有数据了");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pager.pageNo += 1;
|
||||||
|
getLists();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置为第一页
|
||||||
|
const resetPage = () => {
|
||||||
|
pager.pageNo = 1;
|
||||||
|
pager.lists = [];
|
||||||
|
getLists();
|
||||||
|
};
|
||||||
|
// 重置参数
|
||||||
|
const resetParams = () => {
|
||||||
|
Object.keys(paramsInit).forEach((item) => {
|
||||||
|
params[item] = paramsInit[item];
|
||||||
|
});
|
||||||
|
pager.lists = [];
|
||||||
|
getLists();
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
pager,
|
||||||
|
getLists,
|
||||||
|
NextPage,
|
||||||
|
resetParams,
|
||||||
|
resetPage,
|
||||||
|
};
|
||||||
|
}
|
7
x_admin_app/images.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
declare module '*.svg'
|
||||||
|
declare module '*.png'
|
||||||
|
declare module '*.jpg'
|
||||||
|
declare module '*.jpeg'
|
||||||
|
declare module '*.gif'
|
||||||
|
declare module '*.bmp'
|
||||||
|
declare module '*.tiff'
|
20
x_admin_app/index.html
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-cn">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
|
CSS.supports('top: constant(a)'))
|
||||||
|
document.write(
|
||||||
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
|
</script>
|
||||||
|
<title></title>
|
||||||
|
<!--preload-links-->
|
||||||
|
<!--app-context-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--app-html--></div>
|
||||||
|
<script type="module" src="/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
x_admin_app/main.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import App from "./App";
|
||||||
|
import { createSSRApp } from "vue";
|
||||||
|
|
||||||
|
import { installMethods } from "@/methods/index";
|
||||||
|
import * as Pinia from "pinia";
|
||||||
|
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App);
|
||||||
|
|
||||||
|
app.use(Pinia.createPinia());
|
||||||
|
|
||||||
|
installMethods(app);
|
||||||
|
|
||||||
|
return {
|
||||||
|
app,
|
||||||
|
Pinia, // 此处必须将 Pinia 返回
|
||||||
|
};
|
||||||
|
}
|
132
x_admin_app/manifest.json
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"name": "x_admin_app",
|
||||||
|
"appid": "__UNI__FB29F21",
|
||||||
|
"description": "",
|
||||||
|
"versionName": "1.0.2",
|
||||||
|
"versionCode": 102,
|
||||||
|
"transformPx": false,
|
||||||
|
"app-plus": {
|
||||||
|
"compatible": {
|
||||||
|
"ignoreVersion": true
|
||||||
|
},
|
||||||
|
"usingComponents": true,
|
||||||
|
"nvueStyleCompiler": "uni-app",
|
||||||
|
"compilerVersion": 3,
|
||||||
|
"splashscreen": {
|
||||||
|
"alwaysShowBeforeRender": true,
|
||||||
|
"waiting": true,
|
||||||
|
"autoclose": true,
|
||||||
|
"delay": 0
|
||||||
|
},
|
||||||
|
"modules": {},
|
||||||
|
"distribute": {
|
||||||
|
"android": {
|
||||||
|
"permissions": [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
|
],
|
||||||
|
"minSdkVersion": 26,
|
||||||
|
"schemes": "x_admin",
|
||||||
|
"targetSdkVersion": 30
|
||||||
|
},
|
||||||
|
"ios": {
|
||||||
|
"urltypes": "x_admin",
|
||||||
|
"dSYMs": false
|
||||||
|
},
|
||||||
|
"sdkConfigs": {
|
||||||
|
"ad": {}
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"android": {
|
||||||
|
"hdpi": "unpackage/res/icons/72x72.png",
|
||||||
|
"xhdpi": "unpackage/res/icons/96x96.png",
|
||||||
|
"xxhdpi": "unpackage/res/icons/144x144.png",
|
||||||
|
"xxxhdpi": "unpackage/res/icons/192x192.png"
|
||||||
|
},
|
||||||
|
"ios": {
|
||||||
|
"appstore": "unpackage/res/icons/1024x1024.png",
|
||||||
|
"ipad": {
|
||||||
|
"app": "unpackage/res/icons/76x76.png",
|
||||||
|
"app@2x": "unpackage/res/icons/152x152.png",
|
||||||
|
"notification": "unpackage/res/icons/20x20.png",
|
||||||
|
"notification@2x": "unpackage/res/icons/40x40.png",
|
||||||
|
"proapp@2x": "unpackage/res/icons/167x167.png",
|
||||||
|
"settings": "unpackage/res/icons/29x29.png",
|
||||||
|
"settings@2x": "unpackage/res/icons/58x58.png",
|
||||||
|
"spotlight": "unpackage/res/icons/40x40.png",
|
||||||
|
"spotlight@2x": "unpackage/res/icons/80x80.png"
|
||||||
|
},
|
||||||
|
"iphone": {
|
||||||
|
"app@2x": "unpackage/res/icons/120x120.png",
|
||||||
|
"app@3x": "unpackage/res/icons/180x180.png",
|
||||||
|
"notification@2x": "unpackage/res/icons/40x40.png",
|
||||||
|
"notification@3x": "unpackage/res/icons/60x60.png",
|
||||||
|
"settings@2x": "unpackage/res/icons/58x58.png",
|
||||||
|
"settings@3x": "unpackage/res/icons/87x87.png",
|
||||||
|
"spotlight@2x": "unpackage/res/icons/80x80.png",
|
||||||
|
"spotlight@3x": "unpackage/res/icons/120x120.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"splashscreen": {
|
||||||
|
"useOriginalMsgbox": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nvueLaunchMode": "",
|
||||||
|
"nativePlugins": {
|
||||||
|
"usb-serial-for-uniapp": {
|
||||||
|
"__plugin_info__": {
|
||||||
|
"name": "usb-serial-for-uniapp",
|
||||||
|
"description": "uniapp的USB串口通信插件,驱动基于开源项目usb-serial-for-android,无需ROOT,支持OTG USB串口、CP210X、CH34X等",
|
||||||
|
"platforms": "Android",
|
||||||
|
"url": "https://ext.dcloud.net.cn/plugin?id=13935",
|
||||||
|
"android_package_name": "uni.UNIFB29F21",
|
||||||
|
"ios_bundle_id": "",
|
||||||
|
"isCloud": true,
|
||||||
|
"bought": 1,
|
||||||
|
"pid": "13935",
|
||||||
|
"parameters": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"quickapp": {},
|
||||||
|
"mp-weixin": {
|
||||||
|
"appid": "",
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": false
|
||||||
|
},
|
||||||
|
"usingComponents": true,
|
||||||
|
"unipush": {
|
||||||
|
"enable": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mp-alipay": {
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"mp-baidu": {
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"mp-toutiao": {
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"uniStatistics": {
|
||||||
|
"enable": false
|
||||||
|
},
|
||||||
|
"vueVersion": "3",
|
||||||
|
"locale": "zh-Hans",
|
||||||
|
"fallbackLocale": "zh-Hans"
|
||||||
|
}
|
27
x_admin_app/methods/index.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { perms } from "@/utils/perms.js";
|
||||||
|
import { toPath } from "@/utils/utils.js";
|
||||||
|
import env from "@/utils/env";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 获取文件路径
|
||||||
|
* @param {String} src 文件路径
|
||||||
|
* @return {String} 文件路径
|
||||||
|
*/
|
||||||
|
export function filePath(src :string) {
|
||||||
|
let path = "";
|
||||||
|
if (src) {
|
||||||
|
if (src.startsWith("http")) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
path = `${env.baseUrl}${src}`;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 在全局配置对象中添加$perms属性,并将其值设为perms
|
||||||
|
export function installMethods(app) {
|
||||||
|
app.config.globalProperties.$perms = perms;
|
||||||
|
app.config.globalProperties.$toPath = toPath;
|
||||||
|
app.config.globalProperties.$filePath = filePath;
|
||||||
|
}
|
12
x_admin_app/package.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"bignumber.js": "^9.1.2",
|
||||||
|
"crypto-js": "^4.2.0",
|
||||||
|
"dayjs": "^1.11.10",
|
||||||
|
"uuid": "^9.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "^3.4.8",
|
||||||
|
"@uni-helper/uni-app-types": "^0.5.13"
|
||||||
|
}
|
||||||
|
}
|
84
x_admin_app/pages.json
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"pages": [{
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "管理系统"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/login/login",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "登录"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my/my",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/monitor_project/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "项目监控",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"onReachBottomDistance": 100,
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"path": "pages/monitor_project/details",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "项目监控详情",
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/monitor_project/edit",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "编辑项目监控"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/monitor_project/search",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "搜索项目监控"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "x admin",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#ccc",
|
||||||
|
"pageOrientation": "portrait"
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#000000",
|
||||||
|
"selectedColor": "#007aff",
|
||||||
|
"borderStyle": "black",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"list": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/index",
|
||||||
|
"iconPath": "static/icons/tabs/home.png",
|
||||||
|
"selectedIconPath": "static/icons/tabs/homeActive.png",
|
||||||
|
"text": "首页"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"pagePath": "pages/my/my",
|
||||||
|
"iconPath": "static/icons/tabs/my.png",
|
||||||
|
"selectedIconPath": "static/icons/tabs/myActive.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
121
x_admin_app/pages/index/index.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<uv-swiper :list="list" circular indicator indicatorMode="dot"></uv-swiper>
|
||||||
|
<!-- <uv-notice-bar :text="text" direction="column"></uv-notice-bar> -->
|
||||||
|
|
||||||
|
<uv-grid :border="false">
|
||||||
|
<uv-grid-item v-for="(item, index) in baseList" :key="index" @click="toList(item)">
|
||||||
|
<uv-icon :customStyle="{ padding: '50rpx 0 20rpx' }" :name="item.icon" :size="26"></uv-icon>
|
||||||
|
|
||||||
|
<text class="grid-text">{{ item.title }}</text>
|
||||||
|
</uv-grid-item>
|
||||||
|
</uv-grid>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref
|
||||||
|
} from "vue";
|
||||||
|
|
||||||
|
import {
|
||||||
|
toPath,
|
||||||
|
toast,
|
||||||
|
scanCode,
|
||||||
|
queryToObj,
|
||||||
|
} from "@/utils/utils.js";
|
||||||
|
|
||||||
|
let list = [
|
||||||
|
"https://cdn.uviewui.com/uview/swiper/swiper1.png",
|
||||||
|
"https://cdn.uviewui.com/uview/swiper/swiper2.png",
|
||||||
|
"https://cdn.uviewui.com/uview/swiper/swiper3.png",
|
||||||
|
];
|
||||||
|
let text = ["Fota", "轻松管理"];
|
||||||
|
|
||||||
|
|
||||||
|
let baseList = [
|
||||||
|
// {
|
||||||
|
// icon: "/static/index/product.png",
|
||||||
|
// path: "/pages/product/product",
|
||||||
|
// title: "产品",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// icon: "/static/index/group.png",
|
||||||
|
// path: "/pages/group/group",
|
||||||
|
// title: "分组",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// icon: "/static/index/version.png",
|
||||||
|
// path: "/pages/version/version",
|
||||||
|
// title: "版本",
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
icon: "/static/index/equipment.png",
|
||||||
|
path: "/pages/monitor_project/index",
|
||||||
|
title: "项目监控",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
icon: "/static/index/equipment.png",
|
||||||
|
path: "/pages/equipment/equipment",
|
||||||
|
title: "设备管理",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
icon: "scan",
|
||||||
|
// path: "/pages/equipment/equipment",
|
||||||
|
title: "扫码维护",
|
||||||
|
fn: function() {
|
||||||
|
// console.log('this', this);
|
||||||
|
scanCode().then((path) => {
|
||||||
|
// toPath(path);
|
||||||
|
if (!path) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var query = queryToObj(path);
|
||||||
|
if (!query.state) {
|
||||||
|
toast("请扫描设备二维码");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toPath("/pages/equipment/details", {
|
||||||
|
number: query.state,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: "/static/index/equipmentLog.png",
|
||||||
|
path: "/pages/statistics/statistics",
|
||||||
|
title: "销量统计",
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// icon: "/static/index/sysUp.png",
|
||||||
|
// path: "/pages/log/sysUp/sysUp",
|
||||||
|
// title: "上行日志",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// icon: "/static/index/sysDown.png",
|
||||||
|
// path: "/pages/log/sysDown/sysDown",
|
||||||
|
// title: "下行日志",
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// icon: "/static/index/log.png",
|
||||||
|
// path: "/pages/log/sysLog/sysLog",
|
||||||
|
// title: "系统日志",
|
||||||
|
// },
|
||||||
|
];
|
||||||
|
|
||||||
|
function toList(item) {
|
||||||
|
if (item.fn) {
|
||||||
|
item.fn();
|
||||||
|
} else {
|
||||||
|
toPath(item.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.grid-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
</style>
|
176
x_admin_app/pages/login/login.vue
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<uv-form
|
||||||
|
class="form"
|
||||||
|
ref="form"
|
||||||
|
labelWidth="60"
|
||||||
|
labelAlign="right"
|
||||||
|
:model="model"
|
||||||
|
:rules="rules"
|
||||||
|
>
|
||||||
|
<uv-form-item class="hide">
|
||||||
|
<uv-input
|
||||||
|
class="hide"
|
||||||
|
v-model="model.username"
|
||||||
|
placeholder="请输入账号"
|
||||||
|
:rules="[{ required: true, message: '请填写账号' }]"
|
||||||
|
/>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item class="hide">
|
||||||
|
<uv-input
|
||||||
|
type="password"
|
||||||
|
v-model="model.password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
:rules="[{ required: true, message: '请填写密码' }]"
|
||||||
|
/>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="账号" name="username" prop="username">
|
||||||
|
<uv-input
|
||||||
|
v-model="model.username"
|
||||||
|
placeholder="请输入账号"
|
||||||
|
:rules="[{ required: true, message: '请填写账号' }]"
|
||||||
|
/>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="密码" name="password" prop="password">
|
||||||
|
<uv-input
|
||||||
|
type="password"
|
||||||
|
v-model="model.password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
:rules="[{ required: true, message: '请填写密码' }]"
|
||||||
|
/>
|
||||||
|
</uv-form-item>
|
||||||
|
|
||||||
|
<Verify
|
||||||
|
@success="VerifySuccess"
|
||||||
|
:mode="'pop'"
|
||||||
|
:captchaType="'blockPuzzle'"
|
||||||
|
ref="verifyRef"
|
||||||
|
:imgSize="{ width: '310px', height: '155px' }"
|
||||||
|
></Verify>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="footer">
|
||||||
|
<!-- -->
|
||||||
|
|
||||||
|
<wd-button class="btn" size="large" @click="VerifyShow" block
|
||||||
|
>VerifyShow</wd-button
|
||||||
|
>
|
||||||
|
|
||||||
|
<wd-button class="btn" size="large" @click="handleSubmit" block
|
||||||
|
>登录</wd-button
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
</uv-form>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive } from "vue";
|
||||||
|
import { v1 as uuid_v1 } from "uuid";
|
||||||
|
|
||||||
|
import Verify from "@/components/verifition/verify";
|
||||||
|
|
||||||
|
import { login } from "@/api/user.js";
|
||||||
|
import { setLocalStorage } from "@/utils/storage.js";
|
||||||
|
import { toast } from "@/utils/utils.js";
|
||||||
|
// import appicon from "@/static/appicon.png";
|
||||||
|
|
||||||
|
import { useUserStore } from "@/stores/user";
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
|
||||||
|
const model = reactive({
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
});
|
||||||
|
const rules = {
|
||||||
|
username: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请填写账号",
|
||||||
|
trigger: ["blur", "change"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请填写密码",
|
||||||
|
trigger: ["blur", "change"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
};
|
||||||
|
const form = ref();
|
||||||
|
const verifyRef=ref()
|
||||||
|
function VerifyShow(e) {
|
||||||
|
verifyRef.value.show()
|
||||||
|
}
|
||||||
|
function VerifySuccess(e) {
|
||||||
|
console.log('VerifySuccess',e);
|
||||||
|
|
||||||
|
handleSubmit(e)
|
||||||
|
}
|
||||||
|
function handleSubmit(verify) {
|
||||||
|
form.value
|
||||||
|
.validate()
|
||||||
|
.then((res) => {
|
||||||
|
let data = {
|
||||||
|
username: model.username,
|
||||||
|
password: model.password,
|
||||||
|
|
||||||
|
...verify
|
||||||
|
};
|
||||||
|
|
||||||
|
// userStore.getUser();
|
||||||
|
|
||||||
|
login(data)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
setLocalStorage("token", res.data.token);
|
||||||
|
|
||||||
|
userStore.getInfo().then((res) => {
|
||||||
|
uni.switchTab({
|
||||||
|
url: "/pages/index/index",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
toast(res.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toast(err.message);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toast(err.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.hide {
|
||||||
|
height: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
border: 0 !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
margin: 200rpx 20rpx;
|
||||||
|
|
||||||
|
.captchaImage {
|
||||||
|
padding: 0 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
padding: 60rpx 20rpx 200rpx;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
background-color: #00b294;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
102
x_admin_app/pages/monitor_project/details.vue
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page-content">
|
||||||
|
<uv-navbar leftText="" :placeholder="true" title="监控项目详情" autoBack>
|
||||||
|
<template v-slot:right>
|
||||||
|
<uv-icon name="edit-pen" size="20" @click="edit"></uv-icon>
|
||||||
|
</template>
|
||||||
|
</uv-navbar>
|
||||||
|
|
||||||
|
<uv-form labelPosition="left" labelWidth="80" :model="form">
|
||||||
|
<uv-form-item label="项目uuid" prop="projectKey" borderBottom>
|
||||||
|
{{form.projectKey}}
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="项目名称" prop="projectName" borderBottom>
|
||||||
|
{{form.projectName}}
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="项目类型" prop="projectType" borderBottom>
|
||||||
|
{{form.projectType}}
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="创建时间" prop="createTime" borderBottom>
|
||||||
|
{{form.createTime}}
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="更新时间" prop="updateTime" borderBottom>
|
||||||
|
{{form.updateTime}}
|
||||||
|
</uv-form-item>
|
||||||
|
</uv-form>
|
||||||
|
<uv-button
|
||||||
|
v-if="$perms('admin:monitor_project:edit')"
|
||||||
|
type="primary"
|
||||||
|
text="编辑"
|
||||||
|
customStyle="margin-top: 20rpx"
|
||||||
|
@click="edit"
|
||||||
|
></uv-button>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
computed
|
||||||
|
} from "vue";
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow,
|
||||||
|
onPullDownRefresh
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
import {
|
||||||
|
useDictData
|
||||||
|
} from "@/hooks/useDictOptions";
|
||||||
|
import {
|
||||||
|
monitor_project_detail
|
||||||
|
} from "@/api/monitor_project";
|
||||||
|
|
||||||
|
|
||||||
|
import {
|
||||||
|
toast,
|
||||||
|
alert,
|
||||||
|
toPath
|
||||||
|
} from "@/utils/utils";
|
||||||
|
|
||||||
|
let form = ref({});
|
||||||
|
onLoad((e) => {
|
||||||
|
console.log("onLoad", e);
|
||||||
|
getDetails(e.id);
|
||||||
|
});
|
||||||
|
onShow((e) => {
|
||||||
|
if (form.value?.id) {
|
||||||
|
getDetails(form.value.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
onPullDownRefresh(() => {
|
||||||
|
getDetails(form.value.id);
|
||||||
|
});
|
||||||
|
function getDetails(id) {
|
||||||
|
monitor_project_detail(id).then((res) => {
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
if (res.code == 200) {
|
||||||
|
if (res?.data) {
|
||||||
|
form.value = res?.data
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast(res.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
toast(err.message||"网络错误");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit() {
|
||||||
|
toPath("/pages/monitor_project/edit", { id: form.value.id });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-content {
|
||||||
|
padding: 10rpx 20rpx 300rpx;
|
||||||
|
}
|
||||||
|
</style>
|
112
x_admin_app/pages/monitor_project/edit.vue
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page-content">
|
||||||
|
<uv-form
|
||||||
|
labelPosition="left"
|
||||||
|
labelWidth="80"
|
||||||
|
:model="form"
|
||||||
|
:rules="formRules"
|
||||||
|
ref="formRef"
|
||||||
|
>
|
||||||
|
|
||||||
|
<uv-form-item label="项目uuid" prop="projectKey" borderBottom>
|
||||||
|
<uv-input v-model="form.projectKey" border="surround"></uv-input>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="项目名称" prop="projectName" borderBottom>
|
||||||
|
<uv-input v-model="form.projectName" border="surround"></uv-input>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="项目类型" prop="projectType" borderBottom>
|
||||||
|
<x-picker v-model="form.projectType" valueKey="value" labelKey="name" :columns="dictData.project_type"></x-picker>
|
||||||
|
</uv-form-item>
|
||||||
|
|
||||||
|
<uv-button
|
||||||
|
type="primary"
|
||||||
|
text="提交"
|
||||||
|
customStyle="margin-top: 20rpx"
|
||||||
|
@click="submit"
|
||||||
|
></uv-button>
|
||||||
|
</uv-form>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, computed } from "vue";
|
||||||
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import {
|
||||||
|
monitor_project_detail,
|
||||||
|
monitor_project_edit,
|
||||||
|
} from "@/api/monitor_project";
|
||||||
|
import { toast, alert } from "@/utils/utils";
|
||||||
|
import { useDictData } from "@/hooks/useDictOptions";
|
||||||
|
const { dictData } = useDictData(['project_type'])
|
||||||
|
let formRef = ref();
|
||||||
|
let form = ref({
|
||||||
|
id: "",
|
||||||
|
projectKey: "",
|
||||||
|
projectName: "",
|
||||||
|
projectType: "",
|
||||||
|
});
|
||||||
|
const formRules = {
|
||||||
|
projectKey: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请输入项目uuid",
|
||||||
|
trigger: ["blur"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
projectName: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请输入项目名称",
|
||||||
|
trigger: ["blur"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
projectType: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: "请选择项目类型",
|
||||||
|
trigger: ["blur"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
onLoad((e) => {
|
||||||
|
console.log("onLoad", e);
|
||||||
|
getDetails(e.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
function getDetails(id) {
|
||||||
|
monitor_project_detail(id)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
if (res?.data) {
|
||||||
|
form.value = res?.data;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
toast(res.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toast(err.message || "网络错误");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit(item) {
|
||||||
|
console.log("submit", form);
|
||||||
|
formRef.value.validate().then(() => {
|
||||||
|
monitor_project_edit(form.value).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
toast("编辑成功");
|
||||||
|
|
||||||
|
getDetails(form.value?.id);
|
||||||
|
} else {
|
||||||
|
toast(res.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-content {
|
||||||
|
padding: 10rpx 20rpx 300rpx;
|
||||||
|
}
|
||||||
|
</style>
|
119
x_admin_app/pages/monitor_project/index.vue
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
|
||||||
|
<uv-sticky :customNavHeight="0" bgColor="#fff">
|
||||||
|
<uv-status-bar></uv-status-bar>
|
||||||
|
<uv-navbar
|
||||||
|
leftText=""
|
||||||
|
:safeAreaInsetTop="false"
|
||||||
|
:fixed="false"
|
||||||
|
title="监控项目"
|
||||||
|
autoBack
|
||||||
|
>
|
||||||
|
<template v-slot:right>
|
||||||
|
<uv-icon v-if="!fromSearch" name="search" size="24" @click="moreSearch"></uv-icon>
|
||||||
|
</template>
|
||||||
|
</uv-navbar>
|
||||||
|
<!-- <view class="search">
|
||||||
|
<uv-search
|
||||||
|
placeholder="请输入搜索内容"
|
||||||
|
shape="square"
|
||||||
|
v-model="queryParams.key"
|
||||||
|
:showAction="false"
|
||||||
|
bgColor="#fff"
|
||||||
|
borderColor="rgba(0, 0, 0, .1)"
|
||||||
|
@search="resetPage"
|
||||||
|
></uv-search>
|
||||||
|
</view> -->
|
||||||
|
</uv-sticky>
|
||||||
|
|
||||||
|
<uv-list>
|
||||||
|
<uv-list-item
|
||||||
|
v-for="item of pager.lists"
|
||||||
|
:key="item.id"
|
||||||
|
clickable
|
||||||
|
show-arrow
|
||||||
|
:title="item.projectName"
|
||||||
|
:note="item.projectType"
|
||||||
|
|
||||||
|
@click="toDetails(item)"
|
||||||
|
></uv-list-item>
|
||||||
|
</uv-list>
|
||||||
|
|
||||||
|
<uv-back-top :scroll-top="scrollTop"></uv-back-top>
|
||||||
|
|
||||||
|
<uv-empty v-if="pager.loading =='nomore'&&pager.lists.length == 0" marginTop="150" mode="data"></uv-empty>
|
||||||
|
|
||||||
|
<uv-loading-page
|
||||||
|
:loading="pager.pageNo == 1 && pager.loading == 'loading'"
|
||||||
|
loading-text="加载中..."
|
||||||
|
font-size="24rpx"
|
||||||
|
></uv-loading-page>
|
||||||
|
<uv-load-more
|
||||||
|
v-if="pager.lists.length > 0"
|
||||||
|
:status="pager.loading"
|
||||||
|
:loading-text="pager.loadingText"
|
||||||
|
:loadmore-text="pager.loadmoreText"
|
||||||
|
:nomore-text="pager.nomoreText"
|
||||||
|
@loadmore="NextPage"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onPullDownRefresh,
|
||||||
|
onReachBottom,
|
||||||
|
onPageScroll,
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
import { monitor_project_list } from "@/api/monitor_project";
|
||||||
|
import { usePaging } from "@/hooks/usePaging";
|
||||||
|
import { toPath } from "@/utils/utils";
|
||||||
|
const queryParams = reactive({
|
||||||
|
key: "",
|
||||||
|
|
||||||
|
});
|
||||||
|
let fromSearch=ref(false);
|
||||||
|
onLoad((e) => {
|
||||||
|
console.log("monitor_project onLoad", e);
|
||||||
|
if (e) {
|
||||||
|
for (const key in e) {
|
||||||
|
if (Object.hasOwnProperty.call(e, key)) {
|
||||||
|
fromSearch.value = true;
|
||||||
|
queryParams[key] = e[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getLists();
|
||||||
|
});
|
||||||
|
const { pager, getLists, NextPage, resetPage, resetParams } = usePaging({
|
||||||
|
fetchFun: monitor_project_list,
|
||||||
|
params: queryParams,
|
||||||
|
});
|
||||||
|
let scrollTop = ref(0);
|
||||||
|
onPageScroll((e) => {
|
||||||
|
scrollTop.value = e.scrollTop;
|
||||||
|
});
|
||||||
|
onPullDownRefresh(() => {
|
||||||
|
resetPage();
|
||||||
|
});
|
||||||
|
onReachBottom(() => {
|
||||||
|
NextPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
function toDetails(item) {
|
||||||
|
toPath("/pages/monitor_project/details", { id: item.id });
|
||||||
|
}
|
||||||
|
function moreSearch() {
|
||||||
|
toPath("/pages/monitor_project/search");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.search {
|
||||||
|
padding: 5rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
75
x_admin_app/pages/monitor_project/search.vue
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
<view class="page-content">
|
||||||
|
<uv-form labelPosition="left" labelWidth="80" :model="form" ref="formRef">
|
||||||
|
<uv-form-item label="项目uuid" prop="projectKey" borderBottom>
|
||||||
|
<uv-input v-model="form.projectKey"> </uv-input>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="项目名称" prop="projectName" borderBottom>
|
||||||
|
<uv-input v-model="form.projectName"> </uv-input>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item
|
||||||
|
label="项目类型"
|
||||||
|
prop="projectType"
|
||||||
|
borderBottom
|
||||||
|
>
|
||||||
|
<x-picker v-model="form.projectType" valueKey="value" labelKey="name" :columns="dictData.project_type"></x-picker>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="创建时间" prop="createTime" borderBottom>
|
||||||
|
<xDateRange
|
||||||
|
v-model:startTime="form.createTimeStart"
|
||||||
|
v-model:endTime="form.createTimeEnd"
|
||||||
|
></xDateRange>
|
||||||
|
</uv-form-item>
|
||||||
|
<uv-form-item label="更新时间" prop="updateTime" borderBottom>
|
||||||
|
<xDateRange
|
||||||
|
v-model:startTime="form.updateTimeStart"
|
||||||
|
v-model:endTime="form.updateTimeEnd"
|
||||||
|
></xDateRange>
|
||||||
|
</uv-form-item>
|
||||||
|
|
||||||
|
<uv-button
|
||||||
|
type="primary"
|
||||||
|
text="搜索"
|
||||||
|
customStyle="margin-top: 20rpx"
|
||||||
|
@click="submit"
|
||||||
|
></uv-button>
|
||||||
|
</uv-form>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { reactive, ref, computed } from "vue";
|
||||||
|
import { toPath, toast, clearObjEmpty } from "@/utils/utils";
|
||||||
|
import { useDictData } from "@/hooks/useDictOptions";
|
||||||
|
import xDateRange from "@/components/x-date-range/x-date-range.vue"
|
||||||
|
const { dictData } = useDictData(['project_type'])
|
||||||
|
let formRef = ref();
|
||||||
|
let form = ref({
|
||||||
|
projectKey: "",
|
||||||
|
projectName: "",
|
||||||
|
projectType: "",
|
||||||
|
createTimeStart: "",
|
||||||
|
createTimeEnd: "",
|
||||||
|
updateTimeStart: "",
|
||||||
|
updateTimeEnd: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
function submit() {
|
||||||
|
console.log("submit", form.value);
|
||||||
|
|
||||||
|
const search = clearObjEmpty(form.value);
|
||||||
|
|
||||||
|
if (Object.keys(search).length === 0) {
|
||||||
|
return toast("请输入查询条件");
|
||||||
|
}
|
||||||
|
|
||||||
|
toPath("/pages/monitor_project/index", search);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-content {
|
||||||
|
padding: 10rpx 20rpx 300rpx;
|
||||||
|
}
|
||||||
|
</style>
|
63
x_admin_app/pages/my/my.vue
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<view class="my">
|
||||||
|
<uv-sticky offsetTop="-1" bgColor="#ffffff">
|
||||||
|
<view style="background: #fff">
|
||||||
|
<uv-cell :title="userStore?.username" :label="userStore?.nickname" isLink>
|
||||||
|
<!-- -->
|
||||||
|
<template v-slot:icon>
|
||||||
|
<button class="avatar-wrapper" open-type="chooseAvatar" @click.stop>
|
||||||
|
<uv-avatar
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
shape="circle"
|
||||||
|
:src="$filePath(userStore.avatar)"
|
||||||
|
mode="widthFix"
|
||||||
|
></uv-avatar>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</uv-cell>
|
||||||
|
</view>
|
||||||
|
</uv-sticky>
|
||||||
|
<uv-button
|
||||||
|
class="btn"
|
||||||
|
type="primary"
|
||||||
|
text="登录"
|
||||||
|
@click="toLogin"
|
||||||
|
></uv-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useUserStore } from "@/stores/user";
|
||||||
|
|
||||||
|
const userStore = useUserStore();
|
||||||
|
|
||||||
|
function toLogin() {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: "/pages/login/login",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.my {
|
||||||
|
background-color: rgba(243, 246, 249, 1);
|
||||||
|
padding-bottom: 40px;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 7px;
|
||||||
|
background-color: white;
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
margin: 200rpx 20rpx;
|
||||||
|
}
|
||||||
|
</style>
|
BIN
x_admin_app/static/appicon.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
x_admin_app/static/default.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
x_admin_app/static/icons/tabs/home.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
x_admin_app/static/icons/tabs/homeActive.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
x_admin_app/static/icons/tabs/my.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
x_admin_app/static/icons/tabs/myActive.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
x_admin_app/static/index/equipment.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
x_admin_app/static/index/equipmentLog.png
Normal file
After Width: | Height: | Size: 7.4 KiB |
BIN
x_admin_app/static/index/group.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
x_admin_app/static/index/log.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
x_admin_app/static/index/product.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
x_admin_app/static/index/serial.png
Normal file
After Width: | Height: | Size: 3.2 KiB |
BIN
x_admin_app/static/index/sysDown.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
x_admin_app/static/index/sysUp.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
x_admin_app/static/index/version.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
77
x_admin_app/stores/user.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
import { logout, getInfo } from "@/api/user";
|
||||||
|
|
||||||
|
import { getLocalStorage, removeLocalStorage } from "@/utils/storage.js";
|
||||||
|
|
||||||
|
export const useUserStore = defineStore("user", {
|
||||||
|
state: () => {
|
||||||
|
return {
|
||||||
|
nickname: "",
|
||||||
|
username: "",
|
||||||
|
avatar: "",
|
||||||
|
userInfo: {},
|
||||||
|
menu: [],
|
||||||
|
auth: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
// 也可以这样定义
|
||||||
|
// state: () => ({ count: 0 })
|
||||||
|
actions: {
|
||||||
|
// get user info
|
||||||
|
getInfo() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let token = getLocalStorage("token");
|
||||||
|
if (!token) {
|
||||||
|
return reject(new Error("需要登录"));
|
||||||
|
}
|
||||||
|
getInfo(token)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
const { data } = res;
|
||||||
|
this.nickname = data.user.nickname;
|
||||||
|
this.username = data.user.username;
|
||||||
|
|
||||||
|
this.avatar = data.user.avatar ||"";
|
||||||
|
// this.menu = data.menu;
|
||||||
|
// this.auth = data.auth;
|
||||||
|
this.userInfo = data.user;
|
||||||
|
resolve(data);
|
||||||
|
} else {
|
||||||
|
reject(new Error(res.message));
|
||||||
|
}
|
||||||
|
|
||||||
|
// addRoutes(result.menu);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// user logout
|
||||||
|
logout() {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
logout()
|
||||||
|
.then(() => {
|
||||||
|
// resetRouter();
|
||||||
|
this.resetToken();
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// remove token
|
||||||
|
resetToken() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
// this.token = "";
|
||||||
|
this.name = "";
|
||||||
|
this.avatar = "";
|
||||||
|
removeLocalStorage("token");
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
29
x_admin_app/tsconfig.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"include": [
|
||||||
|
"global.d.ts",
|
||||||
|
"methods/**/*",
|
||||||
|
"api/**/*.ts",
|
||||||
|
"pages/**/*.vue",
|
||||||
|
"components/**/*.vue",
|
||||||
|
"stores/**/*",
|
||||||
|
"utils/**/*",
|
||||||
|
"typings/**/*.d.ts",
|
||||||
|
"hooks/usePaging.ts"
|
||||||
|
],
|
||||||
|
"exclude": ["dist", "node_modules", "uni_modules", "unpackage"],
|
||||||
|
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"]
|
||||||
|
},
|
||||||
|
"types": ["@dcloudio/types", "@uni-helper/uni-app-types"]
|
||||||
|
}
|
||||||
|
}
|
7
x_admin_app/typings/methods.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
declare module 'vue' {
|
||||||
|
interface ComponentCustomProperties {
|
||||||
|
$filePath: (typeof import('@/methods/index'))['filePath']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {}
|
32
x_admin_app/typings/uniapp.d.ts
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/// <reference types="@dcloudio/types" />
|
||||||
|
/// <reference types="@dcloudio/types" />
|
||||||
|
/// <reference types="@dcloudio/types" />
|
||||||
|
/// <reference types="@dcloudio/types" />
|
||||||
|
|
||||||
|
declare module '@dcloudio/uni-app' {
|
||||||
|
export const onShow: (callback: ((options?: App.LaunchShowOption) => void) | (() => void), target?: null) => Function;
|
||||||
|
export const onHide: (callback: (() => void) | (() => void), target?: null) => Function;
|
||||||
|
export const onLaunch: (callback: (options?: App.LaunchShowOption) => void, target?: null) => Function;
|
||||||
|
export const onError: (callback: (error: string) => void, target?: null) => Function;
|
||||||
|
export const onPageNotFound: (callback: (options: App.PageNotFoundOption) => void, target?: null) => Function;
|
||||||
|
export const onUnhandledRejection: (callback: (options: UniApp.OnUnhandledRejectionCallbackResult) => void, target?: null) => Function;
|
||||||
|
export const onThemeChange: (callback: (options: UniApp.OnThemeChangeCallbackResult) => void, target?: null) => Function;
|
||||||
|
export const onUniNViewMessage: (callback: (options: AnyObject) => void, target?: null) => Function;
|
||||||
|
export const onInit: (callback: (query?: AnyObject) => void, target?: null) => Function;
|
||||||
|
export const onLoad: (callback: (query?: AnyObject) => void, target?: null) => Function;
|
||||||
|
export const onReady: (callback: () => void, target?: null) => Function;
|
||||||
|
export const onUnload: (callback: () => void, target?: null) => Function;
|
||||||
|
export const onPullDownRefresh: (callback: () => void, target?: null) => Function;
|
||||||
|
export const onReachBottom: (callback: () => void, target?: null) => Function;
|
||||||
|
export const onShareAppMessage: (callback: (options: Page.ShareAppMessageOption) => Page.CustomShareContent, target?: null) => Function;
|
||||||
|
export const onShareTimeline: (callback: () => Page.ShareTimelineContent, target?: null) => Function;
|
||||||
|
export const onAddToFavorites: (callback: (options: Page.AddToFavoritesOption) => Page.CustomFavoritesContent, target?: null) => Function;
|
||||||
|
export const onPageScroll: (callback: (options: Page.PageScrollOption) => void, target?: null) => Function;
|
||||||
|
export const onResize: (callback: (options: Page.PageScrollOption) => void, target?: null) => Function;
|
||||||
|
export const onTabItemTap: (callback: (options: Page.TabItemTapOption) => void, target?: null) => Function;
|
||||||
|
export const onNavigationBarButtonTap: (callback: (options: Page.NavigationBarButtonTapOption) => void, target?: null) => Function;
|
||||||
|
export const onBackPress: (callback: (options: Page.BackPressOption) => any, target?: null) => Function;
|
||||||
|
export const onNavigationBarSearchInputChanged: (callback: (event: Page.NavigationBarSearchInputEvent) => void, target?: null) => Function;
|
||||||
|
export const onNavigationBarSearchInputConfirmed: (callback: (event: Page.NavigationBarSearchInputEvent) => void, target?: null) => Function;
|
||||||
|
export const onNavigationBarSearchInputClicked: (callback: () => void, target?: null) => Function;
|
||||||
|
}
|
10
x_admin_app/uni.promisify.adaptor.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
uni.addInterceptor({
|
||||||
|
returnValue (res) {
|
||||||
|
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
76
x_admin_app/uni.scss
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* 这里是uni-app内置的常用样式变量
|
||||||
|
*
|
||||||
|
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||||
|
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||||
|
*
|
||||||
|
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||||
|
*/
|
||||||
|
// @import '@/uni_modules/uv-ui-tools/theme.scss';
|
||||||
|
/* 颜色变量 */
|
||||||
|
|
||||||
|
/* 行为相关颜色 */
|
||||||
|
$uni-color-primary: #007aff;
|
||||||
|
$uni-color-success: #4cd964;
|
||||||
|
$uni-color-warning: #f0ad4e;
|
||||||
|
$uni-color-error: #dd524d;
|
||||||
|
|
||||||
|
/* 文字基本颜色 */
|
||||||
|
$uni-text-color:#333;//基本色
|
||||||
|
$uni-text-color-inverse:#fff;//反色
|
||||||
|
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||||
|
$uni-text-color-placeholder: #808080;
|
||||||
|
$uni-text-color-disable:#c0c0c0;
|
||||||
|
|
||||||
|
/* 背景颜色 */
|
||||||
|
$uni-bg-color:#ffffff;
|
||||||
|
$uni-bg-color-grey:#f8f8f8;
|
||||||
|
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||||
|
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
$uni-border-color:#c8c7cc;
|
||||||
|
|
||||||
|
/* 尺寸变量 */
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
$uni-font-size-sm:12px;
|
||||||
|
$uni-font-size-base:14px;
|
||||||
|
$uni-font-size-lg:16px;
|
||||||
|
|
||||||
|
/* 图片尺寸 */
|
||||||
|
$uni-img-size-sm:20px;
|
||||||
|
$uni-img-size-base:26px;
|
||||||
|
$uni-img-size-lg:40px;
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
$uni-border-radius-sm: 2px;
|
||||||
|
$uni-border-radius-base: 3px;
|
||||||
|
$uni-border-radius-lg: 6px;
|
||||||
|
$uni-border-radius-circle: 50%;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-row-sm: 5px;
|
||||||
|
$uni-spacing-row-base: 10px;
|
||||||
|
$uni-spacing-row-lg: 15px;
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
$uni-spacing-col-sm: 4px;
|
||||||
|
$uni-spacing-col-base: 8px;
|
||||||
|
$uni-spacing-col-lg: 12px;
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
$uni-color-title: #2C405A; // 文章标题颜色
|
||||||
|
$uni-font-size-title:20px;
|
||||||
|
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||||
|
$uni-font-size-subtitle:26px;
|
||||||
|
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||||
|
$uni-font-size-paragraph:15px;
|
7
x_admin_app/uni_modules/uv-action-sheet/changelog.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## 1.0.2(2023-07-02)
|
||||||
|
uv-action-sheet 由于弹出层uv-popup的修改,打开和关闭方法更改,详情参考文档:https://www.uvui.cn/components/actionSheet.html
|
||||||
|
## 1.0.1(2023-05-16)
|
||||||
|
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||||
|
2. 优化部分功能
|
||||||
|
## 1.0.0(2023-05-10)
|
||||||
|
uv-action-sheet 底部操作菜单
|
@@ -0,0 +1,50 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 标题,有值则显示,同时会显示关闭按钮
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 选项上方的描述信息
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 数据
|
||||||
|
actions: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
// 取消按钮的文字,不为空时显示按钮
|
||||||
|
cancelText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 点击某个菜单项时是否关闭弹窗
|
||||||
|
closeOnClickAction: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 处理底部安全区(默认true)
|
||||||
|
safeAreaInsetBottom: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 小程序的打开方式
|
||||||
|
openType: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 点击遮罩是否允许关闭 (默认true)
|
||||||
|
closeOnClickOverlay: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 圆角值
|
||||||
|
round: {
|
||||||
|
type: [Boolean, String, Number],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.actionSheet
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,280 @@
|
|||||||
|
|
||||||
|
<template>
|
||||||
|
<uv-popup
|
||||||
|
ref="popup"
|
||||||
|
mode="bottom"
|
||||||
|
:safeAreaInsetBottom="safeAreaInsetBottom"
|
||||||
|
:round="round"
|
||||||
|
:close-on-click-overlay="closeOnClickOverlay"
|
||||||
|
@change="popupChange"
|
||||||
|
>
|
||||||
|
<view class="uv-action-sheet">
|
||||||
|
<view
|
||||||
|
class="uv-action-sheet__header"
|
||||||
|
v-if="title"
|
||||||
|
>
|
||||||
|
<text class="uv-action-sheet__header__title uv-line-1">{{title}}</text>
|
||||||
|
<view
|
||||||
|
class="uv-action-sheet__header__icon-wrap"
|
||||||
|
@tap.stop="cancel"
|
||||||
|
>
|
||||||
|
<uv-icon
|
||||||
|
name="close"
|
||||||
|
size="17"
|
||||||
|
color="#c8c9cc"
|
||||||
|
bold
|
||||||
|
></uv-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text
|
||||||
|
class="uv-action-sheet__description"
|
||||||
|
:style="[{
|
||||||
|
marginTop: `${title && description ? 0 : '18px'}`
|
||||||
|
}]"
|
||||||
|
v-if="description"
|
||||||
|
>{{description}}</text>
|
||||||
|
<slot>
|
||||||
|
<uv-line v-if="description"></uv-line>
|
||||||
|
<view class="uv-action-sheet__item-wrap">
|
||||||
|
<view v-for="(item, index) in actions" :key="index">
|
||||||
|
<!-- #ifdef MP -->
|
||||||
|
<button
|
||||||
|
class="uv-reset-button"
|
||||||
|
:openType="item.openType"
|
||||||
|
@getuserinfo="onGetUserInfo"
|
||||||
|
@contact="onContact"
|
||||||
|
@getphonenumber="onGetPhoneNumber"
|
||||||
|
@error="onError"
|
||||||
|
@launchapp="onLaunchApp"
|
||||||
|
@opensetting="onOpenSetting"
|
||||||
|
:lang="lang"
|
||||||
|
:session-from="sessionFrom"
|
||||||
|
:send-message-title="sendMessageTitle"
|
||||||
|
:send-message-path="sendMessagePath"
|
||||||
|
:send-message-img="sendMessageImg"
|
||||||
|
:show-message-card="showMessageCard"
|
||||||
|
:app-parameter="appParameter"
|
||||||
|
@tap="selectHandler(index)"
|
||||||
|
:hover-class="!item.disabled && !item.loading ? 'uv-action-sheet--hover' : ''"
|
||||||
|
>
|
||||||
|
<!-- #endif -->
|
||||||
|
<view
|
||||||
|
class="uv-action-sheet__item-wrap__item"
|
||||||
|
@tap.stop="selectHandler(index)"
|
||||||
|
:hover-class="!item.disabled && !item.loading ? 'uv-action-sheet--hover' : ''"
|
||||||
|
:hover-stay-time="150"
|
||||||
|
>
|
||||||
|
<template v-if="!item.loading">
|
||||||
|
<text
|
||||||
|
class="uv-action-sheet__item-wrap__item__name"
|
||||||
|
:style="[itemStyle(index)]"
|
||||||
|
>{{ item.name }}</text>
|
||||||
|
<text
|
||||||
|
v-if="item.subname"
|
||||||
|
class="uv-action-sheet__item-wrap__item__subname"
|
||||||
|
>{{ item.subname }}</text>
|
||||||
|
</template>
|
||||||
|
<uv-loading-icon
|
||||||
|
v-else
|
||||||
|
custom-class="van-action-sheet__loading"
|
||||||
|
size="18"
|
||||||
|
mode="circle"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<!-- #ifdef MP -->
|
||||||
|
</button>
|
||||||
|
<!-- #endif -->
|
||||||
|
<uv-line v-if="index !== actions.length - 1"></uv-line>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
<uv-gap
|
||||||
|
bgColor="#eaeaec"
|
||||||
|
height="6"
|
||||||
|
v-if="cancelText"
|
||||||
|
></uv-gap>
|
||||||
|
<view hover-class="uv-action-sheet--hover">
|
||||||
|
<text
|
||||||
|
@touchmove.stop.prevent
|
||||||
|
:hover-stay-time="150"
|
||||||
|
v-if="cancelText"
|
||||||
|
class="uv-action-sheet__cancel-text"
|
||||||
|
@tap="cancel"
|
||||||
|
>{{cancelText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uv-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import button from '@/uni_modules/uv-ui-tools/libs/mixin/button.js'
|
||||||
|
import openType from '@/uni_modules/uv-ui-tools/libs/mixin/openType.js'
|
||||||
|
import props from './props.js';
|
||||||
|
/**
|
||||||
|
* ActionSheet 操作菜单
|
||||||
|
* @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
|
||||||
|
* @tutorial https://www.uvui.cn/components/actionSheet.html
|
||||||
|
* @property {Boolean} show 操作菜单是否展示 (默认 false )
|
||||||
|
* @property {String} title 操作菜单标题
|
||||||
|
* @property {String} description 选项上方的描述信息
|
||||||
|
* @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
|
||||||
|
* @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
|
||||||
|
* @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
|
||||||
|
* @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
|
||||||
|
* @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
|
||||||
|
* @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
|
||||||
|
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
|
||||||
|
* @property {String} sessionFrom 会话来源,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
|
||||||
|
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
|
||||||
|
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
|
||||||
|
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
|
||||||
|
*
|
||||||
|
* @event {Function} select 点击ActionSheet列表项时触发
|
||||||
|
* @event {Function} close 点击取消按钮时触发
|
||||||
|
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
|
||||||
|
* @event {Function} contact 客服消息回调,openType="contact"时有效
|
||||||
|
* @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
|
||||||
|
* @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
|
||||||
|
* @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
|
||||||
|
* @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
|
||||||
|
* @example <uv-action-sheet ref="actionSheet" :actions="list" :title="title" ></uv-action-sheet>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "uv-action-sheet",
|
||||||
|
mixins: [openType, button, mpMixin , mixin, props],
|
||||||
|
emits: ['close', 'select'],
|
||||||
|
computed: {
|
||||||
|
// 操作项目的样式
|
||||||
|
itemStyle() {
|
||||||
|
return (index) => {
|
||||||
|
let style = {};
|
||||||
|
if (this.actions[index].color) style.color = this.actions[index].color
|
||||||
|
if (this.actions[index].fontSize) style.fontSize = this.$uv.addUnit(this.actions[index].fontSize)
|
||||||
|
// 选项被禁用的样式
|
||||||
|
if (this.actions[index].disabled) style.color = '#c0c4cc'
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open() {
|
||||||
|
this.$refs.popup.open();
|
||||||
|
},
|
||||||
|
close() {
|
||||||
|
this.$refs.popup.close();
|
||||||
|
},
|
||||||
|
popupChange(e) {
|
||||||
|
if(!e.show) this.$emit('close');
|
||||||
|
},
|
||||||
|
// 点击取消按钮
|
||||||
|
cancel() {
|
||||||
|
this.close();
|
||||||
|
},
|
||||||
|
selectHandler(index) {
|
||||||
|
const item = this.actions[index]
|
||||||
|
if (item && !item.disabled && !item.loading) {
|
||||||
|
this.$emit('select', item)
|
||||||
|
if (this.closeOnClickAction) {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$show-lines: 1;
|
||||||
|
$show-reset-button: 1;
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||||
|
$uv-action-sheet-reset-button-width:100% !default;
|
||||||
|
$uv-action-sheet-title-font-size: 16px !default;
|
||||||
|
$uv-action-sheet-title-padding: 12px 30px !default;
|
||||||
|
$uv-action-sheet-title-color: $uv-main-color !default;
|
||||||
|
$uv-action-sheet-header-icon-wrap-right:15px !default;
|
||||||
|
$uv-action-sheet-header-icon-wrap-top:15px !default;
|
||||||
|
$uv-action-sheet-description-font-size:13px !default;
|
||||||
|
$uv-action-sheet-description-color:14px !default;
|
||||||
|
$uv-action-sheet-description-margin: 18px 15px !default;
|
||||||
|
$uv-action-sheet-item-wrap-item-padding:15px !default;
|
||||||
|
$uv-action-sheet-item-wrap-name-font-size:16px !default;
|
||||||
|
$uv-action-sheet-item-wrap-subname-font-size:13px !default;
|
||||||
|
$uv-action-sheet-item-wrap-subname-color: #c0c4cc !default;
|
||||||
|
$uv-action-sheet-item-wrap-subname-margin-top:10px !default;
|
||||||
|
$uv-action-sheet-cancel-text-font-size:16px !default;
|
||||||
|
$uv-action-sheet-cancel-text-color:$uv-content-color !default;
|
||||||
|
$uv-action-sheet-cancel-text-font-size:15px !default;
|
||||||
|
$uv-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
|
||||||
|
|
||||||
|
.uv-reset-button {
|
||||||
|
width: $uv-action-sheet-reset-button-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-action-sheet {
|
||||||
|
text-align: center;
|
||||||
|
&__header {
|
||||||
|
position: relative;
|
||||||
|
padding: $uv-action-sheet-title-padding;
|
||||||
|
&__title {
|
||||||
|
font-size: $uv-action-sheet-title-font-size;
|
||||||
|
color: $uv-action-sheet-title-color;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon-wrap {
|
||||||
|
position: absolute;
|
||||||
|
right: $uv-action-sheet-header-icon-wrap-right;
|
||||||
|
top: $uv-action-sheet-header-icon-wrap-top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__description {
|
||||||
|
font-size: $uv-action-sheet-description-font-size;
|
||||||
|
color: $uv-tips-color;
|
||||||
|
margin: $uv-action-sheet-description-margin;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item-wrap {
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
padding: $uv-action-sheet-item-wrap-item-padding;
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
font-size: $uv-action-sheet-item-wrap-name-font-size;
|
||||||
|
color: $uv-main-color;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__subname {
|
||||||
|
font-size: $uv-action-sheet-item-wrap-subname-font-size;
|
||||||
|
color: $uv-action-sheet-item-wrap-subname-color;
|
||||||
|
margin-top: $uv-action-sheet-item-wrap-subname-margin-top;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__cancel-text {
|
||||||
|
font-size: $uv-action-sheet-cancel-text-font-size;
|
||||||
|
color: $uv-action-sheet-cancel-text-color;
|
||||||
|
text-align: center;
|
||||||
|
padding: $uv-action-sheet-cancel-text-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--hover {
|
||||||
|
background-color: $uv-action-sheet-cancel-text-hover-background-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
92
x_admin_app/uni_modules/uv-action-sheet/package.json
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-action-sheet",
|
||||||
|
"displayName": "uv-action-sheet 底部操作菜单 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"description": "该组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheet API,配置更加灵活,所有平台都表现一致。",
|
||||||
|
"keywords": [
|
||||||
|
"action-sheet",
|
||||||
|
"uvui",
|
||||||
|
"uv-ui",
|
||||||
|
"操作菜单",
|
||||||
|
"菜单选择"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools",
|
||||||
|
"uv-popup",
|
||||||
|
"uv-icon",
|
||||||
|
"uv-line",
|
||||||
|
"uv-loading-icon",
|
||||||
|
"uv-gap"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
x_admin_app/uni_modules/uv-action-sheet/readme.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
## ActionSheet 操作菜单
|
||||||
|
|
||||||
|
> **组件名:uv-action-sheet**
|
||||||
|
|
||||||
|
本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。
|
||||||
|
|
||||||
|
本组件功能类似于uni的uni.showActionSheet API,配置更加灵活,所有平台都表现一致。
|
||||||
|
|
||||||
|
### <a href="https://www.uvui.cn/components/actionSheet.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
10
x_admin_app/uni_modules/uv-album/changelog.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
## 1.0.4(2023-12-06)
|
||||||
|
1. 阻止事件冒泡处理
|
||||||
|
## 1.0.3(2023-10-23)
|
||||||
|
1. 修复报错的BUG
|
||||||
|
## 1.0.2(2023-10-23)
|
||||||
|
1. 修复设置singleSize、multipleSize、space等值带单位,存在不显示的BUG
|
||||||
|
## 1.0.1(2023-09-13)
|
||||||
|
1. 添加依赖
|
||||||
|
## 1.0.0(2023-08-30)
|
||||||
|
1. 新增uv-album相册组件
|
@@ -0,0 +1,312 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uv-album">
|
||||||
|
<view
|
||||||
|
class="uv-album__row"
|
||||||
|
ref="uv-album__row"
|
||||||
|
v-for="(arr, index) in showUrls"
|
||||||
|
:forComputedUse="albumWidth"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="uv-album__row__wrapper"
|
||||||
|
v-for="(item, index1) in arr"
|
||||||
|
:key="index1"
|
||||||
|
:style="[imageStyle(index + 1, index1 + 1)]"
|
||||||
|
@tap.stop="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="getSrc(item)"
|
||||||
|
:mode="
|
||||||
|
urls.length === 1
|
||||||
|
? imageHeight > 0
|
||||||
|
? singleMode
|
||||||
|
: 'widthFix'
|
||||||
|
: multipleMode
|
||||||
|
"
|
||||||
|
:style="[
|
||||||
|
{
|
||||||
|
width: imageWidth,
|
||||||
|
height: imageHeight
|
||||||
|
}
|
||||||
|
]"
|
||||||
|
></image>
|
||||||
|
<view
|
||||||
|
v-if="
|
||||||
|
showMore &&
|
||||||
|
urls.length > rowCount * showUrls.length &&
|
||||||
|
index === showUrls.length - 1 &&
|
||||||
|
index1 === showUrls[showUrls.length - 1].length - 1
|
||||||
|
"
|
||||||
|
class="uv-album__row__wrapper__text"
|
||||||
|
>
|
||||||
|
<uv-text
|
||||||
|
:text="`+${urls.length - maxCount}`"
|
||||||
|
color="#fff"
|
||||||
|
:size="$uv.getPx(multipleSize) * 0.3"
|
||||||
|
align="center"
|
||||||
|
customStyle="justify-content: center"
|
||||||
|
></uv-text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
|
||||||
|
const dom = uni.requireNativePlugin('dom')
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Album 相册
|
||||||
|
* @description 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码
|
||||||
|
* @tutorial https://www.uvui.cn/components/album.html
|
||||||
|
* @property {Array} urls 图片地址列表 Array<String>|Array<Object>形式
|
||||||
|
* @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
* @property {String | Number} singleSize 单图时,图片长边的长度 (默认 180 )
|
||||||
|
* @property {String | Number} multipleSize 多图时,图片边长 (默认 70 )
|
||||||
|
* @property {String | Number} space 多图时,图片水平和垂直之间的间隔 (默认 6 )
|
||||||
|
* @property {String} singleMode 单图时,图片缩放裁剪的模式 (默认 'scaleToFill' )
|
||||||
|
* @property {String} multipleMode 多图时,图片缩放裁剪的模式 (默认 'aspectFill' )
|
||||||
|
* @property {String | Number} maxCount 取消按钮的提示文字 (默认 9 )
|
||||||
|
* @property {Boolean} previewFullImage 是否可以预览图片 (默认 true )
|
||||||
|
* @property {String | Number} rowCount 每行展示图片数量,如设置,singleSize和multipleSize将会无效 (默认 3 )
|
||||||
|
* @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
|
||||||
|
*
|
||||||
|
* @event {Function} albumWidth 某些特殊的情况下,需要让文字与相册的宽度相等,这里事件的形式对外发送 (回调参数 width )
|
||||||
|
* @example <uv-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></uv-album>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uv-album',
|
||||||
|
mixins: [mpMixin, mixin],
|
||||||
|
emits: ['albumWidth'],
|
||||||
|
props: {
|
||||||
|
// 图片地址,Array<String>|Array<Object>形式
|
||||||
|
urls: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
// 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
keyName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 单图时,图片长边的长度
|
||||||
|
singleSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 180
|
||||||
|
},
|
||||||
|
// 多图时,图片边长
|
||||||
|
multipleSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 70
|
||||||
|
},
|
||||||
|
// 多图时,图片水平和垂直之间的间隔
|
||||||
|
space: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 6
|
||||||
|
},
|
||||||
|
// 单图时,图片缩放裁剪的模式
|
||||||
|
singleMode: {
|
||||||
|
type: String,
|
||||||
|
default: 'scaleToFill'
|
||||||
|
},
|
||||||
|
// 多图时,图片缩放裁剪的模式
|
||||||
|
multipleMode: {
|
||||||
|
type: String,
|
||||||
|
default: 'aspectFill'
|
||||||
|
},
|
||||||
|
// 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
|
||||||
|
maxCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 9
|
||||||
|
},
|
||||||
|
// 是否可以预览图片
|
||||||
|
previewFullImage: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 每行展示图片数量,如设置,singleSize和multipleSize将会无效
|
||||||
|
rowCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 3
|
||||||
|
},
|
||||||
|
// 超出maxCount时是否显示查看更多的提示
|
||||||
|
showMore: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.album
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 单图的宽度
|
||||||
|
singleWidth: 0,
|
||||||
|
// 单图的高度
|
||||||
|
singleHeight: 0,
|
||||||
|
// 单图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比
|
||||||
|
singlePercent: 0.6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
urls: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
if (newVal.length === 1) {
|
||||||
|
this.getImageRect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imageStyle() {
|
||||||
|
return (index1, index2) => {
|
||||||
|
const { space, rowCount, multipleSize, urls } = this;
|
||||||
|
const rowLen = this.showUrls.length;
|
||||||
|
const allLen = this.urls.length;
|
||||||
|
const style = {
|
||||||
|
marginRight: this.$uv.addUnit(space),
|
||||||
|
marginBottom: this.$uv.addUnit(space)
|
||||||
|
}
|
||||||
|
// 如果为最后一行,则每个图片都无需下边框
|
||||||
|
if (index1 === rowLen) style.marginBottom = 0
|
||||||
|
// 每行的最右边一张和总长度的最后一张无需右边框
|
||||||
|
if (
|
||||||
|
index2 === rowCount ||
|
||||||
|
(index1 === rowLen &&
|
||||||
|
index2 === this.showUrls[index1 - 1].length)
|
||||||
|
)
|
||||||
|
style.marginRight = 0
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 将数组划分为二维数组
|
||||||
|
showUrls() {
|
||||||
|
const arr = []
|
||||||
|
this.urls.map((item, index) => {
|
||||||
|
// 限制最大展示数量
|
||||||
|
if (index + 1 <= this.maxCount) {
|
||||||
|
// 计算该元素为第几个素组内
|
||||||
|
const itemIndex = Math.floor(index / this.rowCount)
|
||||||
|
// 判断对应的索引是否存在
|
||||||
|
if (!arr[itemIndex]) {
|
||||||
|
arr[itemIndex] = []
|
||||||
|
}
|
||||||
|
arr[itemIndex].push(item)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return arr
|
||||||
|
},
|
||||||
|
imageWidth() {
|
||||||
|
return this.$uv.addUnit(
|
||||||
|
this.urls.length === 1 ? this.singleWidth : this.multipleSize
|
||||||
|
)
|
||||||
|
},
|
||||||
|
imageHeight() {
|
||||||
|
return this.$uv.addUnit(
|
||||||
|
this.urls.length === 1 ? this.singleHeight : this.multipleSize
|
||||||
|
)
|
||||||
|
},
|
||||||
|
// 此变量无实际用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度
|
||||||
|
// 因为用户在某些特殊的情况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送
|
||||||
|
albumWidth() {
|
||||||
|
let width = 0
|
||||||
|
if (this.urls.length === 1) {
|
||||||
|
width = this.singleWidth
|
||||||
|
} else {
|
||||||
|
width =
|
||||||
|
this.showUrls[0].length * this.$uv.getPx(this.multipleSize) +
|
||||||
|
this.$uv.getPx(this.space) * (this.showUrls[0].length - 1)
|
||||||
|
}
|
||||||
|
this.$emit('albumWidth', width)
|
||||||
|
return width
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 预览图片
|
||||||
|
onPreviewTap(url) {
|
||||||
|
const urls = this.urls.map((item) => {
|
||||||
|
return this.getSrc(item)
|
||||||
|
})
|
||||||
|
uni.previewImage({
|
||||||
|
current: url,
|
||||||
|
urls
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取图片的路径
|
||||||
|
getSrc(item) {
|
||||||
|
return this.$uv.test.object(item) ?
|
||||||
|
(this.keyName && item[this.keyName]) || item.src :
|
||||||
|
item
|
||||||
|
},
|
||||||
|
// 单图时,获取图片的尺寸
|
||||||
|
// 在小程序中,需要将网络图片的的域名添加到小程序的download域名才可能获取尺寸
|
||||||
|
// 在没有添加的情况下,让单图宽度默认为盒子的一定宽度(singlePercent)
|
||||||
|
getImageRect() {
|
||||||
|
const src = this.getSrc(this.urls[0])
|
||||||
|
uni.getImageInfo({
|
||||||
|
src,
|
||||||
|
success: (res) => {
|
||||||
|
// 判断图片横向还是竖向展示方式
|
||||||
|
const isHorizotal = res.width >= res.height
|
||||||
|
this.singleWidth = isHorizotal ?
|
||||||
|
this.singleSize :
|
||||||
|
(res.width / res.height) * this.$uv.getPx(this.singleSize)
|
||||||
|
this.singleHeight = !isHorizotal ?
|
||||||
|
this.singleSize :
|
||||||
|
(res.height / res.width) * this.singleWidth
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
this.getComponentWidth()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取组件的宽度
|
||||||
|
async getComponentWidth() {
|
||||||
|
// 延时一定时间,以获取dom尺寸
|
||||||
|
await this.$uv.sleep(30)
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
this.$uGetRect('.uv-album__row').then((size) => {
|
||||||
|
this.singleWidth = size.width * this.singlePercent
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
// 这里ref="uv-album__row"所在的标签为通过for循环出来,导致this.$refs['uv-album__row']是一个数组
|
||||||
|
const ref = this.$refs['uv-album__row'][0]
|
||||||
|
ref &&
|
||||||
|
dom.getComponentRect(ref, (res) => {
|
||||||
|
this.singleWidth = res.size.width * this.singlePercent
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
.uv-album {
|
||||||
|
@include flex(column);
|
||||||
|
&__row {
|
||||||
|
@include flex(row);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
&__wrapper {
|
||||||
|
position: relative;
|
||||||
|
&__text {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
@include flex(row);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
88
x_admin_app/uni_modules/uv-album/package.json
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-album",
|
||||||
|
"displayName": "uv-album 相册 全面兼容vue3+2、app、h5、小程序等多端",
|
||||||
|
"version": "1.0.4",
|
||||||
|
"description": "本组件提供一个类似相册的功能,让开发者开发起来更加得心应手,功能齐全,灵活配置可以,开箱即用。减少重复的模板代码",
|
||||||
|
"keywords": [
|
||||||
|
"album",
|
||||||
|
"uv-ui",
|
||||||
|
"uvui",
|
||||||
|
"相册",
|
||||||
|
"图片"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools",
|
||||||
|
"uv-text"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
x_admin_app/uni_modules/uv-album/readme.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Album 相册
|
||||||
|
|
||||||
|
> **组件名:uv-album**
|
||||||
|
|
||||||
|
本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。
|
||||||
|
|
||||||
|
功能齐全,灵活配置可以,开箱即用。减少重复的模板代码。
|
||||||
|
|
||||||
|
# <a href="https://www.uvui.cn/components/album.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small>
|
||||||
|
|
||||||
|
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</a>
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
7
x_admin_app/uni_modules/uv-alert/changelog.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## 1.0.2(2023-06-01)
|
||||||
|
1. 修复点击触发两次实践的BUG
|
||||||
|
## 1.0.1(2023-05-16)
|
||||||
|
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||||
|
2. 优化部分功能
|
||||||
|
## 1.0.0(2023-05-10)
|
||||||
|
uv-alert 警告提示组件
|
@@ -0,0 +1,45 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 显示文字
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 主题,success/warning/info/error
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'warning'
|
||||||
|
},
|
||||||
|
// 辅助性文字
|
||||||
|
description: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否可关闭
|
||||||
|
closable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否显示图标
|
||||||
|
showIcon: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 浅或深色调,light-浅色,dark-深色
|
||||||
|
effect: {
|
||||||
|
type: String,
|
||||||
|
default: 'light'
|
||||||
|
},
|
||||||
|
// 文字是否居中
|
||||||
|
center: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 字体大小
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 14
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.alert
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,246 @@
|
|||||||
|
<template>
|
||||||
|
<uv-transition
|
||||||
|
mode="fade"
|
||||||
|
:show="show"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="uv-alert"
|
||||||
|
:class="[`uv-alert--${type}--${effect}`]"
|
||||||
|
@tap.stop="clickHandler"
|
||||||
|
:style="[$uv.addStyle(customStyle)]"
|
||||||
|
>
|
||||||
|
<view
|
||||||
|
class="uv-alert__icon"
|
||||||
|
v-if="showIcon"
|
||||||
|
>
|
||||||
|
<uv-icon
|
||||||
|
:name="iconName"
|
||||||
|
size="18"
|
||||||
|
:color="iconColor"
|
||||||
|
></uv-icon>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="uv-alert__content"
|
||||||
|
:style="[{
|
||||||
|
paddingRight: closable ? '20px' : 0
|
||||||
|
}]"
|
||||||
|
>
|
||||||
|
<text
|
||||||
|
class="uv-alert__content__title"
|
||||||
|
v-if="title"
|
||||||
|
:style="[{
|
||||||
|
fontSize: $uv.addUnit(fontSize),
|
||||||
|
textAlign: center ? 'center' : 'left'
|
||||||
|
}]"
|
||||||
|
:class="[effect === 'dark' ? 'uv-alert__text--dark' : `uv-alert__text--${type}--light`]"
|
||||||
|
>{{ title }}</text>
|
||||||
|
<text
|
||||||
|
class="uv-alert__content__desc"
|
||||||
|
v-if="description"
|
||||||
|
:style="[{
|
||||||
|
fontSize: $uv.addUnit(fontSize),
|
||||||
|
textAlign: center ? 'center' : 'left'
|
||||||
|
}]"
|
||||||
|
:class="[effect === 'dark' ? 'uv-alert__text--dark' : `uv-alert__text--${type}--light`]"
|
||||||
|
>{{ description }}</text>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="uv-alert__close"
|
||||||
|
v-if="closable"
|
||||||
|
@tap.stop="closeHandler"
|
||||||
|
>
|
||||||
|
<uv-icon
|
||||||
|
name="close"
|
||||||
|
:color="iconColor"
|
||||||
|
size="15"
|
||||||
|
></uv-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uv-transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import props from './props.js';
|
||||||
|
/**
|
||||||
|
* Alert 警告提示
|
||||||
|
* @description 警告提示,展现需要关注的信息。
|
||||||
|
* @tutorial https://www.uvui.cn/components/alertTips.html
|
||||||
|
*
|
||||||
|
* @property {String} title 显示的文字
|
||||||
|
* @property {String} type 使用预设的颜色 (默认 'warning' )
|
||||||
|
* @property {String} description 辅助性文字,颜色比title浅一点,字号也小一点,可选
|
||||||
|
* @property {Boolean} closable 关闭按钮(默认为叉号icon图标) (默认 false )
|
||||||
|
* @property {Boolean} showIcon 是否显示左边的辅助图标 ( 默认 false )
|
||||||
|
* @property {String} effect 多图时,图片缩放裁剪的模式 (默认 'light' )
|
||||||
|
* @property {Boolean} center 文字是否居中 (默认 false )
|
||||||
|
* @property {String | Number} fontSize 字体大小 (默认 14 )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
* @event {Function} click 点击组件时触发
|
||||||
|
* @example <uv-alert :title="title" type = "warning" :closable="closable" :description = "description"></uv-alert>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uv-alert',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
emits: ['click'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
iconColor() {
|
||||||
|
return this.effect === 'light' ? this.type : '#fff'
|
||||||
|
},
|
||||||
|
// 不同主题对应不同的图标
|
||||||
|
iconName() {
|
||||||
|
switch (this.type) {
|
||||||
|
case 'success':
|
||||||
|
return 'checkmark-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
return 'close-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'warning':
|
||||||
|
return 'error-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'info':
|
||||||
|
return 'info-circle-fill';
|
||||||
|
break;
|
||||||
|
case 'primary':
|
||||||
|
return 'more-circle-fill';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 'error-circle-fill';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 点击内容
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('click')
|
||||||
|
},
|
||||||
|
// 点击关闭按钮
|
||||||
|
closeHandler() {
|
||||||
|
this.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||||
|
.uv-alert {
|
||||||
|
position: relative;
|
||||||
|
background-color: $uv-primary;
|
||||||
|
padding: 8px 10px;
|
||||||
|
@include flex(row);
|
||||||
|
align-items: center;
|
||||||
|
border-top-left-radius: 4px;
|
||||||
|
border-top-right-radius: 4px;
|
||||||
|
border-bottom-left-radius: 4px;
|
||||||
|
border-bottom-right-radius: 4px;
|
||||||
|
|
||||||
|
&--primary--dark {
|
||||||
|
background-color: $uv-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary--light {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error--dark {
|
||||||
|
background-color: $uv-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error--light {
|
||||||
|
background-color: #FEF0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success--dark {
|
||||||
|
background-color: $uv-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success--light {
|
||||||
|
background-color: #f5fff0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning--dark {
|
||||||
|
background-color: $uv-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning--light {
|
||||||
|
background-color: #FDF6EC;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info--dark {
|
||||||
|
background-color: $uv-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info--light {
|
||||||
|
background-color: #f4f4f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
@include flex(column);
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
color: $uv-main-color;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__desc {
|
||||||
|
color: $uv-main-color;
|
||||||
|
font-size: 14px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__title--dark,
|
||||||
|
&__desc--dark {
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--primary--light,
|
||||||
|
&__text--primary--light {
|
||||||
|
color: $uv-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--success--light,
|
||||||
|
&__text--success--light {
|
||||||
|
color: $uv-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--warning--light,
|
||||||
|
&__text--warning--light {
|
||||||
|
color: $uv-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--error--light,
|
||||||
|
&__text--error--light {
|
||||||
|
color: $uv-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--info--light,
|
||||||
|
&__text--info--light {
|
||||||
|
color: $uv-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__close {
|
||||||
|
position: absolute;
|
||||||
|
top: 11px;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
88
x_admin_app/uni_modules/uv-alert/package.json
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-alert",
|
||||||
|
"displayName": "uv-alert 警告提示 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"description": "uv-alert 警告提示,展现需要关注的信息。灵活配置,功能齐全,兼容全端",
|
||||||
|
"keywords": [
|
||||||
|
"alert",
|
||||||
|
"uvui",
|
||||||
|
"uv-ui",
|
||||||
|
"警告提示"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools",
|
||||||
|
"uv-transition",
|
||||||
|
"uv-icon"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
x_admin_app/uni_modules/uv-alert/readme.md
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
## Alert 警告提示
|
||||||
|
|
||||||
|
> **组件名:uv-alert**
|
||||||
|
|
||||||
|
警告提示,展现需要关注的信息。
|
||||||
|
|
||||||
|
当某个页面需要向用户显示警告的信息时。
|
||||||
|
|
||||||
|
非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。
|
||||||
|
|
||||||
|
### <a href="https://www.uvui.cn/components/alert.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
13
x_admin_app/uni_modules/uv-avatar/changelog.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
## 1.0.5(2023-12-06)
|
||||||
|
1. 优化
|
||||||
|
## 1.0.4(2023-12-06)
|
||||||
|
1. 优化
|
||||||
|
## 1.0.3(2023-12-06)
|
||||||
|
1. 阻止事件冒泡处理,单个头像模式
|
||||||
|
## 1.0.2(2023-12-06)
|
||||||
|
1. 阻止事件冒泡处理
|
||||||
|
## 1.0.1(2023-05-16)
|
||||||
|
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||||
|
2. 优化部分功能
|
||||||
|
## 1.0.0(2023-05-10)
|
||||||
|
uv-avatar 头像组件
|
@@ -0,0 +1,53 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 头像图片组
|
||||||
|
urls: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
// 最多展示的头像数量
|
||||||
|
maxCount: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
// 头像形状
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: 'circle'
|
||||||
|
},
|
||||||
|
// 图片裁剪模式
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'scaleToFill'
|
||||||
|
},
|
||||||
|
// 超出maxCount时是否显示查看更多的提示
|
||||||
|
showMore: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 头像大小
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 40
|
||||||
|
},
|
||||||
|
// 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
keyName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 头像之间的遮挡比例
|
||||||
|
gap: {
|
||||||
|
type: [String, Number],
|
||||||
|
validator(value) {
|
||||||
|
return value >= 0 && value <= 1
|
||||||
|
},
|
||||||
|
default: 0.5
|
||||||
|
},
|
||||||
|
// 需额外显示的值
|
||||||
|
extraValue: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.avatarGroup
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uv-avatar-group">
|
||||||
|
<view
|
||||||
|
class="uv-avatar-group__item"
|
||||||
|
v-for="(item, index) in showUrl"
|
||||||
|
:key="index"
|
||||||
|
:style="{
|
||||||
|
marginLeft: index === 0 ? 0 : $uv.addUnit(-size * gap)
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<uv-avatar
|
||||||
|
:size="size"
|
||||||
|
:shape="shape"
|
||||||
|
:mode="mode"
|
||||||
|
:src="$uv.test.object(item) ? keyName && item[keyName] || item.url : item"
|
||||||
|
></uv-avatar>
|
||||||
|
<view
|
||||||
|
class="uv-avatar-group__item__show-more"
|
||||||
|
v-if="showMore && index === showUrl.length - 1 && (urls.length > maxCount || extraValue > 0)"
|
||||||
|
@tap="clickHandler"
|
||||||
|
>
|
||||||
|
<uv-text
|
||||||
|
color="#ffffff"
|
||||||
|
:size="size * 0.4"
|
||||||
|
:text="`+${extraValue || urls.length - showUrl.length}`"
|
||||||
|
align="center"
|
||||||
|
customStyle="justify-content: center"
|
||||||
|
></uv-text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import props from './props.js';
|
||||||
|
/**
|
||||||
|
* AvatarGroup 头像组
|
||||||
|
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
||||||
|
* @tutorial https://www.uvui.cn/components/avatar.html
|
||||||
|
*
|
||||||
|
* @property {Array} urls 头像图片组 (默认 [] )
|
||||||
|
* @property {String | Number} maxCount 最多展示的头像数量 ( 默认 5 )
|
||||||
|
* @property {String} shape 头像形状( 'circle' (默认) | 'square' )
|
||||||
|
* @property {String} mode 图片裁剪模式(默认 'scaleToFill' )
|
||||||
|
* @property {Boolean} showMore 超出maxCount时是否显示查看更多的提示 (默认 true )
|
||||||
|
* @property {String | Number} size 头像大小 (默认 40 )
|
||||||
|
* @property {String} keyName 指定从数组的对象元素中读取哪个属性作为图片地址
|
||||||
|
* @property {String | Number} gap 头像之间的遮挡比例(0.4代表遮挡40%) (默认 0.5 )
|
||||||
|
* @property {String | Number} extraValue 需额外显示的值
|
||||||
|
* @event {Function} showMore 头像组更多点击
|
||||||
|
* @example <uv-avatar-group:urls="urls" size="35" gap="0.4" ></uv-avatar-group:urls=>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uv-avatar-group',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
showUrl() {
|
||||||
|
return this.urls.slice(0, this.maxCount)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('showMore')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||||
|
|
||||||
|
.uv-avatar-group {
|
||||||
|
@include flex;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
margin-left: -10px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&--no-indent {
|
||||||
|
// 如果你想质疑作者不会使用:first-child,说明你太年轻,因为nvue不支持
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__show-more {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -0,0 +1,80 @@
|
|||||||
|
import { range } from '@/uni_modules/uv-ui-tools/libs/function/test.js'
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 头像图片路径(不能为相对路径)
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 头像形状,circle-圆形,square-方形
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: 'circle'
|
||||||
|
},
|
||||||
|
// 头像尺寸
|
||||||
|
size: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 40
|
||||||
|
},
|
||||||
|
// 裁剪模式
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'scaleToFill'
|
||||||
|
},
|
||||||
|
// 显示的文字
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 背景色
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#c0c4cc'
|
||||||
|
},
|
||||||
|
// 文字颜色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#fff'
|
||||||
|
},
|
||||||
|
// 文字大小
|
||||||
|
fontSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 18
|
||||||
|
},
|
||||||
|
// 显示的图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 显示小程序头像,只对百度,微信,QQ小程序有效
|
||||||
|
mpAvatar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否使用随机背景色
|
||||||
|
randomBgColor: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 加载失败的默认头像(组件有内置默认图片)
|
||||||
|
defaultUrl: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
|
||||||
|
colorIndex: {
|
||||||
|
type: [String, Number],
|
||||||
|
// 校验参数规则,索引在0-19之间
|
||||||
|
validator(n) {
|
||||||
|
return range(n, [0, 19]) || n === ''
|
||||||
|
},
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 组件标识符
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.avatar
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,175 @@
|
|||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="uv-avatar"
|
||||||
|
:class="[`uv-avatar--${shape}`]"
|
||||||
|
:style="[{
|
||||||
|
backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $uv.random(0, 19)] : bgColor) : 'transparent',
|
||||||
|
width: $uv.addUnit(size),
|
||||||
|
height: $uv.addUnit(size),
|
||||||
|
}, $uv.addStyle(customStyle)]"
|
||||||
|
@tap="clickHandler"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU -->
|
||||||
|
<open-data
|
||||||
|
v-if="mpAvatar && allowMp"
|
||||||
|
type="userAvatarUrl"
|
||||||
|
:style="[{
|
||||||
|
width: $uv.addUnit(size),
|
||||||
|
height: $uv.addUnit(size)
|
||||||
|
}]"
|
||||||
|
/>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU -->
|
||||||
|
<template v-if="mpAvatar && allowMp"></template>
|
||||||
|
<!-- #endif -->
|
||||||
|
<uv-icon
|
||||||
|
v-else-if="icon"
|
||||||
|
:name="icon"
|
||||||
|
:size="fontSize"
|
||||||
|
:color="color"
|
||||||
|
></uv-icon>
|
||||||
|
<uv-text
|
||||||
|
v-else-if="text"
|
||||||
|
:text="text"
|
||||||
|
:size="fontSize"
|
||||||
|
:color="color"
|
||||||
|
align="center"
|
||||||
|
customStyle="justify-content: center"
|
||||||
|
></uv-text>
|
||||||
|
<image
|
||||||
|
class="uv-avatar__image"
|
||||||
|
v-else
|
||||||
|
:class="[`uv-avatar__image--${shape}`]"
|
||||||
|
:src="avatarUrl || defaultUrl"
|
||||||
|
:mode="mode"
|
||||||
|
@error="errorHandler"
|
||||||
|
:style="[{
|
||||||
|
width: $uv.addUnit(size),
|
||||||
|
height: $uv.addUnit(size)
|
||||||
|
}]"
|
||||||
|
></image>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import props from './props.js';
|
||||||
|
const base64Avatar =
|
||||||
|
"data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYGCAsMCgoLCgoMEAwMDAwMDBAMDg8QDw4MExMUFBMTHBsbGxwfHx8fHx8fHx8fAQcHBw0MDRgQEBgaFREVGh8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx//wAARCADIAMgDAREAAhEBAxEB/8QAcQABAQEAAwEBAAAAAAAAAAAAAAUEAQMGAgcBAQAAAAAAAAAAAAAAAAAAAAAQAAIBAwICBgkDBQAAAAAAAAABAhEDBCEFMVFBYXGREiKBscHRMkJSEyOh4XLxYjNDFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8A/fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHbHFyZ/Dam+yLA+Z2L0Pjtyj2poD4AAAAAAAAAAAAAAAAAAAAAAAAKWFs9y6lcvvwQeqj8z9wFaziY1n/HbUX9XF97A7QAGXI23EvJ1goyfzR0YEfN269jeZ+a03pNe0DIAAAAAAAAAAAAAAAAAAAACvtO3RcVkXlWutuL9YFYAAAAAOJRjKLjJVi9GmB5/csH/mu1h/in8PU+QGMAAAAAAAAAAAAAAAAAAaMDG/6MmMH8C80+xAelSSVFolwQAAAAAAAHVlWI37ErUulaPk+hgeYnCUJuElSUXRrrQHAAAAAAAAAAAAAAAAABa2Oz4bM7r4zdF2ICmAAAAAAAAAg7zZ8GX41wuJP0rRgYAAAAAAAAAAAAAAAAAD0m2R8ODaXU33tsDSAAAAAAAAAlb9HyWZcnJd9PcBHAAAAAAAAAAAAAAAAAPS7e64Vn+KA0AAAAAAAAAJm+v8Ftf3ewCKAAAAAAAAAAAAAAAAAX9muqeGo9NttP06+0DcAAAAAAAAAjb7dTu2ra+VOT9P8AQCWAAAAAAAAAAAAAAAAAUNmyPt5Ltv4bui/kuAF0AAAAAAADiUlGLlJ0SVW+oDzOXfd/Ind6JPRdS0QHSAAAAAAAAAAAAAAAAAE2nVaNcGB6Lbs6OTao9LsF51z60BrAAAAAABJ3jOVHjW3r/sa9QEgAAAAAAAAAAAAAAAAAAAPu1duWriuW34ZR4MC9hbnZyEoy8l36XwfYBsAAADaSq9EuLAlZ+7xSdrGdW9Hc5dgEdtt1erfFgAAAAAAAAAAAAAAAAADVjbblX6NR8MH80tEBRs7HYivyzlN8lovaBPzduvY0m6eK10TXtAyAarO55lpJK54orolr+4GqO/Xaea1FvqbXvA+Z77kNeW3GPbV+4DJfzcm/pcm3H6Vou5AdAFLC2ed2Pjv1txa8sV8T6wOL+yZEKu1JXFy4MDBOE4ScZxcZLinoB8gAAAAAAAAAAAB242LeyJ+C3GvN9C7QLmJtePYpKS+5c+p8F2IDYAANJqj1T4oCfk7Nj3G5Wn9qXJax7gJ93Z82D8sVNc4v30A6Xg5i42Z+iLfqARwcyT0sz9MWvWBps7LlTf5Grce9/oBTxdtxseklHxT+uWr9AGoAB138ezfj4bsFJdD6V2MCPm7RdtJzs1uW1xXzL3gTgAAAAAAAAADRhYc8q74I6RWs5ckB6GxYtWLat21SK731sDsAAAAAAAAAAAAAAAASt021NO/YjrxuQXT1oCOAAAAAAABzGLlJRSq26JAelwsWONYjbXxcZvmwO8AAAAAAAAAAAAAAAAAAef3TEWPkVivx3NY9T6UBiAAAAAABo2+VmGXblddIJ8eivRUD0oAAAAAAAAAAAAAAAAAAAYt4tKeFKVNYNSXfRgefAAAAAAAAr7VuSSWPedKaW5v1MCsAAAAAAAAAAAAAAAAAAIe6bj96Ts2n+JPzSXzP3ATgAAAAAAAAFbbt1UUrOQ9FpC4/UwK6aaqtU+DAAAAAAAAAAAAAAA4lKMIuUmoxWrb4ARNx3R3q2rLpa4Sl0y/YCcAAAAAAAAAAANmFud7G8r89r6X0dgFvGzLGRGtuWvTF6NAdwAAAAAAAAAAAy5W442PVN+K59EePp5ARMvOv5MvO6QXCC4AZwAAAAAAAAAAAAAcxlKLUotprg1owN+PvORborq+7Hnwl3gUbO74VzRydt8pKn68ANcJwmqwkpLmnUDkAAAAfNy9atqtyagut0AxXt5xIV8Fbj6lRd7Am5G65V6qUvtwfyx94GMAAAAAAAAAAAAAAAAAAAOU2nVOj5gdsc3LiqRvTpyqwOxbnnrhdfpSfrQB7pnv/AGvuS9gHXPMy5/Fem1yq0v0A6W29XqwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf//Z";
|
||||||
|
/**
|
||||||
|
* Avatar 头像
|
||||||
|
* @description 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
||||||
|
* @tutorial https://www.uvui.cn/components/avatar.html
|
||||||
|
*
|
||||||
|
* @property {String} src 头像路径,如加载失败,将会显示默认头像(不能为相对路径)
|
||||||
|
* @property {String} shape 头像形状 ( circle (默认) | square)
|
||||||
|
* @property {String | Number} size 头像尺寸,可以为指定字符串(large, default, mini),或者数值 (默认 40 )
|
||||||
|
* @property {String} mode 头像图片的裁剪类型,与uni的image组件的mode参数一致,如效果达不到需求,可尝试传widthFix值 (默认 'scaleToFill' )
|
||||||
|
* @property {String} text 用文字替代图片,级别优先于src
|
||||||
|
* @property {String} bgColor 背景颜色,一般显示文字时用 (默认 '#c0c4cc' )
|
||||||
|
* @property {String} color 文字颜色 (默认 '#ffffff' )
|
||||||
|
* @property {String | Number} fontSize 文字大小 (默认 18 )
|
||||||
|
* @property {String} icon 显示的图标
|
||||||
|
* @property {Boolean} mpAvatar 显示小程序头像,只对百度,微信,QQ小程序有效 (默认 false )
|
||||||
|
* @property {Boolean} randomBgColor 是否使用随机背景色 (默认 false )
|
||||||
|
* @property {String} defaultUrl 加载失败的默认头像(组件有内置默认图片)
|
||||||
|
* @property {String | Number} colorIndex 如果配置了randomBgColor为true,且配置了此值,则从默认的背景色数组中取出对应索引的颜色值,取值0-19之间
|
||||||
|
* @property {String} name 组件标识符 (默认 'level' )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @event {Function} click 点击组件时触发 index: 用户传递的标识符
|
||||||
|
* @example <uv-avatar :src="src" mode="square"></uv-avatar>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uv-avatar',
|
||||||
|
emits: ['click'],
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 如果配置randomBgColor参数为true,在图标或者文字的模式下,会随机从中取出一个颜色值当做背景色
|
||||||
|
colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
|
||||||
|
'#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
|
||||||
|
'#73d1f1',
|
||||||
|
'#80a7dc'
|
||||||
|
],
|
||||||
|
avatarUrl: this.src,
|
||||||
|
allowMp: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值
|
||||||
|
// 而组件内部不能直接修改props的值,所以需要一个中间变量
|
||||||
|
src: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal) {
|
||||||
|
this.avatarUrl = newVal
|
||||||
|
// 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示
|
||||||
|
if(!newVal) {
|
||||||
|
this.errorHandler()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
imageStyle() {
|
||||||
|
const style = {}
|
||||||
|
return style
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
// 目前只有这几个小程序平台具有open-data标签
|
||||||
|
// 其他平台可以通过uni.getUserInfo类似接口获取信息,但是需要弹窗授权(首次),不合符组件逻辑
|
||||||
|
// 故目前自动获取小程序头像只支持这几个平台
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
|
||||||
|
this.allowMp = true
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
// 判断传入的name属性,是否图片路径,只要带有"/"均认为是图片形式
|
||||||
|
isImg() {
|
||||||
|
return this.src.indexOf('/') !== -1
|
||||||
|
},
|
||||||
|
// 图片加载时失败时触发
|
||||||
|
errorHandler() {
|
||||||
|
this.avatarUrl = this.defaultUrl || base64Avatar
|
||||||
|
},
|
||||||
|
clickHandler() {
|
||||||
|
this.$emit('click', this.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
|
||||||
|
.uv-avatar {
|
||||||
|
@include flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&--circle {
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__image {
|
||||||
|
&--circle {
|
||||||
|
border-radius: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
89
x_admin_app/uni_modules/uv-avatar/package.json
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-avatar",
|
||||||
|
"displayName": "uv-avatar 头像 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||||
|
"version": "1.0.5",
|
||||||
|
"description": "uv-avatar 本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。",
|
||||||
|
"keywords": [
|
||||||
|
"uv-avatar",
|
||||||
|
"uvui",
|
||||||
|
"uv-ui",
|
||||||
|
"avatar",
|
||||||
|
"头像"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools",
|
||||||
|
"uv-icon",
|
||||||
|
"uv-text"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
x_admin_app/uni_modules/uv-avatar/readme.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
## Avatar 头像
|
||||||
|
|
||||||
|
> **组件名:uv-avatar**
|
||||||
|
|
||||||
|
本组件一般用于展示头像的地方,如个人中心,或者评论列表页的用户头像展示等场所。
|
||||||
|
|
||||||
|
### <a href="https://www.uvui.cn/components/avatar.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
8
x_admin_app/uni_modules/uv-back-top/changelog.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
## 1.0.2(2023-07-03)
|
||||||
|
1. 优化插槽自定义内容部分
|
||||||
|
2. 增加backToTop方法说明
|
||||||
|
## 1.0.1(2023-05-16)
|
||||||
|
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||||
|
2. 优化部分功能
|
||||||
|
## 1.0.0(2023-05-10)
|
||||||
|
uv-back-top 返回顶部
|
@@ -0,0 +1,58 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 返回顶部的形状,circle-圆形,square-方形
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'circle'
|
||||||
|
},
|
||||||
|
// 自定义图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: 'arrow-upward'
|
||||||
|
},
|
||||||
|
// 提示文字
|
||||||
|
text: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 返回顶部滚动时间
|
||||||
|
duration: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 100
|
||||||
|
},
|
||||||
|
// 滚动距离
|
||||||
|
scrollTop: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// 距离顶部多少距离显示,单位px
|
||||||
|
top: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 400
|
||||||
|
},
|
||||||
|
// 返回顶部按钮到底部的距离,单位px
|
||||||
|
bottom: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 100
|
||||||
|
},
|
||||||
|
// 返回顶部按钮到右边的距离,单位px
|
||||||
|
right: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 20
|
||||||
|
},
|
||||||
|
// 层级
|
||||||
|
zIndex: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 9
|
||||||
|
},
|
||||||
|
// 图标的样式,对象形式
|
||||||
|
iconStyle: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
color: '#909399',
|
||||||
|
fontSize: '19px'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.backtop
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<uv-transition mode="fade" :customStyle="backTopStyle" :show="show">
|
||||||
|
<slot>
|
||||||
|
<view class="uv-back-top" :style="[contentStyle]" @click="backToTop">
|
||||||
|
<uv-icon :name="icon" :custom-style="iconStyle"></uv-icon>
|
||||||
|
<text v-if="text" class="uv-back-top__text">{{text}}</text>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</uv-transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import props from './props.js';
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const dom = weex.requireModule('dom')
|
||||||
|
// #endif
|
||||||
|
/**
|
||||||
|
* backTop 返回顶部
|
||||||
|
* @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
|
||||||
|
* @tutorial https://www.uvui.cn/components/backTop.html
|
||||||
|
* @property {String} mode 返回顶部的形状,circle-圆形,square-方形 (默认 'circle' )
|
||||||
|
* @property {String} icon 自定义图标 (默认 'arrow-upward' ) 见官方文档示例
|
||||||
|
* @property {String} text 提示文字
|
||||||
|
* @property {String | Number} duration 返回顶部滚动时间 (默认 100)
|
||||||
|
* @property {String | Number} scrollTop 滚动距离 (默认 0 )
|
||||||
|
* @property {String | Number} top 距离顶部多少距离显示,单位px (默认 400 )
|
||||||
|
* @property {String | Number} bottom 返回顶部按钮到底部的距离,单位px (默认 100 )
|
||||||
|
* @property {String | Number} right 返回顶部按钮到右边的距离,单位px (默认 20 )
|
||||||
|
* @property {String | Number} zIndex 层级 (默认 9 )
|
||||||
|
* @property {Object<Object>} iconStyle 图标的样式,对象形式 (默认 {color: '#909399',fontSize: '19px'})
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
*
|
||||||
|
* @example <uv-back-top :scrollTop="scrollTop"></uv-back-top>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uv-back-top',
|
||||||
|
emits: ['click'],
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
computed: {
|
||||||
|
backTopStyle() {
|
||||||
|
// 动画组件样式
|
||||||
|
const style = {
|
||||||
|
bottom: this.$uv.addUnit(this.bottom),
|
||||||
|
right: this.$uv.addUnit(this.right),
|
||||||
|
width: '40px',
|
||||||
|
height: '40px',
|
||||||
|
position: 'fixed',
|
||||||
|
zIndex: 10,
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
show() {
|
||||||
|
return this.$uv.getPx(this.scrollTop) > this.$uv.getPx(this.top)
|
||||||
|
},
|
||||||
|
contentStyle() {
|
||||||
|
const style = {}
|
||||||
|
let radius = 0
|
||||||
|
// 是否圆形
|
||||||
|
if (this.mode === 'circle') {
|
||||||
|
radius = '100px'
|
||||||
|
} else {
|
||||||
|
radius = '4px'
|
||||||
|
}
|
||||||
|
// 为了兼容安卓nvue,只能这么分开写
|
||||||
|
style.borderTopLeftRadius = radius
|
||||||
|
style.borderTopRightRadius = radius
|
||||||
|
style.borderBottomLeftRadius = radius
|
||||||
|
style.borderBottomRightRadius = radius
|
||||||
|
return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
backToTop() {
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
if (!this.$parent.$refs['uv-back-top']) {
|
||||||
|
this.$uv.error(`nvue页面需要给页面最外层元素设置"ref='uv-back-top'`)
|
||||||
|
}
|
||||||
|
dom.scrollToElement(this.$parent.$refs['uv-back-top'], {
|
||||||
|
offset: 0
|
||||||
|
})
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifndef APP-NVUE
|
||||||
|
uni.pageScrollTo({
|
||||||
|
scrollTop: 0,
|
||||||
|
duration: this.duration
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
$uv-back-top-flex: 1 !default;
|
||||||
|
$uv-back-top-height: 100% !default;
|
||||||
|
$uv-back-top-background-color: #E1E1E1 !default;
|
||||||
|
$uv-back-top-tips-font-size: 12px !default;
|
||||||
|
.uv-back-top {
|
||||||
|
@include flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
flex: $uv-back-top-flex;
|
||||||
|
height: $uv-back-top-height;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: $uv-back-top-background-color;
|
||||||
|
&__tips {
|
||||||
|
font-size: $uv-back-top-tips-font-size;
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
89
x_admin_app/uni_modules/uv-back-top/package.json
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-back-top",
|
||||||
|
"displayName": "uv-back-top 返回顶部 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"description": "返回顶部 组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。",
|
||||||
|
"keywords": [
|
||||||
|
"uv-back-top",
|
||||||
|
"uvui",
|
||||||
|
"uv-ui",
|
||||||
|
"avatar",
|
||||||
|
"返回顶部"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools",
|
||||||
|
"uv-icon",
|
||||||
|
"uv-transition"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
x_admin_app/uni_modules/uv-back-top/readme.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
## BackTop 返回顶部
|
||||||
|
|
||||||
|
> **组件名:uv-back-top**
|
||||||
|
|
||||||
|
该组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
|
||||||
|
|
||||||
|
### <a href="https://www.uvui.cn/components/backTop.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
7
x_admin_app/uni_modules/uv-badge/changelog.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## 1.0.2(2023-06-04)
|
||||||
|
1. 修复type等属性为null的时候不显示徽标的BUG
|
||||||
|
## 1.0.1(2023-05-16)
|
||||||
|
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||||
|
2. 优化部分功能
|
||||||
|
## 1.0.0(2023-05-10)
|
||||||
|
uv-badge 徽标数,数字角标
|
@@ -0,0 +1,73 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否显示圆点
|
||||||
|
isDot: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 显示的内容
|
||||||
|
value: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否显示
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 最大值,超过最大值会显示 '{max}+'
|
||||||
|
max: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 999
|
||||||
|
},
|
||||||
|
// 主题类型,error|warning|success|primary
|
||||||
|
type: {
|
||||||
|
type: [String,undefined,null],
|
||||||
|
default: 'error'
|
||||||
|
},
|
||||||
|
// 当数值为 0 时,是否展示 Badge
|
||||||
|
showZero: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 背景颜色,优先级比type高,如设置,type参数会失效
|
||||||
|
bgColor: {
|
||||||
|
type: [String, null],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// 字体颜色
|
||||||
|
color: {
|
||||||
|
type: [String, null],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
// 徽标形状,circle-四角均为圆角,horn-左下角为直角
|
||||||
|
shape: {
|
||||||
|
type: [String,undefined,null],
|
||||||
|
default: 'circle'
|
||||||
|
},
|
||||||
|
// 设置数字的显示方式,overflow|ellipsis|limit
|
||||||
|
// overflow会根据max字段判断,超出显示`${max}+`
|
||||||
|
// ellipsis会根据max判断,超出显示`${max}...`
|
||||||
|
// limit会依据1000作为判断条件,超出1000,显示`${value/1000}K`,比如2.2k、3.34w,最多保留2位小数
|
||||||
|
numberType: {
|
||||||
|
type: [String,undefined,null],
|
||||||
|
default: 'overflow'
|
||||||
|
},
|
||||||
|
// 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
|
||||||
|
offset: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
// 是否反转背景和字体颜色
|
||||||
|
inverted: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否绝对定位
|
||||||
|
absolute: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.badge
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,176 @@
|
|||||||
|
<template>
|
||||||
|
<text
|
||||||
|
v-if="show && ((Number(value) === 0 ? showZero : true) || isDot)"
|
||||||
|
:class="[isDot ? 'uv-badge--dot' : 'uv-badge--not-dot', inverted && 'uv-badge--inverted', shape === 'horn' && 'uv-badge--horn', `uv-badge--${propsType}${inverted ? '--inverted' : ''}`]"
|
||||||
|
:style="[$uv.addStyle(customStyle), badgeStyle]"
|
||||||
|
class="uv-badge"
|
||||||
|
>{{ isDot ? '' :showValue }}</text>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import props from './props.js';
|
||||||
|
/**
|
||||||
|
* badge 徽标数
|
||||||
|
* @description 该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。
|
||||||
|
* @tutorial https://www.uvui.cn/components/badge.html
|
||||||
|
*
|
||||||
|
* @property {Boolean} isDot 是否显示圆点 (默认 false )
|
||||||
|
* @property {String | Number} value 显示的内容
|
||||||
|
* @property {Boolean} show 是否显示 (默认 true )
|
||||||
|
* @property {String | Number} max 最大值,超过最大值会显示 '{max}+' (默认999)
|
||||||
|
* @property {String} type 主题类型,error|warning|success|primary (默认 'error' )
|
||||||
|
* @property {Boolean} showZero 当数值为 0 时,是否展示 Badge (默认 false )
|
||||||
|
* @property {String} bgColor 背景颜色,优先级比type高,如设置,type参数会失效
|
||||||
|
* @property {String} color 字体颜色 (默认 '#ffffff' )
|
||||||
|
* @property {String} shape 徽标形状,circle-四角均为圆角,horn-左下角为直角 (默认 'circle' )
|
||||||
|
* @property {String} numberType 设置数字的显示方式,overflow|ellipsis|limit (默认 'overflow' )
|
||||||
|
* @property {Array}} offset 设置badge的位置偏移,格式为 [x, y],也即设置的为top和right的值,absolute为true时有效
|
||||||
|
* @property {Boolean} inverted 是否反转背景和字体颜色(默认 false )
|
||||||
|
* @property {Boolean} absolute 是否绝对定位(默认 false )
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
* @example <uv-badge :type="type" :count="count"></uv-badge>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uv-badge',
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
computed: {
|
||||||
|
// 是否将badge中心与父组件右上角重合
|
||||||
|
boxStyle() {
|
||||||
|
let style = {};
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
// 整个组件的样式
|
||||||
|
badgeStyle() {
|
||||||
|
const style = {}
|
||||||
|
if(this.color) {
|
||||||
|
style.color = this.color
|
||||||
|
}
|
||||||
|
if (this.bgColor && !this.inverted) {
|
||||||
|
style.backgroundColor = this.bgColor
|
||||||
|
}
|
||||||
|
if (this.absolute) {
|
||||||
|
style.position = 'absolute'
|
||||||
|
// 如果有设置offset参数
|
||||||
|
if(this.offset.length) {
|
||||||
|
// top和right分为为offset的第一个和第二个值,如果没有第二个值,则right等于top
|
||||||
|
const top = this.offset[0]
|
||||||
|
const right = this.offset[1] || top
|
||||||
|
style.top = this.$uv.addUnit(top)
|
||||||
|
style.right = this.$uv.addUnit(right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style
|
||||||
|
},
|
||||||
|
showValue() {
|
||||||
|
switch (this.numberType) {
|
||||||
|
case "overflow":
|
||||||
|
return Number(this.value) > Number(this.max) ? this.max + "+" : this.value
|
||||||
|
break;
|
||||||
|
case "ellipsis":
|
||||||
|
return Number(this.value) > Number(this.max) ? "..." : this.value
|
||||||
|
break;
|
||||||
|
case "limit":
|
||||||
|
return Number(this.value) > 999 ? Number(this.value) >= 9999 ?
|
||||||
|
Math.floor(this.value / 1e4 * 100) / 100 + "w" : Math.floor(this.value /
|
||||||
|
1e3 * 100) / 100 + "k" : this.value
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return Number(this.value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
propsType(){
|
||||||
|
return this.type || 'error'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||||
|
$uv-badge-primary: $uv-primary !default;
|
||||||
|
$uv-badge-error: $uv-error !default;
|
||||||
|
$uv-badge-success: $uv-success !default;
|
||||||
|
$uv-badge-info: $uv-info !default;
|
||||||
|
$uv-badge-warning: $uv-warning !default;
|
||||||
|
$uv-badge-dot-radius: 100px !default;
|
||||||
|
$uv-badge-dot-size: 8px !default;
|
||||||
|
$uv-badge-dot-right: 4px !default;
|
||||||
|
$uv-badge-dot-top: 0 !default;
|
||||||
|
$uv-badge-text-font-size: 11px !default;
|
||||||
|
$uv-badge-text-right: 10px !default;
|
||||||
|
$uv-badge-text-padding: 2px 5px !default;
|
||||||
|
$uv-badge-text-align: center !default;
|
||||||
|
$uv-badge-text-color: #FFFFFF !default;
|
||||||
|
|
||||||
|
.uv-badge {
|
||||||
|
border-top-right-radius: $uv-badge-dot-radius;
|
||||||
|
border-top-left-radius: $uv-badge-dot-radius;
|
||||||
|
border-bottom-left-radius: $uv-badge-dot-radius;
|
||||||
|
border-bottom-right-radius: $uv-badge-dot-radius;
|
||||||
|
@include flex;
|
||||||
|
line-height: $uv-badge-text-font-size;
|
||||||
|
text-align: $uv-badge-text-align;
|
||||||
|
font-size: $uv-badge-text-font-size;
|
||||||
|
color: $uv-badge-text-color;
|
||||||
|
|
||||||
|
&--dot {
|
||||||
|
height: $uv-badge-dot-size;
|
||||||
|
width: $uv-badge-dot-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--inverted {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--not-dot {
|
||||||
|
padding: $uv-badge-text-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--horn {
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary {
|
||||||
|
background-color: $uv-badge-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary--inverted {
|
||||||
|
color: $uv-badge-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error {
|
||||||
|
background-color: $uv-badge-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error--inverted {
|
||||||
|
color: $uv-badge-error;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
background-color: $uv-badge-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success--inverted {
|
||||||
|
color: $uv-badge-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info {
|
||||||
|
background-color: $uv-badge-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info--inverted {
|
||||||
|
color: $uv-badge-info;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning {
|
||||||
|
background-color: $uv-badge-warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning--inverted {
|
||||||
|
color: $uv-badge-warning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
87
x_admin_app/uni_modules/uv-badge/package.json
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-badge",
|
||||||
|
"displayName": "uv-badge 徽标数,数字角标 全面兼容小程序、nvue、vue2、vue3等多端",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"description": "徽标数一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。",
|
||||||
|
"keywords": [
|
||||||
|
"uv-badge",
|
||||||
|
"uvui",
|
||||||
|
"uv-ui",
|
||||||
|
"徽标数",
|
||||||
|
"数字角标"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
x_admin_app/uni_modules/uv-badge/readme.md
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
## Badge 徽标数
|
||||||
|
|
||||||
|
> **组件名:uv-badge**
|
||||||
|
|
||||||
|
该组件一般用于图标右上角显示未读的消息数量,提示用户点击,有圆点和圆包含文字两种形式。
|
||||||
|
|
||||||
|
### <a href="https://www.uvui.cn/components/badge.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|
33
x_admin_app/uni_modules/uv-button/changelog.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
## 1.0.15(2023-12-20)
|
||||||
|
1. 优化
|
||||||
|
## 1.0.14(2023-12-06)
|
||||||
|
1. 优化
|
||||||
|
## 1.0.13(2023-12-06)
|
||||||
|
1. 阻止事件冒泡处理
|
||||||
|
## 1.0.12(2023-10-19)
|
||||||
|
1. 增加后置插槽
|
||||||
|
## 1.0.11(2023-09-21)
|
||||||
|
1. 修复通过customStyle修改按钮宽度,组件中最外层节点不改变的问题
|
||||||
|
## 1.0.10(2023-09-15)
|
||||||
|
1. 按钮支持open-type="agreePrivacyAuthorization"
|
||||||
|
## 1.0.9(2023-09-11)
|
||||||
|
1. 增加参数iconSize,用于控制图标的大小
|
||||||
|
## 1.0.8(2023-09-10)
|
||||||
|
1. 修复多个按钮在一行宽度不正常的BUG
|
||||||
|
## 1.0.7(2023-09-07)
|
||||||
|
1. 修复warning颜色对应错误的BUG
|
||||||
|
## 1.0.6(2023-07-25)
|
||||||
|
1. 增加customTextStyle属性,方便自定义文字样式
|
||||||
|
## 1.0.5(2023-07-20)
|
||||||
|
1. 解决微信小程序动态设置hover-class点击态不消失的BUG
|
||||||
|
## 1.0.4(2023-06-29)
|
||||||
|
1. 修改上次更新出现nvue报错异常
|
||||||
|
## 1.0.3(2023-06-28)
|
||||||
|
修复:设置open-type="chooseAvatar"等值不生效的BUG
|
||||||
|
## 1.0.2(2023-06-01)
|
||||||
|
1. 修复按钮点击触发两次的BUG
|
||||||
|
## 1.0.1(2023-05-16)
|
||||||
|
1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
|
||||||
|
2. 优化部分功能
|
||||||
|
## 1.0.0(2023-05-10)
|
||||||
|
uv-button 按钮
|
@@ -0,0 +1,46 @@
|
|||||||
|
$uv-button-active-opacity:0.75 !default;
|
||||||
|
$uv-button-loading-text-margin-left:4px !default;
|
||||||
|
$uv-button-text-color: #FFFFFF !default;
|
||||||
|
$uv-button-text-plain-error-color:$uv-error !default;
|
||||||
|
$uv-button-text-plain-warning-color:$uv-warning !default;
|
||||||
|
$uv-button-text-plain-success-color:$uv-success !default;
|
||||||
|
$uv-button-text-plain-info-color:$uv-info !default;
|
||||||
|
$uv-button-text-plain-primary-color:$uv-primary !default;
|
||||||
|
.uv-button {
|
||||||
|
&--active {
|
||||||
|
opacity: $uv-button-active-opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active--plain {
|
||||||
|
background-color: rgb(217, 217, 217);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__loading-text {
|
||||||
|
margin-left:$uv-button-loading-text-margin-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text,
|
||||||
|
&__loading-text {
|
||||||
|
color:$uv-button-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--error {
|
||||||
|
color:$uv-button-text-plain-error-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--warning {
|
||||||
|
color:$uv-button-text-plain-warning-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--success{
|
||||||
|
color:$uv-button-text-plain-success-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--info {
|
||||||
|
color:$uv-button-text-plain-info-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text--plain--primary {
|
||||||
|
color:$uv-button-text-plain-primary-color;
|
||||||
|
}
|
||||||
|
}
|
163
x_admin_app/uni_modules/uv-button/components/uv-button/props.js
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
// 是否细边框
|
||||||
|
hairline: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 按钮的预置样式,info,primary,error,warning,success
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'info'
|
||||||
|
},
|
||||||
|
// 按钮尺寸,large,normal,small,mini
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: 'normal'
|
||||||
|
},
|
||||||
|
// 按钮形状,circle(两边为半圆),square(带圆角)
|
||||||
|
shape: {
|
||||||
|
type: String,
|
||||||
|
default: 'square'
|
||||||
|
},
|
||||||
|
// 按钮是否镂空
|
||||||
|
plain: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否禁止状态
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否加载中
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 加载中提示文字
|
||||||
|
loadingText: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 加载状态图标类型
|
||||||
|
loadingMode: {
|
||||||
|
type: String,
|
||||||
|
default: 'spinner'
|
||||||
|
},
|
||||||
|
// 加载图标大小
|
||||||
|
loadingSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 14
|
||||||
|
},
|
||||||
|
// 开放能力,具体请看uniapp稳定关于button组件部分说明
|
||||||
|
// https://uniapp.dcloud.io/component/button
|
||||||
|
openType: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
|
||||||
|
// 取值为submit(提交表单),reset(重置表单)
|
||||||
|
formType: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效
|
||||||
|
// 只微信小程序、QQ小程序有效
|
||||||
|
appParameter: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效
|
||||||
|
hoverStopPropagation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效
|
||||||
|
lang: {
|
||||||
|
type: String,
|
||||||
|
default: 'en'
|
||||||
|
},
|
||||||
|
// 会话来源,open-type="contact"时有效。只微信小程序有效
|
||||||
|
sessionFrom: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 会话内消息卡片标题,open-type="contact"时有效
|
||||||
|
// 默认当前标题,只微信小程序有效
|
||||||
|
sendMessageTitle: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效
|
||||||
|
// 默认当前分享路径,只微信小程序有效
|
||||||
|
sendMessagePath: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 会话内消息卡片图片,open-type="contact"时有效
|
||||||
|
// 默认当前页面截图,只微信小程序有效
|
||||||
|
sendMessageImg: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,
|
||||||
|
// 用户点击后可以快速发送小程序消息,open-type="contact"时有效
|
||||||
|
showMessageCard: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
|
||||||
|
dataName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 节流,一定时间内只能触发一次
|
||||||
|
throttleTime: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// 按住后多久出现点击态,单位毫秒
|
||||||
|
hoverStartTime: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
// 手指松开后点击态保留时间,单位毫秒
|
||||||
|
hoverStayTime: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 200
|
||||||
|
},
|
||||||
|
// 按钮文字,之所以通过props传入,是因为slot传入的话
|
||||||
|
// nvue中无法控制文字的样式
|
||||||
|
text: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 按钮图标
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 按钮图标大小
|
||||||
|
iconSize: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 按钮图标颜色
|
||||||
|
iconColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#000000'
|
||||||
|
},
|
||||||
|
// 按钮颜色,支持传入linear-gradient渐变色
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 自定义按钮文本样式
|
||||||
|
customTextStyle: {
|
||||||
|
type: [Object,String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
...uni.$uv?.props?.button
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,528 @@
|
|||||||
|
<template>
|
||||||
|
<view
|
||||||
|
class="uv-button-wrapper"
|
||||||
|
:style="[btnWrapperStyle]"
|
||||||
|
>
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<!-- #ifdef MP -->
|
||||||
|
<!-- 为了解决微信小程序动态设置hover-class点击态不消失的BUG -->
|
||||||
|
<view class="uv-button-wrapper--dis" v-if="disabled || loading"></view>
|
||||||
|
<button
|
||||||
|
:hover-start-time="Number(hoverStartTime)"
|
||||||
|
:hover-stay-time="Number(hoverStayTime)"
|
||||||
|
:form-type="formType"
|
||||||
|
:open-type="openType"
|
||||||
|
:app-parameter="appParameter"
|
||||||
|
:hover-stop-propagation="hoverStopPropagation"
|
||||||
|
:send-message-title="sendMessageTitle"
|
||||||
|
:send-message-path="sendMessagePath"
|
||||||
|
:lang="lang"
|
||||||
|
:data-name="dataName"
|
||||||
|
:session-from="sessionFrom"
|
||||||
|
:send-message-img="sendMessageImg"
|
||||||
|
:show-message-card="showMessageCard"
|
||||||
|
@getphonenumber="onGetPhoneNumber"
|
||||||
|
@getuserinfo="onGetUserInfo"
|
||||||
|
@error="onError"
|
||||||
|
@opensetting="onOpenSetting"
|
||||||
|
@launchapp="onLaunchApp"
|
||||||
|
@contact="onContact"
|
||||||
|
@chooseavatar="onChooseavatar"
|
||||||
|
@agreeprivacyauthorization="onAgreeprivacyauthorization"
|
||||||
|
@addgroupapp="onAddgroupapp"
|
||||||
|
@chooseaddress="onChooseaddress"
|
||||||
|
@subscribe="onSubscribe"
|
||||||
|
@login="onLogin"
|
||||||
|
@im="onIm"
|
||||||
|
hover-class="uv-button--active"
|
||||||
|
class="uv-button uv-reset-button"
|
||||||
|
:style="[baseColor, $uv.addStyle(customStyle)]"
|
||||||
|
@tap="clickHandler"
|
||||||
|
:class="bemClass"
|
||||||
|
>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef MP -->
|
||||||
|
<button
|
||||||
|
:hover-start-time="Number(hoverStartTime)"
|
||||||
|
:hover-stay-time="Number(hoverStayTime)"
|
||||||
|
:form-type="formType"
|
||||||
|
:open-type="openType"
|
||||||
|
:app-parameter="appParameter"
|
||||||
|
:hover-stop-propagation="hoverStopPropagation"
|
||||||
|
:send-message-title="sendMessageTitle"
|
||||||
|
:send-message-path="sendMessagePath"
|
||||||
|
:lang="lang"
|
||||||
|
:data-name="dataName"
|
||||||
|
:session-from="sessionFrom"
|
||||||
|
:send-message-img="sendMessageImg"
|
||||||
|
:show-message-card="showMessageCard"
|
||||||
|
:hover-class="!disabled && !loading ? 'uv-button--active' : ''"
|
||||||
|
class="uv-button uv-reset-button"
|
||||||
|
:style="[baseColor, $uv.addStyle(customStyle)]"
|
||||||
|
@tap="clickHandler"
|
||||||
|
:class="bemClass"
|
||||||
|
>
|
||||||
|
<!-- #endif -->
|
||||||
|
<template v-if="loading">
|
||||||
|
<uv-loading-icon
|
||||||
|
:mode="loadingMode"
|
||||||
|
:size="loadingSize * 1.15"
|
||||||
|
:color="loadingColor"
|
||||||
|
></uv-loading-icon>
|
||||||
|
<text
|
||||||
|
class="uv-button__loading-text"
|
||||||
|
:style="[
|
||||||
|
{ fontSize: textSize + 'px' },
|
||||||
|
$uv.addStyle(customTextStyle)
|
||||||
|
]"
|
||||||
|
>{{ loadingText || text }}</text>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<uv-icon
|
||||||
|
v-if="icon"
|
||||||
|
:name="icon"
|
||||||
|
:color="iconColorCom"
|
||||||
|
:size="getIconSize"
|
||||||
|
:customStyle="{ marginRight: '2px' }"
|
||||||
|
></uv-icon>
|
||||||
|
<slot>
|
||||||
|
<text
|
||||||
|
class="uv-button__text"
|
||||||
|
:style="[
|
||||||
|
{ fontSize: textSize + 'px' },
|
||||||
|
$uv.addStyle(customTextStyle)
|
||||||
|
]"
|
||||||
|
>{{ text }}</text>
|
||||||
|
</slot>
|
||||||
|
<slot name="suffix"></slot>
|
||||||
|
</template>
|
||||||
|
</button>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<view
|
||||||
|
:hover-start-time="Number(hoverStartTime)"
|
||||||
|
:hover-stay-time="Number(hoverStayTime)"
|
||||||
|
class="uv-button"
|
||||||
|
:hover-class="
|
||||||
|
!disabled && !loading && !color && (plain || type === 'info')
|
||||||
|
? 'uv-button--active--plain'
|
||||||
|
: !disabled && !loading && !plain
|
||||||
|
? 'uv-button--active'
|
||||||
|
: ''
|
||||||
|
"
|
||||||
|
@tap="clickHandler"
|
||||||
|
:class="bemClass"
|
||||||
|
:style="[baseColor, $uv.addStyle(customStyle)]"
|
||||||
|
>
|
||||||
|
<template v-if="loading">
|
||||||
|
<uv-loading-icon
|
||||||
|
:mode="loadingMode"
|
||||||
|
:size="loadingSize * 1.15"
|
||||||
|
:color="loadingColor"
|
||||||
|
></uv-loading-icon>
|
||||||
|
<text
|
||||||
|
class="uv-button__loading-text"
|
||||||
|
:style="[nvueTextStyle,$uv.addStyle(customTextStyle)]"
|
||||||
|
:class="[plain && `uv-button__text--plain--${type}`]"
|
||||||
|
>{{ loadingText || text }}</text>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<uv-icon
|
||||||
|
v-if="icon"
|
||||||
|
:name="icon"
|
||||||
|
:color="iconColorCom"
|
||||||
|
:size="getIconSize"
|
||||||
|
></uv-icon>
|
||||||
|
<text
|
||||||
|
class="uv-button__text"
|
||||||
|
:style="[
|
||||||
|
{
|
||||||
|
marginLeft: icon ? '2px' : 0,
|
||||||
|
},
|
||||||
|
nvueTextStyle,
|
||||||
|
$uv.addStyle(customTextStyle)
|
||||||
|
]"
|
||||||
|
:class="[plain && `uv-button__text--plain--${type}`]"
|
||||||
|
>{{ text }}</text>
|
||||||
|
<slot name="suffix"></slot>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import throttle from '@/uni_modules/uv-ui-tools/libs/function/throttle.js';
|
||||||
|
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
|
||||||
|
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
|
||||||
|
import button from '@/uni_modules/uv-ui-tools/libs/mixin/button.js'
|
||||||
|
import openType from '@/uni_modules/uv-ui-tools/libs/mixin/openType.js'
|
||||||
|
import props from "./props.js";
|
||||||
|
/**
|
||||||
|
* button 按钮
|
||||||
|
* @description Button 按钮
|
||||||
|
* @tutorial https://www.uvui.cn/components/button.html
|
||||||
|
* @property {Boolean} hairline 是否显示按钮的细边框 (默认 true )
|
||||||
|
* @property {String} type 按钮的预置样式,info,primary,error,warning,success (默认 'info' )
|
||||||
|
* @property {String} size 按钮尺寸,large,normal,mini (默认 normal)
|
||||||
|
* @property {String} shape 按钮形状,circle(两边为半圆),square(带圆角) (默认 'square' )
|
||||||
|
* @property {Boolean} plain 按钮是否镂空,背景色透明 (默认 false)
|
||||||
|
* @property {Boolean} disabled 是否禁用 (默认 false)
|
||||||
|
* @property {Boolean} loading 按钮名称前是否带 loading 图标(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) (默认 false)
|
||||||
|
* @property {String | Number} loadingText 加载中提示文字
|
||||||
|
* @property {String} loadingMode 加载状态图标类型 (默认 'spinner' )
|
||||||
|
* @property {String | Number} loadingSize 加载图标大小 (默认 15 )
|
||||||
|
* @property {String} openType 开放能力,具体请看uniapp稳定关于button组件部分说明
|
||||||
|
* @property {String} formType 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件
|
||||||
|
* @property {String} appParameter 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 (注:只微信小程序、QQ小程序有效)
|
||||||
|
* @property {Boolean} hoverStopPropagation 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效(默认 true )
|
||||||
|
* @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文(默认 en )
|
||||||
|
* @property {String} sessionFrom 会话来源,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
|
||||||
|
* @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
|
||||||
|
* @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
|
||||||
|
* @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效(默认false)
|
||||||
|
* @property {String} dataName 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取
|
||||||
|
* @property {String | Number} throttleTime 节流,一定时间内只能触发一次 (默认 0 )
|
||||||
|
* @property {String | Number} hoverStartTime 按住后多久出现点击态,单位毫秒 (默认 0 )
|
||||||
|
* @property {String | Number} hoverStayTime 手指松开后点击态保留时间,单位毫秒 (默认 200 )
|
||||||
|
* @property {String | Number} text 按钮文字,之所以通过props传入,是因为slot传入的话(注:nvue中无法控制文字的样式)
|
||||||
|
* @property {String} icon 按钮图标
|
||||||
|
* @property {String} iconColor 按钮图标颜色
|
||||||
|
* @property {String} color 按钮颜色,支持传入linear-gradient渐变色
|
||||||
|
* @property {Object} customStyle 定义需要用到的外部样式
|
||||||
|
* @event {Function} click 非禁止并且非加载中,才能点击
|
||||||
|
* @event {Function} getphonenumber open-type="getPhoneNumber"时有效
|
||||||
|
* @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo
|
||||||
|
* @event {Function} error 当使用开放能力时,发生错误的回调
|
||||||
|
* @event {Function} opensetting 在打开授权设置页并关闭后回调
|
||||||
|
* @event {Function} launchapp 打开 APP 成功的回调
|
||||||
|
* @example <uv-button>月落</uv-button>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: "uv-button",
|
||||||
|
// #ifdef MP
|
||||||
|
mixins: [mpMixin, mixin, button, openType, props],
|
||||||
|
// #endif
|
||||||
|
// #ifndef MP
|
||||||
|
mixins: [mpMixin, mixin, props],
|
||||||
|
// #endif
|
||||||
|
emits: ['click'],
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 生成bem风格的类名
|
||||||
|
bemClass() {
|
||||||
|
// this.bem为一个computed变量,在mixin中
|
||||||
|
if (!this.color) {
|
||||||
|
return this.bem("button",
|
||||||
|
["type", "shape", "size"],
|
||||||
|
["disabled", "plain", "hairline"]);
|
||||||
|
} else {
|
||||||
|
// 由于nvue的原因,在有color参数时,不需要传入type,否则会生成type相关的类型,影响最终的样式
|
||||||
|
return this.bem("button",
|
||||||
|
["shape", "size"],
|
||||||
|
["disabled", "plain", "hairline"]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loadingColor() {
|
||||||
|
if (this.plain) {
|
||||||
|
// 如果有设置color值,则用color值,否则使用type主题颜色
|
||||||
|
return this.color ? this.color : '#3c9cff';
|
||||||
|
}
|
||||||
|
if (this.type === "info") {
|
||||||
|
return "#c9c9c9";
|
||||||
|
}
|
||||||
|
return "rgb(200, 200, 200)";
|
||||||
|
},
|
||||||
|
iconColorCom() {
|
||||||
|
// 如果是镂空状态,设置了color就用color值,否则使用主题颜色,
|
||||||
|
// uv-icon的color能接受一个主题颜色的值
|
||||||
|
if (this.iconColor) return this.iconColor;
|
||||||
|
if (this.plain) {
|
||||||
|
return this.color ? this.color : this.type;
|
||||||
|
} else {
|
||||||
|
return this.type === "info" ? "#000000" : "#ffffff";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
baseColor() {
|
||||||
|
let style = {};
|
||||||
|
if (this.color) {
|
||||||
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
||||||
|
style.color = this.plain ? this.color : "white";
|
||||||
|
if (!this.plain) {
|
||||||
|
// 非镂空,背景色使用自定义的颜色
|
||||||
|
style["background-color"] = this.color;
|
||||||
|
}
|
||||||
|
if (this.color.indexOf("gradient") !== -1) {
|
||||||
|
// 如果自定义的颜色为渐变色,不显示边框,以及通过backgroundImage设置渐变色
|
||||||
|
// weex文档说明可以写borderWidth的形式,为什么这里需要分开写?
|
||||||
|
// 因为weex是阿里巴巴为了部门业绩考核而做的你懂的东西,所以需要这么写才有效
|
||||||
|
style.borderTopWidth = 0;
|
||||||
|
style.borderRightWidth = 0;
|
||||||
|
style.borderBottomWidth = 0;
|
||||||
|
style.borderLeftWidth = 0;
|
||||||
|
if (!this.plain) {
|
||||||
|
style.backgroundImage = this.color;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 非渐变色,则设置边框相关的属性
|
||||||
|
style.borderColor = this.color;
|
||||||
|
style.borderWidth = "1px";
|
||||||
|
style.borderStyle = "solid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
// nvue版本按钮的字体不会继承父组件的颜色,需要对每一个text组件进行单独的设置
|
||||||
|
nvueTextStyle() {
|
||||||
|
let style = {};
|
||||||
|
// 针对自定义了color颜色的情况,镂空状态下,就是用自定义的颜色
|
||||||
|
if (this.type === "info") {
|
||||||
|
style.color = "#323233";
|
||||||
|
}
|
||||||
|
if (this.color) {
|
||||||
|
style.color = this.plain ? this.color : "white";
|
||||||
|
}
|
||||||
|
style.fontSize = this.textSize + "px";
|
||||||
|
return style;
|
||||||
|
},
|
||||||
|
// 字体大小
|
||||||
|
textSize() {
|
||||||
|
let fontSize = 14,
|
||||||
|
{ size } = this;
|
||||||
|
if (size === "large") fontSize = 16;
|
||||||
|
if (size === "normal") fontSize = 14;
|
||||||
|
if (size === "small") fontSize = 12;
|
||||||
|
if (size === "mini") fontSize = 10;
|
||||||
|
return fontSize;
|
||||||
|
},
|
||||||
|
// 设置图标大小
|
||||||
|
getIconSize() {
|
||||||
|
const size = this.iconSize ? this.iconSize : this.textSize * 1.35;
|
||||||
|
return this.$uv.addUnit(size);
|
||||||
|
},
|
||||||
|
// 设置外层盒子的宽度,其他样式不需要
|
||||||
|
btnWrapperStyle() {
|
||||||
|
const style = {};
|
||||||
|
const customStyle = this.$uv.addStyle(this.customStyle);
|
||||||
|
if(customStyle.width) style.width = customStyle.width;
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clickHandler() {
|
||||||
|
// 非禁止并且非加载中,才能点击
|
||||||
|
if (!this.disabled && !this.loading) {
|
||||||
|
// 进行节流控制,每this.throttle毫秒内,只在开始处执行
|
||||||
|
throttle(() => {
|
||||||
|
this.$emit("click");
|
||||||
|
}, this.throttleTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
$show-reset-button: 1;
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/variable.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
|
||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||||
|
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
@import "./vue.scss";
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
@import "./nvue.scss";
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
$uv-button-uv-button-height: 40px !default;
|
||||||
|
$uv-button-text-font-size: 15px !default;
|
||||||
|
$uv-button-loading-text-font-size: 15px !default;
|
||||||
|
$uv-button-loading-text-margin-left: 4px !default;
|
||||||
|
$uv-button-large-width: 100% !default;
|
||||||
|
$uv-button-large-height: 50px !default;
|
||||||
|
$uv-button-normal-padding: 0 12px !default;
|
||||||
|
$uv-button-large-padding: 0 15px !default;
|
||||||
|
$uv-button-normal-font-size: 14px !default;
|
||||||
|
$uv-button-small-min-width: 60px !default;
|
||||||
|
$uv-button-small-height: 30px !default;
|
||||||
|
$uv-button-small-padding: 0px 8px !default;
|
||||||
|
$uv-button-mini-padding: 0px 8px !default;
|
||||||
|
$uv-button-small-font-size: 12px !default;
|
||||||
|
$uv-button-mini-height: 22px !default;
|
||||||
|
$uv-button-mini-font-size: 10px !default;
|
||||||
|
$uv-button-mini-min-width: 50px !default;
|
||||||
|
$uv-button-disabled-opacity: 0.5 !default;
|
||||||
|
$uv-button-info-color: #323233 !default;
|
||||||
|
$uv-button-info-background-color: #fff !default;
|
||||||
|
$uv-button-info-border-color: #ebedf0 !default;
|
||||||
|
$uv-button-info-border-width: 1px !default;
|
||||||
|
$uv-button-info-border-style: solid !default;
|
||||||
|
$uv-button-success-color: #fff !default;
|
||||||
|
$uv-button-success-background-color: $uv-success !default;
|
||||||
|
$uv-button-success-border-color: $uv-button-success-background-color !default;
|
||||||
|
$uv-button-success-border-width: 1px !default;
|
||||||
|
$uv-button-success-border-style: solid !default;
|
||||||
|
$uv-button-primary-color: #fff !default;
|
||||||
|
$uv-button-primary-background-color: $uv-primary !default;
|
||||||
|
$uv-button-primary-border-color: $uv-button-primary-background-color !default;
|
||||||
|
$uv-button-primary-border-width: 1px !default;
|
||||||
|
$uv-button-primary-border-style: solid !default;
|
||||||
|
$uv-button-error-color: #fff !default;
|
||||||
|
$uv-button-error-background-color: $uv-error !default;
|
||||||
|
$uv-button-error-border-color: $uv-button-error-background-color !default;
|
||||||
|
$uv-button-error-border-width: 1px !default;
|
||||||
|
$uv-button-error-border-style: solid !default;
|
||||||
|
$uv-button-warning-color: #fff !default;
|
||||||
|
$uv-button-warning-background-color: $uv-warning !default;
|
||||||
|
$uv-button-warning-border-color: $uv-button-warning-background-color !default;
|
||||||
|
$uv-button-warning-border-width: 1px !default;
|
||||||
|
$uv-button-warning-border-style: solid !default;
|
||||||
|
$uv-button-block-width: 100% !default;
|
||||||
|
$uv-button-circle-border-top-right-radius: 100px !default;
|
||||||
|
$uv-button-circle-border-top-left-radius: 100px !default;
|
||||||
|
$uv-button-circle-border-bottom-left-radius: 100px !default;
|
||||||
|
$uv-button-circle-border-bottom-right-radius: 100px !default;
|
||||||
|
$uv-button-square-border-top-right-radius: 3px !default;
|
||||||
|
$uv-button-square-border-top-left-radius: 3px !default;
|
||||||
|
$uv-button-square-border-bottom-left-radius: 3px !default;
|
||||||
|
$uv-button-square-border-bottom-right-radius: 3px !default;
|
||||||
|
$uv-button-icon-min-width: 1em !default;
|
||||||
|
$uv-button-plain-background-color: #fff !default;
|
||||||
|
$uv-button-hairline-border-width: 0.5px !default;
|
||||||
|
|
||||||
|
.uv-button {
|
||||||
|
height: $uv-button-uv-button-height;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
@include flex;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
font-size: $uv-button-text-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__loading-text {
|
||||||
|
font-size: $uv-button-loading-text-font-size;
|
||||||
|
margin-left: $uv-button-loading-text-margin-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--large {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
width: $uv-button-large-width;
|
||||||
|
/* #endif */
|
||||||
|
height: $uv-button-large-height;
|
||||||
|
padding: $uv-button-large-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--normal {
|
||||||
|
padding: $uv-button-normal-padding;
|
||||||
|
font-size: $uv-button-normal-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--small {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
min-width: $uv-button-small-min-width;
|
||||||
|
/* #endif */
|
||||||
|
height: $uv-button-small-height;
|
||||||
|
padding: $uv-button-small-padding;
|
||||||
|
font-size: $uv-button-small-font-size;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--mini {
|
||||||
|
height: $uv-button-mini-height;
|
||||||
|
font-size: $uv-button-mini-font-size;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
min-width: $uv-button-mini-min-width;
|
||||||
|
/* #endif */
|
||||||
|
padding: $uv-button-mini-padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
opacity: $uv-button-disabled-opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--info {
|
||||||
|
color: $uv-button-info-color;
|
||||||
|
background-color: $uv-button-info-background-color;
|
||||||
|
border-color: $uv-button-info-border-color;
|
||||||
|
border-width: $uv-button-info-border-width;
|
||||||
|
border-style: $uv-button-info-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--success {
|
||||||
|
color: $uv-button-success-color;
|
||||||
|
background-color: $uv-button-success-background-color;
|
||||||
|
border-color: $uv-button-success-border-color;
|
||||||
|
border-width: $uv-button-success-border-width;
|
||||||
|
border-style: $uv-button-success-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--primary {
|
||||||
|
color: $uv-button-primary-color;
|
||||||
|
background-color: $uv-button-primary-background-color;
|
||||||
|
border-color: $uv-button-primary-border-color;
|
||||||
|
border-width: $uv-button-primary-border-width;
|
||||||
|
border-style: $uv-button-primary-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--error {
|
||||||
|
color: $uv-button-error-color;
|
||||||
|
background-color: $uv-button-error-background-color;
|
||||||
|
border-color: $uv-button-error-border-color;
|
||||||
|
border-width: $uv-button-error-border-width;
|
||||||
|
border-style: $uv-button-error-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--warning {
|
||||||
|
color: $uv-button-warning-color;
|
||||||
|
background-color: $uv-button-warning-background-color;
|
||||||
|
border-color: $uv-button-warning-border-color;
|
||||||
|
border-width: $uv-button-warning-border-width;
|
||||||
|
border-style: $uv-button-warning-border-style;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--block {
|
||||||
|
@include flex;
|
||||||
|
width: $uv-button-block-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--circle {
|
||||||
|
border-top-right-radius: $uv-button-circle-border-top-right-radius;
|
||||||
|
border-top-left-radius: $uv-button-circle-border-top-left-radius;
|
||||||
|
border-bottom-left-radius: $uv-button-circle-border-bottom-left-radius;
|
||||||
|
border-bottom-right-radius: $uv-button-circle-border-bottom-right-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--square {
|
||||||
|
border-bottom-left-radius: $uv-button-square-border-top-right-radius;
|
||||||
|
border-bottom-right-radius: $uv-button-square-border-top-left-radius;
|
||||||
|
border-top-left-radius: $uv-button-square-border-bottom-left-radius;
|
||||||
|
border-top-right-radius: $uv-button-square-border-bottom-right-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
min-width: $uv-button-icon-min-width;
|
||||||
|
line-height: inherit !important;
|
||||||
|
vertical-align: top;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
background-color: $uv-button-plain-background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--hairline {
|
||||||
|
border-width: $uv-button-hairline-border-width !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@@ -0,0 +1,93 @@
|
|||||||
|
@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
|
||||||
|
// nvue下hover-class无效
|
||||||
|
$uv-button-before-top:50% !default;
|
||||||
|
$uv-button-before-left:50% !default;
|
||||||
|
$uv-button-before-width:100% !default;
|
||||||
|
$uv-button-before-height:100% !default;
|
||||||
|
$uv-button-before-transform:translate(-50%, -50%) !default;
|
||||||
|
$uv-button-before-opacity:0 !default;
|
||||||
|
$uv-button-before-background-color:#000 !default;
|
||||||
|
$uv-button-before-border-color:#000 !default;
|
||||||
|
$uv-button-active-before-opacity:.15 !default;
|
||||||
|
$uv-button-icon-margin-left:4px !default;
|
||||||
|
$uv-button-plain-uv-button-info-color:$uv-info;
|
||||||
|
$uv-button-plain-uv-button-success-color:$uv-success;
|
||||||
|
$uv-button-plain-uv-button-error-color:$uv-error;
|
||||||
|
$uv-button-plain-uv-button-warning-color:$uv-warning;
|
||||||
|
|
||||||
|
.uv-button-wrapper {
|
||||||
|
position: relative;
|
||||||
|
&--dis {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.uv-button {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
position: absolute;
|
||||||
|
top:$uv-button-before-top;
|
||||||
|
left:$uv-button-before-left;
|
||||||
|
width:$uv-button-before-width;
|
||||||
|
height:$uv-button-before-height;
|
||||||
|
border: inherit;
|
||||||
|
border-radius: inherit;
|
||||||
|
transform:$uv-button-before-transform;
|
||||||
|
opacity:$uv-button-before-opacity;
|
||||||
|
content: " ";
|
||||||
|
background-color:$uv-button-before-background-color;
|
||||||
|
border-color:$uv-button-before-border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--active {
|
||||||
|
&:before {
|
||||||
|
opacity: .15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__icon+&__text:not(:empty),
|
||||||
|
&__loading-text {
|
||||||
|
margin-left:$uv-button-icon-margin-left;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.uv-button--primary {
|
||||||
|
color: $uv-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.uv-button--info {
|
||||||
|
color:$uv-button-plain-uv-button-info-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.uv-button--success {
|
||||||
|
color:$uv-button-plain-uv-button-success-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.uv-button--error {
|
||||||
|
color:$uv-button-plain-uv-button-error-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--plain {
|
||||||
|
&.uv-button--warning {
|
||||||
|
color:$uv-button-plain-uv-button-warning-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
x_admin_app/uni_modules/uv-button/package.json
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"id": "uv-button",
|
||||||
|
"displayName": "uv-button 按钮 全面兼容vue3+2、app、h5、小程序等多端",
|
||||||
|
"version": "1.0.15",
|
||||||
|
"description": "按钮组件内部实现以uni-app的button组件为基础,进行二次封装,灵活配置,功能齐全,兼容全端。",
|
||||||
|
"keywords": [
|
||||||
|
"uv-button",
|
||||||
|
"uvui",
|
||||||
|
"uv-ui",
|
||||||
|
"button",
|
||||||
|
"按钮"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uv-ui-tools",
|
||||||
|
"uv-loading-icon",
|
||||||
|
"uv-icon"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
x_admin_app/uni_modules/uv-button/readme.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
## Button 按钮
|
||||||
|
|
||||||
|
> **组件名:uv-button**
|
||||||
|
|
||||||
|
该组件内部实现以`uni-app`的`button`组件为基础,进行二次封装,灵活配置,功能齐全,兼容全端。灵活配置,内置状态设置,开箱即用。
|
||||||
|
|
||||||
|
# <a href="https://www.uvui.cn/components/button.html" target="_blank">查看文档</a>
|
||||||
|
|
||||||
|
## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small>
|
||||||
|
|
||||||
|
### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
|
||||||
|
|
||||||
|
<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
</a>
|
||||||
|
|
||||||
|
#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>
|