Переглянути джерело

update:内部培训统计改进

luoaoxuan 1 рік тому
батько
коміт
2c0ce50c17

+ 14 - 0
src/api/platform/org/employee.js

@@ -338,3 +338,17 @@ export function removeRoleUser (params) {
         params: params
     })
 }
+
+// ===================内部培训人员============================================
+
+/**
+ * 内部培训统计
+ * @param {*} params
+ */
+export function getUserStatisticList (params) {
+    return request({
+        url: BUSINESS_BASE_URL() + '/employee/train/statistic',
+        method: 'get',
+        params
+    })
+}

+ 310 - 0
src/views/component/trainingManage/index.vue

@@ -0,0 +1,310 @@
+<template>
+    <div class="main-container">
+        <ibps-container
+            class="page"
+        >
+            <template>
+                <ibps-crud
+                    key="istree"
+                    ref="crud"
+                    :data="listData"
+                    :toolbars="listConfig.toolbars"
+                    :search-form="listConfig.searchForm"
+                    :pk-key="pkKey"
+                    :columns="listConfig.columns"
+                    :loading="loading"
+                    :pagination="pagination"
+                    :display-field="tableTitle"
+                    :index-row="false"
+                    @sort-change="handleSortChange"
+                    @action-event="handleAction"
+                    @pagination-change="handlePaginationChange"
+                >
+
+                    <template
+                        slot="userIdSlot"
+                        slot-scope="{row}"
+                    >
+                        <ibps-user-selector
+                            type="user"
+                            :value="row.id_"
+                            readonly-text="text"
+                            :disabled="true"
+                            :multiple="true"
+                        />
+
+                    </template>
+                    <template
+                        slot="positionIdSlot"
+                        slot-scope="{row}"
+                    >
+                        <ibps-user-selector
+                            type="position"
+                            :value="row.positions_"
+                            readonly-text="text"
+                            :disabled="true"
+                            :multiple="true"
+                        />
+                    </template>
+
+                    <template
+                        slot="customButton"
+                        slot-scope="{row}"
+                    >
+                        <el-button type="text" icon="el-icon-view" @click="goLook(row)">查阅</el-button>
+
+                    </template>
+
+                    <template slot="user">
+                        <ibps-user-selector
+                            v-model="user"
+                            type="user"
+                            readonly-text="text"
+                            :multiple="true"
+                        />
+                    </template>
+                    <template slot="position">
+                        <ibps-user-selector
+                            v-model="pos"
+                            type="position"
+                            readonly-text="text"
+                            :multiple="false"
+                        />
+                    </template>
+                    <template slot="time">
+                        <el-date-picker
+                            v-model="selectItem"
+                            size="mini"
+                            type="daterange"
+                            :picker-options="pickerOptions"
+                            range-separator="至"
+                            start-placeholder="开始日期"
+                            end-placeholder="结束日期"
+                            align="right"
+                            value-format="yyyy-MM-dd"
+                        />
+                    </template>
+                </ibps-crud>
+            </template>
+        </ibps-container>
+        <TrainingStatic v-if="dialogVisible" :params="params" @close="close" />
+
+    </div>
+</template>
+<script>
+import ActionUtils from '@/utils/action'
+import FixHeight from '@/mixins/height'
+import ibpsUserSelector from '@/business/platform/org/selector'
+
+import { getUserStatisticList } from '@/api/platform/org/employee'
+import TrainingStatic from './trainingStatic.vue'
+
+export default {
+    components: {
+        ibpsUserSelector, TrainingStatic
+    },
+    mixins: [FixHeight],
+    data () {
+        const { level, userList } = this.$store.getters
+        return {
+            level: level.second || level.first,
+            userList: userList,
+            dialogVisible: false,
+            params: {},
+            loading: false,
+            selectItem: '',
+            pickerOptions: {
+                shortcuts: [{
+                    text: '最近一周',
+                    onClick (picker) {
+                        const end = new Date()
+                        const start = new Date()
+                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
+                        picker.$emit('pick', [start, end])
+                    }
+                }, {
+                    text: '最近一个月',
+                    onClick (picker) {
+                        const end = new Date()
+                        const start = new Date()
+                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
+                        picker.$emit('pick', [start, end])
+                    }
+                }, {
+                    text: '最近三个月',
+                    onClick (picker) {
+                        const end = new Date()
+                        const start = new Date()
+                        start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
+                        picker.$emit('pick', [start, end])
+                    }
+                }]
+            },
+            allData: [],
+
+            pkKey: 'id', // 主键  如果主键不是pk需要传主键
+            pkValue: '',
+            templateKey: '',
+            visible: false,
+            categoryKey: '',
+            tableTitle: '内部培训统计',
+            listData: [],
+            selectListData: [],
+            bianlistData: {
+                dataResult: [],
+                pageResult: {
+                    limit: 0,
+                    page: 0,
+                    totalCount: 0,
+                    totalPages: 0
+                }
+            },
+            //   listTreeData: [],
+            listConfig: {
+                // 工具栏
+                toolbars: [
+                    { key: 'search' }
+                ],
+                // 查询条件
+                searchForm: {
+                    forms: [
+                        { prop: '', label: '姓名', fieldType: 'slot', slotName: 'user' },
+                        { prop: '', label: '部门', fieldType: 'slot', slotName: 'position' },
+                        { prop: '', label: '统计时段', fieldType: 'slot', slotName: 'time' }
+                    ]
+                },
+                // 表格字段配置
+                columns: [
+                    { prop: 'id_', label: '姓名', width: 100, slotName: 'userIdSlot' },
+                    { prop: 'positions_', label: '部门', width: 120, slotName: 'positionIdSlot' },
+                    { prop: 'jian_ding_zi_ge_z', label: '工号', width: 140 },
+                    { prop: 'planedjoin', label: '应参训次数', width: 120 },
+                    { prop: 'truejoin', label: '实参训次数', width: 120 },
+                    { prop: 'participationRate', label: '参训率', width: 120 },
+                    { label: '操作', width: 120, slotName: 'customButton' }
+                ]
+            },
+            pagination: {
+                limit: 20, page: 1
+            },
+            sorts: {},
+            sqlWhere: {},
+            searchWhere: {},
+            user: '',
+            pos: ''
+        }
+    },
+    mounted () {
+        this.getDatas()
+    },
+
+    methods: {
+        close () {
+            this.dialogVisible = false
+            this.getDatas()
+        },
+        goLook (row) {
+            this.params.peixunrenyuan = row.id_
+            if (this.selectItem && this.selectItem.length > 0) {
+                this.params.time = [this.selectItem[0], this.selectItem[1]]
+            } else {
+                delete this.params.time
+            }
+            this.dialogVisible = true
+        },
+        async getDatas () {
+            this.loading = true
+            const params = {
+                diDian: this.level
+            }
+            if (this.user) {
+                params.userId = this.user
+            }
+            if (this.pos) {
+                params.deptId = this.pos
+            }
+            if (this.selectItem && this.selectItem.length > 0) {
+                const [start, end] = this.selectItem
+                params.startTime = start
+                params.endTime = end
+            }
+            console.log('params', params)
+            try {
+                const { data: tempList } = await getUserStatisticList(params)
+                console.log('接口数据', tempList)
+                tempList.forEach(item => { item.jian_ding_zi_ge_z = item.jian_ding_zi_ge_z ? item.jian_ding_zi_ge_z : '/' })
+
+                // 默认参训率排序
+                tempList.sort((a, b) => {
+                    return b.participationRate.split('%')[0] - a.participationRate.split('%')[0]
+                })
+
+                this.selectListData = JSON.parse(JSON.stringify(tempList))
+
+                this.bianlistData.pageResult.totalCount = tempList.length
+                this.bianlistData.pageResult.totalPages = Math.ceil(tempList.length / this.pagination.limit)
+                this.bianlistData.pageResult.limit = this.pagination.limit
+                this.bianlistData.pageResult.page = 1
+                let filterDatas = []
+                if (this.pagination.limit > tempList.length) {
+                    filterDatas = JSON.parse(JSON.stringify(tempList))
+                } else {
+                    for (let index = 0; index < this.bianlistData.pageResult.limit; index++) {
+                        filterDatas.push(tempList[index])
+                    }
+                }
+                this.bianlistData.dataResult = filterDatas
+                ActionUtils.handleListData(this, this.bianlistData)
+                this.loading = false
+            } catch (error) {
+                if (error.message === '服务器君开小差了,请稍后再试') {
+                    this.$message.error('找不到接口,请切换服务环境')
+                }
+                this.loading = false
+            }
+        },
+        refreshData () {
+            this.listData = []
+            this.getDatas()
+        },
+        /**
+ * 处理按钮事件
+ */
+        handleAction (command, position, selection, data, index, button) {
+            switch (command) {
+                case 'search':// 查询
+                    this.refreshData()
+                    break
+                default:
+                    break
+            }
+        },
+        /**
+    * 处理排序
+    */
+        handleSortChange (sort) {
+            this.getDatas()
+        },
+        // 处理分页事件
+        handlePaginationChange (page) {
+            ActionUtils.setPagination(this.pagination, page)
+            this.bianlistData.pageResult.limit = page.limit
+            this.bianlistData.pageResult.page = page.page
+            const filterDatas = []
+            if (this.selectListData.length >= (page.limit * page.page)) {
+                for (let index = (page.limit * page.page) - page.limit; index < (page.limit * page.page); index++) {
+                    filterDatas.push(this.selectListData[index])
+                }
+                this.bianlistData.dataResult = JSON.parse(JSON.stringify(filterDatas))
+            } else {
+                for (let index = (page.limit * page.page) - page.limit; index < this.selectListData.length; index++) {
+                    filterDatas.push(this.selectListData[index])
+                }
+                this.bianlistData.dataResult = JSON.parse(JSON.stringify(filterDatas))
+            }
+            ActionUtils.handleListData(this, this.bianlistData)
+        }
+    }
+}
+</script>
+

