SetProjectmapping.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('cloudenv.set_project_mapping')}}</div>
  4. <div slot="body">
  5. <dialog-selected-tips :name="$t('res.cloudaccount')" :count="params.data.length" :action="$t('cloudenv.set_project_mapping')" />
  6. <dialog-table :data="params.data" :columns="params.columns.slice(0, 3)" />
  7. <a-form-model
  8. ref="form"
  9. class="mt-3"
  10. :model="fd"
  11. :rules="rules"
  12. v-bind="formItemLayout">
  13. <a-form-model-item :label="$t('cloudenv.resource_map_type')" :extra="resourceMapExtra" prop="resource_map_type">
  14. <a-checkbox-group v-model="fd.resource_map_type" :options="resourceMapTypeOpts" @change="resourceMapTypeChange" />
  15. </a-form-model-item>
  16. <!-- 同步策略 -->
  17. <a-form-model-item v-if="openProjectMapping" :label="$t('cloudenv.text_580')" prop="project_mapping_id">
  18. <base-select
  19. v-model="fd.project_mapping_id"
  20. resource="project_mappings"
  21. :select-props="{ placeholder: $t('common.tips.select', [$t('cloudenv.text_580')]), allowClear: true }"
  22. :params="projectMappingParams" />
  23. </a-form-model-item>
  24. <a-form-model-item v-if="openProjectMapping" :label="$t('cloudenv.effective_scope')" prop="effective_scope" :extra="effectiveScopeExtra">
  25. <a-radio-group v-model="fd.effective_scope">
  26. <a-radio-button value="resource">{{$t('cloudenv.resource_tag')}}</a-radio-button>
  27. <a-radio-button value="project">{{$t('cloudenv.project_tag')}}</a-radio-button>
  28. </a-radio-group>
  29. </a-form-model-item>
  30. <a-form-model-item
  31. v-if="fd.resource_map_type.length"
  32. :label="fd.resource_map_type.length === 1 && fd.resource_map_type.includes('project') ? $t('cloudenv.target_project') : $t('cloudenv.default_project')"
  33. prop="project_id">
  34. <base-select
  35. v-model="fd.project_id"
  36. resource="projects"
  37. filterable
  38. remote
  39. :params="projectParams" />
  40. </a-form-model-item>
  41. <a-form-item :label="$t('cloudenv.block_resources')" v-if="!ignoreBlockedResources">
  42. <a-switch
  43. :checkedChildren="$t('cloudenv.text_84')"
  44. :unCheckedChildren="$t('cloudenv.text_85')"
  45. v-model="fd.isOpenBlockedResources" />
  46. </a-form-item>
  47. <a-form-item :label="$t('cloudenv.block_resources_type')" v-if="!ignoreBlockedResources && fd.isOpenBlockedResources">
  48. <base-select
  49. v-model="fd.blockedResources"
  50. :options="BLOCKED_RESOURCES"
  51. :select-props="{ placeholder: $t('common.tips.select', [$t('cloudenv.block_resources_type')]), allowClear: true, mode: 'multiple' }" />
  52. </a-form-item>
  53. </a-form-model>
  54. </div>
  55. <div slot="footer">
  56. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  57. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  58. </div>
  59. </base-dialog>
  60. </template>
  61. <script>
  62. import { BLOCKED_RESOURCES } from '@Cloudenv/constants'
  63. import DialogMixin from '@/mixins/dialog'
  64. import WindowsMixin from '@/mixins/windows'
  65. export default {
  66. name: 'CloudaccountSetPojectmappingDialog',
  67. mixins: [DialogMixin, WindowsMixin],
  68. data () {
  69. const initResourceMapType = []
  70. let initProjectMappingId = null
  71. let initEffectiveScope = ''
  72. let initProjectId = null
  73. let initBlockResource = []
  74. this.params.data.map(item => {
  75. if (!initProjectMappingId && item.project_mapping_id) {
  76. initProjectMappingId = item.project_mapping_id
  77. initResourceMapType.push('project_mapping')
  78. }
  79. if (item.auto_create_project) {
  80. initResourceMapType.push('external_project')
  81. }
  82. if (item.auto_create_project_for_provider) {
  83. initResourceMapType.push('cloudprovider')
  84. }
  85. if (item.tenant_id) {
  86. initProjectId = item.tenant_id
  87. initResourceMapType.push('project')
  88. }
  89. if (item.enable_resource_sync && !initEffectiveScope) {
  90. initEffectiveScope = 'resource'
  91. } else if (item.enable_project_sync && !initEffectiveScope) {
  92. initEffectiveScope = 'project'
  93. }
  94. if (item.skip_sync_resources) {
  95. initBlockResource = item.skip_sync_resources
  96. }
  97. })
  98. return {
  99. BLOCKED_RESOURCES,
  100. loading: false,
  101. showAutoCreateProject: true,
  102. fd: {
  103. resource_map_type: initResourceMapType,
  104. project_id: initProjectId,
  105. project_mapping_id: initProjectMappingId,
  106. effective_scope: initEffectiveScope || 'resource',
  107. isOpenBlockedResources: initBlockResource?.length > 0,
  108. blockedResources: initBlockResource || [],
  109. },
  110. rules: {
  111. resource_map_type: [
  112. { required: true, message: this.$t('cloudenv.select_resource_map_type') },
  113. ],
  114. project_mapping_id: [
  115. { required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.text_580')]) },
  116. ],
  117. blockedResources: [
  118. { required: true, message: this.$t('common.tips.select', [this.$t('cloudenv.block_resources_type')]) },
  119. ],
  120. project_id: [
  121. { required: true, message: this.$t('rules.project') },
  122. ],
  123. },
  124. formItemLayout: {
  125. wrapperCol: {
  126. span: 18,
  127. },
  128. labelCol: {
  129. span: 6,
  130. },
  131. },
  132. }
  133. },
  134. computed: {
  135. resourceMapTypeOpts () {
  136. const ret = [
  137. { value: 'project_mapping', label: this.$t('cloudenv.belong_to_project.project_mapping') },
  138. { value: 'external_project', label: this.$t('cloudenv.belong_to_project.external_project') },
  139. { value: 'cloudprovider', label: this.$t('cloudenv.belong_to_project.cloudprovider') },
  140. { value: 'project', label: this.$t('cloudenv.target_project') },
  141. ]
  142. return ret
  143. },
  144. resourceMapExtra () {
  145. const { resource_map_type: resourceMapType } = this.fd
  146. if (!resourceMapType.length) return ''
  147. if (resourceMapType.length === 1) {
  148. return this.$t(`cloudenv.resource_map_type.${resourceMapType[0]}`)
  149. }
  150. if (resourceMapType.includes('project_mapping') && resourceMapType.includes('external_project') && resourceMapType.includes('cloudprovider')) {
  151. return this.$t('cloudenv.resource_map_type.all')
  152. }
  153. if (resourceMapType.includes('project_mapping') && resourceMapType.includes('external_project')) {
  154. return this.$t('cloudenv.resource_map_type.project_mapping_and_external_project')
  155. }
  156. if (resourceMapType.includes('project_mapping') && resourceMapType.includes('cloudprovider')) {
  157. return this.$t('cloudenv.resource_map_type.project_mapping_and_cloudprovider')
  158. }
  159. if (resourceMapType.includes('external_project') && resourceMapType.includes('cloudprovider')) {
  160. return this.$t('cloudenv.resource_map_type.external_project_and_cloudprovider')
  161. }
  162. const types = resourceMapType.filter(key => key !== 'project')
  163. if (types.length) {
  164. return this.$t(`cloudenv.resource_map_type.${types[0]}`)
  165. } else {
  166. return this.$t('cloudenv.resource_map_type.project')
  167. }
  168. },
  169. effectiveScopeExtra () {
  170. if (this.fd.effective_scope === 'resource') {
  171. return this.$t('cloudenv.resource_tag_tip')
  172. } else if (this.fd.effective_scope === 'project') {
  173. return this.$t('cloudenv.project_tag_tip')
  174. }
  175. return ''
  176. },
  177. projectParams () {
  178. const { projectParams = {} } = this.params
  179. return {
  180. scope: this.$store.getters.scope,
  181. limit: 20,
  182. ...projectParams,
  183. }
  184. },
  185. openProjectMapping () {
  186. return this.fd.resource_map_type.includes('project_mapping')
  187. },
  188. projectMappingParams () {
  189. const ret = {
  190. scope: this.$store.getters.scope,
  191. }
  192. if (this.params.data.length === 1) {
  193. return {
  194. project_domain: this.params.data[0].domain_id,
  195. }
  196. }
  197. return ret
  198. },
  199. isSingle () {
  200. return this.params.data.length === 1
  201. },
  202. ignoreBlockedResources () {
  203. const { ignoreBlockedResources = false } = this.params
  204. return ignoreBlockedResources
  205. },
  206. },
  207. methods: {
  208. genParams () {
  209. const {
  210. resource_map_type,
  211. project_id,
  212. project_mapping_id,
  213. effective_scope,
  214. isOpenBlockedResources,
  215. blockedResources,
  216. } = this.fd
  217. const ret = {}
  218. ret.auto_create_project = resource_map_type.includes('external_project')
  219. ret.auto_create_project_for_provider = resource_map_type.includes('cloudprovider')
  220. if (resource_map_type.includes('project_mapping') && project_mapping_id) {
  221. ret.project_mapping_id = project_mapping_id
  222. }
  223. if (resource_map_type.includes('project_mapping')) {
  224. if (effective_scope === 'resource') {
  225. ret.enable_resource_sync = true
  226. ret.enable_project_sync = false
  227. } else if (effective_scope === 'project') {
  228. ret.enable_project_sync = true
  229. ret.enable_resource_sync = false
  230. }
  231. }
  232. if (project_id) {
  233. ret.project_id = project_id
  234. }
  235. if (!this.ignoreBlockedResources && isOpenBlockedResources) {
  236. ret.skip_sync_resources = blockedResources
  237. delete ret.isOpenBlockedResources
  238. delete ret.blockedResources
  239. }
  240. return ret
  241. },
  242. resourceMapTypeChange (value) {
  243. this.resourceMapType = value
  244. this.openProjectMapping = value.includes('project_mapping')
  245. },
  246. async handleConfirm () {
  247. this.loading = true
  248. try {
  249. await this.$refs.form.validate()
  250. const { skip_sync_resources, ...data } = this.genParams()
  251. await this.params.onManager('batchPerformAction', {
  252. id: this.params.data.map(item => {
  253. return item.id
  254. }),
  255. managerArgs: {
  256. action: 'project-mapping',
  257. data,
  258. },
  259. })
  260. if (!this.ignoreBlockedResources) {
  261. await this.params.onManager('update', {
  262. id: this.params.data[0].id,
  263. managerArgs: {
  264. data: {
  265. skip_sync_resources: skip_sync_resources || [],
  266. },
  267. },
  268. })
  269. }
  270. this.cancelDialog()
  271. } finally {
  272. this.loading = false
  273. }
  274. },
  275. },
  276. }
  277. </script>