From e1e25f4f7fa6b7e31c7f0567cc3744fb3ee6ba98 Mon Sep 17 00:00:00 2001
From: 叶松 <2217086471@qq.com>
Date: 星期三, 27 九月 2023 09:55:59 +0800
Subject: [PATCH] 路由修改

---
 web/src/views/GoodManage/components/InventManage.vue                 |    0 
 web/src/views/GoodManage/components/MixingCost.vue                   |    0 
 web/src/views/QualityManage/AppearCheck.vue                          |    3 
 web/src/views/GoodManage/RevolvingMaterial.vue                       |    3 
 web/src/views/GoodManage/CostStatistics/AuxiliaryCost.vue            |  478 ++++
 web/src/views/GoodManage/components/AuxiliaryType.vue                |    0 
 web/src/views/GoodManage/components/AuxiliaryCost.vue                |    0 
 web/src/views/MaterialsIndex/MixingManage.vue                        |   20 
 web/src/views/EquipmentManage/EquipSpot.vue                          |    3 
 web/src/views/ProjectManage/components/FittConsump.vue               |    0 
 web/src/views/DuctpiecePLM/DespatchManage/components/GpsManage.vue   |    6 
 web/src/views/DuctpiecePLM/PlanManage/DuctPlan.vue                   |  486 ++++
 web/src/views/QualityManage/FinishedManage.vue                       |    3 
 web/src/views/DuctpiecePLM/ReportCenter/SafetycheckIndex.vue         |  130 +
 web/src/views/GoodManage/AuxiliaryIndex.vue                          |    0 
 web/src/views/DuctpiecePLM/DespatchManage/components/CarManage.vue   |    6 
 web/src/views/EquipmentManage/EquipInfo.vue                          |    3 
 web/src/views/DuctpiecePLM/DespatchManage.vue                        |   16 
 web/src/views/DuctpiecePLM/ReportCenter/DieuserReport.vue            |  149 +
 web/src/views/GoodManage/MixingManage.vue                            |   85 
 web/src/views/DuctpiecePLM/ProductTerminal/ReinsInfoPrint.vue        |  435 +++
 web/src/views/QualityManage/DieDetection.vue                         |    3 
 web/src/views/QualityManage/PatternCheck.vue                         |    3 
 web/src/views/DuctpiecePLM/DuctProduct/ProductIndex.vue              |  652 +++++
 web/src/views/DuctpiecePLM/ReportCenter/DuctReport.vue               |    3 
 web/src/views/DuctpiecePLM/DespatchManage/components/DespatchOut.vue |   12 
 web/src/views/GoodManage/CostStatistics/RawCost.vue                  |  452 ++++
 web/src/views/DuctpiecePLM/PlanManage/DuctForward.vue                |    0 
 web/src/views/GoodManage/CostStatistics/RebarCost.vue                |  486 ++++
 web/src/views/DuctpiecePLM/DuctProduct/ProductAnalyse.vue            |  280 ++
 web/src/views/GoodManage/components/MixingInvent.vue                 |    0 
 web/src/views/ProjectManage/components/RebarConsump.vue              |  523 ++++
 web/src/views/GoodManage/components/CostRecord.vue                   |    0 
 web/src/views/DuctpiecePLM/ReportCenter/BearReport.vue               |    3 
 web/src/views/DuctpiecePLM/DespatchManage/ForwardAnalyse.vue         |  405 +++
 web/src/views/DuctpiecePLM/ReportCenter/VideoAgv.vue                 |    3 
 web/src/views/GoodManage/components/MixingIncome.vue                 |    0 
 web/src/views/GoodManage/ReinForcement.vue                           |   81 
 web/src/views/GoodManage/components/RealRaw.vue                      |  435 +++
 web/src/views/GoodManage/components/RebarType.vue                    |    2 
 web/src/views/QualityManage/ProcessMonitor.vue                       |    3 
 web/src/views/QualityManage/TestManage.vue                           |    3 
 web/src/views/GoodManage/components/CheckRecord.vue                  |    0 
 web/src/views/MaterialsIndex/ReinforcementIndex.vue                  |   24 
 web/src/views/ProjectManage/AmountManage.vue                         |   64 
 web/src/views/DuctpiecePLM/DespatchManage/DespatchIndex.vue          |   62 
 web/src/views/GoodManage/components/AuxiliaryInvent.vue              |    0 
 web/src/views/GoodManage/components/MixingCheck.vue                  |    0 
 web/src/views/GoodManage/components/AuxiliaryCheck.vue               |    0 
 web/src/views/QualityManage/RawQuality.vue                           |    3 
 web/src/views/DuctpiecePLM/DuctSpray.vue                             |    0 
 web/src/views/EquipmentManage/EquipDynamic.vue                       |    3 
 web/src/views/GoodManage/components/AuxiliaryIncome.vue              |    0 
 web/src/views/DuctpiecePLM/ProductTerminal/SegmentPrint.vue          |  524 ++++
 web/src/views/GoodManage/components/IncomeRecord.vue                 |    2 
 web/src/views/DuctpiecePLM/ProductTerminal/components/ReinsPrint.vue |  355 +++
 web/src/views/ProjectManage/components/RawConsump.vue                |  456 ++++
 57 files changed, 6,624 insertions(+), 44 deletions(-)

diff --git a/web/src/views/DuctpiecePLM/DespatchManage.vue b/web/src/views/DuctpiecePLM/DespatchManage.vue
index 57e7d35..b01201e 100644
--- a/web/src/views/DuctpiecePLM/DespatchManage.vue
+++ b/web/src/views/DuctpiecePLM/DespatchManage.vue
@@ -16,15 +16,15 @@
   </div>
 </template>
 <script>
