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
})