微信小程序优化

This commit is contained in:
ktianc 2024-03-23 16:52:47 +08:00
parent 53c12a787e
commit 76bd8ed3fe
12 changed files with 595 additions and 47 deletions

21
.gitignore vendored
View File

@ -1,22 +1 @@
# Build and Release Folders
bin-debug/
bin-release/
[Oo]bj/
[Bb]in/
# Other files and folders
.settings/
# Executables
*.swf
*.air
*.ipa
*.apk
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
docker_env/mysql/data/
docker_env/redis/data/
*/.idea
dvadmin-doc/docs/.vuepress/dist

View File

@ -12,7 +12,7 @@ const { start, done } = useNProgress()
const { loadStart, loadDone } = usePageLoading()
const whiteList = ['/login'] // 不重定向白名单
const whiteList = ['/login', '/docs/privacy', '/docs/agreement'] // 不重定向白名单
router.beforeEach(async (to, from, next) => {
start()

View File

@ -70,6 +70,37 @@ export const constantRouterMap: AppRouteRecordRaw[] = [
noTagsView: true
}
},
{
path: '/docs',
name: 'Docs',
meta: {
hidden: true,
title: '在线文档',
noTagsView: true
},
children: [
{
path: 'privacy',
name: 'Privacy',
component: () => import('@/views/Vadmin/Docs/Privacy.vue'),
meta: {
hidden: true,
title: '隐私政策',
noTagsView: true
}
},
{
path: 'agreement',
name: 'Agreement',
component: () => import('@/views/Vadmin/Docs/Agreement.vue'),
meta: {
hidden: true,
title: '用户协议',
noTagsView: true
}
}
]
},
{
path: '/404',
component: () => import('@/views/Error/404.vue'),
@ -115,7 +146,17 @@ const router = createRouter({
})
export const resetRouter = (): void => {
const resetWhiteNameList = ['Login', 'NoFind', 'Root', 'ResetPassword', 'Redirect', 'Home']
const resetWhiteNameList = [
'Login',
'NoFind',
'Root',
'ResetPassword',
'Redirect',
'Home',
'Docs',
'Privacy',
'Agreement'
]
router.getRoutes().forEach((route) => {
const { name } = route
if (name && !resetWhiteNameList.includes(name as string)) {

View File

@ -0,0 +1,29 @@
<script setup lang="ts">
import { ref } from 'vue'
import { getSystemAgreementApi } from '@/api/vadmin/system/settings'
const content = ref(null)
//
const getSystemConfig = async () => {
const res = await getSystemAgreementApi()
if (res) {
content.value = res.data
}
}
getSystemConfig()
</script>
<template>
<div class="content-view" v-html="content"></div>
</template>
<style scoped lang="less">
.content-view {
padding: 20px;
overflow-y: scroll;
overflow-x: hidden;
height: 100%;
}
</style>

View File

@ -0,0 +1,29 @@
<script setup lang="ts">
import { ref } from 'vue'
import { getSystemPrivacyApi } from '@/api/vadmin/system/settings'
const content = ref(null)
//
const getSystemConfig = async () => {
const res = await getSystemPrivacyApi()
if (res) {
content.value = res.data
}
}
getSystemConfig()
</script>
<template>
<div class="content-view" v-html="content"></div>
</template>
<style scoped lang="less">
.content-view {
padding: 20px;
overflow-y: scroll;
overflow-x: hidden;
height: 100%;
}
</style>

View File

@ -170,12 +170,12 @@ async def get_setting_base_config(db: AsyncSession = Depends(db_getter)):
@app.get("/settings/privacy", summary="获取隐私协议")
async def get_settings_privacy(auth: Auth = Depends(FullAdminAuth())):
async def get_settings_privacy(auth: Auth = Depends(OpenAuth())):
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_privacy")).config_value)
@app.get("/settings/agreement", summary="获取用户协议")
async def get_settings_agreement(auth: Auth = Depends(FullAdminAuth())):
async def get_settings_agreement(auth: Auth = Depends(OpenAuth())):
return SuccessResponse((await crud.SettingsDal(auth.db).get_data(config_key="web_agreement")).config_value)

View File

@ -26,6 +26,11 @@ uni.$u.setConfig({
size: 33,
labelSize: 30
},
checkbox: {
size: 33,
labelSize: 30,
iconSize: 20
},
button: {
loadingSize: 28
},

View File

@ -30,23 +30,42 @@
<!-- <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button> -->
<u-button type="primary" text="登录" shape="circle" @click="handleLogin"></u-button>
</view>
<view class="xieyi flex justify-start">
<zb-tooltip :visible.sync="tooltipVisible" content="请阅读并同意" placement="top" ref="tooltip" >
<view>
<!-- <text class="text-grey1">等内容</text> -->
<u-checkbox-group v-model="isAgrement" shape="circle" @change="checkboxChange">
<u-checkbox></u-checkbox>
</u-checkbox-group>
</view>
</zb-tooltip>
<view>
<text class="text-grey1">允许我们在必要场景下合理使用您的个人信息且阅读并同意</text>
<text class="text-blue" @click="handleUserAgrement">用户协议</text>
<text class="text-blue" @click="handlePrivacy">隐私协议</text>
<text class="text-grey1">等内容</text>
</view>
</view>
</view>
<view class="xieyi text-center">
<text class="text-grey1">登录即代表同意</text>
<text class="text-blue" @click="handleUserAgrement">用户协议</text>
<text class="text-blue" @click="handlePrivacy">隐私协议</text>
</view>
<view class="footer text-center">
<!-- <view class="footer text-center">
<u-button
v-if="isAgrement"
type="primary"
text="微信一键登录"
shape="circle"
open-type="getPhoneNumber"
@getphonenumber="wxLogin"
></u-button>
</view>
<u-button
v-else
type="primary"
text="微信一键登录"
shape="circle"
@click="wxLogin"
></u-button>
</view> -->
</view>
</template>
@ -60,7 +79,9 @@ export default {
loginForm: {
telephone: '15020221010',
password: 'kinit2022'
}
},
isAgrement: false,
tooltipVisible: false
}
},
computed: {
@ -96,14 +117,18 @@ export default {
},
//
async handleLogin() {
if (this.loginForm.telephone === '') {
this.$modal.msgError('请输入您的手机号')
} else if (this.loginForm.password === '') {
this.$modal.msgError('请输入您的密码')
} else {
this.$modal.loading('正在登录中...')
this.pwdLogin()
}
if (this.isAgrement) {
if (this.loginForm.telephone === '') {
this.$modal.msgError('请输入您的手机号')
} else if (this.loginForm.password === '') {
this.$modal.msgError('请输入您的密码')
} else {
this.$modal.loading('正在登录中...')
this.pwdLogin()
}
} else {
this.tooltipVisible = true
}
},
//
async pwdLogin() {
@ -122,10 +147,23 @@ export default {
},
//
wxLogin(detail) {
this.onGetPhoneNumber(detail).then((res) => {
this.loginSuccess()
})
}
if (this.isAgrement) {
this.onGetPhoneNumber(detail).then((res) => {
this.loginSuccess()
})
} else {
this.tooltipVisible = true
}
},
//
checkboxChange() {
this.isAgrement = !this.isAgrement
this.tooltipClose()
},
//
tooltipClose() {
this.tooltipVisible = false
}
}
}
</script>
@ -156,7 +194,7 @@ page {
}
.login-form-content {
text-align: center;
// text-align: center;
margin: 20px auto;
margin-top: 15%;
width: 80%;

View File

@ -0,0 +1,24 @@
## 1.0.112023-01-29
优化点击,加入点击自己再次点击也会关闭
## 1.0.102023-01-17
优化
## 1.0.92023-01-17
增加注释
## 1.0.82022-08-18
优化细节
## 1.0.672022-05-09
修复安卓报错
## 1.0.62022-05-07
修改默认展示
## 1.0.52022-04-28
进行优化
## 1.0.42022-04-27
进行优化
## 1.0.32022-04-25
去掉多余得注释
## 1.0.22022-04-25
增加自定义主题颜色
## 1.0.12022-04-25
进行优化显示
## 1.0.02022-04-24
初始化

View File

@ -0,0 +1,290 @@
<template>
<view class="zb-tooltip" :style="{
'--theme-bg-color':color
}">
<view class="zb_tooltip_content" @click.stop="handleClick">
<slot></slot>
<view class="zb_tooltip__popper"
@click.stop="()=>{}"
:style="[style,{
visibility:isShow?'visible':'hidden',
color:color==='white'?'':'#fff',
boxShadow: color==='white'?'0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d':''
}]" >
<slot name="content">{{content}}</slot>
<view class="zb_popper__icon" :style="[arrowStyle]" :class="[{
'zb_popper__up':placement.indexOf('bottom')===0,
'zb_popper__arrow':placement.indexOf('top')===0,
'zb_popper__right':placement.indexOf('right')===0,
'zb_popper__left':placement.indexOf('left')===0,
}]">
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props:{
visible:Boolean,
color:{
type:String,
default:'#303133',
},
placement:{
type:String,
default:'top',
},
content:{
type:String,
default:''
},
show:{
type:Boolean,
default:false,
}
},
data() {
return {
isShow :this.visible,
title: 'Hello',
arrowLeft:0,
query:null,
style:{
},
arrowStyle:{}
}
},
onLoad() {
},
watch:{
isShow:{
handler(val){
this.$emit('update:visible', val)
},
immediate:true,
},
visible:{
handler(val){
if(val){
this.$nextTick(()=>{
this.getPosition()
})
}
this.isShow = val
},
immediate:true,
}
},
mounted(){
// #ifdef H5
window.addEventListener('click',()=>{
this.isShow = false
})
// #endif
this.getPosition()
},
methods: {
close(){
this.isShow = false
},
fixedWrap(){
this.isShow = false
},
async handleClick(){
if(this.isShow){
return this.isShow = false
}
await this.getPosition()
this.isShow = true
},
getPosition(){
return new Promise((resolve) => {
uni.createSelectorQuery().in(this).selectAll('.zb_tooltip_content,.zb_tooltip__popper').boundingClientRect(async (data)=>{
let {left,bottom,right,top,width,height} = data[0]
let obj1 = data[1]
let objStyle = {}
let objStyle1 = {}
switch(this.placement){
case 'top':
if(obj1.width > width){
objStyle.left = `-${(obj1.width - width)/2}px`
}else{
objStyle.left = `${Math.abs(obj1.width - width)/2}px`
}
objStyle.bottom =`${height+8}px`
objStyle1.left = (obj1.width/2-6)+'px'
break;
case 'top-start':
objStyle.left = `0px`
objStyle.bottom =`${height+8}px`
break;
case 'top-end':
objStyle.right = `0px`
objStyle.bottom =`${height+8}px`
objStyle1.right=`8px`
break;
case 'bottom':
if(obj1.width>width){
objStyle.left = `-${(obj1.width - width)/2}px`
}else{
objStyle.left = `${Math.abs(obj1.width - width)/2}px`
}
objStyle.top =`${height+8}px`
objStyle1.left = (obj1.width/2-6)+'px'
break;
case 'bottom-start':
objStyle.left = `0px`
objStyle.top =`${height+8}px`
objStyle1.left = `8px`
break;
case 'bottom-end':
objStyle.right = `0px`
objStyle.top =`${height+8}px`
objStyle1.right = `8px`
break;
case 'right':
objStyle.left = `${width+8}px`
if(obj1.height>height){
objStyle.top =`-${(obj1.height - height)/2}px`
}else{
objStyle.top =`${Math.abs((obj1.height - height)/2)}px`
}
objStyle1.top = `${obj1.height/2-6}px`
break;
case 'right-start':
objStyle.left = `${width+8}px`
objStyle.top =`0px`
objStyle1.top = `8px`
break;
case 'right-end':
objStyle.left = `${width+8}px`
objStyle.bottom =`0px`
objStyle1.bottom = `8px`
break;
case 'left':
objStyle.right = `${width+8}px`
if(obj1.height>height){
objStyle.top =`-${(obj1.height - height)/2}px`
}else{
objStyle.top =`${Math.abs((obj1.height - height)/2)}px`
}
objStyle1.top = `${obj1.height/2-6}px`
break;
case 'left-start':
objStyle.right = `${width+8}px`
objStyle.top =`0px`
objStyle1.top = `8px`
break;
case 'left-end':
objStyle.right = `${width+8}px`
objStyle.bottom =`0px`
objStyle1.bottom = `8px`
break;
}
this.style = objStyle
//
this.arrowStyle = objStyle1
resolve()
}).exec()
})
}
}
}
</script>
<style lang="scss" scoped>
$theme-bg-color: var(--theme-bg-color);
.zb-tooltip{
position: relative;
}
.zb_tooltip_content{
height: 100%;
/* float: left; */
position: relative;
display: inline-block;
// display: flex;
// flex-direction: row;
// align-items: center;
/* overflow: hidden; */
}
.zb_tooltip__popper{
/* transform-origin: center top; */
background: $theme-bg-color;
visibility: hidden;
// color:'#fff';
position: absolute;
border-radius: 4px;
font-size: 12px;
padding: 10px;
min-width: 10px;
word-wrap: break-word;
display: inline-block;
white-space: nowrap;
z-index:9;
}
.zb_popper__icon{
width: 0;
height: 0;
z-index:9;
position: absolute;
}
.zb_popper__arrow{
bottom: -5px;
/* transform-origin: center top; */
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid $theme-bg-color;
}
.zb_popper__right{
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-right: 6px solid $theme-bg-color;
left:-5px;
}
.zb_popper__left{
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid $theme-bg-color;
right:-5px;
}
.zb_popper__up{
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid $theme-bg-color;
top:-5px;
}
.fixed{
position: absolute;width: 100vw;
height: 100vh;
position: fixed;
left: 0;
top: 0;
pointer-events: auto;
background: red;
z-index:-1;
}
</style>

