Browse Source

百岗看板--增加项目看板

xiaost 10 months ago
parent
commit
6fe8ed377b
38 changed files with 2124 additions and 42 deletions
  1. 145 0
      src/assets/scss/indexprj.scss
  2. 0 3
      src/components/fqcechart/bottom1Chart/index.vue
  3. 0 3
      src/components/fqcechart/bottom2Chart/index.vue
  4. 1 1
      src/components/fqcechart/bottom3Chart/chart.vue
  5. 0 3
      src/components/fqcechart/bottom3Chart/index.vue
  6. 0 3
      src/components/fqcechart/up11Chart/index.vue
  7. 2 2
      src/components/fqcechart/up1Chart/index.vue
  8. 1 1
      src/components/fqcechart/up2Chart/chart.vue
  9. 0 3
      src/components/fqcechart/up2Chart/index.vue
  10. 0 3
      src/components/iqcechart/bottom1Chart/index.vue
  11. 0 3
      src/components/iqcechart/bottom2Chart/index.vue
  12. 1 1
      src/components/iqcechart/bottom3Chart/chart.vue
  13. 0 3
      src/components/iqcechart/bottom3Chart/index.vue
  14. 0 3
      src/components/iqcechart/up11Chart/index.vue
  15. 0 3
      src/components/iqcechart/up1Chart/index.vue
  16. 1 1
      src/components/iqcechart/up2Chart/chart.vue
  17. 0 3
      src/components/iqcechart/up2Chart/index.vue
  18. 82 0
      src/components/prjechart/bottom1Chart/chart.vue
  19. 75 0
      src/components/prjechart/bottom1Chart/index.vue
  20. 170 0
      src/components/prjechart/bottom2Chart/chart.vue
  21. 37 0
      src/components/prjechart/bottom2Chart/index.vue
  22. 175 0
      src/components/prjechart/bottom3Chart/chart.vue
  23. 43 0
      src/components/prjechart/bottom3Chart/index.vue
  24. 211 0
      src/components/prjechart/bottom4Chart/chart.vue
  25. 37 0
      src/components/prjechart/bottom4Chart/index.vue
  26. 214 0
      src/components/prjechart/bottom5Chart/chart.vue
  27. 37 0
      src/components/prjechart/bottom5Chart/index.vue
  28. 8 0
      src/router/index.js
  29. 1 0
      src/views/FQC/index.vue
  30. 1 0
      src/views/IQC/index.vue
  31. 83 0
      src/views/PRJ/bottom1.vue
  32. 82 0
      src/views/PRJ/bottom2.vue
  33. 94 0
      src/views/PRJ/bottom3.vue
  34. 90 0
      src/views/PRJ/bottom4.vue
  35. 91 0
      src/views/PRJ/bottom5.vue
  36. 232 0
      src/views/PRJ/index.vue
  37. 204 0
      src/views/PRJ/up1.vue
  38. 6 3
      src/views/login.vue

+ 145 - 0
src/assets/scss/indexprj.scss

@@ -0,0 +1,145 @@
+#index {
+  color: #d3d6dd;
+  width: 1920px;
+  height: 1080px;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  transform-origin: left top;
+  overflow: hidden;
+
+  .bg {
+    width: 100%;
+    height: 100%;
+    padding: 16px 16px 0 16px;
+    background-image: url("../../assets/pageBg.png");
+    background-size: cover;
+    background-position: center center;
+  }
+
+  .host-body {
+    .dv-dec-10,
+    .dv-dec-10-s {
+      width: 33.3%;
+      height: 5px;
+    }
+    .dv-dec-10-s {
+      transform: rotateY(180deg);
+    }
+    .dv-dec-8 {
+      width: 200px;
+      height: 50px;
+    }
+    .title {
+      position: relative;
+      width: 500px;
+      text-align: center;
+      background-size: cover;
+      background-repeat: no-repeat;
+
+      .title-text {
+        font-size: 26px;
+        position: absolute;
+        bottom: 0;
+        left: 50%;
+        transform: translate(-50%);
+      }
+
+      .dv-dec-6 {
+        position: absolute;
+        bottom: -30px;
+        left: 50%;
+        width: 250px;
+        height: 8px;
+        transform: translate(-50%);
+      }
+    }
+
+    // 第二行
+    .aside-width {
+      width: 40%;
+    }
+    .react-r-s,
+    .react-l-s {
+      background-color: #1a5cd7;
+    }
+
+    // 平行四边形
+    .react-right {
+      &.react-l-s {
+        text-align: right;
+        width: 500px;
+      }
+      font-size: 18px;
+      width: 300px;
+      line-height: 50px;
+      text-align: center;
+      transform: skewX(-45deg);
+
+      .react-after {
+        position: absolute;
+        right: -25px;
+        top: 0;
+        height: 50px;
+        width: 50px;
+        background-color: #1a5cd7;
+        transform: skewX(45deg);
+      }
+
+      .text {
+        display: inline-block;
+        transform: skewX(45deg);
+      }
+    }
+
+    .react-left {
+      &.react-l-s {
+        width: 500px;
+        text-align: left;
+      }
+      font-size: 20px;
+      width: 300px;
+      height: 50px;
+      line-height: 50px;
+      text-align: center;
+      transform: skewX(45deg);
+      background-color: #0f1325;
+
+      .react-left {
+        position: absolute;
+        left: -25px;
+        top: 0;
+        height: 50px;
+        width: 50px;
+        background-color: #1a5cd7;
+        transform: skewX(-45deg);
+      }
+
+      .text {
+        display: inline-block;
+        transform: skewX(-45deg);
+      }
+    }
+
+    .body-box {
+      margin-top: 1px;
+      display: flex;
+      flex-direction: column;
+      .content-box {
+        /*display: grid;
+        grid-template-columns: 1fr 2.5fr;*/
+      }
+      // 底部数据
+      .bottom-box {
+        // margin-top: 10px;
+        display: grid;
+        grid-template-columns: 1fr 3fr;
+        .rdown{
+          display: grid;
+          grid-template-columns: 2fr 1fr;
+        }
+      }
+    }
+  }
+}

+ 0 - 3
src/components/fqcechart/bottom1Chart/index.vue

@@ -29,9 +29,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.timing);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     refreshdata() {

+ 0 - 3
src/components/fqcechart/bottom2Chart/index.vue

@@ -23,9 +23,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.intervalId);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     // 根据自己的业务情况修改

+ 1 - 1
src/components/fqcechart/bottom3Chart/chart.vue

