update code

main
lijun 2024-09-27 23:35:14 +08:00
parent 985c037e7e
commit c4ddbef147
9 changed files with 214 additions and 105 deletions

View File

@ -30,9 +30,21 @@ const addTask = (data) => {
data: data data: data
}) })
} }
//创建推理任务
const stopTask = (id) => {
return request({
url: `/tasks/${id}/stop`,
method: 'post',
data: {
operation_id:0
}
})
}
export default { export default {
tasks, tasks,
availableDevices, availableDevices,
running, running,
addTask addTask,
stopTask
} }

View File

@ -6,7 +6,7 @@ import { TOKEN_KEY } from "@/enums/CacheEnum";
// 创建 axios 实例 // 创建 axios 实例
const service = axios.create({ const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API, baseURL: import.meta.env.VITE_APP_BASE_API,
timeout: 50000, timeout: 5000000,
headers: { "Content-Type": "application/json;charset=utf-8" }, headers: { "Content-Type": "application/json;charset=utf-8" },
}); });

View File

@ -12,11 +12,22 @@
<div style="margin-bottom:100px;" class="card-content"> <div style="margin-bottom:100px;" class="card-content">
<addStep1 ref="step1" v-if="active == 1" /> <addStep1 ref="step1" v-if="active == 1" />
<addStep2 ref="step2" v-if="active == 2" /> <addStep2 ref="step2" v-if="active == 2" />
<addStep3 ref="step3" v-if="active==3" :modelInfo="modelInfo"/> <addStep3 ref="step3" v-if="active == 3" :modelInfo="modelInfo" @change="step3Change" />
<addStep4 ref="step4" v-if="active == 4" :modelInfo="modelInfo" @compile="doCompile" @selection="step4Selection" /> <addStep4 ref="step4" v-if="active == 4" :modelInfo="modelInfo" @compile="doCompile"
<addStep5 ref="step5" v-if="active == 5" /> @selection="step4Selection" />
<addStep5 ref="step5" v-if="active == 5" @change="step5Change" />
</div> </div>
<el-card class="card-footer"> <el-card class="card-footer">
<el-button type="primary" v-if="active > 0 && active < 4 && active != 4" @click="doPrev"></el-button>
<template v-if="(active == 4 && (state == 0 || state == 3)) || (active == 5 && state == 0)">
<el-button type="primary" @click="doPrev"></el-button>
</template>
<template v-if="active == 4 && (state == 3 || state == 0)">
<el-button @click="doNext"></el-button>
</template>
<el-button @click="doNext" v-if="active < 4"></el-button>
<!-- <!--
<el-button type="primary" v-if="active == 3 && state == 0" @click="doCompile"></el-button>--> <el-button type="primary" v-if="active == 3 && state == 0" @click="doCompile"></el-button>-->
<el-button type="primary" v-if="active == 4 && state == 1" loading disabled>编译中...</el-button> <el-button type="primary" v-if="active == 4 && state == 1" loading disabled>编译中...</el-button>
@ -24,14 +35,7 @@
<el-button type="primary" v-if="active == 5" @click="doStart" :loading="state > 0" :disabled="state > 0">{{ state <el-button type="primary" v-if="active == 5" @click="doStart" :loading="state > 0" :disabled="state > 0">{{ state
== ==
0 ? "开始推理" : "推理中..." }}</el-button> 0 ? "开始推理" : "推理中..." }}</el-button>
<el-button type="primary" v-if="active > 0 && active < 4 && active != 4" @click="doPrev"></el-button>
<template v-if="(active == 4 && (state == 0 || state == 3)) || (active == 5 && state == 0)">
<el-button type="primary" @click="doPrev"></el-button>
</template>
<template v-if="active == 4 && (state == 3||state==0)">
<el-button @click="doNext"></el-button>
</template>
<el-button @click="doNext" v-if="active < 4"></el-button>
</el-card> </el-card>
</div> </div>
</template> </template>
@ -64,8 +68,8 @@ let info = reactive({
datas: null, datas: null,
taskId: 0, taskId: 0,
inferenceId: 0, inferenceId: 0,
parameters:'', parameters: '',
latestTime:'', latestTime: '',
}) })
// //
const doStart = () => { const doStart = () => {
@ -87,10 +91,10 @@ const doAddTask = () => {
model_id: modelInfo.model_id, model_id: modelInfo.model_id,
connection_id: modelInfo.connection_id, connection_id: modelInfo.connection_id,
data_set_id: info.datas.dataset_id, data_set_id: info.datas.dataset_id,
task_params: info.parameters, task_params: info.parameters || {},
device_id:info.devices.device_id, device_id: info.devices.device_id,
tool_params_id:info.devices.tool_params_id, tool_params_id: info.devices.tool_params_id,
tool_id:info.devices.tool_id tool_id: info.devices.tool_id
} }
taskApi.addTask(postData).then(d => { taskApi.addTask(postData).then(d => {
info.taskId = d.data?.data?.task_id || 0; info.taskId = d.data?.data?.task_id || 0;
@ -99,19 +103,26 @@ const doAddTask = () => {
}; };
// //
const startInference = (d) => { const startInference = (d) => {
// //
info.inferenceId = d.data?.data?.operation_id || 0; info.inferenceId = d.data?.data?.operation_id || 0;
if (info.inferenceId > 0) { if (info.inferenceId > 0) {
ElMessage.success("创建推理任务成功!"); ElMessage.success("创建推理任务成功!");
setTimeout(() => { setTimeout(() => {
router.push({ path: "/simulationEvaluation/execution" }); router.push({ path: "/simulationEvaluation/execution" });
}, 1000); }, 1000);
} }
} }
const step4Selection=row=>{ const step5Change = () => {
info.devices=row; let tmp = step5.value.checkForm();
state.value=3; info.datas = tmp;
}
function step3Change(data) {
info.parameters = data || "";
}
const step4Selection = () => {
let tmp = step4.value.checkForm();
info.devices = tmp;
} }
const doCompile = (row) => { const doCompile = (row) => {
let tmp = row; let tmp = row;
@ -120,19 +131,18 @@ const doCompile = (row) => {
state.value = 1; state.value = 1;
step4.value.updateState(state.value); step4.value.updateState(state.value);
startComplie();// startComplie();//
//ElMessage.success("!");
} else { } else {
ElMessage.error("请选择设备!"); ElMessage.error("请选择设备!");
} }
} }
// //
const startComplie = () => { const startComplie = () => {
let ajaxs =[ inferenceApi.doCompile({ let ajaxs = [inferenceApi.doCompile({
tool_params_id: info.devices.tool_params_id, tool_params_id: info.devices.tool_params_id,
tool_id: info.devices.tool_id, tool_id: info.devices.tool_id,
device_id: info.devices.device_id, device_id: info.devices.device_id,
connection_id: modelInfo.connection_id connection_id: modelInfo.connection_id
}) })
]; ];
addLogs({ msg: "开始部署....", type: "info" }) addLogs({ msg: "开始部署....", type: "info" })
request.all(ajaxs).then(d => { request.all(ajaxs).then(d => {
@ -147,21 +157,23 @@ const startComplie = () => {
}; };
const addLogs = msg => { const addLogs = msg => {
info.logs = [msg, ...info.logs]; if (info.logs.length == 0 || info.logs[0].msg != msg.msg) {
step4.value.updateLogs(info.logs); info.logs = [msg, ...info.logs];
step4.value.updateLogs(info.logs);
}
} }
// //
const doGetComplieLogs = () => { const doGetComplieLogs = () => {
let ajaxs = []; let ajaxs = [];
info.optIds.filter(d => d.state == 0).forEach(o => { info.optIds.filter(d => d.state == 0).forEach(o => {
ajaxs.push(logsApi.userOperation(o.id)); ajaxs.push(logsApi.userOperation(o.id));
ajaxs.push(logsApi.compileDeploy(o.id,info.latestTime)); ajaxs.push(logsApi.compileDeploy(o.id, info.latestTime));
}) })
request.all(ajaxs).then(d => { request.all(ajaxs).then(d => {
d.forEach((it, idx) => { d.forEach((it, idx) => {
let msg = it.data.data; let msg = it.data.data;
info.latestTime=msg.update_time;//'2023-03-01T12:00:00Z';//new Date().toLocaleString(); info.latestTime = msg.update_time;//'2023-03-01T12:00:00Z';//new Date().toLocaleString();
if (msg.operation_result) { if (msg.operation_result) {
addLogs({ msg: msg.operation_result }); addLogs({ msg: msg.operation_result });
info.optIds[idx].state = msg.operation_finished ? 1 : 0; info.optIds[idx].state = msg.operation_finished ? 1 : 0;
@ -180,30 +192,36 @@ const doGetComplieLogs = () => {
} }
const doPrev = () => { const doPrev = () => {
active.value--; active.value--;
if (active.value == 4) { if (active.value == 4) {
state.value = 0; state.value = 0;
info.logs = []; info.logs = [];
info.optIds = []; info.optIds = [];
}else if(active.value==3){ setTimeout(() => {
setTimeout(()=>{ if (info.devices) {
if(info.parameters){ step4.value.returnData(info.devices);
}
}, 400);
} else if (active.value == 3) {
setTimeout(() => {
if (info.parameters) {
step3.value.returnData(info.parameters); step3.value.returnData(info.parameters);
} }
},400); }, 400);
}else if(active.value==2){ } else if (active.value == 2) {
setTimeout(()=>{ setTimeout(() => {
if(modelInfo){ if (modelInfo) {
step2.value.returnData(modelInfo); step2.value.returnData(modelInfo);
} }
},400); }, 400);
}else if(active.value==1){ } else if (active.value == 1) {
setTimeout(()=>{ setTimeout(() => {
if(info.taskInfo){ if (info.taskInfo) {
step1.value.returnData(info.taskInfo); step1.value.returnData(info.taskInfo);
} }
},400); }, 400);
} }
} }
const doNext = () => { const doNext = () => {
@ -222,22 +240,33 @@ const doNext = () => {
info.logs = []; info.logs = [];
info.optIds = []; info.optIds = [];
active.value++; active.value++;
setTimeout(() => {
if (info.parameters) {
step3.value.returnData(info.parameters);
}
}, 400);
} else { } else {
ElMessage.error("请选择模型!"); ElMessage.error("请选择模型!");
} }
} else if (active.value == 3) { } else if (active.value == 3) {
let tmp = step3.value.checkForm(); active.value++;
if (tmp) { setTimeout(() => {
info.parameters=JSON.stringify(tmp); if (info.devices) {
active.value++; step4.value.returnData(info.devices);
} }
}, 400);
} else if (active.value == 4) { } else if (active.value == 4) {
let tmp=step4.value.checkForm(); let tmp = step4.value.checkForm();
if(tmp){ if (tmp) {
active.value++; active.value++;
info.devices=tmp; info.devices = tmp;
state.value = 0; state.value = 0;
}else{ setTimeout(() => {
if (info.datas) {
step5.value.returnData(info.datas);
}
}, 400);
} else {
ElMessage.error("请选择设备!"); ElMessage.error("请选择设备!");
} }
@ -247,6 +276,10 @@ const doNext = () => {
active.value++; active.value++;
} }
} }
onMounted(() => {
window.toolCahce = {}
})
</script> </script>
<style lang='scss'> <style lang='scss'>
.simulation-add-task { .simulation-add-task {

View File

@ -1,6 +1,11 @@
<template> <template>
<el-card style="margin-top:12px" class="simulation-add-add-step2"> <el-card style="margin-top:12px" class="simulation-add-add-step2">
<template #header>模型列表</template> <template #header>
<div style="position: relative;width:100%;">
模型列表
<el-button style="position: absolute;right:10px;top:-4px;" type="primary" @click="doRefresh"></el-button>
</div>
</template>
<el-table v-loading="loading" :data="info.data" stripe @row-click="doRowClick"> <el-table v-loading="loading" :data="info.data" stripe @row-click="doRowClick">
<el-table-column align="center" width="55" label="选择"> <el-table-column align="center" width="55" label="选择">
<template #default="scope"> <template #default="scope">
@ -43,6 +48,10 @@ const handleChange = (row) => {
const doRowClick = (row) => { const doRowClick = (row) => {
modelSelection.value = row.id + ""; modelSelection.value = row.id + "";
} }
//
function doRefresh(){
handleQuery();
}
/** 查询 */ /** 查询 */
function handleQuery(a) { function handleQuery(a) {
if (a) { if (a) {

View File

@ -41,6 +41,7 @@
<script setup> <script setup>
import 'jsoneditor' import 'jsoneditor'
import JsonEditorVue from 'json-editor-vue3' import JsonEditorVue from 'json-editor-vue3'
const emit = defineEmits(["change"]);
const info = reactive({ const info = reactive({
jsonData: {}, jsonData: {},
file: null file: null
@ -71,9 +72,11 @@ function handleFileChange(file) {
type: "warning", type: "warning",
}).then(function () { }).then(function () {
info.jsonData = JSON.parse(res); info.jsonData = JSON.parse(res);
emit("change",info.jsonData)
}); });
} else { } else {
info.jsonData = JSON.parse(res); info.jsonData = JSON.parse(res);
emit("change",info.jsonData)
} }
info.file = file; info.file = file;
uploadRef.value.clearFiles(); uploadRef.value.clearFiles();
@ -128,8 +131,8 @@ function checkForm() {
} }
const returnData = (d) => { const returnData = (d) => {
if(d && isJSON(d,false)){ if(d){
info.jsonData=JSON.parse(d); info.jsonData=d;
info.file=true; info.file=true;
} }
} }

View File

@ -32,8 +32,7 @@
</el-form-item> </el-form-item>
</el-form> </el-form>
</template> </template>
<el-table v-loading="loading" ref="dataTb" :data="info.tableData" stripe @row-click="doRowClick">
<el-table v-loading="loading" ref="dataTb" :data="info.tableData" stripe @row-click="doRowClick">
<el-table-column width="55" > <el-table-column width="55" >
<template #default="scope"> <template #default="scope">
<el-radio v-model="modelSelection" :label="scope.row.id + ''" :disabled="scope.row.working_state!='idle'" <el-radio v-model="modelSelection" :label="scope.row.id + ''" :disabled="scope.row.working_state!='idle'"
@ -115,16 +114,18 @@ const handleChange = (row) => {
if (!row.tool_params_id) { if (!row.tool_params_id) {
ElMessage.error("请选择工具链运行参数列表!"); ElMessage.error("请选择工具链运行参数列表!");
modelSelection.value=""; modelSelection.value="";
emit("selection")
return; return;
} }
modelSelection.value = row.device_id + ""; modelSelection.value = row.device_id + "";
emit("selection")
} }
const info = reactive({ const info = reactive({
tableData: [], tableData: [],
state: 0, state: 0,
logs: [], logs: [],
editItem: null, editItem: null
}); });
const doCompile = (row) => { const doCompile = (row) => {
if (!row.tool_params_id) { if (!row.tool_params_id) {
@ -140,6 +141,10 @@ const doChoice = row => {
const doChoiceSuccess = item => { const doChoiceSuccess = item => {
info.editItem.tool_params_id = item.params_id info.editItem.tool_params_id = item.params_id
info.editItem.tool_params_name = item.params_name info.editItem.tool_params_name = item.params_name
window.toolCahce['d_'+info.editItem.device_id]={
params_id:item.params_id,
params_name:item.params_name
}
} }
/** 查询 */ /** 查询 */
function handleQuery() { function handleQuery() {
@ -155,6 +160,12 @@ function handleQuery() {
info.tableData = (d.data.data.available_device_list || []).map((it) => { info.tableData = (d.data.data.available_device_list || []).map((it) => {
it.id = it.device_id; it.id = it.device_id;
it.checked = false; it.checked = false;
let key="d_"+it.device_id;
let o=window.toolCahce[key];
if(o){
it.tool_params_id=it.tool_params_id||o.params_id;
it.tool_params_name=it.tool_params_name||o.params_name;
}
return it; return it;
}); });
}); });
@ -174,7 +185,11 @@ const updateState = (s) => {
const updateLogs = (logs) => { const updateLogs = (logs) => {
info.logs = logs; info.logs = logs;
}; };
const returnData = (d) => {
if(d){
modelSelection.value=""+d.device_id
}
}
onMounted(() => { onMounted(() => {
handleQuery(); handleQuery();
}); });
@ -182,6 +197,7 @@ defineExpose({
checkForm, checkForm,
updateState, updateState,
updateLogs, updateLogs,
returnData
}); });
</script> </script>

View File

@ -39,6 +39,7 @@ import dataSetApi from '@/api/dataSet'
const datasSelection = ref("")//id const datasSelection = ref("")//id
const loading = ref(false) const loading = ref(false)
const queryFormRef = ref() const queryFormRef = ref()
const emit = defineEmits(["change"]);
const queryParams = reactive({ const queryParams = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
@ -66,9 +67,11 @@ function handleQuery(a) {
const handleChange = (row) => { const handleChange = (row) => {
datasSelection.value = row.dataset_id + ""; datasSelection.value = row.dataset_id + "";
emit("change")
} }
const doRowClick = (row, col, sel) => { const doRowClick = (row, col, sel) => {
datasSelection.value = row.dataset_id + ""; datasSelection.value = row.dataset_id + "";
emit("change")
} }
@ -79,11 +82,18 @@ const checkForm = () => {
} }
return null; return null;
}; };
const returnData = (d) => {
if(d){
datasSelection.value=""+d.dataset_id
}
}
onMounted(() => { onMounted(() => {
handleQuery(); handleQuery();
}); });
defineExpose({ defineExpose({
checkForm checkForm,
returnData
}) })
</script> </script>
<style lang='scss'></style> <style lang='scss'></style>

View File

@ -1,21 +1,24 @@
<template> <template>
<div class="app-container simulation-execution"> <div class="app-container simulation-execution">
<el-card> <el-card>
<div style="text-align: right;margin-bottom: 10px;">
<el-button type="primary" @click="doRefresh"></el-button>
</div>
<el-table v-loading="loading" ref="dataTb" :data="info.dataList" stripe height="400px"> <el-table v-loading="loading" ref="dataTb" :data="info.dataList" stripe height="400px">
<el-table-column label="推理任务名称" align="left" prop="task_name" /> <el-table-column label="推理任务名称" align="left" prop="task_name" />
<el-table-column label="模型名称" align="left" prop="model_name" /> <el-table-column label="模型名称" align="left" prop="model_name" />
<el-table-column label="模型类型" align="left" prop="modl_net_type" /> <el-table-column label="模型类型" align="left" prop="modl_net_type" />
<el-table-column label="互联名称" align="left" prop="connection_name" /> <el-table-column label="互联名称" align="left" prop="connection_name" />
<el-table-column label="推理数据集名称" align="left" prop="data_set_name" /> <el-table-column label="推理数据集名称" align="left" prop="dataset_name" />
<el-table-column label="推理设备名称" align="left" prop="device_name" /> <el-table-column label="推理设备名称" align="left" prop="device_name" />
<el-table-column label="运行状态" fixed="right" align="center" width="120" v-if="1 == 2"> <el-table-column label="运行状态" fixed="right" align="center" width="120" v-if="1 == 2">
<template #default="scope"> <template #default="scope">
<span :class="'run-state state-' + scope.row.state">{{ scope.row.state == 1 ? '完成' : '推理中' }}</span> <span :class="'run-state state-' + scope.row.state">{{ scope.row.state == 1 ? '完成' : '推理中' }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="120" v-if="1 == 2"> <el-table-column label="操作" fixed="right" align="center" width="120" >
<template #default="scope"> <template #default="scope">
<el-button text type="primary"> <el-button text type="primary" @click="doStopTask(scope.row)">
<i-ep-circle-close />&nbsp;终止推理</el-button> <i-ep-circle-close />&nbsp;终止推理</el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -26,9 +29,14 @@
</el-card> </el-card>
<div style="margin-top:30px;font-size:12px;font-weight: bold;margin-left:8px;">推理日志</div> <div style="margin-top:30px;font-size:12px;font-weight: bold;margin-left:8px;">推理日志</div>
<el-card class="split-log"> <el-card class="split-log">
<div v-for="(it, idx) in logList" :key="idx" class="log-item"> <div v-for="(it, idx) in info.logs" :key="idx" class="log-item" :style="'color:'+it.color">
<span>{{ it.date }}</span> <span>[{{ it.logs_level }}]</span>
<span>{{ it.log }}</span> <span>[{{ it.logs_time }}]</span>
<span>{{ it.taskName }} - </span>
<span>{{ it.logs_content }}</span>
</div>
<div v-if="!info.logs || info.logs.length==0">
暂无日志
</div> </div>
</el-card> </el-card>
</div> </div>
@ -64,40 +72,58 @@ const loadLogs = () => {
}); });
request.all(ajaxs).then(d => { request.all(ajaxs).then(d => {
d.forEach(res=>{ d.forEach(res=>{
let logs=res.data?.data?.latest_log_list||[]; let logs=(res.data?.data?.latest_log_list||[]).map(log=>{
logs.forEach(log=>{ let tasks=info.dataList.filter(d=>d.task_id==log.task_id);
logList.push(log); let task=tasks.length>0?tasks[0]:{}
}); log.taskName=task.task_name||"";
log.color=task.color;
if(info.logs.filter(it=>it.task_id==log.task_id && it.logs_content==log.logs_content).length>0){
log.taskName="";
}
return log.taskName?log:"";
}).filter(log=>log);
info.logs=[...logs,...info.logs];
}); });
setTimeout(loadLogs,3000);
}); });
}; };
//
const loadFirstLogs=()=>{ //
let dt=useDateFormat(new Date(),"YYYY-MM-DDTHH:mm:ssZ").value function doRefresh(){
let ajaxs = info.dataList.filter(it => it.state == 0).map(it => { loadData(true)
return LogsApi.inferenceTask(it.task_id,it.device_id,dt) }
}); //
request.all(ajaxs).then(d => { function doStopTask(row){
d.forEach(res=>{ ElMessageBox.confirm("确定要终止任务["+row.task_name+"]", "提示", {
let logs=res.data?.data?.latest_log_list||[]; confirmButtonText: "确定",
logs.forEach(log=>{ cancelButtonText: "取消",
logList.push(log); type: "warning",
}); lockScroll: false,
}).then(() => {
TaskApi.stopTask(row.task_id).then(d=>{
if(d.data.code==0){
ElMessage.success("终止任务["+row.task_name+"]成功!");
setTimeout(doRefresh,5000);
}else{
ElMessage.error("终止任务["+row.task_name+"]失败!");
}
}); });
setTimeout(()=>{
loadLogs();
},2000);
}); });
};
const loadData = () => { }
//
const loadData = (onlyRefresh) => {
loading.value = true; loading.value = true;
TaskApi.running().then(d => { TaskApi.running().then(d => {
loading.value = false; loading.value = false;
info.dataList = (d.data.data.running_task_list || []).map(it => { info.dataList = (d.data.data.running_task_list || []).map((it,idx) => {
it.color="#000000,#0000FF,#8A2BE2,#A52A2A,#DEB887,#5F9EA0,#7FFF00,#D2691E,#FF7F50,#6495ED".split(",")[idx%10];
it.state = 0; it.state = 0;
return it; return it;
}); });
loadFirstLogs(); if(!onlyRefresh){
loadLogs();
}
}); });
} }
onMounted(loadData); onMounted(loadData);

View File

@ -19,10 +19,10 @@
<el-table-column label="任务名称" align="left" prop="task_name" /> <el-table-column label="任务名称" align="left" prop="task_name" />
<el-table-column label="任务说明" align="left" prop="task_desc" /> <el-table-column label="任务说明" align="left" prop="task_desc" />
<el-table-column label="使用数据集" align="left" prop="dataset_name" /> <el-table-column label="使用数据集" align="left" prop="dataset_name" />
<el-table-column label="运行模型" align="left" prop="model_name" width="120" /> <el-table-column label="运行模型" align="left" prop="model_name" />
<el-table-column label="模型网络" align="left" prop="modl_net_type" width="120" /> <el-table-column label="模型网络" align="left" prop="modl_net_type" />
<el-table-column label="创建时间" align="left" prop="create_time" width="120" /> <el-table-column label="创建时间" align="left" prop="create_time" width="160" />
<el-table-column label="完成时间" align="left" prop="finish_time" width="120" /> <el-table-column label="完成时间" align="left" prop="finish_time" width="160" />
<el-table-column label="操作" fixed="right" align="center" width="200" v-if="1==2"> <el-table-column label="操作" fixed="right" align="center" width="200" v-if="1==2">
<template #default="scope"> <template #default="scope">
<el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-view />查看报告</el-button> <el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-view />查看报告</el-button>