merge
|
@ -0,0 +1,47 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 计量计费获取集群及成员集群列表接口
|
||||
export function getClusterList(params) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/kapis/resources.kubesphere.io/v1alpha3/clusters`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 计量计费获取集群-节点列表接口
|
||||
export function getNodeList(cluster, params) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/kapis/clusters/${cluster}/resources.kubesphere.io/v1alpha3/nodes`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 消费账单接口
|
||||
export function getBillNum(params) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/kapis/clusters/${params.resources_filter}/metering.kubesphere.io/v1alpha1/cluster`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 截止到昨天的消费历史
|
||||
export function getHistoryCost(params) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + '/kapis/resources.kubesphere.io/v1alpha3/clusters',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 当前包含的资源
|
||||
export function getResource(params) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + `/kapis/clusters/${params.clusterName}/metering.kubesphere.io/v1alpha1/nodes`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
0
|
|
@ -0,0 +1,120 @@
|
|||
// 大屏云厂商服务器数量查询接口
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getTotalName() {
|
||||
return request({
|
||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryByManufacturer',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
// 大屏服务器数量统计接口
|
||||
export function getTotalNum() {
|
||||
return request({
|
||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryDeviceCount',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 大屏地球地区查询接口
|
||||
export function getEarthRegion() {
|
||||
return request({
|
||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryByArea',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 大屏地球各个区域服务器资源详细接口
|
||||
export function getEarthDetails(area) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_FUNCTION_API + '/function/device/queryResDetailByArea?area=' + area,
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// CPU平均使用率接口
|
||||
export function getCpuAverage(start, end, step) {
|
||||
return request({
|
||||
url: '/monitoringscreen/api/v1/query_range?query=avg(1%20-%20avg(rate(node_cpu_seconds_total%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%2Cmode%3D%22idle%22%7D%5B2m%5D))%20by%20(instance))%20*%20100' + '&start=' + start + '&end=' + end + '&step=' + step + '&_=1642578431700',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 内存平均使用率接口
|
||||
export function getRamAverage(start, end, step) {
|
||||
return request({
|
||||
url: '/monitoringscreen/api/v1/query_range?query=(sum(node_memory_MemTotal_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D%20-%20node_memory_MemAvailable_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D)%20%2F%20sum(node_memory_MemTotal_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D))*100' + '&start=' + start + '&end=' + end + '&step=' + step + '&_=1642578431700',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 计量计费接口总价格
|
||||
export function getMeasure(start, end, step) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + '/kapis/clusters/fedjcce-ten002/metering.kubesphere.io/v1alpha1/cluster' + '?start=' + start + '&end=' + end + '&step=' + step + 's&metrics_filter=meter_cluster_cpu_usage%7Cmeter_cluster_memory_usage%7Cmeter_cluster_net_bytes_transmitted%7Cmeter_cluster_net_bytes_received%7Cmeter_cluster_pvc_bytes_total&resources_filter=fedjcce-ten002',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 内存整体负载接口
|
||||
export function getRamLoad(start, end, step) {
|
||||
return request({
|
||||
url: '/monitoringscreen/api/v1/query_range?query=sum(node_memory_MemTotal_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D%20-%20node_memory_MemAvailable_bytes%7Borigin_prometheus%3D~%22%22%2Cjob%3D~%22node-exporter%22%7D)&start=' + start + '&end=' + end + '&step=' + step + '&_=1642669327729',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 计量计费列表接口
|
||||
export function getMeteringList(start, end, step) {
|
||||
return request({
|
||||
url: process.env.VUE_APP_BASE_API + '/kapis/clusters/fedjcce-ten002/metering.kubesphere.io/v1alpha1/cluster' + '?start=' + start + '&end=' + end + '&step=' + step + 's&metrics_filter=meter_cluster_cpu_usage%7Cmeter_cluster_memory_usage%7Cmeter_cluster_net_bytes_transmitted%7Cmeter_cluster_net_bytes_received%7Cmeter_cluster_pvc_bytes_total&resources_filter=fedjcce-ten002',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// CPU整体负载接口
|
||||
export function getCpuAllload(start, end) {
|
||||
return request({
|
||||
url: '/monitoringscreen/api/v1/query_range?query=node_load15%7Binstance%3D~%22jcc-txy-001%22%7D&start=' + start + '&end=' + end + '&step=900&_=1645409802467',
|
||||
method: 'get',
|
||||
data: JSON,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.7 KiB |
|
@ -1,50 +1,98 @@
|
|||
<template>
|
||||
<!-- 添加容器镜像 -->
|
||||
<!-- 初始容器 和 其他 -->
|
||||
<el-dialog v-if="dialogVisible" width="80%" title="容器" :visible.sync="dialogVisible">
|
||||
<p>
|
||||
容器设置
|
||||
<span class="tips">对容器的名称及容器的计算资源进行设置</span>
|
||||
</p>
|
||||
<el-form ref="createContainerForm" :model="createContainerForm">
|
||||
<el-form-item label="镜像" required="">
|
||||
<el-input v-model="createContainerForm.mirror" placeholder="点击右侧图标可选择镜像,或直接输入名称 例:nginx:latest">
|
||||
<template slot="prepend">DockerHub</template>
|
||||
</el-input>
|
||||
<el-dialog v-if="dialogVisible" width="80%" :title="(!createContainerForm.name?'添加':'编辑')+'容器'" :visible.sync="dialogVisible">
|
||||
|
||||
<el-select v-model="createContainerForm.volumes" filterable class="selectPro" placeholder="选择已有镜像">
|
||||
<el-option
|
||||
v-for="item in volumesList"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
:value="item.label"
|
||||
<el-form ref="createContainerForm" :model="createContainerForm">
|
||||
<div class="border">
|
||||
<p>
|
||||
容器设置
|
||||
<span class="tips">对容器的名称及容器的计算资源进行设置</span>
|
||||
</p>
|
||||
<el-form-item label="镜像" required="">
|
||||
<el-input v-model="createContainerForm.image" placeholder="点击右侧图标可选择镜像,或直接输入名称 例:nginx:latest">
|
||||
<template slot="prepend">DockerHub</template>
|
||||
<el-select slot="append" v-model="createContainerForm.image" filterable class="selectPro" placeholder="选择已有镜像" @change="selectMirror">
|
||||
<el-option
|
||||
v-for="item in imageList"
|
||||
:key="item.name"
|
||||
:label="item.name"
|
||||
:value="item.name"
|
||||
>
|
||||
<el-image
|
||||
style="display:block;float:left;width: 30px; height: 30px"
|
||||
:src="item.imgUrl"
|
||||
fit="fit"
|
||||
/>
|
||||
<span style="width:20%; display:block;float:left">{{ item.name }}</span>
|
||||
<span style="width:60%;display:block;float:left; color: #8492a6; font-size: 13px">{{ item.description }}</span>
|
||||
<span style="width:10%; display:block;float:left; text-align:right"><i class="el-icon-star-on" />{{ item.star }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-input>
|
||||
<el-card v-loading="loading" class="grayCard" shadow="never">
|
||||
<span v-if="!imageData">{{ !noImage ? '请选择容器镜像' : '没有找到此镜像' }}</span>
|
||||
<div v-if="imageData" style="">
|
||||
<el-button style="float:right" round @click="useDefaultPorts">使用默认端口</el-button>
|
||||
<p>{{ createContainerForm.image }}</p>
|
||||
<span class="tips">
|
||||
{{ moment(imageData.createTime).fromNow() + ', ' +(imageData.size/1024/1024).toFixed(2) + `MB,` + imageData.layers + '层级' }}
|
||||
</span>
|
||||
<table class="el-table">
|
||||
<tr>
|
||||
<td>tag</td>
|
||||
<td>
|
||||
{{ imageData.imageTag }}
|
||||
</td>
|
||||
<td>端口</td>
|
||||
<td>{{ imageData.exposedPorts.join(';') || '暂无默认端口配置' }}</td>
|
||||
<td>
|
||||
{{ imageData.registry }}
|
||||
仓库
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="border">
|
||||
<p>
|
||||
端口设置
|
||||
<span class="tips">设置容器的访问策略</span>
|
||||
</p>
|
||||
<div>
|
||||
<el-form-item
|
||||
v-for="(tag, index) in createContainerForm.ports"
|
||||
:key="'tag'+index"
|
||||
label=""
|
||||
>
|
||||
<span style="width:50%; display:block;float:left">{{ item.label }}{{ item.alias?'('+item.alias+')':'' }}存储类型:{{ item.storageClassName }}</span>
|
||||
<span style="width:10%;display:block;float:left; color: #8492a6; font-size: 13px">容量:{{ item.storage }}</span>
|
||||
<span style="width:40%; display:block;float:left; text-align:right">访问模式:{{ item.accessModes }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<!-- </el-option>
|
||||
</el-select> -->
|
||||
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>容器</td>
|
||||
<td>container-9lxa15</td>
|
||||
<td>
|
||||
<el-select v-model="createContainerForm.readOnly">
|
||||
<el-option
|
||||
v-for="item in mountOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</td>
|
||||
<td><el-input v-model="createContainerForm.mountPath" :disabled="!createContainerForm.readOnly || createContainerForm.readOnly === 'null'" placeholder="容器挂载路径, 例如: /data" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</el-form>
|
||||
<table>
|
||||
<tr>
|
||||
<td>容器</td>
|
||||
<td>container-9lxa15</td>
|
||||
<td>
|
||||
<el-select v-model="createContainerForm.readOnly">
|
||||
<el-option
|
||||
v-for="item in mountOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</td>
|
||||
<td><el-input v-model="createContainerForm.mountPath" :disabled="!createContainerForm.readOnly || createContainerForm.readOnly === 'null'" placeholder="容器挂载路径, 例如: /data" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div></div></el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button icon="el-icon-close" circle @click="dialogVisible = false" />
|
||||
<el-button icon="el-icon-check" circle @click="ok" />
|
||||
|
@ -53,7 +101,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mountOptions } from '@/utils/map'
|
||||
import moment from 'moment'
|
||||
import { isEmpty } from 'lodash'
|
||||
import generate from 'nanoid/generate'
|
||||
import { mountOptions, imagePullPolicyOptions, protocolOptions } from '@/utils/map'
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
|
@ -63,18 +114,31 @@ export default {
|
|||
formData: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
},
|
||||
isEdit: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
// isEdit: {
|
||||
// type: Boolean,
|
||||
// default: false
|
||||
// }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
createContainerForm: {},
|
||||
volumesList: [],
|
||||
createContainerForm: {
|
||||
ports: [],
|
||||
securityContext: {
|
||||
seLinuxOptions: {}
|
||||
}
|
||||
},
|
||||
imageList: [],
|
||||
activeName: 'first',
|
||||
mountOptions
|
||||
namespace: '',
|
||||
imageData: undefined,
|
||||
noImage: false,
|
||||
loading: false,
|
||||
mountOptions,
|
||||
editInfoForm: {},
|
||||
imagePullPolicyOptions,
|
||||
protocolOptions,
|
||||
moment
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -92,37 +156,112 @@ export default {
|
|||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
},
|
||||
addTagNumCheck() {
|
||||
let flag = false
|
||||
this.createContainerForm.ports.forEach(e => {
|
||||
if (e.containerPort === '') {
|
||||
flag = true
|
||||
}
|
||||
})
|
||||
return flag
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 'createContainerForm.image'(newVal) {
|
||||
// throttle(this.selectMirror(), 300)
|
||||
// }
|
||||
},
|
||||
mounted() {
|
||||
this.getVolumeList()
|
||||
},
|
||||
methods: {
|
||||
getVolumeList() {
|
||||
this.$Api.getVolume(this.clusterName).then(res => {
|
||||
const arr = res.items.map(e => { return { label: e.metadata.name, alias: e.metadata.annotations['kubesphere.io/alias-name'], accessModes: e.spec.accessModes.join(','), storage: e.spec.resources.requests.storage, storageClassName: e.spec.storageClassName } })
|
||||
this.volumesList = arr
|
||||
selectPolicy(tag) {
|
||||
tag.name = tag.protocol.toLowerCase() + '-'
|
||||
},
|
||||
addTag() {
|
||||
this.createContainerForm.ports.push({ protocol: 'HTTP', name: 'http-', containerPort: '' })
|
||||
},
|
||||
removeTag(tag, index) {
|
||||
this.createContainerForm.ports.splice(index, 1)
|
||||
// this.blurInput()
|
||||
},
|
||||
selectMirror() {
|
||||
// 选中镜像
|
||||
this.loading = true
|
||||
this.$Api.getImagesInfo(this.namespace, this.createContainerForm.image).then(res => {
|
||||
// if status === 'fail'
|
||||
// 找不到镜像 重新选择
|
||||
// if status === 'succeeded'
|
||||
console.log(res.status)
|
||||
if (res.status === 'succeeded') {
|
||||
const layers = res.imageManifest.layers
|
||||
const size = layers.reduce((prev, layer) => prev + layer.size, 0)
|
||||
this.imageData = {
|
||||
imageTag: res.imageTag,
|
||||
message: res.message || '',
|
||||
registry: res.registry,
|
||||
layers: layers.length,
|
||||
createTime: res.imageBlob.created,
|
||||
size,
|
||||
exposedPorts: Object.keys(
|
||||
res.imageBlob.container_config.ExposedPorts || {}
|
||||
),
|
||||
status: res.status,
|
||||
slug: res.slug || ''
|
||||
}
|
||||
} else {
|
||||
this.imageData = undefined
|
||||
}
|
||||
this.noImage = false
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.noImage = true
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
getImageList() {
|
||||
this.$Api.getImagesList().then(res => {
|
||||
const arr = res.summaries.map(e => {
|
||||
return { name: e.name, description: e.short_description, star: e.star_count, imgUrl: e.logo_url.large || e.logo_url.small }
|
||||
})
|
||||
this.imageList = arr
|
||||
})
|
||||
},
|
||||
useDefaultPorts() {
|
||||
// 端口赋值
|
||||
const ports = this.imageData.exposedPorts.map(port => {
|
||||
const protocol = port.split('/')[1]
|
||||
const containerPort = Number(port.split('/')[0])
|
||||
|
||||
return {
|
||||
name: `${protocol}-${containerPort}`,
|
||||
protocol: protocol.toUpperCase(),
|
||||
containerPort,
|
||||
servicePort: containerPort
|
||||
}
|
||||
})
|
||||
console.log(ports)
|
||||
if (!isEmpty(ports)) {
|
||||
this.createContainerForm.ports = ports
|
||||
}
|
||||
},
|
||||
ok() {
|
||||
const val = {}
|
||||
// generate('0123456789abcdefghijklmnopqrstuvwxyz', length || 6)
|
||||
const container = Object.assign(this.createContainerForm)
|
||||
if (!this.createContainerForm.name) {
|
||||
container.name = 'container-' + generate('0123456789abcdefghijklmnopqrstuvwxyz', 6)
|
||||
this.$emit('addImage', container)
|
||||
} else {
|
||||
this.$emit('editImage', container)
|
||||
}
|
||||
this.dialogVisible = false
|
||||
|
||||
// 存在容器挂载
|
||||
// if(this.createContainerForm.readOnly !== 'null'){
|
||||
// this.formData.spec.template.spec.containers.forEach(e=>{
|
||||
|
||||
// })
|
||||
// }
|
||||
switch (this.activeName) {
|
||||
case 'first':
|
||||
|
||||
break
|
||||
case 'second':
|
||||
break
|
||||
}
|
||||
|
||||
return this.$emit('addVolumes', val)
|
||||
},
|
||||
handleClick() {}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,27 @@
|
|||
<template>
|
||||
<!-- 列表信息可编辑修改 -->
|
||||
<div>
|
||||
<div class="dataList">
|
||||
<div v-for="(item, index) in dataList" :key="index" class="dataList">
|
||||
<i :class="`'el-icon-'${iconName||'receiving'}`" />
|
||||
<div>{{ dataList.key }}</div>
|
||||
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
dataList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataList: []
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
{{ editInfoForm }}
|
||||
<el-form ref="editInfoForm" :rules="rules" :model="editInfoForm">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
|
@ -61,6 +60,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { set } from 'lodash'
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
|
@ -127,40 +127,56 @@ export default {
|
|||
})
|
||||
},
|
||||
submitInfoEdit() {
|
||||
this.formData = {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Namespace',
|
||||
metadata: {
|
||||
labels: {
|
||||
app: this.editInfoForm.name
|
||||
},
|
||||
name: this.editInfoForm.name,
|
||||
annotations: {
|
||||
'kubesphere.io/alias-name': this.editInfoForm.alias,
|
||||
'kubesphere.io/description': this.editInfoForm.description,
|
||||
'kubesphere.io/creator': 'admin'
|
||||
},
|
||||
namespace: this.editInfoForm.namespace
|
||||
},
|
||||
spec: {
|
||||
replicas: 1, // 容器组副本数量,
|
||||
selector: {
|
||||
matchLabels: {
|
||||
app: this.editInfoForm.name
|
||||
}
|
||||
},
|
||||
template: {
|
||||
metadata: {
|
||||
labels: {
|
||||
app: this.editInfoForm.name
|
||||
}, // 名称
|
||||
annotations: {
|
||||
'logging.kubesphere.io/logsidecar-config': '{}'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// when formData is empty do this
|
||||
const { name, alias, description, namespace } = this.editInfoForm
|
||||
set(this.formData, 'metadata.labels.app', name)
|
||||
set(this.formData, 'metadata.name', name)
|
||||
set(this.formData, 'metadata.labels.app', name)
|
||||
set(this.formData, 'spec.selector.matchLabels.app', name)
|
||||
set(this.formData, 'spec.template.metadata.lables.app', name)
|
||||
set(this.formData, 'metadata.annotations[kubesphere.io/alias-name]', alias)
|
||||
set(this.formData, 'metadata.annotations[kubesphere.io/alias-description]', description)
|
||||
set(this.formData, 'metadata.annotations[kubesphere.io/creator]', 'admin')
|
||||
set(this.formData, 'metadata.namespace', namespace)
|
||||
set(this.formData, 'spec.template.metadata.annotations[logging.kubesphere.io/logsidecar-config]', '{}')
|
||||
|
||||
// this.formData = {
|
||||
// apiVersion: 'v1',
|
||||
// kind: 'Namespace',
|
||||
// metadata: {
|
||||
// labels: {
|
||||
// app: this.editInfoForm.name
|
||||
// },
|
||||
// name: this.editInfoForm.name,
|
||||
// annotations: {
|
||||
// 'kubesphere.io/alias-name': this.editInfoForm.alias,
|
||||
// 'kubesphere.io/description': this.editInfoForm.description,
|
||||
// 'kubesphere.io/creator': 'admin'
|
||||
// },
|
||||
// namespace: this.editInfoForm.namespace
|
||||
// },
|
||||
// spec: {
|
||||
// containers: [],
|
||||
// replicas: 1, // 容器组副本数量,
|
||||
// selector: {
|
||||
// matchLabels: {
|
||||
// app: this.editInfoForm.name
|
||||
// }
|
||||
// },
|
||||
// stategy: { type: 'RollingUpdate', rollingUpdate: {}},
|
||||
// securityContext: {},
|
||||
// template: {
|
||||
// metadata: {
|
||||
// labels: {
|
||||
// app: this.editInfoForm.name
|
||||
// }, // 名称
|
||||
// annotations: {
|
||||
// 'logging.kubesphere.io/logsidecar-config': '{}'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
nameValidator(rule, value, callback) {
|
||||
if (!value) {
|
||||
|
|
|
@ -2,29 +2,37 @@
|
|||
<div class="createForm">
|
||||
<el-form ref="editInfoForm" :rules="rules" :model="editInfoForm">
|
||||
<el-form-item
|
||||
prop="namespace"
|
||||
prop="replicas"
|
||||
label="容器组副本数量"
|
||||
>
|
||||
<el-input-number v-model="editInfoForm.num" :min="1" :max="10" label="描述文字" />
|
||||
<el-input-number v-model="editInfoForm.spec.replicas" :min="1" :max="10" label="" />
|
||||
</el-form-item>
|
||||
<p>容器镜像</p>
|
||||
<el-button @click="containerFormVisiable=true">
|
||||
添加容器镜像
|
||||
<span class="tips">Kubesphere 支持从镜像仓库拉取镜像以及通过代码构建新的镜像并部署</span>
|
||||
</el-button>
|
||||
<addContainerForm v-model="containerFormVisiable" :form-data="formData" @addVolumes="addContainer" />
|
||||
<div v-if="editInfoForm.spec.template.spec.containers">
|
||||
<div v-for="(item, index) in editInfoForm.spec.template.spec.containers" :key="index" class="dataList">
|
||||
<i class="el-icon-receiving" />
|
||||
<div>{{ item.name }}</div>
|
||||
<div>镜像:{{ item.image }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<addContainerForm v-model="containerFormVisiable" :form-data="formData" @addImage="addImage" @editImage="editImage" />
|
||||
<!-- <el-form-item
|
||||
prop="mirror"
|
||||
label="更新策略"
|
||||
> -->
|
||||
<p>更新策略</p>
|
||||
<el-radio v-model="editInfoForm.radio1" class="selectRadio" label="1" border>滚动更新(推荐)
|
||||
<el-radio v-model="editInfoForm.spec.strategy.type" class="selectRadio" label="RollingUpdate" border>滚动更新(推荐)
|
||||
<span class="tips">滚动升级将逐步用新版本的实例替换旧版本的实例,升级的过程中,业务流量会同时负载均衡分布到新老的实例上,因此业务不会中断。</span>
|
||||
</el-radio>
|
||||
<el-radio v-model="editInfoForm.radio1" class="selectRadio" label="2" border>替换升级
|
||||
<el-radio v-model="editInfoForm.spec.strategy.type" class="selectRadio" label="Recreate" border>替换升级
|
||||
<span class="tips">替换升级会先删除旧的容器组,再创建新容器组;升级过程中业务会中断</span>
|
||||
</el-radio>
|
||||
<el-collapse v-if="editInfoForm.radio1==='1'">
|
||||
<el-collapse v-if="editInfoForm.spec.strategy.type==='RollingUpdate'">
|
||||
<el-collapse-item>
|
||||
<template slot="title">
|
||||
更新时容器组数量
|
||||
|
@ -35,7 +43,7 @@
|
|||
prop="maxUnavailable"
|
||||
label="容器组最大不可用数量"
|
||||
>
|
||||
<el-input v-model="editInfoForm.maxUnavailable" :maxlength="63" />
|
||||
<el-input v-model="editInfoForm.spec.strategy.rollingUpdate.maxUnavailable" :maxlength="63" />
|
||||
<span class="tips">升级过程中可能不可用的 Pod 的最大数量。</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -44,7 +52,7 @@
|
|||
prop="maxSurge"
|
||||
label="容器组最大超出数量"
|
||||
>
|
||||
<el-input v-model="editInfoForm.maxSurge" :maxlength="63" />
|
||||
<el-input v-model="editInfoForm.spec.strategy.rollingUpdate.maxSurge" :maxlength="63" />
|
||||
<span class="tips">升级过程中「允许超出副本数量的容器组」的最大数量或百分比</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -58,10 +66,10 @@
|
|||
>
|
||||
</el-form-item> -->
|
||||
<div class="selectCheck">
|
||||
<el-checkbox v-model="editInfoForm.checked" size="small">容器组
|
||||
<el-checkbox v-model="checked" size="small">容器组
|
||||
<span class="tips">Security Context的目的是限制不可信容器的行为,保护系统和其他容器不受其影响。</span>
|
||||
</el-checkbox>
|
||||
<div v-if="editInfoForm.checked">
|
||||
<div v-if="checked">
|
||||
<el-alert
|
||||
title="容器组 Security Context 可以为容器组内的容器提供默认的用户和用户组设置以及 seLinuxOptions 的参数设置,如果容器中已经对这些参数进行了定义,则优先以容器中的设置为准。"
|
||||
type="info"
|
||||
|
@ -70,7 +78,7 @@
|
|||
<el-row style="padding: 10px;margin:0 10px;border:1px solid #DCDFE6;font-size:0.7rem" :gutter="20">
|
||||
<el-col :span="24">
|
||||
<el-switch
|
||||
v-model="editInfoForm.runAsNonRoot"
|
||||
v-model="editInfoForm.spec.template.spec.securityContext.runAsNonRoot"
|
||||
/>
|
||||
仅允许非 Root 用户
|
||||
<span class="tips">Kubernetes 在运行容器之前将执行检查,以确保容器进程不是以 root 用户(UID为0)运行,否则将不能启动容器。</span>
|
||||
|
@ -80,7 +88,7 @@
|
|||
prop="runAsUser"
|
||||
label="用户"
|
||||
>
|
||||
<el-input v-model="editInfoForm.runAsUser" />
|
||||
<el-input v-model="editInfoForm.spec.template.spec.securityContext.runAsUser" />
|
||||
<span class="tips">执行容器 entrypoint 进程的 UID。默认为 docker 引擎的 GID</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -90,7 +98,7 @@
|
|||
prop="runAsGroup"
|
||||
label="用户组"
|
||||
>
|
||||
<el-input v-model="editInfoForm.runAsGroup" />
|
||||
<el-input v-model="editInfoForm.spec.template.spec.securityContext.runAsGroup" />
|
||||
<span class="tips">执行容器 entrypoint 进程的 GID。默认为 docker 引擎的 GID</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -102,7 +110,7 @@
|
|||
prop="level"
|
||||
label="Level"
|
||||
>
|
||||
<el-input v-model="editInfoForm.level" />
|
||||
<el-input v-model="editInfoForm.spec.template.spec.securityContext.seLinuxOptions.level" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
@ -110,7 +118,7 @@
|
|||
prop="role"
|
||||
label="Role"
|
||||
>
|
||||
<el-input v-model="editInfoForm.role" />
|
||||
<el-input v-model="editInfoForm.spec.template.spec.securityContext.seLinuxOptions.role" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
@ -118,7 +126,7 @@
|
|||
prop="type"
|
||||
label="Type"
|
||||
>
|
||||
<el-input v-model="editInfoForm.type" />
|
||||
<el-input v-model="editInfoForm.spec.template.spec.securityContext.seLinuxOptions.type" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
|
@ -126,7 +134,7 @@
|
|||
prop="user"
|
||||
label="User"
|
||||
>
|
||||
<el-input v-model="editInfoForm.user" />
|
||||
<el-input v-model="editInfoForm.spec.template.spec.securityContext.seLinuxOptions.user" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -204,24 +212,38 @@ import { policysOptions, policysTypeOptions } from '@/utils/map'
|
|||
import addContainerForm from '@/components/Actions/addContainerForm.vue'
|
||||
export default {
|
||||
components: { addContainerForm },
|
||||
props: {
|
||||
value: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
policysOptions,
|
||||
policysTypeOptions,
|
||||
namespaceOptions: [],
|
||||
editInfoForm: {
|
||||
num: 1,
|
||||
maxUnavailable: '25%',
|
||||
maxSurge: '25%'
|
||||
},
|
||||
// editInfoForm: {
|
||||
// num: 1,
|
||||
// maxUnavailable: '25%',
|
||||
// maxSurge: '25%'
|
||||
// },
|
||||
checked: false,
|
||||
rules: {},
|
||||
editTagForm: [],
|
||||
containerFormVisiable: false,
|
||||
createContainerForm: {},
|
||||
formData: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editInfoForm: {
|
||||
get() {
|
||||
return this.value
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('input', value)
|
||||
}
|
||||
},
|
||||
addTagNumCheck() {
|
||||
let flag = false
|
||||
this.editTagForm.forEach(e => {
|
||||
|
@ -231,6 +253,7 @@ export default {
|
|||
})
|
||||
return flag
|
||||
}
|
||||
|
||||
},
|
||||
watch() {
|
||||
// const customMode = this.editTagForm
|
||||
|
@ -239,7 +262,13 @@ export default {
|
|||
this.setFilterMapNamespaceList()
|
||||
},
|
||||
methods: {
|
||||
addContainer() {},
|
||||
addImage(data) {
|
||||
this.editInfoForm.spec.template.spec.containers.push(data)
|
||||
console.log(data)
|
||||
},
|
||||
editImage(data) {
|
||||
console.log(data)
|
||||
},
|
||||
setFilterMapNamespaceList() {
|
||||
this.$Api.getNamespaceList().then(res => {
|
||||
const arr = res.items.map(e => { return { label: e.metadata.name, value: e.metadata.name } })
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
</el-steps>
|
||||
{{ metaData }}
|
||||
<basicInfoForm v-show="stepNum===0" v-model="metaData" />
|
||||
<containerImage v-show="stepNum===1" :meta-data="metaData" />
|
||||
<mountVolumes v-show="stepNum===2" :meta-data="metaData" />
|
||||
<advancedSettings v-show="stepNum===3" :meta-data="metaData" />
|
||||
<containerImage v-if="stepNum===1" v-model="metaData" />
|
||||
<mountVolumes v-if="stepNum===2" v-model="metaData" />
|
||||
<advancedSettings v-if="stepNum===3" v-model="metaData" />
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="createFormVisible = false">取 消</el-button>
|
||||
<el-button v-if="stepNum!==0" type="primary" @click="prev">上一步</el-button>
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
<!-- <h2 class="headTitle">国家重点研发计划</h2> -->
|
||||
|
||||
<div class="right-menu">
|
||||
<router-link class="selectBtn" to="/clusterSelect">多集群管理</router-link>
|
||||
<router-link class="selectBtn" to="/monitorSelect">计量计费</router-link>
|
||||
<router-link class="selectBtn" to="/monitorSelect">资源管理</router-link>
|
||||
<template v-if="device!=='mobile'">
|
||||
<!-- <search id="header-search" class="right-menu-item" /> -->
|
||||
|
||||
|
@ -34,11 +37,11 @@
|
|||
<router-link to="/prometheusMonitorNew">
|
||||
<el-dropdown-item>数据监控总览</el-dropdown-item>
|
||||
</router-link>
|
||||
<div v-if="clusterName !== 'default'">
|
||||
<!-- <div v-if="clusterName !== 'default'">
|
||||
<router-link to="/">
|
||||
<el-dropdown-item>多集群管理</el-dropdown-item>
|
||||
</router-link>
|
||||
</div>
|
||||
</div> -->
|
||||
<el-dropdown-item v-if="this.$route.path !== '/cluster'" @click.native="toMoniter">
|
||||
用户资源监控
|
||||
</el-dropdown-item>
|
||||
|
@ -114,7 +117,17 @@ export default {
|
|||
position: relative;
|
||||
background: #fff;
|
||||
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||
|
||||
.selectBtn{
|
||||
line-height: 67px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
border-right: 1px solid #eeeeee;
|
||||
border-left: 1px solid #eeeeee;
|
||||
padding: 0 20px;
|
||||
}
|
||||
.navbar .right-menu .right-menu-item.hover-effect{
|
||||
margin-left: 10px;
|
||||
}
|
||||
.headTitle{
|
||||
display: inline-block;
|
||||
line-height: 2rem;
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
</el-menu-item>
|
||||
</app-link>
|
||||
</template>
|
||||
|
||||
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
|
||||
<el-submenu v-if="(item.path.indexOf('/'+routesType)===0)" ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
|
||||
<template slot="title">
|
||||
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
|
||||
</template>
|
||||
|
@ -30,6 +29,7 @@ import { isExternal } from '@/utils/validate'
|
|||
import Item from './Item'
|
||||
import AppLink from './Link'
|
||||
import FixiOSBug from './FixiOSBug'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'SidebarItem',
|
||||
|
@ -56,6 +56,11 @@ export default {
|
|||
this.onlyOneChild = null
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'routesType'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
hasOneShowingChild(children = [], parent) {
|
||||
const showingChildren = children.filter(item => {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
/* Layout */
|
||||
import Layout from '@/layout'
|
||||
import emptyLayout from '@/layout/emptyLayout'
|
||||
// import emptyLayout from '@/layout/emptyLayout'
|
||||
import podRouter from './modules/pod'
|
||||
import virtualMachineRouter from './modules/virtualMachine'
|
||||
import blockChainRouter from './modules/blockChain'
|
||||
|
@ -42,6 +41,7 @@ import functionsRouter from './modules/functions'
|
|||
* a base page that does not have permission requirements
|
||||
* all roles can be accessed
|
||||
*/
|
||||
|
||||
export const constantRoutes = [
|
||||
{
|
||||
path: '/redirect',
|
||||
|
@ -75,31 +75,30 @@ export const constantRoutes = [
|
|||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
component: emptyLayout,
|
||||
redirect: 'cluster',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'cluster',
|
||||
component: () => import('@/views/cluster/index'),
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
path: '/monitorSelect',
|
||||
component: () => import('@/views/monitorSelect/index'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/cluster/overview',
|
||||
component: Layout,
|
||||
redirect: 'overview',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/overview/index'),
|
||||
name: 'Overview',
|
||||
meta: { title: '概览', icon: 'dashboard', affix: true }
|
||||
}
|
||||
]
|
||||
path: '/clusterSelect',
|
||||
component: () => import('@/views/cluster/index'),
|
||||
hidden: true
|
||||
// children: [
|
||||
// {
|
||||
// path: 'clusterSelect',
|
||||
|
||||
// hidden: true
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
// {
|
||||
// path: '/cluster/',
|
||||
// component: Layout,
|
||||
// redirect: 'overview',
|
||||
// children: [
|
||||
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
path: '/prometheusMonitor',
|
||||
component: () => import('@/views/prometheusMonitor/index'),
|
||||
|
|
|
@ -11,49 +11,24 @@ const blockChainRouter = {
|
|||
children: [
|
||||
{
|
||||
path: 'blockChainBrowser',
|
||||
component: emptyLayout,
|
||||
redirect: 'blockChainBrowser',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/blockChain/blockChainBrowser'),
|
||||
name: 'blockChainBrowser',
|
||||
meta: { title: '块链浏览器', icon: 'el-icon-discover', affix: true },
|
||||
hidden: false
|
||||
}
|
||||
|
||||
// {
|
||||
// path: 'detail',
|
||||
// component: () => import('@/views/virtualMachine/hostDetailPanel'),
|
||||
// name: 'detail',
|
||||
// meta: { activeMenu: '/virtual/host' },
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
// {
|
||||
// path: 'overview',
|
||||
// component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
// {
|
||||
// path: 'config',
|
||||
// component: () => import('@/views/virtualMachine/hostConfig'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: 'yaml',
|
||||
// component: () => import('@/views/virtualMachine/hostYAML'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
component: () => import('@/views/blockChain/blockChainBrowser'),
|
||||
name: 'blockChainBrowser',
|
||||
meta: { title: '块链浏览器', icon: 'el-icon-discover', affix: true }
|
||||
},
|
||||
// {
|
||||
// path: '',
|
||||
// component: emptyLayout,
|
||||
// redirect: 'blockChainBrowser',
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// component: () => import('@/views/blockChain/blockChainBrowser'),
|
||||
// name: 'blockChainBrowser',
|
||||
// meta: { title: '块链浏览器', icon: 'el-icon-discover', affix: true },
|
||||
// hidden: false
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
path: 'blockList',
|
||||
component: emptyLayout,
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
import Layout from '@/layout'
|
||||
import emptyLayout from '@/layout/emptyLayout'
|
||||
const blockChainRouter = {
|
||||
path: '/costStatistics',
|
||||
component: Layout,
|
||||
name: '费用统计',
|
||||
meta: {
|
||||
title: '费用统计',
|
||||
icon: 'el-icon-share'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'containerCost',
|
||||
component: emptyLayout,
|
||||
redirect: 'containerCost',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/costStatistics/containerCost'),
|
||||
name: 'containerCost',
|
||||
meta: { title: '容器费用统计', icon: 'el-icon-discover', affix: true },
|
||||
hidden: false
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
export default blockChainRouter
|
|
@ -8,40 +8,47 @@ const functionsRouter = {
|
|||
title: '函数管理',
|
||||
icon: 'el-icon-s-operation'
|
||||
},
|
||||
children: [{
|
||||
path: 'functionList',
|
||||
component: emptyLayout,
|
||||
redirect: 'functionList',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/functionManagement/functionList'),
|
||||
name: 'functionList',
|
||||
meta: { title: '函数列表', icon: 'el-icon-s-opportunity', affix: true },
|
||||
hidden: false
|
||||
}
|
||||
// {
|
||||
// path: 'detail',
|
||||
// component: () => import('@/views/virtualMachine/hostDetailPanel'),
|
||||
// name: 'detail',
|
||||
// meta: { activeMenu: '/virtual/host' },
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
// {
|
||||
// path: 'overview',
|
||||
// component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
// {
|
||||
// path: 'config',
|
||||
// component: () => import('@/views/virtualMachine/hostConfig'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
children: [
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/overview/function'),
|
||||
name: 'functionsOverview',
|
||||
meta: { title: '概览', icon: 'dashboard', affix: true }
|
||||
},
|
||||
{
|
||||
path: 'functionList',
|
||||
component: emptyLayout,
|
||||
redirect: 'functionList',
|
||||
children: [
|
||||
{
|
||||
path: 'functionList',
|
||||
component: () => import('@/views/functionManagement/functionList'),
|
||||
name: 'functionList',
|
||||
meta: { title: '函数列表', icon: 'el-icon-s-opportunity', affix: true },
|
||||
hidden: false
|
||||
}
|
||||
// {
|
||||
// path: 'detail',
|
||||
// component: () => import('@/views/virtualMachine/hostDetailPanel'),
|
||||
// name: 'detail',
|
||||
// meta: { activeMenu: '/virtual/host' },
|
||||
// hidden: true,
|
||||
// children: [
|
||||
// {
|
||||
// path: '',
|
||||
// component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
// {
|
||||
// path: 'overview',
|
||||
// component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
// {
|
||||
// path: 'config',
|
||||
// component: () => import('@/views/virtualMachine/hostConfig'),
|
||||
// meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
// },
|
||||
|
||||
// {
|
||||
// path: 'yaml',
|
||||
|
@ -50,7 +57,7 @@ const functionsRouter = {
|
|||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}]
|
||||
]
|
||||
}]
|
||||
}
|
||||
export default functionsRouter
|
||||
|
|
|
@ -10,6 +10,12 @@ const podRouter = {
|
|||
icon: 'el-icon-s-claim'
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/overview/index'),
|
||||
name: 'clusterOverview',
|
||||
meta: { title: '概览', icon: 'dashboard', affix: true }
|
||||
},
|
||||
{
|
||||
path: 'nodeManagement',
|
||||
component: emptyLayout,
|
||||
|
|
|
@ -8,175 +8,182 @@ const virtualMachineRouter = {
|
|||
title: '虚拟机管理',
|
||||
icon: 'el-icon-s-finance'
|
||||
},
|
||||
children: [{
|
||||
path: 'host',
|
||||
component: emptyLayout,
|
||||
redirect: 'host',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/virtualHost'),
|
||||
name: 'host',
|
||||
meta: { title: '主机', icon: 'el-icon-s-platform', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: () => import('@/views/virtualMachine/hostDetailPanel'),
|
||||
meta: { activeMenu: '/virtual/host' },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'hostDetail',
|
||||
component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/virtualMachine/hostConfig'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/overview/virtualMachine'),
|
||||
name: 'virtualOverview',
|
||||
meta: { title: '概览', icon: 'dashboard', affix: true }
|
||||
},
|
||||
{
|
||||
path: 'host',
|
||||
component: emptyLayout,
|
||||
redirect: 'host',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/virtualHost'),
|
||||
name: 'host',
|
||||
meta: { title: '主机', icon: 'el-icon-s-platform', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: () => import('@/views/virtualMachine/hostDetailPanel'),
|
||||
meta: { activeMenu: '/virtual/host' },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'hostDetail',
|
||||
component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/virtualMachine/hostDetail'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/virtualMachine/hostConfig'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
},
|
||||
|
||||
{
|
||||
path: 'yaml',
|
||||
component: () => import('@/views/virtualMachine/hostYAML'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'virtual-machine',
|
||||
component: emptyLayout,
|
||||
redirect: 'virtual-machine',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/virtualMachine'),
|
||||
name: 'virtual-machine',
|
||||
meta: { title: '虚拟机', icon: 'el-icon-monitor', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/virtualMachine/virtualMachineCreate.vue'),
|
||||
name: 'virtualMachineCreate',
|
||||
meta: { activeMenu: '/virtual/virtual-machine' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'info',
|
||||
component: () => import('@/views/virtualMachine/virtualMachineDetailPanel'),
|
||||
name: 'info',
|
||||
meta: { activeMenu: '/virtual/virtual-machine' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'dataVolume',
|
||||
component: emptyLayout,
|
||||
redirect: 'dataVolume',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/datavolumes.vue'),
|
||||
name: 'dataVolume',
|
||||
meta: { title: '卷', icon: 'el-icon-box', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/virtualMachine/datavolumeCreate.vue'),
|
||||
name: 'dataVolumeCreate',
|
||||
meta: { activeMenu: '/virtual/dataVolume' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: () => import('@/views/virtualMachine/datavolumeDetailPanel'),
|
||||
meta: { activeMenu: '/virtual/dataVolume' },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'datavolumeDetail',
|
||||
component: () => import('@/views/virtualMachine/datavolumeDetail'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/virtualMachine/datavolumeDetail'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/virtualMachine/datavolumeConfig'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'yaml',
|
||||
component: () => import('@/views/virtualMachine/datavolumeYAML'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'images',
|
||||
component: emptyLayout,
|
||||
redirect: 'images',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/images.vue'),
|
||||
name: 'images',
|
||||
meta: { title: '镜像', icon: 'el-icon-picture-outline', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/virtualMachine/imagesCreate.vue'),
|
||||
name: 'imagesCreate',
|
||||
meta: { activeMenu: '/virtual/images' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: () => import('@/views/virtualMachine/imagesDetailPanel.vue'),
|
||||
meta: { activeMenu: '/virtual/images' },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'imagesDetail',
|
||||
component: () => import('@/views/virtualMachine/imagesDetail'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/virtualMachine/imagesDetail'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/virtualMachine/imagesConfig'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'yaml',
|
||||
component: () => import('@/views/virtualMachine/imagesYAML'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
}]
|
||||
}
|
||||
]
|
||||
}]
|
||||
{
|
||||
path: 'yaml',
|
||||
component: () => import('@/views/virtualMachine/hostYAML'),
|
||||
meta: { activeMenu: '/virtual/host', keepAlive: true }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'virtual-machine',
|
||||
component: emptyLayout,
|
||||
redirect: 'virtual-machine',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/virtualMachine'),
|
||||
name: 'virtual-machine',
|
||||
meta: { title: '虚拟机', icon: 'el-icon-monitor', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/virtualMachine/virtualMachineCreate.vue'),
|
||||
name: 'virtualMachineCreate',
|
||||
meta: { activeMenu: '/virtual/virtual-machine' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'info',
|
||||
component: () => import('@/views/virtualMachine/virtualMachineDetailPanel'),
|
||||
name: 'info',
|
||||
meta: { activeMenu: '/virtual/virtual-machine' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'dataVolume',
|
||||
component: emptyLayout,
|
||||
redirect: 'dataVolume',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/datavolumes.vue'),
|
||||
name: 'dataVolume',
|
||||
meta: { title: '卷', icon: 'el-icon-box', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/virtualMachine/datavolumeCreate.vue'),
|
||||
name: 'dataVolumeCreate',
|
||||
meta: { activeMenu: '/virtual/dataVolume' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: () => import('@/views/virtualMachine/datavolumeDetailPanel'),
|
||||
meta: { activeMenu: '/virtual/dataVolume' },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'datavolumeDetail',
|
||||
component: () => import('@/views/virtualMachine/datavolumeDetail'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/virtualMachine/datavolumeDetail'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/virtualMachine/datavolumeConfig'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'yaml',
|
||||
component: () => import('@/views/virtualMachine/datavolumeYAML'),
|
||||
meta: { activeMenu: '/virtual/dataVolume', keepAlive: true }
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'images',
|
||||
component: emptyLayout,
|
||||
redirect: 'images',
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/virtualMachine/images.vue'),
|
||||
name: 'images',
|
||||
meta: { title: '镜像', icon: 'el-icon-picture-outline', affix: true },
|
||||
hidden: false
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
component: () => import('@/views/virtualMachine/imagesCreate.vue'),
|
||||
name: 'imagesCreate',
|
||||
meta: { activeMenu: '/virtual/images' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'detail',
|
||||
component: () => import('@/views/virtualMachine/imagesDetailPanel.vue'),
|
||||
meta: { activeMenu: '/virtual/images' },
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
name: 'imagesDetail',
|
||||
component: () => import('@/views/virtualMachine/imagesDetail'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'overview',
|
||||
component: () => import('@/views/virtualMachine/imagesDetail'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'config',
|
||||
component: () => import('@/views/virtualMachine/imagesConfig'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
},
|
||||
{
|
||||
path: 'yaml',
|
||||
component: () => import('@/views/virtualMachine/imagesYAML'),
|
||||
meta: { activeMenu: '/virtual/images', keepAlive: true }
|
||||
}]
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
export default virtualMachineRouter
|
||||
|
|
|
@ -10,6 +10,7 @@ const getters = {
|
|||
introduction: state => state.user.introduction,
|
||||
roles: state => state.user.roles,
|
||||
permission_routes: state => state.permission.routes,
|
||||
routesType: state => state.user.routesType,
|
||||
errorLogs: state => state.errorLog.logs,
|
||||
clusterName: state => state.cluster.clusterName
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { login, harvesterLogin, blockChainLogin } from '@/api/user'
|
||||
import { login, blockChainLogin } from '@/api/user'
|
||||
import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
import { resetRouter } from '@/router'
|
||||
|
||||
|
@ -7,7 +7,8 @@ const state = {
|
|||
name: '',
|
||||
avatar: '',
|
||||
introduction: '',
|
||||
roles: []
|
||||
roles: [],
|
||||
routesType: localStorage.getItem('routesType') || 'cluster'
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
|
@ -25,6 +26,9 @@ const mutations = {
|
|||
},
|
||||
SET_ROLES: (state, roles) => {
|
||||
state.roles = roles
|
||||
},
|
||||
SET_ROUTESTYPE: (state, routesType) => {
|
||||
state.routesType = routesType
|
||||
}
|
||||
}
|
||||
function encrypt(salt, str) {
|
||||
|
@ -53,14 +57,14 @@ const actions = {
|
|||
const { username, password } = userInfo
|
||||
return Promise.all([
|
||||
login({ 'username': username.trim(), 'encrypt': encrypt('kubesphere', password) }),
|
||||
harvesterLogin({ 'username': 'admin', 'password': 'Nudt@123', 'description': 'UI Session', 'responseType': 'cookie', 'ttl': 57600000 }),
|
||||
// harvesterLogin({ 'username': 'admin', 'password': 'Nudt@123', 'description': 'UI Session', 'responseType': 'cookie', 'ttl': 57600000 }),
|
||||
blockChainLogin({
|
||||
'user': 'exploreradmin',
|
||||
'password': 'exploreradminpw',
|
||||
'network': 'agridepart-network'
|
||||
})]).then(response => {
|
||||
commit('SET_TOKEN', response[2].token)
|
||||
setToken(response[2].token)
|
||||
commit('SET_TOKEN', response[1].token)
|
||||
setToken(response[1].token)
|
||||
// Cookies.set('bToken', response[2].token)
|
||||
})
|
||||
},
|
||||
|
@ -99,6 +103,14 @@ const actions = {
|
|||
})
|
||||
},
|
||||
|
||||
setRouteType({ commit }, type) {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// logout(state.token).then(() => {
|
||||
commit('SET_ROUTESTYPE', type)
|
||||
localStorage.setItem('routesType', type)
|
||||
// })
|
||||
},
|
||||
|
||||
// user logout
|
||||
logout({ commit, state, dispatch }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
const statusOptions = [
|
||||
{ label: '不限', value: '' },
|
||||
{ label: '运行中', value: 'running' },
|
||||
|
@ -21,9 +22,41 @@ const mountOptions = [
|
|||
{ label: '不挂载', value: 'null' }
|
||||
]
|
||||
|
||||
const imagePullPolicyOptions = [
|
||||
{
|
||||
label: '尝试重新下载镜像(Always)',
|
||||
value: 'Always',
|
||||
description: '在创建及更新时,每次都会尝试下载新的镜像'
|
||||
},
|
||||
{
|
||||
label: '优先使用本地镜像(IfNotPresent)',
|
||||
value: 'IfNotPresent',
|
||||
description: '如果本地存在镜像就优先使用本地镜像'
|
||||
},
|
||||
{
|
||||
label: '仅使用本地镜像(Never)',
|
||||
value: 'Never',
|
||||
description: '仅会使用本地镜像,如果本地不存在所需镜像,则会导致容器异常'
|
||||
|
||||
}
|
||||
]
|
||||
const protocolOptions = [
|
||||
{ label: 'GRPC', value: 'GRPC' },
|
||||
{ label: 'HTTP', value: 'HTTP' },
|
||||
{ label: 'HTTP2', value: 'HTTP2' },
|
||||
{ label: 'HTTPS', value: 'HTTPS' },
|
||||
{ label: 'MONGO', value: 'MONGO' },
|
||||
{ label: 'REDIS', value: 'REDIS' },
|
||||
{ label: 'TCP', value: 'TCP' },
|
||||
{ label: 'TLS', value: 'TLS' },
|
||||
{ label: 'UDP', value: 'UDP' }
|
||||
]
|
||||
|
||||
export {
|
||||
statusOptions,
|
||||
policysOptions,
|
||||
policysTypeOptions,
|
||||
mountOptions
|
||||
mountOptions,
|
||||
imagePullPolicyOptions,
|
||||
protocolOptions
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<div :class="['costNumMark', 'blue']">
|
||||
<div>
|
||||
<div class="bigNum">4262052.339</div>
|
||||
<p>CPU消费(Core)</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bigNum">1945.299</div>
|
||||
<p>内存消费(Gi)</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bigNum">391659.532</div>
|
||||
<p>网络流入消费(M)</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bigNum">50421.807</div>
|
||||
<p>网络流出消费(M)</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div :class="['costNumMark', 'green']">
|
||||
<div>
|
||||
<div class="bigNum">3409641.87</div>
|
||||
<p>CPU 消费(¥)</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bigNum">2528.89</div>
|
||||
<p>内存 消费(¥)</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bigNum">3133.28</div>
|
||||
<p>网络流入 消费(¥)</p>
|
||||
</div>
|
||||
<div>
|
||||
<div class="bigNum">15.39</div>
|
||||
<p>网络流出 消费(¥)</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.costNumMark{
|
||||
padding: 5px 20px;
|
||||
border-radius: 5px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
padding: 21px 40px 0 40px;
|
||||
color: #000000;
|
||||
>div{
|
||||
width: 33.3%;
|
||||
display: inline-block;
|
||||
p{
|
||||
margin: 0;
|
||||
margin-bottom: 21px;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
.green{
|
||||
background-color: #00d9a611;
|
||||
border-left: 4px solid #00d9a6;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<div id="lineChart" ref="lineChart" style="height:300px" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chartOption: {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
axisLine: { lineStyle: { color: '#999999' }},
|
||||
data: []
|
||||
// data: createdTime
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#999999' }}
|
||||
},
|
||||
series: [{
|
||||
// data: createCount,
|
||||
data: [],
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: 'rgba(0, 55, 255, 1)'
|
||||
},
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: '#409eff' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: 'white' // 100% 处的颜色
|
||||
}],
|
||||
global: false // 缺省为 false
|
||||
}
|
||||
}
|
||||
}]
|
||||
},
|
||||
lineChart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.lineChart = echarts.init(this.$refs.lineChart)
|
||||
this.lineChart.setOption(this.chartOption)
|
||||
},
|
||||
methods: {
|
||||
setChart(option) {
|
||||
this.lineChart.setOption(option)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,70 @@
|
|||
<template>
|
||||
<div id="gaugeChart" ref="gaugeChart" style="height:300px" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
option: {
|
||||
title: {
|
||||
text: `{v|k8s-node1}\n\n{t|${'34.35%'}}`,
|
||||
x: 'center',
|
||||
y: 'center',
|
||||
textStyle: {
|
||||
rich: {
|
||||
v: { fontSize: 14, color: '#333333' },
|
||||
t: { fontFamily: 'Impact', fontSize: 30, color: '#333333' }
|
||||
}
|
||||
}
|
||||
},
|
||||
color: ['#0097FB',
|
||||
'#92E1FF',
|
||||
'#FFC227',
|
||||
'#30ECA6',
|
||||
'#FDFA4E',
|
||||
'#FF4848'],
|
||||
series: [
|
||||
{
|
||||
name: '标签使用频率',
|
||||
type: 'pie',
|
||||
radius: ['55%', '75%'],
|
||||
center: ['50%', '50%'],
|
||||
roseType: 'radius',
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
shadowBlur: 1,
|
||||
shadowColor: 2,
|
||||
shadowOffsetX: 5,
|
||||
shadowOffsetY: 5
|
||||
},
|
||||
data: [21, 32, 43, 64, 55]
|
||||
}
|
||||
]
|
||||
},
|
||||
gaugeChart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.gaugeChart = echarts.init(this.$refs.gaugeChart)
|
||||
this.gaugeChart.setOption(this.option, true)
|
||||
},
|
||||
methods: {
|
||||
setChart(option) {
|
||||
this.lineChart.setOption(option)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,324 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-card shadow="never" style="height:1000px">
|
||||
<h4>集群选择</h4>
|
||||
<el-tree
|
||||
ref="tree"
|
||||
node-key="id"
|
||||
:load="loadNode"
|
||||
lazy
|
||||
:props="props"
|
||||
show-checkbox
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-card shadow="never">
|
||||
<h4>消费账单</h4>
|
||||
<span class="tips">
|
||||
集群host1自创建以来共消费
|
||||
<span class="tip-num">¥3415319.43</span>
|
||||
</span>
|
||||
<CostDiv />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-card shadow="never">
|
||||
<h4>截止到昨天的消费历史</h4>
|
||||
<div class="change">
|
||||
对账周期
|
||||
<el-date-picker
|
||||
v-model="value1"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
/>
|
||||
</div>
|
||||
<LineChart ref="lineChart" />
|
||||
<List
|
||||
ref="multipleTable"
|
||||
class="multipleTable"
|
||||
:columns="columns"
|
||||
:table-list-data="[{
|
||||
name:'111'
|
||||
},{
|
||||
name:'111'
|
||||
},{
|
||||
name:'111'
|
||||
}]"
|
||||
:cluster-name="clusterName"
|
||||
:pagination="false"
|
||||
tooltip-effect="dark"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="never">
|
||||
<h4>当前包含的资源</h4>
|
||||
<div class="change">
|
||||
<el-select v-model="metrics_filter" placeholder="请选择">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<PieChart ref="pieChart" />
|
||||
<div v-for="item in nodes" :key="item.name +'nodes'" class="nodes-div">
|
||||
<div>
|
||||
<img :src="item.imgSrc" style="width: 52px">
|
||||
<div>
|
||||
<div class="name"> {{ item.name }}</div>
|
||||
<div class="node">集群节点</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>{{ item.value }} Core </div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import CostDiv from './components/CostDiv'
|
||||
import LineChart from './components/LineChart'
|
||||
import PieChart from './components/PieChart'
|
||||
// import { numberToStr } from '@/utils/data-process'
|
||||
import { getClusterList, getNodeList, getBillNum, getResource } from '@/api/one-class-page/costStatistics'
|
||||
|
||||
export default {
|
||||
components: { List, LineChart, PieChart, CostDiv },
|
||||
data() {
|
||||
return {
|
||||
value1: '',
|
||||
metrics_filter: 'meter_node_cpu_usage',
|
||||
options: [{
|
||||
value: 'meter_node_cpu_usage',
|
||||
label: 'CPU 消费'
|
||||
}, {
|
||||
value: 'meter_node_memory_usage_wo_cache',
|
||||
label: '内存 消费'
|
||||
}, {
|
||||
value: 'meter_node_pvc_bytes_total',
|
||||
label: '存储卷 消费'
|
||||
}, {
|
||||
value: 'meter_node_net_bytes_received',
|
||||
label: '网络流入 消费'
|
||||
}, {
|
||||
value: 'meter_node_net_bytes_transmitted',
|
||||
label: '网络流出 消费'
|
||||
}],
|
||||
currentCluster: '',
|
||||
props: {
|
||||
isLeaf: 'leaf',
|
||||
children: 'zones'
|
||||
},
|
||||
nodes: [],
|
||||
columns: [
|
||||
{
|
||||
prop: 'state',
|
||||
label: '资源类型'
|
||||
},
|
||||
{ prop: 'name', label: '最大用量', formatter: (row) => { return <a onClick={() => this.viewDetail(row)}>{row.name}</a> } },
|
||||
{ prop: 'hostIP', label: '最小用量' },
|
||||
{ prop: 'cpu', label: '平均用量', formatter: (row) => { return <div>{row.cpuAll}</div> } },
|
||||
{ prop: 'memory', label: '共消费', formatter: (row) => { return <div>{row.memoryAll}</div> } },
|
||||
{ prop: 'storageSize', label: '价格', formatter: (row) => { return <div>{row.storageAll}</div> } }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
clusterName() {
|
||||
if (localStorage.getItem('clusterName') === 'default') {
|
||||
return ''
|
||||
} else {
|
||||
return '/clusters/' + localStorage.getItem('clusterName')
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
// 集群选择
|
||||
async loadNode(node, resolve) {
|
||||
// 获取集群
|
||||
if (node.level === 0) {
|
||||
const array = []
|
||||
// host集群
|
||||
getClusterList({
|
||||
page: 1,
|
||||
limit: -1,
|
||||
labelSelector: 'cluster-role.kubesphere.io/host',
|
||||
sortBy: 'createTime'
|
||||
}).then(res => {
|
||||
if (res.items.length > 0) {
|
||||
res.items.forEach(n =>
|
||||
array.push({
|
||||
id: n.metadata.uid,
|
||||
label: n.metadata.name,
|
||||
children: []
|
||||
})
|
||||
)
|
||||
this.currentCluster = array[0].label
|
||||
// this.getHistory(array[0].label)
|
||||
this.getResources(array[0].label)
|
||||
// this.getBill(array[0].label)
|
||||
}
|
||||
})
|
||||
// member集群
|
||||
await getClusterList({
|
||||
page: 1,
|
||||
limit: -1,
|
||||
labelSelector: '!cluster-role.kubesphere.io/host',
|
||||
sortBy: 'createTime'
|
||||
}).then(res => {
|
||||
if (res.items.length > 0) {
|
||||
res.items.forEach(n =>
|
||||
array.push({
|
||||
id: n.metadata.uid,
|
||||
label: n.metadata.name,
|
||||
children: []
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
return resolve(array)
|
||||
}
|
||||
// 获取节点
|
||||
if (node.level === 1) {
|
||||
getNodeList(node.data.label).then(res => {
|
||||
let array = []
|
||||
if (res.items.length > 0) {
|
||||
array = res.items.map(n => ({
|
||||
id: n.metadata.uid,
|
||||
label: n.metadata.name,
|
||||
children: [],
|
||||
leaf: true
|
||||
}))
|
||||
}
|
||||
return resolve(array)
|
||||
})
|
||||
}
|
||||
return resolve([])
|
||||
},
|
||||
// 获取消费账单
|
||||
getBill(name) {
|
||||
getBillNum({
|
||||
start: '1641398400',
|
||||
end: '1642003200',
|
||||
step: '3600s',
|
||||
metrics_filter: 'meter_cluster_cpu_usage|meter_cluster_memory_usage|meter_cluster_net_bytes_transmitted|meter_cluster_net_bytes_received|meter_cluster_pvc_bytes_total',
|
||||
resources_filter: name
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
})
|
||||
},
|
||||
getImg(num) {
|
||||
return require('@/assets/img/node' + num + '.png')
|
||||
},
|
||||
// 获取消费历史
|
||||
getHistory(name) {
|
||||
// getClusterList({
|
||||
// start: '1641398400',
|
||||
// end: '1642003200',
|
||||
// step: '3600s',
|
||||
// metrics_filter: 'meter_cluster_cpu_usage|meter_cluster_memory_usage|meter_cluster_net_bytes_transmitted|meter_cluster_net_bytes_received|meter_cluster_pvc_bytes_total',
|
||||
// resources_filter: name
|
||||
// }).then(res => {
|
||||
// console.log(res)
|
||||
const data = [{ 'createdTime': '2021-12-16', 'createCount': 0 }, { 'createdTime': '2021-12-17', 'createCount': 0 }, { 'createdTime': '2021-12-18', 'createCount': 0 }, { 'createdTime': '2021-12-19', 'createCount': 0 }, { 'createdTime': '2021-12-20', 'createCount': 0 }, { 'createdTime': '2021-12-21', 'createCount': 0 }, { 'createdTime': '2021-12-22', 'createCount': 0 }]
|
||||
const createCount = data.map(i => i.createCount)
|
||||
const createdTime = data.map(i => i.createdTime)
|
||||
this.$refs.lineChart.setChart({
|
||||
xAxis: {
|
||||
data: createdTime
|
||||
},
|
||||
series: [{
|
||||
data: createCount
|
||||
}]
|
||||
})
|
||||
// })
|
||||
},
|
||||
// 获取当前包含的资源
|
||||
getResources(name) {
|
||||
getResource({
|
||||
clusterName: name,
|
||||
metrics_filter: this.metrics_filter,
|
||||
resources_filter: 'k8s-node4|k8s-node3|k8s-node2|k8s-node1|k8s-master'
|
||||
}).then(res => {
|
||||
const { results } = res
|
||||
const { data: { result }} = results?.[0]
|
||||
console.log(result)
|
||||
// const
|
||||
if (result.length > 0) {
|
||||
this.nodes = result.map((n, index) => ({
|
||||
name: n.metric.node,
|
||||
value: n.avg_value,
|
||||
imgSrc: this.getImg(index < 4 ? (index + 1) : (index - 3))
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.tips{
|
||||
margin: 20px 0;
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
.tip-num{
|
||||
font-size: 32px;
|
||||
color: #419EFF;
|
||||
font-family: Impact;
|
||||
margin-left: 20px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
}
|
||||
.change{
|
||||
padding: 17px 19px;
|
||||
background: #F7F7F7;
|
||||
font-size: 14px;
|
||||
}
|
||||
.blue{
|
||||
background-color: #419eff11;
|
||||
border-left: 4px solid #419eff;
|
||||
}
|
||||
.bigNum{
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.nodes-div{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
>div{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
.name{
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
}
|
||||
.node{
|
||||
font-size: 14px;
|
||||
color: #999999;
|
||||
line-height: 18px;
|
||||
}
|
||||
img{
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,26 +1,14 @@
|
|||
<template>
|
||||
<div class="cloudComputation">
|
||||
<el-card class="basicInfo" shadow="never">
|
||||
<img src="@/assets/img/pod.png" class="sidebar-logo" alt="容器组">
|
||||
<h4>函数</h4>
|
||||
<span class="tips" />
|
||||
</el-card>
|
||||
<el-card shadow="never">
|
||||
<el-button style="margin-top:30px" type="primary" @click="dialogCreateVisible=true">创建函数</el-button>
|
||||
<el-row :gutter="30">
|
||||
<el-col v-for="(item,index) in functionList" :key="index" :span="6">
|
||||
<el-card class="functionCard">
|
||||
<p class="title">{{ item.functionName }}
|
||||
<el-button
|
||||
type="text"
|
||||
class="insideFloatRight"
|
||||
@click="goDetail(item)"
|
||||
>details</el-button>
|
||||
</p>
|
||||
<el-divider />
|
||||
<p>env: {{ item.runEnv }}</p>
|
||||
<p>memory: {{ item.memorySize }}</p>
|
||||
<p>timeout: {{ item.timeout }}</p>
|
||||
<div class="functionList">
|
||||
<el-button class="opr-btn" size="middle" type="primary" @click="dialogCreateVisible=true">创建函数</el-button>
|
||||
<el-row :gutter="20">
|
||||
<el-col v-for="(item,index) in functionList" :key="index" :span="6">
|
||||
<el-card shadow="never" class="functionCard">
|
||||
<p class="title">{{ item.functionName }}</p>
|
||||
<p>运行环境: {{ item.runEnv }}</p>
|
||||
<p>内存大小: {{ item.memorySize }}</p>
|
||||
<p>超时: {{ item.timeout }}</p>
|
||||
<div class="btn-group">
|
||||
<el-popconfirm
|
||||
confirm-button-text="好的"
|
||||
cancel-button-text="不用了"
|
||||
|
@ -29,123 +17,132 @@
|
|||
title="确认删除此函数么?"
|
||||
@onConfirm="deleteFunc(item.functionId)"
|
||||
>
|
||||
<el-button slot="reference" type="danger" size="small">删除</el-button>
|
||||
<el-button slot="reference" size="small">删除</el-button>
|
||||
</el-popconfirm>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-pagination
|
||||
background
|
||||
:hide-on-single-page="true"
|
||||
:current-page="page"
|
||||
layout="prev, pager, next"
|
||||
:total="total"
|
||||
@current-change="currentChange"
|
||||
/>
|
||||
<el-dialog :visible.sync="dialogCreateVisible" title="创建函数" width="80%">
|
||||
<div class="bg-gray">
|
||||
<el-row :gutter="30">
|
||||
<el-col :span="12">
|
||||
<el-form ref="form" v-model="form" label-width="150px">
|
||||
<el-form-item label="Function Name:" prop="functionName">
|
||||
<el-input v-model="form.functionName" :maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Env:">
|
||||
<el-select v-model="form.runEnv" placeholder="请选择">
|
||||
<el-option label="java8" value="java8" />
|
||||
<el-option label="python3" value="python3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="TimeOut(1-300s):">
|
||||
<el-input v-model="form.timeout" :maxlength="3" />
|
||||
</el-form-item>
|
||||
<el-form-item label="Memory Size(128-1024MB):">
|
||||
<el-input v-model="form.memorySize" :maxlength="4" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span class="el-form-item__label">Entrypoint:</span>
|
||||
<div v-if="form.runEnv==='python3'" class="codemirror">
|
||||
<codemirror v-model="code" :options="cmOption" />
|
||||
</div>
|
||||
<div v-if="form.runEnv === 'java8'">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="#"
|
||||
:http-request="httpRequest"
|
||||
:limit="1"
|
||||
:file-list="fileList"
|
||||
>
|
||||
<el-button size="small" type="primary">上传jar包</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传jar文件</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button @click="createFunc">下一步</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog :visible.sync="dialogExecuteVisible" title="提交运行">
|
||||
<div class="bg-gray">
|
||||
<table class="el-table funcTable">
|
||||
<tr>
|
||||
<td>Function Name:</td>
|
||||
<td :colspan="3">{{ form.functionName }}</td>
|
||||
<td>Created Time:</td>
|
||||
<td>{{ form.createTime }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Env:</td>
|
||||
<td>{{ form.runEnv }}</td>
|
||||
<td>Memory Size:</td>
|
||||
<td>{{ form.memorySize }}</td>
|
||||
<td>Timeout:</td>
|
||||
<td>{{ form.timeout }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Code Size:</td>
|
||||
<td>{{ form.codeSize }}</td>
|
||||
<td>Code Checksum:</td>
|
||||
<td :colspan="3">{{ form.codeChecksum }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td :colspan="5">{{ form.description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EnviromentVariable:</td>
|
||||
<td :colspan="2">{{ form.envVar }}</td>
|
||||
<td :colspan="3">
|
||||
<!-- Enable Native Serverless:
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="goDetail(item)"
|
||||
>函数查看</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-pagination
|
||||
background
|
||||
:hide-on-single-page="true"
|
||||
:current-page="page"
|
||||
layout="prev, pager, next"
|
||||
:total="total"
|
||||
@current-change="currentChange"
|
||||
/>
|
||||
<el-dialog :visible.sync="dialogCreateVisible" title="创建函数" width="80%">
|
||||
<!-- <el-steps :active="active">
|
||||
<el-step title="步骤 1" />
|
||||
<el-step title="步骤 2" />
|
||||
<el-step title="步骤 3" />
|
||||
</el-steps> -->
|
||||
<div class="bg-gray">
|
||||
<el-row :gutter="30">
|
||||
<el-col :span="12">
|
||||
<el-form ref="form" v-model="form" label-width="150px">
|
||||
<el-form-item label="函数名称:" prop="functionName">
|
||||
<el-input v-model="form.functionName" :maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="运行环境:">
|
||||
<el-select v-model="form.runEnv" placeholder="请选择">
|
||||
<el-option label="java8" value="java8" />
|
||||
<el-option label="python3" value="python3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="超时(1-300s):">
|
||||
<el-input v-model="form.timeout" :maxlength="3" />
|
||||
</el-form-item>
|
||||
<el-form-item label="内存大小(128-1024MB):">
|
||||
<el-input v-model="form.memorySize" :maxlength="4" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span class="el-form-item__label">Entrypoint:</span>
|
||||
<div v-if="form.runEnv==='python3'" class="codemirror">
|
||||
<codemirror v-model="code" :options="cmOption" />
|
||||
</div>
|
||||
<div v-if="form.runEnv === 'java8'">
|
||||
<el-upload
|
||||
class="upload-demo"
|
||||
action="#"
|
||||
:http-request="httpRequest"
|
||||
:limit="1"
|
||||
:file-list="fileList"
|
||||
>
|
||||
<el-button size="small" type="primary">上传jar包</el-button>
|
||||
<div slot="tip" class="el-upload__tip">只能上传jar文件</div>
|
||||
</el-upload>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button @click="createFunc">下一步</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog :visible.sync="dialogExecuteVisible" title="函数详情">
|
||||
<div class="bg-gray">
|
||||
<table class="el-table funcTable">
|
||||
<tr>
|
||||
<td>Function Name:</td>
|
||||
<td :colspan="3">{{ form.functionName }}</td>
|
||||
<td>Created Time:</td>
|
||||
<td>{{ form.createTime }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Env:</td>
|
||||
<td>{{ form.runEnv }}</td>
|
||||
<td>Memory Size:</td>
|
||||
<td>{{ form.memorySize }}</td>
|
||||
<td>Timeout:</td>
|
||||
<td>{{ form.timeout }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Code Size:</td>
|
||||
<td>{{ form.codeSize }}</td>
|
||||
<td>Code Checksum:</td>
|
||||
<td :colspan="3">{{ form.codeChecksum }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td :colspan="5">{{ form.description }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>EnviromentVariable:</td>
|
||||
<td :colspan="2">{{ form.envVar }}</td>
|
||||
<td :colspan="3">
|
||||
<!-- Enable Native Serverless:
|
||||
<el-switch
|
||||
v-model="form.enableNS"
|
||||
size="small">
|
||||
</el-switch> -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<el-row style="margin-bottom:30px" :gutter="30">
|
||||
<el-col :span="9">
|
||||
<p>Args:</p>
|
||||
<el-input
|
||||
v-model="jsonObject"
|
||||
type="textarea"
|
||||
rows="6"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1">
|
||||
<el-button class="invokeBtn" @click="invoke">invoke</el-button>
|
||||
</el-col>
|
||||
<el-col :offset="1" :span="9">
|
||||
<p>函数返回值:</p>
|
||||
<el-input v-model="result" rows="6" type="textarea" readonly />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-button @click="getResult">查看过程</el-button> -->
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-card>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<el-row style="margin-bottom:30px" :gutter="30">
|
||||
<el-col :span="9">
|
||||
<p>Args:</p>
|
||||
<el-input
|
||||
v-model="jsonObject"
|
||||
type="textarea"
|
||||
rows="6"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="2" :offset="1">
|
||||
<el-button class="invokeBtn" type="primary" @click="invoke">invoke</el-button>
|
||||
</el-col>
|
||||
<el-col :offset="1" :span="9">
|
||||
<p>函数返回值:</p>
|
||||
<el-input v-model="result" rows="6" type="textarea" readonly />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- <el-button @click="getResult">查看过程</el-button> -->
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -170,6 +167,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
active: 1,
|
||||
dialogCreateVisible: false,
|
||||
dialogExecuteVisible: false,
|
||||
interval: '',
|
||||
|
@ -197,7 +195,7 @@ export default {
|
|||
functionList: [], // 函数列表
|
||||
fileList: [],
|
||||
page: 1,
|
||||
size: 10,
|
||||
size: 12,
|
||||
total: 0
|
||||
}
|
||||
},
|
||||
|
@ -298,7 +296,57 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.cloudComputation{
|
||||
.functionList{
|
||||
margin: 30px 20px;
|
||||
.opr-btn{
|
||||
font-size: 16px;
|
||||
padding: 10px 36px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.el-button--primary{
|
||||
background-color: #468EFC;
|
||||
}
|
||||
.el-card{
|
||||
border: 1px solid #EEEEEE;
|
||||
border-radius: 5px;
|
||||
margin-top:0;
|
||||
.btn-group{
|
||||
width: 100%;
|
||||
padding: 10px 30px;
|
||||
}
|
||||
.el-button{
|
||||
width: 45%;
|
||||
margin:0
|
||||
}
|
||||
.el-popover__reference{
|
||||
margin-right: 10%;
|
||||
}
|
||||
}
|
||||
.el-steps{
|
||||
width: 80%;
|
||||
margin: auto;
|
||||
.el-step__icon.is-text{
|
||||
background: #BCBCBC;
|
||||
color: #ffffff;
|
||||
border-color:#BCBCBC;
|
||||
}
|
||||
.el-step__head.is-finish .is-text{
|
||||
border-color:#468EFC;
|
||||
background: #468EFC;
|
||||
}
|
||||
.el-step.is-horizontal .el-step__line {
|
||||
|
||||
top: 11px;
|
||||
height: 1px;
|
||||
background: #DFDFDF;
|
||||
left: 10%;
|
||||
right: 0;
|
||||
width: 85%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.functionList{
|
||||
.el-tabs__header{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -334,7 +382,7 @@ export default {
|
|||
margin: 30px auto;
|
||||
}
|
||||
.invokeBtn{
|
||||
margin: 40px auto;
|
||||
margin: 60px auto;
|
||||
}
|
||||
}
|
||||
.functionCard{
|
||||
|
@ -345,19 +393,45 @@ export default {
|
|||
padding-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
p{
|
||||
margin: 10px 30px;
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
position: relative;
|
||||
text-indent: 1em;
|
||||
}
|
||||
p:before{
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #2FB4AA;
|
||||
border-radius: 50%;
|
||||
top: 5px;
|
||||
left: 0em;
|
||||
}
|
||||
.title{
|
||||
margin:20px;
|
||||
margin-bottom: 10px;
|
||||
margin:20px 27px;
|
||||
// margin-bottom: 10px;
|
||||
font-size: 18px;
|
||||
text-indent: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
.title:before{
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
.el-button--text{
|
||||
line-height: 1.1rem;
|
||||
}
|
||||
p{
|
||||
margin: 10px 20px;
|
||||
// margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.el-button{
|
||||
margin:10px;
|
||||
border:1px solid #468EFC ;
|
||||
border-radius: 0;
|
||||
}
|
||||
.el-button--default{
|
||||
color: #468EFC;
|
||||
}
|
||||
.insideFloatRight {
|
||||
margin: 0;
|
||||
|
|
|
@ -181,10 +181,14 @@ export default {
|
|||
this.$store.dispatch('user/login', this.loginForm)
|
||||
.then(() => {
|
||||
this.$message.success('登录成功')
|
||||
if (localStorage.getItem('clusterName')) {
|
||||
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
|
||||
if (this.redirect) {
|
||||
if (this.redirect.indexOf('cluster') && !localStorage.getItem('clusterName')) {
|
||||
this.$router.push({ path: '/clusterSelect' })
|
||||
} else {
|
||||
this.$router.push({ path: this.redirect, query: this.otherQuery })
|
||||
}
|
||||
} else {
|
||||
this.$router.push({ path: '/cluster' })
|
||||
this.$router.push({ path: '/monitorSelect' })
|
||||
}
|
||||
this.loading = false
|
||||
})
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<div class="monitor-select">
|
||||
<Navbar />
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/cluster/overview')">
|
||||
<p>容器管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/virtual/overview')">
|
||||
<p>虚拟机管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/functions/overview')">
|
||||
<p>函数管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<a class="monitorSelectBtn" @click="selectMonitor('/blockChain/blockChainBrowser')">
|
||||
<p>块链管理</p>
|
||||
</a>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Navbar from '@/layout/components/Navbar'
|
||||
|
||||
export default {
|
||||
name: 'MonitorSelect',
|
||||
components: { Navbar },
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
selectMonitor(monitor) {
|
||||
this.$store.dispatch('user/setRouteType', monitor.split('/')[1])
|
||||
this.$router.push({ path: monitor })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.monitor-select{
|
||||
.el-col a{
|
||||
display: block;
|
||||
width: 80%;
|
||||
margin: 30px auto;
|
||||
height: 80vh;
|
||||
padding: 30px;
|
||||
border: 1px solid #419ef4;
|
||||
border-radius: 30px;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<div class="functionOverview">
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img src="@/assets/img/hanshu-.png">
|
||||
<h4>函数概览</h4>
|
||||
</el-card>
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>函数调用概览</span>
|
||||
</div>
|
||||
<div v-for="(value,key) in dataMap" :key="key" class="overviewInfo">
|
||||
<span>
|
||||
{{ value }}
|
||||
</span>
|
||||
<p>{{ data[key] }}</p>
|
||||
</div>
|
||||
<!-- <FormData :column="3" :data="data" :data-map="dataMap" /> -->
|
||||
</el-card>
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>函数监控(日创建次数)</span>
|
||||
</div>
|
||||
<div id="lineChart" ref="lineChart" />
|
||||
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import { FormData } from '@/components/FormData'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
export default {
|
||||
// components: { FormData },
|
||||
data() {
|
||||
return {
|
||||
data: {
|
||||
allInstanceConcurrency: 0,
|
||||
allCodeSize: '200Mb',
|
||||
allTimeout: '2000s'
|
||||
},
|
||||
dataMap: {
|
||||
allInstanceConcurrency: '总单实例并发度',
|
||||
allCodeSize: '函数总代码大小',
|
||||
allTimeout: '函数执行总超时时长'
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getOverview()
|
||||
this.initChart()
|
||||
},
|
||||
methods: {
|
||||
getOverview() {
|
||||
this.$Api.getFunctionOverview().then(res => {
|
||||
this.data = res.data
|
||||
this.data.allCodeSize = this.data.allCodeSize + 'Mb'
|
||||
this.data.allTimeout = this.data.allTimeout + 's'
|
||||
})
|
||||
},
|
||||
initChart() {
|
||||
this.$Api.getFunctionMap().then(res => {
|
||||
const createCount = res.data.map(i => i.createCount)
|
||||
const createdTime = res.data.map(i => i.createdTime)
|
||||
const chartOption = {
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
axisLine: { lineStyle: { color: '#999999' }},
|
||||
data: createdTime
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: { lineStyle: { color: '#999999' }}
|
||||
},
|
||||
series: [{
|
||||
data: createCount,
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: 'rgba(0, 55, 255, 1)'
|
||||
},
|
||||
smooth: true,
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [{
|
||||
offset: 0, color: '#409eff' // 0% 处的颜色
|
||||
}, {
|
||||
offset: 1, color: 'white' // 100% 处的颜色
|
||||
}],
|
||||
global: false // 缺省为 false
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
const lineChart = echarts.init(this.$refs.lineChart)
|
||||
lineChart.setOption(chartOption)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" >
|
||||
.functionOverview{
|
||||
.el-card{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.el-card .el-card__header{
|
||||
font-size: 16px;
|
||||
padding-top: 30px;
|
||||
}
|
||||
.overviewInfo{
|
||||
width: 219px;
|
||||
height: 131px;
|
||||
display: inline-block;
|
||||
margin-right: 30px;
|
||||
margin-bottom: 10px;
|
||||
background: #F7F7F7;
|
||||
border-radius: 10px;
|
||||
padding:42px 20px;
|
||||
position: relative;
|
||||
span{color: #505879;}
|
||||
p{
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
.overviewInfo:before{
|
||||
content: '';
|
||||
width: 42px;
|
||||
height: 4px;
|
||||
background: #468EFC;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
left: 20px;
|
||||
}
|
||||
#lineChart{
|
||||
width: 100%;
|
||||
height: 35vh;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
|
@ -1,41 +1,19 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-tabs v-model="activeName" class="overviewTabs">
|
||||
<el-tab-pane name="first">
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img v-if="activeName==='first'" src="@/assets/img/xnj-.png">
|
||||
<img v-else src="@/assets/img/xnj.png">
|
||||
<h4>虚拟机概览</h4>
|
||||
</el-card>
|
||||
<VirtualMachine />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="second">
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img v-if="activeName==='second'" src="@/assets/img/rq.png">
|
||||
<img v-else src="@/assets/img/rq-.png">
|
||||
<h4>容器概览</h4>
|
||||
</el-card>
|
||||
<Pod v-if="activeName==='second'" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="third">
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img v-if="activeName==='third'" src="@/assets/img/hanshu-.png">
|
||||
<img v-else src="@/assets/img/hanshu.png">
|
||||
<h4>函数概览</h4>
|
||||
</el-card>
|
||||
<Function v-if="activeName==='third'" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img src="@/assets/img/rq.png">
|
||||
<h4>容器概览</h4>
|
||||
</el-card>
|
||||
<Pod />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pod from './components/pod'
|
||||
import VirtualMachine from './components/virtualMachine'
|
||||
import Function from './components/function'
|
||||
import Pod from './pod'
|
||||
// import VirtualMachine from './virtualMachine'
|
||||
// import Function from './function'
|
||||
export default {
|
||||
components: { Pod, VirtualMachine, Function },
|
||||
components: { Pod },
|
||||
data() {
|
||||
return {
|
||||
activeName: 'first'
|
||||
|
@ -51,31 +29,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.overviewTabs{
|
||||
.el-tabs__nav-wrap::after{
|
||||
display: none;
|
||||
}
|
||||
.el-tabs__active-bar{
|
||||
display: none;
|
||||
}
|
||||
.el-tabs__item.is-active .overviewTab{
|
||||
background-color: #419ef4;
|
||||
color:#fff;
|
||||
}
|
||||
.el-tabs__nav{
|
||||
width: 100%;
|
||||
}
|
||||
.el-tabs__item{
|
||||
width: 33.33%;
|
||||
padding: 0;
|
||||
|
||||
}
|
||||
.el-tabs__header{
|
||||
margin:0;
|
||||
}
|
||||
|
||||
}
|
||||
.overviewTab{
|
||||
width: 30%;
|
||||
background-color: #419ef4;
|
||||
color:#fff;
|
||||
// cursor: pointer;
|
||||
border-radius: 10px;
|
||||
.el-card__body{
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="12">
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>集群信息</span>
|
||||
</div>
|
||||
<ClusterMessage />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>JCCE组件状态</span>
|
||||
</div>
|
||||
<ComponentStatus />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>集群资源使用情况</span>
|
||||
</div>
|
||||
<ResourceUsage />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-card shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>节点用量 Top5</span>
|
||||
</div>
|
||||
<NodeMessage />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ClusterMessage from '@/components/ClusterManagement/clusterMessage'
|
||||
import ComponentStatus from '@/components/ClusterManagement/componentStatus'
|
||||
import NodeMessage from '@/components/ClusterManagement/nodeMessage'
|
||||
import ResourceUsage from '@/components/ClusterManagement/resourceUsage'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ClusterMessage, ComponentStatus, ResourceUsage, NodeMessage
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-card slot="label" class="overviewTab" shadow="never">
|
||||
<img src="@/assets/img/xnj-.png">
|
||||
<h4>虚拟机概览</h4>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="virtualMachineChart">
|
||||
<el-row :gutter="5">
|
||||
<el-col :span="8">
|
||||
<h4>cpu</h4>
|
||||
<div id="cpuGauge" ref="cpuGauge" />
|
||||
<p>cpu4中的0.39</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<h4>内存</h4>
|
||||
<div id="memoryGauge" ref="memoryGauge" />
|
||||
<p>内存7.75GiB中的4.27</p>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<h4>存储</h4>
|
||||
<div id="storageGauge" ref="storageGauge" />
|
||||
<p>存储197GiB中的9.84</p>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
<table class="table" border="0">
|
||||
<tr>
|
||||
<th>主机</th>
|
||||
<th>虚拟机</th>
|
||||
<th>网络</th>
|
||||
<th>镜像</th>
|
||||
<th>存储卷</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>2</td>
|
||||
<td>3</td>
|
||||
<td>2</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h4>事件</h4>
|
||||
<List
|
||||
ref="multipleTable"
|
||||
:table-list-data="listData"
|
||||
:columns="columns"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from '@/components/list'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
export default {
|
||||
components: { List },
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
{ prop: 'reason', label: '原因', width: '150' },
|
||||
{ prop: 'info', label: '资源信息' },
|
||||
{ prop: 'time', label: '发生时间', width: '150' }
|
||||
],
|
||||
listData: [
|
||||
{
|
||||
reason: 'Created',
|
||||
info: 'VirtualMachineInstance educoder-main VirtualMachineInstance defined. ',
|
||||
time: '2021/4/23 9:40'
|
||||
},
|
||||
{
|
||||
reason: 'Started',
|
||||
info: 'VirtualMachineInstance educoder-main VirtualMachineInstance defined. ',
|
||||
time: '2021/4/23 9:40'
|
||||
},
|
||||
{
|
||||
reason: 'Stopped',
|
||||
info: 'VirtualMachineInstance educoder-main VirtualMachineInstance defined. ',
|
||||
time: '2021/4/23 9:40'
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$nextTick(() => {
|
||||
this.drawChart()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
drawChart() {
|
||||
const cpuGauge = echarts.init(this.$refs.cpuGauge)
|
||||
cpuGauge.setOption(this.returnGaugeOption(5))
|
||||
const memoryGauge = echarts.init(this.$refs.memoryGauge)
|
||||
memoryGauge.setOption(this.returnGaugeOption(16))
|
||||
const storageGauge = echarts.init(this.$refs.storageGauge)
|
||||
storageGauge.setOption(this.returnGaugeOption(3))
|
||||
},
|
||||
returnGaugeOption(data) {
|
||||
return {
|
||||
series: [
|
||||
{
|
||||
type: 'gauge',
|
||||
detail: {
|
||||
formatter: '{value}%',
|
||||
color: '#000000',
|
||||
fontSize: 20,
|
||||
offsetCenter: [0, '0']
|
||||
},
|
||||
center: ['50%', '78%'],
|
||||
radius: '100%',
|
||||
data: [{ value: data }],
|
||||
itemStyle: {
|
||||
color: 'transparent'
|
||||
// show: false,
|
||||
},
|
||||
// splitLine: { show: false },
|
||||
// axisTick: { show: false },
|
||||
axisLabel: { show: false },
|
||||
|
||||
startAngle: 200,
|
||||
endAngle: -20,
|
||||
// progress: {
|
||||
// show: false,
|
||||
// // width: 1,
|
||||
// // itemStyle: { color: '#419ef4' }
|
||||
// },
|
||||
|
||||
axisTick: {
|
||||
length: 16,
|
||||
lineStyle: {
|
||||
color: 'auto',
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
length: 20,
|
||||
lineStyle: {
|
||||
color: 'auto',
|
||||
width: 2
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
width: 6,
|
||||
color: [
|
||||
[data / 100, '#419ef4'],
|
||||
[1, '#dddddd']
|
||||
]
|
||||
}
|
||||
}
|
||||
// axisLine: { lineStyle: { color: [[1, '#409eff']], width: 10 }}
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
#cpuGauge,#memoryGauge,#storageGauge{
|
||||
width: 100%;
|
||||
height: 210px;
|
||||
}
|
||||
.virtualMachineChart{
|
||||
p{
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
|
@ -4,33 +4,23 @@
|
|||
<script>
|
||||
import * as Three from 'three'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
import { getEarthRegion } from '@/api/screen -one-class-page/TotalNum'
|
||||
import { getEarthDetails } from '@/api/screen -one-class-page/TotalNum'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mshs: 1.0,
|
||||
satellitesArr: [],
|
||||
mapMarks: [
|
||||
{
|
||||
value: [116.423784, 39.876303],
|
||||
name: '北京',
|
||||
count: 1637
|
||||
},
|
||||
{
|
||||
value: [120.161360422694918, 30.25886728953814],
|
||||
name: '杭州',
|
||||
count: 1328
|
||||
},
|
||||
{ name: '东京', value: [139.766037, 35.724993], count: 615 },
|
||||
{ name: '新加坡', value: [103.865254, 1.35353], count: 5 },
|
||||
{ name: '孟买', value: [72.841576, 19.017378], count: 5 },
|
||||
{ name: '伦敦', value: [-0.138681, 51.529409], count: 11 },
|
||||
{ name: '迪拜', value: [55.331252, 25.290169], count: 2 }
|
||||
]
|
||||
mapMarks: [],
|
||||
area: []
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getEarth()
|
||||
// this.date_trans()
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
this.$nextTick(() => {
|
||||
// this.drawBarchart()
|
||||
// this.chinaConfigure()
|
||||
// this.load_average()
|
||||
|
@ -38,11 +28,40 @@ export default {
|
|||
// this.memory_total()
|
||||
// this.memory_average()
|
||||
// this.resource_used()
|
||||
this.init()
|
||||
this.init()
|
||||
// this.animate()
|
||||
})
|
||||
})
|
||||
}, 1000)
|
||||
},
|
||||
methods: {
|
||||
getEarth() {
|
||||
getEarthRegion().then(res => {
|
||||
const demo = res.data
|
||||
const that = this
|
||||
// console.log(demo)
|
||||
for (let i = 0; i < demo.length; i++) {
|
||||
const modelItem = []
|
||||
const value = []
|
||||
modelItem['name'] = demo[i].area
|
||||
modelItem['count'] = demo[i].areaCount
|
||||
value[0] = demo[i].value[0]
|
||||
value[1] = demo[i].value[1]
|
||||
modelItem['value'] = value
|
||||
that.mapMarks[i] = modelItem
|
||||
}
|
||||
// console.log(that.mapMarks)
|
||||
})
|
||||
getEarthDetails('杭州').then(res => {
|
||||
const demo = res.data
|
||||
const that = this
|
||||
that.area['resourceArea'] = demo.resourceArea
|
||||
that.area['userNum'] = demo.userNum
|
||||
that.area['areaCount'] = demo.areaCount
|
||||
that.area['clusterNum'] = demo.clusterNum
|
||||
that.area['usagedRate'] = demo.usagedRate
|
||||
// console.log(that.area)
|
||||
})
|
||||
},
|
||||
init() {
|
||||
const earth = document.getElementById('earth')
|
||||
|
||||
|
@ -134,7 +153,7 @@ export default {
|
|||
// this.scene.add(this.mesh4)
|
||||
// this.scene.add(this.mesh5)
|
||||
this.setMark(this.mapMarks)
|
||||
this.setAreaMark()
|
||||
this.setAreaMark(this.area)
|
||||
this.renderer.setSize(width, height)// 设置渲染区域尺寸
|
||||
// this.renderer.setClearColor(0x03060f, 1) // 设置背景颜色
|
||||
earth.appendChild(this.renderer.domElement)
|
||||
|
@ -213,7 +232,7 @@ export default {
|
|||
context.stroke()
|
||||
return canvas
|
||||
},
|
||||
setAreaMark() {
|
||||
setAreaMark(_area) {
|
||||
const borderSize = 2
|
||||
const ctx = document.createElement('canvas').getContext('2d')
|
||||
// measure how long the name will be
|
||||
|
@ -230,11 +249,11 @@ export default {
|
|||
ctx.strokeStyle = '#008aff'
|
||||
ctx.strokeRect(0, 0, width, 580)
|
||||
ctx.fillStyle = 'white'
|
||||
ctx.fillText('资源区域:亚太1区', borderSize * 30, borderSize * 20)
|
||||
ctx.fillText('活跃用户:1574', borderSize * 30, borderSize * 20 + 100)
|
||||
ctx.fillText('服务器数量:3580', borderSize * 30, borderSize * 20 + 200)
|
||||
ctx.fillText('集群数量:284', borderSize * 30, borderSize * 20 + 300)
|
||||
ctx.fillText('资源使用率:50%', borderSize * 30, borderSize * 20 + 400)
|
||||
ctx.fillText('资源区域: ' + _area.resourceArea, borderSize * 30, borderSize * 20)
|
||||
ctx.fillText('活跃用户: ' + _area.userNum, borderSize * 30, borderSize * 20 + 100)
|
||||
ctx.fillText('服务器数量: ' + _area.areaCount, borderSize * 30, borderSize * 20 + 200)
|
||||
ctx.fillText('集群数量: ' + _area.clusterNum, borderSize * 30, borderSize * 20 + 300)
|
||||
ctx.fillText('资源使用率: ' + _area.usagedRate, borderSize * 30, borderSize * 20 + 400)
|
||||
|
||||
const markPos = this.getPosition(130.21029 + 90, 23.527138, 100)
|
||||
var texture = new Three.CanvasTexture(ctx.canvas)
|
||||
|
@ -284,14 +303,17 @@ export default {
|
|||
this.marking.add(mesh)
|
||||
|
||||
// text
|
||||
// console.log(typeof (_markData[i].name + ':' + _markData[i].count + '个'))
|
||||
var texture = new Three.CanvasTexture(this.getCanvasFont(_markData[i].name + ':' + _markData[i].count + '个'))
|
||||
// console.log(_markData[i].count.toString().length)
|
||||
const fontNumber = _markData[i].count.toString().length * 5.8642578125 + _markData[i].name.length * 10 + 10 + 2.4072265625 + 5
|
||||
texture.needsUpdate = true
|
||||
var fontMesh = new Three.Sprite(
|
||||
new Three.SpriteMaterial({
|
||||
map: texture
|
||||
})
|
||||
)
|
||||
fontMesh.scale.x = 40
|
||||
fontMesh.scale.x = fontNumber
|
||||
fontMesh.scale.y = 10
|
||||
fontMesh.position.set(markPos.x + 10, markPos.y + 10, markPos.z - 20)
|
||||
this.textMarking.add(fontMesh)
|
||||
|
@ -304,19 +326,25 @@ export default {
|
|||
const ctx = document.createElement('canvas').getContext('2d')
|
||||
// measure how long the name will be
|
||||
const doubleBorderSize = borderSize * 2
|
||||
const width = (ctx.measureText(name).width + doubleBorderSize) * 10
|
||||
const width = (ctx.measureText(name).width + doubleBorderSize * 2) * 11
|
||||
ctx.canvas.width = width
|
||||
// ctx.canvas.height = height
|
||||
// ctx.canvas.height = hei ght
|
||||
// need to set font again after resizing canvas
|
||||
ctx.textBaseline = 'top'
|
||||
ctx.font = '80px Arial'
|
||||
ctx.font = '85px Arial'
|
||||
ctx.lineWidth = 15
|
||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'
|
||||
ctx.fillRect(0, 0, width, 150)
|
||||
ctx.strokeStyle = '#00ffd2'
|
||||
ctx.strokeRect(0, 0, width, 150)
|
||||
ctx.fillStyle = 'white'
|
||||
ctx.fillText(name, borderSize * 30, borderSize * 20)
|
||||
// console.log(ctx.measureText(name).width)
|
||||
if (ctx.measureText(name).width > 540) {
|
||||
ctx.fillText(name, borderSize * 80, borderSize * 20)
|
||||
} else {
|
||||
ctx.fillText(name, borderSize * 60, borderSize * 20)
|
||||
}
|
||||
|
||||
return ctx.canvas
|
||||
},
|
||||
getPosition(_longitude, _latitude, _radius) {
|
||||
|
|
208
yarn.lock
|
@ -14,7 +14,7 @@
|
|||
"resolved" "https://registry.nlark.com/@babel/compat-data/download/@babel/compat-data-7.14.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40babel%2Fcompat-data%2Fdownload%2F%40babel%2Fcompat-data-7.14.0.tgz"
|
||||
"version" "7.14.0"
|
||||
|
||||
"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.1.0", "@babel/core@^7.11.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.4.0-0", "@babel/core@^7.9.6":
|
||||
"@babel/core@^7.1.0", "@babel/core@^7.11.0", "@babel/core@^7.9.6":
|
||||
"integrity" "sha1-U5XjBAXwd2Bn+9nPCITxW/t3Cjg="
|
||||
"resolved" "https://registry.nlark.com/@babel/core/download/@babel/core-7.14.3.tgz"
|
||||
"version" "7.14.3"
|
||||
|
@ -1505,7 +1505,7 @@
|
|||
"resolved" "https://registry.nlark.com/@vue/cli-plugin-vuex/download/@vue/cli-plugin-vuex-4.5.13.tgz"
|
||||
"version" "4.5.13"
|
||||
|
||||
"@vue/cli-service@^3.0.0 || ^4.0.0-0", "@vue/cli-service@4.4.4":
|
||||
"@vue/cli-service@4.4.4":
|
||||
"integrity" "sha1-JWyZDkmi/43FM7dzxQSmVDXHXEw="
|
||||
"resolved" "https://registry.nlark.com/@vue/cli-service/download/@vue/cli-service-4.4.4.tgz?cache=0&sync_timestamp=1620981774837&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40vue%2Fcli-service%2Fdownload%2F%40vue%2Fcli-service-4.4.4.tgz"
|
||||
"version" "4.4.4"
|
||||
|
@ -1816,7 +1816,7 @@
|
|||
"resolved" "https://registry.nlark.com/acorn/download/acorn-5.7.4.tgz?cache=0&sync_timestamp=1620134123724&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-5.7.4.tgz"
|
||||
"version" "5.7.4"
|
||||
|
||||
"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", "acorn@^6.0.1", "acorn@^6.4.1":
|
||||
"acorn@^6.0.1", "acorn@^6.4.1":
|
||||
"integrity" "sha1-NYZv1xBSjpLeEM8GAWSY5H454eY="
|
||||
"resolved" "https://registry.nlark.com/acorn/download/acorn-6.4.2.tgz?cache=0&sync_timestamp=1620134123724&other_urls=https%3A%2F%2Fregistry.nlark.com%2Facorn%2Fdownload%2Facorn-6.4.2.tgz"
|
||||
"version" "6.4.2"
|
||||
|
@ -1867,7 +1867,7 @@
|
|||
"resolved" "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1616882441894&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz"
|
||||
"version" "3.5.2"
|
||||
|
||||
"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.3", "ajv@^6.12.4", "ajv@^6.9.1", "ajv@>=5.0.0":
|
||||
"ajv@^6.1.0", "ajv@^6.10.0", "ajv@^6.10.2", "ajv@^6.12.3", "ajv@^6.12.4":
|
||||
"integrity" "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ="
|
||||
"resolved" "https://registry.nlark.com/ajv/download/ajv-6.12.6.tgz?cache=0&sync_timestamp=1621517743418&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fajv%2Fdownload%2Fajv-6.12.6.tgz"
|
||||
"version" "6.12.6"
|
||||
|
@ -2076,11 +2076,6 @@
|
|||
"resolved" "https://registry.nlark.com/array-uniq/download/array-uniq-1.0.3.tgz?cache=0&sync_timestamp=1620042045402&other_urls=https%3A%2F%2Fregistry.nlark.com%2Farray-uniq%2Fdownload%2Farray-uniq-1.0.3.tgz"
|
||||
"version" "1.0.3"
|
||||
|
||||
"array-uniq@1.0.2":
|
||||
"integrity" "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0="
|
||||
"resolved" "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
|
||||
"array-unique@^0.2.1":
|
||||
"integrity" "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM="
|
||||
"resolved" "https://registry.npm.taobao.org/array-unique/download/array-unique-0.2.1.tgz"
|
||||
|
@ -2222,7 +2217,7 @@
|
|||
"esutils" "^2.0.2"
|
||||
"js-tokens" "^3.0.2"
|
||||
|
||||
"babel-core@^6.0.0 || ^7.0.0-0", "babel-core@^6.25.0 || ^7.0.0-0", "babel-core@^7.0.0-bridge.0":
|
||||
"babel-core@^7.0.0-bridge.0":
|
||||
"integrity" "sha1-laSS3dkPm06aSh2hTrM1uHtjTs4="
|
||||
"resolved" "https://registry.npm.taobao.org/babel-core/download/babel-core-7.0.0-bridge.0.tgz"
|
||||
"version" "7.0.0-bridge.0"
|
||||
|
@ -3074,13 +3069,12 @@
|
|||
dependencies:
|
||||
"anymatch" "~3.1.1"
|
||||
"braces" "~3.0.2"
|
||||
"fsevents" "~2.3.1"
|
||||
"glob-parent" "~5.1.0"
|
||||
"is-binary-path" "~2.1.0"
|
||||
"is-glob" "~4.0.1"
|
||||
"normalize-path" "~3.0.0"
|
||||
"readdirp" "~3.5.0"
|
||||
optionalDependencies:
|
||||
"fsevents" "~2.3.1"
|
||||
|
||||
"chokidar@>=2.0.0 <4.0.0", "chokidar@2.1.5":
|
||||
"integrity" "sha1-CuhDTZYigaX1bHKGnnnLbZ2GrU0="
|
||||
|
@ -3264,11 +3258,6 @@
|
|||
"resolved" "https://registry.npm.taobao.org/clone/download/clone-2.1.2.tgz"
|
||||
"version" "2.1.2"
|
||||
|
||||
"clone@^2.1.2":
|
||||
"integrity" "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
||||
"resolved" "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz"
|
||||
"version" "2.1.2"
|
||||
|
||||
"clone@2.x":
|
||||
"integrity" "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
||||
"resolved" "https://registry.npm.taobao.org/clone/download/clone-2.1.2.tgz"
|
||||
|
@ -3527,13 +3516,6 @@
|
|||
"resolved" "https://registry.npm.taobao.org/cookie/download/cookie-0.4.0.tgz"
|
||||
"version" "0.4.0"
|
||||
|
||||
"copy-anything@^2.0.1":
|
||||
"integrity" "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ=="
|
||||
"resolved" "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz"
|
||||
"version" "2.0.3"
|
||||
dependencies:
|
||||
"is-what" "^3.12.0"
|
||||
|
||||
"copy-concurrently@^1.0.0":
|
||||
"integrity" "sha1-kilzmMrjSTf8r9bsgTnBgFHwteA="
|
||||
"resolved" "https://registry.npm.taobao.org/copy-concurrently/download/copy-concurrently-1.0.5.tgz"
|
||||
|
@ -3705,7 +3687,7 @@
|
|||
"postcss" "^7.0.1"
|
||||
"timsort" "^0.3.0"
|
||||
|
||||
"css-loader@*", "css-loader@^3.5.3":
|
||||
"css-loader@^3.5.3":
|
||||
"integrity" "sha1-Lkssfm4tJ/jI8o9hv/zS5ske9kU="
|
||||
"resolved" "https://registry.nlark.com/css-loader/download/css-loader-3.6.0.tgz"
|
||||
"version" "3.6.0"
|
||||
|
@ -3959,8 +3941,8 @@
|
|||
"ms" "^2.1.1"
|
||||
|
||||
"debug@^3.2.6":
|
||||
"integrity" "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="
|
||||
"resolved" "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz"
|
||||
"integrity" "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o="
|
||||
"resolved" "https://registry.npm.taobao.org/debug/download/debug-3.2.7.tgz?cache=0&sync_timestamp=1607566571506&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-3.2.7.tgz"
|
||||
"version" "3.2.7"
|
||||
dependencies:
|
||||
"ms" "^2.1.1"
|
||||
|
@ -4465,7 +4447,7 @@
|
|||
"resolved" "https://registry.nlark.com/entities/download/entities-2.2.0.tgz"
|
||||
"version" "2.2.0"
|
||||
|
||||
"errno@^0.1.1", "errno@^0.1.3", "errno@~0.1.7":
|
||||
"errno@^0.1.3", "errno@~0.1.7":
|
||||
"integrity" "sha1-i7Ppx9Rjvkl2/4iPdrSAnrwugR8="
|
||||
"resolved" "https://registry.nlark.com/errno/download/errno-0.1.8.tgz"
|
||||
"version" "0.1.8"
|
||||
|
@ -4597,7 +4579,7 @@
|
|||
"resolved" "https://registry.nlark.com/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz?cache=0&sync_timestamp=1620088667316&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz"
|
||||
"version" "1.3.0"
|
||||
|
||||
"eslint@^5.0.0 || ^6.0.0", "eslint@>= 1.6.0", "eslint@>= 4.12.1", "eslint@>=1.6.0 <7.0.0", "eslint@>=5.0.0", "eslint@6.7.2":
|
||||
"eslint@6.7.2":
|
||||
"integrity" "sha1-wXcHykrXstivmGoz/rpx4Yqf7NE="
|
||||
"resolved" "https://registry.nlark.com/eslint/download/eslint-6.7.2.tgz?cache=0&sync_timestamp=1621646990959&other_urls=https%3A%2F%2Fregistry.nlark.com%2Feslint%2Fdownload%2Feslint-6.7.2.tgz"
|
||||
"version" "6.7.2"
|
||||
|
@ -4694,9 +4676,7 @@
|
|||
"version" "1.8.1"
|
||||
|
||||
"eve@git://github.com/adobe-webplatform/eve.git#eef80ed":
|
||||
"integrity" "sha512-VrMCMjRWGSuyiV/1SP58K4lIui3jlfD3uBapV8jahx9/RsqZad/FL7Tq5NRTHWFI8yd1dVLgUrEDPrA70gnOTw=="
|
||||
"resolved" "git+ssh://git@github.com/adobe-webplatform/eve.git#eef80ed8d188423c2272746fb8ae5cc8dad84cb1"
|
||||
"version" "0.4.1"
|
||||
|
||||
"event-pubsub@4.3.0":
|
||||
"integrity" "sha1-9o2Ba8KfHsAsU53FjI3UDOcss24="
|
||||
|
@ -5009,7 +4989,7 @@
|
|||
dependencies:
|
||||
"flat-cache" "^2.0.1"
|
||||
|
||||
"file-loader@*", "file-loader@^4.2.0":
|
||||
"file-loader@^4.2.0":
|
||||
"integrity" "sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8="
|
||||
"resolved" "https://registry.nlark.com/file-loader/download/file-loader-4.3.0.tgz"
|
||||
"version" "4.3.0"
|
||||
|
@ -5322,6 +5302,19 @@
|
|||
"resolved" "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz"
|
||||
"version" "1.0.0"
|
||||
|
||||
"fsevents@^1.2.7":
|
||||
"integrity" "sha1-8yXLBFVZJCi88Rs4M3DvcOO/zDg="
|
||||
"resolved" "https://registry.npm.taobao.org/fsevents/download/fsevents-1.2.13.tgz"
|
||||
"version" "1.2.13"
|
||||
dependencies:
|
||||
"bindings" "^1.5.0"
|
||||
"nan" "^2.12.1"
|
||||
|
||||
"fsevents@~2.3.1":
|
||||
"integrity" "sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro="
|
||||
"resolved" "https://registry.npm.taobao.org/fsevents/download/fsevents-2.3.2.tgz"
|
||||
"version" "2.3.2"
|
||||
|
||||
"function-bind@^1.1.1":
|
||||
"integrity" "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
|
||||
"resolved" "https://registry.npm.taobao.org/function-bind/download/function-bind-1.1.1.tgz"
|
||||
|
@ -5578,9 +5571,8 @@
|
|||
"minimist" "^1.2.5"
|
||||
"neo-async" "^2.6.0"
|
||||
"source-map" "^0.6.1"
|
||||
"wordwrap" "^1.0.0"
|
||||
optionalDependencies:
|
||||
"uglify-js" "^3.1.4"
|
||||
"wordwrap" "^1.0.0"
|
||||
|
||||
"har-schema@^2.0.0":
|
||||
"integrity" "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
|
@ -5816,7 +5808,7 @@
|
|||
"resolved" "https://registry.npm.taobao.org/html-tags/download/html-tags-3.1.0.tgz"
|
||||
"version" "3.1.0"
|
||||
|
||||
"html-webpack-plugin@^3.0.0 || ^4.0.0", "html-webpack-plugin@^3.2.0", "html-webpack-plugin@>=2.26.0", "html-webpack-plugin@3.2.0":
|
||||
"html-webpack-plugin@^3.2.0", "html-webpack-plugin@3.2.0":
|
||||
"integrity" "sha1-sBq71yOsqqeze2r0SS69oD2d03s="
|
||||
"resolved" "https://registry.nlark.com/html-webpack-plugin/download/html-webpack-plugin-3.2.0.tgz"
|
||||
"version" "3.2.0"
|
||||
|
@ -5910,7 +5902,7 @@
|
|||
"resolved" "https://registry.npm.taobao.org/human-signals/download/human-signals-1.1.1.tgz?cache=0&sync_timestamp=1584198662293&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhuman-signals%2Fdownload%2Fhuman-signals-1.1.1.tgz"
|
||||
"version" "1.1.1"
|
||||
|
||||
"husky@^1.3.1":
|
||||
"husky@1.3.1":
|
||||
"integrity" "sha1-JoI+OZMAOIyir/8Rz6ioawAz+uA="
|
||||
"resolved" "https://registry.npm.taobao.org/husky/download/husky-1.3.1.tgz?cache=0&sync_timestamp=1617004245593&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhusky%2Fdownload%2Fhusky-1.3.1.tgz"
|
||||
"version" "1.3.1"
|
||||
|
@ -5926,7 +5918,7 @@
|
|||
"run-node" "^1.0.0"
|
||||
"slash" "^2.0.0"
|
||||
|
||||
"iconv-lite@^0.4.24", "iconv-lite@^0.4.4", "iconv-lite@0.4.24":
|
||||
"iconv-lite@^0.4.24", "iconv-lite@0.4.24":
|
||||
"integrity" "sha1-ICK0sl+93CHS9SSXSkdKr+czkIs="
|
||||
"resolved" "https://registry.nlark.com/iconv-lite/download/iconv-lite-0.4.24.tgz?cache=0&sync_timestamp=1621826342262&other_urls=https%3A%2F%2Fregistry.nlark.com%2Ficonv-lite%2Fdownload%2Ficonv-lite-0.4.24.tgz"
|
||||
"version" "0.4.24"
|
||||
|
@ -5960,7 +5952,7 @@
|
|||
"resolved" "https://registry.npm.taobao.org/ignore/download/ignore-4.0.6.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fignore%2Fdownload%2Fignore-4.0.6.tgz"
|
||||
"version" "4.0.6"
|
||||
|
||||
"image-size@^0.5.1", "image-size@~0.5.0":
|
||||
"image-size@^0.5.1":
|
||||
"integrity" "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w="
|
||||
"resolved" "https://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz?cache=0&sync_timestamp=1618424661730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimage-size%2Fdownload%2Fimage-size-0.5.5.tgz"
|
||||
"version" "0.5.5"
|
||||
|
@ -6603,11 +6595,6 @@
|
|||
"resolved" "https://registry.npm.taobao.org/is-utf8/download/is-utf8-0.2.1.tgz"
|
||||
"version" "0.2.1"
|
||||
|
||||
"is-what@^3.12.0":
|
||||
"integrity" "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
|
||||
"resolved" "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz"
|
||||
"version" "3.14.1"
|
||||
|
||||
"is-whitespace@^0.3.0":
|
||||
"integrity" "sha1-Fjnssb4DauxppUy7QBz77XEUq38="
|
||||
"resolved" "https://registry.npm.taobao.org/is-whitespace/download/is-whitespace-0.3.0.tgz"
|
||||
|
@ -6957,7 +6944,7 @@
|
|||
"jest-regex-util" "^24.3.0"
|
||||
"jest-snapshot" "^24.9.0"
|
||||
|
||||
"jest-resolve@*", "jest-resolve@^24.9.0":
|
||||
"jest-resolve@^24.9.0":
|
||||
"integrity" "sha1-3/BMdoevNMTdflJIktnPd+XRcyE="
|
||||
"resolved" "https://registry.nlark.com/jest-resolve/download/jest-resolve-24.9.0.tgz"
|
||||
"version" "24.9.0"
|
||||
|
@ -7130,7 +7117,7 @@
|
|||
"merge-stream" "^2.0.0"
|
||||
"supports-color" "^7.0.0"
|
||||
|
||||
"jest@^24.9.0", "jest@>=24 <25":
|
||||
"jest@^24.9.0":
|
||||
"integrity" "sha1-mH0pDAWgi1LFYYjBAC42jtsAcXE="
|
||||
"resolved" "https://registry.nlark.com/jest/download/jest-24.9.0.tgz?cache=0&sync_timestamp=1621937261609&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjest%2Fdownload%2Fjest-24.9.0.tgz"
|
||||
"version" "24.9.0"
|
||||
|
@ -7341,7 +7328,7 @@
|
|||
"integrity" "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss="
|
||||
"resolved" "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz?cache=0&sync_timestamp=1604161876665&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonfile%2Fdownload%2Fjsonfile-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
optionalDependencies:
|
||||
dependencies:
|
||||
"graceful-fs" "^4.1.6"
|
||||
|
||||
"jsonlint@1.6.3":
|
||||
|
@ -7450,49 +7437,6 @@
|
|||
"resolved" "https://registry.npm.taobao.org/left-pad/download/left-pad-1.3.0.tgz"
|
||||
"version" "1.3.0"
|
||||
|
||||
"less-loader@^6.0.0":
|
||||
"integrity" "sha512-k9KrSkjkdGCQwbKPHfbJT9AfRCmOCHCCjiQCc0v2fdVCRTlJvr1Si68Zk6Z4d4UyVkp0U/nEEdQeH4wV/jW8/g=="
|
||||
"resolved" "https://registry.npmjs.org/less-loader/-/less-loader-6.0.0.tgz"
|
||||
"version" "6.0.0"
|
||||
dependencies:
|
||||
"clone" "^2.1.2"
|
||||
"less" "^3.11.1"
|
||||
"loader-utils" "^2.0.0"
|
||||
"schema-utils" "^2.6.6"
|
||||
|
||||
"less@^3.11.1":
|
||||
"integrity" "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw=="
|
||||
"resolved" "https://registry.npmjs.org/less/-/less-3.13.1.tgz"
|
||||
"version" "3.13.1"
|
||||
dependencies:
|
||||
"copy-anything" "^2.0.1"
|
||||
"tslib" "^1.10.0"
|
||||
optionalDependencies:
|
||||
"errno" "^0.1.1"
|
||||
"graceful-fs" "^4.1.2"
|
||||
"image-size" "~0.5.0"
|
||||
"make-dir" "^2.1.0"
|
||||
"mime" "^1.4.1"
|
||||
"native-request" "^1.0.5"
|
||||
"source-map" "~0.6.0"
|
||||
|
||||
"less@^4.1.1":
|
||||
"integrity" "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw=="
|
||||
"resolved" "https://registry.npmjs.org/less/-/less-4.1.1.tgz"
|
||||
"version" "4.1.1"
|
||||
dependencies:
|
||||
"copy-anything" "^2.0.1"
|
||||
"parse-node-version" "^1.0.1"
|
||||
"tslib" "^1.10.0"
|
||||
optionalDependencies:
|
||||
"errno" "^0.1.1"
|
||||
"graceful-fs" "^4.1.2"
|
||||
"image-size" "~0.5.0"
|
||||
"make-dir" "^2.1.0"
|
||||
"mime" "^1.4.1"
|
||||
"needle" "^2.5.2"
|
||||
"source-map" "~0.6.0"
|
||||
|
||||
"leven@^3.1.0":
|
||||
"integrity" "sha1-d4kd6DQGTMy6gq54QrtrFKE+1/I="
|
||||
"resolved" "https://registry.npm.taobao.org/leven/download/leven-3.1.0.tgz"
|
||||
|
@ -7674,15 +7618,6 @@
|
|||
"emojis-list" "^3.0.0"
|
||||
"json5" "^1.0.1"
|
||||
|
||||
"loader-utils@^2.0.0":
|
||||
"integrity" "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ=="
|
||||
"resolved" "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"big.js" "^5.2.2"
|
||||
"emojis-list" "^3.0.0"
|
||||
"json5" "^2.1.2"
|
||||
|
||||
"locate-path@^2.0.0":
|
||||
"integrity" "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4="
|
||||
"resolved" "https://registry.npm.taobao.org/locate-path/download/locate-path-2.0.0.tgz?cache=0&sync_timestamp=1597081764621&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flocate-path%2Fdownload%2Flocate-path-2.0.0.tgz"
|
||||
|
@ -8085,11 +8020,6 @@
|
|||
dependencies:
|
||||
"mime-db" "1.47.0"
|
||||
|
||||
"mime@^1.4.1":
|
||||
"integrity" "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
"resolved" "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz"
|
||||
"version" "1.6.0"
|
||||
|
||||
"mime@^2.4.4":
|
||||
"integrity" "sha1-bj3GzCuVEGQ4MOXxnVy3U9pe6r4="
|
||||
"resolved" "https://registry.npm.taobao.org/mime/download/mime-2.5.2.tgz"
|
||||
|
@ -8223,11 +8153,6 @@
|
|||
dependencies:
|
||||
"commander" "*"
|
||||
|
||||
"moment@^2.29.1":
|
||||
"integrity" "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
"resolved" "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz"
|
||||
"version" "2.29.1"
|
||||
|
||||
"move-concurrently@^1.0.1":
|
||||
"integrity" "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I="
|
||||
"resolved" "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz"
|
||||
|
@ -8241,8 +8166,8 @@
|
|||
"run-queue" "^1.0.3"
|
||||
|
||||
"ms@^2.1.1":
|
||||
"integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz"
|
||||
"integrity" "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI="
|
||||
"resolved" "https://registry.npm.taobao.org/ms/download/ms-2.1.3.tgz?cache=0&sync_timestamp=1607433926553&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.3.tgz"
|
||||
"version" "2.1.3"
|
||||
|
||||
"ms@2.0.0":
|
||||
|
@ -8292,6 +8217,11 @@
|
|||
"object-assign" "^4.0.1"
|
||||
"thenify-all" "^1.0.0"
|
||||
|
||||
"nan@^2.12.1":
|
||||
"integrity" "sha1-9TdkAGlRaPTMaUrJOT0MlYXu6hk="
|
||||
"resolved" "https://registry.npm.taobao.org/nan/download/nan-2.14.2.tgz?cache=0&sync_timestamp=1602591709094&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fnan%2Fdownload%2Fnan-2.14.2.tgz"
|
||||
"version" "2.14.2"
|
||||
|
||||
"nanomatch@^1.2.1", "nanomatch@^1.2.9":
|
||||
"integrity" "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk="
|
||||
"resolved" "https://registry.npm.taobao.org/nanomatch/download/nanomatch-1.2.13.tgz"
|
||||
|
@ -8309,25 +8239,11 @@
|
|||
"snapdragon" "^0.8.1"
|
||||
"to-regex" "^3.0.1"
|
||||
|
||||
"native-request@^1.0.5":
|
||||
"integrity" "sha512-uZ5rQaeRn15XmpgE0xoPL8YWqcX90VtCFglYwAgkvKM5e8fog+vePLAhHxuuv/gRkrQxIeh5U3q9sMNUrENqWw=="
|
||||
"resolved" "https://registry.npmjs.org/native-request/-/native-request-1.1.0.tgz"
|
||||
"version" "1.1.0"
|
||||
|
||||
"natural-compare@^1.4.0":
|
||||
"integrity" "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
|
||||
"resolved" "https://registry.npm.taobao.org/natural-compare/download/natural-compare-1.4.0.tgz"
|
||||
"version" "1.4.0"
|
||||
|
||||
"needle@^2.5.2":
|
||||
"integrity" "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ=="
|
||||
"resolved" "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz"
|
||||
"version" "2.9.1"
|
||||
dependencies:
|
||||
"debug" "^3.2.6"
|
||||
"iconv-lite" "^0.4.4"
|
||||
"sax" "^1.2.4"
|
||||
|
||||
"negotiator@0.6.2":
|
||||
"integrity" "sha1-/qz3zPUlp3rpY0Q2pkiD/+yjRvs="
|
||||
"resolved" "https://registry.npm.taobao.org/negotiator/download/negotiator-0.6.2.tgz"
|
||||
|
@ -8973,11 +8889,6 @@
|
|||
"json-parse-even-better-errors" "^2.3.0"
|
||||
"lines-and-columns" "^1.1.6"
|
||||
|
||||
"parse-node-version@^1.0.1":
|
||||
"integrity" "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA=="
|
||||
"resolved" "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"parse-passwd@^1.0.0":
|
||||
"integrity" "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY="
|
||||
"resolved" "https://registry.npm.taobao.org/parse-passwd/download/parse-passwd-1.0.0.tgz"
|
||||
|
@ -9864,11 +9775,6 @@
|
|||
dependencies:
|
||||
"safe-buffer" "^5.1.0"
|
||||
|
||||
"randombytes@2.0.3":
|
||||
"integrity" "sha1-Z0yZdgkBw8QRJ3GjHlIdw0nMCew="
|
||||
"resolved" "https://registry.npmjs.org/randombytes/-/randombytes-2.0.3.tgz"
|
||||
"version" "2.0.3"
|
||||
|
||||
"randomfill@^1.0.3":
|
||||
"integrity" "sha1-ySGW/IarQr6YPxvzF3giSTHWFFg="
|
||||
"resolved" "https://registry.npm.taobao.org/randomfill/download/randomfill-1.0.4.tgz"
|
||||
|
@ -9877,23 +9783,13 @@
|
|||
"randombytes" "^2.0.5"
|
||||
"safe-buffer" "^5.1.0"
|
||||
|
||||
"randomstring@^1.2.1":
|
||||
"integrity" "sha512-eMnfell9XuU3jfCx3f4xCaFAt0YMFPZhx9R3PSStmLarDKg5j5vivqKhf/8pvG+VX/YkxsckHK/VPUrKa5V07A=="
|
||||
"resolved" "https://registry.npmjs.org/randomstring/-/randomstring-1.2.1.tgz"
|
||||
"version" "1.2.1"
|
||||
dependencies:
|
||||
"array-uniq" "1.0.2"
|
||||
"randombytes" "2.0.3"
|
||||
|
||||
"range-parser@^1.2.1", "range-parser@~1.2.0", "range-parser@~1.2.1":
|
||||
"integrity" "sha1-PPNwI9GZ4cJNGlW4SADC8+ZGgDE="
|
||||
"resolved" "https://registry.npm.taobao.org/range-parser/download/range-parser-1.2.1.tgz"
|
||||
"version" "1.2.1"
|
||||
|
||||
"raphael@git+https://github.com/nhn/raphael.git#2.2.0-c":
|
||||
"integrity" "sha512-glTY/CkZjpevnNwgI0d8I+y6nqezB8INg3YHzQZdqWyTKJc+rIvr0qSkI8m+4XXLXmR2AfHu2wPOB9/AAG1agA=="
|
||||
"resolved" "git+ssh://git@github.com/nhn/raphael.git#78a6ed3ec269f33b6457b0ec66f8c3d1f2ed70e0"
|
||||
"version" "2.2.0-c"
|
||||
dependencies:
|
||||
"eve" "git://github.com/adobe-webplatform/eve.git#eef80ed"
|
||||
|
||||
|
@ -10180,7 +10076,7 @@
|
|||
"stealthy-require" "^1.1.1"
|
||||
"tough-cookie" "^2.3.3"
|
||||
|
||||
"request@^2.34", "request@^2.87.0", "request@^2.88.0", "request@^2.88.2":
|
||||
"request@^2.87.0", "request@^2.88.0", "request@^2.88.2":
|
||||
"integrity" "sha1-1zyRhzHLWofaBH4gcjQUb2ZNErM="
|
||||
"resolved" "https://registry.npm.taobao.org/request/download/request-2.88.2.tgz"
|
||||
"version" "2.88.2"
|
||||
|
@ -10419,7 +10315,7 @@
|
|||
"schema-utils" "^2.6.1"
|
||||
"semver" "^6.3.0"
|
||||
|
||||
"sass@^1.3.0", "sass@1.26.2":
|
||||
"sass@1.26.2":
|
||||
"integrity" "sha1-ThfFwjlOLuf/1lOsHYYjFKaldns="
|
||||
"resolved" "https://registry.nlark.com/sass/download/sass-1.26.2.tgz?cache=0&sync_timestamp=1621664429943&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsass%2Fdownload%2Fsass-1.26.2.tgz"
|
||||
"version" "1.26.2"
|
||||
|
@ -10946,9 +10842,7 @@
|
|||
"version" "1.0.3"
|
||||
|
||||
"squire-rte@github:sohee-lee7/Squire#b1e0e1031fa18912d233c204cbe7c7fae4a42621":
|
||||
"integrity" "sha512-/1Wi323QPO3AmcGOXjliEp2Kqzse6/BbCyCj/lw0R0M/zS+7IFm1LnBlgMlfa1yLXRjNcc5PcmE2vnwA4Zlhkg=="
|
||||
"resolved" "git+ssh://git@github.com/sohee-lee7/Squire.git#b1e0e1031fa18912d233c204cbe7c7fae4a42621"
|
||||
"version" "1.9.0"
|
||||
|
||||
"ssf@~0.10.2":
|
||||
"integrity" "sha1-jq4fwpyQpVLnkhII+BiS1vd6yys="
|
||||
|
@ -11728,11 +11622,6 @@
|
|||
"strip-bom" "^3.0.0"
|
||||
"strip-json-comments" "^2.0.0"
|
||||
|
||||
"tslib@^1.10.0":
|
||||
"integrity" "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
"resolved" "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
||||
"version" "1.14.1"
|
||||
|
||||
"tslib@^1.9.0":
|
||||
"integrity" "sha1-zy04vcNKE0vK8QkcQfZhni9nLQA="
|
||||
"resolved" "https://registry.npm.taobao.org/tslib/download/tslib-1.14.1.tgz?cache=0&sync_timestamp=1617647074515&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ftslib%2Fdownload%2Ftslib-1.14.1.tgz"
|
||||
|
@ -12189,13 +12078,6 @@
|
|||
"tsconfig" "^7.0.0"
|
||||
"vue-template-es2015-compiler" "^1.6.0"
|
||||
|
||||
"vue-json-editor@^1.4.3":
|
||||
"integrity" "sha512-st9HdXBgCnyEmmfWrZQiKzp4KuYXzmYVUNDn5h6Fa18MrrGS1amnyUFyv7hQFsNBDW27B7BKkdGOqszYT1srAg=="
|
||||
"resolved" "https://registry.npmjs.org/vue-json-editor/-/vue-json-editor-1.4.3.tgz"
|
||||
"version" "1.4.3"
|
||||
dependencies:
|
||||
"vue" "^2.2.6"
|
||||
|
||||
"vue-loader@^15.9.2":
|
||||
"integrity" "sha1-FbBXdcPgw4QHZ5OTws5t9nOwEEQ="
|
||||
"resolved" "https://registry.nlark.com/vue-loader/download/vue-loader-15.9.7.tgz"
|
||||
|
@ -12225,7 +12107,7 @@
|
|||
"hash-sum" "^1.0.2"
|
||||
"loader-utils" "^1.0.2"
|
||||
|
||||
"vue-template-compiler@^2.0.0", "vue-template-compiler@^2.x", "vue-template-compiler@2.6.10":
|
||||
"vue-template-compiler@2.6.10":
|
||||
"integrity" "sha1-MjtPNJXwT6o1AzN6gvXWUHeZycw="
|
||||
"resolved" "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.10.tgz?cache=0&sync_timestamp=1597927391993&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvue-template-compiler%2Fdownload%2Fvue-template-compiler-2.6.10.tgz"
|
||||
"version" "2.6.10"
|
||||
|
@ -12238,7 +12120,7 @@
|
|||
"resolved" "https://registry.npm.taobao.org/vue-template-es2015-compiler/download/vue-template-es2015-compiler-1.9.1.tgz"
|
||||
"version" "1.9.1"
|
||||
|
||||
"vue@^2 || ^3.0.0-0", "vue@^2.2.6", "vue@^2.5.17", "vue@^2.x", "vue@2.6.10", "vue@2.x":
|
||||
"vue@2.6.10":
|
||||
"integrity" "sha1-pysaQqTYKnIepDjRtr9V5mGVxjc="
|
||||
"resolved" "https://registry.nlark.com/vue/download/vue-2.6.10.tgz"
|
||||
"version" "2.6.10"
|
||||
|
@ -12415,7 +12297,7 @@
|
|||
"source-list-map" "^2.0.0"
|
||||
"source-map" "~0.6.1"
|
||||
|
||||
"webpack@^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0", "webpack@^2.0.0 || ^3.0.0 || ^4.0.0", "webpack@^3.0.0 || ^4.1.0 || ^5.0.0-0", "webpack@^4.0.0", "webpack@^4.0.0 || ^5.0.0", "webpack@^4.36.0 || ^5.0.0", "webpack@^4.4.0", "webpack@>=2", "webpack@>=2.0.0 <5.0.0", "webpack@>=4.0.0":
|
||||
"webpack@^4.0.0":
|
||||
"integrity" "sha1-v5tEBOogoHNgXgoBHRiNd8tq1UI="
|
||||
"resolved" "https://registry.nlark.com/webpack/download/webpack-4.46.0.tgz"
|
||||
"version" "4.46.0"
|
||||
|
|