<!-- filename: index.vue author: liubin date: 2023-09-04 09:34:52 description: 设备产量时序图 --> <template> <div class="production-timegraph-container" style="background: #f2f4f9; flex: 1"> <el-row class="" style=" margin-bottom: 12px; background: #fff; padding: 16px 16px 0; border-radius: 8px; "> <div class="blue-title">生产节拍时序图</div> <!-- <h1>设备状态时序图</h1> --> <!-- 搜索工作栏 --> <SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" :remove-blue="true" @headBtnClick="handleSearchBarBtnClick" /> </el-row> <el-row class="" style=" margin-bottom: 12px; background: #fff; padding: 16px 16px 24px; border-radius: 8px; "> <div class="blue-title">设备产量时序图</div> <div class="main-area"> <div class="graphs" v-if="graphList.length"> <LineChart :config="templateConfig" /> </div> <div class="no-data-bg" v-else></div> </div> </el-row> <!-- 对话框(添加 / 修改) --> <base-dialog dialogTitle="添加设备" :dialogVisible="open" width="500px" @close="open = false" @cancel="open = false" @confirm="submitForm"> <el-select v-if="open" style="width: 100%" v-model="queryParams.equipmentId" placeholder="请选择一个设备"> <el-option v-for="eq in eqList" :key="eq.id" :value="eq.id" :label="eq.name"></el-option> </el-select> </base-dialog> </div> </template> <script> import LineChart from './components/lineChart.vue'; export default { name: 'SGProduction', components: { LineChart }, props: {}, data() { return { accumulators: new Map(), searchBarFormConfig: [ { type: 'select', label: '产线', placeholder: '请选择产线', selectOptions: [], param: 'lineId', required: true }, { type: 'select', label: '工段', placeholder: '请选择工段', selectOptions: [], param: 'sectionId', required: true, }, // 时间段 { type: 'datePicker', label: '时间段', dateType: 'date', // datetimerange // format: 'yyyy-MM-dd HH:mm:ss', format: 'yyyy-MM-dd', valueFormat: 'yyyy-MM-dd HH:mm:ss', // valueFormat: 'timestamp', // rangeSeparator: '-', // startPlaceholder: '开始日期', // endPlaceholder: '结束日期', // defaultTime: ['00:00:00', '23:59:59'], placeholder: '选择日期', param: 'recordTime', required: true }, { type: 'button', btnName: '查询', name: 'search', color: 'primary', }, { type: 'separate', }, { type: 'button', btnName: '添加对比', name: 'compare', color: 'primary', plain: true, }, ], queryParams: { lineId: null, sectionId: null, equipmentId: null, recordTime: [], }, open: false, eqList: [], graphList: [], templateConfig: { color: ['#283D68', '#FFB61F', '#4481FF', '#5AD8A6', '#E97466'], grid: { top: 48, left: 48, right: 24, bottom: 64, }, legend: { top: 0, right: 12, padding: 6, itemWidth: 16, itemHeight: 8, itemGap: 20, textStyle: { fontSize: 12, lineHeight: 12, color: '#0007', }, }, tooltip: { show: true, trigger: 'axis', }, xAxis: { type: 'category', boundaryGap: true, axisTick: { // show: false, alignWithLabel: true, lineStyle: { color: '#0003', }, }, axisLabel: { // show: true, // textStyle: { // color: '#0007', // }, }, data: [], // data: Array(24) // .fill(1) // .map((item, index) => `${index}:00`), }, yAxis: { type: 'value', name: '产量', nameLocation: 'end', nameTextStyle: { fontSize: 14, align: 'center', }, nameGap: 26, max: function (value) { return value.max + Math.floor(value.max / 5); }, }, series: [ // { // name: '产线1', // data: Array(24) // .fill(1) // .map(() => Math.random() * 100), // type: 'line', // symbol: 'circle', // // smooth: true, // }, // { // name: '产线2', // data: Array(24) // .fill(1) // .map(() => Math.random() * 100), // type: 'line', // symbol: 'circle', // // smooth: true, // }, // { // name: '产线3', // data: Array(24) // .fill(1) // .map(() => Math.random() * 100), // type: 'line', // symbol: 'circle', // // smooth: true, // }, ], }, }; }, created() { this.initProductline(); this.initWorksection(); this.initEquipment(); this.getList(); }, methods: { handleSearchBarBtnClick({ btnName, ...payload }) { switch (btnName) { case 'search': this.queryParams.lineId = payload.lineId || null; this.queryParams.sectionId = payload.sectionId || null; this.queryParams.equipmentId = payload.equipmentId || null; this.queryParams.recordTime = payload.recordTime ? [ payload.recordTime, payload.recordTime.replace('00:00:00', '23:59:59'), ] : null; this.getList(); break; case 'compare': this.open = true; break; } }, /** 重置查询条件 */ initQuery() { this.queryParams.lineId = null; this.queryParams.sectionId = null; this.queryParams.equipmentId = null; this.queryParams.recordTime = []; }, /** 对象到数组的转换 */ objectToArray(obj) { return Object.keys(obj).map((key) => { obj[key].sort((a, b) => a.startTime - b.startTime); obj[key].key = key; return obj[key]; }); }, async getList() { const { code, data } = await this.$axios({ url: '/analysis/equipment-analysis/quantity', method: 'get', params: this.queryParams, }); if (code == 0) { this.graphList = this.objectToArray(data); // const eq1 = [ // { totalQuantity: 20, startTime: 1693964578000 }, // { totalQuantity: 43, startTime: 1693964678000 }, // { totalQuantity: 12, startTime: 1693964778000 }, // { totalQuantity: 11, startTime: 1693964878000 }, // { totalQuantity: 98, startTime: 1693965478000 }, // { totalQuantity: 87, startTime: 1693965578000 }, // ]; // eq1.key = 'SS1'; // const eq2 = [ // { totalQuantity: 23, startTime: 1693961578000 }, // { totalQuantity: 42, startTime: 1693964578000 }, // { totalQuantity: 51, startTime: 1693965578000 }, // { totalQuantity: 18, startTime: 1693966578000 }, // { totalQuantity: 77, startTime: 1693966778000 }, // { totalQuantity: 38, startTime: 1693967578000 }, // { totalQuantity: 57, startTime: 1693969578000 }, // ]; // eq2.key = 'SS2'; // this.graphList = [eq1, eq2]; this.graphList.forEach(this.setSeries); } else { this.graphList = []; this.graphList.forEach(this.setSeries); } }, setSeries(eqArr) { if (eqArr.length == 0) { this.templateConfig.series = []; return; } let isInit = false; if (this.accumulators.has(eqArr.key) == false) { this.accumulators.set(eqArr.key, 0); isInit = true; } let accumulator = this.accumulators.get(eqArr.key); if ((accumulator && !isInit) || (accumulator == 0 && isInit == false)) { accumulator++; this.accumulators.set(eqArr.key, accumulator); } this.templateConfig.series.push({ name: eqArr.key + (accumulator == 0 ? '' : '-' + accumulator), // name: Math.random(), type: 'line', symbol: 'circle', data: this.getEquipmentQuantity(eqArr), }); }, /** 获得设备产量 */ getEquipmentQuantity(equipmentArr) { return equipmentArr.map((item) => item.totalQuantity); }, /** 获得设备产量的时间 */ getTimeinfo(equipmentArr) { return equipmentArr.map((item) => new Date(item.startTime).toLocaleTimeString() ); }, /** 准备设备数据 */ async initEquipment() { const { code, data } = await this.$axios({ url: '/base/equipment/listAll', method: 'get', }); if (code == 0) { this.eqList = data.map((item) => { return { name: item.name, id: item.id, }; }); } }, /** 准备产线数据 */ async initProductline() { const { code, data } = await this.$axios({ url: '/base/production-line/listAll', method: 'get', }); if (code == 0) { this.searchBarFormConfig[0].selectOptions = data.map((item) => { return { name: item.name, id: item.id, }; }); } }, /** 准备工段数据 */ async initWorksection() { const { code, data } = await this.$axios({ url: '/base/workshop-section/listAll', method: 'get', }); if (code == 0) { this.searchBarFormConfig[1].selectOptions = data.map((item) => { return { name: item.name, id: item.id, }; }); } }, async submitForm() { const { code, data } = await this.$axios({ url: '/analysis/equipment-analysis/quantity', method: 'get', params: this.queryParams, }); this.queryParams.equipmentId = null; // 清空一下 if (code == 0) { const newEqlist = this.objectToArray(data); if (!newEqlist || newEqlist.length == 0) { this.$message.error('该设备没有产量数据'); return; } this.graphList.push(...newEqlist); newEqlist.forEach(this.setSeries); } this.open = false; }, }, }; </script> <style scoped lang="scss"> .blue-title { position: relative; padding: 4px 0; padding-left: 12px; font-size: 14px; color: #606266; font-weight: 700; margin-bottom: 12px; &::before { content: ''; position: absolute; left: 0; top: 6px; height: 16px; width: 4px; border-radius: 1px; background: #0b58ff; } } </style>