Browse Source

Resources Management

tags/v1.22.8.2^2
chenshihai 3 years ago
parent
commit
1d38bfc906
10 changed files with 630 additions and 185 deletions
  1. +59
    -12
      web_src/vuepages/apis/modules/resources.js
  2. +3
    -3
      web_src/vuepages/const/index.js
  3. +82
    -0
      web_src/vuepages/langs/config/en-US.js
  4. +82
    -0
      web_src/vuepages/langs/config/zh-CN.js
  5. +18
    -17
      web_src/vuepages/pages/resources/components/QueueDialog.vue
  6. +171
    -32
      web_src/vuepages/pages/resources/components/SceneDialog.vue
  7. +21
    -19
      web_src/vuepages/pages/resources/components/SpecificationDialog.vue
  8. +30
    -19
      web_src/vuepages/pages/resources/queue/index.vue
  9. +114
    -52
      web_src/vuepages/pages/resources/scene/index.vue
  10. +50
    -31
      web_src/vuepages/pages/resources/specification/index.vue

+ 59
- 12
web_src/vuepages/apis/modules/resources.js View File

@@ -1,13 +1,5 @@
import service from '../service';

export const getQueueList = (params) => {
return service({
url: '/admin/resources/queue',
method: 'get',
params,
});
}

// 查询资源队列列表
// page 当前页数,从1开始
// cluster 所属集群 :OpenI 启智集群,C2Net 智算集群
@@ -43,11 +35,11 @@ export const updateResQueue = (data) => { // CardsTotalNum,Remark
}

// 查询所有资源队列名称列表
export const getResQueueCode = () => {
export const getResQueueCode = (params) => { // cluster
return service({
url: '/admin/resources/queue/codes',
method: 'get',
params: {},
params,
data: {},
});
}
@@ -70,12 +62,13 @@ export const updateResSpecification = (data) => { // data => { ID: 1, action: 'e
url: `/admin/resources/specification/update/${data.ID}`,
method: 'post',
params: { action: data.action },
data: { UnitPrice: data.action === 'edit' ? data.UnitPrice : undefined }
data: { UnitPrice: data.action === 'edit' || data.action === 'on-shelf' ? data.UnitPrice : undefined }
});
}

// 查询资源队列列表
// 查询资源规格列表
// page
// cluster 所属集群 :OpenI 启智集群,C2Net 智算集群
// queue 所属队列id
// status 状态 : 1 待审核 2已上架 3已下架
export const getResSpecificationList = (params) => {
@@ -86,3 +79,57 @@ export const getResSpecificationList = (params) => {
data: {},
});
}

// 新增资源应用场景
/*
{
"SceneName":"启智集群调试任务", //应用场景名
"JobType":"TRAIN", //任务类型 DEBUG调试任务 BENCHMARK 评测任务 TRAIN 训练 INFERENCE 推理
"IsExclusive":true, //是否专属
"ExclusiveOrg":"123,456", //专属组织
"QueueId":2, //队列id
"SpecIds":[2,3] // 资源规格id
}
*/
export const addResScene = (data) => {
return service({
url: '/admin/resources/scene/add',
method: 'post',
params: {},
data,
});
}

// 更新资源应用场景
// params: action:edit-编辑 delete-删除,
// data: {
// "SceneName":"启智集群调试任务", //应用场景名
// "IsExclusive":true, //是否专属
// "ExclusiveOrg":"123,456", //专属组织
// "SpecIds":[2,3] // 资源规格id
//}
export const updateResScene = (data) => {
return service({
url: `/admin/resources/scene/update/${data.ID}`,
method: 'post',
params: { action: data.action },
data: {
...data
},
});
}

// 查询资源应用场景
// page
// jobType
// center
// queue 所属队列
// IsExclusive 是否专属 1 专属 2 非专属
export const getResSceneList = (params) => {
return service({
url: '/admin/resources/scene/list',
method: 'get',
params,
data: {},
});
}

+ 3
- 3
web_src/vuepages/const/index.js View File

@@ -9,8 +9,8 @@ export const POINT_ACTIONS = [
export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v: i18n.t('trainTask') }, { k: 'INFERENCE', v: i18n.t('inferenceTask') }, { k: 'BENCHMARK', v: i18n.t('benchmarkTask') }];

// 资源管理
export const CLUSTERS = [{ k: 'OpenI', v: '启智集群' }, { k: 'C2Net', v: '智算集群' }];
export const AI_CENTER = [{ k: 'OpenIOne', v: '云脑一' }, { k: 'OpenITwo', v: '云脑二' }, { k: 'chendu', v: '成都人工智能计算中心' }, { k: 'pclcci', v: '鹏城云计算所' }, { k: 'hefei', v: '合肥类脑类脑智能开放平台' }, { k: 'xuchang', v: '中原人工智能计算中心' }];
export const CLUSTERS = [{ k: 'OpenI', v: i18n.t('resourcesManagement.OpenI') }, { k: 'C2Net', v: i18n.t('resourcesManagement.C2Net') }];
export const AI_CENTER = [{ k: 'OpenIOne', v: i18n.t('resourcesManagement.OpenIOne') }, { k: 'OpenITwo', v: i18n.t('resourcesManagement.OpenITwo') }, { k: 'chendu', v: i18n.t('resourcesManagement.chenduCenter') }, { k: 'pclcci', v: i18n.t('resourcesManagement.pclcci') }, { k: 'hefei', v: i18n.t('resourcesManagement.hefeiCenter') }, { k: 'xuchang', v: i18n.t('resourcesManagement.xuchangCenter') }];
export const COMPUTER_RESOURCES = [{ k: 'GPU', v: 'GPU' }, { k: 'NPU', v: 'NPU' }];
export const ACC_CARD_TYPE = [{ k: 'T4', v: 'T4' }, { k: 'A100', v: 'A100' }, { k: 'V100', v: 'V100' }, { k: 'Ascend910', v: 'Ascend 910' }];
export const SPECIFICATION_STATUS = [{ k: '1', v: '待上架' }, { k: '2', v: '已上架' }, { k: '3', v: '已下架' }];
export const SPECIFICATION_STATUS = [{ k: '1', v: i18n.t('resourcesManagement.toOnShelf') }, { k: '2', v: i18n.t('resourcesManagement.onShelf') }, { k: '3', v: i18n.t('resourcesManagement.offShelf') }];

+ 82
- 0
web_src/vuepages/langs/config/en-US.js View File