@@ -67,7 +67,7 @@ export default {
               data: newData.seriesData,
               label: {
                 fontSize: 16,
-                width: 200,
+                width: 210,
                 color:"inherit",
                 formatter: "{b} : ({d}%)"
               },

+ 0 - 3
src/components/fqcechart/bottom3Chart/index.vue

@@ -29,9 +29,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.timing);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     refreshdata() {

+ 0 - 3
src/components/fqcechart/up11Chart/index.vue

@@ -23,9 +23,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.intervalId);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     // 根据自己的业务情况修改

+ 2 - 2
src/components/fqcechart/up1Chart/index.vue

@@ -23,9 +23,9 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.intervalId);
-    this.chart.dispose()
+  /*  this.chart.dispose()
     this.chart.clear()
-    this.chart=null
+    this.chart=null*/
   },
   methods: {
     // 根据自己的业务情况修改

+ 1 - 1
src/components/fqcechart/up2Chart/chart.vue

@@ -67,7 +67,7 @@ export default {
               data: newData.seriesData,
               label: {
                 fontSize: 20,
-                width: 200,
+                width: 210,
                 color:"inherit",
                 formatter: "{b} : ({d}%)"
               },

+ 0 - 3
src/components/fqcechart/up2Chart/index.vue

@@ -29,9 +29,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.timing);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     refreshdata() {

+ 0 - 3
src/components/iqcechart/bottom1Chart/index.vue

@@ -29,9 +29,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.timing);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     refreshdata() {

+ 0 - 3
src/components/iqcechart/bottom2Chart/index.vue

@@ -23,9 +23,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.intervalId);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     // 根据自己的业务情况修改

+ 1 - 1
src/components/iqcechart/bottom3Chart/chart.vue

@@ -67,7 +67,7 @@ export default {
               data: newData.seriesData,
               label: {
                 fontSize: 16,
-                width: 200,
+                width: 210,
                 color:"inherit",
                 formatter: "{b} : ({d}%)",
               },

+ 0 - 3
src/components/iqcechart/bottom3Chart/index.vue

@@ -29,9 +29,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.timing);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     refreshdata() {

+ 0 - 3
src/components/iqcechart/up11Chart/index.vue

@@ -23,9 +23,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.intervalId);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     // 根据自己的业务情况修改

+ 0 - 3
src/components/iqcechart/up1Chart/index.vue

@@ -23,9 +23,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.intervalId);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     // 根据自己的业务情况修改

+ 1 - 1
src/components/iqcechart/up2Chart/chart.vue

@@ -67,7 +67,7 @@ export default {
               data: newData.seriesData,
               label: {
                 fontSize: 20,
-                width: 200,
+                width: 210,
                 color:"inherit",
                 formatter: "{b} : ({d}%)"
               },

+ 0 - 3
src/components/iqcechart/up2Chart/index.vue

@@ -29,9 +29,6 @@ export default {
   },
   beforeDestroy () {
     clearInterval(this.timing);
-    this.chart.dispose()
-    this.chart.clear()
-    this.chart=null
   },
   methods: {
     refreshdata() {

+ 82 - 0
src/components/prjechart/bottom1Chart/chart.vue

@@ -0,0 +1,82 @@
+<template>
+  <div>
+    <Echart
+      :options="options"
+      id="bottom1Chart"
+      height="300px"
+      width="100%"
+    ></Echart>
+  </div>
+</template>
+
+<script>
+import Echart from '@/common/echart'
+export default {
+  data () {
+    return {
+      options: {},
+    };
+  },
+  components: {
+    Echart,
+  },
+  props: {
+    cdata: {
+      type: Object,
+      default: () => ({})
+    },
+  },
+  watch: {
+    cdata: {
+      handler (newData) {
+        this.options = {
+          color: [
+            "#7cd688",
+            "#3bc5b8",
+            "#407cf4",
+            "#fb7293",
+            "#e7bcf3",
+            "#8378ea"
+          ],
+          tooltip: {
+            trigger: "item",
+            formatter: "{b} : {c} ({d}%)"
+          },
+          toolbox: {
+            show: true
+          },
+          calculable: true,
+          legend: {
+            show:true,
+            top: '4%',
+            left: 'center',
+            textStyle: {
+              color: "#fff",
+              fontSize: 18
+            },
+          },
+          series: [
+            {
+              type: "pie",
+              radius: '60%',
+              top: '15%',
+              data: newData.seriesData,
+              label: {
+                fontSize: 18,
+                width: 200,
+                color:"inherit",
+                formatter: "{b} : ({d}%)"
+              },
+            }
+          ]
+        }
+      },
+      immediate: true,
+      deep: true
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 75 - 0
src/components/prjechart/bottom1Chart/index.vue

@@ -0,0 +1,75 @@
+<template>
+  <div>
+    <Chart :cdata="cdata" />
+  </div>
+</template>
+
+<script>
+import Chart from './chart.vue';
+import {mapState} from "vuex";
+
+export default {
+  computed: {
+    ...mapState(['factory']),
+  },
+  data () {
+    return {
+      timing :null,
+      cdata: {
+        seriesData:[]
+      }
+    }
+  },
+  components: {
+    Chart,
+  },
+  mounted () {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing);
+  },
+  methods: {
+    refreshdata() {
+      this.getdata();
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-数据
+      }, 300000);
+    },
+    async getdata() {
+      var caller = 'KB!PRJ!YQINFO';
+      await this.$http.get("kanban/datalist.action?caller="+caller+"&_noc=1&page=1&pageSize=100",
+              {
+                params: {
+                  condition: "1=1"
+                }
+              }).then((result)=>{
+                        let dataList = JSON.parse(result.data.data);
+                        let seriesData0 = new Array();
+                        if(dataList.length>0) {
+                          const element = dataList[0];
+                          let ob = new Object();
+                          ob.value = element.yqlowcount;
+                          ob.name = '延期_低,'+ob.value;
+                          seriesData0.push(ob)
+                          ob = new Object();
+                          ob.value = element.yqmiddlecount;
+                          ob.name = '延期_中,'+ob.value;
+                          seriesData0.push(ob);
+                          ob = new Object();
+                          ob.value = element.yqhighcount;
+                          ob.name = '延期_高,'+ob.value;
+                          seriesData0.push(ob);
+                          this.cdata.seriesData = seriesData0;
+                        }
+                      },(result)=>{
+                        console.error(result)
+                      }
+              );
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 170 - 0
src/components/prjechart/bottom2Chart/chart.vue

@@ -0,0 +1,170 @@
+<template>
+  <div>
+    <Echart
+        :options="options"
+        id="bottom2Chart"
+        height="300px"
+        width="100%"
+        ref="column-board"
+    ></Echart>
+  </div>
+</template>
+
+<script>
+import Echart from '@/common/echart'
+import {mapState} from "vuex";
+export default {
+  computed: {
+    ...mapState(['factory']),
+  },
+  data () {
+    return {
+      timing :null,
+      timing1:null,
+      options:{
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          show:false,
+          textStyle: {
+            fontSize: 18
+          },
+          itemWidth: 29,
+          itemHeight: 19,
+          top:10,
+        },
+        grid: {
+          left: '1%',
+          right: '1%',
+          bottom: '6%',
+          top: 30,
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data:[],
+            axisLabel: {
+              fontSize: 16,
+              rotate: 35,
+              fontWeight: "bold"
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              fontSize: 16
+            }
+          },
+        ],
+        series: [
+          {
+            name: '进行中',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#3dc8c1"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#131212",
+             /* // 修改formatter同时显示两个数值
+              formatter: (params) => {
+                const index = params.dataIndex;
+                const ngValue = this.options.series[0].data[index] || 0;
+                return `OK:${params.value}\nNG:${ngValue}`;
+              }*/
+            },
+          },
+        ],
+        dataZoom: [{
+          type: 'inside', // 滑动条型数据区域缩放组件
+          show: true,
+          xAxisIndex: [0], // 控制 x 轴
+          start: 0,         // 初始起点(0%)
+          end: 50           // 初始终点(50%,即默认显示前半部分)
+        }],
+      },
+    };
+  },
+  components: {
+    Echart, //子组件
+  },
+  props: {
+    cdata: {
+      type: Object,
+      default: () => ({})
+    },
+  },
+
+  mounted() {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+    clearInterval(this.timing1)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata();
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-数据
+      }, 300000);
+      this.interval();
+    },
+    async getdata() {
+      var caller = 'KB!PRJ!MANDATA';
+      await this.$http.get("kanban/datalist.action?caller="+caller+"&_noc=1&page=1&pageSize=100",{
+        params: {
+          condition: "1=1"
+        }
+      }).then((result)=>{
+            let dataList = JSON.parse(result.data.data);
+            let xAxis0 = new Array();
+            let series0 = new Array();
+            for (let index = 0; index < dataList.length; index++) {
+              const element = dataList[index];
+              xAxis0.push(element.v_name);
+              series0.push(element.v_count);
+            }
+           this.options.xAxis[0].data = xAxis0;
+           this.options.series[0].data = series0;
+          },(result)=>{
+            console.error(result)
+          }
+      );
+    },
+    interval() {
+      let currentStart = 0;
+      this.timing1 = setInterval(() => {
+        currentStart += 1;
+        if(this.options.xAxis[0].data.length<8){
+          this.options.dataZoom = [{
+            show: false,
+          }];
+        }else {
+          if (currentStart >= 100) currentStart = 0;
+          this.options.dataZoom = [{
+            type: 'inside', // 滑动条型数据区域缩放组件
+            start: currentStart,
+            end: currentStart + 40 // 每次显示 40% 的数据范围
+          }];
+        }
+      }, 1000);
+    }
+  }
+}
+</script>