+ 47 - 38
src/views/component/trainingManage/trainingStatic.vue

@@ -7,28 +7,16 @@
             width="70%"
             append-to-body
             top
-            style="margin-top:100px"
+            style="margin-top:5vh"
             :close-on-click-modal="false"
             :show-close="false"
             :close-on-press-escape="false"
         >
             <div v-if="refresh" v-loading="loading" class="contain">
                 <div class="selector">
-
-                    <div>
-                        培训状态:
-                        <el-select v-model="selectItem1" placeholder="请选择" @change="onSelectorChange">
-                            <el-option
-                                v-for="item in ['全部','进行中','已结束','未发布','未开始','已删除']"
-                                :key="item"
-                                :label="item"
-                                :value="item"
-                            />
-                        </el-select>
-                    </div>
                     <div>
                         签到状态:
-                        <el-select v-model="selectItem2" placeholder="请选择" @change="onSelectorChange">
+                        <el-select v-model="selectItem2" placeholder="请选择" size="mini" style="width:100px" @change="onSelectorChange">
                             <el-option
                                 v-for="item in ['全部','已签到','未签到','已补签']"
                                 :key="item"
@@ -41,18 +29,24 @@
                         培训时间:
                         <el-date-picker
                             v-model="selectItem3"
-                            type="datetimerange"
+                            size="mini"
+                            type="daterange"
                             :picker-options="pickerOptions"
                             range-separator="至"
                             start-placeholder="开始日期"
                             end-placeholder="结束日期"
                             align="right"
