| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- <template>
- <div class="h-100 position-relative">
- <div class="dashboard-card-wrap">
- <div class="dashboard-card-header">
- <div class="dashboard-card-header-left" @click.alt="showDebuggerInfo = !showDebuggerInfo">{{ form.fd.name || $t('dashboard.text_6') }}
- <a-icon class="ml-2" type="loading" v-if="loading" />
- <a-tooltip v-if="isServersAnypool"><template slot="title">{{ $t('dashboard.server_tips') }}</template><icon type="help" /></a-tooltip>
- </div>
- <div class="dashboard-card-header-right">
- <span v-if="showDebuggerInfo">{{ `${$t('dashboard.text_20')}: ${form.fd.usage_key}` }}</span>
- <slot name="actions" :handle-edit="handleEdit" />
- <a class="ml-2" :style="{ color: isResDeny ? '#ccc' : '' }" v-if="!edit && canShowEdit && !isPageDeny" @click="goPage">
- <icon type="arrow-right" style="font-size:18px" />
- </a>
- </div>
- </div>
- <div class="dashboard-card-body d-flex align-items-center justify-content-center">
- <div class="d-flex">
- <div class="number-card-number mr-1">{{ this.usage.usage }}</div>
- <div class="number-card-unit">{{ this.usage.unit }}</div>
- </div>
- </div>
- </div>
- <base-drawer class="drawer-wrapper" @update:visible="updateVisible" :visible="visible" :title="$t('dashboard.text_5')" @ok="handleSubmit" @cancel="cancel">
- <a-form
- hideRequiredMark
- :form="form.fc"
- v-bind="formItemLayout">
- <slot />
- <a-form-item :label="$t('dashboard.text_6')">
- <a-input v-decorator="decorators.name" />
- </a-form-item>
- <quota-config :fc="form.fc" :decorators="decorators" :usage-label="$t('dashboard.text_20')" @update:usage_key="setDefaultName" />
- <a-form-item v-if="canShowUnitConfig" :label="$t('common_250')">
- <base-select
- v-decorator="decorators.unit"
- isDefaultSelect
- :filterable="true"
- :options="unitOpts"
- :select-props="{ placeholder: $t('common_618') }" />
- </a-form-item>
- </a-form>
- </base-drawer>
- </div>
- </template>
- <script>
- import { mapGetters } from 'vuex'
- import BaseDrawer from '@Dashboard/components/BaseDrawer'
- import QuotaConfig from '@Dashboard/sections/QuotaConfig'
- import { USAGE_CONFIG } from '@Dashboard/constants'
- import { load } from '@Dashboard/utils/cache'
- import { getRequestT } from '@/utils/utils'
- import { hasPermission } from '@/utils/auth'
- import routes from '@/router/routes'
- import mixin from './mixin'
- export default {
- name: 'NumberCardServer',
- components: {
- BaseDrawer,
- QuotaConfig,
- },
- mixins: [mixin],
- props: {
- parmas: Object,
- edit: Boolean,
- },
- data () {
- const usage_key = this.$store.getters.isAdminMode ? 'all.servers' : this.$store.getters.isDomainMode ? 'domain.servers' : 'servers'
- const initialUsageKeyValue = ((this.params && this.params.type !== 'k8s') && this.params.usage_key) || usage_key
- const initialNameValue = ((this.params && this.params.type !== 'k8s') && this.params.name) || this.$t('usage')[initialUsageKeyValue]
- const initialRegionAccountType = ((this.params && this.params.type !== 'k8s') && this.params.regionAccountType) || 'region'
- const initUnitValue = (this.params && this.params.unit) || 'auto'
- return {
- data: {},
- loading: false,
- form: {
- fc: this.$form.createForm(this),
- fd: {
- name: initialNameValue,
- usage_key: initialUsageKeyValue,
- },
- fi: {
- nameTouched: false,
- },
- },
- decorators: {
- name: [
- 'name',
- {
- initialValue: initialNameValue,
- rules: [
- { required: true, message: this.$t('dashboard.text_8') },
- ],
- },
- ],
- cloud_env: [
- 'cloud_env',
- {
- initialValue: this.params && this.params.cloud_env,
- },
- ],
- brand: [
- 'brand',
- {
- initialValue: this.params && this.params.brand,
- },
- ],
- region: [
- 'region',
- {
- initialValue: this.params && this.params.region,
- },
- ],
- regionAccountType: [
- 'regionAccountType',
- {
- initialValue: initialRegionAccountType,
- },
- ],
- account: [
- 'account',
- {
- initialValue: this.params && this.params.account,
- },
- ],
- usage_key: [
- 'usage_key',
- {
- initialValue: initialUsageKeyValue,
- rules: [
- { required: true, message: this.$t('dashboard.text_22') },
- ],
- },
- ],
- unit: [
- 'unit',
- {
- initialValue: initUnitValue,
- },
- ],
- },
- showDebuggerInfo: false,
- unitOpts: [
- { id: 'auto', name: this.$t('common_563') },
- { id: 'K', name: 'KB' },
- { id: 'M', name: 'MB' },
- { id: 'G', name: 'GB' },
- { id: 'T', name: 'TB' },
- ],
- currentUsageKey: initialUsageKeyValue,
- }
- },
- computed: {
- ...mapGetters(['permission']),
- usage () {
- const usage = (this.data && this.data[this.form.fd.usage_key]) || 0
- const ret = {
- usage,
- }
- const config = USAGE_CONFIG[this.form.fd.usage_key]
- // 使用默认单位
- if (config && config.formatter) {
- const fVal = config.formatter(usage)
- const fValArr = fVal.split(' ')
- ret.usage = fValArr[0]
- ret.unit = fValArr[1]
- }
- if (config && config.unit) {
- ret.unit = config.unit
- }
- // 使用用户配置的单位
- if (config && config.userUnitFormatter) {
- if (this.params && this.params.unit && this.params.unit !== 'auto') {
- const fVal = config.userUnitFormatter(usage, this.params.unit)
- const fValArr = fVal.split(' ')
- ret.usage = fValArr[0]
- ret.unit = fValArr[1]
- }
- }
- return ret
- },
- isServersAnypool () {
- if (!this.params) return false
- return ['all.servers.any_pool', 'domain.servers.any_pool', 'servers.any_pool', 'all.servers', 'domain.servers', 'servers'].includes(this.params.usage_key)
- },
- canShowEdit () {
- if (!this.params) return false
- return this.getPageUrl()
- },
- canShowUnitConfig () {
- const config = USAGE_CONFIG[this.currentUsageKey]
- if (config && config.canUseUserUnit) {
- return true
- }
- return false
- },
- isResDeny () {
- const usage_key = this.params?.usage_key || ''
- if (this.isContainerHostUsageKey(usage_key)) {
- return !hasPermission({ key: 'servers_list', permissionData: this.permission })
- }
- if (usage_key.endsWith('servers')) {
- return !hasPermission({ key: 'servers_list', permissionData: this.permission })
- } else if (usage_key.endsWith('hosts') || usage_key.endsWith('baremetals')) {
- return !hasPermission({ key: 'hosts_list', permissionData: this.permission })
- } else if (usage_key.endsWith('isolated_devices')) {
- return !hasPermission({ key: 'isolated_devices_list', permissionData: this.permission })
- }
- return false
- },
- isPageDeny () {
- const path = this.getPageUrl()
- if (!path) return false
- const target = routes.filter(item => item.path === path)
- if (target.length && target[0].meta?.hidden) {
- return target[0].meta.hidden()
- }
- return false
- },
- },
- watch: {
- 'form.fd' (val) {
- this.fetchUsage()
- for (const key in this.decorators) {
- let config = this.decorators[key][1] || {}
- config = {
- ...config,
- initialValue: val[key],
- }
- this.decorators[key][1] = config
- }
- },
- },
- created () {
- if (this.params && this.params.type !== 'k8s') {
- this.form.fd = this.params
- } else if (this.form.fd.usage_key) {
- this.$emit('update', this.options.i, this.form.fd)
- this.setDefaultName(this.form.fd.usage_key)
- this.refresh()
- }
- this.$bus.$on('DashboardCardRefresh', args => {
- this.fetchUsage()
- }, this)
- },
- methods: {
- isPendingDeleteContainerUsageKey (uk) {
- if (!uk) return false
- return uk.split('.').includes('pending_delete_containers')
- },
- isContainerHostUsageKey (uk) {
- if (!uk) return false
- const segs = uk.split('.')
- return segs.includes('containers') || segs.includes('running_containers') || segs.includes('ready_containers') || segs.includes('pending_delete_containers')
- },
- refresh () {
- return this.fetchUsage()
- },
- genUsageParams () {
- const params = {
- scope: this.$store.getters.scope,
- $t: getRequestT(),
- }
- const fd = this.form.fd
- if (fd.cloud_env) params.cloud_env = fd.cloud_env
- if (fd.region) {
- params.range_type = 'cloudregions'
- params.range_id = fd.region
- }
- if (fd.account) {
- params.range_type = 'cloudaccounts'
- params.range_id = fd.account
- }
- if (fd.brand) params.brand = fd.brand
- return params
- },
- async fetchUsage () {
- this.loading = true
- try {
- const params = this.genUsageParams()
- const data = await load({
- res: 'usages',
- action: 'rpc',
- actionArgs: {
- methodname: 'getGeneralUsage',
- params,
- },
- resPath: 'data',
- })
- this.data = data
- } finally {
- this.loading = false
- }
- },
- handleEdit (val) {
- this.updateVisible(true)
- },
- updateVisible (val) {
- this.$emit('update:visible', val)
- },
- async handleSubmit () {
- try {
- const values = await this.form.fc.validateFields()
- this.form.fd = values
- this.$emit('update', this.options.i, values)
- this.updateVisible(false)
- } catch (error) {
- throw error
- }
- },
- goPage () {
- if (!this.params || this.isResDeny) return
- const path = this.getPageUrl()
- if (path) this.$router.push(path)
- },
- getPageUrl () {
- const uk = this.params.usage_key
- if (uk && this.isPendingDeleteContainerUsageKey(uk)) {
- return '/serverrecovery'
- }
- if (uk && this.isContainerHostUsageKey(uk)) {
- return '/vminstance-container'
- }
- switch (this.params.usage_key) {
- case 'all.servers':
- return '/vminstance'
- case 'servers':
- return '/vminstance'
- case 'domain.servers':
- return '/vminstance'
- case 'baremetals':
- return '/physicalmachine'
- case 'domain.baremetals':
- return '/physicalmachine'
- case 'hosts':
- return '/host'
- case 'domain.hosts':
- return '/host'
- case 'all.buckets':
- return '/bucket'
- case 'domain.buckets':
- return '/bucket'
- case 'all.cache':
- return '/redis'
- case 'domain.cache':
- return '/redis'
- case 'all.rds':
- return '/rds'
- case 'domain.rds':
- return '/rds'
- case 'all.loadbalancer':
- return '/lb'
- case 'domain.loadbalancer':
- return '/lb'
- case 'all.eip.floating_ip':
- return '/eip'
- case 'domain.eip.floating_ip':
- return '/eip'
- case 'all.snapshot':
- return '/disk-snapshot'
- case 'domain.snapshot':
- return '/disk-snapshot'
- case 'all.disks.count':
- return '/disk'
- case 'domain.disks.count':
- return '/disk'
- case 'all.servers.isolated_devices':
- return '/gpu'
- case 'domain.servers.isolated_devices':
- return '/gpu'
- default:
- return ''
- }
- },
- },
- }
- </script>
- <style lang="less" scoped>
- .number-card-number {
- font-size: 60px;
- line-height: 48px;
- color: #000000;
- }
- .number-card-unit {
- font-size: 14px;
- color: #000000;
- margin-left: 5px;
- }
- .drawer-wrapper {
- &::v-deep.ant-drawer.ant-drawer-open .ant-drawer-mask {
- animation: none;
- }
- }
- </style>
|