-import DespatchOut from './components/DespatchOut.vue'//出库管理
-import CarManage from './components/CarManage.vue'//车辆管理
-import GpsManage from './components/GpsManage.vue'//车辆管理
+// import DespatchOut from './components/DespatchOut.vue'//出库管理
+// import CarManage from './components/CarManage.vue'//车辆管理
+// import GpsManage from './components/GpsManage.vue'//车辆管理
 export default {
-    components:{
-        DespatchOut,
-        CarManage,
-        GpsManage
-    },
+    // components:{
+    //     DespatchOut,
+    //     CarManage,
+    //     GpsManage
+    // },
     data(){
         return{
             activeName:'first'
diff --git a/web/src/views/DuctpiecePLM/DespatchManage/DespatchIndex.vue b/web/src/views/DuctpiecePLM/DespatchManage/DespatchIndex.vue
new file mode 100644
index 0000000..57e7d35
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/DespatchManage/DespatchIndex.vue
@@ -0,0 +1,62 @@
+<template>
+  <div class="main">
+    <div class="main_tabs">
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+            <el-tab-pane label="出库管理" name="first">
+                <despatch-out ref="Outs"></despatch-out> 
+            </el-tab-pane>
+            <el-tab-pane label="车辆管理" name="second">
+                <car-manage ref="Cars"></car-manage>
+            </el-tab-pane>
+            <el-tab-pane label="GPS设备管理" name="third">
+                <gps-manage ref="Gpss"></gps-manage>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+  </div>
+</template>
+<script>
+import DespatchOut from './components/DespatchOut.vue'//出库管理
+import CarManage from './components/CarManage.vue'//车辆管理
+import GpsManage from './components/GpsManage.vue'//车辆管理
+export default {
+    components:{
+        DespatchOut,
+        CarManage,
+        GpsManage
+    },
+    data(){
+        return{
+            activeName:'first'
+        }
+    },
+    mounted(){
+        this.$refs.Outs.searchButtonInfo(true);
+    },
+    methods:{
+        //切换界面
+        handleClick(tab){
+            switch(tab.name){
+                case 'second':
+                    this.$refs.Cars.searchButtonInfo(true);
+                    break;
+                case 'third':
+                    this.$refs.Gpss.searchButtonInfo(true);
+                    break;
+                default:
+                    this.$refs.Outs.searchButtonInfo(true);
+            }
+        },
+    }
+}
+</script>
+<style scoped lang="scss">
+@import'@/style/layout-main.scss';
+/deep/ .el-tabs__content{
+    position: static;
+}
+
+/deep/.main {
+  background: none;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/DespatchManage/ForwardAnalyse.vue b/web/src/views/DuctpiecePLM/DespatchManage/ForwardAnalyse.vue
new file mode 100644
index 0000000..936ba66
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/DespatchManage/ForwardAnalyse.vue
@@ -0,0 +1,405 @@
+<template>
+  <div class="main tabs_main" style="overflow:hidden;width:none!important;height:none!important;">
+    <div class="main_header">
+        <div class="header_item">
+            <span class="header_label">项目名称:</span>
+            <el-select v-model="search.proId" placeholder="请选择项目名称" clearable>
+                <el-option
+                    v-for="item in optionsProject"
+                    :key="item.proId"
+                    :label="item.proName"
+                    :value="item.proId">
+                </el-option>
+            </el-select>
+        </div>
+        <div class="header_item">
+            <span class="header_label">统计时间:</span>
+            <el-date-picker
+            v-model="search.time"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item">
+            <el-button v-if="showButton('search')" icon="el-icon-search" @click="searchButtonInfo()">查询</el-button>
+            <el-button v-if="showButton('export')" icon="el-icon-download" @click="exportExcel()">导出Excel</el-button>
+        </div>
+    </div>
+    <div class="main_middle">
+        <div class="main_middle_titles">数据统计</div>
+        <div class="main_middle_matter">
+            <div class="middle_items">
+                <div class="middle_items_text">管片运输总量</div>
+                <div class="middle_items_datas">{{showDatas&&showDatas.transport*1}}<span>块</span></div>
+            </div>
+            <div class="middle_items">
+                <div class="middle_items_text">累计发运总量</div>
+                <div class="middle_items_datas">{{showDatas&&showDatas.shipping}}<span>块</span></div>
+            </div>
+            <div class="middle_items">
+                <div class="middle_items_text">累计运输车次</div>
+                <div class="middle_items_datas">{{showDatas&&showDatas.carNum}}<span>次</span></div>
+            </div>
+        </div>
+    </div>
+    <div class="main_content" style="overflow:hidden">
+        <div class="main_content_left">
+            <div class="main_content_left_titles">发运与生产对比</div>
+            <div id="first_chart" style="height:100%"></div>
+        </div>
+        <div class="main_content_right">
+            <div class="main_content_right_titles">运输量排行</div>
+            <div class="main_content_right_ranks" v-if="rankList.length!==0">
+                <div class="tables_items" v-for="(rankItem,rankIndex) in rankList" :key="rankIndex">
+                    <div class="tables_items_first">
+                        <div class="tables_items_first_text">项目名称:</div>
+                        <div class="tables_items_first_data" >{{rankItem.ranKingDtos[0].proName}}</div>
+                        <div class="tables_items_first_text">尺寸:</div>
+                        <div class="tables_items_first_data" >{{rankItem.ranKingDtos[0].sizeName}}</div>
+                    </div>
+                    <div class="tables_items_first">
+                        <div class="tables_items_first_text">块号</div>
+                        <div class="tables_items_first_data" v-for="(titleItem,tIndex) in rankItem.ranKingDtos" :key="tIndex">{{titleItem.blockName}}</div>
+                    </div>
+                    <div class="tables_items_first">
+                        <div class="tables_items_first_text">生产量</div>
+                        <div class="tables_items_first_data" style="background-color:#0B3371" v-for="(productItem,pIndex) in rankItem.ranKingDtos" :key="pIndex">{{productItem.produce}}个</div>
+                    </div>
+                    <div class="tables_items_first">
+                        <div class="tables_items_first_text">发运量</div>
+                        <div class="tables_items_first_data"  style="background-color:#0B3371" v-for="(forwardItem,fIndex) in rankItem.ranKingDtos" :key="fIndex">{{forwardItem.goIn}}个</div>
+                    </div>
+                </div>
+            </div>
+            <div class="main_content_right_ranks_empot" v-if="rankList.length===0">暂无数据</div>
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia';
+export default {
+//   name: 'DuctpieceIndex',
+  data() {
+    return {
+      search:{},//查询条件
+      optionsProject:[],//所以项目
+      rankList:[],//排行榜数目
+      showDatas:null,//展示的数据统计
+    }
+  },
+  mounted() {
+    this.searchButtonInfo()
+    this.getAllProjects()
+  },
+  methods: {
+    //获得所有项目名称
+    getAllProjects(){
+        let obj = {
+            pageNum: 1,
+            pageSize: 100000000
+        }
+        this.$api.Engineer.searchProjects(obj).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsProject = res.data.list
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+    //查询按钮
+    searchButtonInfo() {
+        let params = {
+            proId:this.search.proId,
+            strTime:this.search.time&&this.search.time[0],
+            endTime:this.search.time&&this.search.time[1]
+        }
+        this.$api.Analyse.searchDataLists(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.showDatas = res.data
+                this.$nextTick(() => {
+                    this.createCharts('first_chart',res.data);
+                })
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+        this.$api.Analyse.searchRanksForward(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.rankList = res.data
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+     // 创建echart图表
+    createCharts(name,data) {
+        const chartsImage = this.$echarts.init(document.getElementById(name));
+        const dataEcharts = [{
+                name: '生产数量',
+                value: data.produce==='0'?0:((data.produce*1/(data.produce*1+data.shipping*1))*100).toFixed(2),
+            },
+            {
+                name: '发运数量',
+                value: data.shipping==='0'?0:((data.shipping*1/(data.produce*1+data.shipping*1))*100).toFixed(2),
+            },
+        ]
+        const option = {
+            animationDuration: 1500,
+            color:[ '#2C77FF','#FAA706'],
+            legend: {
+            // selectedMode: false, // 取消图例上的点击事件
+            type: 'plain',
+            icon: 'circle',
+            orient: 'vertical',
+            left: '70%',
+            top: '45%',
+            // align: 'left',
+            itemGap: 15,
+            itemWidth: 20, // 设置圆圈宽度
+            itemHeight: 20, // 设置高度
+            symbolKeepAspect: false,
+            textStyle: {
+                color: '#fff',
+                rich: {
+                    name: {
+                        verticalAlign: 'right',
+                        align: 'left',
+                        width: 35,
+                        fontSize: 15 //文字大小
+                    },
+                }
+            },
+            data: dataEcharts.map(item => item.name),
+            formatter: function(name) {
+                return ('{name| ' +name +'}')
+            }
+        },
+        series: [{
+            name: '数量',
+            type: 'pie',
+            radius: ['30%', '55%'],
+            center: ['40%', '50%'],
+            data: dataEcharts,
+            itemStyle: {
+                normal: {
+                    borderWidth: 8,//设置边框粗细
+                    borderColor: 'rgba(44,119,255,0.4)'//边框颜色
+                }
+            },
+            label: {
+                normal: {
+                    show: true,//扇形上是否展示数据
+                    position: 'outside',
+                    color:"#fff",
+                    formatter: '{text|{c}%}\n',
+                    rich: {
+                        text: {
+                            align: 'center',
+                            verticalAlign: 'middle',
+                            padding: 8,
+                            fontSize: 20
+                        },
+                        value: {
+                            align: 'center',
+                            verticalAlign: 'middle',
+                            fontSize: 20
+                        }
+                    },
+                },
+                emphasis: {
+                    show: true,
+                    textStyle: {
+                        fontSize: '15'
+                    }
+                }
+            },
+            labelLine: {
+                normal: {
+                    show: true
+                }
+            }
+        }]
+        }
+        chartsImage.clear();
+        chartsImage.setOption(option);
+        window.onresize = () => {
+            chartsImage.resize()
+        }
+    },
+    // 判断按钮权限信息
+    showButton(str) {
+      const pinia = buttonPinia();
+      return pinia.$state.buttonInfo.includes(str);
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "@/style/layout-main.scss";
+
+.main_middle{
+    width: 97%;
+    margin: 10px 18px;
+
+    .main_middle_titles{
+        width: 100%;
+        color: #19F6F8;
+        position: relative;
+        padding: 10px 15px;
+        border-bottom:1px solid #1B50AE ;
+        &::before{
+            content: "";
+            position: absolute;
+            left: 5px;
+            top: 10px;
+            width: 2px;
+            height: 18px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_middle_matter{
+        padding-top: 15px;
+        display: flex;
+
+        .middle_items{
+            width: calc(100%/3 - 25px);
+            margin-right: 20px;
+            height: 200px;
+            background: url('../../../assets/data_analyse_bg.png') no-repeat;
+            background-size: 100% 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            flex-direction: column;
+            .middle_items_text{
+                color: #E1E5EB;
+                font-size: 16px;
+            }
+            .middle_items_datas{
+                color: #18F6F8;
+                font-size: 48px;
+                font-weight: 600;
+                margin-top: 15px;
+                span{
+                    color: #18F6F8;
+                    font-size: 14px;
+                }
+            }
+        }
+    }
+}
+
+.main_content{
+    width: 100%;
+    overflow: auto;
+    display: flex;
+    .main_content_left{
+        width: 40%;
+        .main_content_left_titles{
+            color: #19F6F8;
+            position: relative;
+            margin: 0px 18px;
+            padding: 10px 15px;
+            border-bottom:1px solid #1B50AE ;
+            &::before{
+                content: "";
+                position: absolute;
+                left: 5px;
+                top: 10px;
+                width: 2px;
+                height: 18px;
+                background-color: #18F6F8;
+            }
+        }
+    }
+    .main_content_right{
+        width: 58%;
+        .main_content_right_titles{
+            margin: 0px 18px;
+            color: #19F6F8;
+            position: relative;
+            padding: 10px 15px;
+            border-bottom:1px solid #1B50AE ;
+            &::before{
+                content: "";
+                position: absolute;
+                left: 5px;
+                top: 10px;
+                width: 2px;
+                height: 18px;
+                background-color: #18F6F8;
+            }
+        }
+        .main_content_right_ranks_empot{
+            color: #909399;
+            height: 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+        }
+        .main_content_right_ranks{
+            width: 100%;
+            height: 500px;
+            padding: 10px 25px;
+            overflow: auto;
+            .tables_items{
+                padding-top: 20px;
+
+                .tables_items_first{
+                    display: flex;
+                    line-height: 30px;
+                    &:last-child{
+                        border-bottom: 1px solid #2155A2; 
+                        border-right: 1px solid #2155A2;
+                    }
+                    &:nth-child(2){
+                        border-right: 1px solid #2155A2;
+                    }
+                    &:nth-child(1){
+                        border-right: 1px solid #2155A2;
+                    }
+                    .tables_items_first_text{
+                        width: 120px;
+                        text-align: center;
+                        padding: 5px 0px;
+                        color: #18F5F7;
+                        flex: none;
+                        border-left: 1px solid #2155A2;
+                        border-top: 1px solid #2155A2;
+                        background-color: #031A46;
+                    }
+                    .tables_items_first_data{
+                        padding: 5px 0px;
+                        color: #18F5F7;
+                        text-align: center;
+                        border-left: 1px solid #2155A2;
+                        border-top: 1px solid #2155A2;
+                        flex: 1;
+                        background-color: #031A46;
+                    }
+                }
+            }
+        }
+    }
+
+}
+
+/deep/.el-radio-button__orig-radio:checked + .el-radio-button__inner{
+    color: #19F7F9;
+    border-color: #18F6F8;
+    background-color: #0D4573!important;
+}
+/deep/.el-radio-button__inner{
+    background-color: #0D4573;
+    border-color:#18F6F8;
+    border-radius: 0px 0px !important;
+    border-color: #18F6F8;
+    color: #E2E9EE;
+}
+</style>
diff --git a/web/src/views/DuctpiecePLM/components/CarManage.vue b/web/src/views/DuctpiecePLM/DespatchManage/components/CarManage.vue
similarity index 97%
rename from web/src/views/DuctpiecePLM/components/CarManage.vue
rename to web/src/views/DuctpiecePLM/DespatchManage/components/CarManage.vue
index 82e4521..adb5164 100644
--- a/web/src/views/DuctpiecePLM/components/CarManage.vue
+++ b/web/src/views/DuctpiecePLM/DespatchManage/components/CarManage.vue
@@ -84,8 +84,8 @@
 </template>
 
 <script>
-import { buttonPinia } from '../../../pinia/index';
-import { throttle, changeSize } from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+import { buttonPinia } from '../../../../pinia/index';
+import { throttle, changeSize } from '../../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
   export default {
     data() {
       return {
@@ -279,5 +279,5 @@
 </script>
 
 <style lang="sass" scoped>
-@import '../../../style/layout-main.scss';
+@import '../../../../style/layout-main.scss';
 </style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/components/DespatchOut.vue b/web/src/views/DuctpiecePLM/DespatchManage/components/DespatchOut.vue
similarity index 98%
rename from web/src/views/DuctpiecePLM/components/DespatchOut.vue
rename to web/src/views/DuctpiecePLM/DespatchManage/components/DespatchOut.vue
index 5072eff..1d478e5 100644
--- a/web/src/views/DuctpiecePLM/components/DespatchOut.vue
+++ b/web/src/views/DuctpiecePLM/DespatchManage/components/DespatchOut.vue
@@ -335,13 +335,13 @@
 </template>
 
 <script>
-import qidian from "../../../assets/start_line.png";
-import zhong from "../../../assets/end_line.png";
+import qidian from "../../../../assets/start_line.png";
+import zhong from "../../../../assets/end_line.png";
 import BaiduMap from 'vue-baidu-map/components/map/Map.vue';
 import BmPolyline from 'vue-baidu-map/components/overlays/Polyline.vue';
 // import UploadImage from '../../../components/uploadImage.vue'
-import { buttonPinia } from '../../../pinia/index';
-import { throttle, changeSize} from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+import { buttonPinia } from '../../../../pinia/index';
+import { throttle, changeSize} from '../../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
   export default {
     components:{
       //  UploadImage,
@@ -860,13 +860,13 @@
 </script>
 
 <style lang="scss" scoped>
-@import '../../../style/layout-main.scss';
+@import '../../../../style/layout-main.scss';
 .gps_infos{
   padding: 20px;
   position: absolute;
   top: 15%;
   right: 10px;
-  background: url("../../../assets/gps_info_bg.png") no-repeat;
+  background: url("../../../../assets/gps_info_bg.png") no-repeat;
   background-size: 100% 100%;
 
   .gps_infos_items{
diff --git a/web/src/views/DuctpiecePLM/components/GpsManage.vue b/web/src/views/DuctpiecePLM/DespatchManage/components/GpsManage.vue
similarity index 96%
rename from web/src/views/DuctpiecePLM/components/GpsManage.vue
rename to web/src/views/DuctpiecePLM/DespatchManage/components/GpsManage.vue
index 0400128..f0002cd 100644
--- a/web/src/views/DuctpiecePLM/components/GpsManage.vue
+++ b/web/src/views/DuctpiecePLM/DespatchManage/components/GpsManage.vue
@@ -66,8 +66,8 @@
 </template>
 
 <script>
-import { buttonPinia } from '../../../pinia/index';
-import { throttle, changeSize } from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+import { buttonPinia } from '../../../../pinia/index';
+import { throttle, changeSize } from '../../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
   export default {
     data() {
       return {
@@ -219,5 +219,5 @@
 </script>
 
 <style lang="sass" scoped>
-@import '../../../style/layout-main.scss';
+@import '../../../../style/layout-main.scss';
 </style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/DuctProduct/ProductAnalyse.vue b/web/src/views/DuctpiecePLM/DuctProduct/ProductAnalyse.vue
new file mode 100644
index 0000000..1c86c71
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/DuctProduct/ProductAnalyse.vue
@@ -0,0 +1,280 @@
+<template>
+  <div class="main tabs_main">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">生产时间:</span>
+        <el-date-picker
+          v-model="timeData"
+          type="monthrange"
+          value-format="yyyy-MM-dd"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期">
+        </el-date-picker>
+      </div>
+      <div class="header_item">
+        <el-button
+          v-if="showButton('search')"
+          icon="el-icon-search"
+          @click="searchData()">
+          查询
+        </el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <div id="first_chart" class="main_content_chart"></div>
+      <div id="second_chart" class="main_content_chart"></div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia';
+export default {
+  name: 'DuctpieceIndex',
+  data() {
+    return {
+      timeData: '',
+    }
+  },
+  mounted() {
+    const dateYear = new Date().getFullYear();
+    this.timeData = [`${dateYear}-01-01`, `${dateYear}-12-01`];
+    this.searchData()
+  },
+  methods: {
+    // 
+    searchData() {
+      this.searchPipeComparePlan();
+      this.searchPipeMonthPlan();
+    },
+    // 查询管片环比增长率
+    async searchPipeMonthPlan() {
+      const { data } = await this.$api.Analyse.searchPipeMonthPlan({
+        startTime: this.timeData ? this.timeData[0] : '',
+        endTime: this.timeData ? this.timeData[1] : '',
+      });
+      if(data.length === 0) {
+        this.$message.warning('请选择生产时间');
+        return false;
+      }
+      this.$nextTick(() => {
+        this.createCharts('first_chart', data);
+      })
+    },
+    // 查询管片理论实际对比
+    async searchPipeComparePlan() {
+      const { data } = await this.$api.Analyse.searchPipeComparePlan({
+        startTime: this.timeData ? this.timeData[0] : '',
+        endTime: this.timeData ? this.timeData[1] : '',
+      });
+      if(data.length === 0) {
+        this.$message.warning('请选择生产时间');
+        return false;
+      }
+      this.$nextTick(() => {
+        this.createCharts('second_chart', data);
+      })
+    },
+     // 创建echart图表
+    createCharts(name, data) {
+      const labelData = data.map(item => item.month);
+      const firstData = data.map(item => item.count ? item.count : 0);
+      const secondData = name === 'first_chart' ? data.map(item => item.rate ? item.rate : 0) : data.map(item => item.rate ? item.planProduct : 0);
+      const chartsImage = this.$echarts.init(document.getElementById(name));
+      const option = {
+        animationDuration: 1500,
+        tooltip: {
+          trigger: "axis",
+          formatter: function (params) {
+            var relVal = params[0].name;
+            if(name === 'first_chart') {
+              for (let i = 0; i < params.length; i++) {
+                if (params[i].componentIndex === 0) {
+                  relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    "月生产量" +
+                    " : " +
+                    params[i].value;
+                } else {
+                  relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    "环比增长率" +
+                    " : " +
+                    params[i].value +
+                    "%";
+                }
+              }
+            } else {
+              for (let i = 0; i < params.length; i++) {
+                if (params[i].componentIndex === 0) {
+                  relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    "实际生产量" +
+                    " : " +
+                    params[i].value;
+                } else {
+                  relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    "计划生产量" +
+                    " : " +
+                    params[i].value;
+                }
+              }
+            }
+            return relVal;
+          },
+        },
+        grid: {
+          top: "15%",
+          right: "3%",
+          left: "2%",
+          bottom: "11%",
+        },
+        xAxis: [
+          {
+            type: "category",
+            data: labelData,
+            axisLine: {
+              lineStyle: {
+                width: 2,
+                color: "#B7E4F7",
+              },
+            },
+            axisLabel: {
+              color: "#B7E4F7",
+            },
+            axisTick: {
+              show: false,
+            },
+          },
+        ],
+        yAxis: [
+          {
+            type: "value",
+            max: 100,
+            splitNumber: 10,
+            axisLabel: {
+              formatter: "{value}",
+              textStyle: {
+                color: "#CAD3E0",
+              },
+            },
+            splitLine: {
+              lineStyle: {
+                width: 2,
+                type: "dashed",
+                color: "#28477C",
+              },
+            },
+          },
+          {
+            type: "value",
+            max: 100,
+            splitNumber: 10,
+            axisLabel: {
+              formatter: "{value}%",
+              textStyle: {
+                color: "#B7E4F7",
+              },
+            },
+            splitLine: {
+              show: false,
+            },
+          },
+        ],
+        series: [
+          {
+            type: "bar",
+            data: firstData,
+            yAxisIndex: 0,
+            itemStyle: {
+              normal: {
+                color: new this.$echarts.graphic.LinearGradient( 0, 0, 0, 1,
+                  [
+                    {
+                      offset: 0,
+                      color: "rgba(15, 106, 134, 1)", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "rgba(28, 186, 233, 1)", // 100% 处的颜色
+                    },
+                  ],
+                  false
+                ),
+              },
+            },
+          },
+          {
+            type: "bar",
+            data: secondData,
+            yAxisIndex: 1,
+            itemStyle: {
+              normal: {
+                color: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1,
+                  [
+                    {
+                      offset: 0,
+                      color: "rgba(194, 92, 61, 1)", // 0% 处的颜色
+                    },
+                    {
+                      offset: 1,
+                      color: "rgba(250, 205, 145, 1)", // 100% 处的颜色
+                    },
+                  ],
+                  false
+                ),
+              },
+            },
+          },
+        ],
+      }
+      chartsImage.clear();
+      chartsImage.setOption(option);
+    },
+    // 判断按钮权限信息
+    showButton(str) {
+      const pinia = buttonPinia();
+      return pinia.$state.buttonInfo.includes(str);
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "@/style/layout-main.scss";
+
+.main_content_chart {
+  position: relative;
+  height: 50%;
+
+  &:first-child {
+    &::before {
+      position: absolute;
+      padding-bottom: 10px;
+      width: 100%;
+      content: '| 月生产环比';
+      color: #20E8F1;
+      top: 0;
+      border-bottom: 1px solid #18499D;
+    }
+  }
+
+  &:last-child {
+    &::before {
+      position: absolute;
+      padding-bottom: 10px;
+      width: 100%;
+      content: '| 实际生产数据与计划生产量对比';
+      color: #20E8F1;
+      top: 0;
+      border-bottom: 1px solid #18499D;
+    }
+  }
+}
+</style>
diff --git a/web/src/views/DuctpiecePLM/DuctProduct/ProductIndex.vue b/web/src/views/DuctpiecePLM/DuctProduct/ProductIndex.vue
new file mode 100644
index 0000000..0130282
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/DuctProduct/ProductIndex.vue
@@ -0,0 +1,652 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="projectId" clearable placeholder="请选择项目" @change="changeHeaderProject">
+          <el-option
+            v-for="item in projectData"
+            :key="item.proId"
+            :label="item.proName"
+            :value="item.proId">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">环号:</span>
+        <el-input v-model="ringNum" clearable placeholder="请输入环号"></el-input>
+      </div>
+      <div class="header_item">
+        <span class="header_label">生产班组:</span>
+        <el-select v-model="groupId" clearable placeholder="请选择生产班组">
+          <el-option
+            v-for="item in groupData"
+            :key="item.groupId"
+            :label="item.groupName"
+            :value="item.groupId">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">质量标注:</span>
+        <el-select v-model="checkResult" clearable placeholder="请选择质量标注">
+          <el-option label="合格" :value="1"></el-option>
+          <el-option label="不合格" :value="2"></el-option>
+          <el-option label="报废" :value="3"></el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">配筋:</span>
+        <el-select v-model="reinforcement" clearable placeholder="请选择配筋">
+          <el-option
+            v-for="item in reinforcementData"
+            :key="item.hasSteel"
+            :label="item.dictName"
+            :value="item.hasSteel">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">注浆孔:</span>
+        <el-select v-model="groutingHoles" clearable placeholder="请选择注浆孔">
+          <el-option
+            v-for="item in groutingHolesData"
+            :key="item.groutingHoles"
+            :label="item.dictName"
+            :value="item.groutingHoles">
+          </el-option>
+        </el-select> 
+      </div>
+      <div class="header_item">
+        <span class="header_label">块号:</span>
+        <el-select v-model="blockNum" clearable placeholder="请选择块号">
+          <el-option
+            v-for="item in blockNumData"
+            :key="item.blockNum"
+            :label="item.dictName"
+            :value="item.blockNum">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">入模时间:</span>
+        <el-date-picker
+          v-model="inModTime"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd">
+        </el-date-picker>
+      </div>
+      <!-- <div class="header_item">
+        <span class="header_label">浇筑日期:</span>
+        <el-date-picker
+          v-model="pouringTime"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd">
+        </el-date-picker>
+      </div> -->
+      <div class="header_item">
+        <span class="header_label">质检时间:</span>
+        <el-date-picker
+          v-model="checkTime"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd">
+        </el-date-picker>
+      </div>
+      <div class="header_item">
+        <el-button v-if="showButton('search')" icon="el-icon-search" @click="searchDuctpiecePLMList(true)">查询</el-button>
+        <el-button v-if="showButton('insert')" icon="el-icon-download" @click="propInsert()">新增管片</el-button>
+        <el-button v-if="showButton('insert')" icon="el-icon-download" @click="exportExcel()">导出Excel</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <el-table
+        v-loading="loading"
+        :data="ductpieceList"
+        height="100%">
+        <el-table-column label="序号" width="60" align="center">
+          <template #default="scope">
+            <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="ringNum" label="环号" align="center"></el-table-column>
+        <el-table-column prop="proName" label="项目名称" align="center"></el-table-column>
+        <el-table-column prop="pipeNum" label="管片编号" align="center"></el-table-column>
+        <el-table-column prop="turnName" label="转向" align="center"></el-table-column>
+        <el-table-column prop="reinforcementName" label="配筋" align="center"></el-table-column>
+        <el-table-column prop="groutingHolesName" label="注浆孔" align="center"></el-table-column>
+        <el-table-column prop="blockNumName" label="块号" align="center"></el-table-column>
+        <el-table-column prop="mouldNum" label="模具" align="center"></el-table-column>
+        <el-table-column prop="intoModTime" label="入模时间" align="center"></el-table-column>
+        <!-- <el-table-column prop="pouringTime" label="浇筑时间" align="center"></el-table-column> -->
+        <el-table-column prop="checkTime" label="质检时间" align="center"></el-table-column>
+        <el-table-column prop="groupName" label="生产班组" align="center"></el-table-column>
+        <el-table-column label="质量标注" align="center">
+          <template #default="{ row }">
+            <div>
+               {{ row.checkResult == 0 ? '未质检' : row.checkResult == 1 ? '合格' : row.checkResult == 2 ? '不合格' : row.checkResult == 3 ? '报废' : ''}}
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center" width="300">
+          <template #default="{ row }">
+            <template v-if="showButton('update') && row.checkResult !== 1">
+              <el-button class="table_btn" size="mini" @click="propIssue(row)">存在问题</el-button>
+            </template>
+            <el-button class="table_btn" size="mini" v-if="showButton('update') && row.checkResult == 0" @click="propUpdate(row)">修改环号</el-button>
+            <el-button class="table_btn" size="mini" v-if="showButton('delete')" @click="propCheckHistory(row)">质量追溯</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+    <el-dialog
+      class="prop_dialog"
+      title="存在问题"
+      :visible.sync="asyncDuctPiece"
+      width="35%">
+      <el-form ref="form" :model="formDuctPiece" :rules="rulesDuctPiece" label-width="auto" class="rule_form">
+        <el-form-item label="质检结果:">
+          <span class="issue_status">{{checkResultStr}}</span>
+        </el-form-item>
+        <el-form-item label="存在问题:">
+          <el-input 
+            v-model="formDuctPiece.existProblem" 
+            type="textarea"
+            disabled
+            placeholder="请输入存在问题"></el-input>
+        </el-form-item>
+        <el-form-item label="问题图片:">
+          <div class="problem_content">
+            <el-image
+              v-for="item in fileList"
+              :key="item.id"
+              class="problem_image"
+              :src="item.url">
+            </el-image>
+          </div>
+        </el-form-item>
+        <el-form-item label="问题处理结果:">
+          <el-input 
+            v-model="formDuctPiece.exeProResult" 
+            type="textarea"
+            clearable 
+            placeholder="请输入问题处理结果"></el-input>
+        </el-form-item>
+        <el-form-item label="备注:">
+          <el-input 
+            v-model="formDuctPiece.exeProNote" 
+            type="textarea"
+            clearable 
+            placeholder="请输入备注"
+            maxlength="200"
+            show-word-limit></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="asyncDuctPiece = false">取 消</el-button>
+        <el-button class="submit_btn" @click="submitInsertForm()">提 交</el-button>
+      </div>
+    </el-dialog>
+    <!-- 质量追溯 -->
+    <el-dialog
+      class="prop_dialog"
+      title="质量追溯"
+      :visible.sync="asyncRetrospect"
+      width="70%">
+      <div class="retrospect_content">
+        <div class="retrospect_content_title">
+          钢筋笼信息
+        </div>
+        <div class="retrospect_content_table">
+          <div 
+            class="table_item" 
+            :style="{width: `calc(100% / ${asyncCageInfo.length})`}"
+            v-for="item in asyncCageInfo"
+            :key="item.id">
+            <div class="table_item_chunk table_th">{{item.label}}</div>
+            <div class="table_item_chunk table_td">{{ 
+              item.value === 'steelCheckResult' ? showCheckResult(retrospectInfo[item.value]) : retrospectInfo[item.value]}}
+            </div>
+          </div>
+        </div>
+        <div class="retrospect_content_title">
+          模具信息
+        </div>
+        <div class="retrospect_content_table">
+          <div 
+            class="table_item" 
+            :style="{width: `calc(100% / ${asyncMouldInfo.length})`}"
+            v-for="item in asyncMouldInfo"
+            :key="item.id">
+            <div class="table_item_chunk table_th">{{item.label}}</div>
+            <div class="table_item_chunk table_td">{{retrospectInfo[item.value]}}</div>
+          </div>
+        </div>
+        <div class="retrospect_content_title">
+          管片信息
+        </div>
+        <div class="retrospect_content_table">
+          <div 
+            class="table_item" 
+            :style="{width: `calc(100% / ${asyncDuctpieceInfo.length})`}"
+            v-for="item in asyncDuctpieceInfo"
+            :key="item.id">
+            <div class="table_item_chunk table_th">{{item.label}}</div>
+            <div class="table_item_chunk table_td">{{retrospectInfo[item.value]}}</div>
+          </div>
+        </div>
+      </div>
+    </el-dialog>
+    <el-dialog
+      class="prop_dialog"
+      :title="asyncTitle ? '新增管片' : '修改环号'"
+      :visible.sync="asyncInsert"
+      width="35%">
+      <el-form ref="formInsert" :model="formInsert" :rules="rulesInsert" label-width="auto" class="rule_form">
+        <el-form-item label="项目名称:" prop="proId" v-if="asyncTtile">
+          <el-select v-model="formInsert.proId" clearable placeholder="请选择项目信息" @change="getAllSteelPipeData">
+            <el-option
+              v-for="item in projectData"
+              :key="item.proId"
+              :label="item.proName"
+              :value="item.proId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="环号:" prop="ringNum">
+          <el-input v-model="formInsert.ringNum" clearable placeholder="请输入环号"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="asyncInsert = false">取 消</el-button>
+        <el-button class="submit_btn" @click="asyncTitle ? submitInsertPipe() : submitUpdatePipe()">提 交</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { cageInfo, mouldInfo, ductpiedceInfo } from '../file/retrospect';
+import { buttonPinia } from '../../../pinia';
+import { downLoadFile, throttle } from '../../../plugins/public';
+  export default {
+    data() {
+      return {
+        projectId: '',
+        projectData: [],
+        ringNum: '', // 环号
+        groupId: '', // 班组
+        groupData: [], // 班组信息
+        checkResult: '', // 质量标注
+        reinforcement: '', // 配筋
+        reinforcementData: [], // 配筋信息
+        groutingHoles: '', // 注浆孔
+        groutingHolesData: [], // 注浆孔信息
+        blockNum: '', // 块号
+        blockNumData: [], // 块号信息
+        inModTime: '', // 入模时间
+        pouringTime: '', // 浇筑时间
+        checkTime: '', // 质检时间
+        pageNum: 1,
+        pageSize: 10,
+        total: 0,
+        loading: false,
+        ductpieceList: [],
+        asyncDuctPiece: false, // 存在问题弹窗
+        formDuctPiece: {}, // 表单信息
+        rulesDuctPiece: {}, // 表单校验规则
+        issueType: '',
+        asyncRetrospect: false, // 质量追溯弹窗
+        asyncCageInfo: cageInfo, // 钢筋笼信息
+        asyncMouldInfo: mouldInfo, // 模具信息
+        asyncDuctpieceInfo: ductpiedceInfo, // 管片信息
+        retrospectInfo: {},// 质量追溯信息
+        pipeId: '',
+        checkResultStr: '',
+        asyncTitle: true,
+        asyncInsert: false,
+        formInsert: {},
+        rulesInsert: {
+          proId: [{
+            required: true,
+            message: '请选择项目名称',
+            trigger: 'blur'
+          }],
+          ringNum: [{
+            required: true,
+            message: '请输入环号',
+            trigger: 'blur'
+          }],
+        },
+        proData: [],
+        steelData: [],
+        mouldData: [],
+      }
+    },
+    mounted() {
+      this.getAllProjects();
+      this.getAllGroupData();
+      this.searchDuctpiecePLMList(true);
+    },
+    methods: {
+      // 根据项目获取钢筋笼 模具信息
+      async getAllSteelPipeData(proId) {
+        this.steelData = [];
+        this.mouldData = [];
+        const { data } = await this.$api.DuctpiecePLM.getAllSteelPipeData({
+          proId: proId
+        });
+        this.steelData = data.steel;
+        this.mouldData = data.mod;
+      },
+      // 获取全部班组
+      async getAllGroupData() {
+        const { data } = await this.$api.DuctpiecePLM.getAllGroupData();
+        this.groupData = data;
+      },
+      // 获取全部项目
+      async getAllProjects() {
+        const { data } = await this.$api.Engineer.getAllProjects();
+        this.projectData = data;
+      },
+      // 查询管片信息
+      searchDuctpiecePLMList(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        this.loading = true;
+        this.ductpieceList = [];
+        this.$api.DuctpiecePLM.searchDuctpiecePLMList({
+          pageNum: this.pageNum,
+          pageSize: this.pageSize,
+          proId: this.projectId,
+          ringNum: this.ringNum,
+          groupId: this.groupId,
+          checkResult: this.checkResult,
+          reinforcement: this.reinforcement,
+          groutingHoles: this.groutingHoles,
+          blockNum: this.blockNum,
+          inModStartTime: this.inModTime ? this.inModTime[0] + ' 00:00:00' : '',
+          inModEndTime: this.inModTime ? this.inModTime[1] + ' 23:59:59' : '',
+          pouringStartTime: this.pouringTime ? this.pouringTime[0] + ' 00:00:00' : '',
+          pouringEndTime: this.pouringTime ? this.pouringTime[1] + ' 23:59:59' : '',
+          checkStartTime: this.checkTime ? this.checkTime[0] + ' 00:00:00' : '',
+          checkEndTime: this.checkTime ? this.checkTime[1] + ' 23:59:59' : ''
+        }).then((res) => {
+          if(res.success) {
+            this.total = res.data.total;
+            this.ductpieceList = res.data.list;
+          }
+          this.loading = false;
+        }).catch(() => {
+          this.loading = false;
+        })
+      },
+      // 打开新增管片信息
+      propInsert() {
+        this.asyncTitle = true;
+        this.asyncInsert = true;
+        this.getAllProjects();
+      },
+      // 打开修改环号信息
+      propUpdate(row) {
+        this.asyncTitle = false;
+        this.asyncInsert = true;
+        this.$set(this.formInsert, 'pipeNum', row.pipeNum);
+        this.$set(this.formInsert, 'ringNum', row.ringNum);
+      },
+      // 导出Excel
+      exportExcel() {
+        this.$api.System.GETEXPORTTOKENDATA({
+          ringNum: this.ringNum,
+          groupId: this.groupId,
+          checkResult: this.checkResult,
+          reinforcement: this.reinforcement,
+          groutingHoles: this.groutingHoles,
+          blockNum: this.blockNum,
+          inModStartTime: this.inModTime[0],
+          inModEndTime: this.inModTime[1],
+          pouringStartTime: this.pouringTime[0],
+          pouringEndTime: this.pouringTime[1],
+          checkStartTime: this.checkTime[0],
+          checkEndTime: this.checkTime[1]
+        }).then((res) => {
+          if(res.success) {
+            downLoadFile(res.data, '/m/pipeInfo/export');
+          }
+        })
+      },
+      // 打开存在问题
+      propIssue(row) {
+        this.pipeId = row.pipeId
+        this.checkResultStr = row.checkResultStr;
+        this.issueType = row.type;
+        this.asyncDuctPiece = true;
+        this.$api.DuctpiecePLM.getProblemInfo({
+          pipeId: row.pipeId
+        }).then((res) => {
+          if(res.success) {
+            this.$set(this.formDuctPiece, 'pipeCheckId', res.data.pipeCheckId);
+            this.$set(this.formDuctPiece, 'existProblem', res.data.existProblem);
+            this.$set(this.formDuctPiece, 'exeProResult', res.data.exeProResult);
+            this.$set(this.formDuctPiece, 'exeProNote', res.data.exeProNote);
+            this.fileList = res.data.files.map((item, index) => {
+              return {
+                id: index + 1,
+                url: `https://pipe.thhy-tj.com/${item}`
+              }
+            })
+          }
+        })
+      },
+      // 打开质量追溯
+      propCheckHistory(row) {
+        this.asyncRetrospect = true;
+        this.retrospectInfo = {};
+        this.$api.DuctpiecePLM.getCheckHistoryInfo({
+          pipeId: row.pipeId
+        }).then((res) => {
+          if(res.success) {
+            this.retrospectInfo = res.data;
+          }
+        })
+      },
+      // 提交存在问题
+      submitInsertForm: throttle(function() {
+        const params = Object.assign({}, this.formDuctPiece);
+        params.checkResultStr = this.checkResultStr;
+        params.pipeId = this.pipeId;
+        this.$api.DuctpiecePLM.insertIssueInfo(params).then((res) => {
+          if(res.success) {
+            this.asyncDuctPiece = false;
+            this.searchDuctpiecePLMList(true);
+            this.$message.success('添加成功!');
+          } else {
+            this.$message.warning(res.statusMsg);
+          }
+        })
+      }, 3000),
+      // 提交新增管片信息
+      submitInsertPipe: throttle(function() {
+        this.$refs.formInsert.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.formInsert);
+            this.$api.DuctpiecePLM.insertPipeData(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncInsert = false;
+                this.searchDuctpiecePLMList(true);
+                this.$message.success('新增成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 提交修改环号信息
+      submitUpdatePipe: throttle(function() {
+        this.$refs.formInsert.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.formInsert);
+            this.$api.DuctpiecePLM.updataRingNumData(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncInsert = false;
+                this.searchDuctpiecePLMList(true);
+                this.$message.success('修改成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 
+      showCheckResult(value) {
+        return !value ? '' : value == 1 ? '合格' : '存在问题';
+      },
+      // 根据项目获取尺寸 配筋 块号信息
+      changeHeaderProject(data) {
+          this.blockNum = '';
+          this.reinforcement = '';
+          this.groutingHoles = '';
+          this.groutingHolesData = [];
+          this.blockNumData = [];
+          this.reinforcementData = [];
+        if(data) {
+          this.$api.Basics.getProjectSystemInfoData({
+            proId: data
+          }).then((res) => {
+            this.groutingHolesData = res.data.proGroutings;
+            this.blockNumData = res.data.proBloks;
+            this.reinforcementData = res.data.proHas;
+          })
+        }
+      },
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchDuctpiecePLMList();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchDuctpiecePLMList();
+      },
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },
+    },
+    watch: {
+      asyncDuctpieceInfo(bol) {
+        if(!bol) {
+          this.formDuctPiece = {};
+          this.pipeId = '';
+          this.checkResultStr = '';
+          this.fileList = [];
+        }
+      },
+      asyncInsert(bol) {
+        if(!bol) {
+          this.steelData = [];
+          this.mouldData = [];
+          this.formInsert = {};
+          this.$refs.formInsert.resetFields();
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '../../../style/layout-main.scss';
+
+.issue_status {
+  color: #F42829;
+}
+
+.retrospect_content {
+  padding: 0 0 20px 0;
+
+  .retrospect_content_title {
+    position: relative;
+    padding: 0 15px 15px;
+    font-size: 16px;
+    font-weight: 600;
+    color: #FFF;
+    border-bottom: 1px solid #0d5274;
+
+    &::before {
+      content: "";
+      position: absolute;
+      top: 50%;
+      left: 0;
+      transform: translateY(-85%);
+      width: 3px;
+      height: 50%;
+      background: #18F6F8;
+    }
+  }
+
+  .retrospect_content_table {
+    display: flex;
+    margin: 10px 10px 10px 0;
+
+    .table_item {
+      border: 1px solid #1CB7E0;
+      border-right: none;
+
+      &:last-child {
+        border-right: 1px solid #1CB7E0;
+      }
+
+      .table_item_chunk {
+        padding: 10px;
+        color: #18F6F8;
+        text-align: center;
+      }
+
+      .table_th {
+        border-bottom: 1px solid #1CB7E0;
+        background: #082F57;
+      }
+    }
+  }
+}
+
+.problem_content {
+  display: flex;
+  flex-wrap: wrap;
+
+  .problem_image {
+    margin: 5px 10px;
+    width: 100px;
+    height: 100px;
+  }
+}
+
+::v-deep .el-date-editor .el-range-separator {
+  color: #fff !important;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/DuctSpray.vue b/web/src/views/DuctpiecePLM/DuctSpray.vue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/DuctSpray.vue
diff --git a/web/src/views/DuctpiecePLM/PlanManage/DuctForward.vue b/web/src/views/DuctpiecePLM/PlanManage/DuctForward.vue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/PlanManage/DuctForward.vue
diff --git a/web/src/views/DuctpiecePLM/PlanManage/DuctPlan.vue b/web/src/views/DuctpiecePLM/PlanManage/DuctPlan.vue
new file mode 100644
index 0000000..7cbf4d0
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/PlanManage/DuctPlan.vue
@@ -0,0 +1,486 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="search.proId" placeholder="请选择项目名称" clearable filterable>
+            <el-option
+            v-for="item in optionsProject"
+            :key="item.proId"
+            :label="item.proName"
+            :value="item.proId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">年份:</span>
+        <el-date-picker
+            v-model="search.planYear"
+            value-format="yyyy"
+            type="year"
+            placeholder="请选择年份">
+        </el-date-picker>
+      </div>
+      <div class="header_item">
+        <el-button icon="el-icon-search" v-if="showButton('search')" @click="searchButtonInfo(true)">查询</el-button>
+        <el-button class="search_btn" icon="el-icon-plus" v-if="showButton('insert')" @click="insertProp">新增</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+        <div style="overflow-y:auto;overflow-x:hidden;height:calc(100% - 5px)">
+            <div class="plan_main_card" v-for="(item,index) in dataList" :key="index">
+                <div class="plan_main_header">
+                    <div class="plan_header_left">
+                        <span class="plan_header_one">{{item.proName}}</span>
+                        <span>{{item.planYear}}年</span>
+                        <span>{{item.sizeName}}</span>
+                    </div>
+                    <div class="plan_header_right">
+                        <el-button style="background-image:none;border:1px solid #38B2FA;border-radius:5px;padding:5px 10px;" :size="size" v-if="showButton('update')" class="table_btn" @click="updateProp(item)">修改</el-button>
+                        <el-button style="background-image:none;border:1px solid #FD494B;background-color:#434F69;border-radius:5px;padding:5px 10px;" :size="size" class="delete_btn" v-if="showButton('delete')" @click="deleteInfo(item)">删除</el-button>
+                    </div>
+                </div>
+                <div class="plan_main_content">
+                    <div class="plan_content_items">
+                        <div class="plan_content_title">月份</div>
+                        <div class="plan_content_datas" style="background-color:#052C55;color:#39B5FE" v-for="(item,index) in numLists" :key="index">{{item}}</div>
+                    </div>
+                    <div class="plan_content_items" style="margin-bottom:0px;border-bottom-color:transparent;">
+                        <div class="plan_content_title">管片需求数量(环)</div>
+                        <div class="plan_content_datas" v-for="(iten,index) in item.planProductArray" :key="index">{{iten.split('.')[0]}}</div>
+                    </div>
+                    <div class="plan_content_items">
+                        <div class="plan_content_title">已生产管片数量(环)</div>
+                        <div class="plan_content_datas" v-for="(it,index) in item.productedArray" :key="index">{{it.split('.')[0]}}</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+    <el-dialog
+      class="prop_dialog"
+      :title="asyncTitle===true ? '新增' :asyncTitle===false ? '修改':'查看'"
+      :close-on-click-modal="false"
+      :visible.sync="asyncVisible"
+      width="35%">
+      <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="auto" class="rule_form">
+        <el-form-item label="项目名称:" prop="proId">
+          <el-select v-model="ruleForm.proId" placeholder="请选择项目名称" :disabled="disabled" @change="changeSizes" clearable>
+                <el-option
+                v-for="item in optionsProject"
+                :key="item.proId"
+                :label="item.proName"
+                :value="item.proId">
+                </el-option>
+            </el-select>
+        </el-form-item>
+        <el-form-item label="尺寸:" prop="size">
+          <el-select v-model="ruleForm.size" placeholder="请选择尺寸" :disabled="disabled">
+            <el-option
+                v-for="item in optionsSize"
+                :key="item.sizeId"
+                :label="item.sizeName"
+                :value="item.sizeId">
+            </el-option>
+        </el-select>
+        </el-form-item>
+        <el-form-item label="年份:" prop="planYear">
+          <el-date-picker
+            v-model="ruleForm.planYear"
+            value-format="yyyy"
+            :disabled="disabled"
+            type="year"
+            placeholder="请选择年份">
+          </el-date-picker>
+        </el-form-item>
+        <div class="months_items">
+            <div v-for="(item,index) in monthLists" :key="index" class="month_index">
+                <el-input placeholder="请输入" v-model="item.planProduct" type="number" :disabled="disabled">
+                    <template slot="prepend">{{item.month}}月</template>
+                </el-input>
+            </div>
+            <div class="months_nums">
+                <span>合计:</span>
+                <span style="color:#18F8F9;font-size:20px;font-weight:600;margin-left:5px">{{allMonths}}</span>
+                <span>环</span>
+            </div>
+        </div>
+      </el-form>
+      <div slot="footer" v-if="asyncTitle !=='see'">
+        <el-button @click="asyncVisible = false">取 消</el-button>
+        <el-button class="submit_btn" @click="asyncTitle ? submitInsert() : submitUpdate()">提 交</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia/index';
+import { throttle, changeSize } from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+  export default {
+    data() {
+      return {
+        size: changeSize(), // 组件尺寸
+        pageNum: 1,
+        pageSize: 10,
+        search:{},//查询条件
+        total: 0,
+        disabled:false,//是否禁止修改
+        loading: false,
+        allMonths:null,//计算出来的总数
+        rowId:'',//某一行id
+        dataList: [], //管片生产计划信息
+        optionsProject:[],//项目名称
+        asyncTitle: true, // 对话框title 新增:true  修改:false
+        asyncVisible: false, // 添加 修改对话框
+        ruleForm: {}, // 按钮表单
+        rules: {
+          proId: [{
+            required: true,
+            message: '请选择项目名称',
+            trigger: 'change'
+          }],
+          size: [{
+            required: true,
+            message: '请选择尺寸',
+            trigger: 'change'
+          }],
+          planYear: [{
+            required: true,
+            message: '请选择年份',
+            trigger: 'change'
+          }],
+        },
+        optionsSize:[],//尺寸
+        optionsHass:[],//配筋
+        optionsBlocks:[],//块号
+        monthLists:[],//弹框中的月
+        numLists:[1,2,3,4,5,6,7,8,9,10,11,12,'合计'],
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+      that.searchButtonInfo(true);
+      that.getAllProjects()
+    },
+    watch:{
+       'monthLists':{
+        handler:function(val){
+            let allNum=0
+            val.map(item =>{
+                allNum+=item.planProduct*1
+            })
+            this.allMonths = allNum
+            return this.allMonths
+        },
+        deep:true
+       },
+       asyncVisible(bol) {
+        if(!bol) {
+          this.ruleForm = {};
+          this.$refs.ruleForm.resetFields();
+        }
+      }
+    },
+    methods: {
+    //获取管片计划月份
+      getPlanMonth(val){
+        this.$api.Ducts.getMonthsList({planId:val}).then(res=>{
+            if(res.statusMsg==='ok'){
+                this.monthLists = res.data.monthList
+                this.allMonths = res.data.planProduct
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+      },
+     //获得所有项目名称
+     getAllProjects(){
+        let obj = {
+            pageNum: 1,
+            pageSize: 100000000
+        }
+        this.$api.Engineer.searchProjects(obj).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsProject = res.data.list
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+     },
+     //通过选择项目选择尺寸
+     changeSizes(val){
+      this.ruleForm.size = ""
+      this.$api.Reinforce.searchProjectSize({proId:val,pageNum: 1,
+          pageSize:100000000}).then(res=>{
+        if(res.statusMsg === 'ok'){
+          if(this.ruleForm.proId ===""){
+            this.optionsSize = []
+          }else{
+            this.optionsSize = res.data.list
+          }
+        }else{
+            this.$message.warning(res.statusMsg)
+        }
+      })
+     },
+      // 查询按钮列表信息
+      searchButtonInfo(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        let params = Object.assign({},this.search,{
+          pageNum: this.pageNum,
+          pageSize: this.pageSize
+        })
+        this.loading = true;
+        this.$api.Ducts.searchDuctPlan(params).then((res) => {
+          if(res.statusMsg === 'ok') {
+            this.total = res.data.total;
+            this.dataList = res.data.list;
+            this.loading = false;
+          }else{
+            this.$message.warning(res.statusMsg)
+          }
+        })
+      },
+      // 新增按钮信息
+      insertProp() {
+        this.asyncTitle = true;
+        this.asyncVisible = true;
+        this.disabled = false
+        this.getPlanMonth()
+      },
+      // 修改按钮信息
+      updateProp(row) {
+        this.$api.Reinforce.searchProjectSize({proId:row.proId,pageNum: 1,
+            pageSize:100000000}).then(res=>{
+          if(res.statusMsg === 'ok'){
+              this.optionsSize = res.data.list
+          }else{
+              this.$message.warning(res.statusMsg)
+          }
+        })
+        this.asyncTitle = false;
+        this.asyncVisible = true;
+        this.disabled = false
+        this.ruleForm = row
+        this.getPlanMonth(row.planId)
+        this.$set(this.ruleForm,'planYear',row.planYear+'')
+        this.rowId = row.planId
+      },
+      //查看按钮
+      detailaProp(row){
+        this.asyncTitle = 'see'
+        this.asyncVisible = true;
+        this.disabled = true
+        this.ruleForm = row
+        this.$set(this.ruleForm,'planYear',row.planYear+'')
+        this.getPlanMonth(row.planId)
+      },
+      // 删除按钮信息
+      deleteInfo(row) {
+        this.$confirm("该操作将删除该信息,是否继续删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+       })
+       .then(() => {
+         this.$api.Ducts.deleteDuctPlan({planId: row.planId})
+        .then(res => {
+          if(res.statusMsg === 'ok') {
+            this.searchButtonInfo(true);
+            this.$message.success("删除成功!");
+          } else {
+            this.$message.warning(res.statusMsg);
+          }
+        })
+       })
+       .catch(() => {
+         this.$message.warning("您已取消");
+       })
+      },
+      // 提交添加按钮信息
+      submitInsert: throttle(function() {
+        this.$refs.ruleForm.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.ruleForm);
+            params.monthList = this.monthLists
+            params.planProduct = this.allMonths
+            this.$api.Ducts.insertDuctPlan(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncVisible = false;
+                this.searchButtonInfo(true);
+                this.$message.success('添加成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 提交修改按钮信息
+      submitUpdate: throttle(function() {
+        this.$refs.ruleForm.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.ruleForm);
+            params.monthList = this.monthLists
+            params.planProduct = this.allMonths
+            this.$api.Ducts.updateDuctPlan(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncVisible = false;
+                this.searchButtonInfo(true);
+                this.$message.success('添加成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },      
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchButtonInfo();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchButtonInfo();
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '../../../style/layout-main.scss';
+
+.months_items{
+   display: flex;
+    flex-wrap: wrap;
+
+    .month_index{
+        margin-left: 10px;
+        margin-bottom: 10px;
+        max-width: calc(100%/3 - 10px);
+        /deep/.el-input-group__prepend{
+            color: #19F6F8;
+            background-color: #122558;
+            border-color: #1B428F;
+        }
+    }
+    .months_nums{
+        width: 100%;
+        height: 50px;
+        margin-bottom: 24px;
+        border-radius: 3px;
+        background-color: #0B5274;
+        display: flex;
+        align-items: center;
+        span{
+            margin-left: 15px;
+            color: #fff;
+        }
+    }
+}
+.plan_main_card{
+    width: calc(100% - 36px);
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+    border-bottom-left-radius: 6px;
+    border-bottom-right-radius: 6px;
+    background-color: #031A46;
+    margin: 0px 5px 24px 0px;
+    box-shadow:0px 0px 8px 0px #0C4F79;
+
+    .plan_main_header{
+        width: 100%;
+        height: 48px;
+        border-top-left-radius: 6px;
+        border-top-right-radius: 6px;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        background-color: rgba(57,181,254,0.3);
+        .plan_header_left{
+            display: flex;
+            span{
+                flex: none;
+                color: #39B5FE;
+                margin-left: 20px;
+                font-size: 16px;
+                font-weight: 600;
+            }
+            .plan_header_one{
+                margin-left: 40px;
+                position: relative;
+                &::before{
+                    position: absolute;
+                    left: -14px;
+                    top: -1px;
+                    content: '';
+                    width: 5px;
+                    height: 20px;
+                    background-color: #39B5FE;
+                }
+            }
+        }
+        .plan_header_right{
+            margin-right: 15px;
+        }
+    }
+    .plan_main_content{
+        width: 100%;
+        height: calc(100% - 30px);
+        background-color:#031A46;
+        padding-top: 20px;
+        padding-bottom: 10px;
+        border-bottom-left-radius: 6px;
+        border-bottom-right-radius: 6px;
+
+
+        .plan_content_items{
+            display: flex;
+            border: 1px solid #39B5FE;
+            margin: 0px 15px 8px 15px;
+
+            .plan_content_title{
+                width: 145px;
+                padding: 12px 0px;
+                flex: none;
+                color: #39B5FE;
+                text-align: center;
+                background-color: #052C55;
+            }
+            .plan_content_datas{
+                flex: 1;
+                padding: 12px 0px;
+                color: #fff;
+                text-align: center;
+                border-left: 1px solid #1CB7E0;
+            }
+        }
+    }
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ProductTerminal/ReinsInfoPrint.vue b/web/src/views/DuctpiecePLM/ProductTerminal/ReinsInfoPrint.vue
new file mode 100644
index 0000000..0cca7d1
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ProductTerminal/ReinsInfoPrint.vue
@@ -0,0 +1,435 @@
+<template>
+  <div class="main" v-if="!showPrint">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="search.proId" placeholder="请选择项目名称" clearable filterable @change="getAllType">
+            <el-option
+            v-for="item in optionsProject"
+            :key="item.proId"
+            :label="item.proName"
+            :value="item.proId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">尺寸:</span>
+        <el-select v-model="search.sizeId" placeholder="请选择尺寸" clearable>
+            <el-option
+                v-for="item in optionsSize"
+                :key="item.dictId"
+                :label="item.dictName"
+                :value="item.dictId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">配筋:</span>
+        <el-select v-model="search.reinforcementId" placeholder="请选择配筋" clearable>
+            <el-option
+                v-for="item in optionsHass"
+                :key="item.dictId"
+                :label="item.dictName"
+                :value="item.dictId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <el-button icon="el-icon-search" v-if="showButton('search')" @click="searchButtonInfo(true)">查询</el-button>
+        <el-button class="search_btn" icon="el-icon-plus" v-if="showButton('insert')" @click="insertProp">新增</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <el-table
+        v-loading="loading"
+        :data="dataList"
+        height="100%">
+        <el-table-column align="center" label="序号" width="60">
+          <template #default="scope">
+            <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="proName" label="项目名称" align="center" show-overflow-tooltip></el-table-column>
+        <el-table-column prop="sizeName" label="尺寸" align="center"></el-table-column>
+        <el-table-column prop="reinforcementName" label="配筋" align="center"></el-table-column>
+        <el-table-column prop="blockName" label="块号" align="center"></el-table-column>
+        <el-table-column prop="printNum" label="数量(个)" align="center"></el-table-column>
+        <el-table-column prop="realName" label="创建人" align="center"></el-table-column>
+        <el-table-column prop="createTime" label="创建时间" align="center" show-overflow-tooltip></el-table-column>
+        <el-table-column label="操作" align="center" width="300">
+          <template #default="{ row }">
+            <el-button class="table_btn" size="mini" v-if="showButton('print')" @click="printProp(row)">打印</el-button>
+            <el-button class="delete_btn" size="mini" v-if="showButton('delete')" @click="deleteInfo(row)">删除</el-button>
+            <el-button class="table_btn" size="mini" v-if="showButton('print')" @click="showPrints(row)">查看打印信息</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- <div v-show="showAbtn"  v-for="(item,index) in printNums" :key="index"> -->
+      <!-- <a :id="`n${index}`" :href="`printpipe://1,${item.produceNumber}`"><p></p></a> -->
+    <!-- </div> -->
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+    <el-dialog
+      class="prop_dialog"
+      :title="asyncTitle ? '新增' : '修改'"
+      :close-on-click-modal="false"
+      :visible.sync="asyncVisible"
+      width="35%">
+      <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="auto" class="rule_form">
+        <el-form-item label="项目名称:" prop="proId">
+          <el-select v-model="ruleForm.proId" placeholder="请选择项目名称" @change="getAllType">
+                <el-option
+                v-for="item in optionsProject"
+                :key="item.proId"
+                :label="item.proName"
+                :value="item.proId">
+                </el-option>
+            </el-select>
+        </el-form-item>
+        <el-form-item label="尺寸:" prop="sizeId">
+          <el-select v-model="ruleForm.sizeId" placeholder="请选择尺寸" clearable>
+            <el-option
+                v-for="item in optionsSize"
+                :key="item.dictId"
+                :label="item.dictName"
+                :value="item.dictId">
+            </el-option>
+        </el-select>
+        </el-form-item>
+        <el-form-item label="配筋:" prop="reinforcementId">
+          <el-select v-model="ruleForm.reinforcementId" placeholder="请选择配筋" clearable>
+            <el-option
+                v-for="item in optionsHass"
+                :key="item.dictId"
+                :label="item.dictName"
+                :value="item.dictId">
+            </el-option>
+        </el-select>
+        </el-form-item>
+        <el-form-item label="块号:" prop="blockNum">
+          <el-select v-model="ruleForm.blockNum" placeholder="请选择块号" clearable>
+            <el-option
+                v-for="item in optionsBlocks"
+                :key="item.dictId"
+                :label="item.dictName"
+                :value="item.dictId">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="数量(个):" prop="printNum">
+           <el-input-number v-model="ruleForm.printNum" :min="0"></el-input-number>
+        </el-form-item>
+        <div class="nums_index">
+            <div class="nums_items" v-for="(item,index) in numLists" :key="index" @click="changeNum(item)">{{item}}</div>
+        </div>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="asyncVisible = false">取 消</el-button>
+        <el-button class="submit_btn" @click="asyncTitle ? submitInsert() : submitUpdate()">提 交</el-button>
+      </div>
+    </el-dialog>
+  </div>
+  <div v-else>
+    <reins-print :show-print.sync="showPrint" :rowsData.sync="rowsData"></reins-print>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia/index';
+import { throttle, changeSize} from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+import ReinsPrint from './components/ReinsPrint.vue'
+  export default {
+    components:{
+        ReinsPrint
+    },
+    data() {
+      return {
+        printNums:[],//循环打印多少次数组
+        showAbtn:true,//是否展示a标签
+        size: changeSize(), // 组件尺寸
+        pageNum: 1,
+        pageSize: 10,
+        search:{},//查询条件
+        total: 0,
+        loading: false,
+        showPrint:false,//是否展示打印页面
+        rowsData:null,//一行数据
+        dataList: [], //钢筋笼信息打印
+        optionsProject:[],//项目名称
+        asyncTitle: true, // 对话框title 新增:true  修改:false
+        asyncVisible: false, // 添加 修改对话框
+        ruleForm: {
+            printNum:0
+        }, // 按钮表单
+        rules: {
+          proId: [{
+            required: true,
+            message: '请选择项目名称',
+            trigger: 'change'
+          }],
+          sizeId: [{
+            required: true,
+            message: '请选择尺寸',
+            trigger: 'change'
+          }],
+          reinforcementId: [{
+            required: true,
+            message: '请选择配筋',
+            trigger: 'change'
+          }],
+          blockNum: [{
+            required: true,
+            message: '请选择块号',
+            trigger: 'change'
+          }],
+          printNum: [{
+            required: true,
+            message: '请输入数量',
+            trigger: 'blur'
+          }],
+        },
+        optionsSize:[],//尺寸
+        optionsHass:[],//配筋
+        optionsBlocks:[],//块号
+        numLists:[5,10,15,20,25,30,40,50,60,70,80,90],//数字列表
+      }
+    },
+    watch: {
+      asyncVisible(bol) {
+        if(!bol) {
+          this.ruleForm = {};
+          this.$refs.ruleForm.resetFields();
+        }
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+      that.searchButtonInfo(true);
+      that.getAllProjects()
+    },
+    methods: {
+      //执行去打印
+      gopPrints(numbers, arr){
+          const link = document.createElement('a');
+          link.id = `link`;
+          link.href = `printpipe://1,${arr[arr.length-1].produceNumber},${numbers}`
+          link.click()
+      },
+      //跳转打印页面
+      showPrints(row){
+        this.rowsData = row
+        this.showPrint = true
+      },
+     //选择个数
+     changeNum(value){
+        this.$set(this.ruleForm,'printNum',value)
+     },
+     //通过选择项目显示不同的尺寸配筋等
+     getAllType(val){
+        this.$set(this.search,'sizeId','')
+        this.$set(this.search,'reinforcementId','')
+        if(this.ruleForm.sizeId !==undefined){
+            this.$set(this.ruleForm,'sizeId','')
+        }
+        if(this.ruleForm.reinforcementId !==undefined){
+            this.$set(this.ruleForm,'reinforcementId','')
+        }
+        if(this.ruleForm.blockNum !==undefined){
+            this.$set(this.ruleForm,'blockNum','')
+        }
+        this.$api.Print.getTypePrints({proId:val,dictType:1}).then(res=>{
+            this.optionsSize = res.data
+        })
+        this.$api.Print.getTypePrints({proId:val,dictType:2}).then(res=>{
+            this.optionsHass = res.data
+        })
+        this.$api.Print.getTypePrints({proId:val,dictType:5}).then(res=>{
+            this.optionsBlocks = res.data
+        })
+     },
+     //获得所有项目名称
+     getAllProjects(){
+        let obj = {
+            pageNum: 1,
+            pageSize: 100000000
+        }
+        this.$api.Engineer.searchProjects(obj).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsProject = res.data.list
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+     },
+      // 查询按钮列表信息
+      searchButtonInfo(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        let params = Object.assign({},this.search,{
+          pageNum: this.pageNum,
+          pageSize: this.pageSize
+        })
+        this.loading = true;
+        this.$api.Print.searchBearPrint(params).then((res) => {
+          if(res.statusMsg === 'ok') {
+            this.total = res.data.total;
+            this.dataList = res.data.list;
+            this.loading = false;
+          }else{
+            this.$message.warning(res.statusMsg)
+          }
+        })
+      },
+      // 新增按钮信息
+      insertProp() {
+        this.asyncTitle = true;
+        this.asyncVisible = true;
+      },
+      // 打印按钮信息
+      printProp(val) {
+        this.$api.Print.printBears({steelPrintId:val.steelPrintId}).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.printNums = res.data;
+                this.gopPrints(val.printNum,this.printNums)
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+      },
+      // 删除按钮信息
+      deleteInfo(row) {
+        this.$confirm("该操作将删除该信息,是否继续删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+       })
+       .then(() => {
+         this.$api.Print.deleteBearPrint({steelPrintId: row.steelPrintId})
+        .then(res => {
+          if(res.statusMsg === 'ok') {
+            this.searchButtonInfo(true);
+            this.$message.success("删除成功!");
+          } else {
+            this.$message.warning(res.statusMsg);
+          }
+        })
+       })
+       .catch(() => {
+         this.$message.warning("您已取消");
+       })
+      },
+      // 提交添加按钮信息
+      submitInsert: throttle(function() {
+        this.$refs.ruleForm.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.ruleForm);
+            this.$api.Print.insertBearPrint(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncVisible = false;
+                this.searchButtonInfo(true);
+                this.$message.success('添加成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 提交修改按钮信息
+      submitUpdate: throttle(function() {
+        this.$refs.ruleForm.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.ruleForm);
+            this.$api.Print.updateDuctRaw(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncVisible = false;
+                this.searchButtonInfo(true);
+                this.$message.success('添加成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },      
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchButtonInfo();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchButtonInfo();
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '../../../style/layout-main.scss';
+.nums_index{
+    display: flex;
+    justify-content: space-between;
+    margin-left: 90px;
+    background-color: #122558;
+    border-radius: 4px;
+    padding: 10px 15px 10px 10px;
+    margin-bottom: 10px;
+    overflow: auto;
+    .nums_items{
+        width: 28px;
+        height: 28px;
+        text-align: center;
+        padding: 5px;
+        border: 1px solid #19F6F8;
+        border-radius: 4px;
+        color: #19F6F8;
+        margin-right: 5px;
+        flex: none;
+
+        &:hover{
+            cursor: pointer;
+            color: #fff;
+            background-color: #18CCD8;
+            border-color: #18CCD8;
+        }
+    }
+}
+//滚动条样式
+::-webkit-scrollbar {
+    width: 4px; 
+    height: 3px;   
+}
+::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    box-shadow: inset 0 0 5px #13497E;
+    background: transparent;
+}
+::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px transparent;
+    border-radius: 0;
+    background: transparent;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ProductTerminal/SegmentPrint.vue b/web/src/views/DuctpiecePLM/ProductTerminal/SegmentPrint.vue
new file mode 100644
index 0000000..55e50bd
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ProductTerminal/SegmentPrint.vue
@@ -0,0 +1,524 @@
+<template>
+  <div class="main" style="height:calc(100% - 60px)!important;">
+    <div class="main_header">
+        <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="search.proId" placeholder="请选择项目名称" clearable>
+            <el-option
+                v-for="item in optionsProject"
+                :key="item.proId"
+                :label="item.proName"
+                :value="item.proId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">环号:</span>
+        <el-input v-model="search.ringNum" :size="size" clearable placeholder="请输入环号"></el-input>
+      </div>
+      <div class="header_item">
+        <el-button icon="el-icon-search" v-if="showButton('print')" @click="searchButtonInfo(true)">查询</el-button>
+        <el-button :size="size" icon="el-icon-printer" v-if="showButton('print')" @click="printClick">打印</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <div :class="{'main_items':pitchIf !==item.pipeId,'main_items_pitch':pitchIf === item.pipeId}" v-for="(item,index) in dataList" :key="index" @click="changeItems(item)">
+        <div :class="{'main_items_top':pitchIf !==item.pipeId,'main_items_top_pitch':pitchIf === item.pipeId}">
+            <div class="main_item_header first_titles">
+                <div class="main_item_title">环号:</div>
+                <div class="main_item_datas">{{item.ringNum}}</div>
+            </div>
+            <div class="main_item_header">
+                <div class="main_item_title">项目名称:</div>
+                <div class="main_item_datas">{{item.proName}}</div>
+            </div>
+        </div>
+        <div :class="{'main_item_contents':pitchIf !==item.pipeId,'main_item_contents_pitch':pitchIf === item.pipeId}">
+            <div class="main_item_left">
+                <div style="width:180px;height:180px">
+                    <img :src="`${baseUrl}/materials/steelPrint/test?num=${item.pipeNum}&type=2&pipeId=${item.pipeId}`" style="width:100%;height:100%">
+                </div>
+                <div class="main_item_idnumber">{{item.pipeNum}}</div>
+            </div>
+            <div class="main_line"></div>
+            <div class="main_item_right">
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">尺寸:</div>
+                    <div class="main_item_info">{{item.sizeName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">注浆孔:</div>
+                    <div class="main_item_info">{{item.groutingName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">配筋:</div>
+                    <div class="main_item_info">{{item.reinforcementName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">转向:</div>
+                    <div class="main_item_info">{{item.turnName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">块号:</div>
+                    <div class="main_item_info">{{item.blockNumName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">入模时间:</div>
+                    <div class="main_item_info">{{item.intoModTime}}</div>
+                </div>
+                <!-- <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">浇筑时间:</div>
+                    <div class="main_item_info">{{item.pouringTime}}</div>
+                </div> -->
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">模具编号:</div>
+                    <div class="main_item_info">{{item.mouldNum}}</div>
+                </div>
+            </div>
+        </div>
+      </div>
+    </div>
+    <div v-show="showAbtn">
+      <a id="segmentPrint" :href="`printpipe://2,${pitchNums}`"><p></p></a>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[9, 18, 45, 90]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia/index';
+import { changeSize} from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+  export default {
+    data() {
+      return {
+        showAbtn:false,//是否展示a标签
+        pitchNums:null,//打印编号
+        size: changeSize(), // 组件尺寸
+        pageNum: 1,
+        pageSize: 9,
+        search:{},//查询条件
+        total: 0,
+        loading: false,
+        url:null,
+        pitchIf:null,
+        dataList: [], //管片信息打印列表
+        optionsProject:[],//项目名称
+        baseUrl: process.env.VUE_APP_BASE_URL
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+      that.getAllProjects()
+    },
+    methods: {
+    //获取二维码
+    // getPrintPhones(val){
+    // this.$api.Print.getPrintPhone({num:val})
+    //     return 
+    // },
+     //选择项目变色
+     changeItems(val){
+        this.pitchIf = val.pipeId
+        this.pitchNums = val.pipeNum
+     },
+     //打印按钮
+     printClick(){
+        if(this.pitchIf === null){
+            this.$message.warning('请选择一个项目进行打印!!!')
+            return false
+        }
+        // this.$api.Print.segmentPrints({recordIds:[this.pitchIf]}).then(res=>{
+        //     if(res.statusMsg === 'ok'){
+        //         this.$message.success(res.data)
+        //         this.gopPrints()
+        //         this.pitchIf = null
+        //     }else{
+        //         this.$message.warning(res.statusMsg)
+        //     }
+        // })
+        this.gopPrints()
+        this.pitchIf = null
+     },
+     //执行去打印
+      gopPrints(){
+          this.$nextTick(()=>{
+            document.getElementById("segmentPrint").click();
+          })
+      },
+     //获得所有项目名称
+     getAllProjects(){
+        let obj = {
+            pageNum: 1,
+            pageSize: 100000000
+        }
+        this.$api.Engineer.searchProjects(obj).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsProject = res.data.list
+                this.$set(this.search,'proId',res.data.list[0].proId)
+                this.searchButtonInfo(true)
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+     },
+     //选择不同的项目进行查询
+     ChangeLists(){
+        this.pitchIf = null
+        this.searchButtonInfo(true)
+     },
+      // 查询按钮列表信息
+      searchButtonInfo(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        let params = Object.assign({},this.search,{
+          pageNum: this.pageNum,
+          pageSize: this.pageSize,
+          typeTime :2
+        })
+        this.loading = true;
+        this.$api.Print.searchSegmentPrint(params).then((res) => {
+          if(res.statusMsg === 'ok') {
+            this.total = res.data.total;
+            this.dataList = res.data.list;
+          }else{
+            this.$message.warning(res.statusMsg)
+          }
+          this.loading = false;
+        })
+      },
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },      
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchButtonInfo();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchButtonInfo();
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '../../../style/layout-main.scss';
+.main_content{
+    width: calc(100% - 30px);
+    display: flex;
+    flex-wrap: wrap;
+    overflow-y: auto!important;
+    overflow-x: hidden;
+
+    .main_items{
+        // width: 100%;
+        // max-width: calc(100%/3 - 25px);
+        width: 500px;
+        height: 358px;
+        border-top-left-radius: 6px;
+        border-top-right-radius: 6px;
+        border-bottom-left-radius: 6px;
+        border-bottom-right-radius: 6px;
+        background-color: #031A46;
+        margin: 30px 20px 5px 5px;
+        box-shadow:0px 0px 8px 0px #0C4F79;
+
+        .main_items_top{
+            height: 40px;
+            padding-top: 8px;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            overflow: auto hidden;
+            border-top-left-radius: 6px;
+            border-top-right-radius: 6px;
+            background-color: rgba(57,181,254,0.3);
+            .first_titles{
+                margin-left: 10px;
+                position: relative;
+                &::before{
+                    width: 5px;
+                    height: 20px;
+                    content: '';
+                    position: absolute;
+                    top: -2px;
+                    left: 5px;
+                    background-color: #39B5FE;
+                }
+            }
+            .main_item_header{
+                padding: 0px 0px 8px 15px;
+                display: flex;
+
+                .main_item_title{
+                    flex: none;
+                    text-align: center;
+                    font-size: 16px;
+                    color: #E1EAEE;
+                }
+                .main_item_datas{
+                    margin-right: 10px;
+                    flex: none;
+                    color: #ffffff;
+                    font-weight: 900;
+                    font-size: 16px;
+                }
+            }
+        }
+        .main_item_contents{
+            width: 100%;
+            height: calc(100% - 29px);
+            background-color: #031A46;
+            border-bottom-left-radius: 4px;
+            border-bottom-right-radius: 4px;
+            display: flex;
+            padding: 25px 6px;
+            // overflow-x: auto;
+            // overflow-y: hidden;
+
+            .main_item_left{
+                width: 260px;
+                height: 100%;
+                display: flex;
+                // justify-content: center;
+                align-items: center;
+                padding: 0px 0px 0px 10px;
+                margin-right: 10px;
+                flex-direction: column;
+
+                .main_item_idnumber{
+                    margin-top: 20px;
+                    color: #fff;
+                    letter-spacing: 3px;
+                    font-size: 15px;
+                }
+            }
+
+            .main_line{
+                width: 2px;
+                height: 100%;
+                background-color: #073E63;
+            }
+
+            .main_item_right{
+                width: calc(100% - 80px);
+                height: 100%;
+
+                .main_item_right_rows{
+                    display: flex;
+                    justify-content: center;
+                    height: 36px;
+                    position: relative;
+
+                    .main_item_rhom{
+                        width: 10px;
+                        height: 10px;
+                        background-color: #39B5FE; 
+                        transform: roate(45deg);
+                        -ms-transform:rotate(45deg);
+                        -moz-transform:rotate(45deg); 
+                        -webkit-transform:rotate(45deg);
+                        -o-transform:rotate(45deg);
+                        position: absolute;
+                        top: 15px;
+                        left: 15px;
+                    }
+                    .main_item_name{
+                        width: 90px;
+                        color: #B8BECB;
+                        position: absolute;
+                        flex: none;
+                        left: 42px;
+                        font-size: 16px;
+                        top: 7px;
+                    }
+                    .main_item_info{
+                        width: 100%;
+                        flex: none;
+                        color: #39B5FE;
+                        position: absolute;
+                        left: 117px;
+                        font-size: 16px;
+                        top: 9px;
+                    }
+                }
+            }
+        }
+    }
+    .main_items_pitch{
+        // width: 100%;
+        // max-width: calc(100%/3 - 25px);
+        width: 517px;
+        height: 358px;
+        border-top-left-radius: 6px;
+        border-top-right-radius:6px;
+        border-bottom-left-radius: 6px;
+        border-bottom-right-radius: 6px;
+        background-color: #00D6F2;
+        margin: 30px 20px 5px 5px;
+        box-shadow:7px -1px 5px 9px #00D6F2;
+
+        .main_items_top_pitch{
+            display: flex;
+            justify-content: space-between;
+            overflow: auto;
+            .first_titles{
+                margin-left: 10px;
+                position: relative;
+                &::before{
+                    width: 5px;
+                    height: 20px;
+                    content: '';
+                    position: absolute;
+                    top: -2px;
+                    left: 5px;
+                    background-color: #fff;
+                }
+            }
+            .main_item_header{
+                padding: 0px 0px 8px 15px;
+                display: flex;
+                margin-top: 4px;
+
+                .main_item_title{
+                    flex: none;
+                    text-align: center;
+                    font-size: 16px;
+                    font-weight: 600;
+                    color: #026D92;
+                }
+                .main_item_datas{
+                    margin-right: 10px;
+                    flex: none;
+                    color: #093267;
+                    font-weight: 550;
+                    font-size: 16px;
+                }
+            }
+        }
+        .main_item_contents_pitch{
+            width: calc(100% + 11px);
+            height: calc(100% - 29px);
+            background-color: #417BEB;
+            border-bottom-left-radius: 6px;
+            border-bottom-right-radius: 6px;
+            display: flex;
+            padding: 25px 0px;
+            // overflow-x: auto;
+            // overflow-y: hidden;
+
+            .main_item_left{
+                width: 260px;
+                height: 100%;
+                display: flex;
+                // justify-content: center;
+                align-items: center;
+                padding: 0px 0px 0px 10px;
+                margin-right: 10px;
+                flex-direction: column;
+
+                .main_item_idnumber{
+                    margin-top: 20px;
+                    color: #fff;
+                    letter-spacing: 3px;
+                    font-size: 15px;
+                }
+            }
+
+            .main_line{
+                width: 2px;
+                height: 100%;
+                background-color: #368BEB;
+            }
+
+            .main_item_right{
+                width: calc(100% - 80px);
+                height: 100%;
+
+                .main_item_right_rows{
+                    display: flex;
+                    justify-content: center;
+                    height: 36px;
+                    position: relative;
+
+                    .main_item_rhom{
+                        width: 10px;
+                        height: 10px;
+                        background-color: #13BECB; 
+                        transform: roate(45deg);
+                        -ms-transform:rotate(45deg);
+                        -moz-transform:rotate(45deg); 
+                        -webkit-transform:rotate(45deg);
+                        -o-transform:rotate(45deg);
+                        position: absolute;
+                        top: 15px;
+                        left: 15px;
+                    }
+                    .main_item_name{
+                        width: 90px;
+                        color: #fff;
+                        position: absolute;
+                        flex: none;
+                        left: 42px;
+                        font-size: 16px;
+                        top: 7px;
+                    }
+                    .main_item_info{
+                        width: 100%;
+                        flex: none;
+                        color: #fff;
+                        position: absolute;
+                        left: 117px;
+                        font-size: 16px;
+                        top: 9px;
+                    }
+                }
+            }
+        }
+    }
+}
+
+//滚动条样式
+::-webkit-scrollbar {
+    width: 4px; 
+    height: 6px;   
+}
+::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    box-shadow: inset 0 0 5px rgba(19,73,126,1);
+    background: rgba(0,0,0,0.2);
+}
+::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px transparent;
+    border-radius: 0;
+    background: transparent;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ProductTerminal/components/ReinsPrint.vue b/web/src/views/DuctpiecePLM/ProductTerminal/components/ReinsPrint.vue
new file mode 100644
index 0000000..1142e20
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ProductTerminal/components/ReinsPrint.vue
@@ -0,0 +1,355 @@
+<template>
+  <div class="main">
+    <div class="main_top">
+        <div class="main_top_title">已打印</div>
+        <el-button  :size="size" v-if="showButton('search')" @click="$emit('update:showPrint', false)">返回</el-button>
+    </div>
+    <div class="main_header">
+      <!-- <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="search.proId" placeholder="请选择项目名称" clearable filterable @change="changeProjects">
+            <el-option
+            v-for="item in optionsProject"
+            :key="item.proId"
+            :label="item.proName"
+            :value="item.proId">
+            </el-option>
+        </el-select>
+      </div> -->
+    </div>
+    <div class="main_content" style="overflow:auto">
+      <div class="main_items" v-for="(item,index) in dataList" :key="index">
+        <div class="main_item_header">
+            <div class="main_item_title">项目名称:</div>
+            <div class="main_item_datas">{{item.proName}}</div>
+        </div>
+        <div class="main_item_contents">
+            <div class="main_item_left">
+              <div style="width:180px;height:180px">
+                <!-- <img src="../../../assets/e.jpg" style="width:100%;height:100%"> -->
+                <img :src="`${baseUrl}/materials/steelPrint/test?num=${item.produceNumber}&type=4&steelProduceId=${item.steelProduceId}`" style="width:100%;height:100%">
+              </div>
+              <div class="main_item_idnumber">{{item.produceNumber}}</div>
+            </div>
+            <div class="main_line"></div>
+            <div class="main_item_right">
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">尺寸:</div>
+                    <div class="main_item_info">{{item.sizeName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">配筋:</div>
+                    <div class="main_item_info">{{item.reinforcementName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">块号:</div>
+                    <div class="main_item_info">{{item.blockName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">制作人:</div>
+                    <div class="main_item_info">{{item.realName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">班组:</div>
+                    <div class="main_item_info">{{item.groupName}}</div>
+                </div>
+                <div class="main_item_right_rows">
+                    <div class="main_item_rhom"></div>
+                    <div class="main_item_name">打印时间:</div>
+                    <div class="main_item_info">{{item.printTime}}</div>
+                </div>
+            </div>
+        </div>
+      </div>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[9, 18, 45, 90]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../../pinia/index';
+import { changeSize} from '../../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+  export default {
+    name: 'ReinPrint',
+    props:{
+        showPrint: {
+            type: Boolean
+        },
+        rowsData:{
+            type:Object
+        }
+    },
+    data() {
+      return {
+        size: changeSize(), // 组件尺寸
+        pageNum: 1,
+        pageSize: 9,
+        search:{},//查询条件
+        total: 0,
+        loading: false,
+        dataList: [], //打印信息
+        optionsProject:[],//项目名称
+        baseUrl: process.env.VUE_APP_BASE_URL
+      }
+    },
+    watch: {
+      asyncVisible(bol) {
+        if(!bol) {
+          this.ruleForm = {};
+          this.$refs.ruleForm.resetFields();
+        }
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+      // that.getAllProjects()
+      that.searchButtonInfo(true)
+    },
+    methods: {
+      //改变项目
+      changeProjects(){
+        this.searchButtonInfo(true)
+      },
+     //获得所有项目名称
+     getAllProjects(){
+        let obj = {
+            pageNum: 1,
+            pageSize: 100000000
+        }
+        this.$api.Engineer.searchProjects(obj).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsProject = res.data.list
+                this.search.proId = this.rowsData.proId
+                this.searchButtonInfo(true);
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+     },
+      // 查询按钮列表信息
+      searchButtonInfo(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        let params = Object.assign({},{
+          pageNum: this.pageNum,
+          pageSize: this.pageSize,
+          proId:this.rowsData.proId,
+          steelPrintId:this.rowsData.steelPrintId
+        })
+        this.loading = true;
+          this.$api.Print.seeBearPrintLists(params).then((res) => {
+            if(res.statusMsg === 'ok') {
+                this.total = res.data.total;
+                this.dataList = res.data.list;
+                this.loading = false;
+            }else{
+              this.$message.warning(res.statusMsg)
+            }
+          })
+      },
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },      
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchButtonInfo();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchButtonInfo();
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '../../../../style/layout-main.scss';
+.main_top{
+    display: flex;
+    justify-content: space-between;
+    padding: 10px 0px 5px 25px;
+    margin: 0px 20px;
+    border-bottom: 1px solid #1B50AF;
+
+    .main_top_title{
+        color: #39B5FE;
+        margin-top: 5px;
+        font-size: 16px;
+        position: relative;
+        &::before{
+            content: "";
+            width: 2px;
+            height: 15px;
+            background-color: #39B5FE;
+            position: absolute;
+            top: 1px;
+            left: -10px;
+        }
+    }
+}
+.main_content{
+    width: calc(100% - 28px);
+    display: flex;
+    flex-wrap: wrap;
+
+    .main_items{
+        // width: 100%;
+        // max-width: calc(100%/3 - 25px);
+        width: 512px;
+        height: 300px;
+        border-top-left-radius: 6px;
+        border-top-right-radius: 6px;
+        border-bottom-left-radius: 6px;
+        border-bottom-right-radius: 6px;
+        background-color: #031A46;
+        margin: 30px 20px 5px 5px;
+        box-shadow:0px 12px 5px 0px #0C4F79;
+
+        .main_item_header{
+            border-top-left-radius: 6px;
+            border-top-right-radius: 6px;
+            background-color: rgba(57,181,254,0.3);
+            line-height: 40px;
+            display: flex;
+            align-items: center;
+
+            .main_item_title{
+                flex: none;
+                width: 100px;
+                text-align: center;
+                font-size: 16px;
+                color: #E1EAEE;
+            }
+            .main_item_datas{
+                flex: 1;
+                color: #ffffff;
+                font-weight: 900;
+                font-size: 16px;
+            }
+        }
+        .main_item_contents{
+            width: 100%;
+            height: calc(100% - 29px);
+            background-color: #031A46;
+            border-bottom-left-radius: 4px;
+            border-bottom-right-radius: 4px;
+            display: flex;
+            overflow: auto;
+
+            .main_item_left{
+                width: 260px;
+                height: 100%;
+                display: flex;
+                justify-content: center;
+                flex-direction: column;
+                align-items: center;
+                padding: 10px 0px 0px 10px;
+                margin-right: 10px;
+
+                .main_item_idnumber{
+                    padding-top: 10px;
+                    color: #fff;
+                    letter-spacing: 3px;
+                    font-size: 15px;
+                }
+            }
+
+            .main_line{
+                width: 2px;
+                height: 84%;
+                margin-top: 24px;
+                background-color: #073E63;
+            }
+
+            .main_item_right{
+                width: calc(100% - 80px);
+                height: 95%;
+                margin-left: 10px;
+                padding-top: 15px;
+                display: flex;
+                flex-direction: column;
+                justify-content: space-between;
+
+                .main_item_right_rows{
+                    display: flex;
+                    // justify-content: center;
+                    height: 35px;
+                    position: relative;
+
+                    .main_item_rhom{
+                       width: 10px;
+                       height: 10px;
+                       background-color: #39B5FE; 
+                       transform: roate(45deg);
+                       -ms-transform:rotate(45deg);
+                       -moz-transform:rotate(45deg); 
+                        -webkit-transform:rotate(45deg);
+                        -o-transform:rotate(45deg);
+                        position: absolute;
+                        top: 15px;
+                        left: 15px;
+                    }
+                    .main_item_name{
+                        width: 80px;
+                        color: #B8BECB;
+                        position: absolute;
+                        flex: none;
+                        left: 42px;
+                        font-size: 16px;
+                        top: 12px;
+                    }
+                    .main_item_info{
+                        width: 100%;
+                        flex: none;
+                        color: #39B5FE;
+                        position: absolute;
+                        left: 120px;
+                        font-size: 16px;
+                        top: 11px;
+                    }
+                }
+            }
+        }
+    }
+}
+//滚动条样式
+::-webkit-scrollbar {
+    width: 4px; 
+    height: 3px;   
+}
+::-webkit-scrollbar-thumb {
+    border-radius: 10px;
+    box-shadow: inset 0 0 5px #13497E;
+    background: transparent;
+}
+::-webkit-scrollbar-track {
+    box-shadow: inset 0 0 5px transparent;
+    border-radius: 0;
+    background: transparent;
+}
+</style>
diff --git a/web/src/views/DuctpiecePLM/ReportCenter/BearReport.vue b/web/src/views/DuctpiecePLM/ReportCenter/BearReport.vue
new file mode 100644
index 0000000..0b5e368
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ReportCenter/BearReport.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>钢筋笼生产报表</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ReportCenter/DieuserReport.vue b/web/src/views/DuctpiecePLM/ReportCenter/DieuserReport.vue
new file mode 100644
index 0000000..7de0266
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ReportCenter/DieuserReport.vue
@@ -0,0 +1,149 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">管片块号:</span>
+        <el-select v-model="search.mouldTypes" placeholder="请选择管片块号" clearable>
+            <el-option
+                v-for="item in optionsDies"
+                :key="item.dictId"
+                :label="item.dictName"
+                :value="item.dictId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">模具编号:</span>
+        <el-input v-model="search.mouldNum" :size="size" clearable placeholder="请输入模具编号"></el-input>
+      </div>
+      <div class="header_item">
+        <el-button   :size="size" icon="el-icon-search" v-if="showButton('search')" @click="searchButtonInfo(true)">查询</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <el-table
+        v-loading="loading"
+        :data="dataList"
+        height="100%">
+        <el-table-column align="center" label="序号" width="60">
+          <template #default="scope">
+            <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="mouldCode" label="模具型号" align="center" ></el-table-column>
+        <el-table-column prop="mouldNum" label="模具编号" align="center" ></el-table-column>
+        <el-table-column prop="mouldTypes" label="模具类型(块号)" align="center" ></el-table-column>
+        <el-table-column prop="sizeName" label="尺寸" align="center" ></el-table-column>
+        <el-table-column prop="turn" label="转向" align="center" ></el-table-column>
+        <el-table-column prop="holes" label="注浆孔" align="center" ></el-table-column>
+        <el-table-column prop="scanNum" label="第N次使用" align="center" ></el-table-column>
+        <el-table-column prop="lengthTime" label="使用时长(秒)" align="center"  show-overflow-tooltip></el-table-column>
+        <el-table-column prop="createTime" label="开始时间" align="center"  show-overflow-tooltip></el-table-column>
+      </el-table>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia/index';
+import { changeSize } from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+  export default {
+    data() {
+      return {
+        size: changeSize(), // 组件尺寸
+        pageNum: 1,
+        pageSize: 10,
+        search:{},//查询条件
+        total: 0,
+        loading: false,
+        dataList: [], //模具使用报表信息列表
+        asyncTitle: true, // 对话框title 新增:true  修改:false
+        asyncVisible: false, // 添加 修改对话框
+        optionsDies:[],//管片块号
+      }
+    },
+    watch: {
+      asyncVisible(bol) {
+        if(!bol) {
+          this.ruleForm = {};
+          this.$refs.ruleForm.resetFields();
+        }
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+      that.searchButtonInfo(true);
+      that.getAllTypes()
+    },
+    methods: {
+    //获取尺寸配筋转向等信息
+      getAllTypes(){
+        let params = {
+            pageNum: 1,
+            pageSize: 100000000,
+            dictType:5
+        }
+        this.$api.Dictionary.searchDictionary(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsDies = res.data.list
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+      },
+      // 查询按钮列表信息
+      searchButtonInfo(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        let params = Object.assign({},this.search,{
+          pageNum: this.pageNum,
+          pageSize: this.pageSize
+        })
+        this.loading = true;
+        this.$api.Report.searchDieList(params).then((res) => {
+          if(res.statusMsg === 'ok') {
+            this.total = res.data.total;
+            this.dataList = res.data.list;
+          }
+          this.loading = false;
+        })
+      },
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },      
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchButtonInfo();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchButtonInfo();
+      }
+    }
+  }
+</script>
+
+<style lang="sass" scoped>
+@import '../../../style/layout-main.scss';
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ReportCenter/DuctReport.vue b/web/src/views/DuctpiecePLM/ReportCenter/DuctReport.vue
new file mode 100644
index 0000000..d409c58
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ReportCenter/DuctReport.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>管片生产报表</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ReportCenter/SafetycheckIndex.vue b/web/src/views/DuctpiecePLM/ReportCenter/SafetycheckIndex.vue
new file mode 100644
index 0000000..1c3a408
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ReportCenter/SafetycheckIndex.vue
@@ -0,0 +1,130 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">考核名称:</span>
+        <el-input v-model="examName" clearable placeholder="请输入考核名称"></el-input>
+      </div>
+      <div class="header_item">
+        <el-button v-if="showButton('search')" icon="el-icon-search" @click="searchSafetycheckList(true)">查询</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <el-table
+        v-loading="loading"
+        :data="safetycheckList"
+        height="100%">
+        <el-table-column label="序号" width="60" align="center">
+          <template #default="scope">
+            <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="examName" label="考核名称" width="180" align="center"></el-table-column>
+        <el-table-column prop="planUserCount" label="应考人数" align="center"></el-table-column>
+        <el-table-column prop="totalUserCount" label="实考人数" align="center"></el-table-column>
+        <el-table-column prop="noExamUserCount" label="缺考人数" align="center"></el-table-column>
+        <el-table-column prop="passUserCount" label="合格人数" align="center"></el-table-column>
+        <el-table-column prop="noPassUserCount" label="不合格人数" align="center"></el-table-column>
+        <el-table-column label="考核记录列表" align="center">
+          <template #default="{ row }">
+            <el-button class="table_btn" size="mini" @click="exportExcel(row)">列表下载</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center">
+          <template #default="{ row }">
+            <el-button class="table_btn" size="mini" @click="exportReport(row)">生成报告</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia';
+import { downLoadFile } from '../../../plugins/public';
+  export default {
+    data() {
+      return {
+        examName: '',
+        loading: false,
+        pageNum: 1,
+        pageSize: 10,
+        total: 0,
+        safetycheckList: [],
+      }
+    },
+    mounted() {
+      this.searchSafetycheckList(true);
+    },
+    methods: {
+      // 查询安全考核报表信息
+      searchSafetycheckList(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        this.loading = true;
+        this.safetycheckList = [];
+        this.$api.Report.searchSafetyCheckReport({
+          pageNum: this.pageNum,
+          pageSize: this.pageSize,
+          examName: this.examName
+        }).then((res) => {
+          if(res.success) {
+            this.total = res.data.total;
+            this.safetycheckList = res.data.list;
+          }
+          this.loading = false;
+        }).catch(() => {
+          this.loading = false;
+        })
+      },
+      // 列表下载
+      exportExcel(item) {
+        this.$api.System.GETEXPORTTOKENDATA({
+          examName: this.examName,
+          examId: item.examId
+        }).then((res) => {
+          if(res.success) {
+            downLoadFile(res.data, '/secure/exam/examRecordDown');
+          }
+        })
+      },
+      // 生成报告
+      exportReport() {
+        console.log('生成报告');
+      },
+      // 切换页码
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchSafetycheckList();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchSafetycheckList();
+      },
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '@/style/layout-main.scss';
+</style>
\ No newline at end of file
diff --git a/web/src/views/DuctpiecePLM/ReportCenter/VideoAgv.vue b/web/src/views/DuctpiecePLM/ReportCenter/VideoAgv.vue
new file mode 100644
index 0000000..cbd0e89
--- /dev/null
+++ b/web/src/views/DuctpiecePLM/ReportCenter/VideoAgv.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>AGv监控</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/EquipmentManage/EquipDynamic.vue b/web/src/views/EquipmentManage/EquipDynamic.vue
new file mode 100644
index 0000000..499356b
--- /dev/null
+++ b/web/src/views/EquipmentManage/EquipDynamic.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>设备动态</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/EquipmentManage/EquipInfo.vue b/web/src/views/EquipmentManage/EquipInfo.vue
new file mode 100644
index 0000000..a3d8ae7
--- /dev/null
+++ b/web/src/views/EquipmentManage/EquipInfo.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>设备信息管理</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/EquipmentManage/EquipSpot.vue b/web/src/views/EquipmentManage/EquipSpot.vue
new file mode 100644
index 0000000..5058d0b
--- /dev/null
+++ b/web/src/views/EquipmentManage/EquipSpot.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>设备点检</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/MaterialsIndex/AuxiliaryIndex.vue b/web/src/views/GoodManage/AuxiliaryIndex.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/AuxiliaryIndex.vue
rename to web/src/views/GoodManage/AuxiliaryIndex.vue
diff --git a/web/src/views/GoodManage/CostStatistics/AuxiliaryCost.vue b/web/src/views/GoodManage/CostStatistics/AuxiliaryCost.vue
new file mode 100644
index 0000000..720fd67
--- /dev/null
+++ b/web/src/views/GoodManage/CostStatistics/AuxiliaryCost.vue
@@ -0,0 +1,478 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+        <div class="header_item">
+            <span class="header_label">物品名称:</span>
+            <el-select v-model="search.steelId" placeholder="请选择物品名称" clearable>
+                <el-option
+                    v-for="item in optionAuxiliary"
+                    :key="item.assistId"
+                    :label="item.assistName+'-'+item.assistModel"
+                    :value="item.assistId">
+                </el-option>
+            </el-select>
+        </div>
+        <div class="header_item">
+            <el-radio-group v-model="tabPosition" @input="timesChange"> 
+                <el-radio-button label="day">日</el-radio-button>
+                <el-radio-button label="month">月</el-radio-button>
+            </el-radio-group>
+        </div>
+        <div class="header_item" v-if="showTimes">
+            <span class="header_label">选择时间:</span>
+            <el-date-picker
+            v-model="search.dayData"
+            :picker-options="pickerOptionsDay"
+            :clearable="false"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item" v-if="!showTimes">
+            <span class="header_label">选择月份:</span>
+            <el-date-picker
+            v-model="search.monthData"
+            :picker-options="pickerOptionsMonth"
+            :clearable="false"
+            type="monthrange"
+            value-format="yyyy-MM"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item">
+            <el-button v-if="showButton('search')" icon="el-icon-search" @click="searchButtonInfo()">查询</el-button>
+            <el-button v-if="showButton('export')" icon="el-icon-download" @click="exportAuxiliaryExcel()">导出Excel</el-button>
+        </div>
+    </div>
+    <!-- <div class="main_middle">
+        <div class="main_middle_titles">数据统计</div>
+        <div class="main_middle_matter">
+            <div class="middle_items" v-for="(item,index) in showDatas" :key="index">
+                <div class="middle_items_text">{{item.steelModel}}</div>
+                <div class="middle_items_datas">{{item.changeStock}}</div>
+            </div>
+        </div>
+    </div> -->
+    <div class="main_content" style="overflow:auto;padding-bottom:100px;">
+        <div v-for="(echartItem,echartIndex) in echartsList" :key="echartIndex" class="echarts_items">
+            <div class="main_echart_titles">{{echartItem.assistName}}</div>
+            <div :id="echartItem.assistId" class="main_content_chart"></div>
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia';
+import { downFiles } from '../../../plugins/public'; 
+export default {
+  name: 'RebarCost',
+  data() {
+    return {
+        search:{
+            dayData:this.getDateTime(),
+            monthData:this.getMonthTime()
+        },//查询条件
+        tabPosition:'day',//默认展示day
+        showTimes:true,//是否展示日的日期  true:日  false: 月
+        dateType:1,// 1:日  2:月
+        optionAuxiliary:[],//材料类型
+        showDatas:[],//展示的数据统计
+        echartsList:[],//展示echarts表
+        chartsImage:null,
+        pickerMinDate:'',//日期选择增加限制
+        pickerOptionsDay:{ //限制选择日期为15天
+            onPick: ({
+                maxDate,
+                minDate
+            }) => {
+                this.pickerMinDate = minDate.getTime()
+                if (maxDate) {
+                    this.pickerMinDate = ''
+                }
+            },
+            disabledDate: (time) => {
+                if (this.pickerMinDate !== '') {
+                    const one = 15 * 24 * 3600 * 1000
+                    const minTime = this.pickerMinDate - one
+                    const maxTime = this.pickerMinDate + one
+                    return time.getTime() < minTime || time.getTime() > maxTime
+
+                }
+            }
+        },
+        minDates: null,
+        maxDates: null,
+        pickerOptionsMonth: {
+            disabledDate: (time) => {
+                if (this.minDates !== null) {
+                    let minMonth = this.minDates.getMonth(),
+                    lastYear = new Date(this.minDates).setMonth(minMonth - 6),
+                    nextYear = new Date(this.minDates).setMonth(minMonth + 6);
+                    // 只能选 minDate 前后6个月的范围
+                    return time.valueOf() < lastYear.valueOf() || time.valueOf() > nextYear.valueOf();
+                }
+                return false;
+            },
+            onPick: ({minDate, maxDate}) => {
+                this.minDates = minDate;
+                this.maxDates = maxDate;
+            }
+        },
+    }
+  },
+  mounted() {
+    // this.searchButtonInfo()
+    this.getAllTypes()
+  },
+  methods: {
+    // 转圈圈
+    functionLoading() {
+        this.loadingView = this.$loading({
+            lock: true,
+            text: '请稍后...',
+            spinner: 'el-icon-loading',
+            background: 'rgba(0, 0, 0, 0.7)'
+        });
+    },
+    //导出
+    exportAuxiliaryExcel() {
+        let params = {
+            assistId:this.search.assistId ===undefined ||this.search.assistId ==='' ?'':this.search.assistId,
+           dateType:this.dateType
+        }
+        if(this.dateType === 1){
+            params.strTime = this.search.dayData&&this.search.dayData[0]
+            params.endTime = this.search.dayData&&this.search.dayData[1]
+            delete params.dayData
+        }else{
+            params.strTime = this.search.monthData&&this.search.monthData[0]
+            params.endTime = this.search.monthData&&this.search.monthData[1]
+            delete params.monthData 
+        }
+        this.functionLoading();
+        this.$api.Analyse.exportAuxilliaryCost(params).then(res => {
+            downFiles(res, '辅材消耗信息', 'xls')
+            this.loadingView.close()
+        })
+        .catch(() => {
+            this.loadingView.close();
+        })
+    },
+    //获取时间(默认15天)
+    getDateTime(){
+      return [new Date(new Date().getTime() - 3600*1000*24*15).toISOString().replace('T',' ').split('.')[0],new Date().toISOString().replace('T',' ').split('.')[0]]
+    },
+    //获取时间(默认6个月)
+    getMonthTime(){
+        let date = new Date();
+        let year = date.getFullYear();
+        let month = date.getMonth() + 1;
+        let newYear = 0;
+        let newMonth = 0;
+        let newDateArr = [];
+        for (let i = 0; i < 7; i++) {
+            //这里是获取前六个月,所以循环6次,根据需要修改
+            if (month - i < 1) {
+            //这里的判断是如果当前月份往前推到了去年  需要做的处理
+            newYear = year - 1;
+            newMonth = month - i + 12 >= 10 ? month - i + 12 : '0' + (month - i + 12);
+            newDateArr.push(newYear + '-' + newMonth); //这里拼接格式化,在时间中间加了个-,根据实际需求来
+            } else {
+            newMonth = month - i >= 10 ? month - i : '0' + (month - i); //这里是对月份小于10做加前面加0处理
+            newDateArr.push(year + '-' + newMonth);
+            }
+        }
+        //这里就最后得到当前年月前六个月组成的时间数组,根据需要赋值使用即可
+        const end = newDateArr[0];
+        const start = newDateArr[6];
+        return [start, end];
+    },
+    //获取所有型号
+    getAllTypes(){
+        this.$api.Analyse.auxilliaryCostList({}).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionAuxiliary = res.data
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+    //展示不同的时间
+    timesChange(val){
+        if(val === 'month'){
+            this.showTimes = false
+            // this.search.dayData = ''
+            this.dateType = 2
+        }else{
+            this.showTimes = true
+            // this.search.monthData = ''
+            this.dateType = 1
+        }
+    },
+    //查询按钮
+    searchButtonInfo() {
+        let params = {
+            assistId:this.search.assistId ===undefined ||this.search.assistId ==='' ?'':this.search.assistId,
+           dateType:this.dateType
+        }
+        if(this.dateType === 1){
+            params.strTime = this.search.dayData&&this.search.dayData[0]
+            params.endTime = this.search.dayData&&this.search.dayData[1]
+            delete params.dayData
+        }else{
+            params.strTime = this.search.monthData&&this.search.monthData[0]
+            params.endTime = this.search.monthData&&this.search.monthData[1]
+            delete params.monthData 
+        }
+        this.$api.Analyse.searchAuxilliaryCost(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.echartsList = res.data
+                res.data.forEach(item=>{
+                    let xtitle = item.betweenDate
+                    let showStock = []
+                    item.assistStatisticsDtos.forEach(ite=>{
+                        xtitle.forEach(iten=>{
+                            if(iten === ite.getDate){
+                                showStock.push({
+                                    getDate:iten,
+                                    changeStock:ite.changeStock
+                                })
+                            }else{
+                               showStock.push({
+                                    getDate:iten,
+                                    changeStock:0
+                                }) 
+                            }
+                        })
+                    })
+                    this.$nextTick(() => {
+                        this.createCharts(item.assistId, showStock,item.assistName);
+                    }) 
+                })
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+     // 创建echart图表
+    createCharts(name, data,titleName) {
+        const labelData = data.map(item => item.getDate);
+        const firstData = data.map(item => item.changeStock ? item.changeStock : 0);
+        this.chartsImage = this.$echarts.init(document.getElementById(name));
+        const option = {
+        animationDuration: 1500,
+        tooltip: {
+            trigger: "axis",
+            backgroundColor:'#071F46',
+            textStyle:{
+                color:'#fff',
+            },
+            formatter: function (params) {
+            var relVal = params[0].name;
+            for (var i = 0; i < params.length; i++) {
+                if (params[i].componentIndex === 0) {
+                relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    `${titleName}` +
+                    " : " +
+                    params[i].value;
+                }
+            }
+            return relVal;
+            },
+        },
+        grid: {
+            top: "15%",
+            right: "3%",
+            left: "3%",
+            bottom: "11%",
+        },
+        xAxis: [
+            {
+            type: "category",
+            data: labelData,
+            axisLine: {
+                lineStyle: {
+                width: 2,
+                color: "#B7E4F7",
+                },
+            },
+            axisLabel: {
+                color: "#B7E4F7",
+            },
+            axisTick: {
+                show: false,
+            },
+            },
+        ],
+        yAxis: [
+            {
+            type: "value",
+            // max: 100,
+            splitNumber: 10,
+            axisLabel: {
+                formatter: "{value}",
+                textStyle: {
+                color: "#CAD3E0",
+                },
+            },
+            splitLine: {
+                lineStyle: {
+                width: 2,
+                type: "dashed",
+                color: "#28477C",
+                },
+            },
+            },
+            {
+            type: "value",
+            max: 100,
+            splitNumber: 10,
+            axisLabel: {
+                formatter: "{value}%",
+                textStyle: {
+                color: "#B7E4F7",
+                },
+            },
+            splitLine: {
+                show: false,
+            },
+            },
+        ],
+        series: [
+            {
+            type: "bar",
+            barWidth:40,
+            data: firstData,
+            yAxisIndex: 0,
+            itemStyle: {
+                normal: {
+                color: new this.$echarts.graphic.LinearGradient( 0, 0, 0, 1,
+                    [
+                    {
+                        offset: 0,
+                        color: "rgba(15, 106, 134, 1)", // 0% 处的颜色
+                    },
+                    {
+                        offset: 1,
+                        color: "rgba(28, 186, 233, 1)", // 100% 处的颜色
+                    },
+                    ],
+                    false
+                ),
+                },
+            },
+            },
+        ],
+        }
+        this.chartsImage.clear();
+        this.chartsImage.setOption(option);
+        window.onresize = () => {
+            this.chartsImage.resize()
+        }
+    },
+    // 判断按钮权限信息
+    showButton(str) {
+      const pinia = buttonPinia();
+      return pinia.$state.buttonInfo.includes(str);
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "@/style/layout-main.scss";
+
+.main_middle{
+    width: 97%;
+    margin: 10px 18px;
+
+    .main_middle_titles{
+        width: 100%;
+        color: #19F6F8;
+        position: relative;
+        padding: 10px 15px;
+        border-bottom:1px solid #1B50AE ;
+        &::before{
+            content: "";
+            position: absolute;
+            left: 5px;
+            top: 10px;
+            width: 2px;
+            height: 18px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_middle_matter{
+        padding-top: 15px;
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+
+        .middle_items{
+            width: 150px;
+            height: 80px;
+            background: url('../../../assets/stir_img.png') no-repeat;
+            background-size: 100% 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            flex-direction: column;
+            .middle_items_text{
+                color: #E1E5EB;
+            }
+            .middle_items_datas{
+                color: #18F6F8;
+                font-size: 18px;
+                font-weight: 600;
+            }
+        }
+    }
+}
+
+.echarts_items{
+    height: 332px;
+    padding-top: 10px;
+    padding-bottom: 15px;
+    margin-bottom: 20px;
+    .main_echart_titles{
+        width: 97%;
+        color: #18F6F8;
+        padding-bottom: 15px;
+        padding-left: 15px;
+        border-bottom: 1px solid #1C51B1;
+        position: relative;
+        &::before{
+            width: 2px;
+            height: 15px;
+            content: "";
+            position: absolute;
+            top: 3px;
+            left: 5px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_content_chart {
+        height: 100%;
+    }
+}
+/deep/.el-radio-button__orig-radio:checked + .el-radio-button__inner{
+    color: #19F7F9;
+    border-color: #18F6F8;
+    background-color: #0D4573!important;
+}
+/deep/.el-radio-button__inner{
+    background-color: #0D4573;
+    border-color:#18F6F8;
+    border-radius: 0px 0px !important;
+    border-color: #18F6F8;
+    color: #E2E9EE;
+}
+</style>
diff --git a/web/src/views/GoodManage/CostStatistics/RawCost.vue b/web/src/views/GoodManage/CostStatistics/RawCost.vue
new file mode 100644
index 0000000..e53b07f
--- /dev/null
+++ b/web/src/views/GoodManage/CostStatistics/RawCost.vue
@@ -0,0 +1,452 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+        <div class="header_item">
+            <span class="header_label">材料类型:</span>
+            <el-select v-model="search.materialName" placeholder="全部" clearable>
+                <el-option
+                    v-for="item in optionMaterials"
+                    :key="item.dictId"
+                    :label="item.dictName"
+                    :value="item.dictId">
+                </el-option>
+            </el-select>
+        </div>
+        <div class="header_item">
+            <el-radio-group v-model="tabPosition" @input="timesChange"> 
+                <el-radio-button label="day">日</el-radio-button>
+                <el-radio-button label="month">月</el-radio-button>
+            </el-radio-group>
+        </div>
+        <div class="header_item" v-if="showTimes">
+            <span class="header_label">选择时间:</span>
+            <el-date-picker
+            v-model="search.dayData"
+            :picker-options="pickerOptionsDay"
+            :clearable="false"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item" v-if="!showTimes">
+            <span class="header_label">选择月份:</span>
+            <el-date-picker
+            v-model="search.monthData"
+            :picker-options="pickerOptionsMonth"
+            :clearable="false"
+            type="monthrange"
+            value-format="yyyy-MM-dd"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item">
+            <el-button v-if="showButton('search')" icon="el-icon-search" @click="searchButtonInfo()">查询</el-button>
+            <el-button v-if="showButton('export')" icon="el-icon-download" @click="exportExcel()">导出Excel</el-button>
+        </div>
+    </div>
+    <div class="main_middle">
+        <div class="main_middle_titles">数据统计</div>
+        <div class="main_middle_matter">
+            <div class="middle_items" v-for="(item,index) in showDatas" :key="index">
+                <div class="middle_items_text">{{item.materialName}}</div>
+                <div class="middle_items_datas">{{item.materialValue}}</div>
+            </div>
+        </div>
+    </div>
+    <div class="main_content" style="overflow:auto;padding-bottom:100px;">
+        <div v-for="(echartItem,echartIndex) in echartsList" :key="echartIndex" class="echarts_items">
+            <div class="main_echart_titles">{{echartItem.materialCName}}(吨)</div>
+            <div :id="echartItem.materialName" class="main_content_chart"></div>
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia';
+import { downFiles } from '../../../plugins/public'; 
+export default {
+  name: 'MaterialCost',
+  data() {
+    return {
+        search:{
+            dayData:this.getDateTime(),
+            monthData:this.getMonthTime()
+        },//查询条件
+        tabPosition:'day',//默认展示day
+        showTimes:true,//是否展示日的日期  true:日  false: 月
+        dateType:1,// 1:日  2:月
+        optionMaterials:[],//材料类型
+        showDatas:[],//展示的数据统计
+        echartsList:[],//展示echarts表
+        pickerMinDate:'',//日期选择增加限制
+        pickerOptionsDay:{ //限制选择日期为15天
+            onPick: ({
+                maxDate,
+                minDate
+            }) => {
+                this.pickerMinDate = minDate.getTime()
+                if (maxDate) {
+                    this.pickerMinDate = ''
+                }
+            },
+            disabledDate: (time) => {
+                if (this.pickerMinDate !== '') {
+                    const one = 15 * 24 * 3600 * 1000
+                    const minTime = this.pickerMinDate - one
+                    const maxTime = this.pickerMinDate + one
+                    return time.getTime() < minTime || time.getTime() > maxTime
+
+                }
+            }
+        },
+        minDates: null,
+        maxDates: null,
+        pickerOptionsMonth: {
+            disabledDate: (time) => {
+                if (this.minDates !== null) {
+                    let minMonth = this.minDates.getMonth(),
+                    lastYear = new Date(this.minDates).setMonth(minMonth - 6),
+                    nextYear = new Date(this.minDates).setMonth(minMonth + 6);
+                    // 只能选 minDate 前后6个月的范围
+                    return time.valueOf() < lastYear.valueOf() || time.valueOf() > nextYear.valueOf();
+                }
+                return false;
+            },
+            onPick: ({minDate, maxDate}) => {
+                this.minDates = minDate;
+                this.maxDates = maxDate;
+            }
+        },
+    }
+  },
+  mounted() {
+    // this.searchButtonInfo()
+    this.getAllTypes()
+  },
+  methods: {
+    // 导出Excel
+    exportExcel() {
+        let params = {
+           materialName:this.search.materialName ===undefined ||this.search.materialName ==='' ?'both':this.search.materialName,
+           dateType:this.dateType
+        }
+        if(this.dateType === 1){
+            params.startDay = this.search.dayData&&this.search.dayData[0]
+            params.endDay = this.search.dayData&&this.search.dayData[1]
+            delete params.dayData
+        }else{
+            params.startDay = this.search.monthData&&this.search.monthData[0]
+            params.endDay = this.search.monthData&&this.search.monthData[1]
+            delete params.monthData 
+        }
+        this.$api.Ducts.exportBtns(params).then(res=>{
+            downFiles(res, '原材料消耗信息', 'xls')
+        })
+    },
+    //获取时间(默认15天)
+    getDateTime(){
+      return [new Date(new Date().getTime() - 3600*1000*24*15).toISOString().replace('T',' ').split('.')[0],new Date().toISOString().replace('T',' ').split('.')[0]]
+    },
+    //获取时间(默认6个月)
+    getMonthTime(){
+        let date = new Date();
+        let year = date.getFullYear();
+        let month = date.getMonth() + 1;
+        let newYear = 0;
+        let newMonth = 0;
+        let newDateArr = [];
+        for (let i = 0; i < 7; i++) {
+            //这里是获取前六个月,所以循环6次,根据需要修改
+            if (month - i < 1) {
+            //这里的判断是如果当前月份往前推到了去年  需要做的处理
+            newYear = year - 1;
+            newMonth = month - i + 12 >= 10 ? month - i + 12 : '0' + (month - i + 12);
+            newDateArr.push(newYear + '-' + newMonth); //这里拼接格式化,在时间中间加了个-,根据实际需求来
+            } else {
+            newMonth = month - i >= 10 ? month - i : '0' + (month - i); //这里是对月份小于10做加前面加0处理
+            newDateArr.push(year + '-' + newMonth);
+            }
+        }
+        //这里就最后得到当前年月前六个月组成的时间数组,根据需要赋值使用即可
+        const end = newDateArr[0];
+        const start = newDateArr[6];
+        return [start+'-'+'01', end+'-'+'01'];
+    },
+    //获取设备类型
+    getAllTypes(){
+        let params = {
+            pageNum: 1,
+            pageSize: 100000000,
+        }
+        this.$api.Dictionary.searchDictionary(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionMaterials = res.data.list.filter(item=>item.dictType ==='pipe_materials')
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+    //展示不同的时间
+    timesChange(val){
+        if(val === 'month'){
+            this.showTimes = false
+            // this.search.dayData = ''
+            this.dateType = 2
+        }else{
+            this.showTimes = true
+            // this.search.monthData = ''
+            this.dateType = 1
+        }
+    },
+    //查询按钮
+    searchButtonInfo() {
+        let params = {
+           materialName:this.search.materialName ===undefined ||this.search.materialName ==='' ?'both':this.search.materialName,
+           dateType:this.dateType
+        }
+        if(this.dateType === 1){
+            params.startDay = this.search.dayData&&this.search.dayData[0]
+            params.endDay = this.search.dayData&&this.search.dayData[1]
+            delete params.dayData
+        }else{
+            params.startDay = this.search.monthData&&this.search.monthData[0]
+            params.endDay = this.search.monthData&&this.search.monthData[1]
+            delete params.monthData 
+        }
+        this.$api.Analyse.searchMaterialCost(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.showDatas = res.data.materialTotal
+                this.echartsList = res.data.statResult
+                res.data.statResult.forEach(item=>{
+                    this.$nextTick(() => {
+                        this.createCharts(item.materialName, item.statVoList,item.materialCName);
+                    }) 
+                })
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+     // 创建echart图表
+    createCharts(name, data,titleName) {
+        const labelData = data.map(item => item.shuDate);
+        const firstData = data.map(item => item.materialValue ? item.materialValue : 0);
+        const chartsImage = this.$echarts.init(document.getElementById(name));
+        const option = {
+        animationDuration: 1500,
+        tooltip: {
+            trigger: "axis",
+            backgroundColor:'#071F46',
+            textStyle:{
+                color:'#fff',
+            },
+            formatter: function (params) {
+            var relVal = params[0].name;
+            for (var i = 0; i < params.length; i++) {
+                if (params[i].componentIndex === 0) {
+                relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    `${titleName}` +
+                    " : " +
+                    params[i].value;
+                }
+            }
+            return relVal;
+            },
+        },
+        grid: {
+            top: "15%",
+            right: "3%",
+            left: "3%",
+            bottom: "11%",
+        },
+        xAxis: [
+            {
+            type: "category",
+            data: labelData,
+            axisLine: {
+                lineStyle: {
+                width: 2,
+                color: "#B7E4F7",
+                },
+            },
+            axisLabel: {
+                color: "#B7E4F7",
+            },
+            axisTick: {
+                show: false,
+            },
+            },
+        ],
+        yAxis: [
+            {
+            type: "value",
+            // max: 100,
+            splitNumber: 10,
+            axisLabel: {
+                formatter: "{value}",
+                textStyle: {
+                color: "#CAD3E0",
+                },
+            },
+            splitLine: {
+                lineStyle: {
+                width: 2,
+                type: "dashed",
+                color: "#28477C",
+                },
+            },
+            },
+            {
+            type: "value",
+            max: 100,
+            splitNumber: 10,
+            axisLabel: {
+                formatter: "{value}%",
+                textStyle: {
+                color: "#B7E4F7",
+                },
+            },
+            splitLine: {
+                show: false,
+            },
+            },
+        ],
+        series: [
+            {
+            type: "line",
+            smooth:true,
+            data: firstData,
+            barWidth:40,
+            yAxisIndex: 0,
+            itemStyle: {
+                normal: {
+                color: new this.$echarts.graphic.LinearGradient( 0, 0, 0, 1,
+                    [
+                    {
+                        offset: 0,
+                        color: "rgba(15, 106, 134, 1)", // 0% 处的颜色
+                    },
+                    {
+                        offset: 1,
+                        color: "rgba(28, 186, 233, 1)", // 100% 处的颜色
+                    },
+                    ],
+                    false
+                ),
+                },
+            },
+            },
+        ],
+        }
+        chartsImage.clear();
+        chartsImage.setOption(option);
+        window.onresize = () => {
+            chartsImage.resize()
+        }
+    },
+    // 判断按钮权限信息
+    showButton(str) {
+      const pinia = buttonPinia();
+      return pinia.$state.buttonInfo.includes(str);
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "@/style/layout-main.scss";
+
+.main_middle{
+    width: 97%;
+    margin: 10px 18px;
+
+    .main_middle_titles{
+        width: 100%;
+        color: #19F6F8;
+        position: relative;
+        padding: 10px 15px;
+        border-bottom:1px solid #1B50AE ;
+        &::before{
+            content: "";
+            position: absolute;
+            left: 5px;
+            top: 10px;
+            width: 2px;
+            height: 18px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_middle_matter{
+        padding-top: 15px;
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+
+        .middle_items{
+            width: 150px;
+            height: 80px;
+            background: url('../../../assets/stir_img.png') no-repeat;
+            background-size: 100% 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            flex-direction: column;
+            .middle_items_text{
+                color: #E1E5EB;
+            }
+            .middle_items_datas{
+                color: #18F6F8;
+                font-size: 18px;
+                font-weight: 600;
+            }
+        }
+    }
+}
+
+.echarts_items{
+    height: 332px;
+    padding-top: 10px;
+    padding-bottom: 15px;
+    margin-bottom: 20px;
+    .main_echart_titles{
+        width: 97%;
+        color: #18F6F8;
+        padding-bottom: 15px;
+        padding-left: 15px;
+        border-bottom: 1px solid #1C51B1;
+        position: relative;
+        &::before{
+            width: 2px;
+            height: 15px;
+            content: "";
+            position: absolute;
+            top: 3px;
+            left: 5px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_content_chart {
+        height: 100%;
+    }
+}
+/deep/.el-radio-button__orig-radio:checked + .el-radio-button__inner{
+    color: #19F7F9;
+    border-color: #18F6F8;
+    background-color: #0D4573!important;
+}
+/deep/.el-radio-button__inner{
+    background-color: #0D4573;
+    border-color:#18F6F8;
+    border-radius: 0px 0px !important;
+    border-color: #18F6F8;
+    color: #E2E9EE;
+}
+</style>
diff --git a/web/src/views/GoodManage/CostStatistics/RebarCost.vue b/web/src/views/GoodManage/CostStatistics/RebarCost.vue
new file mode 100644
index 0000000..0e54af7
--- /dev/null
+++ b/web/src/views/GoodManage/CostStatistics/RebarCost.vue
@@ -0,0 +1,486 @@
+<template>
+  <div class="main">
+    <div class="main_header">
+        <div class="header_item">
+            <span class="header_label">型号:</span>
+            <el-select v-model="search.steelId" placeholder="请选择型号" clearable>
+                <el-option
+                    v-for="item in optionRebar"
+                    :key="item.steelId"
+                    :label="item.steelName"
+                    :value="item.steelId">
+                </el-option>
+            </el-select>
+        </div>
+        <div class="header_item">
+            <el-radio-group v-model="tabPosition" @input="timesChange"> 
+                <el-radio-button label="day">日</el-radio-button>
+                <el-radio-button label="month">月</el-radio-button>
+            </el-radio-group>
+        </div>
+        <div class="header_item" v-if="showTimes">
+            <span class="header_label">选择时间:</span>
+            <el-date-picker
+            v-model="search.dayData"
+            :picker-options="pickerOptionsDay"
+            :clearable="false"
+            type="daterange"
+            value-format="yyyy-MM-dd"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item" v-if="!showTimes">
+            <span class="header_label">选择月份:</span>
+            <el-date-picker
+            v-model="search.monthData"
+            :picker-options="pickerOptionsMonth"
+            :clearable="false"
+            type="monthrange"
+            value-format="yyyy-MM"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期">
+            </el-date-picker>
+        </div>
+        <div class="header_item">
+            <el-button v-if="showButton('search')" icon="el-icon-search" @click="searchButtonInfo()">查询</el-button>
+            <el-button v-if="showButton('export')" icon="el-icon-download" @click="exportBearExcel()">导出Excel</el-button>
+        </div>
+    </div>
+    <div class="main_middle">
+        <div class="main_middle_titles">数据统计</div>
+        <div class="main_middle_matter">
+            <div class="middle_items" v-for="(item,index) in showDatas" :key="index">
+                <div class="middle_items_text">{{item.steelModel}}</div>
+                <div class="middle_items_datas">{{item.changeStock}}</div>
+            </div>
+        </div>
+    </div>
+    <div class="main_content" style="overflow:auto;padding-bottom:100px;">
+        <div v-for="(echartItem,echartIndex) in echartsList" :key="echartIndex" class="echarts_items">
+            <div class="main_echart_titles">{{echartItem.steelModel}}mm</div>
+            <div :id="echartItem.steelId" class="main_content_chart"></div>
+        </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia';
+import { downFiles } from '../../../plugins/public'; 
+export default {
+  name: 'RebarCost',
+  data() {
+    return {
+        search:{
+            dayData:this.getDateTime(),
+            monthData:this.getMonthTime()
+        },//查询条件
+        tabPosition:'day',//默认展示day
+        showTimes:true,//是否展示日的日期  true:日  false: 月
+        dateType:1,// 1:日  2:月
+        optionRebar:[],//材料类型
+        showDatas:[],//展示的数据统计
+        echartsList:[],//展示echarts表
+        chartsImage:null,
+        pickerMinDate:'',//日期选择增加限制
+        pickerOptionsDay:{ //限制选择日期为15天
+            onPick: ({
+                maxDate,
+                minDate
+            }) => {
+                this.pickerMinDate = minDate.getTime()
+                if (maxDate) {
+                    this.pickerMinDate = ''
+                }
+            },
+            disabledDate: (time) => {
+                if (this.pickerMinDate !== '') {
+                    const one = 15 * 24 * 3600 * 1000
+                    const minTime = this.pickerMinDate - one
+                    const maxTime = this.pickerMinDate + one
+                    return time.getTime() < minTime || time.getTime() > maxTime
+
+                }
+            }
+        },
+        minDates: null,
+        maxDates: null,
+        pickerOptionsMonth: {
+            disabledDate: (time) => {
+                if (this.minDates !== null) {
+                    let minMonth = this.minDates.getMonth(),
+                    lastYear = new Date(this.minDates).setMonth(minMonth - 6),
+                    nextYear = new Date(this.minDates).setMonth(minMonth + 6);
+                    // 只能选 minDate 前后6个月的范围
+                    return time.valueOf() < lastYear.valueOf() || time.valueOf() > nextYear.valueOf();
+                }
+                return false;
+            },
+            onPick: ({minDate, maxDate}) => {
+                this.minDates = minDate;
+                this.maxDates = maxDate;
+            }
+        },
+    }
+  },
+  mounted() {
+    // this.searchButtonInfo()
+    this.getAllTypes()
+  },
+  methods: {
+    // 转圈圈
+    functionLoading() {
+        this.loadingView = this.$loading({
+            lock: true,
+            text: '请稍后...',
+            spinner: 'el-icon-loading',
+            background: 'rgba(0, 0, 0, 0.7)'
+        });
+    },
+    //导出
+    exportBearExcel() {
+        let params = {
+           steelId:this.search.steelId ===undefined ||this.search.steelId ==='' ?'':this.search.steelId,
+           dateType:this.dateType
+        }
+        if(this.dateType === 1){
+            params.strTime = this.search.dayData&&this.search.dayData[0]
+            params.endTime = this.search.dayData&&this.search.dayData[1]
+            delete params.dayData
+        }else{
+            params.strTime = this.search.monthData&&this.search.monthData[0]
+            params.endTime = this.search.monthData&&this.search.monthData[1]
+            delete params.monthData 
+        }
+        this.functionLoading();
+        this.$api.Analyse.exportRebarCost(params).then(res => {
+            downFiles(res, '钢筋消耗信息', 'xls')
+            this.loadingView.close()
+        })
+        .catch(() => {
+            this.loadingView.close();
+        })
+    },
+    //获取时间(默认15天)
+    getDateTime(){
+      return [new Date(new Date().getTime() - 3600*1000*24*15).toISOString().replace('T',' ').split('.')[0],new Date().toISOString().replace('T',' ').split('.')[0]]
+    },
+    //获取时间(默认6个月)
+    getMonthTime(){
+        let date = new Date();
+        let year = date.getFullYear();
+        let month = date.getMonth() + 1;
+        let newYear = 0;
+        let newMonth = 0;
+        let newDateArr = [];
+        for (let i = 0; i < 7; i++) {
+            //这里是获取前六个月,所以循环6次,根据需要修改
+            if (month - i < 1) {
+            //这里的判断是如果当前月份往前推到了去年  需要做的处理
+            newYear = year - 1;
+            newMonth = month - i + 12 >= 10 ? month - i + 12 : '0' + (month - i + 12);
+            newDateArr.push(newYear + '-' + newMonth); //这里拼接格式化,在时间中间加了个-,根据实际需求来
+            } else {
+            newMonth = month - i >= 10 ? month - i : '0' + (month - i); //这里是对月份小于10做加前面加0处理
+            newDateArr.push(year + '-' + newMonth);
+            }
+        }
+        //这里就最后得到当前年月前六个月组成的时间数组,根据需要赋值使用即可
+        const end = newDateArr[0];
+        const start = newDateArr[6];
+        return [start, end];
+    },
+    //获取所有型号
+    getAllTypes(){
+        this.$api.Production.getTableTitleInfo({}).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionRebar = res.data
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+    //展示不同的时间
+    timesChange(val){
+        if(val === 'month'){
+            this.showTimes = false
+            // this.search.dayData = ''
+            this.dateType = 2
+        }else{
+            this.showTimes = true
+            // this.search.monthData = ''
+            this.dateType = 1
+        }
+    },
+    //查询按钮
+    searchButtonInfo() {
+        let params = {
+           steelId:this.search.steelId ===undefined ||this.search.steelId ==='' ?'':this.search.steelId,
+           dateType:this.dateType
+        }
+        if(this.dateType === 1){
+            params.strTime = this.search.dayData&&this.search.dayData[0]
+            params.endTime = this.search.dayData&&this.search.dayData[1]
+            delete params.dayData
+        }else{
+            params.strTime = this.search.monthData&&this.search.monthData[0]
+            params.endTime = this.search.monthData&&this.search.monthData[1]
+            delete params.monthData 
+        }
+        this.$api.Analyse.searchRebarCost(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.echartsList = res.data
+                res.data.forEach(item=>{
+                    let xtitle = item.betweenDate
+                    let showStock = []
+                    item.steelStatisticsDtos.forEach(ite=>{
+                        xtitle.forEach(iten=>{
+                            if(iten === ite.getDate){
+                                showStock.push({
+                                    getDate:iten,
+                                    changeStock:ite.changeStock
+                                })
+                            }else{
+                               showStock.push({
+                                    getDate:iten,
+                                    changeStock:0
+                                }) 
+                            }
+                        })
+                    })
+                    this.$nextTick(() => {
+                        this.createCharts(item.steelId, showStock,item.steelModel);
+                    }) 
+                })
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+        this.$api.Analyse.searchAnalyse(params).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.showDatas = res.data
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+    },
+     // 创建echart图表
+    createCharts(name, data,titleName) {
+        const labelData = data.map(item => item.getDate);
+        const firstData = data.map(item => item.changeStock ? item.changeStock : 0);
+        this.chartsImage = this.$echarts.init(document.getElementById(name));
+        const option = {
+        animationDuration: 1500,
+        tooltip: {
+            trigger: "axis",
+            backgroundColor:'#071F46',
+            textStyle:{
+                color:'#fff',
+            },
+            formatter: function (params) {
+            var relVal = params[0].name;
+            for (var i = 0; i < params.length; i++) {
+                if (params[i].componentIndex === 0) {
+                relVal +=
+                    "<br/>" +
+                    params[i].marker +
+                    `${titleName}` +
+                    " : " +
+                    params[i].value;
+                }
+            }
+            return relVal;
+            },
+        },
+        grid: {
+            top: "15%",
+            right: "3%",
+            left: "3%",
+            bottom: "11%",
+        },
+        xAxis: [
+            {
+            type: "category",
+            data: labelData,
+            axisLine: {
+                lineStyle: {
+                width: 2,
+                color: "#B7E4F7",
+                },
+            },
+            axisLabel: {
+                color: "#B7E4F7",
+            },
+            axisTick: {
+                show: false,
+            },
+            },
+        ],
+        yAxis: [
+            {
+            type: "value",
+            // max: 100,
+            splitNumber: 10,
+            axisLabel: {
+                formatter: "{value}",
+                textStyle: {
+                color: "#CAD3E0",
+                },
+            },
+            splitLine: {
+                lineStyle: {
+                width: 2,
+                type: "dashed",
+                color: "#28477C",
+                },
+            },
+            },
+            {
+            type: "value",
+            max: 100,
+            splitNumber: 10,
+            axisLabel: {
+                formatter: "{value}%",
+                textStyle: {
+                color: "#B7E4F7",
+                },
+            },
+            splitLine: {
+                show: false,
+            },
+            },
+        ],
+        series: [
+            {
+            type: "line",
+            smooth:true,
+            barWidth:40,
+            data: firstData,
+            yAxisIndex: 0,
+            itemStyle: {
+                normal: {
+                color: new this.$echarts.graphic.LinearGradient( 0, 0, 0, 1,
+                    [
+                    {
+                        offset: 0,
+                        color: "rgba(15, 106, 134, 1)", // 0% 处的颜色
+                    },
+                    {
+                        offset: 1,
+                        color: "rgba(28, 186, 233, 1)", // 100% 处的颜色
+                    },
+                    ],
+                    false
+                ),
+                },
+            },
+            },
+        ],
+        }
+        this.chartsImage.clear();
+        this.chartsImage.setOption(option);
+        window.onresize = () => {
+            this.chartsImage.resize()
+        }
+    },
+    // 判断按钮权限信息
+    showButton(str) {
+      const pinia = buttonPinia();
+      return pinia.$state.buttonInfo.includes(str);
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+@import "@/style/layout-main.scss";
+
+.main_middle{
+    width: 97%;
+    margin: 10px 18px;
+
+    .main_middle_titles{
+        width: 100%;
+        color: #19F6F8;
+        position: relative;
+        padding: 10px 15px;
+        border-bottom:1px solid #1B50AE ;
+        &::before{
+            content: "";
+            position: absolute;
+            left: 5px;
+            top: 10px;
+            width: 2px;
+            height: 18px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_middle_matter{
+        padding-top: 15px;
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+
+        .middle_items{
+            width: 150px;
+            height: 80px;
+            background: url('../../../assets/stir_img.png') no-repeat;
+            background-size: 100% 100%;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            flex-direction: column;
+            .middle_items_text{
+                color: #E1E5EB;
+            }
+            .middle_items_datas{
+                color: #18F6F8;
+                font-size: 18px;
+                font-weight: 600;
+            }
+        }
+    }
+}
+
+.echarts_items{
+    height: 332px;
+    padding-top: 10px;
+    padding-bottom: 15px;
+    margin-bottom: 20px;
+    .main_echart_titles{
+        width: 97%;
+        color: #18F6F8;
+        padding-bottom: 15px;
+        padding-left: 15px;
+        border-bottom: 1px solid #1C51B1;
+        position: relative;
+        &::before{
+            width: 2px;
+            height: 15px;
+            content: "";
+            position: absolute;
+            top: 3px;
+            left: 5px;
+            background-color: #18F6F8;
+        }
+    }
+    .main_content_chart {
+        height: 100%;
+    }
+}
+/deep/.el-radio-button__orig-radio:checked + .el-radio-button__inner{
+    color: #19F7F9;
+    border-color: #18F6F8;
+    background-color: #0D4573!important;
+}
+/deep/.el-radio-button__inner{
+    background-color: #0D4573;
+    border-color:#18F6F8;
+    border-radius: 0px 0px !important;
+    border-color: #18F6F8;
+    color: #E2E9EE;
+}
+</style>
diff --git a/web/src/views/GoodManage/MixingManage.vue b/web/src/views/GoodManage/MixingManage.vue
new file mode 100644
index 0000000..595c8c7
--- /dev/null
+++ b/web/src/views/GoodManage/MixingManage.vue
@@ -0,0 +1,85 @@
+<template>
+  <div class="main">
+    <div class="main_tabs">
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+            <el-tab-pane label="库存管理" name="first">
+                <mixing-invent ref="inventm"></mixing-invent> 
+            </el-tab-pane>
+            <el-tab-pane label="入库记录" name="second">
+                <mixing-income ref="incomem"></mixing-income>
+            </el-tab-pane>
+            <el-tab-pane label="消耗记录" name="third">
+                <mixing-cost ref="costsm"></mixing-cost>
+            </el-tab-pane>
+            <el-tab-pane label="校正记录" name="four">
+                <mixing-check ref="checkm"></mixing-check>
+            </el-tab-pane>
+            <el-tab-pane label="原料实际放量" name="five">
+                <real-raw ref="realRaws"></real-raw>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+  </div>
+</template>
+<script>
+import MixingInvent from './components/MixingInvent.vue'//库存管理
+import MixingIncome from './components/MixingIncome.vue'//入库记录
+import MixingCost from './components/MixingCost.vue'//消耗记录
+import MixingCheck from './components/MixingCheck.vue'//校正记录
+import RealRaw from './components/RealRaw.vue'//原料实际放量
+export default {
+    components:{
+        MixingInvent,
+        MixingIncome,
+        MixingCost,
+        MixingCheck,
+        RealRaw
+    },
+    data(){
+        return{
+            activeName:'first'
+        }
+    },
+    mounted(){
+        this.$refs.inventm.searchButtonInfo(true);
+        this.$refs.inventm.getDictNames()
+    },
+    methods:{
+        //切换界面
+        handleClick(tab){
+            switch(tab.name){
+                case 'second':
+                    this.$refs.incomem.searchButtonInfo(true);
+                    this.$refs.incomem.getDictNames()
+                    break;
+                case 'third':
+                    this.$refs.costsm.searchButtonInfo(true);
+                    this.$refs.costsm.getDictNames()
+                    this.$refs.costsm.getAllProjects()
+                    break;
+                case 'four':
+                    this.$refs.checkm.searchButtonInfo(true);
+                    this.$refs.checkm.getDictNames()
+                    break;
+                case 'five':
+                    this.$refs.realRaws.setFormProps();
+                    this.$refs.realRaws.getLists();
+                    this.$refs.realRaws.getMaterialNames();
+                    break;
+                default:
+                    this.$refs.inventm.searchButtonInfo(true);
+            }
+        },
+    }
+}
+</script>
+<style scoped lang="scss">
+@import'@/style/layout-main.scss';
+/deep/ .el-tabs__content{
+    position: static;
+}
+
+/deep/.main {
+  background: none;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/GoodManage/ReinForcement.vue b/web/src/views/GoodManage/ReinForcement.vue
new file mode 100644
index 0000000..ce03670
--- /dev/null
+++ b/web/src/views/GoodManage/ReinForcement.vue
@@ -0,0 +1,81 @@
+<template>
+  <div class="main">
+    <div class="main_tabs">
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+            <el-tab-pane label="库存管理" name="first">
+                <invent-manage ref="invent"></invent-manage> 
+            </el-tab-pane>
+            <el-tab-pane label="入库记录" name="second">
+                <income-record ref="income"></income-record>
+            </el-tab-pane>
+            <el-tab-pane label="消耗记录" name="third">
+                <cost-record ref="costs"></cost-record>
+            </el-tab-pane>
+            <el-tab-pane label="校正记录" name="fourth">
+                <check-record ref="checks"></check-record>
+            </el-tab-pane>
+            <el-tab-pane label="钢筋类型" name="five">
+                <rebar-type ref="rebar"></rebar-type>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+  </div>
+</template>
+<script>
+import InventManage from './components/InventManage.vue'//库存管理
+import IncomeRecord from './components/IncomeRecord.vue'//入库记录
+import CostRecord from './components/CostRecord.vue'//消耗记录
+import CheckRecord from './components/CheckRecord.vue'//校正记录
+import RebarType from './components/RebarType.vue'//钢筋类型
+export default {
+    components:{
+        InventManage,
+        IncomeRecord,
+        CostRecord,
+        CheckRecord,
+        RebarType
+    },
+    data(){
+        return{
+            activeName:'first'
+        }
+    },
+    mounted(){
+        this.$refs.invent.searchButtonInfo(true);
+    },
+    methods:{
+        //切换界面
+        handleClick(tab){
+            switch(tab.name){
+                case 'second':
+                    this.$refs.income.searchButtonInfo(true);
+                    this.$refs.income.getNameList()
+                    break;
+                case 'third':
+                    this.$refs.costs.searchButtonInfo(true);
+                    this.$refs.costs.getNameList()
+                    break;
+                case 'fourth':
+                    this.$refs.checks.searchButtonInfo(true);
+                    this.$refs.checks.getNameList()
+                    break;
+                case 'five':
+                    this.$refs.rebar.searchButtonInfo(true);
+                    break;
+                default:
+                    this.$refs.invent.searchButtonInfo(true);
+            }
+        },
+    }
+}
+</script>
+<style scoped lang="scss">
+@import'@/style/layout-main.scss';
+/deep/ .el-tabs__content{
+    position: static;
+}
+
+/deep/.main {
+  background: none;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/GoodManage/RevolvingMaterial.vue b/web/src/views/GoodManage/RevolvingMaterial.vue
new file mode 100644
index 0000000..a025f6d
--- /dev/null
+++ b/web/src/views/GoodManage/RevolvingMaterial.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>周转材料</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/MaterialsIndex/components/AuxiliaryCheck.vue b/web/src/views/GoodManage/components/AuxiliaryCheck.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/AuxiliaryCheck.vue
rename to web/src/views/GoodManage/components/AuxiliaryCheck.vue
diff --git a/web/src/views/MaterialsIndex/components/AuxiliaryCost.vue b/web/src/views/GoodManage/components/AuxiliaryCost.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/AuxiliaryCost.vue
rename to web/src/views/GoodManage/components/AuxiliaryCost.vue
diff --git a/web/src/views/MaterialsIndex/components/AuxiliaryIncome.vue b/web/src/views/GoodManage/components/AuxiliaryIncome.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/AuxiliaryIncome.vue
rename to web/src/views/GoodManage/components/AuxiliaryIncome.vue
diff --git a/web/src/views/MaterialsIndex/components/AuxiliaryInvent.vue b/web/src/views/GoodManage/components/AuxiliaryInvent.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/AuxiliaryInvent.vue
rename to web/src/views/GoodManage/components/AuxiliaryInvent.vue
diff --git a/web/src/views/MaterialsIndex/components/AuxiliaryType.vue b/web/src/views/GoodManage/components/AuxiliaryType.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/AuxiliaryType.vue
rename to web/src/views/GoodManage/components/AuxiliaryType.vue
diff --git a/web/src/views/MaterialsIndex/components/CheckRecord.vue b/web/src/views/GoodManage/components/CheckRecord.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/CheckRecord.vue
rename to web/src/views/GoodManage/components/CheckRecord.vue
diff --git a/web/src/views/MaterialsIndex/components/CostRecord.vue b/web/src/views/GoodManage/components/CostRecord.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/CostRecord.vue
rename to web/src/views/GoodManage/components/CostRecord.vue
diff --git a/web/src/views/MaterialsIndex/components/IncomeRecord.vue b/web/src/views/GoodManage/components/IncomeRecord.vue
similarity index 99%
rename from web/src/views/MaterialsIndex/components/IncomeRecord.vue
rename to web/src/views/GoodManage/components/IncomeRecord.vue
index e641005..12bd847 100644
--- a/web/src/views/MaterialsIndex/components/IncomeRecord.vue
+++ b/web/src/views/GoodManage/components/IncomeRecord.vue
@@ -422,5 +422,5 @@
 </script>
 
 <style lang="scss" scoped>
-@import '../../../style/layout-main.scss';
+@import'@/style/layout-main.scss';
 </style>
\ No newline at end of file
diff --git a/web/src/views/MaterialsIndex/components/InventManage.vue b/web/src/views/GoodManage/components/InventManage.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/InventManage.vue
rename to web/src/views/GoodManage/components/InventManage.vue
diff --git a/web/src/views/MaterialsIndex/components/MixingCheck.vue b/web/src/views/GoodManage/components/MixingCheck.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/MixingCheck.vue
rename to web/src/views/GoodManage/components/MixingCheck.vue
diff --git a/web/src/views/MaterialsIndex/components/MixingCost.vue b/web/src/views/GoodManage/components/MixingCost.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/MixingCost.vue
rename to web/src/views/GoodManage/components/MixingCost.vue
diff --git a/web/src/views/MaterialsIndex/components/MixingIncome.vue b/web/src/views/GoodManage/components/MixingIncome.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/MixingIncome.vue
rename to web/src/views/GoodManage/components/MixingIncome.vue
diff --git a/web/src/views/MaterialsIndex/components/MixingInvent.vue b/web/src/views/GoodManage/components/MixingInvent.vue
similarity index 100%
rename from web/src/views/MaterialsIndex/components/MixingInvent.vue
rename to web/src/views/GoodManage/components/MixingInvent.vue
diff --git a/web/src/views/GoodManage/components/RealRaw.vue b/web/src/views/GoodManage/components/RealRaw.vue
new file mode 100644
index 0000000..1e31fa8
--- /dev/null
+++ b/web/src/views/GoodManage/components/RealRaw.vue
@@ -0,0 +1,435 @@
+<template>
+  <!-- 生产计划管理 ==> 原料实际放量-->
+  <div class="main tabs_main" style="height:89%">
+    <!-- header-->
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">日期:</span>
+        <el-date-picker v-model="datePicker" type="daterange" range-separator="至" start-placeholder="开始日期"
+          end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" @change="dateChange">
+        </el-date-picker>
+      </div>
+      <div class="header_item">
+        <el-button icon="el-icon-search" v-if="showButton('search')" @click="query">查询</el-button>
+        <el-button class="search_btn" icon="el-icon-plus" v-if="showButton('insert')" @click="addRow">新增</el-button>
+        <el-button icon="el-icon-upload2" v-if="showButton('export')" @click="exportExcel">导出Excel</el-button>
+      </div>
+    </div>
+    <!-- content-->
+    <div class="main_content">
+      <el-table v-loading="loading" :data="dataLists" border height="100%">
+        <!--  -->
+        <el-table-column align="center" label="序号" width="48">
+          <template #default="scope">
+            <span>{{ (queryInfo.pageNum - 1) * queryInfo.pageSize + scope.$index + 1 }}</span>
+          </template>
+        </el-table-column>
+        <!--  -->
+        <el-table-column align="center" label="操作" width="74">
+          <template #default="{ row }">
+            <el-button size="mini" @click="copyRow(row)">复制</el-button>
+          </template>
+        </el-table-column>
+        <!--  -->
+        <el-table-column prop="materialReleaseTime" align="center" label="时间">
+        </el-table-column>
+        <!--  -->
+        <el-table-column prop="quantity" align="center" label="方量">
+        </el-table-column>
+        <!--  -->
+        <el-table-column label="理论配比(kg/m³)" align="center">
+          <el-table-column v-for="item in materialNames" :label="item.dictName" :key="item.dictId" align="center">
+            <template #default="{ row }">
+              {{ row.treleaseTheoryKeys[item.dictId].releaseData | toFloat }}
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <!--  -->
+        <el-table-column label="实际消耗(kg/m³)" align="center">
+          <el-table-column v-for="item in materialNames" :label="item.dictName" :key="item.dictId" align="center">
+            <template #default="{ row }">
+              {{ row.treleaseRealKeys[item.dictId].releaseData | toFloat }}
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <!--  -->
+        <el-table-column label="操作" align="center" width="138">
+          <template #default="{ row }">
+            <el-button class="table_btn" size="mini" v-if="showButton('update')" @click="updateRow(row)">修改</el-button>
+            <el-button class="delete_btn" size="mini" v-if="showButton('delete')" @click="deleteRow(row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <!-- footer-->
+    <div class="main_footer">
+      <el-pagination background @current-change="changePageNum" @size-change="changePageSize"
+        :current-page="queryInfo.pageNum" :page-sizes="[10, 20, 50, 100]" :page-size="queryInfo.pageSize"
+        layout="total, sizes, prev, pager, next, jumper" :total="total">
+      </el-pagination>
+    </div>
+    <!-- dialog-->
+    <el-dialog class="prop_dialog" v-if="isRender" :title="dialogTitle" :visible.sync="asyncVisible" width="700px"
+      @close="closeForm">
+      <el-form :inline="true" size="mini" :model="form" label-width="auto" class="rule_form">
+        <!-- 理论 -->
+        <div class="elFormTitle">理论配比(kg/m³)</div>
+        <!-- 理论配比 -->
+        <el-form-item v-for="item in form.materialTheory" :key="`${item.dictId}${item.releaseType}`"
+          :label="item.dictName">
+          <el-input placeholder="请输入" type="number" v-model="item.releaseData" @input="doCompute($event, item.dictId)"
+            clearable></el-input>
+        </el-form-item>
+        <!-- 方量 -->
+        <el-form-item class="elFormTitle" type="number" label="方量(m³)" style="width:90%">
+          <el-input placeholder="请输入" v-model="form.quantity" @input="doComputeMulti($event)"></el-input>
+        </el-form-item>
+        <!-- 实际配比 -->
+        <el-form-item v-for="item in form.materialReal" :key="`${item.dictId}${item.releaseType}`" :label="item.dictName">
+          <el-input type="number" v-model="item.releaseData" :disabled="true" clearable></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="asyncVisible = false">取 消</el-button>
+        <el-button class="submit_btn" @click="onSubmit">提 交</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {buttonPinia} from '../../../pinia/index'
+import {throttle, downFiles} from '../../../plugins/public'
+export default {
+  data() {
+    return {
+      isRender: false,
+      loading: false,
+      asyncVisible: false, // 添加 修改对话框
+      rowId: '', // 修改id
+      total: 0,
+      submitMode: '', // add update copy
+      dataLists: [],
+      datePicker: '',
+      queryInfo: {
+        pageNum: 1,
+        pageSize: 10,
+        strTime: '',
+        endTime: ''
+      },
+      form: null, // 表单数据 {}
+      materialNames: [], // 原料名称
+      materialNameKeys: {}, // {id: name}
+    }
+  },
+  computed: {
+    dialogTitle() {
+      return this.submitMode === 'update' ? '修改' : '新增'
+    },
+    isUpdate() {
+      return this.submitMode === 'update'
+    },
+  },
+  filters: {
+    toFloat(value) {
+      return value.toFixed(4)
+    }
+  },
+  async created() {
+    // this.setFormProps()
+    // this.getLists()
+    // await this.getMaterialNames()
+    // this.setFormProps()
+  },
+  methods: {
+    getLists() {
+      let params = this.queryInfo
+      this.loading = true
+      this.$api.Ducts.practicalRaw.getLists(params).then(res => {
+        this.loading = false
+        if (res.statusMsg === 'ok') {
+          this.total = res.data.total
+          this.dataLists = res.data.list
+
+          this.dataLists.forEach(item => {
+            // 接口返回是混一起的数据,,需要清洗.
+            item.treleaseTheoryData = []
+            item.treleaseRealData = []
+            item.treleaseTheoryKeys = {}
+            item.treleaseRealKeys = {}
+            if (item.treleaseData.length) {
+              item.treleaseData.forEach(val => {
+                let newVal = {...val}
+                if (val.releaseType === 1) {
+                  item.treleaseTheoryData.push(newVal)
+                  item.treleaseTheoryKeys[val.dictId] = newVal
+                  item.treleaseTheoryKeys[val.dictId].dictName = this.getMaterialNameById(val.dictId)
+                } else if (val.releaseType === 2) {
+                  item.treleaseRealData.push(newVal)
+                  item.treleaseRealKeys[val.dictId] = newVal
+                  item.treleaseRealKeys[val.dictId].dictName = this.getMaterialNameById(val.dictId)
+                }
+              })
+            }
+          })
+        } else {
+          this.$message.warning(res.statusMsg)
+        }
+      })
+    },
+    //获取原料名称
+    getMaterialNames() {
+      return new Promise(resolve => {
+        this.$api.Ducts.practicalRaw.getMaterialNames({}).then(res => {
+          if (res.statusMsg === 'ok') {
+            this.materialNames.push(...res.data)
+            this.materialNames.forEach(item => {
+              this.materialNameKeys[item.dictId] = item.dictName
+            })
+            resolve()
+          } else {
+            this.$message.warning(res.statusMsg)
+          }
+        })
+      })
+
+    },
+    getMaterialNameById(id) {
+      return this.materialNameKeys[id] || ''
+    },
+    setFormProps(options = {}) {
+      const {quantity = 1, materialTheory = [], materialReal = []} = options
+      let _form = {
+        quantity,   // 方量
+        materialTheory, // 原料理论信息
+        materialReal // 原料实际信息信息
+      }
+      if (materialTheory.length) {
+        this.form = _form
+        return
+      }
+      this.materialNames.forEach(item => {
+        _form.materialTheory.push({
+          dictName: item.dictName,  // 原料id
+          dictId: item.dictId,  // 原料id
+          releaseData: '',      // 数值
+          releaseType: 1       // 1理论耗量 2实际消耗
+        })
+        _form.materialReal.push({
+          dictName: item.dictName,
+          dictId: item.dictId,
+          releaseData: '',
+          releaseType: 2
+        })
+      })
+      this.form = _form
+    },
+    doCompute(value, dictId) {
+      let {quantity, materialReal} = this.form
+      for (let i = 0; i < materialReal.length; i++) {
+        let item = materialReal[i]
+        if (item.dictId === dictId) {
+          item.releaseData = quantity * value
+          break
+        }
+      }
+    },
+    doComputeMulti() {
+      let {quantity, materialReal, materialTheory} = this.form
+      let _materialTheory = {}
+      materialTheory.forEach(item => {
+        if (item.releaseData) {
+          _materialTheory[item.dictId] = item.releaseData
+        }
+      })
+      materialReal.forEach(item => {
+        if (_materialTheory[item.dictId]) {
+          item.releaseData = _materialTheory[item.dictId] * quantity
+        } else {
+          item.releaseData = ''
+        }
+      })
+    },
+    showForm() {
+      !this.isRender && (this.isRender = true)
+      this.asyncVisible = true
+    },
+    closeForm() {
+      this.asyncVisible = false
+      this.setFormProps()
+    },
+    dateChange(dates) {
+      dates = dates || []
+      if (dates.length) {
+        dates[1] = dates[1].slice(0, -8) + '23:59:59'
+      }
+      this.queryInfo.strTime = dates[0] || ''
+      this.queryInfo.endTime = dates[1] || ''
+    },
+    // 查询按钮列表信息
+    query() {
+      this.queryInfo.pageNum = 1
+      this.queryInfo.pageSize = 10
+      this.getLists()
+    },
+    addRow() {
+      this.submitMode = 'add'
+      this.showForm()
+    },
+    copyRow(row) {
+      this.submitMode = 'copy'
+      this.rowId = row.materialReleaseId
+      let _materialIds = []
+      this.materialNames.forEach(item => {
+        _materialIds.push(item.dictId)
+      })
+      row.treleaseTheoryData.sort(function (a, b) {
+        return (_materialIds.indexOf(a.dictId) - _materialIds.indexOf(b.dictId))
+      })
+      row.treleaseRealData.sort(function (a, b) {
+        return (_materialIds.indexOf(a.dictId) - _materialIds.indexOf(b.dictId))
+      })
+      let opts = {
+        quantity: row.quantity,
+        materialTheory: row.treleaseTheoryData,
+        materialReal: row.treleaseRealData,
+      }
+      this.setFormProps(opts)
+      this.showForm()
+    },
+    updateRow(row) {
+      this.submitMode = 'update'
+      this.rowId = row.materialReleaseId
+      let _materialIds = []
+      this.materialNames.forEach(item => {
+        _materialIds.push(item.dictId)
+      })
+      row.treleaseTheoryData.sort(function (a, b) {
+        return (_materialIds.indexOf(a.dictId) - _materialIds.indexOf(b.dictId))
+      })
+      row.treleaseRealData.sort(function (a, b) {
+        return (_materialIds.indexOf(a.dictId) - _materialIds.indexOf(b.dictId))
+      })
+      let opts = {
+        quantity: row.quantity,
+        materialTheory: row.treleaseTheoryData,
+        materialReal: row.treleaseRealData,
+      }
+      this.setFormProps(opts)
+      this.showForm()
+    },
+    deleteRow(row) {
+      this.$confirm("该操作将删除该信息,是否继续删除?", "提示", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(() => {
+        this.$api.Ducts.practicalRaw.delete({materialReleaseId: row.materialReleaseId})
+          .then(res => {
+            if (res.statusMsg === 'ok') {
+              this.query()
+              this.$message.success("删除成功!")
+            } else {
+              this.$message.warning(res.statusMsg)
+            }
+          })
+      }).catch(() => {
+        this.$message.warning("您已取消");
+      })
+    },
+    onSubmit: throttle(function () {
+      const {quantity, materialTheory, materialReal} = this.form
+      let releaseData = [...materialTheory, ...materialReal]
+      // 为空数据,重置为0,否则接口报错
+      releaseData.forEach(item => {
+        if (!item.releaseData) {
+          item.releaseData = 0
+        }
+      })
+      let params = {quantity, releaseData}
+      if (this.isUpdate) {
+        // 更新
+        params.materialReleaseId = this.rowId
+        this.$api.Ducts.practicalRaw.update(params).then(res => {
+          if (res.statusMsg === 'ok') {
+            this.closeForm()
+            this.getLists()
+            this.$message.success('修改成功!')
+          } else {
+            this.$message.warning(res.statusMsg)
+          }
+        })
+      } else {
+        // 添加 复制
+        this.$api.Ducts.practicalRaw.insert(params).then(res => {
+          if (res.statusMsg === 'ok') {
+            this.closeForm()
+            this.getLists()
+            this.$message.success('添加成功!')
+          } else {
+            this.$message.warning(res.statusMsg)
+          }
+        })
+      }
+    }, 3000),
+    exportExcel() {
+      let params = this.queryInfo
+      this.$api.Ducts.practicalRaw.exportXls(params).then(res => {
+        if (res && res.size) {
+          downFiles(res, '原料实际放量', 'xlsx')
+        } else {
+          this.$message.warning(res.statusMsg)
+        }
+      })
+    },
+    // 判断按钮权限信息
+    showButton(str) {
+      const pinia = buttonPinia();
+      return pinia.$state.buttonInfo.includes(str);
+    },
+    // 切换页数
+    changePageNum(num) {
+      this.queryInfo.pageNum = num
+      this.getLists()
+    },
+    // 切换每页条数
+    changePageSize(num) {
+      this.queryInfo.pageSize = num
+      this.getLists()
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import '../../../style/layout-main.scss';
+
+.elFormTitle {
+  display: block;
+  font-weight: bold;
+  color: #39B5FE;
+  padding-bottom: 18px;
+  border-bottom: 1px solid #39B5FE;
+
+  &:first-child {
+    position: relative;
+    margin-bottom: 18px;
+    text-indent: 14px;
+
+    &::after {
+      content: '';
+      position: absolute;
+      left: 0;
+      top: 0;
+      width: 2px;
+      height: 16px;
+      border-left: 3px solid #39B5FE;
+    }
+  }
+}
+
+/deep/.prop_dialog .elFormTitle .el-form-item__label {
+  font-weight: bold;
+  color: #39B5FE;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/MaterialsIndex/components/RebarType.vue b/web/src/views/GoodManage/components/RebarType.vue
similarity index 99%
rename from web/src/views/MaterialsIndex/components/RebarType.vue
rename to web/src/views/GoodManage/components/RebarType.vue
index 0921c01..811fc8a 100644
--- a/web/src/views/MaterialsIndex/components/RebarType.vue
+++ b/web/src/views/GoodManage/components/RebarType.vue
@@ -239,5 +239,5 @@
 </script>
 
 <style lang="scss" scoped>
-@import '../../../style/layout-main.scss';
+@import'@/style/layout-main.scss';
 </style>
\ No newline at end of file
diff --git a/web/src/views/MaterialsIndex/MixingManage.vue b/web/src/views/MaterialsIndex/MixingManage.vue
index 5b221a7..0c89919 100644
--- a/web/src/views/MaterialsIndex/MixingManage.vue
+++ b/web/src/views/MaterialsIndex/MixingManage.vue
@@ -19,17 +19,17 @@
   </div>
 </template>
 <script>
-import MixingInvent from './components/MixingInvent.vue'//库存管理
-import MixingIncome from './components/MixingIncome.vue'//入库记录
-import MixingCost from './components/MixingCost.vue'//消耗记录
-import MixingCheck from './components/MixingCheck.vue'//校正记录
+// import MixingInvent from './components/MixingInvent.vue'//库存管理
+// import MixingIncome from './components/MixingIncome.vue'//入库记录
+// import MixingCost from './components/MixingCost.vue'//消耗记录
+// import MixingCheck from './components/MixingCheck.vue'//校正记录
 export default {
-    components:{
-        MixingInvent,
-        MixingIncome,
-        MixingCost,
-        MixingCheck
-    },
+    // components:{
+    //     MixingInvent,
+    //     MixingIncome,
+    //     MixingCost,
+    //     MixingCheck
+    // },
     data(){
         return{
             activeName:'first'
diff --git a/web/src/views/MaterialsIndex/ReinforcementIndex.vue b/web/src/views/MaterialsIndex/ReinforcementIndex.vue
index ce03670..ec4072f 100644
--- a/web/src/views/MaterialsIndex/ReinforcementIndex.vue
+++ b/web/src/views/MaterialsIndex/ReinforcementIndex.vue
@@ -22,19 +22,19 @@
   </div>
 </template>
 <script>
-import InventManage from './components/InventManage.vue'//库存管理
-import IncomeRecord from './components/IncomeRecord.vue'//入库记录
-import CostRecord from './components/CostRecord.vue'//消耗记录
-import CheckRecord from './components/CheckRecord.vue'//校正记录
-import RebarType from './components/RebarType.vue'//钢筋类型
+// import InventManage from './components/InventManage.vue'//库存管理
+// import IncomeRecord from './components/IncomeRecord.vue'//入库记录
+// import CostRecord from './components/CostRecord.vue'//消耗记录
+// import CheckRecord from './components/CheckRecord.vue'//校正记录
+// import RebarType from './components/RebarType.vue'//钢筋类型
 export default {
-    components:{
-        InventManage,
-        IncomeRecord,
-        CostRecord,
-        CheckRecord,
-        RebarType
-    },
+    // components:{
+    //     InventManage,
+    //     IncomeRecord,
+    //     CostRecord,
+    //     CheckRecord,
+    //     RebarType
+    // },
     data(){
         return{
             activeName:'first'
diff --git a/web/src/views/ProjectManage/AmountManage.vue b/web/src/views/ProjectManage/AmountManage.vue
new file mode 100644
index 0000000..5c3e1aa
--- /dev/null
+++ b/web/src/views/ProjectManage/AmountManage.vue
@@ -0,0 +1,64 @@
+<template>
+  <div class="main">
+    <div class="main_tabs">
+      <el-tabs v-model="activeName" @tab-click="handleClick">
+            <el-tab-pane label="预埋件理论耗量" name="first">
+                <fitt-consump ref="Fitts"></fitt-consump> 
+            </el-tab-pane>
+            <el-tab-pane label="钢筋笼理论耗量" name="second">
+                <rebar-consump ref="Rebars"></rebar-consump>
+            </el-tab-pane>
+            <el-tab-pane label="混凝土方量及混凝土原材料" name="third">
+                <raw-consump ref="Raws"></raw-consump>
+            </el-tab-pane>
+        </el-tabs>
+    </div>
+  </div>
+</template>
+<script>
+import FittConsump from './components/FittConsump.vue'//预埋件理论耗量
+import RebarConsump from './components/RebarConsump.vue'//钢筋笼理论耗量
+import RawConsump from './components/RawConsump.vue'//混凝土方量及混凝土原材料
+export default {
+    components:{
+        FittConsump,
+        RebarConsump,
+        RawConsump
+    },
+    data(){
+        return{
+            activeName:'first'
+        }
+    },
+    mounted(){
+        this.$refs.Fitts.searchButtonInfo(true);
+    },
+    methods:{
+        //切换界面
+        handleClick(tab){
+            switch(tab.name){
+                case 'second':
+                    this.$refs.Rebars.getInits();
+                    this.$refs.Rebars.getAllProjectData();
+                    break;
+                case 'third':
+                    this.$refs.Raws.getAllProjects();
+                    this.$refs.Raws.searchButtonInfo(true);
+                    break;
+                default:
+                    this.$refs.Fitts.searchButtonInfo(true);
+            }
+        },
+    }
+}
+</script>
+<style scoped lang="scss">
+@import'@/style/layout-main.scss';
+/deep/ .el-tabs__content{
+    position: static;
+}
+
+/deep/.main {
+  background: none;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/ProjectManage/components/FittConsump.vue b/web/src/views/ProjectManage/components/FittConsump.vue
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/web/src/views/ProjectManage/components/FittConsump.vue
diff --git a/web/src/views/ProjectManage/components/RawConsump.vue b/web/src/views/ProjectManage/components/RawConsump.vue
new file mode 100644
index 0000000..d79a183
--- /dev/null
+++ b/web/src/views/ProjectManage/components/RawConsump.vue
@@ -0,0 +1,456 @@
+<template>
+  <div class="main tabs_main" style="height:89%">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="search.proId" placeholder="请选择项目名称" clearable filterable @change="changeSizes">
+            <el-option
+            v-for="item in optionsProject"
+            :key="item.proId"
+            :label="item.proName"
+            :value="item.proId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">尺寸:</span>
+        <el-select v-model="search.size" placeholder="请选择尺寸" clearable>
+            <el-option
+                v-for="item in optionsSize"
+                :key="item.sizeId"
+                :label="item.sizeName"
+                :value="item.sizeId">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_label">配筋:</span>
+        <el-select v-model="search.reinforcement" placeholder="请选择配筋" clearable>
+            <el-option
+                v-for="item in optionsHass"
+                :key="item.hasSteel"
+                :label="item.has"
+                :value="item.hasSteel">
+            </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <el-button icon="el-icon-search" v-if="showButton('search')" @click="searchButtonInfo(true)">查询</el-button>
+        <el-button class="search_btn" icon="el-icon-plus" v-if="showButton('insert')" @click="insertProp">新增</el-button>
+        <el-button icon="el-icon-upload2" v-if="showButton('export')" @click="exportBtn">导出Excel</el-button>
+      </div>
+    </div>
+    <div class="main_content">
+      <el-table
+        v-loading="loading"
+        :data="dataList"
+        height="100%">
+        <el-table-column align="center" label="序号" width="60">
+          <template #default="scope">
+            <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column :prop="item.prop" v-for="(item,index) in tableTitles" :key="index" :label="item.label" align="center" width="135"></el-table-column>
+        <el-table-column label="操作" align="center" width="200">
+          <template #default="{ row }">
+            <el-button class="table_btn" size="mini" v-if="showButton('update')" @click="updateProp(row)">修改</el-button>
+            <el-button class="delete_btn" size="mini" v-if="showButton('delete')" @click="deleteInfo(row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+    <el-dialog
+      class="prop_dialog"
+      :title="asyncTitle ? '新增' : '修改'"
+      :close-on-click-modal="false"
+      :visible.sync="asyncVisible"
+      width="35%">
+      <el-form ref="ruleForm" :model="ruleForm" :rules="rules" label-width="auto" class="rule_form">
+        <el-form-item label="项目名称:" prop="proId">
+          <el-select v-model="ruleForm.proId" placeholder="请选择项目名称" @change="changeSizes" clearable>
+                <el-option
+                v-for="item in optionsProject"
+                :key="item.proId"
+                :label="item.proName"
+                :value="item.proId">
+                </el-option>
+            </el-select>
+        </el-form-item>
+        <el-form-item label="尺寸:" prop="size">
+          <el-select v-model="ruleForm.size" placeholder="请选择尺寸" >
+            <el-option
+                v-for="item in optionsSize"
+                :key="item.sizeId"
+                :label="item.sizeName"
+                :value="item.sizeId">
+            </el-option>
+        </el-select>
+        </el-form-item>
+        <el-form-item label="配筋:" prop="reinforcement">
+          <el-select v-model="ruleForm.reinforcement" placeholder="请选择配筋">
+            <el-option
+                v-for="item in optionsHass"
+                :key="item.hasSteel"
+                :label="item.has"
+                :value="item.hasSteel">
+            </el-option>
+        </el-select>
+        </el-form-item>
+        <el-form-item label="块号:" prop="blockNum">
+          <el-select v-model="ruleForm.blockNum" placeholder="请选择块号">
+            <el-option
+                v-for="item in optionsBlocks"
+                :key="item.blockNum"
+                :label="item.blockName"
+                :value="item.blockNum">
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <div style="height:300px">
+            <el-table
+                v-loading="loadingForm"
+                :data="rawList"
+                height="100%"
+                :header-cell-style="() => 'background-color: #082F57; color: #39B5FE'">
+                <el-table-column align="center" label="序号" width="60">
+                <template #default="scope">
+                    <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+                </template>
+                </el-table-column>
+                <el-table-column prop="materialNameCn" label="原料名称" align="center" show-overflow-tooltip></el-table-column>
+                <el-table-column  label="重量" align="center" show-overflow-tooltip>
+                    <template #default="{row}">
+                        <el-input 
+                            v-model="row.materialValue" 
+                            :size="size"
+                            type="number"
+                            placeholder="请输入">
+                            <template slot="append">吨</template>
+                        </el-input>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="asyncVisible = false">取 消</el-button>
+        <el-button class="submit_btn" @click="asyncTitle ? submitInsert() : submitUpdate()">提 交</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from '../../../pinia/index';
+import { throttle, changeSize,downLoadFile } from '../../../plugins/public'; // 导入节流、动态切换组件尺寸方法
+  export default {
+    data() {
+      return {
+        size: changeSize(), // 组件尺寸
+        pageNum: 1,
+        pageSize: 10,
+        search:{},//查询条件
+        total: 0,
+        loading: false,
+        loadingForm:false,
+        rowId:'',//某一行id
+        dataList: [], //管片原料理论放量信息
+        tableTitles:[],//表头名称
+        optionsProject:[],//项目名称
+        asyncTitle: true, // 对话框title 新增:true  修改:false
+        asyncVisible: false, // 添加 修改对话框
+        ruleForm: {}, // 按钮表单
+        rules: {
+          proId: [{
+            required: true,
+            message: '请选择项目名称',
+            trigger: 'change'
+          }],
+          size: [{
+            required: true,
+            message: '请选择尺寸',
+            trigger: 'change'
+          }],
+          reinforcement: [{
+            required: true,
+            message: '请选择配筋',
+            trigger: 'change'
+          }],
+          blockNum: [{
+            required: true,
+            message: '请选择块号',
+            trigger: 'change'
+          }],
+        },
+        optionsSize:[],//尺寸
+        optionsHass:[],//配筋
+        optionsBlocks:[],//块号
+        rawList:[],//弹框中的原料数据
+      }
+    },
+    watch: {
+      asyncVisible(bol) {
+        if(!bol) {
+          this.ruleForm = {};
+          this.$refs.ruleForm.resetFields();
+        }
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+    //   that.searchButtonInfo(true);
+    //   that.getAllProjects()
+      // that.getPlanRaw()
+    },
+    methods: {
+      //导出按钮
+      exportBtn(){
+        let params = Object.assign({},this.search)
+        this.$api.Ducts.exportBtns(params).then(res=>{
+            if(res.statusMsg ==='ok'){
+                downLoadFile(res.data,'/materials/rsbMaterialPlan/export')
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+      },
+      //获取计划原料列表
+      getPlanRaw(){
+        this.loadingForm = true
+        this.$api.Ducts.getPlanList({}).then(res=>{
+            if(res.statusMsg==='ok'){
+                this.rawList = res.data
+                this.loadingForm = false
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+      },
+      //通过选择项目选择尺寸
+     changeSizes(val){
+      this.$api.Reinforce.searchProjectSize({proId:val,pageNum: 1,
+          pageSize:100000000}).then(res=>{
+        if(res.statusMsg === 'ok'){
+          if(this.search.proId ===""){
+            this.optionsSize = []
+            this.search.size = ""
+            this.search.reinforcement = ""
+          }else if(this.ruleForm.proId ===""){
+            this.optionsSize = []
+            this.ruleForm.size = ""
+            this.ruleForm.reinforcement = ""
+            this.ruleForm.blockNum = ""
+          }else{
+            this.optionsSize = res.data.list
+          }
+        }else{
+            this.$message.warning(res.statusMsg)
+        }
+      })
+      this.$api.Reinforce.searchProjectBears({proId:val,pageNum: 1,
+          pageSize:1000000}).then(res=>{
+        if(res.statusMsg === 'ok'){
+            this.optionsHass = res.data.hasDtos
+            this.optionsBlocks = res.data.blokDtos
+        }else{
+            this.$message.warning(res.statusMsg)
+        }
+      })
+     },
+     //获得所有项目名称
+     getAllProjects(){
+        let obj = {
+            pageNum: 1,
+            pageSize: 100000000
+        }
+        this.$api.Engineer.searchProjects(obj).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.optionsProject = res.data.list
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+     },
+      // 查询按钮列表信息
+      searchButtonInfo(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        let params = Object.assign({},this.search,{
+          pageNum: this.pageNum,
+          pageSize: this.pageSize
+        })
+        this.loading = true;
+        this.$api.Ducts.searchDuctRaw(params).then((res) => {
+          if(res.statusMsg === 'ok') {
+            this.total = res.data.pageInfo.total;
+            this.dataList = res.data.pageInfo.list;
+            let titles = []
+            titles =res.data.tableHeader.map(item=>{
+                return{
+                    label:item.headName+'(吨)',
+                    prop:item.fieldName
+                }
+            })
+            this.tableTitles = [{
+                label:"项目名称",
+                prop:"proName"
+            },{
+                label:"尺寸",
+                prop:"sizeName"
+            },{
+                label:"配筋",
+                prop:"reinforcementName"
+            },{
+                label:"块号",
+                prop:"blockNumName"
+            },...titles,{
+                label:"创建人",
+                prop:"createUserName"
+            },{
+                label:"创建时间",
+                prop:"createTime"
+            }]
+            this.loading = false;
+          }else{
+            this.$message.warning(res.statusMsg)
+          }
+        })
+      },
+      // 新增按钮信息
+      insertProp() {
+        this.asyncTitle = true;
+        this.asyncVisible = true;
+        this.getPlanRaw()
+      },
+      // 修改按钮信息
+      updateProp(row) {
+        this.asyncTitle = false;
+        this.asyncVisible = true;
+        this.ruleForm = row
+        this.rowId = row.id
+        this.$api.Reinforce.searchProjectSize({proId:row.proId,pageNum: 1,
+          pageSize:100000000}).then(res=>{
+        if(res.statusMsg === 'ok'){
+          if(this.ruleForm.proId ===""){
+            this.optionsSize = []
+          }else{
+            this.optionsSize = res.data.list
+          }
+        }else{
+            this.$message.warning(res.statusMsg)
+        }
+      })
+      this.$api.Reinforce.searchProjectBears({proId:row.proId,pageNum: 1,
+          pageSize:1000000}).then(res=>{
+        if(res.statusMsg === 'ok'){
+            this.optionsHass = res.data.hasDtos
+            this.optionsBlocks = res.data.blokDtos
+        }else{
+            this.$message.warning(res.statusMsg)
+        }
+      })
+        this.$api.Ducts.getPlanList({id:row.id}).then(res=>{
+            if(res.statusMsg === 'ok'){
+                this.rawList = res.data
+            }else{
+                this.$message.warning(res.statusMsg)
+            }
+        })
+      },
+      // 删除按钮信息
+      deleteInfo(row) {
+        this.$confirm("该操作将删除该信息,是否继续删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+       })
+       .then(() => {
+         this.$api.Ducts.deleteDuctRaw({id: row.id})
+        .then(res => {
+          if(res.statusMsg === 'ok') {
+            this.searchButtonInfo(true);
+            this.$message.success("删除成功!");
+          } else {
+            this.$message.warning(res.statusMsg);
+          }
+        })
+       })
+       .catch(() => {
+         this.$message.warning("您已取消");
+       })
+      },
+      // 提交添加按钮信息
+      submitInsert: throttle(function() {
+        this.$refs.ruleForm.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.ruleForm);
+            params.materialsList = this.rawList
+            this.$api.Ducts.insertDuctRaw(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncVisible = false;
+                this.searchButtonInfo(true);
+                this.$message.success('添加成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 提交修改按钮信息
+      submitUpdate: throttle(function() {
+        this.$refs.ruleForm.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.ruleForm);
+            params.materialsList = this.rawList
+            this.$api.Ducts.updateDuctRaw(params).then((res) => {
+              if(res.statusMsg === 'ok') {
+                this.asyncVisible = false;
+                this.searchButtonInfo(true);
+                this.$message.success('添加成功!');
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      },      
+      // 切换页数
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchButtonInfo();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchButtonInfo();
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import '../../../style/layout-main.scss';
+</style>
\ No newline at end of file
diff --git a/web/src/views/ProjectManage/components/RebarConsump.vue b/web/src/views/ProjectManage/components/RebarConsump.vue
new file mode 100644
index 0000000..77d4e21
--- /dev/null
+++ b/web/src/views/ProjectManage/components/RebarConsump.vue
@@ -0,0 +1,523 @@
+<template>
+  <div class="main tabs_main" style="height:89%">
+    <div class="main_header">
+      <div class="header_item">
+        <span class="header_label">项目名称:</span>
+        <el-select v-model="projectId" :size="size" clearable placeholder="请选择项目名称" @change="changeHeaderProject">
+          <el-option
+            v-for="item in projectData"
+            :key="item.proId"
+            :label="item.proName"
+            :value="item.proId">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_labels">尺寸:</span>
+        <el-select v-model="sizeId" :size="size" clearable placeholder="请选择尺寸">
+          <el-option
+            v-for="item in sizeData"
+            :key="item.sizes"
+            :label="item.dictName"
+            :value="item.sizes">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_labels">配筋:</span>
+        <el-select v-model="reinforcementId" :size="size" clearable placeholder="请选择配筋">
+          <el-option
+            v-for="item in reinforcementData"
+            :key="item.hasSteel"
+            :label="item.dictName"
+            :value="item.hasSteel">
+          </el-option>
+        </el-select>
+      </div>
+      <div class="header_item">
+        <span class="header_labels">块号:</span>
+        <el-select v-model="blockId" :size="size" clearable placeholder="请选择块号">
+          <el-option
+            v-for="item in blockData"
+            :key="item.blockNum"
+            :label="item.dictName"
+            :value="item.blockNum">
+          </el-option>
+        </el-select>
+      </div>
+    </div>
+    <div class="main_buttons">
+      <el-button icon="el-icon-search" @click="searchRebartheoryList(true)">查询</el-button>
+      <el-button class="search_btn" icon="el-icon-plus" @click="propInsert()">新增</el-button>
+      <el-button icon="el-icon-download" @click="exportExcel()">导出Excel</el-button>
+    </div>
+    <div class="main_content">
+      <el-table
+        ref="table"
+        v-loading="loading"
+        :data="rebartheoryList"
+        height="100%">
+        <el-table-column label="序号" width="60" align="center">
+          <template #default="scope">
+            <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="proName" label="项目名称" width="180" align="center"></el-table-column>
+        <el-table-column prop="sizeName" label="尺寸" align="center"></el-table-column>
+        <el-table-column prop="reinforcementName" label="配筋" align="center"></el-table-column>
+        <el-table-column prop="blockName" label="块号" align="center"></el-table-column>
+        <template>
+          <el-table-column v-for="item in titleData" :key="item.steelId" :label="`${item.steelName}${item.steelModel}(${item.unit})`" width="180" align="center">
+            <template #default="{ row }">
+              <span>{{showTableInfo(row, item)}}</span>
+            </template>
+          </el-table-column>
+        </template>
+        <el-table-column label="操作" align="center" width="200">
+          <template #default="{ row }">
+            <el-button class="table_btn" size="mini" v-if="showButton('update')" @click="propUpdate(row)">修改</el-button>
+            <el-button class="delete_btn" size="mini" v-if="showButton('delete')" @click="deleteInfo(row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </div>
+    <div class="main_footer">
+      <el-pagination
+        background
+        @current-change="changePageNum"
+        @size-change="changePageSize"
+        :current-page="pageNum"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="total">
+      </el-pagination>
+    </div>
+    <!-- 新增钢筋理论耗量 修改钢筋理论耗量信息 -->
+    <el-dialog
+      class="prop_dialog"
+      :title="asyncTitle ? '新增钢筋理论耗量' : '修改钢筋理论耗量信息'"
+      :visible.sync="asyncRebartheory"
+      width="45%">
+      <el-form ref="form" :model="formRebartheory" :rules="rulesRebartheory" label-width="auto" class="rule_form">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="项目名称:" prop="proId">
+              <el-select v-model="formRebartheory.proId" :size="size" clearable placeholder="请选择项目名称" @change="changeProject">
+                <el-option
+                  v-for="item in projectData"
+                  :key="item.proId"
+                  :label="item.proName"
+                  :value="item.proId">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="尺寸:" prop="sizeId">
+              <el-select v-model="formRebartheory.sizeId" :size="size" clearable placeholder="请选择尺寸">
+                <el-option
+                  v-for="item in sizeDatas"
+                  :key="item.sizes"
+                  :label="item.dictName"
+                  :value="item.sizes">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="配筋:" prop="reinforcementId">
+              <el-select v-model="formRebartheory.reinforcementId" :size="size" clearable placeholder="请选择配筋">
+                <el-option
+                  v-for="item in reinforcementDatas"
+                  :key="item.hasSteel"
+                  :label="item.dictName"
+                  :value="item.hasSteel">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="块号:" prop="blockId">
+              <el-select v-model="formRebartheory.blockId" :size="size" clearable placeholder="请选择块号">
+                <el-option
+                  v-for="item in blockDatas"
+                  :key="item.blockNum"
+                  :label="item.dictName"
+                  :value="item.blockNum">
+                </el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <div style="height: 300px;">
+          <el-table
+            :data="rebarList"
+            height="100%" 
+            :header-cell-style="() => 'background-color: #082F57; color: #18F5DB'">
+            <el-table-column label="序号" width="100" align="center">
+              <template #default="scope">
+                <span>{{scope.$index + 1}}</span>
+              </template>
+            </el-table-column>
+            <el-table-column prop="steelName" label="钢筋名称" align="center"></el-table-column>
+            <el-table-column prop="steelModel" label="规格型号" align="center"></el-table-column>
+            <el-table-column label="理论重量(吨)" align="center">
+              <template #default="{ row }">
+                <el-input-number 
+                  v-model="row.needNum" 
+                  :size="size"
+                  :controls="false"
+                  placeholder="请输入">
+                </el-input-number>
+              </template>
+            </el-table-column>
+            <el-table-column label="系数" align="center">
+              <template #default="{ row }">
+                <el-input-number 
+                  v-model="row.coefficient" 
+                  :size="size" 
+                  :controls="false"
+                  placeholder="请输入">
+                </el-input-number>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="asyncRebartheory = false">取 消</el-button>
+        <el-button class="submit_btn" @click="asyncTitle ? submitInsertForm() : submitUpdateForm()">提 交</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { buttonPinia } from "../../../pinia/index";
+import { changeSize, downFiles, throttle } from "../../../plugins/public";
+  export default {
+    data() {
+      return {
+        projectId: '',
+        projectData: [],
+        sizeId: '',
+        sizeData: [],
+        sizeDatas: [],
+        reinforcementId: '',
+        reinforcementData: [],
+        reinforcementDatas: [],
+        blockId: '',
+        blockData: [],
+        blockDatas: [],
+        size: changeSize(),
+        pageNum: 1,
+        pageSize: 10,
+        total: 0,
+        loading: true,
+        titleData: [], // 表头信息
+        rebartheoryList: [],
+        asyncTitle: true, // true 新r增钢筋理论耗量  false 修改钢筋理论耗量信息
+        asyncRebartheory: false, // 弹窗
+        formRebartheory: {}, // 表单
+        rulesRebartheory: {
+          proId: [{
+            required: true,
+            message: '请选择项目',
+            trigger: ['change', 'blur']
+          }],
+          sizeId: [{
+            required: true,
+            message: '请选择尺寸',
+            trigger: ['change', 'blur']
+          }],
+          reinforcementId: [{
+            required: true,
+            message: '请选择配筋',
+            trigger: ['change', 'blur']
+          }],
+          blockId: [{
+            required: true,
+            message: '请选择块号',
+            trigger: ['change', 'blur']
+          }]
+        }, // 表单校验规则
+        rebarList: [], 
+      }
+    },
+    mounted() {
+      const that = this;
+      // 根据窗口大小动态修改组件尺寸
+      window.onresize = () => {
+        that.size = changeSize();
+      }
+    //   that.getAllProjectData()
+    //   that.getTableTitleData().then(() => {
+    //     that.searchRebartheoryList(true);
+    //   })
+    },
+    methods: {
+      //初始请求
+      getInits(){
+        this.getTableTitleData().then(() => {
+            this.searchRebartheoryList(true);
+        })
+      },
+      // 获取表头信息
+      async getTableTitleData() {
+        // 获取表头信息
+        const { data } = await this.$api.Production.getTableTitleInfo();
+        this.titleData = data;
+        this.$nextTick(() => {
+          this.$refs.table.doLayout();
+        })
+      },
+      // 获取项目信息
+      async getAllProjectData() {
+        const { data } = await this.$api.Engineer.searchProjects({
+          pageNum: 1,
+          pageSize: 1000000
+        });
+        this.projectData = data.list;
+      },
+      // 查询钢筋理论耗量信息
+      searchRebartheoryList(bol) {
+        if(bol) {
+          this.pageNum = 1;
+        }
+        this.$api.Production.searchRebartheoryList({
+          proId: this.projectId,
+          sizeId: this.sizeId,
+          reinforcementId: this.reinforcementId,
+          blockId: this.blockId,
+          pageNum: this.pageNum,
+          pageSize: this.pageSize
+        }).then((res) => {
+          if(res.success) {
+            this.total = res.data.total;
+            this.rebartheoryList = res.data.list;
+          }
+          this.loading = false;
+        }).catch(() => {
+          this.loading = false;
+        })
+      },
+      // 查询钢筋类型列表
+      async searchRebarTypeList() {
+        await this.$api.Rebar.searchType({
+          pageNum: 1,
+          pageSize: 1000000
+        }).then((res) => {
+          if(res.success) {
+            this.rebarList = res.data.list.map(item => {
+              this.$set(item, 'needNum', 1);
+              this.$set(item, 'coefficient', 1);
+              return item;
+            });
+          }
+        })
+      },
+      // 打开添加信息
+      propInsert() {
+        this.asyncTitle = true;
+        this.asyncRebartheory = true;
+        this.searchRebarTypeList();
+      },
+      // 打开修改信息
+      propUpdate(row) {
+        this.asyncTitle = false;
+        this.asyncRebartheory = true;
+        this.changeProject(row.proId);
+        this.searchRebarTypeList().then(() => {
+          this.$api.Production.getRebartheoryInfoData({
+            consumptionId: row.consumptionId
+          }).then((res) => {
+            if(res.success) {
+              this.$set(this.formRebartheory, 'consumptionId', row.consumptionId);
+              this.$set(this.formRebartheory, 'proId', res.data.proId);
+              this.$set(this.formRebartheory, 'sizeId', res.data.sizeId);
+              this.$set(this.formRebartheory, 'reinforcementId', res.data.reinforcementId);
+              this.$set(this.formRebartheory, 'blockId', res.data.blockId);
+              res.data.tsteelNeeds.forEach((item, index) => {
+                this.$set(this.rebarList[index], 'needNum', item.needNum);
+                this.$set(this.rebarList[index], 'coefficient', item.coefficient);
+              });
+            }
+          })
+        })
+      },
+      // 导出Excel
+      exportExcel() {
+        this.$api.Production.exportRebartheoryExcel({
+          proId: this.projectId,
+          sizeId: this.sizeId,
+          reinforcementId: this.reinforcementId,
+          blockId: this.blockId
+        }).then((res) => {
+          if( res && res.success != false) {
+            downFiles(res,'钢筋理论耗量', 'xls');
+          } else if(res && res.success === false) {
+            this.$message.warning(res.data.statusMsg || '请联系管理人员');
+          }
+        })
+      },
+      // 删除钢筋理论消耗量信息
+      deleteInfo(row) {
+        this.$confirm("该操作将删除该消耗量信息,是否继续删除?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+       })
+       .then(() => {
+         this.$api.Production.deleteRebartheoryList({consumptionId: row.consumptionId})
+        .then(res => {
+          if(res.success) {
+            this.searchRebartheoryList(true);
+            this.$message.success("删除成功!");
+          } else {
+            this.$message.warning(res.statusMsg);
+          }
+        })
+       })
+       .catch(() => {
+         this.$message.warning("您已取消");
+       })
+      },
+      // 提交添加信息
+      submitInsertForm: throttle(function() {
+        this.$refs.form.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.formRebartheory);
+            params.needList = this.rebarList.map(item => {
+              return {
+                steelId: item.steelId,
+                needNum : item.needNum,
+                coefficient: item.coefficient
+              }
+            });
+            this.$api.Production.insetRebartheoryInfo(params).then((res) => {
+              if(res.success) {
+                this.asyncRebartheory = false;
+                this.$message.success('添加成功!');
+                this.searchRebartheoryList(true);
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 提交修改信息
+      submitUpdateForm: throttle(function() {
+        this.$refs.form.validate((valid) => {
+          if(valid) {
+            const params = Object.assign({}, this.formRebartheory);
+            params.needList = this.rebarList.map(item => {
+              return {
+                steelId: item.steelId,
+                needNum : item.needNum,
+                coefficient: item.coefficient
+              }
+            });
+            this.$api.Production.updateRebartheoryList(params).then((res) => {
+              if(res.success) {
+                this.asyncRebartheory = false;
+                this.$message.success('修改成功!');
+                this.searchRebartheoryList(true);
+              } else {
+                this.$message.warning(res.statusMsg);
+              }
+            })
+          }
+        })
+      }, 3000),
+      // 动态表头信息回填
+      showTableInfo(row, item) {
+        const data = row.tsteelNeeds.find(element => element.steelId === item.steelId);
+        return data ? data.totals : 0;
+      },
+      // 根据项目获取尺寸 配筋 块号信息
+      changeHeaderProject(data) {
+          this.sizeId = '';
+          this.reinforcementId = '';
+          this.blockId = '';
+          this.blockData = [];
+          this.sizeData = [];
+          this.reinforcementData = [];
+        if(data) {
+          this.$api.Basics.getProjectSystemInfoData({
+            proId: data
+          }).then((res) => {
+            this.blockData = res.data.proBloks;
+            this.sizeData = res.data.proSizes;
+            this.reinforcementData = res.data.proHas;
+          })
+        }
+      },
+      // 根据项目获取尺寸 配筋 块号信息
+      changeProject(data) {
+        if(!this.formRebartheory.proId) {
+          this.blockDatas = [];
+          this.sizeDatas = [];
+          this.reinforcementDatas = [];
+          this.$set(this.formRebartheory, 'sizeId', '');
+          this.$set(this.formRebartheory, 'reinforcementId', '');
+          this.$set(this.formRebartheory, 'blockId', '');
+        }
+        if(data) {
+          this.$api.Basics.getProjectSystemInfoData({
+            proId: data
+          }).then((res) => {
+            this.blockDatas = res.data.proBloks;
+            this.sizeDatas = res.data.proSizes;
+            this.reinforcementDatas = res.data.proHas;
+          })
+        }
+      },
+      // 切换页码
+      changePageNum(page) {
+        this.pageNum = page;
+        this.searchRebartheoryList();
+      },
+      // 切换每页条数
+      changePageSize(size) {
+        this.pageSize = size;
+        this.searchRebartheoryList();
+      },
+      // 判断按钮权限信息
+      showButton(str) {
+        const pinia = buttonPinia();
+        return pinia.$state.buttonInfo.includes(str);
+      }
+    },
+    watch: {
+      asyncRebartheory(bol) {
+        if(!bol) {
+          this.rebarList = [];
+          this.formRebartheory = {};
+          this.$refs.form.resetFields();
+        }
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+@import "@/style/layout-main.scss";
+
+.header_labels {
+  width: auto;
+  color: #fff;
+}
+
+.main_buttons {
+  margin: 0 10px 20px;
+}
+
+::v-deep .el-input-number .el-input__inner {
+  text-align: left;
+  background: transparent;
+}
+</style>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/AppearCheck.vue b/web/src/views/QualityManage/AppearCheck.vue
new file mode 100644
index 0000000..fe2870c
--- /dev/null
+++ b/web/src/views/QualityManage/AppearCheck.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>出场检验</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/DieDetection.vue b/web/src/views/QualityManage/DieDetection.vue
new file mode 100644
index 0000000..6738fe3
--- /dev/null
+++ b/web/src/views/QualityManage/DieDetection.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>模具质量检测</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/FinishedManage.vue b/web/src/views/QualityManage/FinishedManage.vue
new file mode 100644
index 0000000..e5af8a5
--- /dev/null
+++ b/web/src/views/QualityManage/FinishedManage.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>管片成品质量管理</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/PatternCheck.vue b/web/src/views/QualityManage/PatternCheck.vue
new file mode 100644
index 0000000..482fe15
--- /dev/null
+++ b/web/src/views/QualityManage/PatternCheck.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>型式检验</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/ProcessMonitor.vue b/web/src/views/QualityManage/ProcessMonitor.vue
new file mode 100644
index 0000000..ef97584
--- /dev/null
+++ b/web/src/views/QualityManage/ProcessMonitor.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>过程质量监测</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/RawQuality.vue b/web/src/views/QualityManage/RawQuality.vue
new file mode 100644
index 0000000..0cfc980
--- /dev/null
+++ b/web/src/views/QualityManage/RawQuality.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>原材料质量</div>
+</template>
\ No newline at end of file
diff --git a/web/src/views/QualityManage/TestManage.vue b/web/src/views/QualityManage/TestManage.vue
new file mode 100644
index 0000000..63d613b
--- /dev/null
+++ b/web/src/views/QualityManage/TestManage.vue
@@ -0,0 +1,3 @@
+<template>
+    <div>试验管理</div>
+</template>
\ No newline at end of file

--
Gitblit v1.9.3