文章

钉钉H5微应用

钉钉H5微应用

钉钉H5微应用

钉钉H5微应用

应用类型

应用类型开发者使用人员支持的能力是否支持上架到钉钉应用广场
企业内部应用企业内部开发者或委托的服务商开发者安装了该应用的企业内部人员+ 小程序
+ H5微应用
+ 机器人
第三方企业应用产品方案商的开发者购买开通该三方应用的企业内部人员+ 小程序
+ H5微应用
是,需要满足上架要求,上架流程请参考应用上架全流程指引
第三方个人应用产品方案商的开发者钉钉的个人用户+ 小程序
移动应用接入产品方案商的开发者
企业内部开发者
要接入的应用的用户+ 登录(钉钉扫码和使用钉钉账号登录)
+ 分享(将应用分享到钉钉)

成为钉钉开发者

组织管理员登录OA管理后台给开发者添加开发者权限。

能力介绍

  • 账号授权(免登)

支持扫码登录和使用钉钉账号登录。

  • 分享SDK

开发者可以使用钉钉的分享SDK接入钉钉分享功能。用户在分享应用时可以选择分享到钉钉。

  • 机器人

群机器人是钉钉群的高级扩展功能。群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步。

  • 小程序

让移动开发者通过简洁的前端语法写出Native级别的性能体验,并支持多端部署。

  • H5微应用

微应用是指用H5方式开发的应用。

基础概念

CorpId

CorpId 是企业在钉钉中的标识,每个企业拥有唯一的 CorpId

UserId

企业内每个员工都有唯一的 UserId,创建后不可修改。

AppKey/AppSecret

AppKey企业内部应用的唯一身份标识,AppSecret 是对应的调用密钥。

钉钉开发者后台创建企业内部应用后,系统会自动生成一对 ****AppKey****AppSecret**。**


access_token

access_token 是企业后台通过钉钉接口获取信息的重要凭据。在调用钉钉接口时必须携带 access_token 用于验证接口的访问权限。

默认access_token的有效期为7200秒(两小时),有效期内重复获取,会返回相同的access_token,并自动续期。

开发须知

  • 无论是哪种应用,都必须接入钉钉免登,即在用户打开应用时可直接获取用户身份无需输入钉钉账号和密码。

  • H5微应用,部分API需要进行JSAPI鉴权(下面有介绍)。

企业内部应用开发流程

1637120174957-c599767d-410a-43d3-828b-9c4bb8a3d234.png

开发者后台:要注意开发管理目录未配置PC端地址

H5微应用开发

概述

H5微应用JSAPI为应用提供了调用原生控件的能力,帮助开发者高效使用拍照、定位等手机系统的能力,同时可以直接使用扫一扫、分享、钉盘等钉钉特有的能力,带给微应用接近原生代码的体验。

准备工作

  1. 使用npm安装。
1
2
npm install dingtalk-jsapi --save
import * as dd from 'dingtalk-jsapi'; 
  1. 浏览器引入。在浏览器中使用 script 和 link 标签直接引入文件,并使用全局变量 dd。**
1
<script src="https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js"></script>

JSAPI鉴权

钉钉提供的JSAPI有很多是手机的基础能力,对这些JSAPI的调用不需要进行鉴权(即不需要进行dd.config),只需要保证在dd.ready里面调用即可。对于一些钉钉业务相关、安全相关的JSAPI的调用,需要开发者先进行鉴权然后再调用。\

调用JSAPI组件

所有JSAPI组件的调用,必须在 **dd.ready**** **里面执行。

免鉴权

手机的基础能力(弹窗提示、设置导航栏等),对这些JSAPI的调用不需要进行鉴权,直接在dd.ready 里调用

1
2
3
4
5
6
7
8
9
10
11
12
13
dd.ready(function() {
    // dd.ready参数为回调函数,在环境准备就绪时触发,jsapi的调用需要保证在该回调函数触发后调用,否则无效。
    dd.runtime.permission.requestAuthCode({
        corpId: "corpid",
        onSuccess: function(result) {
        /*{
            code: 'hYLK98jkf0m' //string authCode
        }*/
        },
        onFail : function(err) {}
  
    });
});

