xiongzhu 4 年之前
父節點
當前提交
d147bad041

+ 1 - 1
android/app/capacitor.build.gradle

@@ -10,7 +10,7 @@ android {
 apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
 dependencies {
     implementation project(':capacitor-community-keep-awake')
-
+    implementation "com.android.support:support-v4:27.+"
 }
 
 

+ 2 - 1
android/app/src/main/assets/capacitor.config.json

@@ -13,7 +13,8 @@
         }
     },
     "server": {
-        "cleartext": true
+        "cleartext": true,
+        "url": "http://192.168.50.116:8082"
     },
     "android": {
         "backgroundColor": "#ffffff",

+ 4 - 0
android/app/src/main/res/xml/config.xml

@@ -7,5 +7,9 @@
     <param name="onload" value="true"/>
   </feature>
 
+  <feature name="FileOpener2">
+    <param name="android-package" value="io.github.pwlin.cordova.plugins.fileopener2.FileOpener2"/>
+  </feature>
+
   
 </widget>

+ 2 - 1
capacitor.config.json

@@ -13,7 +13,8 @@
         }
     },
     "server": {
-        "cleartext": true
+        "cleartext": true,
+        "url": "http://192.168.50.116:8082"
     },
     "android": {
         "backgroundColor": "#ffffff",

+ 2 - 1
ios/App/App/capacitor.config.json

@@ -13,7 +13,8 @@
         }
     },
     "server": {
-        "cleartext": true
+        "cleartext": true,
+        "url": "http://192.168.50.116:8082"
     },
     "android": {
         "backgroundColor": "#ffffff",

+ 4 - 0
ios/App/App/config.xml

@@ -2,5 +2,9 @@
 <widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
   <access origin="*" />
   
+  <feature name="FileOpener2">
+    <param name="ios-package" value="FileOpener2"/>
+  </feature>
+
   
 </widget>

+ 1 - 0
ios/App/Podfile

@@ -11,6 +11,7 @@ def capacitor_pods
   pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
   pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
   pod 'CapacitorCommunityKeepAwake', :path => '../../node_modules/@capacitor-community/keep-awake'
+  pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
   # Do not delete
 end
 

+ 1 - 0
package.json

@@ -24,6 +24,7 @@
     "axios": "^0.19.0",
     "babel-plugin-import": "^1.13.3",
     "cordova-plugin-android-notch": "^1.0.3",
+    "cordova-plugin-file-opener2": "^3.0.5",
     "core-js": "^2.6.5",
     "dayjs": "^1.10.4",
     "ip": "^1.1.5",

+ 2 - 0
src/components/newsItem.vue

@@ -30,6 +30,8 @@ export default {
     .info {
         .flex-col();
         justify-content: space-between;
+        flex-basis: 0;
+        flex-grow: 1;
         .title {
             .ellipsisLn(2);
             font-size: 16px;

+ 6 - 0
src/router.js

@@ -282,6 +282,12 @@ const router = new Router({
             name: 'approvalList',
             component: () => import(/* webpackChunkName: "approvalList" */ '@/views/approvalList.vue'),
             meta: { statusBar: 'dark' }
+        },
+        {
+            path: '/approval',
+            name: 'approval',
+            component: () => import(/* webpackChunkName: "approval" */ '@/views/approval.vue'),
+            meta: { statusBar: 'dark' }
         }
     ]
 });

+ 450 - 0
src/views/approval.vue

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

+ 6 - 1
src/views/approvalList.vue

@@ -7,7 +7,12 @@
                 <div class="nav-tab-item" :class="{ active: tab === 2 }" @click="tab = 2">完成</div>
             </div>
         </nav-bar>
-        <div v-for="item in list" :key="item.id" class="list-item">
+        <div
+            v-for="item in list"
+            :key="item.id"
+            class="list-item"
+            @click="$router.push({ name: 'approval', query: { id: item.id } })"
+        >
             <div class="strip" :class="getStatusClass(item)"></div>
             <div class="content-wrapper">
                 <div class="info">

+ 5 - 0
yarn.lock

@@ -2487,6 +2487,11 @@ cordova-plugin-android-notch@^1.0.3:
   resolved "https://registry.yarnpkg.com/cordova-plugin-android-notch/-/cordova-plugin-android-notch-1.0.3.tgz#a65cdee618f82a2ad1dd9ef0a7c33e4971715248"
   integrity sha512-4Nsqzrl26wzUAH4zSFY/RxLemxSqmi2Uppw1/Gyt0d2JMtJOW6aj9ZNLVUpFF8tqGmBsUJQi33/Z8JIpah9NDg==
 
+cordova-plugin-file-opener2@^3.0.5:
+  version "3.0.5"
+  resolved "https://registry.yarnpkg.com/cordova-plugin-file-opener2/-/cordova-plugin-file-opener2-3.0.5.tgz#3bf481a724bcec9cfa2257a71915309df5ea5b4d"
+  integrity sha512-tjLHDamH5+y0bJZYVe2967L1S4R8tL4Y0rJUzJGoxsyiw3FUlrJNS199POOpzZZ6Xhlntn9a2o7+84r1dMN21A==
+
 core-js@^2.6.5:
   version "2.6.12"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"