提交 eb05d17a 作者: duanxincheng

Merge branch 'main' into staging0612-template_permission_control

# Conflicts:
#	src/main/java/com/cmeeting/job/CmeetingJob.java
#	src/main/java/com/cmeeting/job/FileProcessTask.java
......@@ -227,8 +227,8 @@ public class UserServiceImpl implements UserService {
private R loginByAD(ApplicationUserVO.Login login) {
// AD验证
// boolean auth = iLdapService.authenticate(login.getUsername().trim(), login.getPassword().trim());
if (true) {
boolean auth = iLdapService.authenticate(login.getUsername().trim(), login.getPassword().trim());
if (auth) {
SysUserSync sysUserSync = sysUserSysMapper.selectOne(new LambdaQueryWrapper<SysUserSync>()
.eq(SysUserSync::getTenantId, permissionTenantId)
.eq(SysUserSync::getUserId, login.getUsername().trim()));
......
......@@ -5,7 +5,9 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cmeeting.email.EmailSender;
import com.cmeeting.mapper.primary.MeetingRecordTemplateMapper;
import com.cmeeting.pojo.MeetingInfo;
import com.cmeeting.pojo.MeetingRecordTemplate;
import com.cmeeting.service.MeetingInfoService;
import com.cmeeting.util.MinioUtils;
import com.cmeeting.util.R;
......@@ -16,6 +18,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
......@@ -50,6 +53,8 @@ public class MeetingInfoController {
private MinioUtils minioUtils;
@Resource
private EmailSender emailSender;
@Resource
private MeetingRecordTemplateMapper meetingRecordTemplateMapper;
@PostMapping("/updateRecordXml")
public R updateRecordXml(@RequestBody MeetingInfoVO vo) {
......@@ -57,6 +62,17 @@ public class MeetingInfoController {
return R.ok(save);
}
/**
* 重新生成
* @param vo
* @return
*/
@PostMapping("/regenerateXml")
public R regenerateXml(@RequestBody MeetingInfoVO vo) {
boolean isSuccess = meetingInfoService.regenerateXml(vo);
return R.ok(isSuccess);
}
@PostMapping("/list")
public R list(@RequestBody MeetingInfoVO vo) {
IPage<MeetingInfo> page = meetingInfoService.getPage(vo);
......@@ -76,10 +92,21 @@ public class MeetingInfoController {
String json = convertXmlToJSON(xml);
vo.setRecordJson(json);
}
} catch (Exception e) {
e.printStackTrace();
// try(InputStream is = minioUtils.getFile(recordXml)){
// byte[] bytes = IOUtils.toByteArray(is);
// String json = convertXmlToJSON(new String(bytes));
// vo.setRecordJson(json);
// }catch (Exception ex){
// e.printStackTrace();
// }
}
try {
if(StringUtils.isNotEmpty(recordContent)){
vo.setRecordContent(minioUtils.getFileText(recordContent));
}
} catch (IOException e) {
} catch (Exception e) {
e.printStackTrace();
}
return R.ok(vo);
......@@ -98,7 +125,6 @@ public class MeetingInfoController {
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf8"));
XWPFTemplate template;
try (XWPFDocument document = new XWPFDocument(); OutputStream os = response.getOutputStream()) {
// 将文本按行分割并逐行添加到 Word 文档
String[] lines = content.split("\\r?\\n");
......@@ -140,13 +166,13 @@ public class MeetingInfoController {
participantsMap.put("meeting_host",meetingInfo.getHost());
dataModel.putAll(participantsMap);
ClassPathResource resource = new ClassPathResource("template/data_network.docx");
MeetingRecordTemplate meetingRecordTemplate = meetingRecordTemplateMapper.selectById(2);
String fileName = String.format(meetingInfo.getSubject() + "_会议纪要_%s.docx", DateUtil.today());
response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf8"));
XWPFTemplate template;
try (InputStream is = resource.getInputStream();OutputStream os = response.getOutputStream()) {
try (InputStream is = minioUtils.getFile(meetingRecordTemplate.getTemplate());OutputStream os = response.getOutputStream()) {
template = XWPFTemplate.compile(is).render(dataModel);
template.write(os);
} catch (IOException e) {
......@@ -179,10 +205,10 @@ public class MeetingInfoController {
participantsMap.put("meeting_host",meetingInfo.getHost());
dataModel.putAll(participantsMap);
ClassPathResource resource = new ClassPathResource("template/data_network.docx");
MeetingRecordTemplate meetingRecordTemplate = meetingRecordTemplateMapper.selectById(2);
XWPFTemplate template;
byte[] meetingMinutesBytes;
try (InputStream is = resource.getInputStream();ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (InputStream is = minioUtils.getFile(meetingRecordTemplate.getTemplate());ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
template = XWPFTemplate.compile(is).render(dataModel);
template.write(baos);
meetingMinutesBytes = baos.toByteArray();
......
......@@ -174,8 +174,8 @@ public class EmailSender {
AtomicInteger retryCount = new AtomicInteger(0);
boolean isSent = false;
// String toEmail = emailPushBuilder.getToEmail();
String toEmail = "duanxincheng@chatbot.cn";
String toEmail = emailPushBuilder.getToEmail();
// String toEmail = "duanxincheng@chatbot.cn";
String subject = emailPushBuilder.getSubject();
String meetingId = emailPushBuilder.getMeetingId();
if(StringUtils.isEmpty(toEmail)){
......
......@@ -91,8 +91,8 @@ public class CmeetingJob {
log.info("-------关联企微腾会人员定时任务结束--------");
}
// @Scheduled(fixedRate = 10 * 60 * 1000,initialDelay = 2 * 60 * 1000)
// @Scheduled(fixedRate = 10 * 60 * 1000)
// @Scheduled(fixedRate = 20 * 60 * 1000,initialDelay = 2 * 60 * 1000)
@Scheduled(fixedRate = 20 * 60 * 1000)
public void execute() {
// 定义时间格式化器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
......@@ -136,7 +136,7 @@ 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 {
......@@ -180,7 +180,8 @@ public class CmeetingJob {
/**
* 定时扫描早于一小时之前的,所有邮件推送未重试过的会议,重新推送邮件
*/
@Scheduled(fixedRate = 30 * 60 * 1000,initialDelay = 15 * 60 * 1000)
// @Scheduled(fixedRate = 30 * 60 * 1000,initialDelay = 15 * 60 * 1000)
// @Scheduled(fixedRate = 30 * 60 * 1000)
public void emailPushRetry() {
try {
log.info("-------邮件推送重试定时任务开始-------");
......@@ -191,6 +192,8 @@ public class CmeetingJob {
meetingInfoService.list(new LambdaQueryWrapper<MeetingInfo>()
.eq(MeetingInfo::getIsGenerated,Boolean.TRUE)
.eq(MeetingInfo::getEmailPushAccess,Boolean.TRUE)
.eq(MeetingInfo::getIsPushed,Boolean.FALSE)
.eq(MeetingInfo::getPushRetry,Boolean.FALSE)
.le(MeetingInfo::getSyncTime,LocalDateTime.now().minusHours(1))
);
......
......@@ -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.TencentMeetingVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
......@@ -12,6 +13,6 @@ import java.util.List;
public interface MeetingInfoMapper extends BaseMapper<MeetingInfo> {
void batchInsert(@Param("meetingSaveList")List<MeetingInfo> meetingSaveList);
List<String> getAllMeetingIds();
List<TencentMeetingVO.SimpleMeetingInfo> getAllMeetingIds();
}
\ No newline at end of file
......@@ -9,4 +9,6 @@ public interface MeetingInfoService extends IService<MeetingInfo> {
IPage<MeetingInfo> getPage(MeetingInfoVO vo);
boolean updateRecordXml(MeetingInfoVO vo);
boolean regenerateXml(MeetingInfoVO vo);
}
......@@ -329,6 +329,7 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
.withSecret(tencentSecretId,tencentSecretKey)
.build();
List<TencentMeetingVO.RecordFile> meetingFiles = new ArrayList<>();
List<TencentMeetingVO.RecordFile> recordFileUrlList = new ArrayList<>();
List<MeetingInfo> meetingSaveList = new ArrayList<>();
// 查询近两天的会议录制列表
......@@ -343,7 +344,7 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
Integer totalPage = firstData.getTotalPage();
//目前已存储的会议id
List<String> meetingIds = meetingInfoMapper.getAllMeetingIds();
List<TencentMeetingVO.SimpleMeetingInfo> meetingIds = meetingInfoMapper.getAllMeetingIds();
List<TencentMeetingUser> meetingUsers = tecentMeetingMapper.getAlluser();
Map<String, String> meetingMap = meetingUsers.stream().collect(Collectors.toMap(TencentMeetingUser::getUserId, TencentMeetingUser::getUserName));
while (currentPage.intValue() <= totalPage){
......@@ -356,11 +357,8 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
//1:录制中
//2:转码中
//3:转码完成
if(meetings.stream().allMatch(item->item.getState() != 3)){
return null;
}
for (CorpRecordsVO.RecordMeeting meeting : meetings) {
//会议没结束,跳过
//录制文件未转码完成,跳过
if(meeting.getState() != 3){
// processLogService.log(meeting.getMeetingId(),null,"会议未结束,跳过生成");
continue;
......@@ -372,15 +370,36 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
//查询会议详情
String meetingId = meeting.getMeetingId();
String subMeetingId = null;
MeetingsApi.ApiV1MeetingsMeetingIdGetRequest meetingRequest =
new MeetingsApi.ApiV1MeetingsMeetingIdGetRequest.Builder(meetingId)
.operatorId(tencentAdminUserId)
.operatorIdType("1")
.instanceid("0")
.build();
LocalDateTime mediaStartTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.valueOf(meeting.getMediaStartTime())), ZoneId.systemDefault());
try {
log.info("【周期会议扫描】:查询用户的已结束会议列表...userId->{}",meeting.getUserid());
//获取子会议id
MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest historyMeetingRequest =
new MeetingsApi.ApiV1HistoryMeetingsUseridGetRequest.Builder(meeting.getUserid())
.pageSize("20")
.page("1")
.meetingCode(meeting.getMeetingCode())
.startTime(String.valueOf(mediaStartTime.toLocalDate().atStartOfDay().atZone(ZoneId.systemDefault()).toEpochSecond()))
.endTime(String.valueOf(mediaStartTime.toLocalDate().atStartOfDay().plusDays(1).atZone(ZoneId.systemDefault()).toEpochSecond()))
.build();
MeetingsApi.ApiV1HistoryMeetingsUseridGetResponse historyMeetingResponse =
client.meetings().v1HistoryMeetingsUseridGet(historyMeetingRequest, new JWTAuthenticator.Builder()
.nonce(BigInteger.valueOf(Math.abs((new SecureRandom()).nextInt()))).timestamp(String.valueOf(System.currentTimeMillis() / 1000L)));
V1HistoryMeetingsUseridGet200Response historyMeetingResponseData = historyMeetingResponse.getData();
List<V1HistoryMeetingsUseridGet200ResponseMeetingInfoListInner> historyMeetingInfoList = historyMeetingResponseData.getMeetingInfoList();
if(CollectionUtils.isEmpty(historyMeetingInfoList)){
log.error("会议未结束,获取子会议id信息失败");
continue;
}
V1HistoryMeetingsUseridGet200ResponseMeetingInfoListInner historyMeeting = historyMeetingInfoList.get(0);
//如果是周期会议
if(historyMeeting.getMeetingType() == 1){
subMeetingId = historyMeeting.getSubMeetingId();
}
//如果数据库中已有相同会议id的记录,跳过同步
if(!meetingIds.contains(meetingId)){
String finalSubMeetingId = subMeetingId;
if(!meetingIds.stream().anyMatch(item->item.getMeetingId().equals(meetingId) && Objects.equals(item.getSubMeetingId(), finalSubMeetingId))){
log.info("【会议检索】新的会议meetingId->{}",meeting.getMeetingId());
List<CorpRecordsVO.RecordFile> recordFiles = meeting.getRecordFiles();
//按转录文件时间升序,便于后续的内容拼接
......@@ -399,6 +418,12 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
}else{
//判断主持人是否存在,如果主持人未参会,是查不到主持人的
//如果主持人未参会,使用会议详情中的创建人作为主持人
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())))
......@@ -469,7 +494,7 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
//会议基本信息保存
MeetingInfo meetingItem = MeetingInfo.builder().meetingId(meetingId).meetingCode(meeting.getMeetingCode())
.subject(meeting.getSubject())
.startTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.valueOf(meeting.getMediaStartTime())), ZoneId.systemDefault()))
.startTime(mediaStartTime)
// .endTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(Long.valueOf(meeting.getEndTime())), ZoneId.systemDefault()))
.isGenerated(Boolean.FALSE).emailPushAccess(Boolean.TRUE).isPushed(Boolean.FALSE).syncTime(LocalDateTime.now())
.subMeetingId(subMeetingId).generateRetry(Boolean.FALSE).pushRetry(Boolean.FALSE)
......@@ -497,8 +522,13 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
List<MeetingInfo> finalSaveList = new ArrayList<>();
for (Map.Entry<String, List<MeetingInfo>> entry : meetingSaveMap.entrySet()) {
MeetingInfo meetingInfo = entry.getValue().get(0);
meetingInfo.setRecordFileId(entry.getValue().stream().map(MeetingInfo::getRecordFileId).collect(Collectors.joining(",")));
List<String> recordFileIdList = entry.getValue().stream().flatMap(s -> Arrays.stream(s.getRecordFileId().split(","))).collect(Collectors.toList());
meetingInfo.setRecordFileId(recordFileIdList.stream().collect(Collectors.joining(",")));
finalSaveList.add(meetingInfo);
meetingFiles.add(TencentMeetingVO.RecordFile.builder()
.meetingId(meetingInfo.getMeetingId())
.subMeetingId(meetingInfo.getSubMeetingId())
.recordFileIdList(recordFileIdList).build());
}
meetingInfoMapper.batchInsert(finalSaveList);
}
......@@ -510,7 +540,7 @@ public class TencentMeetingServiceImpl extends ServiceImpl<TecentMeetingMapper,T
processLogService.log(null,null,sw.toString());
throw new RuntimeException(e.getMessage());
}
return recordFileUrlList;
return meetingFiles;
}
/**
......
......@@ -34,4 +34,13 @@ public class TencentMeetingVO {
private String subMeetingId;//如果是周期会议,这个id表示子会议
private List<String> recordFileIdList;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public static class SimpleMeetingInfo{
private String meetingId;//如果是周期会议,这个id表示主会议
private String subMeetingId;//如果是周期会议,这个id表示子会议
}
}
\ No newline at end of file
......@@ -29,7 +29,7 @@
)
</foreach>
</insert>
<select id="getAllMeetingIds" resultType="java.lang.String">
select meeting_id from cmt_meeting_info
<select id="getAllMeetingIds" resultType="com.cmeeting.vo.TencentMeetingVO$SimpleMeetingInfo">
select meeting_id,sub_meeting_id from cmt_meeting_info
</select>
</mapper>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论