zck 2 недель назад
Родитель
Сommit
3f944b589e
3 измененных файлов с 547 добавлено и 33 удалено
  1. 28 1
      src/api/mes/job.js
  2. 36 32
      src/view/inventory/ruku.vue
  3. 483 0
      src/view/yunyin/shengchanguanli/dahuobaobiao.vue

+ 28 - 1
src/api/mes/job.js

@@ -1447,10 +1447,37 @@ export const video = (params) => {
     params
   })
 }
+
 export const videoContent = (params) => {
   return service({
     url: '/mes_server/work_order/videoContent',
     method: 'get',
     params
   })
-}
+}
+
+
+
+//报表
+
+//大货左侧菜单栏
+export const getWorkOrderDates = (params) => {
+  return service({
+    url: '/mes_server/order_super_loss/getWorkOrderDates',
+    method: 'get',
+    params
+  })
+}
+
+
+
+//大货报表
+export const getWorkOrdersByMonth = (params) => {
+  return service({
+    url: '/mes_server/order_super_loss/getWorkOrdersByMonth',
+    method: 'get',
+    params
+  })
+}
+
+

+ 36 - 32
src/view/inventory/ruku.vue

@@ -630,22 +630,25 @@ const handleInput = async ()=>{
 	restableData.splice(0, restableData.length);//清空表格
 	//订单信息数据查询【接口】
 	const orderSearchdata = await InputOrderSearch({search:add_searchInfo.value});
-	if(orderSearchdata.data.length === 1){
-		_orderid.value = orderSearchdata.data[0]['订单编号']
-		add_searchInfo.value = orderSearchdata.data[0]['订单编号']
-		ddhformData.ddh = orderSearchdata.data[0]['订单编号']
-		ddhformData.kh = orderSearchdata.data[0]['客户编号']
-		ddhformData.sckh = orderSearchdata.data[0]['生产款号']
-		ddhformData.ks = orderSearchdata.data[0]['款式']
-		add_lysearchInfo.value = add_searchInfo.value
+	restableData.splice(0,orderSearchdata.length,...orderSearchdata.data);
+
+	// if(orderSearchdata.data.length === 1){
+	// 	console.log("一条")
+	// 	_orderid.value = orderSearchdata.data[0]['订单编号']
+	// 	add_searchInfo.value = orderSearchdata.data[0]['订单编号']
+	// 	mianliaotabData.value.订单编号 = orderSearchdata.data[0]['订单编号']
+	// 	ddhformData.kh = orderSearchdata.data[0]['客户编号']
+	// 	ddhformData.sckh = orderSearchdata.data[0]['生产款号']
+	// 	ddhformData.ks = orderSearchdata.data[0]['款式']
+	// 	add_lysearchInfo.value = add_searchInfo.value
 		
-		const gitReceiptNumberdata = await gitReceiptNumber({number:'RK'});
-		danhao.value = gitReceiptNumberdata.data.number
-		chukuren.value = userStore.userInfo.nickName
-		riqi.value = currentDates
-	}else{
-		restableData.splice(0,orderSearchdata.length,...orderSearchdata.data);
-	}
+	// 	const gitReceiptNumberdata = await gitReceiptNumber({number:'RK'});
+	// 	danhao.value = gitReceiptNumberdata.data.number
+	// 	chukuren.value = userStore.userInfo.nickName
+	// 	riqi.value = currentDates
+	// }else{
+	// 	restableData.splice(0,orderSearchdata.length,...orderSearchdata.data);
+	// }
 }
 
 //input回车事件
