feat(prompt): 集成flyway
parent
44a27dadcb
commit
3931143674
|
|
@ -188,6 +188,10 @@
|
||||||
<artifactId>tencentcloud-sdk-java-asr</artifactId>
|
<artifactId>tencentcloud-sdk-java-asr</artifactId>
|
||||||
<version>3.1.1470</version>
|
<version>3.1.1470</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.flywaydb</groupId>
|
||||||
|
<artifactId>flyway-core</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,25 @@
|
||||||
package com.imeeting.config;
|
package com.imeeting.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.unisbase.common.ApiResponse;
|
import com.unisbase.common.ApiResponse;
|
||||||
|
import com.unisbase.common.exception.BusinessException;
|
||||||
|
import com.unisbase.common.exception.ErrorCodeEnum;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.server.ServerHttpRequest;
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
import org.springframework.http.server.ServerHttpResponse;
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
|
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@RestControllerAdvice
|
@RestControllerAdvice
|
||||||
|
@Slf4j
|
||||||
public class ApiResponseSuccessCodeAdvice implements ResponseBodyAdvice<Object> {
|
public class ApiResponseSuccessCodeAdvice implements ResponseBodyAdvice<Object> {
|
||||||
|
|
||||||
private static final String LEGACY_SUCCESS_CODE = "0";
|
private static final String LEGACY_SUCCESS_CODE = "0";
|
||||||
|
|
@ -32,4 +42,13 @@ public class ApiResponseSuccessCodeAdvice implements ResponseBodyAdvice<Object>
|
||||||
}
|
}
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler({MethodArgumentNotValidException.class})
|
||||||
|
public ApiResponse<Void> handleBusinessException(MethodArgumentNotValidException ex) {
|
||||||
|
String msg = ex.getBindingResult().getAllErrors()
|
||||||
|
.stream()
|
||||||
|
.map(DefaultMessageSourceResolvable::getDefaultMessage)
|
||||||
|
.collect(Collectors.joining(", "));
|
||||||
|
return new ApiResponse(ErrorCodeEnum.SYSTEM_ERROR.getCode(), msg, (Object) null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ public class CreateMeetingCommand {
|
||||||
|
|
||||||
private Long chapterModelId;
|
private Long chapterModelId;
|
||||||
|
|
||||||
@NotNull(message = "promptId must not be null")
|
@NotNull(message = "总结模板不能为空")
|
||||||
private Long promptId;
|
private Long promptId;
|
||||||
|
|
||||||
private Long hotWordGroupId;
|
private Long hotWordGroupId;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ public class AndroidPushMessageRetryTask {
|
||||||
private final AndroidGatewayPushService androidGatewayPushService;
|
private final AndroidGatewayPushService androidGatewayPushService;
|
||||||
private final TaskSecurityContextRunner taskSecurityContextRunner;
|
private final TaskSecurityContextRunner taskSecurityContextRunner;
|
||||||
|
|
||||||
@Scheduled(fixedDelayString = "${imeeting.android.push.retry-interval-ms:15000}")
|
@Scheduled(fixedDelayString = "${imeeting.android.push.retry-interval-ms:15000}",
|
||||||
|
initialDelayString = "${imeeting.android.push.initial-delay-ms:10000}")
|
||||||
public void retryPendingMessages() {
|
public void retryPendingMessages() {
|
||||||
taskSecurityContextRunner.callAsPlatformAdmin(() -> {
|
taskSecurityContextRunner.callAsPlatformAdmin(() -> {
|
||||||
List<AndroidPushMessage> pendingMessages = androidPushMessageService.listPendingMeetingPushMessages();
|
List<AndroidPushMessage> pendingMessages = androidPushMessageService.listPendingMeetingPushMessages();
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,13 @@ spring:
|
||||||
writetimeout: 5000
|
writetimeout: 5000
|
||||||
# 启用调试日志(生产环境建议关闭)
|
# 启用调试日志(生产环境建议关闭)
|
||||||
debug: true
|
debug: true
|
||||||
|
|
||||||
|
flyway:
|
||||||
|
enabled: true
|
||||||
|
locations: classpath:db/migrations
|
||||||
|
# New databases baseline at 0 and execute V1; manually initialized deployments set version to 1.
|
||||||
|
baseline-on-migrate: true
|
||||||
|
baseline-version: ${FLYWAY_BASELINE_VERSION:1}
|
||||||
springdoc:
|
springdoc:
|
||||||
api-docs:
|
api-docs:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
@ -71,6 +78,10 @@ mybatis-plus:
|
||||||
logic-not-delete-value: 0
|
logic-not-delete-value: 0
|
||||||
|
|
||||||
unisbase:
|
unisbase:
|
||||||
|
flyway:
|
||||||
|
base:
|
||||||
|
baseline-enabled: true
|
||||||
|
baseline-version: ${UNIS_BASELINE_VERSION:0.1.0}
|
||||||
web:
|
web:
|
||||||
auth-endpoints-enabled: true
|
auth-endpoints-enabled: true
|
||||||
management-endpoints-enabled: true
|
management-endpoints-enabled: true
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -200,24 +200,28 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({
|
||||||
const asrRecords = asrRes.data?.data?.records || [];
|
const asrRecords = asrRes.data?.data?.records || [];
|
||||||
const llmRecords = llmRes.data?.data?.records || [];
|
const llmRecords = llmRes.data?.data?.records || [];
|
||||||
const hotwordRecords = hotwordRes.data?.data?.records || [];
|
const hotwordRecords = hotwordRes.data?.data?.records || [];
|
||||||
|
const activeLlmModels = llmRecords.filter((item: AiModelVO) => item.status === 1);
|
||||||
const activePrompts = promptRecords.filter((item: PromptTemplateVO) => item.status === 1);
|
const activePrompts = promptRecords.filter((item: PromptTemplateVO) => item.status === 1);
|
||||||
|
|
||||||
setCreateConfig(nextConfig);
|
setCreateConfig(nextConfig);
|
||||||
setConfigLoaded(true);
|
setConfigLoaded(true);
|
||||||
setType(nextType);
|
setType(nextType);
|
||||||
setAsrModels(asrRecords.filter((item: AiModelVO) => item.status === 1));
|
setAsrModels(asrRecords.filter((item: AiModelVO) => item.status === 1));
|
||||||
setLlmModels(llmRecords.filter((item: AiModelVO) => item.status === 1));
|
setLlmModels(activeLlmModels);
|
||||||
setPrompts(activePrompts);
|
setPrompts(activePrompts);
|
||||||
setHotwordList(hotwordRecords.filter((item: HotWordVO) => item.status === 1));
|
setHotwordList(hotwordRecords.filter((item: HotWordVO) => item.status === 1));
|
||||||
setHotWordGroups((hotWordGroupRes.data.data || []).filter((item: HotWordGroupVO) => item.status === 1));
|
setHotWordGroups((hotWordGroupRes.data.data || []).filter((item: HotWordGroupVO) => item.status === 1));
|
||||||
setUserList(users || []);
|
setUserList(users || []);
|
||||||
|
|
||||||
const defaultPrompt = activePrompts.find((item: PromptTemplateVO) => item.isDefault && item.defaultAvailable);
|
const defaultPrompt = activePrompts.find((item: PromptTemplateVO) => item.isDefault && item.defaultAvailable) || activePrompts[0];
|
||||||
|
const defaultSummaryModel = activeLlmModels.find((item: AiModelVO) => item.id === defaultLlm.data.data?.id)
|
||||||
|
|| activeLlmModels.find((item: AiModelVO) => item.isDefault === 1)
|
||||||
|
|| activeLlmModels[0];
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
title: nextType === "upload" ? `文件会议 ${dayjs().format("MM-DD HH:mm")}` : `实时会议 ${dayjs().format("MM-DD HH:mm")}`,
|
title: nextType === "upload" ? `文件会议 ${dayjs().format("MM-DD HH:mm")}` : `实时会议 ${dayjs().format("MM-DD HH:mm")}`,
|
||||||
meetingTime: dayjs(),
|
meetingTime: dayjs(),
|
||||||
asrModelId: defaultAsr.data.data?.id,
|
asrModelId: defaultAsr.data.data?.id,
|
||||||
summaryModelId: defaultLlm.data.data?.id,
|
summaryModelId: defaultSummaryModel?.id,
|
||||||
promptId: defaultPrompt?.id,
|
promptId: defaultPrompt?.id,
|
||||||
hotWordGroupId: defaultPrompt?.hotWordGroupId ?? 0,
|
hotWordGroupId: defaultPrompt?.hotWordGroupId ?? 0,
|
||||||
summaryDetailLevel: "STANDARD",
|
summaryDetailLevel: "STANDARD",
|
||||||
|
|
@ -295,6 +299,7 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({
|
||||||
message.warning("当前入口已关闭,已切换到可用创建方式");
|
message.warning("当前入口已关闭,已切换到可用创建方式");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === "upload" && !audioUrl) {
|
if (type === "upload" && !audioUrl) {
|
||||||
message.error("请先上传录音文件");
|
message.error("请先上传录音文件");
|
||||||
return;
|
return;
|
||||||
|
|
@ -308,6 +313,10 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!values.promptId) {
|
||||||
|
message.error("总结模板为空");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
try {
|
try {
|
||||||
|
|
@ -520,7 +529,6 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="promptId"
|
name="promptId"
|
||||||
label="总结模板"
|
label="总结模板"
|
||||||
extra="未选择时,系统会按当前可用模板规则自动选择"
|
|
||||||
>
|
>
|
||||||
{prompts.length > 15 ? (
|
{prompts.length > 15 ? (
|
||||||
<Select allowClear placeholder="请选择总结模板" showSearch optionFilterProp="children">
|
<Select allowClear placeholder="请选择总结模板" showSearch optionFilterProp="children">
|
||||||
|
|
@ -529,16 +537,6 @@ export const MeetingCreateDrawer: React.FC<MeetingCreateDrawerProps> = ({
|
||||||
) : (
|
) : (
|
||||||
<div className="meeting-create-template-grid">
|
<div className="meeting-create-template-grid">
|
||||||
<Row gutter={[12, 12]}>
|
<Row gutter={[12, 12]}>
|
||||||
<Col xs={24} sm={12} md={8}>
|
|
||||||
<div
|
|
||||||
onClick={() => form.setFieldsValue({promptId: undefined})}
|
|
||||||
className={watchedPromptId == null ? "meeting-create-template-card is-selected" : "meeting-create-template-card"}
|
|
||||||
>
|
|
||||||
<div className="meeting-create-template-card__name">系统自动选择</div>
|
|
||||||
{watchedPromptId == null &&
|
|
||||||
<div className="meeting-create-template-card__check"><CheckOutlined/></div>}
|
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
{prompts.map(p => {
|
{prompts.map(p => {
|
||||||
const isSelected = watchedPromptId === p.id;
|
const isSelected = watchedPromptId === p.id;
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
|
|
||||||
.permissions-name-cell {
|
.permissions-name-cell {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 80%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue