Detail.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <template>
  2. <detail
  3. :on-manager="onManager"
  4. :base-info="baseInfo"
  5. status-module="rds"
  6. :data="data"
  7. resource="dbinstances"
  8. :extra-info="extraInfo"
  9. auto-hidden-columns-key="rds_hidden_columns" />
  10. </template>
  11. <script>
  12. // import BrandIcon from '@/sections/BrandIcon'
  13. import {
  14. getUserTagColumn,
  15. // getExtTagColumn,
  16. } from '@/utils/common/detailColumn'
  17. import {
  18. getBrandTableColumn,
  19. getSwitchTableColumn,
  20. } from '@/utils/common/tableColumn'
  21. import { sizestr } from '@/utils/utils'
  22. import WindowsMixin from '@/mixins/windows'
  23. import { hasPermission } from '@/utils/auth'
  24. import { DBINSTANCE_CATEGORY, DBINSTANCE_STORAGE_TYPE } from '../constants'
  25. export default {
  26. name: 'RDSDetail',
  27. mixins: [WindowsMixin],
  28. props: {
  29. onManager: {
  30. type: Function,
  31. required: true,
  32. },
  33. data: {
  34. type: Object,
  35. required: true,
  36. },
  37. columns: Array,
  38. },
  39. data () {
  40. const formatPostpaid = (row) => {
  41. const ret = []
  42. if (row.billing_type === 'postpaid') {
  43. ret.push(<div style={{ color: '#0A1F44' }}>{ this.$t('billingType.postpaid') }</div>)
  44. } else if (row.billing_type === 'prepaid') {
  45. ret.push(<div style={{ color: '#0A1F44' }}>{ this.$t('billingType.prepaid') }</div>)
  46. }
  47. if (row.expired_at) {
  48. const dateArr = this.$moment(row.expired_at).fromNow().split(' ')
  49. const date = dateArr.join(' ')
  50. const seconds = this.$moment(row.expired_at).diff(new Date()) / 1000
  51. const textColor = seconds / 24 / 60 / 60 < 7 ? '#DD2727' : '#53627C'
  52. const text = seconds < 0 ? this.$t('db.text_162') : this.$t('db.text_163', [date])
  53. ret.push(<div style={{ color: textColor }}>{text}</div>)
  54. }
  55. return ret
  56. }
  57. return {
  58. baseInfo: [
  59. getUserTagColumn({ onManager: this.onManager, resource: 'dbinstance', columns: () => this.columns, tipName: this.$t('dictionary.dbinstances') }),
  60. // getExtTagColumn({ onManager: this.onManager, resource: 'dbinstance', columns: () => this.columns, tipName: this.$t('dictionary.dbinstances') }),
  61. getBrandTableColumn(),
  62. {
  63. field: 'charge_type',
  64. title: this.$t('db.text_54'),
  65. slots: {
  66. default: ({ row }) => {
  67. return formatPostpaid(row)
  68. },
  69. },
  70. },
  71. {
  72. field: 'region',
  73. title: this.$t('db.text_40'),
  74. slots: {
  75. default: ({ row }) => {
  76. if (!row.region_id) return row.region || '-'
  77. const p = hasPermission({ key: 'cloudregions_get' })
  78. let node
  79. if (p) {
  80. node = (
  81. <list-body-cell-wrap copy row={ row } onManager={ this.onManager } field='region' title={ row.region } hideField={ true }>
  82. <side-page-trigger permission='areas_get' name='CloudregionSidePage' id={row.region_id} vm={this}>{ row.region }</side-page-trigger>
  83. </list-body-cell-wrap>
  84. )
  85. } else {
  86. node = (
  87. <list-body-cell-wrap copy row={ row } onManager={ this.onManager } field='region' title={ row.region } />
  88. )
  89. }
  90. return [
  91. <div class='text-truncate'>{ node }</div>,
  92. ]
  93. },
  94. },
  95. },
  96. {
  97. field: 'zone',
  98. hiddenField: 'region',
  99. title: this.$t('db.text_133'),
  100. slots: {
  101. default: ({ row }) => {
  102. const ret = []
  103. let i = 0
  104. for (;;) {
  105. ++i
  106. const value = row[`zone${i}_name`]
  107. if (!value) break
  108. ret.push(
  109. <div>
  110. {value}({i > 1 ? this.$t('db.text_164') : this.$t('db.text_165')})
  111. </div>,
  112. )
  113. }
  114. return ret
  115. },
  116. },
  117. },
  118. {
  119. field: 'ip_addrs',
  120. title: this.$t('db.intranet_ip'),
  121. minWidth: 200,
  122. slots: {
  123. default: ({ row }) => {
  124. const ip_addrs = (row.ip_addrs || '').split(',')
  125. return [
  126. ...ip_addrs.map(ip => {
  127. return (<list-body-cell-wrap hide-field copy message={ip}><span>{ip}</span></list-body-cell-wrap>)
  128. }),
  129. ]
  130. },
  131. },
  132. hidden: (row) => {
  133. return !row.ip_addrs
  134. },
  135. },
  136. ],
  137. extraInfo: [
  138. {
  139. title: this.$t('db.text_166'),
  140. items: [
  141. {
  142. field: 'engine',
  143. title: this.$t('db.text_57'),
  144. slots: {
  145. default: ({ row }) => {
  146. return `${row.engine} ${row.engine_version}`
  147. },
  148. },
  149. },
  150. {
  151. field: 'maintain_time',
  152. title: this.$t('db.text_167'),
  153. },
  154. {
  155. field: 'instance_type',
  156. title: this.$t('db.text_168'),
  157. },
  158. {
  159. field: 'category',
  160. title: this.$t('db.text_119'),
  161. slots: {
  162. default: ({ row }) => {
  163. return DBINSTANCE_CATEGORY[row.category] || row.category || '-'
  164. },
  165. },
  166. },
  167. {
  168. field: 'storage_type',
  169. title: this.$t('db.text_120'),
  170. slots: {
  171. default: ({ row }) => {
  172. return DBINSTANCE_STORAGE_TYPE[row.storage_type] || row.storage_type || '-'
  173. },
  174. },
  175. },
  176. {
  177. field: 'vcpu_count',
  178. title: 'CPU',
  179. slots: {
  180. default: ({ row }) => {
  181. return this.$t('db.text_170', [row.vcpu_count])
  182. },
  183. },
  184. },
  185. {
  186. field: 'vmem_size_mb',
  187. title: this.$t('db.text_132'),
  188. slots: {
  189. default: ({ row }) => {
  190. return sizestr(row.vmem_size_mb, 'M', 1024)
  191. },
  192. },
  193. },
  194. {
  195. field: 'iops',
  196. title: 'IOPS',
  197. slots: {
  198. default: ({ row }) => {
  199. return row.iops || '-'
  200. },
  201. },
  202. },
  203. ],
  204. hidden: () => this.$isScopedPolicyMenuHidden('rds_hidden_columns.db_info'),
  205. },
  206. {
  207. title: this.$t('db.text_171'),
  208. items: [
  209. {
  210. field: 'internal_connection_str',
  211. title: this.$t('db.text_172'),
  212. slots: {
  213. default: ({ row }) => {
  214. if (row.internal_connection_str) {
  215. return row.provider === 'Qcloud' ? row.internal_connection_str : `${row.internal_connection_str}:${row.port}`
  216. }
  217. return '-'
  218. },
  219. },
  220. },
  221. {
  222. field: 'connection_str',
  223. title: this.$t('db.text_173'),
  224. slots: {
  225. default: ({ row }) => {
  226. const addr = row.connection_str
  227. const btnTxt = addr ? this.$t('db.text_174') : this.$t('db.text_175')
  228. const isRunning = row.status === 'running'
  229. const notRunninTip = !isRunning ? this.$t('db.text_156') : null
  230. let RenderSwitchBtn = null
  231. // 华为云不支持开启外网地址和关闭外网地址
  232. if (row.provider !== 'Huawei') {
  233. if (isRunning) {
  234. RenderSwitchBtn = (<a-button type="link" onClick={() => this.handleSwitchPublicAddress(!addr)}>{btnTxt}</a-button>)
  235. } else {
  236. RenderSwitchBtn = (
  237. <a-tooltip placement='top' title={notRunninTip}>
  238. <a-button type="link" disabled>{btnTxt}</a-button>
  239. </a-tooltip>
  240. )
  241. }
  242. }
  243. return (
  244. <div>
  245. {addr ? row.provider === 'Qcloud' ? addr : `${addr}:${row.port}` : '-'}
  246. {RenderSwitchBtn}
  247. </div>
  248. )
  249. },
  250. },
  251. },
  252. // {
  253. // field: 'port',
  254. // title: '数据库端口号',
  255. // },
  256. {
  257. field: 'vpc',
  258. title: 'VPC',
  259. },
  260. {
  261. field: 'network',
  262. title: this.$t('db.text_176'),
  263. slots: {
  264. default: ({ row }) => {
  265. return row.network || '-'
  266. },
  267. },
  268. },
  269. // {
  270. // field: 'secgroup',
  271. // title: this.$t('db.text_144'),
  272. // slots: {
  273. // default: ({ row }) => {
  274. // return row.secgroup || '-'
  275. // },
  276. // },
  277. // },
  278. {
  279. field: 'secgroups',
  280. title: this.$t('compute.text_105'),
  281. slots: {
  282. default: ({ row }) => {
  283. if (!row.secgroups) return '-'
  284. return row.secgroups.map((item) => {
  285. return <list-body-cell-wrap copy hideField={true} field='name' row={item} message={item.name}>
  286. <side-page-trigger permission='secgroups_get' name='SecGroupSidePage' id={item.id} vm={this}>{ item.name }</side-page-trigger>
  287. </list-body-cell-wrap>
  288. })
  289. },
  290. },
  291. },
  292. ],
  293. hidden: () => this.$isScopedPolicyMenuHidden('rds_hidden_columns.connection_info'),
  294. },
  295. {
  296. title: this.$t('db.text_177'),
  297. items: [
  298. {
  299. field: 'disk_size_gb',
  300. title: this.$t('db.text_116'),
  301. slots: {
  302. default: ({ row }) => {
  303. const { disk_size_gb = 0, disk_size_used_mb = 0 } = row
  304. const used = sizestr(disk_size_used_mb, 'M', 1024)
  305. return `${this.$t('db.text_178', [disk_size_gb])} (${this.$t('db.used', [used])})`
  306. },
  307. },
  308. },
  309. ],
  310. hidden: () => this.$isScopedPolicyMenuHidden('rds_hidden_columns.db_size_gb'),
  311. },
  312. {
  313. title: this.$t('db.text_179'),
  314. items: [
  315. getSwitchTableColumn({
  316. field: 'disable_delete',
  317. title: this.$t('common.text00076'),
  318. change: val => {
  319. this.onManager('update', {
  320. id: this.data.id,
  321. managerArgs: {
  322. data: { disable_delete: val },
  323. },
  324. })
  325. },
  326. }),
  327. ],
  328. hidden: () => this.$isScopedPolicyMenuHidden('rds_hidden_columns.perform_action'),
  329. },
  330. ],
  331. }
  332. },
  333. methods: {
  334. handleSwitchPublicAddress (bool) {
  335. const txts = {
  336. true: {
  337. title: this.$t('db.text_180'),
  338. },
  339. false: {
  340. title: this.$t('db.text_181'),
  341. content: this.$t('db.text_182'),
  342. },
  343. }
  344. this.createDialog('ConfirmDialog', {
  345. ...txts[`${bool}`],
  346. onOk: () => {
  347. return this.onManager('performAction', {
  348. id: this.data.id,
  349. steadyStatus: ['runing'],
  350. managerArgs: {
  351. action: 'public-connection',
  352. data: {
  353. open: bool,
  354. },
  355. },
  356. })
  357. },
  358. })
  359. },
  360. },
  361. }
  362. </script>