From ca0c92a05c8be10ada67ed30aa71e9a3037b3db1 Mon Sep 17 00:00:00 2001
From: zhanghua <314079846@qq.com>
Date: 星期四, 21 十一月 2024 21:52:49 +0800
Subject: [PATCH] Merge branch 'master' of http://42.193.1.25:9521/r/project_management-vue

---
 src/assets/images/login-backgroun1d.jpg       |    0 
 src/components/TableTemplate/index.vue        |  104 +
 vue.config.js                                 |    1 
 src/views/inspection/runHistory.vue           |  245 ++
 src/views/todo/components/processForm.vue     |    0 
 src/components/Crontab/hour.vue               |   10 
 src/views/function/api/leaveApply.js          |   50 
 src/views/todo/components/meetingForm.vue     |   75 
 src/views/process/modelManagement.vue         |  237 ++
 src/components/Editor/index.vue               |    4 
 src/views/todo/myTodoList.vue                 |  156 +
 src/views/function/api/purchase.js            |   50 
 src/views/process/api/model.js                |   41 
 src/views/process/deployManagement.vue        |  300 +++
 src/layout/components/Sidebar/Logo.vue        |    9 
 src/views/indexBar.vue                        |  173 +
 src/views/todo/components/TimeLine.vue        |   68 
 src/views/todo/api/myTodoList.js              |  104 +
 src/views/system/role/selectUser.vue          |    8 
 src/components/HeaderSearch/index.vue         |    8 
 src/views/todo/components/purchaseForm.vue    |  103 +
 src/views/inspection/processInstance.vue      |  180 ++
 src/views/todo/api/allTodoList.js             |   17 
 src/components/ImageUpload/index.vue          |    9 
 src/api/system/user.js                        |    1 
 src/views/inspection/workManagement.vue       |  271 +++
 src/store/modules/user.js                     |    7 
 src/views/inspection/api.js                   |   93 +
 src/assets/styles/element-ui.scss             |   11 
 src/views/inspection/components/workTable.vue |    0 
 src/views/inspection/runInstance.vue          |  122 +
 src/router/index.js                           |   13 
 src/utils/validate.js                         |   22 
 src/views/function/api/meeting.js             |   53 
 src/views/function/purchaseApply.vue          |  289 +++
 src/views/index_old.vue                       | 1067 ++++++++++++
 src/views/todo/api/processTaks.js             |   10 
 src/views/function/lauchMeeting.vue           |  263 +++
 src/views/todo/processTask.vue                |  208 ++
 .env.development                              |    3 
 src/utils/common.js                           |   79 
 src/views/todo/allTodoList.vue                |  156 +
 src/views/function/leaveApply.vue             |  282 +++
 src/views/todo/components/leaveApplyForm.vue  |  180 ++
 .env.production                               |    3 
 src/components/TopNav/index.vue               |    9 
 src/views/process/api/deployService.js        |   63 
 src/components/FileUpload/index.vue           |    7 
 48 files changed, 5,098 insertions(+), 66 deletions(-)

diff --git a/.env.development b/.env.development
index 882fbc9..4214a89 100644
--- a/.env.development
+++ b/.env.development
@@ -9,3 +9,6 @@
 
 # 璺敱鎳掑姞杞�
 VUE_CLI_BABEL_TRANSPILE_MODULES = true
+
+# 寮�鎵撴柊鐨則ab鐨剈rl鍓嶇紑
+VUE_APP_TAB_URL_PREFIX = http://127.0.0.1:8080
diff --git a/.env.production b/.env.production
index 87f71f2..0a50ac3 100644
--- a/.env.production
+++ b/.env.production
@@ -6,3 +6,6 @@
 
 # 灏勬椽椤圭洰绠$悊绯荤粺/鐢熶骇鐜
 VUE_APP_BASE_API = '/prod-api'
+
+# 寮�鎵撴柊鐨則ab鐨剈rl鍓嶇紑
+VUE_APP_TAB_URL_PREFIX = http://127.0.0.1:9999
diff --git a/src/api/system/user.js b/src/api/system/user.js
index 9b0211a..f2f76ef 100644
--- a/src/api/system/user.js
+++ b/src/api/system/user.js
@@ -105,7 +105,6 @@
   return request({
     url: '/system/user/profile/avatar',
     method: 'post',
-    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
     data: data
   })
 }
diff --git a/src/assets/images/login-backgroun1d.jpg b/src/assets/images/login-backgroun1d.jpg
new file mode 100644
index 0000000..8a89eb8
--- /dev/null
+++ b/src/assets/images/login-backgroun1d.jpg
Binary files differ
diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss
index 363092a..c3102f4 100644
--- a/src/assets/styles/element-ui.scss
+++ b/src/assets/styles/element-ui.scss
@@ -89,4 +89,13 @@
   > .el-submenu__title
   .el-submenu__icon-arrow {
   display: none;
-}
\ No newline at end of file
+}
+
+
+.el-tabs--border-card > .el-tabs__content {
+  padding: 0;
+}
+.search-bar .el-button {
+  height: 32px;
+}
+
diff --git a/src/components/Crontab/hour.vue b/src/components/Crontab/hour.vue
index 3216c33..4b1f1fc 100644
--- a/src/components/Crontab/hour.vue
+++ b/src/components/Crontab/hour.vue
@@ -51,16 +51,10 @@
 	methods: {
 		// 鍗曢�夋寜閽�煎彉鍖栨椂
 		radioChange() {
-			if (this.cron.min === '*') {
-			    this.$emit('update', 'min', '0', 'hour');
-			}
-			if (this.cron.second === '*') {
-			    this.$emit('update', 'second', '0', 'hour');
-			}
 			switch (this.radioValue) {
 				case 1:
-					this.$emit('update', 'hour', '*')
-					break;
+        	this.$emit('update', 'hour', '*')
+        	break;
 				case 2:
 					this.$emit('update', 'hour', this.cycleTotal);
 					break;
diff --git a/src/components/Editor/index.vue b/src/components/Editor/index.vue
index 9323e53..8981d76 100644
--- a/src/components/Editor/index.vue
+++ b/src/components/Editor/index.vue
@@ -108,7 +108,7 @@
         if (val !== this.currentValue) {
           this.currentValue = val === null ? "" : val;
           if (this.Quill) {
-            this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue);
+            this.Quill.pasteHTML(this.currentValue);
           }
         }
       },
@@ -136,7 +136,7 @@
           }
         });
       }
-      this.Quill.clipboard.dangerouslyPasteHTML(this.currentValue);
+      this.Quill.pasteHTML(this.currentValue);
       this.Quill.on("text-change", (delta, oldDelta, source) => {
         const html = this.$refs.editor.children[0].innerHTML;
         const text = this.Quill.getText();
diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue
index 12ad4ea..c7f6b0a 100644
--- a/src/components/FileUpload/index.vue
+++ b/src/components/FileUpload/index.vue
@@ -119,14 +119,9 @@
         const fileExt = fileName[fileName.length - 1];
         const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
         if (!isTypeOk) {
-          this.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭紝璇蜂笂浼�${this.fileType.join("/")}鏍煎紡鏂囦欢!`);
+          this.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭�, 璇蜂笂浼�${this.fileType.join("/")}鏍煎紡鏂囦欢!`);
           return false;
         }
-      }
-      // 鏍℃鏂囦欢鍚嶆槸鍚﹀寘鍚壒娈婂瓧绗�
-      if (file.name.includes(',')) {
-        this.$modal.msgError('鏂囦欢鍚嶄笉姝g‘锛屼笉鑳藉寘鍚嫳鏂囬�楀彿!');
-        return false;
       }
       // 鏍℃鏂囦欢澶у皬
       if (this.fileSize) {
diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue
index 339a688..7d6780b 100644
--- a/src/components/HeaderSearch/index.vue
+++ b/src/components/HeaderSearch/index.vue
@@ -22,7 +22,6 @@
 // make search results more in line with expectations
 import Fuse from 'fuse.js/dist/fuse.min.js'
 import path from 'path'
-import { isHttp } from '@/utils/validate'
 
 export default {
   name: 'HeaderSearch',
@@ -73,7 +72,7 @@
     change(val) {
       const path = val.path;
       const query = val.query;
-      if(isHttp(val.path)) {
+      if(this.ishttp(val.path)) {
         // http(s):// 璺緞鏂扮獥鍙f墦寮�
         const pindex = path.indexOf("http");
         window.open(path.substr(pindex, path.length), "_blank");
@@ -116,7 +115,7 @@
         if (router.hidden) { continue }
 
         const data = {
-          path: !isHttp(router.path) ? path.resolve(basePath, router.path) : router.path,
+          path: !this.ishttp(router.path) ? path.resolve(basePath, router.path) : router.path,
           title: [...prefixTitle]
         }
 
@@ -150,6 +149,9 @@
       } else {
         this.options = []
       }
+    },
+    ishttp(url) {
+      return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
     }
   }
 }
diff --git a/src/components/ImageUpload/index.vue b/src/components/ImageUpload/index.vue
index bf7e381..2e64c9b 100644
--- a/src/components/ImageUpload/index.vue
+++ b/src/components/ImageUpload/index.vue
@@ -44,7 +44,6 @@
 
 <script>
 import { getToken } from "@/utils/auth";
-import { isExternal } from "@/utils/validate";
 
 export default {
   props: {
@@ -94,7 +93,7 @@
           // 鐒跺悗灏嗘暟缁勮浆涓哄璞℃暟缁�
           this.fileList = list.map(item => {
             if (typeof item === "string") {
-              if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) {
+              if (item.indexOf(this.baseUrl) === -1) {
                   item = { name: this.baseUrl + item, url: this.baseUrl + item };
               } else {
                   item = { name: item, url: item };
@@ -136,11 +135,7 @@
       }
 
       if (!isImg) {
-        this.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭紝璇蜂笂浼�${this.fileType.join("/")}鍥剧墖鏍煎紡鏂囦欢!`);
-        return false;
-      }
-      if (file.name.includes(',')) {
-        this.$modal.msgError('鏂囦欢鍚嶄笉姝g‘锛屼笉鑳藉寘鍚嫳鏂囬�楀彿!');
+        this.$modal.msgError(`鏂囦欢鏍煎紡涓嶆纭�, 璇蜂笂浼�${this.fileType.join("/")}鍥剧墖鏍煎紡鏂囦欢!`);
         return false;
       }
       if (this.fileSize) {
diff --git a/src/components/TableTemplate/index.vue b/src/components/TableTemplate/index.vue
new file mode 100644
index 0000000..df6fc88
--- /dev/null
+++ b/src/components/TableTemplate/index.vue
@@ -0,0 +1,104 @@
+<template>
+    <div class="c-table-template">
+        <div class="c-table-template__toolbar">
+            <slot name="toolbar"></slot>
+        </div>
+        <div class="c-table-template__content">
+            <el-table
+                :data="data"
+                :row-key="rowKey"
+                default-expand-all
+                @selection-change="handleSelectionChange"
+            >
+                <el-table-column
+                    v-if="selection"
+                    type="selection"
+                    width="55">
+                </el-table-column>
+                <slot name="columns"></slot>
+            </el-table>
+        </div>
+       <div class="c-table-template__footer">
+        <el-pagination
+            v-if="!noPage"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            background
+            layout="total, sizes, prev, pager, next,jumper"
+            :page-sizes="[10, 25, 50]"
+            :total="total">
+        </el-pagination>
+       </div>
+    </div>
+</template>
+
+<script>
+export default {
+    name: "TableTemplate",
+    props: {
+        data: {
+            type: Array,
+            default: () => ([])
+        },
+        fetchData: {
+            type: Function,
+            default: () => ([])
+        },
+        total: {
+            type: Number,
+            default: 0
+        },
+        selection: {
+            type: Boolean,
+            default: false
+        },
+        rowKey: {
+            type: String,
+            default: ""
+        },
+        noPage: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            currentPageSize: 10
+        };
+    },
+    methods: {
+        handleSizeChange(pageSize) {
+            this.currentPageSize = pageSize;
+            this.$emit("page-change", {
+                pageNum: 1,
+                pageSize
+            })
+
+        },
+        handleCurrentChange(pageNum) {
+            this.$emit("page-change", {
+                pageNum,
+                pageSize: this.currentPageSize
+            })
+        },
+        handleSelectionChange(selection) {
+            this.$emit("selection-change", selection)
+        }
+    }
+};
+</script>
+
+<style scoped>
+.c-table-template {
+    padding: 8px;
+}
+.c-table-template__toolbar {
+    margin-bottom: 8px;
+}
+.c-table-template__footer {
+    margin-top: 8px;
+}
+.el-pagination {
+    text-align: right;
+}
+</style>
diff --git a/src/components/TopNav/index.vue b/src/components/TopNav/index.vue
index f214245..3d5b7b9 100644
--- a/src/components/TopNav/index.vue
+++ b/src/components/TopNav/index.vue
@@ -33,7 +33,6 @@
 
 <script>
 import { constantRoutes } from "@/router";
-import { isHttp } from "@/utils/validate";
 
 // 闅愯棌渚ц竟鏍忚矾鐢�
 const hideList = ['/index', '/user/profile'];
@@ -79,7 +78,7 @@
             if(router.path === "/") {
               router.children[item].path = "/" + router.children[item].path;
             } else {
-              if(!isHttp(router.children[item].path)) {
+              if(!this.ishttp(router.children[item].path)) {
                 router.children[item].path = router.path + "/" + router.children[item].path;
               }
             }
@@ -125,9 +124,10 @@
     },
     // 鑿滃崟閫夋嫨浜嬩欢
     handleSelect(key, keyPath) {
+      debugger;
       this.currentIndex = key;
       const route = this.routers.find(item => item.path === key);
-      if (isHttp(key)) {
+      if (this.ishttp(key)) {
         // http(s):// 璺緞鏂扮獥鍙f墦寮�
         window.open(key, "_blank");
       } else if (!route || !route.children) {
@@ -161,6 +161,9 @@
       } else {
         this.$store.dispatch('app/toggleSideBarHide', true);
       }
+    },
+    ishttp(url) {
+      return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
     }
   },
 };
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index 2774cc8..1aac73b 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -3,10 +3,10 @@
     <transition name="sidebarLogoFade">
       <router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
         <img v-if="logo" :src="logo" class="sidebar-logo" />
-        <h1 v-else class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
+        <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
       </router-link>
       <router-link v-else key="expand" class="sidebar-logo-link" to="/">
-        <img v-if="logo" :src="logo" class="sidebar-logo" />
+        <!-- <img v-if="logo" :src="logo" class="sidebar-logo" /> -->
         <h1 class="sidebar-title" :style="{ color: sideTheme === 'theme-dark' ? variables.logoTitleColor : variables.logoLightTitleColor }">{{ title }} </h1>
       </router-link>
     </transition>
@@ -38,6 +38,9 @@
       title: process.env.VUE_APP_TITLE,
       logo: logoImg
     }
+  },
+  mounted() {
+    console.log("title鏄�", process.env.VUE_APP_TITLE);
   }
 }
 </script>
@@ -78,7 +81,7 @@
       color: #fff;
       font-weight: 600;
       line-height: 50px;
-      font-size: 14px;
+      font-size: 24px;
       font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
       vertical-align: middle;
     }
diff --git a/src/router/index.js b/src/router/index.js
index 71907b6..caf7b3c 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -87,6 +87,19 @@
         meta: { title: '涓汉涓績', icon: 'user' }
       }
     ]
+  },
+  {
+    path: '/process',
+    component: Layout,
+    hidden: true,
+    children: [
+      {
+        path: ':taskType/:step/:taskId',
+        component: () => import('@/views/todo/processTask'),
+        name: 'process',
+        meta: { title: '澶勭悊寰呭姙' }
+      }
+    ]
   }
 ]
 
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 63e6ba2..cdbab1e 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -1,7 +1,5 @@
 import { login, logout, getInfo } from '@/api/login'
 import { getToken, setToken, removeToken } from '@/utils/auth'
-import { isHttp, isEmpty } from "@/utils/validate"
-import defAva from '@/assets/images/profile.jpg'
 
 const user = {
   state: {
@@ -57,10 +55,7 @@
       return new Promise((resolve, reject) => {
         getInfo().then(res => {
           const user = res.user
-          let avatar = user.avatar || ""
-          if (!isHttp(avatar)) {
-            avatar = (isEmpty(avatar)) ? defAva : process.env.VUE_APP_BASE_API + avatar
-          }
+          const avatar = (user.avatar == "" || user.avatar == null) ? require("@/assets/images/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
           if (res.roles && res.roles.length > 0) { // 楠岃瘉杩斿洖鐨剅oles鏄惁鏄竴涓潪绌烘暟缁�
             commit('SET_ROLES', res.roles)
             commit('SET_PERMISSIONS', res.permissions)
diff --git a/src/utils/common.js b/src/utils/common.js
new file mode 100644
index 0000000..121e277
--- /dev/null
+++ b/src/utils/common.js
@@ -0,0 +1,79 @@
+function objectToFormData(obj) {
+    const fd = new FormData();
+    Object.keys(obj).forEach(key => {
+        const value = obj[key];
+        fd.set(key, value);
+    });
+    return fd;
+}
+function objectToQueryStr(obj, filterNull = false) {
+    let queryStr = "";
+    Object.keys(obj).forEach(key => {
+        if (filterNull && !obj[key]) {
+           return;
+        }
+        queryStr += `&${key}=${obj[key] || ''}`
+    });
+    console.log(queryStr);
+    return queryStr.slice(1);
+}
+function openWindow(path) {
+    const prefix = process.env.VUE_APP_TAB_URL_PREFIX;
+    window.open(prefix + "" + path);
+}
+
+// 杩愯瀹炰緥
+function listToTree(list) {
+    const nodeMap = {};
+    const firstLevelList = list.filter(item => item.parentExecutionId === "0");
+    firstLevelList.forEach(item => {
+        const {executionId} = item;
+        nodeMap[executionId] = item;
+    });
+    while (true) {
+        list.forEach(item => {
+            const {parentExecutionId, executionId} = item;
+            if (nodeMap[executionId]) return;
+            if (nodeMap[parentExecutionId]) {
+                const parent = nodeMap[parentExecutionId];
+                if (parent.children) {
+                    parent.children.push(item);
+                } else {
+                    parent.children = [item];
+                }
+                nodeMap[executionId] = item;
+            }
+        });
+        if (Object.keys(nodeMap).length === list.length) {
+            return firstLevelList;
+        }
+    }
+
+}
+
+function normalizeDateTimeString(rawDatatimeStr) {
+    function genNumStr(num) {
+        return Number(num) < 10 ? "0" + num : ("" + num) 
+    }
+    if (rawDatatimeStr) {
+        const dateObj = new Date(rawDatatimeStr);
+
+        const yyyy = dateObj.getFullYear();
+        const MM = dateObj.getMonth() + 1;
+        const dd = dateObj.getDate();
+
+        const HH = dateObj.getHours();
+        const mm = dateObj.getMinutes();
+        const ss = dateObj.getSeconds();
+
+        return `${yyyy}-${genNumStr(MM)}-${genNumStr(dd)} ${genNumStr(HH)}:${genNumStr(mm)}:${genNumStr(ss)}`;
+    }
+}
+
+export default {
+    objectToFormData,
+    objectToQueryStr,
+    openWindow,
+    listToTree,
+    normalizeDateTimeString
+};
\ No newline at end of file
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 9d1b89e..57a568e 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -1,26 +1,4 @@
 /**
- * 鍒ゆ柇value瀛楃涓叉槸鍚︿负绌� 
- * @param {string} value
- * @returns {Boolean}
- */
-export function isEmpty(value) {
-  if (value == null || value == "" || value == undefined || value == "undefined") {
-    return true;
-  }
-  return false;
-}
-
-/**
- * 鍒ゆ柇url鏄惁鏄痟ttp鎴杊ttps 
- * @param {string} url
- * @returns {Boolean}
- */
-export function isHttp(url) {
-  return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
-}
-
-/**
- * 鍒ゆ柇path鏄惁涓哄閾�
  * @param {string} path
  * @returns {Boolean}
  */
diff --git a/src/views/function/api/leaveApply.js b/src/views/function/api/leaveApply.js
new file mode 100644
index 0000000..f360128
--- /dev/null
+++ b/src/views/function/api/leaveApply.js
@@ -0,0 +1,50 @@
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+// 鑾峰彇璇峰亣鍒楄〃
+
+export const getLeaveApplyList = data => {
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa1");
+    const queryString = commonUtil.objectToQueryStr(data);
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa2", queryString);
+    return request({
+        url: '/leaveapply/list',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+// 娣诲姞璇峰亣
+// http://101.43.32.218:8020/leaveapply/add
+export const addLeave = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/leaveapply/add',
+        method: 'post',
+        data: fd
+    });
+}
+// 瀵煎嚭
+export const exportLeave = data => {
+    const fd = commonUtil.objectToQueryStr(data)
+    return request({
+        url: '/leaveapply/export',
+        method: 'post',
+        data: fd,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
+        },
+    });
+}
+// 鍒犻櫎
+export const deleteLeave = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/leaveapply/remove',
+        method: 'post',
+        data: fd
+    });
+}
\ No newline at end of file
diff --git a/src/views/function/api/meeting.js b/src/views/function/api/meeting.js
new file mode 100644
index 0000000..e30756d
--- /dev/null
+++ b/src/views/function/api/meeting.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+// 鑾峰彇璇峰亣鍒楄〃
+
+export const getMeetingList = data => {
+    const queryString = commonUtil.objectToQueryStr(data);
+    return request({
+        url: '/meeting/list',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+// 娣诲姞璇峰亣
+// http://101.43.32.218:8020/leaveapply/add
+export const addMeeting = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/meeting/add',
+        method: 'post',
+        data: fd
+    });
+}
+
+// 瀵煎嚭璇峰亣
+// http://101.43.32.218:8020/leaveapply/add
+export const exportMeeting = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/meeting/export',
+        method: 'post',
+        data: fd,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
+        }
+    });
+}
+
+
+// 鍒犻櫎璇峰亣
+// http://101.43.32.218:8020/leaveapply/add
+export const deleteMeeting = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/meeting/remove',
+        method: 'post',
+        data: fd
+    });
+}
\ No newline at end of file
diff --git a/src/views/function/api/purchase.js b/src/views/function/api/purchase.js
new file mode 100644
index 0000000..1ef3bc0
--- /dev/null
+++ b/src/views/function/api/purchase.js
@@ -0,0 +1,50 @@
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+// 鑾峰彇閲囪喘
+
+export const getPurchaseApplyList = data => {
+    const queryString = commonUtil.objectToQueryStr(data);
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa2", queryString);
+    return request({
+        url: '/purchase/list',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+// 娣诲姞閲囪喘
+// http://101.43.32.218:8020/leaveapply/add
+export const addPurchase = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/purchase/add',
+        method: 'post',
+        data: fd
+    });
+}
+
+// 瀵煎嚭
+export const exportPurchase = data => {
+    const fd = commonUtil.objectToQueryStr(data)
+    return request({
+        url: '/purchase/export',
+        method: 'post',
+        data: fd,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
+        },
+    });
+}
+// 鍒犻櫎
+export const deletePurchase = data => {
+    const fd = commonUtil.objectToFormData(data)
+    return request({
+        url: '/purchase/remove',
+        method: 'post',
+        data: fd
+    });
+}
\ No newline at end of file
diff --git a/src/views/function/lauchMeeting.vue b/src/views/function/lauchMeeting.vue
new file mode 100644
index 0000000..46ea1bd
--- /dev/null
+++ b/src/views/function/lauchMeeting.vue
@@ -0,0 +1,263 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>浼氳涓婚</label>
+                <el-input type="text" v-model="searchParams.topic" size="small" />
+            </div>
+            <div>
+                <label>涓绘寔浜�</label>
+                <el-input type="text" v-model="searchParams.host"  size="small"/>
+            </div>
+            <div>
+                <label>浼氳鍦板潃</label>
+                <el-input type="text" v-model="searchParams.place"  size="small" />
+            </div>
+            <div>
+                <label>鍙備細浜哄憳</label>
+                <el-input type="text" v-model="searchParams.peoplelist" size="small" />
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template
+            :data="tableData"
+            :total="total"
+            selection
+            @selection-change="handleSelectionChange"
+            @page-change="handlePageChange"
+        >
+            <template #toolbar>
+                <el-button type="primary" @click="dialogVisible = true" plain icon="el-icon-plus" size="mini">娣诲姞</el-button>
+                <el-button type="danger" :disabled="currentSelection.length === 0" @click="handleDelelteMultiple" plain icon="el-icon-delete" size="mini">鍒犻櫎</el-button>
+            </template>
+            <template #columns>
+                <el-table-column
+                    prop="topic"
+                    label="浼氳涓婚">
+                </el-table-column>
+                <el-table-column
+                    prop="host"
+                    label="涓绘寔浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="place"
+                    label="浼氳鍦板潃">
+
+                </el-table-column>
+                <el-table-column
+                    prop="peoplelist"
+                    label="鍙備細浜哄憳">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="寮�濮嬫椂闂�">
+                </el-table-column>
+                <el-table-column
+                    prop="endTime"
+                    label="缁撴潫鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        icon="el-icon-delete"
+                        @click="handleDelete(scope.$index, scope.row)">鍒犻櫎</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+        <el-dialog :visible.sync="dialogVisible" width="600px">
+            <el-form ref="form" :model="form" label-width="110px">
+                <el-form-item label="浼氳涓婚">
+                    <el-input v-model="form.topic"></el-input>
+                </el-form-item>
+                <el-form-item label="涓绘寔浜�">
+                    <el-input v-model="form.host" disabled></el-input>
+                </el-form-item>
+                <el-form-item label="浼氳鍦板潃">
+                    <el-input v-model="form.place"></el-input>
+                </el-form-item>
+                <el-form-item label="鍙備細浜哄憳">
+                    <el-select v-model="form.peoplelist" multiple>
+                        <el-option
+                            v-for="(user, i) in userList" 
+                            :key="i"
+                            :label="user.userName"
+                            :value="user.userName"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="寮�濮嬫椂闂�">
+                    <el-date-picker type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.startTime" style="width: 100%;"></el-date-picker>
+                </el-form-item>
+                <el-form-item label="缁撴潫鏃堕棿">
+                    <el-date-picker type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.endTime" style="width: 100%;"></el-date-picker>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleAdd">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getMeetingList, addMeeting, deleteMeeting, exportMeeting} from "./api/meeting";
+import {listUser} from "@/api/system/user.js"
+export default {
+    name: "leaveApply",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            dialogVisible: false,
+            form: {
+                topic: "",
+                host: this.$store.state.user.name,
+                place: "",
+                peoplelist: [],
+                startTime: "",
+                endTime: ""
+            },
+            searchParams: {
+                pageNum: 1,
+                pageSize: 10,
+                topic: "",
+                host: "",
+                place: "",
+                peoplelist: "",
+            },
+            currentSelection: [],
+            userList: []
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        },
+        selectionIds() {
+            return this.currentSelection.map(item => item.id)
+        }
+    },
+    mounted() {
+        this.getMeetingListAndRender(this.searchParams);
+        listUser().then(res => {
+            console.log("鑾峰彇鐢ㄦ埛", res);
+            this.userList = res.rows;
+        });
+    },
+    methods: {
+        getMeetingListAndRender(params) {
+            const {pageNum = 1, pageSize = 10, topic, host, place, peoplelist} = params;
+            getMeetingList({
+                pageNum,
+                pageSize,
+                topic,
+                host,
+                place,
+                peoplelist,
+                isAsc: "asc"
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        handleAdd() {
+            console.log("濉啓鐨刦orm鍊兼槸", this.form);
+            const params = Object.assign({}, this.form, {
+                peoplelist: this.form.peoplelist.join()
+            });
+            addMeeting(params).then(res => {
+                this.dialogVisible = false;
+                this.$message.success("娣诲姞鎴愬姛");
+                this.getMeetingListAndRender(this.searchParams);
+            });
+        },
+        handleDelete(index, row) {
+            this.$confirm('纭畾鍒犻櫎鍚楋紵', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const {id} = row;
+                this.deleteByIdsAndRender(id)
+            });
+        },
+        handleDelelteMultiple() {
+            this.$confirm(`纭畾鍒犻櫎閫変腑鐨�${this.currentSelection.length}鏉℃暟鎹悧锛焋, {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const ids = this.selectionIds.join(",");
+                this.deleteByIdsAndRender(ids)
+            });
+        },
+        handleExport() {
+            this.$confirm('纭畾瀵煎嚭鎵�鏈夋暟鎹悧锛�', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                exportMeeting(this.searchParams)
+            });
+        },
+        search() {
+            this.getMeetingListAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.topic = "";
+            this.searchParams.host = "";
+            this.searchParams.place = "";
+            this.searchParams.peoplelist = "";
+            this.getMeetingListAndRender(this.searchParams);
+        },
+        deleteByIdsAndRender(ids) {
+            deleteMeeting({
+                ids
+            }).then(() => {
+                this.$message.error("鍒犻櫎鎴愬姛!")
+                this.getMeetingListAndRender(this.searchParams);
+            })
+        },
+        handleSelectionChange(selection) {
+            this.currentSelection = selection;
+        },
+        handlePageChange({pageNum, pageSize}) {
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getMeetingListAndRender(this.searchParams);
+        }
+    }
+};
+</script>
+
+<style scoped>
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 200px;
+    margin-right: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/function/leaveApply.vue b/src/views/function/leaveApply.vue
new file mode 100644
index 0000000..15b9672
--- /dev/null
+++ b/src/views/function/leaveApply.vue
@@ -0,0 +1,282 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>璇峰亣绫诲瀷</label>
+                <el-select v-model="searchParams.leaveType" size="small">
+                    <el-option label="鎵�鏈�" value="" :key="99"></el-option>
+                    <el-option v-for="(leaveType, i) in leaveTypeList" :label="leaveType" :value="leaveType" :key="i"></el-option>
+                </el-select>
+            </div>
+            <div>
+                <label>鐢宠鏃堕棿</label>
+                <el-date-picker
+                    size="small"
+                    v-model="searchParams.range"
+                    value-format="yyyy-MM-dd HH:mm:ss"
+                    type="datetimerange"
+                    range-separator="鑷�"
+                    start-placeholder="寮�濮嬫棩鏈�"
+                    end-placeholder="缁撴潫鏃ユ湡">
+                </el-date-picker>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template
+            :data="tableData"
+            :total="total"
+            selection
+            @selection-change="handleSelectionChange"
+            @page-change="handlePageChange"
+        >
+            <template #toolbar>
+                <el-button type="primary" @click="dialogVisible = true" plain icon="el-icon-plus" size="mini">娣诲姞</el-button>
+                <el-button type="danger" :disabled="currentSelection.length === 0" @click="handleMultipleDelete" plain icon="el-icon-delete" size="mini">鍒犻櫎</el-button>
+            </template>
+            <template #columns>
+                <el-table-column
+                    prop="userId"
+                    label="璇峰亣浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="璧峰鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="endTime"
+                    label="缁撴潫鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="leaveType"
+                    label="绫诲瀷">
+                </el-table-column>
+                <el-table-column
+                    prop="applyTime"
+                    label="鐢宠鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="瀹為檯璧峰鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="endTime"
+                    label="瀹為檯缁撴潫鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        icon="el-icon-delete"
+                        @click="handleDelete(scope.$index, scope.row)">鍒犻櫎</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+        <el-dialog :visible.sync="dialogVisible" width="600px">
+            <el-form ref="form" :model="form" label-width="110px">
+                <el-form-item label="璇峰亣浜�">
+                    <el-input v-model="form.userId" disabled></el-input>
+                </el-form-item>
+                <el-form-item label="绫诲瀷">
+                    <el-select v-model="form.leaveType">
+                        <el-option v-for="(leaveType, i) in leaveTypeList" :label="leaveType" :value="leaveType" :key="i"></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="璧峰鏃堕棿">
+                    <el-date-picker type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.startTime" style="width: 100%;"></el-date-picker>
+                </el-form-item>
+                <el-form-item label="缁撴潫鏃堕棿">
+                    <el-date-picker type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.endTime" style="width: 100%;"></el-date-picker>
+                </el-form-item>
+                <el-form-item label="鍘熷洜">
+                    <el-input type="textarea" v-model="form.reason"></el-input>
+                </el-form-item>
+                <el-form-item label="閮ㄩ棬棰嗗">
+                    <el-select v-model="form.deptleader">
+                        <el-option
+                            v-for="(user, i) in userList" 
+                            :key="i"
+                            :label="user.userName"
+                            :value="user.userName"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleAddLeave">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+
+// userId: admin
+// leaveType: 浜嬪亣
+// startTime: 1899-11-27 06:30:00
+// endTime: 2024-04-11 23:25:44
+// reason: 123
+// deptleader: admin
+import TableTemplate from "@/components/TableTemplate";
+import {getLeaveApplyList, addLeave, deleteLeave, exportLeave} from "./api/leaveApply";
+import {listUser} from "@/api/system/user.js"
+
+export default {
+    name: "leaveApply",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            searchParams: {
+                leaveType: "",
+                searchParams: [],
+                pageNum: 1,
+                pageSize: 10
+            },
+            leaveTypeList: [" 浜嬪亣", "鐥呭亣", "骞村亣", "涓у亣", "骞村亣"],
+            dialogVisible: false,
+            form: {
+                userId: this.$store.state.user.name,
+                leaveType: "浜嬪亣",
+                startTime: "",
+                endTime: "",
+                reason: "",
+                deptleader: "admin"
+            },
+            currentSelection: [],
+            userList: []
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        },
+        selectionIds() {
+            return this.currentSelection.map(item => item.id)
+        },
+    },
+    mounted() {
+        this.getLeaveApplyListAndRender(this.searchParams)
+        listUser().then(res => {
+            console.log("鑾峰彇鐢ㄦ埛", res);
+            this.userList = res.rows;
+        });
+    },
+    methods: {
+        handleMultipleDelete() {
+            this.$confirm(`纭畾鍒犻櫎閫変腑鐨�${this.currentSelection.length}鏉℃暟鎹悧锛焋, {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const ids = this.selectionIds.join(",");
+                this.deleteByIdsAndRender(ids);
+            });
+           
+        },
+        handleExport() {
+            this.$confirm('纭畾瀵煎嚭鎵�鏈夋暟鎹悧锛�', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const {leaveType, range} = this.searchParams;
+                const params = {
+                    leaveType,
+                    "params[beginApplyTime]": (range && range[0]) || "",
+                    "params[endApplyTime]": (range && range[1]) || "",
+                    isAsc: "asc"
+                };
+                exportLeave(params)
+            });
+        },
+        handleSelectionChange(selection) {
+            this.currentSelection = selection;
+        },
+        getLeaveApplyListAndRender(params) {
+            const {leaveType, range, pageSize = 10, pageNum = 1} = params;
+            getLeaveApplyList({
+                pageSize,
+                pageNum,
+                isAsc: "asc",
+                leaveType,
+                "params[beginApplyTime]": (range && range[0]) || "",
+                "params[endApplyTime]": (range && range[1]) || ""
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        handleAddLeave() {
+            addLeave(this.form).then(res => {
+                this.$message.success("娣诲姞鎴愬姛!");
+                this.dialogVisible = false;
+                this.getLeaveApplyListAndRender(this.searchParams);
+            });
+        },
+        search() {
+            this.getLeaveApplyListAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.leaveType = "";
+            this.searchParams.range = [];
+            this.getLeaveApplyListAndRender(this.searchParams);
+        },
+        handleDelete(index, row) {
+            this.$confirm('纭畾鍒犻櫎鍚楋紵', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const {id} = row;
+                this.deleteByIdsAndRender(id)
+            });
+        },
+        deleteByIdsAndRender(ids) {
+            deleteLeave({
+                ids
+            }).then(() => {
+                this.$message.error("鍒犻櫎鎴愬姛!")
+                this.getLeaveApplyListAndRender(this.searchParams);
+            })
+        },
+        handlePageChange({pageNum, pageSize}) {
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getLeaveApplyListAndRender(this.searchParams);
+        },
+    }
+};
+</script>
+
+<style scoped>
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.search-bar > *{
+    margin-right: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+</style>
diff --git a/src/views/function/purchaseApply.vue b/src/views/function/purchaseApply.vue
new file mode 100644
index 0000000..b1eb602
--- /dev/null
+++ b/src/views/function/purchaseApply.vue
@@ -0,0 +1,289 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>鐢宠鏃堕棿:</label>
+                <el-date-picker
+                    v-model="searchParams.range"
+                    value-format="yyyy-MM-dd HH:mm:ss"
+                    type="datetimerange"
+                    range-separator="鑷�"
+                    start-placeholder="寮�濮嬫棩鏈�"
+                    end-placeholder="缁撴潫鏃ユ湡">
+                </el-date-picker>
+            </div>
+            <div>
+                <label>鐢宠浜�:</label>
+                <el-input type="text" v-model="searchParams.applier" />
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template
+            :data="tableData"
+            :total="total"
+            selection
+            @selection-change="handleSelectionChange"
+            @page-change="handlePageChange"
+        >
+            <template #toolbar>
+                <el-button type="primary" @click="dialogVisible = true" plain icon="el-icon-plus" size="mini">娣诲姞</el-button>
+                <el-button type="danger" :disabled="currentSelection.length === 0" @click="handleMultipleDelete" plain icon="el-icon-delete" size="mini">鍒犻櫎</el-button>
+            </template>
+            <template #columns>
+                <el-table-column
+                    prop="itemlist"
+                    label="閲囪喘娓呭崟">
+                </el-table-column>
+                <el-table-column
+                    prop="total"
+                    label="鎬讳环">
+                </el-table-column>
+                <el-table-column
+                    prop="applytime"
+                    label="鐢宠鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="applyer"
+                    label="鐢宠浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        icon="el-icon-delete"
+                        @click="handleDelete(scope.$index, scope.row)">鍒犻櫎</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+        <el-dialog :visible.sync="dialogVisible" width="600px">
+            <el-form ref="form" :model="form" label-width="80px">
+                <el-form-item label="閲囪喘娓呭崟">
+                    <el-input type="textarea" v-model="form.itemlist"></el-input>
+                </el-form-item>
+                <el-form-item label="鎬讳环">
+                    <el-input type="text" v-model="form.total"></el-input>
+                </el-form-item>
+                <el-form-item label="鐢宠浜�">
+                    <el-input type="text" v-model="form.applyer" disabled></el-input>
+                </el-form-item>
+                <el-form-item label="閲囪喘缁忕悊">
+                    <el-select v-model="form.purchasemanager">
+                        <el-option
+                            v-for="(user, i) in userList" 
+                            :key="i"
+                            :label="user.userName"
+                            :value="user.userName"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="璐㈠姟">
+                    <el-select v-model="form.financeName">
+                        <el-option
+                            v-for="(user, i) in userList" 
+                            :key="i"
+                            :label="user.userName"
+                            :value="user.userName"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="鍑虹撼">
+                    <el-select v-model="form.pay">
+                        <el-option
+                            v-for="(user, i) in userList" 
+                            :key="i"
+                            :label="user.userName"
+                            :value="user.userName"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+                <el-form-item label="鎬荤粡鐞�">
+                    <el-select v-model="form.managerName">
+                        <el-option
+                            v-for="(user, i) in userList" 
+                            :key="i"
+                            :label="user.userName"
+                            :value="user.userName"
+                        ></el-option>
+                    </el-select>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleAdd">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getPurchaseApplyList, addPurchase, deletePurchase, exportPurchase} from "./api/purchase.js";
+import {listUser} from "@/api/system/user.js"
+// itemlist: 绗�
+// total: 100
+// applyer: admin
+// purchasemanager: admin
+// finance: admin
+// pay: admin
+// manager: admin
+export default {
+    name: "leaveApply",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            dialogVisible: false,
+            form: {
+                itemlist: "",
+                total: "",
+                applyer: this.$store.state.user.name,
+                purchasemanager: "admin",
+                financeName: "admin",
+                pay: "admin",
+                managerName: "admin",
+            },
+            searchParams: {
+                range: [],
+                applier: "",
+                pageSize: 10,
+                pageNum: 1
+            },
+            currentSelection: [],
+            userList: []
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        },
+        selectionIds() {
+            return this.currentSelection.map(item => item.id)
+        },
+    },
+    mounted() {
+        this.getPurchaseApplyListAndRender(this.searchParams);
+         listUser().then(res => {
+            console.log("鑾峰彇鐢ㄦ埛", res);
+            this.userList = res.rows;
+        });
+    },
+    methods: {
+        handleSelectionChange(selection) {
+            console.log(selection);
+            this.currentSelection = selection;
+        },
+        getPurchaseApplyListAndRender(params) {
+            const {range = [], pageSize = 10, pageNum = 1, applier = ""} = params;
+            getPurchaseApplyList({
+                pageSize,
+                pageNum,
+                isAsc: "asc",
+                "params[beginApplyTime]": (range && range[0]) || "",
+                "params[endApplyTime]": (range && range[1]) || "",
+                applyer: applier
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        handleAdd() {
+            addPurchase(this.form).then(res => {
+                this.$message.success("娣诲姞鎴愬姛!");
+                this.dialogVisible = false;
+                this.getPurchaseApplyListAndRender(this.searchParams);
+            });
+        },
+        search() {
+            this.getPurchaseApplyListAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.applier = "";
+            this.searchParams.range = [];
+            this.getPurchaseApplyListAndRender(this.searchParams);
+        },
+        handleDelete(index, row) {
+            this.$confirm('纭畾鍒犻櫎鍚楋紵', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const {id} = row;
+                this.deleteByIdsAndRender(id)
+            });
+        },
+        handleMultipleDelete() {
+            this.$confirm(`纭畾鍒犻櫎閫変腑鐨�${this.currentSelection.length}鏉℃暟鎹悧锛焋, {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const ids = this.selectionIds.join(",");
+                this.deleteByIdsAndRender(ids)
+            });
+        },
+        handleExport() {
+            this.$confirm('纭畾瀵煎嚭鎵�鏈夋暟鎹悧锛�', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const {applier, range} = this.searchParams;
+                const params = {
+                    applyer: applier,
+                    "params[beginApplyTime]": (range && range[0]) || "",
+                    "params[endApplyTime]": (range && range[1]) || "",
+                    isAsc: "asc"
+                };
+                exportPurchase(params)
+            });
+        },
+        deleteByIdsAndRender(ids) {
+            deletePurchase({
+                ids
+            }).then(() => {
+                this.$message.error("鍒犻櫎鎴愬姛!")
+                this.getPurchaseApplyListAndRender(this.searchParams);
+            })
+        },
+        handlePageChange({pageNum, pageSize}) {
+            console.log(pageNum, pageSize);
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getPurchaseApplyListAndRender(this.searchParams);
+        }
+    }
+};
+</script>
+
+<style scoped>
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.search-bar > *{
+    margin-right: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+
+</style>
diff --git a/src/views/indexBar.vue b/src/views/indexBar.vue
new file mode 100644
index 0000000..55d95f2
--- /dev/null
+++ b/src/views/indexBar.vue
@@ -0,0 +1,173 @@
+<template>
+    <div :class="className" :style="{height:height,width:width}" />
+  </template>
+  
+  <script>
+  import * as echarts from 'echarts'
+  require('echarts/theme/macarons') // echarts theme
+  import resize from './dashboard/mixins/resize'
+  
+  const animationDuration = 6000
+  
+  export default {
+    mixins: [resize],
+    props: {
+      className: {
+        type: String,
+        default: 'chart'
+      },
+      width: {
+        type: String,
+        default: '100%'
+      },
+      height: {
+        type: String,
+        default: '300px'
+      }
+    },
+    data() {
+      return {
+        chart: null
+      }
+    },
+    mounted() {
+      this.$nextTick(() => {
+        this.initChart()
+      })
+    },
+    beforeDestroy() {
+      if (!this.chart) {
+        return
+      }
+      this.chart.dispose()
+      this.chart = null
+    },
+    methods: {
+      initChart() {
+        this.chart = echarts.init(this.$el, 'macarons')
+  
+        this.chart.setOption({
+          tooltip: {
+            trigger: 'axis',
+            axisPointer: { // 鍧愭爣杞存寚绀哄櫒锛屽潗鏍囪酱瑙﹀彂鏈夋晥
+              type: 'shadow' // 榛樿涓虹洿绾匡紝鍙�変负锛�'line' | 'shadow'
+            }
+          },
+          legend: {
+            data: ["璇峰亣鏁�", "閿�鍋囨暟"]
+          },
+          grid: {
+            top: 10,
+            left: '2%',
+            right: '2%',
+            bottom: '3%',
+            containLabel: true
+          },
+          xAxis: [{
+            type: 'category',
+            data: new Array(31).fill("1鏈�").map((item, i) => {
+                return item + "" + (i + 1);
+            }),
+            axisTick: {
+              alignWithLabel: true
+            }
+          }],
+          yAxis: [{
+            type: 'value',
+            name: "璇峰亣鏁�",
+          },
+          {
+            type: 'value',
+            name: "閿�鍋囨暟",
+            yAxisIndex: 1,
+            min: 0,
+            max: 30,
+          }],
+          series: [
+            {
+                name: '璇峰亣鏁�',
+                type: 'bar',
+                barWidth: '60%',
+                data: [
+                    123,
+                    452,
+                    123,
+                    666,
+                    344,
+                    800,
+                    980,
+                    134,
+                    321,
+                    678,
+                    198,
+                    459,
+                    390,
+                    890,
+                    967,
+                    222,
+                    777,
+                    222,
+                    123,
+                    452,
+                    123,
+                    666,
+                    344,
+                    800,
+                    980,
+                    134,
+                    321,
+                    678,
+                    777,
+                    222,
+                    123,
+                    452
+                ],
+                animationDuration: 1000
+            },
+            {
+                name: "閿�鍋囨暟",
+                type: 'line',
+                smooth: false,
+                yAxisIndex: 1,
+                areaStyle: {},
+                data: [
+                    1,
+                    12,
+                    15,
+                    11,
+                    7,
+                    9,
+                    3,
+                    12,
+                    8,
+                    9,
+                    10,
+                    12,
+                    11,
+                    15,
+                    12,
+                    12,
+                    11,
+                    14,
+                    11,
+                    5,
+                    12,
+                    5,
+                    5,
+                    11,
+                    9,
+                    12,
+                    9,
+                    9,
+                    2,
+                    9,
+                    2
+                ]
+            }
+          ]
+        })
+      }
+    }
+  }
+  </script>
+  
\ No newline at end of file
diff --git a/src/views/index_old.vue b/src/views/index_old.vue
new file mode 100644
index 0000000..1a7310a
--- /dev/null
+++ b/src/views/index_old.vue
@@ -0,0 +1,1067 @@
+<template>
+  <div class="app-container home">
+    <el-row :gutter="20">
+      <el-col :sm="24" :lg="24">
+        <blockquote class="text-warning" style="font-size: 14px">
+          棰嗗彇闃块噷浜戦�氱敤浜戜骇鍝�1888浼樻儬鍒�
+          <br />
+          <el-link
+            href="https://www.aliyun.com/minisite/goods?userCode=brki8iof"
+            type="primary"
+            target="_blank"
+            >https://www.aliyun.com/minisite/goods?userCode=brki8iof</el-link
+          >
+          <br />
+          棰嗗彇鑵捐浜戦�氱敤浜戜骇鍝�2860浼樻儬鍒�
+          <br />
+          <el-link
+            href="https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console"
+            type="primary"
+            target="_blank"
+            >https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=console</el-link
+          >
+          <br />
+          闃块噷浜戞湇鍔″櫒鎶樻墸鍖�
+          <el-link href="http://aly.ruoyi.vip" type="primary" target="_blank"
+            >>鈽涒槢鐐规垜杩涘叆鈽氣槡</el-link
+          >
+          &nbsp;&nbsp;&nbsp; 鑵捐浜戞湇鍔″櫒绉掓潃鍖�
+          <el-link href="http://txy.ruoyi.vip" type="primary" target="_blank"
+            >>鈽涒槢鐐规垜杩涘叆鈽氣槡</el-link
+          ><br />
+          <h4 class="text-danger">
+            浜戜骇鍝侀�氱敤绾㈠寘锛屽彲鍙犲姞瀹樼綉甯歌浼樻儬浣跨敤銆�(浠呴檺鏂扮敤鎴�)
+          </h4>
+        </blockquote>
+
+        <hr />
+      </el-col>
+    </el-row>
+    <el-row :gutter="20">
+      <el-col :sm="24" :lg="12" style="padding-left: 20px">
+        <h2>鑻ヤ緷鍚庡彴绠$悊妗嗘灦</h2>
+        <p>
+          涓�鐩存兂鍋氫竴娆惧悗鍙扮鐞嗙郴缁燂紝鐪嬩簡寰堝浼樼鐨勫紑婧愰」鐩絾鏄彂鐜版病鏈夊悎閫傝嚜宸辩殑銆備簬鏄埄鐢ㄧ┖闂蹭紤鎭椂闂村紑濮嬭嚜宸卞啓涓�濂楀悗鍙扮郴缁熴�傚姝ゆ湁浜嗚嫢渚濈鐞嗙郴缁燂紝濂瑰彲浠ョ敤浜庢墍鏈夌殑Web搴旂敤绋嬪簭锛屽缃戠珯绠$悊鍚庡彴锛岀綉绔欎細鍛樹腑蹇冿紝CMS锛孋RM锛孫A绛夌瓑锛屽綋鐒讹紝鎮ㄤ篃鍙互瀵瑰ス杩涜娣卞害瀹氬埗锛屼互鍋氬嚭鏇村己绯荤粺銆傛墍鏈夊墠绔悗鍙颁唬鐮佸皝瑁呰繃鍚庡崄鍒嗙簿绠�鏄撲笂鎵嬶紝鍑洪敊姒傜巼浣庛�傚悓鏃舵敮鎸佺Щ鍔ㄥ鎴风璁块棶銆傜郴缁熶細闄嗙画鏇存柊涓�浜涘疄鐢ㄥ姛鑳姐��
+        </p>
+        <p>
+          <b>褰撳墠鐗堟湰:</b> <span>v{{ version }}</span>
+        </p>
+        <p>
+          <el-tag type="danger">&yen;鍏嶈垂寮�婧�</el-tag>
+        </p>
+        <p>
+          <el-button
+            type="primary"
+            size="mini"
+            icon="el-icon-cloudy"
+            plain
+            @click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
+            >璁块棶鐮佷簯</el-button
+          >
+          <el-button
+            size="mini"
+            icon="el-icon-s-home"
+            plain
+            @click="goTarget('http://ruoyi.vip')"
+            >璁块棶涓婚〉</el-button
+          >
+        </p>
+      </el-col>
+
+      <el-col :sm="24" :lg="12" style="padding-left: 50px">
+        <el-row>
+          <el-col :span="12">
+            <h2>鎶�鏈�夊瀷</h2>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="6">
+            <h4>鍚庣鎶�鏈�</h4>
+            <ul>
+              <li>SpringBoot</li>
+              <li>Spring Security</li>
+              <li>JWT</li>
+              <li>MyBatis</li>
+              <li>Druid</li>
+              <li>Fastjson</li>
+              <li>...</li>
+            </ul>
+          </el-col>
+          <el-col :span="6">
+            <h4>鍓嶇鎶�鏈�</h4>
+            <ul>
+              <li>Vue</li>
+              <li>Vuex</li>
+              <li>Element-ui</li>
+              <li>Axios</li>
+              <li>Sass</li>
+              <li>Quill</li>
+              <li>...</li>
+            </ul>
+          </el-col>
+        </el-row>
+      </el-col>
+    </el-row>
+    <el-divider />
+    <el-row :gutter="20">
+      <el-col :xs="24" :sm="24" :md="12" :lg="8">
+        <el-card class="update-log">
+          <div slot="header" class="clearfix">
+            <span>鑱旂郴淇℃伅</span>
+          </div>
+          <div class="body">
+            <p>
+              <i class="el-icon-s-promotion"></i> 瀹樼綉锛�<el-link
+                href="http://www.ruoyi.vip"
+                target="_blank"
+                >http://www.ruoyi.vip</el-link
+              >
+            </p>
+            <p>
+              <i class="el-icon-user-solid"></i> QQ缇わ細<s> 婊�937441 </s> <s> 婊�887144332 </s>
+              <s> 婊�180251782 </s> <s> 婊�104180207 </s> <s> 婊�186866453 </s> <s> 婊�201396349 </s>
+              <s> 婊�101456076 </s> <s> 婊�101539465 </s> <s> 婊�264312783 </s> <s> 婊�167385320 </s> 
+              <s> 婊�104748341 </s> <s> 婊�160110482 </s> <s> 婊�170801498 </s> <s> 婊�108482800 </s> 
+              <s> 婊�101046199 </s> <s> 婊�136919097 </s> <s> 婊�143961921 </s> <s> 婊�174951577 </s> 
+              <s> 婊�161281055 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063" target="_blank">138988063</a>
+            </p>
+            <p>
+              <i class="el-icon-chat-dot-round"></i> 寰俊锛�<a
+                href="javascript:;"
+                >/ *鑻ヤ緷</a
+              >
+            </p>
+            <p>
+              <i class="el-icon-money"></i> 鏀粯瀹濓細<a
+                href="javascript:;"
+                class="鏀粯瀹濅俊鎭�"
+                >/ *鑻ヤ緷</a
+              >
+            </p>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :xs="24" :sm="24" :md="12" :lg="8">
+        <el-card class="update-log">
+          <div slot="header" class="clearfix">
+            <span>鏇存柊鏃ュ織</span>
+          </div>
+          <el-collapse accordion>
+            <el-collapse-item title="v3.8.7 - 2023-12-08">
+              <ol>
+                <li>鎿嶄綔鏃ュ織璁板綍閮ㄩ棬鍚嶇О</li>
+                <li>鍏ㄥ眬鏁版嵁瀛樺偍鐢ㄦ埛缂栧彿</li>
+                <li>鏂板缂栫▼寮忓垽鏂祫婧愯闂潈闄�</li>
+                <li>鎿嶄綔鏃ュ織鍒楄〃鏂板IP鍦板潃鏌ヨ</li>
+                <li>瀹氭椂浠诲姟鏂板椤靛幓闄ょ姸鎬侀�夐」</li>
+                <li>浠g爜鐢熸垚鏀寔閫夋嫨鍓嶇妯℃澘绫诲瀷</li>
+                <li>鏄鹃殣鍒楃粍浠舵敮鎸佸閫夋寮瑰嚭绫诲瀷</li>
+                <li>閫氱敤鎺掑簭灞炴�rderBy鍙傛暟闄愬埗闀垮害</li>
+                <li>Excel鑷畾涔夋暟鎹鐞嗗櫒澧炲姞鍗曞厓鏍�/宸ヤ綔绨垮璞�</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.4.8</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈�1.2.20</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.43</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.7</li>
+                <li>鍗囩骇commons.io鍒版渶鏂扮増鏈�2.13.0</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.14</li>
+                <li>淇浜旂骇璺敱缂撳瓨鏃犳晥闂</li>
+                <li>淇澶栭摼甯︾鍙e嚭鐜扮殑寮傚父</li>
+                <li>淇鏍戞ā鏉跨埗绾х紪鐮佸彉閲忛敊璇�</li>
+                <li>淇瀛楀吀琛ㄨ鎯呴〉闈㈡悳绱㈤棶棰�</li>
+                <li>淇鍐呴摼iframe娌℃湁浼犻�掑弬鏁伴棶棰�</li>
+                <li>淇鑷畾涔夊瓧鍏告牱寮忎笉鐢熸晥鐨勯棶棰�</li>
+                <li>淇瀛楀吀缂撳瓨鍒犻櫎鏂规硶鍙傛暟閿欒闂</li>
+                <li>淇Excel瀵煎叆鏁版嵁涓存椂鏂囦欢鏃犳硶鍒犻櫎闂</li>
+                <li>淇鏈櫥褰曞甫鍙傛暟璁块棶鎴愬姛鍚庡弬鏁颁涪澶遍棶棰�</li>
+                <li>淇HeaderSearch缁勪欢璺宠浆query鍙傛暟涓㈠け闂</li>
+                <li>淇浠g爜鐢熸垚瀵煎叆鍚庡繀濉」涓庢暟鎹簱涓嶅尮閰嶉棶棰�</li>
+                <li>淇Excels瀵煎叆鏃舵棤娉曡幏鍙栧埌dictType瀛楀吀鍊奸棶棰�</li>
+                <li>浼樺寲涓嬭浇zip鏂规硶鏂板閬僵灞�</li>
+                <li>浼樺寲澶村儚涓婁紶鍙傛暟鏂板鏂囦欢鍚嶇О</li>
+                <li>浼樺寲瀛楀吀鏍囩鏀寔鑷畾涔夊垎闅旂</li>
+                <li>浼樺寲鑿滃崟绠$悊绫诲瀷涓烘寜閽姸鎬佸彲閫�</li>
+                <li>浼樺寲鍓嶇闃查噸澶嶆彁浜ゆ暟鎹ぇ灏忛檺鍒�</li>
+                <li>浼樺寲TopNav鑿滃崟娌℃湁鍥炬爣svg涓嶆樉绀�</li>
+                <li>浼樺寲鏁板瓧閲戦澶у啓杞崲绮惧害涓㈠け闂</li>
+                <li>浼樺寲瀵屾枃鏈珽ditor缁勪欢妫�楠屽浘鐗囨牸寮�</li>
+                <li>浼樺寲椤电鍦‵irefox娴忚鍣ㄨ閬尅鐨勯棶棰�</li>
+                <li>浼樺寲涓汉涓績/鍩烘湰璧勬枡淇敼鏃舵暟鎹樉绀洪棶棰�</li>
+                <li>浼樺寲缂撳瓨鐩戞帶鍥捐〃鏀寔璺熼殢灞忓箷澶у皬鑷�傚簲璋冩暣</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.6 - 2023-06-30">
+              <ol>
+                <li>鏀寔鐧诲綍IP榛戝悕鍗曢檺鍒�</li>
+                <li>鏂板鐩戞帶椤甸潰鍥炬爣鏄剧ず</li>
+                <li>鎿嶄綔鏃ュ織鏂板娑堣�楁椂闂村睘鎬�</li>
+                <li>灞忚斀瀹氭椂浠诲姟bean杩濊鐨勫瓧绗�</li>
+                <li>鏃ュ織绠$悊浣跨敤绱㈠紩鎻愬崌鏌ヨ鎬ц兘</li>
+                <li>鏃ュ織娉ㄨВ鏀寔鎺掗櫎鎸囧畾鐨勮姹傚弬鏁�</li>
+                <li>鏀寔鑷畾涔夐殣钘忓睘鎬у垪杩囨护瀛愬璞�</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.4.3</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈�1.2.16</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.34</li>
+                <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.15</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.13</li>
+                <li>绉婚櫎apache/commons-fileupload渚濊禆</li>
+                <li>淇椤甸潰鍒囨崲鏃跺竷灞�閿欎贡鐨勯棶棰�</li>
+                <li>淇鍖垮悕娉ㄨВAnonymous绌烘寚閽堥棶棰�</li>
+                <li>淇璺敱璺宠浆琚樆姝㈡椂鍐呴儴浜х敓鎶ラ敊淇℃伅闂</li>
+                <li>淇isMatchedIp鐨勫弬鏁板垽鏂骇鐢熺┖鎸囬拡鐨勯棶棰�</li>
+                <li>淇鐢ㄦ埛澶氳鑹叉暟鎹潈闄愬彲鑳藉嚭鐜版潈闄愭姮鍗囩殑鎯呭喌</li>
+                <li>淇寮�鍚疶opNav鍚庝竴绾ц彍鍗曡矾鐢卞弬鏁拌缃棤鏁堥棶棰�</li>
+                <li>淇DictTag缁勪欢value娌℃湁鍖归厤鐨勫�兼椂鍒欏睍绀簐alue</li>
+                <li>浼樺寲鏂囦欢涓嬭浇鍑虹幇鐨勫紓甯�</li>
+                <li>浼樺寲閫夋嫨鍥炬爣缁勪欢楂樹寒鍥炴樉</li>
+                <li>浼樺寲寮圭獥鍚庡鑸爮鍋忕Щ鐨勯棶棰�</li>
+                <li>浼樺寲淇敼瀵嗙爜鏃ュ織瀛樺偍鏄庢枃闂</li>
+                <li>浼樺寲椤电鏍忓叧闂叾浠栧嚭鐜扮殑寮傚父闂</li>
+                <li>浼樺寲椤电鍏抽棴宸︿晶閫夐」鎺掗櫎棣栭〉閫夐」</li>
+                <li>浼樺寲鍏抽棴褰撳墠tab椤佃烦杞渶鍙充晶tab椤�</li>
+                <li>浼樺寲缂撳瓨鍒楄〃娓呴櫎鎿嶄綔鎻愮ず涓嶅彉鐨勯棶棰�</li>
+                <li>浼樺寲瀛楃鏈娇鐢ㄤ笅鍒掔嚎涓嶈繘琛岄┘宄板紡澶勭悊</li>
+                <li>浼樺寲鐢ㄦ埛瀵煎叆鏇存柊鏃堕渶鑾峰彇鐢ㄦ埛缂栧彿闂</li>
+                <li>浼樺寲渚ц竟鏍忕殑骞冲彴鏍囬涓嶸UE_APP_TITLE淇濇寔鍚屾</li>
+                <li>浼樺寲瀵煎嚭Excel鏃惰缃甦ictType灞炴�ч噸澶嶆煡缂撳瓨闂</li>
+                <li>杩炴帴姹燚ruid鏀寔鏂扮殑閰嶇疆connectTimeout鍜宻ocketTimeout</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.5 - 2023-01-01">
+              <ol>
+                <li>瀹氭椂浠诲姟杩濊鐨勫瓧绗�</li>
+                <li>閲嶇疆鏃跺彇娑堥儴闂ㄩ�変腑</li>
+                <li>鏂板杩斿洖璀﹀憡娑堟伅鎻愮ず</li>
+                <li>蹇界暐涓嶅繀瑕佺殑灞炴�ф暟鎹繑鍥�</li>
+                <li>淇敼鍙傛暟閿悕鏃剁Щ闄ゅ墠缂撳瓨閰嶇疆</li>
+                <li>瀵煎叆鏇存柊鐢ㄦ埛鏁版嵁鍓嶆牎楠屾暟鎹潈闄�</li>
+                <li>鍏煎Excel涓嬫媺妗嗗唴瀹硅繃澶氭棤娉曟樉绀虹殑闂</li>
+                <li>鍗囩骇echarts鍒版渶鏂扮増鏈�5.4.0</li>
+                <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.25.3</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.4.0</li>
+                <li>鍗囩骇kaptcha鍒版渶鏂扮増2.3.3</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈�1.2.15</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.20</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.6</li>
+                <li>浼樺寲寮圭獥鍐呭杩囧灞曠ず涓嶅叏闂</li>
+                <li>浼樺寲swagger-ui闈欐�佽祫婧愪娇鐢ㄧ紦瀛�</li>
+                <li>寮�鍚疶opNav娌℃湁瀛愯彍鍗曢殣钘忎晶杈规爮</li>
+                <li>鍒犻櫎fuse鏃犳晥閫夐」maxPatternLength</li>
+                <li>浼樺寲瀵煎嚭瀵硅薄鐨勫瓙鍒楄〃涓虹┖浼氬嚭鐜癧]闂</li>
+                <li>浼樺寲缂栬緫澶村儚鏃堕�忔槑閮ㄥ垎浼氬彉鎴愰粦鑹查棶棰�</li>
+                <li>浼樺寲灏忓睆骞曚笂淇敼澶村儚鐣岄潰甯冨眬閿欎綅鐨勯棶棰�</li>
+                <li>淇浠g爜鐢熸垚鍕鹃�夊睘鎬ф棤鏁堥棶棰�</li>
+                <li>淇鏂囦欢涓婁紶缁勪欢鏍煎紡楠岃瘉闂</li>
+                <li>淇鍥炴樉鏁版嵁瀛楀吀鏁扮粍寮傚父闂</li>
+                <li>淇sheet瓒呭嚭鏈�澶ц鏁板紓甯搁棶棰�</li>
+                <li>淇Log娉ㄨВGET璇锋眰璁板綍涓嶅埌鍙傛暟闂</li>
+                <li>淇璋冨害鏃ュ織鐐瑰嚮澶氭鏁版嵁涓嶅彉鍖栫殑闂</li>
+                <li>淇涓婚棰滆壊鍦―rawer缁勪欢涓嶄細鍔犺浇闂</li>
+                <li>淇鏂囦欢鍚嶅寘鍚壒娈婂瓧绗︾殑鏂囦欢鏃犳硶涓嬭浇闂</li>
+                <li>淇table涓洿澶氭寜閽垏鎹富棰樿壊鏈敓鏁堜慨澶嶉棶棰�</li>
+                <li>淇鏌愪簺鐗规�х殑鐜鐢熸垚浠g爜鍙樹贡鐮乀XT鏂囦欢闂</li>
+                <li>淇浠g爜鐢熸垚鍥剧墖/鏂囦欢/鍗曢�夋椂閫夋嫨蹇呭~鏃犳硶鏍¢獙闂</li>
+                <li>淇鏌愪簺鐗规�х殑鎯呭喌鐢ㄦ埛缂栬緫瀵硅瘽妗嗕腑瑙掕壊鍜岄儴闂ㄦ棤娉曚慨鏀归棶棰�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.4 - 2022-09-26">
+              <ol>
+                <li>鏁版嵁閫昏緫鍒犻櫎涓嶈繘琛屽敮涓�楠岃瘉</li>
+                <li>Excel娉ㄨВ鏀寔瀵煎嚭瀵硅薄鐨勫瓙鍒楄〃鏂规硶</li>
+                <li>Excel娉ㄨВ鏀寔鑷畾涔夐殣钘忓睘鎬у垪</li>
+                <li>Excel娉ㄨВ鏀寔backgroundColor灞炴�ц缃儗鏅壊</li>
+                <li>鏀寔閰嶇疆瀵嗙爜鏈�澶ч敊璇鏁�/閿佸畾鏃堕棿</li>
+                <li>鐧诲綍鏃ュ織鏂板瑙i攣璐︽埛鍔熻兘</li>
+                <li>閫氱敤涓嬭浇鏂规硶鏂板config閰嶇疆閫夐」</li>
+                <li>鏀寔澶氭潈闄愬瓧绗﹀尮閰嶈鑹叉暟鎹潈闄�</li>
+                <li>椤甸潰鍐呭祵iframe鍒囨崲tab涓嶅埛鏂版暟鎹�</li>
+                <li>鎿嶄綔鏃ュ織璁板綍鏀寔鎺掗櫎鏁忔劅灞炴�у瓧娈�</li>
+                <li>淇澶氭枃浠朵笂浼犳姤閿欏嚭鐜扮殑寮傚父闂</li>
+                <li>淇鍥剧墖棰勮缁勪欢src灞炴�т负null鍊兼帶鍒跺彴鎶ラ敊闂</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.2.2</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.14</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.3</li>
+                <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.25.2</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.10</li>
+                <li>浼樺寲浠诲姟杩囨湡涓嶆墽琛岃皟搴�</li>
+                <li>浼樺寲瀛楀吀鏁版嵁浣跨敤store瀛樺彇</li>
+                <li>浼樺寲淇敼璧勬枡澶村儚琚鐩栫殑闂</li>
+                <li>浼樺寲淇敼鐢ㄦ埛鐧诲綍璐﹀彿閲嶅楠岃瘉</li>
+                <li>浼樺寲浠g爜鐢熸垚鍚屾鍚庡�糔ULL闂</li>
+                <li>浼樺寲瀹氭椂浠诲姟鏀寔鎵ц鐖剁被鏂规硶</li>
+                <li>浼樺寲鐢ㄦ埛涓汉淇℃伅鎺ュ彛闃叉淇敼閮ㄩ棬</li>
+                <li>浼樺寲甯冨眬璁剧疆浣跨敤el-drawer鎶藉眽鏄剧ず</li>
+                <li>浼樺寲娌℃湁鏉冮檺鐨勭敤鎴风紪杈戦儴闂ㄧ己灏戞暟鎹�</li>
+                <li>浼樺寲鏃ュ織娉ㄨВ璁板綍闄愬埗璇锋眰鍦板潃鐨勯暱搴�</li>
+                <li>浼樺寲excel/scale灞炴�у鍑哄崟鍏冩牸鏁板�肩被鍨�</li>
+                <li>浼樺寲鏃ュ織鎿嶄綔涓噸缃寜閽椂閲嶅鏌ヨ鐨勯棶棰�</li>
+                <li>浼樺寲澶氫釜鐩稿悓瑙掕壊鏁版嵁瀵艰嚧鏉冮檺SQL閲嶅闂</li>
+                <li>浼樺寲琛ㄦ牸涓婂彸渚у伐鍏锋潯锛堟悳绱㈡寜閽樉闅�&鍙充晶鏍峰紡鍑稿嚭锛�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.3 - 2022-06-27">
+              <ol>
+                <li>鏂板缂撳瓨鍒楄〃鑿滃崟鍔熻兘</li>
+                <li>浠g爜鐢熸垚鏍戣〃鏂板(灞曞紑/鎶樺彔)</li>
+                <li>Excel娉ㄨВ鏀寔color瀛椾綋棰滆壊</li>
+                <li>鏂板Anonymous鍖垮悕璁块棶涓嶉壌鏉冩敞瑙�</li>
+                <li>鐢ㄦ埛澶村儚涓婁紶闄愬埗鍙兘涓哄浘鐗囨牸寮�</li>
+                <li>鎺ュ彛浣跨敤娉涘瀷浣垮叾鐪嬪埌鍝嶅簲灞炴�у瓧娈�</li>
+                <li>妫�鏌ュ畾鏃朵换鍔ean鎵�鍦ㄥ寘鍚嶆槸鍚︿负鐧藉悕鍗曢厤缃�</li>
+                <li>娣诲姞椤电openPage鏀寔浼犻�掑弬鏁�</li>
+                <li>鐢ㄦ埛缂撳瓨淇℃伅娣诲姞閮ㄩ棬ancestors绁栫骇鍒楄〃</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.8</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.1.6</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈�1.2.11</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増2.0.8</li>
+                <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.14</li>
+                <li>闄嶇骇jsencrypt鐗堟湰鍏煎IE娴忚鍣�</li>
+                <li>鍒犻櫎澶氫綑鐨剆alt瀛楁</li>
+                <li>鏂板鑾峰彇涓嶅甫鍚庣紑鏂囦欢鍚嶇О鏂规硶</li>
+                <li>鏂板鑾峰彇閰嶇疆鏂囦欢涓殑灞炴�у�兼柟娉�</li>
+                <li>鏂板鍐呭缂栫爜/瑙g爜鏂逛究鎻掍欢闆嗘垚浣跨敤</li>
+                <li>瀛楀吀绫诲瀷蹇呴』浠ュ瓧姣嶅紑澶达紝涓斿彧鑳戒负锛堝皬鍐欏瓧姣嶏紝鏁板瓧锛屼笅婊戠嚎锛�</li>
+                <li>浼樺寲璁剧疆鍒嗛〉鍙傛暟榛樿鍊�</li>
+                <li>浼樺寲瀵圭┖瀛楃涓插弬鏁板鐞嗙殑杩囨护</li>
+                <li>浼樺寲鏄剧ず椤哄簭orderNum绫诲瀷涓烘暣鍨�</li>
+                <li>浼樺寲琛ㄥ崟鏋勫缓鎸夐挳涓嶆樉绀烘鍒欐牎楠�</li>
+                <li>浼樺寲瀛楀吀鏁版嵁鍥炴樉鏍峰紡涓嬫媺妗嗘樉绀哄��</li>
+                <li>浼樺寲R鍝嶅簲鎴愬姛鐘舵�佺爜涓庡叏灞�淇濇寔涓�鑷�</li>
+                <li>浼樺寲druid寮�鍚痺all杩囨护鍣ㄥ嚭鐜扮殑寮傚父闂</li>
+                <li>浼樺寲鐢ㄦ埛绠$悊宸︿晶鏍戝瀷缁勪欢澧炲姞閫変腑楂樹寒淇濇寔</li>
+                <li>浼樺寲鏂板鐢ㄦ埛涓庤鑹蹭俊鎭�&鐢ㄦ埛涓庡矖浣嶄俊鎭�昏緫</li>
+                <li>浼樺寲榛樿涓嶅惎鐢ㄥ帇缂╂枃浠剁紦瀛橀槻姝ode_modules杩囧ぇ</li>
+                <li>淇瀛楀吀鏁版嵁鏄剧ず涓嶅叏闂</li>
+                <li>淇鎿嶄綔鏃ュ織鏌ヨ绫诲瀷鏉′欢涓�0鏃朵細鏌ュ埌鎵�鏈夋暟鎹�</li>
+                <li>淇Excel娉ㄨВprompt/combo鍚屾椂浣跨敤涓嶇敓鏁堥棶棰�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.2 - 2022-04-01">
+              <ol>
+                <li>鍓嶇鏀寔璁剧疆鏄惁闇�瑕侀槻姝㈡暟鎹噸澶嶆彁浜�</li>
+                <li>寮�鍚疶opNav娌℃湁瀛愯彍鍗曟儏鍐甸殣钘忎晶杈规爮</li>
+                <li>渚ц竟鏍忚彍鍗曞悕绉拌繃闀挎偓鍋滄樉绀烘爣棰�</li>
+                <li>鐢ㄦ埛璁块棶鎺у埗鏃舵牎楠屾暟鎹潈闄愶紝闃叉瓒婃潈</li>
+                <li>瀵煎嚭Excel鏃跺睆钄藉叕寮忥紝闃叉CSV娉ㄥ叆椋庨櫓</li>
+                <li>缁勪欢ImagePreview鏀寔澶氬浘棰勮鏄剧ず</li>
+                <li>缁勪欢ImageUpload鏀寔澶氬浘鍚屾椂閫夋嫨涓婁紶</li>
+                <li>缁勪欢FileUpload鏀寔澶氭枃浠跺悓鏃堕�夋嫨涓婁紶</li>
+                <li>鏈嶅姟鐩戞帶鏂板杩愯鍙傛暟淇℃伅鏄剧ず</li>
+                <li>瀹氭椂浠诲姟鐩爣瀛楃涓茶繃婊ょ壒娈婂瓧绗�</li>
+                <li>瀹氭椂浠诲姟鐩爣瀛楃涓查獙璇佸寘鍚嶇櫧鍚嶅崟</li>
+                <li>浠g爜鐢熸垚鍒楄〃鍥剧墖鏀寔棰勮</li>
+                <li>浠g爜鐢熸垚缂栬緫淇敼鎵撳紑鏂伴〉绛�</li>
+                <li>浠g爜鐢熸垚鏂板Java绫诲瀷Boolean</li>
+                <li>浠g爜鐢熸垚瀛愯〃鏀寔鏃ユ湡/瀛楀吀閰嶇疆</li>
+                <li>浠g爜鐢熸垚鍚屾淇濈暀蹇呭~/绫诲瀷閫夐」</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈�6.1.2</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.80</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.1</li>
+                <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.11</li>
+                <li>鍗囩骇spring-boot-mybatis鍒版渶鏂扮増2.2.2</li>
+                <li>娣诲姞閬楁紡鐨勫垎椤靛弬鏁板悎鐞嗗寲灞炴��</li>
+                <li>淇敼npm鍗冲皢杩囨湡鐨勬敞鍐屾簮鍦板潃</li>
+                <li>淇鍒嗛〉缁勪欢璇锋眰涓ゆ闂</li>
+                <li>淇閫氱敤鏂囦欢涓嬭浇鎺ュ彛璺ㄥ煙闂</li>
+                <li>淇Xss娉ㄨВ瀛楁鍊间负绌烘椂鐨勫紓甯搁棶棰�</li>
+                <li>淇閫夐」鍗$偣鍑诲彸閿埛鏂颁涪澶卞弬鏁伴棶棰�</li>
+                <li>淇琛ㄥ崟娓呴櫎鍏冪礌浣嶇疆鏈瀭鐩村眳涓棶棰�</li>
+                <li>淇鏈嶅姟鐩戞帶涓繍琛屽弬鏁版樉绀烘潯浠堕敊璇�</li>
+                <li>淇瀵煎叆Excel鏃跺瓧鍏稿瓧娈电被鍨嬩负Long杞箟涓虹┖闂</li>
+                <li>淇鐧诲綍瓒呮椂鍒锋柊椤甸潰璺宠浆鐧诲綍椤甸潰杩樻彁绀洪噸鏂扮櫥褰曢棶棰�</li>
+                <li>浼樺寲鍔犺浇瀛楀吀缂撳瓨鏁版嵁</li>
+                <li>浼樺寲IP鍦板潃鑾峰彇鍒板涓殑闂</li>
+                <li>浼樺寲浠诲姟闃熷垪婊℃椂浠诲姟鎷掔粷绛栫暐</li>
+                <li>浼樺寲鏂囦欢涓婁紶鍏煎Weblogic鐜</li>
+                <li>浼樺寲瀹氭椂浠诲姟榛樿淇濆瓨鍒板唴瀛樹腑鎵ц</li>
+                <li>浼樺寲閮ㄩ棬淇敼缂╂斁鍚庡嚭鐜扮殑閿欎綅闂</li>
+                <li>浼樺寲Excel鏍煎紡鍖栦笉鍚岀被鍨嬬殑鏃ユ湡瀵硅薄</li>
+                <li>浼樺寲鑿滃崟琛ㄥ叧閿瓧瀵艰嚧鐨勬彃浠舵姤閿欓棶棰�</li>
+                <li>浼樺寲Oracle鐢ㄦ埛澶村儚鍒椾负绌烘椂涓嶆樉绀洪棶棰�</li>
+                <li>浼樺寲椤甸潰鑻ユ湭鍖归厤鍒板瓧鍏告爣绛惧垯杩斿洖鍘熷瓧鍏稿��</li>
+                <li>浼樺寲淇鐧诲綍澶辨晥鍚庡娆¤姹傛彁绀哄娆″脊绐楅棶棰�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.1 - 2022-01-01">
+              <ol>
+                <li>鏂板Vue3鍓嶇浠g爜鐢熸垚妯℃澘</li>
+                <li>鏂板鍥剧墖棰勮缁勪欢</li>
+                <li>鏂板鍘嬬缉鎻掍欢瀹炵幇鎵撳寘Gzip</li>
+                <li>鑷畾涔墄ss鏍¢獙娉ㄨВ瀹炵幇</li>
+                <li>鑷畾涔夋枃瀛楀鍒跺壀璐存寚浠�</li>
+                <li>浠g爜鐢熸垚棰勮鏀寔澶嶅埗鍐呭</li>
+                <li>璺敱鏀寔鍗曠嫭閰嶇疆鑿滃崟鎴栬鑹叉潈闄�</li>
+                <li>鐢ㄦ埛绠$悊閮ㄩ棬鏌ヨ閫夋嫨鑺傜偣鍚庡垎椤靛弬鏁板垵濮�</li>
+                <li>淇鐢ㄦ埛鍒嗛厤瑙掕壊灞炴�ч敊璇�</li>
+                <li>淇鎵撳寘鍚庡瓧浣撳浘鏍囧伓鐜扮殑涔辩爜闂</li>
+                <li>淇鑿滃崟绠$悊閲嶇疆琛ㄥ崟鍑虹幇鐨勯敊璇�</li>
+                <li>淇鐗堟湰宸紓瀵艰嚧鐨勬噿鍔犺浇鎶ラ敊闂</li>
+                <li>淇Cron缁勪欢涓懆鍥炴樉闂</li>
+                <li>淇瀹氭椂浠诲姟澶氬弬鏁伴�楀彿鍒嗛殧鐨勯棶棰�</li>
+                <li>淇鏍规嵁ID鏌ヨ鍒楄〃鍙兘鍑虹幇鐨勪富閿孩鍑洪棶棰�</li>
+                <li>淇tomcat閰嶇疆鍙傛暟宸茶繃鏈熼棶棰�</li>
+                <li>鍗囩骇clipboard鍒版渶鏂扮増鏈�2.0.8</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.8.6</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.79</li>
+                <li>鍗囩骇spring-boot鍒版渶鏂扮増鏈�2.5.8</li>
+                <li>鍗囩骇log4j2鍒�2.17.1锛岄槻姝㈡紡娲為闄�</li>
+                <li>浼樺寲涓嬭浇瑙f瀽blob寮傚父鎻愮ず</li>
+                <li>浼樺寲浠g爜鐢熸垚瀛楀吀缁勯噸澶嶉棶棰�</li>
+                <li>浼樺寲鏌ヨ鐢ㄦ埛鐨勮鑹茬粍&宀椾綅缁勪唬鐮�</li>
+                <li>浼樺寲瀹氭椂浠诲姟cron琛ㄨ揪寮忓皬鏃惰缃�24</li>
+                <li>浼樺寲鐢ㄦ埛瀵煎叆鎻愮ず婧㈠嚭鍒欐樉绀烘粴鍔ㄦ潯</li>
+                <li>浼樺寲闃查噸澶嶆彁浜ゆ爣璇嗙粍鍚堜负(key+url+header)</li>
+                <li>浼樺寲鍒嗛〉鏂规硶璁剧疆鎴愰�氱敤鏂逛究鐏垫椿璋冪敤</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.8.0 - 2021-12-01">
+              <ol>
+                <li>鏂板閰嶅骞跺悓姝ョ殑Vue3鍓嶇鐗堟湰</li>
+                <li>鏂板閫氱敤鏂规硶绠�鍖栨ā鎬�/缂撳瓨/涓嬭浇/鏉冮檺/椤电浣跨敤</li>
+                <li>浼樺寲瀵煎嚭鏁版嵁/浣跨敤閫氱敤涓嬭浇鏂规硶</li>
+                <li>Excel娉ㄨВ鏀寔鑷畾涔夋暟鎹鐞嗗櫒</li>
+                <li>Excel娉ㄨВ鏀寔瀵煎叆瀵煎嚭鏍囬淇℃伅</li>
+                <li>Excel瀵煎叆鏀寔@Excels娉ㄨВ</li>
+                <li>鏂板缁勪欢data-dict锛岀畝鍖栨暟鎹瓧鍏镐娇鐢�</li>
+                <li>鏂板Jaxb渚濊禆锛岄槻姝dk8浠ヤ笂鍑虹幇鐨勫吋瀹归敊璇�</li>
+                <li>鐢熶骇鐜浣跨敤璺敱鎳掑姞杞芥彁鍗囬〉闈㈠搷搴旈�熷害</li>
+                <li>淇浜旂骇浠ヤ笂鑿滃崟鍑虹幇鐨�404闂</li>
+                <li>闃查噸鎻愪氦娉ㄨВ鏀寔閰嶇疆闂撮殧鏃堕棿/鎻愮ず娑堟伅</li>
+                <li>鏃ュ織娉ㄨВ鏂板鏄惁淇濆瓨鍝嶅簲鍙傛暟</li>
+                <li>浠诲姟灞忚斀杩濊瀛楃&鍙傛暟蹇界暐鍙屽紩鍙蜂腑鐨勯�楀彿</li>
+                <li>鍗囩骇SpringBoot鍒版渶鏂扮増鏈�2.5.6</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.4.0</li>
+                <li>鍗囩骇spring-boot-mybatis鍒版渶鏂扮増2.2.0</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.8.2</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増1.2.8</li>
+                <li>鍗囩骇velocity鍒版渶鏂扮増鏈�2.3</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.78</li>
+                <li>鍗囩骇axios鍒版渶鏂扮増鏈�0.24.0</li>
+                <li>鍗囩骇dart-sass鍒扮増鏈�1.32.13</li>
+                <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.19.1</li>
+                <li>鍗囩骇jsencrypt鍒版渶鏂扮増鏈�3.2.1</li>
+                <li>鍗囩骇js-cookie鍒版渶鏂扮増鏈�3.0.1</li>
+                <li>鍗囩骇file-saver鍒版渶鏂扮増鏈�2.0.5</li>
+                <li>鍗囩骇sass-loader鍒版渶鏂扮増鏈�10.1.1</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.6</li>
+                <li>鏂板sendGet鏃犲弬璇锋眰鏂规硶</li>
+                <li>绂佺敤el-tag缁勪欢鐨勬笎鍙樺姩鐢�</li>
+                <li>浠g爜鐢熸垚鐐瑰嚮棰勮閲嶇疆婵�娲籺ab</li>
+                <li>AjaxResult閲嶅啓put鏂规硶锛屼互鏂逛究閾惧紡璋冪敤</li>
+                <li>浼樺寲鐧诲綍/楠岃瘉鐮佽姹俬eaders涓嶈缃畉oken</li>
+                <li>浼樺寲鐢ㄦ埛涓汉淇℃伅鎺ュ彛闃叉淇敼鐢ㄦ埛鍚�</li>
+                <li>浼樺寲Cron琛ㄨ揪寮忕敓鎴愬櫒鍏抽棴鏃堕攢姣侀伩鍏嶇紦瀛�</li>
+                <li>浼樺寲娉ㄥ唽鎴愬姛鎻愮ず娑堟伅绫诲瀷success</li>
+                <li>浼樺寲aop璇硶锛屼娇鐢╯pring鑷姩娉ㄥ叆娉ㄨВ</li>
+                <li>浼樺寲璁板綍鐧诲綍淇℃伅锛岀Щ闄や笉蹇呰鐨勪慨鏀�</li>
+                <li>浼樺寲mybatis鍏ㄥ眬榛樿鐨勬墽琛屽櫒</li>
+                <li>浼樺寲Excel瀵煎叆鍥剧墖鍙兘鍑虹幇鐨勫紓甯�</li>
+                <li>淇浠g爜鐢熸垚妯℃澘涓诲瓙琛ㄥ垹闄ょ己灏戜簨鍔�</li>
+                <li>淇鏃ュ織璁板綍鍙兘鍑虹幇鐨勮浆鎹㈠紓甯�</li>
+                <li>淇浠g爜鐢熸垚澶嶉�夋瀛楀吀閬楁紡闂</li>
+                <li>淇鍏抽棴xss鍔熻兘瀵艰嚧鍙噸澶嶈RepeatableFilter澶辨晥</li>
+                <li>淇瀛楃涓叉棤娉曡鍙嶈浆涔夐棶棰�</li>
+                <li>淇鍚庣涓诲瓙琛ㄤ唬鐮佹ā鏉挎柟娉曞悕鐢熸垚閿欒闂</li>
+                <li>淇xss杩囨护鍚庢牸寮忓嚭鐜扮殑寮傚父</li>
+                <li>淇swagger娌℃湁鎸囧畾dataTypeClass瀵艰嚧鍚姩鍑虹幇warn鏃ュ織</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.7.0 - 2021-09-13">
+              <ol>
+                <li>鍙傛暟绠$悊鏀寔閰嶇疆楠岃瘉鐮佸紑鍏�</li>
+                <li>鏂板鏄惁寮�鍚敤鎴锋敞鍐屽姛鑳�</li>
+                <li>瀹氭椂浠诲姟鏀寔鍦ㄧ嚎鐢熸垚cron琛ㄨ揪寮�</li>
+                <li>鑿滃崟绠$悊鏀寔閰嶇疆璺敱鍙傛暟</li>
+                <li>鏀寔鑷畾涔夋敞瑙e疄鐜版帴鍙i檺娴�</li>
+                <li>Excel娉ㄨВ鏀寔Image鍥剧墖瀵煎叆</li>
+                <li>鑷畾涔夊脊灞傛孩鍑烘粴鍔ㄦ牱寮�</li>
+                <li>鑷畾涔夊彲鎷栧姩寮圭獥瀹藉害鎸囦护</li>
+                <li>鑷畾涔夊彲鎷栧姩寮圭獥楂樺害鎸囦护</li>
+                <li>淇浠绘剰璐︽埛瓒婃潈闂</li>
+                <li>淇敼鏃舵鏌ョ敤鎴锋暟鎹潈闄愯寖鍥�</li>
+                <li>淇淇濆瓨閰嶇疆涓婚棰滆壊澶辨晥闂</li>
+                <li>鏂板鏆楄壊鑿滃崟椋庢牸涓婚</li>
+                <li>鑿滃崟&閮ㄩ棬鏂板灞曞紑/鎶樺彔鍔熻兘</li>
+                <li>椤电鏂板鍏抽棴宸︿晶&娣诲姞鍥炬爣</li>
+                <li>椤堕儴鑿滃崟鎺掗櫎闅愯棌鐨勯粯璁よ矾鐢�</li>
+                <li>椤堕儴鑿滃崟鍚屾绯荤粺涓婚鏍峰紡</li>
+                <li>璺宠浆璺敱楂樹寒鐩稿搴旂殑鑿滃崟鏍�</li>
+                <li>浠g爜鐢熸垚涓诲瓙琛ㄥ閫夎鏁版嵁</li>
+                <li>鏃ユ湡鑼冨洿鏀寔娣诲姞澶氱粍</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.5</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.8.0</li>
+                <li>鍗囩骇commons.io鍒版渶鏂扮増鏈瑅2.11.0</li>
+                <li>瀹氭椂浠诲姟灞忚斀ldap杩滅▼璋冪敤</li>
+                <li>瀹氭椂浠诲姟灞忚斀http(s)杩滅▼璋冪敤</li>
+                <li>琛ュ厖瀹氭椂浠诲姟琛ㄥ瓧娈垫敞閲�</li>
+                <li>瀹氭椂浠诲姟瀵规鏌ュ紓甯歌繘琛屼簨鍔″洖婊�</li>
+                <li>鍚敤鐖堕儴闂ㄧ姸鎬佹帓闄ら《绾ц妭鐐�</li>
+                <li>瀵屾枃鏈柊澧炰笂浼犳枃浠跺ぇ灏忛檺鍒�</li>
+                <li>榛樿棣栭〉浣跨敤keep-alive缂撳瓨</li>
+                <li>淇敼浠g爜鐢熸垚瀛楀吀鍥炴樉鏍峰紡</li>
+                <li>鑷畾涔夊垎椤靛悎鐞嗗寲浼犲叆鍙傛暟</li>
+                <li>淇瀛楀吀缁勪欢鍊间负鏁村舰涓嶆樉绀洪棶棰�</li>
+                <li>淇瀹氭椂浠诲姟鏃ュ織鎵ц鐘舵�佹樉绀�</li>
+                <li>瑙掕壊&鑿滃崟鏂板瀛楁灞炴�ф彁绀轰俊鎭�</li>
+                <li>淇瑙掕壊鍒嗛厤鐢ㄦ埛椤甸潰鍙傛暟绫诲瀷閿欒鎻愰啋</li>
+                <li>浼樺寲甯冨眬璁剧疆鍔ㄧ敾鐗规晥</li>
+                <li>浼樺寲寮傚父澶勭悊淇℃伅</li>
+                <li>浼樺寲閿欒token瀵艰嚧鐨勮В鏋愬紓甯�</li>
+                <li>瀵嗙爜妗嗘柊澧炴樉绀哄垏鎹㈠瘑鐮佸浘鏍�</li>
+                <li>瀹氭椂浠诲姟鏂板鏇村鎿嶄綔</li>
+                <li>鏇村鎿嶄綔鎸夐挳娣诲姞鏉冮檺鎺у埗</li>
+                <li>瀵煎叆鐢ㄦ埛鏍峰紡浼樺寲</li>
+                <li>鎻愬彇閫氱敤鏂规硶鍒板熀绫绘帶鍒跺櫒</li>
+                <li>浼樺寲浣跨敤鏉冮檺宸ュ叿鑾峰彇鐢ㄦ埛淇℃伅</li>
+                <li>浼樺寲鐢ㄦ埛涓嶈兘鍒犻櫎鑷繁</li>
+                <li>浼樺寲XSS璺ㄧ珯鑴氭湰杩囨护</li>
+                <li>浼樺寲浠g爜鐢熸垚妯℃澘</li>
+                <li>楠岃瘉鐮侀粯璁�20s瓒呮椂</li>
+                <li>BLOB涓嬭浇鏃舵竻闄RL瀵硅薄寮曠敤</li>
+                <li>浠g爜鐢熸垚瀵煎叆琛ㄦ寜鍒涘缓鏃堕棿鎺掑簭</li>
+                <li>淇浠g爜鐢熸垚椤甸潰鏁版嵁缂栬緫淇濆瓨涔嬪悗鎬绘槸璺宠浆绗竴椤电殑闂</li>
+                <li>淇甯afari娴忚鍣ㄦ棤娉曟牸寮忓寲utc鏃ユ湡鏍煎紡yyyy-MM-dd'T'HH:mm:ss.SSS闂</li>
+                <li>澶氬浘涓婁紶缁勪欢绉婚櫎澶氫綑鐨刟pi鍦板潃&楠岃瘉澶辫触瀵艰嚧鍥剧墖鍒犻櫎闂&鏃犳硶鍒犻櫎鐩稿簲鍥剧墖淇</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.6.0 - 2021-07-12">
+              <ol>
+                <li>瑙掕壊绠$悊鏂板鍒嗛厤鐢ㄦ埛鍔熻兘</li>
+                <li>鐢ㄦ埛绠$悊鏂板鍒嗛厤瑙掕壊鍔熻兘</li>
+                <li>鏃ュ織鍒楄〃鏀寔鎺掑簭鎿嶄綔</li>
+                <li>浼樺寲鍙傛暟&瀛楀吀缂撳瓨鎿嶄綔</li>
+                <li>绯荤粺甯冨眬閰嶇疆鏀寔鍔ㄦ�佹爣棰樺紑鍏�</li>
+                <li>鑿滃崟璺敱閰嶇疆鏀寔鍐呴摼璁块棶</li>
+                <li>榛樿璁块棶鍚庣棣栭〉鏂板鎻愮ず璇�</li>
+                <li>瀵屾枃鏈粯璁や笂浼犺繑鍥瀠rl绫诲瀷</li>
+                <li>鏂板鑷畾涔夊脊绐楁嫋鎷芥寚浠�</li>
+                <li>鍏ㄥ眬娉ㄥ唽甯哥敤閫氱敤缁勪欢</li>
+                <li>鍏ㄥ眬鎸傝浇瀛楀吀鏍囩缁勪欢</li>
+                <li>ImageUpload缁勪欢鏀寔澶氬浘鐗囦笂浼�</li>
+                <li>FileUpload缁勪欢鏀寔澶氭枃浠朵笂浼�</li>
+                <li>鏂囦欢涓婁紶缁勪欢娣诲姞鏁伴噺闄愬埗灞炴��</li>
+                <li>瀵屾枃鏈紪杈戠粍浠舵坊鍔犵被鍨嬪睘鎬�</li>
+                <li>瀵屾枃鏈粍浠跺伐鍏锋爮閰嶇疆瑙嗛</li>
+                <li>灏佽閫氱敤iframe缁勪欢</li>
+                <li>闄愬埗瓒呯骇绠$悊鍛樹笉鍏佽鎿嶄綔</li>
+                <li>鐢ㄦ埛淇℃伅闀垮害鏍¢獙闄愬埗</li>
+                <li>鍒嗛〉缁勪欢鏂板pagerCount灞炴��</li>
+                <li>娣诲姞bat鑴氭湰鎵ц搴旂敤</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.7.4</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.2</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.3.1</li>
+                <li>鍗囩骇commons.io鍒版渶鏂扮増鏈瑅2.10.0</li>
+                <li>鍗囩骇commons.fileupload鍒版渶鏂扮増鏈瑅1.4</li>
+                <li>鍗囩骇swagger鍒版渶鏂扮増鏈瑅3.0.0</li>
+                <li>淇鍏抽棴confirm鎻愮ず妗嗘帶鍒跺彴鎶ラ敊闂</li>
+                <li>淇瀛樺湪鐨凷QL娉ㄥ叆婕忔礊闂</li>
+                <li>瀹氭椂浠诲姟灞忚斀rmi杩滅▼璋冪敤</li>
+                <li>淇鐢ㄦ埛鎼滅储鍒嗛〉鍙橀噺閿欒</li>
+                <li>淇瀵煎嚭瑙掕壊鏁版嵁鑼冨洿缈昏瘧缂哄皯浠呮湰浜�</li>
+                <li>淇琛ㄥ崟鏋勫缓閫夋嫨涓嬫媺閫夋嫨鎺у埗鍙版姤閿欓棶棰�</li>
+                <li>浼樺寲鍥剧墖宸ュ叿绫昏鍙栨枃浠�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.5.0 - 2021-05-25">
+              <ol>
+                <li>鏂板鑿滃崟瀵艰埅鏄剧ず椋庢牸TopNav锛坒alse涓哄乏渚у鑸彍鍗曪紝true涓洪《閮ㄥ鑸彍鍗曪級</li>
+                <li>甯冨眬璁剧疆鏀寔淇濆瓨&閲嶇疆閰嶇疆</li>
+                <li>淇鏍戣〃鏁版嵁鏄剧ず涓嶅叏&鍔犺浇鎱㈤棶棰�</li>
+                <li>鏂板IE娴忚鍣ㄧ増鏈繃浣庢彁绀洪〉闈�</li>
+                <li>鐢ㄦ埛鐧诲綍鍚庤褰曟渶鍚庣櫥褰旾P&鏃堕棿</li>
+                <li>椤甸潰瀵煎嚭鎸夐挳鐐瑰嚮涔嬪悗娣诲姞閬僵</li>
+                <li>瀵屾枃鏈紪杈戝櫒鏀寔鑷畾涔変笂浼犲湴鍧�</li>
+                <li>瀵屾枃鏈紪杈戠粍浠舵柊澧瀝eadOnly灞炴��</li>
+                <li>椤电TagsView鏂板鍏抽棴鍙充晶鍔熻兘</li>
+                <li>鏄鹃殣鍒楃粍浠跺姞杞藉垵濮嬮粯璁ら殣钘忓垪</li>
+                <li>鍏抽棴澶村儚涓婁紶绐楀彛杩樺師榛樿鍥剧墖</li>
+                <li>涓汉淇℃伅娣诲姞鎵嬫満&閭閲嶅楠岃瘉</li>
+                <li>浠g爜鐢熸垚妯℃澘瀵煎嚭鎸夐挳鐐瑰嚮鍚庢坊鍔犻伄缃�</li>
+                <li>浠g爜鐢熸垚妯℃澘鏍戣〃鎿嶄綔鍒楁坊鍔犳柊澧炴寜閽�</li>
+                <li>浠g爜鐢熸垚妯℃澘淇涓诲瓙琛ㄥ瓧娈甸噸鍚嶉棶棰�</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.76</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.6</li>
+                <li>鍗囩骇mybatis鍒版渶鏂扮増3.5.6 闃绘杩滅▼浠g爜鎵ц婕忔礊</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.6.0</li>
+                <li>velocity鍓旈櫎commons-collections鐗堟湰锛岄槻姝�3.2.1鐗堟湰鐨勫弽搴忓垪鍖栨紡娲�</li>
+                <li>鏁版嵁鐩戞帶椤甸粯璁よ处鎴峰瘑鐮侀槻姝㈣秺鏉冭闂�</li>
+                <li>淇firefox涓嬭〃鍗曟瀯寤烘嫋鎷戒細鏂版墦鍗′竴涓�夐」鍗�</li>
+                <li>淇鍚庣瀵煎叆琛ㄦ潈闄愭爣璇�</li>
+                <li>淇鍓嶇鎿嶄綔鏃ュ織&鐧诲綍鏃ュ織鏉冮檺鏍囪瘑</li>
+                <li>璁剧疆Redis閰嶇疆HashKey搴忓垪鍖�</li>
+                <li>鍒犻櫎鎿嶄綔鏃ュ織璁板綍淇℃伅</li>
+                <li>涓婁紶濯掍綋绫诲瀷娣诲姞瑙嗛鏍煎紡</li>
+                <li>淇璇锋眰褰㈠弬鏈紶鍊艰褰曟棩蹇楀紓甯搁棶棰�</li>
+                <li>浼樺寲xss鏍¢獙json璇锋眰鏉′欢</li>
+                <li>鏍戠骇缁撴瀯鏇存柊瀛愯妭鐐逛娇鐢╮eplaceFirst</li>
+                <li>浼樺寲ExcelUtil绌哄�煎鐞�</li>
+                <li>鏃ュ織璁板綍杩囨护BindingResult瀵硅薄锛岄槻姝㈠紓甯�</li>
+                <li>淇敼涓婚鍚巑ini绫诲瀷鎸夐挳鏃犳晥闂</li>
+                <li>浼樺寲閫氱敤涓嬭浇瀹屾垚鍚庡垹闄よ妭鐐�</li>
+                <li>閫氱敤Controller娣诲姞鍝嶅簲杩斿洖娑堟伅</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.4.0 - 2021-02-22">
+              <ol>
+                <li>浠g爜鐢熸垚妯℃澘鏀寔涓诲瓙琛�</li>
+                <li>琛ㄦ牸鍙充晶宸ュ叿鏍忕粍浠舵敮鎸佹樉闅愬垪</li>
+                <li>鍥剧墖缁勪欢娣诲姞棰勮&绉婚櫎鍔熻兘</li>
+                <li>Excel娉ㄨВ鏀寔Image鍥剧墖瀵煎嚭</li>
+                <li>鎿嶄綔鎸夐挳缁勮皟鏁翠负鏈寸礌鎸夐挳鏍峰紡</li>
+                <li>浠g爜鐢熸垚鏀寔鏂囦欢涓婁紶缁勪欢</li>
+                <li>浠g爜鐢熸垚鏃ユ湡鎺т欢鍖哄垎鑼冨洿</li>
+                <li>浠g爜鐢熸垚鏁版嵁搴撴枃鏈被鍨嬬敓鎴愯〃鍗曟枃鏈煙</li>
+                <li>鐢ㄦ埛鎵嬫満閭&鑿滃崟缁勪欢淇敼鍏佽绌哄瓧绗︿覆</li>
+                <li>鍗囩骇SpringBoot鍒版渶鏂扮増鏈�2.2.13 鎻愬崌鍚姩閫熷害</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.4</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.75</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.15.0</li>
+                <li>淇IE11娴忚鍣ㄦ姤閿欓棶棰�</li>
+                <li>浼樺寲澶氱骇鑿滃崟涔嬮棿鍒囨崲鏃犳硶缂撳瓨鐨勯棶棰�</li>
+                <li>淇鍥涚骇鑿滃崟鏃犳硶鏄剧ず闂</li>
+                <li>淇渚ц竟鏍忛潤鎬佽矾鐢变涪澶遍棶棰�</li>
+                <li>淇瑙掕壊绠$悊-缂栬緫瑙掕壊-鍔熻兘鏉冮檺鏄剧ず寮傚父</li>
+                <li>閰嶇疆鏂囦欢鏂板redis鏁版嵁搴撶储寮曞睘鎬�</li>
+                <li>鏉冮檺宸ュ叿绫诲鍔燼dmin鍒ゆ柇</li>
+                <li>瑙掕壊闈炶嚜瀹氫箟鏉冮檺鑼冨洿娓呯┖閫夋嫨鍊�</li>
+                <li>淇瀵煎叆鏁版嵁涓鸿礋娴偣鏁版椂涓㈠け绮惧害闂</li>
+                <li>绉婚櫎path-to-regexp姝e垯鍖归厤鎻掍欢</li>
+                <li>淇鐢熸垚鏍戣〃浠g爜寮傚父</li>
+                <li>淇敼ip瀛楁闀垮害闃叉ipv6鍦板潃闀垮害涓嶅</li>
+                <li>闃叉get璇锋眰鍙傛暟鍊间负false鎴�0绛夌壒娈婂�间細瀵艰嚧鏃犳硶姝g‘鐨勪紶鍙�</li>
+                <li>鐧诲綍鍚巔ush娣诲姞catch闃叉鍑虹幇妫�鏌ラ敊璇�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.3.0 - 2020-12-14">
+              <ol>
+                <li>鏂板缂撳瓨鐩戞帶鍔熻兘</li>
+                <li>鏀寔涓婚椋庢牸閰嶇疆</li>
+                <li>淇澶氱骇鑿滃崟涔嬮棿鍒囨崲鏃犳硶缂撳瓨鐨勯棶棰�</li>
+                <li>澶氱骇鑿滃崟鑷姩閰嶇疆缁勪欢</li>
+                <li>浠g爜鐢熸垚棰勮鏀寔楂樹寒鏄剧ず</li>
+                <li>鏀寔Get璇锋眰鏄犲皠Params鍙傛暟</li>
+                <li>鍒犻櫎鐢ㄦ埛鍜岃鑹茶В缁戝叧鑱�</li>
+                <li>鍘婚櫎鐢ㄦ埛鎵嬫満閭閮ㄩ棬蹇呭~楠岃瘉</li>
+                <li>Excel鏀寔娉ㄨВalign瀵归綈鏂瑰紡</li>
+                <li>Excel鏀寔瀵煎叆Boolean鍨嬫暟鎹�</li>
+                <li>浼樺寲澶村儚鏍峰紡锛岄紶鏍囩Щ鍏ユ偓鍋滈伄缃�</li>
+                <li>浠g爜鐢熸垚棰勮鎻愪緵婊氬姩鏈哄埗</li>
+                <li>浠g爜鐢熸垚鍒犻櫎澶氫綑鐨勬暟瀛梖loat绫诲瀷</li>
+                <li>淇杞崲瀛楃涓茬殑鐩爣瀛楃闆嗗睘鎬�</li>
+                <li>鍥炴樉鏁版嵁瀛楀吀闃叉绌哄�兼姤閿�</li>
+                <li>鏃ュ織璁板綍澧炲姞杩囨护澶氭枃浠跺満鏅�</li>
+                <li>淇敼缂撳瓨Set鏂规硶鍙兘瀵艰嚧宓屽鐨勯棶棰�</li>
+                <li>绉婚櫎鍓嶇涓�浜涘浣欑殑渚濊禆</li>
+                <li>闃叉瀹夊叏鎵弿YUI鍑虹幇鐨勯闄╂彁绀�</li>
+                <li>淇敼node-sass涓篸art-sass</li>
+                <li>鍗囩骇SpringBoot鍒版渶鏂扮増鏈�2.1.18</li>
+                <li>鍗囩骇poi鍒版渶鏂扮増鏈�4.1.2</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.3.6</li>
+                <li>鍗囩骇bitwalker鍒版渶鏂扮増鏈�1.21</li>
+                <li>鍗囩骇axios鍒版渶鏂扮増鏈�0.21.0</li>
+                <li>鍗囩骇element-ui鍒版渶鏂扮増鏈�2.14.1</li>
+                <li>鍗囩骇vue鍒版渶鏂扮増鏈�2.6.12</li>
+                <li>鍗囩骇vuex鍒版渶鏂扮増鏈�3.6.0</li>
+                <li>鍗囩骇vue-cli鍒扮増鏈�4.5.9</li>
+                <li>鍗囩骇vue-router鍒版渶鏂扮増鏈�3.4.9</li>
+                <li>鍗囩骇vue-cli鍒版渶鏂扮増鏈�4.4.6</li>
+                <li>鍗囩骇vue-cropper鍒版渶鏂扮増鏈�0.5.5</li>
+                <li>鍗囩骇clipboard鍒版渶鏂扮増鏈�2.0.6</li>
+                <li>鍗囩骇core-js鍒版渶鏂扮増鏈�3.8.1</li>
+                <li>鍗囩骇echarts鍒版渶鏂扮増鏈�4.9.0</li>
+                <li>鍗囩骇file-saver鍒版渶鏂扮増鏈�2.0.4</li>
+                <li>鍗囩骇fuse.js鍒版渶鏂扮増鏈�6.4.3</li>
+                <li>鍗囩骇js-beautify鍒版渶鏂扮増鏈�1.13.0</li>
+                <li>鍗囩骇js-cookie鍒版渶鏂扮増鏈�2.2.1</li>
+                <li>鍗囩骇path-to-regexp鍒版渶鏂扮増鏈�6.2.0</li>
+                <li>鍗囩骇quill鍒版渶鏂扮増鏈�1.3.7</li>
+                <li>鍗囩骇screenfull鍒版渶鏂扮増鏈�5.0.2</li>
+                <li>鍗囩骇sortablejs鍒版渶鏂扮増鏈�1.10.2</li>
+                <li>鍗囩骇vuedraggable鍒版渶鏂扮増鏈�2.24.3</li>
+                <li>鍗囩骇chalk鍒版渶鏂扮増鏈�4.1.0</li>
+                <li>鍗囩骇eslint鍒版渶鏂扮増鏈�7.15.0</li>
+                <li>鍗囩骇eslint-plugin-vue鍒版渶鏂扮増鏈�7.2.0</li>
+                <li>鍗囩骇lint-staged鍒版渶鏂扮増鏈�10.5.3</li>
+                <li>鍗囩骇runjs鍒版渶鏂扮増鏈�4.4.2</li>
+                <li>鍗囩骇sass-loader鍒版渶鏂扮増鏈�10.1.0</li>
+                <li>鍗囩骇script-ext-html-webpack-plugin鍒版渶鏂扮増鏈�2.1.5</li>
+                <li>鍗囩骇svg-sprite-loader鍒版渶鏂扮増鏈�5.1.1</li>
+                <li>鍗囩骇vue-template-compiler鍒版渶鏂扮増鏈�2.6.12</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.2.1 - 2020-11-18">
+              <ol>
+                <li>闃绘浠绘剰鏂囦欢涓嬭浇婕忔礊</li>
+                <li>浠g爜鐢熸垚鏀寔涓婁紶鎺т欢</li>
+                <li>鏂板鍥剧墖涓婁紶缁勪欢</li>
+                <li>璋冩暣榛樿棣栭〉</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.2</li>
+                <li>mapperLocations閰嶇疆鏀寔鍒嗛殧绗�</li>
+                <li>鏉冮檺淇℃伅璋冩暣</li>
+                <li>璋冩暣sql榛樿鏃堕棿</li>
+                <li>瑙e喅浠g爜鐢熸垚娌℃湁bit绫诲瀷鐨勯棶棰�</li>
+                <li>鍗囩骇pagehelper鍒版渶鏂扮増1.3.0</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v3.2.0 - 2020-10-10">
+              <ol>
+                <li>鍗囩骇springboot鐗堟湰鍒�2.1.17 鎻愬崌瀹夊叏鎬�</li>
+                <li>鍗囩骇oshi鍒版渶鏂扮増鏈瑅5.2.5</li>
+                <li>鍗囩骇druid鍒版渶鏂扮増鏈瑅1.2.1</li>
+                <li>鍗囩骇jjwt鍒扮増鏈�0.9.1</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.74</li>
+                <li>淇敼sass涓簄ode-sass锛岄伩鍏峞l-icon鍥炬爣涔辩爜</li>
+                <li>浠g爜鐢熸垚鏀寔鍚屾鏁版嵁搴�</li>
+                <li>浠g爜鐢熸垚鏀寔瀵屾枃鏈帶浠�</li>
+                <li>浠g爜鐢熸垚椤甸潰鏃朵笉蹇界暐remark灞炴��</li>
+                <li>浠g爜鐢熸垚娣诲姞select蹇呭~閫夐」</li>
+                <li>Excel瀵煎嚭绫诲瀷NUMERIC鏀寔绮惧害娴偣绫诲瀷</li>
+                <li>Excel瀵煎嚭targetAttr浼樺寲鑾峰彇鍊硷紝闃叉get鏂规硶涓嶈鑼�</li>
+                <li>Excel娉ㄨВ鏀寔鑷姩缁熻鏁版嵁鎬诲拰</li>
+                <li>Excel娉ㄨВ鏀寔璁剧疆BigDecimal绮惧害&鑸嶅叆瑙勫垯</li>
+                <li>鑿滃崟&鏁版嵁鏉冮檺鏂板锛堝睍寮�/鎶樺彔 鍏ㄩ��/鍏ㄤ笉閫� 鐖跺瓙鑱斿姩锛�</li>
+                <li>鍏佽鐢ㄦ埛鍒嗛厤鍒伴儴闂ㄧ埗鑺傜偣</li>
+                <li>鑿滃崟鏂板鏄惁缂撳瓨keep-alive</li>
+                <li>琛ㄦ牸鎿嶄綔鍒楅棿璺濊皟鏁�</li>
+                <li>闄愬埗绯荤粺鍐呯疆鍙傛暟涓嶅厑璁稿垹闄�</li>
+                <li>瀵屾枃鏈粍浠朵紭鍖栵紝鏀寔鑷畾涔夐珮搴�&鍥剧墖鍐茬獊闂</li>
+                <li>瀵屾枃鏈伐鍏锋爮鏍峰紡瀵归綈</li>
+                <li>瀵煎叆excel鏁村舰鍊兼牎楠屼紭鍖�</li>
+                <li>淇椤电鍏抽棴鎵�鏈夋椂鍥哄畾鏍囩璺敱涓嶅埛鏂伴棶棰�</li>
+                <li>琛ㄥ崟鏋勫缓甯冨眬鍨嬬粍浠舵柊澧炴寜閽�</li>
+                <li>宸︿晶鑿滃崟鏂囧瓧杩囬暱鏄剧ず鐪佺暐鍙�</li>
+                <li>淇鏍硅妭鐐逛负瀛愰儴闂ㄦ椂锛屾爲鐘剁粨鏋勬樉绀洪棶棰�</li>
+                <li>淇璋冪敤鐩爣瀛楃涓叉渶澶ч暱搴�</li>
+                <li>淇鑿滃崟鎻愮ず淇℃伅閿欒</li>
+                <li>淇瀹氭椂浠诲姟鎵ц涓�娆℃潈闄愭爣璇�</li>
+                <li>淇鏁版嵁搴撳瓧绗︿覆绫诲瀷nvarchar</li>
+                <li>浼樺寲閫掑綊瀛愯妭鐐�</li>
+                <li>浼樺寲鏁版嵁鏉冮檺鍒ゆ柇</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+
+            <el-collapse-item title="v3.1.0 - 2020-08-13">
+              <ol>
+                <li>琛ㄦ牸宸ュ叿鏍忓彸渚ф坊鍔犲埛鏂�&鏄鹃殣鏌ヨ缁勪欢</li>
+                <li>鍚庣鏀寔CORS璺ㄥ煙璇锋眰</li>
+                <li>浠g爜鐢熸垚鏀寔閫夋嫨涓婄骇鑿滃崟</li>
+                <li>浠g爜鐢熸垚鏀寔鑷畾涔夎矾寰�</li>
+                <li>浠g爜鐢熸垚鏀寔澶嶉�夋</li>
+                <li>Excel瀵煎嚭瀵煎叆鏀寔dictType瀛楀吀绫诲瀷</li>
+                <li>Excel鏀寔鍒嗗壊瀛楃涓茬粍鍐呭</li>
+                <li>楠岃瘉鐮佺被鍨嬫敮鎸侊紙鏁扮粍璁$畻銆佸瓧绗﹂獙璇侊級</li>
+                <li>鍗囩骇vue-cli鐗堟湰鍒�4.4.4</li>
+                <li>淇敼 node-sass 涓� dart-sass</li>
+                <li>琛ㄥ崟绫诲瀷涓篒nteger/Long璁剧疆鏁村舰榛樿鍊�</li>
+                <li>浠g爜鐢熸垚鍣ㄩ粯璁apper璺緞涓庨粯璁apperScan璺緞涓嶄竴鑷�</li>
+                <li>浼樺寲闃查噸澶嶆彁浜ゆ嫤鎴櫒</li>
+                <li>浼樺寲涓婄骇鑿滃崟涓嶈兘閫夋嫨鑷繁</li>
+                <li>淇瑙掕壊鐨勬潈闄愬垎閰嶅悗锛屾湭瀹炴椂鐢熸晥闂</li>
+                <li>淇鍦ㄧ嚎鐢ㄦ埛鏃ュ織璁板綍绫诲瀷</li>
+                <li>淇瀵屾枃鏈┖鏍煎拰缂╄繘淇濆瓨鍚庝笉鐢熸晥闂</li>
+                <li>淇鍦ㄧ嚎鐢ㄦ埛鍒ゆ柇閫昏緫</li>
+                <li>鍞竴闄愬埗鏉′欢鍙繑鍥炲崟鏉℃暟鎹�</li>
+                <li>娣诲姞鑾峰彇褰撳墠鐨勭幆澧冮厤缃柟娉�</li>
+                <li>瓒呮椂鐧诲綍鍚庨〉闈㈣烦杞埌棣栭〉</li>
+                <li>鍏ㄥ眬寮傚父鐘舵�佹眽鍖栨嫤鎴鐞�</li>
+                <li>HTML杩囨护鍣ㄦ敼涓哄皢html杞箟</li>
+                <li>妫�鏌ュ瓧绗︽敮鎸佸皬鏁扮偣&闄嶇骇鏀规垚寮傚父鎻愰啋</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+
+            <el-collapse-item title="v3.0.0 - 2020-07-20">
+              <ol>
+                <li>鍗曞簲鐢ㄨ皟鏁翠负澶氭ā鍧楅」鐩�</li>
+                <li>鍗囩骇element-ui鐗堟湰鍒�2.13.2</li>
+                <li>鍒犻櫎babel锛屾彁楂樼紪璇戦�熷害銆�</li>
+                <li>鏂板鑿滃崟榛樿涓荤被鐩�</li>
+                <li>缂栫爜鏂囦欢鍚嶄慨鏀逛负uuid鏂瑰紡</li>
+                <li>瀹氭椂浠诲姟cron琛ㄨ揪寮忛獙璇�</li>
+                <li>瑙掕壊鏉冮檺淇敼鏃跺凡鏈夋潈闄愭湭鑷姩鍕鹃�夊紓甯镐慨澶�</li>
+                <li>闃叉鍒囨崲鏉冮檺鐢ㄦ埛鍚庣櫥褰曞嚭鐜�404</li>
+                <li>Excel鏀寔sort瀵煎嚭鎺掑簭</li>
+                <li>鍒涘缓鐢ㄦ埛涓嶅厑璁搁�夋嫨瓒呯骇绠$悊鍛樿鑹�</li>
+                <li>淇浠g爜鐢熸垚瀵煎叆琛ㄧ粨鏋勫嚭鐜板紓甯搁〉闈笉鎻愰啋闂</li>
+                <li>淇浠g爜鐢熸垚鐐瑰嚮澶氭琛ㄤ慨鏀规暟鎹笉鍙樺寲鐨勯棶棰�</li>
+                <li>淇澶村儚涓婁紶鎴愬姛浜屾鎵撳紑鏃犳硶鏀瑰彉瑁佸壀妗嗗ぇ灏忓拰浣嶇疆闂</li>
+                <li>淇甯冨眬涓簊mall鑰卪ini鐢ㄦ埛琛ㄥ崟鏄剧ず閿欎綅闂</li>
+                <li>淇鐑儴缃插鑷寸殑寮烘崲寮傚父闂</li>
+                <li>淇敼鐢ㄦ埛绠$悊澶嶉�夋瀹藉害锛岄槻姝㈤儴鍒嗘祻瑙堝櫒鍑虹幇鐪佺暐鍙�</li>
+                <li>IpUtils宸ュ叿锛屾竻闄ss鐗规畩瀛楃锛岄槻姝ff娉ㄥ叆鏀诲嚮</li>
+                <li>鐢熸垚domain 濡傛灉鏄诞鐐瑰瀷 缁熶竴鐢˙igDecimal</li>
+                <li>瀹氭椂浠诲姟璋冩暣label-width锛岄槻姝㈤儴缃插嚭鐜伴敊浣�</li>
+                <li>璋冩暣琛ㄥご鍥哄畾鍒楅粯璁ゆ牱寮�</li>
+                <li>浠g爜鐢熸垚妯℃澘璋冩暣锛屽瓧娈典负String骞朵笖蹇呭~鍒欏姞绌轰覆鏉′欢</li>
+                <li>浠g爜鐢熸垚瀛楀吀Integer/Long浣跨敤parseInt</li>
+                <li>
+                  淇dict_sort涓嶅彲update涓�0鐨勯棶棰�&鏌ヨ杩斿洖澧炲姞dict_sort鍗囧簭鎺掑簭
+                </li>
+                <li>淇宀椾綅瀵煎嚭鏉冮檺娉ㄨВ</li>
+                <li>绂佹鍔犲瘑瀵嗘枃杩斿洖鍓嶇</li>
+                <li>淇浠g爜鐢熸垚椤甸潰涓殑鏌ヨ鏉′欢鍒涘缓鏃堕棿鏈敓鏁堢殑闂</li>
+                <li>淇棣栭〉鎼滅储鑿滃崟澶栭摼鏃犳硶鐐瑰嚮璺宠浆闂</li>
+                <li>淇鑿滃崟绠$悊閫夋嫨鍥炬爣锛宐ackspace鍒犻櫎鏃朵笉杩囨护鏁版嵁</li>
+                <li>鐢ㄦ埛绠$悊閮ㄩ棬鍒嗘敮鑺傜偣涓嶅彲妫�鏌�&鏄剧ず璁℃暟</li>
+                <li>鏁版嵁鑼冨洿杩囨护灞炴�ц皟鏁�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+
+            <el-collapse-item title="v2.3.0 - 2020-06-01">
+              <ol>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.70 淇楂樺嵄瀹夊叏婕忔礊</li>
+                <li>dev鍚姩榛樿鎵撳紑娴忚鍣�</li>
+                <li>vue-cli浣跨敤榛樿source-map</li>
+                <li>slidebar eslint鎶ラ敊浼樺寲</li>
+                <li>褰搕ags-view婊氬姩鍏抽棴鍙抽敭鑿滃崟</li>
+                <li>瀛楀吀绠$悊娣诲姞缂撳瓨璇诲彇</li>
+                <li>鍙傛暟绠$悊鏀寔缂撳瓨鎿嶄綔</li>
+                <li>鏀寔涓�绾ц彍鍗曪紙鍜屼富椤靛悓绾э級鍦╩ain鍖哄煙鏄剧ず</li>
+                <li>闄愬埗澶栭摼鍦板潃蹇呴』浠ttp(s)寮�澶�</li>
+                <li>tagview & sidebar 涓婚棰滆壊涓巈lement ui(鍏ㄥ眬)鍚屾</li>
+                <li>淇敼鏁版嵁婧愮被鍨嬩紭鍏堢骇锛屽厛鏍规嵁鏂规硶锛屽啀鏍规嵁绫�</li>
+                <li>鏀寔鏄惁闇�瑕佽缃畉oken灞炴�э紝鑷畾涔夎繑鍥炵爜娑堟伅銆�</li>
+                <li>swagger璇锋眰鍓嶇紑鍔犲叆閰嶇疆銆�</li>
+                <li>鐧诲綍鍦扮偣璁剧疆鍐呭杩囬暱鍒欓殣钘忔樉绀�</li>
+                <li>淇瀹氭椂浠诲姟鎵ц涓�娆℃寜閽悗涓嶆彁绀烘秷鎭棶棰�</li>
+                <li>淇敼涓婄骇閮ㄩ棬锛堥�夋嫨椤规帓闄ゆ湰韬拰涓嬬骇锛�</li>
+                <li>閫氱敤http鍙戦�佹柟娉曞鍔犲弬鏁� contentType 缂栫爜绫诲瀷</li>
+                <li>鏇存崲IP鍦板潃鏌ヨ鎺ュ彛</li>
+                <li>淇椤电鍙橀噺undefined</li>
+                <li>娣诲姞鏍¢獙閮ㄩ棬鍖呭惈鏈仠鐢ㄧ殑瀛愰儴闂�</li>
+                <li>淇敼瀹氭椂浠诲姟璇︽儏涓嬫鎵ц鏃堕棿鏃ユ湡鏄剧ず閿欒</li>
+                <li>瑙掕壊绠$悊鏌ヨ璁剧疆榛樿鎺掑簭瀛楁</li>
+                <li>swagger娣诲姞enable鍙傛暟鎺у埗鏄惁鍚敤</li>
+                <li>鍙json绫诲瀷璇锋眰鏋勫缓鍙噸澶嶈鍙杋nputStream鐨剅equest</li>
+                <li>淇敼浠g爜鐢熸垚瀛楀吀瀛楁int绫诲瀷娌℃湁鑷姩閫変腑闂</li>
+                <li>vuex鐢ㄦ埛鍚嶅彇鍊间慨姝�</li>
+                <li>琛ㄦ牸鏍戞ā鏉垮幓鎺夊浣欑殑)</li>
+                <li>浠g爜鐢熸垚搴忓彿淇</li>
+                <li>鍏ㄥ睆鎯呭喌涓嬩笉璋冩暣涓婂杈硅窛</li>
+                <li>浠g爜鐢熸垚Date瀛楁娣诲姞榛樿鏍煎紡</li>
+                <li>鐢ㄦ埛绠$悊瑙掕壊閫夋嫨鏉冮檺鎺у埗</li>
+                <li>淇璺敱鎳掑姞杞芥姤閿欓棶棰�</li>
+                <li>妯℃澘sql.vm娣诲姞鑿滃崟鐘舵��</li>
+                <li>璁剧疆鐢ㄦ埛鍚嶇О涓嶈兘淇敼</li>
+                <li>dialog娣诲姞append-to-body灞炴�э紝闃叉ie閬僵</li>
+                <li>鑿滃崟鍖哄垎鐘舵�佸拰鏄剧ず闅愯棌鍔熻兘</li>
+                <li>鍗囩骇fastjson鍒版渶鏂扮増1.2.68 淇瀹夊叏鍔犲浐</li>
+                <li>淇浠g爜鐢熸垚濡傛灉閫夋嫨瀛楀吀绫诲瀷缂哄け閫楀彿闂</li>
+                <li>鐧诲綍璇锋眰params鏇存崲涓篸ata锛岄槻姝㈡毚闇瞮rl</li>
+                <li>鏃ュ織杩斿洖鏃堕棿鏍煎紡澶勭悊</li>
+                <li>娣诲姞handle鎺у埗鍏佽鎷栧姩鐨勫厓绱�</li>
+                <li>甯冨眬璁剧疆鐐瑰嚮鎵╁ぇ鑼冨洿</li>
+                <li>浠g爜鐢熸垚鍒楀睘鎬ф帓搴忔煡璇�</li>
+                <li>浠g爜鐢熸垚鍒楁敮鎸佹嫋鍔ㄦ帓搴�</li>
+                <li>淇鏃堕棿鏍煎紡涓嶆敮鎸乮os闂</li>
+                <li>琛ㄥ崟鏋勫缓娣诲姞鐖剁骇class锛岄槻姝㈠啿绐�</li>
+                <li>瀹氭椂浠诲姟骞跺彂灞炴�т慨姝�</li>
+                <li>瑙掕壊绂佺敤&鑿滃崟闅愯棌涓嶆煡璇㈡潈闄�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+
+            <el-collapse-item title="v2.2.0 - 2020-03-18">
+              <ol>
+                <li>绯荤粺鐩戞帶鏂板瀹氭椂浠诲姟鍔熻兘</li>
+                <li>娣诲姞涓�涓墦鍖匴eb宸ョ▼bat</li>
+                <li>淇椤电榧犳爣婊氳疆鎸変笅鐨勬椂鍊欙紝鍙互鍏抽棴涓嶅彲鍏抽棴鐨則ag</li>
+                <li>淇鐐瑰嚮閫�鍑虹櫥褰曟湁鏃朵細鏃犳彁绀洪棶棰�</li>
+                <li>淇闃查噸澶嶆彁浜ゆ敞瑙f棤鏁堥棶棰�</li>
+                <li>淇閫氱煡鍏憡鎵归噺鍒犻櫎寮傚父闂</li>
+                <li>娣诲姞鑿滃崟鏃惰矾鐢卞湴鍧�蹇呭~闄愬埗</li>
+                <li>浠g爜鐢熸垚瀛楁鎻忚堪鍙紪杈�</li>
+                <li>淇鐢ㄦ埛淇敼涓汉淇℃伅瀵艰嚧缂撳瓨涓嶈繃鏈熼棶棰�</li>
+                <li>涓汉淇℃伅鍒涘缓鏃堕棿鑾峰彇姝g‘灞炴�у��</li>
+                <li>鎿嶄綔鏃ュ織璇︾粏鏄剧ず姝g‘绫诲瀷</li>
+                <li>瀵煎叆琛ㄥ崟鍑昏鏁版嵁鏃堕�変腑瀵瑰簲鐨勫閫夋</li>
+                <li>鎵归噺鏇挎崲琛ㄥ墠缂�閫昏緫璋冩暣</li>
+                <li>鍥哄畾閲嶅畾鍚戣矾寰勮〃杈惧紡</li>
+                <li>鍗囩骇element-ui鐗堟湰鍒�2.13.0</li>
+                <li>鎿嶄綔鏃ュ織鎺掑簭璋冩暣</li>
+                <li>淇charts鍒囨崲渚ц竟鏍忔垨鑰呯缉鏀剧獥鍙f樉绀篵ug</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+
+            <el-collapse-item title="v2.1.0 - 2020-02-24">
+              <ol>
+                <li>鏂板琛ㄥ崟鏋勫缓</li>
+                <li>浠g爜鐢熸垚鏀寔鏍戣〃缁撴瀯</li>
+                <li>鏂板鐢ㄦ埛瀵煎叆</li>
+                <li>淇鍔ㄦ�佸姞杞借矾鐢遍〉闈㈠埛鏂伴棶棰�</li>
+                <li>淇鍦板潃寮�鍏虫棤鏁堥棶棰�</li>
+                <li>姹夊寲閿欒鎻愮ず椤甸潰</li>
+                <li>浠g爜鐢熸垚宸茬煡闂淇敼</li>
+                <li>淇澶氭暟鎹簮涓嬮厤缃叧闂嚭鐜板紓甯稿鐞�</li>
+                <li>娣诲姞HTML杩囨护鍣紝鐢ㄤ簬鍘婚櫎XSS婕忔礊闅愭偅</li>
+                <li>淇涓婁紶澶村儚鎺у埗鍙板嚭鐜板紓甯�</li>
+                <li>淇敼鐢ㄦ埛绠$悊鍒嗛〉涓嶆纭殑闂</li>
+                <li>淇楠岃瘉鐮佽褰曟彁绀洪敊璇�</li>
+                <li>淇request.js缂哄皯Message寮曠敤</li>
+                <li>淇琛ㄦ牸鏃堕棿涓虹┖鍑虹幇鐨勫紓甯�</li>
+                <li>娣诲姞Jackson鏃ユ湡鍙嶅簭鍒楀寲鏃跺尯閰嶇疆</li>
+                <li>璋冩暣鏍规嵁鐢ㄦ埛鏉冮檺鍔犺浇鑿滃崟鏁版嵁鏍戝舰缁撴瀯</li>
+                <li>璋冩暣鎴愬姛鐧诲綍涓嶆仮澶嶆寜閽紝闃叉澶氭鐐瑰嚮</li>
+                <li>淇敼鐢ㄦ埛涓汉璧勬枡鍚屾缂撳瓨淇℃伅</li>
+                <li>淇椤甸潰鍚屾椂鍑虹幇el-upload鍜孍ditor涓嶆樉绀哄鐞�</li>
+                <li>淇鍦ㄨ鑹茬鐞嗛〉淇敼鑿滃崟鏉冮檺鍋跺皵鏈�変腑闂</li>
+                <li>閰嶇疆鏂囦欢鏂板redis瀵嗙爜灞炴��</li>
+                <li>璁剧疆mybatis鍏ㄥ眬鐨勯厤缃枃浠�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+
+            <el-collapse-item title="v2.0.0 - 2019-12-02">
+              <ol>
+                <li>鏂板浠g爜鐢熸垚</li>
+                <li>鏂板@RepeatSubmit娉ㄨВ锛岄槻姝㈤噸澶嶆彁浜�</li>
+                <li>鏂板鑿滃崟涓荤洰褰曟坊鍔�/鍒犻櫎鎿嶄綔</li>
+                <li>鏃ュ織璁板綍杩囨护鐗规畩瀵硅薄锛岄槻姝㈣浆鎹㈠紓甯�</li>
+                <li>淇敼浠g爜鐢熸垚璺敱鑴氭湰閿欒</li>
+                <li>鐢ㄦ埛涓婁紶澶村儚瀹炴椂鍚屾缂撳瓨锛屾棤闇�閲嶆柊鐧诲綍</li>
+                <li>璋冩暣鍒囨崲椤电鍚庝笉閲嶆柊鍔犺浇鏁版嵁</li>
+                <li>娣诲姞jsencrypt瀹炵幇鍙傛暟鐨勫墠绔姞瀵�</li>
+                <li>绯荤粺閫�鍑哄垹闄ょ敤鎴风紦瀛樿褰�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v1.1.0 - 2019-11-11">
+              <ol>
+                <li>鏂板鍦ㄧ嚎鐢ㄦ埛绠$悊</li>
+                <li>鏂板鎸夐挳缁勫姛鑳藉疄鐜帮紙鎵归噺鍒犻櫎銆佸鍑恒�佹竻绌猴級</li>
+                <li>鏂板鏌ヨ鏉′欢閲嶇疆鎸夐挳</li>
+                <li>鏂板Swagger鍏ㄥ眬Token閰嶇疆</li>
+                <li>鏂板鍚庣鍙傛暟鏍¢獙</li>
+                <li>淇瀛楀吀绠$悊椤甸潰鐨勬棩鏈熸煡璇㈠紓甯�</li>
+                <li>淇敼鏃堕棿鍑芥暟鍛藉悕闃叉鍐茬獊</li>
+                <li>鍘婚櫎鑿滃崟涓婄骇鏍¢獙锛岄粯璁や负椤剁骇</li>
+                <li>淇鐢ㄦ埛瀵嗙爜鏃犳硶淇敼闂</li>
+                <li>淇鑿滃崟绫诲瀷涓烘寜閽椂涓嶆樉绀烘潈闄愭爣璇�</li>
+                <li>鍏朵粬缁嗚妭浼樺寲</li>
+              </ol>
+            </el-collapse-item>
+            <el-collapse-item title="v1.0.0 - 2019-10-08">
+              <ol>
+                <li>鑻ヤ緷鍓嶅悗绔垎绂荤郴缁熸寮忓彂甯�</li>
+              </ol>
+            </el-collapse-item>
+          </el-collapse>
+        </el-card>
+      </el-col>
+      <el-col :xs="24" :sm="24" :md="12" :lg="8">
+        <el-card class="update-log">
+          <div slot="header" class="clearfix">
+            <span>鎹愯禒鏀寔</span>
+          </div>
+          <div class="body">
+            <img
+              src="@/assets/images/pay.png"
+              alt="donate"
+              width="100%"
+            />
+            <span style="display: inline-block; height: 30px; line-height: 30px"
+              >浣犲彲浠ヨ浣滆�呭枬鏉挅鍟¤〃绀洪紦鍔�</span
+            >
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "Index",
+  data() {
+    return {
+      // 鐗堟湰鍙�
+      version: "3.8.7"
+    };
+  },
+  methods: {
+    goTarget(href) {
+      window.open(href, "_blank");
+    }
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.home {
+  blockquote {
+    padding: 10px 20px;
+    margin: 0 0 20px;
+    font-size: 17.5px;
+    border-left: 5px solid #eee;
+  }
+  hr {
+    margin-top: 20px;
+    margin-bottom: 20px;
+    border: 0;
+    border-top: 1px solid #eee;
+  }
+  .col-item {
+    margin-bottom: 20px;
+  }
+
+  ul {
+    padding: 0;
+    margin: 0;
+  }
+
+  font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+  font-size: 13px;
+  color: #676a6c;
+  overflow-x: hidden;
+
+  ul {
+    list-style-type: none;
+  }
+
+  h4 {
+    margin-top: 0px;
+  }
+
+  h2 {
+    margin-top: 10px;
+    font-size: 26px;
+    font-weight: 100;
+  }
+
+  p {
+    margin-top: 10px;
+
+    b {
+      font-weight: 700;
+    }
+  }
+
+  .update-log {
+    ol {
+      display: block;
+      list-style-type: decimal;
+      margin-block-start: 1em;
+      margin-block-end: 1em;
+      margin-inline-start: 0;
+      margin-inline-end: 0;
+      padding-inline-start: 40px;
+    }
+  }
+}
+</style>
+
diff --git a/src/views/inspection/api.js b/src/views/inspection/api.js
new file mode 100644
index 0000000..012d7d1
--- /dev/null
+++ b/src/views/inspection/api.js
@@ -0,0 +1,93 @@
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+
+// 娴佺▼瀹炰緥
+export const getListProcess = data => {
+    const queryString = commonUtil.objectToQueryStr(data);
+    return request({
+        url: '/flow/monitor/listProcess',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+};
+
+// 鎸傝捣/鍞ら啋娴佺▼瀹炰緥
+export const enableProcess = (processInstanceId, enable) => {
+    const url = (
+        enable
+        ? `/flow/monitor/run/${processInstanceId}`
+        : `/flow/monitor/suspend/${processInstanceId}`
+    );
+    return request({
+        url,
+        method: 'get',
+    });
+}
+
+
+
+
+// 鎵ц瀹炰緥
+export const getListExecutions = data => {
+    const queryString = data && commonUtil.objectToQueryStr(data);
+    return request({
+        url: '/flow/monitor/listExecutions',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+
+// 杩愯鍘嗗彶
+export const getListHistoryProcess = data => {
+    const queryString = commonUtil.objectToQueryStr(data);
+    return request({
+        url: '/flow/monitor/listHistoryProcess',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+// 鑾峰彇鏌愪釜鍘嗗彶鎴栬�呭彉閲�
+export const getListByTypeAndId = (type, processInstanceId) => {
+    const url = type === "history" ? `/flow/monitor/history/${processInstanceId}` : `/flow/monitor/variables/${processInstanceId}`
+    const queryString = commonUtil.objectToQueryStr({
+        pageSize: 100,
+        pageNum: 1,
+        isAsc: "asc"
+    });
+    return request({
+        url,
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+
+
+// 浣滀笟绠$悊
+export const getListJobs = (type, data) => {
+    const queryString = commonUtil.objectToQueryStr(data);
+    return request({
+        url: `/flow/monitor/listJobs?type=${type}`,
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
diff --git a/src/views/inspection/components/workTable.vue b/src/views/inspection/components/workTable.vue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/views/inspection/components/workTable.vue
diff --git a/src/views/inspection/processInstance.vue b/src/views/inspection/processInstance.vue
new file mode 100644
index 0000000..5c025cc
--- /dev/null
+++ b/src/views/inspection/processInstance.vue
@@ -0,0 +1,180 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼鍚嶇О</label>
+                <el-input type="text" v-model="searchParams.name" size="small"/>
+            </div>
+            <div>
+                <label>涓氬姟鍙�</label>
+                <el-input type="text" v-model="searchParams.bussinesskey" size="small"/>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template
+            :data="tableData"
+            :total="total"
+            selection
+            @page-change="handlePageChange">
+            <template #columns>
+                <el-table-column
+                    prop="processInstanceId"
+                    label="娴佺▼瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="businessKey"
+                    label="涓氬姟鍙�">
+                </el-table-column>
+                <el-table-column
+                    prop="name"
+                    label="娴佺▼鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="currentTask"
+                    label="褰撳墠鑺傜偣">
+                </el-table-column>
+                <el-table-column
+                    prop="assignee"
+                    label="褰撳墠澶勭悊浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="suspended"
+                    label="鏄惁鎸傝捣"
+                    :formatter="handleSuspend"
+                >
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="寮�濮嬫椂闂�">
+                </el-table-column>
+                <el-table-column
+                    prop="startUserId"
+                    label="鍙戣捣浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="showProcess(scope.$index, scope.row)">娴佺▼杩涘害</el-button>
+                        <el-button
+                        v-if="!scope.row.suspended"
+                        size="mini"
+                        type="text"
+                        @click="handleEnable(false, scope.row)">鎸傝捣</el-button>
+                        <el-button
+                        v-else
+                        size="mini"
+                        type="text"
+                        @click="handleEnable(true, scope.row)">鍞ら啋</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getListProcess, enableProcess} from "./api";
+import commonHelper from "@/utils/common.js"
+
+export default {
+    name: "ProcessInstance",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            searchParams: {
+                name: "",
+                bussinesskey: "",
+                pageSize: 10,
+                pageNum: 1
+            }
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        }
+    },
+    mounted() {
+        this.getListProcessByParamsAndRender(this.searchParams);
+    },
+    methods: {
+        handleSuspend(row) {
+            return row.suspended ? "鏄�" : "鍚�"
+        },
+        getListProcessByParamsAndRender(params) {
+            const {name = "", bussinesskey = "", pageSize = 10, pageNum = 1} = params;
+            return getListProcess({
+                pageSize,
+                pageNum,
+                isAsc: "asc",
+                name,
+                bussinesskey
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        search() {
+            console.log("鎼滅储寰楀弬鏁�", this.searchParams);
+            this.getListProcessByParamsAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.name = "";
+            this.searchParams.bussinesskey = "";
+            this.getListProcessByParamsAndRender(this.searchParams);
+        },
+        handlePageChange({pageNum, pageSize}) {
+            console.log(pageNum, pageSize);
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getListProcessByParamsAndRender(this.searchParams);
+        },
+        handleEnable(enable, row) {
+            const {processInstanceId} = row;
+            enableProcess(processInstanceId, enable).then(res => {
+                this.$message.success("鎿嶄綔鎴愬姛锛�")
+                this.getListProcessByParamsAndRender(this.searchParams);
+            });
+        },
+        showProcess(index, row) {
+            const {processInstanceId} = row;
+            const url = `/flow/monitor/traceProcess/${processInstanceId}`;
+            commonHelper.openWindow(url);
+        }
+    }
+};
+</script>
+
+<style scoped>
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.search-bar > *{
+    margin-right: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inspection/runHistory.vue b/src/views/inspection/runHistory.vue
new file mode 100644
index 0000000..5c31c27
--- /dev/null
+++ b/src/views/inspection/runHistory.vue
@@ -0,0 +1,245 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼鍚嶇О:</label>
+                <el-input type="text" v-model="searchParams.name" size="small"/>
+            </div>
+            <div>
+                <label>涓氬姟鍙�:</label>
+                <el-input type="text" v-model="searchParams.bussinesskey" size="small"/>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template :data="tableData" :total="total" @page-change="handlePageChange">
+            <template #columns>
+                <el-table-column
+                    prop="processInstanceId"
+                    label="娴佺▼瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="businessKey"
+                    label="涓氬姟鍙�">
+                </el-table-column>
+                <el-table-column
+                    prop="name"
+                    label="娴佺▼鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="currentTask"
+                    label="褰撳墠鑺傜偣">
+                </el-table-column>
+                <el-table-column
+                    prop="assignee"
+                    label="褰撳墠澶勭悊浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="ended"
+                    label="鏄惁缁撴潫"
+                    :formatter="handleEnded"
+                >
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="寮�濮嬫椂闂�">
+                </el-table-column>
+                <el-table-column
+                    prop="endTime"
+                    label="缁撴潫鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="startUserId"
+                    label="鍙戣捣浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="showHistory(scope.$index, scope.row)">鏌ョ湅鍘嗗彶</el-button>
+                        <el-button
+                        v-if="!scope.row.suspended"
+                        size="mini"
+                        type="text"
+                        @click="showVariable(scope.$index, scope.row)">鏌ョ湅鍙橀噺</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+        <el-dialog
+            title="鎵ц璁板綍"
+            :visible.sync="showHistoryDialog"
+        >
+            <el-table :data="historyList" height="500">
+                <el-table-column
+                    prop="taskName"
+                    label="娲诲姩鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="assignee"
+                    label="鍔炵悊浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="comment"
+                    label="瀹℃壒鎰忚">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="寮�濮嬫椂闂�">
+                </el-table-column>
+                <el-table-column
+                    prop="endTime"
+                    label="缁撴潫鏃堕棿">
+                </el-table-column>
+            </el-table>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="showHistoryDialog = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="showHistoryDialog = false">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+        <el-dialog
+            :visible.sync="showVariableDialog"
+        >
+            <el-table :data="variablesList" height="500">
+                <el-table-column
+                    prop="variableName"
+                    label="鍙橀噺鍚�">
+                </el-table-column>
+                <el-table-column
+                    prop="variableTypeName"
+                    label="鍙橀噺绫诲瀷">
+                </el-table-column>
+                <el-table-column
+                    prop="value"
+                    label="鍙橀噺鍊�">
+                </el-table-column>
+                <el-table-column
+                    prop="createTime"
+                    label="鍒涘缓鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="lastUpdatedTime"
+                    label="鏈�鍚庝慨鏀规椂闂�">
+                </el-table-column>
+            </el-table>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="showVariableDialog = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="showVariableDialog = false">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getListHistoryProcess, getListByTypeAndId} from "./api";
+
+export default {
+    name: "RunHistory",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            searchParams: {
+                name: "",
+                bussinesskey: "",
+                pageSize: 10,
+                pageNum: 1
+            },
+            showHistoryDialog: false,
+            showVariableDialog: false,
+            historyList: [],
+            variablesList: []
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        }
+    },
+    mounted() {
+        this.getListHistoryProcessByParamsAndRender(this.searchParams);
+    },
+    methods: {
+        handleEnded(row) {
+            return row.ended ? "鏄�" : "鍚�";
+        },
+        getListHistoryProcessByParamsAndRender(params) {
+            const {pageNum = 1, pageSize = 10, name = "", bussinesskey = ""} = params;
+            getListHistoryProcess({
+                pageSize,
+                pageNum,
+                isAsc: "asc",
+                name,
+                bussinesskey
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        search() {
+            console.log("this.searchParams", this.searchParams)
+            this.getListHistoryProcessByParamsAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.name = "";
+            this.searchParams.bussinesskey = "";
+            this.getListHistoryProcessByParamsAndRender(this.searchParams);
+        },
+        handlePageChange({pageNum, pageSize}) {
+            console.log(pageNum, pageSize);
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getListHistoryProcessByParamsAndRender(this.searchParams);
+        },
+        showHistory(index, row) {
+            const {processInstanceId} = row;
+            this.showHistoryDialog = true;
+            getListByTypeAndId("history", processInstanceId).then(res => {
+                console.log("鑾峰彇鍒板巻鍙�", res);
+                this.historyList = res.rows;
+            });
+        },
+        showVariable(index, row) {
+            const {processInstanceId} = row;
+            this.showVariableDialog = true;
+            getListByTypeAndId("variables", processInstanceId).then(res => {
+                console.log("鑾峰彇鍒板彉閲�", res);
+                this.variablesList = res.rows;
+            });
+        }
+    }
+};
+</script>
+
+
+<style scoped>
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.search-bar > *{
+    margin-right: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inspection/runInstance.vue b/src/views/inspection/runInstance.vue
new file mode 100644
index 0000000..ab71193
--- /dev/null
+++ b/src/views/inspection/runInstance.vue
@@ -0,0 +1,122 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼鍚嶇О</label>
+                <el-input type="text" v-model="searchParams.name" size="small"/>
+            </div>
+            <div>
+                <!-- <el-button type="success" @click="search">鎼滅储</el-button>
+                <el-button type="warning" @click="reset">閲嶇疆</el-button> -->
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template :data="tableData" row-key="executionId" no-page>
+            <template #columns>
+                <el-table-column
+                    prop="executionId"
+                    label="鎵ц瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="name"
+                    label="娴佺▼鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="currentTask"
+                    label="褰撳墠鑺傜偣">
+                </el-table-column>
+                <el-table-column
+                    prop="active"
+                    label="鏄惁婵�娲�">
+                </el-table-column>
+                <el-table-column
+                    prop="suspended"
+                    label="鏄惁鎸傝捣">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="寮�濮嬫椂闂�">
+                </el-table-column>
+                <el-table-column
+                    prop="startUserId"
+                    label="鍙戣捣浜�">
+                </el-table-column>
+            </template>
+        </table-template>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getListExecutions} from "./api";
+import commonUtil from "@/utils/common"
+
+export default {
+    name: "RunInstance",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            tableData: [],
+            searchParams: {
+                name: ""
+            }
+        };
+    },
+    mounted() {
+       this.getListExecutionsByParamsAndRender(this.searchParams);
+    },
+    methods: {
+        search() {
+            this.getListExecutionsByParamsAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.name = "";
+            this.getListExecutionsByParamsAndRender(this.searchParams);
+        },
+        getListExecutionsByParamsAndRender(params) {
+            const {
+                name = "",
+            } = params;
+            let requestParams;
+            if (name) {
+                requestParams = {name};
+            }
+            getListExecutions(requestParams).then(res => {
+                res = res.map(item => {
+                    return {
+                        ...item,
+                        active: item.active ? "鏄�" : "鍚�",
+                        suspended: item.suspended ? "鏄�" : "鍚�"
+                    };
+                });
+                const tree = commonUtil.listToTree(res);
+                this.tableData = tree;
+            });
+        }
+    }
+};
+</script>
+
+<style scoped>
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.search-bar > *{
+    margin-right: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/inspection/workManagement.vue b/src/views/inspection/workManagement.vue
new file mode 100644
index 0000000..9bc2dc4
--- /dev/null
+++ b/src/views/inspection/workManagement.vue
@@ -0,0 +1,271 @@
+<template>
+    <div class="c-work-management" style="margin: 0px 8px 8px;">
+        <el-tabs v-model="activeName" @tab-click="handleTabClick" type="border-card">
+            <el-tab-pane label="瀹氭椂浣滀笟" name="1"></el-tab-pane>
+            <el-tab-pane label="寮傛浣滀笟" name="2"></el-tab-pane>
+            <el-tab-pane label="鎸傝捣浣滀笟" name="3"></el-tab-pane>
+            <el-tab-pane label="姝讳骸浣滀笟" name="4"></el-tab-pane>
+        </el-tabs>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼瀹氫箟ID:</label>
+                <el-input type="text" v-model="searchParams.processDefinitionId" size="small"/>
+            </div>
+            <div v-if="activeName !== '3'">
+                <label>璁″垝鎵ц鏃堕棿:</label>
+                <el-date-picker
+                    v-model="searchParams.range"
+                    value-format="yyyy-MM-dd HH:mm:ss"
+                    type="datetimerange"
+                    range-separator="鑷�"
+                    start-placeholder="寮�濮嬫棩鏈�"
+                    end-placeholder="缁撴潫鏃ユ湡"
+                    size="small"
+                >
+                </el-date-picker>
+            </div>
+            <div class="btns">
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template :data="tableData" :total="total">
+            <template #columns>
+                <el-table-column
+                    v-for="(column, i) in currentColumns"
+                    :key="i"
+                    :prop="column.key"
+                    :label="column.label"
+                ></el-table-column>
+            </template>
+        </table-template>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getListJobs} from "./api";
+import commonUtil from "@/utils/common"
+
+export default {
+    name: "RunHistory",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            activeName: "1",
+            searchParams: {
+                processDefinitionId: "",
+                range: null,
+                pageNum: 1,
+                pageSize: 10
+            },
+            columns: {
+                1: [
+                    {
+                        key: "processDefinitionId",
+                        label: "娴佺▼瀹氫箟缂栧彿"
+                    },
+                    {
+                        key: "jobHandlerType",
+                        label: "浣滀笟绫诲瀷"
+                    },
+                    {
+                        key: "duedate",
+                        label: "璁″垝鎵ц鏃堕棿"
+                    },
+                    {
+                        key: "processInstanceId",
+                        label: "娴佺▼瀹炰緥缂栧彿"
+                    },
+                    {
+                        key: "retries",
+                        label: "鍓╀綑閲嶈瘯娆℃暟"
+                    }
+                ],
+                2: [
+                    {
+                        key: "processDefinitionId",
+                        label: "娴佺▼瀹氫箟缂栧彿"
+                    },
+                    {
+                        key: "jobHandlerType",
+                        label: "浣滀笟绫诲瀷"
+                    },
+                    {
+                        key: "duedate",
+                        label: "璁″垝鎵ц鏃堕棿"
+                    },
+                    {
+                        key: "processInstanceId",
+                        label: "娴佺▼瀹炰緥缂栧彿"
+                    },
+                    {
+                        key: "retries",
+                        label: "鍓╀綑閲嶈瘯娆℃暟"
+                    }
+                ],
+                3: [
+                    {
+                        key: "processDefinitionId",
+                        label: "娴佺▼瀹氫箟缂栧彿"
+                    },
+                    {
+                        key: "jobHandlerType",
+                        label: "浣滀笟绫诲瀷"
+                    },
+                    {
+                        key: "duedate",
+                        label: "璁″垝鎵ц鏃堕棿"
+                    },
+                    {
+                        key: "processInstanceId",
+                        label: "娴佺▼瀹炰緥缂栧彿"
+                    },
+                    {
+                        key: "retries",
+                        label: "鍓╀綑閲嶈瘯娆℃暟"
+                    }
+                ],
+                4: [
+                    {
+                        key: "processDefId",
+                        label: "娴佺▼瀹氫箟缂栧彿"
+                    },
+                    {
+                        key: "jobHandlerType",
+                        label: "浣滀笟绫诲瀷"
+                    },
+                    {
+                        key: "dueDate",
+                        label: "璁″垝鎵ц鏃堕棿"
+                    },
+                    {
+                        key: "processInstanceId",
+                        label: "娴佺▼瀹炰緥缂栧彿"
+                    },
+                    {
+                        key: "exceptionMessage",
+                        label: "寮傚父淇℃伅"
+                    }
+                ]
+            }
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        },
+        currentColumns() {
+            return this.columns[this.activeName];
+        },
+        transferedSearchParams() {
+            return {
+                processDefinitionId: this.searchParams.processDefinitionId,
+                pageNum: this.searchParams.pageNum,
+                pageSize: this.searchParams.pageSize,
+                startDate: (this.searchParams.range && this.searchParams.range[0]) || "",
+                endDate: (this.searchParams.range && this.searchParams.range[1]) || "",
+                isAsc: "asc",
+                type: this.activeName
+            };
+        }
+    },
+    mounted() {
+        this.getListJobByParamsAndRender(this.transferedSearchParams);
+    },
+    methods: {
+        search() {
+            this.getListJobByParamsAndRender(this.transferedSearchParams);
+        },
+        reset() {
+            this.searchParams.processDefinitionId = "";
+            this.searchParams.range = null;
+            this.getListJobByParamsAndRender(this.transferedSearchParams);
+
+        },
+        getListJobByParamsAndRender(params) {
+            const {
+                processDefinitionId = "",
+                pageNum = 1,
+                pageSize = 10,
+                endDate = "",
+                startDate = "",
+                isAsc,
+                type = "1"
+            } = params;
+            getListJobs(type, {
+                pageSize,
+                pageNum,
+                isAsc,
+                processDefinitionId,
+                startDate,
+                endDate
+            }).then(res => {
+                // 杞寲涓�涓嬫椂闂�
+                console.log("this.activeName", this.activeName);
+                if (
+                    this.activeName === "1"
+                    || this.activeName === "2"
+                    || this.activeName === "3"
+                ) {
+                    res.rows.map(item => {
+                        item.duedate = commonUtil.normalizeDateTimeString(item.duedate);
+                    });
+                }
+                if (this.activeName === "4") {
+                    res.rows.map(item => {
+                        item.dueDate = commonUtil.normalizeDateTimeString(item.dueDate);
+                    });
+                }
+               this.responseData = res;
+            });
+        },
+        handleTabClick(tab) {
+            this.getListJobByParamsAndRender(this.transferedSearchParams);
+        }
+    },
+};
+</script>
+<style scoped>
+.c-work-management {
+    background: #FFFFFF;
+    border: 1px solid #DCDFE6;
+    -webkit-box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
+    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12), 0 0 6px 0 rgba(0, 0, 0, 0.04);
+}
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.el-tabs--border-card {
+    border: none;
+    box-shadow: none;
+}
+.search-bar > *{
+    margin-right: 8px;
+}
+.search-bar .el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.search-bar label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+.el-button {
+    height: 32px;
+}
+</style>
+
+<style>
+
+</style>
\ No newline at end of file
diff --git a/src/views/process/api/deployService.js b/src/views/process/api/deployService.js
new file mode 100644
index 0000000..48f601c
--- /dev/null
+++ b/src/views/process/api/deployService.js
@@ -0,0 +1,63 @@
+
+
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+// 鑾峰彇妯″瀷鏁版嵁
+export const getProcesslists = (data) => {
+    const fd = commonUtil.objectToFormData(data);
+    return request({
+      url: '/flow/manage/getprocesslists?pageNum=1&pageSize=10',
+      method: 'post',
+      data: fd
+    })
+}
+
+// 涓婁紶
+export const uploadProcess = (data) => {
+  const fd = commonUtil.objectToFormData(data);
+  return request({
+    url: '/flow/manage/uploadworkflow',
+    method: 'post',
+    data: fd
+  })
+}
+
+// 杞崲妯″瀷
+export const exchangeById = id => {
+  return request({
+    url: `/flow/manage/exchangeProcessToModel/${id}`,
+    method: 'get'
+  });
+}
+
+// 鍒犻櫎娴佺▼淇℃伅
+
+export const deleteProcessByDeployId = deployId => {
+  const data = {
+    ids: deployId
+  };
+  return request({
+    url: `/flow/manage/remove/${deployId}`,
+    method: 'post',
+    data: commonUtil.objectToFormData(data)
+  });
+}
+
+// 鎸傝捣娴佺▼
+export const suspendProcess = params => {
+  return request({
+    url: `/flow/manage/suspendProcessDefinition`,
+    method: 'get',
+    params
+  });
+}
+
+// 婵�娲�
+export const activateProcess = params => {
+  return request({
+    url: `/flow/manage/activateProcessDefinition`,
+    method: 'get',
+    params
+  });
+}
\ No newline at end of file
diff --git a/src/views/process/api/model.js b/src/views/process/api/model.js
new file mode 100644
index 0000000..6519d1a
--- /dev/null
+++ b/src/views/process/api/model.js
@@ -0,0 +1,41 @@
+
+
+import request from '@/utils/request';
+import commonUtil from "@/utils/common"
+
+// 鑾峰彇妯″瀷鏁版嵁
+export const getModelLists = (data) => {
+    return request({
+      url: '/model/manage/modelLists',
+      method: 'post',
+      data: commonUtil.objectToFormData(data)
+    })
+}
+
+// 娣诲姞妯″瀷鏁版嵁
+
+export const addModel = (data) => {
+    return request({
+      url: '/model/manage/add',
+      method: 'post',
+      data
+    })
+}
+
+// 鍙戝竷
+
+export const publishModelById = id => {
+  return request({
+    url: `/model/manage/deploy/${id}`,
+    method: 'post',
+  });
+}
+
+// 鍒犻櫎
+
+export const deleteModelById = id => {
+  return request({
+    url: `/model/manage/remove/${id}`,
+    method: 'post',
+  });
+}
\ No newline at end of file
diff --git a/src/views/process/deployManagement.vue b/src/views/process/deployManagement.vue
new file mode 100644
index 0000000..cb20cb5
--- /dev/null
+++ b/src/views/process/deployManagement.vue
@@ -0,0 +1,300 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼鏍囪瘑</label>
+                <el-input v-model="searchParams.key" size="small"></el-input>
+            </div>
+            <div>
+                <label>娴佺▼鍚嶇О</label>
+                <el-input v-model="searchParams.name" size="small"></el-input>
+            </div>
+            <div>
+                <label>鐗堟湰</label>
+                <el-select v-model="searchParams.latest" size="small">
+                    <el-option label="鍙湅鏂扮増鏈�" value="true"></el-option>
+                    <el-option label="鍏ㄩ儴鐗堟湰" value="false"></el-option>
+                </el-select>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template :data="tableData" :total="total" @page-change="handlePageChange">
+            <template #toolbar>
+                <el-button type="primary" @click="showAddDialog = true" plain size="mini">閮ㄧ讲</el-button>
+            </template>
+            <template #columns>
+                <el-table-column
+                    prop="id"
+                    label="娴佺▼瀹氫箟ID">
+                </el-table-column>
+                <el-table-column
+                    prop="deploymentId"
+                    label="娴佺▼閮ㄧ讲ID">
+                </el-table-column>
+                <el-table-column
+                    prop="key"
+                    label="娴佺▼瀹氫箟key">
+                </el-table-column>
+                <el-table-column
+                    prop="name"
+                    label="娴佺▼鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="resourceName"
+                    label="娴佺▼璧勬簮瀹氫箟">
+                </el-table-column>
+                <el-table-column
+                    prop="version"
+                    label="鐗堟湰鍙�">
+                </el-table-column>
+                <el-table-column
+                    prop="version"
+                    width="200"
+                    label="璇︽儏">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleDefinition(scope.$index, scope.row)">鏌ョ湅瀹氫箟</el-button>
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleProcess(scope.$index, scope.row)">娴佺▼鍥�</el-button>
+                    </template>
+                </el-table-column>
+                <el-table-column
+                    prop="version"
+                    label="鎿嶄綔"
+                    width="240"
+                >
+                    <template slot-scope="scope">
+                        <el-button
+                        v-if="scope.row.suspended"
+                        size="mini"
+                        type="text"
+                        @click="handleActive(scope.$index, scope.row)">婵�娲�</el-button>
+                        <el-button
+                        v-if="!scope.row.suspended"
+                        size="mini"
+                        type="text"
+                        @click="handleHangOff(scope.$index, scope.row)">鎸傝捣</el-button>
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleExchange(scope.$index, scope.row)">杞负妯″瀷</el-button>
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleDelete(scope.$index, scope.row)">鍒犻櫎</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+        <el-dialog
+             title="涓婁紶閮ㄧ讲鏂囦欢"
+            :visible.sync="showAddDialog"
+            width="30%"
+        >
+            <input id="deployFile" type="file" />
+            <div>鎻愮ず锛氫粎鍏佽瀵煎叆鈥渂pmn鈥濄�佲�渪ml鈥濇垨鈥渮ip鈥濇牸寮忔枃浠讹紒</div>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="showAddDialog = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleUpload">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+        <el-dialog
+             :title="`${type === 'hang' ? '鎸傝捣' : '婵�娲�'}娴佺▼瀹氫箟`"
+            :visible.sync="showHangOffDialog"
+            width="30%"
+        >
+            <el-switch
+                v-model="suspend.value1"
+                :active-text="`${type === 'hang' ? '鎸傝捣' : '婵�娲�'}鍏宠仈娴佺▼瀹炰緥`"
+            >
+            </el-switch>
+            <br/>
+            <el-switch
+                v-model="suspend.value2"
+                :active-text="`瀹氭椂${type === 'hang' ? '鎸傝捣' : '婵�娲�'}`"
+            >
+            </el-switch>
+            <br/>
+            <el-date-picker
+                :disabled="!suspend.value2"
+                v-model="suspend.date"
+                value-format="yyyy-MM-dd HH:mm:ss"
+                type="datetime"
+                :placeholder="`閫夋嫨${type === 'hang' ? '鎸傝捣' : '婵�娲�'}鏃堕棿`">
+            </el-date-picker>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="showHangOffDialog = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleSuspendRequest">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getProcesslists, exchangeById, deleteProcessByDeployId, uploadProcess, suspendProcess, activateProcess} from "./api/deployService";
+import commonHelper from "@/utils/common.js"
+
+export default {
+    name: "deployManagement",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            searchParams: {
+                key: "",
+                name: "",
+                latest: "true",
+                orderByColumn: "processSort",
+                isAsc: "asc",
+                pageNum: 1,
+                pageSize: 10
+            },
+            showAddDialog: false,
+            showHangOffDialog: false,
+            suspend: {
+                value1: true,
+                value2: false,
+                date: ""
+            },
+            currentRow: null,
+            type: ""
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        }
+    },
+    mounted() {
+        this.getListAndRenderByParams(this.searchParams)
+    },
+    methods: {
+        handlePageChange({pageNum, pageSize}) {
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getListAndRenderByParams(this.searchParams);
+        },
+        getListAndRenderByParams(params) {
+            getProcesslists(params).then(res => {
+                console.log("鎷垮埌processList", res);
+                this.responseData = res;
+            });
+        },
+        search() {
+            this.getListAndRenderByParams(this.searchParams)
+        },
+        reset() {
+            this.searchParams.key = "";
+            this.searchParams.name = "";
+            this.searchParams.latest = "true";
+            this.getListAndRenderByParams(this.searchParams)
+        },
+        handleDefinition(index, row) {
+            const {deploymentId, resourceName} = row;
+            const path = `/flow/manage/showProcessDefinition/${deploymentId}/${resourceName}`
+            commonHelper.openWindow(path);
+        },
+        handleProcess(index, row) {
+            const {id} = row;
+            console.log("id鏄灏�", id);
+            const path = `/flow/manage/showresource?pdid=${id}`;
+            commonHelper.openWindow(path);
+        },
+        handleExchange(index, row) {
+            const {id} = row;
+            exchangeById(id).then(res => {
+                this.$message.success("杞寲鎴愬姛!")
+            });
+        },
+        handleHangOff(index, row) {
+            this.showHangOffDialog = true;
+            this.type = "hang";
+            this.currentRow = row;
+        },
+        handleActive(index, row) {
+            this.showHangOffDialog = true;
+            this.type = "active";
+            this.currentRow = row;
+        },
+        handleSuspendRequest() {
+            const {id} = this.currentRow;
+            const params = {
+                flag: true,
+                pdid: id,
+            };
+            if (this.suspend.date) {
+                params.date = this.suspend.date;
+            }
+            this.type === "hang" && suspendProcess(params).then(() => {
+                this.$message.success("鎸傝捣鎴愬姛!");
+                this.showHangOffDialog = false;
+                this.getListAndRenderByParams(this.searchParams)
+            });
+
+            this.type === "active" && activateProcess(params).then(() => {
+                this.$message.success("婵�娲绘垚鍔�!");
+                this.showHangOffDialog = false;
+                this.getListAndRenderByParams(this.searchParams)
+            });
+        },
+        handleDelete(index, row) {
+            this.$confirm('纭畾鍒犻櫎璇ユ潯娴佺▼淇℃伅鍚楋紵', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const {deploymentId} = row;
+                deleteProcessByDeployId(deploymentId).then(res => {
+                    this.$message.success("鍒犻櫎鎴愬姛!");
+                    this.getListAndRenderByParams(this.searchParams)
+                 });
+            });
+        },
+        handleUpload() {
+            const deploy = document.querySelector("#deployFile");
+            const uploadfile = deploy.files[0];
+            uploadProcess({
+                uploadfile
+            }).then(() => {
+                this.showAddDialog = false;
+                console.log("file-name");
+                this.getListAndRenderByParams(this.searchParams)
+            });
+        },
+    },
+};
+</script>
+
+<style>
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+.el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.el-switch {
+    margin-bottom: 16px;
+}
+</style>
diff --git a/src/views/process/modelManagement.vue b/src/views/process/modelManagement.vue
new file mode 100644
index 0000000..52ee3fe
--- /dev/null
+++ b/src/views/process/modelManagement.vue
@@ -0,0 +1,237 @@
+<template>
+    <div class="c-model">
+        <div class="search-bar">
+            <div>
+                <label>妯″瀷鏍囪瘑</label>
+                <el-input v-model="searchParams.key" size="small"></el-input>
+            </div>
+            <div>
+                <label>妯″瀷鍚嶇О</label>
+                 <el-input v-model="searchParams.name" size="small"></el-input>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <div class="c-model__content">
+            <table-template
+                :data="tableData"
+                :total="total"
+                @page-change="handlePageChange"
+            >
+                <template #toolbar>
+                    <el-button type="primary" @click="showAddDialog = true" size="mini" plain icon="el-icon-plus">鏂板缓妯″瀷</el-button>
+                </template>
+                <template #columns>
+                    <el-table-column
+                    prop="key"
+                    label="妯″瀷鏍囪瘑"
+                    width="180">
+                </el-table-column>
+                <el-table-column
+                    prop="name"
+                    label="妯″瀷鍚嶇О"
+                    width="180">
+                </el-table-column>
+                <el-table-column
+                    prop="category"
+                    label="鍒嗙被">
+                </el-table-column>
+                <el-table-column
+                    prop="version"
+                    label="鐗堟湰">
+                </el-table-column>
+                <el-table-column
+                    width="320"
+                    prop="lastUpdateTime"
+                    :formatter="handleDateTime"
+                    label="鍒涘缓鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="address"
+                    width="320"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <!--primary / success / warning / danger / info / text-->
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleDesign(scope.$index, scope.row)">璁捐</el-button>
+                        <el-button
+                        v-if="!scope.row.deploymentId"
+                        size="mini"
+                        type="text"
+                        @click="handlePublish(scope.$index, scope.row)">鍙戝竷</el-button>
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleExport(scope.$index, scope.row)">瀵煎嚭</el-button>
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleDelete(scope.$index, scope.row)">鍒犻櫎</el-button>
+                    </template>
+                </el-table-column>
+                </template>
+            </table-template>
+        </div>
+        <el-dialog
+            title="鏂板缓妯″瀷"
+            :visible.sync="showAddDialog"
+        >
+            <el-form ref="form" :model="form" label-width="80px">
+                <el-form-item label="妯″瀷鏍囪瘑">
+                    <el-input v-model="form.key"></el-input>
+                </el-form-item>
+                <el-form-item label="妯″瀷鍚嶇О">
+                    <el-input v-model="form.name"></el-input>
+                </el-form-item>
+                <el-form-item label="鍒嗙被">
+                    <el-input v-model="form.category"></el-input>
+                </el-form-item>
+                <el-form-item label="鎻忚堪">
+                    <el-input type="textarea" v-model="form.description"></el-input>
+                </el-form-item>
+            </el-form>
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="showAddDialog = false">鍙� 娑�</el-button>
+                <el-button type="primary" @click="handleAddModel">纭� 瀹�</el-button>
+            </span>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import {getModelLists, addModel, publishModelById, deleteModelById} from "./api/model.js";
+import commonHelper from "@/utils/common.js"
+import TableTemplate from "@/components/TableTemplate";
+export default {
+    name: "ModelManagement",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            showAddDialog: false,
+            form: {
+                key: "",
+                name: "",
+                category: "",
+                description: "",
+            },
+            searchParams: {
+                name: "",
+                key: "",
+                pageSize: 10,
+                pageNum: 1,
+                orderByColumn: "modelSort",
+                isAsc: "asc",
+            },
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        }
+    },
+    created() {
+        this.getModelByParams(this.searchParams);
+    },
+    methods: {
+        getModelByParams(params) {
+            getModelLists(params).then(res => {
+                this.responseData = res;
+            });
+        },
+        handleAddModel() {
+            const formData = commonHelper.objectToFormData(this.form);
+            addModel(formData).then(res => {
+                console.log(res);
+                this.showAddDialog = false;
+                this.getModelByParams(this.searchParams)
+                this.$message.success("娣诲姞鎴愬姛!");
+                ["key", "name", "category", "description"].forEach(key => {
+                    this.form[key] = "";
+                });
+            });
+        },
+        handleDateTime(row) {
+            const {createTime} = row;
+            return commonHelper.normalizeDateTimeString(createTime);
+        },
+        handleDesign(index, row) {
+            // flowable鏀瑰彉璁捐鐨勮矾寰�
+            const path = "/designer/index.html#/editor/" + row.id;
+            // const path = "/editor?modelId=" + row.id;
+            commonHelper.openWindow(path);
+        },
+        handlePublish(index, row) {
+            const id = row.id;
+            publishModelById(id).then(res => {
+                this.$message.success("閮ㄧ讲鎴愬姛!");
+                this.getModelByParams(this.searchParams);
+            });
+        },
+        handleExport(index, row) {
+            const {key ,id} = row;
+            const a = document.createElement("a");
+            const url = process.env.VUE_APP_TAB_URL_PREFIX + "/model/manage/export/" + id;
+            a.href = url;
+            a.click();
+        },
+        handleDelete(index, row) {
+            this.$confirm('纭畾鍒犻櫎璇ユ潯妯″瀷淇℃伅鍚楋紵', {
+                confirmButtonText: '纭畾',
+                cancelButtonText: '鍙栨秷',
+                type: 'warning'
+            }).then(() => {
+                const id = row.id;
+                deleteModelById(id).then(res => {
+                    this.$message.success("鍒犻櫎鎴愬姛!");
+                    this.getModelByParams(this.searchParams);
+                 });
+            });
+           
+        },
+        search() {
+            this.getModelByParams(this.searchParams);
+        },
+        reset() {
+            this.searchParams.name = "";
+            this.searchParams.key = "";
+            this.getModelByParams(this.searchParams);
+        },
+        handlePageChange({pageNum, pageSize}) {
+            this.searchParams.pageNum = pageNum;
+            this.searchParams.pageSize = pageSize;
+            this.getModelByParams(this.searchParams);
+        },
+    }
+};
+</script>
+
+<style>
+label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+.el-textarea {
+    width: 300px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue
index 10a5365..b2b072f 100644
--- a/src/views/system/role/selectUser.vue
+++ b/src/views/system/role/selectUser.vue
@@ -127,9 +127,11 @@
       }
       authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
         this.$modal.msgSuccess(res.msg);
-        this.visible = false;
-        this.$emit("ok");
-      }); 
+        if (res.code === 200) {
+          this.visible = false;
+          this.$emit("ok");
+        }
+      });
     }
   }
 };