@@ -653,24 +656,25 @@ const add_onSubmit = async ()=>{
 	//清空表格
 	restableData.splice(0, restableData.length);
 	const orderSearchdata = await InputOrderSearch({search:add_searchInfo.value});
-	if(orderSearchdata.data.length === 1){
-		res_bomdialogFormVisible.value = true
-		_orderid.value = orderSearchdata.data[0]['订单编号']
-		add_searchInfo.value = orderSearchdata.data[0]['订单编号']
-		ddhformData.ddh = orderSearchdata.data[0]['订单编号']
-		ddhformData.kh = orderSearchdata.data[0]['客户编号']
-		ddhformData.sckh = orderSearchdata.data[0]['生产款号']
-		ddhformData.ks = orderSearchdata.data[0]['款式']
-		add_lysearchInfo.value = add_searchInfo.value
+	restableData.splice(0,orderSearchdata.length,...orderSearchdata.data);
+	// if(orderSearchdata.data.length === 1){
+	// 	res_bomdialogFormVisible.value = true
+	// 	_orderid.value = orderSearchdata.data[0]['订单编号']
+	// 	add_searchInfo.value = orderSearchdata.data[0]['订单编号']
+	// 	ddhformData.ddh = orderSearchdata.data[0]['订单编号']
+	// 	ddhformData.kh = orderSearchdata.data[0]['客户编号']
+	// 	ddhformData.sckh = orderSearchdata.data[0]['生产款号']
+	// 	ddhformData.ks = orderSearchdata.data[0]['款式']
+	// 	add_lysearchInfo.value = add_searchInfo.value
 		
-		const gitReceiptNumberdata = await gitReceiptNumber({number:'RK'});
-		console.log(gitReceiptNumberdata)
-		danhao.value = gitReceiptNumberdata.data.number
-		chukuren.value = userStore.userInfo.nickName
-		riqi.value = currentDates
-	}else{
-		restableData.splice(0,orderSearchdata.length,...orderSearchdata.data);
-	}
+	// 	const gitReceiptNumberdata = await gitReceiptNumber({number:'RK'});
+	// 	console.log(gitReceiptNumberdata)
+	// 	danhao.value = gitReceiptNumberdata.data.number
+	// 	chukuren.value = userStore.userInfo.nickName
+	// 	riqi.value = currentDates
+	// }else{
+	// 	restableData.splice(0,orderSearchdata.length,...orderSearchdata.data);
+	// }
 };
 
 

+ 483 - 0
src/view/yunyin/shengchanguanli/dahuobaobiao.vue

