diff --git a/src/i18n/langs/cn.json b/src/i18n/langs/cn.json index e196bf8f2..528052434 100644 --- a/src/i18n/langs/cn.json +++ b/src/i18n/langs/cn.json @@ -203,6 +203,7 @@ "Basic": "基本", "PleaseAgreeToTheTerms": "请同意条款", "BasicInfo": "基本信息", + "ApplyInfo": "申请信息", "Cancel": "取消", "Close": "关闭", "Command filter": "命令过滤器", @@ -803,6 +804,8 @@ "reply": "回复", "status": "状态", "title": "标题", + "action": "动作", + "IPGroup": "IP 组", "type": "类型", "user": "用户", "Status": "状态", @@ -815,6 +818,7 @@ "Asset": "资产", "SystemUser": "系统用户", "RequestAssetPerm": "申请资产授权", + "RequestApplicationPerm": "申请应用授权", "Applicant": "申请人", "Pending": "待处理", "Approved": "已同意", @@ -822,7 +826,8 @@ "Closed": "已完成", "helpText": { "ips": "请输入逗号分割的IP地址组", - "fuzzySearch": "支持模糊搜索" + "fuzzySearch": "支持模糊搜索", + "application": "请输入逗号分割的应用组" } }, "tree": { diff --git a/src/i18n/langs/en.json b/src/i18n/langs/en.json index 377f20eab..211187238 100644 --- a/src/i18n/langs/en.json +++ b/src/i18n/langs/en.json @@ -203,6 +203,7 @@ "BadConflictErrorMsg": "Refreshing, please try again later", "Basic": "Basic", "BasicInfo": "Basic info", + "ApplyInfo": "Apply info", "Cancel": "Cancel", "Close": "Close", "Command filter": "Command filter", @@ -789,6 +790,8 @@ "Close": "Close", "Comment": "Comment", "MyTickets": "My tickets", + "action": "Action", + "IPGroup": "IP 组", "Reject": "Reject", "date": "Date", "reply": "Reply", @@ -804,13 +807,15 @@ "SystemUser": "System user", "Applicant": "Applicant", "RequestAssetPerm": "Request asset perm", + "RequestApplicationPerm": "Request application perm", "Pending": "Open", "Approved": "Approved", "Rejected": "Rejected", "Closed": "Closed", "helpText": { "ips": "Enter the IP address group, separated by commas", - "fuzzySearch": "Support for fuzzy search" + "fuzzySearch": "Support for fuzzy search", + "application": "Enter the application group, separated by commas" } }, "tree": { diff --git a/src/router/tickets.js b/src/router/tickets.js index f253d1789..0da04f06f 100644 --- a/src/router/tickets.js +++ b/src/router/tickets.js @@ -27,5 +27,12 @@ export default [ component: () => import('@/views/tickets/RequestAssetPerm/Detail/index'), meta: { title: i18n.t('route.TicketDetail'), activeMenu: '/tickets/tickets' }, hidden: true + }, + { + path: 'tickets/request-application-perm/create', + name: 'RequestApplicationPermTicketCreateUpdate', + component: () => import('@/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate'), + meta: { title: i18n.t('route.TicketCreate'), activeMenu: '/tickets/tickets' }, + hidden: true } ] diff --git a/src/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate.vue b/src/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate.vue new file mode 100644 index 000000000..4fed48dca --- /dev/null +++ b/src/views/tickets/RequestApplicationPerm/RequestApplicationPermTicketCreateUpdate.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/src/views/tickets/RequestAssetPerm/Detail/TicketDetail.vue b/src/views/tickets/RequestAssetPerm/Detail/TicketDetail.vue index dd5a8e8b5..a088f91fa 100644 --- a/src/views/tickets/RequestAssetPerm/Detail/TicketDetail.vue +++ b/src/views/tickets/RequestAssetPerm/Detail/TicketDetail.vue @@ -19,6 +19,18 @@ + + + + + + @@ -49,17 +61,19 @@ export default { return { statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action], requestForm: { - asset: this.object.confirmed_assets, - systemuser: this.object.confirmed_system_users, - actions: this.object.actions + asset: this.object.meta.recommend_assets, + systemuser: this.object.meta.recommend_system_users, + actions: this.object.meta.apply_actions, + apply_date_expired: this.object.meta.apply_date_expired, + apply_date_start: this.object.meta.apply_date_start }, comments: '', assets: [], asset_select2: { multiple: true, - value: this.object.confirmed_assets, + value: this.object.meta.recommend_assets, ajax: { - url: this.object.assets_waitlist_url, + url: `/api/v1/assets/assets/?org_id=${(this.object.org_id === '') ? 'DEFAULT' : this.object.org_id}&protocol__in=rdp,vnc,ssh,telnet`, transformOption: (item) => { return { label: item.hostname, value: item.id } } @@ -67,9 +81,9 @@ export default { }, systemuser_select2: { multiple: true, - value: this.object.confirmed_system_users, + value: this.object.meta.recommend_system_users, ajax: { - url: this.object.system_users_waitlist_url, + url: `/api/v1/assets/system-users/?org_id=${(this.object.org_id === '') ? 'DEFAULT' : this.object.org_id}&protocol__in=rdp,vnc,ssh,telnet`, transformOption: (item) => { return { label: item.name + '(' + item.username + ')', value: item.id } } @@ -93,7 +107,7 @@ export default { }, { key: this.$t('tickets.user'), - value: this.object.user_display + value: this.object.applicant_display }, { key: this.$t('tickets.Assignees'), @@ -101,7 +115,7 @@ export default { }, { key: this.$t('tickets.Assignee'), - value: this.object.assignee_display + value: this.object.processor }, { key: this.$t('common.dateCreated'), @@ -121,23 +135,23 @@ export default { // }, { key: this.$t('tickets.IP'), - value: this.object.ips + value: this.object.meta.apply_ip_group }, { key: this.$t('tickets.Hostname'), - value: this.object.hostname + value: this.object.meta.apply_hostname_group }, { key: this.$t('tickets.SystemUser'), - value: this.object.system_user + value: this.object.meta.apply_system_user_group }, { key: this.$t('common.dateStart'), - value: toSafeLocalDateStr(this.object.date_start) + value: toSafeLocalDateStr(this.object.meta.apply_date_start) }, { key: this.$t('common.dateExpired'), - value: toSafeLocalDateStr(this.object.date_expired) + value: toSafeLocalDateStr(this.object.meta.apply_date_expired) } ] }, @@ -159,31 +173,31 @@ export default { if (this.requestForm.asset.length === 0 || this.requestForm.systemuser.length === 0) { return this.$message.error(this.$t('common.NeedAssetsAndSystemUserErrMsg')) } else { - this.$axios.patch(`/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/`, { - confirmed_system_users: this.requestForm.systemuser, - confirmed_assets: this.requestForm.asset, - actions: this.requestForm.actions - }).then(res => { - this.$axios.post(`/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/approve/`).then( - () => { - this.$message.success(this.$t('common.updateSuccessMsg')) - this.reloadPage() - } - ) - }).catch( + this.$axios.put(`/api/v1/tickets/tickets/${this.object.id}/approve/`, { + meta: { + approve_system_users: this.requestForm.systemuser, + approve_assets: this.requestForm.asset, + approve_actions: this.requestForm.actions, + approve_date_start: this.requestForm.apply_date_start, + approve_date_expired: this.requestForm.apply_date_expired + } + }).then( + () => { + this.$message.success(this.$t('common.updateSuccessMsg')) + this.reloadPage() + } + ).catch( () => this.$message.success(this.$t('common.updateErrorMsg')) ) } }, handleClose() { - const url = `/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/close/` - const data = { status: 'closed' } - this.$axios.post(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err)) + const url = `/api/v1/tickets/tickets/${this.object.id}/close/` + this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err)) }, handleReject() { - const url = `/api/v1/tickets/tickets/request-asset-perm/${this.object.id}/reject/` - const data = { action: 'reject' } - this.$axios.post(url, data).then(res => this.reloadPage()).catch(err => this.$message.error(err)) + const url = `/api/v1/tickets/tickets/${this.object.id}/reject/` + this.$axios.put(url).then(res => this.reloadPage()).catch(err => this.$message.error(err)) } } } diff --git a/src/views/tickets/RequestAssetPerm/Detail/index.vue b/src/views/tickets/RequestAssetPerm/Detail/index.vue index 0e4191f67..22557987c 100644 --- a/src/views/tickets/RequestAssetPerm/Detail/index.vue +++ b/src/views/tickets/RequestAssetPerm/Detail/index.vue @@ -19,12 +19,16 @@ export default { ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' }, config: { activeMenu: 'TicketDetail', + url: '', submenu: [ { title: this.$t('route.TicketDetail'), name: 'TicketDetail' } ], + actions: { + detailApiUrl: `/api/v1/tickets/tickets/${this.$route.params.id}/` + }, getObjectName: this.getObjectName, hasRightSide: false } diff --git a/src/views/tickets/RequestAssetPerm/RequestAssetPermTicketCreateUpdate.vue b/src/views/tickets/RequestAssetPerm/RequestAssetPermTicketCreateUpdate.vue index 1588441d9..f269fdd87 100644 --- a/src/views/tickets/RequestAssetPerm/RequestAssetPermTicketCreateUpdate.vue +++ b/src/views/tickets/RequestAssetPerm/RequestAssetPermTicketCreateUpdate.vue @@ -21,31 +21,54 @@ export default { hasDetailInMsg: false, initial: { ips_or_not: true, - date_expired: date_expired, - date_start: date_start, + apply_date_expired: date_expired, + apply_date_start: date_start, org_id: 'DEFAULT', - actions: ['all', 'connect', 'updownload', 'upload_file', 'download_file'] + type: 'apply_asset', + apply_actions: ['all', 'connect', 'updownload', 'upload_file', 'download_file'] }, fields: [ - [this.$t('common.Basic'), ['title', 'org_id', 'assignees', 'comment']], - [this.$t('tickets.RequestPerm'), ['ips', 'hostname', 'system_user', 'actions', 'date_start', 'date_expired']] + [this.$t('common.Basic'), ['title', 'type', 'org_id', 'assignees', 'comment']], + [this.$t('tickets.RequestPerm'), ['apply_ip_group', 'apply_hostname_group', 'apply_system_user_group', 'apply_actions', 'apply_date_start', 'apply_date_expired']] ], fieldsMeta: { - ips: { + type: { + el: { + disabled: true + } + }, + apply_ip_group: { + label: this.$t('tickets.IPGroup'), helpText: this.$t('tickets.helpText.ips') }, - hostname: { + apply_hostname_group: { + label: this.$t('assets.Hostname'), helpText: this.$t('tickets.helpText.fuzzySearch') }, - system_user: { + apply_system_user_group: { + label: this.$t('assets.SystemUser'), helpText: this.$t('tickets.helpText.fuzzySearch') }, - actions: { + apply_actions: { label: this.$t('perms.Actions'), component: AssetPermissionFormActionField, helpText: this.$t('common.actionsTips') }, + apply_date_start: { + label: this.$t('common.DateStart'), + type: 'date-picker', + el: { + type: 'datetime' + } + }, + apply_date_expired: { + label: this.$t('common.DateEnd'), + type: 'date-picker', + el: { + type: 'datetime' + } + }, org_id: { component: Select2, el: { @@ -54,8 +77,7 @@ export default { }, on: { changeOptions: ([event], updateForm) => { - // console.log(event[0].value) // output: input value - this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/tickets/request-asset-perm/assignees/?org_id=${event[0].value}` + this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/assignees/?org_id=${event[0].value}` } } }, @@ -64,7 +86,7 @@ export default { multiple: true, value: [], ajax: { - url: '/api/v1/tickets/tickets/request-asset-perm/assignees/', + url: `/api/v1/tickets/assignees/?org_id=DEFAULT`, transformOption: (item) => { return { label: item.name + '(' + item.username + ')', value: item.id } } @@ -72,7 +94,7 @@ export default { } } }, - url: '/api/v1/tickets/tickets/request-asset-perm/', + url: '/api/v1/tickets/tickets/?type=apply_asset&action=open', createSuccessNextRoute: { name: 'TicketList' } @@ -80,14 +102,37 @@ export default { }, methods: { performSubmit(validValues) { - const ips = validValues.ips + const meta = {} + const ips = validValues.apply_ip_group if (ips) { - validValues.ips = ips.split(',') + validValues.meta.apply_ip_group = ips.split(',') } if (ips === '') { - delete validValues['ips'] + delete validValues['apply_ip_group'] } - return this.$axios['post'](this.url, validValues) + if (validValues.apply_hostname_group) { + meta.apply_hostname_group = validValues.apply_ip_group + delete validValues['apply_hostname_group'] + } + + if (validValues.apply_system_user_group) { + meta.apply_system_user_group = validValues.apply_system_user_group + delete validValues['apply_system_user_group'] + } + + if (validValues.apply_actions) { + meta.apply_actions = validValues.apply_actions + delete validValues['apply_actions'] + } + meta.apply_date_start = validValues.apply_date_start + delete validValues['apply_date_start'] + + meta.apply_date_expired = validValues.apply_date_expired + delete validValues['apply_date_expired'] + + validValues['meta'] = meta + + return this.$axios['post'](`/api/v1/tickets/tickets/open/?type=apply_asset`, validValues) } } } diff --git a/src/views/tickets/TicketDetail/index.vue b/src/views/tickets/TicketDetail/index.vue index 67fad8d0f..8d9ed98db 100644 --- a/src/views/tickets/TicketDetail/index.vue +++ b/src/views/tickets/TicketDetail/index.vue @@ -16,7 +16,14 @@ export default { }, data() { return { - ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' }, + ticket: { + title: '', + user_display: '', + type_display: '', + status: '', + assignees_display: '', + date_created: '' + }, config: { activeMenu: 'TicketDetail', submenu: [ diff --git a/src/views/tickets/TicketListTable.vue b/src/views/tickets/TicketListTable.vue index 1aed0bef4..25ffc89b1 100644 --- a/src/views/tickets/TicketListTable.vue +++ b/src/views/tickets/TicketListTable.vue @@ -32,7 +32,9 @@ export default { sortable: 'custom', formatterArgs: { getRoute: function({ row }) { - if (row.type === 'request_asset') { + if (row.type === 'apply_asset') { + return 'AssetsTicketDetail' + } else if (row.type === 'apply_application') { return 'AssetsTicketDetail' } else { return 'TicketDetail' @@ -48,7 +50,7 @@ export default { { prop: 'type_display', label: this.$t('tickets.type'), - width: '110px' + width: '160px' }, { prop: 'status', @@ -56,6 +58,20 @@ export default { align: 'center', width: '90px', sortable: 'custom', + formatter: row => { + if (row.status === 'open') { + return { this.$t('tickets.Open') } + } else { + return { this.$t('tickets.Closed') } + } + } + }, + { + prop: 'action', + label: this.$t('tickets.action'), + align: 'center', + width: '90px', + sortable: 'custom', formatter: row => { if (row.status === 'open') { return { this.$t('tickets.Pending') } @@ -69,7 +85,6 @@ export default { return { this.$t('tickets.Closed') } } } - }, { prop: 'date_created', @@ -105,16 +120,20 @@ export default { genExtraMoreActions() { return [ { - name: '', + name: 'RequestAssetPerm', title: this.$t('tickets.RequestAssetPerm'), type: 'primary', can: true, - callback: this.onCallback + callback: () => this.$router.push({ name: 'RequestAssetPermTicketCreateUpdate' }) + }, + { + name: 'RequestApplicationPerm', + title: this.$t('tickets.RequestApplicationPerm'), + type: 'primary', + can: true, + callback: () => this.$router.push({ name: 'RequestApplicationPermTicketCreateUpdate' }) } ] - }, - onCallback() { - this.$router.push({ name: 'RequestAssetPermTicketCreateUpdate' }) } } } diff --git a/src/views/tickets/components/Comments.vue b/src/views/tickets/components/Comments.vue index 4f14a93a5..81779a122 100644 --- a/src/views/tickets/components/Comments.vue +++ b/src/views/tickets/components/Comments.vue @@ -117,7 +117,7 @@ export default { }, getComment() { this.loading = true - const url = `/api/v1/tickets/tickets/${this.object.id}/comments/` + const url = `/api/v1/tickets/comments/?ticket_id=${this.object.id}` this.$axios.get(url).then(res => { this.comments = res }).catch(err => { @@ -148,7 +148,7 @@ export default { createComment(successCallback) { const commentText = this.form.comments const ticketId = this.object.id - const commentUrl = `/api/v1/tickets/tickets/${ticketId}/comments/` + const commentUrl = `/api/v1/tickets/comments/?ticket_id=${this.object.id}` if (!commentText) { return } const body = { body: commentText, diff --git a/src/views/tickets/components/Details.vue b/src/views/tickets/components/Details.vue index a9a749f48..5e7c578a5 100644 --- a/src/views/tickets/components/Details.vue +++ b/src/views/tickets/components/Details.vue @@ -1,7 +1,7 @@