+ 37 - 0
src/components/prjechart/bottom2Chart/index.vue

@@ -0,0 +1,37 @@
+<template>
+  <div>
+    <Chart :cdata="cdata" />
+  </div>
+</template>
+
+<script>
+import Chart from './chart.vue'
+export default {
+  data () {
+    return {
+      cdata: {
+        rateData:[
+        ]
+      }
+    };
+  },
+  components: {
+    Chart,
+  },
+  mounted () {
+
+  },
+  beforeDestroy () {
+    clearInterval(this.intervalId);
+  },
+  methods: {
+    // 根据自己的业务情况修改
+    setData () {
+
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 175 - 0
src/components/prjechart/bottom3Chart/chart.vue

@@ -0,0 +1,175 @@
+<template>
+  <div>
+    <Echart
+        :options="options"
+        id="bottom3Chart"
+        height="300px"
+        width="100%"
+        ref="column-board"
+    ></Echart>
+  </div>
+</template>
+
+<script>
+import Echart from '@/common/echart'
+import {mapState} from "vuex";
+export default {
+  computed: {
+    ...mapState(['factory']),
+  },
+  data () {
+    return {
+      timing :null,
+      timing1:null,
+      options:{
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          show:false,
+          textStyle: {
+            fontSize: 18
+          },
+          itemWidth: 29,
+          itemHeight: 19,
+          top:5,
+          data:[],
+        },
+        grid: {
+          left: '1%',
+          right: '1%',
+          bottom: '2%',
+          top: 25,
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data:[],
+            axisLabel: {
+              fontSize: 16,
+              rotate: 35,
+              fontWeight: "bold",
+              width:120,
+              overflow: "truncate"
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            max:100,
+            axisLabel: {
+              fontSize: 16
+            }
+          },
+        ],
+        series: [
+          {
+            name: '',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#42c5b3"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              position:'top',
+              color:'inherit',
+              formatter: '{c}%',
+            },
+          },
+        ],
+        dataZoom: [{
+          type: 'inside', // 滑动条型数据区域缩放组件
+          show: true,
+          xAxisIndex: [0], // 控制 x 轴
+          start: 0,         // 初始起点(0%)
+          end: 60           // 初始终点(50%,即默认显示前半部分)
+        }],
+      },
+    };
+  },
+  components: {
+    Echart, //子组件
+  },
+  props: {
+    currentYear: {
+      type: Number,
+      required: true
+    }
+  },
+  watch: {
+    // 监听 year 变化,触发图表更新
+    currentYear: {
+      handler() {
+        this.getdata();
+      },
+      immediate: true
+    },
+  },
+
+  mounted() {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing);
+    clearInterval(this.timing1)
+  },
+  methods: {
+    refreshdata() {
+      this.interval();
+    },
+    async getdata() {
+      var caller = 'KB!PRJ!RATEOFPROGRESS';
+      await this.$http.get("kanban/datalist.action?caller="+caller+"&_noc=1&page=1&pageSize=100",{
+        params: {
+          condition: "v_year="+this.currentYear
+        }
+      }).then((result)=>{
+            let dataList = JSON.parse(result.data.data);
+            let xAxis0 = new Array();
+            let series0 = new Array();
+            for (let index = 0; index < dataList.length; index++) {
+              const element = dataList[index];
+              xAxis0.push(element.v_name);
+              series0.push(element.v_rate);
+            }
+           this.options.xAxis[0].data = xAxis0;
+           this.options.series[0].data = series0;
+          },(result)=>{
+            console.error(result)
+          }
+      );
+    },
+    interval() {
+      let currentStart = 0;
+      this.timing1 = setInterval(() => {
+        if(this.options.xAxis[0].data.length<21){
+          this.options.dataZoom = [{
+            show: false,
+          }];
+        }else {
+          currentStart += 1;
+          if (currentStart >= 100) currentStart = 0;
+          this.options.dataZoom = [{
+            type: 'inside', // 滑动条型数据区域缩放组件
+            start: currentStart,
+            end: currentStart + 60 // 每次显示 60% 的数据范围
+          }];
+        }
+      }, 1500);
+    }
+  }
+}
+</script>

