HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

Vue.js自定义PC版模态框组件|vue layer弹层

vue.js

介绍

vlayer 一款基于vue.js构建的桌面端弹框组件。集合了 alert|dialog|modal|msg|notify|popover|toast|actionsheet 等多种功能于一身。

基于vue.js构建pc端弹窗组件|仿layer弹框插件

vlayer

vlayer

快速上手

在main.js中全局引入vlayer组件。

import VLayer from './components/vlayer';  
Vue.use(VLayer);

标签式写法

<v-layer   
    v-model="isConfirm"  
    title="标题内容"  
    content="<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>"  
    xclose  
    z-index="2002"  
    lockScroll="false"  
    resize  
    dragOut  
    :btns="[  
        {text: '取消', click: () => isConfirm=false},  
        {text: '确定', style: 'color:#f90;', click: handleFn},  
    ]"  
/>

函数式写法

let $el = this.$vlayer({  
    title: '标题内容',  
    content: '<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>',   
    xclose: true,  
    zIndex: 2002,  
    lockScroll: false,  
    resize: true,  
    dragOut: true,  
    btns: [  
        {text: '取消', click: () => { $el.close(); }},  
        {text: '确定', click: () => this.handleFn()},  
    ]  
});

效果预览

vlayer

vlayer

vlayer

vlayer

vlayer

vlayer

vlayer

配置参数

vlayer默认支持30+种参数任意搭配。

@@默认参数  
v-model     当前组件是否显示  
title       标题  
content     内容(支持自定义插槽内容)  
type        弹窗类型(toast | footer | actionsheet | android/ios | contextmenu | drawer | iframe | message/notify/popover)  
layerStyle  自定义弹窗样式  
icon        toast图标(loading | success | fail)  
shade       是否显示遮罩层  
shadeClose  是否点击遮罩时关闭弹窗  
lockScroll  是否弹窗出现时将 body 滚动锁定  
opacity     遮罩层透明度  
xclose      是否显示关闭图标  
xposition   关闭图标位置(left | right | top | bottom)  
xcolor      关闭图标颜色  
anim        弹窗动画(scaleIn | fadeIn | footer | fadeInUp | fadeInDown | fadeInLeft | fadeInRight)  
position    弹出位置(auto | ['100px','50px'] | t | r | b | l | lt | rt | lb | rb)  
drawer      抽屉弹窗(top | right | bottom | left)  
follow      跟随元素定位弹窗(支持元素.kk #kk 或 [e.clientX, e.clientY])  
time        弹窗自动关闭秒数(1、2、3)  
zIndex      弹窗层叠(默认8080)  
topmost     置顶当前窗口(默认false)  
area        弹窗宽高(默认auto)设置宽度area: '300px' 设置高度area:['', '200px'] 设置宽高area:['350px', '150px']  
maxWidth    弹窗最大宽度(只有当area:'auto'时,maxWidth的设定才有效)  
maximize    是否显示最大化按钮(默认false)  
fullscreen  全屏弹窗(默认false)  
fixed       弹窗是否固定  
drag        拖拽元素(可定义选择器drag:'.xxx' | 禁止拖拽drag:false)  
dragOut     是否允许拖拽到窗口外(默认false)  
resize      是否允许拉伸尺寸(默认false)  
btns        弹窗按钮(参数:text|style|disabled|click)  
------------------------------------------  
@@组件式事件  
open        打开弹出层时触发(@open="xxx")  
close       关闭弹出层时触发(@close="xxx")  
------------------------------------------  
@@函数式事件  
onOpen      打开弹窗回调  
onClose     关闭弹窗回调

vlayer.vue模板

<template>  
  <div v-show="opened" class="vui__layer" :class="{'vui__layer-closed': closeCls}" :id="vlayerId">  
    <div v-if="JSON.parse(shade)" class="vlayer__overlay" @click="shadeClicked" :style="{opacity}"></div>  
    <div class="vlayer__wrap" :class="[''+anim, type&&'popui__'+type, drawer&&'popui'+drawer, xclose&&'vlayer-closable', tipArrow]" :style="layerStyle">  
      <div v-if="title" class="vlayer__wrap-tit" v-html="title"></div>  
      <div v-if="type=='toast'&&icon" class="vlayer__toast-icon" :class="['vlayer'+icon]" v-html="toastIcon[icon]"></div>  
      <div class="vlayer__wrap-cntbox">  
        <template v-if="$slots.content">  
          <div class="vlayer__wrap-cnt"><slot name="content" /></div>  
        </template>  
        <template v-else>  
          <template v-if="content">  
            <iframe v-if="type=='iframe'" scrolling="auto" allowtransparency="true" frameborder="0" :src="content"></iframe>  
            <!-- message|notify|popover -->  
            <div v-else-if="type=='message' || type=='notify' || type=='popover'" class="vlayer__wrap-cnt">  
              <i v-if="icon" class="vlayer-msg__icon" :class="icon" v-html="messageIcon[icon]"></i>  
              <div class="vlayer-msg__group"><div v-if="title" class="vlayer-msg__title" v-html="title"></div><div class="vlayer-msg__content" v-html="content"></div></div>  
            </div><div v-else class="vlayer__wrap-cnt" v-html="content"></div>  
          </template>  
        </template>  
        <slot />  
      </div>  
      <div v-if="btns" class="vlayer__wrap-btns">  
        <span v-for="(btn,index) in btns" :key="index" class="btn" :class="{'btn-disabled': btn.disabled}" :style="btn.style" v-html="btn.text"></span>  
      </div>  
      <span v-if="xclose" class="vlayer__xclose" :class="!maximize&&xposition" :style="{'color': xcolor}" @click="close"></span>  
      <span v-if="maximize" class="vlayer__maximize"></span>  
      <span v-if="resize" class="vlayer__resize"></span>  
    </div>  
    <!-- 修复拖拽卡顿 -->  
    <div class="vlayer__dragfix"></div>  
  </div>  
</template>

默认标题是拖拽区域,当然也可以自定义拖拽元素,只需设置 drag: '#xxx' 或者设置drag: false 来禁止弹窗拖拽功能。

当设置 dragOut: true 窗体可以拖拽到浏览器外部。

当使用popover弹窗,需要传入follow: '#xxxx' 定位元素。

另外还支持自定义弹窗显示位置,只需配置position即可。

<!-- 自定义弹窗位置 -->  
<v-layer v-model="showPosition" xclose maximize drag=".dragImg" :position="rb">  
    <img class="dragImg" src="xxx.jpg" />  
</v-layer>

设置fullscreen: true会全屏显示弹窗。

vlayer

okay,基于vue.js开发pc端弹窗插件就分享到这里。希望对大家有所帮助哈!✍✍

链接:https://juejin.im/post/6890442763041669127/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

继续阅读 »

介绍

vlayer 一款基于vue.js构建的桌面端弹框组件。集合了 alert|dialog|modal|msg|notify|popover|toast|actionsheet 等多种功能于一身。

基于vue.js构建pc端弹窗组件|仿layer弹框插件

vlayer

vlayer

快速上手

在main.js中全局引入vlayer组件。

import VLayer from './components/vlayer';  
Vue.use(VLayer);

标签式写法

<v-layer   
    v-model="isConfirm"  
    title="标题内容"  
    content="<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>"  
    xclose  
    z-index="2002"  
    lockScroll="false"  
    resize  
    dragOut  
    :btns="[  
        {text: '取消', click: () => isConfirm=false},  
        {text: '确定', style: 'color:#f90;', click: handleFn},  
    ]"  
