index.vue 15.2 KB
<template>
    <div class="clerk-wrapper queueManagementContainer">
        <div class="header manage-head-wrapper">
            <el-form class="boxShadow searchFormSocial" ref="form" label-width="100px" inline>
                <el-form-item :label="$t('table.mall')">
                    <el-select v-model="searchForm.mallId" filterable :placeholder="$t('pholder.select')" @change="mallChange">
                        <el-option v-for="item in mallListForTerm" :key="item.id" :label="item.name" :value="item.id" />
                    </el-select>
                </el-form-item>
                <el-form-item :label="$t('table.areaName')">
                    <el-select v-model="searchForm.cashierAreaId" :placeholder="$t('pholder.areaSelect')" @change="areaChange">
                        <el-option v-for="item in areaListData" :key="item.id" :label="item.name" :value="item.id" />
                    </el-select>
                </el-form-item>
                <el-form-item :label="$t('table.date')">
                    <el-date-picker type="date" :placeholder="$t('pholder.date')" v-model="searchForm.countDate"></el-date-picker>
                </el-form-item>
                <el-form-item>
                    <el-time-picker is-range v-model="searchForm.time" :range-separator="$t('dialog.to')" :start-placeholder="$t('pholder.startDate')" :end-placeholder="$t('pholder.endDate')" placeholder="选择时间范围">  </el-time-picker>
                </el-form-item>
                <!-- <el-form-item :label="$t('table.granularity')">
                    <el-select v-model="searchForm.granularity" :placeholder="$t('pholder.select')">
                        <el-option v-for="item in granularityListData" :key="item.value" :label="item.label" :value="item.value" />
                    </el-select>
                </el-form-item> -->
                <el-form-item>
                    <el-button type="primary" class="search-btn" size="mini" plain @click="searchFun">{{$t('button.search')}}</el-button>
                    <el-button type="primary" class="search-btn" v-if="!playBtnShow" size="mini" plain @click="playFun">{{$t('button.play')}}</el-button>
                    <el-button type="primary" class="search-btn" v-if="playBtnShow" size="mini" plain @click="pauseFun">{{$t('button.pause')}}</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div class="manage-content">
            <div class="asis-table-content" v-loading="loading">
                <canvas id='container' class="boxShadow"></canvas>
                <div class="time-box1" v-show="progressShow">
                    <span style="float: left;">{{startTime}}</span>
                    <span style="color: #2774e9;">{{progressTime}}</span>
                    <span style="float: right;">{{endTime}}</span>
                </div>
                <div id="colorBox" v-show="progressShow"></div>
            </div>
        </div>
    </div>
</template>

