UserSelect.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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']),
  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. defaultProject: {
  120. handler () {
  121. this.fetchUsers()
  122. },
  123. deep: true,
  124. },
  125. },
  126. destroyed () {
  127. this.cm = null
  128. this.dm = null
  129. this.um = null
  130. this.pm = null
  131. this.cpm = null
  132. },
  133. async created () {
  134. this.cm = new this.$Manager('cloudaccounts')
  135. this.dm = new this.$Manager('domains', 'v1')
  136. this.um = new this.$Manager('users', 'v1')
  137. this.pm = new this.$Manager('projects', 'v1')
  138. this.cpm = new this.$Manager('cloudproviders')
  139. await this.getAccount()
  140. if (this.defaultDomainId) {
  141. if (this.isAdminMode) {
  142. await this.getDefaultDomain()
  143. } else {
  144. this.defaultDomain.id = this.defaultDomainId
  145. }
  146. }
  147. if (this.defaultProjectId) {
  148. await this.getDefaultProject()
  149. }
  150. if (this.defaultUserId) {
  151. await this.getDefaultUser()
  152. }
  153. await this.getConditionDomains()
  154. },
  155. methods: {
  156. async getAccount () {
  157. try {
  158. const cloudaccountRes = await this.cm.get({
  159. id: this.cloudaccountId,
  160. params: {
  161. scope: this.$store.getters.scope,
  162. },
  163. })
  164. this.cloudaccount = cloudaccountRes.data || {}
  165. this.accountLoaded = true
  166. } catch (error) {
  167. throw error
  168. }
  169. },
  170. async getProvider () {
  171. try {
  172. const response = await this.cpm.get({
  173. id: this.cloudproviderId,
  174. })
  175. return response.data || {}
  176. } catch (error) {
  177. throw error
  178. }
  179. },
  180. async getDefaultDomain () {
  181. try {
  182. const response = await this.dm.get({
  183. id: this.defaultDomainId,
  184. params: {
  185. scope: this.$store.getters.scope,
  186. },
  187. })
  188. this.defaultDomain = response.data || {}
  189. } catch (error) {
  190. throw error
  191. }
  192. },
  193. async getDefaultProject () {
  194. try {
  195. const response = await this.pm.get({
  196. id: this.defaultProjectId,
  197. params: {
  198. scope: this.$store.getters.scope,
  199. },
  200. })
  201. this.defaultProject = response.data || {}
  202. } catch (error) {
  203. throw error
  204. }
  205. },
  206. async getDefaultUser () {
  207. this.defaultUser.id = this.defaultUserId
  208. },
  209. async getConditionDomains (query) {
  210. if (!this.isAdminMode) {
  211. const domains = [
  212. {
  213. name: this.userInfo.projectDomain,
  214. id: this.userInfo.projectDomainId,
  215. },
  216. ]
  217. this.domains = domains
  218. this.domain = this.domains[0].id
  219. this.domainObj = this.domains[0]
  220. return
  221. }
  222. this.domainLoading = true
  223. const isGoogle = this.cloudaccount.provider === 'Google'
  224. // const isOwner = this.isAdminMode || this.cloudaccount.domain_id === this.$store.getters.userInfo.projectDomainId
  225. const { public_scope, shared_domains, share_mode } = this.cloudaccount
  226. // const userDomain = {
  227. // id: this.userInfo.projectDomainId,
  228. // name: this.userInfo.projectDomain,
  229. // }
  230. const accountDomain = {
  231. id: this.cloudaccount.domain_id,
  232. name: this.cloudaccount.project_domain,
  233. }
  234. let domains = []
  235. if (this.$store.getters.l3PermissionEnable) {
  236. if (public_scope === 'none') {
  237. domains = [accountDomain]
  238. }
  239. if (public_scope === 'domain') {
  240. if (share_mode === 'provider_domain') {
  241. if (isGoogle) {
  242. if (this.cloudproviderId) {
  243. const provider = await this.getProvider()
  244. domains = [{
  245. id: provider.domain_id,
  246. name: provider.project_domain,
  247. }]
  248. } else {
  249. domains = await this.fetchProviderDomains()
  250. }
  251. } else {
  252. domains = [accountDomain]
  253. }
  254. } else {
  255. domains = shared_domains
  256. const hasAccountDomain = R.find(R.propEq('id', accountDomain.id))(domains)
  257. if (!hasAccountDomain) {
  258. domains.push(accountDomain)
  259. }
  260. }
  261. }
  262. if (public_scope === 'system') {
  263. if (share_mode === 'provider_domain') {
  264. if (isGoogle) {
  265. if (this.cloudproviderId) {
  266. const provider = await this.getProvider()
  267. domains = [{
  268. id: provider.domain_id,
  269. name: provider.project_domain,
  270. }]
  271. } else {
  272. domains = await this.fetchProviderDomains()
  273. }
  274. } else {
  275. domains = [accountDomain]
  276. }
  277. } else {
  278. try {
  279. const params = {
  280. scope: this.scope,
  281. limit: 20,
  282. }
  283. if (query) {
  284. params.filter = `name.contains(${query})`
  285. }
  286. try {
  287. const response = await this.dm.list({
  288. params,
  289. })
  290. const data = response.data.data || []
  291. domains = data
  292. } catch (error) {
  293. throw error
  294. }
  295. } catch (error) {
  296. throw error
  297. }
  298. }
  299. }
  300. if (!R.isEmpty(this.defaultDomain)) {
  301. const isFind = R.find(R.propEq('id', this.defaultDomain.id))(domains)
  302. if (!isFind) {
  303. domains.push(this.defaultDomain)
  304. }
  305. }
  306. } else {
  307. domains = [accountDomain]
  308. }
  309. if (query) {
  310. domains = domains.filter(item => item.name.toLowerCase().includes(query))
  311. }
  312. this.domainLoading = false
  313. this.domains = domains
  314. if (!R.isEmpty(this.defaultDomain) && R.find(R.propEq('id', this.defaultDomain.id))(this.domains)) {
  315. this.domain = this.defaultDomain.id
  316. this.domainObj = { ...this.defaultDomain }
  317. } else if (this.domains.length) {
  318. this.domain = this.domains[0].id
  319. this.domainObj = this.domains[0]
  320. } else {
  321. this.domain = ''
  322. this.domainObj = {}
  323. }
  324. },
  325. // 获取项目列表
  326. async fetchProjects (query) {
  327. const params = {
  328. scope: this.scope,
  329. domain_id: this.domain,
  330. limit: 20,
  331. }
  332. if (query) {
  333. params.filter = `name.contains(${query})`
  334. }
  335. try {
  336. const response = await this.pm.list({
  337. params,
  338. })
  339. const data = response.data.data || []
  340. this.projects = data
  341. if (
  342. !R.isEmpty(this.defaultDomain) &&
  343. !R.isEmpty(this.defaultProject) &&
  344. this.defaultProject.domain_id === this.defaultDomain.id
  345. ) {
  346. const isFind = R.find(R.propEq('id', this.defaultProject.id))(this.projects)
  347. if (!isFind) {
  348. if (!query || (query && this.defaultProject.name.includes(query))) {
  349. this.projects.push(this.defaultProject)
  350. }
  351. }
  352. }
  353. if (!R.isEmpty(this.defaultProject) && R.find(R.propEq('id', this.defaultProject.id))(this.projects)) {
  354. this.project = this.defaultProject.id
  355. this.projectObj = { ...this.defaultProject }
  356. } else if (this.projects.length > 0) {
  357. this.project = this.projects[0].id
  358. this.projectObj = this.projects[0]
  359. } else {
  360. this.project = ''
  361. this.projectObj = {}
  362. }
  363. } catch (error) {
  364. throw error
  365. }
  366. },
  367. // 获取可用的user list
  368. async fetchUsers (query) {
  369. const params = {
  370. scope: this.$store.getters.scope,
  371. show_fail_reason: true,
  372. effective: true,
  373. resource: 'project',
  374. group_by: 'user',
  375. limit: 30,
  376. }
  377. if (query) {
  378. params['users.0'] = query
  379. }
  380. if (!this.defaultProject.id) return
  381. try {
  382. const response = await new this.$Manager('role_assignments', 'v1').objectRpc({
  383. methodname: 'GetProjectRole',
  384. objId: this.defaultProject.id,
  385. params,
  386. })
  387. const data = response.data.data || []
  388. this.users = data
  389. if (R.find(R.propEq('id', this.defaultUser.id))(this.users)) {
  390. this.user = this.defaultUser.id
  391. this.users.map(item => {
  392. if (item.id === this.defaultUser.id) {
  393. this.userObj = item
  394. this.defaultUser.name = item.name
  395. }
  396. })
  397. } else if (this.users.length > 0) {
  398. this.user = this.users[0].id
  399. this.userObj = this.users[0]
  400. } else {
  401. this.user = ''
  402. this.userObj = {}
  403. }
  404. } catch (error) {
  405. throw error
  406. }
  407. },
  408. async fetchProviderDomains () {
  409. try {
  410. const response = await this.cpm.list({
  411. params: {
  412. scope: this.$store.getters.scope,
  413. cloudaccount_id: this.cloudaccount.id,
  414. },
  415. })
  416. let data = response.data.data || []
  417. if (data.length) {
  418. data = data.map(item => {
  419. return {
  420. name: item.project_domain,
  421. id: item.domain_id,
  422. }
  423. })
  424. }
  425. if (data.length) {
  426. data = R.uniq(data)
  427. }
  428. return data
  429. } catch (error) {
  430. throw error
  431. }
  432. },
  433. },
  434. }
  435. </script>