UserSelect.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. <template>
  2. <div>
  3. <template v-if="accountLoaded">
  4. <a-row :gutter="8" class="w-100">
  5. <template v-if="isAdminMode && this.$store.getters.l3PermissionEnable">
  6. <a-col :span="8">
  7. <a-select v-model="domain" show-search @search="getConditionDomains" :filter-option="false" allow-clear dropdownClassName="oc-select-dropdown">
  8. <template v-for="item of domains">
  9. <a-select-option :key="item.id" :value="item.id">
  10. <span class="text-color-secondary option-prefix">{{ $t('dictionary.domain') }}: </span>{{ item.name }}
  11. </a-select-option>
  12. </template>
  13. </a-select>
  14. </a-col>
  15. </template>
  16. <a-col :span="isAdminMode ? 8 : 12">
  17. <a-select v-model="project" show-search @search="fetchProjects" :filter-option="false" allow-clear dropdownClassName="oc-select-dropdown">
  18. <template v-for="item of projects">
  19. <a-select-option :key="item.id" :value="item.id">
  20. <span class="text-color-secondary option-prefix">{{ $t('dictionary.project') }}: </span>{{ item.name }}
  21. </a-select-option>
  22. </template>
  23. </a-select>
  24. </a-col>
  25. <a-col :span="isAdminMode ? 8 : 12">
  26. <a-select v-model="user" show-search @search="fetchUsers" :filter-option="false" allow-clear dropdownClassName="oc-select-dropdown">
  27. <template v-for="item of users">
  28. <a-select-option :key="item.id" :value="item.id">
  29. <span class="text-color-secondary option-prefix">{{ $t('dictionary.user') }}: </span>{{ item.name }}
  30. </a-select-option>
  31. </template>
  32. </a-select>
  33. </a-col>
  34. </a-row>
  35. </template>
  36. <template v-else>
  37. <a-spin />
  38. </template>
  39. </div>
  40. </template>
  41. <script>
  42. import * as R from 'ramda'
  43. import { mapGetters } from 'vuex'
  44. export default {
  45. name: 'UserSelect',
  46. props: {
  47. cloudproviderId: String,
  48. cloudaccountId: String,
  49. defaultProjectId: String,
  50. defaultDomainId: String,
  51. defaultUserId: String,
  52. defaultDomainName: String,
  53. },
  54. data () {
  55. return {
  56. cloudaccount: {},
  57. accountLoaded: false,
  58. domainLoading: false,
  59. domains: [],
  60. domain: '',
  61. domainObj: {},
  62. projects: [],
  63. projectLoading: false,
  64. project: '',
  65. projectObj: {},
  66. userLoading: false,
  67. users: [],
  68. user: '',
  69. userObj: {},
  70. defaultProject: {},
  71. defaultDomain: {},
  72. defaultUser: {},
  73. // defaultUserJoinProjects: [],
  74. }
  75. },
  76. computed: {
  77. ...mapGetters(['isAdminMode', 'userInfo', 'scope', 'isDomainMode']),
  78. },
  79. watch: {
  80. domain (val, oldVal) {
  81. if (val !== oldVal) {
  82. if (val) {
  83. const obj = R.find(R.propEq('id', val))(this.domains)
  84. this.$emit('update:domain', obj)
  85. this.fetchProjects()
  86. } else {
  87. this.projects = []
  88. this.project = ''
  89. this.projectObj = {}
  90. this.$emit('update:project', this.projectObj)
  91. }
  92. }
  93. },
  94. project (val, oldVal) {
  95. if (val !== oldVal) {
  96. if (val) {
  97. const obj = R.find(R.propEq('id', val))(this.projects)
  98. this.$emit('update:project', obj)
  99. this.fetchUsers()
  100. } else {
  101. this.users = []
  102. this.user = ''
  103. this.userObj = {}
  104. this.$emit('input', this.user)
  105. this.$emit('change', this.user)
  106. this.$emit('update:user', this.userObj)
  107. }
  108. }
  109. },
  110. user (val, oldVal) {
  111. this.$emit('input', val)
  112. this.$emit('change', val)
  113. const obj = R.find(R.propEq('id', val))(this.users)
  114. this.$emit('update:user', obj)
  115. },
  116. cloudproviderId (val) {
  117. this.getConditionDomains()
  118. },
  119. },
  120. destroyed () {
  121. this.cm = null
  122. this.dm = null
  123. this.um = null
  124. this.pm = null
  125. this.cpm = null
  126. },
  127. async created () {
  128. this.cm = new this.$Manager('cloudaccounts')
  129. this.dm = new this.$Manager('domains', 'v1')
  130. this.um = new this.$Manager('users', 'v1')
  131. this.pm = new this.$Manager('projects', 'v1')
  132. this.cpm = new this.$Manager('cloudproviders')
  133. await this.getAccount()
  134. if (this.defaultDomainId) {
  135. if (this.isAdminMode) {
  136. await this.getDefaultDomain()
  137. } else {
  138. this.defaultDomain.id = this.defaultDomainId
  139. }
  140. }
  141. if (this.defaultProjectId) {
  142. await this.getDefaultProject()
  143. }
  144. if (this.defaultUserId) {
  145. await this.getDefaultUser()
  146. }
  147. await this.getConditionDomains()
  148. },
  149. methods: {
  150. async getAccount () {
  151. try {
  152. const cloudaccountRes = await this.cm.get({
  153. id: this.cloudaccountId,
  154. params: {
  155. scope: this.$store.getters.scope,
  156. },
  157. })
  158. this.cloudaccount = cloudaccountRes.data || {}
  159. this.accountLoaded = true
  160. } catch (error) {
  161. throw error
  162. }
  163. },
  164. async getProvider () {
  165. try {
  166. const response = await this.cpm.get({
  167. id: this.cloudproviderId,
  168. })
  169. return response.data || {}
  170. } catch (error) {
  171. throw error
  172. }
  173. },
  174. async getDefaultDomain () {
  175. try {
  176. const response = await this.dm.get({
  177. id: this.defaultDomainId,
  178. params: {
  179. scope: this.$store.getters.scope,
  180. },
  181. })
  182. this.defaultDomain = response.data || {}
  183. } catch (error) {
  184. throw error
  185. }
  186. },
  187. async getDefaultProject () {
  188. try {
  189. const response = await this.pm.get({
  190. id: this.defaultProjectId,
  191. params: {
  192. scope: this.$store.getters.scope,
  193. },
  194. })
  195. this.defaultProject = response.data || {}
  196. } catch (error) {
  197. throw error
  198. }
  199. },
  200. async getDefaultUser () {
  201. this.defaultUser.id = this.defaultUserId
  202. },
  203. async getConditionDomains (query) {
  204. if (!this.isAdminMode) {
  205. const domains = [
  206. {
  207. name: this.userInfo.projectDomain,
  208. id: this.userInfo.projectDomainId,
  209. },
  210. ]
  211. this.domains = domains
  212. this.domain = this.domains[0].id
  213. this.domainObj = this.domains[0]
  214. return
  215. }
  216. this.domainLoading = true
  217. const isGoogle = this.cloudaccount.provider === 'Google'
  218. // const isOwner = this.isAdminMode || this.cloudaccount.domain_id === this.$store.getters.userInfo.projectDomainId
  219. const { public_scope, shared_domains, share_mode } = this.cloudaccount
  220. // const userDomain = {
  221. // id: this.userInfo.projectDomainId,
  222. // name: this.userInfo.projectDomain,
  223. // }
  224. const accountDomain = {
  225. id: this.cloudaccount.domain_id,
  226. name: this.cloudaccount.project_domain,
  227. }
  228. let domains = []
  229. if (this.$store.getters.l3PermissionEnable) {
  230. if (public_scope === 'none') {
  231. domains = [accountDomain]
  232. }
  233. if (public_scope === 'domain') {
  234. if (share_mode === 'provider_domain') {
  235. if (isGoogle) {
  236. if (this.cloudproviderId) {
  237. const provider = await this.getProvider()
  238. domains = [{
  239. id: provider.domain_id,
  240. name: provider.project_domain,
  241. }]
  242. } else {
  243. domains = await this.fetchProviderDomains()
  244. }
  245. } else {
  246. domains = [accountDomain]
  247. }
  248. } else {
  249. domains = shared_domains
  250. const hasAccountDomain = R.find(R.propEq('id', accountDomain.id))(domains)
  251. if (!hasAccountDomain) {
  252. domains.push(accountDomain)
  253. }
  254. }
  255. }
  256. if (public_scope === 'system') {
  257. if (share_mode === 'provider_domain') {
  258. if (isGoogle) {
  259. if (this.cloudproviderId) {
  260. const provider = await this.getProvider()
  261. domains = [{
  262. id: provider.domain_id,
  263. name: provider.project_domain,
  264. }]
  265. } else {
  266. domains = await this.fetchProviderDomains()
  267. }
  268. } else {
  269. domains = [accountDomain]
  270. }
  271. } else {
  272. try {
  273. const params = {
  274. scope: this.scope,
  275. limit: 20,
  276. }
  277. if (query) {
  278. params.filter = `name.contains(${query})`
  279. }
  280. try {
  281. const response = await this.dm.list({
  282. params,
  283. })
  284. const data = response.data.data || []
  285. domains = data
  286. } catch (error) {
  287. throw error
  288. }
  289. } catch (error) {
  290. throw error
  291. }
  292. }
  293. }
  294. if (!R.isEmpty(this.defaultDomain)) {
  295. const isFind = R.find(R.propEq('id', this.defaultDomain.id))(domains)
  296. if (!isFind) {
  297. domains.push(this.defaultDomain)
  298. }
  299. }
  300. } else {
  301. domains = [accountDomain]
  302. }
  303. if (query) {
  304. domains = domains.filter(item => item.name.toLowerCase().includes(query))
  305. }
  306. this.domainLoading = false
  307. this.domains = domains
  308. if (!R.isEmpty(this.defaultDomain) && R.find(R.propEq('id', this.defaultDomain.id))(this.domains)) {
  309. this.domain = this.defaultDomain.id
  310. this.domainObj = { ...this.defaultDomain }
  311. } else if (this.domains.length) {
  312. this.domain = this.domains[0].id
  313. this.domainObj = this.domains[0]
  314. } else {
  315. this.domain = ''
  316. this.domainObj = {}
  317. }
  318. },
  319. // 获取项目列表
  320. async fetchProjects (query) {
  321. const params = {
  322. scope: this.scope,
  323. domain_id: this.domain,
  324. limit: 20,
  325. }
  326. if (query) {
  327. params.filter = `name.contains(${query})`
  328. }
  329. try {
  330. const response = await this.pm.list({
  331. params,
  332. })
  333. const data = response.data.data || []
  334. this.projects = data
  335. if (
  336. !R.isEmpty(this.defaultDomain) &&
  337. !R.isEmpty(this.defaultProject) &&
  338. this.defaultProject.domain_id === this.defaultDomain.id &&
  339. this.domain === this.defaultDomain.id
  340. ) {
  341. const isFind = R.find(R.propEq('id', this.defaultProject.id))(this.projects)
  342. if (!isFind) {
  343. if (!query || (query && this.defaultProject.name.includes(query))) {
  344. this.projects.push(this.defaultProject)
  345. }
  346. }
  347. }
  348. if (!R.isEmpty(this.defaultProject) && R.find(R.propEq('id', this.defaultProject.id))(this.projects)) {
  349. this.project = this.defaultProject.id
  350. this.projectObj = { ...this.defaultProject }
  351. } else if (this.projects.length > 0) {
  352. this.project = this.projects[0].id
  353. this.projectObj = this.projects[0]
  354. } else {
  355. this.project = ''
  356. this.projectObj = {}
  357. }
  358. } catch (error) {
  359. throw error
  360. }
  361. },
  362. // 获取可用的user list
  363. async fetchUsers (query) {
  364. const params = {
  365. scope: this.$store.getters.scope,
  366. show_fail_reason: true,
  367. effective: true,
  368. resource: 'project',
  369. group_by: 'user',
  370. limit: 30,
  371. }
  372. if (query) {
  373. params['users.0'] = query
  374. }
  375. try {
  376. const response = await new this.$Manager('role_assignments', 'v1').objectRpc({
  377. methodname: 'GetProjectRole',
  378. objId: this.project,
  379. params,
  380. })
  381. const data = response.data.data || []
  382. this.users = data
  383. if (R.find(R.propEq('id', this.defaultUser.id))(this.users)) {
  384. this.user = this.defaultUser.id
  385. this.users.map(item => {
  386. if (item.id === this.defaultUser.id) {
  387. this.userObj = item
  388. this.defaultUser.name = item.name
  389. }
  390. })
  391. } else if (this.users.length > 0) {
  392. this.user = this.users[0].id
  393. this.userObj = this.users[0]
  394. } else {
  395. this.user = ''
  396. this.userObj = {}
  397. }
  398. } catch (error) {
  399. throw error
  400. }
  401. },
  402. async fetchProviderDomains () {
  403. try {
  404. const response = await this.cpm.list({
  405. params: {
  406. scope: this.$store.getters.scope,
  407. cloudaccount_id: this.cloudaccount.id,
  408. },
  409. })
  410. let data = response.data.data || []
  411. if (data.length) {
  412. data = data.map(item => {
  413. return {
  414. name: item.project_domain,
  415. id: item.domain_id,
  416. }
  417. })
  418. }
  419. if (data.length) {
  420. data = R.uniq(data)
  421. }
  422. return data
  423. } catch (error) {
  424. throw error
  425. }
  426. },
  427. },
  428. }
  429. </script>