提交 1882983f 编写于 作者: DCloud_JSON's avatar DCloud_JSON

调整结构,新增个人资料修改

上级 43e66bab
<script>
import initApp from '@/common/appInit.js';
import checkIsAgree from '@/uni_modules/uni-agree/utils/uni-agree.js';
export default {
globalData: {
searchText: '',
appVersion:{}
},
onLaunch: function() {
console.log('App Launch')
initApp();
checkIsAgree();
//#ifdef APP-NVUE || H5
//预加载设置页面
uni.preloadPage({
url: "/pages/ucenter/settings/settings",
complete:e=>{
// console.log(e);
}
});
//#endif
<script>
import initApp from '@/common/appInit.js';
import checkIsAgree from '@/uni_modules/uni-agree/utils/uni-agree.js';
export default {
globalData: {
searchText: '',
appVersion: {}
},
onLaunch: function() {
console.log('App Launch')
initApp();
// #ifdef APP-PLUS
//预加载一键登录
plus.oauth.getServices(oauthServices=>{
// console.log(oauthServices);
oauthServices.forEach(({_id},item)=>{
if(_id=='provider'){
uni.preLogin({
provider:item,
complete:e=>{
console.log(e);
}
})
}
checkIsAgree();
// #endif
//#ifdef APP-NVUE || H5
//预加载设置页面
uni.preloadPage({
url: "/pages/ucenter/settings/settings",
complete: e => {
// console.log(e);
}
});
//#endif
// #ifdef APP-PLUS
//预加载一键登录
plus.oauth.getServices(oauthServices => {
// console.log(oauthServices);
oauthServices.forEach(({
_id
}, item) => {
if (_id == 'provider') {
uni.preLogin({
provider: item,
complete: e => {
console.log(e);
}
})
}
})
uni.preloadPage({
url: "/pages/ucenter/login-page/index/index"
});
}, err => {
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
// #endif
//clientDB的错误提示
const db = uniCloud.database()
function onDBError({
code, // 错误码详见https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=returnvalue
message
}) {
// 处理错误
console.log(code,message);
if([
'TOKEN_INVALID_INVALID_CLIENTID',
'TOKEN_INVALID',
'TOKEN_INVALID_TOKEN_EXPIRED',
'TOKEN_INVALID_WRONG_TOKEN',
'TOKEN_INVALID_ANONYMOUS_USER',
].includes(code)){
uni.navigateTo({
url:'/pages/ucenter/login-page/index/index'
})
uni.preloadPage({url: "/uni_modules/uni-login-page/pages/index/index"});
},err=>{
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
// #endif
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
.border-test{
/* #ifdef APP-NVUE */
border-width: 1rpx;
border-color: #DD524D;
/* #endif */
/* #ifndef APP-NVUE */
border: 1px solid #DD524D;
box-sizing: border-box;
/* #endif */
}
/* #ifndef APP-NVUE */
view,scroll-view,text,
image,switch,navigator,icons {
display: flex;
box-sizing: border-box;
flex-direction: column;
}
scroll-view{
-webkit-overflow-scrolling: touch;
}
/* #endif */
}
}
// 绑定clientDB错误事件
db.on('error', onDBError)
// 解绑clientDB错误事件
//db.off('error', onDBError)
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
.border-test {
/* #ifdef APP-NVUE */
border-width: 1rpx;
border-color: #DD524D;
/* #endif */
/* #ifndef APP-NVUE */
border: 1px solid #DD524D;
box-sizing: border-box;
/* #endif */
}
/* #ifndef APP-NVUE */
view,
scroll-view,
text,
image,
switch,
navigator,
icons {
display: flex;
box-sizing: border-box;
flex-direction: column;
}
scroll-view {
-webkit-overflow-scrolling: touch;
}
/* #endif */
</style>
module.exports = {
"h5":{
"url":"https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com",// 前端网页托管的域名
"openApp":{ // 在h5端全局悬浮引导用户下载app的功能 更多自定义要求在/common/openApp.js中修改
"openUrl":'https://sj.qq.com/myapp/detail.htm?apkName=com.tencent.android.qqdownloader&info=6646FD239A6EBA9E2DEE5DFC7E18D867',
"appname": 'base-app',
"logo": './static/logo.png',
}
},
"mp":{
"weixin":{
"id":"gh_33446d7f7a26"
}
},
"router":{
"needLogin":[ //配置需要路由拦截的页面地址,在打开这些页面之前会自动检查(不联网)uni_id_token的值是否存在/过期等
"/uni_modules/uni-id-users/pages/uni-id-users/edit",
"/uni_modules/uni-news-favorite/pages/uni-news-favorite/list",
"/pages/ucenter/edit/uploadCutImageToUnicloud"
],
"login":["univerify","smsCode","username","weixin","apple"] //默认就是短信验证码登陆
},
"about":{
"appName":"base-app",
"logo":"/static/logo.png",
"company":"数字天堂(北京)网络技术有限公司",
"slogan":"为开发而生",
"agreements":[
{
"title":"用户服务协议",
"url":"https://ask.dcloud.net.cn/protocol.html"
},
{
"title":"隐私政策",
"url":"https://ask.dcloud.net.cn/protocol.html"
}
],
"download":"https://m3w.cn/uniapp"
}
}
\ No newline at end of file
module.exports = {
"h5": {
"url": "https://static-76ce2c5e-31c7-4d81-8fcf-ed1541ecbc6e.bspapp.com", // 前端网页托管的域名
"openApp": { // 在h5端全局悬浮引导用户下载app的功能 更多自定义要求在/common/openApp.js中修改
"openUrl": 'https://sj.qq.com/myapp/detail.htm?apkName=com.tencent.android.qqdownloader&info=6646FD239A6EBA9E2DEE5DFC7E18D867',
"appname": 'base-app',
"logo": './static/logo.png',
}
},
"mp": {
"weixin": {
"id": "gh_33446d7f7a26"
}
},
"router": {
"needLogin": [ //配置需要路由拦截的页面地址,在打开这些页面之前会自动检查(不联网)uni_id_token的值是否存在/过期等
"/pages/ucenter/edit/edit",
"/uni_modules/uni-news-favorite/pages/uni-news-favorite/list",
"/pages/ucenter/edit/uploadCutImageToUnicloud"
],
"login": ["univerify", "smsCode", "username", "weixin", "apple"] //默认就是短信验证码登陆
},
"about": {
"appName": "base-app",
"logo": "/static/logo.png",
"company": "数字天堂(北京)网络技术有限公司",
"slogan": "为开发而生",
"agreements": [{
"title": "用户服务协议",
"url": "https://ask.dcloud.net.cn/protocol.html"
},
{
"title": "隐私政策",
"url": "https://ask.dcloud.net.cn/protocol.html"
}
],
"download": "https://m3w.cn/uniapp"
}
}
......@@ -31,12 +31,12 @@ export default function() {
icon: 'none'
})
uni.navigateTo({
url: "/uni_modules/uni-login-page/pages/index/index"
url: "/pages/ucenter/login-page/index/index"
})
return false
}
//控制登陆优先级
if (url == '/uni_modules/uni-login-page/pages/index/index') {
if (url == '/pages/ucenter/login-page/index/index') {
//一键登录(univerify)、密码登陆(username)、快捷登录&验证码登陆(!univerify&password)
if (login[0] == 'univerify') {
// console.log(e.url,url);
......@@ -45,7 +45,7 @@ export default function() {
}
e.url += "univerify_first=true"
} else if (login[0] == 'username') {
e.url = "/uni_modules/uni-login-page/pages/pwd-login/pwd-login"
e.url = "/pages/ucenter/login-page/pwd-login/pwd-login"
} else {
//默认即是
}
......@@ -62,40 +62,40 @@ export default function() {
uni.addInterceptor('chooseImage', {
fail(e) { // 失败回调拦截
console.log(e);
if (
e.errCode === 11 && uni.getSystemInfoSync().platform == "android" ||
e.errCode === 2 && uni.getSystemInfoSync().platform == "ios"
){
uni.showModal({
title:"无法访问摄像头",
content: "当前无摄像头访问权限,建议前往设置",
confirmText: "前往设置",
success(e) {
if (e.confirm) {
openAppPermissionSetting()
}
}
});
}
if(e.errCode === 12 && uni.getSystemInfoSync().platform == "android"){
uni.showModal({
title:"无法访问相册",
content: "当前无系统相册访问权限,建议前往设置",
confirmText: "前往设置",
success(e) {
if (e.confirm) {
openAppPermissionSetting()
}
}
});
}
if (
e.errCode === 11 && uni.getSystemInfoSync().platform == "android" ||
e.errCode === 2 && uni.getSystemInfoSync().platform == "ios"
){
uni.showModal({
title:"无法访问摄像头",
content: "当前无摄像头访问权限,建议前往设置",
confirmText: "前往设置",
success(e) {
if (e.confirm) {
openAppPermissionSetting()
}
}
});
}
if(e.errCode === 12 && uni.getSystemInfoSync().platform == "android"){
uni.showModal({
title:"无法访问相册",
content: "当前无系统相册访问权限,建议前往设置",
confirmText: "前往设置",
success(e) {
if (e.confirm) {
openAppPermissionSetting()
}
}
});
}
}
})
// #ifdef APP-PLUS
})
// #ifdef APP-PLUS
// 设备网络状态变化事件
eventListenerNetwork()
// #endif
eventListenerNetwork()
// #endif
}
/**
......@@ -132,83 +132,85 @@ function initAppVersion() {
// 设备网络状态变化事件
function eventListenerNetwork() {
//网络掉线
uni.getNetworkType({
success:res=>{
console.log(res);
if(res.networkType=='none'){
showNetworkErrPage()
}
uni.showToast({
title:'当前网络类型:'+res.networkType,
icon:'none',
duration:3000
})
}
});
//监听网络变化
uni.onNetworkStatusChange(res=> {
console.log(res.isConnected);
console.log(res.networkType);
if(res.networkType!='none'){
uni.showToast({
title:'当前网络类型:'+res.networkType,
icon:'none',
duration:3000
})
}else{
showNetworkErrPage()
uni.showToast({
title:'网络类型:'+res.networkType,
icon:'none',
duration:3000
})
}
});
function showNetworkErrPage(){
let pages = getCurrentPages();
console.log('pages.length',pages.length);
if(pages.length===0|| pages[pages.length - 1].route!='/pages/networkErr/networkErr.vue'){
uni.navigateTo({
url:'/pages/networkErr/networkErr'
})
}else{
console.log('已经打开');
}
}
/*
//网络掉线
uni.getNetworkType({
success:res=>{
console.log(res);
if(res.networkType=='none'){
showNetworkErrPage()
}
uni.showToast({
title:'当前网络类型:'+res.networkType,
icon:'none',
duration:3000
})
}
});
//监听网络变化
uni.onNetworkStatusChange(res=> {
console.log(res.isConnected);
console.log(res.networkType);
if(res.networkType!='none'){
uni.showToast({
title:'当前网络类型:'+res.networkType,
icon:'none',
duration:3000
})
}else{
showNetworkErrPage()
uni.showToast({
title:'网络类型:'+res.networkType,
icon:'none',
duration:3000
})
}
});
function showNetworkErrPage(){
let pages = getCurrentPages();
console.log('pages.length',pages.length);
if(pages.length===0 || pages[pages.length - 1].route!='/pages/networkErr/networkErr.vue'){
uni.navigateTo({
url:'/pages/networkErr/networkErr'
})
}else{
console.log('已经打开');
}
}
}
function openAppPermissionSetting(){
// 跳转到**应用**的权限页面
if (uni.getSystemInfoSync().platform == "ios") {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
/*
}
function openAppPermissionSetting(){
// 跳转到**应用**的权限页面
if (uni.getSystemInfoSync().platform == "ios") {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
// console.log(plus.device.vendor);
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
*/
}
/*
uni.addInterceptor(item, {
invoke(e) { // 调用前拦截
},
invoke(e) { // 调用前拦截
},
success() { // 成功回调拦截
},
fail(err) { // 失败回调拦截
......@@ -219,5 +221,5 @@ function openAppPermissionSetting(){
},
returnValue() { // 返回结果拦截
}
}) // 移除拦截器API removeInterceptor('request')
}) // 移除拦截器API removeInterceptor('request')
*/
\ No newline at end of file
<template>
<view class="quick-login-box">
<view class="item" v-for="(item,index) in servicesList" :key="index" @click="item.path?to(item.path):login(item.id,false)">
<view class="quick-login-box">
<view class="item" v-for="(item,index) in servicesList" :key="index"
@click="item.path?to(item.path):login(item.id,false)">
<image class="logo" :src="item.logo" mode="widthFix"></image>
<text class="login-title">{{item.text}}</text>
</view>
</view>
</template>
<script>
import {mapGetters,mapMutations} from 'vuex';
//前一个窗口的页面地址。控制点击切换快捷登陆方式是创建还是返回
import loginSuccess from 'uni_modules/uni-login-page/common/loginSuccess.js';
export default {
<script>
import {
mapGetters,
mapMutations
} from 'vuex';
//前一个窗口的页面地址。控制点击切换快捷登陆方式是创建还是返回
import loginSuccess from '@/pages/ucenter/login-page/common/loginSuccess.js';
export default {
data() {
return {
config: {
"weixin": {
"text": "微信登陆",
"logo": "../../static/login/weixin.png",
"isChecked":true
return {
servicesList: [{
"text": "账号登陆",
"logo": "/static/uni-quick-login/user.png",
"path": "/pages/ucenter/login-page/pwd-login/pwd-login"
},
"apple": {
"text": "苹果登陆",
"logo": "../../static/login/apple.png",
"isChecked":true
},
"univerify": {
"text": "一键登陆",
"logo": "../../static/login/univerify.png",
"isChecked":true
},
"qq": {
"text": "QQ登陆",
"logo": "../../static/login/qq.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"xiaomi": {
"text": "小米登陆",
"logo": "../../static/login/qq.png",
"isChecked":false //暂未提供该登陆方式的接口示例
},
"sinaweibo": {
"text": "微博登录",
"logo": "../../static/login/weibo.png",
"isChecked":false //暂未提供该登陆方式的接口示例
}
},
servicesList:[
{
"text": "账号登陆",
"logo": "../../static/login/db.png",
"path":"/uni_modules/uni-login-page/pages/pwd-login/pwd-login"
},
{
"text": "短信登陆",
"logo": "../../static/login/smsCode.png",
"path":"/uni_modules/uni-login-page/pages/index/index"
}
],
univerifyStyle: { //一键登陆弹出窗的样式配置参数
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
{
"text": "短信验证码",
"logo": "/static/uni-quick-login/sms.png",
"path": "/pages/ucenter/login-page/index/index"
}
]
}
},
props: {
config: {
type: Object,
default () {
return {
"weixin": {
"text": "微信登陆",
"logo": "/static/uni-quick-login/wechat.png",
"isChecked": true
},
"apple": {
"text": "苹果登陆",
"logo": "/static/uni-quick-login/apple.png",
"isChecked": true
},
"univerify": {
"text": "一键登陆",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": true
},
"qq": {
"text": "QQ登陆",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": false //暂未提供该登陆方式的接口示例
},
"xiaomi": {
"text": "小米登陆",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": false //暂未提供该登陆方式的接口示例
},
"sinaweibo": {
"text": "微博登录",
"logo": "/static/uni-quick-login/univerify.png",
"isChecked": false //暂未提供该登陆方式的接口示例
}
}
}
},
univerifyStyle: {
type: Object,
default () {
return { //一键登陆弹出窗的样式配置参数
"fullScreen": true, // 是否全屏显示,true表示全屏模式,false表示非全屏模式,默认值为false。
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
}
}
},
},
created() {
let servicesList = this.servicesList
//去掉当前页面对应的登陆选项
for (var i = 0; i < servicesList.length; i++) {
if (servicesList[i].path == this.getRoute(1)) {
servicesList.splice(i, 1)
}
}
},
created() {
let servicesList = this.servicesList
//去掉当前页面对应的登陆选项
for (var i = 0; i < servicesList.length; i++) {
if(servicesList[i].path == this.getRoute(1)){
servicesList.splice(i,1)
}
}
},
mounted() {
//获取当前环境能用的快捷登陆方式
// #ifdef APP-PLUS
plus.oauth.getServices(oauthServices=>{
this.oauthServices = oauthServices
oauthServices.forEach(({id})=>{
if(this.config[id].isChecked){
this.servicesList.push({...this.config[id],id})
}
})
// console.log(oauthServices);
},err=>{
uni.hideLoading()
uni.showModal({
title: '获取服务供应商失败:' +JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
// #endif
mounted() {
//获取当前环境能用的快捷登陆方式
// #ifdef APP-PLUS
plus.oauth.getServices(oauthServices => {
this.oauthServices = oauthServices
oauthServices.forEach(({
id
}) => {
if (this.config[id].isChecked) {
this.servicesList.push({
...this.config[id],
id
})
}
})
// console.log(oauthServices);
}, err => {
uni.hideLoading()
uni.showModal({
title: '获取服务供应商失败:' + JSON.stringify(err),
showCancel: false,
confirmText: '知道了'
});
console.error('获取服务供应商失败:' + JSON.stringify(err));
})
// #endif
},
methods: {
...mapMutations({
setUserInfo: 'user/login'
}),
getRoute(n=0){
let pages = getCurrentPages();
console.log('route-pages-length',pages.length);
if(n>pages.length){ return '' }
return '/'+pages[pages.length - n].route
},
to(path){
console.log('比较',this.getRoute(2),path)
if(this.getRoute(2)==path){ // 控制路由是重新打开还是返回,避免重复打开页面
uni.navigateBack();
}else{
uni.navigateTo({url:path})
}
methods: {
...mapMutations({
setUserInfo: 'user/login'
}),
getRoute(n = 0) {
let pages = getCurrentPages();
console.log('route-pages-length', pages.length);
if (n > pages.length) {
return ''
}
return '/' + pages[pages.length - n].route
},
login(type,navigateBack=true) {
console.log(arguments);
console.log('services',services);
let oauthService = this.oauthServices.find((service) => service.id == type)
console.log(type);
// #ifdef APP-PLUS
//请勿直接使用前端获取的unionid或openid直接用于登陆,前端的数据都是不可靠的
if(type=='weixin'){
return oauthService.authorize(({code})=>{
console.log(code);
this.quickLogin({code},type)
},
err=>{
uni.hideLoading()
console.log(err);
})
}
// #endif
uni.login({
"provider": type,
"univerifyStyle":this.univerifyStyle,
success:async e => {
console.log(e);
if(type=='apple'){
let res = await this.getUserInfo({provider:"apple"})
Object.assign(e.authResult,res.userInfo)
}
this.quickLogin(e.authResult,type)
},
fail: (err) => {
uni.hideLoading()
console.log(err);
if(type=='univerify'){
if(err.metadata.error_data){
uni.showToast({
title: "一键登陆:"+err.metadata.error_data,
icon: 'none'
});
}
switch (err.errCode){
case 30002:
console.log('在一键登陆界面,点击其他登陆方式');
break;
case 30003:
console.log('关闭了登陆');
if(navigateBack){ uni.navigateBack() }
break;
case 30006:
uni.showModal({
title: "登陆服务初始化错误",
content:err.metadata.error_data,
showCancel: false,
confirmText: '知道了',
});
break;
default:
break;
}
}
}
})
},
quickLogin(params,type){//联网验证登陆
console.log(params,type);
this.request('user-center/login_by_'+type,params,(data,result)=>{
console.log(result);
if(result.code === 0){
if(type=='univerify'){
uni.closeAuthView()
}
uni.hideLoading()
loginSuccess(result)
delete result.userInfo.token
this.setUserInfo(result.userInfo)
}
},{showLoading:true})
},
async getUserInfo(e){
return new Promise((resolve, reject)=>{
uni.getUserInfo({
...e,
success: (res) => {
resolve(res);
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err),
showCancel: false
});
reject(err);
}
})
})
to(path) {
console.log('比较', this.getRoute(2), path)
if (this.getRoute(2) == path) { // 控制路由是重新打开还是返回,避免重复打开页面
uni.navigateBack();
} else {
uni.navigateTo({
url: path
})
}
},
login(type, navigateBack = true) {
console.log(arguments);
console.log('services', services);
let oauthService = this.oauthServices.find((service) => service.id == type)
console.log(type);
// #ifdef APP-PLUS
//请勿直接使用前端获取的unionid或openid直接用于登陆,前端的数据都是不可靠的
if (type == 'weixin') {
return oauthService.authorize(({
code
}) => {
console.log(code);
this.quickLogin({
code
}, type)
},
err => {
uni.hideLoading()
console.log(err);
})
}
// #endif
uni.login({
"provider": type,
"univerifyStyle": this.univerifyStyle,
success: async e => {
console.log(e);
if (type == 'apple') {
let res = await this.getUserInfo({
provider: "apple"
})
Object.assign(e.authResult, res.userInfo)
}
this.quickLogin(e.authResult, type)
},
fail: (err) => {
uni.hideLoading()
console.log(err);
if (type == 'univerify') {
if (err.metadata.error_data) {
uni.showToast({
title: "一键登陆:" + err.metadata.error_data,
icon: 'none'
});
}
switch (err.errCode) {
case 30002:
console.log('在一键登陆界面,点击其他登陆方式');
break;
case 30003:
console.log('关闭了登陆');
if (navigateBack) {
uni.navigateBack()
}
break;
case 30006:
uni.showModal({
title: "登陆服务初始化错误",
content: err.metadata.error_data,
showCancel: false,
confirmText: '知道了',
});
break;
default:
break;
}
}
}
})
},
quickLogin(params, type) { //联网验证登陆
console.log(params, type);
this.request('user-center/login_by_' + type, params, (data, result) => {
console.log(result);
if (result.code === 0) {
if (type == 'univerify') {
uni.closeAuthView()
}
uni.hideLoading()
loginSuccess(result)
delete result.userInfo.token
this.setUserInfo(result.userInfo)
}
}, {
showLoading: true
})
},
async getUserInfo(e) {
return new Promise((resolve, reject) => {
uni.getUserInfo({
...e,
success: (res) => {
resolve(res);
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err),
showCancel: false
});
reject(err);
}
})
})
}
}
}
......@@ -219,6 +253,7 @@
width: 750rpx;
justify-content: space-around;
}
.item {
flex-direction: column;
justify-content: center;
......@@ -228,10 +263,11 @@
.logo {
width: 60rpx;
height: 60rpx;
height: 60rpx;
}
.login-title {
.login-title {
margin-top: 4px;
font-size: 26rpx;
}
</style>
\ No newline at end of file
</style>
......@@ -20,20 +20,20 @@ export default function request(name,params,callback=false,{showLoading=false,lo
return new Promise((resolve,reject)=>{
uniCloud.callFunction({name,data:{action,params},
success(e){
// console.log(e);
console.log(e);
const {result:{data,code}} = e
console.log(data,code);
if (code === 0 ) {
resolve(e)
return callback(data,e.result,e)
}
if(debug){
uni.showModal({
content: JSON.stringify(e),
showCancel: false,
confirmText: '知道了'
})
if (code != 0 ) {
if(debug){
uni.showModal({
content: JSON.stringify(e),
showCancel: false,
confirmText: '知道了'
})
}
}
resolve(e)
return callback(data,e.result,e)
},
fail(err){
reject(err)
......
......@@ -7,30 +7,16 @@
//#endif
"enablePullDownRefresh": true
}
},
// #ifdef APP-PLUS
{
"path": "pages/networkErr/networkErr",
"style": {
"navigationStyle": "custom",
"backgroundColor": "transparent",
"app-plus": {
"animationType": "fade-in",
"background": "transparent",
"popGesture": "none"
}
}
},
// #endif
{
"path": "pages/list/news-list",
"style": {
//#ifndef MP
"navigationStyle": "custom",
//#endif
"enablePullDownRefresh": true
}
},
},
{
"path": "pages/list/news-list",
"style": {
//#ifndef MP
"navigationStyle": "custom",
//#endif
"enablePullDownRefresh": true
}
},
{
"path": "pages/grid/grid",
"style": {
......@@ -39,7 +25,7 @@
//#endif
}
}, {
"path": "uni_modules/uni-login-page/pages/index/index",
"path": "pages/ucenter/login-page/index/index",
"style": {
"navigationBarTitleText": "",
"app-plus": {
......@@ -73,13 +59,18 @@
},
"navigationBarTitleText": "文章详情"
}
}, {
"path": "pages/ucenter/ucenter",
"path": "pages/ucenter/edit/bind-mobile/bind-mobile",
"style": {
"navigationStyle": "custom"
}
}, {
},
{
"path": "pages/ucenter/ucenter",
"style": {
"navigationStyle": "custom"
}
},{
"path": "uni_modules/uni-feedback/pages/opendb-feedback/list",
"style": {
"navigationBarTitleText": "常见问题"
......@@ -144,10 +135,10 @@
}
}
}, {
"path": "uni_modules/uni-agree/pages/uni-agree/uni-agree",
"style": {
"navigationStyle": "custom",
"app-plus":{"popGesture": "none"}
"path": "uni_modules/uni-agree/pages/uni-agree/uni-agree",
"style": {
"navigationStyle": "custom",
"app-plus":{"popGesture": "none"}
}
}, {
"path": "pages/ucenter/settings/settings",
......@@ -156,9 +147,9 @@
}
}, {
"path": "uni_modules/uni-id-users/pages/uni-id-users/edit",
"path": "pages/ucenter/edit/edit",
"style": {
"navigationBarTitleText": "编辑资料"
"navigationBarTitleText": "个人资料"
}
}, {
"path": "pages/ucenter/edit/uploadCutImageToUnicloud",
......@@ -166,17 +157,17 @@
"navigationStyle": "custom"
}
}, {
"path": "uni_modules/uni-login-page/pages/pwd-login/pwd-login",
"path": "pages/ucenter/login-page/pwd-login/pwd-login",
"style": {
"navigationBarTitleText": ""
}
}, {
"path": "uni_modules/uni-login-page/pages/pwd-retrieve/pwd-retrieve",
"path": "pages/ucenter/login-page/pwd-retrieve/pwd-retrieve",
"style": {
"navigationBarTitleText": ""
}
}, {
"path": "uni_modules/uni-login-page/pages/phone-code/phone-code",
"path": "pages/ucenter/login-page/phone-code/phone-code",
"style": {
"navigationBarTitleText": ""
}
......@@ -196,19 +187,19 @@
}
}, {
"path": "uni_modules/uni-login-page/pages/register/register",
"path": "pages/ucenter/login-page/register/register",
"style": {
"navigationBarTitleText": "注册",
"enablePullDownRefresh": false
}
},
{
"path":"uni_modules/uni-news-favorite/pages/uni-news-favorite/list",
"style":{
"navigationBarTitleText": "阅读记录",
"enablePullDownRefresh": false
}
},
{
"path":"uni_modules/uni-news-favorite/pages/uni-news-favorite/list",
"style":{
"navigationBarTitleText": "阅读记录",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
......@@ -222,7 +213,7 @@
"path": "pages/list/list"
},
{
"path": "uni_modules/uni-login-page/pages/index/index"
"path": "pages/ucenter/login-page/index/index"
},
{
"path": "pages/test/test"
......@@ -255,4 +246,4 @@
"text": "我的"
}]
}
}
}
......@@ -53,7 +53,7 @@
import uParse from '@/components/u-parse/parse.vue';
const db = uniCloud.database();
const dbCollectionName = 'opendb-news-favorite';
const newsFavoriteTable = db.collection('opendb-news-favorite')
import { mapGetters } from 'vuex';
export default {
components: {
......@@ -80,7 +80,8 @@
return `_id =="${this.id}"`
},
...mapGetters({
'userInfo':'user/info'
'userInfo':'user/info',
'hasLogin':'user/hasLogin'
})
},
onLoad(event) {
......@@ -114,8 +115,8 @@
},
methods: {
setFavorite(){
if(!this.userInfo)return
db.collection(dbCollectionName).where({
if(!this.has)return
newsFavoriteTable.where({
article_id:this.id,
user_id:this.userInfo._id
})
......@@ -128,9 +129,9 @@
update_date:Date.now()
}
if(res.result.data.length == 0){
return db.collection(dbCollectionName).add(value)
return newsFavoriteTable.add(value)
} else {
return db.collection(dbCollectionName).where({
return newsFavoriteTable.where({
article_id:this.id,
user_id:this.userInfo._id
})
......
<template>
<view class="box">
<view class="content">
<text class="networkErr">网络连接不可用</text>
<button type="default" @click="toSet">去设置</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
statusBarHeight:0
}
},
mounted() {
uni.onNetworkStatusChange(res=> {
console.log(res.isConnected);
console.log(res.networkType);
if(res.networkType!='none'){
uni.showToast({
title:'当前网络类型:'+res.networkType,
icon:'none',
duration:3000
})
uni.navigateBack({
animationType:'fade-out'
})
}
});
},
methods: {
toSet(){
if (uni.getSystemInfoSync().platform == "ios") {
plus.runtime.launchApplication({
action: 'App-Prefs:root=WIFI'
}, function(e) {
console.log(JSON.stringify(e));
});
} else {
var main = plus.android.runtimeMainActivity();
var Intent = plus.android.importClass("android.content.Intent");
var mIntent = new Intent('android.settings.DATA_ROAMING_SETTINGS');
main.startActivity(mIntent);
}
}
},
}
</script>
<style >
page {
background: transparent;
}
.box{
display: flex;
width: 750rpx;
height: 100vh;
justify-content: center;
align-items: center;
}
.content{
height: 100px;
width: 400rpx;
background-color: #DD524D;
}
</style>
......@@ -8,22 +8,26 @@
<text>应用相关权限</text>
<button type="default" @click="openAppPermissionSetting">打开</button>
<button type="default" @click="iosSetting">iosSetting</button> -->
<button type="default" @click="openCamera">打开相机</button>
<button type="default" @click="open=1">打开</button>
<web-view v-if="open" style="height: 1px;" src="https://ur.alipay.com/2tZMWI"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
return {
open:0
}
},
onLoad() {
// 当某个权限调用失败
// 1.先检测手机的该模块是否打开
// 2.检测当前应用是否被授权了该模块对应的权限
// 提示,并点击跳转到设置
// 提示,并点击跳转到设置
// plus.runtime.openURL('https://ur.alipay.com/2tZMWI',e=>{
// console.log(e);
// })
},
methods: {
openCamera(){
......
<template>
<view class="box">
<!-- 登录框 (选择手机号所属国家和地区需要另行实现) -->
<uni-easyinput focus type="number" class="phone-input-box" :inputBorder="false" v-model="formData.phone"
maxlength="11" placeholder="请输入手机号"></uni-easyinput>
<uni-easyinput type="number" class="phone-input-box" :inputBorder="false" v-model="formData.code" maxlength="6"
placeholder="请输入验证码">
<template slot="right">
<login-short-code ref="shortCode" :phone="formData.phone"></login-short-code>
</template>
</uni-easyinput>
<button class="send-btn-box" type="primary" @click="submit">提交</button>
</view>
</template>
<script>
import {
mapMutations,
mapGetters
} from 'vuex';
export default {
data() {
return {
currenPhoneArea: '',
formData: {
phone:"",
code:""
}
}
},
computed: {
tipText() {
return `验证码已通过短信发送至${this.currenPhoneArea} ${this.formData.phone}。密码为6 - 20位`
},
canSubmit() {
return this.isPhone && this.isPwd && this.isCode;
}
},
onLoad(event) {
},
onReady() {
},
methods: {
...mapMutations({
setUserInfo: 'user/login'
}),
/**
* 完成并提交
*/
submit() {
console.log(this.formData);
this.request('user-center/bind_mobile_by_sms', {
"mobile": this.formData.phone,
"code": this.formData.code
}, (data, result) => {
console.log(result);
this.setUserInfo({"mobile":result.mobile})
uni.showToast({
title: result.msg,
icon: 'none'
});
if (result.code === 0) {
uni.navigateBack()
}
})
}
}
}
</script>
<style>
.box {
align-items: center;
justify-content: center;
padding-top: 10px;
}
.box /deep/ .uni-easyinput__content {
height: 45px;
}
.phone-input-box {
width: 650rpx;
height: 50px;
margin-top: 16px;
background-color: #f9f9f9;
border-radius: 6rpx;
flex-direction: row;
flex-wrap: nowrap;
}
.send-btn-box {
width: 650rpx;
margin-top: 15px;
}
</style>
<template>
<view>
<uni-list>
<uni-list-item class="item" link>
<view @click="setAvatar" slot="body" class="item">
<text>头像</text>
<image class="avatarUrl" :src="userInfo.avatar||nullAvatarUrl" mode="widthFix"></image>
</view>
</uni-list-item>
<uni-list-item class="item" @click="setNickname()" title="昵称" :rightText="userInfo.nickname||'未设置'" link></uni-list-item>
<uni-list-item class="item" @click="bindMobile" title="手机号" :rightText="userInfo.mobile||'未绑定'" link></uni-list-item>
</uni-list>
<uni-popup ref="dialog" type="dialog">
<uni-popup-dialog mode="input" :value="userInfo.nickname" @confirm="setNickname" title="设置昵称" placeholder="请输入要设置的昵称">
</uni-popup-dialog>
</uni-popup>
</view>
</template>
<script>
import {
mapMutations,
mapGetters
} from 'vuex';
const db = uniCloud.database();
const usersTable = db.collection('uni-id-users')
export default {
data() {
return {
nullAvatarUrl: '/static/uni-center/logo.png',
univerifyStyle: {
authButton: {
"title": "本机号码一键绑定", // 授权按钮文案
},
otherLoginButton: {
"title": "其他号码绑定",
}
}
}
},
computed: {
...mapGetters({
userInfo: 'user/info',
login: 'user/hasLogin'
})
},
methods: {
...mapMutations({
setUserInfo: 'user/login'
}),
bindMobile() {
// #ifdef APP-PLUS
uni.preLogin({
provider: 'univerify',
success: this.univerify(), //预登录成功
fail(res) { // 预登录失败
// 不显示一键登录选项(或置灰)
console.log(res)
}
})
// #endif
// #ifndef APP-PLUS
this.bindMobileBySmsCode()
//...去用验证码绑定
// #endif
},
univerify() {
uni.login({
"provider": 'univerify',
"univerifyStyle": this.univerifyStyle,
success: async e => {
console.log(e.authResult);
this.request('user-center/bind_mobile_by_univerify',
e.authResult,
(data, result) =>
{
console.log(result);
if(result.code===0){
this.setUserInfo({"mobile":result.mobile})
uni.closeAuthView()
}else{
uni.showModal({
content: JSON.stringify(result.msg),
showCancel: false,
complete() {
uni.closeAuthView()
}
});
}
}
)
},
fail: (err) => {
console.log(err);
this.bindMobileBySmsCode()
}
})
},
bindMobileBySmsCode() {
uni.navigateTo({
url:'/pages/ucenter/edit/bind-mobile/bind-mobile'
})
},
setNickname(nickname) {
console.log(nickname);
if (nickname) {
usersTable.where('_id==$env.uid').update({
nickname
}).then(e => {
console.log(e);
if (e.result.updated) {
uni.showToast({
title: '更新成功',
icon: 'none'
});
this.setUserInfo({
nickname
});
} else {
uni.showToast({
title: '没有变化',
icon: 'none'
});
}
})
this.$refs.dialog.close()
} else {
this.$refs.dialog.open()
}
},
setAvatar() {
console.log('点击编辑信息');
uni.chooseImage({
count: 1,
success: (res) => {
// 头像剪裁尺寸
let options = {
width: 600,
height: 600
}
// 剪裁并上传头像
uni.navigateTo({
url: '/pages/ucenter/edit/uploadCutImageToUnicloud?path=' +
res
.tempFilePaths[0] +
`&options=${JSON.stringify(options)}`,
animationType: "fade-in",
events: {
uploadAvatarAfter: ({
url
}) => {
console.log(url);
// 使用 clientDB 提交数据
usersTable.where('_id==$env.uid').update({
avatar: url
}).then((res) => {
console.log(res);
uni.showToast({
icon: 'none',
title: '修改成功'
})
this.setUserInfo({
avatar: url
});
}).catch((err) => {
uni.showModal({
content: err.message ||
'请求服务失败',
showCancel: false
})
}).finally(() => {
uni.hideLoading()
})
}
}
});
}
})
},
}
}
</script>
<style>
.item {
width: 750rpx;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 60px;
}
.avatarUrl {
width: 50px;
height: 50px;
border-radius: 6px;
}
</style>
......@@ -5,7 +5,6 @@ page {
flex: 1;
height: 100%;
}
/* #endif */
.wrap {
/* #ifndef APP-NVUE */
......
......@@ -41,7 +41,7 @@
<script>
var univerify_first,currentWebview;//是否一键登陆优先
import baseappConfig from '@/baseapp.config.js';
import mixin from '../../common/loginPage.mixin.js';
import mixin from '../common/loginPage.mixin.js';
var currentPage;
export default {
mixins:[mixin],
......@@ -131,7 +131,7 @@ import mixin from '../../common/loginPage.mixin.js';
</script>
<style>
@import url("../../common/loginPage.css");
@import url("../common/loginPage.css");
.content-top-title {
text-align: center;
......
......@@ -28,7 +28,7 @@
</template>
<script>
import mixin from '../../common/loginPage.mixin.js';
import mixin from '../common/loginPage.mixin.js';
export default {
mixins:[mixin],
data() {
......@@ -101,7 +101,7 @@
</script>
<style>
@import url("../../common/loginPage.css");
@import url("../common/loginPage.css");
.phone-input-box{
margin-top: 10px;
}
......
......@@ -21,8 +21,9 @@
<uni-forms-item name="pwd">
<uni-easyinput type="password" class="phone-input-box" :inputBorder="false"
v-model="formData.pwd" placeholder="请输入密码"></uni-easyinput>
</uni-forms-item>
<button class="send-btn-box" type="primary" @click="pwdLogin">登录</button>
</uni-forms-item>
<button class="send-btn-box" :disabled="!canLogin" :type="canLogin?'primary':'default'"
@click="pwdLogin">登录</button>
</uni-forms>
<!-- 忘记密码 -->
<view class="auth-box">
......@@ -36,7 +37,7 @@
</template>
<script>
import mixin from '../../common/loginPage.mixin.js';
import mixin from '../common/loginPage.mixin.js';
export default {
mixins:[mixin],
data() {
......@@ -47,7 +48,7 @@
},
computed: {
canLogin() {
return this.isPhone && this.isPwd;
return this.formData.phone.length && this.isPwd;
}
},
methods: {
......@@ -55,12 +56,12 @@
* 页面跳转,找回密码
*/
toRetrievePwd() {
if (!this.isPhone) return uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
// if (!this.isPhone) return uni.showToast({
// title: '请输入正确的手机号',
// icon: 'none'
// });
uni.navigateTo({
url: '../pwd-retrieve/pwd-retrieve?phoneNumber=' + this.formData.phone + '&phoneArea=' + this.currenPhoneArea
url: '../pwd-retrieve/pwd-retrieve?phoneNumber=' + (this.isPhone?this.formData.phone:'') + '&phoneArea=' + this.currenPhoneArea
})
},
/**
......@@ -119,7 +120,7 @@
toRegister(e){
console.log(e);
uni.navigateTo({
url:'/uni_modules/uni-login-page/pages/register/register'
url:'/pages/ucenter/login-page/register/register'
})
}
}
......@@ -127,7 +128,7 @@
</script>
<style>
@import url("../../common/loginPage.css");
@import url("../common/loginPage.css");
.phone-input-box {
margin-top: 20rpx;
}
......
......@@ -8,11 +8,12 @@
<!-- 登录框 (选择手机号所属国家和地区需要另行实现) -->
<uni-forms ref="form" :value="formData" :rules="rules">
<uni-forms-item name="phone">
<uni-easyinput type="number" class="phone-input-box" :inputBorder="false"
<!-- focus规则如果上一页携带来“手机号码”数据就focus验证码输入框,否则focus手机号码输入框 -->
<uni-easyinput :focus="!formData.phone.length" type="number" class="phone-input-box" :inputBorder="false"
v-model="formData.phone" maxlength="11" placeholder="请输入手机号"></uni-easyinput>
</uni-forms-item>
<uni-forms-item name="code">
<uni-easyinput type="number" class="phone-input-box" :inputBorder="false"
<uni-easyinput :focus="formData.phone.length" type="number" class="phone-input-box" :inputBorder="false"
v-model="formData.code" maxlength="6" placeholder="请输入验证码">
<template slot="right">
<login-short-code ref="shortCode" :phone="formData.phone"></login-short-code>
......@@ -36,7 +37,7 @@
</template>
<script>
import mixin from '../../common/loginPage.mixin.js';
import mixin from '../common/loginPage.mixin.js';
export default {
mixins:[mixin],
data() {
......@@ -60,7 +61,7 @@ import mixin from '../../common/loginPage.mixin.js';
},
onReady() {
if(this.formData.phone){
// this.$refs.shortCode.start();
this.$refs.shortCode.start();
}
},
methods: {
......@@ -91,7 +92,7 @@ import mixin from '../../common/loginPage.mixin.js';
</script>
<style>
@import url("../../common/loginPage.css");
@import url("../common/loginPage.css");
.phone-input-box{
margin-top: 20rpx;
}
......
<template>
<view class="uni-container">
<uni-forms ref="form" :value="formData" :rules="rules" validate-trigger="submit" err-show-type="undertext">
<uni-forms-item name="username" label="用户名" required>
<uni-easyinput placeholder="请输入用户名" v-model="formData.username" trim="both" />
<uni-forms-item name="username" required>
<uni-easyinput :inputBorder="false" class="phone-input-box" placeholder="请输入用户名" v-model="formData.username" trim="both" />
</uni-forms-item>
<uni-forms-item name="nickname" label="昵称">
<uni-easyinput placeholder="请输入用户昵称" v-model="formData.nickname" trim="both" />
<uni-forms-item name="nickname">
<uni-easyinput :inputBorder="false" class="phone-input-box" placeholder="请输入用户昵称" v-model="formData.nickname" trim="both" />
</uni-forms-item>
<uni-forms-item name="password" label="密码" v-model="formData.password" required>
<uni-easyinput placeholder="请输入6-20位密码" type="password" v-model="formData.password" trim="both" />
<uni-forms-item name="password" v-model="formData.password" required>
<uni-easyinput :inputBorder="false" class="phone-input-box" placeholder="请输入6-20位密码" type="password" v-model="formData.password" trim="both" />
</uni-forms-item>
<uni-forms-item name="pwd2" label="确认密码" v-model="formData.pwd2" required>
<uni-easyinput placeholder="再次输入密码" type="password" v-model="formData.pwd2" trim="both" />
</uni-forms-item>
<view class="uni-button-group">
<button type="primary" class="uni-button" @click="submit">注册并登陆</button>
</view>
<uni-forms-item name="pwd2" v-model="formData.pwd2" required>
<uni-easyinput :inputBorder="false" class="phone-input-box" placeholder="再次输入密码" type="password" v-model="formData.pwd2" trim="both" />
</uni-forms-item>
<login-ikonw class="login-iknow" :link="link" text="登录即表示同意用户协议和隐私政策"></login-ikonw>
<button class="send-btn-box" type="primary" @click="submit">注册并登陆</button>
</uni-forms>
</view>
</template>
<script>
import rules from './validator.js';
import mixin from '../../common/loginPage.mixin.js';
import mixin from '../common/loginPage.mixin.js';
export default {
mixins:[mixin],
data() {
......@@ -68,7 +67,8 @@ import mixin from '../../common/loginPage.mixin.js';
}
</script>
<style>
<style>
@import url("../common/loginPage.css");
.uni-container {
padding: 15px;
}
......@@ -102,7 +102,6 @@ import mixin from '../../common/loginPage.mixin.js';
}
.uni-button {
width: 184px;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
......
<template>
<view class="content">
<!-- 功能列表 -->
<uni-list :border="false" class="mb10" v-for="(sublist,index) in agreeList">
<uni-list-item :border="false" class="mb1" v-for="(item,i) in sublist" :key="i" :title="item.title"
<uni-list :border="false" class="mt10" v-for="(sublist,index) in agreeList">
<uni-list-item :border="false" class="list-item" v-for="(item,i) in sublist" :key="i" :title="item.title"
:clickable="true" @click="itemClick(item)" :showSwitch="item.showSwitch" :switchChecked="item.isChecked"
:link="!item.showSwitch"></uni-list-item>
:link="!item.showSwitch"
v-if="item.event!='changePwd'||hasLogin"
></uni-list-item>
</uni-list>
<!-- 退出按钮 -->
<view class="bottom-back" @click="clickLogout">
<text class="bottom-back-text" v-if="userInfo">退出登录</text>
<text class="bottom-back-text" v-if="hasLogin">退出登录</text>
<text class="bottom-back-text" v-else>登录</text>
</view>
</view>
......@@ -56,7 +58,8 @@
},
computed: {
...mapGetters({
'userInfo': 'user/info'
'userInfo': 'user/info',
'hasLogin': 'user/hasLogin',
})
},
onLoad() {
......@@ -71,13 +74,14 @@
}),
toEdit() {
uni.navigateTo({
url: '/uni_modules/uni-id-users/pages/uni-id-users/edit'
url: '/pages/ucenter/edit/edit'
});
},
changePwd() {
uni.navigateTo({
url: '/uni_modules/uni-login-page/pages/pwd-retrieve/pwd-retrieve?phoneNumber=' + (this
.userInfo && this.userInfo.phone ? this.userInfo.phone : '') + '&phoneArea=+86',
url: '/pages/ucenter/login-page/pwd-retrieve/pwd-retrieve?phoneNumber='
+ (this.userInfo && this.userInfo.phone ? this.userInfo.phone : '')
+ '&phoneArea=+86',
fail: err => {
console.log(err);
}
......@@ -185,7 +189,7 @@
})
},
clickLogout() {
if (this.userInfo) {
if (this.hasLogin) {
uni.showModal({
title: '提示',
content: '是否退出登录',
......@@ -202,12 +206,12 @@
});
} else {
uni.navigateTo({
url: '/uni_modules/uni-login-page/pages/index/index'
url: '/pages/ucenter/login-page/index/index'
});
}
},
/**
* 每一项的点击事件
},
/**
* 每一项的点击事件
*/
itemClick(item) {
if (item.event) {
......@@ -218,17 +222,17 @@
uni.showLoading({
title: '清除中',
mask: true
});
/*
任何临时存储或删除不直接影响程序运行逻辑(清除缓存必定造成业务逻辑的变化,如:打开页面的图片不从缓存中读取而从网络请求)的内容都可以视为缓存。主要有storage、和file写入。
缓存分为三部分
原生层(如:webview、x5播放器的、第三方sdk的、地图组件等)
前端框架(重启就会自动清除)
开发者自己的逻辑(如:
本示例的 检测更新功能下载了apk安装包,
其他逻辑需要根据开发者自己的业务设计
比如:有聊天功能的应用,聊天记录是否视为缓存,还是单独提供清除聊天记录的功能由开发者自己设计
});
/*
任何临时存储或删除不直接影响程序运行逻辑(清除缓存必定造成业务逻辑的变化,如:打开页面的图片不从缓存中读取而从网络请求)的内容都可以视为缓存。主要有storage、和file写入。
缓存分为三部分
原生层(如:webview、x5播放器的、第三方sdk的、地图组件等)
前端框架(重启就会自动清除)
开发者自己的逻辑(如:
本示例的 检测更新功能下载了apk安装包,
其他逻辑需要根据开发者自己的业务设计
比如:有聊天功能的应用,聊天记录是否视为缓存,还是单独提供清除聊天记录的功能由开发者自己设计
*/
uni.getSavedFileList({
success:res=>{
......@@ -236,24 +240,24 @@
uni.removeSavedFile({
filePath: res.fileList[0].filePath,
complete:res=>{
console.log(res);
uni.hideLoading()
uni.showToast({
title: '清除成功',
icon: 'none'
console.log(res);
uni.hideLoading()
uni.showToast({
title: '清除成功',
icon: 'none'
});
}
});
}else{
uni.hideLoading()
uni.showToast({
title: '清除成功',
icon: 'none'
});
}else{
uni.hideLoading()
uni.showToast({
title: '清除成功',
icon: 'none'
});
}
},
complete:e=>{
console.log(e);
},
complete:e=>{
console.log(e);
}
});
},
......@@ -314,15 +318,16 @@
font-size: 33rpx;
}
.mb10 {
margin-bottom: 10px;
.mt10 {
margin-top: 10px;
}
.content /deep/ .uni-list {
background-color: #F9F9F9;
}
.mb1 {
margin-bottom: 1px;
.list-item {
height: 50px;
margin-bottom: 1px;
}
</style>
</style>
<template>
<view class="center">
<view class="userInfo" @click="toEdit">
<image class="logo-img" :src="login ? (userInfo.avatar || avatarUrl) :avatarUrl"></image>
<view class="userInfo" @click="toUserInfo">
<image class="logo-img" :src="userInfo.avatar||avatarUrl"></image>
<view class="logo-title">
<text class="uer-name">{{login ? userInfo.nickname||userInfo.username||userInfo.mobile : '未登录'}}</text>
<text class="uer-name">{{userInfo.nickname||userInfo.username||userInfo.mobile||'未登录'}}</text>
<text class="go-login-navigat-arrow navigat-arrow" v-if="!login">&#xe65e;</text>
</view>
</view>
......@@ -21,7 +21,7 @@
<view class="item-footer-badge"></view>
</view>
</uni-list-item>
</uni-list>
</uni-list>
</view>
</template>
......@@ -83,16 +83,17 @@
}, {
title: '设置',
to: '/pages/ucenter/settings/settings'
}, {
}],
[{
title: '关于',
to: '/pages/ucenter/about/about'
}]
]
}
},
onLoad() {
onLoad() {
//#ifdef APP-PLUS
this.ucenterList[this.ucenterList.length - 1].unshift({
this.ucenterList[this.ucenterList.length - 2].unshift({
title: '检查更新',
rightText: this.appVersion.version + '-' + this.appVersion.versionCode,
event: 'checkVersion',
......@@ -106,14 +107,15 @@
login: 'user/hasLogin'
})
// #ifdef APP-PLUS
,appVersion() {
,
appVersion() {
return getApp().appVersion
}
// #endif
},
methods: {
...mapMutations({
setUserInfo: 'user/login'
methods: {
...mapMutations({
setUserInfo: 'user/login'
}),
toSettings() {
uni.navigateTo({
......@@ -129,64 +131,20 @@
}
},
async checkVersion() {
let res = await callCheckVersion()
console.log(res);
if(res.result.code == 0){
uni.showToast({
title: res.result.message,
icon: 'none'
});
let res = await callCheckVersion()
console.log(res);
if (res.result.code == 0) {
uni.showToast({
title: res.result.message,
icon: 'none'
});
}
checkUpdate()
},
toEdit() {
console.log('点击编辑信息');
// uni.navigateTo({
// url: '/uni_modules/uni-id-users/pages/uni-id-users/edit'
// })
const token = uni.getStorageSync('uni_id_token')
if(token){
uni.chooseImage({
count:1,
success:(res)=> {
// 头像剪裁尺寸
let options = {
width:600,
height:600
}
// 剪裁并上传头像
uni.navigateTo({
url:'/pages/ucenter/edit/uploadCutImageToUnicloud?path=' + res.tempFilePaths[0] + `&options=${JSON.stringify(options)}`,
animationType:"fade-in",
events:{
uploadAvatarAfter:({url})=>{
console.log(url);
// 使用 clientDB 提交数据
db.collection('uni-id-users').where('_id==$env.uid').update({avatar:url}).then((res) => {
console.log(res);
uni.showToast({
icon: 'none',
title: '修改成功'
})
this.setUserInfo({avatar:url});
}).catch((err) => {
uni.showModal({
content: err.message || '请求服务失败',
showCancel: false
})
}).finally(() => {
uni.hideLoading()
})
}
}
});
}
})
}else{
uni.navigateTo({
url:'/uni_modules/uni-login-page/pages/index/index'
})
}
toUserInfo() {
uni.navigateTo({
url: '/pages/ucenter/edit/edit'
})
},
tapGrid(index) {
uni.showToast({
......@@ -233,11 +191,6 @@
title: msg,
icon: 'none'
});
}).catch((err) => {
uni.showModal({
content: err.message || '请求服务失败',
showCancel: false
})
}).finally(() => {
uni.hideLoading()
})
......@@ -254,11 +207,9 @@
font-style: normal;
src: url('~@/static/text-icon.ttf') format('truetype');
}
page {
background-color: #f8f8f8;
}
/* #endif*/
/* 解决头条小程序字体图标不显示问题,因为头条运行时自动插入了span标签,且有全局字体 */
......@@ -266,15 +217,12 @@
text :not(view) {
font-family: texticons;
}
/* #endif */
.center {
flex: 1;
flex-direction: column;
background-color: #f8f8f8;
}
.userInfo {
width: 750rpx;
padding: 20rpx;
......@@ -283,25 +231,18 @@
flex-direction: column;
align-items: center;
}
/* .logo-hover {
opacity: 0.8;
} */
.logo-img {
width: 150rpx;
height: 150rpx;
border-radius: 150rpx;
border: solid 1px #FFFFFF;
}
.logo-title {
height: 150rpx;
flex: 1;
align-items: center;
justify-content: space-between;
flex-direction: row;
margin-left: 20rpx;
}
.uer-name {
......@@ -383,6 +324,6 @@
/* #ifdef APP-NVUE */
border-radius: 10rpx;
/* #endif */
background-color: #DD524D;
background-color: #DD524D;
}
</style>
</style>
// 上次启动时的用户信息
let userHistory = uni.getStorageSync('userInfo') || null;
let userHistory = uni.getStorageSync('userInfo') || {};
let state = {
/**
* 是否需要强制登录
*/
/* 是否需要强制登录 */
forcedLogin: false,
hasLogin: Boolean(userHistory),
info: userHistory
......@@ -22,20 +20,18 @@ let state = {
let _info = state.info;
state.info = Object.assign({}, _info, info);
state.hasLogin = true;
uni.setStorageSync('userInfo', info);
uni.setStorageSync('userInfo', state.info);
},
logout(state) {
state.info = null;
state.info = {};
state.hasLogin = false;
uni.setStorageSync('userInfo', null);
uni.setStorageSync('userInfo', {});
uni.setStorageSync('uni_id_token', '');
}
},
actions = {
}
export default {
state,
getters,
......
'use strict';
let uniID = require('uni-id')
const uniCaptcha = require('uni-captcha')
const createConfig = require('uni-config-center')
const uniIdConfig = createConfig({
pluginId: 'uni-id'
})._config
const db = uniCloud.database()
const dbCmd = db.command
exports.main = async (event, context) => {
......@@ -84,8 +88,8 @@ exports.main = async (event, context) => {
} : {
state: 0
})
if(res.type == 'register'){
await registerSuccess(res.uid)
if (res.type == 'register') {
await registerSuccess(res.uid)
}
return await uniIdLogCollection.add(logData)
}
......@@ -94,6 +98,46 @@ exports.main = async (event, context) => {
let res = {}
switch (event.action) {
case 'bind_mobile_by_univerify':
let {
appid, apiKey, apiSecret
} = uniIdConfig.service.univerify
let univerifyRes = await uniCloud.getPhoneNumber({
provider: 'univerify',
appid,
apiKey,
apiSecret,
access_token: params.access_token,
openid: params.openid
})
if (univerifyRes.code === 0) {
res = await uniID.bindMobile({
uid: params.uid,
mobile: univerifyRes.phoneNumber
})
res.mobile = univerifyRes.phoneNumber
}
break;
case 'bind_mobile_by_sms':
console.log({
uid: params.uid,
mobile: params.mobile,
code: params.code
});
let verifyCode = await uniID.verifyCode({
mobile: params.mobile,
code: params.code
})
if (verifyCode.code === 0) {
res = await uniID.bindMobile({
uid: params.uid,
mobile: params.mobile
})
} else {
res = verifyCode
}
console.log(res, verifyCode);
break;
case 'register':
let {
username, password, gender, nickname
......@@ -164,7 +208,15 @@ exports.main = async (event, context) => {
case 'logout':
res = await uniID.logout(event.uniIdToken)
break;
case 'sendSmsCode':
case 'sendSmsCode':
//123546
return uniID.setVerifyCode({
mobile: params.mobile,
code:'123456'
})
// 简单限制一下客户端调用频率
const ipLimit = await db.collection('uni-verify').where({
ip: context.CLIENTIP,
......
{
"name": "user-center",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"uni-captcha": "file:../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-config-center": "file:../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-id": "file:../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id"
}
},
"../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha": {
"version": "0.1.0",
"license": "Apache-2.0"
},
"../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center": {
"version": "0.0.2",
"license": "Apache-2.0"
},
"../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id": {
"version": "3.0.12",
"license": "Apache-2.0",
"dependencies": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
},
"node_modules/uni-captcha": {
"resolved": "../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"link": true
},
"node_modules/uni-config-center": {
"resolved": "../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-id": {
"resolved": "../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id",
"link": true
}
},
"dependencies": {
"uni-captcha": {
"version": "file:../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-config-center": {
"version": "file:../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"uni-id": {
"version": "file:../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id",
"requires": {
"uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
}
......@@ -9,8 +9,8 @@
"author": "",
"license": "ISC",
"dependencies": {
"uni-captcha": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-id": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id"
"uni-captcha": "file:../../../uni_modules/uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-config-center": "file:../../../uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-id": "file:../../../uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id"
}
}
{
"name": "user",
"version": "1.0.0",
"lockfileVersion": 1,
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"uni-captcha": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"uni-id": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id"
}
},
"../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha": {},
"../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center": {},
"../../../../uni-id/uniCloud/cloudfunctions/common/uni-id": {
"dependencies": {
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
},
"../../../../uni-id/uniCloud/cloudfunctions/common/uni-id/node_modules/uni-config-center": {
"resolved": "../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-captcha": {
"resolved": "../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha",
"link": true
},
"node_modules/uni-config-center": {
"resolved": "../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center",
"link": true
},
"node_modules/uni-id": {
"resolved": "../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"link": true
}
},
"dependencies": {
"uni-captcha": {
"version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
......
......@@ -2,7 +2,7 @@
"bsonType": "object",
"required": ["user_id", "title", "content"],
"permission": {
"read": "doc.uid == auth.uid && doc.article_status == 0 || doc.article_status == 1",
"read": "doc.article_status == 0 || doc.article_status == 1",
"create": "auth.uid != null",
"update": "doc.uid == auth.uid",
"delete": "doc.uid == auth.uid"
......
......@@ -8,9 +8,9 @@
</view>
</template>
</uni-forms-item>
<uni-forms-item name="gender" label="性别" required>
<!-- <uni-forms-item name="gender" label="性别" required>
<uni-data-checkbox v-model="formData.gender" :localdata="formOptions.gender_localdata" />
</uni-forms-item>
</uni-forms-item> -->
<uni-forms-item name="mobile" label="手机号码" v-if="formData.mobile">
<uni-easyinput placeholder="手机号码" :disabled="true" v-model="formData.mobile" trim="both" />
</uni-forms-item>
......
{
"id": "uni-login-page",
"displayName": "uni-login-page",
"version": "1.0.0",
"description": "uni-login-page",
"keywords": [
"uni-login-page"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"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": "u",
"aliyun": "u"
},
"client": {
"App": {
"app-vue": "u",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
# uni-login-page
\ No newline at end of file
{
"name": "user-center",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"uni-captcha": {
"version": "file:../../../../uni-captcha/uniCloud/cloudfunctions/common/uni-captcha"
},
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"uni-id": {
"version": "file:../../../../uni-id/uniCloud/cloudfunctions/common/uni-id",
"requires": {
"uni-config-center": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
},
"dependencies": {
"uni-config-center": {
"version": "file:../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
}
}
## 1.2.9(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.2.8(2021-02-05)
- 调整为uni_modules目录规范
## 1.2.7(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持 PC 端
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
## 1.3.0(2021-04-13)
修复某些情况下uni-popup-dialog输入框的值获取失败的问题
## 1.2.9(2021-02-05)
- 优化 组件引用关系,通过uni_modules引用组件
## 1.2.8(2021-02-05)
- 调整为uni_modules目录规范
## 1.2.7(2021-02-05)
- 调整为uni_modules目录规范
- 新增 支持 PC 端
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('keyup', listener)
})
},
render: () => {}
}
// #endif
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('keyup', listener)
})
},
render: () => {}
}
// #endif
<template>
<view class="uni-popup-dialog">
<view class="uni-dialog-title">
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{title}}</text>
</view>
<view class="uni-dialog-content">
<text class="uni-dialog-content-text" v-if="mode === 'base'">{{content}}</text>
<input v-else class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholder" :focus="focus">
</view>
<view class="uni-dialog-button-group">
<view class="uni-dialog-button" @click="close">
<text class="uni-dialog-button-text">取消</text>
</view>
<view class="uni-dialog-button uni-border-left" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">确定</text>
</view>
</view>
<view v-if="popup.isDesktop" class="uni-popup-dialog__close" @click="close">
<span class="uni-popup-dialog__close-icon "></span>
</view>
<!-- #ifdef H5 -->
<keypress @esc="close" @enter="onOk"/>
<!-- #endif -->
</view>
</template>
<script>
// #ifdef H5
import keypress from './keypress.js'
// #endif
/**
* PopUp 弹出层-对话框样式
* @description 弹出层-对话框样式
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} value input 模式下的默认值
* @property {String} placeholder input 模式下输入提示
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} mode = [base|input] 模式、
* @value base 基础对话框
* @value input 可输入对话框
* @property {String} content 对话框内容
* @property {Boolean} beforeClose 是否拦截取消事件
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default {
name: "uniPopupDialog",
components: {
// #ifdef H5
keypress
// #endif
},
props: {
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: [String, Number],
default: '请输入内容'
},
/**
* 对话框主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'error'
},
/**
* 对话框模式 base/input
*/
mode: {
type: String,
default: 'base'
},
/**
* 对话框标题
*/
title: {
type: String,
default: '提示'
},
/**
* 对话框内容
*/
content: {
type: String,
default: ''
},
/**
* 拦截取消事件 ,如果拦截取消事件,必须监听close事件,执行 done()
*/
beforeClose: {
type: Boolean,
default: false
}
},
data() {
return {
dialogType: 'error',
focus: false,
val: ""
}
},
inject: ['popup'],
watch: {
type(val) {
this.dialogType = val
},
mode(val) {
if (val === 'input') {
this.dialogType = 'info'
}
},
value(val) {
this.val = val
}
},
created() {
// 对话框遮罩不可点击
this.popup.mkclick = false
if (this.mode === 'input') {
this.dialogType = 'info'
this.val = this.value
} else {
this.dialogType = this.type
}
},
mounted() {
this.focus = true
},
methods: {
/**
* 点击确认按钮
*/
<template>
<view class="uni-popup-dialog">
<view class="uni-dialog-title">
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{title}}</text>
</view>
<view class="uni-dialog-content">
<text class="uni-dialog-content-text" v-if="mode === 'base'">{{content}}</text>
<input v-else class="uni-dialog-input" v-model="val" type="text" :placeholder="placeholder" :focus="focus" >
</view>
<view class="uni-dialog-button-group">
<view class="uni-dialog-button" @click="close">
<text class="uni-dialog-button-text">取消</text>
</view>
<view class="uni-dialog-button uni-border-left" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">确定</text>
</view>
</view>
</view>
</template>
<script>
/**
* PopUp 弹出层-对话框样式
* @description 弹出层-对话框样式
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} value input 模式下的默认值
* @property {String} placeholder input 模式下输入提示
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} mode = [base|input] 模式、
* @value base 基础对话框
* @value input 可输入对话框
* @property {String} content 对话框内容
* @property {Boolean} beforeClose 是否拦截取消事件
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default {
name: "uniPopupDialog",
props: {
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: [String, Number],
default: '请输入内容'
},
/**
* 对话框主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'error'
},
/**
* 对话框模式 base/input
*/
mode: {
type: String,
default: 'base'
},
/**
* 对话框标题
*/
title: {
type: String,
default: '提示'
},
/**
* 对话框内容
*/
content: {
type: String,
default: ''
},
/**
* 拦截取消事件 ,如果拦截取消事件,必须监听close事件,执行 done()
*/
beforeClose: {
type: Boolean,
default: false
}
},
data() {
return {
dialogType: 'error',
focus: false,
val: ""
}
},
inject: ['popup'],
watch: {
type(val) {
this.dialogType = val
},
mode(val) {
if (val === 'input') {
this.dialogType = 'info'
}
},
value(val) {
this.val = val
}
},
created() {
// 对话框遮罩不可点击
this.popup.mkclick = false
if (this.mode === 'input') {
this.dialogType = 'info'
this.val = this.value
} else {
this.dialogType = this.type
}
},
mounted() {
this.focus = true
},
methods: {
/**
* 点击确认按钮
*/
onOk() {
this.$emit('confirm', () => {
if (this.mode === 'input'){
this.$emit('confirm', this.val)
}else{
this.popup.close()
if (this.mode === 'input') this.val = this.value
}, this.mode === 'input' ? this.val : '')
},
/**
* 点击取消按钮
*/
close() {
if (this.beforeClose) {
this.$emit('close', () => {
this.popup.close()
})
return
}
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-dialog {
width: 300px;
border-radius: 5px;
background-color: #fff;
}
.uni-dialog-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 15px;
padding-bottom: 5px;
}
.uni-dialog-title-text {
font-size: 16px;
font-weight: 500;
}
.uni-dialog-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
padding: 5px 15px 15px 15px;
}
.uni-dialog-content-text {
font-size: 14px;
color: #6e6e6e;
}
.uni-dialog-button-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
border-top-color: #f5f5f5;
border-top-style: solid;
border-top-width: 1px;
}
.uni-dialog-button {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 45px;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-style: solid;
border-left-width: 1px;
}
.uni-dialog-button-text {
font-size: 14px;
}
.uni-button-color {
color: $uni-color-primary;
}
.uni-dialog-input {
flex: 1;
font-size: 14px;
}
.uni-popup__success {
color: $uni-color-success;
}
.uni-popup__warn {
color: $uni-color-warning;
}
.uni-popup__error {
color: $uni-color-error;
}
.uni-popup__info {
color: #909399;
}
.uni-popup-dialog__close {
/* #ifndef APP-NVUE */
display: block;
cursor: pointer;
/* #endif */
position: absolute;
top: 9px;
right: 17px;
}
.uni-popup-dialog__close-icon {
/* #ifndef APP-NVUE */
display: inline-block;
/* #endif */
width: 13px;
height: 1px;
background: #909399;
transform: rotate(45deg);
}
.uni-popup-dialog__close-icon::after {
/* #ifndef APP-NVUE */
content: '';
display: block;
/* #endif */
width: 13px;
height: 1px;
background: #909399;
transform: rotate(-90deg);
}
</style>
}
},
/**
* 点击取消按钮
*/
close() {
if (this.beforeClose) {
this.$emit('close', () => {
this.popup.close()
})
return
}
this.popup.close()
}
}
}
</script>
<style scoped>
.uni-popup-dialog {
width: 300px;
border-radius: 15px;
background-color: #fff;
}
.uni-dialog-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 15px;
padding-bottom: 5px;
}
.uni-dialog-title-text {
font-size: 16px;
font-weight: 500;
}
.uni-dialog-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
padding: 5px 15px 15px 15px;
}
.uni-dialog-content-text {
font-size: 14px;
color: #6e6e6e;
}
.uni-dialog-button-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
border-top-color: #f5f5f5;
border-top-style: solid;
border-top-width: 1px;
}
.uni-dialog-button {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 45px;
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-style: solid;
border-left-width: 1px;
}
.uni-dialog-button-text {
font-size: 14px;
}
.uni-button-color {
color: #007aff;
}
.uni-dialog-input {
flex: 1;
font-size: 14px;
}
.uni-popup__success {
color: #4cd964;
}
.uni-popup__warn {
color: #f0ad4e;
}
.uni-popup__error {
color: #dd524d;
}
.uni-popup__info {
color: #909399;
}
</style>
\ No newline at end of file
<template>
<view class="uni-popup-message">
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+[type]">
<text class="uni-popup-message-text" :class="'uni-popup__'+[type]+'-text'">{{message}}</text>
</view>
</view>
</template>
<script>
/**
* PopUp 弹出层-消息提示
* @description 弹出层-消息提示
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} message 消息提示文字
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
*/
export default {
name: 'UniPopupMessage',
props: {
/**
* 主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'success'
},
/**
* 消息文字
*/
message: {
type: String,
default: ''
},
/**
* 显示时间,设置为 0 则不会自动关闭
*/
duration: {
type: Number,
default: 3000
}
},
inject: ['popup'],
data() {
return {}
},
created() {
this.popup.childrenMsg = this
},
methods: {
open() {
if (this.duration === 0) return
clearTimeout(this.popuptimer)
this.popuptimer = setTimeout(() => {
this.popup.close()
}, this.duration)
},
close() {
clearTimeout(this.popuptimer)
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-message {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
}
.uni-popup-message__box {
background-color: #e1f3d8;
padding: 10px 15px;
border-color: #eee;
border-style: solid;
border-width: 1px;
flex: 1;
}
@media screen and (min-width: 500px) {
.fixforpc-width {
margin-top: 20px;
border-radius: 4px;
flex: none;
min-width: 380px;
/* #ifndef APP-NVUE */
max-width: 50%;
/* #endif */
/* #ifdef APP-NVUE */
max-width: 500px;
/* #endif */
}
}
.uni-popup-message-text {
font-size: 14px;
padding: 0;
}
.uni-popup__success {
background-color: #e1f3d8;
}
.uni-popup__success-text {
color: #67C23A;
}
.uni-popup__warn {
background-color: #faecd8;
}
.uni-popup__warn-text {
color: #E6A23C;
}
.uni-popup__error {
background-color: #fde2e2;
}
.uni-popup__error-text {
color: #F56C6C;
}
.uni-popup__info {
background-color: #F2F6FC;
}
.uni-popup__info-text {
color: #909399;
}
</style>
<template>
<view class="uni-popup-message">
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+[type]">
<text class="uni-popup-message-text" :class="'uni-popup__'+[type]+'-text'">{{message}}</text>
</view>
</view>
</template>
<script>
/**
* PopUp 弹出层-消息提示
* @description 弹出层-消息提示
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} message 消息提示文字
* @property {String} duration 显示时间,设置为 0 则不会自动关闭
*/
export default {
name: 'UniPopupMessage',
props: {
/**
* 主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'success'
},
/**
* 消息文字
*/
message: {
type: String,
default: ''
},
/**
* 显示时间,设置为 0 则不会自动关闭
*/
duration: {
type: Number,
default: 3000
}
},
inject: ['popup'],
data() {
return {}
},
created() {
this.popup.childrenMsg = this
},
methods: {
open() {
if (this.duration === 0) return
clearTimeout(this.popuptimer)
this.popuptimer = setTimeout(() => {
this.popup.close()
}, this.duration)
},
close() {
clearTimeout(this.popuptimer)
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-message {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
}
.uni-popup-message__box {
background-color: #e1f3d8;
padding: 10px 15px;
border-color: #eee;
border-style: solid;
border-width: 1px;
flex: 1;
}
@media screen and (min-width: 500px) {
.fixforpc-width {
margin-top: 20px;
border-radius: 4px;
flex: none;
min-width: 380px;
/* #ifndef APP-NVUE */
max-width: 50%;
/* #endif */
/* #ifdef APP-NVUE */
max-width: 500px;
/* #endif */
}
}
.uni-popup-message-text {
font-size: 14px;
padding: 0;
}
.uni-popup__success {
background-color: #e1f3d8;
}
.uni-popup__success-text {
color: #67C23A;
}
.uni-popup__warn {
background-color: #faecd8;
}
.uni-popup__warn-text {
color: #E6A23C;
}
.uni-popup__error {
background-color: #fde2e2;
}
.uni-popup__error-text {
color: #F56C6C;
}
.uni-popup__info {
background-color: #F2F6FC;
}
.uni-popup__info-text {
color: #909399;
}
</style>
<template>
<view class="uni-popup-share">
<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view>
<view class="uni-share-content">
<view class="uni-share-content-box">
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
<text class="uni-share-text">{{item.text}}</text>
</view>
</view>
</view>
<view class="uni-share-button-box">
<button class="uni-share-button" @click="close">取消</button>
</view>
</view>
</template>
<script>
export default {
name: 'UniPopupShare',
props: {
title: {
type: String,
default: '分享到'
}
},
inject: ['popup'],
data() {
return {
bottomData: [{
text: '微信',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
name: 'weixin'
},
{
text: 'QQ',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
name: 'qq'
},
{
text: '新浪',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
name: 'sinaweibo'
},
{
text: '复制链接',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
name: 'copy'
}
]
}
},
created() {},
methods: {
/**
* 选择内容
*/
select(item, index) {
this.$emit('select', {
item,
index
}, () => {
this.popup.close()
})
},
/**
* 关闭窗口
*/
close() {
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-share {
background-color: #fff;
}
.uni-share-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 40px;
}
.uni-share-title-text {
font-size: 14px;
color: #666;
}
.uni-share-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 10px;
}
.uni-share-content-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: wrap;
width: 360px;
}
.uni-share-content-item {
width: 90px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
padding: 10px 0;
align-items: center;
}
.uni-share-content-item:active {
background-color: #f5f5f5;
}
.uni-share-image {
width: 30px;
height: 30px;
}
.uni-share-text {
margin-top: 10px;
font-size: 14px;
color: #3B4144;
}
.uni-share-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-share-button {
flex: 1;
border-radius: 50px;
color: #666;
font-size: 16px;
}
.uni-share-button::after {
border-radius: 50px;
}
</style>
<template>
<view class="uni-popup-share">
<view class="uni-share-title"><text class="uni-share-title-text">{{title}}</text></view>
<view class="uni-share-content">
<view class="uni-share-content-box">
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
<text class="uni-share-text">{{item.text}}</text>
</view>
</view>
</view>
<view class="uni-share-button-box">
<button class="uni-share-button" @click="close">取消</button>
</view>
</view>
</template>
<script>
export default {
name: 'UniPopupShare',
props: {
title: {
type: String,
default: '分享到'
}
},
inject: ['popup'],
data() {
return {
bottomData: [{
text: '微信',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
name: 'wx'
},
{
text: '支付宝',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
name: 'wx'
},
{
text: 'QQ',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
name: 'qq'
},
{
text: '新浪',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
name: 'sina'
},
{
text: '百度',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
name: 'copy'
},
{
text: '其他',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
name: 'more'
}
]
}
},
created() {},
methods: {
/**
* 选择内容
*/
select(item, index) {
this.$emit('select', {
item,
index
}, () => {
this.popup.close()
})
},
/**
* 关闭窗口
*/
close() {
this.popup.close()
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup-share {
background-color: #fff;
}
.uni-share-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 40px;
}
.uni-share-title-text {
font-size: 14px;
color: #666;
}
.uni-share-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 10px;
}
.uni-share-content-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: wrap;
width: 360px;
}
.uni-share-content-item {
width: 90px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
padding: 10px 0;
align-items: center;
}
.uni-share-content-item:active {
background-color: #f5f5f5;
}
.uni-share-image {
width: 30px;
height: 30px;
}
.uni-share-text {
margin-top: 10px;
font-size: 14px;
color: #3B4144;
}
.uni-share-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-share-button {
flex: 1;
border-radius: 50px;
color: #666;
font-size: 16px;
}
.uni-share-button::after {
border-radius: 50px;
}
</style>
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('keyup', listener)
})
},
render: () => {}
}
// #endif
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('keyup', listener)
})
},
render: () => {}
}
// #endif
export default {
created() {
if (this.type === 'message') {
// 不显示遮罩
this.maskShow = false
// 获取子组件对象
this.childrenMsg = null
}
},
methods: {
customOpen() {
if (this.childrenMsg) {
this.childrenMsg.open()
}
},
customClose() {
if (this.childrenMsg) {
this.childrenMsg.close()
}
}
}
}
export default {
created() {
if (this.type === 'message') {
// 不显示遮罩
this.maskShow = false
// 获取子组件对象
this.childrenMsg = null
}
},
methods: {
customOpen() {
if (this.childrenMsg) {
this.childrenMsg.open()
}
},
customClose() {
if (this.childrenMsg) {
this.childrenMsg.close()
}
}
}
}
import message from './message.js';
// 定义 type 类型:弹出类型:top/bottom/center
const config = {
// 顶部弹出
top: 'top',
// 底部弹出
bottom: 'bottom',
// 居中弹出
center: 'center',
// 消息提示
message: 'top',
// 对话框
dialog: 'center',
// 分享
share: 'bottom',
}
export default {
data() {
return {
config: config,
popupWidth: 0,
popupHeight: 0
}
},
mixins: [message],
computed: {
isDesktop() {
return this.popupWidth >= 500 && this.popupHeight >= 500
}
},
mounted() {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop
} = uni.getSystemInfoSync()
this.popupWidth = windowWidth
this.popupHeight = windowHeight + windowTop
}
fixSize()
// #ifdef H5
window.addEventListener('resize', fixSize)
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', fixSize)
})
// #endif
},
}
import message from './message.js';
// 定义 type 类型:弹出类型:top/bottom/center
const config = {
// 顶部弹出
top: 'top',
// 底部弹出
bottom: 'bottom',
// 居中弹出
center: 'center',
// 消息提示
message: 'top',
// 对话框
dialog: 'center',
// 分享
share: 'bottom',
}
export default {
data() {
return {
config: config,
popupWidth: 0,
popupHeight: 0
}
},
mixins: [message],
computed: {
isDesktop() {
return this.popupWidth >= 500 && this.popupHeight >= 500
}
},
mounted() {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop
} = uni.getSystemInfoSync()
this.popupWidth = windowWidth
this.popupHeight = windowHeight + windowTop
}
fixSize()
// #ifdef H5
window.addEventListener('resize', fixSize)
this.$once('hook:beforeDestroy', () => {
window.removeEventListener('resize', fixSize)
})
// #endif
},
}
export default {
created() {
if (this.type === 'share') {
// 关闭点击
this.mkclick = false
}
},
methods: {
customOpen() {
console.log('share 打开了');
},
customClose() {
console.log('share 关闭了');
}
}
}
export default {
created() {
if (this.type === 'share') {
// 关闭点击
this.mkclick = false
}
},
methods: {
customOpen() {
console.log('share 打开了');
},
customClose() {
console.log('share 关闭了');
}
}
}
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']"
@touchmove.stop.prevent="clear">
<uni-transition v-if="maskShow" class="uni-mask--hook" :mode-class="['fade']" :styles="maskClass" :duration="duration"
:show="showTrans" @click="onTap" />
<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
<view class="uni-popup__wrapper-box" @click.stop="clear">
<slot />
</view>
</uni-transition>
<!-- #ifdef H5 -->
<keypress v-if="maskShow" @esc="onTap" />
<!-- #endif -->
</view>
</template>
<script>
import popup from './popup.js'
// #ifdef H5
import keypress from './keypress.js'
// #endif
/**
* PopUp 弹出层
* @description 弹出层组件,为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @value message 消息提示
* @value dialog 对话框
* @value share 底部分享示例
* @property {Boolean} animation = [ture|false] 是否开启动画
* @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
* @event {Function} change 打开关闭弹窗触发,e={show: false}
*/
export default {
name: 'UniPopup',
components: {
// #ifdef H5
keypress
// #endif
},
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: 'center'
},
// maskClick
maskClick: {
type: Boolean,
default: true
}
},
provide() {
return {
popup: this
}
},
mixins: [popup],
watch: {
/**
* 监听type类型
*/
type: {
handler: function(newVal) {
this[this.config[newVal]]()
},
immediate: true
},
isDesktop: {
handler: function(newVal) {
this[this.config[this.type]]()
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick: {
handler: function(val) {
this.mkclick = val
},
immediate: true
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
maskClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'right': 0,
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
},
transClass: {
'position': 'fixed',
'left': 0,
'right': 0,
},
maskShow: true,
mkclick: true,
popupstyle: this.isDesktop ? 'fixforpc-top' : 'top'
}
},
created() {
this.mkclick = this.maskClick
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
},
methods: {
clear(e) {
// TODO nvue 取消冒泡
e.stopPropagation()
},
open() {
this.showPopup = true
this.$nextTick(() => {
new Promise(resolve => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.showTrans = true
// fixed by mehaotian 兼容 app 端
this.$nextTick(() => {
resolve();
})
}, 50);
}).then(res => {
// 自定义打开事件
clearTimeout(this.msgtimer)
this.msgtimer = setTimeout(() => {
this.customOpen && this.customOpen()
}, 100)
this.$emit('change', {
show: true,
type: this.type
})
})
})
},
close(type) {
this.showTrans = false
this.$nextTick(() => {
this.$emit('change', {
show: false,
type: this.type
})
clearTimeout(this.timer)
// 自定义关闭事件
this.customOpen && this.customClose()
this.timer = setTimeout(() => {
this.showPopup = false
}, 300)
})
},
onTap() {
if (!this.mkclick) return
this.close()
},
/**
* 顶部弹出样式处理
*/
top() {
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
this.ani = ['slide-top']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
}
},
/**
* 底部弹出样式处理
*/
bottom() {
this.popupstyle = 'bottom'
this.ani = ['slide-bottom']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
'bottom': 0
}
},
/**
* 中间弹出样式处理
*/
center() {
this.popupstyle = 'center'
this.ani = ['zoom-out', 'fade']
this.transClass = {
'position': 'fixed',
/* #ifndef APP-NVUE */
'display': 'flex',
'flexDirection': 'column',
/* #endif */
'bottom': 0,
'left': 0,
'right': 0,
'top': 0,
'justifyContent': 'center',
'alignItems': 'center'
}
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.fixforpc-z-index {
/* #ifndef APP-NVUE */
z-index: 999;
/* #endif */
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
opacity: 0;
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.uni-top-mask {
opacity: 1;
}
.uni-bottom-mask {
opacity: 1;
}
.uni-center-mask {
opacity: 1;
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
}
.top {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.fixforpc-top {
top: 0;
}
.bottom {
bottom: 0;
}
.uni-popup__wrapper-box {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
}
.content-ani {
// transition: transform 0.3s;
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.uni-top-content {
transform: translateY(0);
}
.uni-bottom-content {
transform: translateY(0);
}
.uni-center-content {
transform: scale(1);
opacity: 1;
}
</style>
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']"
@touchmove.stop.prevent="clear">
<uni-transition v-if="maskShow" class="uni-mask--hook" :mode-class="['fade']" :styles="maskClass" :duration="duration"
:show="showTrans" @click="onTap" />
<uni-transition :mode-class="ani" :styles="transClass" :duration="duration" :show="showTrans" @click="onTap">
<view class="uni-popup__wrapper-box" @click.stop="clear">
<slot />
</view>
</uni-transition>
<!-- #ifdef H5 -->
<keypress v-if="maskShow" @esc="onTap" />
<!-- #endif -->
</view>
</template>
<script>
import popup from './popup.js'
// #ifdef H5
import keypress from './keypress.js'
// #endif
/**
* PopUp 弹出层
* @description 弹出层组件,为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @value message 消息提示
* @value dialog 对话框
* @value share 底部分享示例
* @property {Boolean} animation = [ture|false] 是否开启动画
* @property {Boolean} maskClick = [ture|false] 蒙版点击是否关闭弹窗
* @event {Function} change 打开关闭弹窗触发,e={show: false}
*/
export default {
name: 'UniPopup',
components: {
// #ifdef H5
keypress
// #endif
},
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: 'center'
},
// maskClick
maskClick: {
type: Boolean,
default: true
}
},
provide() {
return {
popup: this
}
},
mixins: [popup],
watch: {
/**
* 监听type类型
*/
type: {
handler: function(newVal) {
this[this.config[newVal]]()
},
immediate: true
},
isDesktop: {
handler: function(newVal) {
this[this.config[this.type]]()
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick: {
handler: function(val) {
this.mkclick = val
},
immediate: true
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
maskClass: {
'position': 'fixed',
'bottom': 0,
'top': 0,
'left': 0,
'right': 0,
'backgroundColor': 'rgba(0, 0, 0, 0.4)'
},
transClass: {
'position': 'fixed',
'left': 0,
'right': 0,
},
maskShow: true,
mkclick: true,
popupstyle: this.isDesktop ? 'fixforpc-top' : 'top'
}
},
created() {
this.mkclick = this.maskClick
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
},
methods: {
clear(e) {
// TODO nvue 取消冒泡
e.stopPropagation()
},
open() {
this.showPopup = true
this.$nextTick(() => {
new Promise(resolve => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.showTrans = true
// fixed by mehaotian 兼容 app 端
this.$nextTick(() => {
resolve();
})
}, 50);
}).then(res => {
// 自定义打开事件
clearTimeout(this.msgtimer)
this.msgtimer = setTimeout(() => {
this.customOpen && this.customOpen()
}, 100)
this.$emit('change', {
show: true,
type: this.type
})
})
})
},
close(type) {
this.showTrans = false
this.$nextTick(() => {
this.$emit('change', {
show: false,
type: this.type
})
clearTimeout(this.timer)
// 自定义关闭事件
this.customOpen && this.customClose()
this.timer = setTimeout(() => {
this.showPopup = false
}, 300)
})
},
onTap() {
if (!this.mkclick) return
this.close()
},
/**
* 顶部弹出样式处理
*/
top() {
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
this.ani = ['slide-top']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
}
},
/**
* 底部弹出样式处理
*/
bottom() {
this.popupstyle = 'bottom'
this.ani = ['slide-bottom']
this.transClass = {
'position': 'fixed',
'left': 0,
'right': 0,
'bottom': 0
}
},
/**
* 中间弹出样式处理
*/
center() {
this.popupstyle = 'center'
this.ani = ['zoom-out', 'fade']
this.transClass = {
'position': 'fixed',
/* #ifndef APP-NVUE */
'display': 'flex',
'flexDirection': 'column',
/* #endif */
'bottom': 0,
'left': 0,
'right': 0,
'top': 0,
'justifyContent': 'center',
'alignItems': 'center'
}
}
}
}
</script>
<style lang="scss" scoped>
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.fixforpc-z-index {
/* #ifndef APP-NVUE */
z-index: 999;
/* #endif */
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
opacity: 0;
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.uni-top-mask {
opacity: 1;
}
.uni-bottom-mask {
opacity: 1;
}
.uni-center-mask {
opacity: 1;
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
}
.top {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.fixforpc-top {
top: 0;
}
.bottom {
bottom: 0;
}
.uni-popup__wrapper-box {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
}
.content-ani {
// transition: transform 0.3s;
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.uni-top-content {
transform: translateY(0);
}
.uni-bottom-content {
transform: translateY(0);
}
.uni-center-content {
transform: scale(1);
opacity: 1;
}
</style>
{
"id": "uni-popup",
"displayName": "PopUp 弹出层",
"version": "1.2.9",
"description": " Popup 组件,提供常用的弹层",
"keywords": [
"popup",
"uni-ui",
"弹出层",
"uni-popup"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-transition"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"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"
}
}
}
}
{
"id": "uni-popup",
"displayName": "PopUp 弹出层",
"version": "1.3.0",
"description": " Popup 组件,提供常用的弹层",
"keywords": [
"popup",
"uni-ui",
"弹出层",
"uni-popup"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"category": [
"前端组件",
"通用组件"
],
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
},
"uni_modules": {
"dependencies": [
"uni-transition"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"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"
}
}
}
}
}
\ No newline at end of file
此差异已折叠。
## 1.1.0(2021-04-22)
- 新增 通过方法自定义动画
- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
- 优化 动画触发逻辑,使动画更流畅
- 优化 支持单独的动画类型
- 优化 文档示例
## 1.0.2(2021-02-05)
- 调整为uni_modules目录规范
// const defaultOption = {
// duration: 300,
// timingFunction: 'linear',
// delay: 0,
// transformOrigin: '50% 50% 0'
// }
// #ifdef APP-NVUE
const nvueAnimation = uni.requireNativePlugin('animation')
// #endif
class MPAnimation {
constructor(options, _this) {
this.options = options
this.animation = uni.createAnimation(options)
this.currentStepAnimates = {}
this.next = 0
this.$ = _this
}
_nvuePushAnimates(type, args) {
let aniObj = this.currentStepAnimates[this.next]
let styles = {}
if (!aniObj) {
styles = {
styles: {},
config: {}
}
} else {
styles = aniObj
}
if (animateTypes1.includes(type)) {
if (!styles.styles.transform) {
styles.styles.transform = ''
}
let unit = ''
if(type === 'rotate'){
unit = 'deg'
}
styles.styles.transform += `${type}(${args+unit}) `
} else {
styles.styles[type] = `${args}`
}
this.currentStepAnimates[this.next] = styles
}
_animateRun(styles = {}, config = {}) {
let ref = this.$.$refs['ani'].ref
if (!ref) return
return new Promise((resolve, reject) => {
nvueAnimation.transition(ref, {
styles,
...config
}, res => {
resolve()
})
})
}
_nvueNextAnimate(animates, step = 0, fn) {
let obj = animates[step]
if (obj) {
let {
styles,
config
} = obj
this._animateRun(styles, config).then(() => {
step += 1
this._nvueNextAnimate(animates, step, fn)
})
} else {
this.currentStepAnimates = {}
typeof fn === 'function' && fn()
this.isEnd = true
}
}
step(config = {}) {
// #ifndef APP-NVUE
this.animation.step(config)
// #endif
// #ifdef APP-NVUE
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
this.next++
// #endif
return this
}
run(fn) {
// #ifndef APP-NVUE
this.$.animationData = this.animation.export()
this.$.timer = setTimeout(() => {
typeof fn === 'function' && fn()
}, this.$.durationTime)
// #endif
// #ifdef APP-NVUE
this.isEnd = false
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
this.next = 0
// #endif
}
}
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
'translateZ'
]
const animateTypes2 = ['opacity', 'backgroundColor']
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
MPAnimation.prototype[type] = function(...args) {
// #ifndef APP-NVUE
this.animation[type](...args)
// #endif
// #ifdef APP-NVUE
this._nvuePushAnimates(type, args)
// #endif
return this
}
})
export function createAnimation(option, _this) {
if(!_this) return
clearTimeout(_this.timer)
return new MPAnimation(option, _this)
}
{
"id": "uni-transition",
"displayName": "Transition 过渡动画",
"version": "1.0.2",
"version": "1.1.0",
"description": "元素的简单过渡动画",
"keywords": [
"动画",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册