xiangpei
2024-11-21 fa91cc6202aabdbe3805d26e89a776656790d7d1
初始化
32个文件已添加
5039 ■■■■■ 已修改文件
src/assets/images/login-backgroun1d.jpg 补丁 | 查看 | 原始文档 | blame | 历史
src/components/TableTemplate/index.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/common.js 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/function/api/leaveApply.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/function/api/meeting.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/function/api/purchase.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/function/lauchMeeting.vue 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/function/leaveApply.vue 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/function/purchaseApply.vue 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/indexBar.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index_old.vue 1067 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inspection/api.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inspection/components/workTable.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inspection/processInstance.vue 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inspection/runHistory.vue 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inspection/runInstance.vue 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inspection/workManagement.vue 271 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/process/api/deployService.js 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/process/api/model.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/process/deployManagement.vue 300 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/process/modelManagement.vue 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/allTodoList.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/api/allTodoList.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/api/myTodoList.js 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/api/processTaks.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/components/TimeLine.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/components/leaveApplyForm.vue 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/components/meetingForm.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/components/processForm.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/components/purchaseForm.vue 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/myTodoList.vue 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/todo/processTask.vue 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/images/login-backgroun1d.jpg
src/components/TableTemplate/index.vue
New file
@@ -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>
src/utils/common.js
New file
@@ -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
};
src/views/function/api/leaveApply.js
New file
@@ -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
    });
}
src/views/function/api/meeting.js
New file
@@ -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
    });
}
src/views/function/api/purchase.js
New file
@@ -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
    });
}
src/views/function/lauchMeeting.vue
New file
@@ -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("填写的form值是", 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>
src/views/function/leaveApply.vue
New file
@@ -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>
src/views/function/purchaseApply.vue
New file
@@ -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>
src/views/indexBar.vue
New file
@@ -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>
src/views/index_old.vue
New file
@@ -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,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
        </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>代码生成支持选择前端模板类型</li>
                <li>显隐列组件支持复选框弹出类型</li>
                <li>通用排序属性orderBy参数限制长度</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>修复外链带端口出现的异常</li>
                <li>修复树模板父级编码变量错误</li>
                <li>修复字典表详情页面搜索问题</li>
                <li>修复内链iframe没有传递参数问题</li>
                <li>修复自定义字典样式不生效的问题</li>
                <li>修复字典缓存删除方法参数错误问题</li>
                <li>修复Excel导入数据临时文件无法删除问题</li>
                <li>修复未登录带参数访问成功后参数丢失问题</li>
                <li>修复HeaderSearch组件跳转query参数丢失问题</li>
                <li>修复代码生成导入后必填项与数据库不匹配问题</li>
                <li>修复Excels导入时无法获取到dictType字典值问题</li>
                <li>优化下载zip方法新增遮罩层</li>
                <li>优化头像上传参数新增文件名称</li>
                <li>优化字典标签支持自定义分隔符</li>
                <li>优化菜单管理类型为按钮状态可选</li>
                <li>优化前端防重复提交数据大小限制</li>
                <li>优化TopNav菜单没有图标svg不显示</li>
                <li>优化数字金额大写转换精度丢失问题</li>
                <li>优化富文本Editor组件检验图片格式</li>
                <li>优化页签在Firefox浏览器被遮挡的问题</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>修复开启TopNav后一级菜单路由参数设置无效问题</li>
                <li>修复DictTag组件value没有匹配的值时则展示value</li>
                <li>优化文件下载出现的异常</li>
                <li>优化选择图标组件高亮回显</li>
                <li>优化弹窗后导航栏偏移的问题</li>
                <li>优化修改密码日志存储明文问题</li>
                <li>优化页签栏关闭其他出现的异常问题</li>
                <li>优化页签关闭左侧选项排除首页选项</li>
                <li>优化关闭当前tab页跳转最右侧tab页</li>
                <li>优化缓存列表清除操作提示不变的问题</li>
                <li>优化字符未使用下划线不进行驼峰式处理</li>
                <li>优化用户导入更新时需获取用户编号问题</li>
                <li>优化侧边栏的平台标题与VUE_APP_TITLE保持同步</li>
                <li>优化导出Excel时设置dictType属性重复查缓存问题</li>
                <li>连接池Druid支持新的配置connectTimeout和socketTimeout</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>开启TopNav没有子菜单隐藏侧边栏</li>
                <li>删除fuse无效选项maxPatternLength</li>
                <li>优化导出对象的子列表为空会出现[]问题</li>
                <li>优化编辑头像时透明部分会变成黑色问题</li>
                <li>优化小屏幕上修改头像界面布局错位的问题</li>
                <li>修复代码生成勾选属性无效问题</li>
                <li>修复文件上传组件格式验证问题</li>
                <li>修复回显数据字典数组异常问题</li>
                <li>修复sheet超出最大行数异常问题</li>
                <li>修复Log注解GET请求记录不到参数问题</li>
                <li>修复调度日志点击多次数据不变化的问题</li>
                <li>修复主题颜色在Drawer组件不会加载问题</li>
                <li>修复文件名包含特殊字符的文件无法下载问题</li>
                <li>修复table中更多按钮切换主题色未生效修复问题</li>
                <li>修复某些特性的环境生成代码变乱码TXT文件问题</li>
                <li>修复代码生成图片/文件/单选时选择必填无法校验问题</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>登录日志新增解锁账户功能</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>优化代码生成同步后值NULL问题</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>代码生成树表新增(展开/折叠)</li>
                <li>Excel注解支持color字体颜色</li>
                <li>新增Anonymous匿名访问不鉴权注解</li>
                <li>用户头像上传限制只能为图片格式</li>
                <li>接口使用泛型使其看到响应属性字段</li>
                <li>检查定时任务bean所在包名是否为白名单配置</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>删除多余的salt字段</li>
                <li>新增获取不带后缀文件名称方法</li>
                <li>新增获取配置文件中的属性值方法</li>
                <li>新增内容编码/解码方便插件集成使用</li>
                <li>字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)</li>
                <li>优化设置分页参数默认值</li>
                <li>优化对空字符串参数处理的过滤</li>
                <li>优化显示顺序orderNum类型为整型</li>
                <li>优化表单构建按钮不显示正则校验</li>
                <li>优化字典数据回显样式下拉框显示值</li>
                <li>优化R响应成功状态码与全局保持一致</li>
                <li>优化druid开启wall过滤器出现的异常问题</li>
                <li>优化用户管理左侧树型组件增加选中高亮保持</li>
                <li>优化新增用户与角色信息&用户与岗位信息逻辑</li>
                <li>优化默认不启用压缩文件缓存防止node_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>开启TopNav没有子菜单情况隐藏侧边栏</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>代码生成列表图片支持预览</li>
                <li>代码生成编辑修改打开新页签</li>
                <li>代码生成新增Java类型Boolean</li>
                <li>代码生成子表支持日期/字典配置</li>
                <li>代码生成同步保留必填/类型选项</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前端代码生成模板</li>
                <li>新增图片预览组件</li>
                <li>新增压缩插件实现打包Gzip</li>
                <li>自定义xss校验注解实现</li>
                <li>自定义文字复制剪贴指令</li>
                <li>代码生成预览支持复制内容</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到最新版本v5.8.6</li>
                <li>升级fastjson到最新版1.2.79</li>
                <li>升级spring-boot到最新版本2.5.8</li>
                <li>升级log4j2到2.17.1,防止漏洞风险</li>
                <li>优化下载解析blob异常提示</li>
                <li>优化代码生成字典组重复问题</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依赖,防止jdk8以上出现的兼容错误</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到最新版本v5.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>代码生成点击预览重置激活tab</li>
                <li>AjaxResult重写put方法,以方便链式调用</li>
                <li>优化登录/验证码请求headers不设置token</li>
                <li>优化用户个人信息接口防止修改用户名</li>
                <li>优化Cron表达式生成器关闭时销毁避免缓存</li>
                <li>优化注册成功提示消息类型success</li>
                <li>优化aop语法,使用spring自动注入注解</li>
                <li>优化记录登录信息,移除不必要的修改</li>
                <li>优化mybatis全局默认的执行器</li>
                <li>优化Excel导入图片可能出现的异常</li>
                <li>修复代码生成模板主子表删除缺少事务</li>
                <li>修复日志记录可能出现的转换异常</li>
                <li>修复代码生成复选框字典遗漏问题</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>支持自定义注解实现接口限流</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>代码生成主子表多选行数据</li>
                <li>日期范围支持添加多组</li>
                <li>升级element-ui到最新版本2.15.5</li>
                <li>升级oshi到最新版本v5.8.0</li>
                <li>升级commons.io到最新版本v2.11.0</li>
                <li>定时任务屏蔽ldap远程调用</li>
                <li>定时任务屏蔽http(s)远程调用</li>
                <li>补充定时任务表字段注释</li>
                <li>定时任务对检查异常进行事务回滚</li>
                <li>启用父部门状态排除顶级节点</li>
                <li>富文本新增上传文件大小限制</li>
                <li>默认首页使用keep-alive缓存</li>
                <li>修改代码生成字典回显样式</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>优化代码生成模板</li>
                <li>验证码默认20s超时</li>
                <li>BLOB下载时清除URL对象引用</li>
                <li>代码生成导入表按创建时间排序</li>
                <li>修复代码生成页面数据编辑保存之后总是跳转第一页的问题</li>
                <li>修复带safari浏览器无法格式化utc日期格式yyyy-MM-dd'T'HH:mm:ss.SSS问题</li>
                <li>多图上传组件移除多余的api地址&验证失败导致图片删除问题&无法删除相应图片修复</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>富文本默认上传返回url类型</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到最新版本v5.7.4</li>
                <li>升级element-ui到最新版本2.15.2</li>
                <li>升级pagehelper到最新版1.3.1</li>
                <li>升级commons.io到最新版本v2.10.0</li>
                <li>升级commons.fileupload到最新版本v1.4</li>
                <li>升级swagger到最新版本v3.0.0</li>
                <li>修复关闭confirm提示框控制台报错问题</li>
                <li>修复存在的SQL注入漏洞问题</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(false为左侧导航菜单,true为顶部导航菜单)</li>
                <li>布局设置支持保存&重置配置</li>
                <li>修复树表数据显示不全&加载慢问题</li>
                <li>新增IE浏览器版本过低提示页面</li>
                <li>用户登录后记录最后登录IP&时间</li>
                <li>页面导出按钮点击之后添加遮罩</li>
                <li>富文本编辑器支持自定义上传地址</li>
                <li>富文本编辑组件新增readOnly属性</li>
                <li>页签TagsView新增关闭右侧功能</li>
                <li>显隐列组件加载初始默认隐藏列</li>
                <li>关闭头像上传窗口还原默认图片</li>
                <li>个人信息添加手机&邮箱重复验证</li>
                <li>代码生成模板导出按钮点击后添加遮罩</li>
                <li>代码生成模板树表操作列添加新增按钮</li>
                <li>代码生成模板修复主子表字段重名问题</li>
                <li>升级fastjson到最新版1.2.76</li>
                <li>升级druid到最新版本v1.2.6</li>
                <li>升级mybatis到最新版3.5.6 阻止远程代码执行漏洞</li>
                <li>升级oshi到最新版本v5.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>树级结构更新子节点使用replaceFirst</li>
                <li>优化ExcelUtil空值处理</li>
                <li>日志记录过滤BindingResult对象,防止异常</li>
                <li>修改主题后mini类型按钮无效问题</li>
                <li>优化通用下载完成后删除节点</li>
                <li>通用Controller添加响应返回消息</li>
                <li>其他细节优化</li>
              </ol>
            </el-collapse-item>
            <el-collapse-item title="v3.4.0 - 2021-02-22">
              <ol>
                <li>代码生成模板支持主子表</li>
                <li>表格右侧工具栏组件支持显隐列</li>
                <li>图片组件添加预览&移除功能</li>
                <li>Excel注解支持Image图片导出</li>
                <li>操作按钮组调整为朴素按钮样式</li>
                <li>代码生成支持文件上传组件</li>
                <li>代码生成日期控件区分范围</li>
                <li>代码生成数据库文本类型生成表单文本域</li>
                <li>用户手机邮箱&菜单组件修改允许空字符串</li>
                <li>升级SpringBoot到最新版本2.2.13 提升启动速度</li>
                <li>升级druid到最新版本v1.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>权限工具类增加admin判断</li>
                <li>角色非自定义权限范围清空选择值</li>
                <li>修复导入数据为负浮点数时丢失精度问题</li>
                <li>移除path-to-regexp正则匹配插件</li>
                <li>修复生成树表代码异常</li>
                <li>修改ip字段长度防止ipv6地址长度不够</li>
                <li>防止get请求参数值为false或0等特殊值会导致无法正确的传参</li>
                <li>登录后push添加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>代码生成预览支持高亮显示</li>
                <li>支持Get请求映射Params参数</li>
                <li>删除用户和角色解绑关联</li>
                <li>去除用户手机邮箱部门必填验证</li>
                <li>Excel支持注解align对齐方式</li>
                <li>Excel支持导入Boolean型数据</li>
                <li>优化头像样式,鼠标移入悬停遮罩</li>
                <li>代码生成预览提供滚动机制</li>
                <li>代码生成删除多余的数字float类型</li>
                <li>修正转换字符串的目标字符集属性</li>
                <li>回显数据字典防止空值报错</li>
                <li>日志记录增加过滤多文件场景</li>
                <li>修改缓存Set方法可能导致嵌套的问题</li>
                <li>移除前端一些多余的依赖</li>
                <li>防止安全扫描YUI出现的风险提示</li>
                <li>修改node-sass为dart-sass</li>
                <li>升级SpringBoot到最新版本2.1.18</li>
                <li>升级poi到最新版本4.1.2</li>
                <li>升级oshi到最新版本v5.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>代码生成支持上传控件</li>
                <li>新增图片上传组件</li>
                <li>调整默认首页</li>
                <li>升级druid到最新版本v1.2.2</li>
                <li>mapperLocations配置支持分隔符</li>
                <li>权限信息调整</li>
                <li>调整sql默认时间</li>
                <li>解决代码生成没有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到最新版本v5.2.5</li>
                <li>升级druid到最新版本v1.2.1</li>
                <li>升级jjwt到版本0.9.1</li>
                <li>升级fastjson到最新版1.2.74</li>
                <li>修改sass为node-sass,避免el-icon图标乱码</li>
                <li>代码生成支持同步数据库</li>
                <li>代码生成支持富文本控件</li>
                <li>代码生成页面时不忽略remark属性</li>
                <li>代码生成添加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>代码生成支持选择上级菜单</li>
                <li>代码生成支持自定义路径</li>
                <li>代码生成支持复选框</li>
                <li>Excel导出导入支持dictType字典类型</li>
                <li>Excel支持分割字符串组内容</li>
                <li>验证码类型支持(数组计算、字符验证)</li>
                <li>升级vue-cli版本到4.4.4</li>
                <li>修改 node-sass 为 dart-sass</li>
                <li>表单类型为Integer/Long设置整形默认值</li>
                <li>代码生成器默认mapper路径与默认mapperScan路径不一致</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>修复代码生成导入表结构出现异常页面不提醒问题</li>
                <li>修复代码生成点击多次表修改数据不变化的问题</li>
                <li>修复头像上传成功二次打开无法改变裁剪框大小和位置问题</li>
                <li>修复布局为small者mini用户表单显示错位问题</li>
                <li>修复热部署导致的强换异常问题</li>
                <li>修改用户管理复选框宽度,防止部分浏览器出现省略号</li>
                <li>IpUtils工具,清除Xss特殊字符,防止Xff注入攻击</li>
                <li>生成domain 如果是浮点型 统一用BigDecimal</li>
                <li>定时任务调整label-width,防止部署出现错位</li>
                <li>调整表头固定列默认样式</li>
                <li>代码生成模板调整,字段为String并且必填则加空串条件</li>
                <li>代码生成字典Integer/Long使用parseInt</li>
                <li>
                  修复dict_sort不可update为0的问题&查询返回增加dict_sort升序排序
                </li>
                <li>修正岗位导出权限注解</li>
                <li>禁止加密密文返回前端</li>
                <li>修复代码生成页面中的查询条件创建时间未生效的问题</li>
                <li>修复首页搜索菜单外链无法点击跳转问题</li>
                <li>修复菜单管理选择图标,backspace删除时不过滤数据</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>当tags-view滚动关闭右键菜单</li>
                <li>字典管理添加缓存读取</li>
                <li>参数管理支持缓存操作</li>
                <li>支持一级菜单(和主页同级)在main区域显示</li>
                <li>限制外链地址必须以http(s)开头</li>
                <li>tagview & sidebar 主题颜色与element ui(全局)同步</li>
                <li>修改数据源类型优先级,先根据方法,再根据类</li>
                <li>支持是否需要设置token属性,自定义返回码消息。</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类型请求构建可重复读取inputStream的request</li>
                <li>修改代码生成字典字段int类型没有自动选中问题</li>
                <li>vuex用户名取值修正</li>
                <li>表格树模板去掉多余的)</li>
                <li>代码生成序号修正</li>
                <li>全屏情况下不调整上外边距</li>
                <li>代码生成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>修复代码生成如果选择字典类型缺失逗号问题</li>
                <li>登录请求params更换为data,防止暴露url</li>
                <li>日志返回时间格式处理</li>
                <li>添加handle控制允许拖动的元素</li>
                <li>布局设置点击扩大范围</li>
                <li>代码生成列属性排序查询</li>
                <li>代码生成列支持拖动排序</li>
                <li>修复时间格式不支持ios问题</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>添加一个打包Web工程bat</li>
                <li>修复页签鼠标滚轮按下的时候,可以关闭不可关闭的tag</li>
                <li>修复点击退出登录有时会无提示问题</li>
                <li>修复防重复提交注解无效问题</li>
                <li>修复通知公告批量删除异常问题</li>
                <li>添加菜单时路由地址必填限制</li>
                <li>代码生成字段描述可编辑</li>
                <li>修复用户修改个人信息导致缓存不过期问题</li>
                <li>个人信息创建时间获取正确属性值</li>
                <li>操作日志详细显示正确类型</li>
                <li>导入表单击行数据时选中对应的复选框</li>
                <li>批量替换表前缀逻辑调整</li>
                <li>固定重定向路径表达式</li>
                <li>升级element-ui版本到2.13.0</li>
                <li>操作日志排序调整</li>
                <li>修复charts切换侧边栏或者缩放窗口显示bug</li>
                <li>其他细节优化</li>
              </ol>
            </el-collapse-item>
            <el-collapse-item title="v2.1.0 - 2020-02-24">
              <ol>
                <li>新增表单构建</li>
                <li>代码生成支持树表结构</li>
                <li>新增用户导入</li>
                <li>修复动态加载路由页面刷新问题</li>
                <li>修复地址开关无效问题</li>
                <li>汉化错误提示页面</li>
                <li>代码生成已知问题修改</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和Editor不显示处理</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>新增代码生成</li>
                <li>新增@RepeatSubmit注解,防止重复提交</li>
                <li>新增菜单主目录添加/删除操作</li>
                <li>日志记录过滤特殊对象,防止转换异常</li>
                <li>修改代码生成路由脚本错误</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>