diff --git a/src/views/todo/allTodoList.vue b/src/views/todo/allTodoList.vue
new file mode 100644
index 0000000..9f80b40
--- /dev/null
+++ b/src/views/todo/allTodoList.vue
@@ -0,0 +1,156 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼鍚嶇О</label>
+                <el-input v-model="searchParams.processName" size="small"></el-input>
+            </div>
+            <div>
+                <label>浠诲姟鍚嶇О</label>
+                 <el-input v-model="searchParams.taskName" size="small"></el-input>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template
+            :data="tableData"
+            :total="total"
+            @page-change="handlePageChange"
+        >
+            <template #columns>
+                <el-table-column
+                    prop="taskName"
+                    label="浠诲姟鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="processInstanceId"
+                    label="娴佺▼瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="executionId"
+                    label="鎵ц瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="businessKey"
+                    label="涓氬姟鍙�">
+                </el-table-column>
+                <el-table-column
+                    prop="processName"
+                    label="娴佺▼鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="starter"
+                    label="鍙戣捣浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="assignee"
+                    label="鍔炵悊浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="createTime"
+                    label="浠诲姟鍒涘缓鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="娴佺▼鍚姩鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleTodo(scope.$index, scope.row)">鍔炵悊</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getAllTodoList} from "./api/allTodoList";
+
+export default {
+    name: "AllTodoList",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            searchParams: {
+                taskName: "",
+                processName: "",
+                pageNum: 1,
+                pageSize: 10
+            }
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        }
+    },
+    mounted() {
+       this.getAllTodoListByParamsAndRender(this.searchParams);
+    },
+    methods: {
+        getAllTodoListByParamsAndRender(params) {
+            const {pageSize = 1, pageNum = 10, processName = "", taskName = ""} = params;
+            getAllTodoList({
+                pageSize,
+                pageNum,
+                isAsc: "asc",
+                processName,
+                taskName
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        search() {
+            this.getAllTodoListByParamsAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.processName = "";
+            this.searchParams.taskName = "";
+            this.getAllTodoListByParamsAndRender(this.searchParams);
+        },
+        handlePageChange() {},
+        handleTodo(index, row) {
+            console.log("todo", row);
+            const {formKey, taskId, businessKey} = row;
+            this.$router.push({
+                path: `/process/${formKey}/${taskId}?id=${businessKey}`,
+                meta: { title: "娴嬭瘯" },
+                params: {row}
+            })
+        }
+    },
+};
+</script>
+
+<style scoped>
+label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/todo/api/allTodoList.js b/src/views/todo/api/allTodoList.js
new file mode 100644
index 0000000..3f9cb28
--- /dev/null
+++ b/src/views/todo/api/allTodoList.js
@@ -0,0 +1,17 @@
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+// 鑾峰彇鎴戠殑寰呭姙
+export const getAllTodoList = data => {
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa1");
+    const queryString = commonUtil.objectToQueryStr(data);
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa2", queryString);
+    return request({
+        url: '/task/manage/alllist',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
\ No newline at end of file
diff --git a/src/views/todo/api/myTodoList.js b/src/views/todo/api/myTodoList.js
new file mode 100644
index 0000000..d8d2bdd
--- /dev/null
+++ b/src/views/todo/api/myTodoList.js
@@ -0,0 +1,104 @@
+import request from '@/utils/request'
+import commonUtil from "@/utils/common";
+
+// 鑾峰彇鎴戠殑寰呭姙
+export const getMyTodoList = data => {
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa1");
+    const queryString = commonUtil.objectToQueryStr(data);
+    console.log("aaaaaaaaaaaaaaaaaaaaaaa2", queryString);
+    return request({
+        url: '/task/manage/mylist',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+//
+
+export const getProcessByTaskid = taskId => {
+    return request({
+        url: `/task/manage/history/${taskId}`,
+        method: 'get'
+    });
+}
+
+// 澶勭悊寰呭姙
+export const processTask = data => {
+    const {taskId} = data;
+    delete data.taskId;
+    return request({
+        url: `/task/manage/completeTask/${taskId}`,
+        method: 'post',
+        data
+    });
+}
+
+// 濉啓浼氳绾
+export const fillMeetingRecord = data => {
+    const queryString = commonUtil.objectToQueryStr(data);
+    return request({
+        url: '/meeting/edit',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+// 閿�鍋�
+export const checkoutLeave = data => {
+    const queryString = commonUtil.objectToQueryStr(data, true);
+    return request({
+        url: '/leaveapply/update',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+
+// 鏇存柊閲囪喘
+export const updatePurchase = data => {
+    const queryString = commonUtil.objectToQueryStr(data, true);
+    return request({
+        url: '/purchase/edit',
+        method: 'post',
+        data: queryString,
+        headers: {
+            'Content-Type': 'application/x-www-form-urlencoded'
+        },
+    });
+}
+
+
+
+// 鎾ら攢璇峰亣鐢宠
+export const forceEnd = taskId => {
+    return request({
+        url: `/dynamic/flow/forceEnd/${taskId}`,
+        method: 'get',
+    });
+}
+
+// 璇峰亣椹冲洖
+export const rejectLeave = taskId => {
+    return request({
+        url: `/dynamic/flow/jump/${taskId}/applyleave`,
+        method: 'get',
+    });
+}
+
+
+// 鑾峰彇寰呭姙涓氬姟鏁版嵁
+export const getInfoByTaskId = (url, taksId) => {
+    return request({
+        url: url + `?taskid=${taksId}`,
+        method: 'get',
+    });
+}
\ No newline at end of file
diff --git a/src/views/todo/api/processTaks.js b/src/views/todo/api/processTaks.js
new file mode 100644
index 0000000..54cacf3
--- /dev/null
+++ b/src/views/todo/api/processTaks.js
@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+// 澶勭悊寰呭姙
+export const processTask = data => {
+    return request({
+        url: '/task/manage/mylist',
+        method: 'post',
+        data
+    });
+}
\ No newline at end of file
diff --git a/src/views/todo/components/TimeLine.vue b/src/views/todo/components/TimeLine.vue
new file mode 100644
index 0000000..cf7d563
--- /dev/null
+++ b/src/views/todo/components/TimeLine.vue
@@ -0,0 +1,68 @@
+<template>
+    <div class="c-time-line">
+        <el-timeline>
+            <el-timeline-item
+                v-for="(activity, index) in activities"
+                :key="index"
+            >
+                <el-card>
+                    <div class="c-time-line__paragraph">寮�濮�: <span>{{activity.startTime}}</span></div>
+                    <div class="c-time-line__paragraph2">{{activity.assignee}}: {{activity.taskName}}</div>
+                    <div class="c-time-line__paragraph2">{{activity.comment}}</div>
+                    <div class="c-time-line__paragraph">缁撴潫: <span>{{activity.endTime}}</span></div>
+
+                </el-card>
+            </el-timeline-item>
+        </el-timeline>
+    </div>
+</template>
+
+<script>
+
+
+// taskName: "閲囪喘缁忕悊瀹℃壒"
+// assignee: "admin"
+// startTime: "2024-04-28 23:51:04"
+// processInstanceId: "7529"
+export default {
+    name: "TimeLine",
+    props: {
+        activities: {
+            type: Array,
+            default: () => ([])
+        }
+    }
+};
+</script>
+
+<style>
+
+.el-card__body {
+    width: 330px;
+    padding-top: 8px;
+    padding-bottom: 8px;
+}
+.el-timeline-item {
+    padding-bottom: 0px;
+}
+.c-time-line__paragraph {
+    margin-bottom: 4px;
+    line-height: 1.5em;
+}
+.c-time-line__paragraph span {
+    color: #1ab394;
+}
+.c-time-line__paragraph2 {
+    font-size: 18px;
+    line-height: 1.5em;
+}
+.el-timeline-item__node--normal {
+    background-color: #1ab394;
+    width:16px;
+    height: 16px;
+    left: -3px;
+}
+.el-timeline-item__tail {
+    top: 8px;
+}
+</style>
diff --git a/src/views/todo/components/leaveApplyForm.vue b/src/views/todo/components/leaveApplyForm.vue
new file mode 100644
index 0000000..ad7f577
--- /dev/null
+++ b/src/views/todo/components/leaveApplyForm.vue
@@ -0,0 +1,180 @@
+<template>
+    <div class="c-leaveapply-form">
+        <el-form  ref="form" :model="form" label-width="120px">
+            <el-form-item label="璇峰亣浜�">
+                <el-input v-model="form.userId" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item label="绫诲瀷">
+                <el-input v-if="step !== 'modifyapply' && step !== 'addleave'" v-model="form.leaveType" :disabled="canNotEdit"></el-input>
+                <el-select v-else v-model="form.leaveType">
+                    <el-option v-for="(leaveType, i) in leaveTypeList" :label="leaveType" :value="leaveType" :key="i"></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="璧峰鏃堕棿">
+                <el-input v-if="step !== 'modifyapply' && step !== 'addleave'" v-model="form.startTime" :disabled="canNotEdit"></el-input>
+                <el-date-picker v-else type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.startTime" style="width: 100%;"></el-date-picker>
+            </el-form-item>
+            <el-form-item label="缁撴潫鏃堕棿">
+                <el-input v-if="step !== 'modifyapply' && step !== 'addleave'" v-model="form.endTime" :disabled="canNotEdit"></el-input>
+                <el-date-picker v-else type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.endTime" style="width: 100%;"></el-date-picker>
+            </el-form-item>
+            <el-form-item label="鍘熷洜">
+                <el-input v-model="form.reason" :disabled="canNotEdit"></el-input>
+            </el-form-item>
+            <el-form-item label="浜轰簨" v-if="step==='deptleadercheck'">
+                <el-select v-model="form.hr">
+                    <el-option
+                        v-for="(user, i) in userList" 
+                        :key="i"
+                        :label="user.userName"
+                        :value="user.userName"
+                    ></el-option>
+                </el-select>
+            </el-form-item>
+            <template v-if="step==='deptleadercheck' || step==='hrcheck'">
+                <el-form-item label="瀹℃壒缁撴灉" >
+                    <el-radio-group v-model="form.resource">
+                        <el-radio label="true">鍚屾剰</el-radio>
+                        <el-radio label="false">鎷掔粷</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="瀹℃壒鎰忚">
+                    <el-input type="textarea" v-model="form.comment"></el-input>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                    <el-button type="danger" @click="cancel" v-if="step!=='destroyapply'">鎾ら攢</el-button>
+                    <el-button type="warning" @click="reject" v-if="step!=='destroyapply'">椹冲洖</el-button>
+                </el-form-item>
+            </template>
+            <template v-if="step==='destroyapply'">
+                <el-form-item label="瀹為檯璧峰鏃堕棿">
+                    <el-date-picker
+                        v-model="form.realityStartTime"
+                        value-format="yyyy-MM-dd HH:mm:ss"
+                        type="datetime"
+                        :placeholder="`閫夋嫨${type === 'hang' ? '鎸傝捣' : '婵�娲�'}鏃堕棿`">
+                    </el-date-picker>
+                </el-form-item>
+                <el-form-item label="瀹為檯缁撴潫鏃堕棿">
+                    <el-date-picker
+                        v-model="form.realityEndTime"
+                        value-format="yyyy-MM-dd HH:mm:ss"
+                        type="datetime"
+                        :placeholder="`閫夋嫨${type === 'hang' ? '鎸傝捣' : '婵�娲�'}鏃堕棿`">
+                    </el-date-picker>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                </el-form-item>
+            </template>
+            <template v-if="step==='addleave'">
+                <el-form-item>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                    <el-button type="danger" @click="cancel">鎾ら攢</el-button>
+                </el-form-item>
+            </template>
+            <template v-if="step==='modifyapply'">
+                <el-form-item label="鏄惁閲嶆柊鐢宠" >
+                    <el-radio-group v-model="form.reapply">
+                        <el-radio label="true">鏄�</el-radio>
+                        <el-radio label="false">鍚�</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item>
+                    <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+                </el-form-item>
+            </template>
+        </el-form>
+    </div>
+</template>
+
+<script>
+
+// comment: "1"
+// deptleaderapprove: "true"
+// hr: "admin"
+
+const stepMap = {
+    // 鍙戣捣璇峰亣鐢宠,姝ゅ涓洪┏鍥炲悗杩斿洖鐨勪綅缃�
+    addleave: "addleave",
+    // 璇峰亣娴佺▼涓嫆缁濊繃绋�,鍥炲埌鐢宠浜鸿繘琛屼慨鏀�
+    modifyapply: "modifyapply",
+    // 閮ㄩ棬棰嗗瀹℃壒
+    deptleadercheck: "deptleaderapprove",
+    // 浜轰簨瀹℃壒
+    hrcheck: "hrapprove",
+    // 閿�鍋�
+    destroyapply: "destroyapply"
+};
+
+import {listUser} from "@/api/system/user.js"
+export default {
+    props: {
+        step: {
+            type: String,
+            default: ""
+        },
+        formInfo: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    data() {
+        return {
+            form: {
+                reapply: "true",
+                resource: "true",
+                realityStartTime: "",
+                realityEndTime: "",
+                userId: "",
+                endTime: "",
+                startTime: "",
+                reason: "",
+                leaveType: "",
+                comment: ""
+            },
+            leaveTypeList: [" 浜嬪亣", "鐥呭亣", "骞村亣", "涓у亣", "骞村亣"],
+            userList: []
+        };
+    },
+    computed: {
+        canNotEdit() {
+            return this.step !== "addleave" && this.step !== "modifyapply";
+        }
+    },
+    watch: {
+        formInfo(newFormData) {
+            this.form.userId = newFormData.userId;
+            this.form.endTime = newFormData.endTime;
+            this.form.startTime = newFormData.startTime;
+            this.form.reason = newFormData.reason;
+            this.form.comment = newFormData.comment;
+            this.form.leaveType = newFormData.leaveType;
+            this.form.realityEndTime = newFormData.realityEndTime;
+            this.form.realityStartTime = newFormData.realityStartTime;
+        }
+    },
+    mounted() {
+        listUser().then(res => {
+            console.log("鑾峰彇鐢ㄦ埛", res);
+            this.userList = res.rows;
+            this.form.hr = this.userList[0] && this.userList[0].userName;
+        });
+    },
+    methods: {
+        onSubmit() {
+            this.$emit("submit", {
+                ...this.form,
+                [stepMap[this.step]]: this.form.resource,
+            });
+        },
+        reject() {
+            this.$emit("reject")
+        },
+        cancel() {
+            this.$emit("cancel")
+        }
+    }
+};
+</script>
diff --git a/src/views/todo/components/meetingForm.vue b/src/views/todo/components/meetingForm.vue
new file mode 100644
index 0000000..07f9bc4
--- /dev/null
+++ b/src/views/todo/components/meetingForm.vue
@@ -0,0 +1,75 @@
+<template>
+    <div class="c-meeting-form">
+        <el-form  ref="form" :model="form" label-width="80px">
+            <el-form-item label="浼氳涓婚">
+                <el-input v-model="form.topic" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="涓绘寔浜�">
+                <el-input v-model="form.host" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="浼氳鍦板潃">
+                <el-input v-model="form.place" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="鍙備細浜哄憳">
+                <el-input v-model="form.peoplelist" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="寮�濮嬫椂闂�">
+                <el-input v-model="form.startTime" disabled></el-input>
+            </el-form-item>
+            <el-form-item label="缁撴潫鏃堕棿">
+                <el-input v-model="form.endTime" disabled></el-input>
+            </el-form-item>
+            <el-form-item v-if="step === 'input'" label="浼氳绾">
+                <el-input type="textarea" v-model="form.content"></el-input>
+            </el-form-item>
+            <el-form-item>
+                <el-button type="primary" @click="onSubmit">{{step === "signate" ? "绛惧埌" : "鎻愪氦"}}</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+
+<script>
+
+export default {
+    props: {
+        step: {
+            type: String,
+            default: ""
+        },
+        formInfo: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    data() {
+        return {
+            form: {
+                place: "",
+                endTime: "",
+                peoplelist: "",
+                startTime: "",
+                topic: "",
+                host: ""
+            }
+        };
+    },
+    watch: {
+        formInfo(newFormValue) {
+            this.form.place = newFormValue.place;
+            this.form.endTime = newFormValue.endTime;
+            this.form.peoplelist = newFormValue.peoplelist;
+            this.form.startTime = newFormValue.startTime;
+            this.form.topic = newFormValue.topic;
+            this.form.host = newFormValue.host;
+        }
+    },
+    methods: {
+        onSubmit() {
+            this.$emit("submit", {
+                content: this.form.content
+            })
+        }
+    }
+};
+</script>
diff --git a/src/views/todo/components/processForm.vue b/src/views/todo/components/processForm.vue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/views/todo/components/processForm.vue
diff --git a/src/views/todo/components/purchaseForm.vue b/src/views/todo/components/purchaseForm.vue
new file mode 100644
index 0000000..cd3b6e8
--- /dev/null
+++ b/src/views/todo/components/purchaseForm.vue
@@ -0,0 +1,103 @@
+<template>
+    <div class="c-purchase-form">
+        <el-form  ref="form" :model="form" label-width="100px">
+            <el-form-item label="鐢宠浜�">
+                <el-input v-model="form.applyer" :disabled="true"></el-input>
+            </el-form-item>
+            <el-form-item label="鐢宠鏃堕棿">
+                <el-input v-if="step !== 'updateapply'" v-model="form.applytime" :disabled="canNotEdit">></el-input>
+                <el-date-picker v-else type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="閫夋嫨鏃ユ湡" v-model="form.applytime" style="width: 100%;"></el-date-picker>
+            </el-form-item>
+            <el-form-item label="閲囪喘娓呭崟">
+                <el-input v-model="form.itemlist" :disabled="canNotEdit">></el-input>
+            </el-form-item>
+            <el-form-item label="鎬讳环">
+                <el-input v-model="form.total" :disabled="canNotEdit">></el-input>
+            </el-form-item>
+            <template v-if="step === 'finance' || step === 'purchasemanager'|| step ==='manager'">
+                <el-form-item label="瀹℃壒缁撴灉">
+                    <el-radio-group v-model="form.result">
+                        <el-radio label="true">鍚屾剰</el-radio>
+                        <el-radio label="false">鎷掔粷</el-radio>
+                    </el-radio-group>
+                </el-form-item>
+                <el-form-item label="瀹℃壒鎰忚">
+                    <el-input type="textarea" v-model="form.comment"></el-input>
+                </el-form-item>
+            </template>
+            <el-form-item label="鏄惁閲嶆柊鐢宠" v-if="step==='updateapply'">
+                <el-radio-group v-model="form.updateapply">
+                    <el-radio label="true">鏄�</el-radio>
+                    <el-radio label="false">鍚�</el-radio>
+                </el-radio-group>
+            </el-form-item>
+            <el-form-item>
+                <el-button type="primary" @click="onSubmit">鎻愪氦</el-button>
+            </el-form-item>
+        </el-form>
+    </div>
+</template>
+
+<script>
+
+
+const keyMap = {
+    purchasemanager: "purchaseauditi",
+    finance: "finance",
+    pay: "pay",
+    manager: "manager",
+    receiveitem: "receiveitem",
+    // 鎷掔粷鍚庯紝鐢宠浜洪噸鏂扮敵璇�
+    updateapply: "updateapply"
+};
+export default {
+    props: {
+        step: {
+            type: String,
+            default: ""
+        },
+        formInfo: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    data() {
+        return {
+            form: {
+                updateapply: "true",
+                result: "true",
+                applyer: "",
+                applytime: "",
+                itemlist: "",
+                total: "",
+                comment: ""
+            }
+        };
+    },
+    watch: {
+        formInfo(newFormValue) {
+            this.form.applyer = newFormValue.applyer;
+            this.form.applytime = newFormValue.applytime;
+            this.form.itemlist = newFormValue.itemlist;
+            this.form.total = newFormValue.total;
+            this.form.comment = newFormValue.comment;
+        }
+    },
+    computed: {
+        canNotEdit() {
+            return this.step !== "updateapply";
+        }
+    },
+    methods: {
+        onSubmit() {
+            const params = {
+                ...this.form
+            };
+            if (this.step !== "updateapply") {
+                params[keyMap[this.step]] = this.form.result;
+            }
+            this.$emit("submit", params)
+        }
+    }
+};
+</script>
diff --git a/src/views/todo/myTodoList.vue b/src/views/todo/myTodoList.vue
new file mode 100644
index 0000000..e83f4bc
--- /dev/null
+++ b/src/views/todo/myTodoList.vue
@@ -0,0 +1,156 @@
+<template>
+    <div>
+        <div class="search-bar">
+            <div>
+                <label>娴佺▼鍚嶇О</label>
+                <el-input v-model="searchParams.processName" size="small"></el-input>
+            </div>
+            <div>
+                <label>浠诲姟鍚嶇О</label>
+                 <el-input v-model="searchParams.taskName" size="small"></el-input>
+            </div>
+            <div>
+                <el-button type="primary" @click="search" size="mini" icon="el-icon-search">鎼滅储</el-button>
+                <el-button type="default" @click="reset" size="mini" icon="el-icon-refresh">閲嶇疆</el-button>
+            </div>
+        </div>
+        <table-template
+            :data="tableData"
+            :total="total"
+            @page-change="handlePageChange"
+        >
+            <template #columns>
+                <el-table-column
+                    prop="taskName"
+                    label="浠诲姟鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="processInstanceId"
+                    label="娴佺▼瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="executionId"
+                    label="鎵ц瀹炰緥缂栧彿">
+                </el-table-column>
+                <el-table-column
+                    prop="businessKey"
+                    label="涓氬姟鍙�">
+                </el-table-column>
+                <el-table-column
+                    prop="processName"
+                    label="娴佺▼鍚嶇О">
+                </el-table-column>
+                <el-table-column
+                    prop="starter"
+                    label="鍙戣捣浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="assignee"
+                    label="鍔炵悊浜�">
+                </el-table-column>
+                <el-table-column
+                    prop="createTime"
+                    label="浠诲姟鍒涘缓鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="startTime"
+                    label="娴佺▼鍚姩鏃堕棿">
+                </el-table-column>
+                <el-table-column
+                    prop="operation"
+                    label="鎿嶄綔">
+                    <template slot-scope="scope">
+                        <el-button
+                        size="mini"
+                        type="text"
+                        @click="handleTodo(scope.$index, scope.row)">鍔炵悊</el-button>
+                    </template>
+                </el-table-column>
+            </template>
+        </table-template>
+    </div>
+</template>
+
+<script>
+import TableTemplate from "@/components/TableTemplate";
+import {getMyTodoList} from "./api/myTodoList";
+
+export default {
+    name: "AllTodoList",
+    components: {
+        TableTemplate
+    },
+    data() {
+        return {
+            responseData: {},
+            searchParams: {
+                taskName: "",
+                processName: "",
+                pageNum: 1,
+                pageSize: 10
+            }
+        };
+    },
+    computed: {
+        tableData() {
+            return this.responseData.rows || []
+        },
+        total() {
+            return this.responseData.total || 0
+        }
+    },
+    mounted() {
+       this.getAllTodoListByParamsAndRender(this.searchParams);
+    },
+    methods: {
+        getAllTodoListByParamsAndRender(params) {
+            const {pageSize = 1, pageNum = 10, processName = "", taskName = ""} = params;
+            getMyTodoList({
+                pageSize,
+                pageNum,
+                isAsc: "asc",
+                processName,
+                taskName
+            }).then(res => {
+                this.responseData = res;
+            });
+        },
+        search() {
+            this.getAllTodoListByParamsAndRender(this.searchParams);
+        },
+        reset() {
+            this.searchParams.processName = "";
+            this.searchParams.taskName = "";
+            this.getAllTodoListByParamsAndRender(this.searchParams);
+        },
+        handlePageChange() {},
+        handleTodo(index, row) {
+            console.log("todo", row);
+            const {formKey, taskId, businessKey} = row;
+            this.$router.push({
+                path: `/process/${formKey}/${taskId}?id=${businessKey}`,
+                meta: { title: "娴嬭瘯" },
+                params: {row}
+            })
+        }
+    },
+};
+</script>
+
+<style scoped>
+label {
+    font-size: 14px;
+    color: #606266;
+    margin-right: 8px;
+}
+.search-bar {
+    display: flex;
+    margin-top: 8px;
+    margin-left: 8px;
+}
+.el-input {
+    display: inline-block;
+    width: 300px;
+    margin-right: 10px;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/todo/processTask.vue b/src/views/todo/processTask.vue
new file mode 100644
index 0000000..4ad1076
--- /dev/null
+++ b/src/views/todo/processTask.vue
@@ -0,0 +1,208 @@
+<template>
+    <div class="c-process-task">
+        <div class="c-process-task__form">
+            <leave-apply-form
+                v-if="taskType === 'leaveapply'"
+                :step="step"
+                :form-info="formInfo"
+                @submit="handleSubmit"
+                @cancel="handleCancel"
+                @reject="handleReject"
+            ></leave-apply-form>
+            <purchase-form
+                v-if="taskType === 'purchase'"
+                :step="step"
+                :form-info="formInfo"
+                @submit="handleSubmit"
+            ></purchase-form>
+            <meeting-form
+                v-if="taskType === 'meeting'"
+                :step="step"
+                :form-info="formInfo"
+                @submit="handleSubmit"
+            ></meeting-form>
+        </div>
+        <div>
+            <time-line :activities="activities"></time-line>
+        </div>
+    </div>
+</template>
+
+<script>
+import {
+    getProcessByTaskid,
+    processTask,
+    fillMeetingRecord,
+    checkoutLeave,
+    forceEnd,
+    rejectLeave,
+    updatePurchase,
+    getInfoByTaskId
+} from "./api/myTodoList";
+import TimeLine from './components/TimeLine.vue';
+
+import leaveApplyForm from './components/leaveApplyForm.vue';
+import meetingForm from './components/meetingForm.vue';
+import purchaseForm from './components/purchaseForm.vue';
+import LeaveApply from '../function/leaveApply.vue';
+const urlMap = {
+    // 閮ㄩ棬棰嗗瀹℃壒
+    "deptleadercheck": "/leaveapply/deptleadercheck",
+    // 浜轰簨瀹℃壒
+    "hrcheck": "/leaveapply/hrcheck",
+    // 閿�鍋�
+    "destroyapply": "/leaveapply/destroyapply",
+    // 璇峰亣娴佺▼涓嫆缁濊繃绋�,鍥炲埌鐢宠浜鸿繘琛屼慨鏀�
+    "modifyapply": "/leaveapply/modifyapply",
+    // 鍙戣捣璇峰亣鐢宠,姝ゅ涓洪┏鍥炲悗杩斿洖鐨勪綅缃�
+    "addleave": "/leaveapply/addleave",
+
+    purchasemanager: "/purchase/purchasemanager",
+    finance: "/purchase/finance",
+    pay: "/purchase/pay",
+    receiveitem: "/purchase/receiveitem",
+    manager: "/purchase/manager",
+    // 鎷掔粷鍚庯紝鐢宠浜洪噸鏂扮敵璇�
+    updateapply: "/purchase/updateapply",
+
+    input: "/meeting/input",
+    signate: "/meeting/signate"
+}
+export default {
+    components: {
+        TimeLine,
+        leaveApplyForm,
+        meetingForm,
+        purchaseForm,
+        LeaveApply
+    },
+    data() {
+        return {
+            activities: [],
+            taskType: "",
+            step: "",
+            taskId: "",
+            formInfo: {}
+        };
+    },
+    mounted() {
+        console.log("寰呭姙", this.$route.params)
+        const {taskId, taskType, step} = this.$route.params;
+        this.taskId = taskId;
+        this.taskType = taskType;
+        this.step = step;
+        getProcessByTaskid(taskId).then(res => {
+            console.log("鎷垮埌娴佺▼淇℃伅", res);
+            this.activities = res;
+        });
+        console.log("step","taskId",step ,urlMap[step], taskId);
+        getInfoByTaskId(urlMap[step], taskId).then(res => {
+            console.log("step","taskId", res);
+            if (res.data) {
+                this.formInfo = res.data;
+            }
+        });
+    },
+    methods: {
+        handleSubmit(data) {
+            if (this.taskType === "meeting") {
+                if (this.step === "input") {
+                    const id = this.$route.query.id;
+                    const {content} = data;
+                    console.log(id);
+                    fillMeetingRecord({
+                        id,
+                        content
+                    }).then(res => {
+                        console.log("瀹℃壒閫氳繃!");
+                    });
+                }
+            }
+     
+            if (this.taskType === "leaveapply") {
+                if (
+                    this.step === "destroyapply"
+                    || this.step === "addLeave"
+                    || this.step === "modifyapply"
+                ) {
+                    const {realityStartTime, realityEndTime, reapply} = data;
+                    const id = this.$route.query.id;
+                    const taskId = this.taskId;
+                    checkoutLeave({
+                        ...data,
+                        id,
+                        taskId
+                    }).then(res => {
+                        console.log("閿�鍋囨垚鍔燂紒");
+                    });
+                }
+            }
+
+            if (this.taskType === "purchase") {
+                const id = this.$route.query.id;
+                const taskId = this.taskId;
+                if ( this.step === "updateapply") {
+                    updatePurchase({
+                        ...data,
+                        id,
+                        taskId
+                    }).then(res => {
+                        console.log("鏇存柊鎴愬姛!");
+                    });
+                }
+            }
+            processTask({
+                taskId: this.taskId,
+                ...data
+            }).then(res => {
+                this.$message.success("澶勭悊鎴愬姛!");
+                this.$tab.closePage(this.$route).then(({ visitedViews }) => {
+                    this.toLastView(visitedViews, this.$route)
+                });
+            });
+        },
+        toLastView(visitedViews, view) {
+            const latestView = visitedViews.slice(-1)[0]
+            if (latestView) {
+                this.$router.push(latestView.fullPath)
+            } else {
+                // now the default is to redirect to the home page if there is no tags-view,
+                // you can adjust it according to your needs.
+                if (view.name === 'Dashboard') {
+                // to reload home page
+                this.$router.replace({ path: '/redirect' + view.fullPath })
+                } else {
+                this.$router.push('/')
+                }
+            }
+        },
+        handleCancel() {
+            forceEnd(this.taskId).then(res => {
+                console.log("鎾ら攢鎴愬姛");
+                this.$tab.closePage(this.$route).then(({ visitedViews }) => {
+                    this.toLastView(visitedViews, this.$route)
+                });
+            });
+        },
+        handleReject() {
+            rejectLeave(this.taskId).then(res => {
+                console.log("椹冲洖鎴愬姛!");
+                this.$tab.closePage(this.$route).then(({ visitedViews }) => {
+                    this.toLastView(visitedViews, this.$route)
+                });
+            })
+        },
+    }
+};
+</script>
+
+<style>
+.c-process-task {
+    padding: 16px;
+    display: flex;
+    justify-content: center;
+}
+.c-process-task__form {
+    width: 500px;
+}
+</style>
diff --git a/vue.config.js b/vue.config.js
index 05a393b..12d3629 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -27,7 +27,6 @@
   lintOnSave: process.env.NODE_ENV === 'development',
   // 濡傛灉浣犱笉闇�瑕佺敓浜х幆澧冪殑 source map锛屽彲浠ュ皢鍏惰缃负 false 浠ュ姞閫熺敓浜х幆澧冩瀯寤恒��
   productionSourceMap: false,
-  transpileDependencies: ['quill'],
   // webpack-dev-server 鐩稿叧閰嶇疆
   devServer: {
     host: '0.0.0.0',

--
Gitblit v1.8.0