ÏîÄ¿´úÂë/WIDESEA_WMSClient/config/buttons.js
@@ -319,7 +319,7 @@ name: "å ³éåæ®", icon: '', class: '', value: 'CloseOrder', value: ' ', type: 'warning', onClick: function () { } ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/Dt_AllocateOrder.js
@@ -404,7 +404,6 @@ param.wheres.push(...wheres); return true; return true; }, searchAfter(result) { //æ¥è¯¢åï¼resultè¿åçæ¥è¯¢æ°æ®,å¯ä»¥å¨æ¾ç¤ºå°è¡¨æ ¼åå¤çè¡¨æ ¼çå¼ ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js
@@ -5,12 +5,13 @@ import { ElDialog , ElForm, ElFormItem, ElInput, ElButton, ElMessage ,ElSelect ,ElOption } from 'element-plus'; // å¼å ¥ElMessageï¼è§£å³æç¤ºæ ååº import gridBody from '../inbound/extend/Pallet.vue' import gridHeader from './extend/EmptyTrayInbound.vue' import gridFooter from "./extend/UndoPalletGroup.vue"; let extension = { components: { //æ¥è¯¢ç颿©å±ç»ä»¶ gridHeader: gridHeader, gridBody: gridBody, gridFooter: '', gridFooter: gridFooter, //æ°å»ºãç¼è¾å¼¹åºæ¡æ©å±ç»ä»¶ modelHeader: '', modelBody: '', @@ -44,207 +45,8 @@ // this.$emit('openPalletDialog', targetRow.orderNo); // } // }, { name: 'æ¤éç»ç', type: 'primary', value: 'æ¤éç»ç', onClick: function () { console.log('æ¤éç»çæé®è¢«ç¹å»'); const mountNode = document.createElement('div'); document.body.appendChild(mountNode); // ååºå¼è¡¨åæ°æ®ï¼æçå·ï¼å¿ å¡«ï¼ const formData = reactive({ palletCode: '', // æçå·è¾å ¥æ¡ barcode:'' }); // æäº¤è¡¨åçç»ä¸é»è¾ const submitForm = async () => { const formRef = vnode.component.refs.cancelPalletForm; try { // æ§è¡è¡¨åæ ¡éªï¼æçå·å¿ å¡«ï¼ await formRef.validate(); } catch (err) { ElMessage.warning('请è¾å ¥ææçæçå·'); return; } // åèµ·æ¤éç»çè¯·æ± try { //console.log('åèµ·æ¤éç»ç请æ±ï¼æçå·ï¼', formData.palletCode.trim()); const response = await http.post('/api/InboundOrder/UndoPalletGroup?palletCode='+formData.palletCode.trim()+'&barcode='+formData.barcode.trim()); const { status, message, data } = response; if (status) { ElMessage.success(`æ¤éç»çæåï¼æçå·ï¼${formData.palletCode.trim()}`); this.refresh(); // æååå·æ°å表 // å ³éå¯¹è¯æ¡ render(null, mountNode); document.body.removeChild(mountNode); } else { console.log('æ¤éç»ç失败ï¼å端æç¤ºï¼', message); ElMessage.error(message || data?.message || 'æ¤éç»ç失败'); selectPalletCodeInput(); // éä¸è¾å ¥æ¡æ¹ä¾¿éæ°è¾å ¥ } } catch (error) { console.error('æ¤éç»ç请æ±å¼å¸¸ï¼', error); ElMessage.error('ç½ç»å¼å¸¸ææ¥å£é误ï¼è¯·ç¨åéè¯'); selectPalletCodeInput(); } }; // éä¸è¾å ¥æ¡ææ¬ï¼æ¹ä¾¿éæ°è¾å ¥ï¼ const selectPalletCodeInput = () => { setTimeout(() => { const inputRef = vnode.component.refs.palletCodeInput; if (inputRef) { const targetInput = inputRef.$el?.querySelector('input') || inputRef; targetInput?.focus(); targetInput?.select(); } }, 100); }; // åå»ºå¯¹è¯æ¡VNode const vnode = createVNode(ElDialog, { title: 'æ¤éç»ç', width: '400px', modelValue: true, appendToBody: true, onOpened: () => { // å¯¹è¯æ¡æå¼åèªå¨èç¦è¾å ¥æ¡ setTimeout(() => { const inputRef = vnode.component.refs.palletCodeInput; inputRef?.focus(); }, 100); }, 'onUpdate:modelValue': (isVisible) => { if (!isVisible) { render(null, mountNode); document.body.removeChild(mountNode); } } }, { default: () => h(ElForm, { model: formData, rules: { palletCode: [ { required: true, message: '请è¾å ¥æçå·', trigger: ['blur', 'enter'] }, { min: 1, max: 50, message: 'æçå·é¿åº¦ä¸è½è¶ è¿50个å符', trigger: ['blur', 'input'] } ] }, ref: 'cancelPalletForm' }, [ // æçå·è¾å ¥é¡¹ h(ElFormItem, { label: 'æçå·', prop: 'palletCode', required: true }, [ h(ElInput, { type: 'text', modelValue: formData.palletCode, 'onUpdate:modelValue': (val) => { formData.palletCode = val; }, ref: 'palletCodeInput', placeholder: 'æ«ç è¾å ¥ææå¨è¾å ¥æçå·', maxLength: 50, // çå¬å车äºä»¶ï¼æ«ç æªé»è®¤ä¼åéåè½¦ï¼ onKeydown: (e) => { if (e.key === 'Enter') { e.preventDefault(); submitForm(); } } }) ]), h(ElFormItem,{label: 'æ¡ç ', prop: 'barcode'},[ h(ElInput, { type: 'text', modelValue: formData.barcode, 'onUpdate:modelValue': (val) => { formData.barcode = val; }, placeholder: 'å¯éï¼æ«ç è¾å ¥ææå¨è¾å ¥æ¡ç ', maxLength: 50, onKeydown: (e) => { if (e.key === 'Enter') { e.preventDefault(); submitForm(); } } }) ]), // åºé¨æé®åº h('div', { style: { textAlign: 'right', marginTop: '16px' } }, [ h(ElButton, { type: 'text', onClick: () => { render(null, mountNode); document.body.removeChild(mountNode); ElMessage.info('åæ¶æ¤éç»ç'); } }, 'åæ¶'), h(ElButton, { type: 'primary', onClick: submitForm.bind(this) // ç»å®thisä¸ä¸æ }, '确认æ¤é') ]) ]) }); vnode.appContext = this.$.appContext; render(vnode, mountNode); } }, { name: 'åæ¹å ¥åº', type: 'primary', value: 'åæ¹å ¥åº', onClick: async function () { console.log('åæ¹å ¥åºæé®è¢«ç¹å»ï¼å¼å§æ ¡éª'); const selectedRows = this.$refs.table.getSelected(); // æ ¡éª1ï¼æ¯å¦éä¸è¡ï¼è³å°éæ©ä¸æ¡ï¼ if (selectedRows.length === 0) { console.log('æ ¡éªä¸éè¿ï¼æªéä¸ä»»ä½åæ®'); ElMessage.warning('è¯·éæ©è³å°ä¸æ¡åæ®'); return; } // æ¶éææéä¸åæ®çç¼å·ï¼è¿æ»¤æ åæ®å·çå¼å¸¸è¡ï¼ const inboundOrderNos = selectedRows .filter(row => row.orderNo) .map(row => row.orderNo); // æ ¡éª2ï¼æ¯å¦æææåæ®å· if (inboundOrderNos.length === 0) { console.log('æ ¡éªä¸éè¿ï¼éä¸åæ®æ ææç¼å·'); ElMessage.warning('éä¸ç忮䏿 ææç¼å·ï¼è¯·éæ°éæ©'); return; } try { console.log('åèµ·åæ¹å ¥åºè¯·æ±ï¼åæ°ï¼', { inboundOrderNos}); const response = await http.post('/api/InboundOrder/BatchOrderFeedbackToMes', { orderNos: inboundOrderNos, inout:1 }); const { status, message, data } = response; if (status) { console.log('åæ¹å ¥åºæåï¼å端è¿åï¼', data); ElMessage.success(`åæ¹å ¥åºæåï¼å ±å¤ç${inboundOrderNos.length}æ¡åæ®`); this.refresh(); // å ¥åºæååå·æ°å表ï¼å¤ç¨åæé»è¾ï¼ } else { console.log('åæ¹å ¥åºå¤±è´¥ï¼å端æç¤ºï¼', message); ElMessage.error(message || data?.message || 'åæ¹å ¥åºå¤±è´¥'); } } catch (error) { console.error('åæ¹å ¥åºè¯·æ±å¼å¸¸ï¼', error); ElMessage.error('ç½ç»å¼å¸¸ææ¥å£é误ï¼è¯·ç¨åéè¯'); } } },], box: [], detail: [] }, ], box: [], detail: [] }, methods: { //ä¸é¢è¿äºæ¹æ³å¯ä»¥ä¿çä¹å¯ä»¥å é¤ onInit() { @@ -260,6 +62,73 @@ this.$refs.gridHeader.open(); } } var UndoPalletGroupBtn = this.buttons.find( (x) => x.value == "UndoPalletGroup" ); if (UndoPalletGroupBtn != null) { UndoPalletGroupBtn.onClick = () => { this.$refs.gridFooter.open(); }; } var BatchInOrderFeedbackToMesBtn = this.buttons.find( (x) => x.value == "BatchInOrderFeedbackToMes" ); if (BatchInOrderFeedbackToMesBtn != null) { BatchInOrderFeedbackToMesBtn.onClick = () => { var rows = this.$refs.table.getSelected(); // æ ¡éªæ¯å¦æé䏿°æ® if (!rows || rows.length === 0) { return this.$Message.error("请å éæ©éè¦å¤ççåæ®"); } if (rows.length > 1) { return this.$Message.error("è¯·éæ©ä¸æ¡æ°æ®"); } this.http.post(`api/Inbound/BatchInOrderFeedbackToMes?id=${rows[0].id}`, {}, "æ°æ®å¤çä¸...") .then((x) => { if (x.status) { this.$Message.success(x.message); this.refresh(); } else { return this.$Message.error(x.message); } }) .catch((error) => { // å¢å å¼å¸¸æè·ï¼å¤çç½ç»éè¯¯çæ åµ //_this.$Message.error('请æ±å¤±è´¥ï¼' + (error.message || 'æªç¥é误')); }); }; } var CloseOrderBtn = this.buttons.find( (x) => x.value == "CloseOrder" ); if (CloseOrderBtn != null) { CloseOrderBtn.onClick = () => { var rows = this.$refs.table.getSelected(); // æ ¡éªæ¯å¦æé䏿°æ® if (!rows || rows.length === 0) { return this.$Message.error("请å éæ©éè¦å ³éçåæ®"); } if (rows.length > 1) { return this.$Message.error("è¯·éæ©ä¸æ¡åæ®"); } this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].orderNo}`, {}, "æ°æ®å¤çä¸...") .then((x) => { if (x.status) { this.$Message.success(x.message); this.refresh(); } else { return this.$Message.error(x.message); } }) .catch((error) => { // å¢å å¼å¸¸æè·ï¼å¤çç½ç»éè¯¯çæ åµ //_this.$Message.error('请æ±å¤±è´¥ï¼' + (error.message || 'æªç¥é误')); }); }; } }, onInited() { ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js
@@ -82,7 +82,7 @@ if (rows.length > 1) { return this.$Message.error("è¯·éæ©ä¸æ¡åæ®"); } this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].id}`, {}, "æ°æ®å¤çä¸...") this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].inboundOrderNo}`, {}, "æ°æ®å¤çä¸...") .then((x) => { if (x.status) { this.$Message.success(x.message); ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js
@@ -555,6 +555,34 @@ //æ¡æ¶åå§åé ç½®å //妿è¦é ç½®æç»è¡¨,卿¤æ¹æ³æä½ //this.detailOptions.columns.forEach(column=>{ }); var CloseOrderBtn = this.buttons.find( (x) => x.value == "CloseOrder" ); if (CloseOrderBtn != null) { CloseOrderBtn.onClick = () => { var rows = this.$refs.table.getSelected(); // æ ¡éªæ¯å¦æé䏿°æ® if (!rows || rows.length === 0) { return this.$Message.error("请å éæ©éè¦å ³éçåæ®"); } if (rows.length > 1) { return this.$Message.error("è¯·éæ©ä¸æ¡åæ®"); } this.http.post(`api/InboundOrder/HandCloseOrder?orderIds=${rows[0].orderNo}`, {}, "æ°æ®å¤çä¸...") .then((x) => { if (x.status) { this.$Message.success(x.message); this.refresh(); } else { return this.$Message.error(x.message); } }) .catch((error) => { // å¢å å¼å¸¸æè·ï¼å¤çç½ç»éè¯¯çæ åµ //_this.$Message.error('请æ±å¤±è´¥ï¼' + (error.message || 'æªç¥é误')); }); }; } }, searchBefore(param) { ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/Home.vue
@@ -70,17 +70,52 @@ </el-col> </el-row> <!-- å¾è¡¨åºåï¼ç¬¬ä¸è¡ï¼ --> <el-row :gutter="20" class="chart-row"> <el-col :span="12"> <!-- æ¿æ¢el-card为divï¼ä¿çchart-cardç±»å --> <el-col :span="8"> <div class="chart-card"> <div class="chart-title">åºä½å©ç¨ç</div> <div ref="locationRateRef" class="chart-container"></div> </div> </el-col> <el-col :span="12"> <!-- 临æä¿¡æ¯æ¹ä¸ºè¡¨æ ¼ --> <el-col :span="8"> <div class="chart-card"> <div class="chart-title">ç©æä¸´æä¿¡æ¯</div> <!-- 临æç©æè¡¨æ ¼ --> <div class="expiration-table-container"> <el-table :data="expirationTableData" border stripe style="width: 100%;" :empty-text="emptyText" > <el-table-column prop="materielCode" label="ç©æç¼ç " align="center" /> <el-table-column prop="materielName" label="ç©æåç§°" align="center" show-overflow-tooltip /> <el-table-column prop="batchNo" label="æ¹æ¬¡å·" align="center" /> <el-table-column prop="validDate" label="æææ" align="center" /> <el-table-column label="临æç级" align="center"> <template #default="{ row }"> <span :class="getExpireLevelClass(row.expireLevel)">{{ row.expireLevel }}</span> </template> </el-table-column> <el-table-column prop="daysToExpiration" label="临æå¤©æ°" align="center"> <template #default="{ row }"> <span :class="row.daysToExpiration < 0 ? 'text-red' : ''"> {{ row.daysToExpiration < 0 ? 'å·²è¿æ' : `${row.daysToExpiration}天` }} </span> </template> </el-table-column> <!-- <el-table-column prop="barcode" label="æ¡ç " align="center" /> --> <el-table-column prop="stockQuantity" label="åºåæ°é" align="center" /> <el-table-column prop="locationCode" label="åºä½" align="center" /> <el-table-column prop="palletCode" label="æçç¼å·" align="center" /> </el-table> </div> </div> </el-col> <el-col :span="8"> <div class="chart-card"> <div class="chart-title">è¿7æ¥åºå ¥åºè¶å¿ï¼å¾ååèµ°å¿ï¼</div> <div ref="stockTrendRef" class="chart-container"></div> @@ -95,7 +130,6 @@ <!-- è¡¨æ ¼åºå - ç»å®å端ä½ä¸æ°æ® --> <el-row :gutter="20" class="table-row" width="100%"> <el-col :span="24"> <!-- æ¿æ¢el-card为divï¼ä¿çtable-cardç±»å --> <div class="table-card"> <div class="table-title">宿¶ä½ä¸çæ§</div> <el-table :data="showTaskList" border style="width: 100%;"> @@ -125,9 +159,13 @@ </template> <script setup> import { ref, onMounted, onUnmounted, nextTick } from 'vue'; import { ref, onMounted, onUnmounted, nextTick, computed } from 'vue'; import * as echarts from 'echarts'; import http from "@/api/http.js"; // è¡¥å 缺失ç徿 å¯¼å ¥ import { Box, Document, Download, Upload } from '@element-plus/icons-vue'; // è¡¥å ElMessageå¯¼å ¥ import { ElMessage } from 'element-plus'; // ååºå¼æ°æ® const month = ref('month'); @@ -146,9 +184,86 @@ taskList: [], inboundCount: 0, outboundCount: 0, inventoryLocationDist: [], // åºååºä½å叿°æ® exceptionTypeTrend: [] // å¼å¸¸ç±»åè¶å¿æ°æ® inventoryLocationDist: [], exceptionTypeTrend: [], nearExpirationList: [] // æ¹ä¸ºæ°ç»ç±»åï¼å¹é æ°æ°æ®ç»æ }); // 临æè¡¨æ ¼æ°æ®ï¼è®¡ç®å±æ§ï¼éé æ°çæ°ç»æ°æ®ç»æï¼ const expirationTableData = computed(() => { // æ°æ°æ®ç»ææ¯æ°ç»ï¼ç´æ¥åæ°ç»å¹¶å¤çç©ºå¼ const expirationList = bigscreendata.value.nearExpirationList || []; // ç¬¬ä¸æ¥ï¼å»é - æ ç©æç¼ç +æ¹æ¬¡å·+æçç¼å·+æææ å¯ä¸æ è¯å»é const uniqueMap = new Map(); expirationList.forEach(item => { // æ¼æ¥å¯ä¸æ è¯ï¼å¤ç空å¼ï¼é¿å å 空å¼å¯¼è´éå¤å¤æéè¯¯ï¼ const uniqueKey = [ item.materielCode || 'æªç¥ç¼ç ', item.batchNo || 'æªç¥æ¹æ¬¡', item.palletCode || 'æªç¥æç', ].join('|'); // ç¨ç¹æ®å符åéï¼é¿å åæ®µå¼æ¼æ¥åæ··æ· // åªä¿çç¬¬ä¸æ¬¡åºç°çè®°å½ if (!uniqueMap.has(uniqueKey)) { uniqueMap.set(uniqueKey, item); } }); // æåå»éåçæ°ç» const uniqueExpirationList = Array.from(uniqueMap.values()); // ç¬¬äºæ¥ï¼éåå»éåçæ°æ®ï¼è¡¥å 临æç级åé»è®¤å¼ return uniqueExpirationList.map(item => { // æåå½åç©æç临æå¤©æ°ï¼æ ¸å¿åæ®µï¼ const daysToExpiration = item.daysToExpiration || 0; // 计ç®ä¸´æç级 let expireLevel = ''; if (daysToExpiration < 0) { expireLevel = 'å·²è¿æ'; } else if (daysToExpiration <= 7) { expireLevel = '7天å 临æ'; } else if (daysToExpiration <= 15) { expireLevel = '15天å 临æ'; } else if (daysToExpiration <= 30) { expireLevel = '30天å 临æ'; } else { expireLevel = '30天以ä¸'; } return { materielCode: item.materielCode || 'æªç¥ç¼ç ', materielName: item.materielName || 'æªç¥åç§°', batchNo: item.batchNo || 'æªç¥æ¹æ¬¡', validDate: item.validDate || 'æªç¥æææ', daysToExpiration: daysToExpiration, expireLevel: expireLevel, stockQuantity: item.stockQuantity || 0, locationCode: item.locationCode || 'æªç¥åºä½', palletCode: item.palletCode || 'æªç¥æç', unit: item.unit || 'PCS' }; }); }); // ç©ºæ°æ®æç¤ºææ¬ï¼ä¿®æ£å¤æé»è¾ï¼ const emptyText = computed(() => { const expirationList = bigscreendata.value.nearExpirationList || []; // æ°ç»é¿åº¦ä¸º0æ¶æ¾ç¤ºç©ºæç¤ºï¼å¦å䏿¾ç¤ºï¼åé»è¾ååäºï¼ return expirationList.length === 0 ? 'ææ ä¸´æç©ææ°æ®' : ''; }); // è·å临æççº§æ ·å¼ç±» const getExpireLevelClass = (level) => { switch(level) { case 'å·²è¿æ': return 'expire-level expired'; case '7天å 临æ': return 'expire-level urgent'; case '15天å 临æ': return 'expire-level warning'; case '30天å 临æ': return 'expire-level normal'; case '30天以ä¸': return 'expire-level low'; default: return 'expire-level default'; } }; const taskStatusMap = { 100: "æ°å»º", @@ -171,57 +286,54 @@ 990: "ä»»å¡å¼å¸¸", 110: "æåæºæ§è¡ä¸" }; // è·åä»»å¡ç¶æææ¬ const getTaskStatusText = (statusNum) => { // å¤ç空å¼ãæ æå¼ï¼å åºæ¾ç¤ºâæªç¥ç¶æâ if (statusNum === undefined || statusNum === null || isNaN(statusNum)) { return "æªç¥ç¶æ"; } // ç²¾åå¹é æ å°å¼ï¼æ å¹é åè¿åâæªç¥ç¶æâ return taskStatusMap[statusNum] || "æªç¥ç¶æ"; }; const showTaskList = ref([]); // è¡¨æ ¼æ¾ç¤ºç5æ¡ä»»å¡ï¼è½®æç¨ï¼ const currentTaskIndex = ref(5); // ä¸ä¸ä¸ªè¦æ¾ç¤ºçä»»å¡ç´¢å¼ï¼åå§ä»ç¬¬6æ¡å¼å§ï¼å5æ¡é»è®¤æ¾ç¤ºï¼ let taskCarouselTimer = null; // è½®æå®æ¶å¨ // è¡¨æ ¼æ¾ç¤ºçä»»å¡å表ï¼è½®æç¨ï¼ const showTaskList = ref([]); const currentTaskIndex = ref(5); let taskCarouselTimer = null; // æ°åæ ¼å¼åï¼ååä½åéï¼ const formatNumber = (num) => { if (!num) return '0'; return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; // ä»»å¡å表轮æé»è¾ const startTaskCarousel = () => { // æ¸ é¤æ§å®æ¶å¨ï¼é²æ¢éå¤å¯å¨ if (taskCarouselTimer) clearInterval(taskCarouselTimer); const totalTask = bigscreendata.value.taskList.length; // 任塿°<=5æ¶ï¼ä¸è½®æï¼æ²¡ææ´å¤ä»»å¡å¯æ¢ï¼ if (totalTask <= 5) { showTaskList.value = [...bigscreendata.value.taskList]; return; } // å¯å¨5ç§å®æ¶å¨ taskCarouselTimer = setInterval(() => { // 1. æ°å¢ä¸1æ¡ä»»å¡å°æ¾ç¤ºå表æ«å°¾ showTaskList.value.push(bigscreendata.value.taskList[currentTaskIndex.value]); // 2. å é¤å表æåé¢1æ¡æ§ä»»å¡ï¼å§ç»ä¿æ5æ¡ï¼ showTaskList.value.shift(); // 3. æ´æ°ä¸ä¸ä¸ªä»»å¡ç´¢å¼ï¼è¶ åºæ»æ°åéç½®ï¼å¾ªç¯è½®æï¼ currentTaskIndex.value++; if (currentTaskIndex.value >= totalTask) { currentTaskIndex.value = 0; // é置为0ï¼å¾ªç¯ææ¾ currentTaskIndex.value = 0; } }, 5000); // 5ç§é´é }, 5000); }; // è·åä»»å¡ç±»åææ¬ const getTaskTypeText = (taskTypeNum) => { // å¤ç空å¼/æ æå¼ if (!taskTypeNum || isNaN(taskTypeNum)) return "æªç¥ç±»å"; // 对åºå端TaskEnumHelperçåç»è§å if (taskTypeNum >= 500 && taskTypeNum < 900) return "å ¥åº"; if (taskTypeNum >= 100 && taskTypeNum < 500) return "åºåº"; if (taskTypeNum >= 900 && taskTypeNum < 1000) return "ç§»åº"; return "å ¶ä»ä½ä¸"; // å åº return "å ¶ä»ä½ä¸"; }; // è·åä»»å¡ç¶ææ ·å¼ç±» @@ -230,15 +342,14 @@ return "status-unknown"; } // æ ¹æ®ç¶æèå´è¿åä¸åæ ·å¼ if (statusNum >= 900) return "status-completed"; // 宿 if (statusNum >= 400) return "status-processing"; // è¾é线æ§è¡ä¸ if (statusNum >= 300) return "status-processing"; // AGVæ§è¡ä¸ if (statusNum >= 200) return "status-processing"; // å åæºæ§è¡ä¸ if (statusNum >= 100) return "status-pending"; // æ°å»ºãå·²åé if (statusNum === 970) return "status-suspended"; // æèµ· if (statusNum === 980) return "status-canceled"; // åæ¶ if (statusNum === 990) return "status-error"; // å¼å¸¸ if (statusNum >= 900) return "status-completed"; if (statusNum >= 400) return "status-processing"; if (statusNum >= 300) return "status-processing"; if (statusNum >= 200) return "status-processing"; if (statusNum >= 100) return "status-pending"; if (statusNum === 970) return "status-suspended"; if (statusNum === 980) return "status-canceled"; if (statusNum === 990) return "status-error"; return "status-unknown"; }; @@ -247,34 +358,32 @@ const getTypeClass = (taskTypeNum) => { if (!taskTypeNum || isNaN(taskTypeNum)) return "type-unknown"; // 对åºå端TaskEnumHelperçåç»è§å if (taskTypeNum >= 500 && taskTypeNum < 900) return "type-inbound"; // å ¥åº if (taskTypeNum >= 100 && taskTypeNum < 500) return "type-outbound"; // åºåº if (taskTypeNum >= 900 && taskTypeNum < 1000) return "type-transfer"; // ç§»åº if (taskTypeNum >= 500 && taskTypeNum < 900) return "type-inbound"; if (taskTypeNum >= 100 && taskTypeNum < 500) return "type-outbound"; if (taskTypeNum >= 900 && taskTypeNum < 1000) return "type-transfer"; return "type-other"; // å ¶ä»ä½ä¸ return "type-other"; }; // è·ååç«¯å¤§å±æ°æ® const fetchBigGreenData = async () => { try { debugger const res = await http.get('/api/BigScreen/GetBigGreenData'); console.log('大屿°æ®', res); bigscreendata.value = res.data || res; // æ°æ®æ´æ°åå·æ°å¾è¡¨ // æ°æ®æ´æ°åå·æ°å¾è¡¨åè¡¨æ ¼ nextTick(() => { const total = bigscreendata.value.taskList.length; // åå§åæ¾ç¤ºå5æ¡ï¼ä¸è¶³5æ¡åæ¾ç¤ºå ¨é¨ï¼ showTaskList.value = total >=5 ? [...bigscreendata.value.taskList.slice(0,5)] : [...bigscreendata.value.taskList]; startTaskCarousel(); // å¯å¨ä»»å¡è½®æ startTaskCarousel(); refreshCharts(); }); } catch (error) { ElMessage.error('æ°æ®è·å失败ï¼è¯·æ£æ¥å端æ¥å£æ¯å¦æ£å¸¸'); console.error('æ°æ®è·å失败ï¼', error); } }; @@ -292,23 +401,21 @@ const locationRateRef = ref(null); const exceptionTrendRef = ref(null); // å¾è¡¨å®ä¾ï¼å ¨å±ç®¡çï¼ç¨äºéæ¯åresizeï¼ // å¾è¡¨å®ä¾ï¼å ¨å±ç®¡çï¼ let inventoryPieChart = null; let stockTrendChart = null; let locationRateChart = null; let exceptionTrendChart = null; // åå§ååºååºä½åå¸é¥¼å¾ï¼å ³èåç«¯æ°æ®ï¼ // åå§ååºååºä½åå¸é¥¼å¾ const initInventoryPie= () => { if (!inventoryPieRef.value) return; // 鿝æ§å®ä¾ï¼é²æ¢å åæ³æ¼ if (inventoryPieChart) { inventoryPieChart.dispose(); } inventoryPieChart = echarts.init(inventoryPieRef.value); // ä¼å 使ç¨åç«¯æ°æ®ï¼æ æ°æ®åç¨é»è®¤å¼ const locationData = bigscreendata.value.inventoryLocationDist.length ? bigscreendata.value.inventoryLocationDist : [ @@ -361,7 +468,7 @@ return inventoryPieChart; }; // åå§åè¿7æ¥åºå ¥åºè¶å¿å¾ï¼å ³èåç«¯æ°æ®ï¼ // åå§åè¿7æ¥åºå ¥åºè¶å¿å¾ const initStockTrend = () => { if (!stockTrendRef.value) return; @@ -370,15 +477,11 @@ } stockTrendChart = echarts.init(stockTrendRef.value); // ä¼å 使ç¨åç«¯æ°æ® const trendData = bigscreendata.value.dailyInOutBoundList; console.log('åºå ¥åºè¶å¿æ°æ®', trendData); // è®¡ç®æ°æ®ä¸çæå¤§å¼ï¼ç¨äºè®¾ç½®Yè½´èå´ const maxInbound = Math.max(...trendData.map(item => item.dailyInboundQuantity || 0)); const maxOutbound = Math.max(...trendData.map(item => item.dailyOutboundQuantity || 0)); const maxInbound = trendData.length ? Math.max(...trendData.map(item => item.dailyInboundQuantity || 0)) : 0; const maxOutbound = trendData.length ? Math.max(...trendData.map(item => item.dailyOutboundQuantity || 0)) : 0; const maxValue = Math.max(maxInbound, maxOutbound); console.log('æå¤§å¼è®¡ç®ç»æ:', { maxInbound, maxOutbound, maxValue }); const option = { tooltip: { @@ -407,7 +510,6 @@ type: 'value', name: 'æ°é', min: 0, // æ ¹æ®æ°æ®å¨æè®¾ç½®æå¤§å¼ï¼çåºä¸äºç©ºé´ max: maxValue > 0 ? Math.ceil(maxValue * 1.2) : 10 }, series: [ @@ -438,18 +540,15 @@ return stockTrendChart; }; // åå§ååºä½å©ç¨çç¯å½¢å¾ï¼ä¿®æ£ï¼ç»ä¸å®ä¾ç®¡çï¼å ³èåç«¯æ°æ®ï¼ // åå§ååºä½å©ç¨çç¯å½¢å¾ const initLocationRate = () => { if (!locationRateRef.value) return; // 鿝æ§å®ä¾ if (locationRateChart) { locationRateChart.dispose(); } locationRateChart = echarts.init(locationRateRef.value); // ä¼å 使ç¨åç«¯æ°æ®ï¼æ æ°æ®åç¨é»è®¤å¼ console.log('åºä½å©ç¨çæ°æ®', bigscreendata.value.locationUtilizationRate); const utilizationRate = bigscreendata.value.locationUtilizationRate || 0; const freeRate = 100 - utilizationRate; @@ -507,7 +606,7 @@ return locationRateChart; }; // åå§åå¼å¸¸ç±»åç»è®¡è¶å¿å¾ï¼å ³èåç«¯æ°æ®ï¼ // åå§åå¼å¸¸ç±»åç»è®¡è¶å¿å¾ const initExceptionTrend = () => { if (!exceptionTrendRef.value) return; @@ -516,7 +615,6 @@ } exceptionTrendChart = echarts.init(exceptionTrendRef.value); // ä¼å 使ç¨åç«¯æ°æ® const exceptionData = bigscreendata.value.exceptionTypeTrend.length ? bigscreendata.value.exceptionTypeTrend : { @@ -602,11 +700,11 @@ return exceptionTrendChart; }; // å·æ°ææå¾è¡¨ï¼ç§»é¤æ æé·è¾¾å¾é»è¾ï¼ // å·æ°ææå¾è¡¨ const refreshCharts = () => { const charts = [ initStockTrend, initLocationRate, initLocationRate ]; charts.forEach(initFunc => { @@ -633,7 +731,7 @@ }); }; // ç»ä»¶æè½½æ¶ï¼å è¯·æ±æ°æ®ï¼ååå§åå¾è¡¨ // ç»ä»¶æè½½æ¶ onMounted(() => { // å è·ååç«¯æ°æ® fetchBigGreenData(); @@ -647,7 +745,7 @@ }); }); // ç»ä»¶å¸è½½æ¶ï¼éæ¯å¾è¡¨å®ä¾ï¼ç§»é¤äºä»¶çå¬ // ç»ä»¶å¸è½½æ¶ onUnmounted(() => { const charts = [ inventoryPieChart, @@ -661,7 +759,7 @@ chart.dispose(); } }); clearInterval(taskCarouselTimer); // æ¸ é¤è½®æå®æ¶å¨ clearInterval(taskCarouselTimer); window.removeEventListener('resize', handleResize); }); </script> @@ -692,7 +790,7 @@ margin-bottom: 20px; } /* æ ¸å¿ä¿®æ¹ï¼è¡¥å divçcardçåºç¡æ ·å¼ï¼æ¨¡æel-cardçè§è§ææ */ /* æ ¸å¿æ ·å¼ï¼å¡çåºç¡æ ·å¼ */ .stats-card, .chart-card, .table-card { background: #fff; border-radius: 8px; @@ -712,7 +810,6 @@ overflow: hidden; background: linear-gradient(145deg, #ffffff 0%, #f9fafc 100%); } .stats-card:hover { transform: translateY(-6px) scale(1.02); @@ -735,7 +832,6 @@ transition: all 0.3s ease; } .card-title { font-size: 15px; color: #606266; @@ -745,23 +841,16 @@ } .card-value { font-size: 26px; font-weight: 600; margin: 4px 0; background: linear-gradient(to right, #409eff, #36cfc9); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .card-value { font-size: 32px; font-weight: 700; margin: 8px 0 4px; color: #2c3e50; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); line-height: 1.2; background: linear-gradient(to right, #409eff, #36cfc9); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .card-change { @@ -799,6 +888,58 @@ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.03); } /* 临æç©æè¡¨æ ¼å®¹å¨æ ·å¼ */ .expiration-table-container { width: 100%; height: 100%; min-height: 300px; flex: 1; overflow-y: auto; } /* 临æç级æ ç¾æ ·å¼ */ .expire-level { padding: 2px 8px; border-radius: 4px; font-size: 12px; font-weight: 500; } .expire-level.expired { background-color: #fff2f0; color: #ff4d4f; border: 1px solid #ffccc7; } .expire-level.urgent { background-color: #fff7e6; color: #fa8c16; border: 1px solid #ffd591; } .expire-level.warning { background-color: #f6ffed; color: #52c41a; border: 1px solid #b7eb8f; } .expire-level.normal { background-color: #e6f7ff; color: #1890ff; border: 1px solid #91d5ff; } .expire-level.low { background-color: #f0f2f5; color: #666666; border: 1px solid #d9d9d9; } .expire-level.default { background-color: #fafafa; color: #8c8c8c; border: 1px solid #e8e8e8; } /* å·²è¿ææåçº¢è² */ .text-red { color: #ff4d4f; font-weight: 500; } .chart-title, .table-title { @@ -814,7 +955,6 @@ position: relative; letter-spacing: 0.5px; } .view-btn { font-size: 12px; @@ -1090,10 +1230,7 @@ animation: pulse 2.8s infinite; } .btn-group { margin-left: 10px; } /* ç§»é¤åæçel-card__bodyæ ·å¼ç©¿éï¼å ä¸ºå·²ç»æ¿æ¢ä¸ºçº¯div */ </style> ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/BigGreenService/BigGreenService.cs
@@ -58,7 +58,7 @@ //计ç®åºä½å©ç¨ç var freeLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.Free).Count(); var inStockLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus == (int)LocationStatusEnum.InStock || x.LocationStatus == (int)LocationStatusEnum.Pallet).Count(); var inStockLocation = _locationInfoRepository.Db.Queryable<Dt_LocationInfo>().Where(x => x.LocationStatus != (int)LocationStatusEnum.Free).Count(); int totalLocation = freeLocation + inStockLocation; decimal locationUtilizationRate = totalLocation == 0 ? 0 @@ -75,7 +75,7 @@ // 4. è·åè¿7æ¥æ¯æ¥åºå ¥åºæç»ï¼æ ¸å¿ä¿®æ¹ï¼è°ç¨ä¸é¢çæ¹æ³ï¼ var dailyInOutBoundList = Get7DaysDailyInOutBound(); var nearExpirationList = GetMaterialsNearExpiration(); List<StockInfoDetailExtDTO> nearExpirationList = GetMaterialsNearExpiration(); //è·åä½ä¸ç»è®¡ var completeTask = SimpleStatistics(); //ä»»å¡ @@ -239,7 +239,7 @@ public List<SimpleStatisticsDTO> CompleteTask { get; set; } public NearExpirationDTO NearExpirationList { get; set; } public List<StockInfoDetailExtDTO> NearExpirationList { get; set; } } /// <summary> @@ -270,82 +270,70 @@ public int Count { get; set; } } public class NearExpirationDTO public class StockInfoDetailExtDTO : Dt_StockInfoDetail { public int DaysToExpiration { get; set; } public List<Dt_StockInfoDetail> Details { get; set; } public string LocationCode { get; set; } public string PalletCode { get; set; } public int DaysToExpiration { get; set; } } ///<summary> ///è·åè¿30天è¦è¿æçç©æ /// </summary> public NearExpirationDTO GetMaterialsNearExpiration() public List<StockInfoDetailExtDTO> GetMaterialsNearExpiration() { // åå§åè¿åDTO var resultDTO = new NearExpirationDTO List<StockInfoDetailExtDTO> resultDTO = new List<StockInfoDetailExtDTO>(); var nearExpirationList = _stockInfoDetailRepository.QueryData() .Join( _stockInfoRepository.QueryData(), detail => detail.StockId, stock => stock.Id, (detail, stock) => new { Details = new List<Dt_StockInfoDetail>(), LocationCode = string.Empty, PalletCode = string.Empty, DaysToExpiration = 0 // åå§åå¤©æ° }; DateTime currentTime = DateTime.Now; DateTime thirtyDaysLater = currentTime.AddDays(30); // çé30天å è¿æçåºåæç» var nearExpirationList = _stockInfoDetailRepository.Db.Queryable<Dt_StockInfoDetail>() .Where(x => (x.ValidDate.Value - x.CreateDate).TotalDays <= 30) Detail = detail, LocationCode = stock.LocationCode, PalletCode = stock.PalletCode } ) .Where(x => x.Detail.ValidDate.HasValue && (x.Detail.ValidDate.Value - x.Detail.CreateDate).TotalDays <= 30) .ToList(); // æ ç¬¦åæ¡ä»¶çæç»ï¼ç´æ¥è¿å if (!nearExpirationList.Any()) { return resultDTO; } var firstStockId = nearExpirationList.First().StockId; var stock = _stockInfoRepository.Db.Queryable<Dt_StockInfo>() .First(x => x.Id == firstStockId); if (stock == null) foreach (var item in nearExpirationList) { return resultDTO; int daysToExpire = item.Detail.ValidDate.HasValue ? Math.Max(0, (item.Detail.ValidDate.Value - item.Detail.CreateDate).Days) : 0; var extDetail = new StockInfoDetailExtDTO { MaterielCode = item.Detail.MaterielCode, MaterielName = item.Detail.MaterielName, BatchNo = item.Detail.BatchNo, SupplyCode = item.Detail.SupplyCode, StockQuantity = item.Detail.StockQuantity, CreateDate = item.Detail.CreateDate, ValidDate = item.Detail.ValidDate, LocationCode = item.LocationCode, PalletCode = item.PalletCode, Barcode = item.Detail.Barcode, DaysToExpiration = daysToExpire }; resultDTO.Add(extDetail); } resultDTO.LocationCode = stock.LocationCode; resultDTO.PalletCode = stock.PalletCode; int minDaysToExpiration = int.MaxValue; foreach (var detail in nearExpirationList) { TimeSpan totalDaysToExpiration = detail.ValidDate.Value - detail.CreateDate; double remainingDays = totalDaysToExpiration.TotalDays; int daysToExpiration = (int)Math.Ceiling(Math.Max(0, remainingDays)); if (daysToExpiration < minDaysToExpiration) { minDaysToExpiration = daysToExpiration; } resultDTO.Details.Add(detail); } resultDTO.DaysToExpiration = minDaysToExpiration; resultDTO = resultDTO.OrderBy(d => d.DaysToExpiration).ToList(); return resultDTO; } ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IInboundService/IInboundOrderService.cs
@@ -28,6 +28,6 @@ WebResponseContent UnPalletGroupBarcode(string orderNo); WebResponseContent HandCloseOrder(List<int> orderIds); WebResponseContent HandCloseOrder(List<string> orderIds); } } ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs
@@ -47,9 +47,10 @@ private readonly IRepository<Dt_StockInfo> _stockRepository; private readonly IRepository<Dt_LocationInfo> _locationInfoRepository; private readonly IBasicService _basicService; private readonly IRepository<Dt_AllocateOrder> _allocateOrderRepository; public IRepository<Dt_InboundOrder> Repository => BaseDal; public InboundOrderService(IRepository<Dt_InboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IStockService stockService, IInboundOrderDetailService inboundOrderDetailService, IMaterialUnitService materialUnitService, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_StockInfo> stockRepository, IRepository<Dt_LocationType> locationTypeRepository, IMaterielInfoService materielInfoService, IBasicService basicService, IRepository<Dt_LocationInfo> locationInfoRepository) : base(BaseDal) public InboundOrderService(IRepository<Dt_InboundOrder> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_Task> taskRepository, IStockService stockService, IInboundOrderDetailService inboundOrderDetailService, IMaterialUnitService materialUnitService, IRepository<Dt_StockInfoDetail> stockDetailRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IRepository<Dt_WarehouseArea> warehouseAreaRepository, IRepository<Dt_StockInfo> stockRepository, IRepository<Dt_LocationType> locationTypeRepository, IMaterielInfoService materielInfoService, IBasicService basicService, IRepository<Dt_LocationInfo> locationInfoRepository, IRepository<Dt_AllocateOrder> allocateOrderRepository) : base(BaseDal) { _mapper = mapper; _unitOfWorkManage = unitOfWorkManage; @@ -66,6 +67,7 @@ _materielInfoService = materielInfoService; _basicService = basicService; _locationInfoRepository = locationInfoRepository; _allocateOrderRepository = allocateOrderRepository; } public async Task<WebResponseContent> ReceiveInboundOrder(List<Dt_InboundOrder> models, int operateType) @@ -968,13 +970,17 @@ return content.OK(data: details); } public WebResponseContent HandCloseOrder(List<int> orderIds) public WebResponseContent HandCloseOrder(List<string> orderNos) { try { foreach (int id in orderIds) foreach (var orderNo in orderNos) { var inbound = _inboundOrderRepository.QueryFirst(x => x.Id == id); var inbound = _inboundOrderRepository.QueryFirst(x => x.InboundOrderNo == orderNo); if(inbound == null) { return WebResponseContent.Instance.Error($"è¯¥åæ®ä¸åå¨ï¼æ æ³è¿è¡å ³é"); } if(inbound.OrderStatus !=(int)InOrderStatusEnum.æªå¼å§ && inbound.OrderStatus != (int)InOrderStatusEnum.å ¥åºä¸) { return WebResponseContent.Instance.Error($"è¯¥åæ®ç¶æä¸å¯ä»¥å ³é"); ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs
@@ -260,7 +260,7 @@ [HttpPost, Route("HandCloseOrder"), AllowAnonymous, MethodParamsValidate] public WebResponseContent HandCloseOrder(List<int> orderIds) public WebResponseContent HandCloseOrder(List<string> orderIds) { return Service.HandCloseOrder(orderIds); } ÏîÄ¿×ÊÁÏ/½Ó¿ÚÎĵµ/~$es½Ó¿ÚÎĵµ.docxBinary files differ