feat: 引用

This commit is contained in:
zhanghao 2025-09-19 14:16:28 +08:00
parent 944c0dd0f2
commit 4f4af08bbe
10 changed files with 1254 additions and 989 deletions

View File

@ -201,7 +201,7 @@ export const dynamicRoutes = [
{ {
path: "index/:id", path: "index/:id",
component: () => import("@/views/vi/testProject/plan/index"), component: () => import("@/views/vi/testProject/plan/index"),
name: "Data", name: "Plan",
meta: { title: "方案管理", activeMenu: "/vi/testProject" }, meta: { title: "方案管理", activeMenu: "/vi/testProject" },
}, },
], ],

View File

@ -22,9 +22,10 @@ export const getInput = (nodeId, isStrict = true) => {
const obj = { const obj = {
value: item.id, value: item.id,
label: item.properties.name, label: item.properties.name,
type: 'input',
children: [] children: []
} }
const optionData = transformTree(item.properties.inputParams, obj.children) const optionData = transformTree(item.properties.inputParams, obj.children, 'input')
obj.children.push(optionData) obj.children.push(optionData)
arr.push(obj) arr.push(obj)
} }
@ -32,9 +33,10 @@ export const getInput = (nodeId, isStrict = true) => {
const obj = { const obj = {
value: item.id, value: item.id,
label: item.properties.name + '(输入)', label: item.properties.name + '(输入)',
type: 'input',
children: [] children: []
} }
const optionData = transformTree(item.properties.nodeParams, obj.children) const optionData = transformTree(item.properties.nodeParams, obj.children, 'input')
obj.children.push(optionData) obj.children.push(optionData)
arr.push(obj) arr.push(obj)
} }
@ -43,9 +45,10 @@ export const getInput = (nodeId, isStrict = true) => {
const obj = { const obj = {
value: item.id, value: item.id,
label: item.properties.name + '(输出)', label: item.properties.name + '(输出)',
type: 'output',
children: [] children: []
} }
const optionData = transformTree(item.properties.outputParams, obj.children) const optionData = transformTree(item.properties.outputParams, obj.children, 'output')
obj.children.push(optionData) obj.children.push(optionData)
arr.push(obj) arr.push(obj)
} }
@ -55,11 +58,12 @@ export const getInput = (nodeId, isStrict = true) => {
return flag return flag
} }
const transformTree = (arr, parent = []) => { const transformTree = (arr, parent = [], type) => {
arr.forEach(item => { arr.forEach(item => {
const currentNode = { const currentNode = {
value: item.name, value: item.name,
label: item.name, label: item.name,
type,
children: [] children: []
}; };
parent.push(currentNode); parent.push(currentNode);
@ -67,7 +71,7 @@ const transformTree = (arr, parent = []) => {
if (item.children?.length > 0) { if (item.children?.length > 0) {
transformTree(item.children, currentNode.children); transformTree(item.children, currentNode.children);
} else { } else {
delete currentNode.children delete currentNode.children
} }
}); });
return parent; return parent;

View File

@ -106,7 +106,7 @@ export const collapseList = [
{ name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: deviceOptions(), disabled: true } { name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: deviceOptions(), disabled: true }
], ],
outputType: 'img', outputType: 'img',
outputParams: [{ name: 'imageUrl', type: 'Array<String>', desc: '图片地址数组'}] outputParams: [{ name: 'imageUrl', type: 'array<string>', desc: '图片地址数组', disabled: true}]
}, },
{ {
icon: cameraSvg, icon: cameraSvg,
@ -145,7 +145,7 @@ export const collapseList = [
{ name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: deviceOptions(), disabled: true } { name: "deviceId", type: "input", input: "", componentType: 'select', selectOptions: deviceOptions(), disabled: true }
], ],
outputType: 'video', outputType: 'video',
outputParams: [{ name: 'videoUrl', type: 'Array<String>', desc: '视频播放地址数组'}] outputParams: [{ name: 'videoUrl', type: 'array<string>', desc: '视频播放地址数组'}]
} }
], ],
}, },
@ -254,7 +254,7 @@ export const collapseList = [
}, },
], ],
}, },
{ {
collapseTitle: "大模型", collapseTitle: "大模型",
nodeList: [ nodeList: [
{ {
@ -273,4 +273,21 @@ export const collapseList = [
}, },
], ],
}, },
{
collapseTitle: "语音交互",
nodeList: [
{
icon: microphoneSvg,
name: "唤醒语料",
type: "serviceNode",
desc: "唤醒语料处理",
action: 'VI_WAKE_CORPUS',
nodeParams: [
{ name: "", type: "input", input: ""}
],
outputType: 'json',
outputParams: [{ name: 'coordinates', type: 'Object', desc: '坐标对象'}]
},
],
},
] ]

