BottomBar.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <template>
  2. <page-footer>
  3. <template v-slot:right>
  4. <div class="d-flex align-items-center" v-if="hasMeterService()">
  5. <div class="mr-4 d-flex align-items-center">
  6. <div class="text-truncate">{{$t('common_419')}}</div>
  7. <div class="ml-2 prices">
  8. <div class="hour d-flex">
  9. <template v-if="price">
  10. <m-animated-number :value="price" :formatValue="priceFormat" />
  11. <discount-price class="ml-2 mini-text" :discount="discount" :origin="originPrice" />
  12. </template>
  13. </div>
  14. <div class="tips text-truncate">
  15. <span v-html="priceTips" />
  16. </div>
  17. </div>
  18. </div>
  19. </div>
  20. <div class="btns-wrapper d-flex align-items-center">
  21. <a-button
  22. class="ml-3"
  23. type="primary"
  24. native-type="submit"
  25. html-type="submit"
  26. @click="handleConfirm"
  27. :loading="loading">{{ $t('common_258') }}</a-button>
  28. <a-button class="ml-3" @click="() => $router.back()">{{$t('common.cancel')}}</a-button>
  29. </div>
  30. </template>
  31. </page-footer>
  32. </template>
  33. <script>
  34. import _ from 'lodash'
  35. import * as R from 'ramda'
  36. import { mapGetters } from 'vuex'
  37. import { findPlatform } from '@/utils/common/hypervisor'
  38. import DiscountPrice from '@/sections/DiscountPrice'
  39. import { hasMeterService } from '@/utils/auth'
  40. import { PriceFetcherByPriceKey } from '@/utils/common/price'
  41. import { currencyUnitMap } from '@/constants/currency'
  42. export default {
  43. name: 'BottomBar',
  44. components: {
  45. DiscountPrice,
  46. },
  47. inject: ['form', 'cloudEnv'],
  48. props: {
  49. currentCloudregion: {
  50. type: Object,
  51. },
  52. size: {
  53. type: Number,
  54. },
  55. bgpType: {
  56. required: true,
  57. },
  58. isHCSO: {
  59. required: false,
  60. default: false,
  61. },
  62. isHCS: {
  63. required: false,
  64. default: false,
  65. },
  66. cloudAccountId: String,
  67. },
  68. data () {
  69. this._getPrice = _.debounce(this._getPrice, 500)
  70. return {
  71. loading: false,
  72. priceObj: null,
  73. currency: currencyUnitMap.CNY.sign,
  74. discount: 0,
  75. price: null,
  76. priceFormat: null,
  77. originPrice: null,
  78. priceTips: '--',
  79. hasMeterService,
  80. }
  81. },
  82. computed: {
  83. ...mapGetters(['userInfo']),
  84. },
  85. watch: {
  86. currentCloudregion (value) {
  87. if (value.provider) {
  88. this._getPrice()
  89. return
  90. }
  91. if (value.external_id) {
  92. this._getPrice()
  93. }
  94. },
  95. size () {
  96. this._getPrice()
  97. },
  98. bgpType () {
  99. this._getPrice()
  100. },
  101. cloudAccountId () {
  102. this._getPrice()
  103. },
  104. },
  105. created () {
  106. this._getPrice()
  107. },
  108. methods: {
  109. resetPrice () {
  110. this.priceObj = null
  111. this.currency = currencyUnitMap.CNY.sign
  112. this.discount = 0
  113. this.price = null
  114. this.priceFormat = null
  115. this.originPrice = null
  116. this.priceTips = '--'
  117. },
  118. async _getPrice () {
  119. try {
  120. if (R.isEmpty(this.currentCloudregion) || !hasMeterService()) return
  121. if (!this.size) {
  122. this.resetPrice()
  123. return
  124. }
  125. let region = ''
  126. let externalProvider = ''
  127. if (this.currentCloudregion.external_id) {
  128. const arr = this.currentCloudregion.external_id.split('/')
  129. region = arr[1]
  130. externalProvider = arr[0]
  131. }
  132. const provider = externalProvider || this.currentCloudregion.provider
  133. const env = findPlatform(provider)
  134. if (env === 'private') return // 私有云暂时不支持EIP价格查询
  135. let bgpType = this.bgpType || ''
  136. if (provider.toLowerCase() === 'huawei') {
  137. if (['cn-southwest-2', 'cn-north-1', 'cn-east-2', 'cn-south-1'].indexOf(region) >= 0) {
  138. bgpType = '19_sbgp'
  139. } else if (region === 'cn-northeast-1') {
  140. bgpType = '19_telcom'
  141. } else {
  142. bgpType = '19_bgp'
  143. }
  144. } else if (provider.toLowerCase() === 'aliyun') {
  145. bgpType = 'bgp'
  146. }
  147. let price_key = `${provider}::${region}::::bandwidth::${bgpType}`
  148. if (provider.toLowerCase() === 'onecloud') {
  149. price_key = `${provider}::${region}::::eip::bandwidth${this.bgpType ? '.' + this.bgpType : ''}`
  150. }
  151. const pf = new PriceFetcherByPriceKey({
  152. scope: this.$store.getters.scope,
  153. priceKey: price_key,
  154. amount: this.size,
  155. cloudaccountId: this.cloudAccountId,
  156. })
  157. const p = await pf.getPriceObj()
  158. this.currency = p.currency
  159. this.discount = p.discount
  160. this.price = p.price
  161. this.priceFormat = p.priceFormat
  162. this.originPrice = p.originPrice
  163. this.priceTips = p.priceTips
  164. } catch (err) {
  165. throw err
  166. }
  167. },
  168. doCreate (data) {
  169. return new this.$Manager('eips').create({ data })
  170. },
  171. async handleConfirm () {
  172. this.loading = true
  173. try {
  174. const values = await this.form.fc.validateFields()
  175. values.domain = values.domain?.key
  176. values.tenant = values.project.key
  177. Reflect.deleteProperty(values, 'project')
  178. if (this.cloudEnv === 'private' && !this.isHCSO && !this.isHCS) {
  179. delete values.charge_type
  180. values.bandwidth = 0
  181. if (values.ip_addr) {
  182. values.ip = values.ip_addr
  183. delete values.ip_addr
  184. }
  185. }
  186. await this.doCreate(values)
  187. this.loading = false
  188. this.$message.success(this.$t('k8s.text_184'))
  189. this.$router.push('/eip')
  190. } catch (error) {
  191. this.loading = false
  192. throw error
  193. }
  194. },
  195. },
  196. }
  197. </script>
  198. <style lang="less" scoped>
  199. @import '../../../../../../src/styles/less/theme';
  200. .prices {
  201. .hour {
  202. color: @error-color;
  203. font-size: 24px;
  204. }
  205. .tips {
  206. color: #999;
  207. font-size: 12px;
  208. }
  209. }
  210. </style>