提交 b855e0ea 作者: duanxincheng

迭代纪要生成大模型调用服务,转录文件上传至知识向量库,邮件推送开关

父级 20004cec
......@@ -357,6 +357,12 @@
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>cn.chatbot</groupId>
<artifactId>meetingLLM</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
......
......@@ -2,6 +2,8 @@ package com.cmeeting.ad.config;
import cn.hutool.core.util.ArrayUtil;
import com.cmeeting.ad.filter.RobotJwtAuthenticationTokenFilter;
import com.cmeeting.ad.handler.RobotAccessDeniedHandler;
import com.cmeeting.ad.handler.RobotAuthenticationEntryPointImpl;
import com.cmeeting.ad.service.CustomUserDetailsService;
import com.cmeeting.ad.service.UserService;
import lombok.extern.slf4j.Slf4j;
......@@ -119,10 +121,10 @@ public class RobotWebSecurityConfig extends WebSecurityConfigurerAdapter {
// 添加自定义异常入口
// httpSecurity
// .exceptionHandling()
// .authenticationEntryPoint(new RobotAuthenticationEntryPointImpl())
// .accessDeniedHandler(new RobotAccessDeniedHandler());
httpSecurity
.exceptionHandling()
.authenticationEntryPoint(new RobotAuthenticationEntryPointImpl())
.accessDeniedHandler(new RobotAccessDeniedHandler());
// 添加JWT filter 用户名登录
httpSecurity
......
package com.cmeeting.ad.handler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.access.AccessDeniedHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @Classname PreAccessDeniedHandler
* @Description 用来解决匿名用户访问无权限资源时的异常
* @Author Created by robot
* @Date 2019/12/19 3:35 下午
* @Version 1.0
*/
@Slf4j
public class RobotAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException e)
throws IOException, ServletException {
// log.error("请求访问: " + request.getRequestURI() + " 接口, 没有访问权限");
// SecurityUtil.writeJavaScript(R.error(HttpStatus.HTTP_UNAUTHORIZED,
// "请求访问:" + request.getRequestURI() + "接口,没有访问权限"), response);
}
}
package com.cmeeting.ad.handler;
import cn.hutool.json.JSONUtil;
import com.cmeeting.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
/**
* 用来解决认证过的用户访问无权限资源时的异常
*
* @author robot
*/
@Slf4j
public class RobotAuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable {
private static final long serialVersionUID = -8970718410437077606L;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException {
log.error("请求访问: " + request.getRequestURI() + " 接口, 经jwt认证失败,无法访问系统资源.");
response.setContentType("application/json;charset=UTF-8");
PrintWriter writer = null;
try {
writer = response.getWriter();
writer.write(JSONUtil.toJsonPrettyStr(R.error(401, "登录超时,请重新登录")));
writer.flush();
} catch (IOException ex) {
log.error(ex.getMessage());
} finally {
if (writer != null) {
writer.close();
}
}
}
}
......@@ -231,18 +231,16 @@ public class UserServiceImpl implements UserService {
@Override
public Object tokenAuth(ApplicationUserVO.LoginDecrypt vo) {
// String aigcToken = vo.getData();
// String url = userAdminConfig.getSystemDomain() + "/cloud/info";
// JSONObject object = HttpClientUtils.httpGet(url, aigcToken);
// if("0".equals(object.get("code"))){
// return null;
// }
// JSONObject data = object.getJSONObject("data");
// RobotSecurityUser robotSecurityUser = JSON.parseObject(data.toJSONString(), RobotSecurityUser.class);
RobotSecurityUser robotSecurityUser = new RobotSecurityUser();
robotSecurityUser.setUsername("00010786");
robotSecurityUser.setNickName("黄飞");
UserVo.Auth authParams = UserVo.Auth.builder().id(robotSecurityUser.getUsername()).nick(robotSecurityUser.getNickName()).build();
String aigcToken = vo.getData();
String url = userAdminConfig.getSystemDomain() + "/cloud/info";
JSONObject object = HttpClientUtils.httpGet(url, aigcToken);
if("0".equals(object.get("code"))){
return null;
}
JSONObject data = object.getJSONObject("data");
RobotSecurityUser robotSecurityUser = JSON.parseObject(data.toJSONString(), RobotSecurityUser.class);
UserVo.Auth authParams = UserVo.Auth.builder().id(String.format("%08d", robotSecurityUser.getUserId())).nick(robotSecurityUser.getNickName()).build();
String token = auth(authParams);
return token;
}
......
......@@ -3,4 +3,6 @@ package com.cmeeting.constant;
public class RecordTemplateConstant {
public static final String TEMPLATE_TYPE_SYSTEM = "system";
public static final String TEMPLATE_TYPE_CUSTOM = "custom";
public static final String REL_TYPE_DEPT = "1";
public static final String REL_TYPE_USER = "2";
}
......@@ -4,6 +4,8 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cmeeting.ad.entity.RobotSecurityUser;
import com.cmeeting.ad.util.SecurityUtil;
import com.cmeeting.email.EmailSender;
import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper;
import com.cmeeting.mapper.primary.UserIdMapper;
......@@ -25,6 +27,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
......@@ -58,6 +61,10 @@ public class MeetingInfoController {
private MeetingRecordTemplateMapper meetingRecordTemplateMapper;
@Resource
private UserIdMapper userIdMapper;
@Value(value = "${permission.applicationId}")
private String permissionApplicationId;
@Value(value = "${userAdmin.file-download-path}")
private String fileDownloadPath;
@PostMapping("/updateRecordXml")
public R updateRecordXml(@RequestBody MeetingInfoVO vo) {
......@@ -84,6 +91,9 @@ public class MeetingInfoController {
@PostMapping("/detail")
public R detail(@RequestBody MeetingInfoVO vo) {
RobotSecurityUser user = SecurityUtil.getUser();
vo.setUserId(user.getId());
vo.setApplicationId(permissionApplicationId);
MeetingInfo meetingInfo = meetingInfoService.getById(vo.getId());
BeanUtils.copyProperties(meetingInfo,vo);
String recordXml = vo.getRecordXml();
......@@ -107,7 +117,7 @@ public class MeetingInfoController {
}
try {
if(StringUtils.isNotEmpty(recordContent)){
vo.setRecordContent(minioUtils.getFileText(recordContent));
vo.setRecordContent(minioUtils.getFileText(recordContent.replaceAll(fileDownloadPath,"")));
}
} catch (Exception e) {
e.printStackTrace();
......
......@@ -30,9 +30,14 @@ public class RecordTemplateController {
@PostMapping("/create")
public R create(@RequestBody MeetingRecordTemplate recordTemplate) {
RobotSecurityUser user = SecurityUtil.getUser();
recordTemplate.setCreateTime(LocalDateTime.now());
LocalDateTime now = LocalDateTime.now();
recordTemplate.setCreateTime(now);
recordTemplate.setUpdateTime(now);
recordTemplate.setIsDel(Boolean.FALSE);
recordTemplate.setCreateUser(user.getId());
recordTemplate.setUpdateUser(user.getId());
recordTemplate.setCreateUserName(user.getNickName());
recordTemplate.setUpdateUserName(user.getNickName());
boolean save = recordTemplateService.save(recordTemplate);
return R.ok(save);
}
......@@ -42,6 +47,7 @@ public class RecordTemplateController {
RobotSecurityUser user = SecurityUtil.getUser();
recordTemplate.setUpdateTime(LocalDateTime.now());
recordTemplate.setUpdateUser(user.getId());
recordTemplate.setUpdateUserName(user.getNickName());
boolean save = recordTemplateService.updateById(recordTemplate);
return R.ok(save);
}
......@@ -68,6 +74,17 @@ public class RecordTemplateController {
}
/**
* 用户下拉选择的模板列表(权限内)
* @param vo
* @return
*/
@PostMapping("/selectList")
public R selectList(@RequestBody RecordTemplateVO vo) {
List<MeetingRecordTemplate> records = recordTemplateService.getSelectList(vo);
return R.ok(records);
}
/**
* 普通用户纪要模板,查出有授权的系统模板和个人创建的自定义模板
* @param vo
* @return
......
package com.cmeeting.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* @author 吕轶伟
* @date 2024/6/26 下午4:17
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class DocResultDto {
/**
* 分类id
*/
private String categoryId;
/**
* 分类路径
*/
private String docPath;
/**
* 文档名称
*/
private String docName;
/**
* 文档标题
*/
private String docTitle;
/**
* 文档类型(0:word, 1: excel, 2: ppt, 3: pdf, 4: txt, 5: 用户自建文档)
*/
private String docType;
/**
* 文档内容(针对text文档)
*/
private String docContent;
/**
* 预览地址
*/
private String previewPath;
/**
* 文档状态(0: 启用, 1: 停用)
*/
private String docStatus;
private String size;
/**
* 同步状态(0: 上传成功, 1: 上传失败, 2: 同步中, 3: 处理中, 4: 同步成功, 5: 同步失败, 6: 用户取消同步)
*/
private String syncStatus;
/**
* 知识库id
*/
private String libraryId;
private boolean checked;
private boolean isSys;
private List<TagTypeResultDto> tagTypeList;
/**
* 主键ID
*/
private String id;
/**
* 0-正常,1-删除
*/
private boolean isDel;
/**
* 用户创建人
*/
private String createUser;
/**
* 更新者
*/
private String updateUser;
/**
* 修改时间
*/
private Date updateTime;
/**
* 创建时间
*/
private Date createTime;
/**
* 租户id
*/
private String tenantId;
private String parentId;
private String libraryName;
private String categoryName;
private List<RelAttachFileDto> relAttachFiles;
private RelAttachFileDto sourceFile;
private String pdfPath;
private String xlfFilePath;
private String authorId;
private String author;
}
\ No newline at end of file
package com.cmeeting.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 文档附件信息表(RelAttachFile)实体类
*
* @author makejava
* @since 2024-07-16 19:05:34
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RelAttachFileDto {
/**
* id
*/
private String id;
/**
* 文档id
*/
private String docId;
/**
* 附件名称
*/
private String name;
/**
* 附件地址
*/
private String filePath;
/**
* 文件大小
*/
private String size;
}
package com.cmeeting.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author 吕轶伟
* @date 2024/6/26 下午4:17
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TagTypeResultDto {
private String id;
/**
* 标签类型值
*/
private String tagTypeValue;
/**
* 标签颜色
*/
private String tagColor;
private List<Tag> tagList;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Tag{
/**
* 标签值
*/
private String tagValue;
/**
* 标签类型id
*/
private String tagTypeId;
/**
* 标签id
*/
private String id;
}
private String tenantId;
}
......@@ -48,6 +48,12 @@ public class EmailSender {
private String SENDER;
@Value("${email.sender-pwd}")
private String EMAIL_PWD;
@Value("${email.push-switch}")
private Boolean pushSwitch;
@Value("${email.environment}")
private String environment;
@Value("${email.test-receiver}")
private String testReceiver;
private String CLIENT_ID = "c06fe7cf-2a89-4099-9805-ce03031938f8";
private String CLIENT_SECRET = "wsu8Q~GxYxPLf2akioQZDRG8NR1EzCAHIAQRVc6u";
......@@ -177,12 +183,13 @@ public class EmailSender {
// 创建会话
log.info("sender->{},email_pwd->{}",SENDER, EMAIL_PWD);
if(!pushSwitch){
log.info("【邮箱推送】:应用未开启邮件推送功能");
}
AtomicInteger retryCount = new AtomicInteger(0);
boolean isSent = false;
String toEmail = emailPushBuilder.getToEmail();
// String toEmail = "duanxincheng@chatbot.cn";
String toEmail = "test".equals(environment) ? testReceiver : emailPushBuilder.getToEmail();
String subject = emailPushBuilder.getSubject();
String meetingId = emailPushBuilder.getMeetingId();
String subMeetingId = emailPushBuilder.getSubMeetingId();
......@@ -191,7 +198,7 @@ public class EmailSender {
String toUser = emailPushBuilder.getToUser();
if(StringUtils.isEmpty(toEmail)){
log.error("收件邮箱为空,推送失败");
processLogService.log(meetingId,null,"收件邮箱为空,推送失败");
processLogService.log(meetingId,null,"收件邮箱为空,推送失败。environment->"+environment+",testReceiver->"+testReceiver+",realEmail->"+emailPushBuilder.getToEmail());
return false;
}
log.info("准备开始邮件推送...");
......
package com.cmeeting.exception;
import com.cmeeting.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @Classname BExceptionHandler
* @Description 自定义异常处理
* @Author robot
* @Date 2019-03-29 13:23
* @Version 1.0
*/
@Slf4j
@RestControllerAdvice
public class BExceptionHandler {
/**
* 处理自定义异常
*/
@ExceptionHandler(RobotBaseException.class)
public R handlerException(RobotBaseException e) {
return R.error(e.getCode(), e.getMessage());
}
/**
* @Description 请求参数值异常
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public R handlerException(MethodArgumentNotValidException e) {
return R.error(-1, e.getMessage());
}
}
package com.cmeeting.exception;
import cn.hutool.core.collection.CollectionUtil;
import com.cmeeting.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import java.sql.SQLException;
/**
* 自定义异常处理
*
* @author 王长伟
*/
@Slf4j
@RestControllerAdvice
public class BizExceptionHandler {
/**
* 处理自定义异常
*/
@ExceptionHandler(RobotBaseException.class)
public R handlerException(RobotBaseException e) {
return R.error(e.getMsg());
}
/**
* 请求参数值异常(超过长度,或者类型不对等)
* @param e
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public R handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.error(e.getMessage(), e);
if (CollectionUtil.isNotEmpty(e.getBindingResult().getFieldErrors())) {
String validateMessage = e.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
return R.error(validateMessage);
}
return R.error("参数错误");
}
/**
* 请求参数key不对
* @param e
* @return
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
public R handlerMissingServletRequestParameterException(Exception e) {
log.error(e.getMessage(), e);
return R.error(1001, "参数错误");
}
@ExceptionHandler(NoHandlerFoundException.class)
public R handlerNoFoundException(Exception e) {
log.error(e.getMessage(), e);
return R.error(404, "路径不存在,请检查路径是否正确");
}
/**
* 数据库中已存在该记录
* @param e
* @return
*/
@ExceptionHandler(DuplicateKeyException.class)
public R handleDuplicateKeyException(DuplicateKeyException e) {
log.error(e.getMessage(), e);
return R.error(300, "数据库中已存在该记录");
}
@ExceptionHandler(AccessDeniedException.class)
public R handleAuthorizationException(AccessDeniedException e) {
log.error(e.getMessage());
return R.error(403, "没有权限,请联系管理员授权");
}
@ExceptionHandler(AccountExpiredException.class)
public R handleAccountExpiredException(AccountExpiredException e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage());
}
@ExceptionHandler(UsernameNotFoundException.class)
public R handleUsernameNotFoundException(UsernameNotFoundException e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage());
}
@ExceptionHandler(Exception.class)
public R handleException(Exception e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage());
}
@ExceptionHandler(SQLException.class)
public R handlerSqlException(SQLException e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage());
}
@ExceptionHandler(ValidateCodeException.class)
public R handleValidateCodeException(ValidateCodeException e) {
log.error(e.getMessage(), e);
return R.error(e.getMessage());
}
}
......@@ -18,33 +18,33 @@ public class RobotBaseException extends RuntimeException implements Serializable
@Setter
@Getter
private String message;
private String msg;
@Setter
@Getter
private int code = 200;
private int code;
public RobotBaseException(String msg) {
super(msg);
this.message = msg;
}
public RobotBaseException(String msg, Throwable e) {
super(msg, e);
this.message = msg;
this.msg = msg;
}
public RobotBaseException(String msg, int code) {
super(msg);
this.message = msg;
this.msg = msg;
this.code = code;
}
public RobotBaseException(String msg, int code, Throwable e) {
public RobotBaseException(String msg, Throwable e) {
super(msg, e);
this.message = msg;
this.msg = msg;
}
public RobotBaseException(String msg, Throwable e, int code) {
super(msg, e);
this.msg = msg;
this.code = code;
}
}
package com.cmeeting.exception;
import org.springframework.security.core.AuthenticationException;
/**
* @Classname ValidateCodeException
* @Author Created by robot
* @Date 2019-07-07 23:06
* @Version 1.0
*/
public class ValidateCodeException extends AuthenticationException {
private static final long serialVersionUID = 5022575393500654459L;
public ValidateCodeException(String message) {
super(message);
}
}
......@@ -2,6 +2,7 @@ package com.cmeeting.mapper.primary;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.cmeeting.pojo.MeetingInfo;
import com.cmeeting.vo.MeetingInfoVO;
import com.cmeeting.vo.TencentMeetingVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
......@@ -15,4 +16,6 @@ public interface MeetingInfoMapper extends BaseMapper<MeetingInfo> {
List<TencentMeetingVO.SimpleMeetingInfo> getAllMeetingIds();
// List<MeetingInfo> selectList(MeetingInfoVO vo);
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ import java.util.List;
public interface SysUserSysMapper extends BaseMapper<SysUserSync> {
String getCompanyEmail(String wid, String tenantId);
String getParentDeptId(String deptId, String tenantId);
String getParentDeptId(@Param(value = "deptId")String deptId,@Param(value = "tenantId") String tenantId);
List<UserDTO> getUserEmail(@Param(value = "tenantId")String tenantId);
......@@ -21,7 +21,7 @@ public interface SysUserSysMapper extends BaseMapper<SysUserSync> {
List<SysDept> getSimpleDeptList(@Param(value = "tenantId")String tenantId);
List<String> getSubDeptId(@Param(value = "deptId")String deptId);
List<String> getSubDeptId(@Param(value = "deptId")String deptId,@Param(value = "tenantId")String tenantId);
List<String> getUsersByDept(@Param(value = "deptIds") List<String> deptIds);
List<String> getUsersByDept(@Param(value = "deptIds") List<String> deptIds,@Param(value = "tenantId")String tenantId);
}
......@@ -133,4 +133,9 @@ public class MeetingInfo implements Serializable {
* 模板ID
*/
private Integer templateId;
/**
* 转录文件知识库id
*/
private String transDocId;
}
\ No newline at end of file
......@@ -72,11 +72,19 @@ public class MeetingRecordTemplate implements Serializable {
* 创建人
*/
private String createUser;
/**
* 创建人名称
*/
private String createUserName;
/**
* 更新人
*/
private String updateUser;
/**
* 更新人名称
*/
private String updateUserName;
/**
* 删除标识
......@@ -87,4 +95,12 @@ public class MeetingRecordTemplate implements Serializable {
* 模板文件
*/
private String template;
/**
* 引用的纪要模板id
*/
private Integer referTemplateId;
/**
* 引用的纪要模板名称
*/
private String referTemplateName;
}
\ No newline at end of file
......@@ -9,6 +9,8 @@ import com.cmeeting.mapper.primary.MeetingInfoMapper;
import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper;
import com.cmeeting.pojo.UserId;
import com.cmeeting.util.MinioUtils;
import com.cmeeting.util.UserAdminConfig;
import com.cmeeting.util.UserAdminTokenUtil;
import com.cmeeting.vo.TencentMeetingVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -47,6 +49,10 @@ public class FileProcessProducer {
private String llmApiAddr;
@Value(value = "${tencent.base-save-path}")
private String baseSavePath;
@Value("${permission.applicationId}")
public String applicationId;
@Value("${permission.tenantId}")
public String permTenantId;
@Resource
private MeetingInfoMapper meetingInfoMapper;
@Resource
......@@ -57,6 +63,11 @@ public class FileProcessProducer {
private EmailSender emailSender;
@Resource
private ProcessLogService processLogService;
@Resource
private UserAdminConfig userAdminConfig;
//中集知识库文件的预览访问路径前缀
@Value("${userAdmin.file-download-path}")
private String fileDownloadPath;
/**
* 批量提交生成纪要任务
......@@ -68,7 +79,7 @@ public class FileProcessProducer {
*/
public void submitBatchTasks(List<TencentMeetingVO.RecordFile> recordFiles, List<UserDTO.TemplateAuthorizedUserDTO> authorizedUsers, Map<String,String> tidWidRelations, Boolean finalRetry) {
List<Future<?>> futures = new ArrayList<>();
String adminToken = UserAdminTokenUtil.getUserAdminToken();
for (TencentMeetingVO.RecordFile recordFile : recordFiles) {
// 为每个URL创建任务
FileProcessTask task = new FileProcessTask(
......@@ -90,7 +101,12 @@ public class FileProcessProducer {
finalRetry,
processLogService,
authorizedUsers,
tidWidRelations
tidWidRelations,
userAdminConfig,
adminToken,
applicationId,
fileDownloadPath,
permTenantId
);
// 提交任务到线程池
......
......@@ -37,4 +37,11 @@ public interface MeetingRecordTemplateService extends IService<MeetingRecordTemp
* @return
*/
List<UserDTO.TemplateAuthorizedUserDTO> selectAuthorizedUsers();
/**
* 用户下拉选择的模板列表(权限内)
* @param vo
* @return
*/
List<MeetingRecordTemplate> getSelectList(RecordTemplateVO vo);
}
package com.cmeeting.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cmeeting.ad.entity.SysUserSync;
public interface SysUserSyncService extends IService<SysUserSync> {
String getDeptPathByUserId(String userId);
}
......@@ -15,6 +15,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmeeting.ad.entity.RobotSecurityUser;
import com.cmeeting.ad.util.SecurityUtil;
import com.cmeeting.log.service.ProcessLogService;
import com.cmeeting.mapper.primary.MeetingInfoMapper;
import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper;
......@@ -88,6 +90,8 @@ public class MeetingInfoServiceImpl extends ServiceImpl<MeetingInfoMapper, Meeti
@Override
public IPage<MeetingInfo> getPage(MeetingInfoVO vo) {
RobotSecurityUser user = SecurityUtil.getUser();
vo.setUserId(user.getId());
LambdaQueryWrapper<MeetingInfo> queryWrapper = new LambdaQueryWrapper<>();
IPage<MeetingInfo> resultPage = mapper.selectPage(new Page<>(vo.getCurrent(), vo.getSize()), queryWrapper);
return resultPage;
......
......@@ -19,9 +19,12 @@ import com.cmeeting.mapper.secondary.SysUserSysMapper;
import com.cmeeting.pojo.MeetingRecordTemplate;
import com.cmeeting.pojo.RecordTemplatePermission;
import com.cmeeting.service.MeetingRecordTemplateService;
import com.cmeeting.service.SysUserSyncService;
import com.cmeeting.util.MinioUtils;
import com.cmeeting.vo.RecordTemplateVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
......@@ -41,15 +44,22 @@ public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordT
private RecordTemplatePermissionMapper permissionMapper;
@Resource
private SysUserSysMapper sysUserSysMapper;
@Resource
private SysUserSyncService sysUserSyncService;
@Value(value = "${permission.tenantId}")
private String permissionTenantId;
@Override
public IPage<MeetingRecordTemplate> getPage(RecordTemplateVO vo) {
RobotSecurityUser user = SecurityUtil.getUser();
LambdaQueryWrapper<MeetingRecordTemplate> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(MeetingRecordTemplate::getIsDel,Boolean.FALSE);
queryWrapper.eq(vo.getType() != null,MeetingRecordTemplate::getType,vo.getType());
queryWrapper.like(vo.getName() != null,MeetingRecordTemplate::getName,vo.getName());
queryWrapper.like(vo.getMeetingType() != null,MeetingRecordTemplate::getMeetingType,vo.getMeetingType());
queryWrapper.eq(StringUtils.isNotEmpty(vo.getType()),MeetingRecordTemplate::getType,vo.getType());
queryWrapper.like(StringUtils.isNotEmpty(vo.getName()),MeetingRecordTemplate::getName,vo.getName());
queryWrapper.like(StringUtils.isNotEmpty(vo.getMeetingType()),MeetingRecordTemplate::getMeetingType,vo.getMeetingType());
queryWrapper.like(StringUtils.isNotEmpty(vo.getCreateUser()),MeetingRecordTemplate::getCreateUserName,vo.getCreateUser());
queryWrapper.between(vo.getStartTime() != null && vo.getEndTime() != null,MeetingRecordTemplate::getUpdateTime,vo.getStartTime(),vo.getEndTime());
queryWrapper.orderByDesc(MeetingRecordTemplate::getId);
IPage<MeetingRecordTemplate> resultPage = baseMapper.selectPage(new Page<>(vo.getCurrent(), vo.getSize()), queryWrapper);
List<MeetingRecordTemplate> records = resultPage.getRecords();
if(!CollectionUtils.isEmpty(records)){
......@@ -77,6 +87,9 @@ public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordT
systemQueryWrapper.eq(MeetingRecordTemplate::getType,RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM);
systemQueryWrapper.like(vo.getName() != null,MeetingRecordTemplate::getName,vo.getName());
systemQueryWrapper.like(vo.getMeetingType() != null,MeetingRecordTemplate::getMeetingType,vo.getMeetingType());
systemQueryWrapper.like(StringUtils.isNotEmpty(vo.getCreateUser()),MeetingRecordTemplate::getCreateUserName,vo.getCreateUser());
systemQueryWrapper.between(vo.getStartTime() != null && vo.getEndTime() != null,MeetingRecordTemplate::getUpdateTime,vo.getStartTime(),vo.getEndTime());
systemQueryWrapper.orderByDesc(MeetingRecordTemplate::getId);
List<MeetingRecordTemplate> systemTemplateList = baseMapper.selectList(systemQueryWrapper);
//用户可见的系统模板权限
List<MeetingRecordTemplate> authorizedSystemTemplateList = new ArrayList<>();
......@@ -96,6 +109,9 @@ public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordT
customQueryWrapper.eq(MeetingRecordTemplate::getCreateUser, user.getId());
customQueryWrapper.like(vo.getName() != null,MeetingRecordTemplate::getName,vo.getName());
customQueryWrapper.like(vo.getMeetingType() != null,MeetingRecordTemplate::getMeetingType,vo.getMeetingType());
customQueryWrapper.like(StringUtils.isNotEmpty(vo.getCreateUser()),MeetingRecordTemplate::getCreateUserName,vo.getCreateUser());
customQueryWrapper.between(vo.getStartTime() != null && vo.getEndTime() != null,MeetingRecordTemplate::getUpdateTime,vo.getStartTime(),vo.getEndTime());
customQueryWrapper.orderByDesc(MeetingRecordTemplate::getId);
List<MeetingRecordTemplate> customTemplateList = baseMapper.selectList(customQueryWrapper);
List<MeetingRecordTemplate> resultList = new ArrayList<>();
......@@ -180,9 +196,9 @@ public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordT
List<String> deptPath = new ArrayList<>();
for (RecordTemplatePermission deptPermission : deptPermissions) {
String deptId = deptPermission.getRelId();
getDeptPath(deptPath,deptId);
getDeptPath(deptPath,deptId,permissionTenantId);
}
List<String> usersByDept = sysUserSysMapper.getUsersByDept(deptPath);
List<String> usersByDept = sysUserSysMapper.getUsersByDept(deptPath,permissionTenantId);
if(!CollectionUtils.isEmpty(usersByDept))
authorizedUsers.addAll(usersByDept);
}
......@@ -192,21 +208,66 @@ public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordT
return result;
}
@Override
public List<MeetingRecordTemplate> getSelectList(RecordTemplateVO vo) {
RobotSecurityUser user = SecurityUtil.getUser();
//查出所有系统模板
LambdaQueryWrapper<MeetingRecordTemplate> systemQueryWrapper = new LambdaQueryWrapper<>();
systemQueryWrapper.eq(MeetingRecordTemplate::getIsDel,Boolean.FALSE);
systemQueryWrapper.eq(MeetingRecordTemplate::getType,RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM);
systemQueryWrapper.like(vo.getName() != null,MeetingRecordTemplate::getName,vo.getName());
systemQueryWrapper.like(vo.getMeetingType() != null,MeetingRecordTemplate::getMeetingType,vo.getMeetingType());
systemQueryWrapper.orderByDesc(MeetingRecordTemplate::getId);
List<MeetingRecordTemplate> systemTemplateList = baseMapper.selectList(systemQueryWrapper);
if(CollectionUtils.isEmpty(systemTemplateList)) return new ArrayList<>();
//用户可见的系统模板权限
List<MeetingRecordTemplate> records = new ArrayList<>();
//查出所有系统模板授权人员信息
List<RecordTemplatePermission> userPermissions = permissionMapper.selectList(new LambdaQueryWrapper<RecordTemplatePermission>()
.eq(RecordTemplatePermission::getTemplateType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)
.eq(RecordTemplatePermission::getRelId,user.getId())
.eq(RecordTemplatePermission::getRelType,RecordTemplateConstant.REL_TYPE_USER)
);
//当前登录人员被直接授权的模板
List<Integer> templateIdsAccepted = CollectionUtils.isEmpty(userPermissions)
? new ArrayList<>() : userPermissions.stream().map(RecordTemplatePermission::getTemplateId).collect(Collectors.toList());
//查出所有系统模板授权部门信息
List<RecordTemplatePermission> deptPermissions = permissionMapper.selectList(new LambdaQueryWrapper<RecordTemplatePermission>()
.eq(RecordTemplatePermission::getTemplateType, RecordTemplateConstant.TEMPLATE_TYPE_SYSTEM)
.eq(RecordTemplatePermission::getRelId,user.getId())
.eq(RecordTemplatePermission::getRelType,RecordTemplateConstant.REL_TYPE_DEPT));
//查出当前登录人的部门向上路径
String deptPathByUser = sysUserSyncService.getDeptPathByUserId(user.getId());
if(StringUtils.isNotEmpty(deptPathByUser) && !CollectionUtils.isEmpty(deptPermissions)){
List<Integer> templateIdsDeptAccepted = deptPermissions.stream().filter(item -> deptPathByUser.contains(item.getRelId()))
.map(RecordTemplatePermission::getTemplateId).collect(Collectors.toList());
if(!CollectionUtils.isEmpty(templateIdsDeptAccepted)) templateIdsAccepted.addAll(templateIdsDeptAccepted);
}
for (MeetingRecordTemplate template : systemTemplateList) {
if(templateIdsAccepted.contains(template.getId())){
records.add(template);
}
}
return records;
}
/**
* 获取部门的路径
* @param deptPath
* @param deptId
*/
private void getDeptPath(List<String> deptPath, String deptId) {
private void getDeptPath(List<String> deptPath, String deptId, String tenantId) {
if(!deptPath.contains(deptId)) deptPath.add(deptId);
List<String> subDeptIds = sysUserSysMapper.getSubDeptId(deptId);
List<String> subDeptIds = sysUserSysMapper.getSubDeptId(deptId,tenantId);
if(CollectionUtils.isEmpty(subDeptIds)) return;
for (String subDeptId : subDeptIds) {
//部门id去重
if(!deptPath.contains(subDeptId)){
deptPath.add(subDeptId);
getDeptPath(deptPath,subDeptId);
getDeptPath(deptPath,subDeptId,tenantId);
}
}
......
package com.cmeeting.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmeeting.ad.entity.SysUserSync;
import com.cmeeting.mapper.secondary.SysUserSysMapper;
import com.cmeeting.service.SysUserSyncService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
@Service
@Slf4j
public class SysUserSyncServiceImpl extends ServiceImpl<SysUserSysMapper, SysUserSync> implements SysUserSyncService {
@Value(value = "${permission.tenantId}")
private String perTenantId;
@Override
public String getDeptPathByUserId(String userId) {
SysUserSync sysUserSync = baseMapper.selectOne(new LambdaQueryWrapper<SysUserSync>().eq(SysUserSync::getTenantId, perTenantId).eq(SysUserSync::getUserId, userId));
String deptId = sysUserSync.getDeptId();
String deptPath = getDeptPath("/" + deptId, deptId);
return deptPath;
}
/**
* 向上获取某个部门的路径
* @param deptId
*/
private String getDeptPath(String deptPath,String deptId) {
String parentDeptId = baseMapper.getParentDeptId(deptId,perTenantId);
if(StringUtils.isEmpty(parentDeptId)) return deptPath;
return "/" + parentDeptId + deptPath;
}
}
......@@ -368,10 +368,11 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
String subMeetingId = null;
LocalDateTime mediaStartTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.valueOf(meeting.getMediaStartTime())), ZoneId.systemDefault());
try {
log.info("【周期会议扫描】:查询用户的已结束会议列表...userId->{}",meeting.getUserid());
String userid = meeting.getUserid();
log.info("【周期会议扫描】:查询用户的已结束会议列表...meetingCode->{},userId->{}",meeting.getMeetingCode(), userid);
//获取子会议id
MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest historyMeetingRequest =
new MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest.Builder(meeting.getUserid())
new MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest.Builder(userid)
.pageSize("20")
.page("1")
.meetingCode(meeting.getMeetingCode())
......@@ -558,14 +559,14 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
getDeptPath(deptPath,deptId,tenantId);
}
//已被授权部门下的userid
List<String> accessUserIds = !CollectionUtils.isEmpty(deptPath) ? sysUserSyncMapper.getUsersByDept(deptPath) : new ArrayList<>();
List<String> accessUserIds = !CollectionUtils.isEmpty(deptPath) ? sysUserSyncMapper.getUsersByDept(deptPath,permissionTenantId) : new ArrayList<>();
//已被直接授权的人员追加进去
accessUserIds.addAll(auths.stream().filter(item -> item.getType().equals(1)).map(CoreModulePermissions::getRelId).collect(Collectors.toList()));
if(!CollectionUtils.isEmpty(accessUserIds)){
//查出人员邮箱
List<UserDTO> userEmailList = sysUserSyncMapper.getUserEmail(permissionTenantId);
Map<String, String> userEmailMap = CollectionUtils.isEmpty(userEmailList) ? new HashMap<>()
: userEmailList.stream().collect(Collectors.toMap(UserDTO::getWid, UserDTO::getEmail));
: userEmailList.stream().collect(Collectors.toMap(UserDTO::getWid, UserDTO::getEmail,(existing, replacement) -> existing));
List<UserDTO> accessUsers = new ArrayList<>();
for (String accessUserId : accessUserIds) {
......@@ -598,7 +599,7 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
*/
private void getDeptPath(List<String> deptPath, String deptId, String tenantId) {
if(!deptPath.contains(deptId)) deptPath.add(deptId);
List<String> subDeptIds = sysUserSyncMapper.getSubDeptId(deptId);
List<String> subDeptIds = sysUserSyncMapper.getSubDeptId(deptId,tenantId);
if(CollectionUtils.isEmpty(subDeptIds)) return;
for (String subDeptId : subDeptIds) {
......
package com.cmeeting.util;
import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
public class CustomMultipartFile implements MultipartFile {
private final String name;
private final String originalFilename;
private final String contentType;
private final byte[] content;
public CustomMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
this.name = name;
this.originalFilename = originalFilename;
this.contentType = contentType;
this.content = content;
}
@Override
public String getName() {
return name;
}
@Override
public String getOriginalFilename() {
return originalFilename;
}
@Override
public String getContentType() {
return contentType;
}
@Override
public boolean isEmpty() {
return content == null || content.length == 0;
}
@Override
public long getSize() {
return content.length;
}
@Override
public byte[] getBytes() throws IOException {
return content;
}
@JSONField(serialize = false)
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(content);
}
@JSONField(serialize = false)
@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
try (OutputStream os = new FileOutputStream(dest)) {
os.write(content);
}
}
}
package com.cmeeting.util;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
......@@ -18,6 +16,8 @@ import java.io.Serializable;
@ToString
@Accessors(chain = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class R implements Serializable {
public static final int SUCCESS_CODE = 0;
......
......@@ -12,4 +12,6 @@ public class UserAdminConfig {
private String userAdminDomain;
@Value("${userAdmin.systemDomain}")
private String systemDomain;
@Value("${userAdmin.docDomain}")
private String docDomain;
}
package com.cmeeting.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
......@@ -61,11 +63,15 @@ public class MeetingInfoVO {
/**
* 会议开始时间(时间戳)
*/
@DateTimeFormat(pattern = "yyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime startTime;
/**
* 会议结束时间(时间戳)
*/
@DateTimeFormat(pattern = "yyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime endTime;
/**
......@@ -91,6 +97,8 @@ public class MeetingInfoVO {
/**
* 同步时间
*/
@DateTimeFormat(pattern = "yyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime syncTime;
/**
......@@ -113,6 +121,8 @@ public class MeetingInfoVO {
/**
* 同步时间
*/
@DateTimeFormat(pattern = "yyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime updateTime;
/**
......@@ -123,4 +133,14 @@ public class MeetingInfoVO {
* 会议纪要json
*/
private String recordJson;
/**
* 用户信息
*/
private String userId;
private String applicationId;
/**
* 转录文件知识库id
*/
private String transDocId;
}
\ No newline at end of file
package com.cmeeting.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import java.util.List;
/**
......@@ -48,6 +51,25 @@ public class RecordTemplateVO {
*/
private Integer size;
/**
* 创建人查询条件
*/
private String createUser;
/**
* 时间查询条件开始
*/
@DateTimeFormat(pattern = "yyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime startTime;
/**
* 时间查询条件结束
*/
@DateTimeFormat(pattern = "yyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", locale = "zh", timezone = "GMT+8")
private LocalDateTime endTime;
@Data
public static class TemplatePermissionVO{
/**
......
server:
port: 8080
port: 8081
############################################################## minio
MINIO_ADDRESS: http://192.168.10.154:9000
......@@ -110,6 +110,9 @@ email:
sender: ${EMAIL_SENDER}
sender-pwd: ${EMAIL_SENDER_PWD}
smtp-host: ${EMAIL_SMTP_HOST}
push-switch: true #邮件推送总开关,高优先级
environment: test #test推给本公司人员,prod推给用户
test-receiver: duanxincheng@chatbot.cn #用于测试的收方邮箱
llm:
api-addr: ${LLM_API_ADDR}
......@@ -127,10 +130,12 @@ ldap:
domain: '@cimc.com'
userAdmin:
domain: http://192.168.10.154:9103
systemDomain: http://192.168.10.154:9101
domain: http://192.168.10.154:8303
systemDomain: http://192.168.10.154:8301
appId: af94e0ec9cc0bef2bfa63f470f6f4351
secret: 4luHTMYMyXzOmDHN0ZOSMwOst702plcr9EKqAHtT8Nag6EPlP0VSFvqv9Zq0NRDE
file-download-path: /download/minio/
docDomain: http://192.168.10.154:8302/knowledgePlatform
removeMenus: 关键词回复,业务词库,同义词管理,答案库
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论