+ 43 - 0
src/components/prjechart/bottom3Chart/index.vue

@@ -0,0 +1,43 @@
+<template>
+  <div>
+    <Chart :cdata="cdata" v-if="currentYear" :current-year="currentYear"/>
+  </div>
+</template>
+
+<script>
+import Chart from './chart.vue'
+export default {
+  data () {
+    return {
+      cdata: {
+        rateData:[
+        ]
+      }
+    };
+  },
+  components: {
+    Chart,
+  },
+  props: {
+    currentYear: {
+      type: Number,
+      required: true
+    }
+  },
+  mounted () {
+
+  },
+  beforeDestroy () {
+    clearInterval(this.intervalId);
+  },
+  methods: {
+    // 根据自己的业务情况修改
+    setData () {
+
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 211 - 0
src/components/prjechart/bottom4Chart/chart.vue

@@ -0,0 +1,211 @@
+<template>
+  <div>
+    <Echart
+        :options="options"
+        id="bottom4Chart"
+        height="300px"
+        width="100%"
+        ref="column-board"
+    ></Echart>
+  </div>
+</template>
+
+<script>
+import Echart from '@/common/echart'
+import {mapState} from "vuex";
+export default {
+  computed: {
+    ...mapState(['factory']),
+  },
+  data () {
+    return {
+      timing :null,
+      timing1 :null,
+      options:{
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          show:true,
+          textStyle: {
+            fontSize: 18
+          },
+          itemWidth: 29,
+          itemHeight: 19,
+          top:5,
+          data: ['硬件设计师数量', '软件设计师数量', '结构设计师数量']
+        },
+        grid: {
+          left: '1%',
+          right: '1%',
+          bottom: '2%',
+          top: 35,
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data:[],
+            axisLabel: {
+              fontSize: 16,
+              rotate: 35,
+              fontWeight: "bold",
+              width:100,
+              overflow: "truncate"
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              fontSize: 16
+            }
+          },
+        ],
+        series: [
+          {
+            name: '硬件设计师数量',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#1578ff"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#f3e7e7",
+            },
+          },
+          {
+            name: '软件设计师数量',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#d4637a"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#f3e7e7",
+            },
+          },
+          {
+            name: '结构设计师数量',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#9676ff"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#f3e7e7",
+            },
+          },
+        ],
+        dataZoom: [{
+          type: 'inside', // 滑动条型数据区域缩放组件
+          show: true,
+          xAxisIndex: [0], // 控制 x 轴
+          start: 0,         // 初始起点(0%)
+          end: 35           // 初始终点(50%,即默认显示前半部分)
+        }],
+      },
+    };
+  },
+  components: {
+    Echart, //子组件
+  },
+  props: {
+    cdata: {
+      type: Object,
+      default: () => ({})
+    },
+  },
+
+  mounted() {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+    clearInterval(this.timing1)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata();
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-数据
+      }, 300000);
+      this.interval();
+    },
+    async getdata() {
+      var caller = 'KB!PRJ!MANNEED';
+      await this.$http.get("kanban/datalist.action?caller="+caller+"&_noc=1&page=1&pageSize=100",{
+        params: {
+          condition: "1=1"
+        }
+      }).then((result)=>{
+            let dataList = JSON.parse(result.data.data);
+            let xAxis0 = new Array();
+            let series0 = new Array();
+            let series1 = new Array();
+            let series2 = new Array();
+            for (let index = 0; index < dataList.length; index++) {
+              const element = dataList[index];
+              xAxis0.push(element.v_name);
+              series0.push(element.v_yjcount);
+              series1.push(element.v_softcount);
+              series2.push(element.v_jgcount);
+            }
+           this.options.xAxis[0].data = xAxis0;
+           this.options.series[0].data = series0;
+           this.options.series[1].data = series1;
+           this.options.series[2].data = series2;
+          },(result)=>{
+            console.error(result)
+          }
+      );
+    },
+    interval() {
+      let currentStart = 0;
+      this.timing1 = setInterval(() => {
+        if (this.options.xAxis[0].data.length < 16) {
+          this.options.dataZoom = [{
+            show: false,
+          }];
+        } else {
+          currentStart += 1;
+          if (currentStart >= 100) currentStart = 0;
+          this.options.dataZoom = [{
+            type: 'inside', // 滑动条型数据区域缩放组件
+            start: currentStart,
+            end: currentStart + 28 // 每次显示 30% 的数据范围
+          }];
+        }
+      }, 1500);
+    }
+  }
+}
+</script>

+ 37 - 0
src/components/prjechart/bottom4Chart/index.vue

