DataRerun.vue 12.9 KB
<template>
    <a-form class="data-return-form" :model="queryForm" layout="inline" :label-col="{ style: { width: '70px' } }">
        <a-form-item label="类型:">
          <a-select style="width: 176px" v-model:value="queryForm.dataType">
            <a-select-option :value="1">全店重跑</a-select-option>
            <a-select-option :value="2">分类重跑</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="集团:">
            <a-select v-model:value="queryForm.account_id"
                      style="width: 280px"
                      mode="multiple"
                      :maxTagCount="1"
                      :options="accountList"
                      @change="onAccountChange"
                      optionFilterProp="label"
                      show-search
            >
            </a-select>
        </a-form-item>
        <a-form-item label="广场:">
            <a-select v-model:value="queryForm.plaza_id"
                      style="width: 280px"
                      mode="multiple"
                      :maxTagCount="1"
                      :options="plazaList"
                      optionFilterProp="label"
                      show-search
            >
            </a-select>
        </a-form-item>
        <a-form-item label="数据类型:">
            <a-select v-model:value="queryForm.scheduleTypeList"
                      style="width: 200px"
                      mode="multiple"
                      :maxTagCount="1"
                      :disabled="queryForm.dataType === 2"
                      :options="showedProgressList"
            >
                <template #dropdownRender="{ menuNode: menu }">
                    <v-nodes :vnodes="menu"/>
                    <a-divider style="margin: 4px 0"/>
                    <div
                        @mousedown="e => e.preventDefault()"
                    >
                        <a-button @click="selectAll()" type="link">全选</a-button>
                        <a-button @click="clearAll()" type="link">清空</a-button>
                    </div>
                </template>
            </a-select>
        </a-form-item>
        <a-form-item label="开始日期:">
            <a-date-picker v-model:value="queryForm.startDate"/>
        </a-form-item>
        <a-form-item label="结束日期:">
            <a-date-picker v-model:value="queryForm.endDate"/>
        </a-form-item>
        <a-form-item>
            <a-button type="primary" @click="confirmSearch">开始</a-button>
            <!--<a-button type="primary" style="margin-left: 10px" @click="confirmSearch2">数据重跑</a-button>-->
        </a-form-item>
    </a-form>

    <div class="result-wrapper-2">
        <el-row v-for="item in resultList" style="padding: 2px 0">
            <el-col :span="3">
                {{ progressMap[item.scheduleType] + ':' }}
            </el-col>
            <el-col :span="21">
                <el-progress :text-inside="true" :stroke-width="26" :percentage="item?.progress"/>
            </el-col>
        </el-row>
    </div>
    <InformationDisplay :data="informationList" :key="informationList"></InformationDisplay>
</template>

<script>
import {reactive, ref, toRaw} from 'vue'
import moment from 'moment'
import snapshotRecordApi from '@/views/SnapshotCluster/SnapshotRecord/SnapshotRecordApi'
import {isArray} from '@/PublicUtil/Judgment'
import {formatDate, formatTime} from '@/PublicUtil/PublicUtil'
import InformationDisplay from '@/component/InformationDisplay/InformationDisplay'
import dataRerunApi from '@/views/DataRerun/DataRerunApi'
import {PlusOutlined} from '@ant-design/icons-vue'

