Files
laws_chery_client/src/components/ProcessDetailList.vue
T
2024-06-11 15:39:01 +08:00

421 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="page-box">
<div class="personnel-info">
<slot name="personnelInfo"></slot>
</div>
<div class="approval-list">
<!--查询区域-->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
<a-col :md="8" :sm="8">
<!--状态-->
<a-form-item :label="$t('status')" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-dict-select-tag
:placeholder="$t('pleaseEnter') + $t('status')"
dict-code="prc_node_status"
v-model="queryParam.finishFlag"></j-dict-select-tag>
</a-form-item>
</a-col>
<div style="float: right;overflow: hidden;margin-right: 11px" class="table-page-search-submitButtons">
<a-button class="box-button" type="primary" icon="search" @click="searchQuery">{{ $t('query') }}</a-button>
<a-button class="box-button" icon="reload" style="margin-left: 8px" @click="searchReset">{{ $t('reset') }}</a-button>
</div>
</a-row>
</a-form>
</div>
<div class="table-page-oper-submitButtons">
<!--催办-->
<a-button type="primary" @click="handleUrge" icon="bell" v-if="showUrgeButton">
{{ $t('workCenter.processDetail.urgeHandle') }}
</a-button>
<!--流程图-->
<!--<a-button type="primary" @click="viewFlowChart" icon="apartment" ghost>{{ $t('workCenter.processDetail.flowChart') }}</a-button>-->
</div>
<div>
<!-- rowKey加了id是因为强制撤回的记录没有taskId -->
<j-table
:columns="columns"
:dataSource="dataSource"
:can-drag="true"
:loading="loading"
:rowKey="record => {return record.id + ',' + (record.taskId || '')}"
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
:pagination="ipagination"
:scroll="{x: '100%', y: yScrollHeight}"
@change="handleTableChange">
<!-- 耗时 -->
<!--<template v-slot:timeConsuming="{text, record}">-->
<!-- <a-tooltip overlay-class-name="tooltip-style">-->
<!-- <template slot="title">{{ record.endTime && record.createTime ? computedTimeConsuming(record) : global.emptyLine }}</template>-->
<!-- <div class="table-text">-->
<!-- {{ record.endTime && record.createTime ? computedTimeConsuming(record) : global.emptyLine }}-->
<!-- </div>-->
<!-- </a-tooltip>-->
<!--</template>-->
<!--审批意见-->
<template v-slot:approvalOpinion="{text, record}">
<a-tooltip overlay-class-name="tooltip-style">
<template slot="title">{{ text || text === 0 ? record.commitFlag_dictText : global.emptyLine }}</template>
<div class="table-text" :class="{'agree-color': record.commitFlag + '' === '1', 'reject-color': record.commitFlag + '' === '2'}">
{{ text || text === 0 ? record.commitFlag_dictText : global.emptyLine }}
</div>
</a-tooltip>
</template>
<!--附件-->
<template v-slot:file="{text, record}">
<a v-if="text" @click="fileLook(record)">{{ $t('view') }}</a>
<div v-else class="table-text">{{ global.emptyLine }}</div>
<!--<a-tooltip overlay-class-name="tooltip-style">-->
<!-- <template slot="title">{{ text || text === 0 ? text : global.emptyLine }}</template>-->
<!-- <div class="table-text can-click-table-text" v-if="text || text === 0" @click="handlePreview(record)">{{ text }}</div>-->
<!-- <div v-else class="table-text">{{ global.emptyLine }}</div>-->
<!--</a-tooltip>-->
</template>
</j-table>
</div>
<div id="images">
<div class="image" v-viewer="{movable: false}">
<img v-show="image" :src="imageUrl" alt="">
</div>
</div>
</div>
<flow-chart-modal ref="flowChartModal" />
<upload-file ref="uploadFile" disabled></upload-file>
</div>
</template>
<script>
import { JeroListMixin } from '../mixins/JeroListMixin.js'
import JTable from './jero/JTable.vue'
import Vue from 'vue'
import { ACCESS_TOKEN } from '../store/mutation-types.js'
import { downloadFile, getFileAccessHttpUrl, getAction } from '../api/manage.js'
import { previewPdf } from '../utils/previewPdf.js'
import FlowChartModal from './FlowChartModal.vue'
import UploadFile from './UploadFile'
import { filterObj } from '../utils/util'
import { kkFilePreview } from '../utils/kkFilePreview'
import { urgeProcessNode } from '../api/workCenter'
// 支持预览的文件后缀
const CAN_PREVIEW_FILE_SUFFIX = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx']
const FILE_TYPE_IMGS = ['jpg', 'jpeg', 'png', 'raw']
const FILE_TYPE_PDF = 'pdf'
export default {
name: 'ProcessDetailList',
components: { UploadFile, JTable, FlowChartModal },
mixins: [JeroListMixin],
props: {
// 需要有list属性,用于混入里的接口获取
url: {
type: Object,
required: false,
default: () => {
return {
list: '/workCenter/getApprovalRecordList'
}
}
},
// 催办按钮的权限
urgePermissionFlag: {
type: String,
required: false,
default: null
},
// 流程图按钮的权限
flowChartPermissionFlag: {
type: String,
required: false,
default: null
},
// 流程key
processKey: {
type: String,
required: false,
default: null
},
// 是否展示催办按钮
showUrgeButton: {
type: Boolean,
required: false,
default: false
}
},
computed: {
yScrollHeight () {
/**
* 前几个使用变量是为了配合iframe嵌套,算出页面显示范围的高度
* 48px:分页器的高度
* 48pxa-card的padding(上24+下24
* 54px:表头行的高度
*/
return `calc(100vh - ${this.defaultHeight['user-info-height']} - ${this.defaultHeight['breadcrumb-height']} - ${this.defaultHeight.oneLineSearchHeight} - ${this.defaultHeight.oneLineOperationHeight} - 48px - 48px - 54px - 56px)`
}
},
data () {
return {
labelCol: {
span: 1
},
wrapperCol: {
span: 14
},
columns: [
// 任务节点
{
dataIndex: 'taskName',
title: this.$t('workCenter.processDetail.taskNode'),
width: 150
},
// 任务受理人
{
dataIndex: 'taskAcceptor',
title: this.$t('workCenter.processDetail.taskHandler'),
width: 120
},
// 创建时间
{
dataIndex: 'createTime',
title: this.$t('createTime'),
width: 150
},
// 完成时间
{
dataIndex: 'endTime',
title: this.$t('workCenter.processDetail.completionTime'),
width: 150
},
// 耗时
{
title: this.$t('workCenter.processDetail.timeConsuming'),
width: 150,
dataIndex: 'overTime',
scopedSlots: { customRender: 'text' }
},
// 审批意见
{
dataIndex: 'commitFlag',
title: this.$t('workCenter.processDetail.approvalOpinion'),
width: 100,
scopedSlots: { customRender: 'approvalOpinion' }
},
// 意见内容
{
dataIndex: 'commitText',
title: this.$t('workCenter.processDetail.opinionContent'),
width: 120
},
// 附件
{
dataIndex: 'commitFile',
title: this.$t('businessSupport.questionAnswer.attach'),
width: 160,
scopedSlots: { customRender: 'file' }
},
// 状态
{
dataIndex: 'finishFlag_dictText',
title: this.$t('status'),
width: 100
}
],
image: false,
imageUrl: null,
/* 排序参数 */
// 后端需要去掉
isorter: null
}
},
methods: {
loadData (arg) {
if (!this.url.list) {
this.$message.warning('请设置url.list属性!')
return
}
if (arg === 1) {
this.ipagination.current = 1
}
const params = this.getQueryParams()// 查询条件
// 流程监控进详情,并且是已撤回的流程不查状态为进行中的任务
if (this.$route.query.source === 'monitorList' && this.$route.query.prcStatus === '3') {
params.finishFlagSearch = '2,3,4'
}
if (this.$route.query.processInstanceId) {
params.processInstanceId = this.$route.query.processInstanceId
} else {
// 没有流程实例id,那就是新增,不用查
return
}
this.loading = true
getAction(this.url.list, params).then((res) => {
if (res.success) {
// update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
this.dataSource = res.result.records || res.result
if (res.result.total) {
this.ipagination.total = res.result.total
} else {
this.ipagination.total = 0
}
// update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
getQueryParams () {
// 获取查询条件
const sqp = {}
if (this.superQueryParams) {
sqp.superQueryParams = encodeURI(this.superQueryParams)
sqp.superQueryMatchType = this.superQueryMatchType
}
const param = Object.assign(sqp, this.queryParam, this.isorter, this.filters)
param.field = this.getQueryField()
param.pageNo = this.ipagination.current
param.pageSize = this.ipagination.pageSize
return filterObj(param)
},
// 计算耗时
computedTimeConsuming (record) {
// 结束时间和创建时间
const endTime = new Date(record.endTime)
const createTime = new Date(record.createTime)
// 计算时间差 转化为秒数
const time = parseInt((endTime.getTime() - createTime.getTime()) / 1000)
// 总秒数转化为对应的天数
const days = parseInt(time / (24 * 60 * 60))
// 计算小时
const hours = parseInt((time % (24 * 60 * 60)) / (60 * 60))
// 计算分钟
const minutes = parseInt((time % (60 * 60)) / 60)
// 计算秒
const seconds = time % 60
return (days ? days + '天 ' : '') + (hours ? hours + '小时 ' : '') +
(minutes ? minutes + '分钟 ' : '') + (seconds ? seconds + '秒' : '')
},
// 附件列的查看点击
fileLook (record) {
this.$refs.uploadFile.open(record.commitFile)
},
/**
* 催办
*/
handleUrge () {
if (!this.selectedRowKeys || this.selectedRowKeys.length === 0) {
this.$message.warning(this.$t('selectAtLeastOne'))
return
}
this.loading = true
const taskIds = this.selectedRowKeys.map(item => {
return item.split(',')[1]
})
urgeProcessNode({ taskId: taskIds.join(',') }).then(res => {
if (res.success) {
this.$message.success(res.message)
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.loading = false
})
},
/**
* 跳转流程图页面
*/
viewFlowChart () {
if (!this.processKey) {
return
}
this.$refs.flowChartModal.processKey = this.processKey
this.$refs.flowChartModal.open()
},
handlePreview (file) {
if (!file || !file.url) {
return
}
// 截取文件后缀名
const fileSuffix = file.fileName ? file.fileName.split('.')[file.fileName.split('.').length - 1] : ''
const canPreview = CAN_PREVIEW_FILE_SUFFIX.some(tt => fileSuffix.toLowerCase() === tt)
// 判断是否为可预览格式的文件
if (!canPreview) {
this.$message.loading('该文件类型不支持预览,正在为您准备下载...').then(() => {
this.handleDownload(file)
})
return
}
const fileFullUrl = `${window._CONFIG.domianWebSocketURL}/sys/common/view/${file.id}?at=${Vue.ls.get(ACCESS_TOKEN)}&fullfilename=${file.fileName}`
// 图片预览,使用自己添加的组件
if (canPreview && FILE_TYPE_IMGS.includes(fileSuffix.toLowerCase())) {
this.imageUrl = getFileAccessHttpUrl(file.id)
// 获取viewer实例
const viewer = this.$el.querySelector('.image').$viewer
// 调用show方法进行显示预览图
viewer.show()
// this.$refs.imagePreviewModal.open(file)
return
}
// pdf预览
if (canPreview && FILE_TYPE_PDF.includes(fileSuffix.toLowerCase())) {
const url = previewPdf(file.id)
window.open(url)
return
}
// 其余可预览文件仍使用KKFile进行预览
kkFilePreview(fileFullUrl)
}
}
}
</script>
<style scoped lang="less">
.page-box {
height: 100%;
display: flex;
}
.personnel-info {
height: 100%;
width: 400px;
padding: 32px;
overflow: auto;
border-right: 1px solid #E5E6EB;
}
.approval-list {
height: 100%;
flex: 1;
width: 0;
overflow: auto;
padding: 32px 32px 0;
}
.agree-color {
color: #229B1F;
}
// 这个地方的颜色不用primary-color是因为拒绝永远是红色的
.reject-color {
color: #D52C26;
}
.table-page-oper-submitButtons {
.ant-btn {
margin-bottom: 20px;
}
}
/deep/ .ant-form-item-label {
min-width: 90px !important;
}
</style>