|
|
@@ -0,0 +1,451 @@ |
|
|
|
<template> |
|
|
|
<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"> |
|
|
|
<el-option v-for="item in queueList" :key="item.k" :label="item.v" :value="item.k" /> |
|
|
|
</el-select> |
|
|
|
<el-select class="select" size="medium" v-model="selStatus" @change="selectChange"> |
|
|
|
<el-option v-for="item in statusList" :key="item.k" :label="item.v" :value="item.k" /> |
|
|
|
</el-select> |
|
|
|
</div> |
|
|
|
<div> |
|
|
|
<el-button size="medium" icon="el-icon-refresh" @click="syncComputerNetwork" v-loading="syncLoading"> |
|
|
|
{{ $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="$t('resourcesManagement.resourceSpecification')" align="left" |
|
|
|
header-align="center" min-width="160"> |
|
|
|
</el-table-column> |
|
|
|
<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="$t('resourcesManagement.sourceSpecCode')" align="center" |
|
|
|
header-align="center"> |
|
|
|
</el-table-column> |
|
|
|
<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="$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="$t('operation')" align="center" header-align="center" width="100"> |
|
|
|
<template slot-scope="scope"> |
|
|
|
<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, true)">{{ $t('edit') }}</span> |
|
|
|
<span class="op-btn" @click="offShelfPrev(scope.row)">{{ |
|
|
|
$t('resourcesManagement.toOffShelf') |
|
|
|
}}</span> |
|
|
|
</span> |
|
|
|
<span v-if="scope.row.Status == '3' || scope.row.Status == '1' && scope.row.UnitPrice"> |
|
|
|
<span class="op-btn" @click="onShelf(scope.row)">{{ |
|
|
|
$t('resourcesManagement.toOnShelf') |
|
|
|
}}</span> |
|
|
|
</span> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
<template slot="empty"> |
|
|
|
<span style="font-size: 12px">{{ |
|
|
|
loading ? $t('loading') : $t('noData') |
|
|
|
}}</span> |
|
|
|
</template> |
|
|
|
</el-table> |
|
|
|
</div> |
|
|
|
<div class="__r_p_pagination"> |
|
|
|
<div style="margin-top: 2rem"> |
|
|
|
<div class="center"> |
|
|
|
<el-pagination background @current-change="currentChange" :current-page="pageInfo.curpage" |
|
|
|
:page-sizes="pageInfo.pageSizes" :page-size="pageInfo.pageSize" |
|
|
|
layout="total, sizes, prev, pager, next, jumper" :total="pageInfo.total"> |
|
|
|
</el-pagination> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<SpecificationDialog :visible.sync="specificationDialogShow" :type="specificationDialogType" |
|
|
|
:editOr="specificationDialogEditOr" :data="specificationDialogData" @confirm="specificationDialogConfirm"> |
|
|
|
</SpecificationDialog> |
|
|
|
|
|
|
|
<BaseDialog :visible.sync="offShelfDialogShow" :width="`600px`" :title="$t('tips')"> |
|
|
|
<div class="form"> |
|
|
|
<div class="form-row" style="flex-direction:column;"> |
|
|
|
<div class="content" style="margin:8px 0">{{ $t('resourcesManagement.offShelfDlgTip1') }}</div> |
|
|
|
<div class="content" style="margin:8px 0;font-weight: bold;">{{ offSelfDialogContent }}</div> |
|
|
|
<div class="content" style="margin:8px 0">{{ $t('resourcesManagement.offShelfDlgTip2') }}</div> |
|
|
|
</div> |
|
|
|
<div class="form-row" style="margin-top: 20px"> |
|
|
|
<div class="content"> |
|
|
|
<el-button type="primary" class="btn confirm-btn" @click="offShelf">{{ $t('confirm') }}</el-button> |
|
|
|
<el-button class="btn" @click="offShelfDialogShow = false">{{ $t('cancel') }}</el-button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</BaseDialog> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script> |
|
|
|
import SpecificationDialog from '../components/SpecificationDialog.vue'; |
|
|
|
import BaseDialog from '~/components/BaseDialog.vue'; |
|
|
|
import { getResQueueCode, getResSpecificationList, updateResSpecification, syncResSpecification, getResSpecificationScenes } from '~/apis/modules/resources'; |
|
|
|
import { SPECIFICATION_STATUS, CLUSTERS, ACC_CARD_TYPE } from '~/const'; |
|
|
|
import { getListValueWithKey } from '~/utils'; |
|
|
|
import { formatDate } from 'element-ui/lib/utils/date-util'; |
|
|
|
|
|
|
|
export default { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
selQueue: '', |
|
|
|
queueList: [{ k: '', v: this.$t('resourcesManagement.allResQueue') }], |
|
|
|
selStatus: '', |
|
|
|
statusList: [{ k: '', v: this.$t('resourcesManagement.allStatus') }, ...SPECIFICATION_STATUS], |
|
|
|
clusterList: [...CLUSTERS], |
|
|
|
accCardTypeList: [...ACC_CARD_TYPE], |
|
|
|
syncLoading: false, |
|
|
|
loading: false, |
|
|
|
tableData: [], |
|
|
|
pageInfo: { |
|
|
|
curpage: 1, |
|
|
|
pageSize: 10, |
|
|
|
pageSizes: [10], |
|
|
|
total: 0, |
|
|
|
}, |
|
|
|
specificationDialogShow: false, |
|
|
|
specificationDialogType: 'add', |
|
|
|
specificationDialogEditOr: false, |
|
|
|
specificationDialogData: {}, |
|
|
|
|
|
|
|
offShelfDialogShow: false, |
|
|
|
offShelfDialogData: {}, |
|
|
|
offSelfDialogContent: '', |
|
|
|
}; |
|
|
|
}, |
|
|
|
components: { BaseDialog, SpecificationDialog }, |
|
|
|
methods: { |
|
|
|
getQueueList() { |
|
|
|
getResQueueCode().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)} - ${item.AiCenterName})`, |
|
|
|
}); |
|
|
|
} |
|
|
|
this.queueList.push(...list); |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err); |
|
|
|
}); |
|
|
|
}, |
|
|
|
getTableData() { |
|
|
|
const params = { |
|
|
|
queue: this.selQueue, |
|
|
|
status: this.selStatus, |
|
|
|
page: this.pageInfo.curpage, |
|
|
|
pagesize: this.pageInfo.pageSize, |
|
|
|
}; |
|
|
|
this.loading = true; |
|
|
|
getResSpecificationList(params).then(res => { |
|
|
|
this.loading = false; |
|
|
|
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)}`; |
|
|
|
const NGPU = `${Queue.ComputeResource}:${Spec.AccCardsNum + '*' + getListValueWithKey(this.accCardTypeList, Queue.AccCardType)}`; |
|
|
|
return { |
|
|
|
...Spec, |
|
|
|
SourceSpecId: Spec.SourceSpecId || '--', |
|
|
|
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)} - ${Queue.AiCenterName})`, |
|
|
|
UpdatedTimeStr: formatDate(new Date(Spec.UpdatedTime * 1000), 'yyyy-MM-dd HH:mm:ss'), |
|
|
|
Status: Spec.Status.toString(), |
|
|
|
StatusStr: getListValueWithKey(this.statusList, Spec.Status.toString()), |
|
|
|
} |
|
|
|
}); |
|
|
|
this.tableData = data; |
|
|
|
this.pageInfo.total = res.Data.TotalSize; |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err); |
|
|
|
this.loading = false; |
|
|
|
}); |
|
|
|
}, |
|
|
|
syncComputerNetwork() { |
|
|
|
this.syncLoading = true; |
|
|
|
syncResSpecification().then(res => { |
|
|
|
this.syncLoading = false; |
|
|
|
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 => { |
|
|
|
console.log(err); |
|
|
|
this.syncLoading = false; |
|
|
|
this.$message({ |
|
|
|
type: 'error', |
|
|
|
message: this.$t('submittedFailed') |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
selectChange() { |
|
|
|
this.pageInfo.curpage = 1; |
|
|
|
this.getTableData(); |
|
|
|
}, |
|
|
|
currentChange(val) { |
|
|
|
this.pageInfo.curpage = val; |
|
|
|
this.getTableData(); |
|
|
|
}, |
|
|
|
showDialog(type, data, editOr) { |
|
|
|
this.specificationDialogType = type; |
|
|
|
this.specificationDialogEditOr = !!editOr; |
|
|
|
this.specificationDialogData = data ? { ...data } : {}; |
|
|
|
this.specificationDialogShow = true; |
|
|
|
}, |
|
|
|
specificationDialogConfirm() { |
|
|
|
this.specificationDialogShow = false; |
|
|
|
this.getTableData(); |
|
|
|
}, |
|
|
|
onShelf(data) { |
|
|
|
const type = 'on-shelf'; |
|
|
|
this.$confirm(type === 'on-shelf' ? this.$t('resourcesManagement.onShelfConfirm') : this.$t('resourcesManagement.offShelfConfirm'), this.$t('tips'), { |
|
|
|
confirmButtonText: this.$t('confirm1'), |
|
|
|
cancelButtonText: this.$t('cancel'), |
|
|
|
type: 'warning', |
|
|
|
lockScroll: false, |
|
|
|
}).then(() => { |
|
|
|
updateResSpecification({ |
|
|
|
ID: data.ID, |
|
|
|
action: type |
|
|
|
}).then(res => { |
|
|
|
res = res.data; |
|
|
|
if (res.Code === 0) { |
|
|
|
this.$message({ |
|
|
|
type: 'success', |
|
|
|
message: this.$t('submittedSuccessfully') |
|
|
|
}); |
|
|
|
this.getTableData(); |
|
|
|
} else { |
|
|
|
if (type === 'on-shelf' && res.Code === 1001) { |
|
|
|
this.$message({ |
|
|
|
type: 'info', |
|
|
|
message: this.$t('resourcesManagement.onShelfCode1001') |
|
|
|
}); |
|
|
|
} else { |
|
|
|
this.$message({ |
|
|
|
type: 'error', |
|
|
|
message: this.$t('submittedFailed') |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err); |
|
|
|
this.$message({ |
|
|
|
type: 'error', |
|
|
|
message: this.$t('submittedFailed') |
|
|
|
}); |
|
|
|
}); |
|
|
|
}).catch(() => { }); |
|
|
|
}, |
|
|
|
offShelfPrev(data) { |
|
|
|
this.$confirm(this.$t('resourcesManagement.offShelfConfirm'), this.$t('tips'), { |
|
|
|
confirmButtonText: this.$t('confirm1'), |
|
|
|
cancelButtonText: this.$t('cancel'), |
|
|
|
type: 'warning', |
|
|
|
lockScroll: false, |
|
|
|
}).then(() => { |
|
|
|
this.offShelfDialogData = data; |
|
|
|
getResSpecificationScenes({ ID: data.ID }).then(res => { |
|
|
|
res = res.data; |
|
|
|
if (res.Code === 0) { |
|
|
|
if (res.Data.List.length) { |
|
|
|
this.offShelfDialogShow = true; |
|
|
|
this.offSelfDialogContent = res.Data.List.map((item) => `[${item.ID}]${item.SceneName}`).join(', '); |
|
|
|
} else { |
|
|
|
this.offShelf(); |
|
|
|
} |
|
|
|
} else { |
|
|
|
console.log(res); |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err); |
|
|
|
}); |
|
|
|
}).catch(() => { }); |
|
|
|
}, |
|
|
|
offShelf() { |
|
|
|
updateResSpecification({ |
|
|
|
ID: this.offShelfDialogData.ID, |
|
|
|
action: 'off-shelf' |
|
|
|
}).then(res => { |
|
|
|
res = res.data; |
|
|
|
if (res.Code === 0) { |
|
|
|
this.$message({ |
|
|
|
type: 'success', |
|
|
|
message: this.$t('submittedSuccessfully') |
|
|
|
}); |
|
|
|
this.offShelfDialogShow = false; |
|
|
|
this.getTableData(); |
|
|
|
} else { |
|
|
|
this.$message({ |
|
|
|
type: 'error', |
|
|
|
message: this.$t('submittedFailed') |
|
|
|
}); |
|
|
|
} |
|
|
|
}).catch(err => { |
|
|
|
console.log(err); |
|
|
|
this.$message({ |
|
|
|
type: 'error', |
|
|
|
message: this.$t('submittedFailed') |
|
|
|
}); |
|
|
|
}); |
|
|
|
}, |
|
|
|
}, |
|
|
|
mounted: function () { |
|
|
|
this.getQueueList(); |
|
|
|
this.getTableData(); |
|
|
|
}, |
|
|
|
beforeDestroy: function () { |
|
|
|
}, |
|
|
|
}; |
|
|
|
</script> |
|
|
|
|
|
|
|
<style scoped lang="less"> |
|
|
|
.title { |
|
|
|
height: 30px; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
margin-bottom: 5px; |
|
|
|
|
|
|
|
span { |
|
|
|
font-weight: 700; |
|
|
|
font-size: 16px; |
|
|
|
color: rgb(16, 16, 16); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.tools-bar { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: space-between; |
|
|
|
margin-bottom: 10px; |
|
|
|
|
|
|
|
.select { |
|
|
|
margin-right: 10px; |
|
|
|
|
|
|
|
/deep/ .el-input__inner { |
|
|
|
border-radius: 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.table-container { |
|
|
|
margin-bottom: 16px; |
|
|
|
|
|
|
|
/deep/ .el-table__header { |
|
|
|
th { |
|
|
|
background: rgb(245, 245, 246); |
|
|
|
font-size: 12px; |
|
|
|
color: rgb(36, 36, 36); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/deep/ .el-table__body { |
|
|
|
td { |
|
|
|
font-size: 12px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.op-btn { |
|
|
|
cursor: pointer; |
|
|
|
font-size: 12px; |
|
|
|
color: rgb(25, 103, 252); |
|
|
|
margin-right: 4px; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.center { |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
} |
|
|
|
|
|
|
|
.form { |
|
|
|
margin: 5px 0 5px 0; |
|
|
|
display: flex; |
|
|
|
justify-content: center; |
|
|
|
flex-direction: column; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
|
|
|
|
.form-row { |
|
|
|
display: flex; |
|
|
|
min-height: 42px; |
|
|
|
margin-bottom: 4px; |
|
|
|
|
|
|
|
.content { |
|
|
|
width: 500px; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
.btn { |
|
|
|
color: rgb(2, 0, 4); |
|
|
|
background-color: rgb(194, 199, 204); |
|
|
|
border-color: rgb(194, 199, 204); |
|
|
|
|
|
|
|
&.confirm-btn { |
|
|
|
color: #fff; |
|
|
|
background-color: rgb(56, 158, 13); |
|
|
|
border-color: rgb(56, 158, 13); |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |