List.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. <template>
  2. <page-list
  3. :list="list"
  4. :columns="templateListColumns || columns"
  5. :group-actions="groupActions"
  6. :single-actions="singleActions"
  7. :showSearchbox="showSearchbox"
  8. :showGroupActions="showGroupActions"
  9. :show-single-actions="!isTemplate"
  10. :export-data-options="exportDataOptions"
  11. :show-page="!isTemplate" />
  12. </template>
  13. <script>
  14. import * as R from 'ramda'
  15. import expectStatus from '@/constants/expectStatus'
  16. import { getNameFilter, getEnabledFilter, getStatusFilter, getBrandFilter, getPublicFilter, getDomainFilter, getDescriptionFilter, getCreatedAtFilter } from '@/utils/common/tableFilter'
  17. import { getEnabledSwitchActions } from '@/utils/common/tableActions'
  18. import WindowsMixin from '@/mixins/windows'
  19. import ListMixin from '@/mixins/list'
  20. import ResTemplateListMixin from '@/mixins/resTemplateList'
  21. import GlobalSearchMixin from '@/mixins/globalSearch'
  22. import { typeClouds } from '@/utils/common/hypervisor'
  23. import { isCE } from '@/utils/utils'
  24. import SingleActionsMixin from '../mixins/singleActions'
  25. import ColumnsMixin from '../mixins/columns'
  26. const providerMap = typeClouds.getProviderlowcase()
  27. export default {
  28. name: 'CloudaccountList',
  29. mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
  30. props: {
  31. id: String,
  32. getParams: {
  33. type: Object,
  34. default: () => ({}),
  35. },
  36. cloudEnv: String,
  37. isAllowCreate: {
  38. type: Boolean,
  39. default: true,
  40. },
  41. hiddenActions: {
  42. type: Array,
  43. default: () => ([]),
  44. },
  45. },
  46. data () {
  47. return {
  48. batchDeleteBill: true,
  49. list: this.$list.createList(this, {
  50. ctx: this,
  51. id: this.id,
  52. resource: 'cloudaccounts',
  53. getParams: this.getParam,
  54. isTemplate: this.isTemplate,
  55. templateLimit: this.templateLimit,
  56. steadyStatus: {
  57. status: Object.values(expectStatus.cloudaccount).flat(),
  58. sync_status: Object.values(expectStatus.cloudaccountSyncStatus).flat(),
  59. },
  60. filterOptions: {
  61. id: {
  62. label: this.$t('table.title.id'),
  63. },
  64. name: getNameFilter(),
  65. description: getDescriptionFilter(),
  66. // access_url: getFilter({
  67. // field: 'access_url',
  68. // title: '环境',
  69. // }),
  70. enabled: getEnabledFilter(),
  71. status: getStatusFilter('cloudaccount'),
  72. health_status: getStatusFilter({
  73. field: 'health_status',
  74. statusModule: 'cloudaccountHealthStatus',
  75. title: this.$t('cloudenv.text_93'),
  76. }),
  77. brand: getBrandFilter(),
  78. account: {
  79. label: this.$t('cloudenv.text_94'),
  80. filter: true,
  81. formatter: val => {
  82. return `account.contains(${val})`
  83. },
  84. },
  85. enable_auto_sync: getEnabledFilter({ label: this.$t('cloudenv.text_83') }),
  86. share_mode: getPublicFilter(),
  87. project_domains: getDomainFilter(),
  88. created_at: getCreatedAtFilter(),
  89. },
  90. responseData: this.responseData,
  91. hiddenColumns: ['guest_count', 'host_count', 'enable_auto_sync', 'probe_at', 'access_url', 'created_at'],
  92. }),
  93. groupActions: [
  94. {
  95. label: this.$t('cloudenv.text_104'),
  96. permission: 'cloudaccounts_create',
  97. action: () => {
  98. this.$router.push({ name: 'CloudaccountCreate' })
  99. },
  100. meta: () => {
  101. return {
  102. buttonType: 'primary',
  103. validate: this.isAllowCreate,
  104. }
  105. },
  106. hidden: () => this.hiddenActions.includes('create'),
  107. },
  108. {
  109. label: this.$t('common.batchAction'),
  110. actions: () => {
  111. const ownerDomain = this.$store.getters.isAdminMode || this.list.selectedItems.every(obj => obj.domain_id === this.$store.getters.userInfo.projectDomainId)
  112. return [
  113. {
  114. label: this.$t('cloudenv.sync_account'),
  115. permission: 'cloudaccounts_perform_sync',
  116. action: () => {
  117. // this.list.batchPerformAction('sync', { full_sync: true, force: true }, this.list.steadyStatus)
  118. this.createDialog('FullSyncResourceDialog', {
  119. title: this.$t('cloudenv.sync_account'),
  120. name: this.$t('common.account'),
  121. action: this.$t('cloudenv.sync_account'),
  122. steadyStatus: this.list.steadyStatus,
  123. data: this.list.selectedItems,
  124. columns: this.columns,
  125. onManager: this.onManager,
  126. })
  127. },
  128. meta: () => this.syncPolicy(this.list.selectedItems),
  129. },
  130. // {
  131. // label: this.$t('cloudenv.text_106'),
  132. // permission: 'cloudaccounts_perform_enable_auto_sync,cloudaccounts_perform_disable_auto_sync',
  133. // action: () => {
  134. // this.createDialog('CloudaccountSetAutoSyncDialog', {
  135. // data: this.list.selectedItems,
  136. // columns: this.columns,
  137. // onManager: this.onManager,
  138. // steadyStatus: this.list.steadyStatus,
  139. // })
  140. // },
  141. // meta: () => this.setAutoSyncPolicy(this.list.selectedItems, ownerDomain),
  142. // },
  143. {
  144. label: this.$t('cloudenv.text_107'),
  145. permission: 'cloudaccounts_perform_sync',
  146. action: () => {
  147. this.list.batchPerformAction('sync', null, this.list.steadyStatus)
  148. },
  149. meta: () => this.syncPolicy(this.list.selectedItems), // 和【全量同步】同逻辑
  150. },
  151. {
  152. label: this.$t('cloudenv.read_only'),
  153. permission: 'cloudaccounts_update',
  154. action: () => {
  155. this.createDialog('CloudaccountSetReadOnlyDialog', {
  156. data: this.list.selectedItems,
  157. columns: this.columns,
  158. onManager: this.onManager,
  159. })
  160. },
  161. meta: () => {
  162. return {
  163. validate: !this.list.selectedItems.some(item => {
  164. return [
  165. providerMap.vmware.key,
  166. providerMap.jdcloud.key,
  167. providerMap.ecloud.key,
  168. providerMap.s3.key,
  169. providerMap.ceph.key,
  170. providerMap.xsky.key,
  171. ].includes(item.brand)
  172. }),
  173. }
  174. },
  175. },
  176. {
  177. label: this.$t('cloudenv.set_project_mapping'),
  178. permission: 'cloudaccounts_perform_project_mapping',
  179. action: () => {
  180. this.createDialog('CloudaccountSetPojectmappingDialog', {
  181. data: this.list.selectedItems,
  182. columns: this.columns,
  183. onManager: this.onManager,
  184. })
  185. },
  186. meta: () => {
  187. return {
  188. validate: !!this.list.selectedItems.length,
  189. }
  190. },
  191. },
  192. {
  193. label: this.$t('cloudenv.action.update_credential'),
  194. permission: 'cloudaccounts_update',
  195. action: () => {
  196. this.createDialog('CloudaccountRerunBillDialog', {
  197. data: this.list.selectedItems,
  198. columns: this.columns,
  199. onManager: this.onManager,
  200. })
  201. },
  202. meta: () => {
  203. const ret = { validate: !!this.list.selectedItems.length }
  204. if (!ret.validate) return ret
  205. this.list.selectedItems.map(obj => {
  206. const ownerDomain = this.isAdminMode || obj.domain_id === this.userInfo.projectDomainId
  207. if (!ownerDomain) {
  208. ret.validate = false
  209. }
  210. if (obj.status === 'deleted') {
  211. ret.validate = false
  212. }
  213. if (!obj.tenant_id) {
  214. ret.validate = false
  215. ret.tooltip = this.$t('bill.please_set_project_mapping')
  216. }
  217. })
  218. return ret
  219. },
  220. hidden: () => isCE() || this.$store.getters.isSysCE,
  221. },
  222. ...getEnabledSwitchActions(this, undefined, ['cloudaccounts_perform_enable', 'cloudaccounts_perform_disable'], {
  223. actions: [
  224. async (obj) => {
  225. const ids = this.list.selectedItems.map(item => item.id)
  226. await this.onManager('batchPerformAction', {
  227. id: ids,
  228. managerArgs: {
  229. action: 'enable',
  230. },
  231. })
  232. this.$store.dispatch('auth/getCapabilities')
  233. },
  234. async (obj) => {
  235. const ids = this.list.selectedItems.map(item => item.id)
  236. await this.onManager('batchPerformAction', {
  237. id: ids,
  238. managerArgs: {
  239. action: 'disable',
  240. },
  241. })
  242. this.$store.dispatch('auth/getCapabilities')
  243. },
  244. ],
  245. metas: [
  246. () => {
  247. const isDisable = !!this.list.selectedItems.find(item => !item.enabled)
  248. return {
  249. validate: this.list.selectedItems.length && ownerDomain && isDisable,
  250. }
  251. },
  252. () => {
  253. const isEnable = !!this.list.selectedItems.find(item => item.enabled)
  254. return {
  255. validate: this.list.selectedItems.length && ownerDomain && isEnable,
  256. }
  257. },
  258. ],
  259. }),
  260. {
  261. label: this.$t('cloudenv.text_108'),
  262. permission: 'cloudaccounts_delete',
  263. action: () => {
  264. const supportBillBrands = ['Aws', 'Aliyun', 'Google', 'Huawei', 'Azure', 'Qcloud', 'Ksyun']
  265. const supportBill = this.list.selectedItems.some(item => {
  266. return supportBillBrands.includes(item.brand)
  267. })
  268. this.createDialog('DeleteResDialog', {
  269. vm: this,
  270. data: this.list.selectedItems,
  271. columns: this.columns,
  272. title: this.$t('cloudenv.text_109'),
  273. name: this.$t('dictionary.cloudaccount'),
  274. onManager: this.onManager,
  275. content: () => {
  276. if (supportBill && this.$appConfig.isPrivate && !this.$store.getters.isSysCE) {
  277. return <a-checkbox v-model={ this.batchDeleteBill }>{ this.$t('cloudenv.text_497') }</a-checkbox>
  278. }
  279. return null
  280. },
  281. success: async () => {
  282. if (supportBill && this.batchDeleteBill && this.$appConfig.isPrivate && !this.$store.getters.isSysCE) {
  283. const manager = new this.$Manager('billtasks/submit', 'v1')
  284. try {
  285. const p = this.list.selectedItems.filter(item => {
  286. return supportBillBrands.includes(item.brand)
  287. }).map(item => {
  288. return manager.create({
  289. data: {
  290. task_type: 'delete_bill',
  291. account_id: item.id,
  292. },
  293. })
  294. })
  295. await Promise.all(p)
  296. } catch (err) {
  297. throw err
  298. }
  299. }
  300. this.batchDeleteBill = true
  301. this.$store.dispatch('auth/getCapabilities')
  302. },
  303. cancel: () => {
  304. this.batchDeleteBill = true
  305. },
  306. })
  307. },
  308. meta: () => {
  309. const deleteResult = this.$getDeleteResult(this.list.selectedItems)
  310. if (!deleteResult.validate) {
  311. return deleteResult
  312. }
  313. return {
  314. validate: ownerDomain,
  315. }
  316. },
  317. },
  318. ]
  319. },
  320. meta: () => {
  321. return {
  322. validate: this.list.selectedItems && this.list.selectedItems.length > 0,
  323. }
  324. },
  325. },
  326. ],
  327. }
  328. },
  329. computed: {
  330. exportDataOptions () {
  331. return {
  332. title: this.$t('cloudenv.text_12'),
  333. downloadType: 'local',
  334. items: this.columns,
  335. hiddenFields: ['resource_tenant'],
  336. }
  337. },
  338. },
  339. watch: {
  340. cloudEnv (val) {
  341. this.$nextTick(() => {
  342. this.list.fetchData(0)
  343. })
  344. },
  345. },
  346. created () {
  347. this.initSidePageTab('cloudaccount-detail')
  348. this.list.fetchData()
  349. this.$bus.$on('CloudAccountListSingleRefresh', args => {
  350. this.list.singleRefresh(...args)
  351. }, this)
  352. },
  353. methods: {
  354. getParam () {
  355. const ret = {
  356. ...(R.is(Function, this.getParams) ? this.getParams() : this.getParams),
  357. }
  358. if (this.cloudEnv) ret.cloud_env = this.cloudEnv
  359. return ret
  360. },
  361. handleOpenSidepage (row, tab) {
  362. this.sidePageTriggerHandle(this, 'CloudaccountSidePage', {
  363. id: row.id,
  364. resource: 'cloudaccounts',
  365. getParams: this.getParams,
  366. refresh: this.refresh,
  367. }, {
  368. list: this.list,
  369. hiddenActions: this.hiddenActions,
  370. tab,
  371. })
  372. },
  373. },
  374. }
  375. </script>