479 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			479 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
<!--
 | 
						|
 * @Author: zhp
 | 
						|
 * @Date: 2024-04-15 10:49:13
 | 
						|
 * @LastEditTime: 2024-07-09 11:08:43
 | 
						|
 * @LastEditors: zhp
 | 
						|
 * @Description:
 | 
						|
-->
 | 
						|
<template>
 | 
						|
  <div style="display: flex; flex-direction: column; min-height: calc(100vh - 96px - 35px)">
 | 
						|
    <el-row :gutter="10">
 | 
						|
      <el-col :span="4">
 | 
						|
        <div class="app-container" style="padding: 16px; height: auto; text-align: left; border-radius: 8px;">
 | 
						|
          <!-- <p style="margin-bottom: 0">数据概览</p> -->
 | 
						|
          <div class="view">
 | 
						|
            <div style="padding: 10px 0; width: 100%">
 | 
						|
              <div class="topDiv">
 | 
						|
                <div style="width: 4px; height: 52px; background: #71CC8C; border-radius: 2px;"></div>
 | 
						|
                <div class="centerDiv">
 | 
						|
                  <span style="font-size: 30px; line-height: 30px; color: rgba(0,0,0,0.85);">{{ inputNum }}</span>
 | 
						|
                  <span style="font-size: 14px; color: rgba(0,0,0,0.85);">在制工单数量</span>
 | 
						|
                </div>
 | 
						|
                <svg-icon icon-class="workProcess" style="width: 26px; height: 26px" />
 | 
						|
              </div>
 | 
						|
            </div>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
      </el-col>
 | 
						|
      <el-col :span="20">
 | 
						|
        <div class="app-container" style="padding: 16px; height: auto; text-align: left; border-radius: 8px;">
 | 
						|
          <!-- <p style="margin-bottom: 0">数据概览</p> -->
 | 
						|
          <div class="view">
 | 
						|
            <div style="padding: 10px 0; width: 100%" v-for="(item, index) in factorys" :key="index">
 | 
						|
              <div class="topDiv">
 | 
						|
                <div style="width: 4px; height: 52px; background: #3A79FF; border-radius: 2px;"></div>
 | 
						|
                <div class="centerDiv">
 | 
						|
                  <span style="font-size: 30px; line-height: 30px; color: rgba(0,0,0,0.85);">{{ factoryNum[index]
 | 
						|
                    }}</span>
 | 
						|
                  <span style="font-size: 14px; color: rgba(0,0,0,0.85);">{{item}}</span>
 | 
						|
                </div>
 | 
						|
                <svg-icon icon-class="factoryWorkOrder" style="width: 26px; height: 26px" />
 | 
						|
              </div>
 | 
						|
            </div>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
      </el-col>
 | 
						|
    </el-row>
 | 
						|
    <!-- <div class="app-container" style="margin-top: 8px; height: auto;">
 | 
						|
      <search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
 | 
						|
    </div> -->
 | 
						|
    <div class="app-container" style="margin-top: 8px;flex-grow: 1;">
 | 
						|
      <!-- <search-bar :formConfigs="formConfig2" ref="searchBarForm" style="margin-bottom: 0" /> -->
 | 
						|
      <search-bar :formConfigs="formConfig" ref="searchBarForm" @headBtnClick="buttonClick" />
 | 
						|
      <base-table :table-props="tableProps" :page="listQuery.pageNo" :limit="listQuery.pageSize" :table-data="tableData"
 | 
						|
        :max-height="tableH">
 | 
						|
        <method-btn v-if="tableBtn.length" slot="handleBtn" label="操作" :width="120" fixed="right"
 | 
						|
          :method-list="tableBtn" @clickBtn="handleClick" />
 | 
						|
      </base-table>
 | 
						|
      <pagination :limit.sync="listQuery.pageSize" :page.sync="listQuery.pageNo" :total="listQuery.total"
 | 
						|
        @pagination="getDataList" />
 | 
						|
    </div>
 | 
						|
    <add-or-update v-if="detailOrUpdateVisible" ref="detailOrUpdate" :date="listQuery.date"
 | 
						|
      @refreshDataList="successSubmit" @destroy="detailOrUpdateVisible = false" />
 | 
						|
    <div id="dayRepDom" style="position: absolute;top:0;display: none;">
 | 
						|
      <ExportDayReport :beProcessObj="beProcessObj" :produceData="produceData" :hisObj="hisObj" :pieList="pieList" />
 | 
						|
    </div>
 | 
						|
  </div>
 | 
						|