View File

@ -33,10 +33,10 @@
<el-option label="Number" value="number" /> <el-option label="Number" value="number" />
<el-option label="Boolean" value="boolean" /> <el-option label="Boolean" value="boolean" />
<el-option v-if="depth < endDepth" label="Object" value="object" /> <el-option v-if="depth < endDepth" label="Object" value="object" />
<!-- <el-option label="Array<String>" value="array<string>" /> <el-option label="Array<String>" value="array<string>" />
<el-option label="Array<Number>" value="array<number>" /> <el-option label="Array<Number>" value="array<number>" />
<el-option label="Array<Boolean>" value="array<boolean>" /> <el-option label="Array<Boolean>" value="array<boolean>" />
<el-option v-if="depth < endDepth" label="Array<Object>" value="array<object>" /> --> <el-option v-if="depth < endDepth" label="Array<Object>" value="array<object>" />
</el-select> </el-select>
</el-form-item> </el-form-item>

View File

@ -91,10 +91,12 @@
:prop="`nodeParams.${index}.quote`" :prop="`nodeParams.${index}.quote`"
> >
<el-cascader <el-cascader
:ref="el => { if (el) cascaderRefs[index] = el }"
v-model="property.quote" v-model="property.quote"
:options="quoteOptions" :options="quoteOptions"
placeholder="请选择" placeholder="请选择"
@visible-change="visibleChange" @visible-change="visibleChange"
@change="(value) => cascaderChange(value, index)"
/> />
</el-form-item> </el-form-item>
</el-form-item> </el-form-item>
@ -105,28 +107,50 @@
</div> </div>
<div class="output__container" v-if="props.properties?.outputParams?.length > 0"> <div class="output__container" v-if="props.properties?.outputParams?.length > 0">
<div class="title"> <div class="title">
<div class="tag"></div> <div class="left">
<div class="text">输出</div> <div class="tag"></div>
<div class="text">输出</div>
</div>
<div class="right" >
<el-button
:disabled="flowStore.disableForm"
@click="addOutputFormItem"
class="addFormItem"
>
<el-icon :size="20"><Plus /></el-icon>
</el-button>
</div>
</div> </div>
<div class="form__container"> <div class="form__container">
<el-form <el-form
:inline="true" :inline="true"
:model="formData"
label-position="top" label-position="top"
label-width="auto" label-width="auto"
:disabled="true" :rules="outputRules"
ref="outputFormRef"
> >
<el-row v-for="(item, index) in props.properties.outputParams"> <!-- <el-row v-for="(item, index) in formData.outputParams">
<el-form-item label="参数名" > <el-form-item :label="index === 0 ? '参数名' : ''" >
<el-input :value="item.name" /> <el-input :value="item.name" :disabled="item?.disabled" />
</el-form-item> </el-form-item>
<el-form-item label="参数类型" > <el-form-item :label="index === 0 ? '参数类型' : ''" >
<el-input :value="item.type" /> <el-input :value="item.type" />
</el-form-item> </el-form-item>
<el-form-item label="描述" > <el-form-item :label="index === 0 ? '描述' : ''">
<el-input :value="item.desc" /> <el-input :value="item.desc" />
</el-form-item> </el-form-item>
</el-row> </el-row> -->
<FormItemRecursive
:current-list="formData.outputParams"
prop-path="outputParams"
:depth="0"
:is-first-level="true"
:endDepth="2"
:parent-path="[]"
@delete-item="deleteTopLevelItem"
/>
</el-form> </el-form>
</div> </div>
</div> </div>
@ -143,6 +167,7 @@ import NodeState from "../../components/NodeState.vue";
import "vue3-json-viewer/dist/index.css"; import "vue3-json-viewer/dist/index.css";
import { emitter } from "@/utils/eventBus"; import { emitter } from "@/utils/eventBus";
import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue"; import IPlayer from "@/views/device/register/components/LogicFlow/IPlayer/index.vue";
import FormItemRecursive from "./FormItemRecursive.vue";
const props = defineProps({ const props = defineProps({
model: Object, model: Object,
@ -155,6 +180,7 @@ const flowStore = useFlowStore();
const formData = reactive({ const formData = reactive({
nodeParams: [], nodeParams: [],
outputParams: []
}); });
const rules = reactive({}); const rules = reactive({});
@ -166,19 +192,40 @@ const handleTypeChange = (index) => {
} else { } else {
formData.nodeParams[index].input = ""; formData.nodeParams[index].input = "";
const option = getInput(props.model.id); const option = getInput(props.model.id);
console.log('option', option)
if (option) { if (option) {
quoteOptions.value = option; quoteOptions.value = option;
} }
} }
}; };
const dynamicForm = ref(); const cascaderRefs = ref([])
const outputRules = reactive({});
const cascaderChange = (value, index) => {
const selectedOptions = cascaderRefs.value[index].getCheckedNodes(true);
formData.nodeParams[index].quoteType = selectedOptions[0].data.type
}
const addOutputFormItem = () => {
formData.outputParams.push({
name: '',
type: '',
desc: '',
children: []
})
}
const dynamicForm = ref();
const outputFormRef = ref()
const setNodeProperties = async () => { const setNodeProperties = async () => {
try { try {
const result = await dynamicForm.value.validate(); const result = await dynamicForm.value.validate();
console.log(123456)
const test = await outputFormRef.value.validate()
console.log('test', test)
if (result) { if (result) {
const data = toRaw(formData); const data = toRaw(formData);
console.log('data', data)
const properties = lf.getProperties(props.model.id); const properties = lf.getProperties(props.model.id);
lf.setProperties(props.model.id, { lf.setProperties(props.model.id, {
...properties, ...properties,
@ -187,7 +234,7 @@ const setNodeProperties = async () => {
emits("contentChange"); emits("contentChange");
} }
} catch { } catch {
dynamicForm.value.clearValidate(); // dynamicForm.value.clearValidate();
} }
}; };
@ -228,6 +275,24 @@ const addFormItem = () => {
emits("contentChange"); emits("contentChange");
}; };
//
const deleteTopLevelItem = (fullPath) => {
//
let currentLevel = formData.outputParams;
//
for (let i = 0; i < fullPath.length - 1; i++) {
const index = fullPath[i];
//
currentLevel = currentLevel[index].children;
}
//
const lastIndex = fullPath[fullPath.length - 1];
currentLevel.splice(lastIndex, 1);
emits("contentChange");
}
watch( watch(
() => props.properties, () => props.properties,
() => { () => {
@ -238,6 +303,9 @@ watch(
quoteOptions.value = option; quoteOptions.value = option;
} }
} }
if (props.properties.outputParams && props.properties.outputParams.length > 0) {
formData.outputParams = props.properties.outputParams;
}
}, },
{ {
immediate: true, immediate: true,
@ -385,19 +453,33 @@ defineExpose({
height: 32px; height: 32px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between;
.tag { .left {
width: 3px; display: flex;
height: 16px; align-items: center;
background: #1664ff;
border-radius: 0 4px 4px 0; .tag {
margin-right: 12px; width: 3px;
height: 16px;
background: #1664ff;
border-radius: 0 4px 4px 0;
margin-right: 12px;
}
.text {
font-size: 16px;
font-weight: 700;
color: #0c0d0e;
}
} }
.text { .right {
font-size: 16px; .addFormItem {
font-weight: 700; border: none;
color: #0c0d0e; background: transparent;
cursor: pointer;
}
} }
} }
@ -410,15 +492,15 @@ defineExpose({
align-items: end; align-items: end;
.el-input { .el-input {
--el-input-width: 170px; --el-input-width: 120px;
} }
.el-select { .el-select {
--el-select-width: 170px; --el-select-width: 120px;
} }
.el-cascader { .el-cascader {
--el-form-inline-content-width: 170px; --el-form-inline-content-width: 120px;
} }
} }
} }

View File

@ -5,14 +5,14 @@
<div> <div>
<el-form :inline="true" :model="formData" :rules="rules" ref="dynamicForm" label-position="top" label-width="auto" :disabled="flowStore.disableForm"> <el-form :inline="true" :model="formData" :rules="rules" ref="dynamicForm" label-position="top" label-width="auto" :disabled="flowStore.disableForm">
<div v-for="(property, index) in formData.nodeParams" :key="index"> <div v-for="(property, index) in formData.nodeParams" :key="index">
<el-row> <el-row v-if="property.name !== 'loopType'">
<el-form-item :label="index === 0 ? '参数名' : ''" :prop="`nodeParams.${index}.name`" :rules="[{ required: true, message: '请输入参数名', trigger: 'blur' }]"> <el-form-item :label="index === 0 ? '参数名' : ''" :prop="`nodeParams.${index}.name`" :rules="[{ required: true, message: '请输入参数名', trigger: 'blur' }]">
<el-input :disabled="index === 0" v-model="property.name" placeholder="请输入" clearable /> <el-input :disabled="index === 0" v-model="property.name" placeholder="请输入" clearable />
</el-form-item> </el-form-item>
<el-form-item :label="index === 0 ? '参数值' : ''" :prop="`nodeParams.${index}.type`" > <el-form-item :label="index === 0 ? '参数值' : ''" :prop="`nodeParams.${index}.type`" >
<el-select v-model="property.type" @change="handleTypeChange(index)"> <el-select v-model="property.type" @change="handleTypeChange(index)">
<el-option label="引用" value="quote" /> <el-option label="引用" value="quote" />
<el-option label="输入" value="input" /> <el-option label="输入" value="input" />
</el-select> </el-select>
<el-form-item v-if="property.type === 'input'" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.input`"> <el-form-item v-if="property.type === 'input'" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.input`">
<el-input-number v-model="property.input" :min="0" :controls="false" :step-strictly="true" placeholder="请输入" clearable /> <el-input-number v-model="property.input" :min="0" :controls="false" :step-strictly="true" placeholder="请输入" clearable />
@ -22,6 +22,18 @@
</el-form-item> </el-form-item>
</el-form-item> </el-form-item>
</el-row> </el-row>
<el-row v-else>
<el-form-item :label="index === 0 ? '参数名' : ''" :prop="`nodeParams.${index}.name`" :rules="[{ required: true, message: '请输入参数名', trigger: 'blur' }]">
<el-input :disabled="index === 0" v-model="property.name" placeholder="请输入" clearable />
</el-form-item>
<el-form-item :label="index === 0 ? '参数值' : ''" :rules="[{ required: true, message: '请输入参数值', trigger: 'blur' }]" :prop="`nodeParams.${index}.input`" >
<el-select v-model="property.input" @change="handleTypeChange(index)">
<el-option label="普通" value="NORMAL" />
<el-option label="单次和连续" value="MULTIPLE_CORPUS" />
<el-option label="连续多条语料" value="CONTINUOUS_MULTIPLE_CORPUS" />
</el-select>
</el-form-item>
</el-row>
</div> </div>
</el-form> </el-form>
</div> </div>
@ -49,7 +61,8 @@ const props = defineProps({
const flowStore = useFlowStore() const flowStore = useFlowStore()
const formData = reactive({ const formData = reactive({
nodeParams: [ nodeParams: [
{ name: "loopNum", type: "input", input: null, quote: "" } { name: "loopNum", type: "input", input: null, quote: "" },
{ name: "loopType", type: "input", input: 'NORMAL', quote: "" },
] ]
}) })
@ -152,6 +165,7 @@ onMounted(() => {
.group__container { .group__container {
width: 100%; width: 100%;
height: 100%; height: 100%;
min-height: 420px;
background: #fff; background: #fff;
padding: 12px; padding: 12px;
cursor: default; cursor: default;
@ -167,7 +181,7 @@ onMounted(() => {
} }
:deep(.loop__container) { :deep(.loop__container) {
height: 80px; height: auto;
.el-input { .el-input {
width: 92px; width: 92px;
@ -187,7 +201,7 @@ onMounted(() => {
} }
.child__container { .child__container {
min-height: 80px; min-height: 100px;
flex: 1; flex: 1;
background-color: #f6f8fa; background-color: #f6f8fa;
border-radius: 8px; border-radius: 8px;

View File

@ -1,179 +1,262 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> <div ref="topContainerRef">
<el-form-item label="字典名称" prop="dictName"> <el-form
<el-input :model="queryParams"
v-model="queryParams.dictName" ref="queryRef"
placeholder="请输入字典名称" :inline="true"
clearable v-show="showSearch"
style="width: 240px" label-width="68px"
@keyup.enter="handleQuery" >
/> <el-form-item label="字典名称" prop="dictName">
</el-form-item> <el-input
<el-form-item label="字典类型" prop="dictType"> v-model="queryParams.dictName"
<el-input placeholder="请输入字典名称"
v-model="queryParams.dictType" clearable
placeholder="请输入字典类型" style="width: 240px"
clearable @keyup.enter="handleQuery"
style="width: 240px" />
@keyup.enter="handleQuery" </el-form-item>
/> <el-form-item label="字典类型" prop="dictType">
</el-form-item> <el-input
<el-form-item label="状态" prop="status"> v-model="queryParams.dictType"
<el-select placeholder="请输入字典类型"
v-model="queryParams.status" clearable
placeholder="字典状态" style="width: 240px"
clearable @keyup.enter="handleQuery"
style="width: 240px" />
> </el-form-item>
<el-option <el-form-item label="状态" prop="status">
v-for="dict in sys_normal_disable" <el-select
:key="dict.value" v-model="queryParams.status"
:label="dict.label" placeholder="字典状态"
:value="dict.value" clearable
/> style="width: 240px"
</el-select> >
</el-form-item> <el-option
<el-form-item label="创建时间" style="width: 308px"> v-for="dict in sys_normal_disable"
<el-date-picker :key="dict.value"
v-model="dateRange" :label="dict.label"
value-format="YYYY-MM-DD" :value="dict.value"
type="daterange" />
range-separator="-" </el-select>
start-placeholder="开始日期" </el-form-item>
end-placeholder="结束日期" <el-form-item label="创建时间" style="width: 308px">
></el-date-picker> <el-date-picker
</el-form-item> v-model="dateRange"
<el-form-item> value-format="YYYY-MM-DD"
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> type="daterange"
<el-button icon="Refresh" @click="resetQuery">重置</el-button> range-separator="-"
</el-form-item> start-placeholder="开始日期"
</el-form> end-placeholder="结束日期"
></el-date-picker>
</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-row :gutter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="primary" type="primary"
plain plain
icon="Plus" icon="Plus"
@click="handleAdd" @click="handleAdd"
v-hasPermi="['system:dict:add']" v-hasPermi="['system:dict:add']"
>新增</el-button> >新增</el-button
</el-col> >
<el-col :span="1.5"> </el-col>
<el-button <el-col :span="1.5">
type="success" <el-button
plain type="success"
icon="Edit" plain
:disabled="single" icon="Edit"
@click="handleUpdate" :disabled="single"
v-hasPermi="['system:dict:edit']" @click="handleUpdate"
>修改</el-button> v-hasPermi="['system:dict:edit']"
</el-col> >修改</el-button
<el-col :span="1.5"> >
<el-button </el-col>
type="danger" <el-col :span="1.5">
plain <el-button
icon="Delete" type="danger"
:disabled="multiple" plain
@click="handleDelete" icon="Delete"
v-hasPermi="['system:dict:remove']" :disabled="multiple"
>删除</el-button> @click="handleDelete"
</el-col> v-hasPermi="['system:dict:remove']"
<el-col :span="1.5"> >删除</el-button
<el-button >
type="warning" </el-col>
plain <el-col :span="1.5">
icon="Download" <el-button
@click="handleExport" type="warning"
v-hasPermi="['system:dict:export']" plain
>导出</el-button> icon="Download"
</el-col> @click="handleExport"
<el-col :span="1.5"> v-hasPermi="['system:dict:export']"
<el-button >导出</el-button
type="danger" >
plain </el-col>
icon="Refresh" <el-col :span="1.5">
@click="handleRefreshCache" <el-button
v-hasPermi="['system:dict:remove']" type="danger"
>刷新缓存</el-button> plain
</el-col> icon="Refresh"
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> @click="handleRefreshCache"
</el-row> v-hasPermi="['system:dict:remove']"
>刷新缓存</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
</div>
<el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange"> <div :style="containerHeight">
<el-table-column type="selection" width="55" align="center" /> <el-table
<el-table-column label="字典编号" align="center" prop="dictId" /> height="100%"
<el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true"/> v-loading="loading"
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true"> :data="typeList"
<template #default="scope"> @selection-change="handleSelectionChange"
<router-link :to="'/system/dict-data/index/' + scope.row.dictId" class="link-type"> >
<span>{{ scope.row.dictType }}</span> <el-table-column type="selection" width="55" align="center" />
</router-link> <el-table-column label="字典编号" align="center" prop="dictId" />
</template> <el-table-column
</el-table-column> label="字典名称"
<el-table-column label="状态" align="center" prop="status"> align="center"
<template #default="scope"> prop="dictName"
<dict-tag :options="sys_normal_disable" :value="scope.row.status" /> :show-overflow-tooltip="true"
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
<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-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:dict:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:dict: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"
/> />
<el-table-column
label="字典类型"
align="center"
:show-overflow-tooltip="true"
>
<template #default="scope">
<router-link
:to="'/system/dict-data/index/' + scope.row.dictId"
class="link-type"
>
<span>{{ scope.row.dictType }}</span>
</router-link>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
label="备注"
align="center"
prop="remark"
:show-overflow-tooltip="true"
/>
<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-column
label="操作"
align="center"
width="160"
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button
link
type="primary"
icon="Edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:dict:edit']"
>修改</el-button
>
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['system:dict:remove']"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改参数配置对话框 --> <pagination
<el-dialog :title="title" v-model="open" width="500px" append-to-body> v-show="total > 0"
<el-form ref="dictRef" :model="form" :rules="rules" label-width="80px"> :total="total"
<el-form-item label="字典名称" prop="dictName"> v-model:page="queryParams.pageNum"
<el-input v-model="form.dictName" placeholder="请输入字典名称" /> v-model:limit="queryParams.pageSize"
</el-form-item> @pagination="getList"
<el-form-item label="字典类型" prop="dictType"> />
<el-input v-model="form.dictType" placeholder="请输入字典类型" /> </div>
</el-form-item>
<el-form-item label="状态" prop="status"> <!-- 添加或修改参数配置对话框 -->
<el-radio-group v-model="form.status"> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-radio <el-form ref="dictRef" :model="form" :rules="rules" label-width="80px">
v-for="dict in sys_normal_disable" <el-form-item label="字典名称" prop="dictName">
:key="dict.value" <el-input v-model="form.dictName" placeholder="请输入字典名称" />
:value="dict.value" </el-form-item>
>{{ dict.label }}</el-radio> <el-form-item label="字典类型" prop="dictType">
</el-radio-group> <el-input v-model="form.dictType" placeholder="请输入字典类型" />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="状态" prop="status">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input> <el-radio-group v-model="form.status">
</el-form-item> <el-radio
</el-form> v-for="dict in sys_normal_disable"
<template #footer> :key="dict.value"
<div class="dialog-footer"> :value="dict.value"
<el-button type="primary" @click="submitForm"> </el-button> >{{ dict.label }}</el-radio
<el-button @click="cancel"> </el-button> >
</div> </el-radio-group>
</template> </el-form-item>
</el-dialog> <el-form-item label="备注" prop="remark">
</div> <el-input
v-model="form.remark"
type="textarea"
placeholder="请输入内容"
></el-input>
</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>
</div>
</template> </template>
<script setup name="Dict"> <script setup name="Dict">
import useDictStore from '@/store/modules/dict' import useDictStore from "@/store/modules/dict";
import { listType, getType, delType, addType, updateType, refreshCache } from "@/api/system/dict/type"; import {
listType,
getType,
delType,
addType,
updateType,
refreshCache,
} from "@/api/system/dict/type";
import { useContainerHeight } from "@/hooks/tableHeight";
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { sys_normal_disable } = proxy.useDict("sys_normal_disable"); const { sys_normal_disable } = proxy.useDict("sys_normal_disable");
@ -196,11 +279,15 @@ const data = reactive({
pageSize: 10, pageSize: 10,
dictName: undefined, dictName: undefined,
dictType: undefined, dictType: undefined,
status: undefined status: undefined,
}, },
rules: { rules: {
dictName: [{ required: true, message: "字典名称不能为空", trigger: "blur" }], dictName: [
dictType: [{ required: true, message: "字典类型不能为空", trigger: "blur" }] { required: true, message: "字典名称不能为空", trigger: "blur" },
],
dictType: [
{ required: true, message: "字典类型不能为空", trigger: "blur" },
],
}, },
}); });
@ -209,11 +296,13 @@ const { queryParams, form, rules } = toRefs(data);
/** 查询字典类型列表 */ /** 查询字典类型列表 */
function getList() { function getList() {
loading.value = true; loading.value = true;
listType(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => { listType(proxy.addDateRange(queryParams.value, dateRange.value)).then(
typeList.value = response.rows; (response) => {
total.value = response.total; typeList.value = response.rows;
loading.value = false; total.value = response.total;
}); loading.value = false;
}
);
} }
/** 取消按钮 */ /** 取消按钮 */
@ -229,7 +318,7 @@ function reset() {
dictName: undefined, dictName: undefined,
dictType: undefined, dictType: undefined,
status: "0", status: "0",
remark: undefined remark: undefined,
}; };
proxy.resetForm("dictRef"); proxy.resetForm("dictRef");
} }
@ -256,7 +345,7 @@ function handleAdd() {
/** 多选框选中数据 */ /** 多选框选中数据 */
function handleSelectionChange(selection) { function handleSelectionChange(selection) {
ids.value = selection.map(item => item.dictId); ids.value = selection.map((item) => item.dictId);
single.value = selection.length != 1; single.value = selection.length != 1;
multiple.value = !selection.length; multiple.value = !selection.length;
} }
@ -265,7 +354,7 @@ function handleSelectionChange(selection) {
function handleUpdate(row) { function handleUpdate(row) {
reset(); reset();
const dictId = row.dictId || ids.value; const dictId = row.dictId || ids.value;
getType(dictId).then(response => { getType(dictId).then((response) => {
form.value = response.data; form.value = response.data;
open.value = true; open.value = true;
title.value = "修改字典类型"; title.value = "修改字典类型";
@ -274,16 +363,16 @@ function handleUpdate(row) {
/** 提交按钮 */ /** 提交按钮 */
function submitForm() { function submitForm() {
proxy.$refs["dictRef"].validate(valid => { proxy.$refs["dictRef"].validate((valid) => {
if (valid) { if (valid) {
if (form.value.dictId != undefined) { if (form.value.dictId != undefined) {
updateType(form.value).then(response => { updateType(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功"); proxy.$modal.msgSuccess("修改成功");
open.value = false; open.value = false;
getList(); getList();
}); });
} else { } else {
addType(form.value).then(response => { addType(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功"); proxy.$modal.msgSuccess("新增成功");
open.value = false; open.value = false;
getList(); getList();
@ -296,19 +385,27 @@ function submitForm() {
/** 删除按钮操作 */ /** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const dictIds = row.dictId || ids.value; const dictIds = row.dictId || ids.value;
proxy.$modal.confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?').then(function() { proxy.$modal
return delType(dictIds); .confirm('是否确认删除字典编号为"' + dictIds + '"的数据项?')
}).then(() => { .then(function () {
getList(); return delType(dictIds);
proxy.$modal.msgSuccess("删除成功"); })
}).catch(() => {}); .then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
} }
/** 导出按钮操作 */ /** 导出按钮操作 */
function handleExport() { function handleExport() {
proxy.download("system/dict/type/export", { proxy.download(
...queryParams.value "system/dict/type/export",
}, `dict_${new Date().getTime()}.xlsx`); {
...queryParams.value,
},
`dict_${new Date().getTime()}.xlsx`
);
} }
/** 刷新缓存按钮操作 */ /** 刷新缓存按钮操作 */

View File

@ -32,6 +32,13 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" :xxl="6">
<el-form-item label="场景类型" prop="sceneCode">
<el-select v-model="queryParams.sceneCode" clearable placeholder="请选择场景类型">
<el-option v-for="item in sceneList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</template> </template>
</TableSearch> </TableSearch>
@ -225,6 +232,11 @@
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="场景类型" prop="sceneCode">
<el-select v-model="form.sceneCode" placeholder="请输入检测项描述">
<el-option v-for="item in sceneList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input <el-input
v-model="form.remark" v-model="form.remark"
@ -280,6 +292,20 @@ const multiple = ref(true);
const total = ref(0); const total = ref(0);
const title = ref(""); const title = ref("");
const sceneList = [{
label: '普通',
value: 'NORMAL'
},{
label: '语音交互-唤醒场景',
value: 'VI_WAKEUP_CORPUS'
},{
label: '语音交互-单次对话场景',
value: 'VI_SINGLE_CORPUS'
},{
label: '语音交互-连续对话场景',
value: 'VI_CONTINUOUS_CORPUS'
}]
const data = reactive({ const data = reactive({
form: {}, form: {},
queryParams: { queryParams: {

View File

@ -140,7 +140,7 @@
</el-row> </el-row>
</div> </div>
<div :style="containerHeight"> <div :style="containerHeight">
<el-table <el-table
v-loading="loading" v-loading="loading"
height="100%" height="100%"
@ -148,7 +148,7 @@
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目ID" align="center" prop="projectId" /> <el-table-column label="项目ID" align="center" prop="projectId" width="150" show-overflow-tooltip />
<el-table-column label="项目名称" align="center" prop="projectName" width="150" show-overflow-tooltip /> <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="tester" />
<el-table-column <el-table-column
@ -179,6 +179,12 @@
@click="handleSetting(row)" @click="handleSetting(row)"
>配置 >配置
</el-button> </el-button>
<el-button
size="mini"
type="text"
@click="handleExecute(row)"
>执行
</el-button>
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
@ -250,6 +256,14 @@
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item label="排序" prop="sort">
<el-input-number
v-model="form.sort"
placeholder="排序"
/>
</el-form-item>
</el-col>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="项目描述" prop="description"> <el-form-item label="项目描述" prop="description">
<el-input <el-input
@ -524,6 +538,10 @@ const handleSetting = (row) => {
router.push('/vi/plan/index/' + row.projectId) router.push('/vi/plan/index/' + row.projectId)
} }
const handleExecute = (row) => {
console.log('暂未开发')
}
onMounted(() => { onMounted(() => {
getList(); getList();
}); });

View File

@ -8,14 +8,6 @@
v-show="showSearch" v-show="showSearch"
label-width="100px" 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-form-item label="方案名称" prop="schemeName">
<el-input <el-input
v-model="queryParams.schemeName" v-model="queryParams.schemeName"
@ -24,6 +16,14 @@
@keyup.enter="handleQuery" @keyup.enter="handleQuery"
/> />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark">
<el-input
v-model="queryParams.remark"
placeholder="请输入备注"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" <el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button >搜索</el-button
@ -90,9 +90,9 @@
@selection-change="handleSelectionChange" @selection-change="handleSelectionChange"
> >
<el-table-column type="selection" width="55" align="center" /> <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="schemeId" min-width="150" show-overflow-tooltip />
<el-table-column label="所属项目ID" align="center" prop="projectId" /> <el-table-column label="所属项目ID" align="center" prop="projectId" min-width="150" show-overflow-tooltip />
<el-table-column label="方案名称" align="center" prop="schemeName" /> <el-table-column label="方案名称" align="center" prop="schemeName" min-width="150" show-overflow-tooltip />
<el-table-column <el-table-column
label="语料ID列表" label="语料ID列表"
align="center" align="center"
@ -100,11 +100,14 @@
width="300" width="300"
show-overflow-tooltip show-overflow-tooltip
/> />
<el-table-column label="备注" align="center" prop="remark" /> <el-table-column label="排序" align="center" prop="sort" />
<el-table-column label="备注" align="center" prop="remark" min-width="150" show-overflow-tooltip />
<el-table-column <el-table-column
label="操作" label="操作"
align="center" align="center"
class-name="small-padding fixed-width" class-name="small-padding fixed-width"
width="200"
fixed="right"
> >
<template #default="scope"> <template #default="scope">
<el-button <el-button
@ -176,6 +179,9 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="form.sort" :min="0" :step="1" step-strictly />
</el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input <el-input
v-model="form.remark" v-model="form.remark"
@ -248,6 +254,7 @@ const data = reactive({
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
projectId: route.params.id,
schemeName: null, schemeName: null,
corpusIds: null, corpusIds: null,
}, },
@ -340,7 +347,7 @@ function handleUpdate(row) {
function submitForm() { function submitForm() {
proxy.$refs["schemeRef"].validate((valid) => { proxy.$refs["schemeRef"].validate((valid) => {
if (valid) { if (valid) {
if (form.value.sceneType === "1") { if (form.value.sceneType === 1) {
form.value.corpusIds = null; form.value.corpusIds = null;
} else { } else {
if (!form.value?.corpusIds || form.value?.corpusIds?.length === 0) { if (!form.value?.corpusIds || form.value?.corpusIds?.length === 0) {