-                            value-format="timestamp"
+                            value-format="yyyy-MM-dd"
+                            style="width:240px"
                         />
                     </div>
+                    <div>
+                        <span style="width:110px">培训主题:</span>
+                        <el-input v-model="selectItem1" placeholder="请输入培训主题" size="mini" />
+                    </div>
                 </div>
                 <div class="table">
-                    <el-table :data="showPaperList" row-key="id_">
+                    <el-table :data="showPaperList" row-key="id_" border>
                         <el-table-column
                             prop=""
                             label="序号"
@@ -60,6 +54,11 @@
                             width="100"
                             :index="showIndex"
                         />
+                        <el-table-column
+                            prop="pei_xun_nei_rong_"
+                            label="培训主题"
+                            show-overflow-tooltip
+                        />
                         <el-table-column
                             prop="bian_zhi_ren_"
                             label="培训负责人"
@@ -75,11 +74,7 @@
                                 />
                             </template>
                         </el-table-column>
-                        <el-table-column
-                            prop="bian_zhi_shi_jian"
-                            label="创建时间"
-                            width="150"
-                        />
+
                         <el-table-column
                             prop="pei_xun_shi_jian_"
                             label="培训时间"
@@ -110,7 +105,7 @@
                             width="100"
                         >
                             <template slot-scope="{row}">
-                                <el-button type="primary" size="mini" :disabled="row.shi_fou_guo_shen_!=='已结束' || row.status!=='未签到'" :title="showTitle(row)" icon="el-icon-finished" @click="onRegister(row)">补签</el-button>
+                                <el-button type="primary" size="mini" :disabled="row.status!=='未签到'" :title="showTitle(row)" icon="el-icon-finished" @click="onRegister(row)">补签</el-button>
                             </template>
                         </el-table-column>
 
