audit.vue 6.04 KB
<template>
	<view class="page">
		<view class="fixed">
			<view class="tabs" :class="[`${tab === 'base' ? 'bg1' : 'bg2'}`]">
				<view :class="['tab', { active: tab === 'base' }]" @click="tab = 'base'">基础信息</view>
				<view :class="['tab', { active: tab === 'flow' }]" @click="tab = 'flow'">流程</view>
			</view>
		</view>
		<view class="body">
			<view v-if="tab === 'base'">
				<component :is="componentName" :id="auditCtx.businessId" ref="basicRef" />
			</view>
			<view v-else>
				<FlowTimeline :nodeList="nodeList" :isEnd="isEnd" />
			</view>
		</view>
		<view class="footer">
			<button v-if="extraBtnText" class="btn extra" @click="onExtra">{{ extraBtnText }}</button>
			<button class="btn reject" @click="onReject">驳回</button>
			<button class="btn pass" type="primary" @click="onPass">通过</button>
		</view>

		<uni-popup ref="approvePopup" type="center" :mask-click="false">
			<view class="action-modal">
				<view class="action-modal_header">{{ approveType === 'PASS' ? '通过' : '驳回' }}</view>
				<view class="action-modal_body">
					<text class="tip">{{ approveType === 'PASS' ? '您将通过该信息的审核' : '您将驳回该信息的审核' }}</text>
					<uni-easyinput v-model="approveComment"
						:placeholder="approveType === 'PASS' ? '请输入通过原因' : '请输入驳回原因'" />
				</view>
				<view class="action-modal_footer">
					<button class="btn cancel" @click="cancelApprove">取消</button>
					<button class="btn confirm" type="primary" @click="confirmApprove">{{ approveType === 'PASS' ? '通过'
						: '驳回' }}</button>
				</view>
			</view>
		</uni-popup>
	</view>
</template>
<script>
import FlowTimeline from '@/components/flow-timeline/index.vue'
import { getSysFlowComponentPath } from '@/utils/flow-components.js'
import { getFlowLinkByInstanceIdApi } from '@/api/flow.js'
export default {
	components: {
		FlowTimeline
	},
	data() {
		return {
			tab: 'base',
			auditCtx: {
				taskId: '',
				instanceId: '',
				businessId: '',
				bizFlag: ''
			},
			isEnd: false, // 流程是否结束
			nodeList: [],
			extraBtnText: '客户信息',
			approveType: 'PASS',
			approveComment: ''
		}
	},
	computed: {
		componentName() {
			const name = getSysFlowComponentPath(this.auditCtx.bizFlag || '')
			return name || ''
		}
	},
	onLoad() {
		const CACHE_KEY = 'FLOW_AUDIT_CACHE'
		const cache = uni.getStorageSync(CACHE_KEY) || {};
		console.log('审核__cache', cache)
		this.auditCtx = cache;
		if (this.auditCtx && this.auditCtx.instanceId) {
			this.loadFlowLinkByInstanceId(this.auditCtx.instanceId)
		}
	},
	methods: {
		loadFlowLinkByInstanceId(instanceId) {
			getFlowLinkByInstanceIdApi({ instanceId }).then(res => {
				console.log('审核__loadFlowLinkByInstanceId', res)
				const _data = res && res.data ? res.data : {};
				this.nodeList = _data.nodeList || [];
				this.isEnd = _data.end || false;
			}).catch(() => { })
		},
		getPayload() {
			const ref = this.$refs.basicRef
			const vals = ref && typeof ref.getFormValues === 'function' ? ref.getFormValues() : {}
			return {
				bizFlag: this.auditCtx.bizFlag,
				...vals
			}
		},
		onReject() {
			this.approveType = 'REFUSE'
			this.approveComment = ''
			this.$refs.approvePopup.open()
		},
		onPass() {
			this.approveType = 'PASS'
			this.approveComment = ''
			this.$refs.approvePopup.open()
		},
		onExtra() {
			const payload = this.getPayload()
			uni.showToast({
				title: this.extraBtnText,
				icon: 'none'
			})
		},
		cancelApprove() {
			this.$refs.approvePopup.close()
		},
		confirmApprove() {
			const payload = {
				...this.getPayload(),
				approveType: this.approveType,
				approveComment: this.approveComment
			}
			this.$refs.approvePopup.close()
			uni.showToast({
				title: this.approveType === 'PASS' ? '已通过' : '已驳回',
				icon: 'none'
			})
		}
	}
}
</script>
<style lang="scss" scoped>
.page {
	display: flex;
	flex-direction: column;
	height: 100vh
}

.fixed {
	position: fixed;
	top: 96rpx;
	left: 0;
	right: 0;
	z-index: 2;

	.tabs {
		display: flex;
		align-items: center;
		height: 96rpx;

		&.bg1 {
			background-image: url('/static/images/flow/tab_1_icon.png');
			background-repeat: no-repeat;
			background-position: right center;
			background-size: cover;
		}

		&.bg2 {
			background-image: url('/static/images/flow/tab_2_icon.png');
			background-repeat: no-repeat;
			background-position: right center;
			background-size: cover;
		}

		.tab {
			width: 50%;
			height: 96rpx;
			line-height: 96rpx;
			text-align: center;
			font-weight: 600;
			color: rgba(0, 0, 0, 0.9);

			&.active {
				color: $theme-primary;
			}
		}
	}
}

.body {
	flex: 1;
	padding-top: 104rpx;
	padding-bottom: 150rpx
}

.footer {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 32rpx;
	padding-bottom: calc(32rpx + env(safe-area-inset-bottom));
	background: #fff;
	box-shadow: 0 -8rpx 24rpx rgba(0, 0, 0, 0.06);
	display: flex;
	gap: 32rpx;

	.btn {
		height: 80rpx;
		line-height: 80rpx;
		border-radius: 12rpx;
		font-size: 32rpx;
		flex: 1;
	}

	.reject {
		background: #fff;
		color: #D54941;
		border: 1rpx solid #D54941;
	}

	.pass {
		background: $theme-primary;
		color: #fff;
	}

	.extra {
		background: #fff;
		color: $theme-primary;
		border: none;

		&::after {
			border: none;
		}
	}
}

.action-modal {
	width: 560rpx;
	padding: 32rpx 28rpx 20rpx;
	background: #fff;
	border-radius: 20rpx;

	&_header {
		text-align: center;
		font-size: 34rpx;
		font-weight: 600;
		margin-bottom: 12rpx;
		color: rgba(0, 0, 0, 0.9);
	}

	&_body {
		padding: 12rpx 4rpx 24rpx;

		.tip {
			display: block;
			text-align: center;
			font-size: 32rpx;
			color: rgba(0, 0, 0, 0.6);
			margin-bottom: 32rpx;
		}

		::v-deep .uni-easyinput {
			width: 100%;
		}
	}

	&_footer {
		display: flex;
		justify-content: space-between;
		gap: 16rpx;

		.btn {
			flex: 1;
			height: 80rpx;
			line-height: 80rpx;
			border-radius: 12rpx;
			font-size: 30rpx;
			font-size: 32rpx;

			&::after {
				border: none;
			}
		}

		.cancel {
			background: #fff;
			color: rgba(0, 0, 0, 0.9);
		}

		.confirm {
			background: #fff !important;
			color: $theme-primary !important;
		}
	}
}
</style>