Преглед на файлове

柯赛增加财务看板

xiaost преди 1 месец
родител
ревизия
d25350a7cb

+ 162 - 0
src/assets/scss/indexfinance.scss

@@ -0,0 +1,162 @@
+#index {
+  color: #d3d6dd;
+  width: 1920px;
+  height: 1080px;
+  position:fixed;
+  top:0;
+  left:0;
+  bottom:0;
+  right:0;
+  /*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/bg3.jpg");
+    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;
+        width: 400px;
+        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: #1a5cd7;
+
+      .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: 10px;
+      display: grid;
+      grid-template-columns: 1.5fr 1fr;
+      .left-box {
+        display: flex;
+        flex-direction: column;
+        .ledown-box{
+          display: grid;
+          grid-template-columns: 2fr 1fr;
+        }
+      }
+
+      //下方区域的布局
+     /* .content-box {
+        display: grid;
+        grid-template-columns: 1.5fr 1.3fr 1.2fr;
+      }*/
+     /* .content-box {
+        display: grid;
+        grid-template-columns:  1.2fr 1.1fr 1fr;
+      }
+
+      // 底部数据
+      .bottom-box {
+       // margin-top: 10px;
+        display: grid;
+        grid-template-columns: 1fr ;
+      }*/
+    }
+  }
+}

+ 8 - 0
src/router/index.js

