当前位置: 首页 > news >正文

钉钉二次开发-企业内部系统集成官方OA审批流程(三)

书接上回,本文主要分享 企业内部系统集成钉钉官方OA审批流程的步骤 的第二部分。

前端代码集成钉钉免登JSAPI:

前端通过corpid 获得钉钉临时访问码code,再通过临时访问码code调用此接口返回当前用户的姓名、userid、 钉钉用户id、  系统工号、 钉钉部门id列表、 业务系统访问token 等信息,然后将 token 存储到 localStorage。

前端框架使用 react

操作 localStorage 的基础代码

export function getToken(){return localStorage.getItem("token") as string
}export function setToken(token:string){localStorage.setItem("token",token)
}export function removeToken(){localStorage.removeItem("token")
}

判断字段是否包含指定的字符串 

export function containsStr(str:string, target:string): boolean{str = str === null ? 'str' : str;target = target === null ? 'target' : target;if(str.indexOf(target) !== -1){// 字段str包含指定的字符串return true;} else {// 字段str不包含指定的字符串return false;}
}

钉钉免登录插件

export class checkLoginPlugin extends Middleware {async handler(ctx: MiddlewareContext<{}>, next: () => Promise<any>): Promise<void> {// 判断是否获取到了tokenvar token = getToken()const base_url = import.meta.env.BASE_URL;localStorage.setItem("base_url", base_url);if (token) {// token有值axios({method: 'get',baseURL: '/sale',url: '/api/checkToken?token=' + token,headers: {'Content-Type': 'application/json',},}).then((res: AxiosResponse) => {if (res.data.code == 200) {// token有效,打开应用localStorage.setItem("dingUserId", res.data.dingUserId);localStorage.setItem("dingDeptIds", res.data.dingDeptId);// 检查当前登录人的角色中是否包含 MANAGER 可以辅助实现数据权限校验var role_no = localStorage.getItem("role_no") as string;if (containsStr(role_no, "MANAGER")) {localStorage.setItem("manager", "true");} else {localStorage.setItem("manager", "false");}next()} else {               // token无效,钉钉重新获取token,不是钉钉,直接提示未登录if (dd.env.platform !== "notInDingTalk") {// 钉钉打开应用,重新获取code及tokenconst corpid = import.meta.env.CORPIDdd.ready(() => {dd.runtime.permission.requestAuthCode({corpId: corpid,}).then((result) => {const { code } = result;axios({method: 'get',baseURL: '/sale',url: '/dd/login?code=' + code,headers: {'Content-Type': 'application/json'},}).then((res: AxiosResponse) => {localStorage.setItem("token", res.data.data.token);localStorage.setItem("dingUserId", res.data.data.dingUserId);localStorage.setItem("dingDeptIds", res.data.data.dingDeptIds);localStorage.setItem("user_info", res.data.data.user_info);localStorage.setItem("userno", res.data.data.user_no);localStorage.setItem("user_id", res.data.data.user_id);// 检查当前登录人的角列表是否包含 MANAGER 可以辅助实现数据权限校验var role_no = localStorage.getItem("role_no") as string;if (containsStr(role_no, "MANAGER")) {localStorage.setItem("manager", "true");} else {localStorage.setItem("manager", "false");}token = res.data.data.token;// 可以继续访问应用资源next()return res.data.data}).catch(err => {router.navigate("/check")  //登录页return Promise.reject(err)})},).catch(err => {// 出现异常,跳转到登录页router.navigate("/checkLogin")});});} else {// 从钉钉外打开应用,跳转到登录页router.navigate("/checkLogin")}}}).catch(err => {// 出现异常,跳转到登录页router.navigate("/checkLogin")return Promise.reject(err)})} else {// token没有值if (dd.env.platform !== "notInDingTalk") {// 钉钉打开应用,重新获取钉钉临时code及tokenconst corpid = import.meta.env.CORPIDdd.ready(() => {dd.runtime.permission.requestAuthCode({corpId: corpid,}).then((result) => {const { code } = result;axios({method: 'get',baseURL: '/sale',url: '/dd/login?code=' + code,headers: {'Content-Type': 'application/json'},}).then((res: AxiosResponse) => {localStorage.setItem("usertoken", res.data.data.token);localStorage.setItem("dingtalkUserId", res.data.data.dingtalkUserId);localStorage.setItem("dingtalkDeptIds", res.data.data.dingtalkDeptIds);localStorage.setItem("user_info", res.data.data.user_info);localStorage.setItem("userno", res.data.data.user_no);localStorage.setItem("user_id", res.data.data.user_id);// 检查当前登录人的角色中是否包含 MANAGER 可以辅助实现数据权限校验var role_no = localStorage.getItem("role_no") as string;if (containsStr(role_no, "MANAGER")) {localStorage.setItem("manager", "true");} else {localStorage.setItem("manager", "false");}token = res.data.data.token;next()return res.data.data}).catch(err => {// 出现异常,跳转到登录页router.navigate("/checkLogin")return Promise.reject(err)})},).catch(err => {// 出现异常,跳转到登录页router.navigate("/checkLogin")});});} else {    // 从钉钉外打开应用,跳转到登录页router.navigate("/checkLogin")}}}}

相关文章:

钉钉二次开发-企业内部系统集成官方OA审批流程(三)

书接上回&#xff0c;本文主要分享 企业内部系统集成钉钉官方OA审批流程的步骤 的第二部分。 前端代码集成钉钉免登JSAPI: 前端通过corpid 获得钉钉临时访问码code&#xff0c;再通过临时访问码code调用此接口返回当前用户的姓名、userid、 钉钉用户id、 系统工号、 钉钉部门…...

代码随想录算法训练营第五十四 | ● 392.判断子序列 ● 115.不同的子序列

392.判断子序列 https://programmercarl.com/0392.%E5%88%A4%E6%96%AD%E5%AD%90%E5%BA%8F%E5%88%97.html class Solution { public:bool isSubsequence(string s, string t) {if(s.size()0 )return true;if(t.size()0)return false;vector<vector<int>> dp(s.size(…...

C++设计模式-外观模式,游戏引擎管理多个子系统,反汇编

运行在VS2022&#xff0c;x86&#xff0c;Debug下。 30. 外观模式 为子系统定义一组统一的接口&#xff0c;这个高级接口会让子系统更容易被使用。应用&#xff1a;如在游戏开发中&#xff0c;游戏引擎包含多个子系统&#xff0c;如物理、渲染、粒子、UI、音频等。可以使用外观…...

嵌入式软件测试相关分析

嵌入式软件测试相关分析 1. 引言 在软件发展之初&#xff0c;上个世纪五六十年代&#xff0c;软件被视为数学领域&#xff0c;编程是为了进行数学计算&#xff0c;由数学公式推导&#xff0c;来写函数。因此&#xff0c;在那个时候所编写的程序是被视为数学问题&#xff0c;数…...

vue+jave实现文件报表增加文件下载功能

需求背景:系统有文件交互功能。但没有做页面展示。为了测试方便&#xff0c;写了报表展示并可下载文件做检查。(所以下载是依赖表数据的) 使用语言和框架: 前端:vue-cli 后端:springBoot 前端实现 1、在报表vue文件&#xff0c;显示下载按钮并实现下载接口请求和处理。 //报…...

网站安全性评估方法

评估一个网站的安全性是一个多方面的过程&#xff0c;涉及到对网站的技术架构、代码质量、数据处理、用户交互等多个维度的考察。以下是一些常用的评估方法&#xff1a; 1.了解常见的安全风险&#xff1a;包括恶意软件、钓鱼攻击、跨站脚本攻击等&#xff0c;这些都是网站可能…...

【小程序】WXML模板语法

目录 数据绑定 数据绑定的基本原则 在data中定义页面的数据 Mustache语法的格式 Mustache语法的应用场景 事件绑定 什么是事件 小程序中常用的事件 事件对象的属性列表 target和currentTarget的区别 bindtap的语法格式 在事件处理函数中为data中的数据赋值 事件…...

[数据集][目标检测]厨房积水检测数据集VOC+YOLO格式88张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;88 标注数量(xml文件个数)&#xff1a;88 标注数量(txt文件个数)&#xff1a;88 标注类别数…...

QSlider样式示例

参考代码&#xff1a; /********************QSlider横向滑动条样式**********************/ QSlider {background-color: rgba(170, 255, 255, 100); /* 设置滑动条主体*/ }QSlider::groove:horizontal {border: 1px solid #999999;height: 8px; /* 默认…...

【Linux】进程3——PID/PPID,父进程,子进程

在讲父子进程之前&#xff0c;我们接着上面那篇继续讲 1.查看进程 mycode.c makefile 我们在zs_108直接编译mycode.c&#xff0c;直接运行&#xff0c;然后我们转换另一个账号来查看这个进程 我们可以通过ps指令来查看进程 我们就会好奇了&#xff0c;第二行是什么&#xff…...

开发常用的组件库

框架&#xff1a; Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org) React 官方中文文档 (docschina.org) Svelte 中文文档 | Svelte 中文网 SolidJS 反应式 JavaScript 库 页面样式&#xff1a; 网页端&#xff1a; 指南 |元素 (eleme.cn) Mint UI (mint-ui.github.io…...

深度解析地铁票务系统的技术架构与创新应用

在城市交通体系中&#xff0c;地铁作为一种快速、便捷的公共交通方式&#xff0c;已经成为现代都市生活的重要组成部分。而地铁票务系统的技术架构&#xff0c;则是支撑地铁运营的核心之一。本文将深度解析地铁票务系统的技术架构与创新应用&#xff0c;从系统设计、数据管理、…...

Python集合的基本概念和使用方法

目录 集合&#xff08;Set&#xff09; 基本概念 基本特性 基本操作 集合运算 成员测试 高级操作 集合推导式 总结 集合&#xff08;Set&#xff09; Python集合&#xff08;Set&#xff09;是Python语言中一个非常实用且强大的数据结构&#xff0c;它用于存储多个不…...

谷歌浏览器124版本Webdriver驱动下载

查看谷歌浏览器版本 在浏览器的地址栏输入&#xff1a; chrome://version/回车后即可查看到对应版本(不要点击帮助-关于Google chrome&#xff0c;因为点击后会自动更新谷歌版本) 114之前版本&#xff1a;下载链接 ​​​​​​123以后版本&#xff1a;下载链接&#xff0…...

十大排序

本文将以「 通俗易懂」的方式来描述排序的基本实现。 &#x1f9d1;‍&#x1f4bb;阅读本文前&#xff0c;需要一点点编程基础和一点点数据结构知识 本文的所有代码以cpp实现 文章目录 排序的定义 插入排序 ⭐ &#x1f9d0;算法描述 &#x1f496;具体实现 &#x1f…...

微信小程序学习笔记(1)

文章目录 一、文件作用app.json&#xff1a;project.config.json:sitemap.json页面中.json 二、项目首页三、语法**WXML**和**HTML**WXSS 和CSS的区别小程序中.js文件的分类 一、文件作用 app.json&#xff1a; 当前小程序的全局配置&#xff0c;包括所有页面路径、窗口外观、…...

OpenGauss数据库-6.表空间管理

第1关&#xff1a;创建表空间 gsql -d postgres -U gaussdb -W passwd123123 CREATE TABLESPACE fastspace OWNER omm relative location tablespace/tablespace_1; 第2关&#xff1a;修改表空间 gsql -d postgres -U gaussdb -W passwd123123 ALTER TABLESPACE fastspace R…...

相约乌镇 续写网络空间命运与共的新篇章(二)

从乌镇峰会升级为世界互联网大会&#xff0c;既是展示互联网发展成果的技术盛会&#xff0c;也是尖端科技综合运用的宏大场景。从枕水江南散发出的“互联网之光”&#xff0c;到前沿技术的创新突破和场景应用&#xff0c;澎湃的是数字经济浪潮&#xff0c;激荡的是科技创新能量…...

【全网最简单的解决办法】vscode中点击运行出现仅当从 VS 开发人员命令提示符处运行 VS Code 时,cl.exe 生成和调试才可用

首先确保你是否下载好了gcc编译器&#xff01;&#xff01;&#xff01; 检测方法&#xff1a; winR 打开cmd命令窗 输入where gcc(如果出现路径则说明gcc配置好啦&#xff01;) where gcc 然后打开我们的vscode 把这个文件删除掉 再次点击运行代码&#xff0c;第一个出现…...

NFS共享存储服务

NFS共享存储服务 NFS&#xff1a;network file system ,在计算机网络中共享文件系统的协议。 计算机之间可以通过网络共享目录和文件&#xff0c;分为两个部分&#xff1a; 1、rpcbind&#xff1a;远程共享调用 2、nfs&#xff1a;共享服务&#xff0c;端口号&#xff1a;2…...

提示工程实战:从核心模式到高级技巧的AI交互优化指南

1. 项目概述&#xff1a;从代码仓库到提示工程实战指南最近在GitHub上看到一个名为“SKY-lv/prompt-engineer”的仓库&#xff0c;点进去一看&#xff0c;发现这不仅仅是一个简单的代码集合&#xff0c;更像是一位资深从业者&#xff08;SKY-lv&#xff09;精心整理的提示工程实…...

ubantu安装vscode

在火狐浏览器中搜索vscode官网&#xff0c;找到.deb文件下载&#xff0c;下载完成后文件所在的位置为 主文件夹/下载 文件夹内。...

CircuitPython FancyLED库:专业级可寻址LED色彩动画开发指南

1. 项目概述&#xff1a;为什么需要FancyLED&#xff1f;在嵌入式开发&#xff0c;尤其是物联网和交互式装置项目中&#xff0c;可寻址LED&#xff08;如NeoPixel、DotStar&#xff09;已经成为构建动态视觉反馈的核心组件。无论是制作一个会呼吸的氛围灯&#xff0c;还是一个能…...

【Midjourney胶片摄影风格终极指南】:20年影像工程师亲授7种不可外传的参数组合与暗房逻辑复刻法

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;胶片摄影的数字复刻本质与Midjourney底层成像机制 胶片摄影的“颗粒感”“色偏”“晕影”并非缺陷&#xff0c;而是光化学反应在银盐乳剂中非线性响应的物理印记&#xff1b;Midjourney 并不模拟胶片&a…...

紧急更新!MJ v6.1新增--style raw对表现主义的影响深度解析(附6种失效场景急救方案)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;紧急更新&#xff01;MJ v6.1新增--style raw对表现主义的影响深度解析&#xff08;附6种失效场景急救方案&#xff09; MidJourney v6.1 引入的 --style raw 参数并非简单降低美学修饰&#xff0c;而是…...

Playnite完整指南:高效统一你的跨平台游戏库管理体验

Playnite完整指南&#xff1a;高效统一你的跨平台游戏库管理体验 【免费下载链接】Playnite Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games. 项目地址: http…...

HSTracker:macOS平台炉石传说智能数据分析与决策辅助系统

HSTracker&#xff1a;macOS平台炉石传说智能数据分析与决策辅助系统 【免费下载链接】HSTracker A deck tracker and deck manager for Hearthstone on macOS 项目地址: https://gitcode.com/gh_mirrors/hs/HSTracker HSTracker是一款专为macOS平台设计的炉石传说智能套…...

告别Keil!用Arduino生态玩转国产GD32芯片的3个实战技巧

用Arduino生态解锁GD32开发的三大高阶玩法 在嵌入式开发领域&#xff0c;Keil和IAR等传统工具链长期占据主导地位&#xff0c;但它们的封闭生态和复杂配置流程正在被更开放的解决方案挑战。GD32作为国产MCU的优秀代表&#xff0c;其与Arduino生态的融合为开发者提供了一条高效率…...

ARM架构TLB机制与TLBI指令详解

1. ARM TLB机制与TLBI指令概述在ARM架构中&#xff0c;TLB&#xff08;Translation Lookaside Buffer&#xff09;是内存管理单元&#xff08;MMU&#xff09;的核心组件&#xff0c;负责缓存虚拟地址到物理地址的转换结果。当CPU访问内存时&#xff0c;首先查询TLB获取地址转换…...

2026年实测推荐:10款思维导图工具,开发者效率翻倍

作为技术博主&#xff0c;我常年用思维导图拆解需求、梳理架构、记录学习笔记。2026年&#xff0c;工具们卷出了新高度&#xff1a;AI辅助、白板一体化、实时协作成了标配。本文从开发者视角出发&#xff0c;实测了10款热门工具&#xff0c;帮你选出最适合的那把“瑞士军刀”。…...