/>

函数式写法

let $el = this.$vlayer({  
    title: '标题内容',  
    content: '<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>',   
    xclose: true,  
    zIndex: 2002,  
    lockScroll: false,  
    resize: true,  
    dragOut: true,  
    btns: [  
        {text: '取消', click: () => { $el.close(); }},  
        {text: '确定', click: () => this.handleFn()},  
    ]  
});

效果预览

vlayer

vlayer

vlayer

vlayer

vlayer

vlayer

vlayer

配置参数

vlayer默认支持30+种参数任意搭配。

@@默认参数  
v-model     当前组件是否显示  
title       标题  
content     内容(支持自定义插槽内容)  
type        弹窗类型(toast | footer | actionsheet | android/ios | contextmenu | drawer | iframe | message/notify/popover)  
layerStyle  自定义弹窗样式  
icon        toast图标(loading | success | fail)  
shade       是否显示遮罩层  
shadeClose  是否点击遮罩时关闭弹窗  
lockScroll  是否弹窗出现时将 body 滚动锁定  
opacity     遮罩层透明度  
xclose      是否显示关闭图标  
xposition   关闭图标位置(left | right | top | bottom)  
xcolor      关闭图标颜色  
anim        弹窗动画(scaleIn | fadeIn | footer | fadeInUp | fadeInDown | fadeInLeft | fadeInRight)  
position    弹出位置(auto | ['100px','50px'] | t | r | b | l | lt | rt | lb | rb)  
drawer      抽屉弹窗(top | right | bottom | left)  
follow      跟随元素定位弹窗(支持元素.kk #kk 或 [e.clientX, e.clientY])  
time        弹窗自动关闭秒数(1、2、3)  
zIndex      弹窗层叠(默认8080)  
topmost     置顶当前窗口(默认false)  
area        弹窗宽高(默认auto)设置宽度area: '300px' 设置高度area:['', '200px'] 设置宽高area:['350px', '150px']  
maxWidth    弹窗最大宽度(只有当area:'auto'时,maxWidth的设定才有效)  
maximize    是否显示最大化按钮(默认false)  
fullscreen  全屏弹窗(默认false)  
fixed       弹窗是否固定  
drag        拖拽元素(可定义选择器drag:'.xxx' | 禁止拖拽drag:false)  
dragOut     是否允许拖拽到窗口外(默认false)  
resize      是否允许拉伸尺寸(默认false)  
btns        弹窗按钮(参数:text|style|disabled|click)  
------------------------------------------  
@@组件式事件  
open        打开弹出层时触发(@open="xxx")  
close       关闭弹出层时触发(@close="xxx")  
------------------------------------------  
@@函数式事件  
onOpen      打开弹窗回调  
onClose     关闭弹窗回调

vlayer.vue模板

<template>  
  <div v-show="opened" class="vui__layer" :class="{'vui__layer-closed': closeCls}" :id="vlayerId">  
    <div v-if="JSON.parse(shade)" class="vlayer__overlay" @click="shadeClicked" :style="{opacity}"></div>  
    <div class="vlayer__wrap" :class="[''+anim, type&&'popui__'+type, drawer&&'popui'+drawer, xclose&&'vlayer-closable', tipArrow]" :style="layerStyle">  
      <div v-if="title" class="vlayer__wrap-tit" v-html="title"></div>  
      <div v-if="type=='toast'&&icon" class="vlayer__toast-icon" :class="['vlayer'+icon]" v-html="toastIcon[icon]"></div>  
      <div class="vlayer__wrap-cntbox">  
        <template v-if="$slots.content">  
          <div class="vlayer__wrap-cnt"><slot name="content" /></div>  
        </template>  
        <template v-else>  
          <template v-if="content">  
            <iframe v-if="type=='iframe'" scrolling="auto" allowtransparency="true" frameborder="0" :src="content"></iframe>  
            <!-- message|notify|popover -->  
            <div v-else-if="type=='message' || type=='notify' || type=='popover'" class="vlayer__wrap-cnt">  
              <i v-if="icon" class="vlayer-msg__icon" :class="icon" v-html="messageIcon[icon]"></i>  
              <div class="vlayer-msg__group"><div v-if="title" class="vlayer-msg__title" v-html="title"></div><div class="vlayer-msg__content" v-html="content"></div></div>  
            </div><div v-else class="vlayer__wrap-cnt" v-html="content"></div>  
          </template>  
        </template>  
        <slot />  
      </div>  
      <div v-if="btns" class="vlayer__wrap-btns">  
        <span v-for="(btn,index) in btns" :key="index" class="btn" :class="{'btn-disabled': btn.disabled}" :style="btn.style" v-html="btn.text"></span>  
      </div>  
      <span v-if="xclose" class="vlayer__xclose" :class="!maximize&&xposition" :style="{'color': xcolor}" @click="close"></span>  
      <span v-if="maximize" class="vlayer__maximize"></span>  
      <span v-if="resize" class="vlayer__resize"></span>  
    </div>  
    <!-- 修复拖拽卡顿 -->  
    <div class="vlayer__dragfix"></div>  
  </div>  
</template>

默认标题是拖拽区域,当然也可以自定义拖拽元素,只需设置 drag: '#xxx' 或者设置drag: false 来禁止弹窗拖拽功能。

当设置 dragOut: true 窗体可以拖拽到浏览器外部。

当使用popover弹窗,需要传入follow: '#xxxx' 定位元素。

另外还支持自定义弹窗显示位置,只需配置position即可。

<!-- 自定义弹窗位置 -->  
<v-layer v-model="showPosition" xclose maximize drag=".dragImg" :position="rb">  
    <img class="dragImg" src="xxx.jpg" />  
</v-layer>

设置fullscreen: true会全屏显示弹窗。

vlayer

okay,基于vue.js开发pc端弹窗插件就分享到这里。希望对大家有所帮助哈!✍✍

链接:https://juejin.im/post/6890442763041669127/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

收起阅读 »

从uniapp的webview跳回APP的方法

Webview

今天找一个网站:https://www.jianshu.com/p/163b1cdd664d 分享出来以后查看

今天找一个网站:https://www.jianshu.com/p/163b1cdd664d 分享出来以后查看

uni-app打包的基于DiscuzQ的App上架iOS了,欢迎来摸鱼

iOS打包

https://apps.apple.com/cn/app/id1539378146

imgbed.cn图床

中间被拒绝过一次,因为没有写明摄像头用途,更改再次提交就通过了

继续阅读 »

https://apps.apple.com/cn/app/id1539378146

imgbed.cn图床

中间被拒绝过一次,因为没有写明摄像头用途,更改再次提交就通过了

收起阅读 »

11.3日升级以后,横屏项目在CHROME中显示正常,但真机调试布局出现问题(升级前完全正常)

为什么一直好好的,前几天升级以后,我的横屏项目在CHROME中显示正常,但真机调试布局出现问题,如附件1和附件2显示。11.3日还是正常的,后面升级过就不正常了。我已经尝试如下:
1、以为是基座的问题,重新编译过基座也是不行。
2、按照https://ask.dcloud.net.cn/article/37911改了 __uniappview.html文件的内容并重新打开编译基座,还是不行

现在导致根本无法真机调试,而且还有其他几个项目也是用UNIAPP开发的横屏项目,改过的都不敢更新了。非常紧急,希望得到支持,非常感谢,非常感谢!!!

继续阅读 »

为什么一直好好的,前几天升级以后,我的横屏项目在CHROME中显示正常,但真机调试布局出现问题,如附件1和附件2显示。11.3日还是正常的,后面升级过就不正常了。我已经尝试如下:
1、以为是基座的问题,重新编译过基座也是不行。
2、按照https://ask.dcloud.net.cn/article/37911改了 __uniappview.html文件的内容并重新打开编译基座,还是不行

现在导致根本无法真机调试,而且还有其他几个项目也是用UNIAPP开发的横屏项目,改过的都不敢更新了。非常紧急,希望得到支持,非常感谢,非常感谢!!!

收起阅读 »

5+ App 一键登录使用指南

一键登录 univerify

概述

uni一键登录是DCloud联合个推公司推出的,整合了三大运营商网关认证能力的服务。

通过运营商的底层SDK,实现App端无需短信验证码直接获取手机号,也就是很多主流App都提供的一键登陆功能。

uni一键登录是替代短信验证登录的下一代登录验证方式,能消除现有短信验证模式等待时间长、操作繁琐和容易泄露的痛点。

  • 支持版本:HBuilderX 3.0+
  • 支持项目类型:uni-app的App端,5+ App,Wap2App
  • 支持系统平台: Android,iOS
  • 支持运营商: 中国移动,中国联通,中国电信

uni-app 项目请参考:一键登录(uni-verify)

运行效果展示(支持全屏模式和非全屏模式)

全屏效果 非全屏效果
<img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/full_styles_v2.png"> <img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/half_styles_v2.png">

注:页面标注的属性可以修改,具体请参考下面的 univerifyStyle 数据结构说明

开通

开通uni一键登录服务

开发者需要登录DCloud开发者中心,申请开通一键登录服务。

详细步骤参考:开通一键登录服务的详细教程

开通成功后会得到 apiKey、apiSecret。这2个信息,后续需要配置在uniCloud的云函数里。同时注意保密,这2个信息也是计费凭证。

集成模块

开通uniCloud服务

一键登录在客户端获取 access_token 后,必须在 uniCloud 换取手机号码。
对于5+ App,需要新建一个 uni-app 应用,且开通其uniCloud服务。
在uniCloud的云函数中拿到手机号后,可以通过云函数url方式生成普通的http接口给 5+ App 使用。
开通uniCloud是免费的,其中阿里云是全免费,腾讯云是提供一个免费服务空间。

注意:
虽然一键登录需要uniCloud,但并不要求开发者把所有的后台服务都迁移到uniCloud

服务器API详见:uniCloud云函数中使用一键登录

开发

客户端 - 获取 AuthService

使用一键登录,需要先调用plus.oauth.getServices获取服务对应的 AuthService 对象:

  • id 为 'univerify'
  • description 为 '一键登录'

示例代码如下:

var auth = null  
plus.oauth.getServices(function(services) {  
    for (var i in services) {  
        var service = services[i];  
        if (service.id == "univerify") {  
            auth = service;  
            break;  
        }  
    }  
}  

客户端 - 预登录(可选)

预登录auth.preLogin操作可以判断当前设备环境是否支持一键登录授权认证,如果支持则可以显示一键登录选项,同时预登录会准备好相关环境,显著提升后续一键登录的操作速度。

如果当前设备环境不支持一键登录,此时应该显示其他的登录选项。

示例代码如下:

auth.preLogin(function(){  //预登录成功  
    // 显示一键登录选项  
},function(error){  // 预登录失败  
    // 不显示一键登录选项(或置灰)  
        // 根据错误信息判断失败原因,如有需要可将错误提交给统计服务器  
    console.log(error.message);  
})  

错误信息数据示例:

{  
    "appid": "pPyZW6PXba10aJ00911",  
    "code": 30005,  
    "message": "-20202当前没有开启蜂窝网络, 请检查是否开启蜂窝网络。",  
    "metadata": {  
        "resultCode": "1",  
        "resultData": {},  
        "resultMsg": "获取鉴权信息失败",  
        "traceId": ""  
    },  
    "uid": "8b91b76e0f074cef74aa30811ff737"  
}

客户端 - 请求登录授权

调用请求登录授权auth.login接口,弹出用户授权界面,根据用户操作及授权结果返回对应的回调,获取到openidaccess_token

示例代码如下:

auth.login(function(event){  //登录成功  
    var openid = auth.authResult.openid;  
    var access_tolen = auth.authResult.access_token;  
},function(error){  //登录失败  

},{ // 自定义页面参数  
   univerifyStyle: { // 自定义登录框样式  
    //参考`univerifyStyle 数据结构`  
  }  
})

univerifyStyle 数据结构

{    
    "fullScreen": false, // 是否全屏显示,默认值: false  
    "backgroundColor": "#ffffff",  // 授权页面背景颜色,默认值:#ffffff  
    "backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)    
    "icon": {    
        "path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo     
    },    
    "phoneNum": {    
        "color": "#202020"  // 手机号文字颜色 默认值:#202020    
    },    
    "slogan": {    
        "color": "#BBBBBB"  //  slogan 字体颜色 默认值:#BBBBBB    
    },    
    "authButton": {    
        "normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5    
        "highlightColor": "#2861c5",  // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)    
        "disabledColor": "#73aaf5",  // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)    
        "textColor": "#ffffff",  // 授权按钮文字颜色 默认值:#ffffff    
        "title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”    
        "borderRadius": "24px"  // 授权按钮圆角 默认值:"24px" (按钮高度的一半)  
    },    
    "otherLoginButton": {    
        "visible": true, // 是否显示其他登录按钮,默认值:true    
        "normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明   
        "highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明   
        "textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565    
        "title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”    
        "borderColor": "",  //边框颜色 默认值:透明(仅iOS支持)    
        "borderRadius": "0px" // 其他登录按钮圆角 默认值:"0px"   
    },    
    "privacyTerms": {    
        "defaultCheckBoxState":true, // 条款勾选框初始状态 默认值: true  
        "uncheckedImage":"", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)   
        "checkedImage":"", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)     
        "textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB    
        "termsColor": "#5496E3", //  协议文字颜色 默认值: #5496E3    
        "prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”    
        "suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”    
        "privacyItems": [    
            // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效    
            {    
                "url": "https://", // 点击跳转的协议详情页面    
                "title": "用户服务协议" // 协议名称    
            }    
        ]    
    },  
    "buttons": { // 仅全屏模式生效,配置页面下方按钮  (3.1.14+ 版本支持)  
        "iconWidth": "45px",        // 图标宽度(高度等比例缩放) 默认值:45px  
        "list": [{  
                "iconPath": "/static/wechat.png",  // 图标路径仅支持本地图片  
                "onclick": function() {}  // 按钮点击回调方法  
            },  
            {  
                "iconPath": "/static/apple.png",  
                "onclick": function() {} // 按钮点击回调方法  
            }  
        ]  
    }  
}

