diff --git a/src/components/AccountCreateUpdateForm/index.vue b/src/components/AccountCreateUpdateForm/index.vue index efa0aa5c8..6a7e28c66 100644 --- a/src/components/AccountCreateUpdateForm/index.vue +++ b/src/components/AccountCreateUpdateForm/index.vue @@ -50,21 +50,21 @@ export default { protocols: [ { name: 'ssh', - secret_types: ['password', 'ssh_key', 'token', 'api_key'] + secret_types: ['password', 'ssh_key', 'token', 'access_key'] } ] }, url: '/api/v1/accounts/accounts/', - form: this.account || {}, + form: Object.assign(this.account, { on_invalid: 'skip' }), encryptedFields: ['secret'], fields: [ [this.$t('assets.Asset'), ['assets']], [this.$t('common.Basic'), ['name', 'username', 'privileged', 'su_from']], [this.$t('assets.Secret'), [ - 'secret_type', 'secret', 'ssh_key', 'token', - 'api_key', 'passphrase' + 'secret_type', 'secret', 'ssh_key', + 'token', 'access_key', 'passphrase' ]], - [this.$t('common.Other'), ['push_now', 'strategy', 'is_active', 'comment']] + [this.$t('common.Other'), ['push_now', 'on_invalid', 'is_active', 'comment']] ], fieldsMeta: { assets: { @@ -78,7 +78,7 @@ export default { return this.platform || this.asset } }, - strategy: { + on_invalid: { rules: [Required], label: this.$t('ops.RunasPolicy'), helpText: this.$t('accounts.BulkCreateStrategy'), @@ -154,11 +154,11 @@ export default { component: UploadSecret, hidden: (formValue) => formValue.secret_type !== 'token' }, - api_key: { - id: 'api_key', + access_key: { + id: 'access_key', label: this.$t('assets.AccessKey'), component: UploadSecret, - hidden: (formValue) => formValue.secret_type !== 'api_key' + hidden: (formValue) => formValue.secret_type !== 'access_key' }, secret_type: { type: 'radio-group', @@ -210,7 +210,7 @@ export default { }, { label: this.$t('assets.AccessKey'), - value: 'api_key' + value: 'access_key' } ] const secretTypes = [] diff --git a/src/components/AccountListTable/AccountCreateUpdate.vue b/src/components/AccountListTable/AccountCreateUpdate.vue index 65684cdbf..497c5af03 100644 --- a/src/components/AccountListTable/AccountCreateUpdate.vue +++ b/src/components/AccountListTable/AccountCreateUpdate.vue @@ -59,6 +59,9 @@ export default { } }, computed: { + protocols() { + return this.asset ? this.asset.protocol : [] + }, iVisible: { get() { return this.visible @@ -66,46 +69,62 @@ export default { set(val) { this.$emit('update:visible', val) } - }, - protocols() { - return this.asset ? this.asset.protocol : [] } }, methods: { addAccount(form) { const formValue = Object.assign({}, form) - let assets = [] + let data, url if (this.asset) { - assets = [this.asset.id] + data = { + asset: this.asset.id, + ...formValue + } + url = `/api/v1/accounts/accounts/` } else { - assets = formValue.assets + data = formValue + url = `/api/v1/accounts/accounts/bulk/` + if (data.assets.length === 0) { + this.$message.error(this.$tc('assets.PleaseSelectAsset')) + return + } } - delete formValue.assets - if (assets.length === 0) { - this.$message.error(this.$tc('assets.PleaseSelectAsset')) - return - } - const data = [] - for (const asset of assets) { - data.push({ - ...formValue, - asset - }) - } - this.$axios.post(`/api/v1/accounts/accounts/`, data).then(() => { - this.iVisible = false - this.$emit('add', true) - this.$message.success(this.$tc('common.createSuccessMsg')) - }).catch(error => this.setFieldError(error)) + this.$axios.post(url, data).then((data) => { + this.handleResult(data, null) + }).catch(error => { + this.handleResult(null, error) + }) }, editAccount(form) { const data = { ...form } this.$axios.patch(`/api/v1/accounts/accounts/${this.account.id}/`, data).then(() => { - this.iVisible = false - this.$emit('add', true) this.$message.success(this.$tc('common.updateSuccessMsg')) }).catch(error => this.setFieldError(error)) }, + handleResult(resp, error) { + let bulkCreate = !this.asset + if (error && !Array.isArray(error)) { + bulkCreate = false + } + // if (resp && !Array.isArray(resp)) { + // bulkCreate = false + // } + if (!bulkCreate) { + if (!error) { + this.$message.success(this.$tc('common.createSuccessMsg')) + } else { + this.setFieldError(error) + } + } else { + let result + if (error) { + result = error.response.data + } else { + result = resp + } + this.$emit('bulk-create-done', result) + } + }, setFieldError(error) { const response = error.response const data = response.data diff --git a/src/components/AccountListTable/AccountList.vue b/src/components/AccountListTable/AccountList.vue index 5c70864a3..3a14abca6 100644 --- a/src/components/AccountListTable/AccountList.vue +++ b/src/components/AccountListTable/AccountList.vue @@ -20,6 +20,12 @@ :title="accountCreateUpdateTitle" :visible.sync="showAddDialog" @add="addAccountSuccess" + @bulk-create-done="showBulkCreateResult($event)" + /> + @@ -32,10 +38,12 @@ import UpdateSecretInfo from './UpdateSecretInfo' import AccountCreateUpdate from './AccountCreateUpdate' import { connectivityMeta } from './const' import { openTaskPage } from '@/utils/jms' +import ResultDialog from './BulkCreateResultDialog.vue' export default { name: 'AccountListTable', components: { + ResultDialog, ListTable, UpdateSecretInfo, ViewSecret, @@ -95,7 +103,9 @@ export default { return { showViewSecretDialog: false, showUpdateSecretDialog: false, + showResultDialog: false, showAddDialog: false, + createAccountResults: [], accountCreateUpdateTitle: this.$t('assets.AddAccount'), iAsset: this.asset, account: {}, @@ -298,11 +308,6 @@ export default { } }, ...this.headerExtraActions - // { - // name: 'autocreate', - // title: this.$t('accounts.AutoCreate'), - // type: 'default' - // } ], extraMoreActions: [ { @@ -365,6 +370,13 @@ export default { }, refresh() { this.$refs.ListTable.reloadTable() + }, + showBulkCreateResult(results) { + this.showResultDialog = false + this.createAccountResults = results + setTimeout(() => { + this.showResultDialog = true + }, 100) } } } diff --git a/src/components/AccountListTable/BulkCreateResultDialog.vue b/src/components/AccountListTable/BulkCreateResultDialog.vue new file mode 100644 index 000000000..860242ea0 --- /dev/null +++ b/src/components/AccountListTable/BulkCreateResultDialog.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/src/components/ListTable/index.vue b/src/components/ListTable/index.vue index 1ce7d4f5b..a4b6c69db 100644 --- a/src/components/ListTable/index.vue +++ b/src/components/ListTable/index.vue @@ -63,6 +63,9 @@ export default { dateEnd: extraQuery.date_to }, this.headerActions.datePicker) } + if (this.$route.query.order) { + extraQuery['order'] = this.$route.query.order + } return { selectedRows: [], init: false, diff --git a/src/i18n/langs/zh.json b/src/i18n/langs/zh.json index b644296fa..752feb46a 100644 --- a/src/i18n/langs/zh.json +++ b/src/i18n/langs/zh.json @@ -1,6 +1,7 @@ { "": "", "accounts": { + "AddAccountResult": "账号批量添加结果", "BulkCreateStrategy": "创建时对于不符合要求的账号,如:密钥类型不合规,唯一键约束,可选择以上策略。", "AccountTemplate": "账号模版", "HistoryDate": "日期", @@ -442,6 +443,10 @@ "ReLoginErr": "登录时长已超过 5 分钟,请重新登录" }, "common": { + "Created": "已创建", + "Updated": "已更新", + "Skipped": "已跳过", + "Error": "错误", "ServerError": "服务器错误", "CommunityEdition": "社区版", "EnterpriseEdition": "企业版", diff --git a/src/utils/common.js b/src/utils/common.js index 2c77a4fbe..fdac73aa8 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -1,5 +1,6 @@ import i18n from '@/i18n/i18n' import { message } from '@/utils/message' + const _ = require('lodash') const moment = require('moment') @@ -244,10 +245,10 @@ export function getDayFuture(days, now) { export function getErrorResponseMsg(error) { let msg = '' let data = '' - if (error.response.status === 500) { + if (error?.response?.status === 500) { data = i18n.t('common.ServerError') } else { - data = error.response && error.response.data || error + data = error?.response && error?.response.data || error } if (data && (data.error || data.msg || data.detail)) { msg = data.error || data.msg || data.detail diff --git a/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue b/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue index be1701b6f..53dcc45e2 100644 --- a/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue +++ b/src/views/assets/Asset/AssetCreateUpdate/components/AccountTemplateDialog.vue @@ -137,11 +137,16 @@ export default { handleConfirm() { this.iVisible = false // 过滤掉添加里还没有id的账号 - const hasIdAccounts = this.accounts.filter(i => i?.id).map(item => item.id) + const templates = this.accounts.filter(i => i?.template).map(item => item.template) const newAddAccounts = this.accountsSelected.filter(i => { - if (!hasIdAccounts.includes(i.id)) { - i.template = true - return i + return templates.indexOf(i.id) === -1 + }).map(item => { + return { + template: item.id, + name: item.name, + username: item.username, + secret_type: item.secret_type.value, + privileged: item.privileged } }) this.accounts.push(...newAddAccounts) @@ -168,7 +173,7 @@ export default { }) if (status) { this.$refs.dataTable.$refs.dataTable.toggleRowSelection(row, false) - this.$message.error(this.$t('accounts.SameTypeAccountTip')) + this.$message.error(this.$tc('accounts.SameTypeAccountTip')) } return status }, diff --git a/src/views/assets/Asset/AssetCreateUpdate/components/AssetAccounts.vue b/src/views/assets/Asset/AssetCreateUpdate/components/AssetAccounts.vue index 79d04d258..3c2d8c658 100644 --- a/src/views/assets/Asset/AssetCreateUpdate/components/AssetAccounts.vue +++ b/src/views/assets/Asset/AssetCreateUpdate/components/AssetAccounts.vue @@ -20,7 +20,7 @@ @@ -28,7 +28,7 @@ {{ $t('common.Add') }} - + {{ $t('common.TemplateAdd') }} diff --git a/src/views/assets/Asset/AssetDetail/Account.vue b/src/views/assets/Asset/AssetDetail/Account.vue index cd0d3606a..839ad857d 100644 --- a/src/views/assets/Asset/AssetDetail/Account.vue +++ b/src/views/assets/Asset/AssetDetail/Account.vue @@ -15,8 +15,8 @@ /> @@ -73,7 +73,7 @@ export default { methods: { onConfirm(data) { data = data?.map(i => { - i.template = true + i.template = i.id i.asset = this.object.id return i })