</template>
 | 
						|
 | 
						|
<script>
 | 
						|
// import { parseTime } from '../../core/mixins/code-filter';
 | 
						|
import { getWorkOrderPage, exportExcel, getOverView, getWorkOrderDetail } from '@/api/produceData/order';
 | 
						|
// import inputTable from './inputTable.vue';
 | 
						|
import lineChart from './lineChart';
 | 
						|
import ExportDayReport from './dayReportComponents/ExportDayReport'
 | 
						|
import moment from 'moment'
 | 
						|
import tableHeightMixin from "@/mixins/tableHeightMixin";
 | 
						|
// import ButtonNav from '@/components/ButtonNav'
 | 
						|
import basicPage from '@/mixins/basic-page'
 | 
						|
import AddOrUpdate from './add-or-updata';
 | 
						|
import { factoryList, factoryArray } from "@/utils/constants";
 | 
						|
// import { publicFormatter } from "@/utils/dict";
 | 
						|
import statusChart from "./statusChart.vue";
 | 
						|
import html2canvas from 'html2canvas'
 | 
						|
import JsPDF from 'jspdf'
 | 
						|
// import FileSaver from 'file-saver'
 | 
						|
// import * as XLSX from 'xlsx'
 | 
						|
export default {
 | 
						|
  components: { lineChart, AddOrUpdate, ExportDayReport },
 | 
						|
  mixins: [basicPage, tableHeightMixin],
 | 
						|
	data() {
 | 
						|
    return {
 | 
						|
      factorys: ['瑞昌中建材', '邯郸中建材', '株洲中建材', '佳木斯中建材', '成都中建材', '凯盛光伏', '蚌埠兴科'],
 | 
						|
      factoryNum: [0, 0, 0, 0, 0, 0, 0],
 | 
						|
      inputNum: 0,
 | 
						|
      heightNum: 180,
 | 
						|
      factoryList,
 | 
						|
      produceData: [],
 | 
						|
      pieList:[],
 | 
						|
      hisObj: {
 | 
						|
        seriesList: [],
 | 
						|
        dateList:[],
 | 
						|
      },
 | 
						|
      beProcessObj: {
 | 
						|
        xAxisList: [],
 | 
						|
        yAxisList:[]
 | 
						|
      },
 | 
						|
      factoryArray,
 | 
						|
      listQuery: {
 | 
						|
        pageSize: 20,
 | 
						|
        pageNo: 1,
 | 
						|
        factorys: undefined,
 | 
						|
        total: 0,
 | 
						|
        time: undefined,
 | 
						|
        orderStatus:undefined
 | 
						|
      },
 | 
						|
      detailOrUpdateVisible:false,
 | 
						|
      tableBtn: [
 | 
						|
          {
 | 
						|
            type: 'detail',
 | 
						|
            btnName: '详情',
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'export',
 | 
						|
          btnName: '导出',
 | 
						|
        },
 | 
						|
        // {
 | 
						|
        //     type: 'delete',
 | 
						|
        //     btnName: '删除',
 | 
						|
        //   },
 | 
						|
      ].filter((v) => v),
 | 
						|
      typeList: [
 | 
						|
        {
 | 
						|
          name: '芯片',
 | 
						|
          id: 0,
 | 
						|
        },
 | 
						|
        {
 | 
						|
          name: '标准组件',
 | 
						|
          id: 1,
 | 
						|
        },
 | 
						|
        {
 | 
						|
          name: 'BIPV产品',
 | 
						|
          id: 2,
 | 
						|
        },
 | 
						|
      ],
 | 
						|
      formConfig: [
 | 
						|
        {
 | 
						|
          type: "select",
 | 
						|
          label: "工厂名称",
 | 
						|
          selectOptions: factoryArray,
 | 
						|
          labelField: 'name',
 | 
						|
          valueField: 'id',
 | 
						|
          param: "factory",
 | 
						|
          multiple: true,
 | 
						|
					filterable: true
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: "select",
 | 
						|
          label: "工单状态",
 | 
						|
          selectOptions: [
 | 
						|
            {
 | 
						|
              label: '未开始',
 | 
						|
              value: 0
 | 
						|
            },
 | 
						|
            {
 | 
						|
              label: '生产中',
 | 
						|
              value: 1
 | 
						|
            },
 | 
						|
            {
 | 
						|
              label: '已完成',
 | 
						|
              value: 2
 | 
						|
            }
 | 
						|
          ],
 | 
						|
          labelField: "label",
 | 
						|
          valueField: "value",
 | 
						|
          param: "orderStatus",
 | 
						|
          multiple: true,
 | 
						|
					filterable: true
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: "datePicker",
 | 
						|
          label: "时间段",
 | 
						|
          dateType: "daterange",
 | 
						|
          format: "yyyy-MM-dd",
 | 
						|
          valueFormat: "yyyy-MM-dd",
 | 
						|
          rangeSeparator: "-",
 | 
						|
          startPlaceholder: "开始日期",
 | 
						|
          endPlaceholder: "结束日期",
 | 
						|
          param: "timeSlot",
 | 
						|
          defaultSelect: [],
 | 
						|
          defaultTime: ["00:00:00", "23:59:59"],
 | 
						|
          width: 250,
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: "button",
 | 
						|
          btnName: "查询",
 | 
						|
          name: "search",
 | 
						|
          color: "primary",
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: "separate",
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: "button",
 | 
						|
          btnName: "导出",
 | 
						|
          name: "export",
 | 
						|
          color: "primary",
 | 
						|
          plain: true
 | 
						|
        },
 | 
						|
      ],
 | 
						|
      formConfig2: [
 | 
						|
        {
 | 
						|
          type: 'title',
 | 
						|
          label: '工厂信息',
 | 
						|
        },
 | 
						|
      ],
 | 
						|
      formConfig1: [
 | 
						|
        {
 | 
						|
          type: 'title',
 | 
						|
          label: '良品数量',
 | 
						|
        },
 | 
						|
      ],
 | 
						|
      tableProps: [
 | 
						|
        {
 | 
						|
          prop: 'factory',
 | 
						|
          label: '工厂名称',
 | 
						|
          filter: (val) => factoryList[val],
 | 
						|
          minWidth: 220,
 | 
						|
          showOverflowtooltip: true
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'workOrderNumber',
 | 
						|
          label: '工单号',
 | 
						|
          minWidth: 130,
 | 
						|
          showOverflowtooltip: true
 | 
						|
          // filter: (val) => ['玻璃芯片', '标准组件', 'BIPV', '定制组件'][val]
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'workOrderType',
 | 
						|
          label: '工单类型',
 | 
						|
          // filter: publicFormatter('workorder_status')
 | 
						|
          filter: (val) => ['', '芯片工单', '组件类型', 'bipv类型'][val],
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'plannedInvestment',
 | 
						|
          label: '计划投入',
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'actualInvestment',
 | 
						|
          label: '实际投入',
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'targetProduction',
 | 
						|
          label: '目标产量',
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'actualProduction',
 | 
						|
          label: '实际产量',
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'productionProgress',
 | 
						|
          label: '生产进度',
 | 
						|
          filter: (val) => (val * 100).toFixed(2) + '%'
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'orderStatus',
 | 
						|
          label: '工单状态',
 | 
						|
          subcomponent: statusChart
 | 
						|
          // filter: (val) => ['', '未开始', '生产中', '已完成'][val],
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'startTime',
 | 
						|
          label: '开始时间',
 | 
						|
          minWidth: 100,
 | 
						|
          showOverflowtooltip: true
 | 
						|
        },
 | 
						|
        {
 | 
						|
          prop: 'endTime',
 | 
						|
          label: '完成时间',
 | 
						|
          minWidth: 100,
 | 
						|
          showOverflowtooltip: true
 | 
						|
        }
 | 
						|
      ],
 | 
						|
      tableData: [],
 | 
						|
      xAxis: [],
 | 
						|
      lineData: {}
 | 
						|
      // data: {}
 | 
						|
			// proLineList: [],
 | 
						|
			// all: {}
 | 
						|
		};
 | 
						|
  },
 | 
						|
	created() {
 | 
						|
    const today = new Date()
 | 
						|
    const sevenDaysAgo = new Date(today.getTime() - (6 * 24 * 60 * 60 * 1000))
 | 
						|
    this.listQuery.time = [moment(sevenDaysAgo).format('yyyy-MM-DD'), moment(today).format('yyyy-MM-DD')]
 | 
						|
    this.formConfig[2].defaultSelect = this.listQuery.time
 | 
						|
	},
 | 
						|
  mounted() {
 | 
						|
    this.getOverView()
 | 
						|
  },
 | 
						|
  methods: {
 | 
						|
    exportPDF() {
 | 
						|
      setTimeout(() => {
 | 
						|
        this.$message.success('正在导出,请稍等!')
 | 
						|
        const element = document.getElementById('dayRepDom')
 | 
						|
        element.style.display = 'block'
 | 
						|
        const fileName = '工单数据' + moment().format('yyMMDD') + '.pdf'
 | 
						|
        html2canvas(element, {
 | 
						|
          dpi: 300, // Set to 300 DPI
 | 
						|
          scale: 3 // Adjusts your resolution
 | 
						|
        }).then(function (canvas) {
 | 
						|
          const imgWidth = 595.28
 | 
						|
          const imgHeight = 841.89
 | 
						|
          const pageData = canvas.toDataURL('image/jpeg', 1.0)
 | 
						|
          const PDF = new JsPDF('', 'pt', [imgWidth, imgHeight])
 | 
						|
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
 | 
						|
          setTimeout(() => {
 | 
						|
            PDF.save(fileName) // 导出文件名
 | 
						|
          }, 1000)
 | 
						|
        })
 | 
						|
        element.style.display = 'none'
 | 
						|
      }, 3000)
 | 
						|
 | 
						|
    },
 | 
						|
    getOverView() {
 | 
						|
      getOverView().then(res => {
 | 
						|
        // this.data = res.data
 | 
						|
        if (res.code === 0) {
 | 
						|
          for(const i in res.data) {
 | 
						|
            if (i === '在制工单数量') {
 | 
						|
              this.inputNum = res.data[i]
 | 
						|
            } else {
 | 
						|
              const index = this.factorys.indexOf(i)
 | 
						|
              if (index > -1) {
 | 
						|
                this.factoryNum[index] = res.data[i]
 | 
						|
              }
 | 
						|
            }
 | 
						|
          }
 | 
						|
        }
 | 
						|
      })
 | 
						|
    },
 | 
						|
    otherMethods(val) {
 | 
						|
      console.log(val)
 | 
						|
      if (val.type === 'detail') {
 | 
						|
        this.detailOrUpdateVisible = true;
 | 
						|
        // this.addOrEditTitle = "详情";
 | 
						|
        this.$nextTick(() => {
 | 
						|
          this.$refs.detailOrUpdate.init(val.data.id);
 | 
						|
        });
 | 
						|
      } else {
 | 
						|
        getWorkOrderDetail(val.data.id).then((res) => {
 | 
						|
          if (res.code === 0) {
 | 
						|
            // this.loading = false
 | 
						|
 | 
						|
            const xAxisList = Object.keys(res.data.inProcessDis)
 | 
						|
            const yAxisList = Object.values(res.data.inProcessDis)
 | 
						|
            this.beProcessObj.xAxisList = xAxisList
 | 
						|
            this.beProcessObj.yAxisList = yAxisList
 | 
						|
            // console.log(this.beProcessObj)
 | 
						|
              ; const data = res.data.prodWorkOrderDO
 | 
						|
            const barList = [data.targetProduction, data.plannedInvestment, data.actualInvestment, data.actualProduction, data.wasteNum, data.reworkNum]
 | 
						|
            const seriesList = []
 | 
						|
            const dateList = []
 | 
						|
            res.data.his.forEach(element => {
 | 
						|
              seriesList.push(element.actualProduction)
 | 
						|
              dateList.push(element.recordTime[0] + '-' + element.recordTime[1] + '-' + element.recordTime[2])
 | 
						|
            })
 | 
						|
            this.hisObj.seriesList = seriesList
 | 
						|
            this.hisObj.dateList = dateList
 | 
						|
            this.produceData = barList
 | 
						|
            this.pieList = [
 | 
						|
              { value: data.actualProduction ? data.actualProduction : 0, name: '实际产出' },
 | 
						|
              { value: data.wasteNum ? data.wasteNum : 0, name: '废品数量' },
 | 
						|
              { value: data.reworkNum ? data.reworkNum : 0, name: '待再加工数量' }
 | 
						|
            ]
 | 
						|
          }
 | 
						|
          this.$nextTick(() => {
 | 
						|
            this.exportPDF()
 | 
						|
          })
 | 
						|
        })
 | 
						|
 | 
						|
      }
 | 
						|
    },
 | 
						|
    async getDataList() {
 | 
						|
      const res = await getWorkOrderPage(this.listQuery)
 | 
						|
      this.tableData = res.data.list
 | 
						|
      this.listQuery.total = res.data.total
 | 
						|
      if (this.listQuery.total > 0) {
 | 
						|
        this.tableData.forEach(item => {
 | 
						|
          item.startTime = item.startDate ? item.startDate[0] + '-' + item.startDate[1] + '-' + item.startDate[2] : '--'
 | 
						|
          item.endTime = item.endDate ? item.endDate[0] + '-' + item.endDate[1] + '-' + item.endDate[2] : '--'
 | 
						|
        })
 | 
						|
      }
 | 
						|
    },
 | 
						|
		buttonClick(val) {
 | 
						|
			this.listQuery.factorys = val.factory?.length > 0 ? val.factory : undefined
 | 
						|
      this.listQuery.orderStatus = val.orderStatus?.length > 0 ? val.orderStatus : undefined
 | 
						|
      this.listQuery.time = val.timeSlot?.length > 0 ? val.timeSlot : undefined
 | 
						|
			switch (val.btnName) {
 | 
						|
				case 'search':
 | 
						|
					this.listQuery.pageNo = 1;
 | 
						|
					this.listQuery.pageSize = 20;
 | 
						|
          if (this.listQuery.time) {
 | 
						|
            this.getDataList();
 | 
						|
          } else {
 | 
						|
            this.$message.warning('请选择时间范围!')
 | 
						|
          }
 | 
						|
					break;
 | 
						|
				case 'export':
 | 
						|
          if (this.listQuery.time) {
 | 
						|
            this.handleExport();
 | 
						|
          } else {
 | 
						|
            this.$message.warning('请选择时间范围!')
 | 
						|
          }
 | 
						|
					break;
 | 
						|
				default:
 | 
						|
					console.log(val);
 | 
						|
			}
 | 
						|
		},
 | 
						|
		/** 导出按钮操作 */
 | 
						|
    handleExport() {
 | 
						|
      this.$modal.confirm('是否确认导出工单数据?').then(() => {
 | 
						|
        // 处理查询参数
 | 
						|
        // let params = {...this.listQuery};
 | 
						|
        // params.current = 1;
 | 
						|
        // params.size = 999;
 | 
						|
        this.exportLoading = true;
 | 
						|
        return exportExcel({
 | 
						|
          factorys: this.listQuery.factorys,
 | 
						|
          orderStatus: this.listQuery.orderStatus,
 | 
						|
          time: this.listQuery.time
 | 
						|
        });
 | 
						|
      }).then(response => {
 | 
						|
        this.$download.excel(response, '工单数据.xls');
 | 
						|
        this.exportLoading = false;
 | 
						|
      }).catch(() => {})
 | 
						|
    },
 | 
						|
	},
 | 
						|
};
 | 
						|
