|
- <template>
- <div>
- <div class="ui container" id="header">
- <el-row style="margin-top: 15px">
- <el-table
- ref="table"
- :data="tableData"
- style="min-width: 100%"
- row-key="rowKey"
- lazy
- :load="load"
- :tree-props="{ children: 'Children', hasChildren: 'hasChildren' }"
- :header-cell-style="tableHeaderStyle"
- >
- <el-table-column
- prop="name"
- :label="i18n.model_name"
- align="left"
- min-width="20%"
- >
- <template slot-scope="scope">
- <div class="expand-icon" v-if="scope.row.hasChildren === false">
- <i class="el-icon-arrow-right"></i>
- </div>
- <!-- <i class="el-icon-time"></i> -->
- <span v-if="!scope.row.Children" :class="scope.row.modelType == '1' ? 'm-local' : 'm-online'">{{ scope.row.modelType == '1' ? i18n.local : i18n.online }}</span>
- <a
- class="text-over"
- :href="showinfoHref + encodeURIComponent(scope.row.name)"
- :title="scope.row.name"
- >{{ scope.row.name }}</a
- >
- </template>
- </el-table-column>
-
- <el-table-column
- prop="version"
- :label="i18n.model_version"
- align="center"
- min-width="6%"
- >
- <template slot-scope="scope">
- <span class="text-over" :title="scope.row.version">{{
- scope.row.version
- }}</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="versionCount"
- :label="i18n.model_version_num"
- align="center"
- min-width="7%"
- >
- <template slot-scope="scope">
- <span class="text-over" :title="scope.row.versionCount">{{
- scope.row.versionCount
- }}</span>
- </template>
- </el-table-column>
-
- <el-table-column
- prop="size"
- :label="i18n.model_size"
- align="center"
- min-width="10%"
- >
- <template slot-scope="scope">
- <span class="text-over">{{ renderSize(scope.row.size) }}</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="engineName"
- :label="i18n.model_egine"
- align="center"
- min-width="8%"
- >
- <template slot-scope="scope">
- <span class="text-over" :title="scope.row.engineName">{{
- scope.row.engineName
- }}</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="computeResource"
- :label="i18n.model_compute_resource"
- align="center"
- min-width="8%"
- >
- <template slot-scope="scope">
- <span class="text-over">{{ scope.row.computeResource }}</span>
- </template>
- </el-table-column>
- <el-table-column
- prop="isPrivate"
- :label="i18n.model_status"
- align="center"
- min-width="6.75%"
- >
- <template slot-scope="scope">
- <span class="text-over" :title="scope.row.status_title">
- <i style="vertical-align: middle" :class="scope.row.status"></i
- ></span>
- <span style="color: #fa8c16;" v-if="scope.row.isPrivate">{{ i18n.modelaccess_private }}</span>
- <span style="color: #13c28d;" v-else="!scope.row.isPrivate">{{ i18n.modelaccess_public }}</span>
-
- </template>
- </el-table-column>
-
- <el-table-column
- prop="createdUnix"
- :label="i18n.model_create_time"
- align="center"
- min-width="13.75%"
- >
- <template slot-scope="scope">
- {{ transTime(scope.row.createdUnix) }}
- </template>
- </el-table-column>
- <el-table-column
- prop="userName"
- :label="i18n.model_creator"
- align="center"
- min-width="6.75%"
- >
- <template slot-scope="scope">
- <a
- :href="!scope.row.userName ? '#' : '/' + scope.row.userName"
- :title="scope.row.userName || defaultAvatarName"
- >
- <img
- class="ui avatar image"
- :src="scope.row.userRelAvatarLink || defaultAvatar"
- />
- </a>
- </template>
- </el-table-column>
-
- <el-table-column
- :label="i18n.model_operation"
- min-width="15%"
- align="center"
- >
- <template slot-scope="scope">
- <div class="space-around" >
-
- <a class="op-btn"
- v-show="scope.row.modelType == 1"
- :href="url + 'create_local_model_1?type=1&name=' + encodeURIComponent(scope.row.name) + '&id=' + scope.row.id"
- :class="{ disabled: !scope.row.isCanOper }"
- >{{ i18n.modify }}</a>
- <a class="op-btn" v-show="scope.row.modelType != 1" style="color:transparent;cursor:default;" >{{ i18n.modify }}</a>
- <a class="op-btn" style="color: #13c28d;" v-show="repoIsPrivate == false && scope.row.isPrivate==true && scope.row.isCanOper" @click="
- modifyModelStatus(scope.row.id, scope.row.cName, scope.row.rowKey,false)
- ">{{ i18n.modelaccess_setpublic }}</a>
- <a class="op-btn" style="color: #fa8c16;" v-show="repoIsPrivate == false && scope.row.isPrivate==false && scope.row.isCanOper" @click="
- modifyModelStatus(scope.row.id, scope.row.cName, scope.row.rowKey,true)
- ">{{ i18n.modelaccess_setprivate }}</a>
-
- <a class="op-btn"
- :href="loadhref + scope.row.id"
- :class="{ disabled: !scope.row.isCanDownload }"
- >{{ i18n.model_download }}</a>
- <a class="op-btn"
- :class="{ disabled: !scope.row.isCanDelete }"
- @click="
- deleteModel(scope.row.id, scope.row.cName, scope.row.rowKey)
- "
- >{{ i18n.model_delete }}</a>
- </div>
- </template>
- </el-table-column>
- </el-table>
- </el-row>
- <div class="ui container" style="margin-top: 50px; text-align: center">
- <el-pagination
- background
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- :current-page="currentPage"
- :page-sizes="[5, 10, 15]"
- :page-size="pageSize"
- layout="total, sizes, prev, pager, next, jumper"
- :total="totalNum"
- >
- </el-pagination>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- import { modifyModelStatus } from '~/apis/modules/modelmanage';
- const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config;
- const REPOISPRIVATE = window.REPO_IS_PRIVATE;
- export default {
- components: {},
- data() {
- return {
- i18n: {},
- currentPage: 1,
- pageSize: 10,
- totalNum: 0,
- params: { page: 0, pageSize: 10 },
- tableData: [],
- url: "",
- isLoading: true,
- loadNodeMap: new Map(),
- submitId: {},
- repo: location.pathname.split('/').slice(0, 3).join('/'),
- defaultAvatar: "/user/avatar/Ghost/-1",
- defaultAvatarName: "Ghost",
- data: "",
- timer: null,
- timerFlag: false,
- repoIsPrivate: REPOISPRIVATE,
- };
- },
- methods: {
- load(tree, treeNode, resolve) {
- try {
- this.loadNodeMap.set(tree.cName, { tree, treeNode, resolve });
- this.$axios
- .get(this.url + "show_model_child_api", {
- params: {
- name: tree.cName,
- },
- })
- .then((res) => {
- let trainTaskInfo;
- let tableData;
- tableData = res.data;
- for (let i = 0; i < tableData.length; i++) {
- trainTaskInfo = JSON.parse(tableData[i].trainTaskInfo || '{}');
- tableData[i].engineName = this.getEngineName(tableData[i]);
- // tableData[i].computeResource = trainTaskInfo.ComputeResource;
- tableData[i].computeResource = tableData[i].type == '0' ? 'CPU/GPU' : 'NPU';
- tableData[i].cName = tableData[i].name;
- tableData[i].rowKey = tableData[i].id + Math.random();
- tableData[i].name = "";
- tableData[i].versionCount = "";
- tableData[i].Children = true;
- }
- resolve(tableData || []);
- });
- } catch (e) {
- this.loading = false;
- }
- },
- tableHeaderStyle({ row, column, rowIndex, columnIndex }) {
- if (rowIndex === 0) {
- return "background:#f5f5f6;color:#606266";
- }
- },
- handleSizeChange(val) {
- this.params.pageSize = val;
- this.getModelList();
- },
- handleCurrentChange(val) {
- this.params.page = val;
- this.getModelList();
- },
- showcreateVue(name, version, label) {
- let title = this.i18n.model_create_version_title;
- $(".ui.modal.second")
- .modal({
- centered: false,
- onShow: function () {
- $("#model_header").text(title);
- $('input[name="name"]').addClass("model_disabled");
- $('input[name="name"]').attr("readonly", "readonly");
- $('input[name="modelSelectedFile"]').attr("readonly", "readonly");
- $('input[name="version"]').addClass("model_disabled");
- $(".ui.dimmer").css({
- "background-color": "rgb(136, 136, 136,0.7)",
- });
- $("#job-name").empty();
- $("#name").val(name);
- $("#label").val(label);
- let version_string = versionAdd(version);
- $("#version").val(version_string);
- loadTrainList();
- },
- onHide: function () {
- document.getElementById("formId").reset();
- $('input[name="name"]').removeClass("model_disabled");
- $('input[name="name"]').removeAttr("readonly");
- $('input[name="modelSelectedFile"]').removeAttr("readonly");
- var cityObj = $("#modelSelectedFile");
- cityObj.attr("value", "");
- $("#choice_model").dropdown("clear");
- $("#choice_version").dropdown("clear");
- $("#choice_Engine").dropdown("clear");
- $(".ui.dimmer").css({ "background-color": "" });
- $(".ui.error.message").text();
- $(".ui.error.message").css("display", "none");
- },
- })
- .modal("show");
- },
- check() {
- let jobid = document.getElementById("jobId").value;
- let versionname = document.getElementById("versionName").value;
- let name = document.getElementById("name").value;
- let version = document.getElementById("version").value;
- let modelSelectedFile =
- document.getElementById("modelSelectedFile").value;
- if (jobid == "") {
- $(".required.ten.wide.field").addClass("error");
- return false;
- } else {
- $(".required.ten.wide.field").removeClass("error");
- }
- if (modelSelectedFile == "") {
- $("#modelSelectedFile").addClass("error");
- return false;
- } else {
- $("#modelSelectedFile").removeClass("error");
- }
- if (versionname == "") {
- $(".required.six.widde.field").addClass("error");
- return false;
- } else {
- $(".required.six.widde.field").removeClass("error");
- }
-
- if (name == "") {
- $("#modelname").addClass("error");
- return false;
- } else {
- $("#modelname").removeClass("error");
- }
- if (versionname == "") {
- $("#verionname").addClass("error");
- return false;
- } else {
- $("#verionname").removeClass("error");
- }
- return true;
- },
- submit() {
- let context = this;
- let flag = this.check();
- if (flag) {
- let cName = $("input[name='name']").val();
- let version = $("input[name='version']").val();
- let data = $("#formId").serialize();
- const initModel = $("input[name='initModel']").val();
- let url_href =
- version === "0.0.1"
- ? context.url_create_newModel
- : context.url_create_newVersion;
- $("#mask").css({ display: "block", "z-index": "9999" });
-
- $.ajax({
- url: url_href,
- type: "POST",
- data: data,
- success: function (res) {
- context.getModelList();
- $("input[name='modelSelectedFile']").val("");
- $(".ui.modal.second").modal("hide");
- if (initModel === "0") {
- location.reload();
- }
- },
- error: function (xhr) {
- // 隐藏 loading
- // 只有请求不正常(状态码不为200)才会执行
- $(".ui.error.message").text(xhr.responseText);
- $(".ui.error.message").css("display", "block");
- },
- complete: function (xhr) {
- $("#mask").css({ display: "none", "z-index": "1" });
- },
- });
- } else {
- return false;
- }
- },
- loadrefresh(row) {
- const store = this.$refs.table.store;
- if (!this.loadNodeMap.get(row.cName)) {
- const parent = store.states.data;
- const index = parent.findIndex((child) => child.rowKey == row.rowKey);
- this.getModelList();
- } else {
- let { tree, treeNode, resolve } = this.loadNodeMap.get(row.cName);
- const keys = Object.keys(store.states.lazyTreeNodeMap);
- if (keys.includes(row.rowKey)) {
- this.getModelList();
- } else {
- let parentRow = store.states.data.find(
- (child) => child.cName == row.cName
- );
- let childrenIndex = store.states.lazyTreeNodeMap[
- parentRow.rowKey
- ].findIndex((child) => child.rowKey == row.rowKey);
- parentRow.versionCount = parentRow.versionCount - 1;
- const parent = store.states.lazyTreeNodeMap[parentRow.rowKey];
- if (parent.length === 1) {
- this.getModelList();
- } else {
- parent.splice(childrenIndex, 1);
- }
- }
- }
- },
- modifyModelStatus(id, name, rowKey,isPrivate) {
- let data = {'id':id,'isPrivate':isPrivate,'repo':this.repo};
- modifyModelStatus(data).then(res => {
- res = res.data;
- if (res && res.code == '0') {
- this.getModelList();
- } else {
- this.$message({
- type: 'error',
- message: this.$t('modelManage.infoModificationFailed'),
- });
- }
- }).catch(err => {
- console.log(err);
- this.$message({
- type: 'error',
- message: this.$t('modelManage.infoModificationFailed'),
- });
- });
- },
- deleteModel(id, name, rowKey) {
- let row = { cName: name, id: id, rowKey: rowKey };
- let _this = this;
- let flag = 1;
- $(".ui.basic.modal.first")
- .modal({
- onDeny: function () {
- flag = false;
- },
- onApprove: function () {
- _this.$axios
- .delete(_this.url + "delete_model", {
- params: {
- id: id,
- },
- })
- .then((res) => {
- _this.loadrefresh(row);
- // _this.getModelList()
- });
- flag = true;
- },
- onHidden: function () {
- if (flag == false) {
- $(".alert")
- .html(_this.i18n['canceled_operation'])
- .removeClass("alert-success")
- .addClass("alert-danger")
- .show()
- .delay(1500)
- .fadeOut();
- } else {
- $(".alert")
- .html(_this.i18n['successfully_deleted'])
- .removeClass("alert-danger")
- .addClass("alert-success")
- .show()
- .delay(1500)
- .fadeOut();
- }
- },
- })
- .modal("show");
- },
- getEngineName(model) {
- if (model.engine == 0) {
- return "PyTorch";
- } else if (model.engine == 1 || model.engine == 121) {
- return "TensorFlow";
- } else if (
- model.engine == 2 ||
- model.engine == 122 ||
- model.engine == 35
- ) {
- return "MindSpore";
- } else if (model.engine == 4) {
- return "PaddlePaddle";
- } else if (model.engine == 5) {
- return "OneFlow";
- } else if (model.engine == 6) {
- return "MXNet";
- } else {
- return "Other";
- }
- },
- intervalModelist() {
- if (!this.timerFlag) {
- this.timer = setInterval(() => {
- this.getModelList();
- }, 10000);
- }
- },
- getModelList() {
- let countStatus = 0;
- try {
- this.loadNodeMap.clear();
- this.$axios
- .get(this.url + "show_model_api", {
- params: this.params,
- })
- .then((res) => {
- $(".ui.grid").removeAttr("style");
- $("#loadContainer").removeClass("loader");
- let trainTaskInfo;
- this.tableData = res.data.data;
- for (let i = 0; i < this.tableData.length; i++) {
- trainTaskInfo = JSON.parse(this.tableData[i].trainTaskInfo || '{}');
- this.tableData[i].cName = this.tableData[i].name;
- this.tableData[i].rowKey = this.tableData[i].id + Math.random();
- this.tableData[i].engineName = this.getEngineName(
- this.tableData[i]
- );
- // this.tableData[i].computeResource = trainTaskInfo.ComputeResource;
- this.tableData[i].computeResource = this.tableData[i].type == '0' ? 'CPU/GPU' : 'NPU';
- this.tableData[i].hasChildren = res.data.data[i].versionCount === 1 ? false : true;
- if (this.tableData[i].status !== 1) {
- countStatus++;
- }
-
- switch (this.tableData[i].status) {
- case 1:
- this.tableData[i].status = "WAITING";
- this.tableData[i].status_title = this.i18n.model_wait;
- break;
- case 2:
- this.tableData[i].status = "FAILED";
- this.tableData[i].status_title = this.tableData[i].statusDesc;
- break;
- default:
- this.tableData[i].status = "SUCCEEDED";
- this.tableData[i].status_title = this.i18n.model_success;
- break;
- }
- }
- this.totalNum = res.data.count;
- if (countStatus === this.tableData.length) {
- clearInterval(this.timer);
- this.timer = null;
- this.timerFlag = false;
- } else {
- this.intervalModelist();
- this.timerFlag = true;
- }
- })
- .catch((err) => {
- console.log(err);
- });
- } catch (e) {
- console.log(e);
- }
- },
- },
- computed: {
- loadhref() {
- return this.url + "downloadall?id=";
- },
- showinfoHref() {
- return this.url + "show_model_info?name=";
- },
- transStatus(){
- return function (state) {
- if(state){
- return this.i18n.modelaccess_private;
- }
- return this.i18n.modelaccess_public;
- }
- },
- transTime() {
- return function (time) {
- let date = new Date(time * 1000); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
- let Y = date.getFullYear() + "-";
- let M =
- (date.getMonth() + 1 < 10
- ? "0" + (date.getMonth() + 1)
- : date.getMonth() + 1) + "-";
- let D =
- (date.getDate() < 10 ? "0" + date.getDate() : date.getDate()) + " ";
- let h =
- (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) +
- ":";
- let m =
- (date.getMinutes() < 10
- ? "0" + date.getMinutes()
- : date.getMinutes()) + ":";
- let s =
- date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
- return Y + M + D + h + m + s;
- };
- },
- renderSize() {
- return function (value) {
- if (null == value || value == "") {
- return "0 Bytes";
- }
- var unitArr = new Array(
- "Bytes",
- "KB",
- "MB",
- "GB",
- "TB",
- "PB",
- "EB",
- "ZB",
- "YB"
- );
- var index = 0;
- var srcsize = parseFloat(value);
- index = Math.floor(Math.log(srcsize) / Math.log(1024));
- var size = srcsize / Math.pow(1024, index);
- size = size.toFixed(2); //保留的小数位数
- return size + unitArr[index];
- };
- },
- },
- mounted() {
- this.submitId = document.getElementById("submitId");
- this.intervalModelist();
- this.url = location.href.split("show_model")[0];
- this.submitId.addEventListener("click", this.submit);
- this.url_create_newVersion = this.url + "create_model";
- this.url_create_newModel = this.url + "create_new_model";
- },
- created() {
- if (document.documentElement.attributes["lang"].nodeValue == "en-US") {
- this.i18n = this.$locale.US;
- } else {
- this.i18n = this.$locale.CN;
- }
- this.getModelList();
- },
- beforeDestroy() {
- // 实例销毁之前对点击事件进行解绑
- this.submitId.removeEventListener("click", this.submit);
- clearInterval(this.timer);
- },
- };
- </script>
-
- <style scoped>
- .text-over {
- overflow: hidden;
- text-overflow: ellipsis;
- vertical-align: middle;
- white-space: nowrap;
- }
-
- .m-local {
- background-color: rgb(22, 132, 252);
- color: white;
- padding: 2px 3px;
- border-radius: 4px;
- font-size: 12px;
- margin-right: 2px;
- }
-
- .m-online {
- background-color: rgb(91, 185, 115);
- color: white;
- padding: 2px 3px;
- border-radius: 4px;
- font-size: 12px;
- margin-right: 2px;
- }
-
- .el-icon-arrow-right {
- font-family: element-icons !important;
- speak: none;
- font-style: normal;
- font-weight: 400;
- font-feature-settings: normal;
- font-variant: normal;
- text-transform: none;
- line-height: 1;
- vertical-align: middle;
- display: inline-block;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- border: 1px solid #d4d4d5;
- border-radius: 50%;
- color: #d4d4d5;
- margin-right: 4px;
- }
-
- .el-icon-arrow-right::before {
- content: "\e6e0";
- }
-
- .expand-icon {
- display: inline-block;
- width: 20px;
- line-height: 20px;
- height: 20px;
- text-align: center;
- margin-right: 3px;
- font-size: 12px;
- }
-
- /deep/ .el-table_1_column_1.is-left .cell {
- padding-right: 0px !important;
- white-space: nowrap;
- }
-
- /deep/ .el-table__expand-icon .el-icon-arrow-right {
- font-family: element-icons !important;
- speak: none;
- font-style: normal;
- font-weight: 400;
- font-feature-settings: normal;
- font-variant: normal;
- text-transform: none;
- line-height: 1;
- vertical-align: middle;
- display: inline-block;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- border: 1px solid #3291f8;
- border-radius: 50%;
- color: #3291f8;
- margin-right: 4px;
- }
-
- .space-around {
- display: flex;
- justify-content: space-around;
- }
-
- .op-btn-c {
- text-align: right;
- padding-right: 20px;
- }
-
- .op-btn {
- margin: 0 0 0 5px;
- }
-
- .disabled {
- cursor: default;
- pointer-events: none;
- color: rgba(0, 0, 0, 0.6) !important;
- opacity: 0.45 !important;
- }
- </style>
|