diff --git a/README.md b/README.md index d476a836b6cf28b215e8966faedd2c90648b04b6..1e5ef5311dd6d640a36591327e4538c0f0a0f873 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,10 @@ uni-starter + uniCloud admin,提供了用户端和管理端的基础模板, ### 功能模块介绍 #### 1. 拦截器与路由守卫 -第三方路由拦截库,一般带有window对象等问题并不适合在uni-app中使用;另外传统路由拦截方式都是给原生方法做嵌套,首先这种写法并不优雅,另外不同项目的作者可能会不同的第三方路由库,这非常不利于生态的建设。你可能从插件市场拉下来一个项目有太多的学习成本,与你自有项目结合有大量差异需要去磨平。为此`uni-starter`基于`uni.addInterceptor`拦截器。 -拦截器顾名思义,是在框架方法执行的各个环节(包含:拦截前触发、成功回调拦截、失败回调拦截、完成回调拦截)插入逻辑,篡改参数或终止运行。 +第三方路由拦截库,一般带有window对象等问题,并不适合在uni-app中使用;另外传统路由拦截方式都是给原生方法做嵌套,首先这种写法并不优雅,也不支持ide的代码提示。 +另外不同项目的作者可能会不同的第三方路由库,这非常不利于生态的建设。你可能从插件市场拉下来一个项目有太多的学习成本,与你自有项目结合有大量差异需要去磨平。 +为此`uni-starter`基于`uni.addInterceptor`(拦截器)实现路由守卫。 +拦截器顾名思义,是在框架方法执行的各个环节(包含:拦截前触发、成功回调拦截、失败回调拦截、完成回调拦截)插入逻辑,篡改数据或终止运行。 ``` const {"router": {needLogin,login} } = uniStarterConfig //需要登录的页面 let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]; @@ -85,7 +87,6 @@ uni-starter + uniCloud admin,提供了用户端和管理端的基础模板, ``` #### 2.登录模块 -- uni-start集成的登录方式有:验证码登录(smsCode)、读取手机SIM卡一键登录(univerify)、账号密码登录(username)、微信登录(weixin)、苹果登录(apple) - 使用方式:在 `uni-starter.config.js`->`router`->`login`下完全列举你需要的登录方式。这里支持用[条件编译](https://uniapp.dcloud.io/platform?id=%e6%9d%a1%e4%bb%b6%e7%bc%96%e8%af%91)因此你可以配置在不同平台下拥有的登录方式。 - 优先级策略: 如果:配置内容为:["username","smsCode"],用户执行如下代码: @@ -94,10 +95,10 @@ uni-starter + uniCloud admin,提供了用户端和管理端的基础模板, url: "/pages/ucenter/login-page/index/index" }) ``` - 访问登录页面,但会被拦截器自动切换到“配置的第0项的登录方式对应的页面”,即账户登录方式页面,路径:`/pages/ucenter/login-page/pwd-login/pwd-login`。 - -- 生效策略:未列举到的或设备环境不支持的登录方式将被隐藏。 -- 配置: + 访问登录页面,会被拦截器自动切换到"配置的第0项(这里是`username`)的登录方式对应的页面”,即`账户登录`方式页面,路径:`/pages/ucenter/login-page/pwd-login/pwd-login`。 +- uni-start集成的登录方式有:验证码登录(smsCode)、读取手机SIM卡一键登录(univerify)、账号密码登录(username)、微信登录(weixin)、苹果登录(apple) +- 生效策略:登陆方式有如上5种,你希望有几种登陆方式就在配置中列举几种。有的登陆方式可能因为设备环境问题而不被支持;比如你正确地配置了微信登陆,但是用户的手机并没有安装微信,这样微信登陆功能就无法使用,并且如果出现这种情况你的app会被iOS的App Store拒绝上架。所以在这里,我们的生效策略在检测:你是否有列举到某个配置项为前提的情况下,增加了检测当前环境是否支持,如果不支持会自动隐藏。 +- 其他配置: + 服务端:uni-starter服务端使用[uni-config-center](https://ext.dcloud.net.cn/plugin?id=4425)统一管理这些配置,文件路径`/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json`详情下文[目录结构](#id=catalogue) 和[uni-id配置说明](https://uniapp.dcloud.io/uniCloud/uni-id?id=configjson%e7%9a%84%e8%af%b4%e6%98%8e) + 应用模块:`manifest.json` App模块配置 --> OAuth(登录鉴权)--> 勾选并配置你所需要的模块 - 短信登陆: @@ -186,7 +187,7 @@ uni-starter + uniCloud admin,提供了用户端和管理端的基础模板, 2. 配置后提交云端打包后生效。理论上绝大部分和`manifest.json`生效相关的配置均需要提交云打包后生效 #### 10.拦截器改造后的uniCloud -1. Debug,调试期间开启Debug。接口一旦file就会弹出真实错误信息。否则将弹出,系统错误请稍后再试! +1. Debug,调试期间开启Debug。接口一旦fail就会弹出真实错误信息。否则将弹出,系统错误请稍后再试! ``` if(Debug){ console.log(e); @@ -409,3 +410,4 @@ uni-starter ### 第三方插件(感谢插件作者,排名不分前后): 1. 图片裁剪 [limeClipper](https://ext.dcloud.net.cn/plugin?id=3594) @作者: 陌上华年 2. 二维码生成 [Sansnn-uQRCode](https://ext.dcloud.net.cn/plugin?id=1287) @作者: 3snn +3. clipboard.js [clipboard](https://clipboardjs.com/) \ No newline at end of file diff --git a/changelog.md b/changelog.md index 7543eac413ab2c2e78476a7fdc48f2629d3cb4a3..922e9aec112728133f7d81f162088718831b6871 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,7 @@ +## 1.0.19(2021-06-17) +1.新增获取邀请码接口getUserInviteCode 2.在邀请用户下载应用页面,自动设置被邀请用户的剪切板为邀请者的code(仅支持安卓端) 3.在注册或登陆并注册请求时自动添加剪切板中的请求参数 4.统一接口名称为驼峰法 +## 1.0.18(2021-06-15) +修复,APP端有安装微信客户端但未显示微信登陆快捷键的问题 ## 1.0.17(2021-06-09) 修复,非APP端deviceInfo为空引起的登陆失败问题 ## 1.0.16(2021-06-08) diff --git a/common/appInit.js b/common/appInit.js index 1439267b1869e28ba01d99c1c3b2e370a8cc1b12..fc99de6ebdd07c9fafdc6e991a471668ddf308b5 100644 --- a/common/appInit.js +++ b/common/appInit.js @@ -9,11 +9,15 @@ import interceptorChooseImage from '@/uni_modules/json-interceptor-chooseImage/j const db = uniCloud.database() export default function() { + // #ifndef H5 setTimeout(()=>{ + // #endif // uniStarterConfig挂载到getApp(). const app = getApp({allowDefault: true}) app.globalData.config = uniStarterConfig; + // #ifndef H5 },30) + // #endif // 初始化appVersion(仅app生效) initAppVersion(); @@ -108,6 +112,31 @@ export default function() { } console.log("重新登陆/注册,获取设备id",deviceInfo); option.data.deviceInfo = deviceInfo + + // #ifndef H5 + //注册可能不仅仅走register接口,还有登陆并注册的接口 + option.data.inviteCode = await new Promise((callBack)=>{ + uni.getClipboardData({ + success: function (res) { + if(res.data.slice(0,18) =='uniInvitationCode:'){ + let uniInvitationCode = res.data.slice(18,38) + console.log('当前用户是其他用户推荐下载的,推荐者的code是:'+uniInvitationCode); + // uni.showModal({ + // content: '当前用户是其他用户推荐下载的,推荐者的code是:'+uniInvitationCode, + // showCancel: false + // }); + callBack(uniInvitationCode) + //当前用户是其他用户推荐下载的。这里登记他的推荐者id 为当前用户的myInviteCode。判断如果是注册 + }else{ + callBack(false) + } + }, + fail() { + callBack(false) + } + }); + }) + // #endif } // #endif console.log(JSON.stringify(option)); @@ -174,10 +203,14 @@ export default function() { console.log(e.result.code); switch (e.result.code){ case 403: - uni.showModal({ - content: '未登陆,跳登陆', - showCancel: false - }); + uni.navigateTo({ + url: "/pages/ucenter/login-page/index/index" + }) + break; + case 30203: + uni.navigateTo({ + url: "/pages/ucenter/login-page/index/index" + }) break; case 50101: uni.showToast({ @@ -234,6 +267,13 @@ export default function() { }, fail(err) { // 失败回调拦截 console.log(err); + if(Debug){ + console.log(err); + uni.showModal({ + content: JSON.stringify(err), + showCancel: false + }); + } }, }) }) diff --git a/components/uni-id-show/uni-id-show.vue b/components/uni-id-show/uni-id-show.vue deleted file mode 100644 index 79cdfbbdafc83d67e0c0539f2ecf3dcde6cb1e5d..0000000000000000000000000000000000000000 --- a/components/uni-id-show/uni-id-show.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - \ No newline at end of file diff --git a/components/uni-quick-login/uni-quick-login.vue b/components/uni-quick-login/uni-quick-login.vue index f1e4a36143557d99982b9c066487c5b330bdfc56..c1ed8f812b2ae18ac82997ed530e665f50ff0786 100644 --- a/components/uni-quick-login/uni-quick-login.vue +++ b/components/uni-quick-login/uni-quick-login.vue @@ -121,11 +121,11 @@ }) => { if (this.config[id].isChecked && this.loginConfig.includes(id)) { if (id == 'weixin') { - if (~plus.runtime.isApplicationExist({ + if (!plus.runtime.isApplicationExist({ pname: 'com.tencent.mm', action: 'weixin://' })) { - // console.log("微信应用未安装"); + console.log("微信应用未安装"); return } } @@ -297,12 +297,12 @@ console.log({ params, type - }); + }); + let action = 'loginBy'+ type.trim().toLowerCase().replace(type[0], type[0].toUpperCase()) uniCloud.callFunction({ name: 'uni-id-cf', data: { - action: 'login_by_' + type, - params + action,params }, success: ({ result @@ -321,7 +321,7 @@ complete: () => { uni.hideLoading() } - }) + }) }, async getUserInfo(e) { return new Promise((resolve, reject) => { diff --git a/manifest.json b/manifest.json index 762f6f9cb354cb5defafff27c60eb4822423b9fe..ece50634acfacad2bf83cf4190c7114b07bda0db 100644 --- a/manifest.json +++ b/manifest.json @@ -32,8 +32,6 @@ }, "Share": { }, - "Push": { - }, "OAuth": { }, "FaceID": { @@ -70,8 +68,6 @@ }, "sdkConfigs": { "oauth": { - "univerify": { - }, "apple": { }, "weixin": { diff --git a/package.json b/package.json index e45031c3850ff1d1e231a3f4a937c318778b231a..a2078b1b207a2b7b5d4d53fa8e6eda683e1a4061 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "id": "uni-starter", "displayName": "uni-starter", - "version": "1.0.17", - "description": "云端一体应用快速开发模版", + "version": "1.0.19", + "description": "云端一体应用快速开发基本项目模版", "keywords": [ "uni-starter", "login", @@ -12,7 +12,7 @@ ], "repository": "https://codechina.csdn.net/dcloud/uni-starter.git", "engines": { - "HBuilderX": "^3.1.17" + "HBuilderX": "^3.1.18" }, "dcloudext": { "category": [ @@ -77,4 +77,4 @@ } } } -} \ No newline at end of file +} diff --git a/pages.json b/pages.json index 109004046c2c2441fd8a0561c361d60ca207fe54..6a2fdc8a405f343956068d0ee1d2ccbc542e6822 100644 --- a/pages.json +++ b/pages.json @@ -1,9 +1,8 @@ { - "pages": [ - { + "pages": [{ "path": "pages/list/list", "style": { - "navigationStyle":"custom", + "navigationStyle": "custom", "enablePullDownRefresh": true } }, @@ -70,7 +69,8 @@ "style": { "navigationBarTitleText": "关于" // #ifdef APP-PLUS - ,"app-plus": { + , + "app-plus": { "titleNView": { "buttons": [{ "type": "share" @@ -136,7 +136,7 @@ "navigationBarTitleText": "" } - },{ + }, { "path": "pages/common/webview/webview", "style": { "navigationBarTitleText": "", @@ -156,6 +156,13 @@ "navigationBarTitleText": "阅读记录", "enablePullDownRefresh": true } + }, { + "path": "pages/ucenter/invite/invite", + "style": { + "navigationStyle":"custom", + "enablePullDownRefresh": false + } + } ], "globalStyle": { @@ -169,9 +176,9 @@ "list": [{ "path": "pages/list/list" }, - { - "path": "pages/ucenter/login-page/index/index" - },{ + { + "path": "pages/ucenter/login-page/index/index" + }, { "path": "pages/ucenter/userinfo/userinfo" }, { @@ -202,4 +209,4 @@ "text": "我的" }] } -} +} diff --git a/pages/list/list.nvue b/pages/list/list.nvue index 06a2c8a032051ba1405854a5fa9cf91bd020856d..c1eff8254dbc88966836791dffac995195cbebaa 100644 --- a/pages/list/list.nvue +++ b/pages/list/list.nvue @@ -3,7 +3,7 @@ - + + \ No newline at end of file diff --git a/pages/ucenter/invite/invite.vue b/pages/ucenter/invite/invite.vue new file mode 100644 index 0000000000000000000000000000000000000000..cf8f2bda0c94e40066e6946a7596f6436fabb9e3 --- /dev/null +++ b/pages/ucenter/invite/invite.vue @@ -0,0 +1,95 @@ + + + diff --git a/pages/ucenter/login-page/phone-code/phone-code.vue b/pages/ucenter/login-page/phone-code/phone-code.vue index bfd3d7675a027dc3ad1be467433527833ca8be4f..70a8dbb96bf70877febcff3a274a8454c4730ec9 100644 --- a/pages/ucenter/login-page/phone-code/phone-code.vue +++ b/pages/ucenter/login-page/phone-code/phone-code.vue @@ -42,17 +42,6 @@ }, methods: { submit(){ //完成并提交 - // this.-request('uni-id-cf/loginBySms', - // { - // "mobile":this.phone, - // "code":this.code - // }, - // e=>{ - // console.log(e); - // this.loginSuccess(e) - // }, - // {showLoading:true}) - uniCloud.callFunction({ name:'uni-id-cf', data:{ diff --git a/pages/ucenter/login-page/pwd-login/pwd-login.vue b/pages/ucenter/login-page/pwd-login/pwd-login.vue index 886935fed541f2fc9eb80a5a9eb9e1ba5f3aa0c9..a6a7c1ea45af35c441e1159f6f58729965f1908b 100644 --- a/pages/ucenter/login-page/pwd-login/pwd-login.vue +++ b/pages/ucenter/login-page/pwd-login/pwd-login.vue @@ -95,44 +95,8 @@ } } }) - - // this.-request('uni-id-cf/login', { - // "username": this.username, - // "password": this.password, - // "captcha":this.captcha - // }, result => { - // console.log(result); - // if (result.code === 0) { - // this.loginSuccess(result) - // } else { - // if (result.needCaptcha) { - // uni.showToast({ - // title: result.msg, - // icon: 'none' - // }); - // this.createCaptcha() - // }else{ - // uni.showModal({ - // title: '错误', - // content: result.msg, - // showCancel: false, - // confirmText: '知道了' - // }); - // } - // } - // }) }, createCaptcha(){ - // this.-request( - // 'uni-id-cf/createCaptcha', { - // scene: "login" - // }, - // result => { - // if (result.code === 0) { - // this.captchaBase64 = result.captchaBase64 - // } - // }) - uniCloud.callFunction({ name:'uni-id-cf', data:{ diff --git a/pages/ucenter/login-page/pwd-retrieve/pwd-retrieve.vue b/pages/ucenter/login-page/pwd-retrieve/pwd-retrieve.vue index 752f0dfb4fc1ee23030847df53e3f3e36ce06876..f4d169807213f6f1389cc18d97a5477619498459 100644 --- a/pages/ucenter/login-page/pwd-retrieve/pwd-retrieve.vue +++ b/pages/ucenter/login-page/pwd-retrieve/pwd-retrieve.vue @@ -137,20 +137,6 @@ submit() { this.$refs.form.submit() .then(res => { - // this.-request('uni-id-cf/resetPwdBySmsCode', { - // "mobile": this.formData.phone, - // "code": this.formData.code, - // "password": this.formData.pwd - // }, result => { - // console.log(result); - // uni.showToast({ - // title: result.msg, - // icon: 'none' - // }); - // if (result.code === 0) { - // uni.navigateBack() - // } - // }) uniCloud.callFunction({ name:'uni-id-cf', data:{ diff --git a/pages/ucenter/login-page/register/register.vue b/pages/ucenter/login-page/register/register.vue index 90c93eeff0d556ebbcda99fccfada8f6b3e57fb4..1f8f4a013efa96c06d87215fb8359bb6c301ecf5 100644 --- a/pages/ucenter/login-page/register/register.vue +++ b/pages/ucenter/login-page/register/register.vue @@ -63,12 +63,6 @@ import mixin from '../common/login-page.mixin.js'; }) }, submitForm(params) { - // this.-request('uni-id-cf/register',params,result=>{ - // console.log(result); - // if(result.code === 0){ - // this.loginSuccess(result) - // } - // }) uniCloud.callFunction({ name:'uni-id-cf', data:{ diff --git a/pages/ucenter/ucenter.vue b/pages/ucenter/ucenter.vue index 61124142fb51e920fae92d09aea13ae62caa5d45..020a5278739407228b7232287c83d2e888877542 100644 --- a/pages/ucenter/ucenter.vue +++ b/pages/ucenter/ucenter.vue @@ -14,11 +14,8 @@ + :clickable="true" :to="item.to" @click="ucenterListClick(item)" :show-extra-icon="true" + :extraIcon="{type:item.icon,color:'#999'}"> {{item.rightText}} @@ -35,6 +32,7 @@ } from 'vuex'; import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update'; import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version'; + import uniShare from 'uni_modules/uni-share/js_sdk/uni-share.js'; const db = uniCloud.database(); const dbCollectionName = 'uni-id-scores'; @@ -65,34 +63,41 @@ { "title": '去评分', "event": 'gotoMarket', - "icon":"hand-thumbsup" + "icon": "hand-thumbsup" }, //#endif { "title": '阅读过的文章', "to": '/pages/ucenter/read-news-log/read-news-log', - "icon":"flag" + "icon": "flag" }, { "title": '我的积分', "to": '', "event": 'getScore', - "icon":"paperplane" - } + "icon": "paperplane" + } + // #ifndef H5 + ,{ + "title": '分销推荐', + "event": 'share', + "icon": "redo" + } + // #endif ], [{ "title": '问题与反馈', "to": '/uni_modules/uni-feedback/pages/uni-feedback/uni-feedback', - "icon":"help" + "icon": "help" }, { "title": '设置', "to": '/pages/ucenter/settings/settings', - "icon":"gear" + "icon": "gear" }], [{ "title": '关于', "to": '/pages/ucenter/about/about', - "icon":"info" + "icon": "info" }] ] } @@ -103,7 +108,7 @@ title: '检查更新', rightText: this.appVersion.version + '-' + this.appVersion.versionCode, event: 'checkVersion', - icon:'loop', + icon: 'loop', showBadge: this.appVersion.hasNew }) //#endif @@ -206,6 +211,79 @@ }).finally(() => { uni.hideLoading() }) + }, + async share() { + let {result} = await uniCloud.callFunction({ + name: 'uni-id-cf', + data: { + action: 'getUserInviteCode' + } + }) + console.log(result); + let myInviteCode = result.myInviteCode || result.userInfo.my_invite_code + console.log(myInviteCode); + let { + appName, + logo, + company, + slogan + } = this.appConfig.about + // #ifdef APP-PLUS + uniShare({ + content: { //公共的分享类型(type)、链接(herf)、标题(title)、summary(描述)、imageUrl(缩略图) + type: 0, + href: this.appConfig.h5.url + + `/#/pages/ucenter/invite/invite?code=${myInviteCode}`, + title: appName, + summary: slogan, + imageUrl: logo + '?x-oss-process=image/resize,m_fill,h_100,w_100' //压缩图片解决,在ios端分享图过大导致的图片失效问题 + }, + menus: [{ + "img": "/static/app-plus/sharemenu/wechatfriend.png", + "text": "微信好友", + "share": { + "provider": "weixin", + "scene": "WXSceneSession" + } + }, + { + "img": "/static/app-plus/sharemenu/wechatmoments.png", + "text": "微信朋友圈", + "share": { + "provider": "weixin", + "scene": "WXSenceTimeline" + } + }, + { + "img": "/static/app-plus/sharemenu/weibo.png", + "text": "微博", + "share": { + "provider": "sinaweibo" + } + }, + { + "img": "/static/app-plus/sharemenu/qq.png", + "text": "QQ", + "share": { + "provider": "qq" + } + }, + { + "img": "/static/app-plus/sharemenu/copyurl.png", + "text": "复制", + "share": "copyurl" + }, + { + "img": "/static/app-plus/sharemenu/more.png", + "text": "更多", + "share": "shareSystem" + } + ], + cancelText: "取消分享", + }, e => { //callback + console.log(e); + }) + // #endif } } } @@ -285,17 +363,17 @@ /*修改边线粗细示例*/ /* #ifndef APP-NVUE */ - .center-list /deep/ .uni-list--border:after{ + .center-list /deep/ .uni-list--border:after { -webkit-transform: scaleY(0.2); - transform: scaleY(0.2); + transform: scaleY(0.2); margin-left: 80rpx; - } - - .center-list /deep/ .uni-list--border-top, - .center-list /deep/ .uni-list--border-bottom{ - display: none; - } - + } + + .center-list /deep/ .uni-list--border-top, + .center-list /deep/ .uni-list--border-bottom { + display: none; + } + /* #endif */ .item-footer { flex-direction: row; @@ -319,4 +397,4 @@ /* #endif */ background-color: #DD524D; } - + diff --git a/pages/ucenter/userinfo/bind-mobile/bind-mobile.vue b/pages/ucenter/userinfo/bind-mobile/bind-mobile.vue index 5283ccf6bb96e1230112ade9bbe9d303835c9b56..16dd92fcb6aab9d9728d43e52555eef61614d422 100644 --- a/pages/ucenter/userinfo/bind-mobile/bind-mobile.vue +++ b/pages/ucenter/userinfo/bind-mobile/bind-mobile.vue @@ -48,20 +48,6 @@ */ submit() { console.log(this.formData); - // this.-request('uni-id-cf/bind_mobile_by_sms', { - // "mobile": this.formData.phone, - // "code": this.formData.code - // }, result=> { - // console.log(result); - // this.setUserInfo({"mobile":result.mobile}) - // uni.showToast({ - // title: result.msg, - // icon: 'none' - // }); - // if (result.code === 0) { - // uni.navigateBack() - // } - // }) uniCloud.callFunction({ name:'uni-id-cf', data:{ diff --git a/pages/ucenter/userinfo/userinfo.vue b/pages/ucenter/userinfo/userinfo.vue index 5645b3a745baf1bc04551fa8b31cb1ce45c67832..66ceb301fd579526ab563b670ef3f1d80a079747 100644 --- a/pages/ucenter/userinfo/userinfo.vue +++ b/pages/ucenter/userinfo/userinfo.vue @@ -70,25 +70,6 @@ "univerifyStyle": this.univerifyStyle, success: async e => { console.log(e.authResult); - // this.-request('uni-id-cf/bind_mobile_by_univerify', - // e.authResult, - // 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() - // } - // }); - // } - // } - // ) uniCloud.callFunction({ name:'uni-id-cf', data:{ @@ -114,7 +95,7 @@ }, fail: (err) => { console.log(err); - if(err.code=='30002'){ + if(err.code=='30002'||err.code=='30001'){ this.bindMobileBySmsCode() } } diff --git a/static/h5/download-app/adriod.png b/static/h5/download-app/adriod.png new file mode 100755 index 0000000000000000000000000000000000000000..cc0981584587371ae4471c51ecf7d4bfc307978f Binary files /dev/null and b/static/h5/download-app/adriod.png differ diff --git a/static/h5/download-app/apple.png b/static/h5/download-app/apple.png new file mode 100755 index 0000000000000000000000000000000000000000..9f3d7593a18eb804b7052e53a48e231dd602c2f7 Binary files /dev/null and b/static/h5/download-app/apple.png differ diff --git a/static/h5/download-app/back.png b/static/h5/download-app/back.png new file mode 100755 index 0000000000000000000000000000000000000000..fb3faec87f62c00f653723105b6ff5ee3e97551a Binary files /dev/null and b/static/h5/download-app/back.png differ diff --git a/static/h5/download-app/openImg.png b/static/h5/download-app/openImg.png new file mode 100755 index 0000000000000000000000000000000000000000..6de7ef2e3564078cd78f111888a9f0c25d65b2a5 Binary files /dev/null and b/static/h5/download-app/openImg.png differ diff --git a/uni-starter.config.js b/uni-starter.config.js index 2832b013dea5553a5e0dec99803d6525c2fc4c33..bec8335d3cdef32c0de2c139d4957b39926bc008 100644 --- a/uni-starter.config.js +++ b/uni-starter.config.js @@ -42,7 +42,7 @@ module.exports = { //公司名称 "company": "数字天堂(北京)网络技术有限公司", //口号 - "slogan": "为开发而生", + "slogan": "云端一体应用快速开发模版", //政策协议 "agreements": [{ "title": "用户服务协议", //协议名称 diff --git a/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js b/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js index 217cadf1e8fc0601aa7f868984b8fdb855eaeb4d..45af2a6edb499707a4e9035a44136ce832740d23 100644 --- a/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js +++ b/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js @@ -7,37 +7,45 @@ const uniIdConfig = createConfig({ })._config const db = uniCloud.database() const dbCmd = db.command -exports.main = async (event, context) => { +exports.main = async (event, context) => { //UNI_WYQ:这里的uniID换成新的,保证多人访问不会冲突 - uniID = uniID.createInstance({context}) - console.log('event : ' + JSON.stringify(event)) - /* - 1.event为客户端 uniCloud.callFunction填写的data的值,这里介绍一下其中的属性 - action:表示要执行的任务名称、比如:登陆login、退出登陆 logout等 - params:业务数据内容 - uniIdToken:系统自动传递的token,数据来源客户端的 uni.getStorageSync('uni_id_token') - */ - const {action,uniIdToken} = event; - const deviceInfo = event.deviceInfo || {}; - let params = event.params || {}; - /* - 2.在某些操作之前我们要对用户对身份进行校验(也就是要检查用户的token)再将得到的uid写入params.uid - 校验用到的方法是uniID.checkToken 详情:https://uniapp.dcloud.io/uniCloud/uni-id?id=checktoken - - 讨论,我们假设一个这样的场景,代码如下。 - 如: - uniCloud.callFunction({ - name:"xxx", - data:{ - "params":{ - uid:"通过某种方式获取来的别人的uid" - } - } - }) - 用户就这样轻易地伪造了他人的uid传递给服务端,有一句话叫:前端从来的数据是不可信任的 - 所以这里我们需要将uniID.checkToken返回的uid写入到params.uid - */ - let noCheckAction = ['register','checkToken','login','logout','sendSmsCode','createCaptcha','verifyCaptcha','refreshCaptcha','inviteLogin','login_by_weixin','login_by_univerify','login_by_apple','loginBySms','resetPwdBySmsCode'] + uniID = uniID.createInstance({ + context + }) + console.log('event : ' + JSON.stringify(event)) + /* + 1.event为客户端 uniCloud.callFunction填写的data的值,这里介绍一下其中的属性 + action:表示要执行的任务名称、比如:登陆login、退出登陆 logout等 + params:业务数据内容 + uniIdToken:系统自动传递的token,数据来源客户端的 uni.getStorageSync('uni_id_token') + */ + const { + action, + uniIdToken + } = event; + const deviceInfo = event.deviceInfo || {}; + let params = event.params || {}; + /* + 2.在某些操作之前我们要对用户对身份进行校验(也就是要检查用户的token)再将得到的uid写入params.uid + 校验用到的方法是uniID.checkToken 详情:https://uniapp.dcloud.io/uniCloud/uni-id?id=checktoken + + 讨论,我们假设一个这样的场景,代码如下。 + 如: + uniCloud.callFunction({ + name:"xxx", + data:{ + "params":{ + uid:"通过某种方式获取来的别人的uid" + } + } + }) + 用户就这样轻易地伪造了他人的uid传递给服务端,有一句话叫:前端从来的数据是不可信任的 + 所以这里我们需要将uniID.checkToken返回的uid写入到params.uid + */ + let noCheckAction = ['register', 'checkToken', 'login', 'logout', 'sendSmsCode', 'createCaptcha', + 'verifyCaptcha', 'refreshCaptcha', 'inviteLogin', 'loginByWeixin', 'loginByUniverify', + 'loginByApple', 'loginBySms', 'resetPwdBySmsCode', 'registerAdmin' + ] if (!noCheckAction.includes(action)) { if (!uniIdToken) { return { @@ -52,14 +60,23 @@ exports.main = async (event, context) => { params.uid = payload.uid } + //禁止前台用户传递角色 + if (action.slice(0,7) == "loginBy") { + if (params.role) { + return { + code: 403, + msg: '禁止前台用户传递角色' + } + } + } //3.注册成功后创建新用户的积分表方法 - async function registerSuccess(uid) { - //添加当前用户设备信息 - await db.collection('uni-id-device').add({ - ...deviceInfo, - user_id:uid - }) + async function registerSuccess(uid) { + //添加当前用户设备信息 + await db.collection('uni-id-device').add({ + ...deviceInfo, + user_id: uid + }) await db.collection('uni-id-scores').add({ user_id: uid, score: 1, @@ -67,16 +84,16 @@ exports.main = async (event, context) => { balance: 1, comment: "", create_date: Date.now() - }) + }) } //4.记录成功登录的日志方法 - const loginLog = async (res = {}, type = 'login') => { + const loginLog = async (res = {}) => { const now = Date.now() const uniIdLogCollection = db.collection('uni-id-log') let logData = { deviceId: params.deviceId || context.DEVICEID, ip: params.ip || context.CLIENTIP, - type, + type: res.type, ua: context.CLIENTUA, create_date: now }; @@ -88,19 +105,21 @@ exports.main = async (event, context) => { } : { state: 0 }) - if (res.type == 'register') { + if (res.type == 'register') { await registerSuccess(res.uid) - }else{ - if(Object.keys(deviceInfo).length){ - //更新当前用户设备信息 - await db.collection('uni-id-device').where({user_id:res.uid}).update(deviceInfo) - } + } else { + if (Object.keys(deviceInfo).length) { + //更新当前用户设备信息 + await db.collection('uni-id-device').where({ + user_id: res.uid + }).update(deviceInfo) + } } return await uniIdLogCollection.add(logData) } - let res = {} - switch (action) { //根据action的值执行对应的操作 + let res = {} + switch (action) { //根据action的值执行对应的操作 case 'bind_mobile_by_univerify': let { appid, apiKey, apiSecret @@ -122,22 +141,20 @@ exports.main = async (event, context) => { } break; case 'bind_mobile_by_sms': - console.log({ - uid: params.uid, - mobile: params.mobile, - code: params.code - }); + // console.log({ + // uid: params.uid, + // mobile: params.mobile, + // code: params.code + // }); res = await uniID.bindMobile({ uid: params.uid, mobile: params.mobile, code: params.code }) - console.log(res); + // console.log(res); break; - case 'register': - var { - username, password, nickname - } = params + case 'register': + var {username, password, nickname,inviteCode} = params if (/^1\d{10}$/.test(username)) { return { code: 401, @@ -150,34 +167,30 @@ exports.main = async (event, context) => { msg: '用户名不能是邮箱' } } - res = await uniID.register({ - username, - password, - nickname - }); + res = await uniID.register({username, password, nickname,inviteCode}); if (res.code === 0) { await registerSuccess(res.uid) } break; - case 'login': - //防止黑客恶意破解登录,连续登录失败一定次数后,需要用户提供验证码 - const getNeedCaptcha = async () => { - //当用户最近“2小时内(recordDate)”登录失败达到2次(recordSize)时。要求用户提交验证码 - const now = Date.now(), - recordDate = 120 * 60 * 1000, - recordSize = 2; - const uniIdLogCollection = db.collection('uni-id-log') - let recentRecord = await uniIdLogCollection.where({ - deviceId: params.deviceId || context.DEVICEID, - create_date: dbCmd.gt(now - recordDate), - type: 'login' - }) - .orderBy('create_date', 'desc') - .limit(recordSize) - .get(); - return recentRecord.data.filter(item => item.state === 0).length === recordSize; - } - + case 'login': + //防止黑客恶意破解登录,连续登录失败一定次数后,需要用户提供验证码 + const getNeedCaptcha = async () => { + //当用户最近“2小时内(recordDate)”登录失败达到2次(recordSize)时。要求用户提交验证码 + const now = Date.now(), + recordDate = 120 * 60 * 1000, + recordSize = 2; + const uniIdLogCollection = db.collection('uni-id-log') + let recentRecord = await uniIdLogCollection.where({ + deviceId: params.deviceId || context.DEVICEID, + create_date: dbCmd.gt(now - recordDate), + type: 'login' + }) + .orderBy('create_date', 'desc') + .limit(recordSize) + .get(); + return recentRecord.data.filter(item => item.state === 0).length === recordSize; + } + let passed = false; let needCaptcha = await getNeedCaptcha(); console.log('needCaptcha', needCaptcha); @@ -193,17 +206,22 @@ exports.main = async (event, context) => { res = await uniID.login({ ...params, queryField: ['username', 'email', 'mobile'] - }); - if(res.code === 0){ - await loginLog(res); + }); + if (res.code === 0) { + await loginLog(res); } needCaptcha = await getNeedCaptcha(); } res.needCaptcha = needCaptcha; break; - case 'login_by_weixin': - res = await uniID.loginByWeixin({...params}); + case 'loginByWeixin': + var { + username, password, nickname + } = params + res = await uniID.loginByWeixin({ + ...params + }); await uniID.updateUser({ uid: res.uid, username: "微信用户" @@ -211,11 +229,11 @@ exports.main = async (event, context) => { res.userInfo.username = "微信用户" await loginLog(res) break; - case 'login_by_univerify': + case 'loginByUniverify': res = await uniID.loginByUniverify(params) await loginLog(res) break; - case 'login_by_apple': + case 'loginByApple': res = await uniID.loginByApple(params) await loginLog(res) break; @@ -258,7 +276,6 @@ exports.main = async (event, context) => { type: params.type, templateId }) - await loginLog(res) break; case 'loginBySms': if (!params.code) { @@ -302,7 +319,7 @@ exports.main = async (event, context) => { } } let loginBySmsRes = await uniID.loginBySms(params) - console.log(loginBySmsRes); + // console.log(loginBySmsRes); if (loginBySmsRes.code === 0) { res = await uniID.resetPwd({ password: params.password, @@ -337,6 +354,19 @@ exports.main = async (event, context) => { case 'refreshCaptcha': res = await uniCaptcha.refresh(params) break; + case 'getUserInviteCode': + res = await uniID.getUserInfo({ + uid: params.uid, + field: ['my_invite_code'] + }) + if (!res.userInfo.my_invite_code) { + res = await uniID.setUserInviteCode({ + uid: params.uid + }) + } + break; + + // ----------- admin api ----------- case 'registerAdmin': var { username, password @@ -352,12 +382,39 @@ exports.main = async (event, context) => { message: '超级管理员已存在,请登录...' } } - return this.ctx.uniID.register({ + return uniID.register({ username, password, role: ["admin"] }) break; + case 'registerUser': + const { + userInfo + } = await uniID.getUserInfo({ + uid: params.uid, + }) + if (userInfo.role.indexOf('admin') === -1 && params.role.indexOf('admin') > -1) { + res = { + code: 403, + message: '非法访问, 无权限注册超级管理员', + } + } else { + res = await uniID.register({ + ...params + }) + if (res.code === 0) { + delete res.token + delete res.tokenExpired + } + } + break; + case 'getCurrentUserInfo': + res = uniID.getUserInfo({ + uid: params.uid, + ...params + }) + break; default: res = { code: 403, diff --git a/uniCloud-aliyun/cloudfunctions/uni-id-cf/uni-id-cf.param.json b/uniCloud-aliyun/cloudfunctions/uni-id-cf/uni-id-cf.param.json index 69667c33f3b64037e0cbc0be1d7fd2fd3ce18c1f..e56192fea0b8602cc578e85534e45aa66cf6d181 100644 --- a/uniCloud-aliyun/cloudfunctions/uni-id-cf/uni-id-cf.param.json +++ b/uniCloud-aliyun/cloudfunctions/uni-id-cf/uni-id-cf.param.json @@ -1,8 +1,10 @@ // 本文件中的json内容将在云函数【运行】时作为参数传给云函数。 // 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam { - "action": "login_by_weixin", + "action": "getUserInviteCode", "params": { "code": "093tK5Ga1X1D6B0MSAHa13uRH04tK5Gs" - } + }, + "uniInvitationCode":"CY2A8B", + "uniIdToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiI2MGMwMzMwOTI0OTU3OTAwMDFiMDAwZGIiLCJyb2xlIjpbXSwicGVybWlzc2lvbiI6W10sImNsaWVudElkIjoiMTk1Zjc3YzE4MGMyM2UzZjVhOGE4ZjM4ZTQyOTAxODYiLCJpYXQiOjE2MjMyMjgxMTYsImV4cCI6MTYyMzIzNTMxNn0.vtNSqdhCaI6fdvk5aHo5Dmdsb5MkBS8omk0b0YzAgIs" } diff --git a/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json index 9655ed1230029ecaaf31711bf94c47446e496cf1..6b0d083db7fc19f2a23bfbab377ab1f984d35eff 100644 --- a/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json +++ b/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json @@ -4,7 +4,7 @@ "tokenExpiresIn": 7200, "tokenExpiresThreshold": 600, "passwordErrorLimit": 6, - "bindTokenToDevice": true, + "bindTokenToDevice": false, "passwordErrorRetryTime": 3600, "autoSetInviteCode": false, "forceInviteCode": false, diff --git a/uni_modules_tools/copy/manifest.json b/uni_modules_tools/copy/manifest.json index 52544ce081add7b455b14527551ebeaeb29bcec7..86c154c394e70febc29705f8c0a4c7aff629daa3 100644 --- a/uni_modules_tools/copy/manifest.json +++ b/uni_modules_tools/copy/manifest.json @@ -30,7 +30,6 @@ "modules" : { "Fingerprint" : {}, "Share" : {}, - "Push" : {}, "OAuth" : {}, "FaceID" : {} }, @@ -60,7 +59,6 @@ "ios" : {}, "sdkConfigs" : { "oauth" : { - "univerify" : {}, "apple" : {}, "weixin" : { "appid" : "wxffdd8fa6ec4ef2a0", diff --git a/uni_modules_tools/copy/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json b/uni_modules_tools/copy/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json index 02ce9bbf5736bc5d4f76b9cc71d64416435daf1f..25f8fe6b69214a7bf713f0ac8f6d68c2450f372c 100644 --- a/uni_modules_tools/copy/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json +++ b/uni_modules_tools/copy/uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json @@ -4,7 +4,7 @@ "tokenExpiresIn": 7200, "tokenExpiresThreshold": 600, "passwordErrorLimit": 6, - "bindTokenToDevice": true, + "bindTokenToDevice": false, "passwordErrorRetryTime": 3600, "autoSetInviteCode": false, "forceInviteCode": false,