feat: 修改文件
parent
d8bfdb21fa
commit
af5c658bd9
|
|
@ -301,17 +301,40 @@ public class MeetingController {
|
|||
return markdown;
|
||||
}
|
||||
if (!markdown.startsWith("---")) {
|
||||
return markdown;
|
||||
return unwrapMarkdownFence(markdown);
|
||||
}
|
||||
int second = markdown.indexOf("\n---", 3);
|
||||
if (second < 0) {
|
||||
return markdown;
|
||||
return unwrapMarkdownFence(markdown);
|
||||
}
|
||||
int contentStart = second + 4;
|
||||
if (contentStart < markdown.length() && markdown.charAt(contentStart) == '\n') {
|
||||
contentStart++;
|
||||
}
|
||||
return markdown.substring(contentStart).trim();
|
||||
return unwrapMarkdownFence(markdown.substring(contentStart).trim());
|
||||
}
|
||||
|
||||
private String unwrapMarkdownFence(String markdown) {
|
||||
if (markdown == null) {
|
||||
return null;
|
||||
}
|
||||
String normalized = markdown.trim();
|
||||
if (!normalized.startsWith("```")) {
|
||||
return normalized;
|
||||
}
|
||||
int firstLineEnd = normalized.indexOf('\n');
|
||||
if (firstLineEnd < 0) {
|
||||
return normalized;
|
||||
}
|
||||
String firstLine = normalized.substring(0, firstLineEnd).trim().toLowerCase();
|
||||
if (!"```".equals(firstLine) && !"```markdown".equals(firstLine) && !"```md".equals(firstLine)) {
|
||||
return normalized;
|
||||
}
|
||||
int lastFence = normalized.lastIndexOf("\n```");
|
||||
if (lastFence <= firstLineEnd) {
|
||||
return normalized.substring(firstLineEnd + 1).trim();
|
||||
}
|
||||
return normalized.substring(firstLineEnd + 1, lastFence).trim();
|
||||
}
|
||||
|
||||
@GetMapping("/transcripts/{id}")
|
||||
|
|
@ -423,6 +446,9 @@ public class MeetingController {
|
|||
return ApiResponse.error("无权修改此会议信息");
|
||||
}
|
||||
|
||||
if (meeting.getSummaryContent() != null) {
|
||||
meetingService.updateSummaryContent(meeting.getId(), meeting.getSummaryContent());
|
||||
}
|
||||
return ApiResponse.ok(meetingService.updateById(meeting));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,4 +34,7 @@ public class Meeting extends BaseEntity {
|
|||
private String creatorName;
|
||||
|
||||
private Long latestSummaryTaskId;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String summaryContent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ public interface MeetingService extends IService<Meeting> {
|
|||
void completeRealtimeMeeting(Long meetingId, String audioUrl);
|
||||
void updateSpeakerInfo(Long meetingId, String speakerId, String newName, String label);
|
||||
void updateMeetingParticipants(Long meetingId, String participants);
|
||||
void updateSummaryContent(Long meetingId, String summaryContent);
|
||||
void reSummary(Long meetingId, Long summaryModelId, Long promptId);
|
||||
java.util.Map<String, Object> getDashboardStats(Long tenantId, Long userId, boolean isAdmin);
|
||||
List<MeetingVO> getRecentMeetings(Long tenantId, Long userId, boolean isAdmin, int limit);
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ public class AiTaskServiceImpl extends ServiceImpl<AiTaskMapper, AiTask> impleme
|
|||
JsonNode respNode = objectMapper.readTree(response.body());
|
||||
|
||||
if (response.statusCode() == 200 && respNode.has("choices")) {
|
||||
String content = respNode.path("choices").path(0).path("message").path("content").asText();
|
||||
String content = sanitizeSummaryContent(respNode.path("choices").path(0).path("message").path("content").asText());
|
||||
|
||||
// Save to File
|
||||
String timestamp = java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss").format(LocalDateTime.now());
|
||||
|
|
@ -387,6 +387,33 @@ public class AiTaskServiceImpl extends ServiceImpl<AiTaskMapper, AiTask> impleme
|
|||
return httpClient.send(HttpRequest.newBuilder().uri(URI.create(url)).GET().build(), HttpResponse.BodyHandlers.ofString()).body();
|
||||
}
|
||||
|
||||
private String sanitizeSummaryContent(String content) {
|
||||
if (content == null || content.isBlank()) {
|
||||
return content;
|
||||
}
|
||||
String normalized = content.trim();
|
||||
int thinkEndIndex = normalized.lastIndexOf("</think>");
|
||||
if (thinkEndIndex >= 0) {
|
||||
normalized = normalized.substring(thinkEndIndex + "</think>".length()).trim();
|
||||
}
|
||||
if (!normalized.startsWith("```")) {
|
||||
return normalized;
|
||||
}
|
||||
int firstLineEnd = normalized.indexOf('\n');
|
||||
if (firstLineEnd < 0) {
|
||||
return normalized;
|
||||
}
|
||||
String firstLine = normalized.substring(0, firstLineEnd).trim().toLowerCase();
|
||||
if (!"```".equals(firstLine) && !"```markdown".equals(firstLine) && !"```md".equals(firstLine)) {
|
||||
return normalized;
|
||||
}
|
||||
int lastFence = normalized.lastIndexOf("\n```");
|
||||
if (lastFence <= firstLineEnd) {
|
||||
return normalized.substring(firstLineEnd + 1).trim();
|
||||
}
|
||||
return normalized.substring(firstLineEnd + 1, lastFence).trim();
|
||||
}
|
||||
|
||||
private void updateMeetingStatus(Long id, int status) {
|
||||
Meeting m = new Meeting(); m.setId(id); m.setStatus(status); meetingMapper.updateById(m);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,6 +256,35 @@ public class MeetingServiceImpl extends ServiceImpl<MeetingMapper, Meeting> impl
|
|||
.set(Meeting::getParticipants, participants == null ? "" : participants));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateSummaryContent(Long meetingId, String summaryContent) {
|
||||
Meeting meeting = this.getById(meetingId);
|
||||
if (meeting == null) {
|
||||
throw new RuntimeException("Meeting not found");
|
||||
}
|
||||
|
||||
AiTask summaryTask = findLatestSummaryTask(meeting);
|
||||
if (summaryTask == null || summaryTask.getResultFilePath() == null || summaryTask.getResultFilePath().isBlank()) {
|
||||
throw new RuntimeException("Summary file not found");
|
||||
}
|
||||
|
||||
String basePath = uploadPath.endsWith("/") ? uploadPath : uploadPath + "/";
|
||||
Path summaryPath = Paths.get(basePath, summaryTask.getResultFilePath().replace("\\", "/"));
|
||||
try {
|
||||
Path parent = summaryPath.getParent();
|
||||
if (parent != null) {
|
||||
Files.createDirectories(parent);
|
||||
}
|
||||
|
||||
String existingContent = Files.exists(summaryPath) ? Files.readString(summaryPath, StandardCharsets.UTF_8) : "";
|
||||
String frontMatter = extractFrontMatter(existingContent, meeting, summaryTask);
|
||||
Files.writeString(summaryPath, frontMatter + normalizeSummaryMarkdown(summaryContent), StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Update summary file failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void reSummary(Long meetingId, Long summaryModelId, Long promptId) {
|
||||
|
|
@ -435,19 +464,7 @@ public class MeetingServiceImpl extends ServiceImpl<MeetingMapper, Meeting> impl
|
|||
|
||||
private String loadSummaryContent(Meeting meeting) {
|
||||
try {
|
||||
AiTask summaryTask = null;
|
||||
if (meeting.getLatestSummaryTaskId() != null) {
|
||||
summaryTask = aiTaskMapper.selectById(meeting.getLatestSummaryTaskId());
|
||||
}
|
||||
if (summaryTask == null || summaryTask.getResultFilePath() == null || summaryTask.getResultFilePath().isBlank()) {
|
||||
summaryTask = aiTaskMapper.selectOne(new LambdaQueryWrapper<AiTask>()
|
||||
.eq(AiTask::getMeetingId, meeting.getId())
|
||||
.eq(AiTask::getTaskType, "SUMMARY")
|
||||
.eq(AiTask::getStatus, 2)
|
||||
.isNotNull(AiTask::getResultFilePath)
|
||||
.orderByDesc(AiTask::getId)
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
AiTask summaryTask = findLatestSummaryTask(meeting);
|
||||
if (summaryTask == null || summaryTask.getResultFilePath() == null || summaryTask.getResultFilePath().isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -466,6 +483,64 @@ public class MeetingServiceImpl extends ServiceImpl<MeetingMapper, Meeting> impl
|
|||
}
|
||||
}
|
||||
|
||||
private AiTask findLatestSummaryTask(Meeting meeting) {
|
||||
AiTask summaryTask = null;
|
||||
if (meeting.getLatestSummaryTaskId() != null) {
|
||||
summaryTask = aiTaskMapper.selectById(meeting.getLatestSummaryTaskId());
|
||||
}
|
||||
if (summaryTask == null || summaryTask.getResultFilePath() == null || summaryTask.getResultFilePath().isBlank()) {
|
||||
summaryTask = aiTaskMapper.selectOne(new LambdaQueryWrapper<AiTask>()
|
||||
.eq(AiTask::getMeetingId, meeting.getId())
|
||||
.eq(AiTask::getTaskType, "SUMMARY")
|
||||
.eq(AiTask::getStatus, 2)
|
||||
.isNotNull(AiTask::getResultFilePath)
|
||||
.orderByDesc(AiTask::getId)
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
return summaryTask;
|
||||
}
|
||||
|
||||
private String extractFrontMatter(String markdown, Meeting meeting, AiTask summaryTask) {
|
||||
if (markdown != null && markdown.startsWith("---")) {
|
||||
int second = markdown.indexOf("\n---", 3);
|
||||
if (second >= 0) {
|
||||
int end = second + 4;
|
||||
if (end < markdown.length() && markdown.charAt(end) == '\n') {
|
||||
end++;
|
||||
}
|
||||
return markdown.substring(0, end);
|
||||
}
|
||||
}
|
||||
return "---\n" +
|
||||
"updatedAt: " + LocalDateTime.now() + "\n" +
|
||||
"meetingId: " + meeting.getId() + "\n" +
|
||||
"summaryTaskId: " + summaryTask.getId() + "\n" +
|
||||
"---\n\n";
|
||||
}
|
||||
|
||||
private String normalizeSummaryMarkdown(String markdown) {
|
||||
if (markdown == null) {
|
||||
return "";
|
||||
}
|
||||
String normalized = markdown.trim();
|
||||
if (!normalized.startsWith("```")) {
|
||||
return normalized;
|
||||
}
|
||||
int firstLineEnd = normalized.indexOf('\n');
|
||||
if (firstLineEnd < 0) {
|
||||
return normalized;
|
||||
}
|
||||
String firstLine = normalized.substring(0, firstLineEnd).trim().toLowerCase();
|
||||
if (!"```".equals(firstLine) && !"```markdown".equals(firstLine) && !"```md".equals(firstLine)) {
|
||||
return normalized;
|
||||
}
|
||||
int lastFence = normalized.lastIndexOf("\n```");
|
||||
if (lastFence <= firstLineEnd) {
|
||||
return normalized.substring(firstLineEnd + 1).trim();
|
||||
}
|
||||
return normalized.substring(firstLineEnd + 1, lastFence).trim();
|
||||
}
|
||||
|
||||
private Integer resolveMeetingDuration(Long meetingId) {
|
||||
MeetingTranscript latestTranscript = transcriptMapper.selectOne(new LambdaQueryWrapper<MeetingTranscript>()
|
||||
.eq(MeetingTranscript::getMeetingId, meetingId)
|
||||
|
|
@ -492,16 +567,16 @@ public class MeetingServiceImpl extends ServiceImpl<MeetingMapper, Meeting> impl
|
|||
return markdown;
|
||||
}
|
||||
if (!markdown.startsWith("---")) {
|
||||
return markdown;
|
||||
return normalizeSummaryMarkdown(markdown);
|
||||
}
|
||||
int second = markdown.indexOf("\n---", 3);
|
||||
if (second < 0) {
|
||||
return markdown;
|
||||
return normalizeSummaryMarkdown(markdown);
|
||||
}
|
||||
int contentStart = second + 4;
|
||||
if (contentStart < markdown.length() && markdown.charAt(contentStart) == '\n') {
|
||||
contentStart++;
|
||||
}
|
||||
return markdown.substring(contentStart).trim();
|
||||
return normalizeSummaryMarkdown(markdown.substring(contentStart).trim());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:postgresql://192.168.1.55:5432/imeeting_db
|
||||
url: jdbc:postgresql://10.100.51.199:5432/imeeting_db
|
||||
username: postgres
|
||||
password: postgres
|
||||
data:
|
||||
redis:
|
||||
host: 192.168.1.55
|
||||
host: 10.100.51.199
|
||||
port: 6379
|
||||
password: unis@123
|
||||
database: 15
|
||||
|
|
|
|||
Loading…
Reference in New Issue