<script>
    import moment from 'moment'
    export default {
        data() {
            return {
                startTime:'',
                endTime:'',
                mallListForTerm: [],
                areaListData: [],
                areaOneObj:{},
                loading: false,
                searchForm: {
                    mallId: '',
                    cashierAreaId: '',
                    countDate: new Date(),
                    time:[new Date(), new Date()],
                    granularity:5
                },
                canvas: null, //canvas实例
                ctx: null, //ctx画笔
                widthX: 0, //缩放比例X
                heightX: 0, //缩放比例Y
                dataList: [], //点位坐标
                pic: null,
                timeInterval:null,
                progressShow:false,
                progressTime:'',
                playBtnShow:false,
                colorBoxWidth:0,
                channelNum:0,
                granularityListData:[
                    {
                        value: 1,
                        label: '1min'
                    }, {
                      value: 2,
                      label: '2min'
                    }, {
                      value: 3,
                      label: '3min'
                    }, {
                      value: 5,
                      label: '5min'
                    }, {
                      value: 10,
                      label: '10min'
                    },{
                      value: 20,
                      label: '20min'
                    },{
                      value: 30,
                      label: '30min'
                    },
                ]
            }
        },
        mounted() {
            this.getMallListForTerm();
            this.canvas = document.getElementById("container");
            this.ctx = this.canvas.getContext("2d");
            this.canvas.width = document.body.clientWidth - 248;
            this.canvas.height = 400;
            this.widthX = (1920 / this.canvas.width).toFixed(2);
            this.heightX = (1080 / this.canvas.height).toFixed(2);
            window.addEventListener("resize", () => {
              this.setCanvasWidth();
            });
            this.loading = true;
        },
        computed: {
            tableHeight() {
                const windowInnerHeight = window.innerHeight;
                return windowInnerHeight - windowInnerHeight * 0.24;
            },
        },
        beforeDestroy() {
          if (this.timeInterval) {
            clearInterval(this.timeInterval);
          }
        },
        methods: {
            // 广场
            getMallListForTerm() {
                this.mallListForTerm = [];
                this.searchForm.mallId = "";
                this.$api.base.mall({
                    accountId: this.$cookie.get('accountId'),
                    status_arr: "1,3"
                }).then(data => {
                    let result = data.data;
                    if (result.data.length) {
                        if (this.getSessionLocal("mallId")) {
                            this.searchForm.mallId = Number(this.getSessionLocal("mallId"));
                        } else {
                            this.searchForm.mallId = result.data[0].id;
                            this.setSessionLocal("mallId", this.searchForm.mallId);
                        }
                        this.getOpenTime()
                        this.mallListForTerm = result.data;
                    }
                    this.getAreaList(this.searchForm.mallId);
                })
            },
            mallChange(val) {
                this.setSessionLocal("mallId", val);
                this.searchForm.cashierAreaId = ''
                this.channelNum = 0
                this.getAreaList(val)
                this.getOpenTime()
            },
            // 获取门店开门关闭时间
            getOpenTime(){
                this.$api.base.getOpentimeList({mallId:this.searchForm.mallId}).then(res=>{
                    let result = res.data;
                    if(result.code==200){
                        let data = result.data.list[0]
                        let endTime = data.endTime
                        if(endTime.substring(10)=='00:00:00'){
                            endTime =endTime.substring(0,10)+ '23:59:59'
                        }
                        this.searchForm.time = [moment(data.startTime).format('YYYY-MM-DD HH:mm:ss'),moment(endTime).format('YYYY-MM-DD HH:mm:ss')]
                    }
                })
            },
            // 区域
            getAreaList(val) {
                this.areaListData = [];
                this.$api.queueManagementApi.getAreaList({
                    mallId: val,
                    pageNum: 1,
                    pageSize: 999999
                }).then(res => {
                    let result = res.data;
                    if (result.code == 200) {
                        if (result.data.list && result.data.list.length > 0) {
                            this.searchForm.cashierAreaId = result.data.list[0].id
                            this.areaListData = result.data.list;
                            this.areaOneObj = result.data.list[0]
                            this.getChannelList()
                            this.pic = new Image();
                            this.pic.src =this.areaListData[0] && window._vionConfig.picUrl + this.areaListData[0].pic;
                            this.pic.onload = () => {
                              this.drawCirlce();
                            };
                            this.searchFun()
                        }
                    }
                })
            },
            areaChange(val){
                this.areaOneObj = this.areaListData.find(item=> item.id==val);
                this.pic = new Image();
                this.pic.src =this.areaOneObj && window._vionConfig.picUrl + this.areaOneObj.pic;
                this.pic.onload = () => {
                  this.drawCirlce();
                };
                this.getChannelList()
                this.searchFun()
            },
            // 通道
            getChannelList() {
                this.$api.queueManagementApi.getChannelList({
                    areaId: this.searchForm.cashierAreaId,
                    pageNum: 1,
                    pageSize: 999999
                }).then(res => {
                    let result = res.data;
                    if (result.code == 200) {
                        this.channelNum=result.data.list.length
                    }
                })
            },
            playFun(){
                this.startTime = moment(this.searchForm.time[0]).format('HH:mm:ss')
                this.endTime = moment(this.searchForm.time[1]).format('HH:mm:ss')
                document.getElementById("colorBox").innerHTML='';
                this.playBtnShow = true
                this.progressShow = true;
                let openT = new Date(this.searchForm.time[0]).getTime();
                let closeT = new Date(this.searchForm.time[1]).getTime();
                let num = (closeT-openT)/1000/60/this.searchForm.granularity;
                this.colorBoxWidth = (this.canvas.width/(num+1)).toFixed(2);
                this.colorBoxWidth = this.colorBoxWidth - 0.01
                this.getDistribution(moment(openT).format('HH:mm:ss'))
                this.timeInterval = setInterval(() => {
                    openT = openT + 1000 * 60 * this.searchForm.granularity
                    if(openT > closeT){
                        clearInterval(this.timeInterval);
                        return false
                    }else{
                        this.progressTime = moment(openT).format('HH:mm:ss')
                        this.getDistribution(moment(openT).format('HH:mm:ss'))
                    }
                }, 1500);
            },
            pauseFun(){
                this.playBtnShow = false
                clearInterval(this.timeInterval);
            },
            pushBox(color){
                var boxParent = document.getElementById("colorBox");
                let boxChild = document.createElement("span");
                boxChild.style.background = color;
                boxChild.style.width = this.colorBoxWidth + 'px';
                boxChild.style.height = "50px";
                boxChild.style.display = "inline-block";
                boxParent.appendChild(boxChild);
            },
            searchFun() {
                clearInterval(this.timeInterval);
                this.getDistribution()
            },
            // 获取主页大屏人员点位分布
            async getDistribution(time) {
                if(time){
                    this.searchForm.countDate = moment(this.searchForm.countDate).format('YYYY-MM-DD') +' '+time
                }else{
                    this.searchForm.countDate = moment(this.searchForm.countDate).format('YYYY-MM-DD') +' '+moment(this.searchForm.time[0]).format('HH:mm:ss')
                }
                let parmas = {
                    cashierAreaId:this.searchForm.cashierAreaId,
                    countDate: this.searchForm.countDate,
                }
              let res = await this.$api.queueManagementApi.getdistribution(parmas);
              let { code, data } = res.data;
              if (code == 200) {
                  this.loading = false;
                let red = data.red ? data.red : [];
                let green = data.green ? data.green : [];
                this.dataList = [
                  ...red.map((item) => ({ ...item, status: 1 })),
                  ...green.map((item) => ({ ...item, status: 0 })),
                ];
                if(time){
                    let color = ''
                    if(red.length<=this.areaOneObj.safeNum*this.channelNum){
                        color = 'green'
                    }else if(red.length>this.areaOneObj.safeNum*this.channelNum && red.length<=this.areaOneObj.warnNum*this.channelNum){
                        color = 'yellow'
                    }else{
                        color = 'red'
                    }
                    this.pushBox(color)
                }
                this.drawCirlce();
              }
            },
            //动态设置canvas的宽度
            setCanvasWidth() {
              if (this.fullscreen) {
                this.canvas.width = document.body.clientWidth - 20;
                this.canvas.height = 480;
              } else {
                this.canvas.width = document.body.clientWidth - 248;
                this.canvas.height = 300;
              }
              this.widthX = (1920 / this.canvas.width).toFixed(2);
              this.heightX = (1080 / this.canvas.height).toFixed(2);
              this.drawCirlce();
            },
            // 画圆点
            drawCirlce() {
              if (!this.pic) return false;
              this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
              this.ctx.drawImage(this.pic, 0, 0, this.canvas.width, this.canvas.height);
              this.dataList.forEach((item) => {
                if (item.status == 1) {
                  this.ctx.fillStyle = "red";
                } else {
                  this.ctx.fillStyle = "green";
                }
                this.ctx.beginPath();
                this.ctx.arc(
                  (item.x / 100) * this.canvas.width,
                  (item.y / 100) * this.canvas.height,
                  5,
                  0,
                  2 * Math.PI
                );
                this.ctx.fill();
              });
            },
        }
    }
</script>

<style scoped="scoped" lang="less">
    /deep/.el-select{
        width: 180px;
    }
    /deep/.el-date-editor{
        width: 180px;
    }
    /deep/.el-date-editor--timerange.el-input__inner{
        width: 220px;
    }
    /deep/.el-form-item__label{
        height: 30px;
        line-height: 30px !important;
    }
    /deep/.el-form-item__content{
        height: 30px;
        line-height: 30px;
    }
    /deep/.el-date-editor .el-range-separator{
        line-height: 22px;
    }
    .time-box1{
        width: 100%;
        text-align: center;
        margin-top: 5px;
        height: 30px;
        line-height: 30px;
    }
    #container{
      margin-top: 10px;
      margin-bottom: 10px;
    }
    #colorBox{
        border: 1px solid #ccc;
        margin-top: 10px;
        height: 52px;
        box-sizing: border-box;
    }
</style>