35 changed files with 1828 additions and 3 deletions
@ -0,0 +1,62 @@
|
||||
/** |
||||
* 当前环境 |
||||
* @type {string} |
||||
*/ |
||||
export const ENV = 'dev'; |
||||
|
||||
/** |
||||
* 打开日志打印 |
||||
* @type {boolean} |
||||
*/ |
||||
export const OPEN_LOG = true; |
||||
|
||||
/** |
||||
* 首页路径 |
||||
* @type {string} |
||||
*/ |
||||
export const INDEX_PATH = '/pages/Index/index'; |
||||
|
||||
/** |
||||
* 登录页路径 |
||||
* @type {string} |
||||
*/ |
||||
export const LOGIN_PATH = '/pages/Login/index'; |
||||
|
||||
/** |
||||
* token字段 |
||||
* @type {string} |
||||
*/ |
||||
export const TOKEN_FIELD = 'token'; |
||||
|
||||
/** |
||||
* 用户信息字段 |
||||
* @type {string} |
||||
*/ |
||||
export const USERINFO_FIELD = 'info'; |
||||
|
||||
/** |
||||
* 页面信息字段 |
||||
* @type {string} |
||||
*/ |
||||
export const PAGEINFO_FIELD = 'page_info'; |
||||
|
||||
/** |
||||
* 列表分页数量 |
||||
* @type {string} |
||||
*/ |
||||
export const LIMIT = '10'; |
||||
|
||||
/** |
||||
* 默认列表请求数据 |
||||
* @type {string} |
||||
*/ |
||||
export const DEFAULT_LIST_PAGE = { |
||||
page:1, |
||||
pageSize:LIMIT, |
||||
}; |
||||
|
||||
/** |
||||
* 默认列表请求数据 |
||||
* @type {string} |
||||
*/ |
||||
export const UPLOAD_PATH = '/common/upload'; |
@ -0,0 +1,21 @@
|
||||
MIT License |
||||
|
||||
Copyright (c) 2020 www.mview.com |
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
of this software and associated documentation files (the "Software"), to deal |
||||
in the Software without restriction, including without limitation the rights |
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
copies of the Software, and to permit persons to whom the Software is |
||||
furnished to do so, subject to the following conditions: |
||||
|
||||
The above copyright notice and this permission notice shall be included in all |
||||
copies or substantial portions of the Software. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
SOFTWARE. |
@ -0,0 +1,5 @@
|
||||
# 组件 |
||||
## sticky |
||||
` |
||||
吸顶组件,不填写顶部距离时默认吸附导航栏下边,使用fixed模式 |
||||
` |
@ -0,0 +1,125 @@
|
||||
<template> |
||||
<view class="m-avatar-container"> |
||||
<slot name="avatar"> |
||||
<button v-if="!privateStatus && choose" open-type="chooseAvatar" class="avatarBtn" @chooseavatar="chooseAvatar" :style="{ |
||||
width:size,height:size |
||||
}"> |
||||
<image class="img" mode="aspectFill" :src="avatarUrl" :style="{width:size,height:size,borderRadius:radius}" /> |
||||
</button> |
||||
<button v-else class="avatarBtn" :style="{ |
||||
width:size,height:size |
||||
}" @click="choose ? needPrivate : ''"> |
||||
<image class="img" mode="aspectFill" :src="avatarUrl" :style="{width:size,height:size,borderRadius:radius}" /> |
||||
</button> |
||||
|
||||
<!-- <image mode="aspectFill" :src="src" ></image>--> |
||||
</slot> |
||||
</view> |
||||
</template> |
||||
|
||||
<script> |
||||
/** |
||||
* Sticky 头像 |
||||
* @description 警告提示,展现需要关注的信息。 |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
const base64Avatar = |
||||
"data:image/jpg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAAA8AAD/4QMraHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIwMTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjREMEQwRkY0RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjREMEQwRkY1RjgwNDExRUE5OTY2RDgxODY3NkJFODMxIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NEQwRDBGRjJGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NEQwRDBGRjNGODA0MTFFQTk5NjZEODE4Njc2QkU4MzEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7/7gAOQWRvYmUAZMAAAAAB/9sAhAAGBAQEBQQGBQUGCQYFBgkLCAYG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"; |
||||
export default { |
||||
name: 'm-avatar', |
||||
props:{ |
||||
src:{ |
||||
type:String, |
||||
default:'' |
||||
}, |
||||
defaultImage:{ |
||||
type:String, |
||||
default: '' |
||||
}, |
||||
size:{ |
||||
type:String, |
||||
default: '150rpx' |
||||
}, |
||||
choose:{ |
||||
type:Boolean, |
||||
default: true |
||||
}, |
||||
radius:{ |
||||
type:String, |
||||
default: '50%' |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
avatar:'', |
||||
privateStatus:true, |
||||
avatarUrl:'', |
||||
} |
||||
}, |
||||
watch: { |
||||
// 监听头像src的变化,赋值给内部的avatarUrl变量,因为图片加载失败时,需要修改图片的src为默认值 |
||||
// 而组件内部不能直接修改props的值,所以需要一个中间变量 |
||||
src: { |
||||
immediate: true, |
||||
handler(newVal) { |
||||
this.avatarUrl = newVal |
||||
// 如果没有传src,则主动触发error事件,用于显示默认的头像,否则src为''空字符等的时候,会无内容展示 |
||||
if(!newVal) { |
||||
this.errorHandler() |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
computed: { |
||||
|
||||
}, |
||||
methods: { |
||||
errorHandler() { |
||||
this.avatarUrl = base64Avatar; |
||||
}, |
||||
chooseAvatar(v) { |
||||
uni.$m.uploadFile(v.detail.avatarUrl).then(res => { |
||||
this.avatarUrl = res.show_path; |
||||
this.$emit('change',this.avatarUrl) |
||||
}) |
||||
}, |
||||
checkPrivacy(){ |
||||
// #ifdef MP-WEIXIN |
||||
uni.getPrivacySetting({ |
||||
success: res => { |
||||
console.log("是否需要授权:", res.needAuthorization, "隐私协议的名称为:", res.privacyContractName) |
||||
this.privateStatus = res.needAuthorization; |
||||
}, |
||||
fail: () => { |
||||
}, |
||||
complete: () => {}, |
||||
}) |
||||
// #endif |
||||
}, |
||||
needPrivate(){ |
||||
this.$emit('needPrivate',true); |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.checkPrivacy(); |
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.safe-area{ |
||||
width:100%; |
||||
} |
||||
.m-sticky-container{ |
||||
width:100%; |
||||
z-index: 997; |
||||
} |
||||
button{ |
||||
padding:0; |
||||
background:none; |
||||
&::after{ |
||||
border:none; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,17 @@
|
||||
export default { |
||||
props: { |
||||
// 是否占位
|
||||
safeArea: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
type: { |
||||
type: String, |
||||
default: 'fixed' |
||||
}, |
||||
offsetTop: { |
||||
type: String, |
||||
default: '0' |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,105 @@
|
||||
<script setup> |
||||
import {computed,defineProps} from "vue"; |
||||
|
||||
/** |
||||
* 按钮 |
||||
* @description |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
const emit = defineEmits(['click']); |
||||
function clickHandle(event){ |
||||
emit('click',event); |
||||
} |
||||
|
||||
const props = defineProps({ |
||||
containerPadding:{ |
||||
type:[String,Number], |
||||
default:'10px' |
||||
}, |
||||
buttonPadding:{ |
||||
type:[String,Number], |
||||
default:'10px' |
||||
}, |
||||
textStyle:{ |
||||
type:[Object], |
||||
default:'' |
||||
}, |
||||
justifyAlign:{ |
||||
type:String, |
||||
default:'center' |
||||
}, |
||||
verticalAlign:{ |
||||
type:String, |
||||
default:'center' |
||||
}, |
||||
border:{ |
||||
type:String, |
||||
default:'1px solid #999999;' |
||||
}, |
||||
buttonColor:{ |
||||
type:String, |
||||
}, |
||||
radius:{ |
||||
type:[String,Number], |
||||
default:'10px' |
||||
}, |
||||
text:{ |
||||
type:String, |
||||
default:'确认' |
||||
}, |
||||
customStyle:{ |
||||
type:[String,Object], |
||||
default:{} |
||||
} |
||||
}); |
||||
|
||||
const containerStyle = computed(() => { |
||||
return { |
||||
'padding':props.containerPadding, |
||||
'justify-content':props.justifyAlign, |
||||
'align-items':props.verticalAlign, |
||||
} |
||||
}); |
||||
const buttonStyle = computed(() => { |
||||
return { |
||||
...uni.$m.addStyle(props.customStyle), |
||||
'border':props.border, |
||||
'border-radius':props.radius, |
||||
'background-color':props.buttonColor, |
||||
'padding':props.buttonPadding, |
||||
} |
||||
}); |
||||
</script> |
||||
|
||||
<template> |
||||
<view class="m-button-container" @click="clickHandle" style="display: flex;" :style="containerStyle"> |
||||
<view class="button" :style="buttonStyle"> |
||||
<view class="m-button-pre"> |
||||
<slot name="pre"></slot> |
||||
</view> |
||||
<view class="m-button-title" :style="textStyle"> |
||||
<m-text |
||||
:text="text" |
||||
:size="textStyle.size" |
||||
:color="textStyle.color" |
||||
:line-height="textStyle.lineHeight" |
||||
:align="textStyle.align || 'center'" |
||||
:display="textStyle.display" |
||||
></m-text> |
||||
</view> |
||||
<view class="m-button-pre"> |
||||
<slot name="after"></slot> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</template> |
||||
|
||||
<style lang="scss"> |
||||
.button{ |
||||
flex:0 0 1; |
||||
width:100%; |
||||
|
||||
text-align: center; |
||||
} |
||||
</style> |
@ -0,0 +1,27 @@
|
||||
<template> |
||||
<view class="" style="padding:26rpx;border-radius: 20rpx;background-color:#fff;box-shadow:0rpx 0rpx 30rpx #dfdfdf"> |
||||
<slot></slot> |
||||
</view> |
||||
</template> |
||||
|
||||
<script> |
||||
/** |
||||
* 卡片 |
||||
* @description |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
export default { |
||||
name: 'm-card', |
||||
methods: { |
||||
|
||||
}, |
||||
mounted() { |
||||
|
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
|
||||
</style> |
@ -0,0 +1,60 @@
|
||||
<script setup> |
||||
/** |
||||
* 复选框 |
||||
* @description |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
import {ref, watch} from "vue"; |
||||
|
||||
const props = defineProps({ |
||||
checkData:{type:Object,default:{}}, |
||||
labelSize:{type:[String,Number],default:'26rpx'}, |
||||
size:{type:[String,Number],default:'32rpx'}, |
||||
activeColor:{type:String,default:'#578CF5'}, |
||||
inActiveColor:{type:String,default:'transparent'}, |
||||
borderInActiveColor:{type:String,default:'#999'}, |
||||
labelStyle:{type:Object,default:{}} |
||||
}); |
||||
|
||||
const emit = defineEmits(['change','update:modelValue']); |
||||
const checked = ref([]); |
||||
function checkedHandle(item,index){ |
||||
const posIndex = checked.value.indexOf(index) |
||||
if(posIndex !== -1){ |
||||
checked.value.splice(posIndex,1); |
||||
}else{ |
||||
checked.value.push(index) |
||||
} |
||||
emit('update:modelValue',(posIndex === -1)); |
||||
emit('change',{ele:item,checked:(posIndex === -1)}); |
||||
} |
||||
</script> |
||||
<template> |
||||
<view class="m-checkbox-group"> |
||||
<view class="m-checkbox"> |
||||
<view class="item row align-center" v-for="(item,index) in checkData" @click="checkedHandle(item,index)"> |
||||
<view class="box border-box mr-1" :style="{borderColor:(checked.indexOf(index) !== -1)?activeColor:borderInActiveColor}"> |
||||
<view class="icon" :style="{backgroundColor:(checked.indexOf(index) !== -1)?activeColor:inActiveColor}"></view> |
||||
</view> |
||||
<view class="label"><m-text :text="item.label" :size="labelStyle.size" :line-height="labelStyle.lingHeight" :color="labelStyle.color"></m-text></view> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</template> |
||||
|
||||
<style lang="scss" scoped> |
||||
.box{ |
||||
width:32rpx; |
||||
height:32rpx; |
||||
padding:5rpx; |
||||
border-radius:50%; |
||||
border:3rpx solid; |
||||
.icon{ |
||||
width:100%; |
||||
height:100%; |
||||
border-radius:50%; |
||||
background:transparent; |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,55 @@
|
||||
<template> |
||||
<view class="mz-header-container" :style="{top:(offsetTop === '0')?offSetDefault:offsetTop,position:type}"> |
||||
<view class="safe-area-top" :style="{height:safeHeight,display:((type !== 'sticky') || 'none')}"></view> |
||||
<slot> |
||||
|
||||
</slot> |
||||
</view> |
||||
</template> |
||||
|
||||
<script> |
||||
import props from './props.js'; |
||||
/** |
||||
* header 头部 |
||||
* @description 警告提示,展现需要关注的信息。 |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
export default { |
||||
name: 'mz-header', |
||||
mixins: [props], |
||||
data() { |
||||
return { |
||||
show: true, |
||||
safeHeight:'' |
||||
} |
||||
}, |
||||
computed: { |
||||
offSetDefault(){ |
||||
return uni.getSystemInfoSync().statusBarHeight+44+'px'; |
||||
}, |
||||
}, |
||||
methods: { |
||||
getSafeHeight(){ |
||||
new Promise((resolve,reject) => { |
||||
resolve(uni.getSystemInfoSync().statusBarHeight); |
||||
}).then((height) => { |
||||
this.safeHeight = height+'px'; |
||||
}) |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.getSafeHeight(); |
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.safe-area{ |
||||
width:100%; |
||||
} |
||||
.mz-header-container{ |
||||
width:100%; |
||||
z-index: 997; |
||||
} |
||||
</style> |
@ -0,0 +1,17 @@
|
||||
export default { |
||||
props: { |
||||
// 是否占位
|
||||
safeArea: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
type: { |
||||
type: String, |
||||
default: 'fixed' |
||||
}, |
||||
offsetTop: { |
||||
type: String, |
||||
default: '0' |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,13 @@
|
||||
<template> |
||||
<view class="mz-input-container"> |
||||
<input type="text"> |
||||
</view> |
||||
</template> |
||||
|
||||
<script setup> |
||||
|
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
|
||||
</style> |
@ -0,0 +1,100 @@
|
||||
<template> |
||||
<uv-popup ref="popup" type="center" :closeOnClickOverlay="false" :is-mask-click="false" round="20rpx" mode="bottom" |
||||
custom-style="padding:20rpx"> |
||||
<view class="popup-box" style="padding:40rpx"> |
||||
<view style="padding:20rpx 0;"> |
||||
<m-text bold text="用户隐私保护提示" color="#020b18" size="32rpx"></m-text> |
||||
</view> |
||||
<view class="row"> |
||||
<view class=""> |
||||
<m-text color="#020b18" line-height="50rpx" text="用户隐私保护提示" size="28rpx"></m-text> |
||||
</view> |
||||
<view class=""> |
||||
<m-text color="#178AF2" size="28rpx" line-height="50rpx" text="《小程序隐私保护指引》" |
||||
@click="openPrivacyContract"></m-text> |
||||
</view> |
||||
<view class=""> |
||||
<m-text color="#020b18" size="28rpx" line-height="50rpx" |
||||
text="当您点击同意并开始使用产品服务时,即表示你已理解并同意该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法更好的体验产品。"></m-text> |
||||
</view> |
||||
|
||||
|
||||
</view> |
||||
<view class="row" style="padding:30rpx;display:flex;box-sizing: border-box;"> |
||||
<view class="col-6" style="padding:15rpx;flex:0 0 50%;box-sizing: border-box;"> |
||||
<button @click="closePrivacyAuthorization"> |
||||
<m-text text="拒绝" size="32rpx" line-height="100rpx" align="center" color="#666"></m-text> |
||||
</button> |
||||
</view> |
||||
|
||||
<view class="col-6" style="padding:15rpx;flex:0 0 50%;box-sizing: border-box;"> |
||||
<button id="agree-btn" open-type="agreePrivacyAuthorization" color="#45C55E" class="weui-btn agree" |
||||
@agreeprivacyauthorization="handleAgreePrivacyAuthorization" :style="{backgroundColor:buttonColor}"> |
||||
<m-text text="同意" size="32rpx" line-height="100rpx" align="center" color="#fff"></m-text> |
||||
</button> |
||||
</view> |
||||
</view> |
||||
</view> |
||||
</uv-popup> |
||||
</template> |
||||
|
||||
<script> |
||||
/** |
||||
* Sticky 头像 |
||||
* @description 警告提示,展现需要关注的信息。 |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
export default { |
||||
name: 'm-private', |
||||
props: { |
||||
src: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
defaultImage: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
size: { |
||||
type: String, |
||||
default: '150rpx' |
||||
}, |
||||
buttonColor: { |
||||
type: String, |
||||
default: '#45C55E' |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
avatar: '', |
||||
} |
||||
}, |
||||
computed: {}, |
||||
methods: { |
||||
open() { |
||||
this.$refs.popup.open(); |
||||
}, |
||||
openPrivacyContract() { |
||||
uni.openPrivacyContract({}); |
||||
}, |
||||
closePrivacyAuthorization() { |
||||
this.$refs.popup.close(); |
||||
}, |
||||
handleAgreePrivacyAuthorization() { |
||||
this.$refs.popup.close(); |
||||
this.$emit('agreePrivate',true); |
||||
} |
||||
}, |
||||
mounted() { |
||||
|
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
button.agree{ |
||||
//background-color:#45C55E; |
||||
color:#ffffff; |
||||
} |
||||
</style> |
@ -0,0 +1,17 @@
|
||||
export default { |
||||
props: { |
||||
// 是否占位
|
||||
safeArea: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
type: { |
||||
type: String, |
||||
default: 'fixed' |
||||
}, |
||||
offsetTop: { |
||||
type: String, |
||||
default: '0' |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,29 @@
|
||||
<template> |
||||
<view> |
||||
<slot> |
||||
|
||||
</slot> |
||||
</view> |
||||
</template> |
||||
|
||||
<script> |
||||
/** |
||||
* 单选 |
||||
* @description |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
export default { |
||||
name: 'm-radio', |
||||
methods: { |
||||
|
||||
}, |
||||
mounted() { |
||||
|
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
|
||||
</style> |
@ -0,0 +1,29 @@
|
||||
<template> |
||||
<view> |
||||
<slot> |
||||
|
||||
</slot> |
||||
</view> |
||||
</template> |
||||
|
||||
<script> |
||||
/** |
||||
* 单选 |
||||
* @description |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
export default { |
||||
name: 'm-radio', |
||||
methods: { |
||||
|
||||
}, |
||||
mounted() { |
||||
|
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
|
||||
</style> |
@ -0,0 +1,41 @@
|
||||
<template> |
||||
<view style="width:100%;" :style="{height:height}"></view> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'm-private', |
||||
props: { |
||||
src: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
defaultImage: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
size: { |
||||
type: String, |
||||
default: '150rpx' |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
height: '0', |
||||
} |
||||
}, |
||||
computed: {}, |
||||
methods: {}, |
||||
mounted() { |
||||
uni.$m.uniSysInfo().then(response => { |
||||
this.height = response.safeAreaInsetBottom + 'px'; |
||||
}) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
page { |
||||
width: 100%; |
||||
} |
||||
</style> |
@ -0,0 +1,17 @@
|
||||
export default { |
||||
props: { |
||||
// 是否占位
|
||||
safeArea: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
type: { |
||||
type: String, |
||||
default: 'fixed' |
||||
}, |
||||
offsetTop: { |
||||
type: String, |
||||
default: '0' |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,41 @@
|
||||
<template> |
||||
<view style="width:100vw;" :style="{height:height}"></view> |
||||
</template> |
||||
|
||||
<script> |
||||
export default { |
||||
name: 'm-private', |
||||
props: { |
||||
src: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
defaultImage: { |
||||
type: String, |
||||
default: '' |
||||
}, |
||||
size: { |
||||
type: String, |
||||
default: '150rpx' |
||||
} |
||||
}, |
||||
data() { |
||||
return { |
||||
height: '0', |
||||
} |
||||
}, |
||||
computed: {}, |
||||
methods: {}, |
||||
mounted() { |
||||
uni.$m.uniSysInfo().then(response => { |
||||
this.height = response.sysAndMenuHeight + 'px'; |
||||
}) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
page { |
||||
width: 100%; |
||||
} |
||||
</style> |
@ -0,0 +1,17 @@
|
||||
export default { |
||||
props: { |
||||
// 是否占位
|
||||
safeArea: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
type: { |
||||
type: String, |
||||
default: 'fixed' |
||||
}, |
||||
offsetTop: { |
||||
type: String, |
||||
default: '0' |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,65 @@
|
||||
<template> |
||||
<view class="safe-area" :style="{height:safeHeight,display:((type !== 'sticky') || 'none')}"></view> |
||||
<view class="m-sticky-container" :style="{top:offsetHeightValue,position:type,zIndex: zIndex}"> |
||||
<slot /> |
||||
</view> |
||||
</template> |
||||
|
||||
<script> |
||||
import props from './props.js'; |
||||
/** |
||||
* Sticky 吸顶 |
||||
* @description 警告提示,展现需要关注的信息。 |
||||
* |
||||
* @property {String} title 显示的文字 |
||||
*/ |
||||
export default { |
||||
name: 'm-sticky', |
||||
mixins: [props], |
||||
data() { |
||||
return { |
||||
show: true, |
||||
safeHeight:'', |
||||
offsetHeightValue:'0', |
||||
} |
||||
}, |
||||
computed: { |
||||
offSetDefault(){ |
||||
let offsetHeight = uni.getSystemInfoSync().statusBarHeight; |
||||
// #ifdef MP-WEIXIN |
||||
offsetHeight += 44; |
||||
// #endif |
||||
return offsetHeight; |
||||
}, |
||||
}, |
||||
methods: { |
||||
getSafeHeight(){ |
||||
new Promise((resolve) => { |
||||
uni.$m.sleep(10).then(() => { |
||||
const info = uni.createSelectorQuery().in(this).select('.m-sticky-container'); |
||||
info.boundingClientRect(function (data) { |
||||
resolve(data.height); |
||||
}).exec(function (res) {}); |
||||
}); |
||||
}).then((height) => { |
||||
this.safeHeight = height+'px'; |
||||
this.offsetHeightValue = (parseFloat(uni.$m.getPx(this.offSetDefault,false))+parseFloat(uni.$m.getPx(this.offsetTop,false))+'px') |
||||
this.$emit('change',true); |
||||
}) |
||||
}, |
||||
}, |
||||
mounted() { |
||||
this.getSafeHeight(); |
||||
}, |
||||
} |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.safe-area{ |
||||
width:100%; |
||||
} |
||||
.m-sticky-container{ |
||||
width:100%; |
||||
|
||||
} |
||||
</style> |
@ -0,0 +1,21 @@
|
||||
export default { |
||||
props: { |
||||
// 是否占位
|
||||
safeArea: { |
||||
type: Boolean, |
||||
default: true |
||||
}, |
||||
type: { |
||||
type: String, |
||||
default: 'fixed' |
||||
}, |
||||
offsetTop: { |
||||
type: String, |
||||
default: '0' |
||||
}, |
||||
zIndex: { |
||||
type: String, |
||||
default: '997' |
||||
}, |
||||
} |
||||
} |
@ -0,0 +1,68 @@
|
||||
<script setup> |
||||
import {computed} from "vue"; |
||||
|
||||
const props = defineProps({ |
||||
text:{ |
||||
type:String, |
||||
default:'' |
||||
}, |
||||
align:{ |
||||
type:String, |
||||
default:'left' |
||||
}, |
||||
size:{ |
||||
type:[String,Number], |
||||
default:'16px' |
||||
}, |
||||
bold:{ |
||||
type:[String,Number], |
||||
default:'normal' |
||||
}, |
||||
color:{ |
||||
type:String, |
||||
default:'#000000' |
||||
}, |
||||
lineHeight:{ |
||||
type:[String,Number], |
||||
default:'16px' |
||||
}, |
||||
display:{ |
||||
type:String, |
||||
default:'block' |
||||
}, |
||||
lines:{ |
||||
type:Number, |
||||
}, |
||||
customStyle:{ |
||||
type:[String,Object], |
||||
default:{} |
||||
} |
||||
}) |
||||
|
||||
const textStyle = computed(() => { |
||||
return { |
||||
...uni.$m.addStyle(props.customStyle), |
||||
'text-align':props.align, |
||||
'font-size':props.size, |
||||
'font-weight':props.bold, |
||||
'line-height':props.lineHeight, |
||||
'color':props.color, |
||||
'display':props.display, |
||||
} |
||||
}) |
||||
|
||||
const emit = defineEmits(['click']) |
||||
function handleClick(e){ |
||||
emit('click',e); |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<view class="m-text-container" :class="[lines && `u-line-${lines}`]" :style="textStyle" @click="handleClick"> |
||||
{{text}} |
||||
</view> |
||||
</template> |
||||
|
||||
<style scoped lang="scss"> |
||||
|
||||
</style> |
@ -0,0 +1,26 @@
|
||||
import api from './lib/functions.js' |
||||
import tools from './lib/tools.js' |
||||
import service from "@/uni_modules/m-view/lib/request"; |
||||
const $m = { |
||||
...api, |
||||
...tools, |
||||
service |
||||
} |
||||
|
||||
// $m挂载到uni对象上
|
||||
uni.$m = $m |
||||
|
||||
const install = (Vue) => { |
||||
// #ifndef APP-NVUE
|
||||
// 只有vue,挂载到Vue.prototype才有意义,因为nvue中全局Vue.prototype和Vue.mixin是无效的
|
||||
Vue.config.globalProperties.$m = $m |
||||
// 暂时兼容vue2的$nextTick写法
|
||||
Vue.config.globalProperties.$nextTick = (cb) => { |
||||
cb(); |
||||
} |
||||
// #endif
|
||||
} |
||||
|
||||
export default { |
||||
install |
||||
} |
@ -0,0 +1,91 @@
|
||||
.body-background{ |
||||
position: fixed; |
||||
top:0; |
||||
left:0; |
||||
width:100%; |
||||
height:100%; |
||||
background:{ |
||||
size:100% 100%; |
||||
position: center center; |
||||
repeat:no-repeat; |
||||
} |
||||
z-index: -1; |
||||
} |
||||
.border-box{ |
||||
box-sizing: border-box; |
||||
} |
||||
.flex{ |
||||
display:flex; |
||||
} |
||||
.row{ |
||||
box-sizing: border-box; |
||||
width:100%; |
||||
display:flex; |
||||
flex-wrap: wrap; |
||||
} |
||||
.col-12{ |
||||
box-sizing: border-box; |
||||
flex: 0 0 100%; |
||||
} |
||||
.col-8{ |
||||
box-sizing: border-box; |
||||
flex: 0 0 66.66%; |
||||
} |
||||
.col-6{ |
||||
box-sizing: border-box; |
||||
flex: 0 0 50%; |
||||
} |
||||
.col-4{ |
||||
box-sizing: border-box; |
||||
flex: 0 0 33.33%; |
||||
} |
||||
.col-3{ |
||||
box-sizing: border-box; |
||||
flex: 0 0 25%; |
||||
} |
||||
.col{ |
||||
flex:1; |
||||
} |
||||
.col-auto{ |
||||
flex:auto; |
||||
} |
||||
|
||||
.align-center{ |
||||
align-items: center; |
||||
} |
||||
.justify-center{ |
||||
justify-content: center; |
||||
} |
||||
.justify-between{ |
||||
justify-content: space-between; |
||||
} |
||||
.text-center{ |
||||
text-align: center; |
||||
} |
||||
|
||||
@for $i from 1 through 5 { |
||||
.mb-#{$i} { |
||||
margin-bottom: #{$i}0rpx; |
||||
} |
||||
.mr-#{$i} { |
||||
margin-right: #{$i}0rpx; |
||||
} |
||||
.ml-#{$i} { |
||||
margin-left: #{$i}0rpx; |
||||
} |
||||
.mt-#{$i} { |
||||
margin-top: #{$i}0rpx; |
||||
} |
||||
.pb-#{$i} { |
||||
padding-bottom: #{$i}0rpx; |
||||
} |
||||
.pr-#{$i} { |
||||
padding-right: #{$i}0rpx; |
||||
} |
||||
.pl-#{$i} { |
||||
padding-left: #{$i}0rpx; |
||||
} |
||||
.pt-#{$i} { |
||||
padding-top: #{$i}0rpx; |
||||
} |
||||
} |
@ -0,0 +1,8 @@
|
||||
import {host} from "../../../api/config.js"; |
||||
|
||||
export function getSts(data) { |
||||
return uni.$m.service({ |
||||
url: `${host}/user/agree-privacy`, |
||||
method: "post", |
||||
}); |
||||
} |
@ -0,0 +1,498 @@
|
||||
// #ifdef MP-WEIXIN
|
||||
|
||||
const QQMapWX = require('./qqmap-wx-jssdk.min.js'); |
||||
import * as QQMapwx from './/qqmap-wx-jssdk.min.js'; |
||||
|
||||
var qqMapSdk; |
||||
|
||||
// #endif
|
||||
|
||||
// import {getSTS} from "@/api/other";
|
||||
|
||||
import {imghost, host, oss} from '@/config/host.js' |
||||
import {INDEX_PATH, PAGEINFO_FIELD, TOKEN_FIELD, UPLOAD_PATH, USERINFO_FIELD} from '@/config/config.js' |
||||
// import store from "@/store";
|
||||
export default { |
||||
|
||||
loginModalState: true, |
||||
mapLocation: () => { |
||||
|
||||
return new Promise((relove, reject) => { |
||||
|
||||
wx.authorize({ |
||||
scope: 'scope.userFuzzyLocation', |
||||
success(res) { |
||||
if (res.errMsg == 'authorize:ok') { |
||||
wx.getFuzzyLocation({ |
||||
type: 'wgs84', |
||||
success(re) { |
||||
console.log(re); |
||||
uni.chooseLocation({ |
||||
latitude: re.latitude, |
||||
longitude: re.longitude, |
||||
success: function (data) { |
||||
console.log(data); |
||||
let obj = { |
||||
latitude: data.latitude, |
||||
longitude: data.longitude, |
||||
address: data.address |
||||
} |
||||
if (data.errMsg == 'chooseLocation:ok') { |
||||
qqMapSdk = new QQMapWX({ |
||||
key: 'K65BZ-LULE4-744UV-X4EIA-27RA5-A4FWT' |
||||
}) |
||||
qqMapSdk.reverseGeocoder({ |
||||
location: { |
||||
latitude: data.latitude, |
||||
longitude: data.longitude |
||||
}, |
||||
success: function (mapres) { |
||||
console.log(mapres); |
||||
if (mapres.message == 'query ok') { |
||||
obj.name = mapres.result.formatted_addresses.recommend |
||||
obj.city = mapres.result.address_component.city |
||||
relove(obj) |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
}); |
||||
} |
||||
}) |
||||
} |
||||
}, |
||||
fail(err) { |
||||
reject(err); |
||||
} |
||||
}) |
||||
}) |
||||
}, |
||||
getLocation(details) { |
||||
return new Promise((relove, reject) => { |
||||
qqMapSdk = new QQMapWX({ |
||||
key: 'K65BZ-LULE4-744UV-X4EIA-27RA5-A4FWT' |
||||
}) |
||||
qqMapSdk.geocoder({ |
||||
//获取表单传入地址
|
||||
address: details.activedeta.city + details.activedeta.address, //地址参数,例:固定地址,address: '北京市海淀区彩和坊路海淀西大街74号'
|
||||
success: function (res) {//成功后的回调
|
||||
console.log(res); |
||||
relove(res.result) |
||||
}, |
||||
fail: function (error) { |
||||
console.error(error); |
||||
}, |
||||
complete: function (res) { |
||||
console.log(res); |
||||
} |
||||
}) |
||||
}) |
||||
}, |
||||
urlToObj: (url) => { |
||||
let obj = {} |
||||
let str = url.slice(url.indexOf('?') + 1) |
||||
let arr = str.split('&') |
||||
for (let j = arr.length, i = 0; i < j; i++) { |
||||
let arr_temp = arr[i].split('=') |
||||
obj[arr_temp[0]] = arr_temp[1] |
||||
} |
||||
return obj |
||||
}, |
||||
uploadFile: (file) => { |
||||
// console.log(file);
|
||||
return new Promise((resolve, reject) => { |
||||
uni.showLoading({ |
||||
title: '上传中' |
||||
}).then() |
||||
uni.uploadFile({ |
||||
url: host+UPLOAD_PATH, //仅为示例,非真实的接口地址
|
||||
filePath: file, |
||||
name: 'file', |
||||
success: (uploadFileRes) => { |
||||
uni.hideLoading() |
||||
resolve(JSON.parse(uploadFileRes.data).data) |
||||
}, |
||||
fail: (err => { |
||||
reject(err); |
||||
}) |
||||
}); |
||||
}) |
||||
}, |
||||
getImgUrl: (url) => { |
||||
if (url) { |
||||
if (url.indexOf('http') === -1) { |
||||
return imgHost + url |
||||
} else { |
||||
return url |
||||
} |
||||
} else { |
||||
return '' |
||||
} |
||||
|
||||
}, |
||||
getImgUrlToHttps: (url) => { |
||||
if (url) { |
||||
if (url.indexOf('https') == -1) { |
||||
console.log(url.replace('http', 'https')) |
||||
return url.replace('http', 'https') |
||||
} else { |
||||
return url |
||||
} |
||||
} else { |
||||
return '' |
||||
} |
||||
|
||||
}, |
||||
/** |
||||
* 失败 |
||||
*/ |
||||
error: (msg) => { |
||||
|
||||
return new Promise((relove, reject) => { |
||||
uni.showToast({ |
||||
title: msg, |
||||
icon: "none" |
||||
}) |
||||
setTimeout(() => { |
||||
relove(); |
||||
}, 1500) |
||||
}) |
||||
|
||||
}, |
||||
/** |
||||
* 成功提示 |
||||
*/ |
||||
success: (msg) => { |
||||
|
||||
return new Promise((relove, reject) => { |
||||
uni.showToast({ |
||||
title: msg, |
||||
icon: "success" |
||||
}) |
||||
setTimeout(() => { |
||||
relove(); |
||||
}, 1500) |
||||
}) |
||||
|
||||
}, |
||||
/** |
||||
* 确认对话框 |
||||
* @param {Object} contents |
||||
* @param {Object} callback |
||||
*/ |
||||
confirm: (contents) => { |
||||
|
||||
return new Promise((relove, reject) => { |
||||
|
||||
uni.showModal({ |
||||
title: '提示', |
||||
content: contents, |
||||
success: function (res) { |
||||
if (res.confirm) { |
||||
relove(); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
}) |
||||
|
||||
}, |
||||
payment: (param) => { |
||||
|
||||
return new Promise((relove, reject) => { |
||||
uni.requestPayment({ |
||||
provider: 'wxpay', |
||||
timeStamp: param.timeStamp, |
||||
nonceStr: param.nonceStr, |
||||
package: param.package, |
||||
signType: param.signType, |
||||
paySign: param.paySign, |
||||
success: function (res) { |
||||
relove(res); |
||||
}, |
||||
fail: function (err) { |
||||
console.log(err); |
||||
|
||||
api.error("支付失败"); |
||||
reject(err); |
||||
} |
||||
}); |
||||
|
||||
}) |
||||
}, |
||||
navHeight: () => { |
||||
let system, menu, systemBar, navigationBar, navPaddingTop, navHeight, headerPadding; |
||||
//获取系统信息
|
||||
try { |
||||
wx.getSystemInfo({ |
||||
success: res => { |
||||
this.system = res |
||||
} |
||||
}) |
||||
// log('res',this.system);
|
||||
//获取胶囊信息
|
||||
this.menu = wx.getMenuButtonBoundingClientRect() |
||||
this.systemBar = this.system.statusBarHeight //状态栏高度
|
||||
this.navigationBar = (this.menu.top - this.system.statusBarHeight) * 2 + this.menu.height //胶囊高度
|
||||
this.navPaddingTop = this.systemBar; |
||||
this.navHeight = this.menu.height; |
||||
this.headerPadding = (this.menu.top - this.systemBar); |
||||
|
||||
this.systemBarHeight = (this.navPaddingTop + this.navHeight + (this.headerPadding * 2)) |
||||
} catch (e) { |
||||
//默认高度,刘海屏
|
||||
this.navPaddingTop = 43; |
||||
this.navHeight = 32; |
||||
this.headerPadding = 4; |
||||
} |
||||
return { |
||||
navPaddingTop: this.navPaddingTop, |
||||
navHeight: this.navHeight, |
||||
headerPadding: this.headerPadding, |
||||
systemBarHeight: this.systemBarHeight, |
||||
windowHeihgt: (this.system.windowHeight - this.systemBarHeight) |
||||
}; |
||||
}, |
||||
wxSystemInfo: () => { |
||||
let system; |
||||
//获取系统信息
|
||||
try { |
||||
wx.getSystemInfo({ |
||||
success: res => { |
||||
this.system = res |
||||
} |
||||
}) |
||||
} catch (e) { |
||||
|
||||
} |
||||
return { |
||||
system: this.system |
||||
}; |
||||
}, |
||||
uniSysInfo: () => { |
||||
return new Promise((resolve, reject) => { |
||||
if (uni.getStorageSync('sysInfo')) { |
||||
resolve(uni.getStorageSync('sysInfo')); |
||||
} else { |
||||
let menuButtonInfo = uni.getMenuButtonBoundingClientRect(); |
||||
let sysInfo = uni.getSystemInfoSync(); |
||||
let sysMenuHeight = sysInfo.statusBarHeight; |
||||
let sysWindowHeight = sysInfo.windowHeight; |
||||
let menuButtonHeight = menuButtonInfo.height |
||||
let menuButtonPadding = menuButtonInfo.top - sysMenuHeight; |
||||
let sysAndMenuHeight = sysMenuHeight + 44;// (sysMenuHeight+menuButtonHeight+(menuButtonPadding*2));
|
||||
let windowHeight = (sysWindowHeight - sysAndMenuHeight); |
||||
let safeAreaInsetBottom = (sysInfo.safeAreaInsets.bottom); |
||||
let data = { |
||||
sysMenuHeight: sysMenuHeight, |
||||
menuButtonHeight: menuButtonHeight, |
||||
menuButtonPadding: menuButtonPadding, |
||||
sysAndMenuHeight: sysAndMenuHeight, |
||||
windowHeight: windowHeight, |
||||
safeAreaInsetBottom: safeAreaInsetBottom, |
||||
} |
||||
uni.setStorageSync('sysInfo', data); |
||||
resolve(data); |
||||
} |
||||
|
||||
}) |
||||
}, |
||||
uploadOssFile: (file) => { |
||||
return new Promise((resolve, reject) => { |
||||
// getSTS({}).then(res => {
|
||||
// // const client = new OSS(res.data);
|
||||
// // console.log(file);
|
||||
// uni.showLoading({
|
||||
// title:'上传中'
|
||||
// })
|
||||
// let timer = new Date();
|
||||
// let address = timer.getFullYear() + '' + (timer.getMonth() + 1) + '' + timer.getDate();
|
||||
// address = 'upload/' + address + '/';
|
||||
// var imageSrc = file;
|
||||
// let str = file.substr(file.lastIndexOf('.'));
|
||||
// let nameStr = address + timer.getTime() + str;
|
||||
// uni.uploadFile({
|
||||
// url: `${oss}`, //仅为示例,非真实的接口地址
|
||||
// filePath:file,
|
||||
// name: 'file',
|
||||
// header: {
|
||||
// "content-type": "application/json;charset=utf-8",
|
||||
// },
|
||||
// formData:Object.assign({
|
||||
// name:nameStr,
|
||||
// key:nameStr,
|
||||
// success_action_status: '200',
|
||||
// },res.data),
|
||||
// success: (uploadFileRes) => {
|
||||
// uni.hideLoading()
|
||||
// resolve ({show_path:oss+'/' + nameStr});
|
||||
// // relove(JSON.parse(uploadFileRes.data).data)
|
||||
// // console.log(JSON.parse(uploadFileRes.data).data);
|
||||
// },
|
||||
// fail:(res) =>{
|
||||
// uni.hideLoading()
|
||||
// console.log(res)
|
||||
// return {};
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
}) |
||||
}, |
||||
logout: (reLaunch = true, confirm = true) => { |
||||
return new Promise((resolve, reject) => { |
||||
if (confirm) { |
||||
api.confirm('是否退出登录').then(res => { |
||||
api.doLogout(reLaunch) |
||||
resolve(); |
||||
}) |
||||
} else { |
||||
api.doLogout(reLaunch); |
||||
resolve(); |
||||
} |
||||
|
||||
}) |
||||
}, |
||||
doLogout: (reLaunch = true) => { |
||||
uni.showLoading({title: '退出中'}).then(); |
||||
uni.clearStorageSync(); |
||||
// store.commit('userInfo',{});
|
||||
// store.commit('userExtends',{});
|
||||
uni.$m.uniSysInfo().then(() => { |
||||
if (reLaunch) { |
||||
uni.reLaunch({url: '/pages/Index/index'}).then(); |
||||
} |
||||
uni.hideLoading(); |
||||
}).catch(err => { |
||||
uni.hideLoading(); |
||||
}) |
||||
}, |
||||
navTo: (url, token = false) => { |
||||
if (token) { |
||||
if (uni.getStorageSync('token')) { |
||||
uni.navigateTo({ |
||||
url: url |
||||
}).then(); |
||||
} else { |
||||
uni.navigateTo({ |
||||
url: '/pages/Login/index' |
||||
}).then(); |
||||
} |
||||
} else { |
||||
uni.navigateTo({ |
||||
url: url |
||||
}).then(); |
||||
} |
||||
}, |
||||
navBack: () => { |
||||
return uni.navigateBack({ |
||||
delta:1, |
||||
fail:() => { |
||||
uni.navigateTo({ |
||||
url: INDEX_PATH |
||||
}).then() |
||||
} |
||||
}); |
||||
}, |
||||
switchTo: (url, token = false) => { |
||||
if (token) { |
||||
if (uni.getStorageSync('token')) { |
||||
uni.switchTab({ |
||||
url: url |
||||
}) |
||||
} else { |
||||
uni.switchTab({ |
||||
url: '/pages/Login/index' |
||||
}) |
||||
} |
||||
} else { |
||||
uni.switchTab({ |
||||
url: url |
||||
}) |
||||
} |
||||
}, |
||||
getFileType: (name) => { |
||||
let str = name.substr(name.lastIndexOf('.') + 1).toUpperCase(); |
||||
const imageType = ['JPG', 'JPEG', 'PNG', 'GIF', 'BMP', 'TIF', 'TGA', 'DDS', 'SVG', 'EPS', 'RAW', 'PSD']; |
||||
const videoType = ['MP4', 'MOV', 'WMV', 'FLV', 'AVI', 'AVCHD', 'WEBM', 'MKV']; |
||||
if (imageType.indexOf(str) !== -1) { |
||||
return 'image'; |
||||
} else if (videoType.indexOf(str) !== -1) { |
||||
return 'video'; |
||||
} else { |
||||
return 'none'; |
||||
} |
||||
}, |
||||
sleep: (time) => { |
||||
return new Promise((resolve, reject) => { |
||||
setTimeout(() => { |
||||
resolve(); |
||||
}, time); |
||||
}); |
||||
}, |
||||
getDomHeight: (domName) => { |
||||
return new Promise((resolve) => { |
||||
uni.$m.sleep(10).then(() => { |
||||
const info = uni.createSelectorQuery().select(domName); |
||||
info.boundingClientRect(function (data) { |
||||
console.log(data) |
||||
resolve(data.height); |
||||
}).exec(function (res) { |
||||
}); |
||||
}); |
||||
}) |
||||
}, |
||||
isTop: (data) => { |
||||
return data.scrollTop <= 20; |
||||
}, |
||||
//设置用户信息
|
||||
setUserInfo: (data) => { |
||||
uni.setStorageSync(TOKEN_FIELD, data[TOKEN_FIELD]); |
||||
uni.setStorageSync(USERINFO_FIELD, data[USERINFO_FIELD]); |
||||
}, |
||||
// 获取用户信息
|
||||
getUserInfo: (field = null) => { |
||||
const user = uni.getStorageSync(USERINFO_FIELD); |
||||
return field?user[field]:user; |
||||
}, |
||||
//微信网页登录
|
||||
wechatWeb: (request, params) => { |
||||
request(params).then(res => { |
||||
uni.$m.setUserInfo(res.data); |
||||
uni.$m.success('登录成功') |
||||
setTimeout(() => { |
||||
if (params.url) { |
||||
uni.reLaunch({url: params.url}).then(); |
||||
} else { |
||||
uni.reLaunch({url: INDEX_PATH}).then(); |
||||
} |
||||
}, 2000) |
||||
}); |
||||
}, |
||||
setPageInfo: (pageName, data) => { |
||||
let pageInfo = uni.getStorageSync(PAGEINFO_FIELD) || {}; |
||||
pageInfo[pageName] = data; |
||||
uni.setStorageSync(PAGEINFO_FIELD, pageInfo); |
||||
}, |
||||
getPageInfo: (pageName) => { |
||||
let pageInfo = uni.getStorageSync(PAGEINFO_FIELD) || {}; |
||||
return pageInfo[pageName]; |
||||
}, |
||||
list: (request, lists, pages, status) => { |
||||
if (status.value === 'nomore') { |
||||
return false; |
||||
} |
||||
status.value = 'loading'; |
||||
request(pages).then(res => { |
||||
lists.value = lists.value.concat(lists.value,res.data) |
||||
if (res.data.length === 0) { |
||||
status.value = 'nomore' |
||||
} else { |
||||
status.value = 'loadmore' |
||||
} |
||||
pages.page++; |
||||
}).catch((err) => { |
||||
status.value = 'loadmore' |
||||
}); |
||||
}, |
||||
}; |
File diff suppressed because one or more lines are too long
@ -0,0 +1,46 @@
|
||||
import {TOKEN_FIELD} from '@/config/config.js' |
||||
const service = (params) => { |
||||
return new Promise((resolve, reject) => { |
||||
let token=uni.getStorageSync(TOKEN_FIELD) |
||||
uni.request({ |
||||
url: params.url, |
||||
data: params.data, |
||||
method: params.method, |
||||
dataType: "json", |
||||
header: { |
||||
"content-type": "application/json;charset=utf-8", |
||||
"Authorization":"Bearer "+ token.token |
||||
} |
||||
}).then(res => { |
||||
if (res.statusCode === 200) { |
||||
let data = res.data; |
||||
switch (data.code) { |
||||
case 200: |
||||
resolve(data); |
||||
break; |
||||
case 203: |
||||
resolve(data); |
||||
break; |
||||
case 1001: |
||||
uni.setStorageSync('token',data.data) |
||||
service(params) |
||||
break; |
||||
case 1002: |
||||
reject(data); |
||||
break; |
||||
default: |
||||
reject(data); |
||||
break; |
||||
} |
||||
|
||||
} else { |
||||
uni.$m.error('连接服务器失败') |
||||
} |
||||
}) |
||||
|
||||
}) |
||||
|
||||
|
||||
|
||||
} |
||||
export default service; |
@ -0,0 +1,112 @@
|
||||
import QQMapWX from "@/uni_modules/m-view/lib/qqmap-wx-jssdk.min"; |
||||
|
||||
export default { |
||||
/** |
||||
* 添加单位 |
||||
* @param num |
||||
* @param unit |
||||
* @returns {string} |
||||
*/ |
||||
addUnit(num, unit = 'px') { |
||||
return (/px$/.test(num)) ? num : num + unit; |
||||
}, |
||||
/** |
||||
* 转换成px |
||||
* 和upx2px区别是可带单位 |
||||
* @param num |
||||
* @returns {string} |
||||
*/ |
||||
getPx(num, isUnit = true) { |
||||
return this.addUnit(( |
||||
/(rpx|upx)$/.test(num)) |
||||
? uni.upx2px(parseFloat(num)) |
||||
: parseFloat(num), isUnit ? 'px' : ''); |
||||
}, |
||||
|
||||
/** |
||||
* 样式转换格式 |
||||
* @param customStyle |
||||
* @param target |
||||
* @returns {{}|*|string|string} |
||||
*/ |
||||
addStyle(customStyle, target = 'object') { |
||||
// 字符串转字符串,对象转对象情形,直接返回
|
||||
if (this.empty(customStyle) || typeof (customStyle) === 'object' && target === 'object' || target === 'string' && |
||||
typeof (customStyle) === 'string') { |
||||
return customStyle |
||||
} |
||||
// 字符串转对象
|
||||
if (target === 'object') { |
||||
// 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的
|
||||
customStyle = this.trim(customStyle) |
||||
// 根据";"将字符串转为数组形式
|
||||
const styleArray = customStyle.split(';') |
||||
const style = {} |
||||
// 历遍数组,拼接成对象
|
||||
for (let i = 0; i < styleArray.length; i++) { |
||||
// 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤
|
||||
if (styleArray[i]) { |
||||
const item = styleArray[i].split(':') |
||||
style[this.trim(item[0])] = this.trim(item[1]) |
||||
} |
||||
} |
||||
return style |
||||
} |
||||
// 这里为对象转字符串形式
|
||||
let string = '' |
||||
for (const i in customStyle) { |
||||
// 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名
|
||||
const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() |
||||
string += `${key}:${customStyle[i]};` |
||||
} |
||||
// 去除两端空格
|
||||
return this.trim(string) |
||||
}, |
||||
/** |
||||
* 判断是否为空 |
||||
*/ |
||||
empty(value) { |
||||
switch (typeof value) { |
||||
case 'undefined': |
||||
return true |
||||
case 'string': |
||||
if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true |
||||
break |
||||
case 'boolean': |
||||
if (!value) return true |
||||
break |
||||
case 'number': |
||||
if (value === 0 || isNaN(value)) return true |
||||
break |
||||
case 'object': |
||||
if (value === null || value.length === 0) return true |
||||
for (const i in value) { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
return false |
||||
}, |
||||
/** |
||||
* @description 去除空格 |
||||
* @param str |
||||
* @param pos |
||||
*/ |
||||
trim(str, pos = 'both') { |
||||
str = String(str) |
||||
if (pos == 'both') { |
||||
return str.replace(/^\s+|\s+$/g, '') |
||||
} |
||||
if (pos == 'left') { |
||||
return str.replace(/^\s*/, '') |
||||
} |
||||
if (pos == 'right') { |
||||
return str.replace(/(\s*$)/g, '') |
||||
} |
||||
if (pos == 'all') { |
||||
return str.replace(/\s+/g, '') |
||||
} |
||||
return str |
||||
}, |
||||
}; |
||||
|
@ -0,0 +1,85 @@
|
||||
{ |
||||
"id": "mview", |
||||
"name": "mview", |
||||
"displayName": "mview", |
||||
"version": "3.1.36", |
||||
"description": "mview", |
||||
"keywords": [ |
||||
"mview" |
||||
], |
||||
"repository": "no", |
||||
"engines": { |
||||
"HBuilderX": "^3.1.0" |
||||
}, |
||||
"dcloudext": { |
||||
"sale": { |
||||
"regular": { |
||||
"price": "0.00" |
||||
}, |
||||
"sourcecode": { |
||||
"price": "0.00" |
||||
} |
||||
}, |
||||
"contact": { |
||||
"qq": "1416956117" |
||||
}, |
||||
"declaration": { |
||||
"ads": "无", |
||||
"data": "无", |
||||
"permissions": "无" |
||||
}, |
||||
"npmurl": "no", |
||||
"type": "component-vue" |
||||
}, |
||||
"uni_modules": { |
||||
"dependencies": [], |
||||
"encrypt": [], |
||||
"platforms": { |
||||
"cloud": { |
||||
"tcb": "y", |
||||
"aliyun": "y" |
||||
}, |
||||
"client": { |
||||
"Vue": { |
||||
"vue2": "n", |
||||
"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" |
||||
}, |
||||
"快应用": { |
||||
"华为": "y", |
||||
"联盟": "y" |
||||
} |
||||
} |
||||
} |
||||
}, |
||||
"dependencies": { |
||||
"clipboard": "^2.0.11", |
||||
"dayjs": "^1.11.3" |
||||
}, |
||||
"publishConfig": { |
||||
"registry": "no" |
||||
} |
||||
} |
Loading…
Reference in new issue