@@ -0,0 +1,37 @@
+<template>
+  <div>
+    <Chart :cdata="cdata" />
+  </div>
+</template>
+
+<script>
+import Chart from './chart.vue'
+export default {
+  data () {
+    return {
+      cdata: {
+        rateData:[
+        ]
+      }
+    };
+  },
+  components: {
+    Chart,
+  },
+  mounted () {
+
+  },
+  beforeDestroy () {
+    clearInterval(this.intervalId);
+  },
+  methods: {
+    // 根据自己的业务情况修改
+    setData () {
+
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 214 - 0
src/components/prjechart/bottom5Chart/chart.vue

@@ -0,0 +1,214 @@
+<template>
+  <div>
+    <Echart
+        :options="options"
+        id="bottom5Chart"
+        height="300px"
+        width="100%"
+        ref="column-board"
+    ></Echart>
+  </div>
+</template>
+
+<script>
+import Echart from '@/common/echart'
+import {mapState} from "vuex";
+export default {
+  computed: {
+    ...mapState(['factory']),
+  },
+  data () {
+    return {
+      timing :null,
+      timing1 :null,
+      options:{
+        tooltip: {
+          trigger: 'axis',
+          axisPointer: {
+            type: 'shadow'
+          }
+        },
+        legend: {
+          show:true,
+          textStyle: {
+            fontSize: 18
+          },
+          itemWidth: 25,
+          itemHeight: 15,
+          top:5,
+          data: ['硬件', '软件', '结构']
+        },
+        grid: {
+          left: '1%',
+          right: '1%',
+          bottom: '3%',
+          top: 40,
+          containLabel: true
+        },
+        xAxis: [
+          {
+            type: 'category',
+            data:[],
+            axisLabel: {
+              fontSize: 16,
+              rotate: 35,
+              fontWeight: "bold",
+              width:50,
+              overflow: "truncate"
+            }
+          }
+        ],
+        yAxis: [
+          {
+            type: 'value',
+            axisLabel: {
+              fontSize: 16
+            }
+          },
+        ],
+        series: [
+          {
+            name: '硬件',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#1578ff"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#f3e7e7",
+              position:'top'
+            },
+          },
+          {
+            name: '软件',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#d4637a"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#f3e7e7",
+              position:'top'
+            },
+          },
+          {
+            name: '结构',
+            type: 'bar',
+            barWidth: 20,
+            stack: 'Ad',
+            emphasis: {
+              focus: 'series'
+            },
+            data:[],
+            itemStyle: {
+              color: "#9676ff"
+            },
+            label: {
+              show: true,
+              fontSize:14,
+              fontWeight: "bold",
+              color:"#f3e7e7",
+              position:'top'
+            },
+          },
+        ],
+        dataZoom: [{
+          type: 'inside', // 滑动条型数据区域缩放组件
+          show: true,
+          xAxisIndex: [0], // 控制 x 轴
+          start: 0,         // 初始起点(0%)
+          end: 50           // 初始终点(50%,即默认显示前半部分)
+        }],
+      },
+    };
+  },
+  components: {
+    Echart, //子组件
+  },
+  props: {
+    cdata: {
+      type: Object,
+      default: () => ({})
+    },
+  },
+
+  mounted() {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+    clearInterval(this.timing1)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata();
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-数据
+      }, 300000);
+      this.interval()
+    },
+    async getdata() {
+      var caller = 'KB!PRJ!MANONHAND';
+      await this.$http.get("kanban/datalist.action?caller="+caller+"&_noc=1&page=1&pageSize=100",{
+        params: {
+          condition: "1=1"
+        }
+      }).then((result)=>{
+            let dataList = JSON.parse(result.data.data);
+            let xAxis0 = new Array();
+            let series0 = new Array();
+            let series1 = new Array();
+            let series2 = new Array();
+            for (let index = 0; index < dataList.length; index++) {
+              const element = dataList[index];
+              xAxis0.push(element.v_name);
+              series0.push(element.v_yjcount);
+              series1.push(element.v_softcount);
+              series2.push(element.v_jgcount);
+            }
+           this.options.xAxis[0].data = xAxis0;
+           this.options.series[0].data = series0;
+           this.options.series[1].data = series1;
+           this.options.series[2].data = series2;
+          },(result)=>{
+            console.error(result)
+          }
+      );
+    },
+    interval() {
+      let currentStart = 0;
+      this.timing1 = setInterval(() => {
+        if (this.options.xAxis[0].data.length < 8) {
+          this.options.dataZoom = [{
+            show: false,
+          }];
+        } else{
+          currentStart += 1;
+          if (currentStart >= 100) currentStart = 0;
+          this.options.dataZoom = [{
+            type: 'inside', // 滑动条型数据区域缩放组件
+            start: currentStart,
+            end: currentStart + 30 // 每次显示 30% 的数据范围
+          }];
+        }
+      }, 1500);
+    }
+  }
+}
+</script>

+ 37 - 0
src/components/prjechart/bottom5Chart/index.vue

@@ -0,0 +1,37 @@
+<template>
+  <div>
+    <Chart :cdata="cdata" />
+  </div>
+</template>
+
+<script>
+import Chart from './chart.vue'
+export default {
+  data () {
+    return {
+      cdata: {
+        rateData:[
+        ]
+      }
+    };
+  },
+  components: {
+    Chart,
+  },
+  mounted () {
+
+  },
+  beforeDestroy () {
+    clearInterval(this.intervalId);
+  },
+  methods: {
+    // 根据自己的业务情况修改
+    setData () {
+
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 8 - 0
src/router/index.js

@@ -34,6 +34,14 @@ const routes = [{
     title: "FQC",
     requireAuth: true // 标识该路由是否需要登录
   }
+},{
+  path: '/PRJ',
+  name: 'PRJ',
+  component: () => import('../views/./PRJ/index.vue'),
+  meta: {
+    title: "项目",
+    requireAuth: true // 标识该路由是否需要登录
+  }
 }]
 const router = new VueRouter({
   routes

+ 1 - 0
src/views/FQC/index.vue

@@ -46,6 +46,7 @@
                 </span>
                 <el-dropdown-menu slot="dropdown">
                   <el-dropdown-item class="dropdownitem"><router-link to="IQC">IQC</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="PRJ">项目</router-link></el-dropdown-item>
                 </el-dropdown-menu>
               </el-dropdown>
               <span class="text">&nbsp;&nbsp;&nbsp;&nbsp;</span>

+ 1 - 0
src/views/IQC/index.vue

@@ -46,6 +46,7 @@
                 </span>
                 <el-dropdown-menu slot="dropdown">
                   <el-dropdown-item class="dropdownitem"><router-link to="FQC">FQC</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="PRJ">项目</router-link></el-dropdown-item>
                 </el-dropdown-menu>
               </el-dropdown>
               <span class="text">&nbsp;&nbsp;&nbsp;&nbsp;</span>

+ 83 - 0
src/views/PRJ/bottom1.vue

@@ -0,0 +1,83 @@
+<template>
+  <div id="prj-bottom1">
+    <div class="bg-color-black">
+      <div class="d-flex">
+        <span>
+          <icon name="align-left" class="text-icon"></icon>
+        </span>
+        <span class="fs-xxl mx-2 fw-b">延期情况</span>
+      </div>
+      <div class="body-box pt-2">
+        <Bottom1Chart />
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<script>
+import Bottom1Chart from "_c/prjechart/bottom1Chart/index.vue";
+
+export default {
+  data() {
+    return {
+      timing: null,
+    }
+  },
+  components: {Bottom1Chart},
+  mounted() {
+    //this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata(); //获取数据
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-主题词
+      }, 10000);
+    },
+
+    async getdata() {
+
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 350px;
+$box-width: 100%;
+#prj-bottom1 {
+  padding: 13px;
+  // padding: 5px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    padding: 5px;
+    height: $box-height - 25px;
+    //  width: width - 5px;
+    border-radius: 10px;
+  }
+
+  .text {
+    color: #c3cbde;
+    font-size: 25px;
+  }
+
+  .body-box {
+    width: $box-width;
+    overflow: hidden;
+
+    .dv-scroll-board {
+      height: $box-height - 65px;
+    }
+    ::v-deep  .dv-scroll-board .header {
+      font-size: 20px;
+    }
+  }
+
+}
+</style>

+ 82 - 0
src/views/PRJ/bottom2.vue

@@ -0,0 +1,82 @@
+<template>
+  <div id="prj-bottom2">
+    <div class="bg-color-black">
+      <div class="d-flex">
+        <span>
+          <icon name="align-left" class="text-icon"></icon>
+        </span>
+        <span class="fs-xxl mx-2 fw-b">项目研发负责人-正在进行中</span>
+      </div>
+      <div class="body-box pt-2">
+        <Bottom2Chart />
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<script>
+import Bottom2Chart from "_c/prjechart/bottom2Chart/index.vue";
+export default {
+  data() {
+    return {
+      timing: null,
+    }
+  },
+  components: {Bottom2Chart},
+  mounted() {
+    //this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata(); //获取数据
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-主题词
+      }, 10000);
+    },
+
+    async getdata() {
+
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 350px;
+$box-width: 100%;
+#prj-bottom2 {
+  padding: 13px;
+  // padding: 5px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    padding: 5px;
+    height: $box-height - 25px;
+    //  width: width - 5px;
+    border-radius: 10px;
+  }
+
+  .text {
+    color: #c3cbde;
+    font-size: 25px;
+  }
+
+  .body-box {
+    width: $box-width;
+    overflow: hidden;
+
+    .dv-scroll-board {
+      height: $box-height - 65px;
+    }
+    ::v-deep  .dv-scroll-board .header {
+      font-size: 20px;
+    }
+  }
+
+}
+</style>

