singleActions.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. import { mapGetters } from 'vuex'
  2. import { changeToArr } from '@/utils/utils'
  3. import expectStatus from '@/constants/expectStatus'
  4. import { getEnabledSwitchActions } from '@/utils/common/tableActions'
  5. import i18n from '@/locales'
  6. import { findPlatform, getDisabledProvidersActionMeta, typeClouds } from '@/utils/common/hypervisor'
  7. import { hasMeterService, hasSetupKey, billSupportBrands } from '@/utils/auth'
  8. import { BRAND_MAP, CLOUD_ENVS } from '@/constants'
  9. import { CLOUDACCOUNT_TYPES } from '@Cloudenv/views/cloudaccount/constants'
  10. import setting from '@/config/setting'
  11. const steadyStatus = {
  12. status: Object.values(expectStatus.cloudaccount).flat(),
  13. sync_status: Object.values(expectStatus.cloudaccountSyncStatus).flat(),
  14. }
  15. const providerMap = typeClouds.getProviderlowcase()
  16. export default {
  17. data () {
  18. return {
  19. deleteBill: true,
  20. }
  21. },
  22. computed: {
  23. ...mapGetters(['l3PermissionEnable', 'userInfo', 'isAdminMode']),
  24. globalSettingSetupKeys () {
  25. const { globalSetting } = this.$store.state
  26. if (globalSetting && globalSetting.value) {
  27. return globalSetting.value.setupKeys
  28. }
  29. return undefined
  30. },
  31. types () {
  32. const typesMap = {}
  33. for (const box in CLOUDACCOUNT_TYPES) {
  34. for (const brand in CLOUDACCOUNT_TYPES[box]) {
  35. if (hasSetupKey([brand])) {
  36. if (!typesMap[box]) {
  37. typesMap[box] = {
  38. [brand]: CLOUDACCOUNT_TYPES[box][brand],
  39. }
  40. } else {
  41. typesMap[box][brand] = CLOUDACCOUNT_TYPES[box][brand]
  42. }
  43. if (brand === 'cloudpods') {
  44. const { companyInfo = {} } = this.$store.state.app
  45. const { inner_copyright_en, inner_copyright, inner_logo, inner_logo_format } = companyInfo
  46. CLOUDACCOUNT_TYPES[box][brand].name = setting.language === 'en' ? (inner_copyright_en || CLOUDACCOUNT_TYPES[box][brand].name) : (inner_copyright || CLOUDACCOUNT_TYPES[box][brand].name)
  47. CLOUDACCOUNT_TYPES[box][brand].logo = inner_logo && inner_logo_format ? `data:${inner_logo_format};base64,${inner_logo}` : CLOUDACCOUNT_TYPES[box][brand].logo
  48. }
  49. }
  50. }
  51. }
  52. if (hasSetupKey(['bill']) && !hasSetupKey(['onecloud', 'public', 'private', 'vmware', 'storate'])) {
  53. const setUpKeys = this.globalSettingSetupKeys || []
  54. const billTargetItems = billSupportBrands.filter(key => setUpKeys.includes('bill_' + key))
  55. if (!billTargetItems.length) {
  56. // 旧版本 license只签发bill
  57. if (!hasSetupKey('public')) {
  58. if (!typesMap.public) {
  59. typesMap.public = {}
  60. }
  61. billSupportBrands.map(key => {
  62. typesMap.public[key] = CLOUDACCOUNT_TYPES.public[key]
  63. })
  64. }
  65. } else {
  66. // 新版本 license签发billItem
  67. typesMap.public = typesMap.public || {}
  68. billTargetItems.map(key => {
  69. typesMap.public[key] = CLOUDACCOUNT_TYPES.public[key]
  70. })
  71. }
  72. }
  73. return typesMap
  74. },
  75. },
  76. created () {
  77. this.singleActions = [
  78. // 同步云账号
  79. {
  80. label: i18n.t('cloudenv.sync_account'),
  81. permission: 'cloudaccounts_perform_sync',
  82. action: (obj) => {
  83. this.createDialog('FullSyncResourceDialog', {
  84. title: this.$t('cloudenv.sync_account'),
  85. name: this.$t('common.account'),
  86. action: this.$t('cloudenv.sync_account'),
  87. steadyStatus,
  88. data: [obj],
  89. columns: this.columns,
  90. onManager: this.onManager,
  91. callback: () => {
  92. this.$message.success(this.$t('cloudenv.text_381'))
  93. },
  94. })
  95. },
  96. meta: (obj) => {
  97. if (obj.sync_status !== 'idle') {
  98. return {
  99. validate: false,
  100. tooltip: this.$t('cloudenv.syncing_account_disable_action'),
  101. }
  102. }
  103. return this.syncPolicy(obj)
  104. },
  105. },
  106. {
  107. label: i18n.t('common.more'),
  108. actions: (obj) => {
  109. const ownerDomain = this.isAdminMode || obj.domain_id === this.userInfo.projectDomainId
  110. return [
  111. // 状态设置
  112. {
  113. label: i18n.t('cloudenv.action_group.set_status'),
  114. submenus: [
  115. // 启用、禁用
  116. ...getEnabledSwitchActions(this, obj, ['cloudaccounts_perform_enable', 'cloudaccounts_perform_disable'], {
  117. actions: [
  118. async (obj) => {
  119. await this.onManager('batchPerformAction', {
  120. id: [obj.id],
  121. managerArgs: {
  122. action: 'enable',
  123. },
  124. })
  125. this.$store.dispatch('auth/getCapabilities')
  126. },
  127. async (obj) => {
  128. await this.onManager('batchPerformAction', {
  129. id: [obj.id],
  130. managerArgs: {
  131. action: 'disable',
  132. },
  133. })
  134. this.$store.dispatch('auth/getCapabilities')
  135. },
  136. ],
  137. metas: [
  138. () => {
  139. return {
  140. validate: !obj.enabled && ownerDomain,
  141. }
  142. },
  143. () => {
  144. return {
  145. validate: obj.enabled && ownerDomain,
  146. }
  147. },
  148. ],
  149. }),
  150. // 连接测试
  151. {
  152. label: i18n.t('cloudenv.text_107'),
  153. permission: 'cloudaccounts_perform_sync',
  154. action: () => {
  155. this.onManager('performAction', {
  156. id: obj.id,
  157. steadyStatus,
  158. managerArgs: {
  159. action: 'sync',
  160. },
  161. })
  162. },
  163. meta: () => {
  164. let tooltip
  165. if (!obj.enabled) tooltip = i18n.t('cloudenv.text_312')
  166. let canSync = true
  167. if (obj.enable_auto_sync && obj.sync_status !== 'idle') {
  168. canSync = false
  169. tooltip = i18n.t('cloudenv.text_313')
  170. }
  171. return {
  172. validate: (obj.enabled && canSync) && ownerDomain,
  173. tooltip,
  174. }
  175. },
  176. },
  177. ],
  178. },
  179. // 属性设置
  180. {
  181. label: i18n.t('cloudenv.action_group.set_props'),
  182. submenus: [
  183. // 设置自动同步
  184. {
  185. label: i18n.t('cloudenv.text_106'),
  186. permission: 'cloudaccounts_perform_enable_auto_sync,cloudaccounts_perform_disable_auto_sync',
  187. action: () => {
  188. this.sidePageTriggerHandle(this, 'CloudaccountSidePage', {
  189. id: obj.id,
  190. resource: 'cloudaccounts',
  191. getParams: this.getParams,
  192. refresh: this.refresh,
  193. }, {
  194. tab: 'scheduledtasks-list',
  195. list: this.list,
  196. hiddenActions: this.hiddenActions,
  197. })
  198. },
  199. meta: () => this.setAutoSyncPolicy(obj, ownerDomain),
  200. },
  201. // 设置同步策略
  202. {
  203. label: this.$t('cloudenv.set_project_mapping'),
  204. permission: 'cloudaccounts_perform_project_mapping',
  205. action: (obj) => {
  206. this.createDialog('CloudaccountSetPojectmappingDialog', {
  207. data: [obj],
  208. columns: this.columns,
  209. onManager: this.onManager,
  210. projectParams: { domain_id: obj.domain_id },
  211. })
  212. },
  213. },
  214. // 更新账号
  215. {
  216. label: i18n.t('cloudenv.action.update_account'),
  217. permission: 'cloudaccounts_perform_update_credential',
  218. action: obj => {
  219. this.createDialog('CloudaccountUpdateDialog', {
  220. data: [obj],
  221. columns: this.columns,
  222. onManager: this.onManager,
  223. })
  224. },
  225. meta: obj => {
  226. let tooltip
  227. if (!obj.enabled) tooltip = i18n.t('cloudenv.text_312')
  228. return {
  229. validate: obj.enabled && ownerDomain,
  230. tooltip,
  231. }
  232. },
  233. },
  234. // 克隆账号
  235. {
  236. label: i18n.t('cloudenv.action.clone_account'),
  237. permission: 'cloudaccounts_create',
  238. action: obj => {
  239. this.$router.push({ name: 'CloudaccountCreate', params: obj })
  240. },
  241. // 查看当前云是否允许创建
  242. meta: obj => {
  243. let validate = false
  244. const values = Object.values(this.types)
  245. if (obj.provider) {
  246. values.map(item => {
  247. const brands = Object.values(item)
  248. if (brands.some(l => l.provider === obj.provider)) {
  249. validate = true
  250. }
  251. })
  252. }
  253. return {
  254. validate,
  255. }
  256. },
  257. hidden: () => this.hiddenActions.includes('create'),
  258. },
  259. // 只读模式
  260. {
  261. label: i18n.t('cloudenv.read_only'),
  262. permission: 'cloudaccounts_update',
  263. action: () => {
  264. this.createDialog('CloudaccountSetReadOnlyDialog', {
  265. data: [obj],
  266. columns: this.columns,
  267. onManager: this.onManager,
  268. })
  269. },
  270. meta: obj => {
  271. return {
  272. validate: ![
  273. providerMap.vmware.key,
  274. providerMap.jdcloud.key,
  275. providerMap.ecloud.key,
  276. providerMap.s3.key,
  277. providerMap.ceph.key,
  278. providerMap.xsky.key,
  279. ].includes(obj.brand),
  280. }
  281. },
  282. },
  283. // 开启免密登录
  284. {
  285. label: i18n.t('cloudenv.setup_ssh_authentication'),
  286. permission: 'cloudaccounts_update',
  287. action: () => {
  288. this.createDialog('CloudaccountSetSamlAuthDialog', {
  289. data: [obj],
  290. columns: this.columns,
  291. onManager: this.onManager,
  292. refresh: this.refresh,
  293. })
  294. },
  295. meta: () => {
  296. let tooltip
  297. const isSupportSAMLAuth = ['Aws', 'Aliyun', 'Huawei', 'Qcloud', 'Azure', 'HCSO', 'HCS'].includes(obj.brand)
  298. if (!isSupportSAMLAuth) tooltip = this.$t('cloudaccount.tooltip.not_support_sso', [BRAND_MAP[obj.brand]?.label || obj.brand])
  299. if (obj.brand === 'Azure' && obj.access_url !== 'AzurePublicCloud') {
  300. let txt
  301. Object.keys(i18n.t('cloudAccountAccessType')).forEach(k => {
  302. if (obj.access_url.indexOf(k) > -1) {
  303. txt = i18n.t('cloudAccountAccessType')[k]
  304. }
  305. })
  306. tooltip = this.$t('cloudaccount.tooltip.not_support_sso', [`${BRAND_MAP[obj.brand]?.label || obj.brand} ${txt}`])
  307. return { validate: false, tooltip }
  308. }
  309. return {
  310. validate: ownerDomain && isSupportSAMLAuth,
  311. tooltip,
  312. }
  313. },
  314. },
  315. // 设置共享
  316. {
  317. label: i18n.t('cloudenv.text_281'),
  318. permission: 'cloudaccounts_perform_public',
  319. action: () => {
  320. this.createDialog('CloudaccountSetShareDialog', {
  321. data: [obj],
  322. columns: this.columns,
  323. onManager: this.onManager,
  324. steadyStatus,
  325. })
  326. },
  327. meta: () => {
  328. let tooltip = ''
  329. let validate = this.l3PermissionEnable && this.isAdminMode
  330. if (!this.l3PermissionEnable) {
  331. tooltip = i18n.t('cloudenv.text_314')
  332. } else if (!this.isAdminMode) {
  333. tooltip = i18n.t('cloudenv.text_315')
  334. }
  335. if (obj.sync_status !== 'idle' || obj.sync_status2 !== 'idle') {
  336. validate = false
  337. tooltip = i18n.t('cloudenv.syncing_account_disable_action')
  338. }
  339. return {
  340. validate,
  341. tooltip,
  342. }
  343. },
  344. },
  345. // 设置代理
  346. {
  347. label: i18n.t('cloudenv.text_316'),
  348. permission: 'cloudaccounts_update',
  349. action: () => {
  350. this.createDialog('UpdateProxySettingDialog', {
  351. title: i18n.t('cloudenv.text_316'),
  352. data: [obj],
  353. columns: this.columns,
  354. onManager: this.onManager,
  355. })
  356. },
  357. meta: () => {
  358. return {
  359. validate: ownerDomain,
  360. }
  361. },
  362. },
  363. ],
  364. },
  365. // 费用设置
  366. {
  367. label: i18n.t('cloudenv.action_group.set_fee'),
  368. submenus: [
  369. // 更新账单
  370. {
  371. label: i18n.t('cloudenv.action.update_credential'),
  372. permission: 'cloudaccounts_perform_update_credential',
  373. action: obj => {
  374. this.$router.push({
  375. name: 'CloudaccountUpdateBill',
  376. query: {
  377. id: obj.id,
  378. provider: obj.provider,
  379. backPath: '/cloudaccount',
  380. },
  381. })
  382. },
  383. meta: obj => {
  384. const supportBrands = [
  385. ...billSupportBrands,
  386. BRAND_MAP.Ksyun.key,
  387. ]
  388. return {
  389. validate: this.$appConfig.isPrivate &&
  390. (supportBrands.some(key => key.toLowerCase() === (obj.brand || '').toLowerCase()) || obj.cloud_env === CLOUD_ENVS.private) &&
  391. ownerDomain,
  392. }
  393. },
  394. hidden: !hasMeterService() || !this.$appConfig.isPrivate || this.$store.getters.isSysCE,
  395. },
  396. // 设置优惠率
  397. {
  398. label: i18n.t('cloudaccount.table.action.set_discount'),
  399. permission: 'prices_perform_discount',
  400. action: () => {
  401. this.createDialog('CloudaccountSetDiscountDialog', {
  402. data: [obj],
  403. columns: this.columns,
  404. onManager: this.onManager,
  405. })
  406. },
  407. meta: () => {
  408. const ownerDomain = this.isAdminMode || obj.domain_id === this.userInfo.projectDomainId
  409. const isPublic = findPlatform(obj.brand.toLowerCase()) === 'public'
  410. const ret = {
  411. validate: true,
  412. }
  413. if (!isPublic) {
  414. ret.validate = false
  415. ret.tooltip = this.$t('cloudaccount.tooltip.disable_set_discount')
  416. return ret
  417. }
  418. if (!ownerDomain) {
  419. ret.validate = false
  420. ret.tooltip = this.$t('common.share', [this.$t('cloudenv.text_12')])
  421. return ret
  422. }
  423. return ret
  424. },
  425. extraMeta: obj => {
  426. return getDisabledProvidersActionMeta({
  427. row: obj,
  428. disabledProviders: ['BingoCloud', 'VolcEngine'],
  429. })
  430. },
  431. hidden: () => {
  432. return !hasMeterService()
  433. },
  434. },
  435. ],
  436. },
  437. // 删除
  438. {
  439. label: i18n.t('common.delete'),
  440. submenus: [
  441. // 删除
  442. {
  443. label: i18n.t('common.delete'),
  444. permission: 'cloudaccounts_delete',
  445. action: () => {
  446. this.createDialog('DeleteResDialog', {
  447. vm: this,
  448. data: [obj],
  449. columns: this.columns,
  450. title: i18n.t('cloudenv.text_109'),
  451. name: this.$t('dictionary.cloudaccount'),
  452. onManager: this.onManager,
  453. content: () => {
  454. if (this.$appConfig.isPrivate && !this.$store.getters.isSysCE) {
  455. return <a-checkbox v-model={this.deleteBill}>{this.$t('cloudenv.text_497')}</a-checkbox>
  456. }
  457. return null
  458. },
  459. success: async () => {
  460. if (this.deleteBill && this.$appConfig.isPrivate && !this.$store.getters.isSysCE) {
  461. const manager = new this.$Manager('billtasks/submit', 'v1')
  462. try {
  463. const data = {
  464. task_type: 'delete_bill',
  465. account_id: obj.id,
  466. }
  467. await manager.create({
  468. data,
  469. })
  470. } catch (err) {
  471. throw err
  472. }
  473. }
  474. this.deleteBill = true
  475. this.$store.dispatch('auth/getCapabilities')
  476. },
  477. cancel: () => {
  478. this.deleteBill = true
  479. },
  480. })
  481. },
  482. meta: () => {
  483. const deleteResult = this.$getDeleteResult(obj)
  484. if (!deleteResult.validate) {
  485. return deleteResult
  486. }
  487. return {
  488. validate: ownerDomain,
  489. }
  490. },
  491. },
  492. ],
  493. },
  494. ]
  495. },
  496. },
  497. ]
  498. },
  499. methods: {
  500. syncPolicy (item) {
  501. let tooltip
  502. const items = changeToArr(item)
  503. if (!items.length) return { validate: false }
  504. const enabledValid = items.every(obj => {
  505. if (!obj.enabled) {
  506. tooltip = i18n.t('cloudenv.text_312')
  507. return false
  508. }
  509. return true
  510. })
  511. const autoSyncValid = items.every(obj => {
  512. if (obj.enable_auto_sync && obj.sync_status !== 'idle') {
  513. tooltip = i18n.t('cloudenv.text_313')
  514. return false
  515. }
  516. return true
  517. })
  518. const ownerDomain = this.isAdminMode || items.every(obj => obj.domain_id === this.userInfo.projectDomainId)
  519. return {
  520. validate: enabledValid && autoSyncValid && ownerDomain,
  521. tooltip,
  522. }
  523. },
  524. setAutoSyncPolicy (item, ownerDomain) {
  525. let tooltip
  526. const items = changeToArr(item)
  527. if (!items.length) return { validate: false }
  528. const enabledValid = items.every(obj => {
  529. if (!obj.enabled) {
  530. tooltip = i18n.t('cloudenv.text_312')
  531. return false
  532. }
  533. return true
  534. })
  535. return {
  536. validate: enabledValid && ownerDomain,
  537. tooltip,
  538. }
  539. },
  540. },
  541. }