CMVR-IOT-UI/src/views/vi/testProject/index.vue

729 lines
22 KiB
Vue
Raw Normal View History

2025-09-09 16:37:38 +08:00
<template>
<div class="app-container">
2025-09-11 15:42:24 +08:00
<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>
2025-09-09 16:37:38 +08:00
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
2025-09-11 15:42:24 +08:00
size="mini"
2025-09-09 16:37:38 +08:00
@click="handleAdd"
2025-09-11 15:42:24 +08:00
v-hasPermi="['system:project:add']"
>新增</el-button
>
2025-09-09 16:37:38 +08:00
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
2025-09-11 15:42:24 +08:00
size="mini"
2025-09-09 16:37:38 +08:00
:disabled="single"
@click="handleUpdate"
2025-09-11 15:42:24 +08:00
v-hasPermi="['system:project:edit']"
>修改</el-button
>
2025-09-09 16:37:38 +08:00
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
2025-09-11 15:42:24 +08:00
size="mini"
2025-09-09 16:37:38 +08:00
:disabled="multiple"
@click="handleDelete"
2025-09-11 15:42:24 +08:00
v-hasPermi="['system:project:remove']"
>删除</el-button
>
</el-col>
2025-10-15 16:23:28 +08:00
<!-- <el-col :span="1.5">
2025-09-11 15:42:24 +08:00
<el-button
type="warning"
plain
icon="Download"
size="mini"
@click="handleExport"
v-hasPermi="['system:project:export']"
>导出</el-button
>
2025-10-15 16:23:28 +08:00
</el-col> -->
2025-09-11 15:42:24 +08:00
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
2025-09-09 16:37:38 +08:00
</el-row>
2025-09-11 15:42:24 +08:00
</div>
2025-09-09 16:37:38 +08:00
2025-09-19 14:16:28 +08:00
<div :style="containerHeight">
2025-09-11 15:42:24 +08:00
<el-table
2025-10-24 09:48:24 +08:00
v-loading="loading"
height="100%"
:data="projectList"
@selection-change="handleSelectionChange"
2025-09-11 15:42:24 +08:00
>
2025-10-24 09:48:24 +08:00
<el-table-column type="selection" width="55" align="center" />
<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="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" prop="status">
<template #default="{ row }">
{{ row.status == 0 ? '已执行': '未执行' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="300px" class-name="small-padding fixed-width" fixed="right">
<template #default="{ row }">
<el-button
size="mini"
type="text"
2026-02-04 09:26:00 +08:00
v-if="row.status == 1"
2025-10-24 09:48:24 +08:00
@click="handleSetting(row)"
v-hasPermi="['system:project:add','system:project:edit']"
>配置
</el-button>
<el-button
size="mini"
type="text"
v-if="row.status == 1"
@click="handleExecute(row)"
v-hasPermi="['system:project:add','system:project:edit']"
>执行
</el-button>
<el-button
v-if="row.status == 0"
2026-02-04 09:26:00 +08:00
size="mini"
type="text"
2025-10-24 09:48:24 +08:00
v-hasPermi="['system:project:add','system:project:edit']"
@click="handleOpenDashboard(row)"
>可视化
</el-button>
2026-02-04 09:26:00 +08:00
<el-button
v-if="row.status == 0"
size="mini"
type="text"
v-hasPermi="['system:project:add','system:project:edit']"
@click="handleEvaluate(row)"
>评价
</el-button>
2025-10-24 09:48:24 +08:00
<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>
2025-09-11 15:42:24 +08:00
2025-10-24 09:48:24 +08:00
<pagination
v-show="total > 0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
2025-09-11 15:42:24 +08:00
</div>
2025-09-09 16:37:38 +08:00
<!-- 添加或修改语料库对话框 -->
2025-09-11 15:42:24 +08:00
<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">
2025-09-09 16:37:38 +08:00
<div class="card">
<div class="form-title">项目信息</div>
2025-09-11 15:42:24 +08:00
<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>
2025-09-19 14:16:28 +08:00
<el-col :span="12">
<el-form-item label="排序" prop="sort">
<el-input-number
v-model="form.sort"
placeholder="排序"
/>
</el-form-item>
</el-col>
2026-02-03 17:36:41 +08:00
<el-col :span="12">
<el-form-item label="评价指标" prop="indicatorId">
<el-tree-select
v-model="form.indicatorId"
:data="indicatorData"
:props="{ label: 'name', value: 'id', children: 'children' }"
:render-after-expand="false"
/>
</el-form-item>
</el-col>
2025-09-11 15:42:24 +08:00
<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>
2025-09-09 16:37:38 +08:00
</div>
2025-09-11 15:42:24 +08:00
<div class="card">
2025-09-09 16:37:38 +08:00
<div class="form-title">样品信息</div>
2025-09-11 15:42:24 +08:00
<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">
2026-02-03 17:36:41 +08:00
<el-input v-model="form.entrustUnit" placeholder="请输入委托单位" />
2025-09-11 15:42:24 +08:00
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="生产单位" prop="productionUnit">
2026-02-03 17:36:41 +08:00
<el-input v-model="form.productionUnit" placeholder="请输入生产单位" />
2025-09-11 15:42:24 +08:00
</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>
2025-09-09 16:37:38 +08:00
</div>
</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>
2025-09-25 16:35:06 +08:00
<el-drawer
v-model="openDashboard"
:destroy-on-close="true"
:size="580"
:title="currentLog.projectName + '的流程'"
append-to-body
modal-class="rdashboad-log"
@close="handleClose"
>
<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>
2025-09-09 16:37:38 +08:00
</div>
</template>
2025-09-11 15:42:24 +08:00
<script setup>
import {
listProject,
getProject,
delProject,
addProject,
updateProject,
} from "@/api/vi/project";
import TableSearch from "@/components/TableSearch/index.vue";
import { useContainerHeight } from "@/hooks/tableHeight";
2025-11-27 14:19:52 +08:00
2025-09-25 16:35:06 +08:00
import { getExecuteRunParams, queryExecuteInstId } from "@/api/vi/project.js"
import { appendParamsToPath } from "@/utils/fn.js";
2026-02-03 17:36:41 +08:00
import { getChildrenByParentIdWithLevelLimitApi } from "@/api/evaluate/indicator.js";
2026-02-04 09:26:00 +08:00
import { ElMessage } from "element-plus";
2025-09-11 15:42:24 +08:00
const topContainerRef = ref();
const containerHeight = useContainerHeight(topContainerRef);
2025-09-09 16:37:38 +08:00
2025-09-11 15:42:24 +08:00
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("");
2025-09-09 16:37:38 +08:00
const data = reactive({
2025-09-11 15:42:24 +08:00
form: {},
2025-09-09 16:37:38 +08:00
queryParams: {
pageNum: 1,
pageSize: 10,
2025-09-11 15:42:24 +08:00
projectName: null,
tester: null,
planStart: null,
planEnd: null,
description: null,
sampleName: null,
trademark: null,
modelSpec: null,
quantity: null,
status: null,
2025-09-09 16:37:38 +08:00
},
rules: {
2025-09-11 15:42:24 +08:00
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" }],
},
});
2025-09-09 16:37:38 +08:00
2025-09-11 15:42:24 +08:00
const { queryParams, form, rules } = toRefs(data);
2025-09-09 16:37:38 +08:00
2025-09-11 15:42:24 +08:00
/** 查询语音交互-项目列表 */
2025-09-09 16:37:38 +08:00
function getList() {
2025-09-11 15:42:24 +08:00
loading.value = true;
listProject(queryParams.value).then((response) => {
projectList.value = response.rows;
total.value = response.total;
loading.value = false;
});
2025-09-09 16:37:38 +08:00
}
// 取消按钮
function cancel() {
2025-09-11 15:42:24 +08:00
open.value = false;
reset();
2025-09-09 16:37:38 +08:00
}
// 表单重置
function reset() {
form.value = {
2025-09-11 15:42:24 +08:00
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");
2025-09-09 16:37:38 +08:00
}
/** 搜索按钮操作 */
function handleQuery() {
2025-09-11 15:42:24 +08:00
queryParams.value.pageNum = 1;
getList();
2025-09-09 16:37:38 +08:00
}
/** 重置按钮操作 */
function resetQuery() {
2025-09-11 15:42:24 +08:00
proxy.resetForm("queryRef");
handleQuery();
2025-09-09 16:37:38 +08:00
}
// 多选框选中数据
function handleSelectionChange(selection) {
2025-09-11 15:42:24 +08:00
ids.value = selection.map((item) => item.projectId);
single.value = selection.length != 1;
multiple.value = !selection.length;
2025-09-09 16:37:38 +08:00
}
/** 新增按钮操作 */
function handleAdd() {
2025-09-11 15:42:24 +08:00
reset();
open.value = true;
title.value = "添加测试项目";
2025-09-09 16:37:38 +08:00
}
/** 修改按钮操作 */
function handleUpdate(row) {
2025-09-11 15:42:24 +08:00
reset();
const _projectId = row.projectId || ids.value;
getProject(_projectId).then((response) => {
form.value = response.data;
open.value = true;
title.value = "修改测试项目";
});
2025-09-09 16:37:38 +08:00
}
/** 提交按钮 */
function submitForm() {
2025-09-11 15:42:24 +08:00
proxy.$refs["projectRef"].validate((valid) => {
2025-09-09 16:37:38 +08:00
if (valid) {
2025-09-11 15:42:24 +08:00
if (form.value.projectId != null) {
updateProject(form.value).then((response) => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
2025-09-09 16:37:38 +08:00
} else {
2025-09-11 15:42:24 +08:00
addProject(form.value).then((response) => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
2025-09-09 16:37:38 +08:00
}
}
2025-09-11 15:42:24 +08:00
});
2025-09-09 16:37:38 +08:00
}
/** 删除按钮操作 */
function handleDelete(row) {
2025-09-11 15:42:24 +08:00
const _projectIds = row.projectId || ids.value;
proxy.$modal
.confirm('是否确认删除语音交互-项目编号为"' + _projectIds + '"的数据项?')
.then(function () {
return delProject(_projectIds);
})
.then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
2025-09-09 16:37:38 +08:00
}
/** 导出按钮操作 */
function handleExport() {
2025-09-11 15:42:24 +08:00
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)
2025-09-09 16:37:38 +08:00
}
2026-02-04 09:26:00 +08:00
const handleEvaluate = (row) => {
2025-11-27 14:19:52 +08:00
router.push({
path: "/vi/evaluate/index/" + row.projectId, // 目标路由路径
// 对象序列化为 JSON 字符串(关键)
query: {
data: JSON.stringify(row)
}
})
2025-09-25 16:35:06 +08:00
}
2026-02-04 09:26:00 +08:00
const handleExecute = (row) => {
ElMessage.info('功能开发中。。。')
}
2025-09-25 16:35:06 +08:00
const currentLog = ref({});
const openDashboard = ref(false);
const taskRightList = ref([]);
const lastInstId = ref('')
const handleOpenDashboard = (row) => {
openDashboard.value = true;
currentLog.value = row;
getRightTaskList(row.projectId);
getExecuteInstId(row.projectId)
}
//获取右侧编排数据
const getRightTaskList = (projectId) => {
getExecuteRunParams(projectId).then((response) => {
taskRightList.value =
response.data?.map((item) => {
return {
name: item.schemeName,
id: item.itemId,
};
}) || [];
});
};
const getExecuteInstId = (projectId) => {
queryExecuteInstId(projectId).then((res) => {
console.log('res', res)
lastInstId.value = res.data
})
2025-09-19 14:16:28 +08:00
}
2025-09-25 16:35:06 +08:00
// 取消按钮
function handleClose() {
openDashboard.value = false;
}
const handleLogicFlow = (item) => {
const params = {
instId: lastInstId.value,
taskId: currentLog.value.projectId,
itemId: item.id,
name: item.name,
state: "0",
isLog: true,
};
const fullPath = appendParamsToPath("/flow", params);
window.open(fullPath, "_blank");
};
2026-02-03 17:36:41 +08:00
const indicatorData = ref([]);
const getIndicatorData = () => {
getChildrenByParentIdWithLevelLimitApi(0,2, 0).then((res) => {
if (res.code === 200) {
indicatorData.value = res.data || []
}
})
}
2025-09-09 16:37:38 +08:00
onMounted(() => {
2025-09-11 15:42:24 +08:00
getList();
2026-02-03 17:36:41 +08:00
getIndicatorData();
2025-09-11 15:42:24 +08:00
});
2025-09-09 16:37:38 +08:00
</script>
<style lang="scss" scoped>
2025-09-11 15:42:24 +08:00
:deep() {
.testProject_dialog {
.el-date-editor {
--el-date-editor-width: 100%;
}
2025-09-09 16:37:38 +08:00
2025-09-11 15:42:24 +08:00
.el-input-number {
width: 100%;
}
2025-09-09 16:37:38 +08:00
2025-09-11 15:42:24 +08:00
.card {
padding: 12px;
border: 1px solid #e4e7ed;
border-radius: 8px;
margin-bottom: 20px;
2025-09-09 16:37:38 +08:00
2025-09-11 15:42:24 +08:00
&: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;
}
}
2025-09-09 16:37:38 +08:00
}
}
}
</style>