|
@@ -0,0 +1,812 @@
|
|
|
+<template>
|
|
|
+ <div class="all padding-20">
|
|
|
+ <el-card style="margin-bottom: 20px;">
|
|
|
+ <el-form inline>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select class="date-picker-width" size="medium" v-model="formData.dc_status" placeholder="复核状态" :disabled="loading">
|
|
|
+ <el-option v-for="item in dc_status_options" :key="item.id" :label="item.name" :value="item.id"/>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select size="medium" v-model="formData.source_type" placeholder="全部来源" :disabled="loading">
|
|
|
+ <el-option v-for="item in source_types" :key="item.id" :label="item.name" :value="item.id"/>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select size="medium" v-model="formData.is_enable" style="margin-right: 5px" :disabled="loading">
|
|
|
+ <el-option label="已启用用户" :value="1"></el-option>
|
|
|
+ <el-option label="未授权&未启用用户" :value="0"></el-option>
|
|
|
+ </el-select>
|
|
|
+ <el-tooltip effect="dark" placement="top">
|
|
|
+ <template slot="content">
|
|
|
+ 人员状态过滤。默认仅显示组织架构中“已启用”人员的积分事件,未启用、已离职等人员的积分事件可以通过“未启用&未授权”筛选查看
|
|
|
+ </template>
|
|
|
+ <span><i class="el-icon-warning"></i></span>
|
|
|
+ </el-tooltip>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select size="medium" v-model="formData.employee_ids" filterable clearable placeholder="请输入或选择人员" :disabled="loading">
|
|
|
+ <el-option v-for="item in employee_list" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-select size="medium" v-model="formData.pt_id" clearable placeholder="A/B分" :disabled="loading">
|
|
|
+ <el-option v-for="item in pts" :key="item.name" :label="item.name" :value="item.id"/>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <el-cascader
|
|
|
+ v-model="formData.rules"
|
|
|
+ :options="rule_trees"
|
|
|
+ :props="{ checkStrictly: true, value: 'id', label: 'name', children: 'child' }"
|
|
|
+ @change="onRuleChange"
|
|
|
+ size="medium"
|
|
|
+ ref="rule"
|
|
|
+ clearable
|
|
|
+ placeholder="规则分类"
|
|
|
+ :disabled="loading"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-date-picker
|
|
|
+ v-model="formData.time_scope"
|
|
|
+ type="daterange"
|
|
|
+ size="medium"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ :disabled="loading"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <el-input
|
|
|
+ size="medium"
|
|
|
+ clearable
|
|
|
+ max="20"
|
|
|
+ v-model="formData.keyword"
|
|
|
+ placeholder="搜索内容"
|
|
|
+ :disabled="loading"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+<!-- <el-form-item>-->
|
|
|
+<!-- <el-input-->
|
|
|
+<!-- size="medium"-->
|
|
|
+<!-- clearable-->
|
|
|
+<!-- v-model="formData.point"-->
|
|
|
+<!-- placeholder="分值"-->
|
|
|
+<!-- @input="onPointInput"-->
|
|
|
+<!-- :disabled="loading"-->
|
|
|
+<!-- />-->
|
|
|
+<!-- </el-form-item>-->
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <el-cascader
|
|
|
+ size="medium"
|
|
|
+ v-model="dept_names"
|
|
|
+ :options="dept_tree"
|
|
|
+ :props="{ checkStrictly: true, multiple: true, value: 'id', label: 'name', children: '_child' }"
|
|
|
+ ref="dept"
|
|
|
+ filterable
|
|
|
+ collapse-tags
|
|
|
+ clearable
|
|
|
+ placeholder="全公司"
|
|
|
+ style="min-width: 300px"
|
|
|
+ :disabled="loading"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <NumberRangeSelector
|
|
|
+ :min.sync="formData.minPoint"
|
|
|
+ :max.sync="formData.maxPoint"
|
|
|
+ :disabled="loading"
|
|
|
+ title="分值区间"
|
|
|
+ @scopeSubmit="handlePointScopeSubmit"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <el-row :gutter="5" justify="center" align="center">
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button-group>
|
|
|
+ <el-button type="primary" size="medium" :disabled="!canSubmitBatch" @click="openBatch">批处理</el-button>
|
|
|
+ </el-button-group>
|
|
|
+ <span style="padding-left: 20px;" :class="websocketAuth ? 'green' : 'orange'">
|
|
|
+ <i :class="websocketAuth ? 'el-icon-connection' : 'el-icon-warning-outline'">
|
|
|
+ {{websocketAuth ? '服务已启动' : '服务启动中.....'}}
|
|
|
+ </i>
|
|
|
+ </span>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-card>
|
|
|
+ <div>
|
|
|
+ <el-table
|
|
|
+ :data="integralList"
|
|
|
+ style="width: 100%;"
|
|
|
+ v-loading="loading"
|
|
|
+ @row-click="openDetail"
|
|
|
+ @selection-change="onSelectionChange"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ v-if="formData.dc_status === 0"
|
|
|
+ type="selection"
|
|
|
+ width="55"
|
|
|
+ :key="1"
|
|
|
+ />
|
|
|
+ <el-table-column prop="employee_name" label="姓名" align="center" width="200px" :key="2" >
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <div class="flex-box">
|
|
|
+ <userImage :user_name="scope.row.employee_name" :img_url="scope.row.employee_img_url" width="50px" height="50px"></userImage>
|
|
|
+ <span style="line-height: 50px; padding-left: 10px;">{{ scope.row.employee_name }}</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="dept"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="部门"
|
|
|
+ align="center"
|
|
|
+ :key="3"
|
|
|
+ />
|
|
|
+ <el-table-column prop="point" label="积分" align="center" :key="4">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span :class="scope.row.point < 0 ? 'green' : 'red'">{{ scope.row.point }} {{ $getTypsName(scope.row.pt_id) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="remark" label="事件内容" align="center" show-overflow-tooltip :key="5" />
|
|
|
+ <el-table-column prop="event_time" label="时间" align="center" :key="6"/>
|
|
|
+ <el-table-column prop="source_type" label="事件来源" align="center" :key="7">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span v-show="scope.row.source_type == 1">
|
|
|
+ 积分奖扣
|
|
|
+ <span v-if="scope.row.recorder_name">({{ scope.row.recorder_name }})</span>
|
|
|
+ </span>
|
|
|
+ <span v-show="scope.row.source_type == 2">任务</span>
|
|
|
+ <span v-show="scope.row.source_type == 3">积分系统分配</span>
|
|
|
+ <span v-show="scope.row.source_type == 4">考勤系统分配</span>
|
|
|
+ <span v-show="scope.row.source_type == 5">
|
|
|
+ 积分申请
|
|
|
+ <span v-if="scope.row.applyor_name">({{ scope.row.applyor_name }})</span>
|
|
|
+ </span>
|
|
|
+ <span v-show="scope.row.source_type == 6">绩效任务包</span>
|
|
|
+ <span v-show="scope.row.source_type == 8">积分导入</span>
|
|
|
+ <span v-show="scope.row.source_type == 9">A分转B分</span>
|
|
|
+ <span v-show="scope.row.source_type == 10">钉钉汇报(日志)奖扣分</span>
|
|
|
+ <span v-show="scope.row.source_type > 10">其他</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+<!-- <el-table-column prop="create_time" label="操作" v-if="formData.dc_status === 0" :key="8">-->
|
|
|
+<!-- <template slot-scope="scope">-->
|
|
|
+<!-- <el-link :underline="false" type="primary" :disabled="loading" @click.stop="openPass(scope.row)">通过</el-link>-->
|
|
|
+<!-- <el-link :underline="false" type="primary" :disabled="loading" style="padding: 0 10px;" @click.stop="setGrade(scope.row)">调整分数</el-link>-->
|
|
|
+<!-- <el-link :underline="false" type="danger" :disabled="loading" style="padding: 0 10px;" @click.stop="reject(scope.row)">驳回</el-link>-->
|
|
|
+<!-- </template>-->
|
|
|
+<!-- </el-table-column>-->
|
|
|
+ <template slot="empty">
|
|
|
+ <noData></noData>
|
|
|
+ </template>
|
|
|
+ </el-table>
|
|
|
+ <center class="pagination">
|
|
|
+ <el-pagination
|
|
|
+ background
|
|
|
+ @size-change="v => formData.page_size = v"
|
|
|
+ @current-change="v => formData.page = v"
|
|
|
+ :current-page="formData.page"
|
|
|
+ :page-sizes="[10, 20, 50,100]"
|
|
|
+ layout="total, sizes, prev, pager, next"
|
|
|
+ :page-size="formData.page_size"
|
|
|
+ :total="formData.total"
|
|
|
+ />
|
|
|
+ </center>
|
|
|
+ </div>
|
|
|
+ <el-dialog
|
|
|
+ :visible.sync="showDetail"
|
|
|
+ custom-class="text-center"
|
|
|
+ title="积分信息"
|
|
|
+ :close-on-click-modal="!loading || !currentItem"
|
|
|
+ :close-on-press-escape="!loading || !currentItem"
|
|
|
+ :show-close="false"
|
|
|
+ :before-close="closeDetail"
|
|
|
+ >
|
|
|
+ <div v-if="currentItem">
|
|
|
+ <el-row :gutter="5" v-if="this.currentItem.dc_status === 0" style="margin-bottom: 10px;">
|
|
|
+ <el-col :span="6" v-if="event_review_point">
|
|
|
+ <el-input size="small" v-model="currentItem.point" type="number">
|
|
|
+ <template #prepend>积分</template>
|
|
|
+ </el-input>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="event_review_point > 0 ? 14 : 19" >
|
|
|
+ <el-input :size=" event_review_point > 0 ? 'small' : 'medium'" v-model="currentItem.comment" maxlength="50" show-word-limit clearable >
|
|
|
+ <template #prepend>备注</template>
|
|
|
+ </el-input>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="event_review_point > 0 ? 4 : 5">
|
|
|
+ <el-button-group>
|
|
|
+ <el-button :size=" event_review_point > 0 ? 'small' : 'medium'" type="warning" @click="disagree" :disabled="loading">驳回</el-button>
|
|
|
+ <el-button :size=" event_review_point > 0 ? 'small' : 'medium'" type="primary" :disabled="!websocketAuth" :loading="loading" @click="agree">通过</el-button>
|
|
|
+ </el-button-group>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-descriptions
|
|
|
+ :column="1"
|
|
|
+ border
|
|
|
+ :label-style="{textAlign:'center'}"
|
|
|
+ :content-style="{textAlign: 'center'}"
|
|
|
+ >
|
|
|
+ <el-descriptions-item label="姓名">{{currentItem.employee_name}} {{currentItem.dept}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="积分">{{currentItem.point_mark}} {{$getTypsName(currentItem.pt_id)}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="内容">{{currentItem.remark}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="事件时间">{{currentItem.event_time}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="创建时间">{{currentItem.create_time}}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+<!-- <template v-if="currentItem?.dc_remark?.flow?.length > 0">-->
|
|
|
+ <template v-if="currentItem.dc_remark && currentItem.dc_remark.flow">
|
|
|
+ <h3 style="margin: 10px 0;">复核流程</h3>
|
|
|
+ <el-steps
|
|
|
+ :active="currentItem.dc_remark.flow.length"
|
|
|
+ align-center
|
|
|
+ >
|
|
|
+ <el-step
|
|
|
+ v-for="(item,index) in currentItem.dc_remark.flow"
|
|
|
+ :key="index"
|
|
|
+ :title="`${item.employee_name} ${item.action === 'agree' ? '复核通过' : (item.action === 'disagree' ? '复核驳回' : '')}`"
|
|
|
+ >
|
|
|
+ <template #description>
|
|
|
+ {{$moment(item.time * 1000).format('YYYY-MM-DD')}} {{item.comment || ''}}
|
|
|
+ </template>
|
|
|
+ </el-step>
|
|
|
+ </el-steps>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <el-empty v-else/>
|
|
|
+ </el-dialog>
|
|
|
+ <el-dialog
|
|
|
+ :visible.sync="showBatch"
|
|
|
+ custom-class="text-center"
|
|
|
+ title="批处理"
|
|
|
+ :close-on-click-modal="!loading || !selectedItems || selectedItems.length === 0"
|
|
|
+ :close-on-press-escape="!loading || !selectedItems || selectedItems.length === 0"
|
|
|
+ :show-close="false"
|
|
|
+ :before-close="closeBatch"
|
|
|
+ >
|
|
|
+ <el-row :gutter="5">
|
|
|
+ <el-col :span="18">
|
|
|
+ <el-input
|
|
|
+ v-model="batchComment"
|
|
|
+ maxlength="50"
|
|
|
+ show-word-limit
|
|
|
+ :disabled="loading"
|
|
|
+ >
|
|
|
+ <template #prepend>备注</template>
|
|
|
+ </el-input>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="6">
|
|
|
+ <el-button-group>
|
|
|
+ <el-button type="warning" @click="disagreeBatch" :disabled="loading">驳回</el-button>
|
|
|
+ <el-button type="primary" :disabled="!websocketAuth" :loading="loading" @click="agreeBatch">通过</el-button>
|
|
|
+ </el-button-group>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-progress text-inside :stroke-width="20" :percentage="batchProgress" style="margin: 10px 0;" v-show="loading" />
|
|
|
+ <el-table :data="selectedItems">
|
|
|
+ <el-table-column
|
|
|
+ prop="employee_name"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="姓名"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="point_mark"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="积分"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="remark"
|
|
|
+ show-overflow-tooltip
|
|
|
+ label="内容"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column align="center">
|
|
|
+ <template #header>
|
|
|
+ 结果
|
|
|
+ <el-dropdown trigger="click" @command="copyResult" v-if="canClipboard">
|
|
|
+ <span><i class="el-icon-more"/></span>
|
|
|
+ <el-dropdown-menu slot="dropdown">
|
|
|
+ <el-dropdown-item command="normal">复制结果</el-dropdown-item>
|
|
|
+ <el-dropdown-item command="origin">复制结果源</el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </el-dropdown>
|
|
|
+ </template>
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-link :type="scope.row.code === 1 ? 'primary' : (scope.row.code === 1 ? 'primary' : 'warning')">
|
|
|
+ <template v-if="loading && scope.row.code === -1">
|
|
|
+ <i class="el-icon-loading"></i>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ {{ batchResultMark(scope.row) }}
|
|
|
+ </template>
|
|
|
+ </el-link>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+
|
|
|
+<script>
|
|
|
+import {onlyNumberFilter} from "@/utils";
|
|
|
+import {isNumeric} from "echarts/lib/util/number";
|
|
|
+import {_debounce, getTypsName} from "@/api/auth";
|
|
|
+import {wsClient} from "@/api/wsService";
|
|
|
+import NumberRangeSelector from '@/components/numberRangeSelector'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "integral_review",
|
|
|
+ components:{NumberRangeSelector},
|
|
|
+ data(){
|
|
|
+ let pts = this.$getTyps().filter(item => item.code !== 'JX');
|
|
|
+ return {
|
|
|
+ pts,
|
|
|
+ rule_trees:[],
|
|
|
+ employee_list:[],
|
|
|
+ event_review_point:0,
|
|
|
+ source_types:[
|
|
|
+ { id: 0, name: '全部来源' },
|
|
|
+ { id: 1, name: '积分奖扣' },
|
|
|
+ { id: 2, name: '任务' },
|
|
|
+ { id: 3, name: '积分系统分配' },
|
|
|
+ { id: 4, name: '考勤系统分配' },
|
|
|
+ { id: 5, name: '积分申请' },
|
|
|
+ // {id: 6,name: '绩效任务包'},
|
|
|
+ { id: 8, name: '积分导入' },
|
|
|
+ { id: 9, name: 'A分转B分' },
|
|
|
+ { id: 10, name: '钉钉汇报(日志)分' }
|
|
|
+ ],
|
|
|
+ dc_status_options:[
|
|
|
+ { id: 0, name: '待复核' },
|
|
|
+ { id: 1, name: '通过' },
|
|
|
+ { id: 2, name: '驳回' },
|
|
|
+ ],
|
|
|
+ loading: false,
|
|
|
+ dept_names:[],
|
|
|
+ dept_tree: [],
|
|
|
+ formData: {
|
|
|
+ page: 1,
|
|
|
+ page_size: 10,
|
|
|
+ employee_ids:'',
|
|
|
+ pt_id:'',
|
|
|
+ source_type:0,
|
|
|
+ rules:[],
|
|
|
+ rule_id:0,
|
|
|
+ time_scope:[],
|
|
|
+ start_day:'',
|
|
|
+ end_day:'',
|
|
|
+ dc_status:0,
|
|
|
+ keyword:'',
|
|
|
+ point:'',
|
|
|
+ is_enable:1,
|
|
|
+ dept_ids:'',
|
|
|
+ minPoint:null,
|
|
|
+ maxPoint:null,
|
|
|
+ },
|
|
|
+ integralList:[],
|
|
|
+ selectedItems:[],
|
|
|
+ wsClient:wsClient,
|
|
|
+ showDetail:false,
|
|
|
+ showBatch:false,
|
|
|
+ currentItem:null,
|
|
|
+ batchComment:'',
|
|
|
+ batchPoint:0,
|
|
|
+ batchResult:[]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods:{
|
|
|
+ getTypsName,
|
|
|
+ getRuleTrees(){
|
|
|
+ this.$axios('get', '/api/integral/rule/trees').then(res => {
|
|
|
+ this.rule_trees = this.getRuleTreeData(res.data.data.rule_tree);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 规则递归 children
|
|
|
+ getRuleTreeData(data) {
|
|
|
+ for (var i = 0; i < data.length; i++) {
|
|
|
+ if (data[i].child.length < 1) {
|
|
|
+ // children若为空数组,则将children设为undefined
|
|
|
+ data[i].child = undefined;
|
|
|
+ } else {
|
|
|
+ // children若不为空数组,则继续 递归调用 本方法
|
|
|
+ this.getRuleTreeData(data[i].child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+ getEmployee(){
|
|
|
+ this.$axios('get', '/api/employee/index', { page: 0, page_size: 3000, is_official: 1 }).then(res => {
|
|
|
+ this.employee_list = res.data.data.list;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onRuleChange(val){
|
|
|
+ this.formData.rule_id = val.length === 0 ? 0 : this.formData.rules[this.formData.rules.length - 1]
|
|
|
+ },
|
|
|
+ onPointInput(v){
|
|
|
+ this.formData.point = onlyNumberFilter(v)
|
|
|
+ },
|
|
|
+ getDepartment(){
|
|
|
+ this.$axios('get', '/api/department/tree').then(res => {
|
|
|
+ this.dept_tree = this.getTreeData(res.data.data.list);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 递归判断列表,把最后的children设为undefined
|
|
|
+ getTreeData(data) {
|
|
|
+ for (var i = 0; i < data.length; i++) {
|
|
|
+ if (data[i]._child.length < 1) {
|
|
|
+ // children若为空数组,则将children设为undefined
|
|
|
+ data[i]._child = undefined;
|
|
|
+ } else {
|
|
|
+ // children若不为空数组,则继续 递归调用 本方法
|
|
|
+ this.getTreeData(data[i]._child);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ },
|
|
|
+ handlePointScopeSubmit(){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ getIntegralList(){
|
|
|
+ let self = this
|
|
|
+ if (self.loading) return;
|
|
|
+ self.loading = true;
|
|
|
+ let data = {
|
|
|
+ page:self.formData.page,
|
|
|
+ page_size:self.formData.page_size,
|
|
|
+ is_enable:self.formData.is_enable,
|
|
|
+ dc_status:[self.formData.dc_status],
|
|
|
+ }
|
|
|
+ if ([1,2].includes(self.formData.dc_status)) data.order_key = 'dc_time'
|
|
|
+
|
|
|
+ if (self.formData.source_type) data.source_type = self.formData.source_type;
|
|
|
+ if (self.formData.employee_ids) data.employee_ids = self.formData.employee_ids;
|
|
|
+ if (self.formData.pt_id) data.pt_id = self.formData.pt_id;
|
|
|
+ if (self.formData.rule_id) data.rule_id = self.formData.rule_id;
|
|
|
+ if (self.formData.start_day && self.formData.end_day) {
|
|
|
+ data.start_day = self.formData.start_day
|
|
|
+ data.end_day = self.formData.end_day
|
|
|
+ }
|
|
|
+ if (self.formData.keyword) data.keyword = self.formData.keyword
|
|
|
+ if (isNumeric(self.formData.point)) data.point = self.formData.point;
|
|
|
+ if (self.formData.dept_ids) data.dept_ids = self.formData.dept_ids;
|
|
|
+ if (self.formData.minPoint !== null && self.formData.maxPoint !== null) {
|
|
|
+ data.min_point = self.formData.minPoint
|
|
|
+ data.max_point = self.formData.maxPoint
|
|
|
+ }
|
|
|
+
|
|
|
+ self.$axios('get', '/api/integral/statistics/integral', data).then(res => {
|
|
|
+ self.integralList = res.data.data.list;
|
|
|
+ if(data.page === 1){
|
|
|
+ self.formData.total = res.data.data.total;
|
|
|
+ }
|
|
|
+ }).finally(() => {
|
|
|
+ self.loading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ onSelectionChange(selection){
|
|
|
+ this.selectedItems = selection.map(item => {
|
|
|
+ return {
|
|
|
+ event_id:item.id,
|
|
|
+ employee_name:item.employee_name,
|
|
|
+ point:item.point,
|
|
|
+ point_mark:item.point_mark + " " + this.$getTypsName(item.pt_id),
|
|
|
+ remark:item.remark,
|
|
|
+ hasFinish:false,
|
|
|
+ code:-1,
|
|
|
+ msg:'',
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ openDetail(item){
|
|
|
+ this.currentItem = item
|
|
|
+
|
|
|
+ let data = {
|
|
|
+ event_id: item.id
|
|
|
+ }
|
|
|
+ this.loading = true
|
|
|
+ this.$axios('get', '/api/integral/statistics/integral/info', data)
|
|
|
+ .then(res => {
|
|
|
+ if (res.data.code !== 1) return
|
|
|
+ this.currentItem.dc_remark = res.data.data.dc_remark
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ this.loading = false
|
|
|
+ this.showDetail = true
|
|
|
+ })
|
|
|
+ },
|
|
|
+ closeDetail(){
|
|
|
+ this.showDetail = false
|
|
|
+ this.currentItem = null
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ agree(){
|
|
|
+ if (!this.currentItem || this.loading) return
|
|
|
+ let data = {
|
|
|
+ type:'event_check',
|
|
|
+ action:'agree',
|
|
|
+ event_id:this.currentItem.id,
|
|
|
+ point:this.currentItem.point,
|
|
|
+ comment:this.currentItem?.comment || ''
|
|
|
+ }
|
|
|
+ this.showDetail = false
|
|
|
+ this.currentItem = null
|
|
|
+ this.loading = true
|
|
|
+ if (!this.wsClient.getAuthStatus()){
|
|
|
+ this.wsClient.initWebSocket(() => {
|
|
|
+ this.wsClient.send(data)
|
|
|
+ },(msg) => {
|
|
|
+ if (msg.type !== 'event_check') return
|
|
|
+ this.loading = false
|
|
|
+ this.getIntegralList()
|
|
|
+ })
|
|
|
+ }else {
|
|
|
+ this.wsClient.send(data,(msg) => {
|
|
|
+ if (msg.type !== 'event_check') return
|
|
|
+ this.loading = false
|
|
|
+ this.getIntegralList()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ disagree(){
|
|
|
+ if (!this.currentItem || this.loading) return
|
|
|
+ let data = {
|
|
|
+ type:'event_check',
|
|
|
+ action:'disagree',
|
|
|
+ event_id:this.currentItem.id,
|
|
|
+ comment:this.currentItem?.comment || ''
|
|
|
+ }
|
|
|
+ this.showDetail = false
|
|
|
+ this.currentItem = null
|
|
|
+ this.loading = true
|
|
|
+ if (!this.wsClient.getAuthStatus()){
|
|
|
+ this.wsClient.initWebSocket(() => {
|
|
|
+ this.wsClient.send(data)
|
|
|
+ },(msg) => {
|
|
|
+ if (msg.type !== 'event_check') return
|
|
|
+ this.loading = false
|
|
|
+ this.getIntegralList()
|
|
|
+ })
|
|
|
+ }else {
|
|
|
+ this.wsClient.send(data,(msg) => {
|
|
|
+ if (msg.type !== 'event_check') return
|
|
|
+ this.loading = false
|
|
|
+ this.getIntegralList()
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ openBatch(){
|
|
|
+ console.log(this.selectedItems.map(item => item.event_id).toString())
|
|
|
+ this.showBatch = true
|
|
|
+ this.batchComment = ''
|
|
|
+ },
|
|
|
+ closeBatch(){
|
|
|
+ this.showBatch = false
|
|
|
+ this.batchComment = ''
|
|
|
+ this.batchResult = []
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ agreeBatch(){
|
|
|
+ this.loading = true
|
|
|
+ this.batchResult = []
|
|
|
+ this.wsClient.setBusinessFun((res) => {
|
|
|
+ if (res.type !== 'ping') this.batchResult.push(res)
|
|
|
+ if (res.type !== 'event_check') return
|
|
|
+ this.selectedItems.filter(item => item.event_id === res?.result?.source_msg?.event_id).forEach(item => {
|
|
|
+ item.hasFinish = true
|
|
|
+ item.code = res.code
|
|
|
+ item.msg = res.code === 1 ? '已处理' : (res?.msg ? res.msg : '处理失败')
|
|
|
+ })
|
|
|
+ if (this.selectedItems.filter(item => item.hasFinish).length >= this.selectedItems.length) this.loading = false
|
|
|
+ })
|
|
|
+ this.selectedItems.map(item => {
|
|
|
+ return {
|
|
|
+ type:'event_check',
|
|
|
+ action:'agree',
|
|
|
+ event_id:item.event_id,
|
|
|
+ point:item.point,
|
|
|
+ comment:this.batchComment || ''
|
|
|
+ }
|
|
|
+ }).forEach(data => {
|
|
|
+ this.wsClient.send(data)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ disagreeBatch(){
|
|
|
+ this.loading = true
|
|
|
+ this.batchResult = []
|
|
|
+ this.wsClient.setBusinessFun(res => {
|
|
|
+ if (res.type !== 'ping') this.batchResult.push(res)
|
|
|
+ if (res.type !== 'event_check') return
|
|
|
+ this.selectedItems.filter(item => item.event_id === res?.result?.source_msg?.event_id).forEach(item => {
|
|
|
+ item.hasFinish = true
|
|
|
+ item.code = res.code
|
|
|
+ item.msg = res.code === 1 ? '已处理' : (res?.msg ? res.msg : '处理失败')
|
|
|
+ })
|
|
|
+ if (this.selectedItems.filter(item => item.hasFinish).length >= this.selectedItems.length) this.loading = false
|
|
|
+ })
|
|
|
+ this.selectedItems.map(item => {
|
|
|
+ return {
|
|
|
+ type:'event_check',
|
|
|
+ action:'disagree',
|
|
|
+ event_id:item.event_id,
|
|
|
+ comment:this.batchComment || ''
|
|
|
+ }
|
|
|
+ }).forEach(data => {
|
|
|
+ this.wsClient.send(data)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ copyResult(origin){
|
|
|
+ switch (origin){
|
|
|
+ case 'normal':
|
|
|
+ let result = this.batchResult.filter(res => res.type === 'event_check').map(res => {
|
|
|
+ return {
|
|
|
+ type:res?.result?.source_msg?.type === 'event_check' ? '复核' : res.type,
|
|
|
+ action: res?.result?.source_msg?.action === 'agree' ? '同意' : (res?.result?.source_msg?.action === 'disagree' ? '驳回' : '未知'),
|
|
|
+ msg: res?.msg,
|
|
|
+ code: res?.code,
|
|
|
+ origin: {
|
|
|
+ action:res?.result?.source_msg?.action,
|
|
|
+ comment:res?.result?.source_msg?.comment,
|
|
|
+ no:res?.result?.source_msg?.event_id,
|
|
|
+ p:res?.result?.source_msg?.point,
|
|
|
+ t:res?.result?.source_msg?.type,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ navigator.clipboard.writeText(JSON.stringify(result)).then(() => {
|
|
|
+ this.$message.success("已复制")
|
|
|
+ },(reason) => {
|
|
|
+ console.error('integral review clipboard',reason)
|
|
|
+ this.$message.info("没有任何结果")
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ case 'origin':
|
|
|
+ navigator.clipboard.writeText(JSON.stringify(this.batchResult)).then(() => {
|
|
|
+ this.$message.success("已复制")
|
|
|
+ },(reason) => {
|
|
|
+ console.error('integral review clipboard',reason)
|
|
|
+ this.$message.info("没有任何结果")
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ batchResultMark(item){
|
|
|
+ return !!item.msg ? item.msg : '待处理'
|
|
|
+ },
|
|
|
+
|
|
|
+ },
|
|
|
+ watch:{
|
|
|
+ 'formData.time_scope'(v){
|
|
|
+ if (v){
|
|
|
+ this.formData.start_day = v[0]
|
|
|
+ this.formData.end_day = v[1]
|
|
|
+ }else {
|
|
|
+ this.formData.start_day = ''
|
|
|
+ this.formData.end_day = ''
|
|
|
+ }
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.employee_ids'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.pt_id'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.source_type'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.rule_id'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.dc_status'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ if (v !== 0) this.selectedItems = []
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.dept_ids'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.keyword' : {
|
|
|
+ deep: true,
|
|
|
+ handler: _debounce(function (v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ 'formData.point': {
|
|
|
+ deep: true,
|
|
|
+ handler: _debounce(function (v,o){
|
|
|
+ if (v === o) return
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ 'formData.is_enable'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.page'(v){
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ 'formData.page_size'(v){
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ },
|
|
|
+ dept_names(v){
|
|
|
+ if (v.length !== 0){
|
|
|
+ let dept_ids = v.map(item => item[item.length - 1])
|
|
|
+ let set = new Set(dept_ids)
|
|
|
+ this.formData.dept_ids = [...set].toString()
|
|
|
+ } else {
|
|
|
+ this.formData.dept_ids = []
|
|
|
+ }
|
|
|
+ this.formData.page = 1
|
|
|
+ this.getIntegralList()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed:{
|
|
|
+ websocketAuth(){
|
|
|
+ return this.wsClient.getAuthStatus()
|
|
|
+ },
|
|
|
+ canSubmitBatch(){
|
|
|
+ return !this.loading && this.websocketAuth && this.selectedItems && this.selectedItems.length > 0
|
|
|
+ },
|
|
|
+ batchProgress(){
|
|
|
+ return this.selectedItems && this.selectedItems.length > 0 ? (this.selectedItems.filter(item => item.hasFinish).length / this.selectedItems.length) * 100 : 0
|
|
|
+ },
|
|
|
+ canClipboard(){
|
|
|
+ return !!navigator?.clipboard && this.batchResult && this.batchResult.length > 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted(){
|
|
|
+ this.getEmployee();
|
|
|
+ this.getDepartment();
|
|
|
+ this.getRuleTrees();
|
|
|
+ this.getIntegralList();
|
|
|
+ let siteConfig = this.$getCache('siteConfig');
|
|
|
+ this.event_review_point = siteConfig.event_review_point;
|
|
|
+
|
|
|
+ //初始化长连接
|
|
|
+ this.wsClient.initWebSocket()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ if (this.wsClient) this.wsClient.close()
|
|
|
+ },
|
|
|
+ destroyed() {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+
|
|
|
+.el-table tr{
|
|
|
+ cursor: pointer !important;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+</style>
|