export default {
    components: {
        InformationDisplay,
        PlusOutlined,
        VNodes: (_, {attrs}) => {
            return attrs.vnodes
        },
    },
    setup() {
        const resultList = ref([])
        const informationList = ref([])
        // sequence
        const accountList = ref([])
        const plazaList = ref([])
        const zoneList = ref([])
        const gateList = ref([])
        let webSocketMap = {
            mallcountData: undefined,
            floorcountData: undefined,
            zonecountData: undefined,
            gatecountData: undefined,
            mallfaceSta: undefined,
            floorfaceSta: undefined,
            zonefaceSta: undefined,
            gatefaceSta: undefined,
        }

        // mapping
        const progressMap = {
            mallcountData: "商场客流",
            floorcountData: "楼层客流",
            zonecountData: "店铺客流",
            gatecountData: "监控点客流",
            mallfaceSta: "商场人脸",
            floorfaceSta: "楼层人脸",
            zonefaceSta: "店铺人脸",
            gatefaceSta: "监控点人脸"
        }
        const showedProgressList = ref([])

        for (const key in progressMap)
        {
            const value = progressMap[key]

            showedProgressList.value.push(
                {
                    value: key,
                    label: value,
                }
            )
        }

        const queryForm = reactive(
            {
                dataType: 1,

                account_id: [],
                plaza_id: [],
                scheduleTypeList: [],
                startDate: moment(moment().format('YYYY-MM-DD'), 'YYYY-MM-DD'),
                endDate: moment(moment().format('YYYY-MM-DD'), 'YYYY-MM-DD'),
            }
        )

        const onAccountChange = function() {
            getPlazaList()
        }

        const getPlazaList = function() {
            queryForm.plaza_id = []
            plazaList.value = []
            snapshotRecordApi.getPlazaList(
                {
                    account_id: queryForm.account_id.toString()
                }
            ).then(
                (r) => {
                    if (isArray(r))
                    {
                        for (const item of r)
                        {
                            plazaList.value.push(
                                {
                                    value: item.id,
                                    label: item.name,
                                }
                            )
                        }
                    }
                }
            )
        }

        const getAccountList = function() {
            queryForm.account_id = []
            accountList.value = []
            snapshotRecordApi.getAccountList().then(
                (r) => {
                    if (isArray(r))
                    {
                        for (const item of r)
                        {
                            accountList.value.push(
                                {
                                    value: item.id,
                                    label: item.name,
                                }
                            )
                        }
                    }
                }
            )
        }

        const floatToPercent = function(floatNum) {
            if (!floatNum)
            {
                return 0
            }
            let formatNum = Math.floor(floatNum * 100)
            return formatNum >= 100 ? 100 : formatNum
        }

        const dealMessage = function(message) {
            // scheduleType
            const {dates, mallIds, mallNames, status, stepCount, scheduleType, counter} = message
            let resObj = {}
            resObj.dates = dates
            resObj.mallIds = mallIds
            resObj.mallNames = mallNames
            resObj.status = status
            resObj.progress = floatToPercent(stepCount)
            resObj.totalNum = 0
            resObj.totalPage = 0
            resObj.current = 0
            resObj.curPageSize = 0
            resObj.currentPage = 0
            resObj.scheduleType = scheduleType
            if (counter)
            {
                // dataNum dateMallNum step totalData totalDate totalMall totalMallDateProduct allDataCount
                resObj.totalNum = counter.allDataCount
                resObj.totalPage = counter.totalMallDateProduct
                resObj.current = counter.dataNum
                resObj.curPageSize = counter.totalData
                resObj.currentPage = counter.dateMallNum
            }
            if (resultList.value.length)
            {
                const isSameScheduleType = resultList.value.some(item => item.scheduleType === scheduleType)
                isSameScheduleType
                    ? resultList.value.forEach(item => {
                        //
                        item.progress = floatToPercent(stepCount)
                        if (counter)
                        {
                            item.totalNum = counter.allDataCount
                            item.totalPage = counter.totalMallDateProduct
                            item.current = counter.dataNum
                            item.curPageSize = counter.totalData
                            item.currentPage = counter.dateMallNum
                        }
                    })
                    : resultList.value.push(resObj)
                resObj = {}
            }
            else
            {
                resultList.value.push(resObj)
                resObj = {}
            }
        }

        const initializeWebSocket = function(scheduleType) {
            if (webSocketMap[scheduleType] !== undefined)
            {
                webSocketMap[scheduleType].close()
            }

            webSocketMap[scheduleType] = new WebSocket(`${window._socketUrl}/recal/schedule/${scheduleType}`)

            webSocketMap[scheduleType].onopen = () => {
                queryData(scheduleType)
            }

            webSocketMap[scheduleType].onmessage = function(event) {
                let message = JSON.parse(event.data)
                dealMessage(message)
                if (message.stepCount === 1)
                {
                    webSocketMap[scheduleType].close()
                }
            }
        }

        const queryData = function(scheduleType) {
            const rawData = toRaw(queryForm)
            const data = {
                mallIds: rawData.plaza_id,
                scheduleType: scheduleType,
                startDate: formatDate(rawData.startDate) + ' ' + '00:00:00',
                endDate: formatDate(rawData.endDate) + ' ' + '00:00:00',
            }
            dataRerunApi.getResult(data, scheduleType).then(
                (r) => {
                    informationList.value.push(r)
                }
            )
        }

        const confirmSearch = function() {
            if (queryForm.dataType === 1) {
              resultList.value = []
              informationList.value = []
              for (const scheduleType of queryForm.scheduleTypeList)
              {
                  initializeWebSocket(scheduleType)
              }
            } else {
              // 分类重跑
              confirmSearch2()
            }
        }


        // 新需求:数据重跑
        const initializeWebSocket2 = function(scheduleType) {
          if (webSocketMap[scheduleType] !== undefined)
          {
            webSocketMap[scheduleType].close()
          }

          // const targetUrl = `${window._socketUrl}/recal/schedule/${scheduleType}`
          const targetUrl = ''
          webSocketMap[scheduleType] = new WebSocket(targetUrl)

          webSocketMap[scheduleType].onopen = () => {
            // 查询条件
            queryData(scheduleType)
          }

          webSocketMap[scheduleType].onmessage = function(event) {
            let message = JSON.parse(event.data)
            dealMessage(message)
            if (message.stepCount === 1)
            {
              webSocketMap[scheduleType].close()
            }
          }
        }
        const confirmSearch2 = function() {
          resultList.value = []
          informationList.value = []
          for (const scheduleType of queryForm.scheduleTypeList)
          {
            initializeWebSocket2(scheduleType)
          }
        }

        const selectAll = function() {
            queryForm.scheduleTypeList = []

            for (const key in progressMap)
            {
                queryForm.scheduleTypeList.push(key)
            }
        }

        const clearAll = function() {
            queryForm.scheduleTypeList = []
        }

        const __main = function() {
            getAccountList()
        }

        __main()

        return {
            // sequence
            accountList,
            plazaList,
            zoneList,
            gateList,
            resultList,
            informationList,
            showedProgressList,
            // mapping
            progressMap,
            queryForm,
            onAccountChange,
            initializeWebSocket,
            confirmSearch,
            selectAll,
            clearAll,

            confirmSearch2,
        }
    }
}
</script>

<style lang="less" scoped>
@import "./DataRerun.less";
.data-return-form {
  /deep/.ant-form-item {
    margin-bottom: 10px;
  }
}
</style>