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

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

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

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

前端框架使用 react

操作 localStorage 的基础代码

TypeScript 复制代码
export function getToken(){
    return localStorage.getItem("token") as string
}

export function setToken(token:string){
    localStorage.setItem("token",token)
}

export function removeToken(){
    localStorage.removeItem("token")
}

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

TypeScript 复制代码
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;
    }
}

钉钉免登录插件

TypeScript 复制代码
export class checkLoginPlugin extends Middleware {
  async handler(ctx: MiddlewareContext<{}>, next: () => Promise<any>): Promise<void> {
    // 判断是否获取到了token
    var 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及token
            const corpid = import.meta.env.CORPID
            dd.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及token
        const corpid = import.meta.env.CORPID
        dd.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")
      }
    }

  }

}
相关推荐
短剑重铸之日6 分钟前
《设计模式》第六篇:装饰器模式
java·后端·设计模式·装饰器模式
像少年啦飞驰点、8 分钟前
零基础入门 Spring Boot:从‘Hello World’到可上线微服务的完整学习路径
java·spring boot·web开发·编程入门·后端开发
心 -10 分钟前
全栈实时聊天室(java项目)
java
1104.北光c°30 分钟前
【从零开始学Redis | 第一篇】Redis常用数据结构与基础
java·开发语言·spring boot·redis·笔记·spring·nosql
阿猿收手吧!39 分钟前
【C++】volatile与线程安全:核心区别解析
java·c++·安全
Hui Baby1 小时前
Java SPI 与 Spring SPI
java·python·spring
摇滚侠1 小时前
Maven 教程,Maven 安装及使用,5 小时上手 Maven 又快又稳
java·maven
倔强菜鸟1 小时前
2026.2.2--Jenkins的基本使用
java·运维·jenkins
hai74251 小时前
在 Eclipse 的 JSP 项目中引入 MySQL 驱动
java·mysql·eclipse
瑞雪兆丰年兮1 小时前
[从0开始学Java|第十一天]学生管理系统
java·开发语言