2213980799@qq.com 1 tahun lalu
induk
melakukan
47da0e9ac1
4 mengubah file dengan 544 tambahan dan 1 penghapusan
  1. 42 0
      src/api/main/index.js
  2. 205 0
      src/views/home/data.js
  3. 296 0
      src/views/home/index.vue
  4. 1 1
      src/views/login/index.vue

+ 42 - 0
src/api/main/index.js

@@ -0,0 +1,42 @@
+import request from '@/utils/request';
+
+
+// 产品合格率
+
+export async function queryHomePage (data) {
+    const res = await request.post(`/qms/quality_work_order/queryHomePage` , data);
+    if (res.data.code == 0) {
+      return res.data.data;
+    }
+    return Promise.reject(new Error(res.data.message));
+  }
+
+// 工厂查询
+
+export async function queryFactory () {
+  const res = await request.get(`/qms/quality_work_order/queryFactory`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+
+// 班组查询
+
+export async function queryTeam () {
+  const res = await request.get(`/qms/quality_work_order/queryTeam`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 产线查询
+
+export async function queryProductionLine () {
+  const res = await request.get(`/qms/quality_work_order/queryProductionLine`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 205 - 0
src/views/home/data.js

@@ -0,0 +1,205 @@
+// 引入Day.js库
+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;
+}
+export const userList = [
+
+    {
+        columnKey: 'index',
+        label: '序号',
+        type: 'index',
+        width: 55,
+        align: 'center',
+        showOverflowTooltip: true,
+        fixed: 'left'
+    },
+
+    {
+        prop: 'name',
+        label: '姓名',
+        width: 100,
+        align: 'center',
+        showOverflowTooltip: true,
+    },
+    {
+        prop: 'jobNumber',
+        label: '工号',
+        width: 120,
+        align: 'center',
+        showOverflowTooltip: true,
+    },
+    {
+        prop: 'qualified',
+        label: '合格率',
+        align: 'center',
+        slot: 'qualified'
+    }
+
+];
+export const unacceptedProduct = [
+    {
+        columnKey: 'index',
+        label: '序号',
+        type: 'index',
+        width: 55,
+        align: 'center',
+        showOverflowTooltip: true,
+        fixed: 'left'
+    },
+
+
+    {
+        prop: 'name',
+        label: '类型',
+        width: 120,
+        align: 'center',
+        showOverflowTooltip: true,
+    },
+    {
+        prop: 'jobNumber',
+        label: '编码',
+        width: 180,
+        align: 'center',
+        showOverflowTooltip: true,
+    },
+    {
+        prop: 'qualified',
+        label: '不良原因',
+        align: 'center',
+    },
+    {
+        prop: 'qualified2',
+        width: 150,
+        label: '申请人',
+        align: 'center',
+    },
+    {
+        prop: 'qualified3',
+        width: 120,
+        label: '操作',
+        align: 'center',
+    }
+
+];
+
+export const barOption = (data, itemStyle = {}) => {
+    return {
+        tooltip: {
+            formatter: '{b}:{c}' + '%',
+            trigger: 'item'
+        },
+        color: ['#398f4e',],
+        xAxis: {
+            type: 'category',
+            data: data.map(item => item.name),
+            axisLabel: {
+                fontSize: window.innerHeight * 0.012,
+
+            }
+
+        },
+        yAxis: {
+            type: 'value'
+        },
+        series: [
+            {
+                // showBackground: true,
+                barWidth: '20%',
+                data: data.map(item => item.value),
+                type: 'bar',
+                // backgroundStyle: {
+                //     // color: 'rgba(180, 180, 180, 0.2)',
+                //     // shadowColor: 'rgba(0, 0, 0, 0.5)',
+                //     // shadowBlur: 10
+                // },
+                itemStyle
+            }
+        ]
+    }
+}
+
+export const preOption = (data, radius = ['45%', '60%'], labelLineShow = true, labelPosition = 'outside') => {
+    return {
+        color: ['#398f4e', '#458ef7', '#fdc537', '#fe6869', '#975fe6'],
+        tooltip: {
+            formatter: '{b}:{c}' + '%',
+            trigger: 'item'
+        },
+        legend: {
+            orient: 'vertical',
+            left: 'left',
+            left: '10%',
+            top: '25%',
+            itemGap: window.innerHeight * 0.018,
+            textStyle: {
+                fontSize: window.innerHeight * 0.014,
+            }
+        },
+        series: [
+            {
+                center: ['60%', '50%'],
+                label: {
+                    position: labelPosition,
+                    show: true,
+                    formatter: '{c}' + '%',
+                    fontSize: window.innerHeight * 0.014,
+                    // color:"#fff"
+                },
+                labelLine: {
+                    show: labelLineShow
+                },
+                type: 'pie',
+                radius,
+                itemStyle: {
+                    borderWidth: 0,
+                    shadowBlur: 10,
+                    shadowColor: 'rgba(0, 0, 0, 0.5)'
+                },
+                data
+            }
+        ]
+    }
+}
+
+export const lineOption = (data, type) => {
+
+
+console.log(getDatesInMonth(),'getDatesInMonth')
+
+    let timeData = type == 1 ? ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'] : type == 2 ?getDatesInMonth():['周一', '周二', '周三', '周四', '周五', '周六', '周日']
+    return {
+
+        tooltip: {
+            formatter: (item) => {
+                return item.seriesName + " " + item.name + "合格率:" + item.value + '%'
+            },
+            trigger: 'item'
+        },
+
+
+        xAxis: {
+            type: 'category',
+            axisLabel: {
+                fontSize: window.innerHeight * 0.012,
+
+            },
+            data: timeData
+        },
+        yAxis: {
+            type: 'value'
+        },
+        series: data
+    }
+}

+ 296 - 0
src/views/home/index.vue

@@ -0,0 +1,296 @@
+<template>
+  <div class="ele-body">
+    <el-row :gutter="15">
+      <el-col :span="8" style="height: 40%">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span>工厂合格率</span>
+          </div>
+          <v-chart
+            ref="pieRef1"
+            style="height: 100%"
+            :option="factoryQualifiedOption"
+          />
+        </el-card>
+      </el-col>
+      <el-col :span="8" style="height: 40%">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span>班组合格率</span>
+          </div>
+          <v-chart
+            ref="pieRef2"
+            style="height: 100%"
+            :option="teamQualifiedOption"
+          />
+        </el-card>
+      </el-col>
+      <el-col :span="8" style="height: 40%">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span>产线合格率</span>
+          </div>
+          <v-chart
+            ref="pieRef3"
+            style="height: 100%"
+            :option="lineQualifiedOption"
+          />
+        </el-card>
+      </el-col>
+      <!-- <el-col :span="8" style="height: 40%">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span>人员合格率</span>
+          </div>
+          <ele-pro-table
+            ref="table"
+            :columns="userList"
+            :datasource="datasource"
+            :toolbar="false"
+            :needPage="false"
+            height="100%"
+          >
+            
+
+            <template v-slot:qualified="{ row }">
+              <el-progress
+                :text-inside="true"
+                :stroke-width="24"
+                :percentage="80"
+                text-color="#fff"
+                color="#398e4e"
+              ></el-progress>
+            </template>
+          </ele-pro-table>
+        </el-card>
+      </el-col> -->
+      <el-col :span="12" style="margin-top: 15px; height: calc(60% - 15px)">
+        <el-card class="box-card">
+          <div
+            slot="header"
+            class="clearfix"
+            style="display: flex; align-items: center"
+          >
+            <span>产品合格率</span>
+            <div style="margin-left: 15px">
+              <el-radio-group
+                style="margin-right: 15px"
+                v-model="form.timeType"
+                @change="timeTypeChange"
+              >
+                <el-radio-button label="3">本周</el-radio-button>
+                <el-radio-button label="2">本月</el-radio-button>
+                <el-radio-button label="1">本年</el-radio-button>
+              </el-radio-group>
+              自定义时间:
+              <el-date-picker
+                style="width: 140px"
+                v-model="form.finishTime"
+                type="date"
+                value-format="yyyy-MM-dd"
+              ></el-date-picker>
+            </div>
+          </div>
+          <v-chart ref="lineRef" style="height: 100%" :option="lineOption" />
+        </el-card>
+      </el-col>
+      <el-col :span="12" style="margin-top: 15px; height: calc(60% - 15px)">
+        <el-card class="box-card">
+          <div slot="header" class="clearfix">
+            <span>不良类型占比</span>
+          </div>
+          <v-chart ref="pieRef4" style="height: 100%" :option="preOption" />
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+<script>
+import {
+  queryHomePage,
+  queryFactory,
+  queryTeam,
+  queryProductionLine
+} from '@/api/main';
+import dictMixins from '@/mixins/dictMixins';
+import {
+  userList,
+  unacceptedProduct,
+  lineOption,
+  preOption,
+  barOption
+} 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 EleChart from 'ele-admin/packages/ele-chart';
+
+import VChart from 'vue-echarts';
+import { echartsMixin } from '@/utils/echarts-mixin';
+// 按需加载 echarts
+use([
+  CanvasRenderer,
+  BarChart,
+  PieChart,
+  GridComponent,
+  TooltipComponent,
+  LegendComponent,
+  LineChart
+]);
+export default {
+  mixins: [
+    dictMixins,
+    echartsMixin(['pieRef1', 'pieRef2', 'pieRef3', 'pieRef4', 'lineRef'])
+  ],
+  components: { VChart },
+  data() {
+    return {
+      teamQualifiedOption: {},
+      factoryQualifiedOption: {},
+      lineQualifiedOption: {},
+      preOption: {},
+      barOption: {},
+      lineOption: {},
+      form: {
+        finishTime: '',
+        timeType: '1'
+      }
+    };
+  },
+  computed: {
+    userList: () => userList,
+    unacceptedProduct: () => unacceptedProduct
+  },
+
+  created() {
+    this.preOption = preOption([
+      { value: 40, name: '  开线' },
+      { value: 30, name: '  缺口' },
+      { value: 15, name: '  色差' },
+      { value: 10, name: '  损坏' },
+      { value: 5, name: '  污渍' }
+    ]);
+
+    this.queryHomePage();
+    this.queryFactory();
+    this.queryTeam();
+    this.queryProductionLine();
+  },
+  methods: {
+    timeTypeChange() {
+      this.queryHomePage();
+    },
+    async queryFactory() {
+      const data = await queryFactory();
+      this.factoryQualifiedOption = preOption(
+        data.map((item) => {
+          return { value: item.qualificationRate, name: item.factoryName };
+        }),
+        '70%',
+        false,
+        'inside'
+      );
+    },
+    async queryTeam() {
+      const data = await queryTeam();
+      this.teamQualifiedOption = barOption(
+        data.map((item) => {
+          return { value: item.qualificationRate, name: item.teamName };
+        })
+      );
+    },
+    async queryProductionLine() {
+      const data = await queryProductionLine();
+      (this.lineQualifiedOption = barOption(
+        data.map((item) => {
+          return { value: item.qualificationRate, name: item.productionLineName };
+        }),
+          {
+            normal: {
+              barBorderRadius: 30,
+              color: EleChart.graphic.LinearGradient(0, 0, 0, 1, [
+                {
+                  offset: 0,
+                  color: '#00feff'
+                },
+                {
+                  offset: 0.5,
+                  color: '#027eff'
+                },
+                {
+                  offset: 1,
+                  color: '#0286ff'
+                }
+              ])
+            }
+          }
+        ))
+    },
+    async queryHomePage() {
+      const data = await queryHomePage(this.form);
+      let values = [];
+      for (let key in data) {
+        values.push(data[key]);
+      }
+      this.lineOption = lineOption(
+        values.map((item) => {
+          return {
+            name: item.productName,
+            data: item.listQualificationRate,
+            type: 'line'
+          };
+        }),
+        this.form.timeType
+      );
+      // console.log(values)
+    },
+    datasource({ page, where, limit }) {
+      return getList({
+        ...where,
+        pageNum: page,
+        size: limit
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.clearfix {
+  font-size: 0.7vw;
+
+  > span {
+    font-weight: bold;
+  }
+  :deep(.el-radio-button__inner) {
+    font-size: 0.7vw;
+  }
+}
+.ele-body {
+  height: calc(100vh - 126px);
+  > .el-row {
+    height: 100%;
+  }
+  .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%;
+    }
+  }
+}
+</style>
+
+  

+ 1 - 1
src/views/login/index.vue

@@ -191,7 +191,7 @@
       },
       },
       /* 跳转到首页 */
       /* 跳转到首页 */
       goHome () {
       goHome () {
-        this.$router.push(this.$route?.query?.from ?? '/').catch(() => {});
+        this.$router.push(this.$route?.query?.from ?? '/home').catch(() => {});
       },
       },
       /* 更换图形验证码 */
       /* 更换图形验证码 */
       changeCaptcha () {
       changeCaptcha () {