客户端 - 关闭一键登录界面

请求登录认证操作完成后,不管成功或失败都不会关闭一键登录界面,需要主动调用auth.closeAuthView方法关闭。
客户端登录认证完成只是说明获取 access_token 成功,需要将此数据提交到服务器获取手机号码,完成业务服务登录逻辑后通知客户端关闭登录界面。

auth.closeAuthView()

获取勾选框状态 (3.2.5+ 版本支持)

获取用户是否选中了勾选框

var state = auth.getCheckBoxState();  
// true 选中,false 未选中

换取手机号码

在 uniCloud 中可以将客户端获取的 access_token 置换为真实的手机号码。
重要提示:为了保证数据的安全,用户手机号码信息不应该返回给客户端 !!!

前置条件:已创建一个uni-app 应用,且开通uniCloud服务。
对于5+ App来说,因为本身不支持uniCloud能力:因此需要http服务化云函数进行调用。

操作步骤:

  • 新建云函数,实现一键登录功能并上传部署。
    创建云函数,代码参考uni-app 实现

  • 将刚才上传的云函数,开通http服务状态。

  • 5+ 应用访问uni-app 应用的 http 服务

返回数据示例

{  
    "data": {  
        "code": 0,  
        "success": true,  
        "phoneNumber": "166xxxx6666"  
    },  
    "statusCode": 200,  
    "header": {  
        "Content-Type": "application/json; charset=utf-8",  
        "Connection": "keep-alive",  
        "Content-Length": "53",  
        "Date": "Fri, 06 Nov 2020 08:57:21 GMT",  
        "X-CloudBase-Request-Id": "xxxxxxxxxxx",  
        "ETag": "xxxxxx""  
    },  
    "errMsg": "request:ok"  
}

