Compare commits

..

3 Commits

Author SHA1 Message Date
haha e3b440c689 Merge branch 'main' of http://62.234.3.186:3000/sxyanzhu/AIManage
# Conflicts:
#	yarn.lock
2024-08-01 23:47:25 +08:00
haha 67498e433f update code 2024-08-01 23:46:40 +08:00
haha 1b6cba1a1c update code 2024-07-31 00:33:09 +08:00
13 changed files with 1018 additions and 9827 deletions

View File

@ -3,9 +3,9 @@ VITE_APP_PORT = 3000
# 代理前缀 # 代理前缀
VITE_APP_BASE_API = '/api' VITE_APP_BASE_API = '/api'
VITE_APP_API_URL = http://62.234.3.186/mk/ai/api #VITE_APP_API_URL = http://62.234.3.186/mk/ai/api
# 线上接口地址 # 线上接口地址
#VITE_APP_API_URL = http://10.5.1.137:8800 VITE_APP_API_URL = http://10.5.1.137:8800
# 开发接口地址 # 开发接口地址
# VITE_APP_API_URL = http://localhost:8989 # VITE_APP_API_URL = http://localhost:8989

View File

@ -47,12 +47,28 @@ const download=(id)=>{
method: "get" method: "get"
}); });
} }
//上传数据文件
const upload = (file) => {
debugger
const formData = new FormData();
formData.append("file_name", file.name);
formData.append("file_content",file)
formData.append("file",file)
return request({
url: `/models/upload`,
method: "post",
data: formData,
headers: {
"Content-Type": "multipart/form-data",
},
});
}
export default { export default {
list, list,
add, add,
deleteModel, deleteModel,
findOne, findOne,
adaptOperators, adaptOperators,
download download,
upload
} }

View File

@ -0,0 +1,30 @@
<template>
<el-dialog v-model="info.show" :title="info.title" :close-on-press-escape="false" :close-on-click-modal="false"
align-center append-to-body :width="info.width" modal-class="choice-tool-param-dlg">
<json-viewer :value="info.data" copyable boxed sort theme="my-json-view jv-light" />
<template #footer>
<div style="padding-right: var(--el-dialog-padding-primary);text-align: center;">
<el-button type="primary" @click="info.show = false">关闭</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup>
const info = reactive({
title: 'Json View',
show: false,
width: '960px',
data: null
})
const showDialog = opt => {
info.title = opt.title || info.title;
info.width = opt.width || info.width;
info.show = true;
info.data = opt.data || {};
}
defineExpose({
showDialog
})
</script>

View File

