123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779 |
- <template>
- <div>
- <div class="diy_tip_bg">
- <el-alert class="diy-tip" type="success" description>
- <p><b>统计每个责任人在定期检查和临时检查的表现情况,可结合分值、不合格项、奖扣分及次数等数据对责任人进行考核评定</b></p>
- </el-alert>
- </div>
- <div class="manager_statistics_box boxMinHeight">
- <div class="flex-box flex-d-center">
- <el-form :inline="true">
- <el-form-item label="时间">
- <el-date-picker v-model="time" :clearable='false' type="daterange" value-format="yyyy-MM-dd"
- range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
- </el-form-item>
- <el-form-item>
- <div class="flex-box-ce">
- <el-select v-model="selectTypeIndex" placeholder="请选择" style="width: 80px;margin-right: 6px;">
- <el-option label="部门" :value="1"></el-option>
- <el-option label="岗位" :value="2"></el-option>
- </el-select>
- <el-cascader v-if="selectTypeIndex==1" style="width: 250px;"v-model="dept_id" :options="dept_tree" :props="{checkStrictly: true}" ref="dept"
- filterable change-on-select clearable placeholder="全公司">
- </el-cascader>
- <div class="border flex-box-ce" v-if="selectTypeIndex==2">
- <div class="flex-1" v-if="selectPost.length == 0">请选择岗位</div>
- <div v-else style="width: 180px;" class="font-flex-word">
- <span v-for="(item, index) in selectPost" :key="index">
- <i v-if="index != 0">,</i>{{ item.name }}
- </span>
- </div>
- <span v-if="selectPost.length >0" class="blue">{{selectPost.length}}个</span>
- <i class="el-icon-arrow-down icon-right"></i>
- <div @click="openPost" class="inputDc"></div>
- </div>
- </div>
- </el-form-item>
- <el-form-item>
- <el-input maxlength="10" placeholder="人员搜索" prefix-icon="el-icon-search" v-model="keyword"
- style="width: 200px;" clearable></el-input>
- </el-form-item>
- </el-form>
- <!-- <el-button style="margin-bottom: 16px;" type="primary" @click="submitForm()">导出报表</el-button> -->
- <!-- 导出报表 -->
- <downloadexcel
- v-if="list.length>0"
- :fetch="returnArr"
- name="责任人分值统计.xls"
- :fields="json_fields"
- >
- <el-button type="primary" plain size="medium" style="margin-right: 10px;">导出报表</el-button>
- </downloadexcel>
- </div>
- <el-table :data="list" style="width: 100%;cursor: pointer;" v-loading="loading" @sort-change="sortChange">
- <el-table-column label="责任人" prop="name" width="120" fixed></el-table-column>
- <el-table-column label="所属部门" prop="dept" width="120" fixed>
- <template slot-scope="scope">
- <Tooltip :preHtml="scope.row.dept">
- <div class="font-flex-word" style="width: 100px;">{{scope.row.dept}}</div>
- </Tooltip>
- </template>
- </el-table-column>
- <el-table-column label="时间" width="120" fixed>
- <template slot-scope="scope">
- <div class="font-flex-word" style="width: 100px;">{{scope.row.time}}</div>
- </template>
- </el-table-column>
- <el-table-column label="定期检查" align="center" >
- <el-table-column prop="c_item" label="负责次数" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="total_base_point" label="应得总分" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="total_point" label="实际得分" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="total_reduce_point" label="被扣分" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="c_bug_item" label="不合格(次)" width="140" sortable="custom"></el-table-column>
- <el-table-column prop="c_bug_focus_item" label="重点不合格(次)" width="160" sortable="custom"></el-table-column>
- </el-table-column>
- <el-table-column label="临时检查" align="center">
- <el-table-column prop="sm_point" label="得分(分)" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="sm_reward_point" label="奖分(分)" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="sm_reward_count" label="奖分次数" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="sm_deduce_point" label="扣分(分)" width="120" sortable="custom"></el-table-column>
- <el-table-column prop="sm_deduce_count" label="扣分次数" width="120" sortable="custom"></el-table-column>
- </el-table-column>
- <template slot="empty">
- <NoData></NoData>
- </template>
- </el-table>
- <!-- <center style="padding: 20px 0;">
- <el-pagination background @size-change="handleSizeChange" @current-change="handleCurrentChange"
- :current-page="page" :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next"
- :page-size="page_size" :total="total"></el-pagination>
- </center> -->
- </div>
- <!-- 选择岗位 -->
- <el-dialog title="选择岗位" :visible.sync="isShowRule" class="fromNormGain_sty" top="12vh" width="1000px" append-to-body>
- <div class="flex-box">
- <div class="flex-2 kh-left">
- <ul class="scroll-bar ul" v-if="tabs.length > 0" style="height: 440px;overflow: auto;">
- <li class="flex-box-ce li" v-for="(item, index) in tabs" :key="index" :class="[tabItem.id == item.id ? 'isActiveLi' : '']" @click="activeLi(item, index)">
- <div class="index-name font-flex-word"><i class="el-icon-s-help" v-if="item.id==-1"></i> {{ item.name }}</div>
- </li>
- </ul>
- </div>
- <div class="flex-4">
- <el-input style="width: 200px;" size="small" maxlength="100" show-word-limit v-model="postName" clearable placeholder="搜索"/>
- <div class="table-box">
- <el-table :data="postList" stripe fit v-loading="table_loading" style="cursor: pointer;" @row-click="clickdatail">
- <el-table-column width="40" fixed>
- <template slot-scope="scope">
- <div style="width: 40px;text-align: center;position: relative;">
- <el-checkbox v-model="scope.row.checked"></el-checkbox>
- <div style="width: 40px;height: 40px;position: absolute;top: -10px;z-index: 999;"></div>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="岗位名称" prop="name"></el-table-column>
- <el-table-column label="岗位职责" prop="desc_1" show-overflow-tooltip></el-table-column>
- <template slot="empty">
- <NoData></NoData>
- </template>
- </el-table>
- <center>
- <el-pagination
- small
- :page-size="post_page_size"
- :current-page="post_page"
- layout="prev, pager, next"
- @size-change="handleSizeChange2"
- @current-change="handleCurrentChange2"
- :total="post_total">
- </el-pagination>
- </center>
- </div>
- </div>
- <div>
- <div class="mainEl" style="border-left: 1px solid #f1f1f1;width: 240px;padding: 10px;">
- <div class="mainHead flex-box flex-d-center" v-if="selectItem.length > 0">
- <span>已选择{{ selectItem.length }}个</span>
- <span @click="Empty">清空</span>
- </div>
- <div class="mainTag">
- <el-tag v-for="(item, index) in selectItem" :key="index" closable :disable-transitions="true" @close="TagClose(item, index)">{{ item.name }}</el-tag>
- </div>
- </div>
- </div>
- </div>
- <span slot="footer">
- <el-button @click="isShowRule=false">取 消</el-button>
- <el-button type="primary" @click="ruleConfirm">确认</el-button>
- </span>
- </el-dialog>
- </div>
- </template>
- <script>
- import { _debounce} from '@/utils/auth';
- import Tooltip from '@/components/Tooltip'; //鼠标悬浮显示文字
- import downloadexcel from "vue-json-excel";
- var bool = true; // 五秒执行一次变量
- export default {
- components:{Tooltip,downloadexcel},
- data() {
- return {
- loading: false,
- dept_tree: [],
- page: 1,
- total: 0,
- page_size: 10,
- dept_id: 0,
- formData: {dept_ids: 0,},
- time: [this.$moment().startOf('month').format('YYYY-MM-DD'), this.$moment().endOf('month').format('YYYY-MM-DD')],
- list: [],
- listAll:[],
- keyword: '',
- json_fields:{
- '姓名':'name',
- '部门':'dept',
- '时间':'time',
- '负责次数':'c_item',
- '应得总分':'total_base_point',
- '实际得分':'total_point',
- '被扣分':'total_reduce_point',
- '不合格(次)':'c_bug_item',
- '重点不合格(次)':'c_bug_focus_item',
- '得分(分)':'sm_point',
- '奖分(分)':'sm_reward_point',
- '奖分次数':'sm_reward_count',
- '扣分(分)':'sm_deduce_point',
- '扣分次数':'sm_deduce_count',
- },
- post_total: 0,
- post_page: 1,
- post_page_size: 7,
- tabItem:{name:'销售'},
- tabs:[{name:'全部分类',id:-1}],
- table_loading:false,
- postList:[],
- isShowRule:false,
- selectItem:[],
- selectPost:[],
- selectId:'',
- postName:'',
- selectTypeIndex:1,
- };
- },
- watch: {
- keyword: {
- deep: true,
- handler: _debounce(function(val) {
- this.page = 1;
- this.get_list();
- })
- },
- time(val) {
- this.page = 1;
- this.get_list();
- },
- selectTypeIndex(val) {
- this.page = 1;
- this.get_list();
- },
- dept_id(val) {
- this.page = 1;
- if (val.length > 0) {
- let dept_id=val[val.length-1];
- let dept_list=this.$getCache('dept_tree_pin')[dept_id];
- let ids=[];
- this.getDepts([dept_list],ids);
- this.formData.dept_ids = ids;
- } else {
- this.formData.dept_ids = 0;
- }
- this.$nextTick(() => {
- this.$refs.dept.dropDownVisible = false;
- this.get_list();
- });
- },
- isShowTable(val) {
- if (!val) {
- this.get_list();
- }
- },
- postName: {
- deep: true,
- handler: _debounce(function(val) {
- this.post_page=1;
- this.post_page_size=7;
- this.getTableData();
- })
- },
- },
- methods: {
- openPost(){
- this.tabItem = JSON.parse(JSON.stringify(this.tabs[0]));
- this.selectItem=JSON.parse(JSON.stringify(this.selectPost));
- this.isShowRule = true
- },
- //清除右侧tag
- TagClose(item, index) {
- this.selectItem.splice(index, 1);
- },
- Empty() {
- this.selectItem = [];
- this.postList.forEach(item=>{
- item.checked=false
- })
- },
- clickdatail(item){
- item.checked=!item.checked;
- if(item.checked){
- this.selectItem.push(item);
- }else{
- this.selectItem.forEach((e, index) => {
- if (e.id == item.id) {
- this.selectItem.splice(index, 1);
- }
- });
- }
- },
- activeLi(item, index) {
- this.tabItem = JSON.parse(JSON.stringify(item));
- this.post_page=1;
- this.post_page_size=7;
- this.getTableData();
- },
- getPostType() {
- this.tabs=[{name:'全部分类',id:-1}];
- this.$axiosUser('get', '/api/pro/post/post_cate_list').then(res => {
- this.tabs.push(...res.data.data)
- this.tabItem = JSON.parse(JSON.stringify(this.tabs[0]));
- this.getTableData();
- })
- },
- getTableData() {
- this.table_loading=true;
- let data={
- page:this.post_page,
- page_size:this.post_page_size,
- cate_id:this.tabItem.id,
- name:this.postName
- }
- this.$axiosUser('get', '/api/pro/post/cate_post_list',data).then(res => {
- let list=res.data.data.list;
- let selectItem=this.selectItem;
- list.forEach(item=>{
- item.checked=false
- for (var i in selectItem) {
- if (selectItem[i].id == item.id) {
- item.checked = true;
- }
- }
- })
- this.postList=list;
- this.post_total=res.data.data.total
- }).finally(()=>{
- this.table_loading=false;
- });
- },
- ruleConfirm(){
- this.selectPost=JSON.parse(JSON.stringify(this.selectItem));
- this.isShowRule = false;
- this.get_list();
- },
- returnArr(){
- return this.list;
- },
- sortChange(e){
- let {order,prop}=e;
- if(order===null){
- this.list=this.listAll;
- return false
- }
- let list=JSON.parse(JSON.stringify(this.listAll));
- list.sort((val1,val2)=>{
- if(order=='descending'){
- return val2[prop]-val1[prop]
- }else{
- return val1[prop]-val2[prop]
- }
- })
- this.list=list;
- },
- getDepts(arr,ids){
- if(arr.length>0){
- arr.forEach(item=>{
- ids.push(item.id)
- this.getDepts(item.children,ids)
- })
- }
- },
- onmessageWS(e){
- let that=this;
- if(e.type=='sm_sro'){
- if(e.code==1){
- let list = e.result.list;
- list.forEach(item=>{
- item.time=this.$moment(this.time[0]).format('MM-DD')+'~'+this.$moment(this.time[1]).format('MM-DD');
- })
- this.list = list
- this.listAll = list
- this.loading = false;
- }else{
- this.errorage('x',e.msg)
- }
- }
- // 中途断开
- if(e.type=='break'){
- this.$alert('网络错误,请稍后再试', '网络错误', {
- confirmButtonText: '确定',
- type:'error',
- callback: action => {
- that.not_reuse_employee_id=[];//复用结果
- that.$socketApiTow.closewebsocket();
- }
- });
- }
- },
- errorage(key, arr) {
- //弹窗提示
- if (bool) {
- this.$message({
- message: arr,
- type: key == '√' ? 'success' : key == '?' ? 'warning' : key == 'x' ? 'error' : ''
- });
- bool = false;
- setTimeout(() => {
- bool = true;
- }, 5000);
- }
- },
- get_list() {
- this.loading = true;
- let data={
- type:'sm_sro',
- keyword: this.keyword,
- start_date: this.time[0],
- end_date: this.time[1],
- }
- if(this.selectTypeIndex==1){
- data.dept_ids=this.formData.dept_ids.toString();
- }else{
- let post_ids=this.selectPost.map(e=>{
- return e.id
- })
- data.post_ids=post_ids.toString();
- }
- this.$socketApiTow.sendData(data,this.onmessageWS)
- return false
- // let data = {
- // page: this.page,
- // page_size: this.page_size,
- // keyword: this.keyword,
- // dept_ids: this.formData.dept_ids.toString(),
- // start_date: this.time[0],
- // end_date: this.time[1],
- // };
- this.$axiosUser('get', '/api/pro/sm/statistics/rectify/owners/v2', data).then(res => {
- let list = res.data.data.list;
- list.forEach(item=>{
- item.time=this.$moment(this.time[0]).format('MM-DD')+'~'+this.$moment(this.time[1]).format('MM-DD');
- })
- this.list = list;
- this.listAll = list;
- this.total = res.data.data.total;
- }).finally(() => {
- this.loading = false;
- });
- },
- // 页面变更
- handleCurrentChange2(val) {
- this.post_page = val;
- this.getTableData();
- },
- // 页面跳转
- handleSizeChange2(val) {
- this.post_page_size = val;
- this.getTableData();
- },
- // 页面变更
- handleCurrentChange(val) {
- this.page = val;
- this.get_list();
- },
- handleSizeChange(val) {
- this.page_size = val;
- this.get_list();
- },
- // 递归判断列表,把最后的children设为undefined
- getTreeData(data) {
- for (var i = 0; i < data.length; i++) {
- if (data[i].children.length < 1) {
- // children若为空数组,则将children设为undefined
- data[i].children = undefined;
- } else {
- // children若不为空数组,则继续 递归调用 本方法
- this.getTreeData(data[i].children);
- }
- }
- return data;
- },
- // 下载排名
- submitForm() {
- console.log(this.list);
- return false
- let token = this.$getToken();
- let url = `start_date=${this.time[0]}&end_date=${this.time[1]}&keyword=${this.keyword}`
- if (this.formData.dept_ids) {
- url += `&dept_ids=${this.formData.dept_ids.toString()}`
- }
- // console.log(url)
- // return false
- window.open(this.$serverdomain + '/api/pro/sm/download/rectify/owners/v2?' + url + '&token=' + token);
- }
- },
- mounted() {
- this.getPostType();
- if (this.$getCache('dept_tree')) {
- this.dept_tree = this.getTreeData(this.$getCache('dept_tree'));
- }
- this.get_list();
- },
- beforeDestroy(){
- this.$socketApiTow.closewebsocket();
- }
- };
- </script>
- <style scoped lang="scss">
- .el-pagination {
- text-align: center;
- margin-top: 15px;
- }
- .mainEl {
- .mainHead {
- margin-bottom: 10px;
- span:nth-child(2) {
- color: #409EFF;
- cursor: pointer;
- }
- }
- .mainTag {
- height: 400px;
- overflow-x: hidden;
- overflow-y: auto;
- /deep/ .el-tag--medium {
- background-color: #fff;
- border: 1px solid #e4e4e4;
- border-radius: 20px;
- color: #4c4c4c;
- margin: 5px 5px 5px 0;
- max-width: 240px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- position: relative;
- padding: 0 20px 0 10px;
- }
- .el-tag--medium /deep/ i {
- color: #8f8f8f;
- position: absolute;
- right: 5px;
- top: 5px;
- }
- .el-tag--medium /deep/ i:hover {
- background-color: #9b9b9b;
- color: #fff;
- }
- }
- }
- .width-250 {
- width: 350px;
- }
- .inputDc {
- position: absolute;
- top: 0;
- right: 0;
- left: 0;
- bottom: 0;
- z-index: 9;
- cursor: pointer;
- }
- .border {
- -webkit-appearance: none;
- background-color: #fff;
- background-image: none;
- border-radius: 4px;
- border: 1px solid #dcdfe6;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
- color: #C0C4CF;
- font-size: inherit;
- height: auto;
- outline: 0;
- padding: 0 15px;
- width: 250px;
- position: relative;
- cursor: pointer;
- line-height: 34px;
- }
- .border .font-flex-word{
- color: #606266;
- }
- .diy_tip_bg {
- background: #f5f6f9;
- overflow: hidden;
- .diy-tip {
- border: 1px solid #67c23a;
- p {
- color: #67c23a !important;
- font-size: 15px;
- margin: 0 !important;
- padding-bottom: 4px;
- }
- }
- }
- .message-box .label {
- font-size: 18px;
- font-weight: 600;
- margin-bottom: 20px;
- }
- .message-box .flex-box-ce {
- margin-bottom: 16px;
- }
- .message-box .fontColorC {
- width: 100px;
- }
- .search_box {
- /deep/ button:active {
- background: #409eff;
- }
- /deep/ button:active .el-icon-search {
- color: #fff;
- }
- }
- .date-picker-width {
- width: 100% !important;
- }
- .color_green {
- color: #67c23a;
- }
- .nopoint_box {
- display: inline-block;
- text-align: center;
- width: 100%;
- margin-bottom: 10px;
- }
- .title {
- display: block;
- text-align: center;
- font-size: 12px !important;
- line-height: 30px;
- color: #909399 !important;
- padding: 0;
- }
- .nopoint_box a {
- color: #409eff;
- }
- .chart_content {
- .chart-legend__wrap {
- text-align: right;
- padding: 20px;
- padding-right: 50px;
- & .chart-legend__pink {
- position: relative;
- padding-left: 12px;
- padding-right: 5px;
- &:after {
- content: '';
- position: absolute;
- margin-top: -2px;
- top: 35%;
- left: 0;
- width: 8px;
- height: 8px;
- background: #f56c6c;
- border-radius: 100%;
- }
- }
- & .chart-legend__green {
- position: relative;
- padding-left: 12px;
- &:after {
- content: '';
- position: absolute;
- margin-top: -2px;
- top: 35%;
- left: 0;
- width: 8px;
- height: 8px;
- background: #53b87f;
- border-radius: 100%;
- }
- }
- }
- }
- .drawer_title {
- font-size: 18px;
- padding: 20px;
- }
- .manager_statistics_box {
- background-color: #ffffff;
- padding: 20px;
- /deep/ .el-row .el-checkbox .el-checkbox__label {
- line-height: 20px;
- }
- }
- .headLi {
- padding: 4px;
- list-style: disc;
- font-size: 14px;
- }
- .kh-right {
- padding: 0 10px;
- }
- .pagination {
- position: relative;
- left: -10px;
- }
- .liAction {
- background-color: #ebeef5;
- color: #409EFF;
- }
- .kh-title {
- text-align: center;
- font-weight: 700;
- border-bottom: 1px solid #ebeef5;
- padding-bottom: 10px;
- }
- .kh-left {
- border-right: 1px solid #ebeef5;
- }
- .kh-left li {
- padding: 10px;
- cursor: pointer;
- border-bottom: 1px solid #ebeef5;
- }
- .kh-left li:hover {
- background-color: #ebeef5;
- }
- .kh-Box {
- // height: 430px;
- }
- .bmxx .el-dialog__body {
- padding: 30px 100px 20px 10px !important;
- }
- .el-form-item__label {
- font-weight: normal;
- }
- .li:hover {
- background-color: #f5f7fa;
- }
- .li:hover .el-icon-more {
- display: block;
- }
- .index-name {
- width: 170px;
- }
- .ul {
- max-height: calc(100vh - 230px);
- overflow: auto;
- }
- .ul::-webkit-scrollbar {
- width: 6px;
- height: 6px;
- }
- .ul:hover::-webkit-scrollbar-thumb {
- background-color: #ccc;
- }
- .ul::-webkit-scrollbar-track {
- width: 6px;
- background-color: #f1f1f1;
- -webkit-border-radius: 2em;
- -moz-border-radius: 2em;
- border-radius: 2em;
- }
- .isActiveLi {
- background-color: #f5f7fa;
- color: #409EFF !important;
- position: relative;
- }
- .isActiveLi::after {
- width: 3px;
- content: ' ';
- background-color: #409EFF;
- left: 0;
- bottom: 0;
- top: 0;
- position: absolute;
- }
- </style>
|