feat: 语音交互

This commit is contained in:
zhanghao 2025-09-11 15:42:24 +08:00
parent e749e8ba95
commit 944c0dd0f2
15 changed files with 3735 additions and 2169 deletions

View File

@ -1,77 +1,77 @@
import request from '@/utils/request'
import { method } from 'lodash'
import request from "@/utils/request";
import { method } from "lodash";
// 查询语料库列表
export function listCorpus(query) {
return request({
url: '/vi/corpus/single/list',
method: 'get',
params: query
})
url: "/vi/corpus/single/list",
method: "post",
data: query,
});
}
// 查询语料库详细
export function getCorpus(corpusId) {
return request({
url: '/vi/corpus/' + corpusId,
method: 'get'
})
url: "/vi/corpus/" + corpusId,
method: "get",
});
}
// 新增语料库
export function addCorpus(data) {
return request({
url: '/vi/corpus',
method: 'post',
data: data
})
url: "/vi/corpus",
method: "post",
data: data,
});
}
// 修改语料库
export function updateCorpus(data) {
return request({
url: '/vi/corpus',
method: 'put',
data: data
})
url: "/vi/corpus",
method: "put",
data: data,
});
}
// 删除语料库
export function delCorpus(corpusId) {
return request({
url: '/vi/corpus/' + corpusId,
method: 'delete'
})
url: "/vi/corpus/" + corpusId,
method: "delete",
});
}
export function batchAddCorpus(data) {
return request({
url: '/vi/corpus/continuous/insert',
method: 'post',
data: data
})
url: "/vi/corpus/continuous/insert",
method: "post",
data: data,
});
}
export function batchUpdateCorpus(data) {
return request({
url: '/vi/corpus/continuous/update',
method: 'post',
data: data
})
url: "/vi/corpus/continuous/update",
method: "post",
data: data,
});
}
export function getBatchCorpus(query) {
return request({
url: '/vi/corpus/continuous/list',
method: 'get',
params: query
})
url: "/vi/corpus/continuous/list",
method: "post",
data: query,
});
}
export function deleteBatchCorpus(corpusIds) {
return request({
url: `/vi/corpus/continuous`,
method: 'delete',
data: corpusIds
})
}
method: "delete",
data: corpusIds,
});
}

44
src/api/vi/plan.js Normal file
View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询语音交互-方案列表
export function listScheme(query) {
return request({
url: '/vi/scheme/list',
method: 'get',
params: query
})
}
// 查询语音交互-方案详细
export function getScheme(schemeId) {
return request({
url: '/vi/scheme/' + schemeId,
method: 'get'
})
}
// 新增语音交互-方案
export function addScheme(data) {
return request({
url: '/vi/scheme',
method: 'post',
data: data
})
}
// 修改语音交互-方案
export function updateScheme(data) {
return request({
url: '/vi/scheme',
method: 'put',
data: data
})
}
// 删除语音交互-方案
export function delScheme(schemeId) {
return request({
url: '/vi/scheme/' + schemeId,
method: 'delete'
})
}

44
src/api/vi/project.js Normal file
View File

@ -0,0 +1,44 @@
import request from '@/utils/request'
// 查询语音交互-项目列表
export function listProject(query) {
return request({
url: '/vi/project/list',
method: 'get',
params: query
})
}
// 查询语音交互-项目详细
export function getProject(projectId) {
return request({
url: '/vi/project/' + projectId,
method: 'get'
})
}
// 新增语音交互-项目
export function addProject(data) {
return request({
url: '/vi/project',
method: 'post',
data: data
})
}
// 修改语音交互-项目
export function updateProject(data) {
return request({
url: '/vi/project',
method: 'put',
data: data
})
}
// 删除语音交互-项目
export function delProject(projectId) {
return request({
url: '/vi/project/' + projectId,
method: 'delete'
})
}

View File

@ -1,74 +1,69 @@
<script setup>
import {ArrowDown, ArrowUp} from "@element-plus/icons-vue";
const props = defineProps({
queryParams: {
type: Object,
},
queryRef: {
type: String,
default: 'queryRef'
},
inline: {
type: Boolean,
default: false
},
showSearch: {
type: Boolean,
},
labelWidth: {
type: String,
default: '68px'
}
})
const emits = defineEmits(['search','refresh'])
const {proxy} = getCurrentInstance()
const formData = reactive({
search: false
});
const handleQuery = () => {
emits('search')
}
const resetQuery = () => {
proxy.resetForm(props.queryRef)
emits('refresh')
}
</script>
<template>
<el-form
:model="queryParams"
:ref="queryRef"
:inline="inline"
v-show="showSearch"
:label-width="labelWidth"
>
<el-row :gutter="16">
<slot name="one"></slot>
<el-col :xs="24" :sm="24" :md="12" :lg="6" :xl="6" :xxl="6" style="padding-bottom: 10px;">
<el-space>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" text @click="formData.search = !formData.search">
<template #icon>
<ArrowUp v-if="formData.search"/>
<ArrowDown v-else/>
</template>
<template #default>{{ formData.search ? "收起" : "展开" }}</template>
</el-button>
</el-space>
</el-col>
</el-row>
<el-row :gutter="16">
<TransitionGroup name="other-search">
<slot name="other" v-if="formData.search"></slot>
</TransitionGroup>
</el-row>
</el-form>
</template>
<style scoped lang="scss">
</style>
<script setup>
import {ArrowDown, ArrowUp} from "@element-plus/icons-vue";
const props = defineProps({
queryParams: {
type: Object,
},
queryRef: {
type: String,
default: 'queryRef'
},
inline: {
type: Boolean,
default: false
},
showSearch: {
type: Boolean,
},
labelWidth: {
type: String,
default: '68px'
}
})
const emits = defineEmits(['search','refresh'])
const {proxy} = getCurrentInstance()
const formData = reactive({
search: false
});
const handleQuery = () => {
emits('search')
}
const resetQuery = () => {
proxy.resetForm(props.queryRef)
emits('refresh')
}
</script>
<template>
<el-form
:model="queryParams"
:ref="queryRef"
:inline="inline"
v-show="showSearch"
:label-width="labelWidth"
>
<el-row :gutter="16">
<slot name="one"></slot>
<slot name="other" v-if="formData.search"></slot>
<el-col :xs="24" :sm="24" :md="12" :lg="6" :xl="6" :xxl="6" style="padding-bottom: 10px;">
<el-space>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" text @click="formData.search = !formData.search">
<template #icon>
<ArrowUp v-if="formData.search"/>
<ArrowDown v-else/>
</template>
<template #default>{{ formData.search ? "收起" : "展开" }}</template>
</el-button>
</el-space>
</el-col>
</el-row>
</el-form>
</template>
<style scoped lang="scss">
</style>

21
src/hooks/tableHeight.ts Normal file
View File

@ -0,0 +1,21 @@
import { useElementSize } from '@vueuse/core'
import { computed } from 'vue'
/**
* hook
* @param {Ref<HTMLElement | null>} containerRef - ref引用
* @param {boolean} [immediate=true] -
* @returns {Ref<number>}
*/
export function useContainerHeight(containerRef, immediate = true) {
// 存储容器高度的响应式变量
const { height } = useElementSize(containerRef)
const containerHeight = computed(() => {
let offset = height.value + 84
return { height: `calc(100% - ${offset}px)` }
})
return containerHeight;
}

View File

