飞书交互-根据用户账号获取飞书对话框链接接口开发。

知识分享-增加"联系创建人"按钮,点击后打开飞书联系人对话框。
配置文件整理。
This commit is contained in:
wangzhijiang
2022-12-07 16:25:47 +08:00
parent f927f5c637
commit 4e27c76b78
9 changed files with 184 additions and 19 deletions
@@ -1,9 +1,12 @@
package com.jero.modules.feishu.controller;
import com.alibaba.fastjson.JSONObject;
import com.jero.common.api.vo.Result;
import com.jero.common.aspect.annotation.AutoLog;
import com.jero.modules.feishu.service.IFeishuService;
import com.jero.modules.feishu.utils.LarkDecryptUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -93,4 +96,11 @@ public class LarkController {
log.info(result.toString());
return result;
}
@AutoLog(value = "飞书交互-根据用户账号获取飞书对话框链接")
@ApiOperation(value="书交互-根据用户账号获取飞书对话框链接", notes="书交互-根据用户账号获取飞书对话框链接")
@PostMapping(value = "/getLarkApplinkByUserName")
public Result<?> getLarkApplinkByUserName(@RequestBody JSONObject json){
return this.feishuService.getLarkApplinkByUserName(json);
}
}
@@ -1,6 +1,7 @@
package com.jero.modules.feishu.service;
import com.alibaba.fastjson.JSONObject;
import com.jero.common.api.vo.Result;
import com.jero.modules.feishu.vo.FeishuMsg2Vo;
import com.jero.modules.feishu.vo.FeishuMsgVo;
@@ -103,4 +104,16 @@ public interface IFeishuService {
void sendCard(String[] thirdIds, FeishuMsg2Vo feishuMsgVo) throws IOException;
/**
* 根据手机号,获取来自飞书的用户信息
* @param phoneList
*/
JSONObject getUserInfoFromLarkByPhoneList(List<String> phoneList) throws IOException ;
/**
* 根据用户账号获取飞书对话框链接
* @param json
* @return
*/
Result<?> getLarkApplinkByUserName(JSONObject json);
}
@@ -7,6 +7,9 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jero.common.api.vo.Result;
import com.jero.common.constant.enums.CutEnum;
import com.jero.common.exception.JeroBootException;
import com.jero.modules.feishu.service.IFeishuService;
import com.jero.modules.feishu.vo.FeishuMsg2Vo;
import com.jero.modules.feishu.vo.FeishuMsgVo;
@@ -31,10 +34,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -60,6 +60,14 @@ public class FeishuServiceImpl implements IFeishuService {
@Value("${Feishu.translateTextUrl}")
private String translateTextUrl;
// 获取用户信息Url
@Value("${Feishu.getUserInfoUrl}")
private String getUserInfoUrl;
// 打开用户对话框Url
@Value("${Feishu.appLinkUrl}")
private String appLinkUrl;
@Value(value = "${jero.backUrl}")
private String backUrl;
@Autowired
@@ -1228,4 +1236,97 @@ public class FeishuServiceImpl implements IFeishuService {
}
/**
* 根据手机号,获取来自飞书的用户信息
* @param phoneList
* @throws IOException
*/
@Override
public JSONObject getUserInfoFromLarkByPhoneList(List<String> phoneList) throws IOException {
String token = getTenantAccessToken();
// 设置请求头
Map<String, String> headerMap = new HashMap<>();
headerMap.put("Authorization", "Bearer " + token);
headerMap.put("Content-Type", "application/json; charset=utf-8");
// 设置请求参数
JSONObject paramsMap = new JSONObject();
paramsMap.put("mobiles", phoneList);
// 发送请求给飞书
String response = null;
try {
response = HttpRequestUtil.getResponseOfPOST(getUserInfoUrl, headerMap, paramsMap.toJSONString());
} catch (IOException e) {
e.printStackTrace();
}
// 获取返回结果
JSONObject responseJson = JSONObject.parseObject(response);
if(!responseJson.get("code").toString().equals("0")) {
log.error("请求出现异常:" + responseJson.get("msg") + " " + responseJson);
}
return responseJson;
}
/**
* 根据用户账号获取飞书对话框链接
* @param json
* @return
*/
@Override
public Result<?> getLarkApplinkByUserName(JSONObject json) {
String result = null;
String cut = json.getString("cut");
String userName = json.getString("userName");
if(StringUtils.isEmpty(userName)){
if(StringUtils.equals(cut,CutEnum.CN.getValue())){
throw new JeroBootException("用户账号不能为空,请检查!");
}else if(StringUtils.equals(cut,CutEnum.EN.getValue())){
throw new JeroBootException("User account cannot be empty, please check!");
}
}
SysUser sysUserInfo = this.sysUserService.getUserByName(userName);
if(Objects.isNull(sysUserInfo)){
if(StringUtils.equals(cut,CutEnum.CN.getValue())){
throw new JeroBootException("未找到" + userName +",用户,请检查!");
}else if(StringUtils.equals(cut,CutEnum.EN.getValue())){
throw new JeroBootException("User not found" + userName + ", please check!");
}
}
String phone = sysUserInfo.getPhone();
JSONObject responseJson = null;
List<String> phoneList = Arrays.asList(phone.split(","));
try {
// 根据用户手机号获取该用户在飞书中的信息
responseJson = this.getUserInfoFromLarkByPhoneList(phoneList);
}catch (Exception ex){
ex.printStackTrace();
log.error("根据用户手机号获取该用户在飞书中的信息失败:" + ex.getMessage());
}
JSONArray userJsonArray = JSONObject.parseObject(JSONObject.toJSONString(responseJson.get("data"))).getJSONArray("user_list");
Map<String,Object> userJsonMap = null;
for (Object userJson : userJsonArray) {
userJsonMap = JSONObject.parseObject(JSONObject.toJSONString(userJson),Map.class);
if(userJsonMap.get("user_id") != null){
if(StringUtils.isNotEmpty(userJsonMap.get("user_id").toString()) && StringUtils.equals(userJsonMap.get("mobile").toString(),phone)){
result = this.appLinkUrl + userJsonMap.get("user_id").toString();
break;
}
}else {
throw new JeroBootException("用户:" + userName + ",在飞书中未找到对应user_id信息");
}
}
if(StringUtils.isNotEmpty(result)){
return Result.OK("获取" +userName+ "用户飞书AppLink成功!",result);
}else {
return Result.error("获取" +userName+ "用户飞书AppLink失败!");
}
}
}
@@ -130,22 +130,17 @@ spring:
connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
datasource:
master:
# url: jdbc:mysql://localhost:3306/laws_weilai_stand?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://10.0.3.44:3306/jero-boot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
# url: jdbc:mysql://10.10.10.44:3306/laws_weilai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://121.36.69.172:3307/laws_weilai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
url: jdbc:mysql://121.36.69.172:3307/laws_weilai?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
url: jdbc:mysql://121.36.69.172:3307/laws_weilai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: hzwlsoft.com
driver-class-name: com.mysql.cj.jdbc.Driver
# 10测试环境库
#url: jdbc:mysql://10.10.10.44:3306/laws_weilai?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
#username: root
#password: 123456
#driver-class-name: com.mysql.cj.jdbc.Driver
# 多数据源配置
#multi-datasource1:
#url: jdbc:mysql://localhost:3306/jero-boot2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
@@ -436,7 +431,8 @@ Feishu:
getTenantAccessTokenUrl: https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal
batchSendMessageUrl: https://open.feishu.cn/open-apis/message/v4/batch_send/
translateTextUrl: https://open.feishu.cn/open-apis/translation/v1/text/translate
getUserInfoUrl: https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id?user_id_type=open_id
appLinkUrl: https://applink.feishu.cn/client/chat/open?openId=
local-tool:
uri: http://139.9.235.66:9022
opensso:
Binary file not shown.