@@ -166,7 +161,7 @@ export default {
 
             dialogVisible: true,
             tableList: [],
-            selectItem1: '全部',
+            selectItem1: '',
             selectItem2: '全部',
             selectItem3: '',
             pickerOptions: {
@@ -203,8 +198,8 @@ export default {
             const list = { '已签到': 1, '已补签': 2, '未签到': 3 }
             let tempList = this.tableList
             // 第一次过滤
-            if (this.selectItem1 !== '全部') {
-                tempList = tempList.filter(item => item.shi_fou_guo_shen_ === this.selectItem1)
+            if (this.selectItem1) {
+                tempList = tempList.filter(item => item.pei_xun_nei_rong_.indexOf(this.selectItem1) >= 0)
             }
             // 第二次过滤
             if (this.selectItem2 !== '全部') {
@@ -213,9 +208,11 @@ export default {
             // 第三次过滤
             if (this.selectItem3 && this.selectItem3.length > 0) {
                 tempList = tempList.filter(item => {
-                    const start = this.selectItem3[0]
-                    const end = this.selectItem3[1]
-                    return start <= new Date(item.pei_xun_shi_jian_).getTime() && new Date(item.pei_xun_shi_jian_).getTime() <= end
+                    let [start, end] = this.selectItem3
+                    const now = new Date(item.pei_xun_shi_jian_).getTime()
+                    start = new Date(start)
+                    end = new Date(end)
+                    return start <= now && now <= end
                 })
             }
 
@@ -234,10 +231,12 @@ export default {
     },
     async mounted () {
         this.loading = true
+        if (this.params.time && this.params.time.length) {
+            this.selectItem3 = this.params.time
+        }
         this.getTitle()
         await this.fetchPaperList()
         await this.fetchRegisterList()
-        console.log(this.tableList)
         this.loading = false
     },
     methods: {
@@ -258,7 +257,13 @@ export default {
             }
         },
 
-        onRegister (row) {
+        async onRegister (row) {
+            const sql = `select * from t_qdxxb where ren_yuan_id_='${this.params.peixunrenyuan}' and guan_lian_id_='${row.id_}'`
+            const { variables: { data }} = await this.$common.request('sql', sql)
+            if (data.length > 0) {
+                return this.$message.warning('已签到,请不要重复签到!')
+            }
+
             const peiXunRen = row.pei_xun_ren_yuan_
             const buQianRen = row.bu_qian_ren_yuan_
             // 1.签到表补签操作
@@ -378,17 +383,19 @@ export default {
         },
         // 查询指定人员的培训记录
         async fetchPaperList () {
-            const sql = `select * from t_rypxcjb where FIND_IN_SET('${this.params.peixunrenyuan}', pei_xun_ren_yuan_) > 0`
+            const sql = `select * from t_rypxcjb where FIND_IN_SET('${this.params.peixunrenyuan}', pei_xun_ren_yuan_) > 0 and shi_fou_guo_shen_='已结束'`
             const { variables: { data }} = await this.$common.request('sql', sql)
             this.tableList = data
         },
         // 获取签到状态
         async fetchRegisterList () {
-            this.tableList.forEach(async item => {
-                const sql = `select * from t_qdxxb where guan_lian_id_='${item.id_}' and ren_yuan_id_='${this.params.peixunrenyuan}'`
-                const { variables: { data }} = await this.$common.request('sql', sql)
-                this.$set(item, 'status', data.length > 0 ? '已签到' : '未签到')
-                if (item.shi_fou_guo_shen_ === '已结束' && item.bu_qian_ren_yuan_) {
+            const sql = `select guan_lian_id_,ren_yuan_id_ from t_qdxxb where ren_yuan_id_='${this.params.peixunrenyuan}'`
+            const { variables: { data }} = await this.$common.request('sql', sql)
+            this.tableList.forEach(item => {
+                const id_ = item.id_
+                const index = data.findIndex(i => i.guan_lian_id_ === id_)
+                this.$set(item, 'status', index >= 0 ? '已签到' : '未签到')
+                if (item.bu_qian_ren_yuan_) {
                     const person = item.bu_qian_ren_yuan_.split(',').find(i => i === this.params.peixunrenyuan)
                     if (person) {
                         item.status = '已补签'
@@ -430,7 +437,7 @@ export default {
 .contain{
     padding: 20px;
     .table{
-        height:440px;
+        height:436px;
         overflow: auto;
         margin-top: 20px;
     }
@@ -438,6 +445,8 @@ export default {
         display: flex;
         align-items: center;
         div{
+            display: flex;
+            align-items: center;
             margin: 0 10px;
         }
     }