SetShare.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. <template>
  2. <base-dialog @cancel="cancelDialog">
  3. <div slot="header">{{$t('cloudenv.text_281')}}</div>
  4. <div slot="body">
  5. <dialog-selected-tips :name="$t('dictionary.cloudaccount')" :count="params.data.length" :action="$t('cloudenv.text_281')" />
  6. <dialog-table :data="params.data" :columns="params.columns.slice(0, 3)" />
  7. <a-form-model
  8. ref="form"
  9. :model="fd"
  10. :rules="rules"
  11. v-bind="formItemLayout">
  12. <a-form-model-item :label="$t('cloudenv.text_282')" prop="share_mode" :extra="extra">
  13. <a-radio-group v-model="fd.share_mode">
  14. <template v-for="item of shareModeOptions">
  15. <a-radio-button :key="item.key" :value="item.key">{{ item.label }}</a-radio-button>
  16. </template>
  17. </a-radio-group>
  18. </a-form-model-item>
  19. <a-form-model-item :label="$t('dictionary.domain')" prop="provider_shared_domains" v-if="providerDomainMode">
  20. <template v-if="providerDomainLoaded">
  21. <a-select
  22. :value="fd.provider_shared_domains"
  23. @search="fetchProviderDomains"
  24. :filterOption="false"
  25. mode="multiple"
  26. @select="val => handleHasAllSelect(val, 'provider_shared_domains')"
  27. @deselect="val => handleDeselect(val, 'provider_shared_domains')">
  28. <template v-for="item of providerDomains">
  29. <a-select-option :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
  30. </template>
  31. </a-select>
  32. </template>
  33. <template v-else>
  34. <a-spin />
  35. </template>
  36. </a-form-model-item>
  37. <a-form-model-item :label="$t('dictionary.domain')" prop="system_shared_domains" v-if="systemMode">
  38. <template v-if="systemDomainLoaded">
  39. <a-select
  40. :value="fd.system_shared_domains"
  41. @search="fetchSystemDomains"
  42. :filterOption="false"
  43. mode="multiple"
  44. @select="val => handleHasAllSelect(val, 'system_shared_domains')"
  45. @deselect="val => handleDeselect(val, 'system_shared_domains')">
  46. <template v-for="item of systemDomains">
  47. <a-select-option :key="item.id" :value="item.id">{{ item.name }}</a-select-option>
  48. </template>
  49. </a-select>
  50. </template>
  51. <template v-else>
  52. <a-spin />
  53. </template>
  54. </a-form-model-item>
  55. </a-form-model>
  56. </div>
  57. <div slot="footer">
  58. <a-button type="primary" @click="handleConfirm" :loading="loading">{{ $t('dialog.ok') }}</a-button>
  59. <a-button @click="cancelDialog">{{ $t('dialog.cancel') }}</a-button>
  60. </div>
  61. </base-dialog>
  62. </template>
  63. <script>
  64. import * as R from 'ramda'
  65. import { mapGetters } from 'vuex'
  66. import DialogMixin from '@/mixins/dialog'
  67. import WindowsMixin from '@/mixins/windows'
  68. export default {
  69. name: 'CloudaccountSetShareDialog',
  70. mixins: [DialogMixin, WindowsMixin],
  71. data () {
  72. const isBatch = this.params.data.length >= 2
  73. let shareModeInitialValue = 'account_domain'
  74. let providerSharedDomainsInitialValue = []
  75. let systemSharedDomainsInitialValue = []
  76. // 只有单项操作时,才进行反显
  77. if (!isBatch && this.params.data[0].is_public) {
  78. const firstData = this.params.data[0]
  79. const { share_mode: shareMode, shared_domains: sharedDomains } = firstData
  80. // 共享云订阅
  81. if (shareMode === 'provider_domain') {
  82. shareModeInitialValue = 'provider_domain'
  83. // 为空时是全局
  84. if (R.isNil(sharedDomains) || R.isEmpty(sharedDomains)) {
  85. providerSharedDomainsInitialValue = ['all']
  86. } else {
  87. providerSharedDomainsInitialValue = sharedDomains.map(item => item.id)
  88. }
  89. }
  90. if (shareMode === 'system') {
  91. shareModeInitialValue = 'system'
  92. // 为空时是全局
  93. if (R.isNil(sharedDomains) || R.isEmpty(sharedDomains)) {
  94. systemSharedDomainsInitialValue = ['all']
  95. } else {
  96. systemSharedDomainsInitialValue = sharedDomains.map(item => item.id)
  97. }
  98. }
  99. }
  100. return {
  101. loading: false,
  102. fd: {
  103. share_mode: shareModeInitialValue,
  104. provider_shared_domains: providerSharedDomainsInitialValue,
  105. system_shared_domains: systemSharedDomainsInitialValue,
  106. },
  107. rules: {
  108. share_mode: [
  109. { required: true, message: this.$t('cloudenv.text_283') },
  110. ],
  111. provider_shared_domains: [
  112. { required: true, message: this.$t('cloudenv.text_284', [this.$t('dictionary.domain')]) },
  113. ],
  114. system_shared_domains: [
  115. { required: true, message: this.$t('cloudenv.text_284', [this.$t('dictionary.domain')]) },
  116. ],
  117. },
  118. shareModeOptions: [
  119. { key: 'account_domain', label: this.$t('cloudenv.text_285') },
  120. { key: 'provider_domain', label: this.$t('cloudenv.text_286') },
  121. { key: 'system', label: this.$t('cloudenv.text_287') },
  122. ],
  123. formItemLayout: {
  124. wrapperCol: {
  125. span: 20,
  126. },
  127. labelCol: {
  128. span: 4,
  129. },
  130. },
  131. isBatch,
  132. providerDomainLoaded: false,
  133. providerDomains: [],
  134. systemDomainLoaded: false,
  135. systemDomains: [],
  136. }
  137. },
  138. computed: {
  139. ...mapGetters(['l3PermissionEnable']),
  140. extra () {
  141. const shareModeExtra = {
  142. account_domain: this.$t('cloudenv.text_288', [this.$t('dictionary.cloudaccount'), this.$t('dictionary.domain'), this.$t('dictionary.project'), this.$t('dictionary.cloudaccount')]),
  143. provider_domain: this.$t('cloudenv.text_293', [this.$t('dictionary.domain'), this.$t('dictionary.project'), this.$t('dictionary.cloudaccount'), this.$t('dictionary.project')]),
  144. system: this.$t('cloudenv.text_296', [this.$t('dictionary.domain'), this.$t('dictionary.project'), this.$t('dictionary.cloudaccount')]),
  145. }
  146. return shareModeExtra[this.fd.share_mode]
  147. },
  148. accountDomainMode () {
  149. return this.fd.share_mode === 'account_domain'
  150. },
  151. providerDomainMode () {
  152. return this.fd.share_mode === 'provider_domain'
  153. },
  154. systemMode () {
  155. return this.fd.share_mode === 'system'
  156. },
  157. },
  158. watch: {
  159. providerDomainMode: {
  160. handler (val) {
  161. if (val) {
  162. this.$nextTick(() => {
  163. this.fetchProviderDomains()
  164. })
  165. }
  166. },
  167. immediate: true,
  168. },
  169. systemMode: {
  170. handler (val) {
  171. if (val) {
  172. this.$nextTick(() => {
  173. this.fetchSystemDomains()
  174. })
  175. }
  176. },
  177. immediate: true,
  178. },
  179. },
  180. beforeDestroy () {
  181. this.dm = null
  182. },
  183. created () {
  184. this.dm = new this.$Manager('domains', 'v1')
  185. },
  186. methods: {
  187. async fetchProviderDomains (query) {
  188. try {
  189. const data = await this.fetchDomains(query)
  190. this.providerDomains = data
  191. this.providerDomainLoaded = true
  192. } catch (error) {
  193. throw error
  194. }
  195. },
  196. async fetchSystemDomains (query) {
  197. try {
  198. const data = await this.fetchDomains(query)
  199. this.systemDomains = data
  200. this.systemDomainLoaded = true
  201. } catch (error) {
  202. throw error
  203. }
  204. },
  205. async fetchDomains (query, p = {}) {
  206. const params = {
  207. details: true,
  208. scope: this.scope,
  209. limit: 20,
  210. ...p,
  211. }
  212. if (query) {
  213. params.search = query
  214. }
  215. try {
  216. const response = await this.dm.list({
  217. params,
  218. })
  219. let data = response.data.data || []
  220. if (!this.isBatch && this.params.data[0].shared_domains && this.params.data[0].shared_domains.length) {
  221. data = this.mergeSharedRes(data, this.params.data[0].shared_domains)
  222. }
  223. data.unshift({ id: 'all', name: this.$t('cloudenv.text_297') })
  224. return data
  225. } catch (error) {
  226. throw error
  227. }
  228. },
  229. // 合并已共享的资源,这样可以实现name的反显,不会有先显示id的问题
  230. mergeSharedRes (data, sharedData) {
  231. const ret = [...data]
  232. if (sharedData && sharedData.length > 0) {
  233. R.forEach(value => {
  234. const obj = R.find(R.propEq('id', value.id))(ret)
  235. if (!obj) {
  236. ret.push(obj)
  237. }
  238. })
  239. }
  240. return ret
  241. },
  242. // 全部与选择项互斥交互
  243. handleHasAllSelect (val, field) {
  244. let newVal = []
  245. if (val === 'all') {
  246. newVal = ['all']
  247. } else {
  248. newVal = [...this.fd[field]]
  249. const allIndex = newVal.indexOf('all')
  250. const valIndex = newVal.indexOf(val)
  251. if (valIndex === -1) {
  252. newVal.push(val)
  253. }
  254. if (allIndex !== -1) {
  255. newVal.splice(allIndex, 1)
  256. }
  257. }
  258. this.$nextTick(() => {
  259. this.fd[field] = newVal
  260. this.$refs.form.validate()
  261. })
  262. },
  263. // 取消选中
  264. handleDeselect (val, field) {
  265. const newVal = [...this.fd[field]]
  266. const valIndex = newVal.indexOf(val)
  267. if (valIndex !== -1) {
  268. newVal.splice(valIndex, 1)
  269. }
  270. this.fd[field] = newVal
  271. },
  272. setPublic (ids, data) {
  273. return this.params.onManager('batchPerformAction', {
  274. id: ids,
  275. steadyStatus: this.params.steadyStatus,
  276. managerArgs: {
  277. action: 'public',
  278. data,
  279. },
  280. })
  281. },
  282. setPrivate (ids) {
  283. return this.params.onManager('batchPerformAction', {
  284. id: ids,
  285. steadyStatus: this.params.steadyStatus,
  286. managerArgs: {
  287. action: 'private',
  288. },
  289. })
  290. },
  291. async handleConfirm () {
  292. this.loading = true
  293. try {
  294. await this.$refs.form.validate()
  295. const ids = this.params.data.map(item => item.id)
  296. // 不共享
  297. if (this.accountDomainMode) {
  298. await this.setPrivate(ids)
  299. } else {
  300. const data = {
  301. share_mode: this.fd.share_mode,
  302. }
  303. // 共享云订阅
  304. if (this.providerDomainMode) {
  305. if (this.fd.provider_shared_domains[0] === 'all') {
  306. data.scope = 'system'
  307. } else {
  308. data.scope = 'domain'
  309. data.shared_domains = this.fd.provider_shared_domains
  310. }
  311. }
  312. // 共享云账号
  313. if (this.systemMode) {
  314. if (this.fd.system_shared_domains[0] === 'all') {
  315. data.scope = 'system'
  316. } else {
  317. data.scope = 'domain'
  318. data.shared_domains = this.fd.system_shared_domains
  319. }
  320. }
  321. await this.setPublic(ids, data)
  322. }
  323. this.cancelDialog()
  324. } catch (error) {
  325. throw error
  326. } finally {
  327. this.loading = false
  328. }
  329. },
  330. },
  331. }
  332. </script>