飞书获取用户及部门信息

news2024/12/23 2:36:55
1、进入企业后台管理,创建一个企业自建应用 ,获取App ID,App Secret

2、 对应用设置api权限及数据权限

 

3、Java客户端获取用户,部门信息

 有两种方式可以获取:1、api    2、sdk的方式

我这里采用sdk的方式,需要引入maven依赖

<dependency>
    <groupId>com.larksuite.oapi</groupId>
    <artifactId>oapi-sdk</artifactId>
    <version>2.3.2</version>
</dependency>

 Java代码为:

package com.hniclear.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hniclear.common.mapper.UserInfoMapper;
import com.hniclear.common.model.po.UserInfo;
import com.hniclear.system.mapper.DepartmentMapper;
import com.hniclear.system.model.po.DepartmentInfo;
import com.hniclear.system.model.vo.rsp.devopsLog.DepartmentTreeRsp;
import com.hniclear.system.service.UserService;
import com.lark.oapi.Client;
import com.lark.oapi.service.contact.v3.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class UserServiceImpl implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Value("${feishu.appId}")
    private String appId;

    @Value("${feishu.appSecret}")
    private String appSecret;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private DepartmentMapper departmentMapper;


    @Override
    public List<DepartmentTreeRsp> getDepartmentTree(String parentDepartmentId) {
        List<DepartmentTreeRsp> departmentTreeRsps = new ArrayList<>();
        LambdaQueryWrapper<DepartmentInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(DepartmentInfo::getParentDepartmentId, parentDepartmentId)
                .eq(DepartmentInfo::getIsDeleted, 0);
        List<DepartmentInfo> departmentInfos = departmentMapper.selectList(lambdaQueryWrapper);
        if(CollectionUtils.isEmpty(departmentInfos)){
            return null;
        }
        for(DepartmentInfo departmentInfo : departmentInfos){
            DepartmentTreeRsp departmentTreeRsp = new DepartmentTreeRsp();
            departmentTreeRsp.setId(departmentInfo.getId());
            departmentTreeRsp.setName(departmentInfo.getName());

            LambdaQueryWrapper<UserInfo> userInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userInfoLambdaQueryWrapper.eq(UserInfo::getDepartmentId, departmentInfo.getDepartmentId())
                    .eq(UserInfo::getIsDelete, 0);
            List<UserInfo> userInfos = userInfoMapper.selectList(userInfoLambdaQueryWrapper);
            List<DepartmentTreeRsp.UserInfoRsp> userInfoRsps = new ArrayList<>();
            userInfos.forEach(userInfo -> {
                DepartmentTreeRsp.UserInfoRsp userInfoRsp = new DepartmentTreeRsp.UserInfoRsp();
                BeanUtils.copyProperties(userInfo, userInfoRsp);
                userInfoRsps.add(userInfoRsp);
            });
            departmentTreeRsp.setUsers(userInfoRsps);
            departmentTreeRsp.setChildren(getDepartmentTree(departmentInfo.getDepartmentId()));
            departmentTreeRsps.add(departmentTreeRsp);
        }
        return departmentTreeRsps;
    }

    @Override
    public void sync() {
        Client client = Client.newBuilder(appId, appSecret).build();
        List<Department> departments = syncDepartmentFromFeishu(client);
        if (!CollectionUtils.isEmpty(departments)) {
            insertDepartment(departments);
            List<User> users = syncUsersFromFeishu(departments, client);
            if (!CollectionUtils.isEmpty(users)) {
                insertUser(users);
            }
        }
    }
    @Override
    public List<User> syncUsersFromFeishu(List<Department> departmentList, Client client) {
        try {
            if (CollectionUtils.isEmpty(departmentList)) {
                return null;
            }
            insertDepartment(departmentList);
            List<User> userList = new ArrayList<>();
            for (Department department : departmentList) {
                ListUserResp listUserResp = client.contact().v3().user().list(new ListUserReq(ListUserReq.newBuilder().departmentId(department.getOpenDepartmentId())));
                User[] items = listUserResp.getData().getItems();
                if (items != null) {
                    userList.addAll(Arrays.asList(items));
                }
            }
            return userList;
        } catch (Exception e) {
            log.error("sync users from feishu error", e);
        }
        return null;
    }

    @Override
    public List<Department> syncDepartmentFromFeishu(Client client) {
        try {
            ListDepartmentReq req = new ListDepartmentReq();
            req.setPageSize(50);
            ListDepartmentResp listUserResp = client.contact().v3().department().list(req);
            List<Department> departmentList = new ArrayList<>();
            Department[] items = listUserResp.getData().getItems();
            if (items == null) {
                return null;
            }
            for (Department department : items) {
                getDepartmentList(department.getDepartmentId(), departmentList, client);
            }
            return departmentList;
        } catch (Exception e) {
            log.error("sync users from feishu error", e);
        }
        return null;
    }

    void getDepartmentList(String departmentId, List<Department> departmentList, Client client) throws Exception {
        ChildrenDepartmentReq childrenDepartmentReq = new ChildrenDepartmentReq();
        childrenDepartmentReq.setDepartmentId(departmentId);
        ChildrenDepartmentResp childrenDepartmentResp = client.contact().v3().department().children(childrenDepartmentReq);
        Department[] items = childrenDepartmentResp.getData().getItems();
        if (items == null) {
            return;
        }
        departmentList.addAll(Arrays.asList(items));
        for (Department item : items) {
            getDepartmentList(item.getOpenDepartmentId(), departmentList, client);
        }
    }

    private void insertDepartment(List<Department> departmentList) {
        List<DepartmentInfo> addDepartmentInfos = new ArrayList<>();
        for (Department department : departmentList) {
            DepartmentInfo departmentInfo = new DepartmentInfo();
            LambdaQueryWrapper<DepartmentInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(DepartmentInfo::getDepartmentId, department.getOpenDepartmentId())
                    .eq(DepartmentInfo::getIsDeleted, 0);
            DepartmentInfo existDepartmentInfo = departmentMapper.selectOne(lambdaQueryWrapper);
            if (existDepartmentInfo != null) {
                departmentInfo.setId(existDepartmentInfo.getId());
            }
            departmentInfo.setName(department.getName())
                    .setZhCn(department.getI18nName().getZhCn())
                    .setParentDepartmentId(department.getParentDepartmentId())
                    .setDepartmentId(department.getOpenDepartmentId())
                    .setOrders(department.getOrder())
                    .setCreateTime(new Date())
                    .setIsDeleted(department.getStatus().getIsDeleted())
                    .setMemberCount(department.getMemberCount());
            addDepartmentInfos.add(departmentInfo);
        }
        departmentMapper.insertOrUpdate(addDepartmentInfos);
    }

    private void insertUser(List<User> userList) {
        List<UserInfo> userInfos = new ArrayList<>();
        for (User item : userList) {
            if (item.getMobile() == null) {
                continue;
            }
            String telephone = item.getMobile().contains("+86") ? item.getMobile().replace("+86", "") : item.getMobile();
            UserInfo userInfo = new UserInfo();
            LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(UserInfo::getTelephone, telephone).eq(UserInfo::getIsDelete, 0);
            UserInfo existUserInfo = userInfoMapper.selectOne(lambdaQueryWrapper);
            if (existUserInfo != null) {
                userInfo.setId(existUserInfo.getId());
            }
            String[] departmentIds = item.getDepartmentIds();

            userInfo.setUserName(item.getName())
                    .setDepartmentId(departmentIds[departmentIds.length - 1])
                    .setTelephone(telephone)
                    .setOpenId(item.getOpenId())
                    .setIsDelete(0)
                    .setStatus(1)
                    .setCreateTime(LocalDateTime.now())
                    .setPassword("hni2Meta.")
                    .setType(2);
            userInfos.add(userInfo);
        }
        userInfoMapper.insertOrUpdate(userInfos);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157668.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何给文件夹里面的文件批量添加前缀和编号(利用C#写的小工具)

运行结果 将上面的文件编号效果 下载过后启动这个程序即可&#xff08;这个程序灵感来源是上次给美术资源分类和编号的时候给我干吐了&#xff0c;所以写了这个工具&#xff09; 体验链接&#xff1a;laozhupeiqia/批处理 --- laozhupeiqia/批处理 (github.com) 如果对你有帮助…

【C++】面向对象编程的三大特性:深入解析继承机制

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…

近几年来说最有效率的编程语言和市场最认可的编程语言分别是什么?

在过去的几年中&#xff0c;编程语言的效率和市场认可度在不断演变。不同的语言适用于不同的领域和场景&#xff0c;因而编程语言的“效率”和“市场认可”需要根据具体应用来分析。本文将从两个角度入手&#xff0c;分别探讨近几年中被认为最有效率和最受市场认可的编程语言。…

MISC - 第二天(wireshark,base64解密图片,zip文件伪加密,LSB二进制最低位,ARCHPR工具)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天给大家讲解杂项 乌镇峰会种图 使用了stegsolve工具&#xff0c;查看更多信息 发现flag信息 更改为html后缀flag{97314e7864a8f62627b26f3f998c37f1} wireshark 看题目是 分析pacp数据包&#xff0c;通过网站登录…

模组差分包,可能是你远程升级失败的罪魁祸首!

也许我们已经习惯生活里的问题接连不断。。。但当收到客户的问题反馈&#xff0c;还是会心头一紧&#xff01; 最近有客户反馈在乡村里频繁出现掉线的情况。 我们赶紧排查&#xff1a;换货、换SIM卡&#xff0c;发现只有去年5月22号采购的那批模块在客户环境附近会出现掉线的…

2024年 人工智能领域的一些成果与未来发展趋势 形式丰富多样

目前人工智能领域发展迅速&#xff0c;在多个方面取得显著成果。2024 人工智能大会展览规模、首发新品数均达历史最高&#xff0c;有超过 500 家企业参展&#xff0c;展品数量超过 1500 项。 在教育领域&#xff0c;人工智能落地成果显著。只需一键扫描就可以自动批改试卷的作业…

基于yolov5滑块识别破解(一)

由于内容较长&#xff0c;将分为两个部分来说明&#xff0c;本文讲解yolov5的部署与训练。 1.YOLOv5部署 云端部署&#xff08;训练&#xff09; 服务器创建 如果自己的显卡算力不是很好的&#xff0c;或者是核显电脑&#xff0c;可以租用算力&#xff0c;价格还行一块钱左右就…

nodejs基于vue+express度假村旅游管理系统设计与实现7t82p

目录 功能介绍数据库设计具体实现截图技术栈技术论证解决的思路论文目录核心代码风格详细视频演示源码获取 功能介绍 实现了一个完整的农家乐系统&#xff0c;其中主要有用户表模块、关于我们模块、收藏表模块、公告信息模块、酒店预订模块、酒店信息模块、景区信息模块、景区…

96. UE5 GAS RPG 实现闪电链技能(一)

闪电链有一个施法的过程&#xff0c;就是在按键按下的过程&#xff0c;会在按下的过程一直持续造成伤害&#xff0c;一直等到条件不满足&#xff08;技能键位抬起&#xff0c;蓝量不足&#xff0c;被眩晕&#xff09;时&#xff0c;将结束技能&#xff0c;并退出技能状态。 所以…

以太坊客户端Geth的介绍与搭建

一、以太坊客户端 1.介绍 以太坊客户端是指用于连接、交互和参与以太坊区块链网络的软件。以太坊客户端允许用户执行各种操作&#xff0c;如发送交易、挖矿、部署智能合约、同步区块链数据等。 2.功能 区块链同步&#xff1a;客户端会下载并验证以太坊区块链的所有区块&…

7. 无线网络安全

7. 无线网络安全 (1) 无线网络面临的安全威胁 无线网络由于其开放性和无线传输的特性,面临着多种安全威胁,主要包括: 窃听:攻击者可以截获无线电信号并解析出数据,甚至在加密通信中收集加密信息用于以后的分析。 通信阻断:通过DoS攻击或其他干扰手段阻断通信,使设备间无…

TFT-LCD显示屏(1.8寸 STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理&#xff1a;TFT-LCD色彩空间 三、程序设计 main.c文件 lcd.h文件 lcd.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 TFT-LCD&#xff0c;全称Thin Film Transistor Liquid Crystal Display&a…

gitlab修改访问端口

目录 1.找到gitlab.rb文件&#xff0c;一般在/etc/gitlab/路径下 2.打开配置文件&#xff0c;加上代码 3.重新配置 4.重启gitlab 1.找到gitlab.rb文件&#xff0c;一般在/etc/gitlab/路径下 2.打开配置文件&#xff0c;加上代码 打开文件 sudo vi gitlab.rb 加上默认端口配…

苹果AI手机遇阻,国产手机找到超车机遇

行至九月&#xff0c;2024年&#xff0c;这个所谓AI手机的元年&#xff0c;已经走过近三个季度了。 市场最为期待的AI手机机型也基本都发布了。9月20日&#xff0c;首款搭载Apple Intelligence功能的苹果新品iPhone16正式发售。或许是为了进一步扩大销售&#xff0c;今年天猫A…

【JAVA开源】基于Vue和SpringBoot的甘肃非物质文化网站

本文项目编号 T 042 &#xff0c;文末自助获取源码 \color{red}{T042&#xff0c;文末自助获取源码} T042&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

计算机网络-小型综合网络的搭建涉及到无线路由交换安全

目录 1 拓扑架构 2 做项目的思路 3 做配置 3.1先做核心交换 3.2 防火墙的配置 4 ac 和ap 的配置 4.1 ac上配置安全的东西 5.1 测试​编辑 1 拓扑架构 要求看上面的图 2 做项目的思路 这张网很明显是一个小综合&#xff0c;设计到我们的无线交换&#xff0c;路由…

统信服务器操作系统【SSH登录常见问题】解决方案

方案适用于统信服务器操作系统D/E/A版。 文章目录 前言问题及解决方案问题一问题现象问题原因问题方案问题二问题现象问题原因问题方案问题三问题原因问题方案问题四问题现象问题原因问题方案问题五问题现象问题原因问题方案问题六问题现象问题原因问题方案前言 介绍日常使用s…

语音识别控制(软件、硬件)

1. 环境 python版本&#xff1a;3.11.9 2. 完整代码 import sqlite3 import time import wave # 使用wave库可读、写wav类型的音频文件 from funasr import AutoModel import sounddevice as sd import numpy as np from modelscope import pipeline, Tasks from pypinyin …

软件著作权登记所需要的材料

软件著作权登记所需材料全面解析 在当今数字化时代&#xff0c;软件著作权作为保护软件开发者智力劳动成果的重要法律手段&#xff0c;其登记过程显得尤为重要。 一、软件著作权登记申请表 首先&#xff0c;软件著作权登记需要提交的最基本材料是《软件著作权登记申请表》。这份…

深度优先搜索算法及其matlab程序详解

#################本文为学习《图论算法及其MATLAB实现》的学习笔记################# 深度优先搜索算法(DepthFirst Search),简记DFS算法,是图论中的首要算法,其思想方法渗透到图论中的许多算法之中,尤其是DFS算法在求生成树、割点、块和平面图嵌入算法中起着极为关键的作用。…