diff --git a/README.md b/README.md index 536d6062ac476f35aa47bb2f850c9346895bd755..d62c8ffeefab515e11ed780dbaf4f8c60a91369e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -### 介绍 +### 介绍 `uni-starter`,是一个云端一体的、集成了商用项目开发常见功能的项目模板。 如果说uniCloud admin是管理端项目的基础模板,那么uni-starter则是用户端、尤其是移动端的基础模板。 在这个模板基础之上快速填充自己的业务,即可很快完成一个应用。 diff --git a/changelog.md b/changelog.md index d49fd6ea44b89c5137ac8ee2d4ccc3f025f573b2..6da33be6066ce57a23f97bea23bfbb3a07653fdb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,7 @@ +## 1.0.5(2021-05-20) +改用uni_modules方式处理图片选择api时无权限,引导用户快捷打开系统设置 ## 1.0.4(2021-05-19) -12 +为方便部署,添加空的manifest.json uni-config-center下的uni-id配置 ## 1.0.3(2021-05-18) 重大调整,原云函数名称:user-center改名叫uni-id-cf 修复,绑定手机号码场景。因手机未插SIM导致的一键登录失败后未直接跳到获取短信验证码方式绑定 diff --git a/common/appInit.js b/common/appInit.js index 8dc20e2a6b2b5b774b3054149889a7ccf1db6a5e..2e746ef1ae766c881b0df6e19b087671a544d236 100644 --- a/common/appInit.js +++ b/common/appInit.js @@ -3,6 +3,7 @@ import uniStarterConfig from '@/uni-starter.config.js'; // #ifdef APP-PLUS 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 interceptorChooseImage from '@/uni_modules/json-interceptor-chooseImage/js_sdk/main.js'; // #endif export default function() { @@ -14,9 +15,13 @@ export default function() { // 初始化appVersion(仅app生效) initAppVersion(); - /* - 这里应用了[拦截器](https://uniapp.dcloud.io/api/interceptor?id=addinterceptor)实现了,路由拦截。当应用无访问摄像头/相册权限,引导跳到设置界面 - */ + + // #ifdef APP-PLUS + // 实现,路由拦截。当应用无访问摄像头/相册权限,引导跳到设置界面 + interceptorChooseImage() + // #endif + + //自定义路由拦截 const {"router": {needLogin,login} } = uniStarterConfig //需要登录的页面 let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]; @@ -54,39 +59,6 @@ export default function() { }, }) }) - - //当应用无访问摄像头/相册权限,引导跳到设置界面 - uni.addInterceptor('chooseImage', { - fail(e) { // 失败回调拦截 - console.log(e); - if(uni.getSystemInfoSync().platform == "android" && e.errMsg == 'chooseImage:fail No Permission'){ - if(e.code === 11){ - uni.showModal({ - title:"无法访问摄像头", - content: "当前无摄像头访问权限,建议前往设置", - confirmText: "前往设置", - success(e) { - if (e.confirm) { - openAppPermissionSetting() - } - } - }); - }else{ - uni.showModal({ - title:"无法访问相册", - content: "当前无系统相册访问权限,建议前往设置", - confirmText: "前往设置", - success(e) { - if (e.confirm) { - openAppPermissionSetting() - } - } - }); - } - } - } - }) - // #ifdef APP-PLUS // 监听并提示设备网络状态变化 uni.onNetworkStatusChange(res=> { @@ -139,30 +111,4 @@ function initAppVersion() { // 检查更新 checkUpdate(); // #endif -} - -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); - } } \ No newline at end of file diff --git a/manifest.json b/manifest.json index 277967fdebcbbdc81ffde861dbf2727fafc8e7b9..35e724883f8bea739416cbc441dee5399156bc93 100644 --- a/manifest.json +++ b/manifest.json @@ -1 +1,100 @@ -{"name":"uni-starter","appid":"","description":"集成了商用项目开发常见功能的项目模板","versionName":"1.0.0","versionCode":"100","transformPx":false,"app-plus":{"privacy":{"prompt":"template","template":{"title":"服务协议和隐私政策","message":"  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。
  你可阅读《服务协议》《隐私政策》了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。","buttonAccept":"同意","buttonRefuse":"暂不同意"}},"compatible":{"ignoreVersion":true},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"splashscreen":{"alwaysShowBeforeRender":true,"waiting":true,"autoclose":true,"delay":0},"modules":{"Fingerprint":{},"Share":{},"Push":{},"OAuth":{}},"distribute":{"android":{"permissions":["","","","","","","","","","","","","","","","",""],"abiFilters":["armeabi-v7a","arm64-v8a","x86"]},"ios":{},"sdkConfigs":{"oauth":{"univerify":{},"apple":{}},"ad":{},"share":{},"geolocation":{},"push":{"unipush":{}},"payment":{}}},"nvueLaunchMode":""},"quickapp":{},"mp-weixin":{"appid":"","setting":{"urlCheck":false,"es6":false},"usingComponents":true,"betterScopedSlots":true},"mp-alipay":{"usingComponents":true},"mp-baidu":{"usingComponents":true},"mp-toutiao":{"usingComponents":true},"uniStatistics":{"enable":false},"h5":{"template":""}} \ No newline at end of file +{ + "name": "uni-starter", + "appid": "", + "description": "云端一体应用快速开发模版", + "versionName": "1.0.0", + "versionCode": "100", + "transformPx": false, + "app-plus": { + "privacy": { + "prompt": "template", + "template": { + "title": "服务协议和隐私政策", + "message": "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。
  你可阅读《服务协议》《隐私政策》了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", + "buttonAccept": "同意", + "buttonRefuse": "暂不同意" + } + }, + "compatible": { + "ignoreVersion": true + }, + "usingComponents": true, + "nvueStyleCompiler": "uni-app", + "compilerVersion": 3, + "splashscreen": { + "alwaysShowBeforeRender": true, + "waiting": true, + "autoclose": true, + "delay": 0 + }, + "modules": { + "Fingerprint": {}, + "Share": {}, + "Push": {}, + "OAuth": {} + }, + "distribute": { + "android": { + "permissions": ["", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + "abiFilters": ["armeabi-v7a", "arm64-v8a", "x86"] + }, + "ios": {}, + "sdkConfigs": { + "oauth": { + "univerify": {}, + "apple": {} + }, + "ad": {}, + "share": {}, + "geolocation": {}, + "push": { + "unipush": {} + }, + "payment": {} + } + }, + "nvueLaunchMode": "" + }, + "quickapp": {}, + "mp-weixin": { + "appid": "", + "setting": { + "urlCheck": false, + "es6": false + }, + "usingComponents": true, + "betterScopedSlots": true + }, + "mp-alipay": { + "usingComponents": true + }, + "mp-baidu": { + "usingComponents": true + }, + "mp-toutiao": { + "usingComponents": true + }, + "uniStatistics": { + "enable": false + }, + "h5": { + "template": "" + } +} diff --git a/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js b/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js index 9e959310acc5074b7ac97cef769bbebe9f5f540d..37c947f6640fbb8e531566f9e1a7d1e6735186bb 100644 --- a/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js +++ b/uniCloud-aliyun/cloudfunctions/uni-id-cf/index.js @@ -200,15 +200,12 @@ exports.main = async (event, context) => { res = await uniID.logout(event.uniIdToken) break; case 'sendSmsCode': - // 测试期间短信统一用 123456 正式项目删除即可 return uniID.setVerifyCode({ mobile: params.mobile, code:'123456', type: params.type }) - - // 简单限制一下客户端调用频率 const ipLimit = await db.collection('uni-verify').where({ ip: context.CLIENTIP, @@ -313,6 +310,21 @@ exports.main = async (event, context) => { break; case 'refreshCaptcha': res = await uniCaptcha.refresh(params) + break; + case 'registerAdmin': + let {username,password} = params + let {total} = await db.collection('uni-id-users').where({role: 'admin'}).count() + if (total) { + return { + code: 10001, + message: '超级管理员已存在,请登录...' + } + } + return this.ctx.uniID.register({ + username, + password, + role: ["admin"] + }) break; default: res = { @@ -321,7 +333,6 @@ exports.main = async (event, context) => { } break; } - //返回数据给客户端 return res }; diff --git a/uni_modules.config.json b/uni_modules.config.json new file mode 100644 index 0000000000000000000000000000000000000000..395fea795fe162a14391232e9f3ae5763dd61702 --- /dev/null +++ b/uni_modules.config.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "preupload": "node /Users/dcloud_linju/Desktop/uni_modules_tool/tool.js change", + "postupload": "node /Users/dcloud_linju/Desktop/uni_modules_tool/tool.js recovery" + } +} \ No newline at end of file diff --git a/uni_modules/json-interceptor-chooseImage/changelog.md b/uni_modules/json-interceptor-chooseImage/changelog.md new file mode 100644 index 0000000000000000000000000000000000000000..192e843f8af5fdb90b9969813141c1205561fb4d --- /dev/null +++ b/uni_modules/json-interceptor-chooseImage/changelog.md @@ -0,0 +1,4 @@ +## 1.0.1(2021-05-20) +新增文档和示例代码 +## 1.0.0(2021-05-20) +第一版本发布 diff --git a/uni_modules/json-interceptor-chooseImage/js_sdk/main.js b/uni_modules/json-interceptor-chooseImage/js_sdk/main.js new file mode 100644 index 0000000000000000000000000000000000000000..710d7ba48c845f111638e672ad8cd1c095d1ed7a --- /dev/null +++ b/uni_modules/json-interceptor-chooseImage/js_sdk/main.js @@ -0,0 +1,70 @@ +export default function(){ + //当应用无访问摄像头/相册权限,引导跳到设置界面 + uni.addInterceptor('chooseImage', { + fail(e) { // 失败回调拦截 更多拦截器用法 [详情](https://uniapp.dcloud.io/api/interceptor?id=addinterceptor) + console.log(e); + if (uni.getSystemInfoSync().platform == "android" && e.errMsg == 'chooseImage:fail No Permission') { + if (e.code === 11) { + uni.showModal({ + title: "无法访问摄像头", + content: "当前无摄像头访问权限,建议前往设置", + confirmText: "前往设置", + success(e) { + if (e.confirm) { + gotoAppPermissionSetting() + } + } + }); + } else { + uni.showModal({ + title: "无法访问相册", + content: "当前无系统相册访问权限,建议前往设置", + confirmText: "前往设置", + success(e) { + if (e.confirm) { + gotoAppPermissionSetting() + } + } + }); + } + } else if (e.errCode === 2&&e.errMsg == "chooseImage:fail No filming permission") { + console.log('e.errMsg === 2 ios无法拍照权限 '); + // 注:e.errCode === 8 ios无从相册选择图片的权限 api已内置无需自己用拦截器实现 + uni.showModal({ + title: "无法访问相册", + content: "当前无系统相册访问权限,建议前往设置", + confirmText: "前往设置", + success(e) { + if (e.confirm) { + gotoAppPermissionSetting() + } + } + }); + } + } + }) + + //跳转到**应用**的权限页面 参考来源:https://ext.dcloud.net.cn/plugin?id=594 + function gotoAppPermissionSetting() { + 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("app-settings:"); + application2.openURL(setting2); + plus.ios.deleteObject(setting2); + plus.ios.deleteObject(NSURL2); + plus.ios.deleteObject(application2); + } else { + 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); + } + } +} \ No newline at end of file diff --git a/uni_modules/json-interceptor-chooseImage/package.json b/uni_modules/json-interceptor-chooseImage/package.json new file mode 100644 index 0000000000000000000000000000000000000000..d349d5a3e17413d047f11f4c141ec23706d76f7a --- /dev/null +++ b/uni_modules/json-interceptor-chooseImage/package.json @@ -0,0 +1,76 @@ +{ + "id": "json-interceptor-chooseImage", + "displayName": "拦截器应用示例:图片选择api时无权限,引导用户快捷打开系统设置", + "version": "1.0.1", + "description": "拦截器应用示例:图片选择api时无权限,引导用户快捷打开系统设置", + "keywords": [ + "interceptor,拦截器,相册权限" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "n", + "Android Browser": "n", + "微信浏览器(Android)": "n", + "QQ浏览器(Android)": "n" + }, + "H5-pc": { + "Chrome": "n", + "IE": "n", + "Edge": "n", + "Firefox": "n", + "Safari": "n" + }, + "小程序": { + "微信": "n", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/json-interceptor-chooseImage/readme.md b/uni_modules/json-interceptor-chooseImage/readme.md new file mode 100644 index 0000000000000000000000000000000000000000..dc74da4fe00b9815a6059b70eb65ba1f7b45e7c4 --- /dev/null +++ b/uni_modules/json-interceptor-chooseImage/readme.md @@ -0,0 +1,30 @@ +拦截器顾名思义,是在框架方法执行的各个环节(包含:拦截前触发、成功回调拦截、失败回调拦截、完成回调拦截) +插入逻辑,篡改参数或终止运行。 +#### 优势 +- 这种方式相当于改写了api的内部逻辑,相比语法糖他更加直观,不影响ide的代码提示。 +- 将常规固定的逻辑封装到框架的api内,且支持个性化设计。如你可以在本插件路径:`/uni_modules/json-interceptor-chooseImage/js_sdk/main.js`修改弹出框元素,绘制更漂亮的样式和文字说明。 + +#### 使用示例,App.vue页代码如下: +``` + +``` + +> 跳转到**应用**的权限页面 参考来源:[https://ext.dcloud.net.cn/plugin?id=594](https://ext.dcloud.net.cn/plugin?id=594) 感谢作者@DCloud_heavensoft 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 fce981e3cf95713b3b51deb2e533b6c741a4f29d..ea9fae7b7fc5f5bb973f6f9273fdf0aba5433b14 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 @@ -1,52 +1,65 @@ +/* + 重要的事情说三遍: + 本文件不能有任何注释,删除后才能正常使用 + 本文件不能有任何注释,删除后才能正常使用 + 本文件不能有任何注释,删除后才能正常使用 +*/ { - "passwordSecret": "passwordSecret-demo", - "tokenSecret": "tokenSecret-demo", - "tokenExpiresIn": 7200, - "tokenExpiresThreshold": 600, - "passwordErrorLimit": 6, - "bindTokenToDevice": true, - "passwordErrorRetryTime": 3600, - "autoSetInviteCode": false, - "forceInviteCode": false, - "app-plus": { - "tokenExpiresIn": 2592000, - "oauth": { - "weixin": { - "appid": "", - "appsecret": "" - }, - "apple": { - "bundleId": "" - } - } - }, - "mp-weixin": { - "oauth": { - "weixin": { - "appid": "", - "appsecret": "" - } - } - }, - "mp-alipay": { - "oauth": { - "alipay": { - "appid": "", - "privateKey": "" - } - } - }, - "service": { - "sms": { - "name": "DCloud", - "codeExpiresIn": 300, - "smsKey": "", - "smsSecret": "" - }, - "univerify": { - "appid": "", - "apiKey": "", - "apiSecret": "" - } - } + "passwordSecret": "passwordSecret-demo", // 数据库中password字段是加密存储的,这里的passwordSecret即为加密密码所用的密钥,注意修改为自己的密钥,使用一个较长的字符串即可 + "tokenSecret": "tokenSecret-demo", // 生成token所用的密钥,注意修改为自己的,使用一个较长的字符串即可 + "tokenExpiresIn": 7200, // 全平台token过期时间,未指定过期时间的平台会使用此值 + "tokenExpiresThreshold": 600, // 新增于uni-id 1.1.7版本,checkToken时如果token有效期小于此值则自动获取新token,请注意将新token返回给前端保存,如果不配置此参数则不开启自动获取新token功能 + "bindTokenToDevice": false, // 是否将token和设备绑定,设置为true会进行ua校验,uni-id 3.0.12前默认为true,3.0.12及以后版本默认调整为false + "passwordErrorLimit": 6, // 密码错误最大重试次数 + "passwordErrorRetryTime": 3600, // 密码错误重试次数超限之后的冻结时间 + "autoSetInviteCode": false, // 是否在用户注册时自动设置邀请码,默认不自动设置 + "forceInviteCode": false, // 是否强制用户注册时必填邀请码,默认为false(需要注意的是目前只有短信验证码注册才可以填写邀请码),设置为true时需要在loginBySms时指定type为register来使用注册,登录时也要传入type为login + "removePermissionAndRoleFromToken": false, // 新增于uni-id 3.0.0版本,如果配置为false则自动缓存用户的角色、权限到token中,默认值为false。详细说明见https://uniapp.dcloud.io/uniCloud/uni-id?id=cachepermissionintoken + "app-plus": { + "tokenExpiresIn": 2592000, + "oauth": { + // App微信登录所用到的appid、appsecret需要在微信开放平台获取,注意:不是公众平台而是开放平台 + "weixin": { + "appid": "weixin appid", + "appsecret": "weixin appsecret" + }, + "apple": { // 使用苹果登录时需要 + "bundleId": "your bundleId" + } + } + }, + "mp-weixin": { + "tokenExpiresIn": 259200, + "oauth": { + // 微信小程序登录所用的appid、appsecret需要在对应的小程序管理控制台获取 + "weixin": { + "appid": "weixin appid", + "appsecret": "weixin appsecret" + } + } + }, + "mp-alipay": { + "tokenExpiresIn": 259200, + "oauth": { + // 支付宝小程序登录用到的appid、privateKey请参考支付宝小程序的文档进行设置或者获取,https://opendocs.alipay.com/open/291/105971#LDsXr + "alipay": { + "appid": "alipay appid", + "privateKey": "alipay privateKey", // 私钥 + "keyType": "PKCS8" // 私钥类型,如果私钥类型不是PKCS8,需要填写此字段,否则会出现“error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag”错误 + } + } + }, + "service": { + "sms": { + "name": "your app name", // 应用名称,对应短信模版的name + "codeExpiresIn": 180, // 验证码过期时间,单位为秒,注意一定要是60的整数倍 + "smsKey": "your sms key", // 短信密钥key,开通短信服务处可以看到 + "smsSecret": "your sms secret" // 短信密钥secret,开通短信服务处可以看到 + }, + "univerify": { + "appid": "your appid", // 当前应用的appid,使用云函数URL化,此项必须配置 + "apiKey": "your apiKey",// apiKey 和 apiSecret 在开发者中心获取,开发者中心:https://dev.dcloud.net.cn/uniLogin/index?type=0,文档:https://ask.dcloud.net.cn/article/37965 + "apiSecret": "your apiSecret" + } + } } \ No newline at end of file