+ 94 - 0
src/views/PRJ/bottom3.vue

@@ -0,0 +1,94 @@
+<template>
+  <div id="prj-bottom3">
+    <div class="bg-color-black">
+      <div class="d-flex">
+        <span>
+          <icon name="align-left" class="text-icon"></icon>
+        </span>
+        <span class="fs-xxl mx-2 fw-b">项目进度表(按任务数)-- {{currentYear}}</span>
+      </div>
+      <div class="body-box pt-2">
+        <Bottom3Chart v-if="currentYear" :current-year="currentYear"/>
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<script>
+import Bottom3Chart from "_c/prjechart/bottom3Chart/index.vue";
+
+export default {
+  data() {
+    return {
+      yeardata:[],
+      timing: null,
+      currentIndex: 0
+    }
+  },
+  computed: {
+    // 根据索引计算当前年份
+    currentYear() {
+      return this.yeardata[this.currentIndex];
+    }
+  },
+  components: {Bottom3Chart},
+  mounted() {
+    this.yeardata.push(new Date().getFullYear());
+    this.yeardata.push(new Date().getFullYear()-1);
+    this.yeardata.push(new Date().getFullYear()-2);
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.timing = setInterval(() => {
+        this.nextYear(); //获取-主题词
+      }, 15000);
+    },
+
+    // 切换到下一个年份
+    nextYear() {
+      this.currentIndex = (this.currentIndex + 1) % this.yeardata.length;
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 350px;
+$box-width: 100%;
+#prj-bottom3 {
+  padding: 13px;
+  // padding: 5px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    padding: 5px;
+    height: $box-height - 25px;
+    //  width: width - 5px;
+    border-radius: 10px;
+  }
+
+  .text {
+    color: #c3cbde;
+    font-size: 25px;
+  }
+
+  .body-box {
+    width: $box-width;
+    overflow: hidden;
+
+    .dv-scroll-board {
+      height: $box-height - 65px;
+    }
+    ::v-deep  .dv-scroll-board .header {
+      font-size: 20px;
+    }
+  }
+
+}
+</style>

+ 90 - 0
src/views/PRJ/bottom4.vue

@@ -0,0 +1,90 @@
+<template>
+  <div id="prj-bottom4">
+    <div class="bg-color-black">
+      <div class="d-flex">
+        <span>
+          <icon name="align-left" class="text-icon"></icon>
+        </span>
+        <span class="fs-xxl mx-2 fw-b">项目维度-设计师需求</span>
+      </div>
+      <div class="body-box pt-2">
+        <Bottom4Chart />
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<script>
+import Bottom4Chart from "_c/prjechart/bottom4Chart/index.vue";
+
+export default {
+  data() {
+    return {
+      timing: null,
+    }
+  },
+  components: {Bottom4Chart},
+  mounted() {
+    //this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata(); //获取数据
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-主题词
+      }, 10000);
+    },
+
+    async setdata() {
+      await this.$http.get("kanban/datalist.action?caller=KB!FQC!MONTHDATA&_noc=1&page=1&pageSize=100&condition=1=1")
+          .then((result)=>{
+                let dataList = JSON.parse(result.data.data);
+                 this.firstdata = dataList[0];
+              },(result)=>{
+                console.error(result)
+              }
+          );
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 350px;
+$box-width: 100%;
+#prj-bottom4 {
+  padding: 13px;
+  // padding: 5px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    padding: 5px;
+    height: $box-height - 25px;
+    //  width: width - 5px;
+    border-radius: 10px;
+  }
+
+  .text {
+    color: #c3cbde;
+    font-size: 25px;
+  }
+
+  .body-box {
+    width: $box-width;
+    overflow: hidden;
+
+    .dv-scroll-board {
+      height: $box-height - 65px;
+    }
+    ::v-deep  .dv-scroll-board .header {
+      font-size: 20px;
+    }
+  }
+
+}
+</style>

+ 91 - 0
src/views/PRJ/bottom5.vue

@@ -0,0 +1,91 @@
+<template>
+  <div id="prj-bottom5">
+    <div class="bg-color-black">
+      <div class="d-flex">
+        <span>
+          <icon name="align-left" class="text-icon"></icon>
+        </span>
+        <span class="fs-xxl mx-2 fw-b">设计师在手项目</span>
+      </div>
+      <div class="body-box pt-2">
+        <Bottom5Chart />
+      </div>
+    </div>
+  </div>
+</template>
+
+
+<script>
+import Bottom5Chart from "_c/prjechart/bottom5Chart/index.vue";
+
+export default {
+  data() {
+    return {
+      prjcount: 0, //项目数
+      timing: null,
+    }
+  },
+  components: {Bottom5Chart},
+  mounted() {
+    //this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata(); //获取数据
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-主题词
+      }, 10000);
+    },
+
+    async setdata() {
+      await this.$http.get("kanban/datalist.action?caller=KB!FQC!MONTHDATA&_noc=1&page=1&pageSize=100&condition=1=1")
+          .then((result)=>{
+                let dataList = JSON.parse(result.data.data);
+                 this.firstdata = dataList[0];
+              },(result)=>{
+                console.error(result)
+              }
+          );
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 350px;
+$box-width: 100%;
+#prj-bottom5 {
+  padding: 13px;
+  // padding: 5px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    padding: 5px;
+    height: $box-height - 25px;
+    //  width: width - 5px;
+    border-radius: 10px;
+  }
+
+  .text {
+    color: #c3cbde;
+    font-size: 25px;
+  }
+
+  .body-box {
+    width: $box-width;
+    overflow: hidden;
+
+    .dv-scroll-board {
+      height: $box-height - 65px;
+    }
+    ::v-deep  .dv-scroll-board .header {
+      font-size: 20px;
+    }
+  }
+
+}
+</style>

