Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
cmeeting
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
翟斌
cmeeting
Commits
2089d7b6
提交
2089d7b6
authored
6月 09, 2025
作者:
duanxincheng
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
纪要模板上传,邮件推送服务迭代,历史会议纪要接口(包括导出原文,导出会议纪要)
父级
4ce8c62e
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
502 行增加
和
73 行删除
+502
-73
src/main/java/com/cmeeting/config/ThreadPoolConfig.java
+2
-2
src/main/java/com/cmeeting/controller/MeetingInfoController.java
+0
-0
src/main/java/com/cmeeting/controller/RecordTemplateController.java
+29
-2
src/main/java/com/cmeeting/controller/TencentMeetingController.java
+2
-14
src/main/java/com/cmeeting/email/EmailSender.java
+18
-13
src/main/java/com/cmeeting/job/CmeetingJob.java
+1
-1
src/main/java/com/cmeeting/job/EmailPushTask.java
+14
-32
src/main/java/com/cmeeting/job/FileProcessTask.java
+0
-0
src/main/java/com/cmeeting/pojo/MeetingInfo.java
+10
-0
src/main/java/com/cmeeting/pojo/MeetingRecordTemplate.java
+6
-0
src/main/java/com/cmeeting/service/MeetingInfoService.java
+5
-0
src/main/java/com/cmeeting/service/MeetingRecordTemplateService.java
+10
-0
src/main/java/com/cmeeting/service/impl/MeetingInfoServiceImpl.java
+76
-0
src/main/java/com/cmeeting/service/impl/MeetingRecordTemplateServiceImpl.java
+55
-0
src/main/java/com/cmeeting/service/impl/TecentMeetingServiceImpl.java
+0
-0
src/main/java/com/cmeeting/util/MinioUtils.java
+16
-9
src/main/java/com/cmeeting/util/SignatureUtil.java
+41
-0
src/main/java/com/cmeeting/vo/CorpRecordsVO.java
+52
-0
src/main/java/com/cmeeting/vo/EmailPush.java
+38
-0
src/main/java/com/cmeeting/vo/MeetingInfoVO.java
+127
-0
src/main/resources/template/data_net_template.docx
+0
-0
没有找到文件。
src/main/java/com/cmeeting/config/ThreadPoolConfig.java
浏览文件 @
2089d7b6
...
...
@@ -15,9 +15,9 @@ public class ThreadPoolConfig {
public
ThreadPoolTaskExecutor
fileProcessExecutor
()
{
ThreadPoolTaskExecutor
executor
=
new
ThreadPoolTaskExecutor
();
// 核心线程数 (CPU密集型任务建议核心数+1)
executor
.
setCorePoolSize
(
4
);
// 固定核心线程数,避免动态获取CPU核心数
executor
.
setCorePoolSize
(
2
);
// 固定核心线程数,避免动态获取CPU核心数
// 最大线程数
executor
.
setMaxPoolSize
(
4
);
executor
.
setMaxPoolSize
(
2
);
// 队列容量
executor
.
setQueueCapacity
(
1000
);
// 线程名前缀
...
...
src/main/java/com/cmeeting/controller/MeetingInfoController.java
0 → 100644
浏览文件 @
2089d7b6
差异被折叠。
点击展开。
src/main/java/com/cmeeting/controller/RecordTemplateController.java
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
controller
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
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.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.service.MeetingRecordTemplateService
;
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
java.time.LocalDateTime
;
...
...
@@ -45,9 +44,37 @@ public class RecordTemplateController {
return
R
.
ok
(
save
);
}
/**
* 纪要模板列表,通过type区分为系统模板还是自定义模板
* @param vo
* @return
*/
@PostMapping
(
"/list"
)
public
R
list
(
@RequestBody
RecordTemplateVO
vo
)
{
IPage
<
MeetingRecordTemplate
>
page
=
recordTemplateService
.
getPage
(
vo
);
return
R
.
ok
(
page
);
}
/**
* 普通用户纪要模板,查出有授权的系统模板和个人创建的自定义模板
* @param vo
* @return
*/
@PostMapping
(
"/personalList"
)
public
R
personalList
(
@RequestBody
RecordTemplateVO
vo
)
{
IPage
<
MeetingRecordTemplate
>
page
=
recordTemplateService
.
getPersonalPage
(
vo
);
return
R
.
ok
(
page
);
}
@PostMapping
(
"/detail"
)
public
R
detail
(
@RequestBody
RecordTemplateVO
vo
)
{
MeetingRecordTemplate
detail
=
recordTemplateService
.
getById
(
vo
.
getId
());
return
R
.
ok
(
detail
);
}
@PostMapping
(
"/templateUpload"
)
public
R
templateUpload
(
@RequestParam
(
"file"
)
MultipartFile
file
,
@RequestParam
(
"id"
)
Integer
id
)
{
String
template
=
recordTemplateService
.
templateUpload
(
file
,
id
);
return
R
.
ok
(
template
);
}
}
src/main/java/com/cmeeting/controller/TencentMeetingController.java
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
controller
;
import
com.cmeeting.pojo.TencentMeetingUser
;
import
com.cmeeting.service.TecentMeetingService
;
import
com.cmeeting.vo.TencentMeetingVO
;
import
com.tencentcloudapi.wemeet.Client
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
import
org.springframework.web.bind.annotation.*
;
@RestController
@RequestMapping
(
"/tencent"
)
@RequestMapping
(
"/tencent
Meeting
"
)
public
class
TencentMeetingController
{
@Autowired
private
TecentMeetingService
tecentMeetingService
;
...
...
@@ -22,9 +15,4 @@ public class TencentMeetingController {
public
void
addUsers
()
{
tecentMeetingService
.
doUsers
();
}
// @GetMapping("/getMeetingFiles")
// public void getMeetingFiles(){
// tecentMeetingService.getMeetingFiles();
// }
}
src/main/java/com/cmeeting/email/EmailSender.java
浏览文件 @
2089d7b6
...
...
@@ -5,6 +5,7 @@ import com.azure.core.credential.TokenRequestContext;
import
com.azure.identity.ClientSecretCredential
;
import
com.azure.identity.ClientSecretCredentialBuilder
;
import
com.cmeeting.log.service.ProcessLogService
;
import
com.cmeeting.vo.EmailPush
;
import
com.microsoft.graph.authentication.TokenCredentialAuthProvider
;
import
com.microsoft.graph.models.*
;
import
com.microsoft.graph.models.Message
;
...
...
@@ -31,6 +32,7 @@ import java.nio.file.Paths;
import
java.util.Arrays
;
import
java.util.Base64
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Properties
;
import
java.util.concurrent.atomic.AtomicInteger
;
...
...
@@ -159,13 +161,10 @@ public class EmailSender {
/**
* 发送邮件,带附件
* @param toEmail
* @param subject
* @param attachmentPath
* @param meetingId
* @param emailPushBuilder
* @return
*/
public
boolean
sendEmailWithAttachment
(
String
toEmail
,
String
subject
,
String
attachmentPath
,
String
meetingId
)
{
public
boolean
sendEmailWithAttachment
(
EmailPush
emailPushBuilder
)
{
log
.
info
(
"sendEmailWithAttachment start..."
);
// 创建会话
...
...
@@ -175,6 +174,10 @@ public class EmailSender {
AtomicInteger
retryCount
=
new
AtomicInteger
(
0
);
boolean
isSent
=
false
;
// String toEmail = emailPushBuilder.getToEmail();
String
toEmail
=
"duanxincheng@chatbot.cn"
;
String
subject
=
emailPushBuilder
.
getSubject
();
String
meetingId
=
emailPushBuilder
.
getMeetingId
();
if
(
StringUtils
.
isEmpty
(
toEmail
)){
log
.
error
(
"收件邮箱为空,推送失败"
);
processLogService
.
log
(
meetingId
,
null
,
"收件邮箱为空,推送失败"
);
...
...
@@ -204,7 +207,7 @@ public class EmailSender {
GraphServiceClient
<
Request
>
graphClient
=
GraphServiceClient
.
builder
().
authenticationProvider
(
tokenCredAuthProvider
).
buildClient
();
com
.
microsoft
.
graph
.
models
.
Message
message
=
new
Message
();
message
.
subject
=
subject
;
message
.
subject
=
subject
+
"会议纪要"
;
ItemBody
body
=
new
ItemBody
();
body
.
contentType
=
BodyType
.
TEXT
;
body
.
content
=
"您好:\n\n 附件为您本次会议的会议纪要,烦请下载查看"
;
...
...
@@ -218,13 +221,15 @@ public class EmailSender {
message
.
toRecipients
=
toRecipientsList
;
//构建附件
LinkedList
<
Attachment
>
attachmentsList
=
new
LinkedList
<>();
byte
[]
recordXmlData
=
Files
.
readAllBytes
(
Paths
.
get
(
attachmentPath
));
FileAttachment
attachments
=
new
FileAttachment
();
attachments
.
name
=
attachmentPath
.
substring
(
attachmentPath
.
lastIndexOf
(
"/"
)
+
1
);
attachments
.
oDataType
=
"#microsoft.graph.fileAttachment"
;
attachments
.
contentType
=
"application/msword"
;
attachments
.
contentBytes
=
recordXmlData
;
attachmentsList
.
add
(
attachments
);
for
(
EmailPush
.
Attachment
attachment
:
emailPushBuilder
.
getAttachments
())
{
FileAttachment
attachments
=
new
FileAttachment
();
attachments
.
name
=
attachment
.
getName
()
+
".docx"
;
attachments
.
oDataType
=
"#microsoft.graph.fileAttachment"
;
attachments
.
contentType
=
"application/msword"
;
attachments
.
contentBytes
=
attachment
.
getBytes
();
attachmentsList
.
add
(
attachments
);
}
AttachmentCollectionResponse
attachmentCollectionResponse
=
new
AttachmentCollectionResponse
();
attachmentCollectionResponse
.
value
=
attachmentsList
;
...
...
src/main/java/com/cmeeting/job/CmeetingJob.java
浏览文件 @
2089d7b6
...
...
@@ -134,7 +134,7 @@ public class CmeetingJob {
}
// @Scheduled(fixedRate = 5 * 60 * 1000,initialDelay = 2 * 60 * 1000)
@Scheduled
(
fixedRate
=
5
*
60
*
1000
)
@Scheduled
(
fixedRate
=
10
*
60
*
1000
)
public
void
execute
()
{
// 定义时间格式化器
DateTimeFormatter
formatter
=
DateTimeFormatter
.
ofPattern
(
"yyyy-MM-dd HH:mm:ss"
);
...
...
src/main/java/com/cmeeting/job/EmailPushTask.java
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
job
;
import
cn.chatbot.openai.completion.chat.ChatCompletionRequest
;
import
cn.chatbot.openai.completion.chat.ChatMessage
;
import
cn.chatbot.openai.completion.chat.ChatMessageRole
;
import
cn.chatbot.openai.completion.chat.Message
;
import
cn.chatbot.openai.service.LLMService
;
import
cn.hutool.core.util.IdUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper
;
...
...
@@ -12,48 +7,27 @@ import com.cmeeting.email.EmailSender;
import
com.cmeeting.mapper.primary.MeetingInfoMapper
;
import
com.cmeeting.mapper.primary.MeetingRecordTemplateMapper
;
import
com.cmeeting.pojo.MeetingInfo
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.util.MinioUtils
;
import
com.cmeeting.vo.EmailPush
;
import
com.deepoove.poi.XWPFTemplate
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.dataformat.xml.XmlMapper
;
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.records.api.RecordsApi
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200Response
;
import
com.tencentcloudapi.wemeet.service.records.model.V1AddressesRecordFileIdGet200ResponseAiMeetingTranscriptsInner
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
okhttp3.OkHttpClient
;
import
okhttp3.Request
;
import
okhttp3.Response
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.poi.xwpf.extractor.XWPFWordExtractor
;
import
org.apache.poi.xwpf.usermodel.XWPFDocument
;
import
org.apache.commons.io.IOUtils
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.stereotype.Service
;
import
java.io.*
;
import
java.math.BigInteger
;
import
java.nio.charset.Charset
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Files
;
import
java.nio.file.Paths
;
import
java.security.SecureRandom
;
import
java.time.Instant
;
import
java.time.LocalDateTime
;
import
java.time.ZoneId
;
import
java.time.format.DateTimeFormatter
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
java.util.stream.Collectors
;
@Data
@NoArgsConstructor
...
...
@@ -105,9 +79,9 @@ public class EmailPushTask {
dataModel
.
putAll
(
participantsMap
);
String
path
=
Thread
.
currentThread
().
getContextClassLoader
().
getResource
(
""
).
getPath
();
ClassPathResource
resource
=
new
ClassPathResource
(
"template/data_net
_template
.docx"
);
ClassPathResource
resource
=
new
ClassPathResource
(
"template/data_net
work
.docx"
);
meetingName
=
dataModel
.
get
(
"meeting_name"
)
!=
null
?
String
.
valueOf
(
dataModel
.
get
(
"meeting_name"
))
:
"腾讯会议纪要"
;
targetFileName
=
meetingName
+
"_
"
+
nowTime
;
targetFileName
=
meetingName
+
"_
data_network"
;
try
(
InputStream
inputStream
=
resource
.
getInputStream
())
{
XWPFTemplate
template
=
XWPFTemplate
.
compile
(
inputStream
).
render
(
dataModel
);
template
.
writeAndClose
(
new
FileOutputStream
(
path
+
targetFileName
+
".docx"
));
...
...
@@ -118,8 +92,16 @@ public class EmailPushTask {
}
//邮件推送
// isSuccess = emailSender.sendEmailWithAttachment("duanxincheng@chatbot.cn",meetingName,savePath + targetFileName + ".docx",meetingId);
isSuccess
=
emailSender
.
sendEmailWithAttachment
(
meetingInfo
.
getEmail
(),
meetingName
,
savePath
+
targetFileName
+
".docx"
,
meetingId
);
List
<
EmailPush
.
Attachment
>
attachments
=
new
ArrayList
<>();
try
(
InputStream
is
=
new
FileInputStream
(
path
+
targetFileName
+
".docx"
)){
byte
[]
meetingMinutesBytes
=
IOUtils
.
toByteArray
(
is
);
EmailPush
.
Attachment
attachment
=
EmailPush
.
Attachment
.
builder
().
name
(
meetingInfo
.
getSubject
()+
"_数据网络中心"
).
bytes
(
meetingMinutesBytes
).
build
();
attachments
.
add
(
attachment
);
}
catch
(
Exception
e
){
throw
new
RuntimeException
(
e
);
}
EmailPush
emailPushBuilder
=
EmailPush
.
builder
().
toEmail
(
meetingInfo
.
getEmail
()).
meetingId
(
meetingId
).
attachments
(
attachments
).
subject
(
meetingInfo
.
getSubject
()).
build
();
isSuccess
=
emailSender
.
sendEmailWithAttachment
(
emailPushBuilder
);
}
catch
(
Exception
e
)
{
// 异常处理
int
currentRetryCount
=
retryCount
.
getAndIncrement
();
...
...
src/main/java/com/cmeeting/job/FileProcessTask.java
浏览文件 @
2089d7b6
差异被折叠。
点击展开。
src/main/java/com/cmeeting/pojo/MeetingInfo.java
浏览文件 @
2089d7b6
...
...
@@ -114,4 +114,13 @@ public class MeetingInfo implements Serializable {
* 邮箱
*/
private
String
email
;
/**
* 同步时间
*/
private
LocalDateTime
updateTime
;
/**
* 模板ID
*/
private
Integer
templateId
;
}
\ No newline at end of file
src/main/java/com/cmeeting/pojo/MeetingRecordTemplate.java
浏览文件 @
2089d7b6
...
...
@@ -76,4 +76,9 @@ public class MeetingRecordTemplate implements Serializable {
* 删除标识
*/
private
Boolean
isDel
;
/**
* 模板文件
*/
private
String
template
;
}
\ No newline at end of file
src/main/java/com/cmeeting/service/MeetingInfoService.java
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
service
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.cmeeting.pojo.MeetingInfo
;
import
com.cmeeting.vo.MeetingInfoVO
;
public
interface
MeetingInfoService
extends
IService
<
MeetingInfo
>
{
IPage
<
MeetingInfo
>
getPage
(
MeetingInfoVO
vo
);
boolean
updateRecordXml
(
MeetingInfoVO
vo
);
}
src/main/java/com/cmeeting/service/MeetingRecordTemplateService.java
浏览文件 @
2089d7b6
...
...
@@ -4,7 +4,17 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import
com.baomidou.mybatisplus.extension.service.IService
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.vo.RecordTemplateVO
;
import
org.springframework.web.multipart.MultipartFile
;
public
interface
MeetingRecordTemplateService
extends
IService
<
MeetingRecordTemplate
>
{
IPage
<
MeetingRecordTemplate
>
getPage
(
RecordTemplateVO
vo
);
IPage
<
MeetingRecordTemplate
>
getPersonalPage
(
RecordTemplateVO
vo
);
/**
* 上传附件模板
* @param file
* @param id
* @return
*/
String
templateUpload
(
MultipartFile
file
,
Integer
id
);
}
src/main/java/com/cmeeting/service/impl/MeetingInfoServiceImpl.java
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
service
.
impl
;
import
cn.hutool.core.util.IdUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
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.mapper.primary.MeetingInfoMapper
;
import
com.cmeeting.pojo.MeetingInfo
;
import
com.cmeeting.service.MeetingInfoService
;
import
com.cmeeting.util.MinioUtils
;
import
com.cmeeting.vo.MeetingInfoVO
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.dataformat.xml.XmlMapper
;
import
org.springframework.stereotype.Service
;
import
javax.annotation.Resource
;
import
java.io.IOException
;
import
java.nio.charset.StandardCharsets
;
import
java.time.LocalDateTime
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
@Service
public
class
MeetingInfoServiceImpl
extends
ServiceImpl
<
MeetingInfoMapper
,
MeetingInfo
>
implements
MeetingInfoService
{
@Resource
private
MeetingInfoMapper
mapper
;
@Resource
private
MinioUtils
minioUtils
;
@Override
public
IPage
<
MeetingInfo
>
getPage
(
MeetingInfoVO
vo
)
{
LambdaQueryWrapper
<
MeetingInfo
>
queryWrapper
=
new
LambdaQueryWrapper
<>();
IPage
<
MeetingInfo
>
resultPage
=
mapper
.
selectPage
(
new
Page
<>(
vo
.
getCurrent
(),
vo
.
getSize
()),
queryWrapper
);
return
resultPage
;
}
@Override
public
boolean
updateRecordXml
(
MeetingInfoVO
vo
)
{
//前端的表单json转xml,xml格式的纪要内容便于生成会议纪要文件
String
recordJson
=
vo
.
getRecordJson
();
String
recordXml
=
convertJSONToXml
(
recordJson
);
String
key
=
vo
.
getMeetingId
()
+
"-recordXmlPath-"
+
IdUtil
.
fastSimpleUUID
()
+
".xml"
;
minioUtils
.
upload
(
key
,
recordXml
.
getBytes
(
StandardCharsets
.
UTF_8
));
vo
.
setRecordXml
(
key
);
LambdaUpdateWrapper
<
MeetingInfo
>
updateWrapper
=
new
LambdaUpdateWrapper
<>();
updateWrapper
.
eq
(
MeetingInfo:
:
getId
,
vo
.
getId
());
updateWrapper
.
set
(
MeetingInfo:
:
getUpdateTime
,
LocalDateTime
.
now
());
updateWrapper
.
set
(
MeetingInfo:
:
getRecordXml
,
key
);
return
update
(
null
,
updateWrapper
);
}
private
String
convertJSONToXml
(
String
json
)
{
try
{
// 解析 JSON 字符串
ObjectMapper
jsonMapper
=
new
ObjectMapper
();
List
<
Map
<
String
,
String
>>
list
=
jsonMapper
.
readValue
(
json
,
List
.
class
);
// 创建 XML 根节点
Map
<
String
,
Object
>
root
=
new
HashMap
<>();
// 处理每个 JSON 项
for
(
Map
<
String
,
String
>
item
:
list
)
{
String
keyValue
=
item
.
get
(
"key"
);
String
keyName
=
item
.
get
(
"keyName"
);
String
value
=
item
.
get
(
"value"
);
// 创建子节点
Map
<
String
,
Object
>
subNode
=
new
HashMap
<>();
subNode
.
put
(
"label"
,
keyName
);
subNode
.
put
(
""
,
value
);
// 添加到根节点
root
.
put
(
keyValue
,
subNode
);
}
// 转换为 XML
XmlMapper
xmlMapper
=
new
XmlMapper
();
return
xmlMapper
.
writeValueAsString
(
root
);
}
catch
(
IOException
e
)
{
log
.
error
(
"JSON 转 XML 失败: "
+
e
.
getMessage
());
throw
new
RuntimeException
(
"JSON 转 XML 失败"
,
e
);
}
}
}
src/main/java/com/cmeeting/service/impl/MeetingRecordTemplateServiceImpl.java
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
service
.
impl
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.io.FileUtil
;
import
cn.hutool.core.util.IdUtil
;
import
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
;
import
com.baomidou.mybatisplus.core.metadata.IPage
;
import
com.baomidou.mybatisplus.extension.plugins.pagination.Page
;
...
...
@@ -7,10 +10,15 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import
com.cmeeting.mapper.primary.MeetingRecordTemplateMapper
;
import
com.cmeeting.pojo.MeetingRecordTemplate
;
import
com.cmeeting.service.MeetingRecordTemplateService
;
import
com.cmeeting.util.MinioUtils
;
import
com.cmeeting.vo.RecordTemplateVO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Service
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.annotation.Resource
;
import
java.io.InputStream
;
import
java.util.Date
;
import
java.util.List
;
@Service
...
...
@@ -18,12 +26,58 @@ public class MeetingRecordTemplateServiceImpl extends ServiceImpl<MeetingRecordT
@Resource
private
MeetingRecordTemplateMapper
mapper
;
@Autowired
private
MinioUtils
minioUtils
;
@Override
public
IPage
<
MeetingRecordTemplate
>
getPage
(
RecordTemplateVO
vo
)
{
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
());
IPage
<
MeetingRecordTemplate
>
resultPage
=
mapper
.
selectPage
(
new
Page
<>(
vo
.
getCurrent
(),
vo
.
getSize
()),
queryWrapper
);
return
resultPage
;
}
@Override
public
IPage
<
MeetingRecordTemplate
>
getPersonalPage
(
RecordTemplateVO
vo
)
{
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
());
IPage
<
MeetingRecordTemplate
>
resultPage
=
mapper
.
selectPage
(
new
Page
<>(
vo
.
getCurrent
(),
vo
.
getSize
()),
queryWrapper
);
return
resultPage
;
}
/**
* 上传附件模板到minio
* @param file
* @param id
* @return
*/
@Override
public
String
templateUpload
(
MultipartFile
file
,
Integer
id
)
{
MeetingRecordTemplate
detail
=
getById
(
id
);
String
separator
=
"/"
;
String
point
=
"."
;
// 获取文件名
String
originalFilename
=
file
.
getOriginalFilename
();
// 获取文件后缀
String
originalSuffix
=
FileUtil
.
getSuffix
(
originalFilename
);
// 生成文件名
String
nowDate
=
DateUtil
.
format
(
new
Date
(),
"yyyy-MM-dd"
);
String
uuid
=
IdUtil
.
fastSimpleUUID
();
String
originalFilePath
=
separator
+
nowDate
+
separator
+
uuid
+
point
+
originalSuffix
;
// 获取文件流
try
(
InputStream
is
=
file
.
getInputStream
()){
minioUtils
.
upload
(
originalFilePath
,
is
);
}
catch
(
Exception
e
){
throw
new
RuntimeException
(
e
.
getMessage
());
}
detail
.
setTemplate
(
originalFilePath
);
updateById
(
detail
);
return
originalFilePath
;
}
}
\ No newline at end of file
src/main/java/com/cmeeting/service/impl/TecentMeetingServiceImpl.java
浏览文件 @
2089d7b6
差异被折叠。
点击展开。
src/main/java/com/cmeeting/util/MinioUtils.java
浏览文件 @
2089d7b6
...
...
@@ -4,10 +4,8 @@ import io.minio.MinioClient;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.io.ByteArrayInputStream
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.*
;
import
java.nio.charset.StandardCharsets
;
@Component
public
class
MinioUtils
{
...
...
@@ -33,6 +31,20 @@ public class MinioUtils {
}
}
public
String
getFileText
(
String
fileName
)
throws
IOException
{
InputStream
is
=
getFile
(
fileName
);
StringBuilder
textBuilder
=
new
StringBuilder
();
try
(
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
is
,
StandardCharsets
.
UTF_8
)))
{
String
line
;
while
((
line
=
reader
.
readLine
())
!=
null
)
{
textBuilder
.
append
(
line
);
textBuilder
.
append
(
System
.
lineSeparator
());
}
}
return
textBuilder
.
toString
();
}
public
InputStream
getFile
(
String
fileName
){
try
{
getMinioClient
();
...
...
@@ -57,11 +69,6 @@ public class MinioUtils {
public
void
upload
(
String
path
,
byte
[]
bytes
)
{
try
(
ByteArrayInputStream
inputStream
=
new
ByteArrayInputStream
(
bytes
))
{
// 自动管理流的生命周期,无需手动close
int
data
;
while
((
data
=
inputStream
.
read
())
!=
-
1
)
{
System
.
out
.
print
((
char
)
data
);
}
upload
(
path
,
inputStream
);
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
e
);
...
...
src/main/java/com/cmeeting/util/SignatureUtil.java
0 → 100644
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
util
;
import
javax.crypto.Mac
;
import
javax.crypto.spec.SecretKeySpec
;
import
java.nio.charset.StandardCharsets
;
import
java.security.InvalidKeyException
;
import
java.security.NoSuchAlgorithmException
;
import
java.util.Base64
;
public
class
SignatureUtil
{
static
String
HMAC_ALGORITHM
=
"HmacSHA256"
;
static
char
[]
HEX_CHAR
=
{
'0'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
,
'8'
,
'9'
,
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
};
static
String
bytesToHex
(
byte
[]
bytes
)
{
char
[]
buf
=
new
char
[
bytes
.
length
*
2
];
int
index
=
0
;
for
(
byte
b
:
bytes
)
{
buf
[
index
++]
=
HEX_CHAR
[
b
>>>
4
&
0xf
];
buf
[
index
++]
=
HEX_CHAR
[
b
&
0xf
];
}
return
new
String
(
buf
);
}
public
static
String
generateSignature
(
String
secretId
,
String
secretKey
,
String
httpMethod
,
String
headerNonce
,
String
headerTimestamp
,
String
requestUri
,
String
requestBody
)
throws
NoSuchAlgorithmException
,
InvalidKeyException
{
String
tobeSig
=
httpMethod
+
"\nX-TC-Key="
+
secretId
+
"&X-TC-Nonce="
+
headerNonce
+
"&X-TC-Timestamp="
+
headerTimestamp
+
"\n"
+
requestUri
+
"\n"
+
requestBody
;
Mac
mac
=
Mac
.
getInstance
(
HMAC_ALGORITHM
);
SecretKeySpec
secretKeySpec
=
new
SecretKeySpec
(
secretKey
.
getBytes
(
StandardCharsets
.
UTF_8
),
mac
.
getAlgorithm
());
mac
.
init
(
secretKeySpec
);
byte
[]
hash
=
mac
.
doFinal
(
tobeSig
.
getBytes
(
StandardCharsets
.
UTF_8
));
String
hexHash
=
bytesToHex
(
hash
);
return
new
String
(
Base64
.
getEncoder
().
encode
(
hexHash
.
getBytes
(
StandardCharsets
.
UTF_8
)));
}
}
src/main/java/com/cmeeting/vo/CorpRecordsVO.java
0 → 100644
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
vo
;
import
lombok.Data
;
import
java.util.List
;
/**
* 会议纪要模板展示层
*/
/**
* 会议纪要模板展示层
*/
@Data
public
class
CorpRecordsVO
{
private
Integer
totalCount
;
private
Integer
totalPage
;
private
Integer
currentPage
;
private
Integer
currentSize
;
private
List
<
RecordMeeting
>
recordMeetings
;
@Data
public
class
RecordMeeting
{
private
String
meetingRecordId
;
private
String
meetingId
;
private
String
meetingCode
;
private
String
userid
;
private
String
hostUserId
;
private
Integer
mediaStartTime
;
private
String
subject
;
private
Integer
state
;
private
Integer
recordType
;
private
List
<
RecordFile
>
recordFiles
;
}
@Data
public
class
RecordFile
{
private
String
recordFileId
;
private
Integer
recordStartTime
;
private
Integer
recordEndTime
;
private
Integer
recordSize
;
private
Integer
sharingState
;
private
String
sharingUrl
;
private
Boolean
requiredSameCorp
;
private
Boolean
requiredParticipant
;
private
Integer
sharingExpire
;
private
Boolean
allowDownload
;
private
String
downloadAddress
;
private
String
viewAddress
;
}
}
\ No newline at end of file
src/main/java/com/cmeeting/vo/EmailPush.java
0 → 100644
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
vo
;
import
lombok.AllArgsConstructor
;
import
lombok.Builder
;
import
lombok.Data
;
import
lombok.NoArgsConstructor
;
;
import
java.util.List
;
/**
* 会议纪要模板展示层
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public
class
EmailPush
{
private
String
toEmail
;
private
String
subject
;
private
String
meetingId
;
/**
* 附件
*/
private
List
<
Attachment
>
attachments
;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public
static
class
Attachment
{
private
String
name
;
private
byte
[]
bytes
;
}
}
\ No newline at end of file
src/main/java/com/cmeeting/vo/MeetingInfoVO.java
0 → 100644
浏览文件 @
2089d7b6
package
com
.
cmeeting
.
vo
;
import
lombok.Data
;
import
java.time.LocalDateTime
;
/**
* 会议纪要模板展示层
*/
@Data
public
class
MeetingInfoVO
{
/**
* 当前页
*/
private
Integer
current
;
/**
* 每页最大数据行
*/
private
Integer
size
;
/**
* 主键id
*/
private
Integer
id
;
/**
* 会议主题
*/
private
String
subject
;
/**
* 会议ID(字符串类型)
*/
private
String
meetingId
;
/**
* 子会议ID
*/
private
String
subMeetingId
;
/**
* 会议号码
*/
private
String
meetingCode
;
/**
* 主持人
*/
private
String
host
;
/**
* 主持人uid
*/
private
String
hostUid
;
/**
* 参会人员名单
*/
private
String
participantUsers
;
/**
* 会议开始时间(时间戳)
*/
private
LocalDateTime
startTime
;
/**
* 会议结束时间(时间戳)
*/
private
LocalDateTime
endTime
;
/**
* 是否生成会议纪要完成
*/
private
Boolean
isGenerated
;
/**
* 推送邮件许可 为false不推送
*/
private
Boolean
emailPushAccess
;
/**
* 是否推送邮件完成
*/
private
Boolean
isPushed
;
/**
* 会议纪要重新生成标识
*/
private
Boolean
generateRetry
;
/**
* 邮件推送重试标识
*/
private
Boolean
pushRetry
;
/**
* 同步时间
*/
private
LocalDateTime
syncTime
;
/**
* 转录文本
*/
private
String
recordContent
;
/**
* 纪要xml
*/
private
String
recordXml
;
/**
* 每个会议对应的转录文件id,多个用逗号分隔,按参会前后升序
*/
private
String
recordFileId
;
/**
* 邮箱
*/
private
String
email
;
/**
* 同步时间
*/
private
LocalDateTime
updateTime
;
/**
* 模板ID
*/
private
Integer
templateId
;
/**
* 会议纪要json
*/
private
String
recordJson
;
}
\ No newline at end of file
src/main/resources/template/data_net_template.docx
deleted
100644 → 0
浏览文件 @
4ce8c62e
File deleted
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论