View File

@ -0,0 +1,83 @@
{
"id": "zb-tooltip",
"displayName": "zb-tooltip (文字提示气泡框)",
"version": "1.0.11",
"description": "简单的文字提示气泡框,可以自定义皮肤颜色",
"keywords": [
"tooltip",
"tip",
"文字提示",
"气泡框",
"自定义皮肤颜色、Popover"
],
"repository": "",
"engines": {
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "u"
},
"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"
},
"快应用": {
"华为": "y",
"联盟": "y"
}
}
}
}
}

View File

@ -0,0 +1,30 @@
## 介绍
基于uni-app开发的一个普通的提示组件功能点击提示
## 友情链接
#### vue-admin-perfect —— [企业级、通用型中后台前端解决方案 预览地址](http://182.61.5.190:8889/)
#### vue-admin-perfect —— [企业级、通用型中后台前端解决方案基于vue3.0+TS+Element-Plus 最新版,同时支持电脑,手机,平板)](https://github.com/zouzhibin/vue-admin-perfect)
## Tooltip 属性
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
| ------ | ------ | ------ | ------ | ------ |
| visible | 是否显示 tooltip支持 .sync 修饰符 | Boolean |visible.sync | false |
| content | 显示的内容,也可以通过 slot#content | String |-- | ' ' |
| color | 自定义主题颜色| String |'#303133' | '#303133' |
| placement | Tooltip 的出现位置 | String |top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end | top |
## Slot 插槽
| 参数 | 说明 |
| ------ | ------ |
| content | 显示提示框得内容 |
```
因为uniapp 中小程序中没有window对象需手动调用 关闭
第一种办法关闭this.$refs.tooltip.close()
第二种办法关闭visible.sync = false
```