fix: 修复创建单个es索引报错
This commit is contained in:
parent
919ab51570
commit
e5f8cfb8f9
|
|
@ -64,6 +64,23 @@
|
||||||
</svg>
|
</svg>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 权限引导提示 -->
|
||||||
|
<div v-if="showPermissionGuide" class="permission-guide">
|
||||||
|
<div class="permission-guide-content">
|
||||||
|
<div class="permission-icon">🎤</div>
|
||||||
|
<div class="permission-text">
|
||||||
|
<h4>需要麦克风权限</h4>
|
||||||
|
<p>请点击地址栏左侧的麦克风图标,选择"允许"来启用语音功能</p>
|
||||||
|
<div class="permission-steps">
|
||||||
|
<div class="step">1. 点击地址栏的 🔒 或 🎤 图标</div>
|
||||||
|
<div class="step">2. 选择"允许"麦克风访问</div>
|
||||||
|
<div class="step">3. 刷新页面后重试</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="permission-close" @click="showPermissionGuide = false">×</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="input-footer">
|
<div class="input-footer">
|
||||||
<span class="footer-hint">{{ t('vabI18n.chat.sendHint') }}</span>
|
<span class="footer-hint">{{ t('vabI18n.chat.sendHint') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -100,8 +117,13 @@ const inputText = ref(props.modelValue)
|
||||||
// 语音录制相关状态
|
// 语音录制相关状态
|
||||||
const isRecording = ref(false)
|
const isRecording = ref(false)
|
||||||
const isProcessingVoice = ref(false)
|
const isProcessingVoice = ref(false)
|
||||||
|
const showPermissionGuide = ref(false)
|
||||||
let mediaRecorder: MediaRecorder | null = null
|
let mediaRecorder: MediaRecorder | null = null
|
||||||
let audioChunks: Blob[] = []
|
let audioChunks: Blob[] = []
|
||||||
|
let audioContext: AudioContext | null = null
|
||||||
|
let mediaStreamSource: MediaStreamAudioSourceNode | null = null
|
||||||
|
let processor: ScriptProcessorNode | null = null
|
||||||
|
let recordedBuffer: Float32Array[] = []
|
||||||
|
|
||||||
// 监听输入值变化
|
// 监听输入值变化
|
||||||
watch(inputText, (newValue) => {
|
watch(inputText, (newValue) => {
|
||||||
|
|
@ -113,67 +135,219 @@ watch(() => props.modelValue, (newValue) => {
|
||||||
inputText.value = newValue
|
inputText.value = newValue
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// WAV格式音频处理工具函数
|
||||||
|
const encodeWAV = (samples: Float32Array, sampleRate: number) => {
|
||||||
|
const buffer = new ArrayBuffer(44 + samples.length * 2)
|
||||||
|
const view = new DataView(buffer)
|
||||||
|
|
||||||
|
// WAV文件头
|
||||||
|
const writeString = (offset: number, string: string) => {
|
||||||
|
for (let i = 0; i < string.length; i++) {
|
||||||
|
view.setUint8(offset + i, string.charCodeAt(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const floatTo16BitPCM = (output: DataView, offset: number, input: Float32Array) => {
|
||||||
|
for (let i = 0; i < input.length; i++, offset += 2) {
|
||||||
|
const s = Math.max(-1, Math.min(1, input[i]))
|
||||||
|
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeString(0, 'RIFF')
|
||||||
|
view.setUint32(4, 32 + samples.length * 2, true)
|
||||||
|
writeString(8, 'WAVE')
|
||||||
|
writeString(12, 'fmt ')
|
||||||
|
view.setUint32(16, 16, true)
|
||||||
|
view.setUint16(20, 1, true)
|
||||||
|
view.setUint16(22, 1, true)
|
||||||
|
view.setUint32(24, sampleRate, true)
|
||||||
|
view.setUint32(28, sampleRate * 2, true)
|
||||||
|
view.setUint16(32, 2, true)
|
||||||
|
view.setUint16(34, 16, true)
|
||||||
|
writeString(36, 'data')
|
||||||
|
view.setUint32(40, samples.length * 2, true)
|
||||||
|
|
||||||
|
floatTo16BitPCM(view, 44, samples)
|
||||||
|
|
||||||
|
return new Blob([view], { type: 'audio/wav' })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并音频缓冲区
|
||||||
|
const mergeBuffers = (buffers: Float32Array[], length: number) => {
|
||||||
|
const result = new Float32Array(length)
|
||||||
|
let offset = 0
|
||||||
|
for (const buffer of buffers) {
|
||||||
|
result.set(buffer, offset)
|
||||||
|
offset += buffer.length
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查麦克风权限状态
|
||||||
|
const checkMicrophonePermission = async () => {
|
||||||
|
try {
|
||||||
|
// 检查是否支持权限API
|
||||||
|
if (!navigator.permissions) {
|
||||||
|
console.warn('浏览器不支持权限API')
|
||||||
|
return 'unknown'
|
||||||
|
}
|
||||||
|
|
||||||
|
const permission = await navigator.permissions.query({ name: 'microphone' as PermissionName })
|
||||||
|
return permission.state
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('无法查询麦克风权限状态:', error)
|
||||||
|
return 'unknown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查浏览器环境和支持性
|
||||||
|
const checkBrowserSupport = () => {
|
||||||
|
// 检查是否为HTTPS或localhost
|
||||||
|
const isSecureContext = window.isSecureContext || location.protocol === 'https:' || location.hostname === 'localhost'
|
||||||
|
|
||||||
|
// 检查API支持
|
||||||
|
const hasMediaDevices = !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia)
|
||||||
|
const hasMediaRecorder = !!window.MediaRecorder
|
||||||
|
|
||||||
|
return {
|
||||||
|
isSecureContext,
|
||||||
|
hasMediaDevices,
|
||||||
|
hasMediaRecorder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 开始录音
|
// 开始录音
|
||||||
const startRecording = async () => {
|
const startRecording = async () => {
|
||||||
if (isRecording.value || isProcessingVoice.value) return
|
if (isRecording.value || isProcessingVoice.value) return
|
||||||
|
|
||||||
|
// 检查浏览器支持
|
||||||
|
const support = checkBrowserSupport()
|
||||||
|
|
||||||
|
if (!support.isSecureContext) {
|
||||||
|
ElMessage.error('语音功能需要在HTTPS环境下使用,请使用HTTPS访问此页面')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!support.hasMediaDevices) {
|
||||||
|
ElMessage.error('您的浏览器不支持麦克风访问功能')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!support.hasMediaRecorder) {
|
||||||
|
ElMessage.error('您的浏览器不支持录音功能')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 先检查权限状态
|
||||||
|
const permissionState = await checkMicrophonePermission()
|
||||||
|
console.log('麦克风权限状态:', permissionState)
|
||||||
|
|
||||||
|
if (permissionState === 'denied') {
|
||||||
|
ElMessage.error('麦克风权限已被拒绝,请在浏览器设置中允许访问麦克风')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
audio: {
|
audio: {
|
||||||
echoCancellation: true,
|
echoCancellation: true,
|
||||||
noiseSuppression: true,
|
noiseSuppression: true,
|
||||||
autoGainControl: true
|
autoGainControl: true,
|
||||||
|
sampleRate: 44100
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// 检查浏览器支持的音频格式
|
console.log('麦克风权限获取成功')
|
||||||
const mimeTypes = [
|
|
||||||
'audio/webm;codecs=opus',
|
|
||||||
'audio/webm',
|
|
||||||
'audio/mp4',
|
|
||||||
'audio/wav'
|
|
||||||
]
|
|
||||||
|
|
||||||
let selectedMimeType = 'audio/webm'
|
// 使用Web Audio API录制WAV格式
|
||||||
for (const mimeType of mimeTypes) {
|
audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()
|
||||||
if (MediaRecorder.isTypeSupported(mimeType)) {
|
mediaStreamSource = audioContext.createMediaStreamSource(stream)
|
||||||
selectedMimeType = mimeType
|
|
||||||
break
|
// 创建音频处理器
|
||||||
}
|
processor = audioContext.createScriptProcessor(4096, 1, 1)
|
||||||
|
recordedBuffer = []
|
||||||
|
|
||||||
|
processor.onaudioprocess = (e) => {
|
||||||
|
const inputBuffer = e.inputBuffer.getChannelData(0)
|
||||||
|
const buffer = new Float32Array(inputBuffer.length)
|
||||||
|
buffer.set(inputBuffer)
|
||||||
|
recordedBuffer.push(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaRecorder = new MediaRecorder(stream, { mimeType: selectedMimeType })
|
// 连接音频节点
|
||||||
audioChunks = []
|
mediaStreamSource.connect(processor)
|
||||||
|
processor.connect(audioContext.destination)
|
||||||
|
|
||||||
mediaRecorder.ondataavailable = (event) => {
|
console.log('开始录制WAV格式音频,采样率:', audioContext.sampleRate)
|
||||||
if (event.data.size > 0) {
|
|
||||||
audioChunks.push(event.data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaRecorder.onstop = async () => {
|
|
||||||
const audioBlob = new Blob(audioChunks, { type: selectedMimeType })
|
|
||||||
await processVoiceToText(audioBlob)
|
|
||||||
|
|
||||||
// 停止所有音频轨道
|
|
||||||
stream.getTracks().forEach(track => track.stop())
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaRecorder.start()
|
|
||||||
isRecording.value = true
|
isRecording.value = true
|
||||||
|
|
||||||
|
// 保存stream引用用于后续停止
|
||||||
|
;(processor as any).stream = stream
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取麦克风权限失败:', error)
|
console.error('获取麦克风权限失败:', error)
|
||||||
ElMessage.error('无法访问麦克风,请检查权限设置')
|
|
||||||
|
// 根据不同的错误类型给出具体的提示
|
||||||
|
if (error.name === 'NotAllowedError') {
|
||||||
|
showPermissionGuide.value = true
|
||||||
|
ElMessage.error('麦克风权限被拒绝,请查看权限引导')
|
||||||
|
} else if (error.name === 'NotFoundError') {
|
||||||
|
ElMessage.error('未找到麦克风设备,请检查设备连接')
|
||||||
|
} else if (error.name === 'NotReadableError') {
|
||||||
|
ElMessage.error('麦克风被其他应用占用,请关闭其他使用麦克风的程序')
|
||||||
|
} else if (error.name === 'OverconstrainedError') {
|
||||||
|
ElMessage.error('麦克风不支持当前配置,请尝试使用其他设备')
|
||||||
|
} else if (error.name === 'SecurityError') {
|
||||||
|
ElMessage.error('安全限制:请确保在HTTPS环境下使用语音功能')
|
||||||
|
} else {
|
||||||
|
// 可能是权限问题,显示引导
|
||||||
|
showPermissionGuide.value = true
|
||||||
|
ElMessage.error(`无法访问麦克风: ${error.message || '未知错误'}`)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 停止录音
|
// 停止录音
|
||||||
const stopRecording = () => {
|
const stopRecording = async () => {
|
||||||
if (!isRecording.value || !mediaRecorder) return
|
if (!isRecording.value) return
|
||||||
|
|
||||||
isRecording.value = false
|
isRecording.value = false
|
||||||
mediaRecorder.stop()
|
|
||||||
|
if (processor && audioContext && mediaStreamSource) {
|
||||||
|
// 断开音频节点连接
|
||||||
|
mediaStreamSource.disconnect()
|
||||||
|
processor.disconnect()
|
||||||
|
|
||||||
|
// 停止音频流
|
||||||
|
const stream = (processor as any).stream
|
||||||
|
if (stream) {
|
||||||
|
stream.getTracks().forEach((track: MediaStreamTrack) => track.stop())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理录制的音频数据
|
||||||
|
if (recordedBuffer.length > 0) {
|
||||||
|
const totalLength = recordedBuffer.reduce((acc, buffer) => acc + buffer.length, 0)
|
||||||
|
const mergedBuffer = mergeBuffers(recordedBuffer, totalLength)
|
||||||
|
|
||||||
|
// 生成WAV格式音频
|
||||||
|
const wavBlob = encodeWAV(mergedBuffer, audioContext.sampleRate)
|
||||||
|
console.log('生成WAV音频文件,大小:', wavBlob.size, 'bytes')
|
||||||
|
|
||||||
|
await processVoiceToText(wavBlob)
|
||||||
|
} else {
|
||||||
|
ElMessage.warning('录音时间过短,请重新录制')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理资源
|
||||||
|
if (audioContext.state !== 'closed') {
|
||||||
|
await audioContext.close()
|
||||||
|
}
|
||||||
|
audioContext = null
|
||||||
|
mediaStreamSource = null
|
||||||
|
processor = null
|
||||||
|
recordedBuffer = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理语音转文字
|
// 处理语音转文字
|
||||||
|
|
@ -188,11 +362,10 @@ const processVoiceToText = async (audioBlob: Blob) => {
|
||||||
try {
|
try {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
|
|
||||||
// 根据录音格式设置文件扩展名
|
// 现在我们生成的是WAV格式
|
||||||
const fileExtension = audioBlob.type.includes('wav') ? 'wav' :
|
formData.append('file', audioBlob, 'recording.wav')
|
||||||
audioBlob.type.includes('mp4') ? 'mp3' : 'webm'
|
|
||||||
|
|
||||||
formData.append('file', audioBlob, `recording.${fileExtension}`)
|
console.log('上传音频文件:', audioBlob.type, '大小:', audioBlob.size)
|
||||||
|
|
||||||
const response = await voiceToText(formData)
|
const response = await voiceToText(formData)
|
||||||
|
|
||||||
|
|
@ -220,10 +393,21 @@ const processVoiceToText = async (audioBlob: Blob) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组件卸载时清理资源
|
// 组件卸载时清理资源
|
||||||
onUnmounted(() => {
|
onUnmounted(async () => {
|
||||||
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
|
if (mediaRecorder && mediaRecorder.state !== 'inactive') {
|
||||||
mediaRecorder.stop()
|
mediaRecorder.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 清理Web Audio API资源
|
||||||
|
if (processor) {
|
||||||
|
processor.disconnect()
|
||||||
|
}
|
||||||
|
if (mediaStreamSource) {
|
||||||
|
mediaStreamSource.disconnect()
|
||||||
|
}
|
||||||
|
if (audioContext && audioContext.state !== 'closed') {
|
||||||
|
await audioContext.close()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -542,6 +726,118 @@ onUnmounted(() => {
|
||||||
animation: spin 0.8s linear infinite;
|
animation: spin 0.8s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 权限引导提示样式 */
|
||||||
|
.permission-guide {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1000;
|
||||||
|
animation: fadeIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-guide-content {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 2rem;
|
||||||
|
max-width: 480px;
|
||||||
|
margin: 1rem;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15);
|
||||||
|
animation: slideUp 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-icon {
|
||||||
|
font-size: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-text h4 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1f2937;
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-text p {
|
||||||
|
color: #6b7280;
|
||||||
|
margin: 0 0 1.5rem 0;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-steps {
|
||||||
|
background: #f9fafb;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid #4f46e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step {
|
||||||
|
color: #374151;
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step:first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
border: none;
|
||||||
|
background: #f3f4f6;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: #6b7280;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.permission-close:hover {
|
||||||
|
background: #e5e7eb;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.input-footer {
|
.input-footer {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,9 +104,9 @@
|
||||||
<el-form :model="uploadForm.docAnalysisStrategy" label-width="140px" class="config-form">
|
<el-form :model="uploadForm.docAnalysisStrategy" label-width="140px" class="config-form">
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
<h4 class="section-title">基础设置</h4>
|
<h4 class="section-title">基础设置</h4>
|
||||||
<!-- <el-form-item label="策略名称">
|
<el-form-item label="策略名称">
|
||||||
<el-input v-model="uploadForm.docAnalysisStrategy.name" placeholder="请输入策略名称" />
|
<el-input v-model="uploadForm.docAnalysisStrategy.name" placeholder="请输入策略名称(可选)" />
|
||||||
</el-form-item> -->
|
</el-form-item>
|
||||||
<el-form-item label="分段模式">
|
<el-form-item label="分段模式">
|
||||||
<el-select v-model="uploadForm.docAnalysisStrategy.segmentationMode" placeholder="选择分段模式">
|
<el-select v-model="uploadForm.docAnalysisStrategy.segmentationMode" placeholder="选择分段模式">
|
||||||
<el-option label="普通分段" value="normal" />
|
<el-option label="普通分段" value="normal" />
|
||||||
|
|
@ -553,9 +553,8 @@ const canProceedToNext = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const canUpload = () => {
|
const canUpload = () => {
|
||||||
if (uploadForm.analysisStrategyType === 'custom') {
|
// 自定义模式不需要策略名称验证,因为UI中已经隐藏了该字段
|
||||||
return uploadForm.docAnalysisStrategy.name !== ''
|
// 只要有基本的配置参数就可以上传
|
||||||
}
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -641,7 +640,7 @@ const handleUpload = async () => {
|
||||||
// 如果是自定义模式,添加解析策略
|
// 如果是自定义模式,添加解析策略
|
||||||
if (uploadForm.analysisStrategyType === 'custom') {
|
if (uploadForm.analysisStrategyType === 'custom') {
|
||||||
requestData.docAnalysisStrategy = {
|
requestData.docAnalysisStrategy = {
|
||||||
name: uploadForm.docAnalysisStrategy.name,
|
name: uploadForm.docAnalysisStrategy.name || '自定义策略',
|
||||||
segmentationMode: 'custom',
|
segmentationMode: 'custom',
|
||||||
indexingTechnique: uploadForm.docAnalysisStrategy.indexingTechnique,
|
indexingTechnique: uploadForm.docAnalysisStrategy.indexingTechnique,
|
||||||
docForm: 'text_model',
|
docForm: 'text_model',
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ public class MetadataServiceImpl implements MetadataService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DifyMetadata> handleYsylcMetadata(String datasetId, String documentId, MultipartFile file,String metadataId) {
|
public List<DifyMetadata> handleYsylcMetadata(String datasetId, String documentId, MultipartFile file,String metadataId) {
|
||||||
// 异步执行
|
// 异步执行工作流
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
String apiKey = tApiKeyService.getApiKeyFromCache(DifyConstants.API_KEY_YSYLC_DATA_PROC);
|
String apiKey = tApiKeyService.getApiKeyFromCache(DifyConstants.API_KEY_YSYLC_DATA_PROC);
|
||||||
workFlowService.runWorkflowByFile(documentId, apiKey, file);
|
workFlowService.runWorkflowByFile(documentId, apiKey, file);
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ public class EsTDatasetFilesImporter {
|
||||||
if (datasetFiles == null) {
|
if (datasetFiles == null) {
|
||||||
throw new IllegalArgumentException("datasetFiles 不存在");
|
throw new IllegalArgumentException("datasetFiles 不存在");
|
||||||
}
|
}
|
||||||
String filePath = datasetFiles.getSourceUrl();
|
String filePath = datasetFiles.getDifyStoragePath();
|
||||||
File file = new File(filePath);
|
File file = new File(filePath);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
throw new IllegalArgumentException(filePath + " 不存在");
|
throw new IllegalArgumentException(filePath + " 不存在");
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,3 @@ elasticsearch:
|
||||||
#是否删除索引,重新构建索引
|
#是否删除索引,重新构建索引
|
||||||
deleteIndex: ${es-deleteIndex:false}
|
deleteIndex: ${es-deleteIndex:false}
|
||||||
|
|
||||||
voice2text:
|
|
||||||
url: ${voice2text-url:http://192.168.8.253:11023/v1/audio/transcriptions}
|
|
||||||
model: ${voice2text-model:whisper-1}
|
|
||||||
Loading…
Reference in New Issue