关于uniCloud对一键登录功能的详细说明

常见问题

  • 双卡手机能否同时获取两个手机号码
    不支持同时获取两个手机号,
    双卡手机以开启数据流量的 SIM 卡进行认证。
继续阅读 »

概述

uni一键登录是DCloud联合个推公司推出的,整合了三大运营商网关认证能力的服务。

通过运营商的底层SDK,实现App端无需短信验证码直接获取手机号,也就是很多主流App都提供的一键登陆功能。

uni一键登录是替代短信验证登录的下一代登录验证方式,能消除现有短信验证模式等待时间长、操作繁琐和容易泄露的痛点。

  • 支持版本:HBuilderX 3.0+
  • 支持项目类型:uni-app的App端,5+ App,Wap2App
  • 支持系统平台: Android,iOS
  • 支持运营商: 中国移动,中国联通,中国电信

uni-app 项目请参考:一键登录(uni-verify)

运行效果展示(支持全屏模式和非全屏模式)

全屏效果 非全屏效果
<img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/full_styles_v2.png"> <img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/half_styles_v2.png">

注:页面标注的属性可以修改,具体请参考下面的 univerifyStyle 数据结构说明

开通

开通uni一键登录服务

开发者需要登录DCloud开发者中心,申请开通一键登录服务。

详细步骤参考:开通一键登录服务的详细教程

开通成功后会得到 apiKey、apiSecret。这2个信息,后续需要配置在uniCloud的云函数里。同时注意保密,这2个信息也是计费凭证。

集成模块

开通uniCloud服务

一键登录在客户端获取 access_token 后,必须在 uniCloud 换取手机号码。
对于5+ App,需要新建一个 uni-app 应用,且开通其uniCloud服务。
在uniCloud的云函数中拿到手机号后,可以通过云函数url方式生成普通的http接口给 5+ App 使用。
开通uniCloud是免费的,其中阿里云是全免费,腾讯云是提供一个免费服务空间。

注意:
虽然一键登录需要uniCloud,但并不要求开发者把所有的后台服务都迁移到uniCloud

服务器API详见:uniCloud云函数中使用一键登录

开发

客户端 - 获取 AuthService

使用一键登录,需要先调用plus.oauth.getServices获取服务对应的 AuthService 对象:

  • id 为 'univerify'
  • description 为 '一键登录'

示例代码如下:

var auth = null  
plus.oauth.getServices(function(services) {  
    for (var i in services) {  
        var service = services[i];  
        if (service.id == "univerify") {  
            auth = service;  
            break;  
        }  
    }  
}  

客户端 - 预登录(可选)

预登录auth.preLogin操作可以判断当前设备环境是否支持一键登录授权认证,如果支持则可以显示一键登录选项,同时预登录会准备好相关环境,显著提升后续一键登录的操作速度。

如果当前设备环境不支持一键登录,此时应该显示其他的登录选项。

示例代码如下:

auth.preLogin(function(){  //预登录成功  
    // 显示一键登录选项  
},function(error){  // 预登录失败  
    // 不显示一键登录选项(或置灰)  
        // 根据错误信息判断失败原因,如有需要可将错误提交给统计服务器  
    console.log(error.message);  
})  

错误信息数据示例:

{  
    "appid": "pPyZW6PXba10aJ00911",  
    "code": 30005,  
    "message": "-20202当前没有开启蜂窝网络, 请检查是否开启蜂窝网络。",  
    "metadata": {  
        "resultCode": "1",  
        "resultData": {},  
        "resultMsg": "获取鉴权信息失败",  
        "traceId": ""  
    },  
    "uid": "8b91b76e0f074cef74aa30811ff737"  
}

客户端 - 请求登录授权

调用请求登录授权auth.login接口,弹出用户授权界面,根据用户操作及授权结果返回对应的回调,获取到openidaccess_token

示例代码如下:

auth.login(function(event){  //登录成功  
    var openid = auth.authResult.openid;  
    var access_tolen = auth.authResult.access_token;  
},function(error){  //登录失败  

},{ // 自定义页面参数  
   univerifyStyle: { // 自定义登录框样式  
    //参考`univerifyStyle 数据结构`  
  }  
})

univerifyStyle 数据结构

{    
    "fullScreen": false, // 是否全屏显示,默认值: false  
    "backgroundColor": "#ffffff",  // 授权页面背景颜色,默认值:#ffffff  
    "backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)    
    "icon": {    
        "path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo     
    },    
    "phoneNum": {    
        "color": "#202020"  // 手机号文字颜色 默认值:#202020    
    },    
    "slogan": {    
        "color": "#BBBBBB"  //  slogan 字体颜色 默认值:#BBBBBB    
    },    
    "authButton": {    
        "normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5    
        "highlightColor": "#2861c5",  // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)    
        "disabledColor": "#73aaf5",  // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)    
        "textColor": "#ffffff",  // 授权按钮文字颜色 默认值:#ffffff    
        "title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”    
        "borderRadius": "24px"  // 授权按钮圆角 默认值:"24px" (按钮高度的一半)  
    },    
    "otherLoginButton": {    
        "visible": true, // 是否显示其他登录按钮,默认值:true    
        "normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明   
        "highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明   
        "textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565    
        "title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”    
        "borderColor": "",  //边框颜色 默认值:透明(仅iOS支持)    
        "borderRadius": "0px" // 其他登录按钮圆角 默认值:"0px"   
    },    
    "privacyTerms": {    
        "defaultCheckBoxState":true, // 条款勾选框初始状态 默认值: true  
        "uncheckedImage":"", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)   
        "checkedImage":"", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)     
        "textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB    
        "termsColor": "#5496E3", //  协议文字颜色 默认值: #5496E3    
        "prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”    
        "suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”    
        "privacyItems": [    
            // 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效    
            {    
                "url": "https://", // 点击跳转的协议详情页面    
                "title": "用户服务协议" // 协议名称    
            }    
        ]    
    },  
    "buttons": { // 仅全屏模式生效,配置页面下方按钮  (3.1.14+ 版本支持)  
        "iconWidth": "45px",        // 图标宽度(高度等比例缩放) 默认值:45px  
        "list": [{  
                "iconPath": "/static/wechat.png",  // 图标路径仅支持本地图片  
                "onclick": function() {}  // 按钮点击回调方法  
            },  
            {  
                "iconPath": "/static/apple.png",  
                "onclick": function() {} // 按钮点击回调方法  
            }  
        ]  
    }  
}

客户端 - 关闭一键登录界面

请求登录认证操作完成后,不管成功或失败都不会关闭一键登录界面,需要主动调用auth.closeAuthView方法关闭。
客户端登录认证完成只是说明获取 access_token 成功,需要将此数据提交到服务器获取手机号码,完成业务服务登录逻辑后通知客户端关闭登录界面。

auth.closeAuthView()

获取勾选框状态 (3.2.5+ 版本支持)

获取用户是否选中了勾选框

var state = auth.getCheckBoxState();  
// true 选中,false 未选中

换取手机号码

在 uniCloud 中可以将客户端获取的 access_token 置换为真实的手机号码。
重要提示:为了保证数据的安全,用户手机号码信息不应该返回给客户端 !!!

前置条件:已创建一个uni-app 应用,且开通uniCloud服务。
对于5+ App来说,因为本身不支持uniCloud能力:因此需要http服务化云函数进行调用。

操作步骤:

  • 新建云函数,实现一键登录功能并上传部署。
    创建云函数,代码参考uni-app 实现

  • 将刚才上传的云函数,开通http服务状态。

  • 5+ 应用访问uni-app 应用的 http 服务

返回数据示例

{  
    "data": {  
        "code": 0,  
        "success": true,  
        "phoneNumber": "166xxxx6666"  
    },  
    "statusCode": 200,  
    "header": {  
        "Content-Type": "application/json; charset=utf-8",  
        "Connection": "keep-alive",  
        "Content-Length": "53",  
        "Date": "Fri, 06 Nov 2020 08:57:21 GMT",  
        "X-CloudBase-Request-Id": "xxxxxxxxxxx",  
        "ETag": "xxxxxx""  
    },  
    "errMsg": "request:ok"  
}

关于uniCloud对一键登录功能的详细说明

常见问题

  • 双卡手机能否同时获取两个手机号码
    不支持同时获取两个手机号,
    双卡手机以开启数据流量的 SIM 卡进行认证。
收起阅读 »

自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android)

自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android):https://ext.dcloud.net.cn/plugin?id=3404

自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android):https://ext.dcloud.net.cn/plugin?id=3404

Biaofun基础widgets教程-SizedBox部分

1 SizedBox
两种用法:一是可用来设置两个widget之间的间距,二是可以用来限制子组件的大小
Biaofun基础widgets教程-SizedBox部分
2 构造函数

SizedBox({   
    Key key,   
    this.width,   
    this.height,   
    Widget child   
})

3 常用属性标梵互动
3.1 width:SizedBox的宽
width: 250,
3.2 height:SizedBox的高
height: 250,
3.3 child:SizedBox的子widget
child: Text("内容"),
4.显示效果

5.代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
// 字体适配
import '../../utils/app_size.dart';

class ListSizedBox extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('SizedBox'),
backgroundColor: Color(0xFFfafcff),
bottom: TabBar(labelColor: Color(0xff030303), tabs: [
Tab(
text: "效果",
),
Tab(
text: "属性",
)
]),
),
body: TabBarView(children: [
Container(
decoration: new BoxDecoration(
color: new Color(0xffffffff),
borderRadius: new BorderRadius.circular((AppSize.width(20))),
),
child: ShowEffect()),
Container(
decoration: new BoxDecoration(
color: new Color(0xffffffff),
borderRadius: new BorderRadius.circular((AppSize.width(20))),
),
child: ShowAttribute()),
]),
),
);
}
}

// 效果
class ShowEffect extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(children: <Widget>[
SizedBox(
width: 150.0,
height: 150.0,
child: Container(
margin: EdgeInsets.all(20.0),
width: 200.0,
height: 200.0,
color: Colors.blue,
),
),
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
margin: EdgeInsets.all(20.0),
width: 200.0,
height: 200.0,
color: Colors.yellow,
),
),
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
margin: EdgeInsets.all(20.0),
width: 200.0,
height: 200.0,
color: Colors.red,
),
)
]);
}
}

// 属性
class ShowAttribute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: rootBundle.loadString('lib/markdown/sizedBox.md'),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Markdown(
data: snapshot.data,
selectable: true,
);
} else {
return Center(
child: Text("加载中..."),
);
}
},
),
);
}
}

本文来源:标梵互动 https://www.biaofun.com/

继续阅读 »

1 SizedBox
两种用法:一是可用来设置两个widget之间的间距,二是可以用来限制子组件的大小
Biaofun基础widgets教程-SizedBox部分
2 构造函数

SizedBox({   
    Key key,   
    this.width,   
    this.height,   
    Widget child   
})

3 常用属性标梵互动
3.1 width:SizedBox的宽
width: 250,
3.2 height:SizedBox的高
height: 250,
3.3 child:SizedBox的子widget
child: Text("内容"),
4.显示效果