@@ -3,6 +3,16 @@ const en = {
noData: 'No Data',
date: 'Date',

confirm: 'Confirm',
cancel: 'Cancel',
pleaseCompleteTheInformationFirst: 'Please Complete the Information first!',
submittedSuccessfully: 'Submitted Successfully!',
submittedFailed: 'Submitted Failed!',
operation: 'Operation',
edit: 'Edit',
delete: 'Delete',
tips: 'Tips',

accomplishTask: 'Accomplish Task',
adminOperate: 'Administrator Operation',
runCloudBrainTask: 'Run CloudBrain Task',
@@ -65,6 +75,78 @@ const en = {

noPointGainRecord: 'No Point Earn Record Yet',
noPointConsumeRecord: 'No Point Consume Record Yet',

resourcesManagement: {
OpenI: 'OpenI',
C2Net: 'C2Net',
OpenIOne: 'OpenI One',
OpenITwo: 'OpenI Two',
chenduCenter: 'ChenDu AI Center',
pclcci: 'PCL Cloud Computer Institute',
hefeiCenter: 'HeFei AI Center',
xuchangCenter: 'XuChang AI Center',
toOnShelf: 'To Be On Shelf',
onShelf: 'On Shelf',
offShelf: 'Off Shelf',
toOnShelf: 'To On Shelf',
toOffShelf: 'To Off Shelf',
toSetPriceAndOnShelf: 'To Set Price and On Shelf',
status: 'Status',
allStatus: 'All Status',
syncAiNetwork: 'Sync AI Network',
resQueue: 'Resources Queue',
allResQueue: 'All Resources Queues',
addResQueue: 'Add Resources Queue',
addResQueueBtn: 'Add Resources Queue',
editResQueue: 'Edit Resources Queue',
resQueueName: 'Resources Queue Name',
whichCluster: 'Cluster',
allCluster: 'All Clusters',
aiCenter: 'AI Center',
aiCenterID: 'AI Center ID',
allAiCenter: 'All AI Centers',
computeResource: 'Compute Resource',
allComputeResource: 'All Compute Resources',
accCardType: 'Acc Card Type',
allAccCardType: 'All Acc Card Type',
cardsTotalNum: 'Cards Total Number',
accCardsNum: 'Acc Cards Number',
remark: 'Remark',
pleaseEnterRemark: 'Please Enter Remark',
pleaseEnterPositiveIntegerCardsTotalNum: 'Please Enter Positive Integer Cards Total Number!',
addResSpecificationAndPriceInfo: 'Add Resources Specification and Price Info',
addResSpecificationBtn: 'Add Resources Specification',
editResSpecificationAndPriceInfo: 'Edit Resources Specification and Price Info',
resSpecificationAndPriceManagement: 'Resources Specification and Price Management',
sourceSpecCode: 'Source Specification Code',
sourceSpecCodeTips: 'OpenI Two Should Enter the Source Specification Code',
sourceSpecId: 'Source Specification ID',
cpuNum: 'CPU Number',
gpuMem: 'GPU Memory',
mem: 'Memory',
shareMem: 'Share Memory',
unitPrice: 'Unit Price',
point_hr: 'Point/hr',
onShelfConfirm: 'Are you sure to on shelf the resources specification?',
offShelfConfirm: 'Are you sure to off shelf the resources specification?',
resSceneManagement: 'Resources Scene Management',
addResScene: 'Add Resources Scene',
addResSceneBtn: 'Add Resources Scene',
editResScene: 'Edit Resources Scene',
resSceneName: 'Resources Scene Name',
jobType: 'Job Type',
allJobType: 'All Job Type',
isExclusive: 'Is Exclusive?',
allExclusiveAndCommonUse: 'All Exclusive and Common Use',
exclusive: 'Exclusive',
commonUse: 'Common Use',
exclusiveOrg: 'Exclusive Organization',
exclusiveOrgTips: 'Multiple organization names are separated by semicolons',
computeCluster: 'Compute Cluster',
resourceSpecification: 'Resource Specification',
lastUpdateTime: 'Last Update Time',
resSceneDeleteConfirm: 'Are you sure to delete the current Resource Scene?',
},
}

export default en;

+ 82
- 0
web_src/vuepages/langs/config/zh-CN.js View File

@@ -3,6 +3,16 @@ const zh = {
noData: '暂无数据',
date: '日期',

confirm: '确认',
cancel: '取消',
pleaseCompleteTheInformationFirst: '请先完善信息!',
submittedSuccessfully: '提交成功!',
submittedFailed: '提交失败!',
operation: '操作',
edit: '修改',
delete: '删除',
tips: '提示',

accomplishTask: '积分任务',
adminOperate: '管理员操作',
runCloudBrainTask: '运行云脑任务',
@@ -65,6 +75,78 @@ const zh = {

noPointGainRecord: '还没有积分获取记录',
noPointConsumeRecord: '还没有积分消耗记录',

resourcesManagement: {
OpenI: '启智集群',
C2Net: '智算集群',
OpenIOne: '云脑一',
OpenITwo: '云脑二',
chenduCenter: '成都人工智能计算中心',
pclcci: '鹏城云计算所',
hefeiCenter: '合肥类脑类脑智能开放平台',
xuchangCenter: '中原人工智能计算中心',
toOnShelf: '待上架',
onShelf: '已上架',
offShelf: '已下架',
toOnShelf: '上架',
toOffShelf: '下架',
toSetPriceAndOnShelf: '定价上架',
status: '状态',
allStatus: '全部状态',
syncAiNetwork: '同步智算网络',
resQueue: '资源池(队列)',
allResQueue: '全部资源池(队列)',
addResQueue: '新建资源池(队列)',
addResQueueBtn: '新增资源池',
editResQueue: '修改资源池(队列)',
resQueueName: '资源池(队列)名称',
whichCluster: '所属集群',
allCluster: '全部集群',
aiCenter: '智算中心',
aiCenterID: '智算中心ID',
allAiCenter: '全部智算中心',
computeResource: '计算资源',
allComputeResource: '全部计算资源',
accCardType: '卡类型',
allAccCardType: '全部卡类型',
cardsTotalNum: '卡数',
accCardsNum: '卡数',
remark: '备注',
pleaseEnterRemark: '请输入备注',
pleaseEnterPositiveIntegerCardsTotalNum: '请输入正整数的卡数!',
addResSpecificationAndPriceInfo: '新增资源规格和单价信息',
addResSpecificationBtn: '新增资源规格',
editResSpecificationAndPriceInfo: '修改资源规格和单价信息',
resSpecificationAndPriceManagement: '资源规格单价管理',
sourceSpecCode: '对应资源编码',
sourceSpecCodeTips: '云脑II需要填写对应的资源编码',
sourceSpecId: '智算网络资源规格ID',
cpuNum: 'CPU数',
gpuMem: '显存',
mem: '内存',
shareMem: '共享内存',
unitPrice: '单价',
point_hr: '积分/时',
onShelfConfirm: '请确认是否上架该规格?',
offShelfConfirm: '请确认是否下架该规格?',
resSceneManagement: '算力资源应用场景管理',
addResScene: '新建算力资源应用场景',
addResSceneBtn: '新增应用场景',
editResScene: '修改算力资源应用场景',
resSceneName: '应用场景名称',
jobType: '任务类型',
allJobType: '全部任务类型',
isExclusive: '是否专属',
allExclusiveAndCommonUse: '全部专属和通用',
exclusive: '专属',
commonUse: '通用',
exclusiveOrg: '专属组织',
exclusiveOrgTips: '多个组织名之间用英文分号隔开',
computeCluster: '算力集群',
resourceSpecification: '资源规格',
lastUpdateTime: '最后更新时间',
resSceneDeleteConfirm: '是否确认删除当前应用场景?',
},
}

export default zh;

+ 18
- 17
web_src/vuepages/pages/resources/components/QueueDialog.vue View File

@@ -1,12 +1,13 @@
<template>
<div class="base-dlg">
<BaseDialog :visible.sync="dialogShow" :width="`750px`" :title="type === 'add' ? `新建资源池(队列)` : '修改资源池(队列)'"
<BaseDialog :visible.sync="dialogShow" :width="`750px`"
:title="type === 'add' ? $t('resourcesManagement.addResQueue') : $t('resourcesManagement.editResQueue')"
@open="open" @opened="opened" @close="close" @closed="closed">
<div class="dlg-content">
<div class="form">
<div class="form-row">
<div class="title required">
<span>资源池(队列)名称</span>
<span>{{ $t('resourcesManagement.resQueueName') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.QueueCode" placeholder="" :disabled="type === 'edit'"></el-input>
@@ -14,7 +15,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>所属集群</span>
<span>{{ $t('resourcesManagement.whichCluster') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.Cluster" :disabled="type === 'edit'">
@@ -24,7 +25,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>智算中心</span>
<span>{{ $t('resourcesManagement.aiCenter') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.AiCenterCode" :disabled="type === 'edit'">
@@ -34,7 +35,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>计算资源</span>
<span>{{ $t('resourcesManagement.computeResource') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.ComputeResource" :disabled="type === 'edit'">
@@ -44,7 +45,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>卡类型</span>
<span>{{ $t('resourcesManagement.accCardType') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.AccCardType" :disabled="type === 'edit'">
@@ -54,25 +55,25 @@
</div>
<div class="form-row">
<div class="title required">
<span>卡数</span>
<span>{{ $t('resourcesManagement.cardsTotalNum') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.CardsTotalNum" type="number" placeholder=""></el-input>
</div>
</div>
<div class="form-row" style="margin-top: 10px">
<div class="title"><span>备注</span></div>
<div class="title"><span>{{ $t('resourcesManagement.remark') }}</span></div>
<div class="content" style="width: 400px">
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 4 }" :placeholder="'请输入备注'"
v-model="dataInfo.Remark">
<el-input type="textarea" :autosize="{ minRows: 3, maxRows: 4 }"
:placeholder="$t('resourcesManagement.pleaseEnterRemark')" v-model="dataInfo.Remark">
</el-input>
</div>
</div>
<div class="form-row" style="margin-top: 20px">
<div class="title"></div>
<div class="content">
<el-button type="primary" class="btn confirm-btn" @click="confirm">确定</el-button>
<el-button class="btn" @click="cancel">取消</el-button>
<el-button type="primary" class="btn confirm-btn" @click="confirm">{{ $t('confirm') }}</el-button>
<el-button class="btn" @click="cancel">{{ $t('cancel') }}</el-button>
</div>
</div>
</div>
@@ -148,14 +149,14 @@ export default {
if (!this.dataInfo.QueueCode || !this.dataInfo.Cluster || !this.dataInfo.AiCenterCode || !this.dataInfo.ComputeResource || !this.dataInfo.AccCardType || !this.dataInfo.CardsTotalNum) {
this.$message({
type: 'info',
message: '请先完善信息!'
message: this.$t('pleaseCompleteTheInformationFirst'),
});
return;
}
if (parseInt(this.dataInfo.CardsTotalNum) != Number(this.dataInfo.CardsTotalNum)) {
this.$message({
type: 'info',
message: '请输入正整数的卡数!'
message: this.$t('pleaseEnterPositiveIntegerCardsTotalNum')
});
return;
}
@@ -165,20 +166,20 @@ export default {
if (res.Code === 0) {
this.$message({
type: 'success',
message: '提交成功!'
message: this.$t('submittedSuccessfully')
});
this.$emit("confirm");
} else {
this.$message({
type: 'error',
message: '提交失败!'
message: this.$t('submittedFailed')
});
}
}).catch(err => {
console.log(err);
this.$message({
type: 'error',
message: '提交失败!'
message: this.$t('submittedFailed')
});
})
},


+ 171
- 32
web_src/vuepages/pages/resources/components/SceneDialog.vue View File

@@ -1,61 +1,73 @@
<template>
<div class="base-dlg">
<BaseDialog :visible.sync="dialogShow" :width="`750px`" :title="type === 'add' ? `新建算力资源应用场景` : '编辑算力资源应用场景'"
<BaseDialog :visible.sync="dialogShow" :width="`750px`"
:title="type === 'add' ? $t('resourcesManagement.addResScene') : $t('resourcesManagement.editResScene')"
@open="open" @opened="opened" @close="close" @closed="closed">
<div class="dlg-content">
<div class="form">
<div class="form-row">
<div class="title required">
<span>应用场景名称</span>
<span>{{ $t('resourcesManagement.resSceneName') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.name" placeholder=""></el-input>
<el-input v-model="dataInfo.SceneName" placeholder=""></el-input>
</div>
</div>
<div class="form-row">
<div class="title required">
<span>任务类型</span>
<span>{{ $t('resourcesManagement.jobType') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.taskType">
<el-select v-model="dataInfo.JobType" :disabled="type === 'edit'">
<el-option v-for="item in taskTypeList" :key="item.k" :label="item.v" :value="item.k" />
</el-select>
</div>
</div>
<div class="form-row">
<div class="title required">
<span>是否专属</span>
<span>{{ $t('resourcesManagement.isExclusive') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.isExclusive" @change="changeIsExclusive">
<el-select v-model="dataInfo.IsExclusive" @change="changeIsExclusive">
<el-option v-for="item in isExclusiveList" :key="item.k" :label="item.v" :value="item.k" />
</el-select>
</div>
</div>
<div class="form-row" v-if="dataInfo.isExclusive === '1'">
<div class="form-row" v-if="dataInfo.IsExclusive === '1'">
<div class="title required">
<span>专属组织</span>
<span>{{ $t('resourcesManagement.exclusiveOrg') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.exclusiveOrg" placeholder="多个组织名之间用英文分号隔开"></el-input>
<el-input v-model="dataInfo.ExclusiveOrg" :placeholder="$t('resourcesManagement.exclusiveOrgTips')">
</el-input>
</div>
</div>
<div class="form-row">
<div class="title required">
<span>资源池队列</span>
<span>{{ $t('resourcesManagement.computeCluster') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.queue" @change="changeQueue">
<el-select v-model="dataInfo.Cluster" @change="changeCluster" :disabled="type === 'edit'">
<el-option v-for="item in clusterList" :key="item.k" :label="item.v" :value="item.k" />
</el-select>
</div>
</div>
<div class="form-row">
<div class="title required">
<span>{{ $t('resourcesManagement.resQueue') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.QueueId" @change="changeQueue" :disabled="type === 'edit'">
<el-option v-for="item in queueList" :key="item.k" :label="item.v" :value="item.k" />
</el-select>
</div>
</div>
<div class="form-row">
<div class="title required">
<span>资源规格</span>
<span>{{ $t('resourcesManagement.resourceSpecification') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.specs" multiple collapse-tags>
<el-select v-model="dataInfo.SpecIds" multiple collapse-tags class="specSel">
<el-option v-for="item in specsList" :key="item.k" :label="item.v" :value="item.k" />
</el-select>
</div>
@@ -63,8 +75,8 @@
<div class="form-row" style="margin-top: 20px">
<div class="title"></div>
<div class="content">
<el-button type="primary" class="btn confirm-btn" @click="confirm">确定</el-button>
<el-button class="btn" @click="cancel">取消</el-button>
<el-button type="primary" class="btn confirm-btn" @click="confirm">{{ $t('confirm') }}</el-button>
<el-button class="btn" @click="cancel">{{ $t('cancel') }}</el-button>
</div>
</div>
</div>
@@ -74,7 +86,9 @@
</template>
<script>
import BaseDialog from '~/components/BaseDialog.vue';
import { getQueueList } from '~/apis/modules/resources';
import { getResQueueCode, getResSpecificationList, addResScene, updateResScene } from '~/apis/modules/resources';
import { JOB_TYPE, CLUSTERS, AI_CENTER, ACC_CARD_TYPE, SPECIFICATION_STATUS } from '~/const';
import { getListValueWithKey } from '~/utils';

export default {
name: "SceneDialog",
@@ -91,10 +105,14 @@ export default {
return {
dialogShow: false,
dataInfo: {},
taskTypeList: [{ k: '1', v: '调试任务' }, { k: '2', v: '训练任务' }, { k: '3', v: '评测任务' }, { k: '4', v: '推理任务' }],
isExclusiveList: [{ k: '', v: '否' }, { k: '1', v: '是' }],
queueList: [{ k: '1', v: '资源池1' }, { k: '2', v: '资源池2' }],
specsList: [{ k: '1', v: 'spec1' }, { k: '2', v: 'spec2' }, { k: '3', v: 'spec3' }, { k: '4', v: 'spec4' }, { k: '5', v: 'spec5' }, { k: '6', v: 'spec6' }],
taskTypeList: [...JOB_TYPE],
clusterList: [...CLUSTERS],
aiCenterList: [...AI_CENTER],
accCardTypeList: [...ACC_CARD_TYPE],
statusList: [...SPECIFICATION_STATUS],
isExclusiveList: [{ k: '2', v: this.$t('resourcesManagement.commonUse') }, { k: '1', v: this.$t('resourcesManagement.exclusive') }],
queueList: [],
specsList: [],
};
},
watch: {
@@ -105,20 +123,77 @@ export default {
methods: {
resetDataInfo() {
this.dataInfo = {
id: '',
name: '',
taskType: '',
isExclusive: '',
exclusiveOrg: '',
queue: '',
specs: ['2', '3'],
SceneName: '',
JobType: '',
IsExclusive: '2',
ExclusiveOrg: '',
Cluster: '',
QueueId: '',
SpecIds: [],
}
},
getQueueList() {
return getResQueueCode({ cluster: this.dataInfo.Cluster }).then(res => {
res = res.data;
if (res.Code === 0) {
const data = res.Data;
const list = [];
for (let i = 0, iLen = data.length; i < iLen; i++) {
const item = data[i];
list.push({
k: item.ID,
v: `${item.QueueCode}(${getListValueWithKey(this.clusterList, item.Cluster)} - ${getListValueWithKey(this.aiCenterList, item.AiCenterCode)})`,
});
}
this.queueList.splice(0, Infinity, ...list);
if (this.queueList.length === 0) {
this.changeQueue();
}
}
}).catch(err => {
console.log(err);
});
},
getResSpecificationList() {
const params = {
cluster: this.dataInfo.Cluster,
queue: this.dataInfo.QueueId,
status: 2,
page: 1,
};
getResSpecificationList(params).then(res => {
res = res.data;
if (res.Code === 0) {
const list = res.Data.List;
const data = list.map((item) => {
const Queue = item.Queue;
const Spec = item.Spec;
const NGPU = `${Queue.ComputeResource}:${Spec.AccCardsNum === 0 ? '0' : Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Queue.AccCardType)}`;
return {
k: Spec.ID,
v: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB, ${this.$t('resourcesManagement.unitPrice')}:${Spec.UnitPrice}${this.$t('resourcesManagement.point_hr')}`,
}
});
this.specsList.splice(0, Infinity, ...data);
}
}).catch(err => {
console.log(err);
});
},
changeIsExclusive() {
this.dataInfo.exclusiveOrg = '';
this.dataInfo.ExclusiveOrg = '';
},
changeCluster() {
this.dataInfo.QueueId = '';
this.dataInfo.SpecIds = [];
this.queueList.splice(0, Infinity);
this.specsList.splice(0, Infinity);
this.getQueueList();
},
changeQueue() {

this.dataInfo.SpecIds = [];
this.specsList.splice(0, Infinity);
this.getResSpecificationList();
},
open() {
this.resetDataInfo();
@@ -126,8 +201,12 @@ export default {
//
} else if (this.type === 'edit') {
this.dataInfo = Object.assign(this.dataInfo, { ...this.data });
this.queueList.splice(0, Infinity);
this.specsList.splice(0, Infinity);
this.getQueueList().then(() => {
this.getResSpecificationList();
});
}
console.log('open', this.type, this.data);
this.$emit("open");
},
opened() {
@@ -141,7 +220,40 @@ export default {
this.$emit("update:visible", false);
},
confirm() {
console.log(this.dataInfo);
if (!this.dataInfo.SceneName || !this.dataInfo.JobType || !this.dataInfo.QueueId || !this.dataInfo.SpecIds.length || (this.dataInfo.IsExclusive === '1' && !this.dataInfo.ExclusiveOrg)) {
this.$message({
type: 'info',
message: this.$t('pleaseCompleteTheInformationFirst')
});
return;
}
const setApi = this.type === 'add' ? addResScene : updateResScene;
setApi({
...this.dataInfo,
action: this.type === 'edit' ? 'edit' : undefined,
IsExclusive: this.dataInfo.IsExclusive === '1',
}).then(res => {
res = res.data;
if (res.Code === 0) {
this.$message({
type: 'success',
message: this.$t('submittedSuccessfully')
});
this.$emit("confirm");
} else {
this.$message({
type: 'error',
message: this.$t('submittedFailed')
});
}
}).catch(err => {
console.log(err);
this.$message({
type: 'error',
message: this.$t('submittedFailed')
});
})

},
cancel() {
this.dialogShow = false;
@@ -201,6 +313,24 @@ export default {
width: 100%;
}
}

.specSel {
/deep/ .el-tag.el-tag--info {
max-width: 81%;
display: flex;
align-items: center;

.el-select__tags-text {
overflow: hidden;
text-overflow: ellipsis;
}

.el-tag__close {
flex-shrink: 0;
right: -5px;
}
}
}
}
}

@@ -216,4 +346,13 @@ export default {
}
}
}

.el-select-dropdown__item {
padding-left: 26px !important;
}

.el-select-dropdown__item.selected::after {
right: 0;
left: 6px;
}
</style>

+ 21
- 19
web_src/vuepages/pages/resources/components/SpecificationDialog.vue View File

@@ -1,12 +1,13 @@
<template>
<div class="base-dlg">
<BaseDialog :visible.sync="dialogShow" :width="`700px`" :title="type === 'add' ? '新增资源规格和单价信息' : '编辑资源规格和单价信息'"
<BaseDialog :visible.sync="dialogShow" :width="`700px`"
:title="type === 'add' ? $t('resourcesManagement.addResSpecificationAndPriceInfo') : $t('resourcesManagement.editResSpecificationAndPriceInfo')"
@open="open" @opened="opened" @close="close" @closed="closed">
<div class="dlg-content">
<div class="form">
<div class="form-row">
<div class="title required">
<span>资源池(队列)</span>
<span>{{ $t('resourcesManagement.resQueue') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.QueueId" :disabled="type === 'edit'">
@@ -16,16 +17,17 @@
</div>
<div class="form-row">
<div class="title">
<span>对应资源编码</span>
<span>{{ $t('resourcesManagement.sourceSpecCode') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.SourceSpecId" placeholder="云脑II需要填写对应的资源编码" :disabled="type === 'edit'">
<el-input v-model="dataInfo.SourceSpecId" :placeholder="$t('resourcesManagement.sourceSpecCodeTips')"
:disabled="type === 'edit'">
</el-input>
</div>
</div>
<div class="form-row">
<div class="title required">
<span>卡数</span>
<span>{{ $t('resourcesManagement.accCardsNum') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.AccCardsNum" type="number" placeholder="" :disabled="type === 'edit'">
@@ -34,7 +36,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>CPU数</span>
<span>{{ $t('resourcesManagement.cpuNum') }}</span>
</div>
<div class="content">
<el-input v-model="dataInfo.CpuCores" type="number" placeholder="" :disabled="type === 'edit'"></el-input>
@@ -42,7 +44,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>显存(GB)</span>
<span>{{ $t('resourcesManagement.gpuMem') }}(GB)</span>
</div>
<div class="content">
<el-input v-model="dataInfo.GPUMemGiB" type="number" placeholder="" :disabled="type === 'edit'">
@@ -51,7 +53,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>内存(GB)</span>
<span>{{ $t('resourcesManagement.mem') }}(GB)</span>
</div>
<div class="content">
<el-input v-model="dataInfo.MemGiB" type="number" placeholder="" :disabled="type === 'edit'"></el-input>
@@ -59,7 +61,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>共享内存(GB)</span>
<span>{{ $t('resourcesManagement.shareMem') }}(GB)</span>
</div>
<div class="content">
<el-input v-model="dataInfo.ShareMemGiB" type="number" placeholder="" :disabled="type === 'edit'">
@@ -68,7 +70,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>单价(积分/时)</span>
<span>{{ $t('resourcesManagement.unitPrice') }}({{ $t('resourcesManagement.point_hr') }})</span>
</div>
<div class="content">
<el-input v-model="dataInfo.UnitPrice" type="number" placeholder=""></el-input>
@@ -76,7 +78,7 @@
</div>
<div class="form-row">
<div class="title required">
<span>状态</span>
<span>{{ $t('status') }}</span>
</div>
<div class="content">
<el-select v-model="dataInfo.Status" :disabled="type === 'edit'">
@@ -87,8 +89,8 @@
<div class="form-row" style="margin-top: 20px">
<div class="title"></div>
<div class="content">
<el-button type="primary" class="btn confirm-btn" @click="confirm">确定</el-button>
<el-button class="btn" @click="cancel">取消</el-button>
<el-button type="primary" class="btn confirm-btn" @click="confirm">{{ $t('confirm') }}</el-button>
<el-button class="btn" @click="cancel">{{ $t('cancel') }}</el-button>
</div>
</div>
</div>
@@ -186,21 +188,21 @@ export default {
) {
this.$message({
type: 'info',
message: '请先完善信息!'
message: this.$t('pleaseCompleteTheInformationFirst')
});
return;
}
if (parseInt(this.dataInfo.AccCardsNum) != Number(this.dataInfo.AccCardsNum)) {
this.$message({
type: 'info',
message: '请输入正整数的卡数!'
message: this.$t('pleaseEnterPositiveIntegerCardsTotalNum')
});
return;
}
const setApi = this.type === 'add' ? addResSpecification : updateResSpecification;
setApi({
...this.dataInfo,
action: this.type === 'edit' ? 'edit' : undefined,
action: this.type === 'edit' ? 'on-shelf' : undefined,
AccCardsNum: Number(this.dataInfo.AccCardsNum),
CpuCores: Number(this.dataInfo.CpuCores),
MemGiB: Number(this.dataInfo.MemGiB),
@@ -213,20 +215,20 @@ export default {
if (res.Code === 0) {
this.$message({
type: 'success',
message: '提交成功!'
message: this.$t('submittedSuccessfully')
});
this.$emit("confirm");
} else {
this.$message({
type: 'error',
message: '提交失败!'
message: this.$t('submittedFailed')
});
}
}).catch(err => {
console.log(err);
this.$message({
type: 'error',
message: '提交失败!'
message: this.$t('submittedFailed')
});
})
},


+ 30
- 19
web_src/vuepages/pages/resources/queue/index.vue View File

@@ -1,6 +1,6 @@
<template>
<div>
<div class="title"><span>资源池(队列)</span></div>
<div class="title"><span>{{ $t('resourcesManagement.resQueue') }}</span></div>
<div class="tools-bar">
<div>
<el-select class="select" size="medium" v-model="selCluster" @change="selectChange">
@@ -17,37 +17,48 @@
</el-select>
</div>
<div>
<el-button size="medium" icon="el-icon-refresh" @click="syncComputerNetwork">同步智算网络</el-button>
<el-button type="primary" icon="el-icon-plus" size="medium" @click="showDialog('add')">新增资源池</el-button>
<el-button size="medium" icon="el-icon-refresh" @click="syncComputerNetwork">
{{ $t('resourcesManagement.syncAiNetwork') }}</el-button>
<el-button type="primary" icon="el-icon-plus" size="medium" @click="showDialog('add')">
{{ $t('resourcesManagement.addResQueueBtn') }}</el-button>
</div>
</div>
<div class="table-container">
<div style="min-height:600px;">
<el-table border :data="tableData" style="width: 100%" v-loading="loading" stripe>
<el-table-column prop="ID" label="ID" align="center" header-align="center" width="80"></el-table-column>
<el-table-column prop="QueueCode" label="资源池(队列)名称" align="center" header-align="center"></el-table-column>
<el-table-column prop="ClusterName" label="所属集群" align="center" header-align="center">
<el-table-column prop="QueueCode" :label="$t('resourcesManagement.resQueueName')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="ClusterName" :label="$t('resourcesManagement.whichCluster')" align="center"
header-align="center">
<template slot-scope="scope">
<span :title="scope.row.Cluster">{{ scope.row.ClusterName }}</span>
</template>
</el-table-column>
<el-table-column prop="AiCenterCode" label="智算中心ID" align="center" header-align="center"></el-table-column>
<el-table-column prop="AiCenterName" label="智算中心" align="center" header-align="center"></el-table-column>
<el-table-column prop="ComputeResourceName" label="计算资源" align="center" header-align="center">
<el-table-column prop="AiCenterCode" :label="$t('resourcesManagement.aiCenterID')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="AiCenterName" :label="$t('resourcesManagement.aiCenter')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="ComputeResourceName" :label="$t('resourcesManagement.computeResource')" align="center"
header-align="center">
</el-table-column>
<el-table-column prop="AccCardTypeName" label="卡类型" align="center" header-align="center"></el-table-column>
<el-table-column prop="CardsTotalNum" label="卡数 " align="center" header-align="center"></el-table-column>
<el-table-column prop="UpdatedTimeStr" label="最后更新时间" align="center" header-align="center"></el-table-column>
<el-table-column prop="Remark" label="备注" align="left" header-align="center" min-width="160">
<el-table-column prop="AccCardTypeName" :label="$t('resourcesManagement.accCardType')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="CardsTotalNum" :label="$t('resourcesManagement.cardsTotalNum')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="UpdatedTimeStr" :label="$t('resourcesManagement.lastUpdateTime')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="Remark" :label="$t('resourcesManagement.remark')" align="left" header-align="center"
min-width="160">
</el-table-column>
<el-table-column label="操作" align="center" header-align="center" width="80">
<el-table-column :label="$t('operation')" align="center" header-align="center" width="80">
<template slot-scope="scope">
<span class="op-btn" @click="showDialog('edit', scope.row)">修改</span>
<span class="op-btn" @click="showDialog('edit', scope.row)">{{ $t('edit') }}</span>
</template>
</el-table-column>
<template slot="empty">
<span style="font-size: 12px">{{
loading ? '加载中...' : '暂无数据'
loading ? $t('loading') : $t('noData')
}}</span>
</template>
</el-table>
@@ -79,13 +90,13 @@ export default {
data() {
return {
selCluster: '',
clusterList: [{ k: '', v: '全部集群' }, ...CLUSTERS],
clusterList: [{ k: '', v: this.$t('resourcesManagement.allCluster') }, ...CLUSTERS],
selComputingCenter: '',
computingCenterList: [{ k: '', v: '全部智算中心' }, ...AI_CENTER],
computingCenterList: [{ k: '', v: this.$t('resourcesManagement.allAiCenter') }, ...AI_CENTER],
selComputingType: '',
computingTypeList: [{ k: '', v: '全部计算资源' }, ...COMPUTER_RESOURCES],
computingTypeList: [{ k: '', v: this.$t('resourcesManagement.allComputeResource') }, ...COMPUTER_RESOURCES],
selCardType: '',
cardTypeList: [{ k: '', v: '全部卡类型' }, ...ACC_CARD_TYPE],
cardTypeList: [{ k: '', v: this.$t('resourcesManagement.allAccCardType') }, ...ACC_CARD_TYPE],
syncLoading: false,
loading: false,
tableData: [],


+ 114
- 52
web_src/vuepages/pages/resources/scene/index.vue View File

@@ -1,6 +1,6 @@
<template>
<div>
<div class="title"><span>算力资源应用场景管理</span></div>
<div class="title"><span>{{ $t('resourcesManagement.resSceneManagement') }}</span></div>
<div class="tools-bar">
<div>
<el-select class="select" size="medium" v-model="selTaskType" @change="selectChange">
@@ -17,32 +17,52 @@
</el-select>
</div>
<div>
<el-button type="primary" icon="el-icon-plus" size="medium" @click="showDialog('add')">新增应用场景</el-button>
<el-button type="primary" icon="el-icon-plus" size="medium" @click="showDialog('add')">
{{ $t('resourcesManagement.addResSceneBtn') }}</el-button>
</div>
</div>
<div class="table-container">
<div style="min-height:600px;">
<el-table border :data="tableData" style="width: 100%" v-loading="loading" stripe>
<el-table-column prop="id" label="ID" align="center" header-align="center" width="100"></el-table-column>
<el-table-column prop="name" label="应用场景名称" align="center" header-align="center"></el-table-column>
<el-table-column prop="taskType" label="任务类型" align="center" header-align="center"></el-table-column>
<el-table-column prop="isExclusive" label="是否专属" align="center" header-align="center"></el-table-column>
<el-table-column prop="exclusiveOrg" label="专属组织" align="center" header-align="center"></el-table-column>
<el-table-column prop="queue" label="资源池(队列)" align="center" header-align="center"></el-table-column>
<el-table-column prop="specs" label="资源规格" align="left" header-align="center">
<el-table-column prop="ID" label="ID" align="center" header-align="center" width="60"></el-table-column>
<el-table-column prop="SceneName" :label="$t('resourcesManagement.resSceneName')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="JobTypeStr" :label="$t('resourcesManagement.jobType')" align="center"
header-align="center" width="120">
</el-table-column>
<el-table-column prop="IsExclusiveStr" :label="$t('resourcesManagement.isExclusive')" align="center"
header-align="center" width="120">
<template slot-scope="scope">
<span :style="{ color: scope.row.IsExclusive ? 'red' : '' }">{{ scope.row.IsExclusiveStr }}</span>
</template>
</el-table-column>
<el-table-column prop="ExclusiveOrg" :label="$t('resourcesManagement.exclusiveOrg')" align="center"
header-align="center">
<template slot-scope="scope">
{{ scope.row.specs }}
<span>{{ scope.row.IsExclusive ? scope.row.ExclusiveOrg : '--' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" header-align="center" width="100">
<el-table-column prop="AiCenterStr" :label="$t('resourcesManagement.aiCenter')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="QueueStr" :label="$t('resourcesManagement.resQueue')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="SpecsList" :label="$t('resourcesManagement.resourceSpecification')" align="left"
header-align="center" min-width="180">
<template slot-scope="scope">
<span class="op-btn" @click="showDialog('edit', scope.row)">修改</span>
<span class="op-btn" style="color:red" @click="deleteRow(scope.row)">删除</span>
<div v-for="item in scope.row.SpecsList" :key="item.k">
<span>{{ item.v }}</span>
</div>
</template>
</el-table-column>
<el-table-column :label="$t('operation')" align="center" header-align="center" width="100">
<template slot-scope="scope">
<span class="op-btn" @click="showDialog('edit', scope.row)">{{ $t('edit') }}</span>
<span class="op-btn" style="color:red" @click="deleteRow(scope.row)">{{ $t('delete') }}</span>
</template>
</el-table-column>
<template slot="empty">
<span style="font-size: 12px">{{
loading ? '加载中...' : '暂无数据'
loading ? $t('loading') : $t('noData')
}}</span>
</template>
</el-table>
@@ -65,8 +85,8 @@

<script>
import SceneDialog from '../components/SceneDialog.vue';
import { getQueueList, getResQueueCode } from '~/apis/modules/resources';
import { CLUSTERS, AI_CENTER, ACC_CARD_TYPE } from '~/const';
import { getQueueList, getResQueueCode, getResSceneList, updateResScene } from '~/apis/modules/resources';
import { JOB_TYPE, CLUSTERS, AI_CENTER, ACC_CARD_TYPE } from '~/const';
import { getListValueWithKey } from '~/utils';
import { formatDate } from 'element-ui/lib/utils/date-util';

@@ -74,14 +94,15 @@ export default {
data() {
return {
selTaskType: '',
taskTypeList: [{ k: '', v: '全部任务类型' }, { k: '1', v: '调试任务' }, { k: '2', v: '训练任务' }, { k: '3', v: '评测任务' }, { k: '4', v: '推理任务' }],
taskTypeList: [{ k: '', v: this.$t('resourcesManagement.allJobType') }, ...JOB_TYPE],
selIsExclusive: '',
isExclusiveList: [{ k: '', v: '全部专属和通用' }, { k: '1', v: '专属' }, { k: '2', v: '通用' }],
isExclusiveList: [{ k: '', v: this.$t('resourcesManagement.allExclusiveAndCommonUse') }, { k: '1', v: this.$t('resourcesManagement.exclusive') }, { k: '2', v: this.$t('resourcesManagement.commonUse') }],
selQueue: '',
queueList: [{ k: '', v: '全部资源池队列' }],
queueList: [{ k: '', v: this.$t('resourcesManagement.allResQueue') }],
clusterList: [...CLUSTERS],
selAiCenter: '',
aiCenterList: [{ k: '', v: '全部智算中心' }, ...AI_CENTER],
aiCenterList: [{ k: '', v: this.$t('resourcesManagement.allAiCenter') }, ...AI_CENTER],
accCardTypeList: [...ACC_CARD_TYPE],
loading: false,
tableData: [],
pageInfo: {
@@ -118,31 +139,49 @@ export default {
},
getTableData() {
const params = {
taskType: this.selTaskType,
isExclusive: this.selIsExclusive,
jobType: this.selTaskType,
IsExclusive: this.selIsExclusive,
queue: this.selQueue,
center: this.selAiCenter,
page: this.pageInfo.curpage,
pagesize: this.pageInfo.pageSize,
};
console.log('params', params);
this.loading = true;
getQueueList(params).then(res => {
getResSceneList(params).then(res => {
this.loading = false;
// const data = res.data.
const data = new Array(20).fill(0).map((_, index) => {
return {
index: index,
id: `id-${index}-${Math.random().toFixed(2)}`,
name: `name-${index}-${Math.random().toFixed(2)}`,
taskType: `taskType-${index}-${Math.random().toFixed(2)}`,
isExclusive: `isExclusive-${index}-${Math.random().toFixed(2)}`,
exclusiveOrg: `exclusiveOrg-${index}-${Math.random().toFixed(2)}`,
queue: `queue-${index}-${Math.random().toFixed(2)}`,
specs: `spec-${index}-${Math.random().toFixed(2)}`,
};
});
this.tableData = data;
this.pageInfo.total = 99;
res = res.data;
if (res.Code === 0) {
const list = res.Data.List;
const data = list.map((item) => {
const Specs = item.Specs;
const specsList = [];
for (let i = 0, iLen = Specs.length; i < iLen; i++) {
const Spec = Specs[i];
const NGPU = `${item.ComputeResource}:${Spec.AccCardsNum === 0 ? '0' : Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, item.AccCardType)}`;
specsList.push({
k: Spec.ID,
v: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB, ${this.$t('resourcesManagement.unitPrice')}:${Spec.UnitPrice}${this.$t('resourcesManagement.point_hr')}`,
})
}
return {
ID: item.ID,
SceneName: item.SceneName,
JobType: item.JobType,
JobTypeStr: getListValueWithKey(this.taskTypeList, item.JobType),
IsExclusive: item.IsExclusive,
IsExclusiveStr: getListValueWithKey(this.isExclusiveList, item.IsExclusive ? '1' : '2'),
ExclusiveOrg: item.ExclusiveOrg,
AiCenterCode: item.AiCenterCode,
AiCenterStr: getListValueWithKey(this.aiCenterList, item.AiCenterCode),
Cluster: item.Cluster,
QueueId: item.QueueId,
QueueStr: item.QueueCode ? `${item.QueueCode}(${getListValueWithKey(this.clusterList, item.Cluster)} - ${getListValueWithKey(this.aiCenterList, item.AiCenterCode)})` : '--',
SpecsList: specsList,
}
});
this.tableData = data;
this.pageInfo.total = res.Data.TotalSize;
}
}).catch(err => {
console.log(err);
this.loading = false;
@@ -157,26 +196,49 @@ export default {
this.getTableData();
},
deleteRow(row) {
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
this.$confirm(this.$t('resourcesManagement.resSceneDeleteConfirm'), this.$t('tips'), {
confirmButtonText: this.$t('confirm'),
cancelButtonText: this.$t('cancel'),
type: 'warning',
lockScroll: false,
}).then(() => {
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
updateResScene({
action: 'delete',
ID: row.ID,
}).then(res => {
res = res.data;
if (res.Code === 0) {
this.$message({
type: 'success',
message: this.$t('submittedSuccessfully')
});
this.getTableData();
} else {
this.$message({
type: 'error',
message: this.$t('submittedFailed')
});
}
}).catch(err => {
this.$message({
type: 'error',
message: this.$t('submittedFailed')
});
});
});
}).catch(() => { });
},
showDialog(type, data) {
this.sceneDialogType = type;
this.sceneDialogData = data ? { ...data } : {};
this.sceneDialogData = data ? {
ID: data.ID,
SceneName: data.SceneName,
JobType: data.JobType,
IsExclusive: data.IsExclusive ? '1' : '2',
ExclusiveOrg: data.ExclusiveOrg,
Cluster: data.Cluster,
QueueId: data.QueueId,
SpecIds: data.SpecsList.map((item) => item.k),
} : {};
this.sceneDialogShow = true;
},
sceneDialogConfirm() {


+ 50
- 31
web_src/vuepages/pages/resources/specification/index.vue View File

@@ -1,6 +1,6 @@
<template>
<div>
<div class="title"><span>资源规格单价管理</span></div>
<div class="title"><span>{{ $t('resourcesManagement.resSpecificationAndPriceManagement') }}</span></div>
<div class="tools-bar">
<div>
<el-select class="select" size="medium" v-model="selQueue" @change="selectChange">
@@ -12,55 +12,74 @@
</div>
<div>
<!-- syncComputerNetwork -->
<el-button size="medium" icon="el-icon-refresh" @click="confirmOperate">同步智算网络</el-button>
<el-button type="primary" icon="el-icon-plus" size="medium" @click="showDialog('add')">新增资源规格</el-button>
<el-button size="medium" icon="el-icon-refresh" @click="confirmOperate">
{{ $t('resourcesManagement.syncAiNetwork') }}</el-button>
<el-button type="primary" icon="el-icon-plus" size="medium" @click="showDialog('add')">
{{ $t('resourcesManagement.addResSpecificationBtn') }}</el-button>
</div>
</div>
<div class="table-container">
<div style="min-height:600px;">
<el-table border :data="tableData" style="width: 100%" v-loading="loading" stripe>
<el-table-column prop="ID" label="ID" align="center" header-align="center" width="60"></el-table-column>
<el-table-column prop="SpecStr" label="资源规格" align="left" header-align="center" min-width="160">
<el-table-column prop="SpecStr" :label="$t('resourcesManagement.resourceSpecification')" align="left"
header-align="center" min-width="160">
</el-table-column>
<el-table-column prop="QueueInfo" label="资源池(队列)" align="center" header-align="center" min-width="100">
<el-table-column prop="QueueInfo" :label="$t('resourcesManagement.resQueue')" align="center"
header-align="center" min-width="100">
</el-table-column>
<el-table-column prop="SourceSpecId" label="智算网络资源规格ID" align="center" header-align="center">
<el-table-column prop="SourceSpecId" :label="$t('resourcesManagement.sourceSpecId')" align="center"
header-align="center">
</el-table-column>
<el-table-column prop="AccCardsNum" label="卡数 " align="center" header-align="center"></el-table-column>
<el-table-column prop="CpuCores" label="CPU " align="center" header-align="center"></el-table-column>
<el-table-column prop="GPUMemGiB" label="显存(GB)" align="center" header-align="center"></el-table-column>
<el-table-column prop="MemGiB" label="内存(GB) " align="center" header-align="center"></el-table-column>
<el-table-column prop="ShareMemGiB" label="共享内存(GB)" align="center" header-align="center"></el-table-column>
<el-table-column prop="UpdatedTimeStr" label="最后更新时间" align="center" header-align="center"></el-table-column>
<el-table-column prop="UnitPrice" label="单价(积分/时)" align="center" header-align="center">
<el-table-column prop="AccCardsNum" :label="$t('resourcesManagement.accCardsNum')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="CpuCores" :label="$t('resourcesManagement.cpuNum') " align="center" header-align="center"></el-table-column>
<el-table-column prop="GPUMemGiB" :label="`${$t('resourcesManagement.gpuMem')}(GB)`" align="center"
header-align="center"></el-table-column>
<el-table-column prop="MemGiB" :label="`${$t('resourcesManagement.mem')}(GB)`" align="center"
header-align="center"></el-table-column>
<el-table-column prop="ShareMemGiB" :label="`${$t('resourcesManagement.shareMem')}(GB)`" align="center"
header-align="center"></el-table-column>
<el-table-column prop="UpdatedTimeStr" :label="$t('resourcesManagement.lastUpdateTime')" align="center"
header-align="center"></el-table-column>
<el-table-column prop="UnitPrice"
:label="`${$t('resourcesManagement.unitPrice')}(${$t('resourcesManagement.point_hr')})`" align="center"
header-align="center">
<template slot-scope="scope">
<span style="font-weight:600;font-size:14px;">{{ scope.row.UnitPrice }}</span>
</template>
</el-table-column>
<el-table-column prop="StatusStr" label="状态" align="center" header-align="center" width="100">
<el-table-column prop="StatusStr" :label="$t('resourcesManagement.status')" align="center"
header-align="center" width="100">
<template slot-scope="scope">
<span :style="{ color: scope.row.Status == '2' ? 'rgb(82, 196, 26)' : 'rgb(245, 34, 45)' }">{{
scope.row.StatusStr
}}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" header-align="center" width="100">
<el-table-column :label="$t('operation')" align="center" header-align="center" width="100">
<template slot-scope="scope">
<span v-if="scope.row.Status == '1'">
<span class="op-btn" @click="showDialog('edit', scope.row)">定价上架</span>
<span v-if="scope.row.Status == '1' && !scope.row.UnitPrice">
<span class="op-btn" @click="showDialog('edit', scope.row)">{{
$t('resourcesManagement.toSetPriceAndOnShelf')
}}</span>
</span>
<span v-if="scope.row.Status == '2'">
<span class="op-btn" @click="showDialog('edit', scope.row)">修改</span>
<span class="op-btn" @click="onOrOffShelf('off-shelf', scope.row)">下架</span>
<span class="op-btn" @click="showDialog('edit', scope.row)">{{ $t('edit') }}</span>
<span class="op-btn" @click="onOrOffShelf('off-shelf', scope.row)">{{
$t('resourcesManagement.toOffShelf')
}}</span>
</span>
<span v-if="scope.row.Status == '3'">
<span class="op-btn" @click="onOrOffShelf('on-shelf', scope.row)">上架</span>
<span v-if="scope.row.Status == '3' || scope.row.Status == '1' && scope.row.UnitPrice">
<span class="op-btn" @click="onOrOffShelf('on-shelf', scope.row)">{{
$t('resourcesManagement.toOnShelf')
}}</span>
</span>
</template>
</el-table-column>
<template slot="empty">
<span style="font-size: 12px">{{
loading ? '加载中...' : '暂无数据'
loading ? $t('loading') : $t('noData')
}}</span>
</template>
</el-table>
@@ -92,9 +111,9 @@ export default {
data() {
return {
selQueue: '',
queueList: [{ k: '', v: '全部资源池' }],
queueList: [{ k: '', v: this.$t('resourcesManagement.allResQueue') }],
selStatus: '',
statusList: [{ k: '', v: '全部状态' }, ...SPECIFICATION_STATUS],
statusList: [{ k: '', v: this.$t('resourcesManagement.allStatus') }, ...SPECIFICATION_STATUS],
clusterList: [...CLUSTERS],
aiCenterList: [...AI_CENTER],
accCardTypeList: [...ACC_CARD_TYPE],
@@ -152,7 +171,7 @@ export default {
const NGPU = `${Queue.ComputeResource}:${Spec.AccCardsNum === 0 ? '0' : Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Queue.AccCardType)}`;
return {
...Spec,
SpecStr: `${NGPU}, CPU:${Spec.CpuCores}, 显存:${Spec.GPUMemGiB}GB, 内存:${Spec.MemGiB}GB, 共享内存:${Spec.ShareMemGiB}GB`,
SpecStr: `${NGPU}, CPU:${Spec.CpuCores}, ${this.$t('resourcesManagement.gpuMem')}:${Spec.GPUMemGiB}GB, ${this.$t('resourcesManagement.mem')}:${Spec.MemGiB}GB, ${this.$t('resourcesManagement.shareMem')}:${Spec.ShareMemGiB}GB`,
QueueId: Queue.ID,
QueueInfo: `${Queue.QueueCode}(${getListValueWithKey(this.clusterList, Queue.Cluster)} - ${getListValueWithKey(this.aiCenterList, Queue.AiCenterCode)})`,
UpdatedTimeStr: formatDate(new Date(Spec.UpdatedTime * 1000), 'yyyy-MM-dd HH:mm:ss'),
@@ -189,9 +208,9 @@ export default {
this.getTableData();
},
onOrOffShelf(type, data) {
this.$confirm(type === 'on-shelf' ? '请确认是否上架该规格?' : '请确认是否下架该规格?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
this.$confirm(type === 'on-shelf' ? this.$t('resourcesManagement.onShelfConfirm') : this.$t('resourcesManagement.offShelfConfirm'), this.$t('tips'), {
confirmButtonText: this.$t('confirm'),
cancelButtonText: this.$t('cancel'),
type: 'warning',
lockScroll: false,
}).then(() => {
@@ -203,20 +222,20 @@ export default {
if (res.Code === 0) {
this.$message({
type: 'success',
message: '操作成功!'
message: this.$t('submittedSuccessfully')
});
this.getTableData();
} else {
this.$message({
type: 'error',
message: '操作失败!'
message: this.$t('submittedFailed')
});
}
}).catch(err => {
console.log(err);
this.$message({
type: 'error',
message: '操作失败!'
message: this.$t('submittedFailed')
});
});
}).catch(() => { });


Loading…
Cancel
Save