After

Width:  |  Height:  |  Size: 529 B

+1
View File
@@ -1363,4 +1363,5 @@ module.exports = {
CuiBan:'CuiBan',
brand:'Brand',
allsubitemsitem:'Whether to delete all subitems under this item',
contactTheFounder:'Contact the founder',
}
+1
View File
@@ -1464,4 +1464,5 @@ module.exports = {
CuiBan:'催办',
brand:'品牌',
allsubitemsitem:'该项目下拥有子项目是否全部删除',
contactTheFounder:'联系创建人',
}
@@ -109,6 +109,10 @@
</div>
</div>
<div class="content-box-button-right">
<div class="content-box-button-text" @click="pushJump(item)">
<img src="~/@assets/feishu.png" alt="" class="jumpicon">
{{$t('contactTheFounder')}}
</div>
<div class="content-box-button-text" @click="forwardClick(item)">
<a-icon type="logout"/>
{{$t('forward')}}
@@ -401,6 +405,20 @@
this.queryForm = row
this.$refs.SelectedByRef.getPush()
},
pushJump(row){
let query = {
userName: row.createBy,
}
postAction('/lark/getLarkApplinkByUserName', query).then((res) => {
if (res.code === 200) {
let url = res.result
window.open(url, '_blank')
} else {
this.$message.warning(res.message)
this.$refs.SelectedByRef.submitLoading = false
}
})
},
SelectedByForm(userIds) {
let query = {
userIds: userIds,
@@ -436,7 +454,10 @@
overflow: hidden;
/*margin: 0 auto;*/
}
.jumpicon{
height: 13.72px;
width: 15.44px;
}
.box-title-text {
line-height: 1.4;
width: 360px;
@@ -53,6 +53,10 @@
</div>
</div>
<div class="content-box-button-right">
<div class="content-box-button-text" @click="pushJump(queryForm)">
<img src="~/@assets/feishu.png" alt="" class="jumpicon">
{{$t('contactTheFounder')}}
</div>
<div class="content-box-button-text" @click="forwardClick(queryForm)">
<a-icon type="logout"/>
{{$t('forward')}}
@@ -449,6 +453,20 @@
this.queryForm = row
this.$refs.SelectedByRef.getPush()
},
pushJump(row){
let query = {
userName: row.createBy,
}
postAction('/lark/getLarkApplinkByUserName', query).then((res) => {
if (res.code === 200) {
let url = res.result
window.open(url, '_blank')
} else {
this.$message.warning(res.message)
this.$refs.SelectedByRef.submitLoading = false
}
})
},
detailClick(item,key) {
this.$router.push({
path: '/docManage/library/detail',
@@ -480,6 +498,10 @@
</script>
<style scoped lang="less">
.jumpicon{
height: 13.72px;
width: 15.44px;
}
.content-box {
width: 100%;
height: auto;