</script>
 | 
						|
 | 
						|
<style scoped>
 | 
						|
.centerDiv {
 | 
						|
  display: flex;
 | 
						|
  flex-direction: column;
 | 
						|
  justify-content: flex-start;
 | 
						|
}
 | 
						|
.topDiv {
 | 
						|
  display: flex;
 | 
						|
  flex-direction: row;
 | 
						|
  justify-content: space-around;
 | 
						|
  align-items: flex-start;
 | 
						|
  flex: 1;
 | 
						|
}
 | 
						|
.view {
 | 
						|
  display: flex;
 | 
						|
  justify-content: space-around;
 | 
						|
  align-items: center;
 | 
						|
  flex: 1;
 | 
						|
}
 | 
						|
.blueTip::before{
 | 
						|
  display: inline-block;
 | 
						|
  content: '';
 | 
						|
  width: 4px;
 | 
						|
  height: 18px;
 | 
						|
  background: #0B58FF;
 | 
						|
  border-radius: 1px;
 | 
						|
  margin-right: 8PX;
 | 
						|
  margin-top: 8px;
 | 
						|
}
 | 
						|
.app-container {
 | 
						|
  margin: 0 0px 0;
 | 
						|
  background-color: #fff;
 | 
						|
  border-radius: 4px;
 | 
						|
  padding: 16px 16px 0;
 | 
						|
  height: calc(100vh - 40px);
 | 
						|
  overflow: auto;
 | 
						|
}
 | 
						|
</style>
 |