Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
cmeeting
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
翟斌
cmeeting
Commits
5cb7fb90
提交
5cb7fb90
authored
6月 12, 2025
作者:
duanxincheng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cmeeting后台登录鉴权,会议修改纪要调优,生成的纪要文件内容格式调优
父级
0db0455d
隐藏空白字符变更
内嵌
并排
正在显示
64 个修改的文件
包含
4039 行增加
和
225 行删除
+4039
-225
pom.xml
+30
-1
src/main/java/com/cmeeting/ad/config/CustomAuthenticationProvider.java
+167
-0
src/main/java/com/cmeeting/ad/config/CustomWhiteConfigProperties.java
+23
-0
src/main/java/com/cmeeting/ad/config/LdapConfig.java
+50
-0
src/main/java/com/cmeeting/ad/config/RobotWebSecurityConfig.java
+141
-0
src/main/java/com/cmeeting/ad/config/RobotWhiteConfigProperties.java
+25
-0
src/main/java/com/cmeeting/ad/controller/UserController.java
+55
-0
src/main/java/com/cmeeting/ad/entity/ModulePermissions.java
+69
-0
src/main/java/com/cmeeting/ad/entity/RelPlatformSettingTenant.java
+44
-0
src/main/java/com/cmeeting/ad/entity/RobotSecurityUser.java
+139
-0
src/main/java/com/cmeeting/ad/entity/RoleTree.java
+28
-0
src/main/java/com/cmeeting/ad/entity/SysMenu.java
+151
-0
src/main/java/com/cmeeting/ad/entity/SysPlatformSetting.java
+109
-0
src/main/java/com/cmeeting/ad/entity/SysTenant.java
+116
-0
src/main/java/com/cmeeting/ad/entity/SysUserSync.java
+193
-0
src/main/java/com/cmeeting/ad/filter/RobotJwtAuthenticationTokenFilter.java
+61
-0
src/main/java/com/cmeeting/ad/service/CustomUserDetailsService.java
+12
-0
src/main/java/com/cmeeting/ad/service/ILdapService.java
+13
-0
src/main/java/com/cmeeting/ad/service/ISysTenantService.java
+15
-0
src/main/java/com/cmeeting/ad/service/UserService.java
+28
-0
src/main/java/com/cmeeting/ad/service/impl/DetailsServiceImpl.java
+46
-0
src/main/java/com/cmeeting/ad/service/impl/LdapServiceImpl.java
+46
-0
src/main/java/com/cmeeting/ad/service/impl/SysTenantServiceImpl.java
+21
-0
src/main/java/com/cmeeting/ad/service/impl/UserServiceImpl.java
+248
-0
src/main/java/com/cmeeting/ad/util/JwtUtil.java
+86
-0
src/main/java/com/cmeeting/ad/util/SecurityUtil.java
+64
-0
src/main/java/com/cmeeting/ad/vo/ApplicationUserVO.java
+130
-0
src/main/java/com/cmeeting/ad/vo/ApplicationVo.java
+25
-0
src/main/java/com/cmeeting/ad/vo/UserVo.java
+71
-0
src/main/java/com/cmeeting/config/MasterDataSourceConfig.java
+11
-8
src/main/java/com/cmeeting/constant/CategoryConstant.java
+23
-0
src/main/java/com/cmeeting/constant/FilterConstant.java
+5
-0
src/main/java/com/cmeeting/constant/LoginTypeConstant.java
+7
-0
src/main/java/com/cmeeting/constant/LoginUserConstant.java
+10
-0
src/main/java/com/cmeeting/constant/UserAdminRouteConstant.java
+132
-0
src/main/java/com/cmeeting/controller/RecordTemplateController.java
+9
-0
src/main/java/com/cmeeting/controller/UserController.java
+0
-25
src/main/java/com/cmeeting/dto/UserDTO.java
+11
-0
src/main/java/com/cmeeting/job/CmeetingJob.java
+4
-2
src/main/java/com/cmeeting/job/EmailPushTask.java
+2
-4
src/main/java/com/cmeeting/job/FileProcessTask.java
+53
-6
src/main/java/com/cmeeting/mapper/primary/CommonMapper.java
+43
-0
src/main/java/com/cmeeting/mapper/primary/RecordTemplatePermissionMapper.java
+16
-0
src/main/java/com/cmeeting/mapper/primary/SysTenantMapper.java
+15
-0
src/main/java/com/cmeeting/mapper/secondary/SysUserSysMapper.java
+3
-1
src/main/java/com/cmeeting/pojo/RecordTemplatePermission.java
+57
-0
src/main/java/com/cmeeting/service/RecordTemplatePermissionService.java
+9
-0
src/main/java/com/cmeeting/service/UserService.java
+0
-10
src/main/java/com/cmeeting/service/impl/MeetingInfoServiceImpl.java
+16
-26
src/main/java/com/cmeeting/service/impl/RecordTemplatePermissionServiceImpl.java
+97
-0
src/main/java/com/cmeeting/service/impl/TencentMeetingServiceImpl.java
+66
-82
src/main/java/com/cmeeting/service/impl/UserServiceImpl.java
+0
-56
src/main/java/com/cmeeting/util/AESUtils.java
+156
-0
src/main/java/com/cmeeting/util/HttpClientUtils.java
+763
-0
src/main/java/com/cmeeting/util/IPUtils.java
+78
-0
src/main/java/com/cmeeting/util/UrlEncoderUtil.java
+19
-0
src/main/java/com/cmeeting/util/UserAdminConfig.java
+13
-0
src/main/java/com/cmeeting/util/UserAdminTokenUtil.java
+57
-0
src/main/java/com/cmeeting/vo/CorpRecordsVO.java
+3
-3
src/main/java/com/cmeeting/vo/RecordTemplateVO.java
+28
-0
src/main/resources/application.yml
+29
-1
src/main/resources/mapper/primary/CommonMapper.xml
+71
-0
src/main/resources/mapper/primary/RecordTemplatePermissionMapper.xml
+20
-0
src/main/resources/mapper/primary/SysTenantMapper.xml
+7
-0
没有找到文件。
pom.xml
浏览文件 @
5cb7fb90
...
@@ -32,7 +32,7 @@
...
@@ -32,7 +32,7 @@
<maven.compiler.source>
1.8
</maven.compiler.source>
<maven.compiler.source>
1.8
</maven.compiler.source>
<maven.compiler.target>
1.8
</maven.compiler.target>
<maven.compiler.target>
1.8
</maven.compiler.target>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<project.build.sourceEncoding>
UTF-8
</project.build.sourceEncoding>
<mybatis-plus.version>
3.
5.3.1
</mybatis-plus.version>
<mybatis-plus.version>
3.
3.0
</mybatis-plus.version>
</properties>
</properties>
<dependencyManagement>
<dependencyManagement>
<dependencies>
<dependencies>
...
@@ -328,6 +328,35 @@
...
@@ -328,6 +328,35 @@
<artifactId>
spring-boot-starter-data-redis
</artifactId>
<artifactId>
spring-boot-starter-data-redis
</artifactId>
<version>
2.7.0
</version>
<!-- 与你的Spring Boot版本一致 -->
<version>
2.7.0
</version>
<!-- 与你的Spring Boot版本一致 -->
</dependency>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-data-ldap
</artifactId>
<version>
2.3.3.RELEASE
</version>
</dependency>
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
<artifactId>
httpclient
</artifactId>
<version>
4.5.5
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-security
</artifactId>
<version>
2.7.0
</version>
</dependency>
<!--security核心包-->
<dependency>
<groupId>
org.springframework.security
</groupId>
<artifactId>
spring-security-core
</artifactId>
<version>
5.7.0
</version>
</dependency>
<dependency>
<groupId>
io.jsonwebtoken
</groupId>
<artifactId>
jjwt
</artifactId>
<version>
0.9.1
</version>
</dependency>
</dependencies>
</dependencies>
<build>
<build>
...
...
src/main/java/com/cmeeting/ad/config/CustomAuthenticationProvider.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
config
;
import
com.cmeeting.ad.service.CustomUserDetailsService
;
import
org.springframework.security.authentication.*
;
import
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.AuthenticationException
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UserDetailsPasswordService
;
import
org.springframework.security.core.userdetails.UserDetailsService
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.security.crypto.factory.PasswordEncoderFactories
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.util.Assert
;
import
java.util.Map
;
/**
* An {@link AuthenticationProvider} implementation that retrieves user details from a
* {@link UserDetailsService}.
*
* @author Ben Alex
* @author Rob Winch zw
* 此方法从DaoAuthenticationProvider中复制过来 因为现在有两种登录方式,一种是原来的登录方式,另一种是手机登录的
* 重写 retrieveUser方法
*/
public
class
CustomAuthenticationProvider
extends
AbstractUserDetailsAuthenticationProvider
{
// ~ Static fields/initializers
// =====================================================================================
/**
* The plaintext password used to perform
* PasswordEncoder#matches(CharSequence, String)} on when the user is
* not found to avoid SEC-2056.
*/
private
static
final
String
USER_NOT_FOUND_PASSWORD
=
"userNotFoundPassword"
;
// ~ Instance fields
// ================================================================================================
private
PasswordEncoder
passwordEncoder
;
/**
* The password used to perform
* {@link PasswordEncoder#matches(CharSequence, String)} on when the user is
* not found to avoid SEC-2056. This is necessary, because some
* {@link PasswordEncoder} implementations will short circuit if the password is not
* in a valid format.
*/
private
volatile
String
userNotFoundEncodedPassword
;
private
CustomUserDetailsService
customUserDetailsService
;
private
UserDetailsPasswordService
userDetailsPasswordService
;
public
CustomAuthenticationProvider
()
{
setPasswordEncoder
(
PasswordEncoderFactories
.
createDelegatingPasswordEncoder
());
}
// ~ Methods
// ========================================================================================================
@SuppressWarnings
(
"deprecation"
)
protected
void
additionalAuthenticationChecks
(
UserDetails
userDetails
,
UsernamePasswordAuthenticationToken
authentication
)
throws
AuthenticationException
{
if
(
authentication
.
getCredentials
()
==
null
)
{
logger
.
debug
(
"Authentication failed: no credentials provided"
);
throw
new
BadCredentialsException
(
messages
.
getMessage
(
"AbstractUserDetailsAuthenticationProvider.badCredentials"
,
"Bad credentials"
));
}
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
// 密码验证在login接口做过了
// if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
// logger.debug("Authentication failed: password does not match stored value");
// throw new BadCredentialsException(messages.getMessage(
// "AbstractUserDetailsAuthenticationProvider.badCredentials",
// "Bad credentials"));
// }
}
protected
void
doAfterPropertiesSet
()
{
Assert
.
notNull
(
this
.
customUserDetailsService
,
"A customUserDetailsService must be set"
);
}
protected
final
UserDetails
retrieveUser
(
String
username
,
UsernamePasswordAuthenticationToken
authentication
)
throws
AuthenticationException
{
prepareTimingAttackProtection
();
Map
<
String
,
String
>
details
=
(
Map
<
String
,
String
>)
authentication
.
getDetails
();
try
{
String
uid
=
details
.
get
(
"userId"
);
String
tenantId
=
details
.
get
(
"tenantId"
);
UserDetails
loadedUser
=
this
.
getCustomUserDetailsService
().
loadUser
(
uid
,
tenantId
);
if
(
loadedUser
==
null
)
{
throw
new
InternalAuthenticationServiceException
(
"customUserDetailsService returned null, which is an interface contract violation"
);
}
return
loadedUser
;
}
catch
(
UsernameNotFoundException
ex
)
{
mitigateAgainstTimingAttack
(
authentication
);
throw
ex
;
}
catch
(
InternalAuthenticationServiceException
ex
)
{
throw
ex
;
}
catch
(
Exception
ex
)
{
throw
new
InternalAuthenticationServiceException
(
ex
.
getMessage
(),
ex
);
}
}
@Override
protected
Authentication
createSuccessAuthentication
(
Object
principal
,
Authentication
authentication
,
UserDetails
user
)
{
boolean
upgradeEncoding
=
this
.
userDetailsPasswordService
!=
null
&&
this
.
passwordEncoder
.
upgradeEncoding
(
user
.
getPassword
());
if
(
upgradeEncoding
)
{
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
String
newPassword
=
this
.
passwordEncoder
.
encode
(
presentedPassword
);
user
=
this
.
userDetailsPasswordService
.
updatePassword
(
user
,
newPassword
);
}
return
super
.
createSuccessAuthentication
(
principal
,
authentication
,
user
);
}
private
void
prepareTimingAttackProtection
()
{
if
(
this
.
userNotFoundEncodedPassword
==
null
)
{
this
.
userNotFoundEncodedPassword
=
this
.
passwordEncoder
.
encode
(
USER_NOT_FOUND_PASSWORD
);
}
}
private
void
mitigateAgainstTimingAttack
(
UsernamePasswordAuthenticationToken
authentication
)
{
if
(
authentication
.
getCredentials
()
!=
null
)
{
String
presentedPassword
=
authentication
.
getCredentials
().
toString
();
this
.
passwordEncoder
.
matches
(
presentedPassword
,
this
.
userNotFoundEncodedPassword
);
}
}
/**
* Sets the PasswordEncoder instance to be used to encode and validate passwords. If
* not set, the password will be compared using {@link PasswordEncoderFactories#createDelegatingPasswordEncoder()}
*
* @param passwordEncoder must be an instance of one of the {@code PasswordEncoder}
* types.
*/
public
void
setPasswordEncoder
(
PasswordEncoder
passwordEncoder
)
{
Assert
.
notNull
(
passwordEncoder
,
"passwordEncoder cannot be null"
);
this
.
passwordEncoder
=
passwordEncoder
;
this
.
userNotFoundEncodedPassword
=
null
;
}
protected
PasswordEncoder
getPasswordEncoder
()
{
return
passwordEncoder
;
}
public
CustomUserDetailsService
getCustomUserDetailsService
()
{
return
customUserDetailsService
;
}
public
void
setCustomUserDetailsService
(
CustomUserDetailsService
customUserDetailsService
)
{
this
.
customUserDetailsService
=
customUserDetailsService
;
}
public
void
setUserDetailsPasswordService
(
UserDetailsPasswordService
userDetailsPasswordService
)
{
this
.
userDetailsPasswordService
=
userDetailsPasswordService
;
}
}
src/main/java/com/cmeeting/ad/config/CustomWhiteConfigProperties.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
config
;
import
lombok.Data
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author liuzhenmeng
* @date 2024/2/4 17:05
*/
@Data
@Component
@ConfigurationProperties
(
prefix
=
"robot.custom"
)
public
class
CustomWhiteConfigProperties
{
/**
* 接口白名单
*/
private
List
<
String
>
whiteTables
=
new
ArrayList
<>();
}
src/main/java/com/cmeeting/ad/config/LdapConfig.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
config
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.ldap.core.LdapTemplate
;
import
org.springframework.ldap.core.support.LdapContextSource
;
@Configuration
public
class
LdapConfig
{
@Value
(
"${ldap.url}"
)
private
String
ldapUrl
;
@Value
(
"${ldap.base}"
)
private
String
ldapBase
;
@Value
(
"${ldap.adName}"
)
private
String
ldapUserDn
;
@Value
(
"${ldap.adPwd}"
)
private
String
ldapUserPwd
;
@Value
(
"${ldap.referral}"
)
private
String
ldapReferral
;
/*
* SpringLdap的javaConfig注入方式
*/
@Bean
public
LdapTemplate
ldapTemplate
()
{
return
new
LdapTemplate
(
contextSourceTarget
());
}
/*
* SpringLdap的javaConfig注入方式
*/
@Bean
public
LdapContextSource
contextSourceTarget
()
{
LdapContextSource
ldapContextSource
=
new
LdapContextSource
();
ldapContextSource
.
setUrl
(
ldapUrl
);
ldapContextSource
.
setBase
(
ldapBase
);
ldapContextSource
.
setUserDn
(
ldapUserDn
);
ldapContextSource
.
setPassword
(
ldapUserPwd
);
ldapContextSource
.
setReferral
(
ldapReferral
);
return
ldapContextSource
;
}
}
src/main/java/com/cmeeting/ad/config/RobotWebSecurityConfig.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
config
;
import
cn.hutool.core.util.ArrayUtil
;
import
com.cmeeting.ad.filter.RobotJwtAuthenticationTokenFilter
;
import
com.cmeeting.ad.service.CustomUserDetailsService
;
import
com.cmeeting.ad.service.UserService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.authentication.AuthenticationProvider
;
import
org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
;
import
org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity
;
import
org.springframework.security.config.annotation.web.builders.HttpSecurity
;
import
org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
;
import
org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
;
import
org.springframework.security.config.http.SessionCreationPolicy
;
import
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
;
import
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
;
import
javax.annotation.Resource
;
import
java.util.List
;
/**
* @Classname WebSecurityConfig
* @Description Security配置类
* @Author robot
* @Date 2019-05-07 09:10
* @Version 1.0
*/
@Slf4j
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity
(
prePostEnabled
=
true
)
public
class
RobotWebSecurityConfig
extends
WebSecurityConfigurerAdapter
{
@Autowired
private
RobotJwtAuthenticationTokenFilter
robotJwtAuthenticationTokenFilter
;
// @Resource
// private RobotJwtCustomTokenFilter robotJwtCustomTokenFilter;
@Autowired
private
CustomWhiteConfigProperties
customWhiteConfigProperties
;
@Autowired
private
CustomUserDetailsService
customUserDetailsService
;
@Autowired
private
RobotWhiteConfigProperties
configProperties
;
/**
* 解决 无法直接注入 AuthenticationManager
*
* @return
* @throws Exception
*/
@Bean
@Override
public
AuthenticationManager
authenticationManagerBean
()
throws
Exception
{
return
super
.
authenticationManagerBean
();
}
@Bean
(
name
=
"customAuthenticationProvider"
)
public
AuthenticationProvider
customAuthenticationProvider
()
{
CustomAuthenticationProvider
customAuthenticationProvider
=
new
CustomAuthenticationProvider
();
customAuthenticationProvider
.
setPasswordEncoder
(
bCryptPasswordEncoder
());
customAuthenticationProvider
.
setHideUserNotFoundExceptions
(
false
);
customAuthenticationProvider
.
setCustomUserDetailsService
(
customUserDetailsService
);
return
customAuthenticationProvider
;
}
@Bean
(
name
=
"bCryptPasswordEncoder"
)
public
BCryptPasswordEncoder
bCryptPasswordEncoder
()
{
BCryptPasswordEncoder
bCryptPasswordEncoder
=
new
BCryptPasswordEncoder
();
return
bCryptPasswordEncoder
;
}
/**
* 配置策略
*
* @param httpSecurity
* @throws Exception
*/
@Override
protected
void
configure
(
HttpSecurity
httpSecurity
)
throws
Exception
{
List
<
String
>
whiteTables
=
configProperties
.
getWhiteTables
();
String
[]
api
=
ArrayUtil
.
toArray
(
whiteTables
,
String
.
class
);
List
<
String
>
customWhiteTables
=
customWhiteConfigProperties
.
getWhiteTables
();
String
[]
customApi
=
ArrayUtil
.
toArray
(
customWhiteTables
,
String
.
class
);
httpSecurity
// 由于使用的是JWT,我们这里不需要csrf
.
csrf
().
disable
()
// 基于token,所以不需要session
.
sessionManagement
().
sessionCreationPolicy
(
SessionCreationPolicy
.
STATELESS
).
and
()
// 过滤请求
.
authorizeRequests
()
// 对于登录login 图标 要允许匿名访问
.
antMatchers
(
customApi
).
access
(
"@robotJwtCustomTokenFilter.checkToken(request)"
)
.
antMatchers
(
api
).
anonymous
()
.
antMatchers
(
HttpMethod
.
GET
,
"/*.html"
,
"/**/*.html"
,
"/**/*.css"
,
"/**/*.js"
,
"/**/*.map"
)
.
permitAll
()
.
antMatchers
(
"/error"
).
anonymous
()
.
antMatchers
(
"/user/**"
).
anonymous
()
.
antMatchers
(
"/web/**"
).
anonymous
()
.
antMatchers
(
"/file/**"
)
.
permitAll
()
// 访问/user 需要拥有admin权限
// .antMatchers("/user").hasAuthority("ROLE_ADMIN")
// 除上面外的所有请求全部需要鉴权认证
.
anyRequest
().
authenticated
()
.
and
()
.
headers
().
frameOptions
().
disable
();
// 添加自定义异常入口
// httpSecurity
// .exceptionHandling()
// .authenticationEntryPoint(new RobotAuthenticationEntryPointImpl())
// .accessDeniedHandler(new RobotAccessDeniedHandler());
// 添加JWT filter 用户名登录
httpSecurity
// 添加JWT验证过滤器
.
addFilterBefore
(
robotJwtAuthenticationTokenFilter
,
UsernamePasswordAuthenticationFilter
.
class
);
}
@Override
public
void
configure
(
AuthenticationManagerBuilder
auth
)
throws
Exception
{
// auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
// auth.userDetailsService(mobileUserDetailsService).passwordEncoder(new BCryptPasswordEncoder());
auth
.
authenticationProvider
(
customAuthenticationProvider
());
}
}
src/main/java/com/cmeeting/ad/config/RobotWhiteConfigProperties.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
config
;
import
lombok.Data
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.stereotype.Component
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author 张伟
* @date 2021/2/2 17:47
*/
@Data
@Component
@ConfigurationProperties
(
prefix
=
"robot.white"
)
public
class
RobotWhiteConfigProperties
{
/**
* 接口白名单
*/
private
List
<
String
>
whiteTables
=
new
ArrayList
<>();
private
List
<
String
>
whiteSignUrls
=
new
ArrayList
<>();
}
src/main/java/com/cmeeting/ad/controller/UserController.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
controller
;
import
com.cmeeting.ad.service.UserService
;
import
com.cmeeting.ad.vo.UserVo
;
import
com.cmeeting.util.IPUtils
;
import
com.cmeeting.util.R
;
import
com.cmeeting.ad.vo.ApplicationUserVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.*
;
import
javax.servlet.http.HttpServletRequest
;
@RestController
@RequestMapping
(
"/user"
)
public
class
UserController
{
@Autowired
private
UserService
userService
;
/**
* 咨询窗用
*
* @param vo
* @return
*/
@CrossOrigin
@PostMapping
(
"/login"
)
public
R
login
(
@RequestBody
@Validated
ApplicationUserVO
.
LoginDecrypt
vo
,
HttpServletRequest
request
)
{
String
ipAddr
=
IPUtils
.
getIpAddr
(
request
);
return
userService
.
login
(
vo
.
getAgentId
(),
vo
.
getData
(),
ipAddr
);
}
@PostMapping
(
value
=
"/auth"
)
public
R
auth
(
@Validated
@RequestBody
UserVo
.
Auth
vo
)
{
return
R
.
ok
(
userService
.
auth
(
vo
));
}
/**
* 授权查询接口
* @param search
* @param type
* @param userType
* @param categoryId
* @param targetId
* @param authType
* @return
*/
@GetMapping
(
"/list"
)
public
R
list
(
String
search
,
@RequestParam
Integer
type
,
@RequestParam
Integer
userType
,
String
categoryId
,
@RequestParam
String
targetId
,
Integer
authType
)
{
return
R
.
ok
(
userService
.
list
(
search
,
type
,
userType
,
categoryId
,
targetId
,
authType
));
}
}
\ No newline at end of file
src/main/java/com/cmeeting/ad/entity/ModulePermissions.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
com.baomidou.mybatisplus.annotation.FieldFill
;
import
com.baomidou.mybatisplus.annotation.TableField
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
* 应用用户配置关联表(ModulePermissions)实体类
*
* @author makejava
* @since 2024-05-11 13:22:54
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@TableName
(
"core_module_permissions"
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
ModulePermissions
implements
Serializable
{
private
static
final
long
serialVersionUID
=
686579698726893795L
;
/**
* 配置表主键
*/
private
String
id
;
/**
* 0 分类 1用户
*/
private
Integer
type
;
/**
* 0自建 1 应用 2通讯录 3超管分享
*/
private
Integer
userType
;
/**
* 0 角色授权 1应用授权 2文档授权
*/
private
Integer
source
;
/**
* 关联id(分类id或用户id)
*/
private
String
relId
;
/**
* 创建时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
private
Date
createTime
;
/**
* 更新时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT_UPDATE
)
private
Date
updateTime
;
/**
* 角色id /应用id /文档id
*/
private
String
targetId
;
private
String
tenantId
;
@TableField
(
exist
=
false
)
private
String
name
;
@TableField
(
exist
=
false
)
private
String
deptName
;
}
src/main/java/com/cmeeting/ad/entity/RelPlatformSettingTenant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
* 租户平台设置关联表(RelPlatformSettingTenant)实体类
*
* @author makejava
* @since 2023-06-12 10:03:26
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@TableName
(
"rel_platform_setting_tenant"
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
RelPlatformSettingTenant
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
89908876679147553L
;
private
String
id
;
private
String
tenantId
;
/**
* 菜单id
*/
private
String
platformSettingId
;
private
Integer
isDel
;
private
Date
createTime
;
private
String
createUser
;
private
Date
updateTime
;
private
String
updateUser
;
}
src/main/java/com/cmeeting/ad/entity/RobotSecurityUser.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.fasterxml.jackson.annotation.JsonIgnore
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
org.springframework.security.core.GrantedAuthority
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
java.util.Collection
;
/**
* 登录用户信息
*
* @author 王长伟
* @Date 2019-05-07 09:11
**/
@Setter
@Getter
@Accessors
(
chain
=
true
)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public
class
RobotSecurityUser
implements
UserDetails
{
/**
* 0系统用户 1应用用户 2通信录用户
*/
private
Integer
userType
;
private
String
id
;
private
Long
userId
;
private
String
username
;
@JsonIgnore
private
String
password
;
private
String
tenantId
;
/**
*
* 用户与租户区别字段
*/
private
Integer
type
;
@JsonIgnore
private
Collection
<?
extends
GrantedAuthority
>
authorities
;
private
RoleTree
menus
;
private
SysPlatformSetting
sysPlatformSetting
;
private
String
nick
;
private
String
picture
;
private
String
path
;
@JsonIgnore
private
boolean
accountNonLocked
;
@JsonIgnore
private
boolean
credentialsNonExpired
;
private
String
status
;
private
String
validity
;
private
Integer
reviewStatus
;
private
Long
kfTenantId
;
private
String
nickName
;
/**
* 是否是工单客服人员
*/
private
Boolean
isCustomerOrder
;
/**
* 最大接待量
*/
private
Integer
maxReception
;
/**
* 工号
*/
private
String
jobNo
;
/**
* 是否过期
*/
private
Boolean
overdue
;
private
String
language
;
/**
* 返回分配给用户的角色列表
*
* @return
*/
@Override
public
Collection
<?
extends
GrantedAuthority
>
getAuthorities
()
{
return
null
;
}
/**
* 账户是否未过期,过期无法验证
* @return
*/
@Override
public
boolean
isAccountNonExpired
()
{
return
true
;
}
/**
* 指定用户是否解锁,锁定的用户无法进行身份验证
* @return
*/
@Override
public
boolean
isAccountNonLocked
()
{
return
true
;
}
/**
* 指示是否未过期的用户的凭据(密码),过期的凭据防止认证
* @return
*/
@Override
public
boolean
isCredentialsNonExpired
()
{
return
true
;
}
/**
* 是否可用 ,禁用的用户不能身份验证
* @return
*/
@Override
public
boolean
isEnabled
()
{
return
true
;
}
public
Boolean
getOverdue
()
{
if
(
StrUtil
.
isNotBlank
(
validity
)){
return
DateUtil
.
parseDate
(
validity
).
getTime
()<
DateUtil
.
date
().
getTime
();
}
else
{
return
false
;
}
}
}
src/main/java/com/cmeeting/ad/entity/RoleTree.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.io.Serializable
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* @author: 王长伟
*/
@Getter
@Setter
public
class
RoleTree
implements
Serializable
{
private
static
final
long
serialVersionUID
=
1L
;
private
List
<
String
>
tenantCenter
=
new
ArrayList
<>();
private
List
<
String
>
interactCenter
=
new
ArrayList
<>();
private
List
<
String
>
knowledgeCenter
=
new
ArrayList
<>();
private
List
<
String
>
llmCenter
=
new
ArrayList
<>();
private
List
<
String
>
statisticsCenter
=
new
ArrayList
<>();
private
List
<
String
>
securityCenter
=
new
ArrayList
<>();
private
List
<
String
>
robotCenter
=
new
ArrayList
<>();
private
List
<
String
>
staffCenter
=
new
ArrayList
<>();
private
List
<
String
>
processCenter
=
new
ArrayList
<>();
}
src/main/java/com/cmeeting/ad/entity/SysMenu.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
com.baomidou.mybatisplus.annotation.*
;
import
com.baomidou.mybatisplus.extension.activerecord.Model
;
import
lombok.Data
;
import
lombok.EqualsAndHashCode
;
import
lombok.experimental.Accessors
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Objects
;
/**
* <p>
* 菜单权限表
* </p>
*
* @author robot
* @since 2019-04-21
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@TableName
(
"sys_menu"
)
public
class
SysMenu
extends
Model
<
SysMenu
>
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* 菜单ID
*/
@TableId
(
value
=
"id"
,
type
=
IdType
.
ASSIGN_ID
)
private
Integer
id
;
/**
* 菜单名称
*/
private
String
name
;
/**
* 菜单权限标识
*/
private
String
perms
;
/**
* 前端path / 即跳转路由
*/
private
String
path
;
/**
* 菜单组件
*/
private
String
component
;
/**
* 父菜单ID
*/
private
Integer
parentId
;
/**
* 图标
*/
private
String
icon
;
/**
* 是否为外链
*/
private
Boolean
isAdmin
;
/**
* 排序
*/
private
Integer
sort
;
/**
* 菜单类型 (类型 1:目录 2:菜单 3:按钮)
*/
private
Integer
type
;
/**
* 所属大功能模块
*/
private
String
parentSystem
;
/**
* 在租户菜单是否展示 新增
*/
private
Integer
isShow
;
/**
* 创建时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
private
Date
createTime
;
/**
* 更新时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT_UPDATE
)
private
Date
updateTime
;
@TableField
(
fill
=
FieldFill
.
INSERT
)
@TableLogic
private
Integer
isDel
;
/**
* 非数据库字段
* 父菜单名称
*/
@TableField
(
exist
=
false
)
private
String
parentName
;
/**
* 非数据库字段
* 菜单等级
*/
@TableField
(
exist
=
false
)
private
Integer
level
;
/**
* 非数据库字段
* 子菜单
*/
@TableField
(
exist
=
false
)
private
List
<
SysMenu
>
children
;
@TableField
(
exist
=
false
)
private
String
parentPath
;
@TableField
(
exist
=
false
)
private
String
key
;
@TableField
(
exist
=
false
)
private
String
title
;
public
String
getTitle
()
{
return
name
;
}
@Override
public
boolean
equals
(
Object
o
)
{
return
Objects
.
hash
(
id
)
==
o
.
hashCode
();
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
id
);
}
}
src/main/java/com/cmeeting/ad/entity/SysPlatformSetting.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
* 平台设置表(SysPlatformSetting)实体类
*
* @author makejava
* @since 2023-06-12 11:43:45
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@TableName
(
"sys_platform_setting"
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
SysPlatformSetting
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
86441288874834748L
;
/**
* 主键id
*/
private
String
id
;
/**
* 是否使用机器人 0:false 1:true, 默认为1
*/
private
Integer
robot
;
/**
* 是否使用数字人 0:false 1:true, 默认为1
*/
private
Integer
digitalPerson
;
/**
* 是否使用客服系统 0:false 1:true ,默认为1
*/
private
Integer
moduleKefu
;
/**
* 是否使用大语言模型 0:false 1:true ,默认为1
*/
private
Integer
largeLanguage
;
/**
* 是否使用工单系统 0:false 1:true , 默认为1
*/
private
Integer
moduleTicket
;
/**
* 是否使用问答知识点 0:false 1:true, 默认为1
*/
private
Integer
qaKnowledge
;
/**
* 是否使用知识导图 0:false 1:true, 默认为1
*/
private
Integer
atlasKnowledge
;
/**
* 是否使用多轮对话 0:false 1:true ,默认为1
*/
private
Integer
dialogKnowledge
;
/**
* 是否使用文档知识点 0:false 1:true , 默认为1
*/
private
Integer
docKnowledge
;
/**
* logo登录标签地址
*/
private
String
loginLogoUrl
;
/**
* logo首页标签地址
*/
private
String
indexLogoUrl
;
/**
* 背景图片地址
*/
private
String
backgroundUrl
;
/**
* 推广图片地址
*/
private
String
advertiseUrl
;
/**
* 底部信息
*/
private
String
bottomInfo
;
/**
* 创建时间;创建时间
*/
private
Date
createTime
;
/**
* 更新时间;更新时间
*/
private
Date
updateTime
;
/**
* 创建人;创建人id
*/
private
String
createUser
;
/**
* 更新人;更新人id
*/
private
String
updateUser
;
/**
* 删除标识;0正常,1删除,默认为0
*/
private
Integer
isDel
;
private
Integer
isAdmin
;
private
String
agreement
;
}
src/main/java/com/cmeeting/ad/entity/SysTenant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
com.baomidou.mybatisplus.annotation.*
;
import
lombok.Getter
;
import
lombok.Setter
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
* <p>
* 租户表
* </p>
*
* @author robot
* @since 2019-08-10
*/
@Getter
@Setter
public
class
SysTenant
implements
Serializable
{
/**
* 租户id
*/
@TableId
(
value
=
"id"
,
type
=
IdType
.
ASSIGN_ID
)
private
String
id
;
private
String
kefuId
;
/**
* 租户名称
*/
private
String
name
;
/**
* 删除标记
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
@TableLogic
private
Boolean
isDel
;
/**
* 创建时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
private
Date
createTime
;
/**
* 更新时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT_UPDATE
)
private
Date
updateTime
;
/**
* 创建时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
private
String
createUser
;
/**
* 更新时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT_UPDATE
)
private
String
updateUser
;
/**
* 有效期
*/
private
String
validity
;
/**
* 0纯网页 11企业微信第三方应用 12企业微信自建 21钉钉第三方应用 22钉钉自建 3 teams
*/
// private Integer tenantType;
/**
* 启用状态(0: 启用, 1: 禁用)
*/
private
String
status
;
/**
* 备注
*/
private
String
remarks
;
/**
* 机器人数量
*/
private
Integer
robotNums
;
/**
* 知识点数量上限
*/
private
Integer
qaNums
;
private
Integer
atlasNums
;
private
Integer
dialogNums
;
private
Integer
docNums
;
private
Integer
formNums
;
private
Integer
userNums
;
private
Integer
regulatorsNums
;
/**
* 知创建租户的系统用户名称
*/
private
String
userName
;
/**
* 语言
*/
private
String
language
;
@TableField
(
exist
=
false
)
private
Boolean
expired
;
}
src/main/java/com/cmeeting/ad/entity/SysUserSync.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
entity
;
import
com.baomidou.mybatisplus.annotation.*
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
com.fasterxml.jackson.annotation.JsonInclude
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.util.Date
;
/**
* 用户同步表(SysUserSync)实体类
*
* @author makejava
* @since 2024-04-25 14:22:40
*/
@Data
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@TableName
(
"sys_user_sync"
)
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude
(
JsonInclude
.
Include
.
NON_NULL
)
public
class
SysUserSync
implements
Serializable
{
private
static
final
long
serialVersionUID
=
389470942890145726L
;
/**
* 同步用户主键id
*/
@TableId
(
value
=
"id"
,
type
=
IdType
.
ASSIGN_ID
)
private
String
id
;
/**
* 用户唯一标识
*/
private
String
userId
;
/**
* 用户姓名
*/
private
String
name
;
/**
* 姓
*/
private
String
lastName
;
/**
* 部门id(用户同步的时候没有给这个值为默认分类)
*/
private
String
deptId
;
/**
* 名
*/
private
String
firstName
;
/**
* 别名
*/
private
String
nickName
;
/**
* 性别 0男 1女
*/
private
String
gender
;
/**
* 手机号
*/
private
String
phone
;
/**
* 个人邮箱
*/
private
String
email
;
/**
* 公司邮箱
*/
private
String
companyEmail
;
/**
* 部门
*/
private
String
department
;
/**
* 分机号
*/
private
String
extensionNumber
;
/**
* 工位
*/
private
String
workStation
;
/**
* 人员类型
*/
private
String
type
;
/**
* 国家
*/
private
String
country
;
/**
* 城市
*/
private
String
city
;
/**
* 地区
*/
private
String
area
;
/**
* 直属上级
*/
private
String
directlySubordinateSuperior
;
/**
* 虚线上级
*/
private
String
dottedLineSuperior
;
/**
* 职务
*/
private
String
position
;
/**
* 职级
*/
private
String
rank
;
/**
* 人员状态
*/
private
String
state
;
/**
* 入职日期
*/
private
String
entryDate
;
/**
* 入职类型
*/
private
String
entryType
;
/**
* 试用期
*/
private
String
probationPeriod
;
/**
* 转正日期
*/
private
String
probationCompletionDate
;
/**
* 转正状态
*/
private
String
probationCompletionType
;
/**
* 出生日期
*/
private
String
birthDate
;
/**
* 籍贯
*/
private
String
nativePlace
;
/**
* 民族
*/
private
String
nationality
;
/**
* 婚姻状况
*/
private
String
maritalStatus
;
/**
* 政治面貌
*/
private
String
politicalOutlook
;
/**
* 首次参加工作日期
*/
private
String
firstWorkDate
;
/**
* 用户信息
*/
private
Object
allFieldParam
;
/**
* 创建时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
,
timezone
=
"GMT+8"
)
private
Date
createTime
;
/**
* 更新时间
*/
@TableField
(
fill
=
FieldFill
.
INSERT
)
@JsonFormat
(
pattern
=
"yyyy-MM-dd HH:mm:ss"
,
timezone
=
"GMT+8"
)
private
Date
updateTime
;
/**
* 租户id
*/
private
String
tenantId
;
@TableField
(
exist
=
false
)
private
String
path
;
@TableField
(
exist
=
false
)
private
String
deptName
;
}
src/main/java/com/cmeeting/ad/filter/RobotJwtAuthenticationTokenFilter.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
filter
;
import
cn.hutool.core.util.ObjectUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.toolkit.StringUtils
;
import
com.cmeeting.ad.entity.RobotSecurityUser
;
import
com.cmeeting.ad.util.JwtUtil
;
import
com.cmeeting.util.RedisUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.web.authentication.WebAuthenticationDetailsSource
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.filter.OncePerRequestFilter
;
import
javax.annotation.Resource
;
import
javax.servlet.FilterChain
;
import
javax.servlet.ServletException
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
/**
* @Author 王长伟
* @Description token过滤器来验证token有效性
* @Date 00:32 2019-03-17
* @Param
* @return
**/
@Slf4j
@Component
public
class
RobotJwtAuthenticationTokenFilter
extends
OncePerRequestFilter
{
@Resource
private
JwtUtil
jwtUtil
;
@Value
(
"${jwt.expireTime}"
)
private
long
expireTime
;
@Resource
private
RedisUtils
redisUtil
;
@Override
protected
void
doFilterInternal
(
HttpServletRequest
request
,
HttpServletResponse
response
,
FilterChain
chain
)
throws
ServletException
,
IOException
{
String
token
=
jwtUtil
.
getToken
(
request
);
if
(
StringUtils
.
isNotBlank
(
token
))
{
Object
o
=
redisUtil
.
get
(
token
);
RobotSecurityUser
securityUser
=
JSONObject
.
parseObject
(
JSONObject
.
toJSONString
(
o
),
RobotSecurityUser
.
class
);
if
(
ObjectUtil
.
isNotNull
(
securityUser
))
{
UsernamePasswordAuthenticationToken
authenticationToken
=
new
UsernamePasswordAuthenticationToken
(
securityUser
,
null
,
securityUser
.
getAuthorities
());
authenticationToken
.
setDetails
(
new
WebAuthenticationDetailsSource
().
buildDetails
(
request
));
SecurityContextHolder
.
getContext
().
setAuthentication
(
authenticationToken
);
//延长token时间
redisUtil
.
expire
(
token
,
expireTime
);
}
}
chain
.
doFilter
(
request
,
response
);
}
}
src/main/java/com/cmeeting/ad/service/CustomUserDetailsService.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
;
import
org.springframework.security.core.userdetails.UserDetails
;
/**
* 写这个方法的目的是为了让业务实现层能够根据类型执行对应的业务逻辑
*/
public
interface
CustomUserDetailsService
{
UserDetails
loadUser
(
String
uid
,
String
tenantId
);
}
src/main/java/com/cmeeting/ad/service/ILdapService.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
;
public
interface
ILdapService
{
/**
* LDAP用户认证
*/
boolean
authenticate
(
String
loginName
,
String
password
);
}
src/main/java/com/cmeeting/ad/service/ISysTenantService.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.cmeeting.ad.entity.SysTenant
;
/**
* <p>
* 租户表 服务类
* </p>
*
* @author robot
* @since 2019-08-10
*/
public
interface
ISysTenantService
extends
IService
<
SysTenant
>
{
}
src/main/java/com/cmeeting/ad/service/UserService.java
0 → 100644
浏览文件 @
5cb7fb90
// service/UserService.java
package
com
.
cmeeting
.
ad
.
service
;
import
com.cmeeting.ad.entity.RoleTree
;
import
com.cmeeting.ad.entity.SysMenu
;
import
com.cmeeting.ad.vo.UserVo
;
import
com.cmeeting.util.R
;
import
java.util.List
;
public
interface
UserService
{
R
login
(
String
agentId
,
String
data
,
String
ip
);
String
auth
(
UserVo
.
Auth
vo
);
List
<
String
>
getRoleIdByUserId
(
String
tenantId
,
String
userId
,
String
path
);
/**
* 获取登录后授权的菜单
* @param sysMenuList
* @return
*/
RoleTree
getLoginMenus
(
List
<
SysMenu
>
sysMenuList
);
Object
list
(
String
search
,
Integer
type
,
Integer
userType
,
String
categoryId
,
String
targetId
,
Integer
authType
);
}
\ No newline at end of file
src/main/java/com/cmeeting/ad/service/impl/DetailsServiceImpl.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
.
impl
;
import
com.alibaba.fastjson.JSONObject
;
import
com.cmeeting.ad.entity.RobotSecurityUser
;
import
com.cmeeting.ad.service.CustomUserDetailsService
;
import
com.cmeeting.constant.LoginUserConstant
;
import
com.cmeeting.constant.UserAdminRouteConstant
;
import
com.cmeeting.util.HttpClientUtils
;
import
com.cmeeting.util.UserAdminConfig
;
import
com.cmeeting.util.UserAdminTokenUtil
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.security.core.userdetails.UserDetails
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
/**
* 登录实现
*
* @author zw
*/
@Slf4j
@Service
public
class
DetailsServiceImpl
implements
CustomUserDetailsService
{
@Resource
private
UserAdminConfig
userAdminConfig
;
/**
* @return 用户基本信息
* @throws UsernameNotFoundException 用户不存在
*/
@Override
public
UserDetails
loadUser
(
String
uid
,
String
tenantId
)
{
RobotSecurityUser
user
=
new
RobotSecurityUser
();
user
.
setUserType
(
LoginUserConstant
.
SYS
);
String
url
=
userAdminConfig
.
getUserAdminDomain
()
+
UserAdminRouteConstant
.
SyncUser
.
INFO
+
"?id="
+
uid
+
"&tenantId="
+
tenantId
;
JSONObject
jsonObject
=
HttpClientUtils
.
httpGet
(
url
,
UserAdminTokenUtil
.
getUserAdminToken
());
JSONObject
data
=
jsonObject
.
getJSONObject
(
"data"
);
user
.
setId
(
data
.
getString
(
"userId"
));
user
.
setUsername
(
data
.
getString
(
"name"
));
user
.
setNick
(
data
.
getString
(
"nickName"
));
user
.
setTenantId
(
data
.
getString
(
"tenantId"
));
return
user
;
}
}
src/main/java/com/cmeeting/ad/service/impl/LdapServiceImpl.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
.
impl
;
import
com.cmeeting.ad.service.ILdapService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.ldap.core.LdapTemplate
;
import
org.springframework.ldap.support.LdapUtils
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.Resource
;
import
javax.naming.directory.DirContext
;
@Component
@Slf4j
public
class
LdapServiceImpl
implements
ILdapService
{
@Resource
private
LdapTemplate
ldapTemplate
;
@Value
(
"${ldap.domain}"
)
private
String
ldapDomain
;
/**
* LDAP用户认证
*/
@Override
public
boolean
authenticate
(
String
loginName
,
String
password
)
{
String
userDomainName
=
loginName
+
ldapDomain
;
DirContext
ctx
=
null
;
try
{
ctx
=
ldapTemplate
.
getContextSource
().
getContext
(
userDomainName
,
password
);
return
true
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
LdapUtils
.
closeContext
(
ctx
);
}
return
false
;
}
}
src/main/java/com/cmeeting/ad/service/impl/SysTenantServiceImpl.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
.
impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.cmeeting.ad.entity.SysTenant
;
import
com.cmeeting.mapper.primary.SysTenantMapper
;
import
com.cmeeting.ad.service.ISysTenantService
;
import
org.springframework.stereotype.Service
;
/**
* <p>
* 租户表 服务实现类
* </p>
*
* @author robot
* @since 2019-08-10
*/
@Service
public
class
SysTenantServiceImpl
extends
ServiceImpl
<
SysTenantMapper
,
SysTenant
>
implements
ISysTenantService
{
}
src/main/java/com/cmeeting/ad/service/impl/UserServiceImpl.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
service
.
impl
;
import
cn.hutool.core.collection.CollUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSONArray
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.cmeeting.ad.entity.*
;
import
com.cmeeting.ad.util.SecurityUtil
;
import
com.cmeeting.ad.vo.UserVo
;
import
com.cmeeting.mapper.primary.CommonMapper
;
import
com.cmeeting.ad.service.ILdapService
;
import
com.cmeeting.ad.service.ISysTenantService
;
import
com.cmeeting.ad.service.UserService
;
import
com.cmeeting.ad.util.JwtUtil
;
import
com.cmeeting.constant.CategoryConstant
;
import
com.cmeeting.constant.UserAdminRouteConstant
;
import
com.cmeeting.mapper.secondary.SysUserSysMapper
;
import
com.cmeeting.util.*
;
import
com.cmeeting.ad.vo.ApplicationUserVO
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.security.authentication.AuthenticationManager
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.util.*
;
import
java.util.stream.Collectors
;
@Service
@Slf4j
public
class
UserServiceImpl
implements
UserService
{
@Value
(
"${aec.key}"
)
public
String
aesKey
;
@Value
(
"${permission.applicationId}"
)
public
String
applicationId
;
@Value
(
"${removeMenus}"
)
private
String
removeMenus
;
@Value
(
"${jwt.expireTime}"
)
private
String
expireTime
;
@Value
(
"${permission.tenantId}"
)
public
String
permissionTenantId
;
@Resource
private
ILdapService
iLdapService
;
@Resource
private
UserAdminConfig
userAdminConfig
;
@Resource
private
AuthenticationManager
authenticationManager
;
@Resource
private
RedisUtils
redisUtils
;
@Resource
private
ISysTenantService
iTenantService
;
@Resource
private
JwtUtil
jwtUtil
;
@Resource
private
CommonMapper
commonMapper
;
@Resource
private
SysUserSysMapper
sysUserSysMapper
;
@Override
public
R
login
(
String
agentId
,
String
data
,
String
ip
)
{
String
mess
=
AESUtils
.
decrypt
(
data
,
aesKey
);
ApplicationUserVO
.
Login
login
=
JSONObject
.
parseObject
(
mess
,
ApplicationUserVO
.
Login
.
class
);
log
.
info
(
"登录信息:{}"
,
login
);
return
loginByAD
(
login
);
}
@Override
public
String
auth
(
UserVo
.
Auth
vo
)
{
String
userId
=
vo
.
getId
();
String
nick
=
vo
.
getNick
();
HashMap
<
String
,
String
>
stringStringHashMap
=
new
HashMap
<>();
SysTenant
sysTenant
=
iTenantService
.
getById
(
permissionTenantId
);
stringStringHashMap
.
put
(
"userId"
,
userId
);
stringStringHashMap
.
put
(
"tenantId"
,
permissionTenantId
);
stringStringHashMap
.
put
(
"language"
,
sysTenant
.
getLanguage
());
// iUserLoginInfoService.updateInfo(null, userId, tenantId, null);
stringStringHashMap
.
put
(
"nick"
,
nick
);
UsernamePasswordAuthenticationToken
usernamePasswordAuthenticationToken
=
new
UsernamePasswordAuthenticationToken
(
userId
,
permissionTenantId
);
usernamePasswordAuthenticationToken
.
setDetails
(
stringStringHashMap
);
Authentication
authentication
=
authenticationManager
.
authenticate
(
usernamePasswordAuthenticationToken
);
SecurityContextHolder
.
getContext
().
setAuthentication
(
authentication
);
RobotSecurityUser
userDetail
=
(
RobotSecurityUser
)
authentication
.
getPrincipal
();
System
.
out
.
println
(
userId
.
toString
());
String
token
=
jwtUtil
.
generateToken
(
userDetail
);
List
<
SysMenu
>
menuList
=
commonMapper
.
getMenuList
(
permissionTenantId
);
// 需要对menuList进行过滤
// 根据uid查询对应角色,然后查询角色对应的菜单权限
// List<String> roleIdList = getRoleIdByUserId(permissionTenantId, userId, path);
// List<SysMenu> menuList1 = CollectionUtils.isEmpty(roleIdList) ? new ArrayList<>() : commonMapper.getMenuByRoleList(roleIdList, permissionTenantId);
// Set<Integer> menuSet = menuList1.stream().map(SysMenu::getId).collect(Collectors.toSet());
// List<SysMenu> filteredMenu = menuList.stream().filter(menu -> menuSet.contains(menu.getId())).collect(Collectors.toList());
// menuList = (List<SysMenu>) CollectionUtils.intersection(filteredMenu, menuList);
menuList
.
sort
(
Comparator
.
comparingInt
(
SysMenu:
:
getSort
));
// 总库去掉部分菜单
if
(
"system"
.
equals
(
userDetail
.
getUsername
()))
{
List
<
String
>
removeMenuList
=
Arrays
.
asList
(
removeMenus
.
split
(
","
));
int
size
=
menuList
.
size
();
for
(
int
i
=
0
;
i
<
size
;
i
++)
{
SysMenu
sysMenu
=
menuList
.
get
(
i
);
String
tempName
=
sysMenu
.
getName
();
if
(
removeMenuList
.
contains
(
tempName
))
{
menuList
.
remove
(
sysMenu
);
size
-=
1
;
i
-=
1
;
}
}
}
RoleTree
loginMenus
=
getLoginMenus
(
menuList
);
HashSet
<
String
>
set
=
new
HashSet
<>();
for
(
SysMenu
sysMenu
:
menuList
)
{
set
.
add
(
sysMenu
.
getPerms
());
}
if
(
set
.
contains
(
"interactCenter"
))
{
//看是否勾选了首页配置 121是首页菜单的id
loginMenus
.
getInteractCenter
().
add
(
"modelList"
);
loginMenus
.
getInteractCenter
().
add
(
"modelPage"
);
}
if
(
set
.
contains
(
"robotCenter"
))
{
//看是否勾选了首页配置 121是首页菜单的id
loginMenus
.
getRobotCenter
().
add
(
"robotPage"
);
}
if
(
set
.
contains
(
"processCenter"
))
{
//看是否勾选了首页配置 121是首页菜单的id
loginMenus
.
getProcessCenter
().
add
(
"processPage"
);
}
userDetail
.
setMenus
(
loginMenus
);
// SysPlatformSetting platformInfo = relPlatformSettingService.getPlatformInfoByCurrentTenantId(userDetail.getTenantId());
// SysPlatformSetting newSysPlatformSetting = new SysPlatformSetting();
// BeanUtil.copyProperties(platformInfo, newSysPlatformSetting);
// newSysPlatformSetting.setDocKnowledge(0);
// userDetail.setSysPlatformSetting(newSysPlatformSetting);
redisUtils
.
set
(
token
,
userDetail
,
Long
.
parseLong
(
expireTime
));
return
token
;
}
@Override
public
List
<
String
>
getRoleIdByUserId
(
String
tenantId
,
String
userId
,
String
path
)
{
List
<
ModulePermissions
>
permissions
=
commonMapper
.
getRoleByTenantId
(
tenantId
);
Map
<
String
,
List
<
ModulePermissions
>>
userMap
=
permissions
.
stream
().
filter
(
per
->
per
.
getType
()
==
1
).
collect
(
Collectors
.
groupingBy
(
ModulePermissions:
:
getRelId
));
Map
<
String
,
List
<
ModulePermissions
>>
deptMap
=
permissions
.
stream
().
filter
(
per
->
per
.
getType
()
==
0
).
collect
(
Collectors
.
groupingBy
(
ModulePermissions:
:
getRelId
));
List
<
String
>
roleList
=
new
ArrayList
<>();
if
(
userMap
.
containsKey
(
userId
))
{
List
<
ModulePermissions
>
tempPers
=
userMap
.
get
(
userId
);
for
(
ModulePermissions
tempPer
:
tempPers
)
{
roleList
.
add
(
tempPer
.
getTargetId
());
}
}
if
(
path
==
null
&&
tenantId
.
equals
(
"1"
))
{
List
<
String
>
admin
=
new
ArrayList
<>();
admin
.
add
(
"1"
);
return
admin
;
}
if
(
StrUtil
.
isNotBlank
(
path
))
{
String
[]
split
=
path
.
split
(
CategoryConstant
.
ROOT_PATH
);
List
<
String
>
deptList
=
Arrays
.
asList
(
split
).
stream
().
filter
(
StrUtil:
:
isNotBlank
).
collect
(
Collectors
.
toList
());
for
(
String
dept
:
deptList
)
{
if
(
deptMap
.
containsKey
(
dept
))
{
List
<
ModulePermissions
>
tempPers
=
deptMap
.
get
(
dept
);
for
(
ModulePermissions
tempPer
:
tempPers
)
{
roleList
.
add
(
tempPer
.
getTargetId
());
}
}
}
}
return
roleList
;
}
@Override
public
RoleTree
getLoginMenus
(
List
<
SysMenu
>
menuList
)
{
RoleTree
roleTree
=
new
RoleTree
();
if
(
CollUtil
.
isEmpty
(
menuList
))
{
return
roleTree
;
}
menuList
.
forEach
(
it
->
{
if
(
it
.
getParentId
()
!=
0
&&
StrUtil
.
isNotBlank
(
it
.
getPath
()))
{
if
(
it
.
getParentSystem
().
contains
(
"tenantCenter"
))
{
roleTree
.
getTenantCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"interactCenter"
))
{
roleTree
.
getInteractCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"knowledgeCenter"
))
{
roleTree
.
getKnowledgeCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"llmCenter"
))
{
roleTree
.
getLlmCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"statisticsCenter"
))
{
roleTree
.
getStatisticsCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"securityCenter"
))
{
roleTree
.
getSecurityCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"robotCenter"
))
{
roleTree
.
getRobotCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"staffCenter"
))
{
roleTree
.
getStaffCenter
().
add
(
it
.
getPerms
());
}
else
if
(
it
.
getParentSystem
().
contains
(
"processCenter"
))
{
roleTree
.
getProcessCenter
().
add
(
it
.
getPerms
());
}
}
});
return
roleTree
;
}
@Override
public
Object
list
(
String
search
,
Integer
type
,
Integer
userType
,
String
categoryId
,
String
targetId
,
Integer
authType
)
{
String
url
=
userAdminConfig
.
getUserAdminDomain
()
+
"/user/list"
+
"?search="
+
UrlEncoderUtil
.
encode
(
search
.
trim
())
+
"&type="
+
type
+
"&userType=2"
+
"&categoryId="
+
categoryId
+
"&targetId="
+
targetId
;
System
.
out
.
println
(
url
);
JSONObject
object
=
HttpClientUtils
.
httpGet
(
url
,
UserAdminTokenUtil
.
getUserAdminToken
());
return
object
;
}
private
R
loginByAD
(
ApplicationUserVO
.
Login
login
)
{
// AD验证
// boolean auth = iLdapService.authenticate(login.getUsername().trim(), login.getPassword().trim());
if
(
true
)
{
SysUserSync
sysUserSync
=
sysUserSysMapper
.
selectOne
(
new
LambdaQueryWrapper
<
SysUserSync
>()
.
eq
(
SysUserSync:
:
getTenantId
,
permissionTenantId
)
.
eq
(
SysUserSync:
:
getUserId
,
login
.
getUsername
().
trim
()));
// if (code != 0) {
// throw new RuntimeException("用户系统异常!");
// }
// if (data != null && data.size() > 0) {
// JSONArray array = filterData(data, application);
// if (array != null && array.size() > 0) {
// return R.ok(array);
// } else {
// array = filterData(data, null);
// return R.ok(array);
// }
// } else {
// throw new RuntimeException("用户未授权!");
// }
return
R
.
ok
(
sysUserSync
);
}
else
{
return
R
.
error
(
"账号/密码错误!"
);
}
}
}
\ No newline at end of file
src/main/java/com/cmeeting/ad/util/JwtUtil.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
util
;
import
cn.hutool.core.util.StrUtil
;
import
com.cmeeting.ad.entity.RobotSecurityUser
;
import
io.jsonwebtoken.Claims
;
import
io.jsonwebtoken.Jwts
;
import
io.jsonwebtoken.SignatureAlgorithm
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
javax.servlet.http.HttpServletRequest
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* @Classname JwtUtil
* @Description JWT工具类
* @Author robot
* @Date 2019-05-07 09:23
* @Version 1.0
*/
@Component
public
class
JwtUtil
{
/**
* 用户名称
*/
private
static
final
String
USERNAME
=
Claims
.
SUBJECT
;
/**
* 密钥
*/
private
static
final
String
SECRET
=
"badou1001"
;
@Value
(
"${jwt.header}"
)
private
String
tokenHeader
;
@Value
(
"${jwt.tokenHead}"
)
private
String
authTokenStart
;
/**
* 生成令牌
*
* @return 令牌
*/
public
String
generateToken
(
RobotSecurityUser
robotSecurityUser
)
{
Map
<
String
,
Object
>
claims
=
new
HashMap
<>(
1
);
claims
.
put
(
USERNAME
,
robotSecurityUser
.
getUsername
());
claims
.
put
(
"time"
,
System
.
currentTimeMillis
());
return
generateToken
(
claims
);
}
public
String
generateToken
(
String
username
,
String
applicationId
)
{
Map
<
String
,
Object
>
claims
=
new
HashMap
<>(
1
);
claims
.
put
(
USERNAME
,
username
);
claims
.
put
(
"applicationId"
,
applicationId
);
claims
.
put
(
"time"
,
System
.
currentTimeMillis
());
return
generateToken
(
claims
);
}
/**
* 从数据声明生成令牌
*
* @param claims 数据声明
* @return 令牌
*/
private
String
generateToken
(
Map
<
String
,
Object
>
claims
)
{
return
Jwts
.
builder
().
setClaims
(
claims
).
signWith
(
SignatureAlgorithm
.
HS512
,
SECRET
).
compact
();
}
/**
* 获取请求token
*
* @param request
* @return
*/
public
String
getToken
(
HttpServletRequest
request
)
{
String
token
=
request
.
getHeader
(
tokenHeader
);
if
(
StrUtil
.
isNotBlank
(
token
)
&&
token
.
length
()
>
authTokenStart
.
length
())
{
token
=
token
.
substring
(
authTokenStart
.
length
()).
trim
();
}
return
token
;
}
}
src/main/java/com/cmeeting/ad/util/SecurityUtil.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
util
;
import
com.cmeeting.ad.entity.RobotSecurityUser
;
import
lombok.experimental.UtilityClass
;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken
;
import
org.springframework.security.core.Authentication
;
import
org.springframework.security.core.context.SecurityContextHolder
;
/**
* @Classname SecurityUtil
* @Description 安全服务工具类
* @Author robot
* @Date 2019-05-08 10:12
* @Version 1.0
*/
@UtilityClass
public
class
SecurityUtil
{
// public void writeJavaScript(R r, HttpServletResponse response) throws IOException {
// response.setStatus(200);
// response.setCharacterEncoding("UTF-8");
// response.setContentType("application/json; charset=utf-8");
// PrintWriter printWriter = response.getWriter();
// printWriter.write(JSON.toJSONString(r));
// printWriter.flush();
// }
/**
* 获取Authentication
*/
private
Authentication
getAuthentication
()
{
return
SecurityContextHolder
.
getContext
().
getAuthentication
();
}
/**
* 获取用户
*
* @return
*/
public
RobotSecurityUser
getUser
()
{
try
{
return
(
RobotSecurityUser
)
getAuthentication
().
getPrincipal
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"登录状态过期"
);
}
}
/**
* 获取租户信息
*
* @return
*/
public
String
getTenantId
()
{
return
getUser
().
getTenantId
();
}
public
void
setUser
(
RobotSecurityUser
robotSecurityUser
)
{
UsernamePasswordAuthenticationToken
authenticationToken
=
new
UsernamePasswordAuthenticationToken
(
robotSecurityUser
,
null
,
robotSecurityUser
.
getAuthorities
());
SecurityContextHolder
.
getContext
().
setAuthentication
(
authenticationToken
);
}
}
src/main/java/com/cmeeting/ad/vo/ApplicationUserVO.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
vo
;
import
lombok.Data
;
import
java.util.List
;
@Data
public
class
ApplicationUserVO
{
@Data
public
static
class
AddUser
{
private
String
id
;
String
name
;
String
username
;
String
password
;
String
applicationId
;
}
@Data
public
static
class
LoginDecrypt
{
String
data
;
String
applicationId
;
String
agentId
;
}
@Data
public
static
class
Sso
{
String
param
;
String
applicationId
;
}
@Data
public
static
class
Auth
{
String
name
;
String
userId
;
String
applicationId
;
}
@Data
public
static
class
LoginOutVO
{
String
userId
;
String
applicationId
;
}
@Data
public
static
class
StatusVO
{
List
<
String
>
idList
;
Integer
status
;
}
@Data
public
static
class
DisabledVO
{
List
<
String
>
idList
;
/**
* 0启用 1禁用
*/
Integer
disabled
;
}
@Data
public
static
class
Id
{
String
id
;
}
@Data
public
static
class
Login
{
String
username
;
String
password
;
String
type
;
//登录方式: password 密码登录 or code 验证码登录
// String key;
// String code;
String
phoneCode
;
}
@Data
public
static
class
ListVO
{
private
String
fromDate
;
/**
* 结束日期
*/
private
String
toDate
;
private
Integer
current
;
private
Integer
size
;
private
String
content
;
private
Integer
status
;
private
String
applicationId
;
}
@Data
public
static
class
Add
{
private
String
name
;
private
String
phone
;
private
String
password
;
private
String
categoryId
;
private
String
applicationId
;
}
@Data
public
static
class
Edit
{
private
String
id
;
private
String
name
;
private
String
phone
;
private
String
password
;
private
Integer
status
;
}
@Data
public
static
class
BatchEdit
{
private
List
<
String
>
ids
;
private
Integer
status
;
}
@Data
public
static
class
SyncSave
{
private
String
applicationId
;
private
List
<
SyncData
>
syncData
;
@Data
public
static
class
SyncData
{
private
String
id
;
//用户id或者部门id
private
Integer
type
;
//0 分类 1用户
}
}
@Data
public
static
class
BatchDelete
{
private
List
<
String
>
idList
;
}
}
src/main/java/com/cmeeting/ad/vo/ApplicationVo.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
vo
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
/**
* @author liuzhenmeng
* @date 2024/10/31 15:18
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public
class
ApplicationVo
{
private
String
applicationId
;
private
String
applicationName
;
private
Integer
applicationType
;
private
String
tenantId
;
}
src/main/java/com/cmeeting/ad/vo/UserVo.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
ad
.
vo
;
import
lombok.Data
;
/**
* 登录
*/
@Data
public
class
UserVo
{
/**
* 登录
*/
@Data
public
static
class
Login
{
String
username
;
String
password
;
String
key
;
}
@Data
public
static
class
officialSiteLogin
{
String
username
;
String
password
;
}
@Data
public
static
class
LoginDecrypt
{
String
data
;
}
@Data
public
static
class
Auth
{
/**
* 用户id (系统和应用用户的主键id,同步用户的userId)
*/
private
String
id
;
private
String
tenantId
;
/**
* 用户类型:0. 系统用户 1. 应用用户 2. 同步用户
*/
private
Integer
type
;
private
String
username
;
private
String
nick
;
private
String
path
;
}
/**
* 更新昵称和头像
*/
@Data
public
static
class
UpdateNick
{
private
String
nick
;
private
String
picture
;
}
/**
* 更新密码
*/
@Data
public
static
class
UpdatePassword
{
private
String
password
;
private
String
newPassword
;
private
String
repeatPassword
;
}
}
src/main/java/com/cmeeting/config/MasterDataSourceConfig.java
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
config
;
package
com
.
cmeeting
.
config
;
import
com.baomidou.mybatisplus.annotation.DbType
;
import
com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
;
import
com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
;
import
com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.mybatis.spring.SqlSessionTemplate
;
import
org.mybatis.spring.SqlSessionTemplate
;
...
@@ -29,11 +27,16 @@ public class MasterDataSourceConfig {
...
@@ -29,11 +27,16 @@ public class MasterDataSourceConfig {
return
DataSourceBuilder
.
create
().
build
();
return
DataSourceBuilder
.
create
().
build
();
}
}
/**
* 分页插件(3.3.0 版本使用旧版 PaginationInterceptor)
*/
@Bean
@Bean
public
MybatisPlusInterceptor
mybatisPlusInterceptor
()
{
public
PaginationInterceptor
paginationInterceptor
()
{
MybatisPlusInterceptor
interceptor
=
new
MybatisPlusInterceptor
();
PaginationInterceptor
paginationInterceptor
=
new
PaginationInterceptor
();
interceptor
.
addInnerInterceptor
(
new
PaginationInnerInterceptor
(
DbType
.
MYSQL
));
// 设置数据库类型
return
interceptor
;
// 溢出总页数后是否进行处理 (默认不处理,会返回最后一页数据)
paginationInterceptor
.
setOverflow
(
true
);
return
paginationInterceptor
;
}
}
@Primary
@Primary
...
@@ -42,7 +45,7 @@ public class MasterDataSourceConfig {
...
@@ -42,7 +45,7 @@ public class MasterDataSourceConfig {
MybatisSqlSessionFactoryBean
bean
=
new
MybatisSqlSessionFactoryBean
();
MybatisSqlSessionFactoryBean
bean
=
new
MybatisSqlSessionFactoryBean
();
bean
.
setDataSource
(
dataSource
);
bean
.
setDataSource
(
dataSource
);
bean
.
setMapperLocations
(
new
PathMatchingResourcePatternResolver
().
getResources
(
"classpath:mapper/primary/*.xml"
));
bean
.
setMapperLocations
(
new
PathMatchingResourcePatternResolver
().
getResources
(
"classpath:mapper/primary/*.xml"
));
bean
.
setPlugins
(
mybatisPlus
Interceptor
());
bean
.
setPlugins
(
pagination
Interceptor
());
return
bean
.
getObject
();
return
bean
.
getObject
();
}
}
...
...
src/main/java/com/cmeeting/constant/CategoryConstant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
constant
;
/**
* @author 王长伟
*/
public
class
CategoryConstant
{
public
static
final
String
ALL
=
"全部"
;
public
static
final
String
ALL_EN
=
"all"
;
/**
* 根父级id
*/
public
static
final
String
ROOT_ID
=
"0"
;
/**
* 根级路径
*/
public
static
final
String
ROOT_PATH
=
"/"
;
}
src/main/java/com/cmeeting/constant/FilterConstant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
constant
;
public
interface
FilterConstant
{
String
ERROR_CONTROLLER_PATH
=
"/error/throw"
;
}
src/main/java/com/cmeeting/constant/LoginTypeConstant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
constant
;
public
interface
LoginTypeConstant
{
String
PASSWORD
=
"password"
;
String
CODE
=
"code"
;
String
AD
=
"ad"
;
}
src/main/java/com/cmeeting/constant/LoginUserConstant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
constant
;
/**
* 登录的用户类型
*/
public
interface
LoginUserConstant
{
Integer
SYS
=
0
;
Integer
APPLICATION
=
1
;
Integer
SYNC
=
2
;
}
src/main/java/com/cmeeting/constant/UserAdminRouteConstant.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
constant
;
/**
* 用户系统功能接口
*
* @author hong
*/
public
interface
UserAdminRouteConstant
{
String
ACCESS_TOKEN
=
"/chatbot/getAccessToken"
;
/**
* 自建用户
*/
interface
SysUser
{
/**
* 分类查询接口
*/
String
CATEGORY_TREE
=
"/chatbot/user/category/tree"
;
/**
* 创建系统自建用户分类
*/
String
ADD_CATEGORY
=
"/chatbot/user/category/add"
;
/**
* 编辑用户分类
*/
String
EDIT_CATEGORY
=
"/chatbot/user/category/edit"
;
/**
* 删除用户分类
*/
String
DELETE_CATEGORY
=
"/chatbot/user/category/remove"
;
/**
* 查询用户列表
*/
String
UPDATE_PASS
=
"/chatbot/user/updatePass"
;
String
LIST
=
"/chatbot/user/list"
;
/**
* 创建用户
*/
String
ADD
=
"/chatbot/user/add"
;
String
COUNT
=
"/chatbot/user/count"
;
/**
* 更新用户
*/
String
EDIT
=
"/chatbot/user/edit"
;
/**
* 删除用户
*/
String
DELETE
=
"/chatbot/user/delete"
;
/**
* 批量删除用户
*/
String
BATCH_DELETE
=
"/chatbot/user/deleteBatchIds"
;
/**
* 用户详情
*/
String
INFO
=
"/chatbot/user/info"
;
/**
* 根据条件查询所有三类用户
*/
String
FIND
=
"/chatbot/user/find"
;
String
FIND_TENANT_ID
=
"/chatbot/user/findTenantIdByUserId"
;
String
FIND_BY_UID
=
"/chatbot/user/findByUid"
;
String
FIND_USER_BY_UID
=
"/chatbot/user/findUserByUid"
;
String
FIND_NAME
=
"/chatbot/user/findName"
;
//根据用户和分类ID查询对应name
String
FIND_ADMIN_NAME
=
"/chatbot/user/findAdminName"
;
//超管查询根据用户和分类ID查询对应name、checked
String
FIND_SHARE_NAME
=
"/chatbot/user/findShareName"
;
//超管查询根据用户和分类ID查询对应name、checked
String
INIT
=
"/chatbot/user/init"
;
// 创建租户的时候 初始化用户系统 Get请求 参数:tenantId, applicationId
String
PUSH
=
"/chatbot/user/push"
;
String
EXPORT
=
"/chatbot/user/export"
;
}
/**
* 同步用户
*/
interface
SyncUser
{
String
CATEGORY_TREE
=
"/chatbot/user/sync/category/tree"
;
// 查询分类
String
LIST
=
"/chatbot/user/sync/list"
;
//查询用户
String
FIELD_INFO
=
"/chatbot/user/sync/field/info"
;
//查询属性
String
FIELD_UPDATE
=
"/chatbot/user/sync/field/update"
;
//更新属性值
// String ADD = "/chatbot/user/sync/add"; //新增
String
TREE
=
"/chatbot/user/sync/tree"
;
//用户查询
String
INFO
=
"/chatbot/user/sync/info"
;
//用户详情
String
PUSH
=
"/chatbot/user/sync/push"
;
//用户同步
String
ZHONGJI_PUSH
=
"/chatbot/user/sync/zhongji_push"
;
//用户同步-中集同步接口
String
INIT_TEMP_TABLE
=
"/chatbot/user/sync/initTempTable"
;
//初始化临时表
String
HANDEL_PTAH
=
"/chatbot/user/sync/category/handelPath"
;
//用户同步后处理分类
String
COMMIT_OR_ROLLBACK
=
"/chatbot/user/sync/commitOrRollback"
;
//用户同步后处理分类
String
REMOVE
=
"/chatbot/user/sync/field/remove"
;
//属性删除
String
MOVE
=
"/chatbot/user/sync/field/move"
;
//用户同步
String
INIT
=
"/chatbot/user/sync/init"
;
//用户同步
String
DEPART
=
"/chatbot/user/sync/getAllDeptByUserId"
;
//用户部门
String
TRUNCATE
=
"/chatbot/user/sync/truncate"
;
//用户部门
String
ALL_CHILDREN
=
"/chatbot/user/sync/children"
;
//查询部门下所有子部门id以及用户id
String
BATCH_DELETE
=
"/chatbot/user/sync/batchDelete"
;
//用户部门
String
FIND_DEPT_NAME
=
"/chatbot/user/sync/getAllDeptByUserId"
;
//查询部门全路径//用户同步
String
ADMIN_LIST
=
"/chatbot/user/sync/adminList"
;
//超管同步用户授权给租户查询
String
AUTH_LIST
=
"/chatbot/user/sync/authList"
;
//超管同步用户已授权用户/部门查询
String
AUTH
=
"/chatbot/user/sync/auth"
;
//超管同步用户已授权用户/部门查询
String
REMOVE_AUTH
=
"/chatbot/user/sync/removeAuth"
;
//超管同步用户已授权用户/部门查询
String
SHARE_TREE
=
"/chatbot/shareUser/tree"
;
//超管分享的部门查询
String
SHARE_LIST
=
"/chatbot/shareUser/list"
;
//超管分享的用户查询
}
/**
* 应用用户
*/
interface
ApplicationUser
{
String
ADD_CATEGORY
=
"/chatbot/user/application/category/add"
;
// 新增分类
String
EDIT_CATEGORY
=
"/chatbot/user/application/category/edit"
;
// 编辑分类
String
CATEGORY_TREE
=
"/chatbot/user/application/category/tree"
;
// 查询分类
String
DELETE_CATEGORY
=
"/chatbot/user/application/category/remove"
;
// 删除分类
String
ADD
=
"/chatbot/user/application/add"
;
// 新增用户
String
EDIT
=
"/chatbot/user/application/edit"
;
// 编辑用户信息
String
BATCH_EDIT
=
"/chatbot/user/application/batchEdit"
;
// 编辑用户信息
String
BATCH_DELETE
=
"/chatbot/user/application/batchDelete"
;
// 编辑用户信息
String
DELETE
=
"/chatbot/user/application/delete"
;
// 删除用户
String
LIST
=
"/chatbot/user/application/list"
;
// 用户列表
String
INFO
=
"/chatbot/user/application/info"
;
// 用户详情
}
interface
Report
{
String
COUNT
=
"/chatbot/report/user/count"
;
// 应用用户+系统用户 总计和新增
}
}
src/main/java/com/cmeeting/controller/RecordTemplateController.java
浏览文件 @
5cb7fb90
...
@@ -4,12 +4,14 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
...
@@ -4,12 +4,14 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.service.MeetingRecordTemplateService
;
import
com.cmeeting.service.MeetingRecordTemplateService
;
import
com.cmeeting.service.RecordTemplatePermissionService
;
import
com.cmeeting.util.R
;
import
com.cmeeting.util.R
;
import
com.cmeeting.vo.RecordTemplateVO
;
import
com.cmeeting.vo.RecordTemplateVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
...
@@ -18,6 +20,8 @@ import java.time.LocalDateTime;
...
@@ -18,6 +20,8 @@ import java.time.LocalDateTime;
public
class
RecordTemplateController
{
public
class
RecordTemplateController
{
@Autowired
@Autowired
private
MeetingRecordTemplateService
recordTemplateService
;
private
MeetingRecordTemplateService
recordTemplateService
;
@Resource
private
RecordTemplatePermissionService
recordTemplatePermissionService
;
@PostMapping
(
"/create"
)
@PostMapping
(
"/create"
)
public
R
create
(
@RequestBody
MeetingRecordTemplate
recordTemplate
)
{
public
R
create
(
@RequestBody
MeetingRecordTemplate
recordTemplate
)
{
...
@@ -77,4 +81,9 @@ public class RecordTemplateController {
...
@@ -77,4 +81,9 @@ public class RecordTemplateController {
String
template
=
recordTemplateService
.
templateUpload
(
file
,
id
);
String
template
=
recordTemplateService
.
templateUpload
(
file
,
id
);
return
R
.
ok
(
template
);
return
R
.
ok
(
template
);
}
}
@PostMapping
(
"/auth"
)
public
R
auth
(
@RequestBody
RecordTemplateVO
.
TemplatePermissionVO
vo
)
{
return
R
.
ok
(
recordTemplatePermissionService
.
auth
(
vo
));
}
}
}
src/main/java/com/cmeeting/controller/UserController.java
deleted
100644 → 0
浏览文件 @
0db0455d
// controller/UserController.java
package
com
.
cmeeting
.
controller
;
import
com.cmeeting.dto.LoginDTO
;
import
com.cmeeting.service.UserService
;
import
com.cmeeting.vo.LoginVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
@RestController
@RequestMapping
(
"/api/user"
)
public
class
UserController
{
@Autowired
private
UserService
userService
;
@PostMapping
(
"/login"
)
public
LoginVO
login
(
@RequestBody
LoginDTO
loginDTO
)
{
return
userService
.
login
(
loginDTO
);
}
}
\ No newline at end of file
src/main/java/com/cmeeting/dto/UserDTO.java
浏览文件 @
5cb7fb90
...
@@ -31,4 +31,14 @@ public class UserDTO {
...
@@ -31,4 +31,14 @@ public class UserDTO {
* 邮箱
* 邮箱
*/
*/
private
String
email
;
private
String
email
;
@Override
public
String
toString
()
{
return
"UserDTO{"
+
"userName='"
+
userName
+
'\''
+
", wid='"
+
wid
+
'\''
+
", tid='"
+
tid
+
'\''
+
", email='"
+
email
+
'\''
+
'}'
;
}
}
}
\ No newline at end of file
src/main/java/com/cmeeting/job/CmeetingJob.java
浏览文件 @
5cb7fb90
...
@@ -93,7 +93,6 @@ public class CmeetingJob {
...
@@ -93,7 +93,6 @@ public class CmeetingJob {
}
}
// @Scheduled(fixedRate = 10 * 60 * 1000,initialDelay = 2 * 60 * 1000)
// @Scheduled(fixedRate = 10 * 60 * 1000,initialDelay = 2 * 60 * 1000)
@Scheduled
(
fixedRate
=
10
*
60
*
1000
)
public
void
execute
()
{
public
void
execute
()
{
// 定义时间格式化器
// 定义时间格式化器
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
...
@@ -115,6 +114,8 @@ public class CmeetingJob {
...
@@ -115,6 +114,8 @@ public class CmeetingJob {
if
(
CollectionUtils
.
isEmpty
(
accessUserIds
))
{
if
(
CollectionUtils
.
isEmpty
(
accessUserIds
))
{
log
.
info
(
"无生成纪要权限的人员"
);
log
.
info
(
"无生成纪要权限的人员"
);
return
;
return
;
}
else
{
log
.
info
(
"生成纪要权限人员:->{}"
,
accessUserIds
.
toString
());
}
}
List
<
TencentMeetingVO
.
RecordFile
>
meetingFiles
=
tencentMeetingService
.
getMeetingFiles
(
accessUserIds
);
List
<
TencentMeetingVO
.
RecordFile
>
meetingFiles
=
tencentMeetingService
.
getMeetingFiles
(
accessUserIds
);
...
@@ -131,7 +132,8 @@ public class CmeetingJob {
...
@@ -131,7 +132,8 @@ public class CmeetingJob {
/**
/**
* 定时扫描早于一小时之前的,所有未重试过的会议,重新生成纪要
* 定时扫描早于一小时之前的,所有未重试过的会议,重新生成纪要
*/
*/
@Scheduled
(
fixedRate
=
30
*
60
*
1000
,
initialDelay
=
10
*
60
*
1000
)
// @Scheduled(fixedRate = 30 * 60 * 1000,initialDelay = 10 * 60 * 1000)
@Scheduled
(
fixedRate
=
30
*
60
*
1000
)
public
void
meetingMinutesRetry
()
{
public
void
meetingMinutesRetry
()
{
try
{
try
{
log
.
info
(
"-------生成纪要重试定时任务开始-------"
);
log
.
info
(
"-------生成纪要重试定时任务开始-------"
);
...
...
src/main/java/com/cmeeting/job/EmailPushTask.java
浏览文件 @
5cb7fb90
...
@@ -58,11 +58,9 @@ public class EmailPushTask {
...
@@ -58,11 +58,9 @@ public class EmailPushTask {
.
eq
(
subMeetingId
!=
null
,
MeetingInfo:
:
getSubMeetingId
,
subMeetingId
));
.
eq
(
subMeetingId
!=
null
,
MeetingInfo:
:
getSubMeetingId
,
subMeetingId
));
while
(
retryCount
.
intValue
()
<=
MAX_RETRY
&&
!
isSuccess
)
{
while
(
retryCount
.
intValue
()
<=
MAX_RETRY
&&
!
isSuccess
)
{
try
{
try
{
String
targetFileName
;
String
meetingName
;
String
meetingName
;
String
recordXmlPath
=
meetingId
+
"-recordXmlPath-"
+
IdUtil
.
fastSimpleUUID
()
+
"xml"
;
String
xml
;
String
xml
;
try
(
InputStream
is
=
minioUtils
.
getFile
(
recordXmlPath
)){
try
(
InputStream
is
=
minioUtils
.
getFile
(
meetingInfo
.
getRecordXml
()
)){
xml
=
convertInputStreamToString
(
is
);
xml
=
convertInputStreamToString
(
is
);
}
catch
(
Exception
e
){
}
catch
(
Exception
e
){
log
.
error
(
e
.
getMessage
());
log
.
error
(
e
.
getMessage
());
...
@@ -86,7 +84,7 @@ public class EmailPushTask {
...
@@ -86,7 +84,7 @@ public class EmailPushTask {
XWPFTemplate
template
=
XWPFTemplate
.
compile
(
inputStream
).
render
(
dataModel
);
XWPFTemplate
template
=
XWPFTemplate
.
compile
(
inputStream
).
render
(
dataModel
);
template
.
writeAndClose
(
new
FileOutputStream
(
dataNetworkMinutesPath
));
template
.
writeAndClose
(
new
FileOutputStream
(
dataNetworkMinutesPath
));
byte
[]
recordXmlData
=
Files
.
readAllBytes
(
Paths
.
get
(
dataNetworkMinutesPath
));
byte
[]
recordXmlData
=
Files
.
readAllBytes
(
Paths
.
get
(
dataNetworkMinutesPath
));
minioUtils
.
upload
(
recordXmlPath
,
recordXmlData
);
minioUtils
.
upload
(
meetingInfo
.
getRecordXml
()
,
recordXmlData
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
}
}
...
...
src/main/java/com/cmeeting/job/FileProcessTask.java
浏览文件 @
5cb7fb90
...
@@ -25,8 +25,7 @@ import com.tencentcloudapi.wemeet.Client;
...
@@ -25,8 +25,7 @@ import com.tencentcloudapi.wemeet.Client;
import
com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder
;
import
com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder
;
import
com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator
;
import
com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator
;
import
com.tencentcloudapi.wemeet.service.meetings.api.MeetingsApi
;
import
com.tencentcloudapi.wemeet.service.meetings.api.MeetingsApi
;
import
com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsMeetingIdParticipantsGet200Response
;
import
com.tencentcloudapi.wemeet.service.meetings.model.*
;
import
com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsMeetingIdParticipantsGet200ResponseParticipantsInner
;
import
com.tencentcloudapi.wemeet.service.records.api.RecordsApi
;
import
com.tencentcloudapi.wemeet.service.records.api.RecordsApi
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200Response
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200Response
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner
;
...
@@ -42,6 +41,7 @@ import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
...
@@ -42,6 +41,7 @@ import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import
org.apache.poi.xwpf.usermodel.XWPFDocument
;
import
org.apache.poi.xwpf.usermodel.XWPFDocument
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
java.io.*
;
import
java.io.*
;
import
java.math.BigInteger
;
import
java.math.BigInteger
;
...
@@ -51,7 +51,10 @@ import java.nio.file.Files;
...
@@ -51,7 +51,10 @@ import java.nio.file.Files;
import
java.nio.file.Paths
;
import
java.nio.file.Paths
;
import
java.security.SecureRandom
;
import
java.security.SecureRandom
;
import
java.text.MessageFormat
;
import
java.text.MessageFormat
;
import
java.time.Instant
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.time.ZoneId
;
import
java.time.format.DateTimeFormatter
;
import
java.time.format.DateTimeFormatter
;
import
java.util.*
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentHashMap
;
...
@@ -94,9 +97,50 @@ public class FileProcessTask {
...
@@ -94,9 +97,50 @@ public class FileProcessTask {
.
withSecret
(
tencentSecretId
,
tencentSecretKey
)
.
withSecret
(
tencentSecretId
,
tencentSecretKey
)
.
build
();
.
build
();
try
{
try
{
//已保存的会议信息
MeetingInfo
meetingInfo
=
meetingInfoMapper
.
selectOne
(
new
LambdaQueryWrapper
<
MeetingInfo
>()
MeetingInfo
meetingInfo
=
meetingInfoMapper
.
selectOne
(
new
LambdaQueryWrapper
<
MeetingInfo
>()
.
eq
(
MeetingInfo:
:
getMeetingId
,
meetingId
)
.
eq
(
MeetingInfo:
:
getMeetingId
,
meetingId
)
.
eq
(
subMeetingId
!=
null
,
MeetingInfo:
:
getSubMeetingId
,
subMeetingId
));
.
eq
(
subMeetingId
!=
null
,
MeetingInfo:
:
getSubMeetingId
,
subMeetingId
));
//下面再查一遍会议信息的意义是,为了获取会议中的子会议Id,如果是周期会议,需要保存下来(重要)
MeetingsApi
.
ApiV1MeetingsMeetingIdGetRequest
meetingRequest
=
new
MeetingsApi
.
ApiV1MeetingsMeetingIdGetRequest
.
Builder
(
meetingId
)
.
operatorId
(
tencentAdminUserId
)
.
operatorIdType
(
"1"
)
.
instanceid
(
"0"
)
.
build
();
MeetingsApi
.
ApiV1MeetingsMeetingIdGetResponse
meetingResponse
=
client
.
meetings
().
v1MeetingsMeetingIdGet
(
meetingRequest
,
new
JWTAuthenticator
.
Builder
()
.
nonce
(
BigInteger
.
valueOf
(
Math
.
abs
((
new
SecureRandom
()).
nextInt
())))
.
timestamp
(
String
.
valueOf
(
System
.
currentTimeMillis
()
/
1000L
)));
V1MeetingsMeetingIdGet200Response
meetingResponseData
=
meetingResponse
.
getData
();
List
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner
>
meetingInfoList
=
meetingResponseData
.
getMeetingInfoList
();
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner
meetingItem
=
meetingInfoList
.
get
(
0
);
//会议类型
//0:一次性会议
//1:周期性会议
Long
meetingType
=
meetingItem
.
getMeetingType
();
if
(
meetingType
.
intValue
()
==
1
){
//如果是周期会议,获取子会议的ID,用于查询参会人员
List
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInnerSubMeetingsInner
>
subMeetings
=
meetingItem
.
getSubMeetings
();
//如果主持人突然取消了后续的所有周期会议,subMeetings列表会返回null
if
(!
CollectionUtils
.
isEmpty
(
subMeetings
)){
LocalDate
meetingStartDate
=
meetingInfo
.
getStartTime
().
toLocalDate
();
Optional
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInnerSubMeetingsInner
>
subMeeting
=
subMeetings
.
stream
().
filter
(
item
->
Instant
.
ofEpochSecond
(
Long
.
valueOf
(
item
.
getStartTime
())).
atZone
(
ZoneId
.
systemDefault
()).
toLocalDate
().
equals
(
meetingStartDate
))
.
findFirst
();
if
(!
subMeeting
.
isPresent
()){
log
.
error
(
"周期会议"
+
meetingId
+
"未知子会议ID"
);
// processLogService.log(meeting.getMeetingId(),subMeetingId,"周期会议"+meetingId+"未知子会议ID");
retryCount
++;
continue
;
}
subMeetingId
=
subMeeting
.
get
().
getSubMeetingId
();
}
else
{
subMeetingId
=
meetingItem
.
getCurrentSubMeetingId
();
log
.
info
(
"周期会议"
+
meetingId
+
"的子会议列表为空,获取当前子会议号"
);
// processLogService.log(meeting.getMeetingId(),subMeetingId,"周期会议"+meetingId+"的子会议列表为空,获取当前子会议号");
}
}
// 获取参会成员明细
// 获取参会成员明细
MeetingsApi
.
ApiV1MeetingsMeetingIdParticipantsGetRequest
participantsRequest
=
MeetingsApi
.
ApiV1MeetingsMeetingIdParticipantsGetRequest
participantsRequest
=
...
@@ -502,8 +546,10 @@ public class FileProcessTask {
...
@@ -502,8 +546,10 @@ public class FileProcessTask {
//特殊处理map格式
//特殊处理map格式
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
map
.
entrySet
())
{
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
map
.
entrySet
())
{
Map
<
String
,
Object
>
value
=
(
Map
<
String
,
Object
>)
entry
.
getValue
();
Map
<
String
,
Object
>
value
=
(
Map
<
String
,
Object
>)
entry
.
getValue
();
Object
realValue
=
value
.
get
(
""
);
//取出正确的value并设置
entry
.
setValue
(
realValue
);
String
realValue
=
String
.
valueOf
(
value
.
get
(
""
)).
replaceAll
(
"^\\n+"
,
""
);
//内容段首移除换行,段末追加换行(会议名称结尾不换行
entry
.
setValue
(
realValue
.
endsWith
(
"\n"
)
||
"meeting_name"
.
equals
(
entry
.
getKey
())
||
"meeting_purpose"
.
equals
(
entry
.
getKey
())
?
realValue
:
realValue
+
"\n"
);
}
}
return
map
;
return
map
;
}
}
...
@@ -514,7 +560,7 @@ public class FileProcessTask {
...
@@ -514,7 +560,7 @@ public class FileProcessTask {
* @return
* @return
*/
*/
private
String
extractXmlFromMarkdown
(
String
markdown
)
{
private
String
extractXmlFromMarkdown
(
String
markdown
)
{
StringBuffer
sb
=
null
;
StringBuffer
sb
;
try
{
try
{
int
start
=
markdown
.
indexOf
(
"<"
);
int
start
=
markdown
.
indexOf
(
"<"
);
if
(
start
==
-
1
){
if
(
start
==
-
1
){
...
@@ -523,7 +569,8 @@ public class FileProcessTask {
...
@@ -523,7 +569,8 @@ public class FileProcessTask {
int
end
=
markdown
.
lastIndexOf
(
">"
)
+
1
;
int
end
=
markdown
.
lastIndexOf
(
">"
)
+
1
;
sb
=
new
StringBuffer
();
sb
=
new
StringBuffer
();
sb
.
append
(
"<root>"
);
sb
.
append
(
"<root>"
);
sb
.
append
(
markdown
.
substring
(
start
,
end
).
trim
());
String
xml
=
markdown
.
substring
(
start
,
end
).
trim
().
replaceAll
(
"\n\n"
,
"\n"
);
sb
.
append
(
xml
);
sb
.
append
(
"</root>"
);
sb
.
append
(
"</root>"
);
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
log
.
info
(
"markdown转xml,markdown->{}"
,
markdown
);
log
.
info
(
"markdown转xml,markdown->{}"
,
markdown
);
...
...
src/main/java/com/cmeeting/mapper/primary/CommonMapper.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
mapper
.
primary
;
import
com.baomidou.mybatisplus.annotation.SqlParser
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.cmeeting.ad.entity.ModulePermissions
;
import
com.cmeeting.ad.entity.SysMenu
;
import
com.cmeeting.ad.vo.ApplicationVo
;
import
com.cmeeting.pojo.User
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
/**
* <p>
* 租户表 Mapper 接口
* </p>
*
* @author robot
* @since 2019-08-10
*/
public
interface
CommonMapper
extends
BaseMapper
<
User
>
{
/**
* 根据租户id获取菜单列表
* @param tenantId
* @return
*/
@SqlParser
(
filter
=
true
)
List
<
SysMenu
>
getMenuList
(
@Param
(
"tenantId"
)
String
tenantId
);
@SqlParser
(
filter
=
true
)
List
<
ModulePermissions
>
getRoleByTenantId
(
@Param
(
"tenantId"
)
String
tenantId
);
@SqlParser
(
filter
=
true
)
List
<
SysMenu
>
getMenuByRoleList
(
@Param
(
"roleIdList"
)
List
<
String
>
roleIdList
,
@Param
(
"tenantId"
)
String
tenantId
);
@SqlParser
(
filter
=
true
)
ApplicationVo
getApplicationNoTenantId
(
@Param
(
"applicationId"
)
String
applicationId
);
List
<
String
>
getSubDeptId
(
@Param
(
value
=
"deptId"
)
String
deptId
);
List
<
String
>
getUsersByDept
(
@Param
(
value
=
"deptIds"
)
List
<
String
>
deptIds
);
}
src/main/java/com/cmeeting/mapper/primary/RecordTemplatePermissionMapper.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
mapper
.
primary
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.cmeeting.pojo.RecordTemplatePermission
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
java.util.List
;
@Mapper
public
interface
RecordTemplatePermissionMapper
extends
BaseMapper
<
RecordTemplatePermission
>
{
void
batchInsert
(
@Param
(
"permissions"
)
List
<
RecordTemplatePermission
>
permissions
);
}
\ No newline at end of file
src/main/java/com/cmeeting/mapper/primary/SysTenantMapper.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
mapper
.
primary
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.cmeeting.ad.entity.SysTenant
;
/**
* <p>
* 租户表 Mapper 接口
* </p>
*
* @author robot
* @since 2019-08-10
*/
public
interface
SysTenantMapper
extends
BaseMapper
<
SysTenant
>
{
}
src/main/java/com/cmeeting/mapper/secondary/SysUserSysMapper.java
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
mapper
.
secondary
;
package
com
.
cmeeting
.
mapper
.
secondary
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.cmeeting.ad.entity.SysUserSync
;
import
com.cmeeting.dto.UserDTO
;
import
com.cmeeting.dto.UserDTO
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
import
org.apache.ibatis.annotations.Param
;
...
@@ -7,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
...
@@ -7,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
import
java.util.List
;
import
java.util.List
;
@Mapper
@Mapper
public
interface
SysUserSysMapper
{
public
interface
SysUserSysMapper
extends
BaseMapper
<
SysUserSync
>
{
String
getCompanyEmail
(
String
wid
,
String
tenantId
);
String
getCompanyEmail
(
String
wid
,
String
tenantId
);
String
getParentDeptId
(
String
deptId
,
String
tenantId
);
String
getParentDeptId
(
String
deptId
,
String
tenantId
);
...
...
src/main/java/com/cmeeting/pojo/RecordTemplatePermission.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
pojo
;
import
com.baomidou.mybatisplus.annotation.IdType
;
import
com.baomidou.mybatisplus.annotation.TableId
;
import
com.baomidou.mybatisplus.annotation.TableName
;
import
lombok.*
;
import
lombok.experimental.Accessors
;
import
java.io.Serializable
;
import
java.time.LocalDateTime
;
/**
* 会议纪要模板实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@EqualsAndHashCode
(
callSuper
=
false
)
@Accessors
(
chain
=
true
)
@TableName
(
"cmt_record_template_permission"
)
public
class
RecordTemplatePermission
implements
Serializable
{
private
static
final
long
serialVersionUID
=
-
26238487532381000L
;
/**
* 主键id
*/
@TableId
(
type
=
IdType
.
AUTO
)
private
Integer
id
;
/**
* 模板id
*/
@TableId
(
type
=
IdType
.
AUTO
)
private
Integer
templateId
;
/**
* 模板类型
*/
private
String
templateType
;
/**
* 对象类型
*/
private
String
relType
;
/**
* 对象id
*/
private
String
relId
;
/**
* 创建时间
*/
private
LocalDateTime
createTime
;
}
\ No newline at end of file
src/main/java/com/cmeeting/service/RecordTemplatePermissionService.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
service
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.cmeeting.pojo.RecordTemplatePermission
;
import
com.cmeeting.vo.RecordTemplateVO
;
public
interface
RecordTemplatePermissionService
extends
IService
<
RecordTemplatePermission
>
{
boolean
auth
(
RecordTemplateVO
.
TemplatePermissionVO
vo
);
}
src/main/java/com/cmeeting/service/UserService.java
deleted
100644 → 0
浏览文件 @
0db0455d
// service/UserService.java
package
com
.
cmeeting
.
service
;
import
com.cmeeting.dto.LoginDTO
;
import
com.cmeeting.vo.LoginVO
;
public
interface
UserService
{
LoginVO
login
(
LoginDTO
loginDTO
);
}
\ No newline at end of file
src/main/java/com/cmeeting/service/impl/MeetingInfoServiceImpl.java
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
service
.
impl
;
package
com
.
cmeeting
.
service
.
impl
;
import
cn.hutool.core.util.IdUtil
;
import
cn.hutool.core.util.IdUtil
;
import
com.alibaba.fastjson2.JSON
;
import
com.alibaba.fastjson2.JSONArray
;
import
com.alibaba.fastjson2.JSONObject
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
...
@@ -55,35 +58,22 @@ public class MeetingInfoServiceImpl extends ServiceImpl<MeetingInfoMapper, Meeti
...
@@ -55,35 +58,22 @@ public class MeetingInfoServiceImpl extends ServiceImpl<MeetingInfoMapper, Meeti
}
}
private
String
convertJSONToXml
(
String
json
)
{
private
String
convertJSONToXml
(
String
json
)
{
try
{
JSONArray
jsonArray
=
JSON
.
parseArray
(
json
);;
// 解析 JSON 字符串
StringBuilder
xmlBuilder
=
new
StringBuilder
();
ObjectMapper
jsonMapper
=
new
ObjectMapper
();
List
<
Map
<
String
,
String
>>
list
=
jsonMapper
.
readValue
(
json
,
List
.
class
);
// 创建 XML 根节点
xmlBuilder
.
append
(
"<root>"
);
Map
<
String
,
Object
>
root
=
new
HashMap
<>();
for
(
int
i
=
0
;
i
<
jsonArray
.
size
();
i
++)
{
JSONObject
jsonObj
=
jsonArray
.
getJSONObject
(
i
);
// 处理每个 JSON 项
String
key
=
jsonObj
.
getString
(
"key"
);
for
(
Map
<
String
,
String
>
item
:
list
)
{
String
label
=
jsonObj
.
getString
(
"keyName"
);
String
keyValue
=
item
.
get
(
"key"
);
String
value
=
jsonObj
.
getString
(
"value"
);
String
keyName
=
item
.
get
(
"keyName"
);
String
value
=
item
.
get
(
"value"
);
// 创建子节点
xmlBuilder
.
append
(
String
.
format
(
"<%s label=\"%s\">%s</%s>"
,
Map
<
String
,
Object
>
subNode
=
new
HashMap
<>();
key
,
label
,
value
,
key
));
subNode
.
put
(
"label"
,
keyName
);
subNode
.
put
(
""
,
value
);
// 添加到根节点
root
.
put
(
keyValue
,
subNode
);
}
// 转换为 XML
XmlMapper
xmlMapper
=
new
XmlMapper
();
return
xmlMapper
.
writeValueAsString
(
root
);
}
catch
(
IOException
e
)
{
log
.
error
(
"JSON 转 XML 失败: "
+
e
.
getMessage
());
throw
new
RuntimeException
(
"JSON 转 XML 失败"
,
e
);
}
}
xmlBuilder
.
append
(
"</root>"
);
return
xmlBuilder
.
toString
();
}
}
}
}
src/main/java/com/cmeeting/service/impl/RecordTemplatePermissionServiceImpl.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
service
.
impl
;
import
com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
;
import
com.cmeeting.mapper.primary.CommonMapper
;
import
com.cmeeting.mapper.primary.RecordTemplatePermissionMapper
;
import
com.cmeeting.pojo.CoreModulePermissions
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.pojo.RecordTemplatePermission
;
import
com.cmeeting.service.MeetingRecordTemplateService
;
import
com.cmeeting.service.RecordTemplatePermissionService
;
import
com.cmeeting.vo.RecordTemplateVO
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
javax.annotation.Resource
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.stream.Collectors
;
@Service
public
class
RecordTemplatePermissionServiceImpl
extends
ServiceImpl
<
RecordTemplatePermissionMapper
,
RecordTemplatePermission
>
implements
RecordTemplatePermissionService
{
@Resource
private
MeetingRecordTemplateService
recordTemplateService
;
@Resource
private
CommonMapper
commonMapper
;
/**
* 授权
* @param vo
*/
@Override
public
boolean
auth
(
RecordTemplateVO
.
TemplatePermissionVO
vo
)
{
List
<
RecordTemplateVO
.
PermissionItem
>
permissionItems
=
vo
.
getPermissionItems
();
if
(
CollectionUtils
.
isEmpty
(
permissionItems
)
||
vo
.
getTemplateId
()
==
null
){
return
false
;
}
MeetingRecordTemplate
template
=
recordTemplateService
.
getById
(
vo
.
getTemplateId
());
if
(
template
==
null
){
throw
new
RuntimeException
(
"模板不存在"
);
}
List
<
RecordTemplatePermission
>
permissions
=
new
ArrayList
<>();
// List<RecordTemplateVO.PermissionItem> deptPermissions = permissionItems.stream().filter(item -> "1".equals(item.getRelType())).collect(Collectors.toList());
// List<RecordTemplateVO.PermissionItem> userPermissions = permissionItems.stream().filter(item -> "2".equals(item.getRelType())).collect(Collectors.toList());
// for (RecordTemplateVO.PermissionItem userPermission : userPermissions) {
// RecordTemplatePermission permission = RecordTemplatePermission.builder()
// .templateId(vo.getTemplateId())
// .templateType(template.getType())
// .relType(userPermission.getRelType())
// .relId(userPermission.getRelId())
// .createTime(now)
// .build();
// permissions.add(permission);
// }
// List<String> deptPath = new ArrayList<>();
// for (RecordTemplateVO.PermissionItem deptPermission : deptPermissions) {
// String deptId = deptPermission.getRelId();
// getDeptPath(deptPath,deptId);
// }
// List<String> accessUserIds = !CollectionUtils.isEmpty(deptPath) ? commonMapper.getUsersByDept(deptPath) : new ArrayList<>();
LocalDateTime
now
=
LocalDateTime
.
now
();
for
(
RecordTemplateVO
.
PermissionItem
permissionItem
:
permissionItems
)
{
RecordTemplatePermission
permission
=
RecordTemplatePermission
.
builder
()
.
templateId
(
vo
.
getTemplateId
())
.
templateType
(
template
.
getType
())
.
relType
(
permissionItem
.
getRelType
())
.
relId
(
permissionItem
.
getRelId
())
.
createTime
(
now
)
.
build
();
permissions
.
add
(
permission
);
}
baseMapper
.
batchInsert
(
permissions
);
return
true
;
}
/**
* 获取部门的路径
* @param deptPath
* @param deptId
*/
private
void
getDeptPath
(
List
<
String
>
deptPath
,
String
deptId
)
{
if
(!
deptPath
.
contains
(
deptId
))
deptPath
.
add
(
deptId
);
List
<
String
>
subDeptIds
=
commonMapper
.
getSubDeptId
(
deptId
);
if
(
CollectionUtils
.
isEmpty
(
subDeptIds
))
return
;
for
(
String
subDeptId
:
subDeptIds
)
{
//部门id去重
if
(!
deptPath
.
contains
(
subDeptId
)){
deptPath
.
add
(
subDeptId
);
getDeptPath
(
deptPath
,
subDeptId
);
}
}
}
}
\ No newline at end of file
src/main/java/com/cmeeting/service/impl/TencentMeetingServiceImpl.java
浏览文件 @
5cb7fb90
...
@@ -337,7 +337,10 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
...
@@ -337,7 +337,10 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
long
startTime
=
now
.
minusDays
(
2
).
toEpochSecond
();
long
startTime
=
now
.
minusDays
(
2
).
toEpochSecond
();
long
endTime
=
now
.
toEpochSecond
();
long
endTime
=
now
.
toEpochSecond
();
AtomicInteger
currentPage
=
new
AtomicInteger
(
1
);
AtomicInteger
currentPage
=
new
AtomicInteger
(
1
);
Integer
totalPage
=
1
;
//获取总页数
CorpRecordsVO
firstData
=
fetchMeetingRecords
(
tencentAdminUserId
,
1
,
startTime
,
endTime
,
1
,
20
);
Integer
totalPage
=
firstData
.
getTotalPage
();
//目前已存储的会议id
//目前已存储的会议id
List
<
String
>
meetingIds
=
meetingInfoMapper
.
getAllMeetingIds
();
List
<
String
>
meetingIds
=
meetingInfoMapper
.
getAllMeetingIds
();
...
@@ -346,7 +349,6 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
...
@@ -346,7 +349,6 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
while
(
currentPage
.
intValue
()
<=
totalPage
){
while
(
currentPage
.
intValue
()
<=
totalPage
){
CorpRecordsVO
data
=
fetchMeetingRecords
(
tencentAdminUserId
,
1
,
startTime
,
endTime
,
currentPage
.
getAndIncrement
(),
20
);
CorpRecordsVO
data
=
fetchMeetingRecords
(
tencentAdminUserId
,
1
,
startTime
,
endTime
,
currentPage
.
getAndIncrement
(),
20
);
//设置总页数
//设置总页数
totalPage
=
data
.
getTotalPage
();
if
(
data
!=
null
&&
data
.
getRecordMeetings
()
!=
null
&&
!
data
.
getRecordMeetings
().
isEmpty
())
{
if
(
data
!=
null
&&
data
.
getRecordMeetings
()
!=
null
&&
!
data
.
getRecordMeetings
().
isEmpty
())
{
List
<
CorpRecordsVO
.
RecordMeeting
>
meetings
=
data
.
getRecordMeetings
();
List
<
CorpRecordsVO
.
RecordMeeting
>
meetings
=
data
.
getRecordMeetings
();
...
@@ -377,64 +379,41 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
...
@@ -377,64 +379,41 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
.
instanceid
(
"0"
)
.
instanceid
(
"0"
)
.
build
();
.
build
();
try
{
try
{
MeetingsApi
.
ApiV1MeetingsMeetingIdGetResponse
meetingResponse
=
//如果数据库中已有相同会议id的记录,跳过同步
client
.
meetings
().
v1MeetingsMeetingIdGet
(
meetingRequest
,
new
JWTAuthenticator
.
Builder
()
if
(!
meetingIds
.
contains
(
meetingId
)){
.
nonce
(
BigInteger
.
valueOf
(
Math
.
abs
((
new
SecureRandom
()).
nextInt
())))
log
.
info
(
"【会议检索】新的会议meetingId->{}"
,
meeting
.
getMeetingId
());
.
timestamp
(
String
.
valueOf
(
System
.
currentTimeMillis
()
/
1000L
)));
List
<
CorpRecordsVO
.
RecordFile
>
recordFiles
=
meeting
.
getRecordFiles
();
V1MeetingsMeetingIdGet200Response
meetingResponseData
=
meetingResponse
.
getData
();
//按转录文件时间升序,便于后续的内容拼接
List
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner
>
meetingInfoList
=
meetingResponseData
.
getMeetingInfoList
();
List
<
String
>
recordFileIdList
=
recordFiles
.
stream
().
sorted
(
Comparator
.
comparingLong
(
CorpRecordsVO
.
RecordFile
::
getRecordStartTime
))
//尝试获取会议详情
.
map
(
CorpRecordsVO
.
RecordFile
::
getRecordFileId
).
collect
(
Collectors
.
toList
());
if
(
meetingInfoList
!=
null
&&
meetingInfoList
.
size
()
>
0
){
TencentMeetingVO
.
RecordFile
recordFileItem
=
TencentMeetingVO
.
RecordFile
.
builder
()
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner
meetingInfo
=
meetingInfoList
.
get
(
0
);
.
recordFileIdList
(
recordFileIdList
).
meetingId
(
meetingId
).
subMeetingId
(
subMeetingId
).
build
();
//会议类型
//0:一次性会议
String
hostId
;
//1:周期性会议
String
hostName
;
Long
meetingType
=
meetingInfo
.
getMeetingType
();
//优先使用会议列表中已有的主持人字段
if
(
meetingType
.
intValue
()
==
1
){
if
(
StringUtils
.
isNotEmpty
(
meeting
.
getHostUserId
())){
//如果是周期会议,获取子会议的ID,用于查询参会人员
hostId
=
meeting
.
getHostUserId
();
List
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInnerSubMeetingsInner
>
subMeetings
=
meetingInfo
.
getSubMeetings
();
hostName
=
meetingMap
.
containsKey
(
hostId
)
?
meetingMap
.
get
(
hostId
)
:
null
;
//如果主持人突然取消了后续的所有周期会议,subMeetings列表会返回null
log
.
info
(
"从会议列表中成功获取到主持人信息"
);
if
(!
CollectionUtils
.
isEmpty
(
subMeetings
)){
}
else
{
LocalDate
meetingStartDate
=
Instant
.
ofEpochMilli
(
meeting
.
getMediaStartTime
()).
atZone
(
ZoneId
.
systemDefault
()).
toLocalDate
();
//判断主持人是否存在,如果主持人未参会,是查不到主持人的
Optional
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInnerSubMeetingsInner
>
subMeeting
=
subMeetings
.
stream
().
filter
(
item
->
//如果主持人未参会,使用会议详情中的创建人作为主持人
Instant
.
ofEpochSecond
(
Long
.
valueOf
(
item
.
getStartTime
())).
atZone
(
ZoneId
.
systemDefault
()).
toLocalDate
().
equals
(
meetingStartDate
))
MeetingsApi
.
ApiV1MeetingsMeetingIdGetResponse
meetingResponse
=
.
findFirst
();
client
.
meetings
().
v1MeetingsMeetingIdGet
(
meetingRequest
,
new
JWTAuthenticator
.
Builder
()
if
(!
subMeeting
.
isPresent
()){
.
nonce
(
BigInteger
.
valueOf
(
Math
.
abs
((
new
SecureRandom
()).
nextInt
())))
log
.
error
(
"周期会议"
+
meetingId
+
"未知子会议ID"
);
.
timestamp
(
String
.
valueOf
(
System
.
currentTimeMillis
()
/
1000L
)));
// processLogService.log(meeting.getMeetingId(),subMeetingId,"周期会议"+meetingId+"未知子会议ID");
V1MeetingsMeetingIdGet200Response
meetingResponseData
=
meetingResponse
.
getData
();
continue
;
List
<
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner
>
meetingInfoList
=
meetingResponseData
.
getMeetingInfoList
();
}
V1MeetingsMeetingIdGet200ResponseMeetingInfoListInner
meetingInfo
=
meetingInfoList
.
get
(
0
);
subMeetingId
=
subMeeting
.
get
().
getSubMeetingId
();
//会议详情中有主持人信息
}
else
{
if
(!
CollectionUtils
.
isEmpty
(
meetingInfo
.
getCurrentHosts
())){
subMeetingId
=
meetingInfo
.
getCurrentSubMeetingId
();
log
.
info
(
"尝试从会议详情中获取主持人信息"
);
log
.
info
(
"周期会议"
+
meetingId
+
"的子会议列表为空,获取当前子会议号"
);
// processLogService.log(meeting.getMeetingId(),subMeetingId,"周期会议"+meetingId+"的子会议列表为空,获取当前子会议号");
}
}
//如果数据库中已有相同会议id的记录,跳过同步
if
(!
meetingIds
.
contains
(
meetingId
)){
log
.
info
(
"【会议检索】新的会议meetingId->{},开始持久化"
,
meeting
.
getMeetingId
());
List
<
CorpRecordsVO
.
RecordFile
>
recordFiles
=
meeting
.
getRecordFiles
();
//按转录文件时间升序,便于后续的内容拼接
List
<
String
>
recordFileIdList
=
recordFiles
.
stream
().
sorted
(
Comparator
.
comparingLong
(
CorpRecordsVO
.
RecordFile
::
getRecordStartTime
))
.
map
(
CorpRecordsVO
.
RecordFile
::
getRecordFileId
).
collect
(
Collectors
.
toList
());
TencentMeetingVO
.
RecordFile
recordFileItem
=
TencentMeetingVO
.
RecordFile
.
builder
()
.
recordFileIdList
(
recordFileIdList
).
meetingId
(
meetingId
).
subMeetingId
(
subMeetingId
).
build
();
String
hostId
;
String
hostName
;
//优先使用会议列表中已有的主持人字段
if
(
StringUtils
.
isNotEmpty
(
meeting
.
getHostUserId
())){
hostId
=
meeting
.
getHostUserId
();
hostName
=
meetingMap
.
containsKey
(
hostId
)
?
meetingMap
.
get
(
hostId
)
:
null
;
}
else
if
(!
CollectionUtils
.
isEmpty
(
meetingInfo
.
getCurrentHosts
())){
//判断主持人是否存在,如果主持人未参会,是查不到主持人的
//如果主持人未参会,使用会议详情中的创建人作为主持人
hostId
=
meetingInfo
.
getCurrentHosts
().
get
(
0
).
getUserid
();
hostId
=
meetingInfo
.
getCurrentHosts
().
get
(
0
).
getUserid
();
hostName
=
meetingMap
.
containsKey
(
hostId
)
?
meetingMap
.
get
(
hostId
)
:
null
;
hostName
=
meetingMap
.
containsKey
(
hostId
)
?
meetingMap
.
get
(
hostId
)
:
null
;
log
.
info
(
"主持人会中缺席,默认会议创建人为主持人"
);
// processLogService.log(meeting.getMeetingId(),subMeetingId,"未找到主持人,默认会议创建人为主持人");
// processLogService.log(meeting.getMeetingId(),subMeetingId,"未找到主持人,默认会议创建人为主持人");
}
else
{
}
else
{
log
.
info
(
"尝试从参会人员列表中获取主持人信息"
);
// 获取参会成员明细
// 获取参会成员明细
MeetingsApi
.
ApiV1MeetingsMeetingIdParticipantsGetRequest
participantsRequest
=
MeetingsApi
.
ApiV1MeetingsMeetingIdParticipantsGetRequest
participantsRequest
=
new
MeetingsApi
.
ApiV1MeetingsMeetingIdParticipantsGetRequest
new
MeetingsApi
.
ApiV1MeetingsMeetingIdParticipantsGetRequest
...
@@ -468,36 +447,41 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
...
@@ -468,36 +447,41 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
continue
;
continue
;
}
}
}
}
String
email
;
//判断是否有权限生成纪要
}
boolean
generateAccess
=
accessUserIds
.
stream
().
anyMatch
(
item
->
item
.
getTid
().
equals
(
hostId
));
String
email
;
if
(!
generateAccess
){
//判断是否有权限生成纪要
log
.
error
(
"【权限校验】主持人{}没有生成纪要权限,跳过生成"
,
hostId
);
boolean
generateAccess
=
accessUserIds
.
stream
().
anyMatch
(
item
->
item
.
getTid
().
equals
(
hostId
));
if
(!
generateAccess
){
log
.
error
(
"【权限校验】主持人{}没有生成纪要权限,跳过生成"
,
hostId
);
// processLogService.log(meeting.getMeetingId(),subMeetingId,"【权限校验】主持人"+hostId+"没有生成纪要权限,跳过生成");
// processLogService.log(meeting.getMeetingId(),subMeetingId,"【权限校验】主持人"+hostId+"没有生成纪要权限,跳过生成");
continue
;
continue
;
}
}
log
.
info
(
"【权限校验】主持人{}允许生成纪要"
,
hostId
);
log
.
info
(
"【权限校验】主持人{}允许生成纪要"
,
hostId
);
// processLogService.log(meeting.getMeetingId(),subMeetingId,"【权限校验】主持人"+hostId+"允许生成纪要");
// processLogService.log(meeting.getMeetingId(),subMeetingId,"【权限校验】主持人"+hostId+"允许生成纪要");
UserDTO
userDTO
=
accessUserIds
.
stream
().
filter
(
item
->
item
.
getTid
().
equals
(
hostId
)).
findFirst
().
get
();
email
=
userDTO
.
getEmail
();
//会议基本信息保存
MeetingInfo
meetingItem
=
MeetingInfo
.
builder
().
meetingId
(
meetingId
).
meetingCode
(
meetingInfo
.
getMeetingCode
())
UserDTO
userDTO
=
accessUserIds
.
stream
().
filter
(
item
->
item
.
getTid
().
equals
(
hostId
)).
findFirst
().
get
();
.
subject
(
meetingInfo
.
getSubject
())
email
=
userDTO
.
getEmail
();
.
startTime
(
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochSecond
(
Long
.
valueOf
(
meetingInfo
.
getStartTime
())),
ZoneId
.
systemDefault
()))
.
endTime
(
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochSecond
(
Long
.
valueOf
(
meetingInfo
.
getEndTime
())),
ZoneId
.
systemDefault
()))
//会议基本信息保存
.
isGenerated
(
Boolean
.
FALSE
).
emailPushAccess
(
Boolean
.
TRUE
).
isPushed
(
Boolean
.
FALSE
).
syncTime
(
LocalDateTime
.
now
())
MeetingInfo
meetingItem
=
MeetingInfo
.
builder
().
meetingId
(
meetingId
).
meetingCode
(
meeting
.
getMeetingCode
())
.
subMeetingId
(
subMeetingId
).
generateRetry
(
Boolean
.
FALSE
).
pushRetry
(
Boolean
.
FALSE
)
.
subject
(
meeting
.
getSubject
())
.
host
(
hostName
)
.
startTime
(
LocalDateTime
.
ofInstant
(
Instant
.
ofEpochMilli
(
Long
.
valueOf
(
meeting
.
getMediaStartTime
())),
ZoneId
.
systemDefault
()))
.
hostUid
(
hostId
)
// .endTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(Long.valueOf(meeting.getEndTime())), ZoneId.systemDefault()))
.
isGenerated
(
Boolean
.
FALSE
).
emailPushAccess
(
Boolean
.
TRUE
).
isPushed
(
Boolean
.
FALSE
).
syncTime
(
LocalDateTime
.
now
())
.
subMeetingId
(
subMeetingId
).
generateRetry
(
Boolean
.
FALSE
).
pushRetry
(
Boolean
.
FALSE
)
.
host
(
hostName
)
.
hostUid
(
hostId
)
// .participantUsers(participants.stream()
// .participantUsers(participants.stream()
// .map(item->new String(Base64.getDecoder().decode(item.getUserName()))).distinct().collect(Collectors.joining("、")))
// .map(item->new String(Base64.getDecoder().decode(item.getUserName()))).distinct().collect(Collectors.joining("、")))
.
recordFileId
(
recordFileIdList
.
stream
().
collect
(
Collectors
.
joining
(
","
)))
.
recordFileId
(
recordFileIdList
.
stream
().
collect
(
Collectors
.
joining
(
","
)))
.
email
(
email
)
.
email
(
email
)
.
build
();
.
build
();
recordFileUrlList
.
add
(
recordFileItem
);
recordFileUrlList
.
add
(
recordFileItem
);
meetingSaveList
.
add
(
meetingItem
);
meetingSaveList
.
add
(
meetingItem
);
}
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
e
.
printStackTrace
();
...
...
src/main/java/com/cmeeting/service/impl/UserServiceImpl.java
deleted
100644 → 0
浏览文件 @
0db0455d
// service/impl/UserServiceImpl.java
package
com
.
cmeeting
.
service
.
impl
;
import
com.cmeeting.dto.LoginDTO
;
import
com.cmeeting.mapper.primary.UserMapper
;
import
com.cmeeting.pojo.User
;
import
com.cmeeting.service.UserService
;
import
com.cmeeting.vo.LoginVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Qualifier
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.DigestUtils
;
@Service
public
class
UserServiceImpl
implements
UserService
{
@Autowired
private
UserMapper
userMapper
;
@Override
public
LoginVO
login
(
LoginDTO
loginDTO
)
{
// 1. 验证用户名是否存在
User
user
=
userMapper
.
findByUsername
(
loginDTO
.
getUsername
());
if
(
user
==
null
)
{
throw
new
RuntimeException
(
"用户名或密码错误"
);
}
// 2. 验证密码
String
inputPassword
=
encryptPassword
(
loginDTO
.
getPassword
(),
user
.
getSalt
());
if
(!
inputPassword
.
equals
(
user
.
getPassword
()))
{
throw
new
RuntimeException
(
"用户名或密码错误"
);
}
// 3. 生成token (这里简化处理,实际应该用JWT等)
String
token
=
generateToken
(
user
);
// 4. 返回登录结果
LoginVO
loginVO
=
new
LoginVO
();
loginVO
.
setUserId
(
user
.
getId
());
loginVO
.
setUsername
(
user
.
getUsername
());
loginVO
.
setToken
(
token
);
return
loginVO
;
}
private
String
encryptPassword
(
String
password
,
String
salt
)
{
// 实际项目中应该使用更安全的加密方式
return
DigestUtils
.
md5DigestAsHex
((
password
+
salt
).
getBytes
());
}
private
String
generateToken
(
User
user
)
{
// 简化处理,实际应该用JWT等安全方式生成token
return
DigestUtils
.
md5DigestAsHex
((
user
.
getId
()
+
user
.
getUsername
()
+
System
.
currentTimeMillis
()).
getBytes
());
}
}
\ No newline at end of file
src/main/java/com/cmeeting/util/AESUtils.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
util
;
//import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64;
import
cn.hutool.core.codec.Base64
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.util.StringUtils
;
import
javax.crypto.BadPaddingException
;
import
javax.crypto.Cipher
;
import
javax.crypto.IllegalBlockSizeException
;
import
javax.crypto.spec.SecretKeySpec
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.UnsupportedEncodingException
;
import
java.security.InvalidKeyException
;
@Slf4j
public
class
AESUtils
{
//// @Value("${aec.key}")
// public static String AES_KEY = "biaopin123456789" ;
/**
* AES加密+Base64转码
*
* @param data 明文(16进制)
* @return
*/
public
static
String
encrypt
(
String
data
,
String
AES_KEY
)
{
byte
[]
keyb
=
null
;
try
{
keyb
=
AES_KEY
.
getBytes
(
"utf-8"
);
}
catch
(
UnsupportedEncodingException
e1
)
{
e1
.
printStackTrace
();
}
// 明文
SecretKeySpec
sKeySpec
=
new
SecretKeySpec
(
keyb
,
"AES"
);
Cipher
cipher
=
null
;
try
{
cipher
=
Cipher
.
getInstance
(
"AES"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
try
{
cipher
.
init
(
Cipher
.
ENCRYPT_MODE
,
sKeySpec
);
}
catch
(
InvalidKeyException
e
)
{
e
.
printStackTrace
();
}
byte
[]
bjiamihou
=
null
;
String
miwen
=
""
;
try
{
bjiamihou
=
cipher
.
doFinal
(
data
.
getBytes
(
"utf-8"
));
// byte加密后
miwen
=
Base64
.
encode
(
bjiamihou
);
// 密文用base64加密
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
catch
(
BadPaddingException
e
)
{
e
.
printStackTrace
();
}
catch
(
IllegalBlockSizeException
e
)
{
e
.
printStackTrace
();
}
return
miwen
;
}
/**
* Base64解码 + AES解码
*
* @param data 密文 (16进制)
* @return
*/
public
static
String
decrypt
(
String
data
,
String
AES_KEY
){
byte
[]
keyb
=
null
;
try
{
keyb
=
AES_KEY
.
getBytes
(
"utf-8"
);
}
catch
(
UnsupportedEncodingException
e1
)
{
e1
.
printStackTrace
();
}
byte
[]
miwen
=
Base64
.
decode
(
data
);
SecretKeySpec
sKeySpec
=
new
SecretKeySpec
(
keyb
,
"AES"
);
Cipher
cipher
=
null
;
try
{
cipher
=
Cipher
.
getInstance
(
"AES"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
try
{
cipher
.
init
(
Cipher
.
DECRYPT_MODE
,
sKeySpec
);
}
catch
(
InvalidKeyException
e
)
{
e
.
printStackTrace
();
}
byte
[]
bjiemihou
=
null
;
String
mingwen
=
""
;
try
{
bjiemihou
=
cipher
.
doFinal
(
miwen
);
// byte加密后
mingwen
=
new
String
(
bjiemihou
,
"utf-8"
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
mingwen
;
}
public
static
Boolean
decryptSign
(
HttpServletRequest
request
,
String
AES_KEY
){
String
lid
=
request
.
getHeader
(
"lid"
);
log
.
info
(
"lid============="
+
lid
);
String
sign
=
request
.
getHeader
(
"sign"
);
log
.
info
(
"sign============="
+
sign
);
String
decrypt
=
decrypt
(
sign
,
AES_KEY
);
log
.
info
(
"decrypt============="
+
decrypt
);
if
(
StringUtils
.
isEmpty
(
lid
)
&&
StringUtils
.
isEmpty
(
sign
)
&&
StringUtils
.
isEmpty
(
decrypt
)){
return
true
;
}
if
(!
lid
.
equals
(
decrypt
)){
log
.
info
(
"----判定成功"
);
return
true
;
}
return
false
;
}
public
static
void
main
(
String
[]
args
)
throws
Exception
{
int
code
=
1
;
/*String[] arr = {""};
System.out.println(Arrays.toString(arr));
System.out.println(StringUtils.isEmpty(Arrays.toString(arr)));
System.out.println(StringUtils.isEmpty(arr[0]));*/
// String json = "{'username':'yanghanjing','password':'badou123456','key':'12632740','code':4,'isSaveLogin':false}";
// JSONObject jsonObject = JSONObject.parseObject(json);
// Map<String, Object> innerMap = jsonObject.getInnerMap();
// System.out.println(innerMap.get("username"));
//测试加密 feishu feishu123
// String json = "{\"username\":\"hongdongbao1\",\"password\":\"hongdongbao123\",\"key\":\"08277992\",\"code\":"+code+",\"isSaveLogin\":false}";
String
json
=
"{\"username\":\"ceshi_117\",\"password\":\"ceshi123\"}"
;
String
miwen
=
encrypt
(
json
,
"biaopin123456789"
);
// 加密
System
.
out
.
println
(
miwen
);
// 测试解密工具类
/*String data = "ts0oGkerChzxZiOKQCkd/z5Hqvt5g9GXrLsZS0dqgCXIJAGmTgUn/Hfg6ponbjAR2WTk3u8x+VNsFtj8NKrf1hvSV7mjZoOdVHSqU9cx+qbPBi/lhBb+mBKTtuWYhG4HwoPl+NLZmCB18a4susJOfA==";
System.out.println(decrypt(data,"biaopin123456789"));// 解密*/
/*JSONObject ject1 = new JSONObject();
JSONObject ject2 = new JSONObject();
ject1.put("1",1);
ject1.put("2",2);
ject1.put("3",3);
ject2.put("3",3);
ject2.put("1",1);
ject2.put("2",1);
System.out.println(ject1.equals(ject2));*/
}
}
src/main/java/com/cmeeting/util/HttpClientUtils.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
util
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.alibaba.fastjson.JSONObject
;
import
com.baomidou.mybatisplus.core.toolkit.CollectionUtils
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.codec.Charsets
;
import
org.apache.http.*
;
import
org.apache.http.client.ClientProtocolException
;
import
org.apache.http.client.config.RequestConfig
;
import
org.apache.http.client.entity.UrlEncodedFormEntity
;
import
org.apache.http.client.methods.CloseableHttpResponse
;
import
org.apache.http.client.methods.HttpGet
;
import
org.apache.http.client.methods.HttpPost
;
import
org.apache.http.client.utils.URIBuilder
;
import
org.apache.http.conn.ssl.NoopHostnameVerifier
;
import
org.apache.http.conn.ssl.TrustStrategy
;
import
org.apache.http.entity.StringEntity
;
import
org.apache.http.impl.client.CloseableHttpClient
;
import
org.apache.http.impl.client.HttpClientBuilder
;
import
org.apache.http.impl.client.HttpClients
;
import
org.apache.http.message.BasicNameValuePair
;
import
org.apache.http.ssl.SSLContextBuilder
;
import
org.apache.http.util.EntityUtils
;
import
org.springframework.stereotype.Component
;
import
javax.net.ssl.SSLContext
;
import
java.io.*
;
import
java.net.URISyntaxException
;
import
java.security.KeyManagementException
;
import
java.security.KeyStoreException
;
import
java.security.NoSuchAlgorithmException
;
import
java.security.cert.CertificateException
;
import
java.security.cert.X509Certificate
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
@Slf4j
@Component
public
class
HttpClientUtils
{
private
static
RequestConfig
requestConfig
=
null
;
static
{
// 设置请求和传输超时时间
requestConfig
=
RequestConfig
.
custom
().
setSocketTimeout
(
180000
).
setConnectTimeout
(
180000
).
setConnectionRequestTimeout
(
180000
).
build
();
}
/**
* 发送get请求
*
* @param url 路径
* @return
*/
public
static
JSONObject
httpGet
(
String
url
)
{
log
.
info
(
"请求地址:【{}】"
,
url
);
// get请求返回结果
JSONObject
jsonResult
=
null
;
CloseableHttpClient
client
=
HttpClients
.
createDefault
();
// 发送get请求
HttpGet
request
=
new
HttpGet
(
url
);
request
.
setConfig
(
requestConfig
);
try
{
CloseableHttpResponse
response
=
client
.
execute
(
request
);
// 请求发送成功,并得到响应
if
(
response
.
getStatusLine
().
getStatusCode
()
==
HttpStatus
.
SC_OK
)
{
// 读取服务器返回过来的json字符串数据
HttpEntity
entity
=
response
.
getEntity
();
String
strResult
=
EntityUtils
.
toString
(
entity
,
"utf-8"
);
// 把json字符串转换成json对象
jsonResult
=
JSONObject
.
parseObject
(
strResult
);
log
.
info
(
"请求返回结果:【{}】"
,
jsonResult
.
toJSONString
());
}
else
{
log
.
error
(
"get请求提交失败:"
+
url
);
}
}
catch
(
IOException
e
)
{
log
.
error
(
"get请求提交失败:"
+
url
,
e
);
}
finally
{
request
.
releaseConnection
();
}
return
jsonResult
;
}
public
static
JSONObject
httpGet
(
String
url
,
String
token
)
{
log
.
info
(
"请求地址:【{}】"
,
url
);
// get请求返回结果
JSONObject
jsonResult
=
null
;
CloseableHttpClient
client
=
HttpClients
.
createDefault
();
// 发送get请求
HttpGet
request
=
new
HttpGet
(
url
);
if
(
token
!=
null
)
{
request
.
setHeader
(
"Authorization"
,
"Bearer "
+
token
);
}
request
.
setConfig
(
requestConfig
);
try
{
CloseableHttpResponse
response
=
client
.
execute
(
request
);
// 请求发送成功,并得到响应
if
(
response
.
getStatusLine
().
getStatusCode
()
==
HttpStatus
.
SC_OK
)
{
// 读取服务器返回过来的json字符串数据
HttpEntity
entity
=
response
.
getEntity
();
String
strResult
=
EntityUtils
.
toString
(
entity
,
"utf-8"
);
// 把json字符串转换成json对象
jsonResult
=
JSONObject
.
parseObject
(
strResult
);
log
.
info
(
"请求返回结果:【{}】"
,
jsonResult
.
toJSONString
());
}
else
{
log
.
error
(
"get请求提交失败:"
+
url
);
}
}
catch
(
IOException
e
)
{
log
.
error
(
"get请求提交失败:"
+
url
,
e
);
}
finally
{
request
.
releaseConnection
();
}
return
jsonResult
;
}
public
static
JSONObject
httpGet
(
String
url
,
String
token
,
List
<
Header
>
headers
,
boolean
isSafe
)
{
log
.
info
(
"请求地址:【{}】"
,
url
);
// get请求返回结果
JSONObject
jsonResult
=
null
;
// 发送get请求
HttpGet
request
=
new
HttpGet
(
url
);
if
(
token
!=
null
)
{
request
.
setHeader
(
"Authorization"
,
"Bearer "
+
token
);
}
// 设置头参数
if
(
CollectionUtils
.
isNotEmpty
(
headers
))
{
for
(
Header
item
:
headers
)
{
request
.
setHeader
(
item
.
getName
(),
item
.
getValue
());
log
.
info
(
"请求Header:{}={}"
,
item
.
getName
(),
item
.
getValue
());
}
}
request
.
setConfig
(
requestConfig
);
try
{
CloseableHttpClient
client
=
null
;
if
(
isSafe
){
client
=
HttpClientBuilder
.
create
().
build
();
}
else
{
// 创建一个信任所有证书的SSLContext
SSLContext
sslContext
=
SSLContextBuilder
.
create
()
.
loadTrustMaterial
(
new
TrustStrategy
()
{
@Override
public
boolean
isTrusted
(
X509Certificate
[]
chain
,
String
authType
)
throws
CertificateException
{
return
true
;
// 忽略所有证书验证
}
})
.
build
();
client
=
HttpClientBuilder
.
create
().
setSSLContext
(
sslContext
)
.
setSSLHostnameVerifier
(
new
NoopHostnameVerifier
())
.
build
();
}
CloseableHttpResponse
response
=
client
.
execute
(
request
);
// 请求发送成功,并得到响应
if
(
response
.
getStatusLine
().
getStatusCode
()
==
HttpStatus
.
SC_OK
)
{
// 读取服务器返回过来的json字符串数据
HttpEntity
entity
=
response
.
getEntity
();
String
strResult
=
EntityUtils
.
toString
(
entity
,
"utf-8"
);
// 把json字符串转换成json对象
jsonResult
=
JSONObject
.
parseObject
(
strResult
);
log
.
info
(
"请求返回结果:【{}】"
,
jsonResult
.
toJSONString
());
}
else
{
log
.
error
(
"get请求提交失败:{},code:{}"
,
url
,
response
.
getStatusLine
().
getStatusCode
());
}
}
catch
(
IOException
|
NoSuchAlgorithmException
|
KeyStoreException
e
)
{
log
.
error
(
"get请求提交失败:"
+
url
,
e
);
}
catch
(
KeyManagementException
e
)
{
throw
new
RuntimeException
(
e
);
}
finally
{
request
.
releaseConnection
();
}
return
jsonResult
;
}
/**
* get请求,参数放在map里
*
* @param url 请求地址
* @param map 参数map
* @return 响应
*/
public
static
JSONObject
getMap
(
String
url
,
Map
<
String
,
String
>
map
)
{
log
.
info
(
url
+
"getMap-start :"
+
System
.
currentTimeMillis
());
log
.
info
(
"请求地址:【{}】"
,
url
);
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
List
<
NameValuePair
>
pairs
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
String
>
entry
:
map
.
entrySet
())
{
pairs
.
add
(
new
BasicNameValuePair
(
entry
.
getKey
(),
entry
.
getValue
()));
}
CloseableHttpResponse
response
=
null
;
try
{
URIBuilder
builder
=
new
URIBuilder
(
url
);
builder
.
setParameters
(
pairs
);
HttpGet
get
=
new
HttpGet
(
builder
.
build
());
response
=
httpClient
.
execute
(
get
);
log
.
info
(
url
+
"getMap-end :"
+
System
.
currentTimeMillis
());
HttpEntity
entity
=
response
.
getEntity
();
String
resultJson
=
EntityUtils
.
toString
(
entity
);
log
.
info
(
"请求返回的原始数据:【{}】"
,
resultJson
);
JSONObject
result
=
JSONObject
.
parseObject
(
resultJson
);
if
(
response
!=
null
&&
response
.
getStatusLine
().
getStatusCode
()
==
200
)
{
log
.
info
(
"返回结果:【{}】"
,
result
.
toJSONString
());
}
else
{
log
.
info
(
"返回结果异常:【{}】"
,
result
.
toJSONString
());
}
return
result
;
}
catch
(
URISyntaxException
e
)
{
log
.
error
(
"请求失败"
,
e
);
}
catch
(
ClientProtocolException
e
)
{
log
.
error
(
"请求失败"
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"请求失败"
,
e
);
}
finally
{
try
{
httpClient
.
close
();
if
(
response
!=
null
)
{
response
.
close
();
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
return
null
;
}
public
static
JSONObject
postForForm
(
String
url
,
Map
<
String
,
String
>
parms
)
{
log
.
info
(
"请求地址:{}"
,
url
);
HttpPost
httpPost
=
new
HttpPost
(
url
);
ArrayList
<
BasicNameValuePair
>
list
=
new
ArrayList
<>();
parms
.
forEach
((
key
,
value
)
->
list
.
add
(
new
BasicNameValuePair
(
key
,
value
)));
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
try
{
if
(
Objects
.
nonNull
(
parms
)
&&
parms
.
size
()
>
0
)
{
httpPost
.
setEntity
(
new
UrlEncodedFormEntity
(
list
,
"UTF-8"
));
}
HttpResponse
response
=
httpClient
.
execute
(
httpPost
);
HttpEntity
entity
=
response
.
getEntity
();
JSONObject
jsonObject
=
JSON
.
parseObject
(
EntityUtils
.
toString
(
entity
,
"UTF-8"
));
log
.
info
(
"请求结果:{}"
,
jsonObject
.
toJSONString
());
return
jsonObject
;
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
if
(
Objects
.
nonNull
(
httpClient
))
{
try
{
httpClient
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
return
null
;
}
/**
* get请求(用于key-value格式的参数,且带有header请求头)
*
* @param url
* @param map 请求的参数map<key,value>键值对
* @return
*/
public
static
String
doGet
(
String
url
,
Map
<
String
,
String
>
map
)
{
log
.
info
(
"请求地址:【{}】"
,
url
);
// 获取连接客户端工具
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
String
entityStr
=
null
;
CloseableHttpResponse
response
=
null
;
try
{
/*
* 由于GET请求的参数都是拼装在URL地址后方,所以我们要构建一个URL,带参数
*/
URIBuilder
uriBuilder
=
new
URIBuilder
(
url
);
/** 第一种添加参数的形式 */
/*uriBuilder.addParameter("name", "root");
uriBuilder.addParameter("password", "123456");*/
for
(
Map
.
Entry
<
String
,
String
>
entry
:
map
.
entrySet
())
{
uriBuilder
.
addParameter
(
entry
.
getKey
(),
entry
.
getValue
());
}
/** 第二种添加参数的形式 */
/* List<NameValuePair> list = new LinkedList<>();
BasicNameValuePair param1 = new BasicNameValuePair("startTime", "2019-1-1 00:00:00");
BasicNameValuePair param2 = new BasicNameValuePair("endTime", "2019-1-9 00:00:00");
list.add(param1);
list.add(param2);
uriBuilder.setParameters(list);*/
// 根据带参数的URI对象构建GET请求对象
HttpGet
httpGet
=
new
HttpGet
(
uriBuilder
.
build
());
/*
* 添加请求头信息
*/
// 浏览器表示
httpGet
.
addHeader
(
"User-Agent"
,
"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)"
);
// 传输的类型
httpGet
.
addHeader
(
"Content-Type"
,
"application/x-www-form-urlencoded"
);
//header的<key,value>
//httpGet.setHeader(headerKey, headerValue);
// 执行请求
response
=
httpClient
.
execute
(
httpGet
);
// 获得响应的实体对象
HttpEntity
entity
=
response
.
getEntity
();
// 使用Apache提供的工具类进行转换成字符串
entityStr
=
EntityUtils
.
toString
(
entity
,
"UTF-8"
);
log
.
info
(
"返回结果:【{}】"
,
entityStr
);
}
catch
(
ClientProtocolException
e
)
{
log
.
error
(
"Http协议出现问题"
,
e
);
}
catch
(
ParseException
e
)
{
log
.
error
(
"解析错误"
,
e
);
}
catch
(
URISyntaxException
e
)
{
log
.
error
(
"URI解析异常"
,
e
);
}
catch
(
IOException
e
)
{
log
.
error
(
"IO异常"
,
e
);
}
finally
{
// 释放连接
if
(
null
!=
response
)
{
try
{
response
.
close
();
httpClient
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
return
entityStr
;
}
/**
* post请求传输json参数
*
* @param url url地址
* @return
*/
public
static
JSONObject
httpPost
(
String
url
,
cn
.
hutool
.
json
.
JSONObject
jsonParam
,
String
token
)
{
// post请求返回结果
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
JSONObject
jsonResult
=
null
;
HttpPost
httpPost
=
new
HttpPost
(
url
);
// 设置请求和传输超时时间
httpPost
.
setConfig
(
requestConfig
);
if
(
token
!=
null
)
{
httpPost
.
setHeader
(
"Authorization"
,
"Bearer "
+
token
);
}
try
{
if
(
null
!=
jsonParam
)
{
// 解决中文乱码问题
StringEntity
entity
=
new
StringEntity
(
jsonParam
.
toString
(),
"utf-8"
);
entity
.
setContentEncoding
(
"UTF-8"
);
entity
.
setContentType
(
"application/json"
);
httpPost
.
setEntity
(
entity
);
}
CloseableHttpResponse
result
=
httpClient
.
execute
(
httpPost
);
// 请求发送成功,并得到响应
if
(
result
.
getStatusLine
().
getStatusCode
()
==
HttpStatus
.
SC_OK
)
{
String
str
=
""
;
try
{
// 读取服务器返回过来的json字符串数据
str
=
EntityUtils
.
toString
(
result
.
getEntity
(),
"utf-8"
);
// 把json字符串转换成json对象
jsonResult
=
JSONObject
.
parseObject
(
str
);
}
catch
(
Exception
e
)
{
log
.
error
(
"post请求提交失败:"
+
url
,
e
);
}
}
}
catch
(
IOException
e
)
{
log
.
error
(
"post请求提交失败:"
+
url
,
e
);
}
finally
{
httpPost
.
releaseConnection
();
}
return
jsonResult
;
}
public
static
JSONObject
httpPost
(
String
url
,
JSONObject
jsonParam
,
String
token
)
{
// post请求返回结果
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
JSONObject
jsonResult
=
null
;
HttpPost
httpPost
=
new
HttpPost
(
url
);
// 设置请求和传输超时时间
httpPost
.
setConfig
(
requestConfig
);
if
(
token
!=
null
)
{
httpPost
.
setHeader
(
"Authorization"
,
"Bearer "
+
token
);
}
try
{
if
(
null
!=
jsonParam
)
{
// 解决中文乱码问题
StringEntity
entity
=
new
StringEntity
(
jsonParam
.
toString
(),
"utf-8"
);
entity
.
setContentEncoding
(
"UTF-8"
);
entity
.
setContentType
(
"application/json"
);
httpPost
.
setEntity
(
entity
);
}
CloseableHttpResponse
result
=
httpClient
.
execute
(
httpPost
);
// 请求发送成功,并得到响应
if
(
result
.
getStatusLine
().
getStatusCode
()
==
HttpStatus
.
SC_OK
)
{
String
str
=
""
;
try
{
// 读取服务器返回过来的json字符串数据
str
=
EntityUtils
.
toString
(
result
.
getEntity
(),
"utf-8"
);
// 把json字符串转换成json对象
jsonResult
=
JSONObject
.
parseObject
(
str
);
}
catch
(
Exception
e
)
{
log
.
error
(
"post请求提交失败:"
+
url
,
e
);
}
}
}
catch
(
IOException
e
)
{
log
.
error
(
"post请求提交失败:"
+
url
,
e
);
}
finally
{
httpPost
.
releaseConnection
();
}
return
jsonResult
;
}
/**
* post请求传输String参数 例如:name=Jack&sex=1&type=2
* Content-type:application/x-www-form-urlencoded
*
* @param url url地址
* @param strParam 参数
* @return
*/
public
static
JSONObject
httpPost
(
String
url
,
String
strParam
)
{
// post请求返回结果
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
JSONObject
jsonResult
=
null
;
HttpPost
httpPost
=
new
HttpPost
(
url
);
httpPost
.
setConfig
(
requestConfig
);
try
{
if
(
null
!=
strParam
)
{
// 解决中文乱码问题
StringEntity
entity
=
new
StringEntity
(
strParam
,
"utf-8"
);
entity
.
setContentEncoding
(
"UTF-8"
);
entity
.
setContentType
(
"application/x-www-form-urlencoded"
);
httpPost
.
setEntity
(
entity
);
}
CloseableHttpResponse
result
=
httpClient
.
execute
(
httpPost
);
// 请求发送成功,并得到响应
if
(
result
.
getStatusLine
().
getStatusCode
()
==
HttpStatus
.
SC_OK
)
{
String
str
=
""
;
try
{
// 读取服务器返回过来的json字符串数据
str
=
EntityUtils
.
toString
(
result
.
getEntity
(),
"utf-8"
);
// 把json字符串转换成json对象
jsonResult
=
JSONObject
.
parseObject
(
str
);
}
catch
(
Exception
e
)
{
log
.
error
(
"post请求提交失败:"
+
url
,
e
);
}
}
}
catch
(
IOException
e
)
{
log
.
error
(
"post请求提交失败:"
+
url
,
e
);
}
finally
{
httpPost
.
releaseConnection
();
}
return
jsonResult
;
}
/**
* 发送POST请求
*
* @param url
* @param header
* @param parametersBody
* @param timeout
* @return
*/
public
static
JSONObject
postRequest
(
String
url
,
List
<
Header
>
header
,
String
parametersBody
,
Integer
timeout
)
{
log
.
info
(
"请求地址:{}"
,
url
);
log
.
info
(
"请求方式:POST"
);
HttpPost
post
=
new
HttpPost
(
url
);
post
.
addHeader
(
"Content-Type"
,
"application/json;charset=UTF-8"
);
post
.
addHeader
(
"Accept"
,
"application/json"
);
// 设置头参数
if
(
CollectionUtils
.
isNotEmpty
(
header
))
{
for
(
Header
item
:
header
)
{
post
.
setHeader
(
item
.
getName
(),
item
.
getValue
());
log
.
info
(
"请求Header:{}={}"
,
item
.
getName
(),
item
.
getValue
());
}
}
try
{
StringEntity
entity
=
new
StringEntity
(
parametersBody
);
post
.
setEntity
(
entity
);
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
// 请求参数
if
(
timeout
!=
null
&&
timeout
.
intValue
()
>
0
)
{
RequestConfig
config
=
RequestConfig
.
custom
().
setConnectTimeout
(
timeout
).
setConnectionRequestTimeout
(
timeout
).
setSocketTimeout
(
timeout
).
build
();
post
.
setConfig
(
config
);
}
try
{
log
.
info
(
"请求参数:{}"
,
parametersBody
);
CloseableHttpClient
client
=
HttpClientBuilder
.
create
().
build
();
HttpResponse
response
=
client
.
execute
(
post
);
int
code
=
response
.
getStatusLine
().
getStatusCode
();
HttpEntity
entity
=
response
.
getEntity
();
String
s
=
EntityUtils
.
toString
(
entity
);
JSONObject
result
=
(
JSONObject
)
JSONObject
.
parseObject
(
s
);
if
(
code
>=
400
)
{
throw
new
RuntimeException
(
result
.
toJSONString
());
}
log
.
info
(
"请求返回结果:{}"
,
result
);
return
result
;
}
catch
(
ClientProtocolException
e
)
{
throw
new
RuntimeException
(
"postRequest -- Client protocol exception!"
,
e
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"postRequest -- IO error!"
,
e
);
}
finally
{
post
.
releaseConnection
();
}
}
/**
* 发送POST请求
*
* @param url
* @param headerParams
* @param parametersBody
* @param timeout
* @return
*/
public
static
JSONObject
postJsonRequest
(
String
url
,
Map
<
String
,
String
>
headerParams
,
String
parametersBody
,
Integer
timeout
)
{
log
.
info
(
"请求地址:{}"
,
url
);
log
.
info
(
"请求方式:POST"
);
HttpPost
post
=
new
HttpPost
(
url
);
post
.
addHeader
(
"Content-Type"
,
"text/plain"
);
// 设置头参数
//设置请求头
if
(
headerParams
!=
null
&&
headerParams
.
size
()
>
0
)
{
for
(
Map
.
Entry
<
String
,
String
>
e
:
headerParams
.
entrySet
())
{
String
value
=
e
.
getValue
();
String
key
=
e
.
getKey
();
if
(
StrUtil
.
isNotBlank
(
value
))
{
post
.
setHeader
(
key
,
value
);
}
}
}
try
{
StringEntity
entity
=
new
StringEntity
(
parametersBody
);
entity
.
setContentType
(
"text/plain"
);
entity
.
setContentEncoding
(
"UTF-8"
);
post
.
setEntity
(
entity
);
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
// 请求参数
if
(
timeout
!=
null
&&
timeout
.
intValue
()
>
0
)
{
RequestConfig
config
=
RequestConfig
.
custom
().
setConnectTimeout
(
timeout
).
setConnectionRequestTimeout
(
timeout
).
setSocketTimeout
(
timeout
).
build
();
post
.
setConfig
(
config
);
}
try
{
log
.
info
(
"请求参数:{}"
,
parametersBody
);
CloseableHttpClient
client
=
HttpClientBuilder
.
create
().
build
();
HttpResponse
response
=
client
.
execute
(
post
);
int
code
=
response
.
getStatusLine
().
getStatusCode
();
HttpEntity
entity
=
response
.
getEntity
();
String
s
=
EntityUtils
.
toString
(
entity
);
JSONObject
result
=
(
JSONObject
)
JSONObject
.
parseObject
(
s
);
if
(
code
>=
400
)
{
throw
new
RuntimeException
(
result
.
toJSONString
());
}
log
.
info
(
"请求返回结果:{}"
,
result
);
return
result
;
}
catch
(
ClientProtocolException
e
)
{
throw
new
RuntimeException
(
"postRequest -- Client protocol exception!"
,
e
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"postRequest -- IO error!"
,
e
);
}
finally
{
post
.
releaseConnection
();
}
}
/**
* get请求,参数放在map里
*
* @param url 请求地址
* @param map 参数map
* @return 响应
*/
public
static
String
getfileMap
(
String
url
,
Map
<
String
,
String
>
map
,
String
fileUrl
,
String
fileName
)
{
CloseableHttpClient
httpClient
=
HttpClients
.
createDefault
();
List
<
NameValuePair
>
pairs
=
new
ArrayList
<>();
for
(
Map
.
Entry
<
String
,
String
>
entry
:
map
.
entrySet
())
{
pairs
.
add
(
new
BasicNameValuePair
(
entry
.
getKey
(),
entry
.
getValue
()));
}
CloseableHttpResponse
response
=
null
;
String
filestr
=
null
;
InputStream
inputStream
=
null
;
try
{
URIBuilder
builder
=
new
URIBuilder
(
url
);
builder
.
setParameters
(
pairs
);
HttpGet
get
=
new
HttpGet
(
builder
.
build
());
response
=
httpClient
.
execute
(
get
);
if
(
response
!=
null
&&
response
.
getStatusLine
().
getStatusCode
()
==
200
)
{
inputStream
=
response
.
getEntity
().
getContent
();
Header
[]
headers1
=
response
.
getHeaders
(
"Content-disposition"
);
/* for (int i = 0; i < headers1.length; i++) {
Header header = headers1[0];
String filenameheader = header.getValue();
String[] strings = filenameheader.split(";");
String strs = strings[1];
String str = strs.substring(11, strs.length() - 1);
String[] spstr = str.split("\\.");
String fileend = spstr[1];
log.info("fileend = " + fileend);
}*/
filestr
=
fileUrl
+
fileName
+
".silk"
;
File
file1
=
new
File
(
filestr
);
if
(!
file1
.
exists
())
{
file1
.
createNewFile
();
}
OutputStream
os
=
new
FileOutputStream
(
file1
);
int
read
=
0
;
byte
[]
temp
=
new
byte
[
1024
*
1024
];
while
((
read
=
inputStream
.
read
(
temp
))
>
0
)
{
byte
[]
bytes
=
new
byte
[
read
];
System
.
arraycopy
(
temp
,
0
,
bytes
,
0
,
read
);
os
.
write
(
bytes
);
}
os
.
flush
();
}
}
catch
(
URISyntaxException
e
)
{
e
.
printStackTrace
();
}
catch
(
ClientProtocolException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
finally
{
try
{
httpClient
.
close
();
if
(
response
!=
null
)
{
response
.
close
();
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
return
filestr
;
}
/**
* 发送POST请求(普通表单形式)
*
* @param url
* @param header
* @param parametersBody
* @param timeout
* @return
*/
public
static
String
postForm
(
String
url
,
List
<
Header
>
header
,
List
<
BasicNameValuePair
>
parametersBody
,
Integer
timeout
)
{
HttpEntity
entity
=
new
UrlEncodedFormEntity
(
parametersBody
,
Charsets
.
UTF_8
);
return
postRequest
(
url
,
"application/x-www-form-urlencoded"
,
header
,
entity
,
timeout
,
true
);
}
/**
* 发送POST请求(JSON形式)
*
* @param url
* @param header 请求header
* @param json 请求body,json格式
* @param timeout 访问超时时间,单位毫秒
* @return
*/
public
static
String
postJSON
(
String
url
,
List
<
Header
>
header
,
String
json
,
Integer
timeout
,
boolean
isSafe
)
{
StringEntity
entity
=
new
StringEntity
(
json
,
Charsets
.
UTF_8
);
return
postRequest
(
url
,
"application/json; charset=utf-8"
,
header
,
entity
,
timeout
,
isSafe
);
}
/**
* 发送POST请求
*
* @param url
* @param mediaType
* @param header
* @param parametersBody
* @param timeout
* @return
*/
private
static
String
postRequest
(
String
url
,
String
mediaType
,
List
<
Header
>
header
,
HttpEntity
parametersBody
,
Integer
timeout
,
boolean
isSafe
)
{
log
.
info
(
"请求地址:{}"
,
url
);
log
.
info
(
"请求方式:POST"
);
HttpPost
post
=
new
HttpPost
(
url
);
post
.
addHeader
(
"Content-Type"
,
mediaType
);
post
.
addHeader
(
"Accept"
,
"application/json"
);
// 设置头参数
if
(
CollectionUtils
.
isNotEmpty
(
header
))
{
for
(
Header
item
:
header
)
{
post
.
setHeader
(
item
.
getName
(),
item
.
getValue
());
log
.
info
(
"请求Header:{}={}"
,
item
.
getName
(),
item
.
getValue
());
}
}
// 请求参数
post
.
setEntity
(
parametersBody
);
if
(
timeout
!=
null
&&
timeout
.
intValue
()
>
0
)
{
RequestConfig
config
=
RequestConfig
.
custom
().
setConnectTimeout
(
timeout
).
setConnectionRequestTimeout
(
timeout
).
setSocketTimeout
(
timeout
).
build
();
post
.
setConfig
(
config
);
}
try
{
log
.
info
(
"请求参数:{}"
,
EntityUtils
.
toString
(
parametersBody
));
CloseableHttpClient
client
=
null
;
if
(
isSafe
){
client
=
HttpClientBuilder
.
create
().
build
();
}
else
{
// 创建一个信任所有证书的SSLContext
SSLContext
sslContext
=
SSLContextBuilder
.
create
()
.
loadTrustMaterial
(
new
TrustStrategy
()
{
@Override
public
boolean
isTrusted
(
X509Certificate
[]
chain
,
String
authType
)
throws
CertificateException
{
return
true
;
// 忽略所有证书验证
}
})
.
build
();
client
=
HttpClientBuilder
.
create
().
setSSLContext
(
sslContext
)
.
setSSLHostnameVerifier
(
new
NoopHostnameVerifier
())
.
build
();
}
HttpResponse
response
=
client
.
execute
(
post
);
int
code
=
response
.
getStatusLine
().
getStatusCode
();
String
result
=
EntityUtils
.
toString
(
response
.
getEntity
());
if
(
code
>=
400
)
{
throw
new
RuntimeException
(
result
);
}
log
.
info
(
"请求返回结果:{}"
,
result
);
return
result
;
}
catch
(
ClientProtocolException
e
)
{
throw
new
RuntimeException
(
"postRequest -- Client protocol exception!"
,
e
);
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"postRequest -- IO error!"
,
e
);
}
catch
(
NoSuchAlgorithmException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
KeyStoreException
e
)
{
throw
new
RuntimeException
(
e
);
}
catch
(
KeyManagementException
e
)
{
throw
new
RuntimeException
(
e
);
}
finally
{
post
.
releaseConnection
();
}
}
}
src/main/java/com/cmeeting/util/IPUtils.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
util
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.util.StringUtils
;
import
javax.servlet.http.HttpServletRequest
;
import
java.net.InetAddress
;
import
java.net.UnknownHostException
;
/**
* 获取Ip
*/
public
class
IPUtils
{
private
static
final
String
IP_UTILS_FLAG
=
","
;
private
static
final
String
UNKNOWN
=
"unknown"
;
private
static
final
String
LOCALHOST_IP
=
"0:0:0:0:0:0:0:1"
;
private
static
final
String
LOCALHOST_IP1
=
"127.0.0.1"
;
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
IPUtils
.
class
);
/**
* 获取IP地址
* <p>
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public
static
String
getIpAddr
(
HttpServletRequest
request
)
{
String
ip
=
null
;
try
{
//以下两个获取在k8s中,将真实的客户端IP,放到了x-Original-Forwarded-For。而将WAF的回源地址放到了 x-Forwarded-For了。
ip
=
request
.
getHeader
(
"X-Original-Forwarded-For"
);
if
(
StringUtils
.
isEmpty
(
ip
)
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"X-Forwarded-For"
);
}
//获取nginx等代理的ip
if
(
StringUtils
.
isEmpty
(
ip
)
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"x-forwarded-for"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"Proxy-Client-IP"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
ip
.
length
()
==
0
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"WL-Proxy-Client-IP"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"HTTP_CLIENT_IP"
);
}
if
(
StringUtils
.
isEmpty
(
ip
)
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getHeader
(
"HTTP_X_FORWARDED_FOR"
);
}
//兼容k8s集群获取ip
if
(
StringUtils
.
isEmpty
(
ip
)
||
UNKNOWN
.
equalsIgnoreCase
(
ip
))
{
ip
=
request
.
getRemoteAddr
();
if
(
LOCALHOST_IP1
.
equalsIgnoreCase
(
ip
)
||
LOCALHOST_IP
.
equalsIgnoreCase
(
ip
))
{
//根据网卡取本机配置的IP
InetAddress
iNet
=
null
;
try
{
iNet
=
InetAddress
.
getLocalHost
();
}
catch
(
UnknownHostException
e
)
{
logger
.
error
(
"getClientIp error: {}"
,
e
);
}
ip
=
iNet
.
getHostAddress
();
}
}
}
catch
(
Exception
e
)
{
logger
.
error
(
"IPUtils ERROR "
,
e
);
}
//使用代理,则获取第一个IP地址
if
(!
StringUtils
.
isEmpty
(
ip
)
&&
ip
.
indexOf
(
IP_UTILS_FLAG
)
>
0
)
{
ip
=
ip
.
substring
(
0
,
ip
.
indexOf
(
IP_UTILS_FLAG
));
}
return
ip
;
}
}
\ No newline at end of file
src/main/java/com/cmeeting/util/UrlEncoderUtil.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
util
;
import
java.net.URLEncoder
;
/**
* @author liuzhenmeng
* @date 2024/8/30 13:41
*/
public
class
UrlEncoderUtil
{
public
static
String
encode
(
String
param
){
try
{
return
URLEncoder
.
encode
(
param
,
"UTF-8"
);
}
catch
(
Exception
e
){
e
.
printStackTrace
();
}
return
param
;
}
}
src/main/java/com/cmeeting/util/UserAdminConfig.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
util
;
import
lombok.Data
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
@Data
@Component
public
class
UserAdminConfig
{
@Value
(
"${userAdmin.domain}"
)
private
String
userAdminDomain
;
}
src/main/java/com/cmeeting/util/UserAdminTokenUtil.java
0 → 100644
浏览文件 @
5cb7fb90
package
com
.
cmeeting
.
util
;
import
com.alibaba.fastjson.JSONObject
;
import
com.cmeeting.constant.UserAdminRouteConstant
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.Resource
;
/**
* @author a
*/
@Component
public
class
UserAdminTokenUtil
{
@Resource
private
RedisUtils
redisUtils
;
@Resource
private
UserAdminConfig
userAdminConfig
;
@Value
(
"${userAdmin.appId}"
)
private
String
appId
;
@Value
(
"${userAdmin.secret}"
)
private
String
secret
;
private
String
getAccessToken
()
{
String
key
=
"user_admin_token_"
+
appId
;
Object
o
=
redisUtils
.
get
(
key
);
if
(
o
!=
null
)
{
return
o
.
toString
();
}
String
url
=
userAdminConfig
.
getUserAdminDomain
()
+
UserAdminRouteConstant
.
ACCESS_TOKEN
;
JSONObject
body
=
new
JSONObject
();
body
.
put
(
"appId"
,
appId
);
body
.
put
(
"secret"
,
secret
);
JSONObject
object
=
HttpClientUtils
.
httpPost
(
url
,
body
,
null
);
if
(
object
!=
null
&&
object
.
getInteger
(
"code"
)
==
0
)
{
String
data
=
object
.
getString
(
"data"
);
redisUtils
.
set
(
key
,
data
,
7000
);
return
data
;
}
else
{
throw
new
RuntimeException
(
"获取accessToken失败"
);
}
}
private
static
UserAdminTokenUtil
util
;
@PostConstruct
public
void
init
()
{
util
=
this
;
}
public
static
String
getUserAdminToken
()
{
return
util
.
getAccessToken
();
}
}
src/main/java/com/cmeeting/vo/CorpRecordsVO.java
浏览文件 @
5cb7fb90
...
@@ -26,7 +26,7 @@ public class CorpRecordsVO {
...
@@ -26,7 +26,7 @@ public class CorpRecordsVO {
private
String
meetingCode
;
private
String
meetingCode
;
private
String
userid
;
private
String
userid
;
private
String
hostUserId
;
private
String
hostUserId
;
private
Integer
mediaStartTime
;
private
Long
mediaStartTime
;
private
String
subject
;
private
String
subject
;
private
Integer
state
;
private
Integer
state
;
private
Integer
recordType
;
private
Integer
recordType
;
...
@@ -36,8 +36,8 @@ public class CorpRecordsVO {
...
@@ -36,8 +36,8 @@ public class CorpRecordsVO {
@Data
@Data
public
class
RecordFile
{
public
class
RecordFile
{
private
String
recordFileId
;
private
String
recordFileId
;
private
Integer
recordStartTime
;
private
Long
recordStartTime
;
private
Integer
recordEndTime
;
private
Long
recordEndTime
;
private
Integer
recordSize
;
private
Integer
recordSize
;
private
Integer
sharingState
;
private
Integer
sharingState
;
private
String
sharingUrl
;
private
String
sharingUrl
;
...
...
src/main/java/com/cmeeting/vo/RecordTemplateVO.java
浏览文件 @
5cb7fb90
...
@@ -2,6 +2,8 @@ package com.cmeeting.vo;
...
@@ -2,6 +2,8 @@ package com.cmeeting.vo;
import
lombok.Data
;
import
lombok.Data
;
import
java.util.List
;
/**
/**
* 会议纪要模板展示层
* 会议纪要模板展示层
*/
*/
...
@@ -42,4 +44,29 @@ public class RecordTemplateVO {
...
@@ -42,4 +44,29 @@ public class RecordTemplateVO {
* 每页最大数据行
* 每页最大数据行
*/
*/
private
Integer
size
;
private
Integer
size
;
@Data
public
static
class
TemplatePermissionVO
{
/**
* 模板id
*/
private
Integer
templateId
;
/**
* 选中的部门或人员
*/
private
List
<
PermissionItem
>
permissionItems
;
}
@Data
public
static
class
PermissionItem
{
/**
* 对象类型
*/
private
String
relType
;
/**
* 关联对象id
*/
private
String
relId
;
}
}
}
\ No newline at end of file
src/main/resources/application.yml
浏览文件 @
5cb7fb90
...
@@ -104,7 +104,7 @@ tencent:
...
@@ -104,7 +104,7 @@ tencent:
meeting
:
meeting
:
token
:
QQZNb7xWQB47MpZF4C2DFAkv8
token
:
QQZNb7xWQB47MpZF4C2DFAkv8
aesKey
:
agy6ALUePp34lljWz1uIQWa7yQq3dgxxQNmfaN9GROm
aesKey
:
agy6ALUePp34lljWz1uIQWa7yQq3dgxxQNmfaN9GROm
base-save-path
:
/save/
base-save-path
:
E:
/save/
email
:
email
:
sender
:
${EMAIL_SENDER}
sender
:
${EMAIL_SENDER}
...
@@ -114,6 +114,34 @@ email:
...
@@ -114,6 +114,34 @@ email:
llm
:
llm
:
api-addr
:
${LLM_API_ADDR}
api-addr
:
${LLM_API_ADDR}
#解密key
aec
:
key
:
biaopin123456789
ldap
:
url
:
'
ldap://10.52.3.20/'
base
:
'
CN=AIGC,OU=数据网络中心,OU=集团公司,OU=集团总部,OU=无HR信息人员,OU=特殊邮箱,DC=cimc,DC=com'
adName
:
'
AIGC@cimc.com'
adPwd
:
'
32Rgn87#8@dbc'
referral
:
'
follow'
domain
:
'
@cimc.com'
userAdmin
:
domain
:
http://192.168.10.154:8303
appId
:
af94e0ec9cc0bef2bfa63f470f6f4351
secret
:
4luHTMYMyXzOmDHN0ZOSMwOst702plcr9EKqAHtT8Nag6EPlP0VSFvqv9Zq0NRDE
removeMenus
:
关键词回复,业务词库,同义词管理,答案库
jwt
:
header
:
Authorization
customHeader
:
'
Custom-Auth-Token'
applicationId
:
'
Application-Id'
tokenHead
:
'
Bearer
'
openingUp-header
:
'
aigc-open-auth-token'
expireTime
:
36000
customExpireTime
:
36000
# 5天
permission
:
permission
:
applicationId
:
${PERMISSION_APPLiCATION_ID}
applicationId
:
${PERMISSION_APPLiCATION_ID}
tenantId
:
${PERMISSION_TENANT_ID}
tenantId
:
${PERMISSION_TENANT_ID}
...
...
src/main/resources/mapper/primary/CommonMapper.xml
0 → 100644
浏览文件 @
5cb7fb90
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.cmeeting.mapper.primary.CommonMapper"
>
<select
id=
"getMenuList"
resultType=
"com.cmeeting.ad.entity.SysMenu"
>
select t1.*
from sys_menu t1
<if
test=
"tenantId != '' and tenantId != 1"
>
inner join rel_menu_tenant t2 on t2.menu_id = t1.id and t2.tenant_id = #{tenantId}
</if>
where 1 = 1
<choose>
<when
test=
"tenantId != '' and tenantId == 1"
>
and is_admin = 1
</when>
<otherwise>
and is_admin = 0
</otherwise>
</choose>
</select>
<select
id=
"getRoleByTenantId"
resultType=
"com.cmeeting.ad.entity.ModulePermissions"
>
select *
from core_module_permissions
where tenant_id = #{tenantId}
and source = 0;
</select>
<select
id=
"getMenuByRoleList"
resultType=
"com.cmeeting.ad.entity.SysMenu"
>
select distinct t1.*
from sys_menu t1
inner join rel_role_menu t2
on t1.id = t2.menu_id
<if
test=
"tenantId!=null and tenantId!=''"
>
and t2.tenant_id = #{tenantId}
</if>
<if
test=
"roleIdList!= null"
>
and role_id in
<foreach
collection=
"roleIdList"
close=
")"
open=
"("
separator=
","
item=
"id"
>
#{id}
</foreach>
</if>
inner join sys_role t3
on t3.disabled = 0
<if
test=
"tenantId!=null and tenantId!=''"
>
and t3.tenant_id = #{tenantId}
</if>
</select>
<select
id=
"getApplicationNoTenantId"
resultType=
"com.cmeeting.ad.vo.ApplicationVo"
>
SELECT
t1.id as applicationId,
t1.`name` as applicationName,
t1.tenant_id as tenantId
FROM
assistant_info t1
where t1.is_del = 0
</select>
<select
id=
"getSubDeptId"
resultType=
"java.lang.String"
>
SELECT dept_id
FROM sys_user_sync_category
WHERE parent_id = #{deptId}
</select>
<select
id=
"getUsersByDept"
resultType=
"java.lang.String"
>
select t1.user_id as wId
from sys_user_sync t1
where t1.dept_id in
<foreach
collection=
"deptIds"
item=
"deptId"
separator=
","
open=
"("
close=
")"
>
#{deptId}
</foreach>
</select>
</mapper>
src/main/resources/mapper/primary/RecordTemplatePermissionMapper.xml
0 → 100644
浏览文件 @
5cb7fb90
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.cmeeting.mapper.primary.RecordTemplatePermissionMapper"
>
<insert
id=
"batchInsert"
>
INSERT IGNORE INTO cmt_record_template_permission (template_id, template_type, rel_type, rel_id, create_time)
VALUES
<foreach
collection=
"permissions"
item=
"permission"
separator=
","
>
(
#{permission.templateId},
#{permission.template_type},
#{permission.relType},
#{permission.relId},
#{permission.createTime}
)
</foreach>
</insert>
</mapper>
src/main/resources/mapper/primary/SysTenantMapper.xml
0 → 100644
浏览文件 @
5cb7fb90
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper
namespace=
"com.cmeeting.mapper.primary.SysTenantMapper"
>
</mapper>
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论