@@ -75,6 +75,14 @@ const routes = [{
       title: "各车间进度",
       requireAuth: true // 标识该路由是否需要登录
     }
+  },{
+    path: '/finance',
+    name: 'finance',
+    component: () => import('../views/finance/index.vue'),
+    meta: {
+      title: "财务",
+      requireAuth: true // 标识该路由是否需要登录
+    }
   }]
 const router = new VueRouter({
   routes

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

@@ -50,6 +50,7 @@
                   <el-dropdown-item class="dropdownitem"><router-link to="quality">品质看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="warehouse">仓库看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="makeprocess">生产进度看板</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="finance">财务</router-link></el-dropdown-item>
                  </el-dropdown-menu>
               </el-dropdown>
               <span class="text">&nbsp;&nbsp;&nbsp;&nbsp;</span>

+ 3 - 3
src/views/compare/right-bottom.vue

@@ -25,7 +25,7 @@ export default {
       config: {
         header: ['周次','达成率最高车间', '达成率%','良率最高车间','良品率%'],
         data: [],
-        rowNum: 20,
+        rowNum: 10,
         headerHeight: 35,
         headerBGC: 'rgba(15,19,37,0.1)',
         oddRowBGC: 'rgba(15,19,37,0.1)',
@@ -100,7 +100,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-$box-height: 450px;
+$box-height: 475px;
 $box-width: 100%;
 #right-bottom {
   padding: 13px;
@@ -140,7 +140,7 @@ $box-width: 100%;
     margin-top: 5px;
 
     .scroll-board {
-      height: 920px;
+      height: 425px;
       border-radius: 10px;
 
       ::v-deep .header {

+ 3 - 3
src/views/compare/right.vue

@@ -25,7 +25,7 @@ export default {
       config: {
         header: ['车间', '计划数', '完成数', '达成率%','不良数','良品率%'],
         data: [],
-        rowNum: 20,
+        rowNum: 10,
         headerHeight: 35,
         headerBGC: 'rgba(15,19,37,0.1)',
         oddRowBGC: 'rgba(15,19,37,0.1)',
@@ -102,7 +102,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-$box-height: 500px;
+$box-height: 475px;
 $box-width: 100%;
 #right {
   padding: 13px;
@@ -142,7 +142,7 @@ $box-width: 100%;
     margin-top: 5px;
 
     .scroll-board {
-      height: 920px;
+      height: 425px;
       border-radius: 10px;
 
       ::v-deep .header {

+ 227 - 0
src/views/finance/index.vue

@@ -0,0 +1,227 @@
+<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" :color="decorationColor" />
+            <div class="title">
+              <span class="title-text">COSTEC-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: 21px;" @click="fullScreen" ref="fullScreen"
+                         v-show=!isFullScreen >全屏</el-button>
+              <el-button type="text" class="text" style="width:50% ;font-size: 21px;" @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="total">总看板</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="prodline">车间看板</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="quality">品质看板</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="warehouse">仓库看板</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="makeprocess">生产进度看板</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="compare">各车间进度</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="left-box">
+            <div>
+              <dv-border-box-12 >
+                <leftup1/>
+              </dv-border-box-12>
+            </div>
+            <div class="ledown-box">
+              <div>
+              <dv-border-box-12 >
+                <leftdown1/>
+              </dv-border-box-12>
+              </div>
+              <div>
+              <dv-border-box-12 >
+                <leftdown2/>
+              </dv-border-box-12>
+              </div>
+            </div>
+          </div>
+          <div class="right-box">
+            <div>
+              <dv-border-box-12 >
+                <right/>
+              </dv-border-box-12>
+            </div>
+            <div>
+              <dv-border-box-12 >
+                <right_bottom/>
+              </dv-border-box-12>
+            </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 leftup1 from './left-up1.vue'
+import leftdown1 from './left-down1.vue'
+import leftdown2 from './left-down2.vue'
+import right from './right.vue'
+import right_bottom from './right-bottom.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: {
+    right,
+    right_bottom,
+    leftdown1,
+    leftup1,
+    leftdown2
+  },
+  created() {
+     this.isFullScreen = document.fullscreenElement;
+  },
+  mounted() {
+    this.timeFn();
+    this.cancelLoading();
+    this.$nextTick(() => {
+        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) {
+        this.fullScreen();
+        /*setTimeout(() => {
+          this.$showMsgBox({
+            caption: "提示",
+            msg: '是否全屏展示?',
+            callback: (data) => {
+              if (data == "yes") {
+                this.fullScreen();
+              }
+            }
+          })
+        }, 3000)*/
+      }
+    },
+
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../assets/scss/indexfinance.scss';
+.dropdown{
+  font-size: 22px;
+  color: #f7f8fa;
+  transform: skewX(45deg);
+  ::v-deep .el-select-dropdown {
+    /* // 若不将下拉框的背景颜色设置为:transparent,那么做不出来半透明的效果;
+    // 因为其最终的显示为:下拉框有一个背景颜色且下拉框的字体有一个背景颜色,重叠后的效果展示; */
+    border: 1px solid #0f1325;
+    background: #04308D !important;
+  }
+
+  ::v-deep .el-input__inner {
+    background-color: #0f1325;
+    color: #fff;
+    border: 1px solid #0f1325;
+  }
+
+  .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>

+ 153 - 0
src/views/finance/left-down1.vue

@@ -0,0 +1,153 @@
+<template>
+  <div id="fleft-bottom1" >
+    <div class="bg-color-black">
+      <div class="plan-header">
+        <div class="d-flex pt-1 pl-2 jc-center">
+          <span class="text mx-2 fw-b">每周车间达成率</span>
+        </div>
+      </div>
+      <div class="plan-body">
+        <dv-scroll-board
+            :config="config"
+            ref="scrollBoard"
+            class="scroll-board"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ProductionPlan',
+  data() {
+    return {
+      config: {
+        header: ['员工','部门名称', '月销售目标','月销售额','月达成率%','年销售目标','年销售额','年达成率%'],
+        data: [],
+        rowNum: 10,
+        headerHeight: 30,
+        headerBGC: 'rgba(15,19,37,0.1)',
+        oddRowBGC: 'rgba(15,19,37,0.1)',
+        evenRowBGC: 'rgba(23,28,51,0.1)',
+        columnWidth: [80, 100, 90,100,90,90,90,90],
+        align: ['center', 'center', 'center', 'center','center','center','center','center']
+      },
+      refreshInterval: null,
+      apiCaller: 'KB!FIN!PROCESS_WEEK'
+    }
+  },
+  mounted() {
+    this.initDataRefresh()
+  },
+  beforeDestroy() {
+    this.clearRefreshInterval()
+  },
+  methods: {
+    initDataRefresh() {
+      this.fetchData()
+      this.refreshInterval = setInterval(this.fetchData, 10000)
+    },
+
+    clearRefreshInterval() {
+      if (this.refreshInterval) {
+        clearInterval(this.refreshInterval)
+        this.refreshInterval = null
+      }
+    },
+
+    async fetchData() {
+      try {
+        const response = await this.$http.get("kanban/datalist.action", {
+          params: {
+            caller: this.apiCaller,
+            _noc: 1,
+            page: 1,
+            pageSize: 100,
+            condition: "1=1"
+          }
+        })
+        this.processResponseData(response.data.data)
+      } catch (error) {
+        console.error('数据获取失败:', error)
+      }
+    },
+
+    processResponseData(rawData) {
+      try {
+        const dataList = JSON.parse(rawData)
+        const formattedData = dataList.map(item => this.formatRowData(item))
+        this.$refs.scrollBoard.updateRows(formattedData)
+      } catch (error) {
+        console.error('数据处理失败:', error)
+      }
+    },
+    formatRowData(item) {
+      const rowClass = 'colorGrass';
+      return [
+        this.createCell(item.week_number, rowClass),
+        this.createCell(item.highest_getrate_wc, rowClass),
+        this.createCell(item.highest_getrate, rowClass),
+        this.createCell(item.highest_okrate_wc, rowClass),
+        this.createCell(item.highest_okrate, rowClass)
+      ]
+    },
+    createCell(content, className) {
+      return `<span class="${className} fs-xxl">${content}</span>`
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 475px;
+$box-width: 100%;
+#fleft-bottom1 {
+  padding: 10px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    height: $box-height - 25px;
+    border-radius: 10px;
+    padding: 5px;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .plan-header {
+    .text {
+      color: #c3cbde;
+      font-size: 25px;
+    }
+    .header-content {
+      border-radius: 10px;
+      padding: 5px;
+      background-color: rgba(15, 19, 37, 0.1);
+
+      .header-title {
+        color: #c3cbde;
+        font-weight: bold;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding: 5px 10px;
+      }
+    }
+  }
+
+  .plan-body {
+    margin-top: 5px;
+
+    .scroll-board {
+      height: 420px;
+      border-radius: 10px;
+
+      ::v-deep .header {
+        font-size: 18px;
+      }
+    }
+  }
+}
+
+</style>

+ 197 - 0
src/views/finance/left-down2.vue

@@ -0,0 +1,197 @@
+<template>
+  <div id="up1">
+    <div class="bg-color-black">
+      <div class="d-flex pt-1 pl-2 jc-center">
+        <span class="fs-xxxl text mx-2 fw-b">成品完工出货</span>
+      </div>
+      <div class="jc-center body-box">
+        <div class="body-box d-flex">
+          <div class="item d-flex jc-center flex-column">
+            <div class="location">
+              <div class="circle-hollow">
+                <div class="info">
+                  <h2 class="pb-2">{{inQty}}</h2>
+                  <p class="fs-xxl pt-2">
+                    入库数量
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+          <div class="item d-flex jc-center flex-column">
+            <div class="circle-hollow">
+              <div class="info">
+                <h2 class="pb-2">{{outQty}}</h2>
+                <p class="fs-xxl pt-2">
+                  出货数量
+                </p>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="down">
+        <div class="d-flex pt-1 pl-2 jc-center ">
+          <span class="fs-xxxl text mx-2 fw-b">完工金额</span>
+        </div>
+        <div class="jc-center body-box">
+          <div class="body-box d-flex">
+            <div class="item d-flex jc-center flex-column">
+              <div class="location">
+                <div class="circle-hollow">
+                  <div class="info">
+                    <h2 class="pb-2">{{monthamount}}</h2>
+                    <p class="fs-xxl pt-2">
+                      月完工金额
+                    </p>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="item d-flex jc-center flex-column">
+              <div class="circle-hollow">
+                <div class="info">
+                  <h2 class="pb-2">{{yearamount}}</h2>
+                  <p class="fs-xxl pt-2">
+                    年完工金额
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {mapState} from "vuex";
+export default {
+  computed: {
+    //数组写法
+    ...mapState(['user','factoryoptions','factory']),
+  },
+  data() {
+    return {
+      monthamount : 0,
+      yearamount : 0,
+      inQty : 0,
+      outQty : 0,
+      timing: null,
+    }
+  },
+  mounted() {
+    this.refreshdata();
+  },
+  beforeDestroy () {
+    clearInterval(this.timing)
+  },
+  methods: {
+    refreshdata() {
+      this.getdata(); //获取-数据
+      this.timing = setInterval(() => {
+        this.getdata(); //获取--数据
+      }, 10000);
+    },
+    async getdata() {
+      this.monthamount = 0;
+      this.yearamount = 0;
+      this.inQty = 0;
+      this.outQty = 0;
+
+      //成品完工出货
+      var caller = 'KB!FIN!FINISHDATA';
+      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);
+            if(dataList.length>0){
+              this.inQty = dataList[0].inqty;
+              this.outQty = dataList[0].outqty;
+            }
+          }, (result) => {
+            console.error(result)
+          }
+      );
+
+
+      //完工金额
+      caller = 'KB!FIN!FINISHAMOUNT';
+      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);
+            if(dataList.length>0){
+              this.monthamount = dataList[0].monthamount;
+              this.yearamount = dataList[0].yearamount;
+            }
+          }, (result) => {
+            console.error(result)
+          }
+      );
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 475px;
+$box-width: 100%;
+#up1 {
+  padding: 10px;
+  height: $box-height;
+  // font-size: 32px;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    height: $box-height - 25px;
+    border-radius: 10px;
+    padding: 5px;
+    width: $box-width;
+    .body-box {
+      padding-top: 15px;
+    }
+  }
+  .down{
+    margin-top: 2.75rem
+  }
+  .text {
+    color: #c3cbde;
+    //font-size: 15px;
+  }
+  .body-box {
+    width: $box-width;
+  }
+
+  .item {
+    width: 50%;
+    align-items: center;
+    .circle-hollow {
+      width: 140px;
+      height: 140px;
+      border: 3px solid #4ecdc4; /* 边框样式 */
+      border-radius: 50%;
+      background-color: transparent; /* 透明背景 */
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      letter-spacing:1px;
+      flex-direction: column; /* 文字垂直排列 */
+      box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* 阴影效果 */
+      .info{
+        text-align: center;
+        width: 120px;
+        p{
+          border-top: 1px solid #ddd;
+        }
+      }
+    }
+  }
+}
+</style>

+ 106 - 0
src/views/finance/left-up1.vue

@@ -0,0 +1,106 @@
+<template>
+  <div id="fleft-up1">
+    <div class="bg-color-black">
+      <div class="d-flex pt-1 pl-2 jc-center">
+        <span class=" text mx-2 fw-b">当日生产明细</span>
+      </div>
+      <div class="body-box">
+        <div class="pt-2 chart-container" ref="chartContainer">
+          <LeftUp1Chart />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import LeftUp1Chart from "../../components/comparechart/leftup1Chart";
+import {mapState} from "vuex";
+import { debounce } from 'lodash';
+
+export default {
+  components: {
+    LeftUp1Chart
+  },
+  computed: {
+    ...mapState(['user','factoryoptions','factory']),
+  },
+  data() {
+    return {
+      timing: null,
+      chartKey: 0, // 用于强制重新渲染图表
+      resizeObserver: null
+    }
+  },
+  mounted() {
+    this.initResizeObserver();
+  },
+  beforeDestroy() {
+    this.cleanup();
+  },
+  methods: {
+    cleanup() {
+      clearInterval(this.timing);
+      if (this.resizeObserver) {
+        this.resizeObserver.disconnect();
+        this.resizeObserver = null;
+      }
+    },
+
+    initResizeObserver() {
+      // 使用防抖函数避免频繁触发
+      const resizeHandler = debounce(() => {
+        this.chartKey += 1; // 强制重新渲染图表
+      }, 300);
+
+      this.resizeObserver = new ResizeObserver(resizeHandler);
+      if (this.$refs.chartContainer) {
+        this.resizeObserver.observe(this.$refs.chartContainer);
+      }
+    },
+
+    refreshdata() {
+
+    },
+
+    async getdata() {
+
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+$box-height: 475px;
+$box-width: 100%;
+#fleft-up1 {
+  padding: 13px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+
+  .bg-color-black {
+    height: $box-height - 25px;
+    border-radius: 10px;
+    padding: 5px;
+    display: flex;
+    flex-direction: column;
+  }
+  .text {
+    color: #c3cbde;
+    font-size: 25px;
+  }
+  .body-box {
+    border-radius: 10px;
+    overflow: hidden;
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+
+    .chart-container {
+      flex: 1;
+      min-height: 0; // 修复flex布局中的尺寸问题
+    }
+  }
+}
+</style>

+ 153 - 0
src/views/finance/right-bottom.vue

@@ -0,0 +1,153 @@
+<template>
+  <div id="right-bottom" >
+    <div class="bg-color-black">
+      <div class="plan-header">
+        <div class="d-flex pt-1 pl-2 jc-center">
+          <span class="text mx-2 fw-b">每周车间达成率</span>
+        </div>
+      </div>
+      <div class="plan-body">
+        <dv-scroll-board
+            :config="config"
+            ref="scrollBoard"
+            class="scroll-board"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ProductionPlan',
+  data() {
+    return {
+      config: {
+        header: ['周次','达成率最高车间', '达成率%','良率最高车间','良品率%'],
+        data: [],
+        rowNum: 10,
+        headerHeight: 35,
+        headerBGC: 'rgba(15,19,37,0.1)',
+        oddRowBGC: 'rgba(15,19,37,0.1)',
+        evenRowBGC: 'rgba(23,28,51,0.1)',
+        columnWidth: [100, 190, 150,160,150],
+        align: ['center', 'center', 'center', 'center','center']
+      },
+      refreshInterval: null,
+      apiCaller: 'KB!ALLWC!PROCESS_WEEK'
+    }
+  },
+  mounted() {
+    this.initDataRefresh()
+  },
+  beforeDestroy() {
+    this.clearRefreshInterval()
+  },
+  methods: {
+    initDataRefresh() {
+      this.fetchData()
+      this.refreshInterval = setInterval(this.fetchData, 10000)
+    },
+
+    clearRefreshInterval() {
+      if (this.refreshInterval) {
+        clearInterval(this.refreshInterval)
+        this.refreshInterval = null
+      }
+    },
+
+    async fetchData() {
+      try {
+        const response = await this.$http.get("kanban/datalist.action", {
+          params: {
+            caller: this.apiCaller,
+            _noc: 1,
+            page: 1,
+            pageSize: 100,
+            condition: "1=1"
+          }
+        })
+        this.processResponseData(response.data.data)
+      } catch (error) {
+        console.error('数据获取失败:', error)
+      }
+    },
+
+    processResponseData(rawData) {
+      try {
+        const dataList = JSON.parse(rawData)
+        const formattedData = dataList.map(item => this.formatRowData(item))
+        this.$refs.scrollBoard.updateRows(formattedData)
+      } catch (error) {
+        console.error('数据处理失败:', error)
+      }
+    },
+    formatRowData(item) {
+      const rowClass = 'colorGrass';
+      return [
+        this.createCell(item.week_number, rowClass),
+        this.createCell(item.highest_getrate_wc, rowClass),
+        this.createCell(item.highest_getrate, rowClass),
+        this.createCell(item.highest_okrate_wc, rowClass),
+        this.createCell(item.highest_okrate, rowClass)
+      ]
+    },
+    createCell(content, className) {
+      return `<span class="${className} fs-xxl">${content}</span>`
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 475px;
+$box-width: 100%;
+#right-bottom {
+  padding: 10px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    height: $box-height - 25px;
+    border-radius: 10px;
+    padding: 5px;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .plan-header {
+    .text {
+      color: #c3cbde;
+      font-size: 25px;
+    }
+    .header-content {
+      border-radius: 10px;
+      padding: 5px;
+      background-color: rgba(15, 19, 37, 0.1);
+
+      .header-title {
+        color: #c3cbde;
+        font-weight: bold;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding: 5px 10px;
+      }
+    }
+  }
+
+  .plan-body {
+    margin-top: 5px;
+
+    .scroll-board {
+      height: 420px;
+      border-radius: 10px;
+
+      ::v-deep .header {
+        font-size: 23px;
+      }
+    }
+  }
+}
+
+</style>

+ 155 - 0
src/views/finance/right.vue

@@ -0,0 +1,155 @@
+<template>
+  <div id="fright" >
+    <div class="bg-color-black">
+      <div class="plan-header">
+        <div class="d-flex pt-1 pl-2 jc-center">
+          <span class="text mx-2 fw-b">各车间达成进度</span>
+        </div>
+      </div>
+      <div class="plan-body">
+        <dv-scroll-board
+            :config="config"
+            ref="scrollBoard"
+            class="scroll-board"
+        />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ProductionPlan',
+  data() {
+    return {
+      config: {
+        header: ['车间', '计划数', '完成数', '达成率%','不良数','良品率%'],
+        data: [],
+        rowNum: 10,
+        headerHeight: 35,
+        headerBGC: 'rgba(15,19,37,0.1)',
+        oddRowBGC: 'rgba(15,19,37,0.1)',
+        evenRowBGC: 'rgba(23,28,51,0.1)',
+        columnWidth: [100, 100, 120,140,100,120],
+        align: ['center', 'center', 'center', 'center']
+      },
+      refreshInterval: null,
+      apiCaller: 'KB!ALLWC!PROCESS'
+    }
+  },
+  mounted() {
+    this.initDataRefresh()
+  },
+  beforeDestroy() {
+    this.clearRefreshInterval()
+  },
+  methods: {
+    initDataRefresh() {
+      this.fetchData()
+      this.refreshInterval = setInterval(this.fetchData, 10000)
+    },
+
+    clearRefreshInterval() {
+      if (this.refreshInterval) {
+        clearInterval(this.refreshInterval)
+        this.refreshInterval = null
+      }
+    },
+
+    async fetchData() {
+      try {
+        const response = await this.$http.get("kanban/datalist.action", {
+          params: {
+            caller: this.apiCaller,
+            _noc: 1,
+            page: 1,
+            pageSize: 100,
+            condition: "1=1"
+          }
+        })
+        this.processResponseData(response.data.data)
+      } catch (error) {
+        console.error('数据获取失败:', error)
+      }
+    },
+
+    processResponseData(rawData) {
+      try {
+        const dataList = JSON.parse(rawData)
+        const formattedData = dataList.map(item => this.formatRowData(item))
+        this.$refs.scrollBoard.updateRows(formattedData)
+      } catch (error) {
+        console.error('数据处理失败:', error)
+      }
+    },
+    formatRowData(item) {
+      const rowClass = 'colorGrass';
+      const rowClass1 = 'colorRed';
+      return [
+        this.createCell(item.v_wccode, rowClass),
+        this.createCell(item.v_planqty, rowClass),
+        this.createCell(item.v_madeqty, rowClass),
+        this.createCell(item.v_rate, item.getratestatus=='max'?rowClass1:rowClass),
+        this.createCell(item.v_ngqty, rowClass),
+        this.createCell(item.v_okrate, item.okratestatus=='max'?rowClass1:rowClass)
+      ]
+    },
+    createCell(content, className) {
+      return `<span class="${className} fs-xxl">${content}</span>`
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$box-height: 475px;
+$box-width: 100%;
+#fright {
+  padding: 10px;
+  height: $box-height;
+  width: $box-width;
+  border-radius: 5px;
+  .bg-color-black {
+    height: $box-height - 20px;
+    border-radius: 10px;
+    padding: 5px;
+    display: flex;
+    flex-direction: column;
+  }
+
+  .plan-header {
+    .text {
+      color: #c3cbde;
+      font-size: 25px;
+    }
+    .header-content {
+      border-radius: 10px;
+      padding: 5px;
+      background-color: rgba(15, 19, 37, 0.1);
+
+      .header-title {
+        color: #c3cbde;
+        font-weight: bold;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        padding: 5px 10px;
+      }
+    }
+  }
+
+  .plan-body {
+    margin-top: 5px;
+
+    .scroll-board {
+      height: 420px;
+      border-radius: 10px;
+
+      ::v-deep .header {
+        font-size: 23px;
+      }
+    }
+  }
+}
+
+</style>

+ 4 - 1
src/views/login.vue

@@ -67,7 +67,8 @@
                     {label: '仓库看板', value: '仓库看板'},
                     {label: '组装看板', value: '组装看板'},
                     {label: '生产进度看板', value: '生产进度看板'},
-                    {label: '各车间进度', value: '各车间进度'}
+                    {label: '各车间进度', value: '各车间进度'},
+                    {label: '财务', value: '财务'}
                 ],
             }
         },
@@ -133,6 +134,8 @@
                                      this.$router.push({path: this.redirect || '/makeprocess'});
                                    }else if(this.loginForm.type =='各车间进度'){
                                      this.$router.push({path: this.redirect || '/compare'});
+                                   }else if(this.loginForm.type =='财务'){
+                                     this.$router.push({path: this.redirect || '/finance'});
                                    }
 
                                   //总看板,品质看板,车间看板,仓库看板

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

@@ -53,6 +53,7 @@
                   <el-dropdown-item class="dropdownitem"><router-link to="warehouse">仓库看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="zz">组装看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="compare">各车间进度</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="finance">财务</router-link></el-dropdown-item>
                 </el-dropdown-menu>
               </el-dropdown>
               <el-select v-model="licode" class="dropdown" @change ="handleBlur" style="width: 150px">

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

@@ -51,6 +51,7 @@
                   <el-dropdown-item class="dropdownitem"><router-link to="zz">组装看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="makeprocess">生产进度看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="compare">各车间进度</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="finance">财务</router-link></el-dropdown-item>
                  </el-dropdown-menu>
               </el-dropdown>
 

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

@@ -51,6 +51,7 @@
                     <el-dropdown-item class="dropdownitem"><router-link to="zz">组装看板</router-link></el-dropdown-item>
                     <el-dropdown-item class="dropdownitem"><router-link to="makeprocess">生产进度看板</router-link></el-dropdown-item>
                     <el-dropdown-item class="dropdownitem"><router-link to="compare">各车间进度</router-link></el-dropdown-item>
+                    <el-dropdown-item class="dropdownitem"><router-link to="finance">财务</router-link></el-dropdown-item>
                   </el-dropdown-menu>
               </el-dropdown>
 

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

@@ -51,6 +51,7 @@
                   <el-dropdown-item class="dropdownitem"><router-link to="zz">组装看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="makeprocess">生产进度看板</router-link></el-dropdown-item>
                   <el-dropdown-item class="dropdownitem"><router-link to="compare">各车间进度</router-link></el-dropdown-item>
+                  <el-dropdown-item class="dropdownitem"><router-link to="finance">财务</router-link></el-dropdown-item>
                 </el-dropdown-menu>
               </el-dropdown>
               <span class="text">&nbsp;&nbsp;&nbsp;&nbsp;</span>

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

@@ -50,6 +50,7 @@
                     <el-dropdown-item class="dropdownitem"><router-link to="zz">组装看板</router-link></el-dropdown-item>
                     <el-dropdown-item class="dropdownitem"><router-link to="makeprocess">生产进度看板</router-link></el-dropdown-item>
                     <el-dropdown-item class="dropdownitem"><router-link to="compare">各车间进度</router-link></el-dropdown-item>
+                    <el-dropdown-item class="dropdownitem"><router-link to="finance">财务</router-link></el-dropdown-item>
                   </el-dropdown-menu>
               </el-dropdown>