<template>
|
<vol-box :footer="false" v-model="model" :height="height" :width="width" :padding="0" :lazy="true" title="审核">
|
|
<div class="audit-model-content" :style="{ height: height - 100 + 'px' }">
|
<el-descriptions class="desc-top" :column="3" size="default" :border="true">
|
<el-descriptions-item v-for="(item, index) in formData" :key="index">
|
<template #label>
|
<div class="cell-item">
|
{{ item.name }}
|
</div>
|
</template>
|
{{ item.value }}
|
</el-descriptions-item>
|
</el-descriptions>
|
<el-radio-group v-show="hasFlow" style="padding-left: 15px;" v-model="activeName" class="ml-4">
|
<el-radio label="audit" size="large">审核</el-radio>
|
<el-radio label="log" size="large">审核记录</el-radio>
|
</el-radio-group>
|
<div v-show="activeName == 'audit' || !hasFlow" class="audit-content">
|
<div class="fx-left" v-if="hasFlow">
|
<div class="v-steps">
|
<div v-for="(item, index) in workFlowSteps" :key="index">
|
<div class="step-item" :class="{'step-item-ad':item.auditId||item.stepAttrType=='start'}" v-if="item.stepAttrType == 'start'">
|
<div class="left-item">
|
<div>流程开始</div>
|
<div class="left-date">{{ item.createDate }}</div>
|
</div>
|
<div class="right-item">
|
<div class="step-line"></div>
|
<i class="step-circle"></i>
|
<div class="step-title">
|
{{ item.stepName }}
|
</div>
|
<div class="step-text">发起人:{{ item.creator }}</div>
|
</div>
|
</div>
|
<div class="step-item" v-else-if="item.stepAttrType == 'end'">
|
<div class="left-item">
|
<div>流程结束</div>
|
</div>
|
<div class="right-item">
|
<div class="step-line"></div>
|
<i class="step-circle"></i>
|
<div class="step-title">
|
{{ item.stepName }}
|
</div>
|
</div>
|
</div>
|
<div v-else :class="{ 'step-current': item.isCurrent }" class="step-item">
|
<div class="left-item">
|
<div>审批时间</div>
|
<div class="left-date">{{ item.auditDate || '待审批' }}</div>
|
</div>
|
<div class="right-item">
|
<div class="step-line"></div>
|
<i class="step-circle"></i>
|
<div class="step-title">
|
{{ item.stepName }}
|
</div>
|
<div class="step-text">审批人:{{ item.auditor }}</div>
|
<div class="step-text">
|
状 态: {{ getAuditStatus(item.auditStatus) }}
|
</div>
|
<div class="step-text">备 注: {{ item.remark || '-' }}</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="fx-right" :style="{ width: !hasFlow ? '100%' : '400px' }" v-if="isCurrentUser || !hasFlow">
|
|
<div v-if="!hasFlow">
|
<el-alert :title="'当前选中【' + rowLen + '】条记录待审核..'" type="success" :closable="false" />
|
</div>
|
<div class="rd">
|
<span>审批:</span>
|
<el-radio-group style="margin-left:15px" v-model="auditParam.value">
|
<el-radio v-for="item in auditParam.data" :key="item.value" :label="item.value">
|
<span>{{ item.text }}</span>
|
</el-radio>
|
</el-radio-group>
|
</div>
|
<el-input style="padding-top: 10px;" v-model="auditParam.reason" type="textarea"
|
:autosize="{ minRows: 4, maxRows: 10 }" placeholder="请输入备注..."></el-input>
|
<div class="btn">
|
<el-button type="primary" @click="auditClick" icon="Check">审批</el-button>
|
</div>
|
</div>
|
</div>
|
<div v-show="activeName == 'log'">
|
<vol-table :tableData="tableData" :columns="columns" :height="height - 250" :pagination-hide="true"
|
:load-key="false" :text-inline="false" :ck="false"></vol-table>
|
</div>
|
</div>
|
</vol-box>
|
</template>
|
<script>
|
import VolTable from '@/components/basic/VolTable.vue';
|
import VolBox from '@/components/basic/VolBox.vue';
|
import http from '@/../src/api/http.js';
|
import { defineComponent, ref, reactive, getCurrentInstance } from 'vue';
|
export default defineComponent({
|
components: {
|
VolTable,
|
VolBox
|
},
|
props: {
|
option: { //生成vue文件的table参数
|
type: Object,
|
default: {
|
key: '',
|
cnName: '',
|
name: '',
|
url: ""
|
}
|
}
|
},
|
setup(props, { emit }) {
|
const height = ref(500);
|
const width = ref(820);
|
const model = ref(false)
|
const workFlowSteps = reactive([]);
|
|
const hasFlow = ref(false)
|
const formData = reactive([]);
|
|
const auditParam = reactive({
|
//审核对象
|
rows: 0, //当前选中审核的行数
|
model: false, //审核弹出框
|
value: -1, //审核结果
|
reason: '', //审核原因
|
//审核选项(main.js里面可以添加其他选项)
|
data: []
|
})
|
const { proxy } = getCurrentInstance();
|
auditParam.data = proxy.$global.audit.data;
|
const tableData = reactive([]);
|
const columns = reactive([
|
{ title: '节点', field: 'stepName', width: 100 },
|
{ title: '审批人', field: 'auditor', width: 80 },
|
{ title: '审批结果', field: 'auditStatus', width: 70, bind: { data: [] } },
|
{ title: '审批时间', field: 'auditDate', width: 145 },
|
{ title: '备注', field: 'remark', width: 120 }
|
]);
|
|
const isCurrentUser = ref(null);
|
const activeName = ref('audit')
|
|
const auditDic = reactive([]);
|
const getAuditStatus = (key) => {
|
return (auditDic.find(x => { return x.key === key + '' }) || { value: key }).value;
|
}
|
const rowLen = ref(0)
|
let currentRows = []
|
const getAuditInfo = (option) => {
|
const table = option.table; //props.option.url.replaceAll('/', '');
|
const url = `api/Sys_WorkFlow/getSteps?tableName=${table}`
|
// let ids = currentRows.map(x => { return x[props.option.key] });
|
let ids = currentRows.map(x => { return x[option.key] });
|
// ['498043c1-fbd0-4a35-a870-523823912a9b']
|
http.post(url, ids, true).then(result => {
|
if (!result.status) {
|
proxy.$message.error(result.message);
|
return;
|
}
|
|
hasFlow.value = !!(result.list || []).length;
|
if (!hasFlow.value) {
|
|
let auditStatus = Object.keys(currentRows[0]).find(x => { return x.toLowerCase() === 'auditstatus' });
|
|
let checkStatus = currentRows.every((x) => {
|
return proxy.$global.audit.status.some(c => { return c === x[auditStatus] || !x[auditStatus] })
|
});
|
if (!checkStatus) {
|
proxy.$message.error('只能选择待审批或审核中的数据');
|
return;
|
}
|
rowLen.value = currentRows.length;
|
model.value = true;
|
width.value = 430;
|
height.value = 330;
|
isCurrentUser.value = true;
|
//没有审批流程的数据只显示
|
return;
|
}
|
model.value = true;
|
height.value = document.body.clientHeight * 0.95;
|
width.value = 820;
|
if (!auditDic.length) {
|
auditDic.push(...(result.auditDic || []))
|
columns.forEach(item => {
|
if (item.field == 'auditStatus') {
|
item.bind.data = auditDic;
|
}
|
})
|
}
|
isCurrentUser.value = result.list.some(x => { return x.isCurrentUser })
|
workFlowSteps.length = 0;
|
workFlowSteps.push(...result.list);
|
tableData.length = 0;
|
tableData.push(...result.log)
|
formData.length = 0;
|
formData.push(...(result.form || []))
|
})
|
}
|
//
|
|
const auditClick = () => {
|
if (auditParam.value == -1) {
|
proxy.$message.error('请选择审批项');
|
return;
|
}
|
|
if (!isFlow.value) {
|
emit("auditClick", auditParam, currentRows, (result) => {
|
if (result.status) {
|
model.value = false;
|
tableData.length = 0;
|
}
|
});
|
return;
|
}
|
//我的流程中点击审批
|
//保存审核
|
let keys = currentRows.map(x => { return x[currentOption.key] });
|
let url = `api/${currentOption.table}/audit?auditReason=${auditParam.reason}&auditStatus=${auditParam.value}`
|
http.post(url, keys, '审核中....').then((x) => {
|
if (!x.status) {
|
proxy.$message.error(x.message);
|
return;
|
}
|
model.value = false;
|
proxy.$parent.search()
|
proxy.$message.success(x.message)
|
});
|
}
|
const isFlow = ref(false);
|
let currentOption = {};
|
const open = (rows, flow) => {
|
isFlow.value = !!flow;
|
currentRows = rows;
|
activeName.value = 'audit'
|
auditParam.reason = '';
|
auditParam.value = -1;
|
|
if (flow) {
|
currentOption = {
|
table: rows[0].WorkTable,
|
key: "WorkTableKey"// rows[0].WorkTableKey
|
}
|
} else {
|
currentOption = {
|
table: props.option.url.replaceAll('/', ''),
|
key: props.option.key
|
}
|
}
|
getAuditInfo(currentOption);
|
|
}
|
|
return {
|
columns,
|
height,
|
width,
|
model,
|
workFlowSteps,
|
getAuditInfo,
|
getAuditStatus,
|
activeName,
|
reactive,
|
tableData,
|
auditParam,
|
auditClick,
|
open,
|
isCurrentUser,
|
hasFlow,
|
rowLen,
|
formData,
|
isFlow
|
}
|
}
|
});
|
</script>
|
|
<style lang="less" scoped>
|
.audit-model-content {
|
padding: 10px;
|
}
|
|
.step-item {
|
background: #fff;
|
display: flex;
|
}
|
|
.left-item {
|
min-width: 180px;
|
text-align: right;
|
padding-right: 25px;
|
padding-top: 8px;
|
|
.left-date {
|
font-size: 13px;
|
padding-top: 7px;
|
color: #6c6c6c;
|
}
|
}
|
|
.right-item {
|
cursor: pointer;
|
position: relative;
|
border-bottom: 1px solid #f3f3f3;
|
padding: 5px 0 5px 5px;
|
}
|
|
.left-item,
|
.right-item {
|
padding-bottom: 10px;
|
}
|
|
.right-item:last-child {
|
border-bottom: 0;
|
}
|
|
.step-line {
|
top: 16px;
|
left: -10px;
|
width: 1px;
|
height: 100%;
|
position: absolute;
|
background-color: #ebedf0;
|
}
|
|
.step-circle {
|
position: absolute;
|
top: 17px;
|
left: -9px;
|
z-index: 2;
|
font-size: 12px;
|
line-height: 1;
|
transform: translate(-50%, -50%);
|
width: 7px;
|
height: 7px;
|
background-color: #a1a1a1;
|
border-radius: 50%;
|
}
|
|
.right-item::before {
|
content: '';
|
}
|
|
.step-content {
|
padding-top: 2px;
|
font-size: 14px;
|
color: #828282;
|
line-height: 1.5;
|
}
|
|
.step-title {
|
font-weight: bold;
|
padding-top: 3px;
|
}
|
|
.step-text {
|
font-size: 13px;
|
color: #999999;
|
padding-top: 6px;
|
}
|
|
.step-current {
|
* {
|
color: #2f95ff !important;
|
}
|
|
.step-circle {
|
background: #2f95ff !important;
|
}
|
|
// border-radius: 5px;
|
// border: 1px solid #d6eaff;
|
font-size: 13px;
|
padding-top: 6px;
|
// background-color: #eff7ffd9;
|
color: black;
|
}
|
|
.audit-content {
|
// background: #f9f9f9;
|
padding: 10px;
|
border-radius: 4px;
|
display: flex;
|
|
.fx-left {
|
flex: 1;
|
width: 0;
|
|
.rd {
|
display: flex;
|
align-items: baseline;
|
}
|
}
|
|
.fx-right {
|
// width: 400px;
|
|
.btn {
|
margin-top: 10px;
|
text-align: center;
|
}
|
}
|
|
}
|
|
.cell-item {
|
font-weight: 500;
|
}
|
|
.desc-top {
|
padding: 5px 10px 0 10px;
|
}
|
.step-item-ad{
|
*{
|
color: #9f9898 !important;
|
}
|
}
|
</style>
|