文章目录
钉钉端开发小程序/微应用,实现钉钉与LCP平台的深度集成
当前存在两套钉钉环境
环境名称 | 适用范围 | 描述 | 备注 |
---|---|---|---|
风神测试 | DEV/SIT | 包含全套组织架构,包含信息技术部员工,少量其它部门参与测试的员工 | 可将公司员工手机号作替换,实现无工号人员正常使用本环境 |
风神物流 | UAT/PROD | 包含全套组织架构,包含公司所有员工,外部员工 |
钉钉开放平台支持小程序和H5微应用两种类型的应用开发。
对比项 | 小程序 | 微应用 |
---|---|---|
加载性能 | 首次使用略慢,后续加载快 | 受到很多因素影响,优化不够好,容易慢 |
使用体验 | 非常顺滑,接近 Native | 容易卡顿 |
页面跳转,返回 | 和 Native 的效果一样 | 做不到和 Native 一样的体验 |
开发环境搭建 | 提供 IDE,快速创建项目 | 成本高 |
调试 | 提供 IDE,可以在电脑上调试大部分功能 | 在电脑上只能调 UI,涉及到钉钉的 jsapi,必须真机调试 |
使用开源 UI 组件 | 目前不支持 | 支持 |
使用 npm 包 | 支持 | 支持 |
模块化组织代码 | 支持 小程序 特有的模块化 | 使用 vue, React 等框架可以轻松获得模块化支持 |
灰度发布 | 钉钉提供 | 需要自己实现 |
CDN | 小程序包默认在CDN | 需要开发者自己购买相关服务 |
开发个人应用 | 支持 | 不支持 |
应用离线化 | 支持 | 不支持 |
当前存在两套编程模式
名称 | 运行环境 | 用途 | 调用方式 |
---|---|---|---|
前端API | 钉钉客户端 | 从客户端发出对钉钉服务器的各类请求,构建客户端界面,调用设备API | 小程序API,在钉钉iOS客户端、Android客户端均可正常使 \ H5微应用API,使用script标签引入JSAPI,不同的方法有不同的使用范围(Android,IOS,PC) |
服务端API | 后台环境 | 从服务端后台发出对钉钉服务器的各类请求,同步应用数据,实现后台管理等 | 支持Java,PHP,.Net,Python后台运行环境。 |
前端API
容器 | 弹窗 | 摇一摇 | 设备 | 日期&月历 |
导航栏 | UI控件 | 获取免登授权码 | 扫码 | 存储 |
地图 | 业务 | 文件 | 图片 | 打开新页面 |
电话 | 发钉 | 通讯录选人 | 外部联系人 | 自定义联系人 |
会话 | 钉盘 | 音频接口 | 支付 | 数据加解密 |
旋转屏幕 | 统一跳转协议 | 页面事件监听 |
后台API
身份验证 | 通讯录管理 | 消息通知 | 智能工作流 | 考勤 |
智能人事 | 日志 | Ding日程 | 签到 | 公告 |
钉钉运动 | 应用管理 | 群机器人 | 文件存储 | 业务事件回调 |
在每个人的钉钉工作台,显示 风神工作台
应用图标
进入钉钉工作台管理后台,创建微应用。选择企业内部自主开发,开发模式选择开发应用,开发应用类型选择微应用,录入名称与Logo,应用首页链接输入移动端待办面板页面链接,PC端首页地址输入PC端统一门户页面,最后录入服务器出口IP,之后发布至所有用户即可。
默认情况下,新加入的应用显示在钉钉工作台最下端。管理员可通过移动端管理工作台功能,调整显示分组与顺序。
属性 | 描述 |
---|---|
应用名称 | 应用的名字 |
应用类型 | 开发应用-微应用:微应用开发类型 \ 开发应用-小程序:小程序开发类型 \ 快捷链接:仅作地址跳转 |
应用logo | 应用的图标 |
应用简介 | 应用的简单描述 |
应用首页地址 | 用户在手机端钉钉工作台上打开这个应用并显示该链接内容。 |
PC端管理地址 | 用户在PC版钉钉工作台上打开这个应用并显示该链接内容。 |
可使用范围 | 能够使用本应用的员工范围 |
AgentId | 在创建应用时,系统会自动生成一个AgentId,可用于发送企业会话消息等场景。 |
服务器出口IP | 为支撑前端应用而布署的服务器授予访问权限 |
AppKey | 在创建应用时,系统会自动分配一对AppKey和AppSecret,该AppKey是应用开发过程中的唯一性标识。 |
AppSecret | AppSecret和上面AppKey一同生成,使用AppKey和AppSecret来换取access_token。 |
不同环境,出口IP与各页面地址配置如下。内网需要同步作Nginx配置,将外网域名请求转发到正确的内网服务器端口上
环境 | 出口IP | 应用首页链接 | PC端首页地址 |
---|---|---|---|
DEV | 219.135.191.*,218.107.3.* | https://dingtest.fslgz.com/自定义路径 | https://dingtest.fslgz.com/自定义路径 |
SIT | 219.135.191.*,218.107.3.* | https://dingtest.fslgz.com/portal/activiti/system_task_collect.html | https://dingtest.fslgz.com/portal/ |
UAT | 58.248.166.*,14.23.175.* | https://app-uat.fslgz.com/portal/activiti/system_task_collect.html | https://app-uat.fslgz.com/portal/ |
PROD | 58.248.166.*,14.23.175.* | https://app.fslgz.com/portal/activiti/system_task_collect.html | https://app.fslgz.com/portal/ |
后台服务端向钉钉服务器请求数据的接口权限
名称 | 描述 | 默认状态 |
---|---|---|
基础权限 | ||
身份验证 | 获取员工的基本信息,用于登录系统/应用 | 是 |
消息通知 | 获取企业的消息通道给企业及员工发送消息 | 是 |
高级权限-企业通讯录 | ||
通讯录只读权限 | 获取企业员工通讯录数据的权限 | 无 |
通讯录编辑权限 | 获取企业员工通讯录数据、新增、删除、修改企业通讯录的权限 | 无 |
手机号码信息 | 获取授权范围内的成员手机号码信息 | 无 |
邮箱等个人信息 | 获取授权范围内的成员信息(如邮箱、工作地点、扩展字段等) | 无 |
未登录员工列表 | 企业使用此接口可查询指定日期内未登录钉钉的企业员工列表 | 无 |
手机号获取userid | 通过手机号获取其所对应员工的userid | 无 |
高级权限-微应用 | ||
钉盘 | 获取钉盘文件的存储、删除、更新的权限 | 无 |
签到 | 获取企业员工签到数据的权限 | 无 |
考勤 | 获取企业员工考勤数据的权限 | 无 |
审批 | 获取企业人员审批数据、发起审批的权限 | 无 |
日志 | 获取企业员工日志数据的权限 | 无 |
公告 | 获取企业员工公告数据的权限 | 无 |
钉钉运动 | 获取企业员工运动数据的权限 | 无 |
智能人事 | 获取企业员工智能人事数据的权限 | 无 |
企业会话 | 获取、管理企业会话数据的权限 | 无 |
DING日程 | 管理钉钉日程数据权限 | 无 |
发布后,该应用将会出现在钉钉的工作台上,企业组织内部的用户将会看到该应用。
名称 | 描述 |
---|---|
全部员工 | 组织内所有员工都可使用 |
部份员工 | 选定范围内的员工才能使用,可按部门或人员选择 |
仅限管理员 | 仅管理员才能使用 |
将钉钉SDK集成至本平台,简化钉钉对接难度
# 消息通知相关,当前系统的路径
sys.webroot.url=https://dingtest.fslgz.com/portal
# 钉钉配置
dingtalk.corp.id=ding6b6ffebcd75ef63335c2f4657eb6378f
dingtalk.app.key=dinggkwxz61kgu7vvw8a
dingtalk.app.secret=VnA-wL-bqviMkIsw_Qn81TqH-Q7fqzCchOglmBjplbjeBZvdzH5MZ8e66vDNefo-
dingtalk.default.agentid=280426666
当项目不作修改时,平台内置的默认参数来源如下
环境名称 | 应用名称 |
---|---|
DEV | 风神工作台SIT |
SIT | 风神工作台SIT |
UAT | 风神工作台UAT |
PROD | 风神工作台 |
com.fsl.lcp.dingding.service.IDingDingService:提供调用钉钉服务的服务端接口
方法 | 参数 | 说明 |
---|---|---|
身份方法 | ||
String getAccessToken() | 无 | 获取access_token,默认过期时间为6900秒。一般情况下,使用者不需使用此方法。LCP钉钉接口所有方法均实现了access_token的自动刷新 |
String getJsTicket() | 无 | 获取js_ticket,默认过期时间为6900秒。一般情况下,使用者不需使用此方法。LCP钉钉接口所有方法均实现了js_ticket的自动刷新 |
JsApiSignatureVo getJsApiSignature(JsApiSignatureVo apiSignatureVo) | JsApiSignatureVo:签名参数。包含 | 使用票据,随机字符串,时间戳,页面地址生成本页面唯一的签名,并返回本次使用的企业Id,应用Id,随机字符串,时间戳,页面地址,签名 |
阿里服务调用 | ||
T execute(String serviceUrl, TaobaoRequest request) | serviceUrl:服务地址 \ request:请求参数 | 调用钉钉接口获取返回值。有四个方法重载 |
消息推送 | ||
OapiMessageCorpconversationAsyncsendV2Response sendWorkMsg(NotifyMessageRecord messageRecord) | messageRecord:钉钉消息 | 发送钉钉工作通知,如果messageRecord对象eUrl为空,则发送markdown消息,否则为卡片消息 |
void sendWorkMsgAsync(NotifyMessageRecord messageRecord) | messageRecord:钉钉消息 | 异步发送钉钉工作通知 |
ResponseData recallTodoAndCopyNotify(Long agentId, Long notifyTaskId) | agentId:应用Id \ notifyTaskId:钉钉工作通知Id | 撤回工作通知消息. |
void sendWebHookMsg(NotifyMessageRecord messageRecord) | messageRecord:钉钉消息 | 发送钉钉webHook消息(群机器人消息) |
void sendWebHookMsgAsync(NotifyMessageRecord messageRecord) | messageRecord:钉钉消息 | 用异步,多线程方式发送钉钉webHook消息(群机器人消息) |
工作流调度 | ||
String createProcessTemplate(Long agentId) | agentId:应用ID | 创建钉钉智能工作流模板 |
ResponseData createProcessInstance(DdProcessInst processInst, boolean saveData) | processInst:钉钉流程实例 \ saveData:是否保存钉钉流程数据 | 创建钉钉智能工作流实例 |
ResponseData updateProcessInstance(DdProcessInst processInst, boolean saveData) | processInst:钉钉流程实例 \ saveData:是否保存钉钉流程数据 | 更新钉钉智能工作流实例 |
ResponseData createProcessTask(DdProcessTask processTask, boolean saveData) | processTask:钉钉任务实例 \ saveData:是否保存钉钉任务数据 | 创建钉钉工作流待办任务. |
ResponseData updateProcessTask(DdProcessTask processTask, boolean saveData) | processTask:钉钉任务实例 \ saveData:是否保存钉钉任务数据 | 更新钉钉工作流待办任务. |
void updateProcessCopyTask(DdProcessTask processTask, boolean saveData) | processTask:钉钉任务实例 \ saveData:是否保存钉钉任务数据 | 更新钉钉工作流抄送类型的待办任务. |
OapiProcessWorkrecordTaskQueryResponse.PageResult queryDdProcessTaskList(String employeeCode, Long offset, Long count, Long status) | employeeCode:工号 \ offset:页码 \ count:每页数量 \ status:待办类型。0表示待处理,-1表示已经移除 | 查询钉钉工作流待办任务列表 |
void recallTodoAndNotify(String employeeCode, String taskId) | employeeCode:工号 \ taskId:钉钉任务实例Id | 撤回当前用户和taskId匹配的数据的待办通知消息和钉钉待办列表 |
void recallCopyAndNotify(String employeeCode, String processInstanceId) | employeeCode:工号 \ processInstanceId:钉钉流程实例Id | 撤回当前用户和taskId匹配的数据的待办通知消息和钉钉待办列表. |
信息查询 | ||
OapiUserGetResponse queryUserInfo(String userId) | userId:钉钉 user_id | 基于钉钉 user_id查询钉钉用户信息 |
List queryAllDdDeptRelation() | 查询所有钉钉部门关联信息 | |
List queryDdDeptRelationList(DdDeptRelation ddDeptRelation, int page, int pageSize) | ddDeptRelation:钉钉部门关联表查询条件 \ page:当前页数 \ pageSize:每页行数 | 分页查询钉钉部门关联信息 |
DdDeptRelation queryDdDeptRelation(DdDeptRelation ddDeptRelation) | ddDeptRelation:钉钉部门关联表查询条件 | 查询单个钉钉部门关联信息 |
List getFunctionByEmployeeCode(String empCode, String eid) | empCode:员工编码 \ eid:功能模块编码 | 基于模块编码与员工编码查询功能清单 |
com.fsl.lcp.dingding.constant.UrlConstant:封装常用的钉钉服务地址信息
接口名称 | 接口 | 地址 |
---|---|---|
获取access_token | GET_TOKEN | https://oapi.dingtalk.com/gettoken |
获取用户详情(GET) | USER_GET | https://oapi.dingtalk.com/user/get |
通过免登授权码和 access_token 获取用户的 userid(GET) | USER_GET_USERINFO | https://oapi.dingtalk.com/user/getuserinfo |
获取部门用户userid列表(GET) | USER_GET_DEPT_MEMBER | https://oapi.dingtalk.com/user/getDeptMember |
获取部门用户(GET) | USER_SIMPLE_LIST | https://oapi.dingtalk.com/user/simplelist |
获取部门用户详情(GET) | USER_LIST_BY_PAGE | https://oapi.dingtalk.com/user/listbypage |
获取管理员列表(GET) | USER_GET_ADMIN | https://oapi.dingtalk.com/user/get_admin |
获取管理员通讯录权限范围(GET) | USER_GET_ADMIN_SCOPE | https://oapi.dingtalk.com/topapi/user/get_admin_scope |
根据unionid获取userid(GET) | USER_GET_BY_UNIONID | https://oapi.dingtalk.com/user/getUseridByUnionid |
创建用户(POST) | USER_CREATE | https://oapi.dingtalk.com/user/create |
更新用户(POST) | USER_UPDATE | https://oapi.dingtalk.com/user/update |
删除用户(GET) | USER_DELETE | https://oapi.dingtalk.com/user/delete |
获取子部门ID列表(GET) | DEPARTMENT_LIST_IDS | https://oapi.dingtalk.com/department/list_ids |
获取部门列表(GET) | DEPARTMENT_LIST | https://oapi.dingtalk.com/department/list |
获取部门详情(GET) | DEPARTMENT_GET | https://oapi.dingtalk.com/department/get |
查询部门的所有上级父部门路径(GET) | DEPARTMENT_LIST_PARENT_BY | https://oapi.dingtalk.com/department/list_parent_depts_by_dept |
查询指定用户的所有上级父部门路径(GET) | DEPARTMENT_LIST_PARENT | https://oapi.dingtalk.com/department/list_parent_depts |
获取企业员工人数(GET) | USER_GET_COUNT | https://oapi.dingtalk.com/user/get_org_user_count |
创建部门(POST) | DEPARTMENT_CREATE | https://oapi.dingtalk.com/department/create |
更新部门(POST) | DEPARTMENT_UPDATE | https://oapi.dingtalk.com/department/update |
删除部门(GET) | DEPARTMENT_DELETE | https://oapi.dingtalk.com/department/delete |
获取角色下的员工列表(POST) | ROLE_SIMPLE_LIST | https://oapi.dingtalk.com/topapi/role/simplelist |
发送工作通知消息(POST) | MESSAGE_CORPCONVERSATION | https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2 |
发起待办(POST) | WORKRECORD_ADD | https://oapi.dingtalk.com/topapi/workrecord/add |
更新待办(POST) | WORKRECORD_UPDATE | https://oapi.dingtalk.com/topapi/workrecord/update |
获取用户待办事项(POST) | WORKRECORD_GET_BY_USER | https://oapi.dingtalk.com/topapi/workrecord/getbyuserid |
上传媒体文件(POST) | MEDIA_UPLOAD | https://oapi.dingtalk.com/media/upload |
单步文件上传(POST) | FIEL_UPLOAD_SINGLE | https://oapi.dingtalk.com/file/upload/single |
分块上传文件-开启/提交分块上传事务(POST) | FIEL_UPLOAD_TRANSACTION | https://oapi.dingtalk.com/file/upload/transaction |
分块上传文件-上传文件块(POST) | FIEL_UPLOAD_CHUNK | https://oapi.dingtalk.com/file/upload/chunk |
注册业务事件回调接口(POST) | CALL_BACK_REGISTER | https://oapi.dingtalk.com/call_back/register_call_back |
查询事件回调接口(POST) | CALL_BACK_GET | https://oapi.dingtalk.com/call_back/get_call_back |
更新事件回调接口(POST) | CALL_BACK_UPDATE | https://oapi.dingtalk.com/call_back/update_call_back |
删除事件回调接口(GET) | CALL_BACK_DELETE | https://oapi.dingtalk.com/call_back/delete_call_back |
获取回调失败的结果(GET) | CALL_BACK_GET_FAILED_RESULT | https://oapi.dingtalk.com/call_back/get_call_back_failed_result |
签到事件回调类型 | CALL_BACK_EVENT_CHECK_IN | check_in |
企业考勤排班详情(POST) | ATTENDANCE_LIST_SCHEDULE | https://oapi.dingtalk.com/topapi/attendance/listschedule |
企业考勤组详情(POST) | ATTENDANCE_GET_SIMPLEGROUP | https://oapi.dingtalk.com/topapi/attendance/getsimplegroups |
获取打卡详情(POST) | ATTENDANCE_LIST_RECORD | https://oapi.dingtalk.com/attendance/listRecord |
获取打卡结果(POST) | ATTENDANCE_LIST | https://oapi.dingtalk.com/attendance/list |
获取请假时长(POST) | ATTENDANCE_GET_LEAVEDURATION | https://oapi.dingtalk.com/topapi/attendance/getleaveapproveduration |
查询请假状态(POST) | ATTENDANCE_GET_LEAVESTATUS | https://oapi.dingtalk.com/topapi/attendance/getleavestatus |
获取用户考勤组(POST) | ATTENDANCE_GET_USERGROUP | https://oapi.dingtalk.com/topapi/attendance/getusergroup |
获取部门用户签到记录(GET) | CHECKIN_RECORD | https://oapi.dingtalk.com/checkin/record |
获取用户签到记录(POST) | CHECKIN_RECORD_GET | https://oapi.dingtalk.com/topapi/checkin/record/get |
对于引用了移动端头页面 mobile_header.html
的页面,如果当前是钉钉执行环境且当前用户未登录系统,平台将使用钉钉提供的免登接口通过两次ajax请求自动完成系统登录。不再有使用cas登录时的页面三次跳转,首次使用体验大幅提升。
首先,在 applicationContext-security.xml
文件中,启用钉钉集成。可以看到,非钉钉环境依然延用cas登录
<beans:import resource="ddAndCasSecurity.xml"/>
然后,尽可能将页面初始化代码都放到Lcp.ready方法里。页面所有对后台接口的调用,都必须在Lcp.ready里、或之后执行。Lcp.ready函数保证了代码执行顺序,其一定会在(mui完成初始化、dd完成初始化、页面完成登录)这三者之后执行。建议使用Lcp.ready替代mui.ready或dd.ready。
var viewM = null;
Lcp.ready(function () {
viewM = new Vue({
el: '#mui-content',
methods: {
pickEmployee: function () {
dd.biz.util.openLink({
url: document.location.origin + '${base.contextPath}/hr/mb_employee_picker.html?multiSelect=false'
});
}
}
});
});
如果存在需要鉴权才使用的api,可以使用Lcp.ddConfig函数。建议Lcp.ddConfig在Lcp.ready之外调用。示例如下:
Lcp.ddConfig({
jsApiList: [
'runtime.info',
'biz.contact.choose',
'device.notification.confirm',
'device.notification.alert',
'device.notification.prompt',
'biz.ding.post',
'biz.util.openLink',
'biz.util.scanCard',
'device.geolocation.get',
]
})
Lcp.ready(function() {
...
)}
当在钉钉上做指定操作时,钉钉会将相关事件主动推送至指定RESTFul接口,实现事件通知。
向钉钉服务器指定地址发起请求,将回调URL作为参数告知钉钉(注册回调接口)。钉钉服务器会立刻向回调URL发起【测试回调URL】事件,来验证URL的合法性,回调URL服务器需要在接收到回调之后返回字符串“success”的加密json数据,才能完成注册。
事件类型 | 类别 | 说明 |
---|---|---|
user_add_org | 用户变更 | 通讯录用户增加 |
user_modify_org | 用户变更 | 通讯录用户更改 |
user_leave_org | 用户变更 | 通讯录用户离职 |
user_active_org | 用户变更 | 加入企业后用户激活 |
org_admin_add | 用户变更 | 通讯录用户被设为管理员 |
org_admin_remove | 用户变更 | 通讯录用户被取消设置管理员 |
org_dept_create | 部门变更 | 通讯录企业部门创建 |
org_dept_modify | 部门变更 | 通讯录企业部门修改 |
org_dept_remove | 部门变更 | 通讯录企业部门删除 |
org_remove | 企业信息变更 | 企业被解散 |
org_change | 企业信息变更 | 企业信息发生变更 |
label_user_change | 角色变更 | 员工角色信息发生变更 |
label_conf_add | 角色变更 | 增加角色或者角色组 |
label_conf_del | 角色变更 | 删除角色或者角色组 |
label_conf_modify | 角色变更 | 修改角色或者角色组 |
事件类型 | 说明 |
---|---|
chat_add_member | 群会话添加人员 |
chat_remove_member | 群会话删除人员 |
chat_quit | 群会话用户主动退群 |
chat_update_owner | 群会话更换群主 |
chat_update_title | 群会话更换群名称 |
chat_disband | 群会话解散群 |
事件类型 | 说明 |
---|---|
check_in | 用户签到 |
事件类型 | 说明 |
---|---|
bpms_instance_change | 审批实例开始,结束 |
bpms_task_change | 审批任务开始,结束,转交 |
通过 IDingDingService.execute 方法调用接口,系统会自动记录接口调用日志,方便问题查看和调试。
mber|群会话删除人员|
|chat_quit|群会话用户主动退群|
|chat_update_owner|群会话更换群主|
|chat_update_title|群会话更换群名称|
|chat_disband|群会话解散群|
事件类型 | 说明 |
---|---|
check_in | 用户签到 |
事件类型 | 说明 |
---|---|
bpms_instance_change | 审批实例开始,结束 |
bpms_task_change | 审批任务开始,结束,转交 |