@@ -0,0 +1,483 @@
+<template>
+  <div>
+    <layout>
+      <layout-header>
+        <div class="top-action-bar">
+          <el-button type="primary" @click="exportMonthlyData" style="margin: 5px">
+            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" style="margin-right: 5px">
+              <path d="M8.5 16a.5.5 0 0 1-.5-.5V1H5a1 1 0 0 1 0-2h6a1 1 0 0 1 0 2h-3.5v14.5a.5.5 0 0 1-.5.5z"/>
+              <path d="M7 14.5V6H2a1 1 0 0 1 0-2h12a1 1 0 0 1 0 2H9v8.5a1.5 1.5 0 0 1-3 0z"/>
+            </svg>
+            导出出货大货生产进度表
+          </el-button>
+        </div>
+      </layout-header>
+
+      <layout>
+        <!-- 左侧日期菜单 -->
+        <layout-sider :resize-directions="['right']" :width="190" style="margin-right: 10px;">
+          <div class="JKWTree-tree treecolor">
+            <h3>出货月份选择</h3>
+            <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
+          </div>
+        </layout-sider>
+
+        <!-- 右侧表格区域 -->
+        <layout-content>
+          <el-main>
+            <div class="gva-table-box">
+              <!-- 表格数据 -->
+              <el-table ref="multipleTable" style="width: 100%; height: 65vh" tooltip-effect="dark"
+                        :row-style="{ height: '25px' }" :header-cell-style="{ padding: '0px' }"
+                        :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
+                        :data="tableData" border row-key="ID"
+                        size="small"
+                        highlight-current-row="true"
+                        @row-click="tableRowClick" :show-overflow-tooltip="true">
+                <el-table-column sortable align="center" label="款式" prop="款式" width="120" />
+                <el-table-column sortable align="center" label="客人编号" prop="客人编号" width="100" />
+                <el-table-column sortable align="center" label="下单日期" prop="下单日期" width="100" />
+                <el-table-column sortable align="center" label="货期" prop="货期" width="100" />
+                <el-table-column sortable align="center" label="款号" prop="款号" width="150" />
+                <el-table-column sortable align="center" label="生产组别" prop="生产组别" width="100" />
+                <el-table-column sortable align="center" label="订单数量" prop="订单数量" width="100" />
+                <el-table-column sortable align="center" label="实裁数量" prop="实裁数量" width="100" />
+                <el-table-column sortable align="center" label="已完成数量" prop="已完成数量" width="120" />
+                <el-table-column sortable align="center" label="入库数量" prop="入库数量" width="100" />
+                <el-table-column sortable align="center" label="面料入库时间" prop="面料入库时间" width="140" />
+                <el-table-column sortable align="center" label="辅料入库时间" prop="辅料入库时间" width="140" />
+                <el-table-column sortable align="center" label="产前样批核" prop="产前样批核" width="120" />
+                <el-table-column sortable align="center" label="开裁日期" prop="开裁日期" width="100" />
+                <el-table-column sortable align="center" label="上车位日期" prop="上车位日期" width="120" />
+                <el-table-column sortable align="center" label="台产" prop="台产" width="80" />
+                <el-table-column sortable align="center" label="车位完成日期" prop="车位完成日期" width="140" />
+                <el-table-column sortable align="center" label="后道完成日期" prop="后道完成日期" width="140" />
+                <el-table-column sortable align="center" label="备注" prop="备注" width="150" />
+              </el-table>
+
+              <!-- 分页 -->
+              <div class="gva-pagination">
+                <el-pagination layout="total" :current-page="page" :page-size="pageSize"
+                               :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
+              </div>
+            </div>
+          </el-main>
+        </layout-content>
+      </layout>
+    </layout>
+  </div>
+</template>
+  <script setup>
+  import {ref, reactive, onMounted} from 'vue'
+  import { Layout, LayoutSider, LayoutContent, LayoutHeader } from '@arco-design/web-vue'
+  import {
+    getWorkOrderDates, getWorkOrdersByMonth,
+  } from '@/api/mes/job'
+
+  import { ElMessage } from 'element-plus'
+  import { useUserStore } from '@/pinia/modules/user'
+  import * as ExcelJS from 'exceljs'
+  import { saveAs } from 'file-saver'
+  const userStore = useUserStore()
+  const _username = ref('')
+  _username.value = userStore.userInfo.userName + '/' + userStore.userInfo.nickName
+  
+  // 左侧树形数据
+  const treeData = ref([])
+  const defaultProps = {
+    label: 'label'
+  }
+  
+  // 右侧表格数据
+  const tableData = reactive([])
+  const page = ref(1)
+  const total = ref(0)
+  const pageSize = ref(10)
+  
+  // 选中的日期
+  const selectedDate = ref('')
+  
+  // 获取日期列表
+  const getDateList = async () => {
+    try {
+      const response = await getWorkOrderDates({});
+      if (response.code === 0) {
+        // 格式化日期数据为树形结构
+        const formattedData = [];
+        const yearMap = {};
+        
+        // 按年份分组
+        response.data.forEach(dateStr => {
+          const year = dateStr.substring(0, 4);
+          const month = dateStr.substring(5);
+          
+          if (!yearMap[year]) {
+            yearMap[year] = [];
+          }
+          yearMap[year].push({
+            label: `${month}月`,
+            value: dateStr
+          });
+        });
+        
+        // 转换为树形结构,并按年份降序排序
+        Object.entries(yearMap)
+          .sort(([yearA], [yearB]) => parseInt(yearB) - parseInt(yearA)) // 年份降序
+          .forEach(([year, months]) => {
+            // 月份降序排序
+            months.sort((a, b) => {
+              const monthA = parseInt(a.value.substring(5));
+              const monthB = parseInt(b.value.substring(5));
+              return monthB - monthA;
+            });
+            
+            formattedData.push({
+              label: year + '年',
+              children: months
+            });
+          });
+        
+        treeData.value = formattedData;
+      } else {
+        ElMessage.error('获取日期列表失败');
+      }
+    } catch (error) {
+      console.error('获取日期列表失败:', error);
+      ElMessage.error('获取日期列表失败');
+    }
+  }
+  
+  // 处理节点点击
+  const handleNodeClick = async (node) => {
+    // 重置所有节点颜色
+    document.querySelectorAll('.treecolor .el-tree-node').forEach(treeNode => {
+      const label = treeNode.querySelector('.el-tree-node__label');
+      if (label) {
+        label.style.color = '';
+      }
+    });
+
+    // 获取当前点击的节点并设置颜色
+    const clickedNode = document.querySelector(`.treecolor .el-tree-node[data-key="${node['$treeNodeId']}"]`);
+    if (clickedNode) {
+      const label = clickedNode.querySelector('.el-tree-node__label');
+      if (label) {
+        label.style.color = 'red';
+      }
+    }
+
+    // 只有叶子节点(包含value属性)才触发数据加载
+    if (node.value) {
+      selectedDate.value = node.value;
+      await getWorkOrderData(node.value);
+    }
+  }
+  
+  // 获取工单数据
+  const getWorkOrderData = async (rq) => {
+    try {
+      const response = await getWorkOrdersByMonth({ rq: rq });
+      if (response.code === 0) {
+        // 格式化日期为月日格式
+        const formatDate = (dateStr) => {
+          if (!dateStr) return '';
+          const date = new Date(dateStr);
+          return `${date.getMonth() + 1}月${date.getDate()}日`;
+        };
+        
+        // 处理数据
+        const formattedData = response.data.map((item, index) => ({
+          ID: index + 1,
+          ...item,
+          '下单日期': formatDate(item['下单日期']),
+          '货期': formatDate(item['货期']),
+          '面料入库时间': formatDate(item['面料入库时间']),
+          '开裁日期': formatDate(item['开裁日期']),
+          '上车位日期': formatDate(item['上车位日期']),
+          '车位完成日期': formatDate(item['车位完成日期']),
+          '后道完成日期': formatDate(item['后道完成日期'])
+        }));
+        
+        tableData.splice(0, tableData.length, ...formattedData);
+        total.value = formattedData.length;
+      } else {
+        ElMessage.error('获取工单数据失败');
+      }
+    } catch (error) {
+      console.error('获取工单数据失败:', error);
+      ElMessage.error('获取工单数据失败');
+    }
+  }
+  
+  // 表格行点击
+  const tableRowClick = (row) => {
+    console.log('点击行:', row);
+  }
+  
+  // 分页处理
+  const handleCurrentChange = (val) => {
+    page.value = val;
+  }
+  
+  const handleSizeChange = (val) => {
+    pageSize.value = val;
+    page.value = 1;
+  }
+  
+  // 生命周期
+  onMounted(() => {
+    getDateList();
+  })
+  
+  // 导出大货生产进度表
+  const exportMonthlyData = async () => {
+    if (!selectedDate.value) {
+      ElMessage.warning('请选择月份');
+      return;
+    }
+    
+    try {
+      // 1. 接口数据获取+处理
+      const rq = selectedDate.value;
+      const year = rq.substring(0, 4);
+      const month = rq.substring(5);
+      // 调用实际的大货生产进度表接口
+      const response = await getWorkOrdersByMonth({ rq: rq });
+      const originalData = response.data;
+      if (!originalData || originalData.length === 0) {
+        ElMessage.warning('暂无数据可导出');
+        return;
+      }
+
+      // 核心配置
+      const YEAR = year;
+      const MONTH = month;
+      // 表头字段
+      const HEADER_FIELDS = ['款式', '客人编号', '下单日期', '货期', '款号', '生产组别', '订单数量', '实裁数量', '已完成数量', '入库数量', '面料入库时间', '辅料入库时间', '产前样批核', '开裁日期', '上车位日期', '台产', '车位完成日期', '后道完成日期', '备注'];
+      const totalCol = HEADER_FIELDS.length;
+
+      // 2. 数据处理 - 根据实际接口返回的数据结构进行调整
+      const dataRows = [];
+      // 处理接口返回的数据
+      originalData.forEach(item => {
+        // 格式化日期为月日格式
+        const formatDate = (dateStr) => {
+          if (!dateStr) return '';
+          const date = new Date(dateStr);
+          return `${date.getMonth() + 1}月${date.getDate()}日`;
+        };
+        
+        // 构建数据行,按照表头字段顺序排列
+        const row = [
+          item['款式'] || '',
+          item['客人编号'] || '',
+          formatDate(item['下单日期']),
+          formatDate(item['货期']),
+          item['款号'] || '',
+          item['生产组别'] || '', // 接口返回中没有生产组别,默认为空
+          item['订单数量'] || '',
+          item['实裁数量'] || '',
+          item['已完成数量'] || '',
+          item['入库数量'] || '',
+          formatDate(item['面料入库时间']),
+          item['辅料入库时间'] || '', // 接口返回中没有辅料入库时间,默认为空
+          item['产前样批核'] || '', // 接口返回中没有产前样批核,默认为空
+          formatDate(item['开裁日期']),
+          formatDate(item['上车位日期']),
+          item['台产'] || '', // 接口返回中没有台产,默认为空
+          formatDate(item['车位完成日期']),
+          formatDate(item['后道完成日期']),
+          item['备注'] || '' // 接口返回中没有备注,默认为空
+        ];
+        dataRows.push(row);
+      });
+
+      // 3. 构建数据行
+      // 标题行
+      const titleRow = [`${MONTH}月份大货生产进度表`];
+      titleRow.push(...Array(totalCol-1).fill('')); // 标题行补空
+
+      // 表头行
+      const headerRow = [...HEADER_FIELDS];
+
+      // ============== ExcelJS 核心:创建工作簿+设置样式 ==============
+      // 4. 创建工作簿和工作表
+      const workbook = new ExcelJS.Workbook();
+      const worksheet = workbook.addWorksheet('Sheet1'); // 工作表名与原Excel一致
+
+      // 5. 写入数据(按行写入:标题行→表头行→数据行)
+      worksheet.addRow(titleRow);
+      worksheet.addRow(headerRow);
+      dataRows.forEach(row => worksheet.addRow(row));
+
+      // 辅助函数:将列索引转换为Excel列字母(如1→A, 2→B, 26→Z, 27→AA)
+      const getColumnLetter = (colIndex) => {
+        let letter = '';
+        let num = colIndex;
+        while (num > 0) {
+          const remainder = (num - 1) % 26;
+          letter = String.fromCharCode(65 + remainder) + letter;
+          num = Math.floor((num - 1) / 26);
+        }
+        return letter;
+      };
+
+      // 6. 样式配置:合并单元格+边框+底色+居中+列宽
+      // 6.1 合并单元格
+      const mergeRange = (range) => worksheet.mergeCells(range);
+      // 合并1:标题行(A1到最后一列1)
+      mergeRange(`A1:${getColumnLetter(totalCol)}1`);
+
+      // 6.2 定义样式模板
+      const commonStyle = { // 所有单元格公共样式:边框+居中+自动换行
+        border: {
+          top: { style: 'thin', color: { argb: 'FF000000' } },
+          bottom: { style: 'thin', color: { argb: 'FF000000' } },
+          left: { style: 'thin', color: { argb: 'FF000000' } },
+          right: { style: 'thin', color: { argb: 'FF000000' } }
+        },
+        alignment: { horizontal: 'center', vertical: 'middle', wrapText: true },
+        font: { size: 11, color: { argb: 'FF000000' } }
+      };
+      const titleStyle = { // 标题行样式:14号字+加粗
+        ...commonStyle,
+        font: { size: 14, bold: true, color: { argb: 'FF000000' } }
+      };
+      const headerStyle = { // 表头行样式:12号字+加粗
+        ...commonStyle,
+        font: { size: 12, bold: true, color: { argb: 'FF000000' } },
+        fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFE6E6E6' } }
+      };
+      const remarkStyle = { // 备注列样式:红色字体
+        ...commonStyle,
+        font: { size: 11, color: { argb: 'FFFF0000' } }
+      };
+
+      // 6.3 应用样式到单元格
+      const lastRow = 2 + dataRows.length; // 最后一行:1行标题+1行表头+数据行
+      
+      // 标题行(第1行):应用标题样式
+      worksheet.getRow(1).eachCell(cell => cell.style = titleStyle);
+      
+      // 表头行(第2行):应用表头样式
+      worksheet.getRow(2).eachCell(cell => cell.style = headerStyle);
+      
+      // 数据行(第3行到最后一行):应用公共样式,备注列应用红色字体
+      for (let row = 3; row <= lastRow; row++) {
+        const currentRow = worksheet.getRow(row);
+        currentRow.eachCell((cell, colIndex) => {
+          // 备注列(最后一列)应用红色字体
+          if (colIndex === totalCol) {
+            cell.style = remarkStyle;
+          } else {
+            cell.style = commonStyle;
+          }
+        });
+      }
+
+      // 6.4 设置列宽(根据实际需求调整)
+      const colWidths = [
+        80,  // 款式
+        80,  // 客人编号
+        80,  // 下单日期
+        80,  // 货期
+        120, // 款号
+        80,  // 生产组别
+        80,  // 订单数量
+        80,  // 实裁数量
+        80,  // 已完成数量
+        80,  // 入库数量
+        100, // 面料入库时间
+        100, // 辅料入库时间
+        100, // 产前样批核
+        80,  // 开裁日期
+        80,  // 上车位日期
+        80,  // 台产
+        100, // 车位完成日期
+        100, // 后道完成日期
+        150  // 备注
+      ];
+      // ExcelJS列宽单位为「字符」,px转字符按 1px ≈ 0.14 换算
+      worksheet.columns = colWidths.map((width, index) => ({
+        key: index+1,
+        width: width * 0.14
+      }));
+
+      // 6.5 调整行高
+      worksheet.getRow(1).height = 30; // 标题行高
+      worksheet.getRow(2).height = 25; // 表头行高
+
+      // ============== 导出Excel文件 ==============
+      // 7. 生成blob并下载
+      const buffer = await workbook.xlsx.writeBuffer();
+      const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
+      saveAs(blob, `${MONTH}月份大货生产进度表.xlsx`);
+
+      ElMessage.success('导出成功!');
+    } catch (error) {
+      console.error('Excel导出失败:', error);
+      ElMessage.error('导出数据失败,请重试');
+    }
+  };
+  
+  </script>
+  <style scoped>
+  /* 基本样式 */
+  .top-action-bar {
+    padding: 10px 20px;
+    background: #fff;
+    border-bottom: 1px solid #e8e8e8;
+  }
+
+  .action-buttons {
+    display: flex;
+    gap: 10px;
+    flex-wrap: wrap;
+  }
+
+  /* 左侧树状图区域 */
+  .JKWTree-tree {
+    height: 100%;
+    padding: 10px;
+    background: #fff;
+    border-right: 1px solid #e8e8e8;
+  }
+
+  .JKWTree-tree h3 {
+    font-size: 15px;
+    font-weight: 700;
+    margin: 10px 0;
+  }
+
+  /* 表格区域 */
+  .gva-table-box {
+    padding: 0px !important;
+  }
+
+  .gva-pagination {
+    margin-top: 10px;
+    text-align: right;
+  }
+
+  /* 表格单元格样式 */
+  :deep(.el-table td .cell) {
+    line-height: 20px !important;
+  }
+
+  /* 响应式设计 */
+  @media (max-width: 1200px) {
+    .cert-wrapper {
+      width: 95%;
+      padding: 30px;
+    }
+  }
+
+  @media (max-width: 768px) {
+    .cert-wrapper {
+      width: 100%;
+      padding: 20px;
+    }
+  }
+  </style>
+  
+