+ 232 - 0
src/views/PRJ/index.vue

@@ -0,0 +1,232 @@
+<template>
+  <div id="index" ref="appRef">
+    <div class="bg">
+      <dv-loading v-if="loading">Loading...</dv-loading>
+      <div v-else class="host-body">
+        <div class="d-flex jc-center">
+          <dv-decoration-10 class="dv-dec-10" />
+          <div class="d-flex jc-center">
+            <dv-decoration-8 class="dv-dec-8" />
+            <div class="title">
+              <span class="title-text">百岗-MES可视化平台</span>
+              <dv-decoration-6
+                class="dv-dec-6"
+                :reverse="true"
+                :color="['#50e3c2', '#67a1e5']"
+              />
+            </div>
+            <dv-decoration-8
+              class="dv-dec-8"
+              :reverse="true"
+              :color="decorationColor"
+            />
+          </div>
+          <dv-decoration-10 class="dv-dec-10-s" />
+        </div>
+
+        <!-- 第二行 -->
+        <div class="d-flex jc-between px-2">
+          <div class="d-flex aside-width">
+            <div class="react-left ml-4 react-l-s bg-color-blue">
+              <span class="react-left"></span>
+              <span class="text fw-b" style="font-size:24px;">项目数据看板</span>
+            </div>
+          </div>
+          <div class="d-flex aside-width">
+            <div class="react-right bg-color-r mr-3">
+              <el-button type="text" class="text" style="width:50% ;font-size: 22px;" @click="fullScreen" ref="fullScreen"
+                         v-show=!isFullScreen >全屏</el-button>
+              <el-button type="text" class="text" style="width:50% ;font-size: 22px;" @click="exitFullScreen" ref="exitFullScreen" v-show=isFullScreen>退出全屏</el-button>
+            </div>
+            <div class="react-right mr-4 react-l-s" style="width: 900px">
+              <span class="react-after"></span>
+              <el-dropdown class="dropdown">
+                <span class="el-dropdown-link" ref="echarType">
+                  项目<i class="el-icon-arrow-down el-icon--right"></i>&nbsp;&nbsp;&nbsp;&nbsp;
+                </span>
+                <el-dropdown-menu slot="dropdown">
+                  <el-dropdown-item class="dropdownitem"><router-link to="IQC">IQC</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="FQC">FQC</router-link></el-dropdown-item>
+                </el-dropdown-menu>
+              </el-dropdown>
+              <span class="text">&nbsp;&nbsp;&nbsp;&nbsp;</span>
+              <span class="text">{{ dateYear }} {{ dateWeek }} {{ dateDay }}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="body-box">
+        <!--上面 -->
+          <div class="content-box">
+              <div>
+                  <up1/>
+              </div>
+          </div>
+      <!--  下面-->
+          <div class="bottom-box">
+            <div class = "bleft">   <!--左-->
+              <div>  <!--左上-->
+                <dv-border-box-12>
+                  <bottom1 />
+                </dv-border-box-12>
+              </div>
+              <div> <!--左下-->
+                <dv-border-box-12>
+                  <bottom2 />
+                </dv-border-box-12>
+              </div>
+            </div>
+            <div class = "bright"> <!--右-->
+              <div> <!--右上-->
+                <dv-border-box-12>
+                  <bottom3 />
+                </dv-border-box-12>
+              </div>
+              <div class = "rdown"> <!--右下-->
+                <div> <!--左-->
+                  <dv-border-box-12>
+                    <bottom4 />
+                  </dv-border-box-12>
+               </div>
+                <div> <!--右-->
+                  <dv-border-box-12>
+                    <bottom5 />
+                  </dv-border-box-12>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import drawMixin from "../../utils/drawMixin";
+import  common  from '../../utils/common';
+import {formatTime} from '../../utils/index.js'
+import up1 from './up1.vue'
+import bottom1 from './bottom1.vue'
+import bottom2 from './bottom2.vue'
+import bottom3 from './bottom3.vue'
+import bottom4 from './bottom4.vue'
+import bottom5 from './bottom5.vue'
+import {mapMutations, mapState} from "vuex"
+
+export default {
+  mixins: [ drawMixin,common ],
+  computed: {
+    ...mapState(['user','factoryoptions','factory']),
+  },
+  data() {
+    return {
+      timing: null,
+      timing2: null,
+      timing3: null,
+      loading: true,
+      dateDay: null,
+      dateYear: null,
+      dateWeek: null,
+      weekday: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
+      decorationColor: ['#568aea', '#000000'],
+    }
+  },
+  components: {
+    up1,
+    bottom1,
+    bottom2,
+    bottom3,
+    bottom4,
+    bottom5
+  },
+  created() {
+     this.isFullScreen = document.fullscreenElement;
+  },
+  mounted() {
+    this.timeFn();
+    this.cancelLoading();
+   // this.autoFullScreen();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing);
+    clearInterval(this.timing2);
+  },
+  methods: {
+    ...mapMutations(['setFactory']),
+    timeFn() {
+      this.timing = setInterval(() => {
+        this.dateDay = formatTime(new Date(), 'HH: mm: ss')
+        this.dateYear = formatTime(new Date(), 'yyyy-MM-dd')
+        this.dateWeek = this.weekday[new Date().getDay()]
+      }, 1000);
+    },
+    cancelLoading() {
+      setTimeout(() => {
+        this.loading = false
+      }, 1000)
+    },
+    autoFullScreen(){
+      if (!this.isFullScreen) {
+        setTimeout(() => {
+          this.$showMsgBox({
+            caption: "提示",
+            msg: '是否全屏展示?',
+            callback: (data) => {
+              if (data == "yes") {
+                this.fullScreen();
+              }
+            }
+          })
+        }, 3000)
+      }
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../assets/scss/indexprj.scss';
+.dropdown{
+  font-size: 22px;
+  font-weight: bold;
+  color: #f6f7fa;
+  transform: skewX(45deg);
+  ::v-deep .el-select-dropdown {
+    /* // 若不将下拉框的背景颜色设置为:transparent,那么做不出来半透明的效果;
+    // 因为其最终的显示为:下拉框有一个背景颜色且下拉框的字体有一个背景颜色,重叠后的效果展示; */
+    border: 1px solid #0f1325;
+    background: #04308D !important;
+  }
+
+  ::v-deep .el-input__inner {
+    background-color: #1a5cd7;
+    color: #fff;
+    border: 1px solid #1a5cd7;
+    font-size: 22px;
+  }
+
+  .el-select-dropdown__item {
+    color: #fff;
+    background-color: #0f1325;
+  }
+  ::v-deep .el-select-dropdown {
+    background-color: transparent;
+    border: 1px solid #0f1325;
+  }
+  ::v-deep.el-select-dropdown__list {
+    padding: 0;
+  }
+  ::v-deep.el-popper[x-placement^="bottom"] {
+    margin-top: 0px;
+  }
+  ::v-deep.el-popper .popper__arrow,
+  ::v-deep.el-popper .popper__arrow::after {
+    display: none;
+  }
+  .el-select-dropdown__item:hover {
+    background-color: rgba(0, 225, 219, 0.690196078431373);
+  }
+}
+
+</style>

+ 204 - 0
src/views/PRJ/up1.vue

@@ -0,0 +1,204 @@
+<template>
+  <div id="prj-up1">
+      <!--项目数  进行中 开发阶段--功能样机  验证阶段、试产阶段  未开始
+       未延期  延期_高 延期_中 延期_低
+       项目总数:取已审核项目申请单;进行中:已启动,未延期:正在进行中的任务延期了算延期;低:一周,中:两周,高:四周,
+       -->
+      <div class="body-box">
+        <div> <!--左侧-->
+          <dv-border-box-12 class="pd">
+              <div class="pt-1">
+                 <span class="fs-xxl mx-2 fw-b">项目数</span>
+                 <div class ="datat fw-b colorBlue">
+                    {{countdata.prjcount}}
+                 </div>
+            </div>
+          </dv-border-box-12>
+        </div>
+        <div class ="right-container"> <!--右侧-->
+          <div class = "ditem up"> <!--上面部分-->
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                  <span class="fs-xxl mx-2 fw-b">进行中</span>
+                  <div class ="datat fw-b colorGrass">
+                    {{countdata.doingcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                  <span class="fs-xxl  mx-2 fw-b">开发阶段--功能样机</span>
+                  <div class ="datat fw-b colorGrass">
+                    {{countdata.kfcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                  <span class="fs-xxl mx-2 fw-b">验证阶段、试产阶段</span>
+                  <div class ="datat fw-b colorGrass">
+                    {{countdata.yzcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                  <span class="fs-xxl mx-2 fw-b">未开始</span>
+                  <div class ="datat fw-b colorGrass">
+                    {{countdata.unstartcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+          </div>
+
+          <div class = "ditem down"> <!--下面部分-->
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                 <span class="fs-xxl mx-2 fw-b">未延期</span>
+                  <div class ="datat fw-b colorGrass">
+                    {{countdata.unyqcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                  <span class="fs-xxl mx-2 fw-b">延期_高</span>
+                  <div class ="datat fw-b colorRed">
+                    {{countdata.yqhighcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                 <span class="fs-xxl mx-2 fw-b">延期_中</span>
+                  <div class ="datat fw-b colorRed">
+                    {{countdata.yqmiddlecount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 class="pd">
+                <div class="pt-1">
+                  <span class="fs-xxl mx-2 fw-b">延期_低</span>
+                  <div class ="datat fw-b colorRemind">
+                    {{countdata.yqlowcount}}
+                  </div>
+                </div>
+              </dv-border-box-12>
+            </div>
+          </div>
+        </div>
+
+      </div>
+  </div>
+</template>
+
+
+<script>
+export default {
+  data() {
+    return {
+      countdata: {
+        prjcount: 0, //项目数
+        doingcount: 0,//进行中
+        kfcount: 0, //开发阶段
+        yzcount: 0, //验证阶段
+        unstartcount: 0, //未开始
+        unyqcount: 0, //未延期
+        yqhighcount: 0, //延期高
+        yqmiddlecount: 0, //延期中
+        yqlowcount: 0,//延期低
+      },
+      timing: null,
+    }
+  },
+  components: {},
+  mounted() {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata(); //获取数据
+      this.timing = setInterval(() => {
+        this.getdata(); //获取-主题词
+      }, 300000); //5分钟刷新一次
+    },
+
+    async getdata() {
+      var caller = 'KB!PRJINFO';
+      var cond = "1=1";
+      /*var cond = "v_year="+this.tyear;*/
+      /*this.countdata.prjcount = 0;
+      this.countdata.doingcount = 0;
+      this.countdata.kfcount = 0;*/
+      await this.$http.get("kanban/datalist.action?caller="+caller+"&_noc=1&page=1&pageSize=100", {
+        params: {
+          condition: cond
+        }
+      }).then((result)=>{
+                let dataList = JSON.parse(result.data.data);
+                if(dataList.length>0) {
+                  this.countdata = dataList[0];
+                }
+              },(result)=>{
+                console.error(result)
+              }
+          );
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 250px;
+$box-width: 100%;
+#prj-up1 {
+  height: $box-height;
+  width: $box-width;
+ // border-radius: 5px;
+  .bg-color-black {
+    padding: 5px;
+    height: $box-height - 25px;
+    //  width: width - 5px;
+    border-radius: 10px;
+  }
+  .body-box {
+    width: $box-width;
+    display: grid;
+    .pd {
+      padding: 13px;
+    }
+    grid-template-columns: 1fr 3fr;
+    .ditem{
+      display: grid;
+      grid-template-columns: 3fr 2fr 2fr 2fr;
+      height: 125px;
+    }
+    .datat{
+      font-size: 55px;
+      position: absolute;
+      top: 58%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+    }
+  }
+
+}
+</style>

+ 6 - 3
src/views/login.vue

@@ -60,9 +60,10 @@
                 },
                 options: [],
                 typeoptions:[
-                    //IQC,FQC,车间看板,仓库看板
+                    //IQC,FQC,项目看板
                     {label: 'IQC', value: 'IQC'},
-                    {label: 'FQC', value: 'FQC'}
+                    {label: 'FQC', value: 'FQC'},
+                    {label: '项目', value: 'PRJ'}
                 ],
             }
         },
@@ -118,7 +119,9 @@
                                        this.$router.push({path: this.redirect || '/IQC'});
                                     }else if(this.loginForm.type =='FQC') {
                                       this.$router.push({path: this.redirect || '/FQC'});
-                                    }
+                                    }else if(this.loginForm.type == 'PRJ'){
+                                      this.$router.push({path: this.redirect || '/PRJ'});
+                                   }
                                 }else{
                                     this.$message.error(res.reason);
                                 }