update code

main
haha 2024-07-26 22:56:44 +08:00
parent 1b6dca100a
commit 3da7053984
11 changed files with 2122 additions and 1035 deletions

View File

@ -54,6 +54,7 @@
"color": "^4.2.3", "color": "^4.2.3",
"echarts": "^5.5.0", "echarts": "^5.5.0",
"element-plus": "^2.7.2", "element-plus": "^2.7.2",
"js-md5": "^0.8.3",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"net": "^1.0.2", "net": "^1.0.2",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",

View File

@ -1 +1,57 @@
function init(){var s=location.search;var url="";var onnxModelName="";if(s.indexOf("=")>=0){url=s.substring(s.indexOf("=")+1);if(url.toLocaleLowerCase().indexOf(".onnx")>=0){onnxModelName=url.substring(url.lastIndexOf("/")+1)}else{console.error("使用方法:onnx.html?url=[onnx路径]");return}}else{console.error("使用方法:onnx.html?url=[onnx路径]");return}document.body.title=onnxModelName;var http=new XMLHttpRequest;http.responseType="arraybuffer";http.open("GET",url);http.onload=function(){if(http.status==200){var reader=proto.protobuf.Reader.create(new Uint8Array(http.response));var onnxProtoModel=window.proto.onnx.ModelProto.decode(reader);let{locations,graphs}=window.getExternalLocations(onnxProtoModel);let model=new window.onnx.Model(onnxProtoModel,graphs,new Map);let host=window;let view=new window.View(host);view.start().then(data=>{view.open(model,onnxModelName)}).catch(err=>{console.log(err)});window.mainView=view}};http.send()}function exportImg(file,blob){const element=this.document.createElement("a");element.download=file;element.href=URL.createObjectURL(blob);this.document.body.appendChild(element);element.click();this.document.body.removeChild(element)}function toggleMenu(){let el=document.getElementById("menu");if(el.style.display=="none"){el.style.display="block";updateState()}else{el.style.display="none"}}function doToggle(att){mainView.toggle(att);updateState()}function updateState(){var op=mainView.options;document.getElementById("opAtt").innerText=op.attributes?"Hide Attributes":"Show Attributes";document.getElementById("opWeight").innerText=op.weights?"Hide Weights":"Show Weights";document.getElementById("opName").innerText=op.names?"Hide Names":"Show Names";document.getElementById("opDir").innerText=op.direction=="vertical"?"Show Horizontal":"Show Vertical";document.getElementById("opMouse").innerText=op.mousewheel=="scroll"?"Mouse Wheel: Zoom":"Mouse Wheel: Scroll"}init(); function init() {
var s = location.search;
var url = "";
var onnxModelName = "";
if (s.indexOf("=") >= 0) {
url = s.substring(s.indexOf("=") + 1);
} else {
console.error("使用方法:onnx.html?id=[模型ID]")
return;
}
document.body.title = onnxModelName;
var accessToken = localStorage.getItem("accessToken");
var http = new XMLHttpRequest();
http.responseType = "json"
http.open('GET', MODELDOWNLOADAPI + `${url}/download`);
http.setRequestHeader("Authorization", accessToken);
http.onload = function () {
if (http.status == 200) {
var reader = proto.protobuf.Reader.create(base64ToUint8Array(http.response.data.file_content));
var onnxProtoModel = window.proto.onnx.ModelProto.decode(reader);
let { locations, graphs } = window.getExternalLocations(onnxProtoModel);
let model = new window.onnx.Model(onnxProtoModel, graphs, new Map());
let host = window;
let view = new window.View(host);
view.start().then((data) => {
view.open(model, onnxModelName);
}).catch((err) => {
console.log(err);
})
window.mainView = view;
}
};
http.send();
}
function base64ToUint8Array(base64String) {
try {
let padding = '='.repeat((4 - base64String.length % 4) % 4);
let base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
let rawData = atob(base64);
let outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
catch (e) {
throw e;
}
}
init();

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,37 @@
import request from "@/utils/request"; import request from "@/utils/request";
//获取任务列表 //获取任务列表
const tasks=()=>{ const tasks = () => {
return request({ return request({
url:'/tasks', url: '/tasks',
method:'get' method: 'get'
}) })
} }
//获取可用的设备状态 //获取可用的设备状态
const availableDevices=()=>{ const availableDevices = (data) => {
return request({ return request({
url:'/tasks/available_devices', url: '/tasks/available_devices',
method:'get' method: 'get',
}) params: data
})
} }
//获取正在执行的任务 //获取正在执行的任务
const running=()=>{ const running = () => {
return request({ return request({
url:'/tasks/running', url: '/tasks/running',
method:'get' method: 'get'
}) })
} }
//创建推理任务 //创建推理任务
const addTask=(data)=>{ const addTask = (data) => {
return request({ return request({
url:'/tasks', url: '/tasks',
method: 'post', method: 'post',
data:data data: data
}) })
} }
export default{ export default {
tasks, tasks,
availableDevices, availableDevices,
running, running,
addTask addTask
} }

View File

@ -1,128 +1,126 @@
<template> <template>
<div class="app-container connection-detail"> <div class="app-container connection-detail">
<el-card> <el-card>
<template #header> <template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" /> <svg-icon icon-class="pause" style="width:20px;height:20px;" />
互联协议信息</template> 互联协议信息</template>
<table style="width:100%" class="tb-base-info"> <table style="width:100%" class="tb-base-info">
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">模型名称:</span> <span class="sp-title">模型名称:</span>
<span class="sp-text">{{ info.data.model_name }}</span> <span class="sp-text">{{ info.data.model_name }}</span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">模型版本:</span> <span class="sp-title">模型版本:</span>
<span class="sp-text">{{ info.data.connection_version }}</span> <span class="sp-text">{{ info.data.connection_version }}</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">互联名称:</span> <span class="sp-title">互联名称:</span>
<span class="sp-text">{{ info.data.connection_name }}</span> <span class="sp-text">{{ info.data.connection_name }}</span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">标签:</span> <span class="sp-title">标签:</span>
<span class="sp-text">{{ info.data.connection_label }}</span> <span class="sp-text">{{ info.data.connection_label }}</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">创建用户:</span> <span class="sp-title">创建用户:</span>
<span class="sp-text">{{ info.data.user_name }}</span> <span class="sp-text">{{ info.data.user_name }}</span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">创建时间:</span> <span class="sp-title">创建时间:</span>
<span class="sp-text">{{ info.data.create_time }}</span> <span class="sp-text">{{ info.data.create_time }}</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 100%;" colspan="2"> <td style="width: 100%;" colspan="2">
<span class="sp-title">互联说明:</span> <span class="sp-title">互联说明:</span>
<span class="sp-text">{{ info.data.connection_desc }}</span> <span class="sp-text">{{ info.data.connection_desc }}</span>
</td> </td>
</tr> </tr>
</table> </table>
</el-card> </el-card>
<el-card style="margin-top: 12px;margin-bottom: 60px;"> <el-card style="margin-top: 12px;margin-bottom: 60px;">
<template #header> <template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" /> <svg-icon icon-class="pause" style="width:20px;height:20px;" />
算子互联信息</template> 算子互联信息</template>
<div class="detail-content" style="position: relative;"> <div class="detail-content" style="position: relative;">
<detailFlow ref="operFlow" @nodeClick="doNodeClick" /> <detailFlow ref="operFlow" @nodeClick="doNodeClick" />
<div class="item" v-if="1 == 2"> <div class="item" v-if="1 == 2">
<div class="div-title"> <div class="div-title">
<i-ep-setting /><span>互联设置</span> <i-ep-setting /><span>互联设置</span>
</div> </div>
<div class="div-chart"> <div class="div-chart">
</div> </div>
</div> </div>
<div class="item node-info" style="margin-left: 100px;" v-if="info.selNode"> <div class="item node-info" style="margin-left: 100px;" v-if="info.selNode">
<div class="div-title"> <div class="div-title">
<i-ep-document /><span>算子基本信息</span> <i-ep-document /><span>算子基本信息</span>
</div> </div>
<div class="div-info"> <div class="div-info">
<div class="row"> <div class="row">
<span class="sp-label">算子名称:</span> <span class="sp-label">算子名称:</span>
<span class="sp-text">{{ info.selNode.operator_name }}</span> <span class="sp-text">{{ info.selNode.operator_name }}</span>
</div>
<div class="row">
<span class="sp-label">算子版本:</span>
<span class="sp-text">{{ info.selNode.operator_version }}</span>
</div>
<div class="row">
<span class="sp-label">算子说明:</span>
<span class="sp-text">{{ info.selNode.operator_desc }}</span>
</div>
<div class="row" v-if="info.param.inputs.length > 0">
<span class="sp-label">输入参数:</span>
<div class="div-param">
<div v-if="info.param.inputs.length > 1" class="div-navs">
<span v-for="(it, idx) in info.param.inputs" @click="doInputSelected(idx)" :key="idx"
class="sp-nav" :class="it.selected ? 'active' : ''">{{ it.input_id }}</span>
</div>
<span class="sp-text sp-paramter scroll">
<span v-for="(it, idx) in info.param.inputs " :key="idx" v-show="it.selected"
class="param-item">
<paramShow :paramInfo="it"></paramShow>
</span>
</span>
</div>
</div>
<div class="row" style="margin-top:4px;" v-if="info.param && info.param.outputs">
<span class="sp-label">输出参数:</span>
<div class="div-param">
<div v-if="info.param.outputs.length > 1" class="div-navs">
<span v-for="(it, idx) in info.param.outputs" @click="doOutputSelected(idx)"
:key="idx" class="sp-nav" :class="it.selected ? 'active' : ''">{{ it.output_id
}}</span>
</div>
<span class="sp-text sp-paramter scroll">
<span v-for="(it, idx) in info.param.outputs " :key="idx" v-show="it.selected"
class="param-item">
<paramShow :paramInfo="it"></paramShow>
</span>
</span>
</div>
</div>
<div class="row" style="margin-top:4px;" v-if="info.param && info.param.process">
<span class="sp-label">处理参数:</span>
<span class="sp-text sp-paramter scroll" v-if="info.param.process">
<paramShow :paramInfo="info.param.process"></paramShow>
</span>
</div>
</div>
</div>
</div> </div>
</el-card> <div class="row">
<el-card class="card-footer"> <span class="sp-label">算子版本:</span>
<el-button type="primary" @click="doBack"></el-button> <span class="sp-text">{{ info.selNode.operator_version }}</span>
</el-card> </div>
</div> <div class="row">
<span class="sp-label">算子说明:</span>
<span class="sp-text">{{ info.selNode.operator_desc }}</span>
</div>
<div class="row" v-if="info.param.inputs.length > 0">
<span class="sp-label">输入参数:</span>
<div class="div-param">
<div v-if="info.param.inputs.length > 1" class="div-navs">
<span v-for="(it, idx) in info.param.inputs" @click="doInputSelected(idx)" :key="idx" class="sp-nav"
:class="it.selected ? 'active' : ''">{{ it.input_id }}</span>
</div>
<span class="sp-text sp-paramter scroll">
<span v-for="(it, idx) in info.param.inputs " :key="idx" v-show="it.selected" class="param-item">
<paramShow :paramInfo="it"></paramShow>
</span>
</span>
</div>
</div>
<div class="row" style="margin-top:4px;" v-if="info.param && info.param.outputs">
<span class="sp-label">输出参数:</span>
<div class="div-param">
<div v-if="info.param.outputs.length > 1" class="div-navs">
<span v-for="(it, idx) in info.param.outputs" @click="doOutputSelected(idx)" :key="idx" class="sp-nav"
:class="it.selected ? 'active' : ''">{{ it.output_id
}}</span>
</div>
<span class="sp-text sp-paramter scroll">
<span v-for="(it, idx) in info.param.outputs " :key="idx" v-show="it.selected" class="param-item">
<paramShow :paramInfo="it"></paramShow>
</span>
</span>
</div>
</div>
<div class="row" style="margin-top:4px;" v-if="info.param && info.param.process">
<span class="sp-label">处理参数:</span>
<span class="sp-text sp-paramter scroll" v-if="info.param.process">
<paramShow :paramInfo="info.param.process"></paramShow>
</span>
</div>
</div>
</div>
</div>
</el-card>
<el-card class="card-footer">
<el-button type="primary" @click="doBack"></el-button>
</el-card>
</div>
</template> </template>
<script setup> <script setup>
@ -132,178 +130,179 @@ import paramShow from './paramShow.vue'
const router = useRouter(); const router = useRouter();
const route = useRoute() const route = useRoute()
const info = reactive({ const info = reactive({
data: {}, data: {},
selNode: null, selNode: null,
param: null, param: null,
}) })
const operFlow = ref(); const operFlow = ref();
const doBack = () => { const doBack = () => {
router.push({ path: "/connection/index" }) router.push({ path: "/connection/index" })
} }
const mapToArray = obj => { const mapToArray = obj => {
let arr = []; let arr = [];
for (let k in obj) { for (let k in obj) {
arr.push({ arr.push({
key: k, value: obj[k] key: k, value: obj[k]
}) })
}; };
return arr; return arr;
} }
const loadData = () => { const loadData = () => {
let id = route.query.id; let id = route.query.id;
ConnApi.detail(id).then(d => { ConnApi.detail(id).then(d => {
info.data = d.data?.data || {}; info.data = d.data?.data || {};
operFlow.value.showFlow(info.data) operFlow.value.showFlow(info.data)
}); });
}; };
const doNodeClick = (node) => { const doNodeClick = (node) => {
info.selNode = node?.properties?.data || {}; info.selNode = node?.properties?.data || {};
info.param = node?.properties?.data?.parameters || { inputs: [], outputs: [], process: {} } info.param = node?.properties?.data?.parameters || { inputs: [], outputs: [], process: {} }
info.param.inputs.forEach((d, idx) => { info.param.inputs.forEach((d, idx) => {
d.selected = idx == 0; d.selected = idx == 0;
}); });
info.param.outputs.forEach((d, idx) => { info.param.outputs.forEach((d, idx) => {
d.selected = idx == 0; d.selected = idx == 0;
}); });
} }
onMounted(() => { onMounted(() => {
loadData(); loadData();
}); });
const doInputSelected=idx=>{ const doInputSelected = idx => {
info.param.inputs.forEach((it,i)=>{ info.param.inputs.forEach((it, i) => {
it.selected=i==idx; it.selected = i == idx;
}); });
} }
const doOutputSelected=idx=>{ const doOutputSelected = idx => {
info.param.outputs.forEach((it,i)=>{ info.param.outputs.forEach((it, i) => {
it.selected=i==idx; it.selected = i == idx;
}); });
} }
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>
.connection-detail { .connection-detail {
:deep(.el-card__header) { :deep(.el-card__header) {
padding: 8px 4px; padding: 8px 4px;
display: flex;
align-items: center
}
.detail-content {
.sp-text {
display: inline-block;
margin-left: 4px;
}
.sp-paramter {
height: 100px;
border: solid 1px #409EFF;
overflow-y: auto;
padding: 4px;
cursor: pointer;
.param-item {
display: block;
}
}
.item {
width: 300px;
&.node-info {
position: absolute;
right: 10px;
top: 10px;
.div-chart {
min-height: unset;
height: auto;
}
.div-info {
min-height: unset;
height: auto;
}
}
.div-title {
color: #409EFF;
display: flex; display: flex;
align-items: center align-items: center;
} font-size: 12px;
}
.detail-content {
.sp-text{ .div-chart {
display: inline-block; border: solid 1px #409EFF;
margin-left:4px; min-height: 400px;
} height: 400px;
.sp-paramter { }
height: 100px;
border: solid 1px #409EFF; .div-info {
overflow-y: auto; border: dotted 1px #409EFF;
padding: 4px; min-height: 600px;
cursor: pointer; height: 600px;
padding: 10px;
.param-item { font-size: 12px;
display: block;
} .row {
} display: flex;
.item { .sp-label {
width: 300px; color: #888;
display: block;
&.node-info { white-space: nowrap;
position: absolute; }
right: 10px;
top: 10px; .sp-text {
flex-grow: 1;
.div-chart { display: block;
min-height: unset; margin-left: 4px;
height: auto; }
}
.div-param {
.div-info { .div-navs {
min-height: unset; .sp-nav {
height: auto; display: inline-block;
} line-height: 24px;
} padding: 0px 12px;
cursor: pointer;
.div-title {
color: #409EFF; &.active {
display: flex; background-color: #409EFF;
align-items: center; color: #fff;
font-size: 12px; }
} }
}
.div-chart { }
border: solid 1px #409EFF; }
min-height: 400px; }
height: 400px;
}
.div-info {
border: dotted 1px #409EFF;
min-height: 600px;
height: 600px;
padding: 10px;
font-size: 12px;
.row {
display: flex;
.sp-label {
color: #888;
display: block;
white-space: nowrap;
}
.sp-text {
flex-grow: 1;
display: block;
margin-left:4px;
}
.div-param {
.div-navs {
.sp-nav {
display: inline-block;
line-height: 24px;
padding: 0px 12px;
cursor: pointer;
&.active {
background-color: #409EFF;
color: #fff;
}
}
}
}
}
}
}
} }
}
} }
.tb-base-info { .tb-base-info {
line-height: 30px; line-height: 30px;
:deep(span) { :deep(span) {
font-size: 14px; font-size: 14px;
} }
} }
:deep(.svg-icon) { :deep(.svg-icon) {
margin-right: 8px; margin-right: 8px;
} }
.card-footer { .card-footer {
position: fixed; position: fixed;
width: calc(100% - 215px); width: calc(100% - 215px);
bottom: 0px; bottom: 0px;
:deep(.el-card__body) { :deep(.el-card__body) {
padding: 10px; padding: 10px;
.el-pagination { .el-pagination {
justify-content: end; justify-content: end;
}
} }
}
} }
</style> </style>