5.代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
// 字体适配
import '../../utils/app_size.dart';

class ListSizedBox extends StatelessWidget {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('SizedBox'),
backgroundColor: Color(0xFFfafcff),
bottom: TabBar(labelColor: Color(0xff030303), tabs: [
Tab(
text: "效果",
),
Tab(
text: "属性",
)
]),
),
body: TabBarView(children: [
Container(
decoration: new BoxDecoration(
color: new Color(0xffffffff),
borderRadius: new BorderRadius.circular((AppSize.width(20))),
),
child: ShowEffect()),
Container(
decoration: new BoxDecoration(
color: new Color(0xffffffff),
borderRadius: new BorderRadius.circular((AppSize.width(20))),
),
child: ShowAttribute()),
]),
),
);
}
}

// 效果
class ShowEffect extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(children: <Widget>[
SizedBox(
width: 150.0,
height: 150.0,
child: Container(
margin: EdgeInsets.all(20.0),
width: 200.0,
height: 200.0,
color: Colors.blue,
),
),
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
margin: EdgeInsets.all(20.0),
width: 200.0,
height: 200.0,
color: Colors.yellow,
),
),
SizedBox(
width: 100.0,
height: 100.0,
child: Container(
margin: EdgeInsets.all(20.0),
width: 200.0,
height: 200.0,
color: Colors.red,
),
)
]);
}
}

// 属性
class ShowAttribute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: rootBundle.loadString('lib/markdown/sizedBox.md'),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
return Markdown(
data: snapshot.data,
selectable: true,
);
} else {
return Center(
child: Text("加载中..."),
);
}
},
),
);
}
}

本文来源:标梵互动 https://www.biaofun.com/

收起阅读 »

DCloud授权登录接入文档

auth2.0授权 插件授权登录 auth2.0授权登录 web登录授权

简介

DCloud用户开放平台,https://open.dcloud.net.cn,是DCloud为三方开发者服务商提供的开放平台。

DCloud将数百万开发者的流量通过开放平台提供给三方开发者服务商。

使用场景:

1.三方的开发者服务商,比如Git服务商,可以制作HBuilderX插件,并且将账户打通。比如在HBuilderX插件中注册项目的右键菜单,在HBuilderX中对项目点右键,一键上传源码到某Git服务商,且无需再重复注册三方Git服务账户。
2.第三方网站,可以申请web授权给自己网站,用户无需在网站注册,直接可以跳转到DCloud登录授权页面进行登录后回跳到网站进行登录。

当然不止是Git服务商、网站,所有其他开发者服务商,如测试、加固、多渠道发布、招聘...,均可通过DCloud用户开放平台共享DCloud的开发者资源。

插件授权使用步骤:

  1. 三方开发商需要在DCloud用户开放平台注册插件应用
  2. 开发HBuilderX插件,调用 hx.authorize.login API,拿到code码。文档详见:https://hx.dcloud.net.cn/ExtensionDocs/Api/README?id=authorize
  3. 插件将code码传到三方开发商服务器,从服务器端向 DCloud用户开放平台 的服务器请求,获取用户信息。文档具体见下。

WEB授权使用步骤:
1.第三方网站需要在DCloud用户开放平台注册授权WEB

  1. 在自己网站拼接url登录链接
  2. 用户登录完成后DCloud会携带code回跳到对应的第三方网址
  3. 第三方网站根据code在服务器端 DCloud用户开放平台 的服务器请求,获取用户信息 文档具体见下。

这套授权体系是国际标准的 OAuth2.0 授权机制。什么是OAuth2.0?
在用户授权的情况下,得到用于换取用户信息的令牌(code码)。拿到用户的授权令牌后,开发者在服务端通过接口换取accessToken,通过accessToken换取用户授权的基本信息。

OAuth2.0 授权登录流程

接入准备

DCloud用户开放平台创建授权,拿到client_id、client_secret

插件授权接入步骤

DCloud用户开放平台创建插件授权时,需要填写插件id。重点解释下这个概念。

HBuilderX的所有插件,发布时均需发布到DCloud插件市场,地址:https://ext.dcloud.net.cn/。HBuilderX用户从插件市场获取插件来使用。

插件市场的每个插件都有一个唯一的插件id,该id由插件作者上传插件时自行输入,提交插件时会进行验重,与其他插件的id不冲突即可使用。

目前创建授权是免审的,可以直接获取到client_id和client_secret。

插件接入流程图

接入流程

1. 通过HX提供的hx.authorize.login()方法获取code HX登录授权api接口
2. 开发者服务商获取到code后在自己服务器端去获取accessToken
3. 通过接口获取accessToken
请求过程建议将 参数 放在 Body 中传值,以保证数据安全。

开发者服务商从自己的服务器端发送请求到DCloud的服务器,地址如下:
https://account.dcloud.net.cn/dcloudOauthv2/accessToken?code={code}&client_id={client_id}&app_secret={app_secret}
请求方式
POST
返回json数据格式

{  
    "ret": 0,   // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "f06e27a0-1e85-11eb-bc60-8fdcccfc955b",     // access_token  
        "access_token_ttl": "2020-12-04 18:10:17",                  // access_token过期时间  
        "refresh_token": "30895c20-1e80-11eb-9c0e-ef6813716901",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 17:29:08"                  // refresh_token过期时间  
    }  
}
4. 通过accessToken获取用户信息

地址
https://account.dcloud.net.cn/dcloudOauthv2/userInfo?access_token={access_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "nickname": "phil123",      // 用户昵称  
        "avatar": "",               // 用户头像地址  
        "uid": "e4541ee0-dada-11ea-a0b7-3f6acaa2391b",  // 用户uid  
        "email": "",        // 用户邮箱 如果用户授权了  
    "phone": "",        // 用户手机号码 如果用户授权了  
    }  
}
accessToken过期后可以通过refreshToken进行获取新的access_token

地址
https://account.dcloud.net.cn/dcloudOauthv2/accessTokenByRefreshToken?refresh_token={refresh_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "88e3b460-1e95-11eb-b2c2-b30587156981",     // access_token  
        "access_token_ttl": "2020-12-04 20:01:56",                  // access_token过期时间  
        "refresh_token": "28c86600-1e87-11eb-b70f-ef63535e6ee0",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 18:19:01"                  // refresh_token过期时间  
    }  
}

WEB授权接入步骤

在DCloud用户开放平台创建WEB授权时,需要填写域名。拿到client_id、client_secret

WEB授权接入流程图

点击体验WEB授权示例

接入流程

1. 拼接DCloud登录授权url链接地址

https://account.dcloud.net.cn/oauth2/webAuthorize?client_id={client_id}&redirect_uri={redirect}&response_type=code
用户登录授权完成后会回跳到redirect并在url参数内携带code参数
注意:
redirect需要进行encodeURIComponent转码
redirect的主域名需要和在开放平台式申请时填写的域名保持一致

