|
|
@@ -0,0 +1,450 @@
|
|
|
+<template>
|
|
|
+ <div class="approval-root">
|
|
|
+ <nav-bar @click-left="$router.go(-1)" title="审批详情"></nav-bar>
|
|
|
+ <div class="info-card">
|
|
|
+ <div class="row">
|
|
|
+ <div class="label">审批名称</div>
|
|
|
+ <div class="value">{{ (process.approval || {}).name }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="label">申请人</div>
|
|
|
+ <div class="value">{{ (process.approval || {}).creator }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="label">发起时间</div>
|
|
|
+ <div class="value">{{ (process.approval || {}).createdAt }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="label">当前流程</div>
|
|
|
+ <div class="value">{{ approvalStatusFormatter((process.approval || {}).status) }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="label">当前审批</div>
|
|
|
+ <div class="value">{{ (process.approval || {}).currentApprover }}</div>
|
|
|
+ </div>
|
|
|
+ <div class="row">
|
|
|
+ <div class="label">附件</div>
|
|
|
+ <div class="value">
|
|
|
+ <div class="btn-attach" @click="openAttach">点击查看</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="history-card">
|
|
|
+ <div class="history-item" v-for="item in history" :key="item.id">
|
|
|
+ <div class="time">
|
|
|
+ {{ item.approvalTime.split(' ')[0] }} <br />
|
|
|
+ {{ item.approvalTime.split(' ')[1] }}
|
|
|
+ </div>
|
|
|
+ <div class="step-line">
|
|
|
+ <div class="dot"></div>
|
|
|
+ </div>
|
|
|
+ <div class="info">
|
|
|
+ <div class="title">
|
|
|
+ <div class="text">{{ getTitle(item) }}</div>
|
|
|
+ <div class="status" :class="{ pass: item.status === 'PASS', deny: item.status === 'DENY' }">
|
|
|
+ {{ item.status === 'PASS' ? '通过' : '不通过' }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="approver">审批人:{{ item.approver }}</div>
|
|
|
+ <div class="remark" v-if="item.remark">{{ item.remark }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="page-title" v-if="process.status === 'PENDING'">
|
|
|
+ 审批意见
|
|
|
+ </div>
|
|
|
+ <div class="form" v-if="process.status === 'PENDING'">
|
|
|
+ <div style="padding:16px 16px 32px 16px;">
|
|
|
+ <van-radio-group v-model="pass" direction="horizontal">
|
|
|
+ <van-radio :name="true" checked-color="#BF1616" style="flex-grow:1">通过</van-radio>
|
|
|
+ <van-radio :name="false" checked-color="#BF1616" style="flex-grow:1">不通过</van-radio>
|
|
|
+ </van-radio-group>
|
|
|
+ </div>
|
|
|
+ <div class="page-title">
|
|
|
+ 审批备注
|
|
|
+ </div>
|
|
|
+ <textarea v-model="remark" class="remark" placeholder="请填写审批备注"></textarea>
|
|
|
+ <div class="page-title">
|
|
|
+ 报送
|
|
|
+ </div>
|
|
|
+ <div class="approver" @click="showActionSheet = true">
|
|
|
+ <div class="label">审批人</div>
|
|
|
+ <div class="value">{{ nextApprovers ? nextApprovers.name : '请选择' }}</div>
|
|
|
+ <img src="../assets/icon_into.png" class="into" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="bottom" v-if="process.status === 'PENDING'">
|
|
|
+ <div class="btn-confirm" @click="submit">提交</div>
|
|
|
+ <div class="btn-cancel" @click="finish">结束流转</div>
|
|
|
+ </div>
|
|
|
+ <van-action-sheet
|
|
|
+ title="选择审批人"
|
|
|
+ v-model="showActionSheet"
|
|
|
+ :actions="approvers"
|
|
|
+ @select="onSelect"
|
|
|
+ cancel-text="取消"
|
|
|
+ :closeable="false"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+import axios from 'axios';
|
|
|
+export default {
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ statusOptions: [
|
|
|
+ { label: '拟稿', value: 'DRAFT' },
|
|
|
+ { label: '一级审批', value: 'LEVEL_1' },
|
|
|
+ { label: '二级审批', value: 'LEVEL_2' },
|
|
|
+ { label: '三级审批', value: 'LEVEL_3' },
|
|
|
+ { label: '四级审批', value: 'LEVEL_4' },
|
|
|
+ { label: '五级审批', value: 'LEVEL_5' },
|
|
|
+ { label: '完成', value: 'FINISH' }
|
|
|
+ ],
|
|
|
+ process: {},
|
|
|
+ history: [],
|
|
|
+ remark: '',
|
|
|
+ pass: null,
|
|
|
+ nextApprovers: null,
|
|
|
+ approvers: [],
|
|
|
+ showActionSheet: false
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getData() {
|
|
|
+ this.$http.get(`/approvalProcess/get/${this.$route.query.id}`).then(res => {
|
|
|
+ this.process = res;
|
|
|
+ this.$http
|
|
|
+ .get(`/approvalProcess/all`, {
|
|
|
+ size: 10000,
|
|
|
+ sort: 'approvalTime',
|
|
|
+ query: { approvalId: res.approval.id, status: 'PASS,DENY' }
|
|
|
+ })
|
|
|
+ .then(res1 => {
|
|
|
+ this.history = res1.content;
|
|
|
+ });
|
|
|
+ if (res.level < 5) {
|
|
|
+ this.$http
|
|
|
+ .get('/approver/all', {
|
|
|
+ query: { level: res.level + 1 }
|
|
|
+ })
|
|
|
+ .then(res => {
|
|
|
+ this.approvers = res.content;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ approvalStatusFormatter(cellValue) {
|
|
|
+ return (this.statusOptions.find(i => i.value === cellValue) || {}).label;
|
|
|
+ },
|
|
|
+ openAttach() {
|
|
|
+ axios
|
|
|
+ .get('https://zhumj.oss-cn-hangzhou.aliyuncs.com/image/user.jpg', { responseType: 'blob' })
|
|
|
+ .then(res => {
|
|
|
+ console.log(res);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getTitle(row) {
|
|
|
+ return ['拟稿', '一级审批', '二级审批', '三级审批', '四级审批', '五级审批'][row.level];
|
|
|
+ },
|
|
|
+ submit() {
|
|
|
+ if (!(this.pass === true || this.pass === false)) {
|
|
|
+ this.$toast('请填写审批意见');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!this.nextApprovers) {
|
|
|
+ this.$toast('请选择报送人员');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$toast.loading();
|
|
|
+ this.$http
|
|
|
+ .post('/approvalProcess/next', {
|
|
|
+ id: this.process.id,
|
|
|
+ pass: this.pass,
|
|
|
+ remark: this.remark,
|
|
|
+ nextApprovers: this.nextApprovers.userId
|
|
|
+ })
|
|
|
+ .then(res => {
|
|
|
+ this.$toast.success('提交成功');
|
|
|
+ this.$toast.clear();
|
|
|
+ this.getData();
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ this.$toast(e.error || '提交失败');
|
|
|
+ this.$toast.clear();
|
|
|
+ this.getData();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ finish() {
|
|
|
+ if (!(this.pass === true || this.pass === false)) {
|
|
|
+ this.$toast('请填写审批意见');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.$toast.loading();
|
|
|
+ this.$http
|
|
|
+ .post('/approvalProcess/next', {
|
|
|
+ id: this.process.id,
|
|
|
+ pass: this.pass,
|
|
|
+ remark: this.remark
|
|
|
+ })
|
|
|
+ .then(res => {
|
|
|
+ this.$toast.success('提交成功');
|
|
|
+ this.$toast.clear();
|
|
|
+ this.getData();
|
|
|
+ })
|
|
|
+ .catch(e => {
|
|
|
+ this.$toast(e.error || '提交失败');
|
|
|
+ this.$toast.clear();
|
|
|
+ this.getData();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onSelect(item) {
|
|
|
+ console.log(item);
|
|
|
+ this.nextApprovers = item;
|
|
|
+ this.showActionSheet = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+.approval-root {
|
|
|
+ background: #f5f7fa !important;
|
|
|
+}
|
|
|
+.info-card {
|
|
|
+ margin: 16px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: white;
|
|
|
+ padding: 14px;
|
|
|
+ .row {
|
|
|
+ font-size: 14px;
|
|
|
+ margin-bottom: 12px;
|
|
|
+ &:last-child {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+ .flex();
|
|
|
+ .label {
|
|
|
+ color: @text3;
|
|
|
+ width: 56px;
|
|
|
+ min-width: 56px;
|
|
|
+ }
|
|
|
+ .value {
|
|
|
+ margin-left: 26px;
|
|
|
+ color: black;
|
|
|
+ }
|
|
|
+ .btn-attach {
|
|
|
+ width: 70px;
|
|
|
+ height: 24px;
|
|
|
+ .flex();
|
|
|
+ justify-content: center;
|
|
|
+ border: 1px solid @prim;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: @prim;
|
|
|
+ font-size: 13px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.history-card {
|
|
|
+ margin: 0 16px 16px 16px;
|
|
|
+ padding: 14px;
|
|
|
+ border-radius: 8px;
|
|
|
+ background: white;
|
|
|
+ .history-item {
|
|
|
+ .flex();
|
|
|
+ align-items: flex-start;
|
|
|
+ .time {
|
|
|
+ font-size: 13px;
|
|
|
+ color: @text3;
|
|
|
+ width: 73px;
|
|
|
+ min-width: 73px;
|
|
|
+ text-align: right;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ .step-line {
|
|
|
+ width: 40px;
|
|
|
+ min-width: 40px;
|
|
|
+ position: relative;
|
|
|
+ align-self: stretch;
|
|
|
+ .dot {
|
|
|
+ width: 11px;
|
|
|
+ height: 11px;
|
|
|
+ background: #34b918;
|
|
|
+ border-radius: 50%;
|
|
|
+ position: absolute;
|
|
|
+ margin: auto;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ top: 7px;
|
|
|
+ }
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ margin: auto;
|
|
|
+ width: 1px;
|
|
|
+ height: 13px;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ background: #34b918;
|
|
|
+ }
|
|
|
+ &::after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ margin: auto;
|
|
|
+ width: 1px;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ top: 13px;
|
|
|
+ bottom: 0;
|
|
|
+ background: #34b918;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .info {
|
|
|
+ flex-grow: 1;
|
|
|
+ .flex-col();
|
|
|
+ color: @text3;
|
|
|
+ font-size: 16px;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ .title {
|
|
|
+ color: black;
|
|
|
+ line-height: 26px;
|
|
|
+ .flex();
|
|
|
+ .text {
|
|
|
+ flex-grow: 1;
|
|
|
+ }
|
|
|
+ .status {
|
|
|
+ &.pass {
|
|
|
+ color: #34b918;
|
|
|
+ }
|
|
|
+ &.deny {
|
|
|
+ color: #ff8833;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .approver {
|
|
|
+ margin-top: 8px;
|
|
|
+ }
|
|
|
+ .remark {
|
|
|
+ margin-top: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ &:first-child .step-line::before {
|
|
|
+ content: none;
|
|
|
+ }
|
|
|
+ &:last-child {
|
|
|
+ .info {
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+ .step-line {
|
|
|
+ &::after {
|
|
|
+ content: none;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.page-title {
|
|
|
+ color: black;
|
|
|
+ font-size: 18px;
|
|
|
+ padding-left: 16px;
|
|
|
+ line-height: 28px;
|
|
|
+ font-weight: bold;
|
|
|
+ position: relative;
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ width: 2px;
|
|
|
+ height: 16px;
|
|
|
+ border-radius: 1px;
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ margin: auto;
|
|
|
+ background: @prim;
|
|
|
+ }
|
|
|
+}
|
|
|
+.form {
|
|
|
+ background: white;
|
|
|
+ margin-top: 8px;
|
|
|
+ .flex-col();
|
|
|
+ padding-bottom: calc(106px + var(--safe-bottom));
|
|
|
+ .remark {
|
|
|
+ border: none;
|
|
|
+ margin: 16px;
|
|
|
+ padding: 0;
|
|
|
+ height: 168px;
|
|
|
+ resize: none;
|
|
|
+ font-size: 16px;
|
|
|
+ &::-webkit-input-placeholder {
|
|
|
+ color: @text3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .approver {
|
|
|
+ height: 68px;
|
|
|
+ padding: 0 10px 0 16px;
|
|
|
+ position: relative;
|
|
|
+ &::after {
|
|
|
+ .setBottomLine();
|
|
|
+ left: 16px;
|
|
|
+ right: 16px;
|
|
|
+ }
|
|
|
+ .flex();
|
|
|
+ .label {
|
|
|
+ color: black;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+ .value {
|
|
|
+ flex-grow: 1;
|
|
|
+ text-align: right;
|
|
|
+ font-size: 15px;
|
|
|
+ color: @text3;
|
|
|
+ }
|
|
|
+ .into {
|
|
|
+ width: 24px;
|
|
|
+ height: 24px;
|
|
|
+ margin-left: 6px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.bottom {
|
|
|
+ position: fixed;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ padding-bottom: var(--safe-bottom);
|
|
|
+ height: 56px;
|
|
|
+ box-sizing: content-box;
|
|
|
+ background: white;
|
|
|
+ box-shadow: 0px -1px 2px 0px rgba(0, 0, 0, 0.04);
|
|
|
+ .flex();
|
|
|
+ padding: 0 20px;
|
|
|
+ .btn-confirm {
|
|
|
+ height: 40px;
|
|
|
+ border-radius: 4px;
|
|
|
+ background: @prim;
|
|
|
+ color: white;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ .flex();
|
|
|
+ justify-content: center;
|
|
|
+ flex-basis: 0;
|
|
|
+ flex-grow: 1;
|
|
|
+ }
|
|
|
+ .btn-cancel {
|
|
|
+ height: 40px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid @prim;
|
|
|
+ color: @prim;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: bold;
|
|
|
+ .flex();
|
|
|
+ justify-content: center;
|
|
|
+ flex-basis: 0;
|
|
|
+ flex-grow: 1;
|
|
|
+ margin-left: 16px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|