@ -192,6 +192,20 @@ export const dynamicRoutes = [
},
],
},
{
path: "/vi/plan",
component: Layout,
hidden: true,
permissions: ["vi:testProject:list"],
children: [
{
path: "index/:id",
component: () => import("@/views/vi/testProject/plan/index"),
name: "Data",
meta: { title: "方案管理", activeMenu: "/vi/testProject" },
},
],
},
{
path: "/monitor/job-log",
component: Layout,
@ -221,7 +235,7 @@ export const dynamicRoutes = [
],
},
];
console.log("constantRoutes", constantRoutes);
const router = createRouter({
history: createWebHistory(),
routes: constantRoutes,

File diff suppressed because it is too large Load Diff

View File

@ -1,371 +1,445 @@
<template>
<div class="app-container">
<TableSearch
:queryParams="queryParams"
:showSearch="showSearch"
label-width="90px"
queryRef="queryRef"
@refresh="resetQuery"
@search="handleQuery"
>
<template #one>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="检测项名称" prop="detectName">
<el-input
v-model="queryParams.detectName"
clearable
placeholder="请输入检测项名称"
style="width:100%"
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="检测项描述" prop="detectDesc">
<el-input
v-model="queryParams.detectDesc"
clearable
placeholder="请输入检测项描述"
style="width:100%"
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
</template>
</TableSearch>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['test:detect:add']"
icon="Plus"
plain
type="primary"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['test:detect:edit']"
:disabled="single"
icon="Edit"
plain
type="success"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['test:detect:remove']"
:disabled="multiple"
icon="Delete"
plain
type="danger"
@click="handleDelete"
>删除
</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="warning"-->
<!-- plain-->
<!-- icon="Download"-->
<!-- @click="handleExport"-->
<!-- v-hasPermi="['test:detect:export']"-->
<!-- >导出-->
<!-- </el-button>-->
<!-- </el-col>-->
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="detectList" @selection-change="handleSelectionChange">
<el-table-column align="center" type="selection" width="55"/>
<el-table-column align="center" label="id" prop="id" show-overflow-tooltip/>
<el-table-column align="center" label="检测项名称" prop="detectName" show-overflow-tooltip/>
<el-table-column align="center" label="检测项描述" prop="detectDesc" show-overflow-tooltip/>
<el-table-column align="center" label="所属分组" prop="groupId" >
<template #default="scope">
{{ groupList?.find(item => item.value === scope.row.groupId)["label"] }}
</template>
</el-table-column>
<el-table-column align="center" label="备注" prop="remark" show-overflow-tooltip/>
<el-table-column align="center" label="启用状态" prop="status">
<template #default="scope">
<el-switch
v-model="scope.row.status"
active-text="启用"
active-value="0"
inactive-text="停用"
inactive-value="1"
inline-prompt
@change="handleChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column align="center" label="配置状态" prop="isDeploy">
<template #default="scope">
<TableTags :options="[
{
label: '已配置',
value:'0',
type:'success'
},
{
label: '未配置',
value:'1',
type:'warning'
}
]" :value="scope.row.isDeploy"></TableTags>
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="200">
<template #default="scope">
<el-button v-hasPermi="['test:detect:edit']" icon="Edit" link type="primary" @click="handleUpdate(scope.row)">
修改
</el-button>
<el-button v-hasPermi="['device:terminal:deploy']" icon="Cpu" link type="primary"
@click="handleDeploy(scope.row)">配置
</el-button>
<!-- <el-button v-hasPermi="['device:terminal:deploy']" icon="Cpu" link type="primary"-->
<!-- @click="()=>dialogVisible=true">配置参数-->
<!-- </el-button>-->
<el-button v-hasPermi="['test:detect:remove']" icon="Delete" link type="primary"
@click="handleDelete(scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<!-- 添加或修改检测项配置对话框 -->
<el-dialog v-model="open" :title="title" append-to-body width="500px">
<el-form ref="detectRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="检测项名称" prop="detectName">
<el-input v-model="form.detectName" placeholder="请输入检测项名称"/>
</el-form-item>
<el-form-item label="检测项描述" prop="detectDesc">
<el-input v-model="form.detectDesc" placeholder="请输入检测项描述"/>
</el-form-item>
<el-form-item label="所属分组">
<el-select v-model="form.groupId" placeholder="请选择所属分组">
<el-option v-for="group in groupList" :key="group.value" :label="group.label"
:value="group.value"></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark"
:rows="2" placeholder="请输入备注" type="textarea"/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dialogVisible" title="参数配置" width="1080px">
<EditTable></EditTable>
</el-dialog>
</div>
</template>
<script name="Detect" setup>
import {addDetect, delDetect, getDetect, listDetect, updateDetect} from "@/api/test/detect"
import TableSearch from "@/components/TableSearch/index.vue"
import {listGroup} from "@/api/system/group.js";
import {appendParamsToPath} from "@/utils/fn.js";
import TableTags from "@/components/TableTags/index.vue";
import EditTable from "@/components/EditTable/index.vue"
const {proxy} = getCurrentInstance()
const detectList = ref([])
const open = ref(false)
const dialogVisible = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
detectName: null,
detectDesc: null,
status: null,
detectVersion: null
},
rules: {
detectName: [
{required: true, message: "检测项名称不能为空", trigger: "blur"}
]
}
})
const {queryParams, form, rules} = toRefs(data)
/** 查询检测项配置列表 */
function getList() {
loading.value = true
listDetect(queryParams.value).then(response => {
detectList.value = response.rows
total.value = response.total
loading.value = false
})
}
//
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {}
proxy.resetForm("detectRef")
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
function resetQuery() {
handleQuery()
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加检测项配置"
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _id = row.id || ids.value
getDetect(_id).then(response => {
form.value = response.data
open.value = true
title.value = "修改检测项配置"
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["detectRef"].validate(valid => {
if (valid) {
if (form.value.id != null) {
updateDetect(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
} else {
addDetect(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value
proxy.$modal.confirm('是否确认删除检测项配置编号为"' + _ids + '"的数据项?').then(function () {
return delDetect(_ids)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {
})
}
/** 配置按钮操作 */
function handleDeploy(row) {
const params = {itemId: row.id, name: row.detectName, state: row.status};
const fullPath = appendParamsToPath('/flow', params);
const p = window.open(
fullPath,
"_blank",
);
}
// visibilitychange
// document.addEventListener("visibilitychange", () => {
// if (document.visibilityState === "visible") {
// //
// getList();
// }
// });
const isMount = ref(false)
onMounted(() => {
handleGetSystemGroup()
getList()
nextTick(() => {
isMount.value = true
})
})
/** 状态开关操作 */
function handleChange(row) {
if (isMount.value) {
updateDetect({status: row.status, id: row.id}).then(response => {
proxy.$modal.msgSuccess("修改成功")
getList()
})
}
}
const groupList = ref([])
/** 获取系统分组列表(默认传1查询检测项列表) */
function handleGetSystemGroup(row) {
listGroup({type: 1}).then(response => {
groupList.value = response.rows?.map((item) => {
return {
label: item.groupName,
value: item.groupId
}
})
})
}
</script>
<template>
<div class="app-container">
<div ref="topContainerRef">
<TableSearch
:queryParams="queryParams"
:showSearch="showSearch"
label-width="90px"
queryRef="queryRef"
@refresh="resetQuery"
@search="handleQuery"
>
<template #one>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="检测项名称" prop="detectName">
<el-input
v-model="queryParams.detectName"
clearable
placeholder="请输入检测项名称"
style="width: 100%"
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="检测项描述" prop="detectDesc">
<el-input
v-model="queryParams.detectDesc"
clearable
placeholder="请输入检测项描述"
style="width: 100%"
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
</template>
</TableSearch>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
v-hasPermi="['test:detect:add']"
icon="Plus"
plain
type="primary"
@click="handleAdd"
>新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['test:detect:edit']"
:disabled="single"
icon="Edit"
plain
type="success"
@click="handleUpdate"
>修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
v-hasPermi="['test:detect:remove']"
:disabled="multiple"
icon="Delete"
plain
type="danger"
@click="handleDelete"
>删除
</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button-->
<!-- type="warning"-->
<!-- plain-->
<!-- icon="Download"-->
<!-- @click="handleExport"-->
<!-- v-hasPermi="['test:detect:export']"-->
<!-- >导出-->
<!-- </el-button>-->
<!-- </el-col>-->
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
</div>
<div :style="containerHeight">
<el-table
v-loading="loading"
height="100%"
:data="detectList"
@selection-change="handleSelectionChange"
>
<el-table-column align="center" type="selection" width="55" />
<el-table-column
align="center"
label="id"
prop="id"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="检测项名称"
prop="detectName"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="检测项描述"
prop="detectDesc"
show-overflow-tooltip
/>
<el-table-column align="center" label="所属分组" prop="groupId">
<template #default="scope">
{{
groupList?.find((item) => item.value === scope.row.groupId)[
"label"
]
}}
</template>
</el-table-column>
<el-table-column
align="center"
label="备注"
prop="remark"
show-overflow-tooltip
/>
<el-table-column align="center" label="启用状态" prop="status">
<template #default="scope">
<el-switch
v-model="scope.row.status"
active-text="启用"
active-value="0"
inactive-text="停用"
inactive-value="1"
inline-prompt
@change="handleChange(scope.row)"
/>
</template>
</el-table-column>
<el-table-column align="center" label="配置状态" prop="isDeploy">
<template #default="scope">
<TableTags
:options="[
{
label: '已配置',
value: '0',
type: 'success',
},
{
label: '未配置',
value: '1',
type: 'warning',
},
]"
:value="scope.row.isDeploy"
></TableTags>
</template>
</el-table-column>
<el-table-column
align="center"
class-name="small-padding fixed-width"
label="操作"
width="200"
>
<template #default="scope">
<el-button
v-hasPermi="['test:detect:edit']"
icon="Edit"
link
type="primary"
@click="handleUpdate(scope.row)"
>
修改
</el-button>
<el-button
v-hasPermi="['device:terminal:deploy']"
icon="Cpu"
link
type="primary"
@click="handleDeploy(scope.row)"
>配置
</el-button>
<!-- <el-button v-hasPermi="['device:terminal:deploy']" icon="Cpu" link type="primary"-->
<!-- @click="()=>dialogVisible=true">配置参数-->
<!-- </el-button>-->
<el-button
v-hasPermi="['test:detect:remove']"
icon="Delete"
link
type="primary"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
</div>
<!-- 添加或修改检测项配置对话框 -->
<el-dialog v-model="open" :title="title" append-to-body width="500px">
<el-form ref="detectRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="检测项名称" prop="detectName">
<el-input v-model="form.detectName" placeholder="请输入检测项名称" />
</el-form-item>
<el-form-item label="检测项描述" prop="detectDesc">
<el-input v-model="form.detectDesc" placeholder="请输入检测项描述" />
</el-form-item>
<el-form-item label="所属分组">
<el-select v-model="form.groupId" placeholder="请选择所属分组">
<el-option
v-for="group in groupList"
:key="group.value"
:label="group.label"
:value="group.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
:rows="2"
placeholder="请输入备注"
type="textarea"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog v-model="dialogVisible" title="参数配置" width="1080px">
<EditTable></EditTable>
</el-dialog>
</div>
</template>
<script name="Detect" setup>
import {
addDetect,
delDetect,
getDetect,
listDetect,
updateDetect,
} from "@/api/test/detect";
import TableSearch from "@/components/TableSearch/index.vue";
import { listGroup } from "@/api/system/group.js";
import { appendParamsToPath } from "@/utils/fn.js";
import TableTags from "@/components/TableTags/index.vue";
import EditTable from "@/components/EditTable/index.vue";
import { useContainerHeight } from "@/hooks/tableHeight";
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance();
const detectList = ref([]);
const open = ref(false);
const dialogVisible = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
detectName: null,
detectDesc: null,
status: null,
detectVersion: null,
},
rules: {
detectName: [
{ required: true, message: "检测项名称不能为空", trigger: "blur" },
],
},
});
const { queryParams, form, rules } = toRefs(data);
/** 查询检测项配置列表 */
function getList() {
loading.value = true;
listDetect(queryParams.value).then((response) => {
detectList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
//
function cancel() {
open.value = false;
reset();
}
//
function reset() {
form.value = {};
proxy.resetForm("detectRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加检测项配置";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const _id = row.id || ids.value;
getDetect(_id).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改检测项配置";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["detectRef"].validate((valid) => {
if (valid) {
if (form.value.id != null) {
updateDetect(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addDetect(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value;
proxy.$modal
.confirm('是否确认删除检测项配置编号为"' + _ids + '"的数据项?')
.then(function () {
return delDetect(_ids);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
/** 配置按钮操作 */
function handleDeploy(row) {
const params = { itemId: row.id, name: row.detectName, state: row.status };
const fullPath = appendParamsToPath("/flow", params);
const p = window.open(fullPath, "_blank");
}
// visibilitychange
// document.addEventListener("visibilitychange", () => {
// if (document.visibilityState === "visible") {
// //
// getList();
// }
// });
const isMount = ref(false);
onMounted(() => {
handleGetSystemGroup();
getList();
nextTick(() => {
isMount.value = true;
});
});
/** 状态开关操作 */
function handleChange(row) {
if (isMount.value) {
updateDetect({ status: row.status, id: row.id }).then((response) => {
proxy.$modal.msgSuccess("修改成功");
getList();
});
}
}
const groupList = ref([]);
/** 获取系统分组列表(默认传1查询检测项列表) */
function handleGetSystemGroup(row) {
listGroup({ type: 1 }).then((response) => {
groupList.value = response.rows?.map((item) => {
return {
label: item.groupName,
value: item.groupId,
};
});
});
}
</script>

View File

@ -1,388 +1,450 @@
<template>
<div class="app-container">
<TableSearch
:queryParams="queryParams"
:showSearch="showSearch"
queryRef="queryRef"
@refresh="resetQuery"
@search="handleQuery"
>
<template #one>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="实例名称" prop="taskName">
<el-input
v-model="queryParams.taskName"
clearable
placeholder="请输入任务名称"
style="width:100%"
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
:clearable="false"
:disabledDate="(time) => {
//
return time.getTime() > Date.now();
}"
type="daterange"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-col>
</template>
</TableSearch>
<el-row :gutter="10" class="mb8">
<right-toolbar v-model:showSearch="showSearch" @queryTable="getInstList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="instList" @selection-change="handleSelectionChange">
<el-table-column align="center" label="id" prop="id" show-overflow-tooltip/>
<el-table-column align="center" label="任务名称" prop="taskName" show-overflow-tooltip/>
<el-table-column align="center" label="创建时间" prop="createTime" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="备注" prop="remark" show-overflow-tooltip/>
<el-table-column align="center" label="实例状态" prop="status" width="180">
<template #default="scope">
<TableTags :options="[
{
label: '已完成',
value:'0',
type:'success'
},
{
label: '执行中',
value:'1',
type:'warning'
},
{
label: '失败',
value: '2',
type:'danger'
}
]" :value="scope.row.status"></TableTags>
</template>
</el-table-column>
<el-table-column align="center" class-name="small-padding fixed-width" label="操作" width="180">
<template #default="scope">
<el-button icon="Notebook" link type="primary"
@click="handleOpenLogDialog(scope.row)">日志
</el-button>
<el-button icon="DataLine" link type="primary"
@click="handleOpenDashboard(scope.row)">流程可视化
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="instTotal>0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="instTotal"
@pagination="getInstList"
/>
<!-- 添加或修改检测项日志对话框 -->
<el-drawer v-model="open" :destroy-on-close="true" :size="580" :title="title" append-to-body modal-class="test-log"
@close="cancel" @open="getLogList">
<el-timeline>
<el-timeline-item
v-for="(item, index) in logList"
:key="index.id"
:hollow="true"
:timestamp="item.createTime"
placement="top"
type="primary"
>
<el-descriptions
:column="1"
:title="item.taskName"
border
direction="vertical"
>
<!-- <template #title>-->
<!-- <div class="flex align-center" style="cursor: pointer" @click="handleLogicFlow(item)">-->
<!-- <div>{{ item.taskName }}</div>-->
<!-- <div class="flex align-center" style="margin-left: 10px;">-->
<!-- <el-icon>-->
<!-- <View/>-->
<!-- </el-icon>-->
<!-- </div>-->
<!-- </div>-->
<!-- </template>-->
<el-descriptions-item label="日志等级">{{ item.logLevel }}</el-descriptions-item>
<el-descriptions-item label="节点类型">{{ item.nodeType }}</el-descriptions-item>
<el-descriptions-item label="消息">{{ item.message }}</el-descriptions-item>
<el-descriptions-item label="执行参数">
<pre>{{ JSON.parse(item.params) }}</pre>
</el-descriptions-item>
</el-descriptions>
<!-- <el-card>-->
<!-- {{ item.message }}-->
<!-- </el-card>-->
</el-timeline-item>
</el-timeline>
<!-- <el-table style="margin-top: 20px;" v-loading="logLoading" :data="logList" :preserve-expanded-content="true">-->
<!-- <el-table-column type="index" width="50" align="center" label="序号"/>-->
<!-- <el-table-column show-overflow-tooltip label="任务名称" align="center" prop="taskName"/>-->
<!-- <el-table-column show-overflow-tooltip label="检测项名称" align="center" prop="detectName"/>-->
<!-- <el-table-column show-overflow-tooltip label="节点类型" align="center" prop="nodeType"/>-->
<!-- <el-table-column show-overflow-tooltip label="日志等级" align="center" prop="logLevel">-->
<!-- <template #default="scope">-->
<!-- <el-tag type="info">{{ scope.row.logLevel }}</el-tag>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column show-overflow-tooltip label="消息" align="center" prop="message"/>-->
<!-- <el-table-column type="expand" width="100" label="执行参数">-->
<!-- <template #default="props">-->
<!-- <pre>-->
<!-- {{ JSON.parse(props.row.params) }}-->
<!-- </pre>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="创建时间" align="center" prop="createTime" width="180">-->
<!-- <template #default="scope">-->
<!-- <span>{{ parseTime(scope.row.createTime) }}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- </el-table>-->
<!-- <div class="flex justify-content-center" style="margin: 20px 0 10px;">-->
<!-- <pagination-->
<!-- v-show="logTotal>0"-->
<!-- :total="logTotal"-->
<!-- v-model:page="logQueryParams.pageNum"-->
<!-- v-model:limit="logQueryParams.pageSize"-->
<!-- @pagination="getLogList"-->
<!-- />-->
<!-- </div>-->
</el-drawer>
<!-- 添加或修改检测项日志对话框 -->
<el-drawer v-model="openDashboard" :destroy-on-close="true" :size="580" :title="currentLog.taskName + '的流程'"
append-to-body
modal-class="rdashboad-log"
@close="cancel">
<el-card v-for="item in taskRightList" shadow="hover" style="width: 100%;margin-bottom: 10px;">
<div class="flex align-center" style="cursor: pointer" @click="handleLogicFlow(item)">
<div>{{ item.name }}</div>
<div class="flex align-center" style="margin-left: 10px;">
<el-icon>
<View/>
</el-icon>
</div>
</div>
</el-card>
</el-drawer>
</div>
</template>
<script name="Log" setup>
import {addLog, delLog, getInst, getLog, listInst, updateLog} from "@/api/test/log"
import TableSearch from "@/components/TableSearch/index.vue"
import {View} from "@element-plus/icons-vue";
import TableTags from "@/components/TableTags/index.vue";
import {appendParamsToPath} from "@/utils/fn.js";
import {getTaskConfig} from "@/api/test/config.js";
import { onMounted } from "vue";
const {proxy} = getCurrentInstance()
const instList = ref([])
const logList = ref([])
const open = ref(false)
const openDashboard = ref(false)
const loading = ref(true)
const logLoading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const instTotal = ref(0)
const logTotal = ref(0)
const title = ref("")
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
createTime: "",
detectName: null,
taskName: null,
},
logQueryParams: {
pageNum: 1,
pageSize: 100000,
instId: null,
},
rules: {}
})
const {queryParams, form, rules, logQueryParams} = toRefs(data)
const startOn = computed(() => queryParams.value.createTime[0] + " 00:00:00" || undefined)
const endOn = computed(() => queryParams.value.createTime[1] + " 23:59:59" || undefined)
/** 查询任务实例列表 */
function getInstList() {
loading.value = true
listInst(Object.assign(queryParams.value, {startOn, endOn})).then(response => {
instList.value = response.rows
instTotal.value = response.total
loading.value = false
})
}
//
function cancel() {
open.value = false
reset()
}
//
function reset() {
logQueryParams.value = {
pageNum: 1,
pageSize: 10,
instId: null,
}
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getInstList()
}
/** 重置按钮操作 */
function resetQuery() {
console.log('11')
proxy.resetForm("queryRef")
handleQuery()
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id)
single.value = selection.length != 1
multiple.value = !selection.length
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加检测项日志"
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _id = row.id || ids.value
getLog(_id).then(response => {
form.value = response.data
open.value = true
title.value = "修改检测项日志"
})
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["logRef"].validate(valid => {
if (valid) {
if (form.value.id != null) {
updateLog(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getInstList()
})
} else {
addLog(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getInstList()
})
}
}
})
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value
proxy.$modal.confirm('是否确认删除检测项日志编号为"' + _ids + '"的数据项?').then(function () {
return delLog(_ids)
}).then(() => {
getInstList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {
})
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('test/log/export', {
...queryParams.value
}, `log_${new Date().getTime()}.xlsx`)
}
/** 查询实例日志列表 */
function getLogList() {
logLoading.value = true
getInst(logQueryParams.value).then(response => {
logList.value = response.rows
logTotal.value = response.total
logLoading.value = false
})
}
function handleOpenLogDialog(row) {
logQueryParams.value.instId = row.id
open.value = true
}
const currentLog = ref({})
const handleLogicFlow = (item) => {
const params = {instId: currentLog.value.id, taskId: currentLog.value.taskId, itemId: item.id, name: item.name, state: '0', isLog: true};
const fullPath = appendParamsToPath('/flow', params);
const p = window.open(
fullPath,
"_blank",
);
}
const handleOpenDashboard = (row) => {
openDashboard.value = true
currentLog.value = row
getRightTaskList(row.taskId)
}
const taskRightList = ref([])
//
const getRightTaskList = (taskId) => {
getTaskConfig({taskId: taskId}
).then(response => {
taskRightList.value = response.rows?.map((item) => {
return {
name: item.itemName,
id: item.itemId
}
}) || []
})
}
onMounted(() => {
getInstList()
})
</script>
<template>
<div class="app-container">
<div ref="topContainerRef">
<TableSearch
:queryParams="queryParams"
:showSearch="showSearch"
queryRef="queryRef"
@refresh="resetQuery"
@search="handleQuery"
>
<template #one>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="实例名称" prop="taskName">
<el-input
v-model="queryParams.taskName"
clearable
placeholder="请输入任务名称"
style="width: 100%"
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
:clearable="false"
:disabledDate="
(time) => {
//
return time.getTime() > Date.now();
}
"
type="daterange"
value-format="YYYY-MM-DD"
/>
</el-form-item>
</el-col>
</template>
</TableSearch>
<el-row :gutter="10" class="mb8">
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getInstList"
></right-toolbar>
</el-row>
</div>
<div :style="containerHeight">
<el-table
v-loading="loading"
height="100%"
:data="instList"
@selection-change="handleSelectionChange"
>
<el-table-column
align="center"
label="id"
prop="id"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="任务名称"
prop="taskName"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="创建时间"
prop="createTime"
width="180"
>
<template #default="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
</template>
</el-table-column>
<el-table-column
align="center"
label="备注"
prop="remark"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="实例状态"
prop="status"
width="180"
>
<template #default="scope">
<TableTags
:options="[
{
label: '已完成',
value: '0',
type: 'success',
},
{
label: '执行中',
value: '1',
type: 'warning',
},
{
label: '失败',
value: '2',
type: 'danger',
},
]"
:value="scope.row.status"
></TableTags>
</template>
</el-table-column>
<el-table-column
align="center"
class-name="small-padding fixed-width"
label="操作"
width="180"
>
<template #default="scope">
<el-button
icon="Notebook"
link
type="primary"
@click="handleOpenLogDialog(scope.row)"
>日志
</el-button>
<el-button
icon="DataLine"
link
type="primary"
@click="handleOpenDashboard(scope.row)"
>流程可视化
</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="instTotal > 0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="instTotal"
@pagination="getInstList"
/>
</div>
<!-- 添加或修改检测项日志对话框 -->
<el-drawer
v-model="open"
:destroy-on-close="true"
:size="580"
:title="title"
append-to-body
modal-class="test-log"
@close="cancel"
@open="getLogList"
>
<el-timeline>
<el-timeline-item
v-for="(item, index) in logList"
:key="index.id"
:hollow="true"
:timestamp="item.createTime"
placement="top"
type="primary"
>
<el-descriptions
:column="1"
:title="item.taskName"
border
direction="vertical"
>
<el-descriptions-item label="日志等级">{{
item.logLevel
}}</el-descriptions-item>
<el-descriptions-item label="节点类型">{{
item.nodeType
}}</el-descriptions-item>
<el-descriptions-item label="消息">{{
item.message
}}</el-descriptions-item>
<el-descriptions-item label="执行参数">
<pre>{{ JSON.parse(item.params) }}</pre>
</el-descriptions-item>
</el-descriptions>
</el-timeline-item>
</el-timeline>
</el-drawer>
<!-- 添加或修改检测项日志对话框 -->
<el-drawer
v-model="openDashboard"
:destroy-on-close="true"
:size="580"
:title="currentLog.taskName + '的流程'"
append-to-body
modal-class="rdashboad-log"
@close="cancel"
>
<el-card
v-for="item in taskRightList"
shadow="hover"
style="width: 100%; margin-bottom: 10px"
>
<div
class="flex align-center"
style="cursor: pointer"
@click="handleLogicFlow(item)"
>
<div>{{ item.name }}</div>
<div class="flex align-center" style="margin-left: 10px">
<el-icon>
<View />
</el-icon>
</div>
</div>
</el-card>
</el-drawer>
</div>
</template>
<script name="Log" setup>
import {
addLog,
delLog,
getInst,
getLog,
listInst,
updateLog,
} from "@/api/test/log";
import TableSearch from "@/components/TableSearch/index.vue";
import { View } from "@element-plus/icons-vue";
import TableTags from "@/components/TableTags/index.vue";
import { appendParamsToPath } from "@/utils/fn.js";
import { getTaskConfig } from "@/api/test/config.js";
import { onMounted } from "vue";
import { useContainerHeight } from "@/hooks/tableHeight";
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance();
const instList = ref([]);
const logList = ref([]);
const open = ref(false);
const openDashboard = ref(false);
const loading = ref(true);
const logLoading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const instTotal = ref(0);
const logTotal = ref(0);
const title = ref("");
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
createTime: "",
detectName: null,
taskName: null,
},
logQueryParams: {
pageNum: 1,
pageSize: 100000,
instId: null,
},
rules: {},
});
const { queryParams, form, rules, logQueryParams } = toRefs(data);
const startOn = computed(
() => queryParams.value.createTime[0] + " 00:00:00" || undefined
);
const endOn = computed(
() => queryParams.value.createTime[1] + " 23:59:59" || undefined
);
/** 查询任务实例列表 */
function getInstList() {
loading.value = true;
listInst(Object.assign(queryParams.value, { startOn, endOn })).then(
(response) => {
instList.value = response.rows;
instTotal.value = response.total;
loading.value = false;
}
);
}
//
function cancel() {
open.value = false;
reset();
}
//
function reset() {
logQueryParams.value = {
pageNum: 1,
pageSize: 10,
instId: null,
};
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getInstList();
}
/** 重置按钮操作 */
function resetQuery() {
console.log("11");
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加检测项日志";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const _id = row.id || ids.value;
getLog(_id).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改检测项日志";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["logRef"].validate((valid) => {
if (valid) {
if (form.value.id != null) {
updateLog(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getInstList();
});
} else {
addLog(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getInstList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _ids = row.id || ids.value;
proxy.$modal
.confirm('是否确认删除检测项日志编号为"' + _ids + '"的数据项?')
.then(function () {
return delLog(_ids);
})
.then(() => {
getInstList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
"test/log/export",
{
...queryParams.value,
},
`log_${new Date().getTime()}.xlsx`
);
}
/** 查询实例日志列表 */
function getLogList() {
logLoading.value = true;
getInst(logQueryParams.value).then((response) => {
logList.value = response.rows;
logTotal.value = response.total;
logLoading.value = false;
});
}
function handleOpenLogDialog(row) {
logQueryParams.value.instId = row.id;
open.value = true;
}
const currentLog = ref({});
const handleLogicFlow = (item) => {
const params = {
instId: currentLog.value.id,
taskId: currentLog.value.taskId,
itemId: item.id,
name: item.name,
state: "0",
isLog: true,
};
const fullPath = appendParamsToPath("/flow", params);
const p = window.open(fullPath, "_blank");
};
const handleOpenDashboard = (row) => {
openDashboard.value = true;
currentLog.value = row;
getRightTaskList(row.taskId);
};
const taskRightList = ref([]);
//
const getRightTaskList = (taskId) => {
getTaskConfig({ taskId: taskId }).then((response) => {
taskRightList.value =
response.rows?.map((item) => {
return {
name: item.itemName,
id: item.itemId,
};
}) || [];
});
};
onMounted(() => {
getInstList();
});
</script>

View File

@ -1,133 +1,28 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="语料名称" prop="corpusName">
<el-input
v-model="queryParams.corpusName"
placeholder="请输入语料名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select v-model="queryParams.voiceType" placeholder="请选择音色" clearable style="width: 200px">
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select v-model="queryParams.dialect" placeholder="请选择语种" clearable style="width: 200px">
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input
v-model="queryParams.expectedResult"
placeholder="请输入预期结果"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['vi:corpus:export']"
>导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="corpusList" table-layout="auto" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column label="语音文本" align="center" prop="textContent" min-width="200" show-overflow-tooltip />
<el-table-column label="语音文件路径" align="center" prop="audioPath" min-width="150" show-overflow-tooltip />
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
<el-table-column label="预期结果" align="center" prop="expectedResult" min-width="150" show-overflow-tooltip />
<el-table-column label="顺序" align="center" prop="sortOrder" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column label="备注" align="center" prop="remark" min-width="150" show-overflow-tooltip />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['vi:corpus:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['vi:corpus:remove']">删除</el-button>
<el-button link type="primary" icon="Upload" @click="handleUpload(scope.row)" v-hasPermi="['vi:corpus:upload']">上传</el-button>
<el-button link type="primary" icon="VideoPlay" @click="handlePlay(scope.row)" v-hasPermi="['vi:corpus:play']">试听</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改语料库对话框 -->
<el-dialog :title="title" v-model="open" width="580px" append-to-body>
<el-form ref="corpusRef" :model="form" :rules="rules" label-width="80px">
<div ref="topContainerRef">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="语料名称" prop="corpusName">
<el-input v-model="form.corpusName" placeholder="请输入语料名称" />
</el-form-item>
<el-form-item label="语音文本" prop="textContent">
<el-input v-model="form.textContent" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="文件路径" prop="audioPath">
<el-input v-model="form.audioPath" type="textarea" placeholder="请输入内容" />
<el-input
v-model="queryParams.corpusName"
placeholder="请输入语料名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select v-model="form.voiceType" placeholder="请选择音色" clearable style="width: 100%">
<el-select
v-model="queryParams.voiceType"
placeholder="请选择音色"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
@ -137,7 +32,12 @@
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select v-model="form.dialect" placeholder="请选择语种" clearable style="width: 100%">
<el-select
v-model="queryParams.dialect"
placeholder="请选择语种"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
@ -147,10 +47,229 @@
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input v-model="form.expectedResult" type="textarea" placeholder="请输入预期结果" />
<el-input
v-model="queryParams.expectedResult"
placeholder="请输入预期结果"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['vi:corpus:export']"
>导出</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
</div>
<div :style="containerHeight">
<el-table
v-loading="loading"
height="100%"
:data="corpusList"
table-layout="auto"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column
label="语音文本"
align="center"
prop="textContent"
min-width="200"
show-overflow-tooltip
/>
<el-table-column
label="语音文件路径"
align="center"
prop="audioPath"
min-width="150"
show-overflow-tooltip
/>
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
<el-table-column
label="预期结果"
align="center"
prop="expectedResult"
min-width="150"
show-overflow-tooltip
/>
<el-table-column label="顺序" align="center" prop="sortOrder" />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column
label="备注"
align="center"
prop="remark"
min-width="150"
show-overflow-tooltip
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="280"
fixed="right"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
<el-button
link
type="primary"
icon="Upload"
@click="handleUpload(scope.row)"
v-hasPermi="['vi:corpus:upload']"
>上传</el-button
>
<el-button
link
type="primary"
icon="VideoPlay"
@click="handlePlay(scope.row)"
v-hasPermi="['vi:corpus:play']"
>试听</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改语料库对话框 -->
<el-dialog :title="title" v-model="open" width="580px" append-to-body>
<el-form ref="corpusRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="语料名称" prop="corpusName">
<el-input v-model="form.corpusName" placeholder="请输入语料名称" />
</el-form-item>
<el-form-item label="语音文本" prop="textContent">
<el-input
v-model="form.textContent"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
<el-form-item label="文件路径" prop="audioPath">
<el-input
v-model="form.audioPath"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select
v-model="form.voiceType"
placeholder="请选择音色"
clearable
style="width: 100%"
>
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select
v-model="form.dialect"
placeholder="请选择语种"
clearable
style="width: 100%"
>
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input
v-model="form.expectedResult"
type="textarea"
placeholder="请输入预期结果"
/>
</el-form-item>
<el-form-item label="顺序" prop="sortOrder">
<el-inputNumber v-model="form.sortOrder" placeholder="请输入顺序" style="width: 200px;" />
<el-inputNumber
v-model="form.sortOrder"
placeholder="请输入顺序"
style="width: 200px"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
@ -167,29 +286,42 @@
</template>
<script setup name="Corpus">
import { listCorpus, getCorpus, delCorpus, addCorpus, updateCorpus } from "@/api/vi/corpus"
import {
listCorpus,
getCorpus,
delCorpus,
addCorpus,
updateCorpus,
} from "@/api/vi/corpus";
import { useContainerHeight } from "@/hooks/tableHeight";
const { proxy } = getCurrentInstance()
const { vi_voice_type, vi_dialect_type } = proxy.useDict("vi_voice_type", "vi_dialect_type")
const corpusList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance();
const { vi_voice_type, vi_dialect_type } = proxy.useDict(
"vi_voice_type",
"vi_dialect_type"
);
const corpusList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const data = reactive({
form: {
type: 'WAKEUP'
type: "WAKEUP",
},
queryParams: {
pageNum: 1,
pageSize: 10,
corpusName: null,
type: 'WAKEUP',
type: "WAKEUP",
continuous: 1,
textContent: null,
voiceType: null,
@ -198,38 +330,36 @@ const data = reactive({
},
rules: {
corpusName: [
{ required: true, message: "请输入语料名称", trigger: "change" }
{ required: true, message: "请输入语料名称", trigger: "change" },
],
textContent: [
{ required: true, message: "请输入语音文本", trigger: "blur" }
{ required: true, message: "请输入语音文本", trigger: "blur" },
],
voiceType: [
{ required: true, message: "请选择音色", trigger: "blur" }
],
dialect: [
{ required: true, message: "请选择语种", trigger: "blur" }
],
}
})
voiceType: [{ required: true, message: "请选择音色", trigger: "blur" }],
dialect: [{ required: true, message: "请选择语种", trigger: "blur" }],
},
});
const { queryParams, form, rules } = toRefs(data)
const { queryParams, form, rules } = toRefs(data);
/** 查询语料库列表 */
function getList() {
loading.value = true
listCorpus(queryParams.value).then(response => {
corpusList.value = response.rows
total.value = response.total
loading.value = false
}).catch(err => {
loading.value = false
})
loading.value = true;
listCorpus(queryParams.value)
.then((response) => {
corpusList.value = response.rows;
total.value = response.total;
loading.value = false;
})
.catch((err) => {
loading.value = false;
});
}
//
function cancel() {
open.value = false
reset()
open.value = false;
reset();
}
//
@ -237,7 +367,7 @@ function reset() {
form.value = {
corpusId: null,
corpusName: null,
type: 'WAKEUP',
type: "WAKEUP",
textContent: null,
audioPath: null,
voiceType: null,
@ -248,95 +378,103 @@ function reset() {
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
}
proxy.resetForm("corpusRef")
updateTime: null,
};
proxy.resetForm("corpusRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.corpusId)
single.value = selection.length != 1
multiple.value = !selection.length
ids.value = selection.map((item) => item.corpusId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加语料库"
reset();
open.value = true;
title.value = "添加语料库";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _corpusId = row.corpusId || ids.value
getCorpus(_corpusId).then(response => {
form.value = response.data
open.value = true
title.value = "修改语料库"
})
reset();
const _corpusId = row.corpusId || ids.value;
getCorpus(_corpusId).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改语料库";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["corpusRef"].validate(valid => {
proxy.$refs["corpusRef"].validate((valid) => {
if (valid) {
console.log('f', form.value)
console.log("f", form.value);
if (form.value.corpusId != null) {
updateCorpus(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
updateCorpus(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addCorpus(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
addCorpus(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
})
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _corpusIds = row.corpusId || ids.value
proxy.$modal.confirm('是否确认删除语料库编号为"' + _corpusIds + '"的数据项?').then(function() {
return delCorpus(_corpusIds)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
const _corpusIds = row.corpusId || ids.value;
proxy.$modal
.confirm('是否确认删除语料库编号为"' + _corpusIds + '"的数据项?')
.then(function () {
return delCorpus(_corpusIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
const handleUpload = (row) => {
console.log('上传')
}
console.log("上传");
};
const handlePlay = () => {
console.log('播放')
}
console.log("播放");
};
/** 导出按钮操作 */
function handleExport() {
proxy.download('vi/corpus/export', {
...queryParams.value
}, `corpus_${new Date().getTime()}.xlsx`)
proxy.download(
"vi/corpus/export",
{
...queryParams.value,
},
`corpus_${new Date().getTime()}.xlsx`
);
}
getList()
getList();
</script>

View File

@ -1,168 +1,173 @@
<template>
<div class="app-container">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="语料名称" prop="corpusName">
<el-input
v-model="queryParams.corpusName"
placeholder="请输入语料名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select
v-model="queryParams.voiceType"
placeholder="请选择音色"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select
v-model="queryParams.dialect"
placeholder="请选择语种"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input
v-model="queryParams.expectedResult"
placeholder="请输入预期结果"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['vi:corpus:export']"
>导出</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="corpusList"
table-layout="auto"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="280"
fixed="right"
<div ref="topContainerRef">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<template #default="{ row }">
<el-form-item label="语料名称" prop="corpusName">
<el-input
v-model="queryParams.corpusName"
placeholder="请输入语料名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select
v-model="queryParams.voiceType"
placeholder="请选择音色"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select
v-model="queryParams.dialect"
placeholder="请选择语种"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input
v-model="queryParams.expectedResult"
placeholder="请输入预期结果"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
link
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
@click="handleUpdate(row)"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
link
type="primary"
type="danger"
plain
icon="Delete"
@click="handleDelete(row)"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
link
type="primary"
icon="VideoPlay"
@click="handlePlay(row)"
v-hasPermi="['vi:corpus:play']"
>试听</el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['vi:corpus:export']"
>导出</el-button
>
</template>
</el-table-column>
</el-table>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
</div>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<div :style="containerHeight">
<el-table
v-loading="loading"
:data="corpusList"
table-layout="auto"
height="100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="280"
fixed="right"
>
<template #default="{ row }">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(row)"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(row)"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
<el-button
link
type="primary"
icon="VideoPlay"
@click="handlePlay(row)"
v-hasPermi="['vi:corpus:play']"
>试听</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改语料库对话框 -->
<el-dialog :title="title" v-model="open" width="740px" append-to-body>
@ -279,6 +284,10 @@ import {
batchAddCorpus,
batchUpdateCorpus,
} from "@/api/vi/corpus";
import { useContainerHeight } from "@/hooks/tableHeight";
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance();
const { vi_voice_type, vi_dialect_type } = proxy.useDict(

View File

@ -1,131 +1,28 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="语料名称" prop="corpusName">
<el-input
v-model="queryParams.corpusName"
placeholder="请输入语料名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select v-model="queryParams.voiceType" placeholder="请选择音色" clearable style="width: 200px">
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select v-model="queryParams.dialect" placeholder="请选择语种" clearable style="width: 200px">
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input
v-model="queryParams.expectedResult"
placeholder="请输入预期结果"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['vi:corpus:export']"
>导出</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="corpusList" table-layout="auto" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column label="语音文本" align="center" prop="textContent" min-width="200" show-overflow-tooltip />
<el-table-column label="语音文件路径" align="center" prop="audioPath" min-width="150" show-overflow-tooltip />
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
<el-table-column label="预期结果" align="center" prop="expectedResult" min-width="150" show-overflow-tooltip />
<el-table-column label="状态" align="center" prop="status" />
<el-table-column label="备注" align="center" prop="remark" min-width="150" show-overflow-tooltip />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['vi:corpus:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['vi:corpus:remove']">删除</el-button>
<el-button link type="primary" icon="VideoPlay" @click="handlePlay(scope.row)" v-hasPermi="['vi:corpus:play']">试听</el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改语料库对话框 -->
<el-dialog :title="title" v-model="open" width="580px" append-to-body>
<el-form ref="corpusRef" :model="form" :rules="rules" label-width="80px">
<div ref="topContainerRef">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="68px"
>
<el-form-item label="语料名称" prop="corpusName">
<el-input v-model="form.corpusName" placeholder="请输入语料名称" />
</el-form-item>
<el-form-item label="语音文本" prop="textContent">
<el-input v-model="form.textContent" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="文件路径" prop="audioPath">
<el-input v-model="form.audioPath" type="textarea" placeholder="请输入内容" />
<el-input
v-model="queryParams.corpusName"
placeholder="请输入语料名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select v-model="form.voiceType" placeholder="请选择音色" clearable style="width: 100%">
<el-select
v-model="queryParams.voiceType"
placeholder="请选择音色"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
@ -135,7 +32,12 @@
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select v-model="form.dialect" placeholder="请选择语种" clearable style="width: 100%">
<el-select
v-model="queryParams.dialect"
placeholder="请选择语种"
clearable
style="width: 200px"
>
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
@ -145,10 +47,220 @@
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input v-model="form.expectedResult" type="textarea" placeholder="请输入预期结果" />
<el-input
v-model="queryParams.expectedResult"
placeholder="请输入预期结果"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['vi:corpus:export']"
>导出</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
</div>
<div :style="containerHeight">
<el-table
v-loading="loading"
height="100%"
:data="corpusList"
table-layout="auto"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column
label="语音文本"
align="center"
prop="textContent"
min-width="200"
show-overflow-tooltip
/>
<el-table-column
label="语音文件路径"
align="center"
prop="audioPath"
min-width="150"
show-overflow-tooltip
/>
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
<el-table-column
label="预期结果"
align="center"
prop="expectedResult"
min-width="150"
show-overflow-tooltip
/>
<el-table-column label="状态" align="center" prop="status" />
<el-table-column
label="备注"
align="center"
prop="remark"
min-width="150"
show-overflow-tooltip
/>
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
width="280"
fixed="right"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button
>
<el-button
link
type="primary"
icon="VideoPlay"
@click="handlePlay(scope.row)"
v-hasPermi="['vi:corpus:play']"
>试听</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改语料库对话框 -->
<el-dialog :title="title" v-model="open" width="580px" append-to-body>
<el-form ref="corpusRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="语料名称" prop="corpusName">
<el-input v-model="form.corpusName" placeholder="请输入语料名称" />
</el-form-item>
<el-form-item label="语音文本" prop="textContent">
<el-input
v-model="form.textContent"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
<el-form-item label="文件路径" prop="audioPath">
<el-input
v-model="form.audioPath"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
<el-form-item label="音色" prop="voiceType">
<el-select
v-model="form.voiceType"
placeholder="请选择音色"
clearable
style="width: 100%"
>
<el-option
v-for="dict in vi_voice_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="语种" prop="dialect">
<el-select
v-model="form.dialect"
placeholder="请选择语种"
clearable
style="width: 100%"
>
<el-option
v-for="dict in vi_dialect_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="预期结果" prop="expectedResult">
<el-input
v-model="form.expectedResult"
type="textarea"
placeholder="请输入预期结果"
/>
</el-form-item>
<el-form-item label="顺序" prop="sortOrder">
<el-inputNumber v-model="form.sortOrder" placeholder="请输入顺序" style="width: 200px;" />
<el-inputNumber
v-model="form.sortOrder"
placeholder="请输入顺序"
style="width: 200px"
/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
@ -165,29 +277,42 @@
</template>
<script setup name="Corpus">
import { listCorpus, getCorpus, delCorpus, addCorpus, updateCorpus } from "@/api/vi/corpus"
import {
listCorpus,
getCorpus,
delCorpus,
addCorpus,
updateCorpus,
} from "@/api/vi/corpus";
import { useContainerHeight } from "@/hooks/tableHeight";
const { proxy } = getCurrentInstance()
const { vi_voice_type, vi_dialect_type } = proxy.useDict("vi_voice_type", "vi_dialect_type")
const corpusList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance();
const { vi_voice_type, vi_dialect_type } = proxy.useDict(
"vi_voice_type",
"vi_dialect_type"
);
const corpusList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const data = reactive({
form: {
type: 'TEST'
type: "TEST",
},
queryParams: {
pageNum: 1,
pageSize: 10,
corpusName: null,
type: 'TEST',
type: "TEST",
continuous: 1,
textContent: null,
audioPath: null,
@ -199,38 +324,36 @@ const data = reactive({
},
rules: {
corpusName: [
{ required: true, message: "请输入语料名称", trigger: "change" }
{ required: true, message: "请输入语料名称", trigger: "change" },
],
textContent: [
{ required: true, message: "请输入语音文本", trigger: "blur" }
{ required: true, message: "请输入语音文本", trigger: "blur" },
],
voiceType: [
{ required: true, message: "请选择音色", trigger: "blur" }
],
dialect: [
{ required: true, message: "请选择语种", trigger: "blur" }
],
}
})
voiceType: [{ required: true, message: "请选择音色", trigger: "blur" }],
dialect: [{ required: true, message: "请选择语种", trigger: "blur" }],
},
});
const { queryParams, form, rules } = toRefs(data)
const { queryParams, form, rules } = toRefs(data);
/** 查询语料库列表 */
function getList() {
loading.value = true
listCorpus(queryParams.value).then(response => {
corpusList.value = response.rows
total.value = response.total
loading.value = false
}).catch(err => {
loading.value = false
})
loading.value = true;
listCorpus(queryParams.value)
.then((response) => {
corpusList.value = response.rows;
total.value = response.total;
loading.value = false;
})
.catch((err) => {
loading.value = false;
});
}
//
function cancel() {
open.value = false
reset()
open.value = false;
reset();
}
//
@ -238,7 +361,7 @@ function reset() {
form.value = {
corpusId: null,
corpusName: null,
type: 'TEST',
type: "TEST",
textContent: null,
audioPath: null,
voiceType: null,
@ -249,97 +372,105 @@ function reset() {
createBy: null,
createTime: null,
updateBy: null,
updateTime: null
}
proxy.resetForm("corpusRef")
updateTime: null,
};
proxy.resetForm("corpusRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.corpusId)
single.value = selection.length != 1
multiple.value = !selection.length
ids.value = selection.map((item) => item.corpusId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加语料库"
reset();
open.value = true;
title.value = "添加语料库";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _corpusId = row.corpusId || ids.value
getCorpus(_corpusId).then(response => {
form.value = response.data
open.value = true
title.value = "修改语料库"
})
reset();
const _corpusId = row.corpusId || ids.value;
getCorpus(_corpusId).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改语料库";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["corpusRef"].validate(valid => {
proxy.$refs["corpusRef"].validate((valid) => {
if (valid) {
console.log('f', form.value)
console.log("f", form.value);
if (form.value.corpusId != null) {
updateCorpus(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
updateCorpus(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addCorpus(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
addCorpus(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
})
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _corpusIds = row.corpusId || ids.value
proxy.$modal.confirm('是否确认删除语料库编号为"' + _corpusIds + '"的数据项?').then(function() {
return delCorpus(_corpusIds)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
const _corpusIds = row.corpusId || ids.value;
proxy.$modal
.confirm('是否确认删除语料库编号为"' + _corpusIds + '"的数据项?')
.then(function () {
return delCorpus(_corpusIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
const handlePlay = () => {
console.log('播放')
}
console.log("播放");
};
/** 导出按钮操作 */
function handleExport() {
proxy.download('vi/corpus/export', {
...queryParams.value
}, `corpus_${new Date().getTime()}.xlsx`)
proxy.download(
"vi/corpus/export",
{
...queryParams.value,
},
`corpus_${new Date().getTime()}.xlsx`
);
}
onMounted(() => {
getList()
})
getList();
});
defineExpose({
getList
})
getList,
});
</script>

View File

@ -1,19 +1,93 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="项目名称" prop="corpusName">
<el-input
v-model="queryParams.corpusName"
placeholder="请输入项目名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<div ref="topContainerRef">
<TableSearch
:queryParams="queryParams"
:showSearch="showSearch"
label-width="100px"
queryRef="queryRef"
@refresh="resetQuery"
@search="handleQuery"
>
<template #one>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="项目名称" prop="projectName">
<el-input
v-model="queryParams.projectName"
placeholder="请输入项目名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="测试人员" prop="tester">
<el-input
v-model="queryParams.tester"
placeholder="请输入测试人员"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="样品名称" prop="sampleName">
<el-input
v-model="queryParams.sampleName"
placeholder="请输入样品名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
</template>
<template #other>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="计划开始时间" prop="planStart">
<el-date-picker
clearable
v-model="queryParams.planStart"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择计划开始时间"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="计划结束时间" prop="planEnd">
<el-date-picker
clearable
v-model="queryParams.planEnd"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择计划结束时间"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="商标" prop="trademark">
<el-input
v-model="queryParams.trademark"
placeholder="请输入商标"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="型号规格" prop="modelSpec">
<el-input
v-model="queryParams.modelSpec"
placeholder="请输入型号规格"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
</el-col>
</template>
</TableSearch>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
@ -21,108 +95,233 @@
type="primary"
plain
icon="Plus"
size="mini"
@click="handleAdd"
v-hasPermi="['vi:corpus:add']"
>新增</el-button>
v-hasPermi="['system:project:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
size="mini"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['vi:corpus:edit']"
>修改</el-button>
v-hasPermi="['system:project:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
size="mini"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['vi:corpus:remove']"
>删除</el-button>
v-hasPermi="['system:project:remove']"
>删除</el-button
>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
size="mini"
@click="handleExport"
v-hasPermi="['system:project:export']"
>导出</el-button
>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</div>
<el-table v-loading="loading" :data="corpusList" table-layout="auto" @selection-change="handleSelectionChange">
<div :style="containerHeight">
<el-table
v-loading="loading"
height="100%"
:data="projectList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目名称" align="center" prop="corpusName" />
<el-table-column label="项目编号" align="center" prop="textContent" min-width="200" show-overflow-tooltip />
<el-table-column label="测试人员" align="center" prop="audioPath" min-width="150" show-overflow-tooltip />
<el-table-column label="计划测试时间" align="center" prop="voiceType" />
<el-table-column label="项目描述" align="center" prop="dialect" show-overflow-tooltip />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
<template #default="scope">
<el-button link type="primary" icon="Upload" @click="handleUpload(scope.row)">详情</el-button>
<el-button link type="primary" icon="Upload" @click="handleUpload(scope.row)">下载</el-button>
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
<el-button link type="primary" icon="VideoPlay" @click="handlePlay(scope.row)">执行</el-button>
<el-table-column label="项目ID" align="center" prop="projectId" />
<el-table-column label="项目名称" align="center" prop="projectName" width="150" show-overflow-tooltip />
<el-table-column label="测试人员" align="center" prop="tester" />
<el-table-column
label="计划测试开始时间"
align="center"
prop="planStart"
width="180"
>
<template #default="{ row }">
<span>{{ parseTime(row.planStart) }}</span>
</template>
</el-table-column>
<el-table-column label="计划测试结束时间" align="center" prop="planEnd" width="180">
<template #default="{ row }">
<span>{{ parseTime(row.planEnd) }}</span>
</template>
</el-table-column>
<el-table-column label="项目描述" width="200" show-overflow-tooltip align="center" prop="description" />
<el-table-column label="样品名称" align="center" prop="sampleName" width="150" show-overflow-tooltip />
<el-table-column label="商标" align="center" prop="trademark" width="150" show-overflow-tooltip />
<el-table-column label="型号规格" align="center" prop="modelSpec" width="150" show-overflow-tooltip />
<el-table-column label="数量" align="center" prop="quantity" />
<el-table-column label="操作" align="center" width="220px" class-name="small-padding fixed-width" fixed="right">
<template #default="{ row }">
<el-button
size="mini"
type="text"
@click="handleSetting(row)"
>配置
</el-button>
<el-button
size="mini"
type="text"
@click="handleUpdate(row)"
v-hasPermi="['system:project:edit']"
>修改</el-button
>
<el-button
size="mini"
type="text"
@click="handleDelete(row)"
v-hasPermi="['system:project:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改语料库对话框 -->
<el-dialog :title="title" v-model="open" width="740px" append-to-body>
<el-form ref="corpusRef" :inline="true" :model="form" :rules="rules" label-width="100px">
<el-dialog
:title="title"
v-model="open"
width="740px"
:append-to-body="false"
body-class="testProject_dialog"
>
<el-form ref="projectRef" :model="form" :rules="rules" label-width="120px">
<div class="card">
<div class="form-title">项目信息</div>
<el-form-item label="项目名称" prop="corpusName">
<el-input v-model="form.corpusName" placeholder="请输入语料名称" />
</el-form-item>
<el-form-item label="项目编号" prop="textContent">
<el-input v-model="form.textContent" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="测试人员" prop="audioPath">
<el-input v-model="form.audioPath" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="计划测试时间" prop="voiceType">
<el-date-picker
v-model="form.voiceType"
type="date"
placeholder="Pick a date"
/>
</el-form-item>
<el-form-item label="项目描述" prop="dialect">
<el-input v-model="form.expectedResult" type="textarea" placeholder="请输入项目描述" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入语料名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="测试人员" prop="tester">
<el-input v-model="form.tester" placeholder="请输入测试人员" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划开始时间" prop="planStart">
<el-date-picker
clearable
v-model="form.planStart"
type="datetime"
placeholder="请选择计划测试开始时间"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划结束时间" prop="planEnd">
<el-date-picker
clearable
v-model="form.planEnd"
type="datetime"
placeholder="请选择计划测试结束时间"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="项目描述" prop="description">
<el-input
v-model="form.description"
type="textarea"
placeholder="请输入项目描述"
/>
</el-form-item>
</el-col>
</el-row>
</div>
<div class="card">
<div class="card">
<div class="form-title">样品信息</div>
<el-form-item label="样品名称" prop="corpusName">
<el-input v-model="form.corpusName" placeholder="请输入语料名称" />
</el-form-item>
<el-form-item label="商标" prop="textContent">
<el-input v-model="form.textContent" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="型号规格" prop="audioPath">
<el-input v-model="form.audioPath" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="样品数量" prop="voiceType">
<el-date-picker
v-model="form.voiceType"
type="date"
placeholder="Pick a date"
/>
</el-form-item>
<el-form-item label="生产单位" prop="dialect">
<el-input v-model="form.expectedResult" placeholder="请输入项目描述" />
</el-form-item>
<el-form-item label="委托单位" prop="dialect">
<el-input v-model="form.expectedResult" placeholder="请输入项目描述" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="样品名称" prop="sampleName">
<el-input v-model="form.sampleName" placeholder="请输入语料名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="商标" prop="trademark">
<el-input v-model="form.trademark" placeholder="请输入内容" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="型号规格" prop="modelSpec">
<el-input v-model="form.modelSpec" placeholder="请输入内容" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="样品数量" prop="quantity">
<el-input-number
v-model="form.quantity"
:min="1"
:step="1"
:step-strictly="true"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="委托单位" prop="entrustUnit">
<el-input v-model="form.entrustUnit" placeholder="请输入项目描述" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产单位" prop="productionUnit">
<el-input v-model="form.productionUnit" placeholder="请输入项目描述" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="送样日期" prop="sampleDate">
<el-date-picker
clearable
v-model="form.sampleDate"
type="datetime"
placeholder="请选择送样日期"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产日期" prop="productionDate">
<el-date-picker
clearable
v-model="form.productionDate"
type="datetime"
placeholder="请选择生产日期"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</div>
</el-form>
<template #footer>
@ -135,175 +334,236 @@
</div>
</template>
<script setup name="Corpus">
import { listCorpus, getCorpus, delCorpus, addCorpus, updateCorpus } from "@/api/vi/corpus"
<script setup>
import {
listProject,
getProject,
delProject,
addProject,
updateProject,
} from "@/api/vi/project";
import TableSearch from "@/components/TableSearch/index.vue";
import { useContainerHeight } from "@/hooks/tableHeight";
const { proxy } = getCurrentInstance()
const { vi_voice_type, vi_dialect_type } = proxy.useDict("vi_voice_type", "vi_dialect_type")
const corpusList = ref([])
const open = ref(false)
const loading = ref(true)
const showSearch = ref(true)
const ids = ref([])
const single = ref(true)
const multiple = ref(true)
const total = ref(0)
const title = ref("")
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance();
const projectList = ref([]);
const open = ref(false);
const loading = ref(false);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const data = reactive({
form: {
},
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
corpusName: null
projectName: null,
tester: null,
planStart: null,
planEnd: null,
description: null,
sampleName: null,
trademark: null,
modelSpec: null,
quantity: null,
status: null,
},
rules: {
}
})
projectName: [{ required: true, message: "项目名称不能为空", trigger: "blur" }],
tester: [{ required: true, message: "请输入测试人员", trigger: "blur" }],
planStart: [{ required: true, message: "请输入计划测试开始时间", trigger: "blur" }],
planEnd: [{ required: true, message: "请输入计划测试结束时间", trigger: "blur" }],
sampleName: [{ required: true, message: "请输入样品名称", trigger: "blur" }],
trademark: [{ required: true, message: "请输入样品商标", trigger: "blur" }],
modelSpec: [{ required: true, message: "请输入样品型号规格", trigger: "blur" }],
entrustUnit: [{ required: true, message: "请输入样品委托单位", trigger: "blur" }],
productionUnit: [{ required: true, message: "请输入样品生产单位", trigger: "blur" }],
quantity: [
{ required: true, message: "请输入样品数量" },
{ type: 'number', message: '请输入样品数量' },],
sampleDate: [{ required: true, message: "请输入样品送达日期", trigger: "blur" }],
productionDate: [{ required: true, message: "请输入样品生产日期", trigger: "blur" }],
},
});
const { queryParams, form, rules } = toRefs(data)
const { queryParams, form, rules } = toRefs(data);
/** 查询语料库列表 */
/** 查询语音交互-项目列表 */
function getList() {
loading.value = true
listCorpus(queryParams.value).then(response => {
corpusList.value = response.rows
total.value = response.total
loading.value = false
}).catch(err => {
loading.value = false
})
loading.value = true;
listProject(queryParams.value).then((response) => {
projectList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
//
function cancel() {
open.value = false
reset()
open.value = false;
reset();
}
//
function reset() {
form.value = {
corpusName: null,
}
proxy.resetForm("corpusRef")
projectId: null,
projectName: null,
tester: null,
planStart: null,
planEnd: null,
description: null,
sampleName: null,
trademark: null,
modelSpec: null,
quantity: null,
status: null,
remark: null,
createBy: null,
createTime: null,
updateBy: null,
updateTime: null,
};
proxy.resetForm("projectRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1
getList()
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef")
handleQuery()
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.corpusId)
single.value = selection.length != 1
multiple.value = !selection.length
ids.value = selection.map((item) => item.projectId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset()
open.value = true
title.value = "添加测试项目"
reset();
open.value = true;
title.value = "添加测试项目";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
const _corpusId = row.corpusId || ids.value
getCorpus(_corpusId).then(response => {
form.value = response.data
open.value = true
title.value = "修改测试项目"
})
reset();
const _projectId = row.projectId || ids.value;
getProject(_projectId).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改测试项目";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["corpusRef"].validate(valid => {
proxy.$refs["projectRef"].validate((valid) => {
if (valid) {
console.log('f', form.value)
if (form.value.corpusId != null) {
updateCorpus(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功")
open.value = false
getList()
})
if (form.value.projectId != null) {
updateProject(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addCorpus(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功")
open.value = false
getList()
})
addProject(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
})
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _corpusIds = row.corpusId || ids.value
proxy.$modal.confirm('是否确认删除语料库编号为"' + _corpusIds + '"的数据项?').then(function() {
return delCorpus(_corpusIds)
}).then(() => {
getList()
proxy.$modal.msgSuccess("删除成功")
}).catch(() => {})
}
const handleUpload = (row) => {
console.log('上传')
}
const handlePlay = () => {
console.log('播放')
const _projectIds = row.projectId || ids.value;
proxy.$modal
.confirm('是否确认删除语音交互-项目编号为"' + _projectIds + '"的数据项?')
.then(function () {
return delProject(_projectIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download('vi/corpus/export', {
...queryParams.value
}, `corpus_${new Date().getTime()}.xlsx`)
proxy.download(
"system/project/export",
{
...queryParams.value,
},
`project_${new Date().getTime()}.xlsx`
);
}
const router = useRouter()
const handleSetting = (row) => {
router.push('/vi/plan/index/' + row.projectId)
}
onMounted(() => {
getList()
})
getList();
});
</script>
<style lang="scss" scoped>
.card {
padding: 12px;
border: 1px solid #e4e7ed;
border-radius: 8px;
margin-bottom: 20px;
:deep() {
.testProject_dialog {
.el-date-editor {
--el-date-editor-width: 100%;
}
&:hover {
box-shadow: 0px 0px 12px rgba(0, 0, 0, .12);
}
.el-input-number {
width: 100%;
}
.form-title {
display: flex;
align-items: center;
font-size: 16px;
margin-bottom: 10px;
.card {
padding: 12px;
border: 1px solid #e4e7ed;
border-radius: 8px;
margin-bottom: 20px;
&::before {
content: '';
width: 4px;
height: 16px;
background: blue;
display: inline-block;
margin-right: 8px;
&:hover {
box-shadow: 0px 0px 12px rgba(0, 0, 0, 0.12);
}
.form-title {
display: flex;
align-items: center;
font-size: 16px;
margin-bottom: 10px;
&::before {
content: "";
width: 4px;
height: 16px;
background: blue;
display: inline-block;
margin-right: 8px;
}
}
}
}
}

View File

@ -0,0 +1,428 @@
<template>
<div class="app-container">
<div ref="topContainerRef">
<el-form
:model="queryParams"
ref="queryRef"
:inline="true"
v-show="showSearch"
label-width="100px"
>
<el-form-item label="所属项目ID" prop="projectId">
<el-input
v-model="queryParams.projectId"
placeholder="请输入所属项目ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="方案名称" prop="schemeName">
<el-input
v-model="queryParams.schemeName"
placeholder="请输入方案名称"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['system:scheme:add']"
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['system:scheme:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['system:scheme:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['system:scheme:export']"
>导出</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
</div>
<div :style="containerHeight">
<el-table
v-loading="loading"
:data="schemeList"
height="100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="方案ID" align="center" prop="schemeId" />
<el-table-column label="所属项目ID" align="center" prop="projectId" />
<el-table-column label="方案名称" align="center" prop="schemeName" />
<el-table-column
label="语料ID列表"
align="center"
prop="corpusIds"
width="300"
show-overflow-tooltip
/>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column
label="操作"
align="center"
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:scheme:edit']"
>修改</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:scheme:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
<!-- 添加或修改语音交互-方案对话框 -->
<el-dialog
:title="title"
v-model="open"
width="700px"
:append-to-body="false"
body-class="plan_dialog"
>
<el-form ref="schemeRef" :model="form" :rules="rules" label-width="100px">
<el-form-item label="方案名称" prop="schemeName">
<el-input v-model="form.schemeName" placeholder="请输入方案名称" />
</el-form-item>
<el-form-item label="播放配置" prop="sceneType">
<el-select
v-model="form.sceneType"
placeholder="Select"
style="width: 240px"
>
<el-option
v-for="item in settingOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="唤醒语料列表" prop="wakeId">
<el-select
v-model="form.wakeId"
placeholder="Select"
style="width: 240px"
>
<el-option
v-for="item in corpusIdsOptions"
:key="item.parentId"
:label="item.corpusName"
:value="item.parentId"
/>
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="form.remark"
type="textarea"
placeholder="请输入内容"
/>
</el-form-item>
</el-form>
<div v-if="form.sceneType && form.sceneType != 1">
<div>语料配置({{ form.sceneType == 2 ? "单次" : "连续" }})</div>
<Setting
type="1"
v-if="form.sceneType == 2"
:corpusIds="selectCorpusIds"
@updateSelectRows="getSelectRows"
/>
<Setting
type="0"
v-if="form.sceneType == 3"
:corpusIds="selectCorpusIds"
@updateSelectRows="getSelectRows"
/>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {
listScheme,
getScheme,
delScheme,
addScheme,
updateScheme,
} from "@/api/vi/plan";
import { listCorpus } from "@/api/vi/corpus";
import Setting from "./setting.vue";
import { onMounted } from "vue";
import { ElMessage } from "element-plus";
import { useContainerHeight } from "@/hooks/tableHeight";
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const route = useRoute();
const { proxy } = getCurrentInstance();
const schemeList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const selectCorpusIds = ref("");
const data = reactive({
form: {
corpusIds: null,
},
queryParams: {
pageNum: 1,
pageSize: 10,
schemeName: null,
corpusIds: null,
},
rules: {
projectId: [
{ required: true, message: "所属项目ID不能为空", trigger: "blur" },
],
schemeName: [
{ required: true, message: "方案名称不能为空", trigger: "blur" },
],
},
});
const { queryParams, form, rules } = toRefs(data);
/** 查询语音交互-方案列表 */
function getList() {
loading.value = true;
listScheme(queryParams.value).then((response) => {
schemeList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
//
function cancel() {
open.value = false;
reset();
}
//
function reset() {
form.value = {
schemeId: null,
schemeName: null,
corpusIds: null,
remark: null,
};
proxy.resetForm("schemeRef");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.schemeId);
single.value = selection.length != 1;
multiple.value = !selection.length;
}
const settingOptions = [
{ value: 1, label: "唤醒场景" },
{ value: 2, label: "单次对话场景" },
{ value: 3, label: "连续对话场景" },
];
const corpusIdsOptions = ref([]);
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加方案";
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const _schemeId = row.schemeId || ids.value;
getScheme(_schemeId).then((response) => {
form.value = response.data;
selectCorpusIds.value = response.data.corpusIds;
title.value = "修改方案";
open.value = true;
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["schemeRef"].validate((valid) => {
if (valid) {
if (form.value.sceneType === "1") {
form.value.corpusIds = null;
} else {
if (!form.value?.corpusIds || form.value?.corpusIds?.length === 0) {
ElMessage.error("请先添加语料");
return;
}
}
if (form.value.schemeId != null) {
updateScheme(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
addScheme({
...form.value,
projectId: route.params.id,
}).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _schemeIds = row.schemeId || ids.value;
proxy.$modal
.confirm('是否确认删除语音交互-方案编号为"' + _schemeIds + '"的数据项?')
.then(function () {
return delScheme(_schemeIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
}
/** 导出按钮操作 */
function handleExport() {
proxy.download(
"system/scheme/export",
{
...queryParams.value,
},
`scheme_${new Date().getTime()}.xlsx`
);
}
const getWakeList = () => {
listCorpus({
pageNum: 1,
pageSize: 100000,
type: "WAKEUP",
continuous: 1,
})
.then((response) => {
corpusIdsOptions.value = response.rows;
})
.catch((err) => {});
};
const getSelectRows = (arr) => {
const corpusIds = arr.map((item) => item.parentId);
form.value.corpusIds = corpusIds.toString();
};
onMounted(() => {
getList();
getWakeList();
});
</script>
<style lang="scss" scoped>
:deep() {
.plan_dialog {
.el-select {
width: 100% !important;
}
}
}
</style>

View File

@ -0,0 +1,191 @@
<template>
<div>
<div class="btn-container">
<el-button type="primary" @click="openDialog">配置语料</el-button>
</div>
<el-table :data="selectList">
<el-table-column label="语料名称" align="center" prop="corpusName" />
<el-table-column
label="语音文本"
align="center"
prop="textContent"
min-width="200"
show-overflow-tooltip
/>
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
</el-table>
<el-dialog title="选择语料" v-model="open" width="700px">
<el-table
ref="tableRef"
:data="corpusList"
:tree-props="{ checkStrictly: true }"
:row-key="rowKey"
>
<el-table-column
type="selection"
width="55"
align="center"
v-show="false"
:selectable="selectable"
/>
<el-table-column
label="语料名称"
align="center"
prop="corpusName"
min-width="100"
show-overflow-tooltip
/>
<el-table-column
label="语音文本"
align="center"
prop="textContent"
min-width="200"
show-overflow-tooltip
/>
<el-table-column label="音色" align="center" prop="voiceType" />
<el-table-column label="语种" align="center" prop="dialect" />
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import { listCorpus, getBatchCorpus } from "@/api/vi/corpus";
const props = defineProps({
type: {
type: String,
default: "1",
},
corpusIds: {
type: String,
default: "",
},
});
const emits = defineEmits(["updateSelectRows"]);
const selectList = ref([]);
const corpusList = ref([]);
const open = ref(false);
const openDialog = () => {
open.value = true;
setTimeout(() => {
toggleRowSelection();
}, 100);
};
const toggleRowSelection = () => {
if (selectList.value.length > 0) {
corpusList.value.forEach((row) => {
selectList.value.forEach((item) => {
if (
item.parentId + (item?.corpusId || "") ===
row.parentId + (row?.corpusId || "")
) {
tableRef.value.toggleRowSelection(row, true);
}
});
});
}
};
const rowKey = (row) => {
return row.parentId + (row?.corpusId || "");
};
const selectable = (row) => {
if (row.continuous + "" === "0") {
return false;
} else {
return true;
}
};
const getList = () => {
if (props.type === "1") {
listCorpus({
pageNum: 1,
pageSize: 100000,
type: "TEST",
continuous: 1,
})
.then((response) => {
corpusList.value = response.rows;
})
.catch((err) => {});
} else {
getBatchCorpus({
pageNum: 1,
pageSize: 100000,
type: "TEST",
continuous: 0,
})
.then((response) => {
corpusList.value = response.rows;
})
.catch((err) => {});
}
};
const tableRef = ref();
const submitForm = () => {
const rows = tableRef.value.getSelectionRows();
selectList.value = rows;
open.value = false;
emits("updateSelectRows", rows);
};
const cancel = () => {
open.value = false;
};
const getSelectList = (corpusIds) => {
if (props.type === "1") {
listCorpus({
pageNum: 1,
pageSize: 100000,
type: "TEST",
continuous: 1,
parentIds: corpusIds,
})
.then((response) => {
selectList.value = response.rows;
})
.catch((err) => {});
} else {
getBatchCorpus({
pageNum: 1,
pageSize: 100000,
type: "TEST",
continuous: 0,
parentIds: corpusIds,
})
.then((response) => {
selectList.value = response.rows;
})
.catch((err) => {});
}
};
onMounted(() => {
getList();
if (props.corpusIds) {
getSelectList(props.corpusIds.split(","));
}
});
</script>
<style lang="scss" scoped>
.btn-container {
text-align: right;
margin-bottom: 12px;
}
</style>