2. 开发者服务商获取到code后在自己服务器端去获取accessToken
3. 通过接口获取accessToken
请求过程建议将 参数 放在 Body 中传值,以保证数据安全。

开发者服务商从自己的服务器端发送请求到DCloud的服务器,地址如下:
https://account.dcloud.net.cn/dcloudOauthv2/accessToken?code={code}&client_id={client_id}&client_secret={client_secret}
请求方式
POST
返回json数据格式

{  
    "ret": 0,   // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "f06e27a0-1e85-11eb-bc60-8fdcccfc955b",     // access_token  
        "access_token_ttl": "2020-12-04 18:10:17",                  // access_token过期时间  
        "refresh_token": "30895c20-1e80-11eb-9c0e-ef6813716901",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 17:29:08"                  // refresh_token过期时间  
    }  
}
4. 通过accessToken获取用户信息

地址
https://account.dcloud.net.cn/dcloudOauthv2/userInfo?access_token={access_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "nickname": "phil123",      // 用户昵称  
        "avatar": "",               // 用户头像地址  
        "uid": "e4541ee0-dada-11ea-a0b7-3f6acaa2391b",  // 用户uid  
        "email": "",        // 用户邮箱 如果用户授权了  
    "phone": "",        // 用户手机号码 如果用户授权了  
    }  
}
accessToken过期后可以通过refreshToken进行获取新的access_token

地址
https://account.dcloud.net.cn/dcloudOauthv2/accessTokenByRefreshToken?refresh_token={refresh_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "88e3b460-1e95-11eb-b2c2-b30587156981",     // access_token  
        "access_token_ttl": "2020-12-04 20:01:56",                  // access_token过期时间  
        "refresh_token": "28c86600-1e87-11eb-b70f-ef63535e6ee0",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 18:19:01"                  // refresh_token过期时间  
    }  
}

案例

csdn开发了HBuilderX插件,无需额外注册csdn账户,即可在HBuilderX中一键上传项目到gitcode代码托管平台。
详见:https://ext.dcloud.net.cn/plugin?id=4882

HBuilderX中也预置了该插件的入口:

同时,csdn的官网也支持了HBuilder登录,开发者可以使用DCloud的账户直接登录csdn。

继续阅读 »

简介

DCloud用户开放平台,https://open.dcloud.net.cn,是DCloud为三方开发者服务商提供的开放平台。

DCloud将数百万开发者的流量通过开放平台提供给三方开发者服务商。

使用场景:

1.三方的开发者服务商,比如Git服务商,可以制作HBuilderX插件,并且将账户打通。比如在HBuilderX插件中注册项目的右键菜单,在HBuilderX中对项目点右键,一键上传源码到某Git服务商,且无需再重复注册三方Git服务账户。
2.第三方网站,可以申请web授权给自己网站,用户无需在网站注册,直接可以跳转到DCloud登录授权页面进行登录后回跳到网站进行登录。

当然不止是Git服务商、网站,所有其他开发者服务商,如测试、加固、多渠道发布、招聘...,均可通过DCloud用户开放平台共享DCloud的开发者资源。

插件授权使用步骤:

  1. 三方开发商需要在DCloud用户开放平台注册插件应用
  2. 开发HBuilderX插件,调用 hx.authorize.login API,拿到code码。文档详见:https://hx.dcloud.net.cn/ExtensionDocs/Api/README?id=authorize
  3. 插件将code码传到三方开发商服务器,从服务器端向 DCloud用户开放平台 的服务器请求,获取用户信息。文档具体见下。

WEB授权使用步骤:
1.第三方网站需要在DCloud用户开放平台注册授权WEB

  1. 在自己网站拼接url登录链接
  2. 用户登录完成后DCloud会携带code回跳到对应的第三方网址
  3. 第三方网站根据code在服务器端 DCloud用户开放平台 的服务器请求,获取用户信息 文档具体见下。

这套授权体系是国际标准的 OAuth2.0 授权机制。什么是OAuth2.0?
在用户授权的情况下,得到用于换取用户信息的令牌(code码)。拿到用户的授权令牌后,开发者在服务端通过接口换取accessToken,通过accessToken换取用户授权的基本信息。

OAuth2.0 授权登录流程

接入准备

DCloud用户开放平台创建授权,拿到client_id、client_secret

插件授权接入步骤

DCloud用户开放平台创建插件授权时,需要填写插件id。重点解释下这个概念。

HBuilderX的所有插件,发布时均需发布到DCloud插件市场,地址:https://ext.dcloud.net.cn/。HBuilderX用户从插件市场获取插件来使用。

插件市场的每个插件都有一个唯一的插件id,该id由插件作者上传插件时自行输入,提交插件时会进行验重,与其他插件的id不冲突即可使用。

目前创建授权是免审的,可以直接获取到client_id和client_secret。

插件接入流程图

接入流程

1. 通过HX提供的hx.authorize.login()方法获取code HX登录授权api接口
2. 开发者服务商获取到code后在自己服务器端去获取accessToken
3. 通过接口获取accessToken
请求过程建议将 参数 放在 Body 中传值,以保证数据安全。

开发者服务商从自己的服务器端发送请求到DCloud的服务器,地址如下:
https://account.dcloud.net.cn/dcloudOauthv2/accessToken?code={code}&client_id={client_id}&app_secret={app_secret}
请求方式
POST
返回json数据格式

{  
    "ret": 0,   // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "f06e27a0-1e85-11eb-bc60-8fdcccfc955b",     // access_token  
        "access_token_ttl": "2020-12-04 18:10:17",                  // access_token过期时间  
        "refresh_token": "30895c20-1e80-11eb-9c0e-ef6813716901",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 17:29:08"                  // refresh_token过期时间  
    }  
}
4. 通过accessToken获取用户信息

地址
https://account.dcloud.net.cn/dcloudOauthv2/userInfo?access_token={access_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "nickname": "phil123",      // 用户昵称  
        "avatar": "",               // 用户头像地址  
        "uid": "e4541ee0-dada-11ea-a0b7-3f6acaa2391b",  // 用户uid  
        "email": "",        // 用户邮箱 如果用户授权了  
    "phone": "",        // 用户手机号码 如果用户授权了  
    }  
}
accessToken过期后可以通过refreshToken进行获取新的access_token

地址
https://account.dcloud.net.cn/dcloudOauthv2/accessTokenByRefreshToken?refresh_token={refresh_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "88e3b460-1e95-11eb-b2c2-b30587156981",     // access_token  
        "access_token_ttl": "2020-12-04 20:01:56",                  // access_token过期时间  
        "refresh_token": "28c86600-1e87-11eb-b70f-ef63535e6ee0",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 18:19:01"                  // refresh_token过期时间  
    }  
}

WEB授权接入步骤

在DCloud用户开放平台创建WEB授权时,需要填写域名。拿到client_id、client_secret

WEB授权接入流程图

点击体验WEB授权示例

接入流程