需鉴权

对于一些钉钉业务、安全相关(如:定位、支付)的JSAPI的调用,需要先鉴权,然后再调用。

**dd.config **中所有的参数必须直接来自服务端,不能直接在前端定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
dd.config({
    agentId: '', // 必填,微应用ID
    corpId: '',//必填,企业ID
    timeStamp: '', // 必填,生成签名的时间戳
    nonceStr: '', // 必填,自定义固定字符串。
    signature: '', // 必填,签名
    type:0/1,   //选填。0表示微应用的jsapi,1表示服务窗的jsapi;不填默认为0。该参数从dingtalk.js的0.8.3版本开始支持
    jsApiList : [
        'runtime.info',
        'biz.contact.choose',
        'device.notification.confirm',
        'device.notification.alert',
        'device.notification.prompt',
        'biz.ding.post',
        'biz.util.openLink',
    ] // 必填,需要使用的jsapi列表,注意:不要带dd。
});

dd.error(function (err) {
    alert('dd error: ' + JSON.stringify(err));
})//该方法必须带上,用来捕获鉴权出现的异常信息,否则不方便排查出现的问题

鉴权后就可以在dd.ready里调用JSAPI了。

接入免登获取用户信息(企业内部应用)

  1. 获取免登授权码 - H5微应用免登
1
2
3
4
5
6
7
dd.ready(function() {
  dd.runtime.permission.requestAuthCode({
    corpId: "ding12345xxx", // 企业id
    onSuccess: function (info) {
      code = info.code // 通过该免登授权码可以获取用户身份
    }});
});

获取的免登授权码有效期5分钟,且只能使用一次。

  1. 获取access_token。调用接口获取access_token,详情请参考获取企业内部应用的access_token
  2. 获取用户userid。调用接口获取用户的userid,详情请参考通过免登码获取用户信息
  3. 获取用户详情。调用接口获取用户详情信息,详情请参考获取用户详情

注意:服务端API在调用前,确保已经为应用添加了接口权限!

JSAPI参考

TIPS

  • rem 布局

设计稿宽 750px,即 1rem=100px。

1
2
3
html {
  font-size: calc(100vw / 750 * 100);
}
  • 钉钉 JSAPI支持自定义头部导航栏(颜色、自定义按钮等)

  • iPhoneX等机型底部留白


H5页面高度设置 height:100vh,页面会产生滚动条。设置 height:100%,iPhoneX等机型下面会留白。

meta标签新增扩展:**viewport-fit=cover**

1
<meta name="viewport" content="width=device-width,initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">

viewport-fit 设置可视视窗的大小,它有三个属性值:

  • Auto:默认值,与Contain表现一致。
  • Contain:可视窗口完全包含网页内容(左图)。
  • Cover:网页内容完全覆盖可视窗口(右图)。

1638167975473-e5c25e7e-f617-42b5-b4b6-3cd5113213f0.webp

  • IOS 页面默认会有弹性效果,为和钉钉系统保持一致,可禁用iOS Webview弹性效果
1
dd.ui.webViewBounce.disable()
  • 原生 fetch 图片上传(当时所有安卓无法上传是代码错误造成)

不要手动设置 headersContent-Type,手动设置 multipart/form-data , 但是少了浏览器自动生成的**boundary**** **参数,缺失也无法解析。

**boundary**** 的重要性:**

在rfc1867协议中规定,我们在指定content-type为multipart/form-data时,表明我们需要传递的是多媒体内容,我们需要指定boundary【分隔符】来分割当上传多个文件/图片。boundary是随机生成的数字和字母的组合。

按照上面的写法可以看出,Request Header里面的content-type中只是设置了multipart/form-data,而没有随机生成的boundary值。

1637827638987-9c74772a-16d2-4d3f-ab33-2e4329886568.png

本文由作者按照 CC BY 4.0 进行授权