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 个修改的文件
包含
2961 行增加
和
142 行删除
+2961
-142
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
+0
-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
+15
-25
src/main/java/com/cmeeting/service/impl/RecordTemplatePermissionServiceImpl.java
+97
-0
src/main/java/com/cmeeting/service/impl/TencentMeetingServiceImpl.java
+0
-0
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
+0
-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 @@
<maven.compiler.source>
1.8
</maven.compiler.source>
<maven.compiler.target>
1.8
</maven.compiler.target>
<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>
<dependencyManagement>
<dependencies>
...
...
@@ -328,6 +328,35 @@
<artifactId>
spring-boot-starter-data-redis
</artifactId>
<version>
2.7.0
</version>
<!-- 与你的Spring Boot版本一致 -->
</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>
<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
差异被折叠。
点击展开。
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
;
import
com.baomidou.mybatisplus.annotation.DbType
;
import
com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor
;
import
com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor
;
import
com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
;
import
org.apache.ibatis.session.SqlSessionFactory
;
import
org.mybatis.spring.SqlSessionTemplate
;
...
...
@@ -29,11 +27,16 @@ public class MasterDataSourceConfig {
return
DataSourceBuilder
.
create
().
build
();
}
/**
* 分页插件(3.3.0 版本使用旧版 PaginationInterceptor)
*/
@Bean
public
MybatisPlusInterceptor
mybatisPlusInterceptor
()
{
MybatisPlusInterceptor
interceptor
=
new
MybatisPlusInterceptor
();
interceptor
.
addInnerInterceptor
(
new
PaginationInnerInterceptor
(
DbType
.
MYSQL
));
return
interceptor
;
public
PaginationInterceptor
paginationInterceptor
()
{
PaginationInterceptor
paginationInterceptor
=
new
PaginationInterceptor
();
// 设置数据库类型
// 溢出总页数后是否进行处理 (默认不处理,会返回最后一页数据)
paginationInterceptor
.
setOverflow
(
true
);
return
paginationInterceptor
;
}
@Primary
...
...
@@ -42,7 +45,7 @@ public class MasterDataSourceConfig {
MybatisSqlSessionFactoryBean
bean
=
new
MybatisSqlSessionFactoryBean
();
bean
.
setDataSource
(
dataSource
);
bean
.
setMapperLocations
(
new
PathMatchingResourcePatternResolver
().
getResources
(
"classpath:mapper/primary/*.xml"
));
bean
.
setPlugins
(
mybatisPlus
Interceptor
());
bean
.
setPlugins
(
pagination
Interceptor
());
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;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.service.MeetingRecordTemplateService
;
import
com.cmeeting.service.RecordTemplatePermissionService
;
import
com.cmeeting.util.R
;
import
com.cmeeting.vo.RecordTemplateVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.time.LocalDateTime
;
...
...
@@ -18,6 +20,8 @@ import java.time.LocalDateTime;
public
class
RecordTemplateController
{
@Autowired
private
MeetingRecordTemplateService
recordTemplateService
;
@Resource
private
RecordTemplatePermissionService
recordTemplatePermissionService
;
@PostMapping
(
"/create"
)
public
R
create
(
@RequestBody
MeetingRecordTemplate
recordTemplate
)
{
...
...
@@ -77,4 +81,9 @@ public class RecordTemplateController {
String
template
=
recordTemplateService
.
templateUpload
(
file
,
id
);
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 {
* 邮箱
*/
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 {
}
// @Scheduled(fixedRate = 10 * 60 * 1000,initialDelay = 2 * 60 * 1000)
@Scheduled
(
fixedRate
=
10
*
60
*
1000
)
public
void
execute
()
{
// 定义时间格式化器
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
...
...
@@ -115,6 +114,8 @@ public class CmeetingJob {
if
(
CollectionUtils
.
isEmpty
(
accessUserIds
))
{
log
.
info
(
"无生成纪要权限的人员"
);
return
;
}
else
{
log
.
info
(
"生成纪要权限人员:->{}"
,
accessUserIds
.
toString
());
}
List
<
TencentMeetingVO
.
RecordFile
>
meetingFiles
=
tencentMeetingService
.
getMeetingFiles
(
accessUserIds
);
...
...
@@ -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
()
{
try
{
log
.
info
(
"-------生成纪要重试定时任务开始-------"
);
...
...
src/main/java/com/cmeeting/job/EmailPushTask.java
浏览文件 @
5cb7fb90
...
...
@@ -58,11 +58,9 @@ public class EmailPushTask {
.
eq
(
subMeetingId
!=
null
,
MeetingInfo:
:
getSubMeetingId
,
subMeetingId
));
while
(
retryCount
.
intValue
()
<=
MAX_RETRY
&&
!
isSuccess
)
{
try
{
String
targetFileName
;
String
meetingName
;
String
recordXmlPath
=
meetingId
+
"-recordXmlPath-"
+
IdUtil
.
fastSimpleUUID
()
+
"xml"
;
String
xml
;
try
(
InputStream
is
=
minioUtils
.
getFile
(
recordXmlPath
)){
try
(
InputStream
is
=
minioUtils
.
getFile
(
meetingInfo
.
getRecordXml
()
)){
xml
=
convertInputStreamToString
(
is
);
}
catch
(
Exception
e
){
log
.
error
(
e
.
getMessage
());
...
...
@@ -86,7 +84,7 @@ public class EmailPushTask {
XWPFTemplate
template
=
XWPFTemplate
.
compile
(
inputStream
).
render
(
dataModel
);
template
.
writeAndClose
(
new
FileOutputStream
(
dataNetworkMinutesPath
));
byte
[]
recordXmlData
=
Files
.
readAllBytes
(
Paths
.
get
(
dataNetworkMinutesPath
));
minioUtils
.
upload
(
recordXmlPath
,
recordXmlData
);
minioUtils
.
upload
(
meetingInfo
.
getRecordXml
()
,
recordXmlData
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
...
...
src/main/java/com/cmeeting/job/FileProcessTask.java
浏览文件 @
5cb7fb90
...
...
@@ -25,8 +25,7 @@ import com.tencentcloudapi.wemeet.Client;
import
com.tencentcloudapi.wemeet.core.authenticator.AuthenticatorBuilder
;
import
com.tencentcloudapi.wemeet.core.authenticator.JWTAuthenticator
;
import
com.tencentcloudapi.wemeet.service.meetings.api.MeetingsApi
;
import
com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsMeetingIdParticipantsGet200Response
;
import
com.tencentcloudapi.wemeet.service.meetings.model.V1MeetingsMeetingIdParticipantsGet200ResponseParticipantsInner
;
import
com.tencentcloudapi.wemeet.service.meetings.model.*
;
import
com.tencentcloudapi.wemeet.service.records.api.RecordsApi
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200Response
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner
;
...
...
@@ -42,6 +41,7 @@ import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import
org.apache.poi.xwpf.usermodel.XWPFDocument
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.stereotype.Service
;
import
org.springframework.util.CollectionUtils
;
import
java.io.*
;
import
java.math.BigInteger
;
...
...
@@ -51,7 +51,10 @@ import java.nio.file.Files;
import
java.nio.file.Paths
;
import
java.security.SecureRandom
;
import
java.text.MessageFormat
;
import
java.time.Instant
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.ZoneId
;
import
java.time.format.DateTimeFormatter
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
...
...
@@ -94,9 +97,50 @@ public class FileProcessTask {
.
withSecret
(
tencentSecretId
,
tencentSecretKey
)
.
build
();
try
{
//已保存的会议信息
MeetingInfo
meetingInfo
=
meetingInfoMapper
.
selectOne
(
new
LambdaQueryWrapper
<
MeetingInfo
>()
.
eq
(
MeetingInfo:
:
getMeetingId
,
meetingId
)
.
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
=
...
...
@@ -502,8 +546,10 @@ public class FileProcessTask {
//特殊处理map格式
for
(
Map
.
Entry
<
String
,
Object
>
entry
:
map
.
entrySet
())
{
Map
<
String
,
Object
>
value
=
(
Map
<
String
,
Object
>)
entry
.
getValue
();
Object
realValue
=
value
.
get
(
""
);
entry
.
setValue
(
realValue
);
//取出正确的value并设置
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
;
}
...
...
@@ -514,7 +560,7 @@ public class FileProcessTask {
* @return
*/
private
String
extractXmlFromMarkdown
(
String
markdown
)
{
StringBuffer
sb
=
null
;
StringBuffer
sb
;
try
{
int
start
=
markdown
.
indexOf
(
"<"
);
if
(
start
==
-
1
){
...
...
@@ -523,7 +569,8 @@ public class FileProcessTask {
int
end
=
markdown
.
lastIndexOf
(
">"
)
+
1
;
sb
=
new
StringBuffer
();
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>"
);
}
catch
(
Exception
e
)
{
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
;
import
com.baomidou.mybatisplus.core.mapper.BaseMapper
;
import
com.cmeeting.ad.entity.SysUserSync
;
import
com.cmeeting.dto.UserDTO
;
import
org.apache.ibatis.annotations.Mapper
;
import
org.apache.ibatis.annotations.Param
;
...
...
@@ -7,7 +9,7 @@ import org.apache.ibatis.annotations.Param;
import
java.util.List
;
@Mapper
public
interface
SysUserSysMapper
{
public
interface
SysUserSysMapper
extends
BaseMapper
<
SysUserSync
>
{
String
getCompanyEmail
(
String
wid
,
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
;
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.update.LambdaUpdateWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
...
...
@@ -55,35 +58,22 @@ public class MeetingInfoServiceImpl extends ServiceImpl<MeetingInfoMapper, Meeti
}
private
String
convertJSONToXml
(
String
json
)
{
try
{
// 解析 JSON 字符串
ObjectMapper
jsonMapper
=
new
ObjectMapper
();
List
<
Map
<
String
,
String
>>
list
=
jsonMapper
.
readValue
(
json
,
List
.
class
);
JSONArray
jsonArray
=
JSON
.
parseArray
(
json
);;
StringBuilder
xmlBuilder
=
new
StringBuilder
();
// 创建 XML 根节点
Map
<
String
,
Object
>
root
=
new
HashMap
<>();
xmlBuilder
.
append
(
"<root>"
);
for
(
int
i
=
0
;
i
<
jsonArray
.
size
();
i
++)
{
JSONObject
jsonObj
=
jsonArray
.
getJSONObject
(
i
);
// 处理每个 JSON 项
for
(
Map
<
String
,
String
>
item
:
list
)
{
String
keyValue
=
item
.
get
(
"key"
);
String
keyName
=
item
.
get
(
"keyName"
);
String
value
=
item
.
get
(
"value"
);
String
key
=
jsonObj
.
getString
(
"key"
);
String
label
=
jsonObj
.
getString
(
"keyName"
);
String
value
=
jsonObj
.
getString
(
"value"
);
// 创建子节点
Map
<
String
,
Object
>
subNode
=
new
HashMap
<>();
subNode
.
put
(
"label"
,
keyName
);
subNode
.
put
(
""
,
value
);
// 添加到根节点
root
.
put
(
keyValue
,
subNode
);
xmlBuilder
.
append
(
String
.
format
(
"<%s label=\"%s\">%s</%s>"
,
key
,
label
,
value
,
key
));
}
xmlBuilder
.
append
(
"</root>"
);
// 转换为 XML
XmlMapper
xmlMapper
=
new
XmlMapper
();
return
xmlMapper
.
writeValueAsString
(
root
);
}
catch
(
IOException
e
)
{
log
.
error
(
"JSON 转 XML 失败: "
+
e
.
getMessage
());
throw
new
RuntimeException
(
"JSON 转 XML 失败"
,
e
);
}
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
差异被折叠。
点击展开。
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
差异被折叠。
点击展开。
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 {
private
String
meetingCode
;
private
String
userid
;
private
String
hostUserId
;
private
Integer
mediaStartTime
;
private
Long
mediaStartTime
;
private
String
subject
;
private
Integer
state
;
private
Integer
recordType
;
...
...
@@ -36,8 +36,8 @@ public class CorpRecordsVO {
@Data
public
class
RecordFile
{
private
String
recordFileId
;
private
Integer
recordStartTime
;
private
Integer
recordEndTime
;
private
Long
recordStartTime
;
private
Long
recordEndTime
;
private
Integer
recordSize
;
private
Integer
sharingState
;
private
String
sharingUrl
;
...
...
src/main/java/com/cmeeting/vo/RecordTemplateVO.java
浏览文件 @
5cb7fb90
...
...
@@ -2,6 +2,8 @@ package com.cmeeting.vo;
import
lombok.Data
;
import
java.util.List
;
/**
* 会议纪要模板展示层
*/
...
...
@@ -42,4 +44,29 @@ public class RecordTemplateVO {
* 每页最大数据行
*/
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:
meeting
:
token
:
QQZNb7xWQB47MpZF4C2DFAkv8
aesKey
:
agy6ALUePp34lljWz1uIQWa7yQq3dgxxQNmfaN9GROm
base-save-path
:
/save/
base-save-path
:
E:
/save/
email
:
sender
:
${EMAIL_SENDER}
...
...
@@ -114,6 +114,34 @@ email:
llm
:
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
:
applicationId
:
${PERMISSION_APPLiCATION_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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论