src/views/inspection/api.js
New file
@@ -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'
        },
    });
}
src/views/inspection/components/workTable.vue
src/views/inspection/processInstance.vue
New file
@@ -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>
src/views/inspection/runHistory.vue
New file
@@ -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>
src/views/inspection/runInstance.vue
New file
@@ -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>
src/views/inspection/workManagement.vue
New file
@@ -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>
src/views/process/api/deployService.js
New file
@@ -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
  });
}
src/views/process/api/model.js
New file
@@ -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',
  });
}
src/views/process/deployManagement.vue
New file
@@ -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>提示:仅允许导入“bpmn”、“xml”或“zip”格式文件!</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>
src/views/process/modelManagement.vue
New file
@@ -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>
src/views/todo/allTodoList.vue
New file
@@ -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>
src/views/todo/api/allTodoList.js
New file
@@ -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'
        },
    });
}
src/views/todo/api/myTodoList.js
New file
@@ -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',
    });
}
src/views/todo/api/processTaks.js
New file
@@ -0,0 +1,10 @@
import request from '@/utils/request'
// 处理待办
export const processTask = data => {
    return request({
        url: '/task/manage/mylist',
        method: 'post',
        data
    });
}
src/views/todo/components/TimeLine.vue
New file
@@ -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>
src/views/todo/components/leaveApplyForm.vue
New file
@@ -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>
src/views/todo/components/meetingForm.vue
New file
@@ -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>
src/views/todo/components/processForm.vue
src/views/todo/components/purchaseForm.vue
New file
@@ -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>
src/views/todo/myTodoList.vue
New file
@@ -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>
src/views/todo/processTask.vue
New file
@@ -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>