添加语音生成
This commit is contained in:
parent
5f770c2b3d
commit
f47cd1213b
|
@ -42,6 +42,7 @@
|
||||||
"@vue-office/excel": "^1.7.11",
|
"@vue-office/excel": "^1.7.11",
|
||||||
"@vue-office/pdf": "^2.0.2",
|
"@vue-office/pdf": "^2.0.2",
|
||||||
"@vueuse/core": "^10.11.0",
|
"@vueuse/core": "^10.11.0",
|
||||||
|
"aix-plugins-aitools": "^1.0.9",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"circular-json": "^0.5.9",
|
"circular-json": "^0.5.9",
|
||||||
"clipboard": "^2.0.11",
|
"clipboard": "^2.0.11",
|
||||||
|
|
|
@ -79,3 +79,19 @@ export const getModelInfo = (params) => {
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 上传tts语音
|
||||||
|
export const aitts = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/aitts/createTts',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 语音关联课
|
||||||
|
export const addFileToSC = (params) => {
|
||||||
|
return request({
|
||||||
|
url: '/smarttalk/file/addFileToSC',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
|
@ -0,0 +1,243 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="height: auto; display: flex">
|
||||||
|
<div style="flex: 1">
|
||||||
|
<div>
|
||||||
|
<aiAudio
|
||||||
|
@saveClick="saveClick"
|
||||||
|
ref="audioRef"
|
||||||
|
:audioSrc="audioSrc"
|
||||||
|
@auditionClick="auditionClick"
|
||||||
|
></aiAudio>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="background: #fff; height: 85vh; min-width: 364px; margin-left: 20px;overflow: hidden;">
|
||||||
|
<div style="padding: 0 20px; height: 100%;">
|
||||||
|
<el-tabs v-model="activeTab" class="prepare-tabs">
|
||||||
|
<el-tab-pane label="素材" name="素材">
|
||||||
|
<div class="prepare-body-header">
|
||||||
|
<div>
|
||||||
|
<label style="font-size: 15px"
|
||||||
|
>共{{
|
||||||
|
currentFileList.filter(
|
||||||
|
(ite) => ite.fileFlag !== 'apt' && ite.fileFlag !== '课件'
|
||||||
|
).length
|
||||||
|
}}个文件</label
|
||||||
|
>
|
||||||
|
<!-- <el-popover placement="top-start" :width="250" trigger="hover">
|
||||||
|
<template #default>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
v-if="lastAsyncAllTime"
|
||||||
|
type="success"
|
||||||
|
size="small"
|
||||||
|
:icon="Check"
|
||||||
|
circle
|
||||||
|
/>
|
||||||
|
{{ lastAsyncAllTime ? toTimeText(lastAsyncAllTime) + '同步成功' : '' }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #reference>
|
||||||
|
<el-button size="small" text @click="asyncAllFile">
|
||||||
|
<el-icon v-loading="asyncAllFileVisiable">
|
||||||
|
<Refresh />
|
||||||
|
</el-icon>
|
||||||
|
{{ asyncAllFileVisiable ? '同步中' : '云同步' }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popover> -->
|
||||||
|
<!-- <el-button size="small" @click="isDialogOpen = true">上传资料</el-button>
|
||||||
|
<el-button size="small" @click="reloadFiles">资源重载</el-button> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-checkbox-group
|
||||||
|
v-model="checkFileList"
|
||||||
|
class="prepare-body-main"
|
||||||
|
:style="{ 'margin-bottom': checkFileList.length > 0 ? '40px' : '0' }"
|
||||||
|
>
|
||||||
|
<file-list-item
|
||||||
|
v-for="(item, index) in currentSCFileList"
|
||||||
|
:key="index"
|
||||||
|
:item="item"
|
||||||
|
:index="index"
|
||||||
|
>
|
||||||
|
</file-list-item>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
import { getSmarttalkPage, moveSmarttalk, creatAPT } from '@/api/file'
|
||||||
|
import FileListItem from '@/views/prepare/container/file-list-item.vue'
|
||||||
|
import { parseCataByNode, creatPPT, asyncLocalFile, removeLocalFiles } from '@/utils/talkFile'
|
||||||
|
import { uploadPicture } from '@/api/aiGeneratedImage/index.js'
|
||||||
|
import { aitts, addFileToSC } from '@/api/file/index.js'
|
||||||
|
import CryptoJS from 'crypto-js'
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
FileListItem
|
||||||
|
},
|
||||||
|
props: {},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeTab: '素材',
|
||||||
|
currentFileList: [],
|
||||||
|
uploadData: {},
|
||||||
|
checkFileList: [],
|
||||||
|
isLoading: false,
|
||||||
|
lastAsyncAllTime: '',
|
||||||
|
audioSrc: null,
|
||||||
|
filedata: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isCheckAll() {
|
||||||
|
return (
|
||||||
|
this.checkFileList.length > 0 && this.checkFileList.length === this.currentSCFileList.length
|
||||||
|
)
|
||||||
|
},
|
||||||
|
currentSCFileList() {
|
||||||
|
// return this.currentFileList.filter((item) => item.fileFlag !== 'apt' && item.fileFlag !== '课件')
|
||||||
|
return this.currentFileList.filter((item) => !['apt', 'aippt'].includes(item.fileFlag))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
auditionClick(requestData) {
|
||||||
|
this.$refs.audioRef.startLoading = true
|
||||||
|
aitts(requestData)
|
||||||
|
.then((res) => {
|
||||||
|
console.log(res)
|
||||||
|
if (res.code == 200) {
|
||||||
|
this.audioSrc = res.data.fullUrl
|
||||||
|
this.filedata = res.data
|
||||||
|
this.$refs.audioRef.startLoading = false
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg)
|
||||||
|
this.$refs.audioRef.startLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.$refs.audioRef.startLoading = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
saveClick(requestData) {
|
||||||
|
this.$refs.audioRef.saveLoading = false
|
||||||
|
aitts(requestData)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
this.filedata = res.data
|
||||||
|
const saveObj = {
|
||||||
|
textbookId: this.uploadData.textbookId,
|
||||||
|
levelFirstId: this.uploadData.levelFirstId,
|
||||||
|
levelSecondId: this.uploadData.levelSecondId,
|
||||||
|
fileSource: this.uploadData.fileSource,
|
||||||
|
fileRoot: this.uploadData.fileRoot,
|
||||||
|
fileShowName: this.filedata.fileNewName,
|
||||||
|
fileFlag: '素材',
|
||||||
|
fileId: this.filedata.id
|
||||||
|
}
|
||||||
|
addFileToSC(saveObj)
|
||||||
|
.then((resone) => {
|
||||||
|
this.asyncAllFile()
|
||||||
|
this.$refs.audioRef.saveLoading = false
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this.$refs.audioRef.saveLoading = false
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg)
|
||||||
|
this.$refs.audioRef.saveLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
this.$refs.audioRef.saveLoading = false
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
asyncAllFile() {
|
||||||
|
this.isLoading = true
|
||||||
|
return getSmarttalkPage({
|
||||||
|
...this.uploadData,
|
||||||
|
orderByColumn: 'createTime',
|
||||||
|
isAsc: 'desc',
|
||||||
|
pageSize: 500
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
this.currentFileList = [...res.rows].filter((item) => item.fileType === 'audio/wav')
|
||||||
|
this.isLoading = false
|
||||||
|
this.lastAsyncAllTime = new Date()
|
||||||
|
localStorage.setItem('lastAsyncAllTime', this.lastAsyncAllTime)
|
||||||
|
this.asyncAllFileVisiable = true
|
||||||
|
for (let i = 0; i < this.currentFileList.length; i++) {
|
||||||
|
let item = this.currentFileList[i]
|
||||||
|
if (item.fileFlag === 'apt') continue
|
||||||
|
if (item.fileFlag === 'aippt') continue
|
||||||
|
await asyncLocalFile(item)
|
||||||
|
}
|
||||||
|
this.asyncAllFileVisiable = false
|
||||||
|
return Promise.resolve()
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.isLoading = false
|
||||||
|
return Promise.resolve()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onMoveSingleFile(item) {
|
||||||
|
this.moveFile = [item]
|
||||||
|
this.isMoveDialogOpen = true
|
||||||
|
},
|
||||||
|
deleteTalk(item) {
|
||||||
|
let index = this.currentFileList.indexOf(item)
|
||||||
|
this.currentFileList.splice(index, 1)
|
||||||
|
},
|
||||||
|
// 打开布置作业窗口
|
||||||
|
openSet(row) {
|
||||||
|
// 布置推送:row 这里是单个,转为list
|
||||||
|
this.rows = [row]
|
||||||
|
this.setDialog = true
|
||||||
|
},
|
||||||
|
// 删除作业
|
||||||
|
delhomework(item) {
|
||||||
|
this.isLoading = true
|
||||||
|
delClasswork(item.id)
|
||||||
|
.then(async (res) => {
|
||||||
|
ElMessage.success('操作成功')
|
||||||
|
this.isLoading = false
|
||||||
|
await this.asyncAllFile()
|
||||||
|
this.initHomeWork()
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.isLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
const route = useRoute()
|
||||||
|
this.uploadData = route.query
|
||||||
|
// this.dataset_id = route.query.datasetId;
|
||||||
|
// this.courseName = route.query.coursetitle;
|
||||||
|
// this.levelFirstId = route.query.levelFirstId;
|
||||||
|
// this.levelSecondId = route.query.levelSecondId;
|
||||||
|
// this.textbookId = route.query.textbookId;
|
||||||
|
this.asyncAllFile() // 刷新资源列表
|
||||||
|
},
|
||||||
|
beforeDestroy() {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped scss>
|
||||||
|
:deep(.prepare-item-info-title) {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
.prepare-body-main{
|
||||||
|
overflow-y: auto;
|
||||||
|
height: 74vh;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -17,6 +17,9 @@ import log from 'electron-log/renderer' // 渲染进程日志-文件记录
|
||||||
import customComponent from '@/components/common' // 自定义组件
|
import customComponent from '@/components/common' // 自定义组件
|
||||||
import plugins from './plugins' // plugins插件
|
import plugins from './plugins' // plugins插件
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import aiAudio from 'aix-plugins-aitools' // 文字转语音插件
|
||||||
|
import '../../../node_modules/aix-plugins-aitools/aitools.css'
|
||||||
|
|
||||||
|
|
||||||
if(process.env.NODE_ENV != 'development') { // 非开发环境,将日志打印到日志文件
|
if(process.env.NODE_ENV != 'development') { // 非开发环境,将日志打印到日志文件
|
||||||
Object.assign(console, log.functions) // 渲染进程日志-控制台替换
|
Object.assign(console, log.functions) // 渲染进程日志-控制台替换
|
||||||
|
@ -46,6 +49,7 @@ app.use(router)
|
||||||
.use(plugins)
|
.use(plugins)
|
||||||
.use(Icon)
|
.use(Icon)
|
||||||
.use(Directive)
|
.use(Directive)
|
||||||
|
.use(aiAudio)
|
||||||
.mount('#app')
|
.mount('#app')
|
||||||
|
|
||||||
const isStadium = (user) => {
|
const isStadium = (user) => {
|
||||||
|
|
|
@ -96,6 +96,12 @@ export const constantRoutes = [
|
||||||
name: 'aiKolors',
|
name: 'aiKolors',
|
||||||
meta: { title: '文生图片', showBread: true }
|
meta: { title: '文生图片', showBread: true }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'aiVoice',
|
||||||
|
component: () => import('@/components/ai-voice/index.vue'),
|
||||||
|
name: 'aiVoice',
|
||||||
|
meta: { title: '语音生成', showBread: true }
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,7 @@ const tools = reactive([{
|
||||||
img: 'airobot'
|
img: 'airobot'
|
||||||
},{
|
},{
|
||||||
name: '语音生成',
|
name: '语音生成',
|
||||||
path: '',
|
path: '/model/aiVoice',
|
||||||
img: 'aiyuyin'
|
img: 'aiyuyin'
|
||||||
},{
|
},{
|
||||||
name: '文生图片',
|
name: '文生图片',
|
||||||
|
@ -211,6 +211,19 @@ const gotoRoute = (item) => {
|
||||||
if (item.path) {
|
if (item.path) {
|
||||||
if (item.path === '/model/aiKolors') {
|
if (item.path === '/model/aiKolors') {
|
||||||
gotoAiKolors(item.path)
|
gotoAiKolors(item.path)
|
||||||
|
}else if(item.path == '/model/aiVoice'){
|
||||||
|
console.log('aiVoice',uploadData.value)
|
||||||
|
const path = '/model/aiVoice'
|
||||||
|
let subjectdata = sessionStore.get('subject.curNode')
|
||||||
|
let datasubject = `课标-${subjectdata.edustage}-${subjectdata.edusubject}`
|
||||||
|
router.push({
|
||||||
|
path,
|
||||||
|
query: {
|
||||||
|
datasetId: dataSetJson[datasubject],
|
||||||
|
coursetitle: currentNode.value.itemtitle,
|
||||||
|
...uploadData.value
|
||||||
|
}
|
||||||
|
});
|
||||||
}else {
|
}else {
|
||||||
router.push(item.path)
|
router.push(item.path)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue