|
|
@@ -0,0 +1,353 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <layout>
|
|
|
+ <layout-header>
|
|
|
+ <div class="">
|
|
|
+ <!-- 按钮部分-->
|
|
|
+ <el-form ref="elSearchFormRef" class="demo-form-inline" :rules="searchRule" >
|
|
|
+ <el-form-item>
|
|
|
+ <!-- <el-input v-model="searchInfo" placeholder="搜索工单编号" clearable style="width: 200px;margin: 5px"></el-input> -->
|
|
|
+ <el-button type="primary" class="bt" icon="download" @click="hzToExcel" >导出到Excel(汇总)</el-button>
|
|
|
+ <el-button type="primary" class="bt" icon="download" @click="mxToExcel" >导出到Excel(明细)</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </layout-header>
|
|
|
+
|
|
|
+ <layout>
|
|
|
+ <!-- 左侧树侧形结构-->
|
|
|
+ <layout-sider :resize-directions="['right']" :width="210" style="margin-right: 10px;">
|
|
|
+ <div class="JKWTree-tree" style="height: 200px">
|
|
|
+ <h3>产品年度投入产出率统计</h3>
|
|
|
+ <el-tree :data="treeData" :props="defaultProps" @node-click="handleNodeClick" @node-expand="handleNodeExpand">
|
|
|
+ </el-tree>
|
|
|
+ </div>
|
|
|
+ </layout-sider>
|
|
|
+
|
|
|
+ <!-- 右侧区域 -->
|
|
|
+ <layout-content >
|
|
|
+ <el-main>
|
|
|
+ <div class="gva-table-box">
|
|
|
+ <!-- 表格数据 -->
|
|
|
+ <el-table ref="multipleTable" style="width: 100%;height: 38vh" tooltip-effect="dark"
|
|
|
+ :row-style="{ height: '25px' }" :header-cell-style="{ padding: '0px' }"
|
|
|
+ :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
|
|
|
+ :data="hztableData" border row-key="ID"
|
|
|
+ size="small" id="hztable"
|
|
|
+
|
|
|
+ :cell-class-name="gxbgCellClass"
|
|
|
+ highlight-current-row="true" @row-dblclick="updateCompanyFunc"
|
|
|
+ @row-click="hztableRowClick" :show-overflow-tooltip="true"
|
|
|
+ @selection-change="handleSelectionChange">
|
|
|
+ <el-table-column align="center" label="成品代号" prop="成品编码" width="120" />
|
|
|
+ <el-table-column align="center" label="成品名称" prop="成品名称" width="300" />
|
|
|
+ <el-table-column align="center" label="投料数量" prop="实际投料" width="100" />
|
|
|
+ <el-table-column align="center" label="入仓数量" prop="入仓数量" width="90" />
|
|
|
+ <el-table-column align="center" label="综合合格率" prop="综合合格率" width="120" />
|
|
|
+ <el-table-column align="center" label="月份01" prop="1月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份02" prop="2月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份03" prop="3月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份04" prop="4月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份05" prop="5月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份06" prop="6月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份07" prop="7月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份08" prop="8月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份09" prop="9月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份10" prop="10月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份11" prop="11月" width="90" />
|
|
|
+ <el-table-column align="center" label="月份12" prop="12月" width="90" />
|
|
|
+ </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>
|
|
|
+
|
|
|
+ <el-table ref="multipleTable" style="width: 100%;height: 40vh" tooltip-effect="dark"
|
|
|
+ :row-style="{ height: '25px' }" :header-cell-style="{ padding: '0px' }"
|
|
|
+ :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
|
|
|
+ :data="mxtableData" border row-key="ID"
|
|
|
+ size="small" id="mxtable"
|
|
|
+
|
|
|
+ :cell-class-name="gxbgCellClass"
|
|
|
+ highlight-current-row="true" @row-dblclick="updateCompanyFunc"
|
|
|
+ @row-click="mxtableRowClick" :show-overflow-tooltip="true"
|
|
|
+ @selection-change="handleSelectionChange">
|
|
|
+ <el-table-column align="center" label="工单编号" prop="工单编号" width="120" />
|
|
|
+ <el-table-column align="center" label="订单数量" prop="订单数量" width="120" />
|
|
|
+ <el-table-column align="center" label="实际投料" prop="实际投料" width="100" />
|
|
|
+ <el-table-column align="center" label="工单完工日期" prop="sys_rq" width="110" />
|
|
|
+ <el-table-column align="center" label="工单入仓数量" prop="入仓数量" width="120" />
|
|
|
+ <el-table-column align="center" label="实际合格率" prop="实际合格率" width="90" />
|
|
|
+ <el-table-column align="center" label="客户编号" prop="客户代号" width="90" />
|
|
|
+ <el-table-column align="center" label="客户名称" prop="客户名称" width="90" />
|
|
|
+ <el-table-column align="center" label="成品代号" prop="产品代号" width="130" />
|
|
|
+ <el-table-column align="center" label="成品名称" prop="产品名称" width="330" />
|
|
|
+ <el-table-column align="center" label="销售订单号" prop="销售订单号" width="90" />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </el-main>
|
|
|
+ </layout-content>
|
|
|
+ </layout>
|
|
|
+ </layout>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <script setup>
|
|
|
+ // 全量引入格式化工具 请按需保留
|
|
|
+ import { Layout, LayoutSider, LayoutContent } from '@arco-design/web-vue';
|
|
|
+ import {ref, reactive} from 'vue'
|
|
|
+ import { exportExcelFile } from '@/utils/excel'
|
|
|
+ import {ElMessage} from "element-plus";
|
|
|
+ import * as XLSX from 'xlsx'
|
|
|
+import FileSaver from 'file-saver'
|
|
|
+import LuckyExcel from 'luckyexcel';
|
|
|
+ import {Productyearleft,Productyearlist,Productmonthlist,} from "@/api/mes/job.js"
|
|
|
+
|
|
|
+ defineOptions({name: 'Company'})
|
|
|
+ // =========== 获取左侧树侧形结构 ===========
|
|
|
+const treeData = ref([]);
|
|
|
+const defaultProps = {
|
|
|
+ children: 'children',
|
|
|
+ label: 'label'
|
|
|
+};
|
|
|
+const getTreeData = async () => {
|
|
|
+ try {
|
|
|
+ const res = await Productyearleft(); // 调用您的API接口
|
|
|
+
|
|
|
+ if (res.code === 0 && res.data) {
|
|
|
+ // 转换数据结构
|
|
|
+ treeData.value = Object.entries(res.data).map(([workshopType, yearsData]) => {
|
|
|
+ // 创建父节点(工单类型)
|
|
|
+ const parentNode = {
|
|
|
+ label: workshopType,
|
|
|
+ value: workshopType,
|
|
|
+ children: []
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理每个年份的数据
|
|
|
+ Object.entries(yearsData).forEach(([year, workshops]) => {
|
|
|
+ // 创建年份节点
|
|
|
+ const yearNode = {
|
|
|
+ label: year,
|
|
|
+ value: `${workshopType}-${year}`,
|
|
|
+ children: workshops.map(workshop => ({
|
|
|
+ label: workshop.trim(),
|
|
|
+ value: `${workshopType}-${year}-${workshop.trim()}`,
|
|
|
+ type: 'workshop'
|
|
|
+ }))
|
|
|
+ };
|
|
|
+
|
|
|
+ parentNode.children.push(yearNode);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 对年份节点按年份倒序排序
|
|
|
+ parentNode.children.sort((a, b) => b.label.localeCompare(a.label));
|
|
|
+
|
|
|
+ return parentNode;
|
|
|
+ });
|
|
|
+
|
|
|
+ console.log('生成的树形数据:', treeData.value);
|
|
|
+ } else {
|
|
|
+ console.error('获取数据失败:', res.msg);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('请求出错:', error);
|
|
|
+ }
|
|
|
+};
|
|
|
+getTreeData();
|
|
|
+
|
|
|
+const hztableData = ref([])
|
|
|
+const _noderq = ref('')
|
|
|
+const handleNodeClick = async (nodeData) => {
|
|
|
+ if(!nodeData.children){
|
|
|
+ _noderq.value = nodeData.value.split('-')[1]
|
|
|
+ const res = await Productyearlist({khdh:nodeData.value.split('-')[2].split('【')[0],rq:nodeData.value.split('-')[1]})
|
|
|
+ hztableData.value = res.data
|
|
|
+
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const mxtableData = ref([])
|
|
|
+const hztableRowClick = async (row, event, column) => {
|
|
|
+ console.log('点击了行:', row,);
|
|
|
+ const res = await Productmonthlist({product_code:row.成品编码,year:_noderq.value})
|
|
|
+ mxtableData.value = res.data
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+//汇总导出按钮
|
|
|
+const hzToExcel = async () => {
|
|
|
+ try {
|
|
|
+ const el = document.getElementById('hztable');
|
|
|
+ // 使用table_to_sheet获取工作表对象
|
|
|
+ const worksheet = XLSX.utils.table_to_sheet(el, { raw: true });
|
|
|
+ //设置从C列开始为数字格式
|
|
|
+ const range = XLSX.utils.decode_range(worksheet['!ref']);
|
|
|
+ for (let col = 2; col <= range.e.c; col++) { // 从C列(索引2)开始
|
|
|
+ for (let row = range.s.r + 1; row <= range.e.r; row++) { // 跳过表头行
|
|
|
+ const cellAddress = XLSX.utils.encode_cell({ r: row, c: col });
|
|
|
+ if (worksheet[cellAddress]) {
|
|
|
+ // 尝试转换为数字
|
|
|
+ const cellValue = worksheet[cellAddress].v;
|
|
|
+ const numValue = Number(cellValue);
|
|
|
+
|
|
|
+ if (!isNaN(numValue)) {
|
|
|
+ worksheet[cellAddress].t = 'n'; // 数字类型
|
|
|
+ worksheet[cellAddress].v = numValue; // 更新值
|
|
|
+ // worksheet[cellAddress].z = '0.000'; // 数字格式
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建并导出工作簿
|
|
|
+ const workbook = XLSX.utils.book_new();
|
|
|
+ XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
|
|
+ XLSX.writeFile(workbook, '年度产出率汇总.xlsx');
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('导出失败:', error);
|
|
|
+ ElMessage.error('导出数据失败,请重试');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//明细导出按钮
|
|
|
+const mxToExcel = async () => {
|
|
|
+ try {
|
|
|
+ const el = document.getElementById('mxtable');
|
|
|
+ // 使用table_to_sheet获取工作表对象
|
|
|
+ const worksheet = XLSX.utils.table_to_sheet(el, { raw: true });
|
|
|
+
|
|
|
+ // 指定需要转换为数字的列索引(0-based索引)
|
|
|
+ const numericColumns = [1, 2, 4];
|
|
|
+
|
|
|
+ // 获取工作表范围
|
|
|
+ const range = XLSX.utils.decode_range(worksheet['!ref']);
|
|
|
+
|
|
|
+ // 遍历所有指定的列
|
|
|
+ numericColumns.forEach(colIndex => {
|
|
|
+ for (let row = range.s.r + 1; row <= range.e.r; row++) { // 跳过表头行
|
|
|
+ const cellAddress = XLSX.utils.encode_cell({ r: row, c: colIndex });
|
|
|
+ if (worksheet[cellAddress]) {
|
|
|
+ // 尝试转换为数字
|
|
|
+ const cellValue = worksheet[cellAddress].v;
|
|
|
+ const numValue = Number(cellValue);
|
|
|
+
|
|
|
+ if (!isNaN(numValue) && cellValue !== '') {
|
|
|
+ worksheet[cellAddress].t = 'n'; // 数字类型
|
|
|
+ worksheet[cellAddress].v = numValue; // 更新值
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 创建并导出工作簿
|
|
|
+ const workbook = XLSX.utils.book_new();
|
|
|
+ XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
|
|
+ XLSX.writeFile(workbook, '年度产出率明细.xlsx');
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('导出失败:', error);
|
|
|
+ ElMessage.error('导出数据失败,请重试');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ </script>
|
|
|
+
|
|
|
+ <style scoped>
|
|
|
+ .form-container {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-column {
|
|
|
+ /*flex: 1;*/
|
|
|
+ margin-right: 15px; /* 调整列之间的间距 */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 左侧输入框宽度调整 */
|
|
|
+ .form-column .el-form-item .el-input {
|
|
|
+ width: 150px; /* 调整左侧输入框的宽度 */
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.hui-plan-usage-lows div) {
|
|
|
+ color: #8c939d !important;
|
|
|
+ }
|
|
|
+ :deep(.lan-plan-usage-lows div) {
|
|
|
+ color: blue !important;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /* 媒体查询,根据需要调整断点 */
|
|
|
+ @media screen and (max-width: 768px) {
|
|
|
+ .form-column {
|
|
|
+ flex: 1 0 100%; /* 在小屏幕下变成单列布局 */
|
|
|
+ margin-right: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*:deep(.el-table td .cell) {*/
|
|
|
+ /* line-height: 30px !important;*/
|
|
|
+ /*}*/
|
|
|
+ .JKWTree-container {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+ .JKWTree-tree {
|
|
|
+ /*width: 300px;*/
|
|
|
+ background-color: #fff;
|
|
|
+ padding: 10px;
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+ .JKWTree-tree h3 {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 700;
|
|
|
+ margin: 10px 0;
|
|
|
+ }
|
|
|
+ .JKWTree-content {
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /* 选中某行时的背景色 */
|
|
|
+ :deep(.el-table__body tr.current-row) > td {
|
|
|
+ background: #ff80ff !important;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+ <style scoped>
|
|
|
+ :deep(.el-table td .cell) {
|
|
|
+ line-height: 20px !important;
|
|
|
+ }
|
|
|
+ :deep(.el-tabs__header){
|
|
|
+ margin-bottom: 0;
|
|
|
+ }
|
|
|
+ .search{
|
|
|
+ margin-left: 0px !important;
|
|
|
+ margin-right: 10px !important;
|
|
|
+ }
|
|
|
+ .bt{
|
|
|
+ margin-left: 2px !important;
|
|
|
+ padding: 3px !important;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ .el-tabs__header{
|
|
|
+ margin: 0px !important;
|
|
|
+ }
|
|
|
+ .gva-table-box{
|
|
|
+ padding: 0px !important;
|
|
|
+ }
|
|
|
+ .mab{
|
|
|
+ margin-bottom: 5px;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+
|