1. 拼接DCloud登录授权url链接地址

https://account.dcloud.net.cn/oauth2/webAuthorize?client_id={client_id}&redirect_uri={redirect}&response_type=code
用户登录授权完成后会回跳到redirect并在url参数内携带code参数
注意:
redirect需要进行encodeURIComponent转码
redirect的主域名需要和在开放平台式申请时填写的域名保持一致

2. 开发者服务商获取到code后在自己服务器端去获取accessToken
3. 通过接口获取accessToken
请求过程建议将 参数 放在 Body 中传值,以保证数据安全。

开发者服务商从自己的服务器端发送请求到DCloud的服务器,地址如下:
https://account.dcloud.net.cn/dcloudOauthv2/accessToken?code={code}&client_id={client_id}&client_secret={client_secret}
请求方式
POST
返回json数据格式

{  
    "ret": 0,   // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "f06e27a0-1e85-11eb-bc60-8fdcccfc955b",     // access_token  
        "access_token_ttl": "2020-12-04 18:10:17",                  // access_token过期时间  
        "refresh_token": "30895c20-1e80-11eb-9c0e-ef6813716901",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 17:29:08"                  // refresh_token过期时间  
    }  
}
4. 通过accessToken获取用户信息

地址
https://account.dcloud.net.cn/dcloudOauthv2/userInfo?access_token={access_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "nickname": "phil123",      // 用户昵称  
        "avatar": "",               // 用户头像地址  
        "uid": "e4541ee0-dada-11ea-a0b7-3f6acaa2391b",  // 用户uid  
        "email": "",        // 用户邮箱 如果用户授权了  
    "phone": "",        // 用户手机号码 如果用户授权了  
    }  
}
accessToken过期后可以通过refreshToken进行获取新的access_token

地址
https://account.dcloud.net.cn/dcloudOauthv2/accessTokenByRefreshToken?refresh_token={refresh_token}
请求方式
POST
返回json数据格式

{  
    "ret": 0,       // 状态码 非0为错误码  
    "desc": "success",  // 描述  
    "data": {  
        "access_token": "88e3b460-1e95-11eb-b2c2-b30587156981",     // access_token  
        "access_token_ttl": "2020-12-04 20:01:56",                  // access_token过期时间  
        "refresh_token": "28c86600-1e87-11eb-b70f-ef63535e6ee0",    // refresh_token  
        "refresh_token_ttl": "2021-11-04 18:19:01"                  // refresh_token过期时间  
    }  
}

案例

csdn开发了HBuilderX插件,无需额外注册csdn账户,即可在HBuilderX中一键上传项目到gitcode代码托管平台。
详见:https://ext.dcloud.net.cn/plugin?id=4882

HBuilderX中也预置了该插件的入口:

同时,csdn的官网也支持了HBuilder登录,开发者可以使用DCloud的账户直接登录csdn。

收起阅读 »

贵阳创业公司诚聘前端开发工程师

招聘

薪资:4K-6K
要求:
一年及以上实际工作经验
精通JS、CSS
独立根据用户需求进行应用设计并实现,完美实现UI设计稿
熟练运用各类主流框架
有使用Vue或uniapp开发和应用上线经验
有意者欢迎联系QQ:2455212990或电话:13123616566

继续阅读 »

薪资:4K-6K
要求:
一年及以上实际工作经验
精通JS、CSS
独立根据用户需求进行应用设计并实现,完美实现UI设计稿
熟练运用各类主流框架
有使用Vue或uniapp开发和应用上线经验
有意者欢迎联系QQ:2455212990或电话:13123616566

收起阅读 »

应用程序开发模式的具体区别是什么?

混合开发 小程序

如今移动互联网发展迅速,大家都在用智能手机,所以很多企业都在开发自己的app产品,我们经常用的微信、支付宝、微博、抖音等都是app产品,虽然很多人说开发app的作用不大,但还是有很多新的app产品出现,所以不是说app不受欢迎,而是之前很多app营销运营模式发生了变化,所以app所扮演的角色仍然很重要。

有哪些应用程序开发的模式呢?第一,本地开发,本地开发是基于安卓和ios平台的官方开发语言开发的,比如我们常用的java语言,c语言等等,大多数智能手机上安装的app都是本地app,需要用户自己下载,本地app有很多优点,比如运行速度快,功能多,用户体验好,功能还可以扩展,缺点就是成本比较高,后期版本更新需要用户更新。
还有一种应用程序开发的方式是使用web语言开发的,通过移动设备上面的浏览器来访问和使用,web开发的app费用较低,并且可以在线使用,另外支持许多移动设备,但也有许多缺点,比如打开速度慢,因为是基于浏览器访问的,还有一点就是功能很少,可以说没有公众号和小程序实用,还有就是很难在手机上调用某些功能,所以如果想要更实用的话,建议不要开发webapp。
另外一种app开发方式也是有用户使用的,即混合app开发,简单地说就是把原生app和H5两种开发技术结合在一起开发的app,具体的比例可以根据难易程度而定,没有标准的比例,混合开发的app优点是与许多平台兼容,比web端的app实现更多的功能,还有一个优势就是可以离线使用,缺点是目前的app开发技术还不够成熟,性能不如原生app,所以如果想要开发更好的app应用,还是应该考虑原生app开发。
本文来源:标梵互动

继续阅读 »

如今移动互联网发展迅速,大家都在用智能手机,所以很多企业都在开发自己的app产品,我们经常用的微信、支付宝、微博、抖音等都是app产品,虽然很多人说开发app的作用不大,但还是有很多新的app产品出现,所以不是说app不受欢迎,而是之前很多app营销运营模式发生了变化,所以app所扮演的角色仍然很重要。

有哪些应用程序开发的模式呢?第一,本地开发,本地开发是基于安卓和ios平台的官方开发语言开发的,比如我们常用的java语言,c语言等等,大多数智能手机上安装的app都是本地app,需要用户自己下载,本地app有很多优点,比如运行速度快,功能多,用户体验好,功能还可以扩展,缺点就是成本比较高,后期版本更新需要用户更新。
还有一种应用程序开发的方式是使用web语言开发的,通过移动设备上面的浏览器来访问和使用,web开发的app费用较低,并且可以在线使用,另外支持许多移动设备,但也有许多缺点,比如打开速度慢,因为是基于浏览器访问的,还有一点就是功能很少,可以说没有公众号和小程序实用,还有就是很难在手机上调用某些功能,所以如果想要更实用的话,建议不要开发webapp。
另外一种app开发方式也是有用户使用的,即混合app开发,简单地说就是把原生app和H5两种开发技术结合在一起开发的app,具体的比例可以根据难易程度而定,没有标准的比例,混合开发的app优点是与许多平台兼容,比web端的app实现更多的功能,还有一个优势就是可以离线使用,缺点是目前的app开发技术还不够成熟,性能不如原生app,所以如果想要开发更好的app应用,还是应该考虑原生app开发。
本文来源:标梵互动

收起阅读 »