@ -98,6 +98,7 @@ declare module "vue" {
SingleUpload: (typeof import("./../components/Upload/SingleUpload.vue"))["default"]; SingleUpload: (typeof import("./../components/Upload/SingleUpload.vue"))["default"];
SizeSelect: (typeof import("./../components/SizeSelect/index.vue"))["default"]; SizeSelect: (typeof import("./../components/SizeSelect/index.vue"))["default"];
SvgIcon: (typeof import("./../components/SvgIcon/index.vue"))["default"]; SvgIcon: (typeof import("./../components/SvgIcon/index.vue"))["default"];
JsonViewDlg: (typeof import("./../components/JsonViewDlg/index.vue"))["default"];
TableSelect: (typeof import("./../components/TableSelect/index.vue"))["default"]; TableSelect: (typeof import("./../components/TableSelect/index.vue"))["default"];
TagsView: (typeof import("./../layout/components/TagsView/index.vue"))["default"]; TagsView: (typeof import("./../layout/components/TagsView/index.vue"))["default"];
ThemeColorPicker: (typeof import("./../layout/components/Settings/components/ThemeColorPicker.vue"))["default"]; ThemeColorPicker: (typeof import("./../layout/components/Settings/components/ThemeColorPicker.vue"))["default"];

View File

@ -128,12 +128,14 @@
import nodePanel from './nodePanel.vue' import nodePanel from './nodePanel.vue'
import editFlow from './editFlow.vue' import editFlow from './editFlow.vue'
import ConnApi from '@/api/connection' import ConnApi from '@/api/connection'
import ModelApi from '@/api/models'
import EditParamDlg from './editParamDlg.vue' import EditParamDlg from './editParamDlg.vue'
import paramShow from './paramShow.vue' import paramShow from './paramShow.vue'
const router = useRouter(); const router = useRouter();
const editForm = ref(ElForm) const editForm = ref(ElForm)
const route = useRoute() const route = useRoute()
const upForm = reactive({ const upForm = reactive({
model_id: '',
model_name: '', model_name: '',
model_version: '', model_version: '',
connection_name: '', connection_name: '',
@ -152,6 +154,7 @@ const info = reactive({
connInfo: null, connInfo: null,
nodes: [], nodes: [],
editObj: null, editObj: null,
type: '',
}) })
const selNode = reactive({ const selNode = reactive({
info: null, info: null,
@ -327,6 +330,7 @@ const doSave = () => {
editForm.value?.validate(valid => { editForm.value?.validate(valid => {
if (valid) { if (valid) {
let postData = { let postData = {
model_id: upForm.model_id,
connection_name: upForm.connection_name, connection_name: upForm.connection_name,
connection_label: upForm.connection_label, connection_label: upForm.connection_label,
connection_desc: upForm.connection_desc, connection_desc: upForm.connection_desc,
@ -335,13 +339,22 @@ const doSave = () => {
operator_connection_nodes: flowData.nodes, operator_connection_nodes: flowData.nodes,
operator_connection_edges: flowData.edges operator_connection_edges: flowData.edges
}; };
if (info.type == "add") {
ConnApi.add(postData).then(d => { ConnApi.add(postData).then(d => {
if (d.data.code == 0) { if (d.data.code == 0) {
ElMessage.success("增加模型成功!"); ElMessage.success("增加互联成功!");
router.push({ path: "/connection/index" }) router.push({ path: "/connection/index" })
} }
}); });
} else {
let id = route.query.id;
ConnApi.updatAll(id, postData).then(d => {
if (d.data.code == 0) {
ElMessage.success("修改互联成功!");
router.push({ path: "/connection/index" })
}
});
}
} }
}); });
@ -349,19 +362,51 @@ const doSave = () => {
const doCancel = () => { const doCancel = () => {
router.push({ path: "/connection/index" }) router.push({ path: "/connection/index" })
} }
const initData = () => { const initConnData = () => {
let id = route.query.id; let id = route.query.id;
ConnApi.detail(id).then(d => { ConnApi.detail(id).then(d => {
info.connInfo = d.data?.data || {}; info.connInfo = d.data?.data || {};
upForm.model_id = info.connInfo.model_id;
upForm.model_name = info.connInfo.model_name; upForm.model_name = info.connInfo.model_name;
upForm.model_version = info.connInfo.model_version; upForm.model_version = info.connInfo.model_version;
upForm.model_name = info.connInfo.model_name; upForm.model_name = info.connInfo.model_name;
upForm.model_name = info.connInfo.model_name; upForm.connection_name = info.connInfo.connection_name;
upForm.connection_label = "";
upForm.connection_desc = info.connInfo.connection_desc;
}); });
}; };
const initEditData = () => {
let id = route.query.id;
ConnApi.detail(id).then(d => {
info.connInfo = d.data?.data || {};
upForm.model_id = info.connInfo.model_id;
upForm.model_name = info.connInfo.model_name;
upForm.model_version = info.connInfo.model_version;
upForm.connection_name = info.connInfo.connection_name;
upForm.connection_label = "";
upForm.connection_desc = info.connInfo.connection_desc;
});
}
const initData = () => {
let id = route.query.id;
ModelApi.findOne(id).then(d => {
upForm.model_id = d.data.data.model_id;
upForm.model_name = d.data.data.model_name;
upForm.model_version = d.data.data.model_version;
});
}
onMounted(() => { onMounted(() => {
if (route.query.type == "edit") {
info.type = "edit"
initEditData();
} else if (route.query.type == "addByConn") {
info.type = "add"
initConnData();
} else {
info.type = "add"
initData(); initData();
window.xapp = getCurrentInstance(); }
}); });
</script> </script>
<style scoped lang='scss'> <style scoped lang='scss'>

View File

@ -1,7 +1,9 @@
<!-- 用户管理 --> <!-- 用户管理 -->
<template> <template>
<div class="app-container"> <div class="app-container">
<div class="search-container"> <div class="search-container" style="position: relative;">
<el-button type="primary" @click="doAddByModel"
style="position: absolute;left:10px;"><i-ep-plus />新建互联</el-button>
<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"
@ -29,23 +31,16 @@
<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="操作" fixed="right" align="center" width="320">
<template #default="scope"> <template #default="scope">
<el-button type="success" size="small" v-if="scope.row.connection_created"></el-button>
<el-button type="info" size="small" v-else plain>未互联</el-button>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" align="center" width="270">
<template #default="scope">
<template v-if="scope.row.connection_created">
<el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-edit />查看</el-button> <el-button text type="primary" size="small" @click="doShowDetail(scope.row)"><i-ep-edit />查看</el-button>
<el-button text type="primary" size="small" <el-button text type="primary" size="small" style="margin:0px;"
@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="doAdd(scope.row)"
</template> style="margin:0px;"><i-ep-plus />新建互联</el-button>
<template v-else> <el-button text type="primary" size="small" @click="handleDelete(scope.row)"
<el-button text type="primary" size="small" @click="doAdd(scope.row)"></el-button> style="margin:0px;"><i-ep-delete />删除</el-button>
</template>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -54,6 +49,7 @@
<pagination v-if="info.total > 0" v-model:total="info.total" v-model:page="queryParams.page_num" <pagination v-if="info.total > 0" v-model:total="info.total" v-model:page="queryParams.page_num"
v-model:limit="queryParams.page_size" @pagination="handleQuery" /> v-model:limit="queryParams.page_size" @pagination="handleQuery" />
</el-card> </el-card>
<selectModelDlg ref="selModelDlg" @success="doSelectSuccess"></selectModelDlg>
</div> </div>
</template> </template>
@ -61,10 +57,11 @@
import { UserQuery } from "@/api/user/model"; import { UserQuery } from "@/api/user/model";
import ConnApi from '@/api/connection' import ConnApi from '@/api/connection'
import selectModelDlg from './selectModelDlg.vue'
const queryFormRef = ref(ElForm); // const queryFormRef = ref(ElForm); //
const router = useRouter(); const router = useRouter();
const selModelDlg = ref();
const loading = ref(false); // const loading = ref(false); //
const removeIds = ref([]); // ID const removeIds = ref([]); // ID
const queryParams = reactive<any>({ const queryParams = reactive<any>({
@ -85,6 +82,9 @@ watch(dateTimeRange, (newVal) => {
} }
}); });
const doAddByModel = () => {
selModelDlg.value.showDialog();
}
/** 查询 */ /** 查询 */
function handleQuery() { function handleQuery() {
loading.value = true; loading.value = true;
@ -134,13 +134,15 @@ function handleDelete(row: { [key: string]: any }) {
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 doSelectSuccess = (row: any) => {
router.push({ path: "/connection/edit", query: { id: row.model_id, type: 'addByModel' } })
}
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: 'addByConn' } })
} }

View File

@ -0,0 +1,54 @@
<template>
<el-dialog v-model="info.show" :title="info.title" :close-on-press-escape="false" :close-on-click-modal="false"
align-center append-to-body :width="info.width" modal-class="choice-model-dlg">
<el-table v-loading="info.loading" :data="info.data" stripe>
<el-table-column label="模型名称" align="left" prop="model_name" width="300" />
<el-table-column label="网络名称" align="left" prop="model_network" v-if="1 == 2" />
<el-table-column label="模型类型" align="left" prop="modl_main_type_name" />
<el-table-column label="版本" align="left" prop="model_version" />
<el-table-column label="说明" align="left" prop="model_desc" />
<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="操作" fixed="right" width="120">
<template #default="scope">
<el-button text type="primary" size="small" @click="doCreateConn(scope.row)"><i-ep-edit />新建互联</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
<script setup>
import ModelApi from '@/api/models'
const emit = defineEmits(['success'])
const info = reactive({
title: '模型选择',
show: false,
width: '960px',
data: null,
loading: false
})
const showDialog = opt => {
info.show = true;
loadData();
}
const doCreateConn = row => {
emit("success", row)
}
const loadData = () => {
info.loading = true
ModelApi.list({
page_num: 1,
page_size: 100
}).then(d => {
info.loading = false
info.data = d.data.data.model_list || [];
})
}
defineExpose({
showDialog
})
</script>

View File

@ -41,7 +41,8 @@
<div class="dev-row3"> <div class="dev-row3">
<div class="device-state"> <div class="device-state">
<img style="position: relative;top: -10px;left:-10px;" :src="'images/state/' + it.working_state + '.png'" /> <img style="position: relative;top: -10px;left:-10px;"
:src="'images/state/' + it.working_state + '.png'" />
<div <div
style="font-size:20px;color:#888;position: relative;top: -10px;padding-right:10px;text-align: center;"> style="font-size:20px;color:#888;position: relative;top: -10px;padding-right:10px;text-align: center;">
{{ getState(it.working_state) }}</div> {{ getState(it.working_state) }}</div>
@ -60,7 +61,9 @@
<span>{{ it.memory_usage }}MB</span> <span>{{ it.memory_usage }}MB</span>
</div> </div>
<div class="chart-line"> <div class="chart-line">
<div class="chart-line-inline" :style="'width:' + (it.memory_usage*100.0/it.memory_total) + '%'"></div> <div class="chart-line-inline"
:style="'width:' + (it.memory_usage * 100.0 / it.memory_total) + '%'">
</div>
</div> </div>
<div class="chart-item-title"> <div class="chart-item-title">
@ -162,7 +165,8 @@ const loadDevice=()=>{
}); });
} }
const loadInfo = () => { const loadInfo = () => {
InfoApi.statistics().then(d => { InfoApi.statistics().then(res => {
let d = res.data
topInfos.value = [ topInfos.value = [
{ title: '模型总数', count: d.data.total_model_count, ucnt: d.data.user_model_count, clsName: 'c1', icon: "images/nav/nav1.png" }, { title: '模型总数', count: d.data.total_model_count, ucnt: d.data.user_model_count, clsName: 'c1', icon: "images/nav/nav1.png" },
{ title: '算子总数', count: d.data.total_operator_count, ucnt: d.data.user_operator_count, clsName: 'c1', icon: "images/nav/nav2.png" }, { title: '算子总数', count: d.data.total_operator_count, ucnt: d.data.user_operator_count, clsName: 'c1', icon: "images/nav/nav2.png" },
@ -241,6 +245,7 @@ onMounted(() => {
.right-panel { .right-panel {
min-width: 240px; min-width: 240px;
max-width: 240px;
padding-left: 8px; padding-left: 8px;
} }
@ -304,6 +309,7 @@ onMounted(() => {
.right-panel { .right-panel {
min-width: 300px; min-width: 300px;
max-width: 300px;
padding-left: 12px; padding-left: 12px;
} }

View File

@ -25,7 +25,8 @@
</template> </template>
<el-scrollbar max-height="504px"> <el-scrollbar max-height="504px">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="isSmallScreen?8:6" v-for="it in devInfos" :key="it.id" class="dev-item" style="margin-bottom: 20px;"> <el-col :span="isSmallScreen ? 8 : 6" v-for="it in devInfos" :key="it.id" class="dev-item"
style="margin-bottom: 20px;">
<el-card shadow="hover"> <el-card shadow="hover">
<template #header> <template #header>
<div class="dev-title">{{ it.name }} <div class="dev-title">{{ it.name }}
@ -40,8 +41,11 @@
<div class="dev-row3"> <div class="dev-row3">
<div class="device-state"> <div class="device-state">
<img style="position: relative;top: -10px;left:-10px;" :src="'images/state/'+it.state+'.png'"/> <img style="position: relative;top: -10px;left:-10px;"
<div style="font-size:20px;color:#888;position: relative;top: -10px;padding-right:10px;text-align: center;" >{{getState(it.state) }}</div> :src="'images/state/' + it.state + '.png'" />
<div
style="font-size:20px;color:#888;position: relative;top: -10px;padding-right:10px;text-align: center;">
{{ getState(it.state) }}</div>
</div> </div>
<div class="dev-chart"> <div class="dev-chart">
<div class="chart-item-title"> <div class="chart-item-title">
@ -186,6 +190,7 @@
position: relative; position: relative;
min-width: 960px; min-width: 960px;
padding: 0px 24px; padding: 0px 24px;
&.is-small { &.is-small {
padding: 0px 12px; padding: 0px 12px;
} }
@ -225,54 +230,67 @@
&.is-small { &.is-small {
.dev-row3 { .dev-row3 {
padding: 0px !important; padding: 0px !important;
.device-state { .device-state {
width: 80px !important; width: 80px !important;
} }
} }
.right-panel { .right-panel {
min-width: 240px; min-width: 240px;
max-width: 240px;
padding-left: 8px; padding-left: 8px;
} }
.model-flow { .model-flow {
.card-item { .card-item {
width: 100px; width: 100px;
} }
.row-1 { .row-1 {
.line { .line {
width: calc(20% - 100px); width: calc(20% - 100px);
top: 10px; top: 10px;
} }
} }
.row-3 { .row-3 {
.line { .line {
width: calc(20% - 100px); width: calc(20% - 100px);
} }
.card-center { .card-center {
.card-center-item { .card-center-item {
width: 100px; width: 100px;
&:first-child { &:first-child {
&::after { &::after {
left: 50px; left: 50px;
} }
&::before { &::before {
left: 50px; left: 50px;
} }
} }
&:last-child { &:last-child {
&::after { &::after {
left: -20px; left: -20px;
} }
&::before { &::before {
left: 51px; left: 51px;
} }
} }
} }
} }
.card-item { .card-item {
&.line-top { &.line-top {
&::after { &::after {
left: 50px; left: 50px;
} }
&::before { &::before {
left: 48px; left: 48px;
} }
@ -281,10 +299,13 @@
} }
} }
} }
.right-panel { .right-panel {
min-width: 300px; min-width: 300px;
max-width: 300px;
padding-left: 12px; padding-left: 12px;
} }
.el-card__body { .el-card__body {
padding: 10px 10px; padding: 10px 10px;
} }
@ -335,15 +356,18 @@
.el-card__header { .el-card__header {
border-bottom: 1px solid #ebeef5; border-bottom: 1px solid #ebeef5;
} }
.el-card__body { .el-card__body {
.el-scrollbar { .el-scrollbar {
padding: 10px; padding: 10px;
} }
} }
} }
.el-card__header { .el-card__header {
padding: 8px; padding: 8px;
border: none; border: none;
.row2-top { .row2-top {
position: relative; position: relative;
@ -356,10 +380,13 @@
} }
} }
.el-card__body { .el-card__body {
padding: 0px; padding: 0px;
.el-scrollbar { .el-scrollbar {
padding: 0px 10px; padding: 0px 10px;
.el-scrollbar__bar.is-horizontal { .el-scrollbar__bar.is-horizontal {
display: none; display: none;
} }
@ -394,22 +421,28 @@
box-shadow: var(--el-box-shadow-light); box-shadow: var(--el-box-shadow-light);
border-radius: 8px; border-radius: 8px;
padding: 10px; padding: 10px;
.dev-row3 { .dev-row3 {
display: flex; display: flex;
padding: 12px; padding: 12px;
align-items: center; align-items: center;
.device-state { .device-state {
width: 100px; width: 100px;
text-align: center; text-align: center;
} }
.state-text { .state-text {
font-size: 16px; font-size: 16px;
&.state0 { &.state0 {
color: var(--el-color-primary); color: var(--el-color-primary);
} }
&.state1 { &.state1 {
color: var(--el-color-warning); color: var(--el-color-warning);
} }
&.state2 { &.state2 {
color: var(--el-color-danger); color: var(--el-color-danger);
} }
@ -419,24 +452,29 @@
flex-grow: 1; flex-grow: 1;
position: relative; position: relative;
top: -10px; top: -10px;
.chart-item-title { .chart-item-title {
margin: 12px 0px 0px; margin: 12px 0px 0px;
font-size: 12px; font-size: 12px;
position: relative; position: relative;
span { span {
&:first-child { &:first-child {
font-weight: bold; font-weight: bold;
} }
&:last-child { &:last-child {
position: absolute; position: absolute;
right: 0px; right: 0px;
} }
} }
} }
.chart-line { .chart-line {
background-color: #ccc; background-color: #ccc;
height: 8px; height: 8px;
border-radius: 4px; border-radius: 4px;
.chart-line-inline { .chart-line-inline {
background-color: var(--el-color-primary); background-color: var(--el-color-primary);
height: 8px; height: 8px;
@ -450,23 +488,28 @@
} }
} }
} }
.proc-card { .proc-card {
margin-top: 20px; margin-top: 20px;
padding: 8px; padding: 8px;
.el-card__header { .el-card__header {
padding: 8px; padding: 8px;
border: none; border: none;
} }
.el-card__body { .el-card__body {
background: #EEF7FE; background: #EEF7FE;
border-radius: 8px; border-radius: 8px;
height: 300px; height: 300px;
} }
&.server-status { &.server-status {
background: #EEF7FE; background: #EEF7FE;
padding: 8px; padding: 8px;
.el-card__header{
} .el-card__header {}
.el-card__body { .el-card__body {
background: #fff; background: #fff;
box-shadow: var(--el-box-shadow-light); box-shadow: var(--el-box-shadow-light);
@ -475,4 +518,3 @@
} }
} }
</style> </style>

View File

@ -21,8 +21,8 @@
<el-table v-loading="loading" :data="tableData" stripe @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="tableData" stripe @selection-change="handleSelectionChange">
<el-table-column label="模型名称" align="left" prop="model_name" width="300" /> <el-table-column label="模型名称" align="left" prop="model_name" width="300" />
<el-table-column label="网络名称" align="left" prop="model_network" /> <el-table-column label="网络名称" align="left" prop="model_network" v-if="1 == 2" />
<el-table-column label="模型类型" align="left" prop="modl_sub_type_name" /> <el-table-column label="模型类型" align="left" prop="modl_main_type_name" />
<el-table-column label="版本" align="left" prop="model_version" /> <el-table-column label="版本" align="left" prop="model_version" />
<el-table-column label="说明" width="300" align="left" prop="model_desc" /> <el-table-column label="说明" width="300" align="left" prop="model_desc" />
<el-table-column label="上传时间" width="120" align="left" prop="create_time" /> <el-table-column label="上传时间" width="120" align="left" prop="create_time" />
@ -31,8 +31,7 @@
<template #default="scope"> <template #default="scope">
<el-button text type="primary" size="small" <el-button text type="primary" size="small"
@click="doShowModelDetail(scope.row)"><i-ep-edit />查看</el-button> @click="doShowModelDetail(scope.row)"><i-ep-edit />查看</el-button>
<el-button text type="primary" size="small" <el-button text type="primary" size="small" @click="doconnection()"><i-ep-link />互联</el-button>
@click="doconnection()"><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>
</el-table-column> </el-table-column>
@ -157,12 +156,15 @@ onMounted(() => {
.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) { :deep(.el-card__body) {
padding: 0px; padding: 0px;
.el-pagination { .el-pagination {
justify-content: end; justify-content: end;
} }

View File

@ -67,7 +67,7 @@
<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> <a style="line-height:24px;" @click="showModelParameters"><el-icon>
<Document /> <Document />
</el-icon></a> </el-icon></a>
</span> </span>
@ -94,6 +94,7 @@
<el-button type="primary" @click="doBack"></el-button> <el-button type="primary" @click="doBack"></el-button>
</el-card> </el-card>
</div> </div>
<JsonViewDlg ref="jsonDlg"></JsonViewDlg>
</template> </template>
<script setup> <script setup>
@ -102,10 +103,18 @@ import request from 'axios'
const router = useRouter(); const router = useRouter();
const route = useRoute() const route = useRoute()
let url = ref("") let url = ref("")
const jsonDlg = ref()
let modelInfo = reactive({ let modelInfo = reactive({
info: {}, info: {},
opers: [] opers: []
}) })
const showModelParameters = () => {
jsonDlg.value.showDialog({
title: '查看网络配置',
width: '800px',
data: modelInfo.info.model_parameters
})
}
const initData = () => { const initData = () => {
let id = route.query.id; let id = route.query.id;
let ajaxs = []; let ajaxs = [];

View File

@ -13,18 +13,17 @@
<el-row> <el-row>
<el-col :span="14"> <el-col :span="14">
<el-form-item label="模型类型" prop="modl_main_type"> <el-form-item label="模型类型" prop="modl_main_type">
<el-select v-model="upForm.modl_main_type" placeholder="请选择" <el-select v-model="upForm.modl_main_type" placeholder="请选择" @change="doMainTypeChange">
@change="doMainTypeChange"> <el-option v-for="(it, idx) in listOpt.modelType" :key="idx" :label="it.modl_main_type_name"
<el-option v-for="(it, idx) in listOpt.modelType" :key="idx" :value="it.modl_main_type" />
:label="it.modl_main_type_name" :value="it.modl_main_type" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<el-form-item label="" prop="modl_sub_type" class="form-item-sub-type"> <el-form-item label="" prop="modl_sub_type" class="form-item-sub-type">
<el-select v-model="upForm.modl_sub_type" placeholder="请选择"> <el-select v-model="upForm.modl_sub_type" placeholder="请选择">
<el-option v-for="(it, idx) in listOpt.modelSubType" :key="idx" <el-option v-for="(it, idx) in listOpt.modelSubType" :key="idx" :label="it.modl_sub_type_name"
:label="it.modl_sub_type_name" :value="it.modl_sub_type" /> :value="it.modl_sub_type" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -39,9 +38,9 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="版本描述"> <el-form-item label="模型描述">
<el-input v-model="upForm.desc" type="textarea" style="width:100%;" :rows="4" <el-input v-model="upForm.model_desc" type="textarea" style="width:100%;" :rows="4"
placeholder="请输入版本描述" /> placeholder="请输入模型描述" />
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -49,21 +48,31 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="算法框架" prop="modl_framework"> <el-form-item label="算法框架" prop="modl_framework">
<el-select v-model="upForm.modl_framework" placeholder="请选择" <el-select v-model="upForm.modl_framework" placeholder="请选择" style="width: 48%;margin-left:2%;">
style="width: 48%;margin-left:2%;"> <el-option v-for="(it, idx) in listOpt.modelFramework" :label="it" :value="it" :key="idx" />
<el-option v-for="(it, idx) in listOpt.modelFramework" :label="it" :value="it"
:key="idx" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12" class="div-mode-type">
<el-form-item label="模型网络" prop="modl_net_type"> <el-row>
<el-select v-model="upForm.modl_net_type" placeholder="请选择" style="width: 48%;margin-left:2%;"> <el-col :span="14">
<el-option v-for="(it,idx) in listOpt.modelNetType" :label="it" :value="it" :key="idx" /> <el-form-item label="模型网络" prop="modl_net_main_type">
<el-select v-model="upForm.modl_net_main_type" placeholder="请选择" @change="doNetMainTypeChange">
<el-option v-for="(it, idx) in listOpt.modelNetType" :label="it.model_net_serial"
:value="it.model_net_serial" :key="idx" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10">
<el-form-item label="" prop="modl_net_type" class="form-item-sub-type">
<el-select v-model="upForm.modl_net_type" placeholder="请选择">
<el-option v-for="(it, idx) in listOpt.modelNetSubType" :label="it" :value="it" :key="idx" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-col>
</el-row> </el-row>
<el-row> <el-row>
@ -81,28 +90,34 @@
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="网络参数"> <el-form-item label="网络参数" prop="model_file_list">
<el-upload v-model:file-list="fileList" class="upload-demo" <el-upload ref="uploadRef1" class="uploadFile1" :http-request="handleFileChange"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" :limit="1"> :on-remove="handleFileRemove" :on-exceed="handleFileExceed" :auto-upload-demo="false" :limit="1"
<el-button type="primary">请选择文件</el-button> accept=".onnx,.ts">
<el-button type="primary"><el-icon class="el-icon--upload"> <i-ep-upload-filled />
</el-icon></el-button>
<template #tip> <template #tip>
<div class="el-upload__tip"> <div class="el-upload__tip">
请上传大小不超过<span style="color:coral">10M</span>,格式为<span 请上传大小不超过<span style="color:coral">10M</span>,格式为<span style="color:coral">onnx/ts</span>的文件
style="color:coral">onnx/ts</span>的文件
</div> </div>
</template> </template>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12" style="position: relative;">
<el-form-item label="网络配置"> <el-button v-if="upForm.model_parameters" style="position: absolute;left:240px;z-index:999"
<el-upload v-model:file-list="fileList" class="upload-demo" @click="showModelParameters">
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" :limit="1"> <i-ep-view />
<el-button type="primary">请选择文件</el-button> 查看配置</el-button>
<el-form-item label="网络配置" prop="model_parameters">
<el-upload class="upload-demo" ref="uploadRef2" :on-remove="handleFileRemoveCfg"
:on-exceed="handleFileExceed" :auto-upload-demo="false" :http-request="handleUploadCfg" :limit="1"
accept=".json">
<el-button type="primary"><el-icon class="el-icon--upload"> <i-ep-upload-filled />
</el-icon></el-button>
<template #tip> <template #tip>
<div class="el-upload__tip"> <div class="el-upload__tip">
请上传大小不超过<span style="color:coral">10M</span>,格式为<span 请上传大小不超过<span style="color:coral">10M</span>,格式为<span style="color:coral">json</span>的文件
style="color:coral">json</span>的文件
</div> </div>
</template> </template>
</el-upload> </el-upload>
@ -112,7 +127,7 @@
</el-row> </el-row>
</el-form> </el-form>
</div> </div>
<div class="div-log"> <div class="div-log" v-if="1 == 2">
<div style="font-weight: bold;font-size:14px;padding:10px 10px">分割日志</div> <div style="font-weight: bold;font-size:14px;padding:10px 10px">分割日志</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 logList" :key="idx" class="log-item">
@ -126,7 +141,7 @@
<el-button @click="doBack"></el-button> <el-button @click="doBack"></el-button>
</el-card> </el-card>
</div> </div>
<JsonViewDlg ref="jsonDlg"></JsonViewDlg>
</template> </template>
<script setup> <script setup>
@ -140,8 +155,12 @@ let listOpt = reactive({
modelNetType: [], modelNetType: [],
modelFileType: [], modelFileType: [],
modelSubType: [], modelSubType: [],
modelNetSubType: [],
upFiles: [],
}) })
let fileList = ref([]) let fileList = ref([])
const uploadRef1 = ref()
let jsonDlg = ref()
const doSave = () => { const doSave = () => {
uploadForm.value?.validate((valid) => { uploadForm.value?.validate((valid) => {
@ -155,7 +174,6 @@ const doSave = () => {
} }
}); });
} }
const doBack = () => { const doBack = () => {
router.push({ path: "/modelMgr/index" }) router.push({ path: "/modelMgr/index" })
@ -167,12 +185,22 @@ let upForm = reactive({
model_desc: '', model_desc: '',
modl_main_type: '', modl_main_type: '',
modl_sub_type: '', modl_sub_type: '',
modl_net_main_type: '',
modl_net_type: '', modl_net_type: '',
modl_framework: '', modl_framework: '',
modl_file_type: '', modl_file_type: '',
model_parameters: {}, model_parameters: null,
model_file_list: [] model_file_list: [
]
}) })
const showModelParameters = () => {
jsonDlg.value.showDialog({
title: '查看网络配置',
width: '800px',
data: upForm.model_parameters
})
}
const logList = reactive([{ const logList = reactive([{
date: '2024-05-06 18:34:36', log: '系统已启动编译' date: '2024-05-06 18:34:36', log: '系统已启动编译'
}, { date: '2024-05-06 18:34:36', log: '系统正在分割目标文件' }, }, { date: '2024-05-06 18:34:36', log: '系统正在分割目标文件' },
@ -185,11 +213,106 @@ const upRules = computed(() => {
modl_sub_type: [{ required: true, trigger: "blur", message: "请选择子类型", }], modl_sub_type: [{ required: true, trigger: "blur", message: "请选择子类型", }],
model_version: [{ required: true, trigger: "blur", message: "请输入模型版本", }], model_version: [{ required: true, trigger: "blur", message: "请输入模型版本", }],
modl_framework: [{ required: true, trigger: "blur", message: "请选择算法框架", }], modl_framework: [{ required: true, trigger: "blur", message: "请选择算法框架", }],
modl_net_main_type: [{ required: true, trigger: "blur", message: "请选择主模型网络", }],
modl_net_type: [{ required: true, trigger: "blur", message: "请选择模型网络", }], modl_net_type: [{ required: true, trigger: "blur", message: "请选择模型网络", }],
modl_file_type: [{ required: true, trigger: "blur", message: "请选择文件类型", }], modl_file_type: [{ required: true, trigger: "blur", message: "请选择文件类型", }],
model_file_list: [{ required: true, trigger: "blur", message: "请上传网络参数", }],
model_parameters: [{ required: true, trigger: "blur", message: "请上传网络配置", }],
} }
}); });
const handleFileRemoveCfg = (a, b) => {
upForm.model_parameters = null;
}
const handleUploadCfg = (file) => {
if (file.file.size > 10 * 1024 * 1024) {
ElMessage.warning("文件大小不能超10M");
file.onError("文件大小不能超10M")
return;
}
let ext = file.file.name.split(".").pop().toLowerCase();
if (["json"].indexOf(ext) == -1) {
ElMessage.warning("请上传json格式文件");
file.onError("请上传json格式文件")
return;
}
// FileReader
let reader = new FileReader();
// FileReader
if (typeof FileReader === "undefined") {
ElMessage.warning("您的浏览器不支持文件读取。");
file.onError("您的浏览器不支持文件读取。")
return;
}
uploadFile(file).then((res) => {
if (isJSON(res)) {
upForm.model_parameters = JSON.parse(res);
}
});
}
/** 解析json */
function isJSON(str) {
try {
//
JSON.parse(str);
return true;
} catch (error) {
return false;
}
}
//
function uploadFile(file) {
return new Promise(function (resolve, reject) {
let reader = new FileReader();
reader.readAsArrayBuffer(file.file);
reader.onload = function (e) {
var ints = new Uint8Array(e.target.result); //使Uint8Array
let snippets = new TextDecoder("UTF-8").decode(ints); //
resolve(snippets);
};
});
}
//
function handleFileChange(file, b) {
if (file.file.size > 10 * 1024 * 1024) {
ElMessage.warning("文件大小不能超10M");
file.onError("文件大小不能超10M")
return;
}
let ext = file.file.name.split(".").pop().toLowerCase();
if (["onnx", "ts"].indexOf(ext) == -1) {
ElMessage.warning("请上传onnx/ts格式文件");
file.onError("请上传onnx/ts格式文件")
return;
}
ModelApi.upload(file.file).then((res) => {
listOpt.upFiles.push({
name: file.file.name,
serverName: res.data.data.file_name
})
debugger
upForm.model_file_list = listOpt.upFiles.map(it => it.serverName);
});
}
function handleFileExceed() {
ElMessage.warning("超过上传上限!");
}
function handleFileRemove(a, b, c) {
let tmps = listOpt.upFiles.filter(d => d.name == a.name);
if (tmps.length > 0) {
let idx = listOpt.upFiles.indexOf(tmps[0]);
listOpt.upFiles.splice(idx, 1);
}
upForm.model_file_list = listOpt.upFiles.map(it => it.serverName);
}
const initData = () => { const initData = () => {
let ajaxs = []; let ajaxs = [];
ajaxs.push(ConstApi.modlMainType()); ajaxs.push(ConstApi.modlMainType());
@ -199,7 +322,11 @@ const initData = () => {
request.all(ajaxs).then(res => { request.all(ajaxs).then(res => {
listOpt.modelType = res[0].data?.data?.modl_main_type_list || []; listOpt.modelType = res[0].data?.data?.modl_main_type_list || [];
listOpt.modelFramework = res[1].data?.data?.modl_framework_list || []; listOpt.modelFramework = res[1].data?.data?.modl_framework_list || [];
listOpt.modelNetType = res[2].data?.data?.model_net_type_list || []; listOpt.modelNetType = (res[2].data?.data?.modl_net_type_list || []).map(it => {
it.selected = false;
it.subSelect = "";
return it;
});
listOpt.modelFileType = res[3].data?.data?.modl_file_type_list || []; listOpt.modelFileType = res[3].data?.data?.modl_file_type_list || [];
}); });
} }
@ -207,6 +334,14 @@ const doMainTypeChange = () => {
let mainType = upForm.modl_main_type; let mainType = upForm.modl_main_type;
let subList = listOpt.modelType.filter(d => d.modl_main_type == mainType); let subList = listOpt.modelType.filter(d => d.modl_main_type == mainType);
listOpt.modelSubType = subList.length > 0 ? subList[0].modl_sub_type_list || [] : []; listOpt.modelSubType = subList.length > 0 ? subList[0].modl_sub_type_list || [] : [];
if (listOpt.modelSubType.filter(d => d.modl_sub_type == upForm.modl_sub_type).length == 0) {
upForm.modl_sub_type = '';
}
}
const doNetMainTypeChange = () => {
let tmps = listOpt.modelNetType.filter(d => d.model_net_serial == upForm.modl_net_main_type);
listOpt.modelNetSubType = tmps.length > 0 ? tmps[0].model_net_type_list : [];
upForm.modl_net_type = '';
} }
onMounted(() => { onMounted(() => {
initData(); initData();

9151
yarn.lock

File diff suppressed because it is too large Load Diff