View File

@ -1,12 +1,12 @@
<!-- 用户管理 --> <!-- 用户管理 -->
<template> <template>
<div class="app-container"> <div class="app-container">
<div class="search-container"> <div class="search-container">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" style="flex-grow: 1;text-align: right;"> <el-form ref="queryFormRef" :model="queryParams" :inline="true" style="flex-grow: 1;text-align: right;">
<el-form-item label="" prop="connection_name"> <el-form-item label="" prop="connection_name">
<el-input v-model="queryParams.connection_name" placeholder="请输入互联名将,标签,模型名称" clearable style="width: 250px" <el-input v-model="queryParams.connection_name" placeholder="请输入互联名将,标签,模型名称" clearable style="width: 250px"
@keyup.enter="handleQuery" /> @keyup.enter="handleQuery" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button> <el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
<el-button @click="resetQuery"> <el-button @click="resetQuery">
@ -16,17 +16,17 @@
</el-form> </el-form>
</div> </div>
<el-card shadow="never" class="table-container"> <el-card shadow="never" class="table-container">
<el-table v-loading="loading" :data="info.data" stripe @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="info.data" stripe @selection-change="handleSelectionChange">
<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" width="120"/> <el-table-column label="网络名称" align="left" prop="modl_net_type" width="120" />
<el-table-column label="模型类型" align="left" prop="modl_main_type_name"> <el-table-column label="模型类型" align="left" prop="modl_net_type">
<template #default="{row}">{{ row.modl_main_type_name }}/{{row.modl_sub_type_name }}</template> <template #default="{ row }">{{ row.modl_main_type_name }}/{{ row.modl_sub_type_name }}</template>
</el-table-column> </el-table-column>
<el-table-column label="版本" align="left" prop="connection_version" /> <el-table-column label="版本" align="left" prop="connection_version" />
<el-table-column label="互联名称" align="left" prop="connection_name" width="120"/> <el-table-column label="互联名称" align="left" prop="connection_name" width="120" />
<el-table-column label="互联说明" align="left" prop="connection_desc" /> <el-table-column label="互联说明" align="left" prop="connection_desc" />
<el-table-column label="互联创建时间" width="120" align="left" prop="create_time" /> <el-table-column label="互联创建时间" width="120" align="left" prop="create_time" />
<el-table-column label="创建用户" width="100" align="left" prop="user_name" /> <el-table-column label="创建用户" width="100" align="left" prop="user_name" />
<el-table-column label="状态" width="100" align="left" prop="connection_created"> <el-table-column label="状态" width="100" align="left" prop="connection_created">
@ -38,15 +38,13 @@
<el-table-column label="操作" fixed="right" align="center" width="270"> <el-table-column label="操作" fixed="right" align="center" width="270">
<template #default="scope"> <template #default="scope">
<template v-if="scope.row.connection_created"> <template v-if="scope.row.connection_created">
<el-button text type="primary" size="small" <el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-edit />查看</el-button>
@click="doShowDetail(scope.row)"><i-ep-edit />查看</el-button> <el-button text type="primary" size="small"
<el-button text type="primary" size="small" @click="doEdit(scope.row.connection_id)"><i-ep-link />修改互联</el-button>
@click="doEdit(scope.row.connection_id)"><i-ep-link/>修改互联</el-button> <el-button text type="primary" size="small" @click="handleDelete(scope.row)"><i-ep-delete />删除</el-button>
<el-button text type="primary" size="small" @click="handleDelete(scope.row)"><i-ep-delete />删除</el-button>
</template> </template>
<template v-else> <template v-else>
<el-button text type="primary" size="small" <el-button text type="primary" size="small" @click="doAdd(scope.row)"></el-button>
@click="doAdd(scope.row)">新建互联</el-button>
</template> </template>
</template> </template>
</el-table-column> </el-table-column>
@ -72,13 +70,13 @@ const removeIds = ref([]); // 删除用户ID集合 用于批量删除
const queryParams = reactive<any>({ const queryParams = reactive<any>({
page_num: 1, page_num: 1,
page_size: 10, page_size: 10,
connection_name:'' connection_name: ''
}); });
const dateTimeRange = ref(""); const dateTimeRange = ref("");
const total = ref(100); // const total = ref(100); //
const info=reactive({ const info = reactive({
total:0, total: 0,
data:[] data: []
}) })
watch(dateTimeRange, (newVal) => { watch(dateTimeRange, (newVal) => {
if (newVal) { if (newVal) {
@ -90,15 +88,15 @@ watch(dateTimeRange, (newVal) => {
/** 查询 */ /** 查询 */
function handleQuery() { function handleQuery() {
loading.value = true; loading.value = true;
ConnApi.list(queryParams).then(d=>{ ConnApi.list(queryParams).then(d => {
loading.value = false; loading.value = false;
info.total=d.data?.total||0; info.total = d.data?.data?.total || 0;
info.data=d.data?.data||[]; info.data = d.data?.data?.connection_list || [];
}); });
} }
function doUploadModel(){ function doUploadModel() {
router.push({ path: "/modelMgr/uploadModel" }); router.push({ path: "/modelMgr/uploadModel" });
} }
@ -125,24 +123,24 @@ function handleDelete(row: { [key: string]: any }) {
cancelButtonText: "取消", cancelButtonText: "取消",
type: "warning", type: "warning",
}).then(function () { }).then(function () {
ConnApi.deleteConnect(row.connection_id).then(d=>{ ConnApi.deleteConnect(row.connection_id).then(d => {
if(d.data.code==0){ if (d.data.code == 0) {
ElMessage.success("删除互联成功"); ElMessage.success("删除互联成功");
} }
}); });
}); });
} }
const doShowDetail=(row:any)=>{ const doShowDetail = (row: any) => {
router.push({path:"/connection/detail",query:{id:row.connection_id}}) router.push({ path: "/connection/detail", query: { id: row.connection_id } })
} }
const doEdit=(row:any)=>{ const doEdit = (row: any) => {
router.push({path:"/connection/edit",query:{id:row.connection_id,type:'edit'}}) router.push({ path: "/connection/edit", query: { id: row.connection_id, type: 'edit' } })
} }
const doAdd=(row:any)=>{ const doAdd = (row: any) => {
router.push({path:"/connection/edit",query:{id:row.connection_id,type:'add'}}) router.push({ path: "/connection/edit", query: { id: row.connection_id, type: 'add' } })
} }
@ -153,19 +151,21 @@ onMounted(() => {
<style scoped lang='scss'> <style scoped lang='scss'>
.search-container{ .search-container {
display:flex; display: flex;
} }
.card-footer{
.card-footer {
position: fixed; position: fixed;
width: calc(100% - 215px); width: calc(100% - 215px);
bottom: 0px; bottom: 0px;
:deep(.el-card__body){
padding:0px; :deep(.el-card__body) {
.el-pagination{ padding: 0px;
.el-pagination {
justify-content: end; justify-content: end;
} }
} }
} }
</style> </style>

View File

@ -1,194 +1,195 @@
<template> <template>
<div class="node-panel"> <div class="node-panel">
<el-tabs type="border-card"> <el-tabs type="border-card">
<el-tab-pane label="前处理"> <el-tab-pane label="前处理">
<div v-for="(it1, idx1) in info.list1" :key="idx1" class="div-item" @mousedown="dragNode(it1, 1)" <div v-for="(it1, idx1) in info.list1" :key="idx1" class="div-item" @mousedown="dragNode(it1, 1)"
v-show="it1.show"> v-show="it1.show">
{{ it1.text }} {{ it1.text }}
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="后处理"> <el-tab-pane label="后处理">
<div v-for="(it2, idx2) in info.list2" :key="idx2" class="div-item item2" @mousedown="dragNode(it2, 2)" <div v-for="(it2, idx2) in info.list2" :key="idx2" class="div-item item2" @mousedown="dragNode(it2, 2)"
v-show="it2.show"> v-show="it2.show">
{{ it2.text }} {{ it2.text }}
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="推理"> <el-tab-pane label="推理">
<div v-for="(it2, idx2) in info.list3" :key="idx2" class="div-item item3" @mousedown="dragNode(it2, 3)" <div v-for="(it2, idx2) in info.list3" :key="idx2" class="div-item item3" @mousedown="dragNode(it2, 3)"
v-show="it2.show"> v-show="it2.show">
{{ it2.text }} {{ it2.text }}
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="数据源"> <el-tab-pane label="数据源">
<div v-for="(it2, idx2) in info.list4" :key="idx2" class="div-item item4" @mousedown="dragNode(it2, 4)" <div v-for="(it2, idx2) in info.list4" :key="idx2" class="div-item item4" @mousedown="dragNode(it2, 4)"
v-show="it2.show"> v-show="it2.show">
{{ it2.text }} {{ it2.text }}
</div> </div>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="数据报告"> <el-tab-pane label="数据报告">
<div v-for="(it2, idx2) in info.list5" :key="idx2" class="div-item item5" @mousedown="dragNode(it2, 5)" <div v-for="(it2, idx2) in info.list5" :key="idx2" class="div-item item5" @mousedown="dragNode(it2, 5)"
v-show="it2.show"> v-show="it2.show">
{{ it2.text }} {{ it2.text }}
</div> </div>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script setup> <script setup>
import OperApi from '@/api/operator' import OperApi from '@/api/operator'
const props = defineProps({ const props = defineProps({
lf: { lf: {
type: Object, type: Object,
require: true, require: true,
default: null default: null
} }
}) })
const dragNode = (it, t) => { const dragNode = (it, t) => {
let color = '#83BBF0'; let color = '#83BBF0';
if (t == 2) { if (t == 2) {
color = '#20C2F9'; color = '#20C2F9';
}
if (t == 3) {
color = '#82DFE7';
}
if (t == 4) {
color = '#A7BEE7';
}
if (t == 5) {
color = '#4C8DD1';
}
props.lf.dnd.startDrag({
type: 'ai-node',
text: it.text,
properties: {
fill: color,
node: it.id,
data: it
} }
if (t == 3) { })
color = '#82DFE7';
}
if (t == 4) {
color = '#A7BEE7';
}
if (t == 5) {
color = '#4C8DD1';
}
props.lf.dnd.startDrag({
type: 'ai-node',
text: it.text,
properties: {
fill: color,
node: it.id,
data: it
}
})
} }
const info = reactive({ const info = reactive({
list1: [], list1: [],
list2: [], list2: [],
list3: [], list3: [],
list4: [], list4: [],
list5: [], list5: [],
}) })
const updateNode = (nodes) => { const updateNode = (nodes) => {
let nds = nodes.nodes.map(d => d.properties.node); let nds = nodes.nodes.map(d => d.properties.node);
if (info.all) { if (info.all) {
info.all.forEach(d => { info.all.forEach(d => {
d.show = nds.indexOf(d.id) == -1 d.show = nds.indexOf(d.id) == -1
}); });
} }
} }
const doEdit = (nd) => { const doEdit = (nd) => {
let tmps = info.all.filter(d => d.id == nd.id); let tmps = info.all.filter(d => d.id == nd.id);
if (tmps.length > 0) { if (tmps.length > 0) {
tmps[0].inputs = nd.inputs; tmps[0].inputs = nd.inputs;
tmps[0].outputs = nd.outputs; tmps[0].outputs = nd.outputs;
tmps[0].process = nd.process; tmps[0].process = nd.process;
} }
} }
defineExpose({ defineExpose({
updateNode, updateNode,
doEdit, doEdit,
}) })
const initData = () => { const initData = () => {
OperApi.list().then(d => { OperApi.list({ page_num: 1, page_size: 100 }).then(d => {
let tmps = (d.data?.data?.operator_list || []).map(it => { let tmps = (d.data?.data?.operator_list || []).map(it => {
it.show = true; it.show = true;
it.text = it.operator_name; it.text = it.operator_name;
it.id = it.operator_id it.id = it.operator_id
if (!it.parameters) { if (!it.parameters) {
it.parameters = { it.parameters = {
inputs: [{ inputs: [{
input_id: 1, input_id: 1,
oper_inout_data_type: "image_rgb24,image_gray8", oper_inout_data_type: "image_rgb24,image_gray8",
size_x: { size_x: {
type: "int", // type: "int", //
value: 480, // value: 480, //
}, },
size_y: { size_y: {
type: "int", type: "int",
value: 480, value: 480,
}
},],
outputs: [{
output_id: 1,
oper_inout_data_type: "same_as_input", //
size_x: {
type: "int", //
value: 580, //
},
size_y: {
type: "int",
value: 580,
},
scale: {
type: "float", //
value: 1.0, //
}
},],
process: {
method: {
type: "nearest/bilinear",
value: "nearest",
},
}
}
} }
return it; },],
}); outputs: [{
info.all = tmps; output_id: 1,
info.list1 = tmps.filter(d => d.oper_main_type == "pre_process"); oper_inout_data_type: "same_as_input", //
info.list2 = tmps.filter(d => d.oper_main_type == "post_process"); size_x: {
info.list3 = tmps.filter(d => d.oper_main_type == "inference"); type: "int", //
info.list4 = tmps.filter(d => d.oper_main_type == "data_source"); value: 580, //
info.list5 = tmps.filter(d => d.oper_main_type == "data_report"); },
size_y: {
type: "int",
value: 580,
},
scale: {
type: "float", //
value: 1.0, //
}
},],
process: {
method: {
type: "nearest/bilinear",
value: "nearest",
},
}
}
}
return it;
}); });
info.all = tmps;
info.list1 = tmps.filter(d => d.oper_main_type == "pre_process");
info.list2 = tmps.filter(d => d.oper_main_type == "post_process");
info.list3 = tmps.filter(d => d.oper_main_type == "inference");
info.list4 = tmps.filter(d => d.oper_main_type == "data_source");
info.list5 = tmps.filter(d => d.oper_main_type == "data_report");
});
} }
onMounted(() => { onMounted(() => {
initData(); initData();
}); });
</script> </script>
<style lang='scss'> <style lang='scss'>
.node-panel { .node-panel {
.el-tabs__item { .el-tabs__item {
padding: 0px 8px !important; padding: 0px 8px !important;
}
.div-item {
font-size: 12px;
border: solid 1px #888;
margin: 0px 40px 10px;
line-height: 30px;
text-align: center;
border-radius: 4px;
background: #83BBF0;
user-select: none;
cursor: move;
&.item2 {
background: #20C2F9;
} }
.div-item { &.item3 {
font-size: 12px; background: #82DFE7;
border: solid 1px #888;
margin: 0px 40px 10px;
line-height: 30px;
text-align: center;
border-radius: 4px;
background: #83BBF0;
user-select: none;
cursor: move;
&.item2 {
background: #20C2F9;
}
&.item3 {
background: #82DFE7;
}
&.item4 {
background: #A7BEE7;
}
&.item5 {
background: #4C8DD1;
}
} }
&.item4 {
background: #A7BEE7;
}
&.item5 {
background: #4C8DD1;
}
}
} }
</style> </style>

View File

@ -1,157 +1,168 @@
<template> <template>
<div class="app-container model-detail"> <div class="app-container model-detail">
<el-card> <el-card>
<template #header> <template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" /> <svg-icon icon-class="pause" style="width:20px;height:20px;" />
基本信息</template> 基本信息</template>
<table style="width:100%" class="tb-base-info"> <table style="width:100%" class="tb-base-info">
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">模型名称:</span> <span class="sp-title">模型名称:</span>
<span class="sp-text">{{modelInfo.info.model_name}}</span> <span class="sp-text">{{ modelInfo.info.model_name }}</span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">模型类型:</span> <span class="sp-title">模型类型:</span>
<span class="sp-text">{{modelInfo.info.modl_main_type_name}} <span class="sp-text">{{ modelInfo.info.modl_main_type_name }}
/{{modelInfo.info.modl_sub_type_name}} /{{ modelInfo.info.modl_sub_type_name }}
</span> </span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">模型版本:</span> <span class="sp-title">模型版本:</span>
<span class="sp-text"> <span class="sp-text">
{{modelInfo.info.model_version}} {{ modelInfo.info.model_version }}
</span> </span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">版本描述:</span> <span class="sp-title">版本描述:</span>
<span class="sp-text"> <span class="sp-text">
{{modelInfo.info.model_desc}} {{ modelInfo.info.model_desc }}
</span> </span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">模型网络:</span> <span class="sp-title">模型网络:</span>
<span class="sp-text"> <span class="sp-text">
{{modelInfo.info.modl_net_type}} {{ modelInfo.info.model_net_type }}
</span> </span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">上传用户:</span> <span class="sp-title">上传用户:</span>
<span class="sp-text"> {{modelInfo.info.user_name}}</span> <span class="sp-text"> {{ modelInfo.info.user_name }}</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">算法框架:</span> <span class="sp-title">算法框架:</span>
<span class="sp-text"> <span class="sp-text">
{{modelInfo.info.modl_framework}} {{ modelInfo.info.modl_framework }}
</span> </span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">上传时间:</span> <span class="sp-title">上传时间:</span>
<span class="sp-text"> <span class="sp-text">
{{modelInfo.info.create_time}} {{ modelInfo.info.create_time }}
</span> </span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">文件格式:</span> <span class="sp-title">文件格式:</span>
<span class="sp-text"> <span class="sp-text">
{{modelInfo.info.modl_file_type}} {{ modelInfo.info.modl_file_type }}
</span> </span>
</td> </td>
<td style="width: 50%;"> <td style="width: 50%;">
<span class="sp-title">网络配置:</span> <span class="sp-title">网络配置:</span>
<span class="sp-text sp-file"> <span class="sp-text sp-file">
<a style="line-height:24px;"ref="#"><el-icon><Document /></el-icon></a> <a style="line-height:24px;" ref="#"><el-icon>
</span> <Document />
</td> </el-icon></a>
</tr> </span>
</table> </td>
</tr>
</table>
</el-card> </el-card>
<el-card style="margin-top: 12px;"> <el-card style="margin-top: 12px;">
<template #header> <template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" />可适配算子</template> <svg-icon icon-class="pause" style="width:20px;height:20px;" />可适配算子</template>
<el-button v-for="(it,idx) in modelInfo.opers" :key="idx">{{ it.oper_type_name }}</el-button> <el-button v-for="(it, idx) in modelInfo.opers" :key="idx">{{ it.operator_name }}</el-button>
</el-card> </el-card>
<el-card style="margin-top: 12px;margin-bottom:60px;"> <el-card style="margin-top: 12px;margin-bottom:60px;">
<template #header> <template #header>
<svg-icon icon-class="pause" style="width:20px;height:20px;" /> <svg-icon icon-class="pause" style="width:20px;height:20px;" />
模型结构</template> 模型结构</template>
<div style="position: relative;min-height:50vh;" class="scroll"> <div style="position: relative;min-height:50vh;" class="scroll">
<iframe frameborder="0" scrolling="no" :src="url" style="width:100%;height:100%;position: absolute;top:0px;"></iframe> <iframe frameborder="0" scrolling="no" :src="url"
</div> style="width:100%;height:100%;position: absolute;top:0px;"></iframe>
</div>
</el-card> </el-card>
<el-card class="card-footer"> <el-card class="card-footer">
<el-button type="primary" @click="doBack"></el-button> <el-button type="primary" @click="doBack"></el-button>
</el-card> </el-card>
</div> </div>
</template> </template>
<script setup> <script setup>
import ModelApi from '@/api/models' import ModelApi from '@/api/models'
import request from 'axios' import request from 'axios'
const router = useRouter(); const router = useRouter();
const route =useRoute() const route = useRoute()
let url=ref("") let url = ref("")
let modelInfo=reactive({ let modelInfo = reactive({
info:{}, info: {},
opers:[] opers: []
}) })
const initData=()=>{ const initData = () => {
let id=route.query.id; let id = route.query.id;
let ajaxs=[]; let ajaxs = [];
ajaxs.push(ModelApi.findOne(id)) ajaxs.push(ModelApi.findOne(id))
ajaxs.push(ModelApi.adaptOperators(id)); ajaxs.push(ModelApi.adaptOperators(id));
request.all(ajaxs).then(res=>{ request.all(ajaxs).then(res => {
modelInfo.info=res[0].data?.data||{}; modelInfo.info = res[0].data?.data || {};
modelInfo.opers=res[1].data?.data?.adapt_operator_list||[]; modelInfo.opers = res[1].data?.data?.adapt_operator_list || [];
}); });
}; };
onMounted(()=>{ onMounted(() => {
url.value="./onnx/onnx.html?url=/ai/siamRPN_192.onnx"; let id = route.query.id;
url.value = "./onnx/onnx.html?id=" + id;
initData(); initData();
}); });
const doBack=()=>{ const doBack = () => {
if(route.query.from=='simulation'){ if (route.query.from == 'simulation') {
router.push({path:"/simulationEvaluation/index"}) router.push({ path: "/simulationEvaluation/index" })
return; return;
} }
router.push({path:"/modelMgr/index"}) router.push({ path: "/modelMgr/index" })
} }
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>
.model-detail{ .model-detail {
:deep(.el-card__header){ :deep(.el-card__header) {
padding:8px 4px; padding: 8px 4px;
display: flex; display: flex;
align-items: center align-items: center
} }
} }
.sp-file{
color:#29d; .sp-file {
color: #29d;
} }
.tb-base-info{
line-height: 30px; .tb-base-info {
:deep(span){ line-height: 30px;
font-size: 14px;
} :deep(span) {
font-size: 14px;
}
} }
:deep(.svg-icon){
margin-right:8px; :deep(.svg-icon) {
margin-right: 8px;
} }
.card-footer{
.card-footer {
position: fixed; position: fixed;
width: calc(100% - 215px); width: calc(100% - 215px);
bottom: 0px; bottom: 0px;
:deep(.el-card__body){
padding:10px; :deep(.el-card__body) {
.el-pagination{ padding: 10px;
.el-pagination {
justify-content: end; justify-content: end;
} }
} }

View File

@ -1,83 +1,84 @@
<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>模型列表</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">
<el-radio v-model="modelSelection" :label="scope.row.id + ''" <el-radio v-model="modelSelection" :label="scope.row.id + ''"
@change="handleChange(scope.row)">&nbsp;</el-radio> @change="handleChange(scope.row)">&nbsp;</el-radio>
</template> </template>
</el-table-column> </el-table-column>
<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="modelType" /> <el-table-column label="模型类型" align="left" prop="modelType" />
<el-table-column label="模型说明" align="left" prop="model_desc" width="120" /> <el-table-column label="模型说明" align="left" prop="model_desc" width="120" />
<el-table-column label="版本" align="left" prop="connection_version" /> <el-table-column label="版本" align="left" prop="connection_version" />
<el-table-column label="互联名称" align="left" prop="connection_name" width="120" /> <el-table-column label="互联名称" align="left" prop="connection_name" width="120" />
<el-table-column label="互联说明" align="left" prop="connection_desc" /> <el-table-column label="互联说明" align="left" prop="connection_desc" />
<el-table-column label="互联创建时间" width="120" align="left" prop="create_time" /> <el-table-column label="互联创建时间" width="120" align="left" prop="create_time" />
</el-table> </el-table>
<pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.pageNum" <pagination v-if="total > 0" v-model:total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="handleQuery" /> v-model:limit="queryParams.pageSize" @pagination="handleQuery" />
</el-card> </el-card>
</template> </template>
<script setup> <script setup>
import connApi from '@/api/connection' import connApi from '@/api/connection'
const loading = ref(false); const loading = ref(false);
const modelSelection = ref("")//id const modelSelection = ref("")//id
const info=reactive({ const info = reactive({
data:[] data: []
}) })
const queryParams = reactive({ const queryParams = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
connection_name:'' connection_name: ''
}); });
const total = ref(100); // const total = ref(100); //
const handleChange = (row) => { const handleChange = (row) => {
modelSelection.value = row.id + ""; modelSelection.value = row.id + "";
} }
const doRowClick=(row)=>{ const doRowClick = (row) => {
modelSelection.value=row.id+""; modelSelection.value = row.id + "";
} }
/** 查询 */ /** 查询 */
function handleQuery(a) { function handleQuery(a) {
if(a){ if (a) {
queryParams.pageSize=a.limit; queryParams.pageSize = a.limit;
queryParams.pageNum=a.page; queryParams.pageNum = a.page;
} }
//ElMessage.success(""); //ElMessage.success("");
loading.value = true; loading.value = true;
connApi.list(queryParams).then(d=>{ connApi.list(queryParams).then(d => {
loading.value=false; loading.value = false; debugger
info.data=(d.data?.data||[]).map(it=>{ info.data = (d.data?.data?.connection_list || []).map(it => {
it.id=it.connection_id;
it.modelType=it.modl_main_type_name+"/"+it.modl_sub_type_name; it.id = it.model_id;
return it; it.modelType = it.modl_net_type;
return it;
}); });
total.value=d.data?.total||0; total.value = d.data?.data?.total || 0;
}); });
} }
const checkForm=()=>{ const checkForm = () => {
if(modelSelection.value){ if (modelSelection.value) {
let tmps=info.data.filter(d=>d.id==modelSelection.value); let tmps = info.data.filter(d => d.id == modelSelection.value);
return tmps.length>0?tmps[0]:null; return tmps.length > 0 ? tmps[0] : null;
} }
return null; return null;
}; };
onMounted(()=>{ onMounted(() => {
handleQuery(); handleQuery();
}); });
defineExpose({ defineExpose({
checkForm checkForm
}) })
</script> </script>

View File

@ -117,6 +117,7 @@ const doChoiceSuccess = item => {
function handleQuery() { function handleQuery() {
loading.value = true; loading.value = true;
let m = props.modelInfo; let m = props.modelInfo;
debugger
taskApi taskApi
.availableDevices({ .availableDevices({
connection_id: m.connection_id, connection_id: m.connection_id,

View File

@ -6045,6 +6045,11 @@ js-base64@^2.1.9:
resolved "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4" resolved "https://registry.npmmirror.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ== integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==
js-md5@^0.8.3:
version "0.8.3"
resolved "https://registry.npmmirror.com/js-md5/-/js-md5-0.8.3.tgz#921bab7efa95bfc9d62b87ee08a57f8fe4305b69"
integrity sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==
js-tokens@^4.0.0: js-tokens@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"