north-glass-erp/northglass-erp/src/assets/main.css
@@ -7,8 +7,8 @@ font-weight: normal; height: 100%; width: 100%; /*min-width: 1536px; min-height: 730px;*/ min-width: 1536px; min-height: 730px; } a, north-glass-erp/northglass-erp/src/components/pp/PrintConsolidatedReplenish.vue
New file @@ -0,0 +1,567 @@ <script setup> import request from "@/utils/request" import {ElDatePicker, ElMessage} from "element-plus" import {nextTick, onMounted, onUnmounted, reactive, ref, watch} from "vue" import {Search} from "@element-plus/icons-vue" import {useRouter} from 'vue-router' import {changeFilterEvent, filterChanged} from "@/hook" import {useI18n} from 'vue-i18n' import deepClone from "@/utils/deepClone"; import QRCode from "qrcode"; import companyInfo from "@/stores/sd/companyInfo"; import userInfo from "@/stores/userInfo" //语言获取 const company = companyInfo() const {t} = useI18n() let router = useRouter() let produceList = ref([]) let list = ref() const details = ref([]) const user=userInfo() const data = ref({ printList: [], processName:[] }) let props = defineProps({ printList:null, printMerge:null, printLike: null, mergeTechnologyNumber:null }) //打印时间 const currentTime = new Date(); const formattedTime = currentTime.getFullYear() + '-' + (currentTime.getMonth() + 1) + '-' + currentTime.getDate() + ' ' + currentTime.getHours() + ':' + currentTime.getMinutes();formattedTime const {currentRoute} = useRouter() const route = currentRoute.value const printMerge = props.printMerge let mergeTechnologyNumber=props.mergeTechnologyNumber let merge=props.printMerge if (merge == '') { merge = null } let like = props.printLike if (like == '') { like = null } data.value.printList = JSON.parse(props.printList) let name=company.companyName let replenishQRCode=company.replenishQRCode //去除重复对象 // let uniqueObjects = {}; // // 遍历原始数据数组 // data.value.printList.forEach(obj => { // // 构建一个唯一键,例如 'NG24071502A001_1' // let key = `${obj.process_id}_${obj.technology_number}_${obj.order_number}`; // // // 如果该键不存在于 uniqueObjects 中,则将该对象添加到 uniqueObjects 中 // if (!uniqueObjects[key]) { // uniqueObjects[key] = obj; // } // }); // data.value.printList = Object.values(uniqueObjects); let flowCardCount = null onMounted(() => { request.post(`/processCard/getSelectPrintingConsolidated/${merge}/${like}/${mergeTechnologyNumber}`, data.value).then((res) => { if (res.code == 200) { produceList.value = deepClone(res.data.data) data.processName = res.data.data[0].processNameList //处理单片厚度 for (let j = 0; j < produceList.value.length; j++) { let sumWeight = 0 produceList.value[j].detailList.forEach((item, index) => { // 解析 separation 字段的 JSON 字符串 let separationObj = JSON.parse(item.separation); // 获取 thickness 的原始值 let thicknessValue = separationObj.thickness; // 去除 'mm' 单位 let thicknessWithoutUnit = thicknessValue.replace('mm', ''); item.separation = thicknessWithoutUnit sumWeight += item.width * item.height * item.quantity / 1000000 * item.separation * 2.5 * 1; }); produceList.value[j].detail[0].weight = sumWeight } //处理合并打印 // if (printMerge !== null && printMerge !== undefined && printMerge !== "") { // // produceList.value.forEach(item => { // item.detail[0].technologyNumber = printMerge; // }); // // //合并打印工艺流程处理 // if (like == null) { // let process = produceList.value[0].detail[0].process // console.log(process) // let indexOfJiaJiao = process.indexOf('夹胶'); // if (indexOfJiaJiao !== -1) { // // 使用 substring 截取 "夹胶" 后面的部分,包括 "夹胶" 本身 // let afterJiaJiao = process.substring(indexOfJiaJiao).trim(); // produceList.value.forEach(item => { // item.detail[0].process = afterJiaJiao // }) // } // // let indexOfProceList = produceList.value[0].processList // let getProceList = indexOfProceList.findIndex(item => item.process === '夹胶'); // // if (getProceList !== -1) { // // 使用 filter 方法过滤出 "夹胶" 及其之后的对象 // produceList.value[0].processList = indexOfProceList.filter((item, index) => index >= getProceList); // } // } // } produceList.value.forEach(item => { let technologyNumberMerge = printMerge.split('').join(','); item.detail[0].technologyNumberMerge = technologyNumberMerge }) //处理编号列 //定义存放编号数组 const s01Values = []; for (let i = 0; i < produceList.value.length; i++) { const s01Values = []; // 遍历 detailList 数组,提取 S01 值到 s01Values 数组 if (produceList.value[i].detailList[0].other_columns != null || produceList.value[i].detailList[0].other_columns != undefined) { produceList.value[i].detailList.forEach(element => { const otherColumnsObject = JSON.parse(element.other_columns); const s01Value = otherColumnsObject.S01; s01Values.push(s01Value || ''); // 如果 S01 值为空,添加空字符串或者其他默认值 }); // 将 s01Values 中的值赋给每个订单详情对象的 s01Value 属性 produceList.value[i].detailList.forEach((detail, index) => { detail.s01Value = index < s01Values.length ? s01Values[index] : ''; // 赋值给 s01Value 属性 }); } } // 使用一个对象来存储合并后的结果 const mergedData = produceList.value.reduce((acc, item) => { const processId = item.detail[0].process_id; // 如果该 process_id 尚未在 acc 中,初始化其数组 if (!acc[processId]) { acc[processId] = { processList: item.processList, detailList: [], detail: item.detail }; } // 合并 detailList acc[processId].detailList = acc[processId].detailList.concat(item.detailList); return acc; }, {}); // 将合并后的对象转换回数组 produceList.value = Object.values(mergedData); flowCardCount=produceList.value.length handleSummary() if (replenishQRCode == 2){ handleGetQRCodeTj()//天津扫码枪报工需要合并层号二维码 }else{ handleGetQRCode()//拆分层号二维码 } } else { ElMessage.warning(res.msg) router.push("/login") } }) } ) const handleGetQRCode = async () => { // 全局 Map 保存 processId+technologyNumber 对应的二维码(保留最后一条) const qrMap = new Map(); // 遍历每个 produce,先对 detailList 排序 produceList.value.forEach(produce => { produce.detailList.sort((a, b) => { const processA = a.processId || a.process_id; const processB = b.processId || b.process_id; const techA = a.technologyNumber || a.technology_number; const techB = b.technologyNumber || b.technology_number; // 先按 processId 排序,再按 technologyNumber 排序 if (processA !== processB) return processA - processB; return techA - techB; }); // 遍历 detailList 生成二维码 map produce.detailList.forEach(item => { const processId = item.processId || item.process_id; const techNum = item.technologyNumber || item.technology_number; const key = `${processId}_${techNum}`; // 保留最后一条 item qrMap.set(key, { itemRef: item, processId, technologyNumber: techNum }); }); }); // 生成二维码并赋值给最后一条对应的 detail for (const [key, value] of qrMap.entries()) { const url = `${value.processId}/${value.technologyNumber}`; const qrcodeData = await QRCode.toDataURL(url); value.itemRef.qrcodeList = [{ qrcode: qrcodeData, processId: value.processId, technologyNumber: value.technologyNumber }]; } // 清理重复条目二维码(非最后一条) produceList.value.forEach(produce => { produce.detailList.forEach(item => { const processId = item.processId || item.process_id; const techNum = item.technologyNumber || item.technology_number; const key = `${processId}_${techNum}`; if (qrMap.get(key).itemRef !== item) { item.qrcodeList = []; } }); }); }; const handleGetQRCodeTj = async () => { let technologyNumber='' for (let i = 0; i < produceList.value.length; i++) { const technologyNumber = produceList.value[i].detail[0].mergeTechnologyNumber.toString(); // 转换为字符串以便处理每个字符 produceList.value[i].detail[0]["qrcodeList"] = []; // 初始化一个空数组用来存储 QR Code const processId = produceList.value[i].detail[0].process_id; const url = `${processId}/${technologyNumber}`; // 生成 QR Code 并存储到数组中 const qrcodeData = await QRCode.toDataURL(url); produceList.value[i].detail[0]["qrcodeList"].push({ qrcode: qrcodeData, technologyNumber: technologyNumber }); } }; //根据输入的数量重新汇总 const handleSummary = () => { for (let i = 0; i < produceList.value.length; i++) { //数量 let totalQuantity = 0; //面积 let totalArea = 0; //重量 let totalWeight = 0; // 对每个集合中的 detailList 进行计算 produceList.value[i].detailList.forEach(collection => { totalQuantity += collection.quantity*1; //每个序号面积 collection.total_area=parseFloat((collection.width*collection.height*collection.quantity/1000000).toFixed(2)) totalArea += collection.total_area*1; totalWeight += collection.width*collection.height*collection.quantity/1000000*collection.separation*2.5*1; //每个序号周长 collection.perimeter= (collection.width*2+collection.height*2)*collection.quantity/1000 }); // 输出每个集合中的总数量 produceList.value[i].detail[0].quantity=totalQuantity produceList.value[i].detail[0].gross_area=totalArea produceList.value[i].detail[0].weight=totalWeight } } </script> <template> <!-- <el-button id="printButton" @click="printFlowCard();">{{ $t('basicData.print') }}</el-button>--> <div id="printFlowCard"> <table v-for="(item,id) in produceList" id="contentTable" :key="id"> <thead> <tr v-for="(itemFlow,index) in item.detail" :key="index"> <td colspan="34"> <div id="bj" style="float: right;font-size: 28px">补 {{ id + 1 }}</div> <div style="left: 150px">{{ company.companyName }}</div> <div>生产流程卡</div> <div style="font-weight: bolder;display: flex;justify-content:space-between"> <div> 补片单号:{{itemFlow.patch_id}} 打印人:{{user.user.userName}} 时间:{{formattedTime}} </div> <div> <span v-if="name=='天津北玻玻璃工业技术有限公司(TJBB-QR7.1-01)'" style="font-size: 10px">{{itemFlow.otherRemarks}}</span> 流程卡号: {{ itemFlow.process_id }}/{{ itemFlow.technologyNumber }} 共 {{ item.count }} 架 </div> </div> </td> </tr> <tr v-for="(items,index) in item.detail" :key="index"> <td class="tdNowrap" >客户名称:</td> <td colspan="2">{{ items.customer_name }}</td> <td class="tdNowrap">项目名称:</td> <td v-if="name=='洛阳北方玻璃技术股份有限公司'" colspan="4" style="min-width: 250px;">{{ items.projectBatch }}</td> <td v-else colspan="4" style="min-width: 250px;">{{ items.project }}</td> <td class="tdNowrap">工艺流程:</td> <td :colspan="2+item.processList.length*2" style="width: 500px">{{ items.process }}</td> </tr> <tr v-for="(itemTr,index) in item.detail" :key="index"> <td class="tdNowrap">磨边类型:</td> <td colspan="2">{{ itemTr.edging_type }}</td> <td class="tdNowrap">单片名称:</td> <td colspan="8">{{ itemTr.glass_child }}</td> <td class="tdNowrap">产品名称:</td> <td :colspan="2+item.processList.length*2">{{ itemTr.product_name }}</td> </tr> <tr> <td rowspan='2'>序号</td> <td rowspan='2'>编号</td> <td rowspan="2">小片顺序</td> <td rowspan='2'>宽*高</td> <td rowspan='2'>数量</td> <td rowspan='2'>面积</td> <td rowspan='2'>周长</td> <td rowspan='2'>半径/备注</td> <td rowspan='2'>类型</td> <td rowspan='2'>原因</td> <td rowspan='2'>工序</td> <td rowspan='2'>班组</td> <td rowspan='2'>信息</td> <td rowspan='2'>备注</td> <td v-for="(itemPr,index) in item.processList" :key="index" colspan="2">{{ itemPr.process }}</td> </tr> <tr> <template v-for=" n in item.processList.length"> <td>{{ company.printLabel.printFlowCard.patch }}</td> <td>{{ company.printLabel.printFlowCard.lackOf }}</td> </template> </tr> </thead> <tbody> <template v-for="(itemDatile,index) in item.detailList" :key="index"> <!-- detailList 数据行 --> <tr> <td>{{ itemDatile.order_number }}</td> <td>{{ itemDatile.s01Value }}</td> <td>{{ itemDatile.technology_number }}</td> <td>{{ itemDatile.child_width }}</td> <td class="item" style="width: 5%;height: 100%;"> <input v-model="itemDatile.quantity" style="width: 100%;height: 100%" @keyup="handleSummary()"/> </td> <td>{{ itemDatile.total_area }}</td> <td>{{ itemDatile.perimeter }}</td> <td>{{ itemDatile.bend_radius }}</td> <td>{{ itemDatile.patch_type }}</td> <td>{{ itemDatile.patch_reason }}</td> <td>{{ itemDatile.patch_processes }}</td> <td>{{ itemDatile.responsible_team }}</td> <td>{{ itemDatile.responsible_personnel }}</td> <td>{{ itemDatile.remarks }}</td> <template v-for=" n in item.processList.length"> <td></td> <td></td> </template> </tr> <!-- 对应二维码行 --> <tr v-if="itemDatile.qrcodeList && itemDatile.qrcodeList.length" :key="'qr-' + index"> <td colspan="34"> <span style="display: flex; flex-wrap: wrap;" v-for="(qr,index) in itemDatile.qrcodeList || []" :key="index"> <img style="width: 80px;height: 80px; margin-right: 5px;" :src="qr.qrcode"> <span style="font-weight: bolder;">{{ qr.processId }}/{{ qr.technologyNumber }}</span> </span> </td> </tr> </template> </tbody> <tfoot> <tr style="height: 14px"> <td v-for="(itemsum,index) in item.detail" :key="index" colspan="34"> 数量: <label>{{ itemsum.quantity }}</label> 面积: <label>{{ parseFloat(itemsum.gross_area.toFixed(2)) }}</label> 重量: <label>{{ parseFloat(itemsum.weight.toFixed(2)) }}</label> </td> </tr> <tr v-for="(itemtextarea,index) in item.detail" :key="index"> <td colspan="4" rowspan="5" style="width: 480px;height: 100px "> <div> </div> </td> <td>完工签名</td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <template v-for=" n in item.processList.length"> <td colspan="2"></td> </template> </tr> <tr> <td>生产日期</td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <template v-for=" n in item.processList.length"> <td colspan="2"></td> </template> </tr> <tr> <td>质检签名</td> <td colspan="2"></td> <td colspan="2">生产签名</td> <td colspan="2"></td> <td colspan="2"></td> <td colspan="2"></td> <template v-for=" n in item.processList.length"> <td colspan="2"></td> </template> </tr> <tr> <td>原片箱号</td> <td colspan="29"></td> </tr> <tr v-for="(qrCodeItem,index) in item.detail" :key="index"> <td colspan="30"> </td> </tr> <tr v-for="(itemtextareas,index) in item.detail" :key="index"> <td colspan="34" rowspan="6" style="width: 99%;height: 150px "> <div style="width: 100%;height: 100%;"><textarea style="height: 99%;width: 99%;border: none;;font-size: 11px;text-align: left">{{itemtextareas.processing_note}}</textarea> </div> </td> </tr> </tfoot> </table> </div> </template> <style scoped> * { margin: 0; padding: 0; text-align: center; } #printButton { margin-top: -40px; width: 100px; } #printFlowCard { text-align: center; //font-weight: bolder; height: 600px; } #contentTable { border-collapse: collapse; border: 1px solid black; width: 100%; } #contentTable thead { font-size: 12px; font-weight: bolder; } #contentTable thead div { font-size: 14px; font-weight: bolder; } #contentTable tr td { border: 1px solid black; height: 18px; font-weight: bolder; } #contentTable tbody { } .tdNowrap { } #contentTable tfoot { font-size: 11px; font-weight: bolder; } input{ border: none; background: none; } @media print { @page { size: auto; /* auto is the initial value */ margin: 2mm 4mm 0mm 4mm /* this affects the margin in the printer settings */ } tbody { display: table-row-group; } table { page-break-before: always; } table { page-break-inside: auto; } thead { display: table-header-group; } tfoot { display: table-footer-group; page-break-inside: avoid; } } .qrCode img { width: 100%; height: 100%; } </style> north-glass-erp/northglass-erp/src/views/LoginView.vue
@@ -124,68 +124,76 @@ <template> <div class="mainDiv" > <div id="main-login"> <div id="img-div"> <img id="img-pic" src="@/assets/img.png" alt=""> </div> <div id="div-login"> <el-select @change="changeLanguage" v-model="language" placeholder=" " style="float: right;width: 6rem"> <el-option value="zh-CN" label="中文" /> <el-option value="en-US" label="English" /> <el-option value="ru" label="Русский язык" /> <el-option value="ar" label="بالعربية" /> <el-option value="ko-KR" label="한국어" /> </el-select> <h2>{{$t('login.SysName')}}</h2> <el-form @submit.native.prevent ref="ruleFormRef" :model="userForm" status-icon :rules="rules" > <el-form-item :label="$t('login.user')+':'" prop="userId"> <el-input v-model="userForm.userId" type="text" autocomplete="off" :prefix-icon="Avatar" :placeholder="$t('login.userErr')" /> </el-form-item> <el-form-item :label="$t('login.password')+':'" prop="pass"> <el-input v-model="userForm.pass" @blur="changeRegister" type="password" autocomplete="off" :prefix-icon="Lock" :placeholder="$t('login.pwErr')" /> </el-form-item> <el-form-item id="submitForm"> <el-button :loading="registerLoadings" :disabled="registerState" type="primary" @click="register" >{{$t('login.register')}} </el-button> <el-button :loading="loginLoadings" type="primary" native-type="submit" @click="submitForm(ruleFormRef)" @keyup.enter.native="keyDown(e)" >{{$t('login.login')}} </el-button> <el-row style="height: 60vh;width: 70vw;" :gutter="50"> <el-col :span="14"> <div id="img-div"> <img id="img-pic" src="@/assets/img.png" alt=""> </div> </el-col> <el-col :span="10"> <div id="div-login"> <el-select @change="changeLanguage" v-model="language" placeholder=" " style="float: right;width: 6rem"> <el-option value="zh-CN" label="中文" /> <el-option value="en-US" label="English" /> <el-option value="ru" label="Русский язык" /> <el-option value="ar" label="بالعربية" /> <el-option value="ko-KR" label="한국어" /> </el-select> <h2>{{$t('login.SysName')}}</h2> <el-form @submit.native.prevent ref="ruleFormRef" :model="userForm" status-icon :rules="rules" > <el-form-item :label="$t('login.user')+':'" prop="userId"> <el-input v-model="userForm.userId" type="text" autocomplete="off" :prefix-icon="Avatar" :placeholder="$t('login.userErr')" /> </el-form-item> <el-form-item :label="$t('login.password')+':'" prop="pass"> <el-input v-model="userForm.pass" @blur="changeRegister" type="password" autocomplete="off" :prefix-icon="Lock" :placeholder="$t('login.pwErr')" /> </el-form-item> <el-form-item id="submitForm"> <el-button :loading="registerLoadings" :disabled="registerState" type="primary" @click="register" >{{$t('login.register')}} </el-button> <el-button :loading="loginLoadings" type="primary" native-type="submit" @click="submitForm(ruleFormRef)" @keyup.enter.native="keyDown(e)" >{{$t('login.login')}} </el-button> </el-form-item> </el-form> </div> </el-form-item> </el-form> </div> </el-col> </el-row> </div> </div> @@ -195,7 +203,8 @@ .mainDiv{ //background-color: #1890FF; overflow: hidden; min-width: 718px; /*width: 100%; height: 100%;*/ } #main-login{ margin: 150px auto 0 auto; @@ -205,7 +214,7 @@ //background-color: #f2f2f2; } #img-div{ width: 55%; width: 100%; height: 100%; display: flex; justify-content: center; @@ -220,10 +229,11 @@ margin-top: 5%; background-color: #fff; float: right; width: 40%; width: 100%; height: 80%; border-radius: 12px; min-width: 318px; min-height: 318px; box-shadow: 0 8px 16px 0 rgba(0,0,0,0), 0 6px 5px 0 rgba(0,0,0,0.19); } h2{ north-glass-erp/northglass-erp/src/views/pp/replenish/PrintReplenishFlowCard.vue
@@ -22,11 +22,13 @@ //import PrintCustomLabel from '@/components/pp/PrintCustomLabelDetails.vue' import QueuePrinter from "@/hook/queue"; import PrintCustomLabelProject from "@/components/pp/PrintCustomLabelProject.vue"; import PrintProcessConsolidated from '@/components/pp/PrintConsolidatedReplenish.vue' const company = companyInfo() //语言获取 const {t} = useI18n() let router = useRouter() const dialogTableVisible = ref(false) const dialogTableConsolidated = ref(false) const dialogTableVisibleLabel = ref(false) const dialogTableVisibleCustomLabel = ref(false) const printVisible= ref(false) @@ -366,6 +368,7 @@ toolbarConfig: { buttons: [ {code: 'print', name: t('processCard.print'), status: 'primary'}, {code: 'printConsolidated', name: t('processCard.mergePrinting'), status: 'primary'}, {code: 'customLabel', name: t('processCard.customLabelPrinting'), status: 'primary'}, {code: 'printLabel', name: t('processCard.labelPrinting'), status: 'primary'}, {code: 'printLabel2', name: t('processCard.labelPrinting2'), status: 'primary'}, @@ -420,11 +423,38 @@ technologyNumber+=selectRecords[i].technology_number } } printRow.value.list = JSON.stringify(selectRecords) console.log(printRow.value.list) printRow.value.printMergeVal=printMerge.value printRow.value.mergeTechnologyNumber=technologyNumber // router.push({path: '/main/processCard/printProcess', query: {printList: JSON.stringify(selectRecords),printMerge:printMergeVal}}) dialogTableVisible.value=true break } case 'printConsolidated': { if(selectRecords===null ||selectRecords===''||selectRecords.length===0){ ElMessage.warning(t('searchOrder.msgList.checkOrder')) return } let id = "" let technologyNumber = "" for (let i = 0; i < selectRecords.length; i++) { if (i + 1 === selectRecords.length) { id += selectRecords[i].id technologyNumber+=selectRecords[i].technology_number } else { id += selectRecords[i].id + "|" technologyNumber+=selectRecords[i].technology_number } } printRow.value.list = JSON.stringify(selectRecords) printRow.value.printMergeVal=printMerge.value printRow.value.mergeTechnologyNumber=technologyNumber // router.push({path: '/main/processCard/printProcess', query: {printList: JSON.stringify(selectRecords),printMerge:printMergeVal}}) dialogTableConsolidated.value=true break } @@ -799,6 +829,20 @@ style="width: 100%;height: 100%" /> </el-dialog> <el-dialog id="sizePrintCalrd" v-model="dialogTableConsolidated" :title="$t('processCard.print')" destroy-on-close style="width: 75%;height:75% "> <template #header="{ close, titleId, titleClass }"> <el-button v-print="printContent" :icon="Printer" circle /> </template> <print-process-consolidated id="child" :printList="printRow.list" :printMerge="printRow.printMergeVal" :printLike="printRow.like" :mergeTechnologyNumber="printRow.mergeTechnologyNumber" style="width: 100%;height: 100%" /> </el-dialog> <!-- 小片标签 --> <el-dialog id="sizeCustomSemi" north-glass-erp/src/main/java/com/example/erp/controller/pp/ProcessCardController.java
@@ -348,6 +348,16 @@ return Result.seccess(flowCardService.getSelectPrintingRefundSv(object,printMerge,printLike,mergeTechnologyNumber)); } @ApiOperation("合并打印流程卡补片数据查询接口") @PostMapping("/getSelectPrintingConsolidated/{printMerge}/{printLike}/{mergeTechnologyNumber}") public Result getSelectPrintingConsolidated( @PathVariable String printMerge, @PathVariable String printLike, @PathVariable String mergeTechnologyNumber, @RequestBody Map<String, Object> object) { return Result.seccess(flowCardService.getSelectPrintingConsolidatedSv(object,printMerge,printLike,mergeTechnologyNumber)); } @ApiOperation("打印流程卡返工数据查询接口") @PostMapping("/getSelectPrinRework/{printMerge}/{printLike}") public Result getSelectPrinRework( north-glass-erp/src/main/java/com/example/erp/entity/pp/FlowCard.java
@@ -105,6 +105,12 @@ //补片状态 @TableField(select = false,exist = false) private Integer patchState; //批次 @TableField(select = false,exist = false) private String batch; //产品名称 @TableField(select = false,exist = false) private String productName; //外键订单表 @TableField(select = false,exist= false) @@ -118,4 +124,6 @@ @TableField(select = false,exist= false) private Product product; } north-glass-erp/src/main/java/com/example/erp/mapper/pp/FlowCardMapper.java
@@ -279,4 +279,6 @@ Boolean updateOrderProcessDetail(String processId, String orderNumber, Integer technologyNumber, int reportingWorkNumCount, int reportingWorkNum, int brokenNum, String process); List<Map<String, String>> getPrimaryListRefundHB(String processId, String technologyNumber, Integer orderNumber, String reportingWorkId, String mergeTechnologyNumber, String patchReason, String orderId); } north-glass-erp/src/main/java/com/example/erp/service/pp/FlowCardService.java
@@ -1532,6 +1532,135 @@ return map; } // public Map<String, Object> getSelectPrintingConsolidatedSv(Map<String, Object> object, String printMerge, String printLike, String mergeTechnologyNumber) { // if (printMerge == null) { // printMerge = ""; // } // if (printLike == null) { // printLike = ""; // } // Map<String, Object> map = new HashMap<>(); // List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();//最终结果 // List<FlowCard> flowCardList = JSONArray.parseArray(JSONObject.toJSONString(object.get("printList")), FlowCard.class); // if (!flowCardList.isEmpty()) { // Set<String> processedKeys = new HashSet<>(); // for (FlowCard flowCard : flowCardList) { // String batch = flowCard.getOrder().getBatch(); // String glassChild = flowCard.getGlassChild(); // Map<String, Object> itemmap = new HashMap<>(); // //流程卡表头表尾数据 // itemmap.put("detail", flowCardMapper.getPrimaryListRefund(flowCard.getProcessId(), String.valueOf(flowCard.getTechnologyNumber()), flowCard.getOrderNumber(), flowCard.getReportingWorkId(), mergeTechnologyNumber, flowCard.getPatchReason(), flowCard.getOrderId())); // // List<Map<String, Object>> detailList = flowCardMapper.getDetailListRefund(flowCard.getProcessId(), flowCard.getTechnologyNumber(), flowCard.getOrderNumber(), flowCard.getReportingWorkId(), flowCard.getPatchReason()); // itemmap.put("detailList", detailList); // //工艺流程 // List<Map<String, Object>> processList = flowCardMapper.getProcessList(flowCard.getProcessId(), flowCard.getTechnologyNumber()); // //工序列表 // List<Map<String, Object>> processNameList = flowCardMapper.getProcessNameList(); // itemmap.put("processList", processList); // itemmap.put("processNameList", processNameList); // // itemmap.put("numberList", numberList); // list.add(itemmap); // // } // } // map.put("data", list); // //初始化值 // printLike = null; // return map; // } public Map<String, Object> getSelectPrintingConsolidatedSv(Map<String, Object> object, String printMerge, String printLike, String mergeTechnologyNumber) { if (printMerge == null) printMerge = ""; if (printLike == null) printLike = ""; Map<String, Object> map = new HashMap<>(); List<Map<String, Object>> list = new ArrayList<>(); List<FlowCard> flowCardList = JSONArray.parseArray( JSONObject.toJSONString(object.get("printList")), FlowCard.class); if (!flowCardList.isEmpty()) { // 用 Map 保存每个 key 对应的合并 detailList Map<String, List<Map<String, Object>>> keyToDetails = new LinkedHashMap<>(); // 用 Map 保存每个 key 对应的第一个 flowCard,用于生成 itemmap 表头等信息 Map<String, FlowCard> keyToFirstFlowCard = new HashMap<>(); for (FlowCard flowCard : flowCardList) { String batch = flowCard.getBatch(); String glassChild = flowCard.getProductName(); String key = batch + "_" + glassChild; List<Map<String, Object>> currentDetailList = flowCardMapper.getDetailListRefund( flowCard.getProcessId(), flowCard.getTechnologyNumber(), flowCard.getOrderNumber(), flowCard.getReportingWorkId(), flowCard.getPatchReason() ); for (Map<String, Object> detail : currentDetailList) { detail.put("processId", flowCard.getProcessId()); detail.put("technologyNumber", flowCard.getTechnologyNumber()); } // 合并 detailList 到对应 key keyToDetails.computeIfAbsent(key, k -> new ArrayList<>()).addAll(currentDetailList); // 保存第一次出现的 flowCard,用于生成 itemmap keyToFirstFlowCard.putIfAbsent(key, flowCard); } // 遍历合并后的 key,生成 itemmap for (Map.Entry<String, List<Map<String, Object>>> entry : keyToDetails.entrySet()) { String key = entry.getKey(); List<Map<String, Object>> mergedDetailList = entry.getValue(); FlowCard firstFlowCard = keyToFirstFlowCard.get(key); Map<String, Object> itemmap = new HashMap<>(); itemmap.put("detailList", mergedDetailList); // 表头表尾 itemmap.put("detail", flowCardMapper.getPrimaryListRefundHB( firstFlowCard.getProcessId(), String.valueOf(firstFlowCard.getTechnologyNumber()), firstFlowCard.getOrderNumber(), firstFlowCard.getReportingWorkId(), mergeTechnologyNumber, firstFlowCard.getPatchReason(), firstFlowCard.getOrderId() )); // 工艺流程 List<Map<String, Object>> processList = flowCardMapper.getProcessList( firstFlowCard.getProcessId(), firstFlowCard.getTechnologyNumber() ); // 工序列表 List<Map<String, Object>> processNameList = flowCardMapper.getProcessNameList(); itemmap.put("processList", processList); itemmap.put("processNameList", processNameList); list.add(itemmap); } } map.put("data", list); return map; } } north-glass-erp/src/main/resources/mapper/pp/DamageDetails.xml
@@ -46,7 +46,7 @@ </if> and a.technology_number = #{technologyNumber} and a.breakage_quantity>0 and c.review_status = 0 and ifnull(c.review_status,0) = 0 </select> </mapper> north-glass-erp/src/main/resources/mapper/pp/FolwCard.xml
@@ -3594,4 +3594,60 @@ where process_id = #{processId} and order_number = #{orderNumber} and technology_number = #{technologyNumber} and process = #{process} </update> <select id="getPrimaryListRefundHB"> select o.customer_name, o.project, if(o.batch!="",CONCAT(o.project,'(',o.batch,')'),o.project) as projectBatch, ogd.process, od.edging_type, ogd.glass_child, od.product_name, o.processing_note, fc.process_id, pl.patch_num as quantity, round(SUM(ogd.total_area), 2) as gross_area, sum(od.weight) as weight, #{technologyNumber} as technologyNumber, concat(fc.process_id, '/', #{technologyNumber}) as processIdNumber, dd.breakage_type, dd.breakage_reason, dd.responsible_process, dd.responsible_team, concat('对应我司单号', o.batch) AS otherRemarks, dd.responsible_personnel, #{mergeTechnologyNumber} as mergeTechnologyNumber, pl.patch_id from flow_card as fc left join sd.order_glass_detail as ogd on fc.order_id = ogd.order_id and fc.order_number = ogd.order_number and fc.technology_number = ogd.technology_number left join sd.order_detail as od on od.order_id = fc.order_id and od.order_number = fc.order_number left join sd.`order` as o on o.order_id = fc.order_id left join sd.product as p on p.id = od.product_id left join (select ogd.order_id, ogd.order_number, ogd.technology_number, ogd.glass_child, GROUP_CONCAT(glass_child SEPARATOR ' ') AS concatenated_glass_child from sd.order_glass_detail as ogd where ogd.order_id = #{orderId} and ogd.order_number = #{orderNumber} and position(ogd.technology_number in #{technologyNumber}) GROUP BY order_id, order_number) as ogdc on ogdc.order_id = ogd.order_id and ogdc.order_number = ogd.order_number and ogdc.technology_number = ogd.technology_number left join patch_log as pl on pl.process_id = fc.process_id and pl.order_sort = fc.order_number and pl.technology_number = fc.technology_number left join pp.reporting_work as rw on rw.order_id = fc.order_id and rw.process_id = fc.process_id left join pp.damage_details as dd on rw.reporting_work_id = dd.reporting_work_id and dd.order_number = fc.order_number and dd.technology_number = fc.technology_number where fc.process_id = #{processId} and fc.order_number = #{orderNumber} and fc.technology_number = #{technologyNumber} and pl.reporting_work_id = #{reportingWorkId} and dd.breakage_reason = #{patchReason} group by fc.process_id </select> </mapper>