Przeglądaj źródła

Merge branch 'test' of http://110.41.163.243:9980/kd-aiot/kd-aiot-frontend-mes into dengfei

695593266@qq.com 10 miesięcy temu
rodzic
commit
8cf4cf5395
3 zmienionych plików z 445 dodań i 366 usunięć
  1. 9 0
      src/api/mes/index.js
  2. 237 178
      src/views/home/data.js
  3. 199 188
      src/views/home/index.vue

+ 9 - 0
src/api/mes/index.js

@@ -76,3 +76,12 @@ export async function getOrderList(params) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+// 不良占比
+export async function queryProportionDefectiveTypes () {
+  const res = await request.post(`/qms/quality_work_order/queryProportionDefectiveTypes`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 237 - 178
src/views/home/data.js

@@ -2,201 +2,260 @@
 const dayjs = require('dayjs');
 // 获取本月日期列表的函数
 function getDatesInMonth() {
-    let year = dayjs().year()
-    let month = dayjs().month()
-    const dates = [];
-    const startDate = dayjs(new Date(year, month, 1));
-    const endDate = dayjs(new Date(year, month + 1, 1)).subtract(1, 'day');
-    let currentDate = startDate;
-    while (currentDate.isBefore(endDate) || currentDate.isSame(endDate, 'day')) {
-        dates.push(currentDate.format('YYYY-MM-DD'));
-        currentDate = currentDate.add(1, 'day');
-    }
-    return dates;
+  let year = dayjs().year();
+  let month = dayjs().month();
+  const dates = [];
+  const startDate = dayjs(new Date(year, month, 1));
+  const endDate = dayjs(new Date(year, month + 1, 1)).subtract(1, 'day');
+  let currentDate = startDate;
+  while (currentDate.isBefore(endDate) || currentDate.isSame(endDate, 'day')) {
+    dates.push(currentDate.format('YYYY-MM-DD'));
+    currentDate = currentDate.add(1, 'day');
+  }
+  return dates;
 }
 
 let statusOpt = [
-      { label: '生产中', value: '5' },
-      { label: '已完成', value: '6' },
-      { label: '已延期', value: '7' },
-    ]
+  { label: '生产中', value: '5' },
+  { label: '已完成', value: '6' },
+  { label: '已延期', value: '7' }
+];
 
 let daysOpt = [
-    { label: '已延期', value: -1},
-    { label: '已完成', value: 0},
-]
+  { label: '已延期', value: -1 },
+  { label: '已完成', value: 0 }
+];
 
 export const columns = [
+  {
+    columnKey: 'index',
+    label: '序号',
+    type: 'index',
+    width: 55,
+    align: 'center',
+    showOverflowTooltip: true,
+    fixed: 'left'
+  },
+  {
+    prop: 'batchNo',
+    label: '批次号',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'code',
+    label: '生产工单编码',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'status',
+    label: '工单状态',
+    align: 'center',
+    showOverflowTooltip: true,
+    formatter: (row) => {
+      let result = statusOpt.find((item) => item.value == row.status);
+      return result ? result.label : '';
+    }
+  },
+  {
+    prop: 'planStartTime',
+    label: '计划开始时间',
+    minWidth: '120',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'planCompleteTime',
+    label: '计划完成时间',
+    minWidth: '120',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'productName',
+    label: '产品名称',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'productCode',
+    label: '产品编码',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  // {
+  //     prop: 'specification',
+  //     label: '规格型号',
+  //     align: 'center',
+  //     showOverflowTooltip: true,
+  // },
+  {
+    prop: 'formingNum',
+    label: '数量(个)',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'taskName',
+    label: '生产工序',
+    align: 'center',
+    showOverflowTooltip: true
+  },
+  {
+    prop: 'days',
+    label: '交期状态',
+    align: 'center',
+    showOverflowTooltip: true,
+    formatter: (row) => {
+      let result = daysOpt.find((item) => item.value == row.days);
+      return result ? result.label : row.days ? '剩余' + row.days + '天' : '';
+    }
+  }
+];
 
-    {
-        columnKey: 'index',
-        label: '序号',
-        type: 'index',
-        width: 55,
-        align: 'center',
-        showOverflowTooltip: true,
-        fixed: 'left'
+export const barOption = (series, itemStyle = {}) => {
+  return {
+    tooltip: {
+      formatter: (item) => {
+        return item.name + ':' + item.seriesName + ' ' + item.value + '个';
+      },
+      trigger: 'item'
     },
-    {
-        prop: 'batchNo',
-        label: '批次号',
-        align: 'center',
-        showOverflowTooltip: true,
+    legend: {
+      // bottom: '2%',
+      itemGap: window.innerHeight * 0.014,
+
+      textStyle: {
+        fontSize: window.innerHeight * 0.013
+      }
     },
-    {
-        prop: 'code',
-        label: '生产工单编码',
-        align: 'center',
-        showOverflowTooltip: true,
+    color: ['#1890ff'],
+    xAxis: {
+      type: 'category',
+      data: [
+        '一月',
+        '二月',
+        '三月',
+        '四月',
+        '五月',
+        '六月',
+        '七月',
+        '八月',
+        '九月',
+        '十月',
+        '十一月',
+        '十二月'
+      ],
+      axisLabel: {
+        fontSize: window.innerHeight * 0.012
+      }
     },
-    {
-        prop: 'status',
-        label: '工单状态',
-        align: 'center',
-        showOverflowTooltip: true,
-        formatter: (row) => {
-            let result = statusOpt.find(item => item.value == row.status)
-            return result ? result.label : ''
+    yAxis: [
+      {
+        type: 'value',
+        name: '(个)',
+        nameTextStyle: {
+          align: 'center',
+          color: '#333',
+          fontSize: window.innerHeight * 0.012,
+          padding: [0, 20, -3, 0]
         }
+      }
+    ],
+    series
+  };
+};
+
+export const pieOption = (data) => {
+  return {
+    color: ['#398f4e', '#458ef7', '#fdc537', '#fe6869', '#975fe6'],
+    tooltip: {
+      formatter: '{b}:{c}' + '%',
+      trigger: 'item'
     },
-    {
-        prop: 'planStartTime',
-        label: '计划开始时间',
-        minWidth: '120',
-        align: 'center',
-        showOverflowTooltip: true,
-    },
-    {
-        prop: 'planCompleteTime',
-        label: '计划完成时间',
-        minWidth: '120',
-        align: 'center',
-        showOverflowTooltip: true,
-    },
-    {
-        prop: 'productName',
-        label: '产品名称',
-        align: 'center',
-        showOverflowTooltip: true,
-    }, {
-        prop: 'productCode',
-        label: '产品编码',
-        align: 'center',
-        showOverflowTooltip: true,
-    }, 
-    // {
-    //     prop: 'specification',
-    //     label: '规格型号',
-    //     align: 'center',
-    //     showOverflowTooltip: true,
-    // }, 
-    {
-        prop: 'formingNum',
-        label: '数量(个)',
-        align: 'center',
-        showOverflowTooltip: true,
-    }, {
-        prop: 'taskName',
-        label: '生产工序',
-        align: 'center',
-        showOverflowTooltip: true,
-    }, {
-        prop: 'days',
-        label: '交期状态',
-        align: 'center',
-        showOverflowTooltip: true,
-        formatter: (row) => {
-            let result = daysOpt.find(item => item.value == row.days)
-            return result ? result.label : row.days ? '剩余' + row.days + '天' : ''
-        }
+    legend: {
+      orient: 'horizontal',
+      left: 'right',
+      right: '15%',
+      bottom: '5%',
+      itemGap: window.innerHeight * 0.018,
+      textStyle: {
+        fontSize: window.innerHeight * 0.014
+      }
     },
-
-];
-
-export const barOption = (series, itemStyle = {}) => {
-    return {
-        tooltip: {
-            formatter: (item) => {
-                return item.name + ":" + item.seriesName + " " + item.value + '个'
-            },
-            trigger: 'item'
+    series: [
+      {
+        center: ['50%', '40%'],
+        label: {
+          position: 'outside',
+          show: true,
+          formatter: (item) => {
+            return item.name + ':' + item.value + '%';
+          },
+          fontSize: window.innerHeight * 0.014
+          // color:"#fff"
         },
-        legend: {
-            // bottom: '2%',
-            itemGap: window.innerHeight * 0.014,
-
-            textStyle: {
-                fontSize: window.innerHeight * 0.013,
-            }
+        labelLine: {
+          show: true
         },
-        color: ['#1890ff'],
-        xAxis: {
-            type: 'category',
-            data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月',],
-            axisLabel: {
-                fontSize: window.innerHeight * 0.012,
-            }
-
+        type: 'pie',
+        radius: '60%',
+        itemStyle: {
+          borderWidth: 0,
+          shadowBlur: 10,
+          shadowColor: 'rgba(0, 0, 0, 0.5)'
         },
-        yAxis: [
-            {
-                type: 'value',
-                name: '(个)',
-                nameTextStyle: {
-                    align: 'center',
-                    color: "#333",
-                    fontSize: window.innerHeight * 0.012,
-                    padding: [0, 20, -3, 0]
-                },
-            }
-        ],
-        series
-    }
-}
+        data
+      }
+    ]
+  };
+};
 
-export const pieOption = (data) => {
-    return {
-        color: ['#398f4e', '#458ef7', '#fdc537', '#fe6869', '#975fe6'],
-        tooltip: {
-            formatter: '{b}:{c}' + '%',
-            trigger: 'item'
+export const pieOptions = (data) => {
+  return {
+    color: ['#398f4e', '#458ef7', '#fdc537', '#fe6869', '#975fe6'],
+    tooltip: {
+      // formatter: '{b}:{c}' + '%',
+      formatter: function (params) {
+        return `${params.name}<br/>数量: ${params.value}<br/>占比: ${params.percent}%`;
+      },
+      trigger: 'item'
+    },
+    legend: {
+      orient: 'horizontal',
+      left: 'right',
+      right: '15%',
+      bottom: '5%',
+      itemGap: window.innerHeight * 0.018,
+      textStyle: {
+        fontSize: window.innerHeight * 0.014
+      }
+    },
+    series: [
+      {
+        center: ['50%', '40%'],
+        label: {
+          position: 'outside',
+          show: true,
+          formatter: (item) => {
+            return item.name + ':' + item.value;
+          },
+          fontSize: 16
+          // color:"#fff"
         },
-        legend: {
-            orient: 'horizontal',
-            left: 'right',
-            right: '15%',
-            bottom: '5%',
-            itemGap: window.innerHeight * 0.018,
-            textStyle: {
-                fontSize: window.innerHeight * 0.014,
-            }
+        labelLine: {
+          show: true
         },
-        series: [
-            {
-                center: ['50%', '40%'],
-                label: {
-                    position: 'outside',
-                    show: true,
-                    formatter: (item) => {
-                        return item.name + ":" + item.value + '%'
-                    },
-                    fontSize: window.innerHeight * 0.014,
-                    // color:"#fff"
-                },
-                labelLine: {
-                    show: true,
-
-                },
-                type: 'pie',
-                radius: '60%',
-                itemStyle: {
-                    borderWidth: 0,
-                    shadowBlur: 10,
-                    shadowColor: 'rgba(0, 0, 0, 0.5)'
-                },
-                data
-            }
-        ]
-    }
-}
-
+        type: 'pie',
+        radius: '60%',
+        itemStyle: {
+          borderWidth: 0,
+          shadowBlur: 10,
+          shadowColor: 'rgba(0, 0, 0, 0.5)'
+        },
+        data
+      }
+    ]
+  };
+};

+ 199 - 188
src/views/home/index.vue

@@ -34,7 +34,7 @@
           <div slot="header" class="clearfix">
             <span>不良品分布图</span>
           </div>
-          <v-chart ref="pieRef" style="height: 100%" :option="pieOption" />
+          <v-chart ref="pieRef" style="height: 100%" :option="pieOptions" />
         </el-card>
       </el-col>
       <el-col :span="24" style="height: 43%; margin-top: 15px">
@@ -57,229 +57,240 @@
   </div>
 </template>
 <script>
-import dictMixins from '@/mixins/dictMixins';
-import { pieOption, barOption, columns } from './data';
-import { use } from 'echarts/core';
-import { CanvasRenderer } from 'echarts/renderers';
-import { BarChart, PieChart, LineChart } from 'echarts/charts';
-import {
-  GridComponent,
-  TooltipComponent,
-  LegendComponent
-} from 'echarts/components';
+  import dictMixins from '@/mixins/dictMixins';
+  import { pieOption, barOption, columns, pieOptions } from './data';
+  import { use } from 'echarts/core';
+  import { CanvasRenderer } from 'echarts/renderers';
+  import { BarChart, PieChart, LineChart } from 'echarts/charts';
+  import {
+    GridComponent,
+    TooltipComponent,
+    LegendComponent
+  } from 'echarts/components';
 
-import VChart from 'vue-echarts';
-import { echartsMixin } from '@/utils/echarts-mixin';
-import { getCount, getCompletionCount, getOrderList } from '@/api/mes/index'
-// 按需加载 echarts
-use([
-  CanvasRenderer,
-  BarChart,
-  PieChart,
-  GridComponent,
-  TooltipComponent,
-  LegendComponent,
-  LineChart
-]);
-export default {
-  mixins: [dictMixins, echartsMixin(['pieRef', 'barRef'])],
-  components: { VChart },
-  data() {
-    return {
-      columns,
-      arr: [
-        {
-          name: '生产总数',
-          num: '188',
-          imgUrl: require('../../assets/Group1.png'),
-          unit: ''
-        },
-        {
-          name: '待生产数量',
-          num: '188',
-          imgUrl: require('../../assets/Group2.png'),
-          unit: ''
-        },
-        {
-          name: '已完成数量',
-          num: '188',
-          imgUrl: require('../../assets/Group3.png'),
-          unit: ''
-        },
-        {
-          name: '生产中数量',
-          num: '188',
-          imgUrl: require('../../assets/Group4.png'),
-          unit: '',
-          color: '#f97876'
-        }
-      ],
+  import VChart from 'vue-echarts';
+  import { echartsMixin } from '@/utils/echarts-mixin';
+  import { getCount, getCompletionCount, getOrderList,queryProportionDefectiveTypes } from '@/api/mes/index';
+  // 按需加载 echarts
+  use([
+    CanvasRenderer,
+    BarChart,
+    PieChart,
+    GridComponent,
+    TooltipComponent,
+    LegendComponent,
+    LineChart
+  ]);
+  export default {
+    mixins: [dictMixins, echartsMixin(['pieRef', 'barRef'])],
+    components: { VChart },
+    data() {
+      return {
+        columns,
+        arr: [
+          {
+            name: '生产总数',
+            num: '188',
+            imgUrl: require('../../assets/Group1.png'),
+            unit: ''
+          },
+          {
+            name: '待生产数量',
+            num: '188',
+            imgUrl: require('../../assets/Group2.png'),
+            unit: ''
+          },
+          {
+            name: '已完成数量',
+            num: '188',
+            imgUrl: require('../../assets/Group3.png'),
+            unit: ''
+          },
+          {
+            name: '生产中数量',
+            num: '188',
+            imgUrl: require('../../assets/Group4.png'),
+            unit: '',
+            color: '#f97876'
+          }
+        ],
 
-      pieOption: {},
-      barOption: {},
-      form: {
-        finishTime: '',
-        timeType: '1'
-      }
-    };
-  },
+        pieOption: {},
+        barOption: {},
+        pieOptions: {},
+        form: {
+          finishTime: '',
+          timeType: '1'
+        }
+      };
+    },
 
-  created() {
-    this.pieOption = pieOption([
-      { value: 40, name: '  外观检测' },
-      { value: 30, name: '  尺寸检测' },
-      { value: 15, name: '  性能检测' },
-      { value: 10, name: '  密度检测' },
-      { value: 5, name: '  重量检测' }
-    ]);
-    
-    this.getCount();
-    this.getCompletionCount();
-  },
-  mounted(){
-    setTimeout(() => {
-      this.$refs.barRef.resize();
-      this.$refs.pieRef.resize();
-    }, 300);
-  },
-  methods: {
-    datasource({page, where, limit}) {
-      where.factoriesId = 0;
-      return getOrderList({
-        ...where,
-        pageNum: page,
-        size: limit
-      });
+    created() {
+      // this.pieOption = pieOption([
+      //   { value: 40, name: '  外观检测' },
+      //   { value: 30, name: '  尺寸检测' },
+      //   { value: 15, name: '  性能检测' },
+      //   { value: 10, name: '  密度检测' },
+      //   { value: 5, name: '  重量检测' }
+      // ]);
 
+      this.getCount();
+      this.getCompletionCount();
     },
-    
-    //首页统计
-    async getCount() {
-      let rest = await getCount({factoriesId: 0});
-      this.arr.forEach((item, index) => {
-        if (item.name === '生产总数') {
-          item.num = rest.formingNum || 0;
-        } else if (item.name === '待生产数量') {
-          item.num = rest.pendingProductionCount || 0;
-        } else if (item.name === '已完成数量') {
-          item.num = rest.formedNum || 0;
-        } else if (item.name === '生产中数量') {
-          item.num = rest.inProgressWorkOrderCount || 0;
-        }
-      })
-      // console.log(rest, 'rest');
+    mounted() {
+      this.proportion();
+      setTimeout(() => {
+        this.$refs.barRef.resize();
+        this.$refs.pieRef.resize();
+      }, 300);
     },
+    methods: {
+      async proportion() {
+        const res = await queryProportionDefectiveTypes();
+        let list = res.map((el) => {
+          return {
+            value: el.unQualifiedNumber,
+            name: el.categoryLevelClassName
+          };
+        });
+        this.pieOptions = pieOptions(list);
+        console.log(res, 'res ----');
+      },
+      datasource({ page, where, limit }) {
+        where.factoriesId = 0;
+        return getOrderList({
+          ...where,
+          pageNum: page,
+          size: limit
+        });
+      },
+      timeTypeChange(){},
+      //首页统计
+      async getCount() {
+        let rest = await getCount({ factoriesId: 0 });
+        this.arr.forEach((item, index) => {
+          if (item.name === '生产总数') {
+            item.num = rest.formingNum || 0;
+          } else if (item.name === '待生产数量') {
+            item.num = rest.pendingProductionCount || 0;
+          } else if (item.name === '已完成数量') {
+            item.num = rest.formedNum || 0;
+          } else if (item.name === '生产中数量') {
+            item.num = rest.inProgressWorkOrderCount || 0;
+          }
+        });
+        // console.log(rest, 'rest');
+      },
 
-    //工单完成统计
-    async getCompletionCount() {
-      let params = {
-        startDate: new Date().getFullYear() + '-01-01',
-        endDate: new Date().getFullYear() + '-12-31',
-        factoriesId: 0,
-      }
-      let rest = await getCompletionCount(params);
-      let inWarehouseCountList = []; //入库数量
-      let inProductCountList = []; //在制工单数
-      for (let i = 0; i < rest.length; i++) {
-        inWarehouseCountList.push(rest[i].inWarehouseCount)
-        inProductCountList.push(rest[i].inProductCountList)
-      }
-      this.barOption = barOption(
-        [
+      //工单完成统计
+      async getCompletionCount() {
+        let params = {
+          startDate: new Date().getFullYear() + '-01-01',
+          endDate: new Date().getFullYear() + '-12-31',
+          factoriesId: 0
+        };
+        let rest = await getCompletionCount(params);
+        let inWarehouseCountList = []; //入库数量
+        let inProductCountList = []; //在制工单数
+        for (let i = 0; i < rest.length; i++) {
+          inWarehouseCountList.push(rest[i].inWarehouseCount);
+          inProductCountList.push(rest[i].inProductCountList);
+        }
+        this.barOption = barOption([
           {
             name: '工单入库数量',
             barWidth: '25%',
             data: inWarehouseCountList,
             type: 'bar',
             yAxisIndex: 0 // 使用第一个Y轴
-          }, {
+          },
+          {
             name: '工单数',
             symbolSize: 10,
             data: inProductCountList,
-            type: 'line', smooth: true,
+            type: 'line',
+            smooth: true,
             itemStyle: {
               color: '#ffab08'
-            },
+            }
           }
         ]);
+      }
     }
-  }
-};
+  };
 </script>
 <style lang="scss" scoped>
-.clearfix {
-  font-size: 0.7vw;
-
-  > span {
-    font-weight: bold;
-  }
-  :deep(.el-radio-button__inner) {
+  .clearfix {
     font-size: 0.7vw;
-  }
-}
-.ele-body {
-  height: calc(100vh - 111px);
-  > .el-row {
-    height: 100%;
-  }
-  .el-card {
-    height: 100%;
-    :deep(.el-card__body) {
-      padding: 0.3vw;
-    }
-    :deep(.el-card__header) {
-      padding: 0.8vw;
+
+    > span {
+      font-weight: bold;
     }
-    :deep(.el-card__body) {
-      height: calc(100% - 1.6vw - 39px);
+    :deep(.el-radio-button__inner) {
+      font-size: 0.7vw;
     }
-    :deep(.ele-pro-table) {
-      height: 99%;
+  }
+  .ele-body {
+    height: calc(100vh - 111px);
+    > .el-row {
+      height: 100%;
     }
-    :deep(.el-table) {
-      font-size: 0.65vw;
+    .el-card {
+      height: 100%;
+      :deep(.el-card__body) {
+        padding: 0.3vw;
+      }
+      :deep(.el-card__header) {
+        padding: 0.8vw;
+      }
+      :deep(.el-card__body) {
+        height: calc(100% - 1.6vw - 39px);
+      }
+      :deep(.ele-pro-table) {
+        height: 99%;
+      }
+      :deep(.el-table) {
+        font-size: 0.65vw;
+      }
     }
   }
-}
-.item {
-  width: 100%;
-  display: flex;
-  margin-bottom: 15px;
-  margin-top: 15px;
-  > div {
-    border-radius: 4px;
-    flex: 1;
-    margin-left: 15px;
-    background: url(../../assets/item_frame.png) no-repeat;
-    background-size: 100% 100%;
+  .item {
+    width: 100%;
     display: flex;
-    align-items: center;
-    padding: 12px;
-    img {
-      width: 2.3vw;
-      // height:1.7vw;
-    }
+    margin-bottom: 15px;
+    margin-top: 15px;
     > div {
+      border-radius: 4px;
+      flex: 1;
+      margin-left: 15px;
+      background: url(../../assets/item_frame.png) no-repeat;
+      background-size: 100% 100%;
       display: flex;
-      flex-direction: column;
-      // margin-left: 0.8vw;
-      justify-content: center;
       align-items: center;
-      width: 80%;
-      span:nth-of-type(1) {
-        font-size: 0.75vw;
+      padding: 12px;
+      img {
+        width: 2.3vw;
+        // height:1.7vw;
       }
-      span:nth-of-type(2) {
-        font-weight: bold;
-        font-size: 1.2vw;
-        margin-top: 0.8vw;
-        span {
-          font-size: 0.7vw;
+      > div {
+        display: flex;
+        flex-direction: column;
+        // margin-left: 0.8vw;
+        justify-content: center;
+        align-items: center;
+        width: 80%;
+        span:nth-of-type(1) {
+          font-size: 0.75vw;
+        }
+        span:nth-of-type(2) {
+          font-weight: bold;
+          font-size: 1.2vw;
+          margin-top: 0.8vw;
+          span {
+            font-size: 0.7vw;
+          }
         }
       }
     }
   }
-}
 </style>
-
-