mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-13 19:35:24 +00:00
feat: 工单管理 (#963)
* feat: 工单多级审批 * fix: action bug Co-authored-by: feng626 <1304903146@qq.com>
This commit is contained in:
@@ -937,6 +937,7 @@
|
||||
"Approved": "已同意",
|
||||
"Rejected": "已拒绝",
|
||||
"Closed": "已完成",
|
||||
"StateClosed": "已关闭",
|
||||
"helpText": {
|
||||
"ips": "请输入逗号分割的IP地址组",
|
||||
"fuzzySearch": "支持模糊搜索",
|
||||
|
||||
@@ -7,50 +7,17 @@
|
||||
:approve="handleApprove"
|
||||
:close="handleClose"
|
||||
:reject="handleReject"
|
||||
>
|
||||
<IBox v-if="hasActionPerm&&object.status !== 'closed'" class="box">
|
||||
<div slot="header" class="clearfix ibox-title">
|
||||
<i class="fa fa-edit" /> {{ $t('common.Actions') }}
|
||||
</div>
|
||||
<template>
|
||||
<el-form ref="requestForm" :model="requestForm" label-width="140px" label-position="left" class="assets">
|
||||
<el-form-item :label="$t('perms.PermName')" required>
|
||||
<el-input v-model="requestForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('assets.Applications')" required>
|
||||
<Select2 v-model="requestForm.application" v-bind="appsSelect2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('tickets.SystemUser')" required>
|
||||
<Select2 v-model="requestForm.systemuser" v-bind="systemuserSelect2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateStart')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_start"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateExpired')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_expired"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</IBox>
|
||||
</GenericTicketDetail>
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formatTime, getDateTimeStamp } from '@/utils/index'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
import { STATUS_MAP } from '../../const'
|
||||
import Select2 from '@/components/FormFields/Select2'
|
||||
import IBox from '@/components/IBox'
|
||||
import GenericTicketDetail from '@/views/tickets/components/GenericTicketDetail'
|
||||
export default {
|
||||
name: '',
|
||||
components: { GenericTicketDetail, IBox, Select2 },
|
||||
components: { GenericTicketDetail },
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
@@ -59,44 +26,16 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action],
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP['notified'] : STATUS_MAP[this.object.state],
|
||||
requestForm: {
|
||||
name: this.object.meta.approve_permission_name,
|
||||
application: this.object.meta['recommend_applications'],
|
||||
systemuser: this.object.meta['recommend_system_users'],
|
||||
application: this.object.meta['apply_applications'],
|
||||
systemuser: this.object.meta['apply_system_users'],
|
||||
apply_date_expired: this.object.meta.apply_date_expired,
|
||||
apply_date_start: this.object.meta.apply_date_start
|
||||
},
|
||||
comments: '',
|
||||
assets: [],
|
||||
appsSelect2: {
|
||||
multiple: true,
|
||||
value: this.object.meta['recommend_applications'],
|
||||
ajax: {
|
||||
url: function() {
|
||||
const oid = this.object.org_id === '' ? 'DEFAULT' : this.object.org_id
|
||||
return `/api/v1/applications/applications/?oid=${oid}&type=${this.object.meta.apply_type}`
|
||||
}.bind(this)(),
|
||||
transformOption: (item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
systemuserSelect2: {
|
||||
multiple: true,
|
||||
value: this.object.meta['recommend_system_users'],
|
||||
ajax: {
|
||||
url: function() {
|
||||
const oid = this.object.org_id === '' ? 'DEFAULT' : this.object.org_id
|
||||
const protocol = this.object.meta.apply_category === 'remote_app' ? 'rdp' : this.object.meta.apply_type
|
||||
return `/api/v1/assets/system-users/?oid=${oid}&protocol=${protocol}`
|
||||
}.bind(this)(),
|
||||
transformOption: (item) => {
|
||||
const username = item.username || '*'
|
||||
return { label: item.name + '(' + username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
assets: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -117,14 +56,6 @@ export default {
|
||||
key: this.$t('tickets.user'),
|
||||
value: this.object['applicant_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignees'),
|
||||
value: this.object['assignees_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: (this.object['processor_display'] === 'No') ? '' : this.object['processor_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.OrgName'),
|
||||
value: this.object['org_name']
|
||||
@@ -141,21 +72,17 @@ export default {
|
||||
},
|
||||
specialCardItems() {
|
||||
return [
|
||||
// {
|
||||
// key: this.$t('tickets.Assignee'),
|
||||
// value: this.object.assignee_display
|
||||
// },
|
||||
{
|
||||
key: this.$t('applications.appType'),
|
||||
value: `${this.object.meta['apply_category_display']} / ${this.object.meta['apply_type_display']} `
|
||||
},
|
||||
{
|
||||
key: this.$t('applications.appName'),
|
||||
value: this.object.meta.apply_application_group.toString()
|
||||
value: this.object.meta.apply_applications_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta.apply_system_user_group.toString()
|
||||
value: this.object.meta.apply_system_users_display
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
@@ -168,22 +95,31 @@ export default {
|
||||
]
|
||||
},
|
||||
assignedCardItems() {
|
||||
const vm = this
|
||||
return [
|
||||
{
|
||||
key: this.$t('tickets.PermissionName'),
|
||||
value: this.object.meta.apply_permission_name,
|
||||
formatter: function(item, value) {
|
||||
const to = { name: 'AssetPermissionDetail', params: { id: vm.object.id }}
|
||||
return <router-link to={to}>{ value }</router-link>
|
||||
}
|
||||
},
|
||||
{
|
||||
key: this.$t('applications.appName'),
|
||||
value: this.object.meta['approve_applications_display']
|
||||
value: this.object.meta['apply_applications_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta['approve_system_users_display']
|
||||
value: this.object.meta['apply_system_users_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_start)
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_start)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateExpired'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_expired)
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_expired)
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -206,13 +142,7 @@ export default {
|
||||
return this.$message.error(this.$tc('common.NeedAssetsAndSystemUserErrMsg'))
|
||||
} else {
|
||||
this.$axios.put(`/api/v1/tickets/tickets/${this.object.id}/approve/`, {
|
||||
meta: {
|
||||
approve_permission_name: this.requestForm.name,
|
||||
approve_system_users: this.requestForm.systemuser,
|
||||
approve_applications: this.requestForm.application,
|
||||
approve_date_start: this.requestForm.apply_date_start,
|
||||
approve_date_expired: this.requestForm.apply_date_expired
|
||||
}
|
||||
meta: {}
|
||||
}).then(
|
||||
() => {
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
import Select2 from '@/components/FormFields/Select2'
|
||||
import { DEFAULT_ORG_ID } from '@/utils/org'
|
||||
import { getDaysFuture } from '@/utils/common'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
export default {
|
||||
@@ -37,7 +36,7 @@ export default {
|
||||
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['title', 'type', 'org_id', 'assignees', 'comment']],
|
||||
[this.$t('common.Basic'), ['title', 'type', 'org_id', 'comment']],
|
||||
[this.$t('tickets.RequestPerm'), ['meta']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
@@ -48,7 +47,9 @@ export default {
|
||||
}
|
||||
},
|
||||
meta: {
|
||||
fields: ['apply_category_type', 'apply_application_group', 'apply_system_user_group', 'apply_date_start', 'apply_date_expired'],
|
||||
fields: [
|
||||
'apply_category_type', 'apply_applications', 'apply_system_users',
|
||||
'apply_date_start', 'apply_date_expired'],
|
||||
fieldsMeta: {
|
||||
apply_date_start: {
|
||||
label: this.$t('common.DateStart'),
|
||||
@@ -57,11 +58,37 @@ export default {
|
||||
type: 'datetime'
|
||||
}
|
||||
},
|
||||
apply_application_group: {
|
||||
helpText: this.$t('tickets.helpText.application')
|
||||
apply_applications: {
|
||||
type: 'assetSelect',
|
||||
component: Select2,
|
||||
label: this.$t('perms.Asset'),
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + ' (' + item.type_display + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
apply_system_user_group: {
|
||||
helpText: this.$t('tickets.helpText.fuzzySearch')
|
||||
apply_system_users: {
|
||||
type: 'systemUserSelect',
|
||||
component: Select2,
|
||||
label: '系统用户',
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '',
|
||||
transformOption: (item) => {
|
||||
if (this.$route.query.type === 'k8s') {
|
||||
return { label: item.name, value: item.id }
|
||||
}
|
||||
const username = item.username || '*'
|
||||
return { label: item.name + '(' + username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
apply_date_expired: {
|
||||
label: this.$t('common.DateEnd'),
|
||||
@@ -131,6 +158,12 @@ export default {
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
on: {
|
||||
change: ([event], updateForm) => {
|
||||
this.fieldsMeta.meta.fieldsMeta.apply_applications.el.ajax.url = `/api/v1/applications/applications/?category=${event[0]}&type=${event[1]}`
|
||||
this.fieldsMeta.meta.fieldsMeta.apply_system_users.el.ajax.url = event[0] === 'remote_app' ? `/api/v1/assets/system-users/?protocol=rdp` : `/api/v1/assets/system-users/?protocol=${event[1]}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,18 +181,6 @@ export default {
|
||||
this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/assignees/?org_id=${event[0].value}`
|
||||
}
|
||||
}
|
||||
},
|
||||
assignees: {
|
||||
el: {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: `/api/v1/tickets/assignees/?org_id=${DEFAULT_ORG_ID}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
url: '/api/v1/tickets/tickets/?type=apply_application&action=open',
|
||||
@@ -179,12 +200,6 @@ export default {
|
||||
validValues.meta.apply_category = validValues.meta.apply_category_type[0]
|
||||
validValues.meta.apply_type = validValues.meta.apply_category_type[1]
|
||||
delete validValues.meta['apply_category_type']
|
||||
if (validValues.meta.apply_application_group) {
|
||||
validValues.meta.apply_application_group = validValues.meta.apply_application_group.split(',')
|
||||
}
|
||||
if (validValues.meta.apply_system_user_group) {
|
||||
validValues.meta.apply_system_user_group = validValues.meta.apply_system_user_group.split(',')
|
||||
}
|
||||
return this.$axios['post'](`/api/v1/tickets/tickets/open/?type=apply_application`, validValues)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,54 +7,17 @@
|
||||
:approve="handleApprove"
|
||||
:close="handleClose"
|
||||
:reject="handleReject"
|
||||
>
|
||||
<IBox v-if="hasActionPerm&&object.status !== 'closed'" class="box">
|
||||
<div slot="header" class="clearfix ibox-title">
|
||||
<i class="fa fa-edit" /> {{ $t('common.Actions') }}
|
||||
</div>
|
||||
<template>
|
||||
<el-form ref="requestForm" :model="requestForm" label-width="140px" label-position="left" class="assets">
|
||||
<el-form-item :label="$t('perms.PermName')" required>
|
||||
<el-input v-model="requestForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('tickets.Asset')" required>
|
||||
<Select2 v-model="requestForm.asset" v-bind="asset_select2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('tickets.SystemUser')" required>
|
||||
<Select2 v-model="requestForm.systemuser" v-bind="systemuser_select2" style="width: 50% !important" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateStart')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_start"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('common.dateExpired')" required>
|
||||
<el-date-picker
|
||||
v-model="requestForm.apply_date_expired"
|
||||
type="datetime"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('assets.Action')" required>
|
||||
<AssetPermissionFormActionField v-model="requestForm.actions" style="width: 30% !important" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</IBox>
|
||||
</GenericTicketDetail>
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { formatTime, getDateTimeStamp } from '@/utils/index'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
import { STATUS_MAP } from '../../const'
|
||||
import Select2 from '@/components/FormFields/Select2'
|
||||
import IBox from '@/components/IBox'
|
||||
import AssetPermissionFormActionField from '@/views/perms/AssetPermission/components/AssetPermissionFormActionField'
|
||||
import GenericTicketDetail from '@/views/tickets/components/GenericTicketDetail'
|
||||
export default {
|
||||
name: '',
|
||||
components: { GenericTicketDetail, IBox, Select2, AssetPermissionFormActionField },
|
||||
components: { GenericTicketDetail },
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
@@ -63,44 +26,13 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action],
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP['notified'] : STATUS_MAP[this.object.state],
|
||||
requestForm: {
|
||||
name: this.object.meta.approve_permission_name,
|
||||
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
|
||||
asset: this.object.meta.apply_assets,
|
||||
systemuser: this.object.meta.apply_system_users
|
||||
},
|
||||
comments: '',
|
||||
assets: [],
|
||||
asset_select2: {
|
||||
multiple: true,
|
||||
value: this.object.meta['recommend_assets'],
|
||||
ajax: {
|
||||
url: (function(object) {
|
||||
const oid = object.org_id === '' ? 'DEFAULT' : object.org_id
|
||||
return `/api/v1/assets/assets/?oid=${oid}&protocol__in=rdp,vnc,ssh,telnet`
|
||||
}(this.object)),
|
||||
transformOption: (item) => {
|
||||
return { label: item.hostname, value: item.id }
|
||||
}
|
||||
}
|
||||
},
|
||||
systemuser_select2: {
|
||||
multiple: true,
|
||||
value: this.object.meta['recommend_system_users'],
|
||||
ajax: {
|
||||
url: (function(object) {
|
||||
const oid = object.org_id === '' ? 'DEFAULT' : object.org_id
|
||||
return `/api/v1/assets/system-users/?oid=${oid}&protocol__in=rdp,vnc,ssh,telnet`
|
||||
}(this.object)),
|
||||
transformOption: (item) => {
|
||||
const username = item.username || '*'
|
||||
return { label: item.name + '(' + username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
assets: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -108,7 +40,7 @@ export default {
|
||||
return [
|
||||
{
|
||||
key: this.$t('tickets.status'),
|
||||
value: this.object.status,
|
||||
value: this.object.state,
|
||||
formatter: (item, val) => {
|
||||
return <el-tag type={this.statusMap.type} size='mini'> { this.statusMap.title }</el-tag>
|
||||
}
|
||||
@@ -121,14 +53,6 @@ export default {
|
||||
key: this.$t('tickets.user'),
|
||||
value: this.object['applicant_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignees'),
|
||||
value: this.object.assignees_display.join(', ')
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: (this.object['processor_display'] === 'No') ? '' : this.object.processor_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.OrgName'),
|
||||
value: this.object.org_name
|
||||
@@ -145,25 +69,17 @@ export default {
|
||||
},
|
||||
specialCardItems() {
|
||||
return [
|
||||
// {
|
||||
// key: this.$t('tickets.Assignee'),
|
||||
// value: this.object.assignee_display
|
||||
// },
|
||||
{
|
||||
key: this.$t('tickets.IP'),
|
||||
value: this.object.meta.apply_ip_group.toString()
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Hostname'),
|
||||
value: this.object.meta.apply_hostname_group.toString()
|
||||
key: this.$t('tickets.Asset'),
|
||||
value: this.object.meta.apply_assets_display
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta.apply_system_user_group.toString()
|
||||
value: this.object.meta.apply_system_users_display
|
||||
},
|
||||
{
|
||||
key: this.$t('assets.Action'),
|
||||
value: this.object.meta['apply_actions_display'].toString()
|
||||
value: this.object.meta['apply_actions_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
@@ -180,7 +96,7 @@ export default {
|
||||
return [
|
||||
{
|
||||
key: this.$t('tickets.PermissionName'),
|
||||
value: this.object.meta.approve_permission_name,
|
||||
value: this.object.meta.apply_permission_name,
|
||||
formatter: function(item, value) {
|
||||
const to = { name: 'AssetPermissionDetail', params: { id: vm.object.id }}
|
||||
return <router-link to={to}>{ value }</router-link>
|
||||
@@ -188,23 +104,23 @@ export default {
|
||||
},
|
||||
{
|
||||
key: this.$t('assets.Asset'),
|
||||
value: this.object.meta['approve_assets_display'].toString()
|
||||
value: this.object.meta['apply_assets_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.SystemUser'),
|
||||
value: this.object.meta['approve_system_users_display'].toString()
|
||||
value: this.object.meta['apply_system_users_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('assets.Action'),
|
||||
value: this.object.meta['approve_actions_display'].toString()
|
||||
value: this.object.meta['apply_actions_display']
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateStart'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_start)
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_start)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateExpired'),
|
||||
value: toSafeLocalDateStr(this.object.meta.approve_date_expired)
|
||||
value: toSafeLocalDateStr(this.object.meta.apply_date_expired)
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -227,14 +143,7 @@ export default {
|
||||
return this.$message.error(this.$tc('common.NeedAssetsAndSystemUserErrMsg'))
|
||||
} else {
|
||||
this.$axios.put(`/api/v1/tickets/tickets/${this.object.id}/approve/`, {
|
||||
meta: {
|
||||
approve_permission_name: this.requestForm.name,
|
||||
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
|
||||
}
|
||||
meta: {}
|
||||
}).then(() => {
|
||||
this.$message.success(this.$tc('common.updateSuccessMsg'))
|
||||
this.reloadPage()
|
||||
|
||||
@@ -16,7 +16,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ticket: { title: '', user_display: '', type_display: '', status: '', assignees_display: '', date_created: '' },
|
||||
ticket: { title: '', user_display: '', type_display: '', status: '', processor: '', date_created: '' },
|
||||
config: {
|
||||
activeMenu: 'TicketDetail',
|
||||
url: '',
|
||||
@@ -35,7 +35,6 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
getObjectName() {
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
import { DEFAULT_ORG_ID } from '@/utils/org'
|
||||
import Select2 from '@/components/FormFields/Select2'
|
||||
import AssetSelect from '@/components/AssetSelect'
|
||||
import { getDaysFuture } from '@/utils/common'
|
||||
import AssetPermissionFormActionField from '@/views/perms/AssetPermission/components/AssetPermissionFormActionField'
|
||||
export default {
|
||||
@@ -32,7 +32,7 @@ export default {
|
||||
type: 'apply_asset'
|
||||
},
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['title', 'type', 'org_id', 'assignees', 'comment']],
|
||||
[this.$t('common.Basic'), ['title', 'type', 'org_id', 'comment']],
|
||||
[this.$t('tickets.RequestPerm'), ['meta']]
|
||||
],
|
||||
fieldsMeta: {
|
||||
@@ -44,8 +44,8 @@ export default {
|
||||
},
|
||||
meta: {
|
||||
fields: [
|
||||
'apply_ip_group', 'apply_hostname_group', 'apply_system_user_group',
|
||||
'apply_actions', 'apply_date_start', 'apply_date_expired'
|
||||
'apply_assets', 'apply_system_users', 'apply_actions',
|
||||
'apply_date_start', 'apply_date_expired'
|
||||
],
|
||||
fieldsMeta: {
|
||||
apply_actions: {
|
||||
@@ -53,14 +53,28 @@ export default {
|
||||
component: AssetPermissionFormActionField,
|
||||
helpText: this.$t('common.actionsTips')
|
||||
},
|
||||
apply_ip_group: {
|
||||
helpText: this.$t('tickets.helpText.ips')
|
||||
apply_assets: {
|
||||
type: 'assetSelect',
|
||||
component: AssetSelect,
|
||||
label: this.$t('perms.Asset'),
|
||||
el: {
|
||||
value: []
|
||||
}
|
||||
},
|
||||
apply_hostname_group: {
|
||||
helpText: this.$t('tickets.helpText.fuzzySearch')
|
||||
},
|
||||
apply_system_user_group: {
|
||||
helpText: this.$t('tickets.helpText.fuzzySearch')
|
||||
apply_system_users: {
|
||||
type: 'systemUserSelect',
|
||||
component: Select2,
|
||||
label: '系统用户',
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/system-users/?protocol__in=rdp,ssh,vnc,telnet',
|
||||
transformOption: (item) => {
|
||||
const username = item.username || '*'
|
||||
return { label: item.name + '(' + username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -71,23 +85,6 @@ export default {
|
||||
options: this.$store.state.users.profile.user_all_orgs.map((item) => {
|
||||
return { label: item.name, value: item.id }
|
||||
})
|
||||
},
|
||||
on: {
|
||||
changeOptions: ([event], updateForm) => {
|
||||
this.fieldsMeta.assignees.el.ajax.url = `/api/v1/tickets/assignees/?org_id=${event[0].value}`
|
||||
}
|
||||
}
|
||||
},
|
||||
assignees: {
|
||||
el: {
|
||||
multiple: true,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: `/api/v1/tickets/assignees/?org_id=${DEFAULT_ORG_ID}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -105,15 +102,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
performSubmit(validValues) {
|
||||
if (validValues.meta.apply_ip_group) {
|
||||
validValues.meta.apply_ip_group = validValues.meta.apply_ip_group.split(',')
|
||||
}
|
||||
if (validValues.meta.apply_hostname_group) {
|
||||
validValues.meta.apply_hostname_group = validValues.meta.apply_hostname_group.split(',')
|
||||
}
|
||||
if (validValues.meta.apply_system_user_group) {
|
||||
validValues.meta.apply_system_user_group = validValues.meta.apply_system_user_group.split(',')
|
||||
}
|
||||
return this.$axios['post'](`/api/v1/tickets/tickets/open/?type=apply_asset`, validValues)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP[this.object.status] : STATUS_MAP[this.object.action],
|
||||
statusMap: this.object.status === 'open' ? STATUS_MAP['notified'] : STATUS_MAP[this.object.state],
|
||||
imageUrl: require('@/assets/img/admin.png'),
|
||||
form: {
|
||||
comments: ''
|
||||
@@ -48,11 +48,11 @@ export default {
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignees'),
|
||||
value: this.object.assignees_display
|
||||
value: this.object.process_map[this.object.approval_step - 1].assignees_display.join(',')
|
||||
},
|
||||
{
|
||||
key: this.$t('tickets.Assignee'),
|
||||
value: this.object.processor_display
|
||||
value: this.object.process_map[this.object.approval_step - 1].processor_display
|
||||
},
|
||||
{
|
||||
key: this.$t('common.dateCreated'),
|
||||
|
||||
@@ -80,10 +80,10 @@ export default {
|
||||
if (row.status === 'open') {
|
||||
return <el-tag type='success' size='mini'style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.Pending') }</el-tag>
|
||||
}
|
||||
switch (row.action) {
|
||||
case 'approve':
|
||||
switch (row.state) {
|
||||
case 'approved':
|
||||
return <el-tag type='primary' size='mini' style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.Approved') }</el-tag>
|
||||
case 'reject':
|
||||
case 'rejected':
|
||||
return <el-tag type='danger' size='mini' style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.Rejected') }</el-tag>
|
||||
default :
|
||||
return <el-tag type='info' size='mini' style='align-items:center; display: flex; justify-content:center;'> { this.$t('tickets.Closed') }</el-tag>
|
||||
|
||||
@@ -103,7 +103,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
hasActionPerm() {
|
||||
return this.object.assignees.indexOf(this.$store.state.users.profile.id) !== -1
|
||||
return this.object.process_map[this.object.approval_step - 1].assignees.indexOf(this.$store.state.users.profile.id) !== -1
|
||||
},
|
||||
isSelfTicket() {
|
||||
return this.object.applicant === this.$store.state.users.profile.id
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<el-col :span="17">
|
||||
<Details :detail-card-items="detailCardItems" :title="$t('common.BasicInfo')" />
|
||||
<Details v-if="specialCardItems.length > 0" :detail-card-items="specialCardItems" :title="$t('common.ApplyInfo')" />
|
||||
<Details v-if="object.action === 'approve' && assignedCardItems.length > 0" :detail-card-items="assignedCardItems" :title="$t('tickets.AssignedInfo')" />
|
||||
<Details v-if="object.state === 'approved' && assignedCardItems.length > 0" :detail-card-items="assignedCardItems" :title="$t('tickets.AssignedInfo')" />
|
||||
<slot id="MoreDetails" />
|
||||
<Comments :object="object" v-bind="$attrs" />
|
||||
</el-col>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<IBox>
|
||||
<div style="height: 350px;">
|
||||
<div style="height: 660px;">
|
||||
<el-steps direction="vertical" :active="ticketSteps">
|
||||
<el-step
|
||||
:title="`${this.$t('tickets.OpenTicket')}:${object.type_display}`"
|
||||
@@ -12,15 +12,27 @@
|
||||
</div>
|
||||
</el-step>
|
||||
<el-step
|
||||
:title="`${this.$t('tickets.HandleTicket')}`"
|
||||
:description="`${this.$t('tickets.Assignees')}:${object.assignees_display}`"
|
||||
/>
|
||||
v-for="(item, i) in process"
|
||||
:key="i"
|
||||
:title="`${thisCopy.$t('tickets.HandleTicket')}`"
|
||||
>
|
||||
<div slot="description">
|
||||
<el-tag :type="`${thisCopy.statusMap[item.state].type}`"> {{ `${thisCopy.statusMap[item.state].title}` }} </el-tag>
|
||||
</div>
|
||||
<div v-if="item.state==='closed'" slot="description" style="color: blue">
|
||||
<div>{{ `${thisCopy.$t('tickets.Assignee')}:${object.applicant_display}` }}</div>
|
||||
<div>{{ `${thisCopy.$t('common.dateFinished')}: ${toSafeLocalDateStr(item.approval_date)}` }}</div>
|
||||
</div>
|
||||
<div v-if="item.state!=='notified' && item.state!=='closed'" slot="description" style="color: blue">
|
||||
<div>{{ `${thisCopy.$t('tickets.Assignee')}:${item.processor_display}` }}</div>
|
||||
<div>{{ `${thisCopy.$t('common.dateFinished')}: ${toSafeLocalDateStr(item.approval_date)}` }}</div>
|
||||
</div>
|
||||
<div slot="description">{{ `${thisCopy.$t('tickets.Assignees')}:${item.assignees_display}` }}</div>
|
||||
</el-step>
|
||||
<el-step
|
||||
:title="`${this.$t('tickets.FinishedTicket')}`"
|
||||
:description="ticketSteps===STATUS.close ? `${this.$t('tickets.Assignee')}:${object.assignee_display}`:'' "
|
||||
>
|
||||
<div v-if="ticketSteps===STATUS.close" slot="description">
|
||||
<div>{{ `${this.$t('tickets.Assignee')}:${object.processor_display}` }}</div>
|
||||
<div v-if="thisCopy.isFinish" slot="description">
|
||||
<div>{{ `${this.$t('common.dateFinished')}: ${toSafeLocalDateStr(object.date_updated)}` }}</div>
|
||||
</div>
|
||||
</el-step>
|
||||
@@ -33,6 +45,7 @@
|
||||
import { formatTime, getDateTimeStamp } from '@/utils/index'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
import IBox from '@/components/IBox'
|
||||
import { STATE_MAP } from '../const'
|
||||
export default {
|
||||
name: 'Steps',
|
||||
components: { IBox },
|
||||
@@ -44,12 +57,30 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
STATUS: { open: 2, close: 3 }
|
||||
STATUS: { open: 2, close: 3 },
|
||||
process: this.object.process_map,
|
||||
thisCopy: this,
|
||||
statusMap: STATE_MAP,
|
||||
isFinish: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ticketSteps() {
|
||||
return this.object.status === 'open' ? this.STATUS.open : this.STATUS.close
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var countApprove = 0
|
||||
this.process.forEach(item => {
|
||||
// eslint-disable-next-line space-before-blocks
|
||||
if (item.state === 'approved'){
|
||||
countApprove += 1
|
||||
}
|
||||
})
|
||||
if (countApprove === process.length) {
|
||||
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
||||
this.isFinish = true
|
||||
return process.length + 2
|
||||
} else {
|
||||
return this.STATUS.open + countApprove
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
|
||||
export const OPEN = 'open'
|
||||
export const APPROVE = 'approve'
|
||||
export const REJECT = 'reject'
|
||||
export const OTHER = ''
|
||||
export const OPEN = 'notified'
|
||||
export const APPROVE = 'approved'
|
||||
export const REJECT = 'rejected'
|
||||
export const CLOSED = 'closed'
|
||||
|
||||
export const STATUS_MAP = {
|
||||
[OPEN]: {
|
||||
@@ -15,7 +15,22 @@ export const STATUS_MAP = {
|
||||
[REJECT]: {
|
||||
type: 'danger', title: i18n.t('tickets.Rejected')
|
||||
},
|
||||
[OTHER]: {
|
||||
[CLOSED]: {
|
||||
type: 'info', title: i18n.t('tickets.Closed')
|
||||
}
|
||||
}
|
||||
|
||||
export const STATE_MAP = {
|
||||
[OPEN]: {
|
||||
type: 'success', title: i18n.t('tickets.Pending')
|
||||
},
|
||||
[APPROVE]: {
|
||||
type: 'primary', title: i18n.t('tickets.Approved')
|
||||
},
|
||||
[REJECT]: {
|
||||
type: 'danger', title: i18n.t('tickets.Rejected')
|
||||
},
|
||||
[CLOSED]: {
|
||||
type: 'warning', title: i18n.t('tickets.StateClosed')
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user