feat: 工单管理 (#963)

* feat: 工单多级审批

* fix: action bug

Co-authored-by: feng626 <1304903146@qq.com>
This commit is contained in:
fit2bot
2021-08-25 19:00:21 +08:00
committed by GitHub
parent d05d3f3fa3
commit ea9316f0a0
12 changed files with 175 additions and 287 deletions

View File

@@ -937,6 +937,7 @@
"Approved": "已同意",
"Rejected": "已拒绝",
"Closed": "已完成",
"StateClosed": "已关闭",
"helpText": {
"ips": "请输入逗号分割的IP地址组",
"fuzzySearch": "支持模糊搜索",

View File

@@ -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'))

View File

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

View File

@@ -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()

View File

@@ -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() {

View File

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

View File

@@ -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'),

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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: {

View File

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