| | |
| | | <template> |
| | | <vol-box v-model="show" :title="'ç»çæä½ - åæ®å·ï¼' + orderNo" :height="1000" :width="1100" :padding="20" :modal="true"> |
| | | <vol-box |
| | | v-model="show" |
| | | :title="'ç»çæä½ - åæ®å·ï¼' + orderNo" |
| | | :height="1000" |
| | | :width="1100" |
| | | :padding="20" |
| | | :modal="true" |
| | | > |
| | | <div class="barcode-scanner-container"> |
| | | |
| | | <!-- ä»åºéæ© - ç´§åå¸å± --> |
| | | <div class="location-section compact"> |
| | | <el-form :model="form" :rules="rules" ref="locationForm" class="compact-form"> |
| | | <el-form-item label="å
¥åºä»åº" prop="warehouseType" class="location-select compact-item"> |
| | | <el-select v-model="form.warehouseType" placeholder="è¯·éæ©ä»åº" clearable filterable |
| | | @change="handleWarehouseChange" style="width: 100%" :loading="warehouseLoading" size="medium"> |
| | | <el-option v-for="item in warehouseTypes" :key="item.warehouseType" :label="item.warehouseTypeDesc" |
| | | :value="item.warehouseType" /> |
| | | <el-form |
| | | :model="form" |
| | | :rules="rules" |
| | | ref="locationForm" |
| | | class="compact-form" |
| | | > |
| | | <el-form-item |
| | | label="å
¥åºä»åº" |
| | | prop="warehouseType" |
| | | class="location-select compact-item" |
| | | > |
| | | <el-select |
| | | v-model="form.warehouseType" |
| | | placeholder="è¯·éæ©ä»åº" |
| | | clearable |
| | | filterable |
| | | @change="handleWarehouseChange" |
| | | style="width: 100%" |
| | | :loading="warehouseLoading" |
| | | size="medium" |
| | | > |
| | | <el-option |
| | | v-for="item in warehouseTypes" |
| | | :key="item.warehouseType" |
| | | :label="item.warehouseTypeDesc" |
| | | :value="item.warehouseType" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | |
| | | <!-- ä»åºåºåéæ© - ç´§åå¸å± --> |
| | | <div class="location-section compact"> |
| | | <el-form :model="form" :rules="rules" ref="locationForm" class="compact-form"> |
| | | <el-form-item label="ä»åºåºå" prop="locationType" class="location-select compact-item"> |
| | | <el-select v-model="form.locationType" placeholder="请å
éæ©ä»åº" clearable filterable |
| | | @change="handleLocationChange" style="width: 100%" :loading="locationLoading" size="medium"> |
| | | <el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc" |
| | | :value="item.locationType" /> |
| | | <el-form |
| | | :model="form" |
| | | :rules="rules" |
| | | ref="locationForm" |
| | | class="compact-form" |
| | | > |
| | | <el-form-item |
| | | label="ä»åºåºå" |
| | | prop="locationType" |
| | | class="location-select compact-item" |
| | | > |
| | | <el-select |
| | | v-model="form.locationType" |
| | | placeholder="请å
éæ©ä»åº" |
| | | clearable |
| | | filterable |
| | | @change="handleLocationChange" |
| | | style="width: 100%" |
| | | :loading="locationLoading" |
| | | size="medium" |
| | | > |
| | | <el-option |
| | | v-for="item in locationTypes" |
| | | :key="item.locationType" |
| | | :label="item.locationTypeDesc" |
| | | :value="item.locationType" |
| | | /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-form> |
| | |
| | | <span><i class="el-icon-scanner"></i> æ«ç åºå</span> |
| | | <span class="scan-status"> |
| | | <span class="scan-indicator"></span> |
| | | {{ form.locationType && form.warehouseType ? 'æ«ç 就绪' : '请å
éæ©ä»åºåä»åºåºå' }} |
| | | {{ |
| | | form.locationType && form.warehouseType |
| | | ? "æ«ç 就绪" |
| | | : "请å
éæ©ä»åºåä»åºåºå" |
| | | }} |
| | | </span> |
| | | </div> |
| | | |
| | | <!-- æçæ¡ç è¾å
¥ --> |
| | | <div class="input-wrapper custom-input-group compact-input"> |
| | | <div class="input-label">æçæ¡ç </div> |
| | | <el-input ref="trayInput" v-model="trayBarcode" placeholder="è¯·æ«ææè¾å
¥æç®±ç åæå车é®" clearable |
| | | :disabled="!form.locationType || !form.warehouseType" @keyup.enter.native="handleTraySubmit" |
| | | @clear="handleTrayClear" @input="handleTrayInput" class="custom-input" size="medium"> |
| | | <el-input |
| | | ref="trayInput" |
| | | v-model="trayBarcode" |
| | | placeholder="è¯·æ«ææè¾å
¥æç®±ç åæå车é®" |
| | | clearable |
| | | :disabled="!form.locationType || !form.warehouseType" |
| | | @keyup.enter.native="handleTraySubmit" |
| | | @clear="handleTrayClear" |
| | | @input="handleTrayInput" |
| | | class="custom-input" |
| | | size="medium" |
| | | > |
| | | <template slot="append"> |
| | | <el-button @click="handleTraySubmit" type="primary" icon="el-icon-position" |
| | | :disabled="!form.locationType || !trayBarcode || !form.warehouseType" size="medium"> |
| | | <el-button |
| | | @click="handleTraySubmit" |
| | | type="primary" |
| | | icon="el-icon-position" |
| | | :disabled=" |
| | | !form.locationType || !trayBarcode || !form.warehouseType |
| | | " |
| | | size="medium" |
| | | > |
| | | 确认 |
| | | </el-button> |
| | | </template> |
| | |
| | | <!-- ç©ææ¡ç è¾å
¥ --> |
| | | <div class="input-wrapper custom-input-group compact-input"> |
| | | <div class="input-label">ç©ææ¡ç </div> |
| | | <el-input ref="barcodeInput" v-model="barcode" placeholder="è¯·æ«ææè¾å
¥ç©ææ¡ç åæå车é®" clearable |
| | | :disabled="!form.locationType || !trayBarcode || !form.warehouseType" |
| | | @keyup.enter.native="debounceHandleBarcodeSubmit" @clear="handleClear" @input="handleBarcodeInput" |
| | | class="custom-input" size="medium"> |
| | | <el-input |
| | | ref="barcodeInput" |
| | | v-model="barcode" |
| | | placeholder="è¯·æ«ææè¾å
¥ç©ææ¡ç åæå车é®" |
| | | clearable |
| | | :disabled=" |
| | | !form.locationType || !trayBarcode || !form.warehouseType |
| | | " |
| | | @keyup.enter.native="debounceHandleBarcodeSubmit" |
| | | @clear="handleClear" |
| | | @input="handleBarcodeInput" |
| | | class="custom-input" |
| | | size="medium" |
| | | > |
| | | <template slot="append"> |
| | | <el-button :loading="loading" @click="debounceHandleBarcodeSubmit" type="primary" icon="el-icon-search" |
| | | :disabled="!form.locationType || !trayBarcode || !barcode || !form.warehouseType" size="medium"> |
| | | {{ loading ? 'æ¥è¯¢ä¸...' : 'æ¥è¯¢' }} |
| | | <el-button |
| | | :loading="loading" |
| | | @click="debounceHandleBarcodeSubmit" |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | :disabled=" |
| | | !form.locationType || |
| | | !trayBarcode || |
| | | !barcode || |
| | | !form.warehouseType |
| | | " |
| | | size="medium" |
| | | > |
| | | {{ loading ? "æ¥è¯¢ä¸..." : "æ¥è¯¢" }} |
| | | </el-button> |
| | | </template> |
| | | </el-input> |
| | |
| | | |
| | | <div class="input-tips compact-tips"> |
| | | <p>æç¤ºï¼è¯·å
éæ©ä»åº â éæ©ä»åºåºå â è¾å
¥æç®±ç â è¾å
¥ç©ææ¡ç </p> |
| | | <p v-if="!form.warehouseType" class="warning-text">â ï¸ è¯·å
éæ©ä»åº</p> |
| | | <p v-if="form.warehouseType && !form.locationType" class="warning-text">â ï¸ è¯·å
éæ©ä»åºåºå</p> |
| | | <p v-if="form.warehouseType && form.locationType && !trayBarcode" class="warning-text">â ï¸ è¯·å
è¾å
¥æç®±ç </p> |
| | | <p v-if="!form.warehouseType" class="warning-text"> |
| | | â ï¸ è¯·å
éæ©ä»åº |
| | | </p> |
| | | <p |
| | | v-if="form.warehouseType && !form.locationType" |
| | | class="warning-text" |
| | | > |
| | | â ï¸ è¯·å
éæ©ä»åºåºå |
| | | </p> |
| | | <p |
| | | v-if="form.warehouseType && form.locationType && !trayBarcode" |
| | | class="warning-text" |
| | | > |
| | | â ï¸ è¯·å
è¾å
¥æç®±ç |
| | | </p> |
| | | </div> |
| | | |
| | | </el-card> |
| | | </div> |
| | | |
| | |
| | | |
| | | <!-- é误æç¤º --> |
| | | <div v-if="error" class="error-message compact"> |
| | | <el-alert :title="error" type="error" show-icon closable @close="error = ''" /> |
| | | <el-alert |
| | | :title="error" |
| | | type="error" |
| | | show-icon |
| | | closable |
| | | @close="error = ''" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- æªç»çå表 --> |
| | |
| | | <div slot="header" class="compact-header"> |
| | | <span><i class="el-icon-tickets"></i> æªç»çæ¡ç </span> |
| | | <span class="list-actions"> |
| | | <el-tag type="primary" size="small">æªç»ç {{ totalStockCount }}</el-tag> |
| | | <el-tag type="primary" size="small" |
| | | >æªç»ç {{ totalStockCount }}</el-tag |
| | | > |
| | | </span> |
| | | </div> |
| | | |
| | | <div class="table-container"> |
| | | <el-table :data="unpalletMaterials" stripe style="width: 100%" height="100%" size="small" |
| | | v-loading="unpalletBarcodesLoading"> |
| | | <el-table-column type="index" label="åºå·" width="60" align="center"></el-table-column> |
| | | <el-table-column prop="barcode" label="æ¡ç " min-width="140" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="materielCode" label="ç©æç¼ç " min-width="150" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="batchNo" label="æ¹æ¬¡" min-width="150" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="orderQuantity" label="æ°é" min-width="130" align="right"></el-table-column> |
| | | <el-table-column prop="unit" label="åä½" width="80" align="center"></el-table-column> |
| | | <el-table-column prop="supplyCode" label="ä¾åºå" min-width="130" show-overflow-tooltip></el-table-column> |
| | | <el-table |
| | | :data="unpalletMaterials" |
| | | stripe |
| | | style="width: 100%" |
| | | height="100%" |
| | | size="small" |
| | | v-loading="unpalletBarcodesLoading" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="åºå·" |
| | | width="60" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="barcode" |
| | | label="æ¡ç " |
| | | min-width="140" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="materielCode" |
| | | label="ç©æç¼ç " |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="batchNo" |
| | | label="æ¹æ¬¡" |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="orderQuantity" |
| | | label="æ°é" |
| | | min-width="130" |
| | | align="right" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="unit" |
| | | label="åä½" |
| | | width="80" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="supplyCode" |
| | | label="ä¾åºå" |
| | | min-width="130" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-card> |
| | | |
| | | </div> |
| | | |
| | | <!-- ç©æå表 - åºå®é«åº¦å¸¦æ»å¨æ¡ --> |
| | |
| | | <div slot="header" class="compact-header"> |
| | | <span><i class="el-icon-tickets"></i> ç»çæ°æ®</span> |
| | | <span class="list-actions"> |
| | | <el-tag type="primary" size="small">å
± {{ materials.length }} æ¡</el-tag> |
| | | <el-tag type="primary" size="small">æªå
¥åºæ°é {{ totalStockSum }}{{ uniqueUnit }}</el-tag> |
| | | <el-tag v-if="trayBarcode" type="success" size="small">æç: {{ trayBarcode }}</el-tag> |
| | | <el-tag v-if="form.warehouseType" type="info" size="small">ä»åº: {{ currentWarehouseName }}</el-tag> |
| | | <el-tag v-if="form.locationType" type="info" size="small">åºå: {{ currentLocationDesc }}</el-tag> |
| | | <el-tag type="primary" size="small" |
| | | >å
± {{ materials.length }} æ¡</el-tag |
| | | > |
| | | <el-tag type="primary" size="small" |
| | | >æªå
¥åºæ°é {{ totalStockSum }}{{ uniqueUnit }}</el-tag |
| | | > |
| | | <el-tag v-if="trayBarcode" type="success" size="small" |
| | | >æç: {{ trayBarcode }}</el-tag |
| | | > |
| | | <el-tag v-if="form.warehouseType" type="info" size="small" |
| | | >ä»åº: {{ currentWarehouseName }}</el-tag |
| | | > |
| | | <el-tag v-if="form.locationType" type="info" size="small" |
| | | >åºå: {{ currentLocationDesc }}</el-tag |
| | | > |
| | | </span> |
| | | </div> |
| | | |
| | | <div v-if="materials.length === 0" class="empty-state compact"> |
| | | <i class="el-icon-document"></i> |
| | | <p v-if="!form.warehouseType">请å
éæ©ä»åº</p> |
| | | <p v-if="form.warehouseType && !form.locationType">请å
éæ©ä»åºåºå</p> |
| | | <p v-if="form.warehouseType && !form.locationType"> |
| | | 请å
éæ©ä»åºåºå |
| | | </p> |
| | | <p v-else-if="!trayBarcode">请å
è¾å
¥æç®±æ¡ç </p> |
| | | <p v-else>ææ ç©ææ°æ®ï¼è¯·æ«ææè¾å
¥ç©ææ¡ç </p> |
| | | </div> |
| | | |
| | | <div class="table-container" v-else> |
| | | <el-table :data="materials" stripe style="width: 100%" height="100%" size="small"> |
| | | <el-table-column type="index" label="åºå·" width="60" align="center"></el-table-column> |
| | | <el-table-column prop="barcode" label="æ¡ç " min-width="140" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="materielCode" label="ç©æç¼ç " min-width="150" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="batchNo" label="æ¹æ¬¡" min-width="150" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="stockQuantity" label="æ°é" min-width="130" align="right"></el-table-column> |
| | | <el-table-column prop="unit" label="åä½" width="80" align="center"></el-table-column> |
| | | <el-table-column prop="supplyCode" label="ä¾åºå" min-width="130" show-overflow-tooltip></el-table-column> |
| | | <el-table-column prop="warehouseType" label="ä»åº" min-width="120" show-overflow-tooltip></el-table-column> |
| | | <el-table |
| | | :data="materials" |
| | | stripe |
| | | style="width: 100%" |
| | | height="100%" |
| | | size="small" |
| | | > |
| | | <el-table-column |
| | | type="index" |
| | | label="åºå·" |
| | | width="60" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="barcode" |
| | | label="æ¡ç " |
| | | min-width="140" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="materielCode" |
| | | label="ç©æç¼ç " |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="batchNo" |
| | | label="æ¹æ¬¡" |
| | | min-width="150" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="stockQuantity" |
| | | label="æ°é" |
| | | min-width="130" |
| | | align="right" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="unit" |
| | | label="åä½" |
| | | width="80" |
| | | align="center" |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="supplyCode" |
| | | label="ä¾åºå" |
| | | min-width="130" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | <el-table-column |
| | | prop="warehouseType" |
| | | label="ä»åº" |
| | | min-width="120" |
| | | show-overflow-tooltip |
| | | ></el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-card> |
| | | </div> |
| | | </div> |
| | | <template #footer> |
| | | <el-button type="danger" size="small" @click="handleDialogClose()">å
³é</el-button> |
| | | <el-button type="danger" size="small" @click="handleDialogClose()" |
| | | >å
³é</el-button |
| | | > |
| | | </template> |
| | | </vol-box> |
| | | </template> |
| | | |
| | | <script> |
| | | import http from '@/api/http.js'; |
| | | import VolBox from '@/components/basic/VolBox.vue'; |
| | | import http from "@/api/http.js"; |
| | | import VolBox from "@/components/basic/VolBox.vue"; |
| | | |
| | | // 鲿彿° |
| | | function debounce(func, wait) { |
| | |
| | | orderNo: "", |
| | | palletVisible: this.visible, |
| | | trayBarcodeReg: /^[A-Z]\d{9}$/, |
| | | trayBarcode: '', |
| | | barcode: '', |
| | | trayBarcode: "", |
| | | barcode: "", |
| | | materials: [], |
| | | loading: false, |
| | | error: '', |
| | | error: "", |
| | | debugMode: false, |
| | | currentFocus: 'warehouse', |
| | | currentFocus: "warehouse", |
| | | |
| | | unpalletBarcodes: [], |
| | | unpalletBarcodesLoading: false, |
| | | unpalletMaterials: [], |
| | | |
| | | scanCode: '', |
| | | scanCode: "", |
| | | lastKeyTime: null, |
| | | isManualInput: false, |
| | | isScanning: false, |
| | | scanTimer: null, |
| | | manualInputTimer: null, |
| | | scanTarget: 'tray', |
| | | scanTarget: "tray", |
| | | isSubmitting: false, |
| | | palletGroupedBarcodes: {}, |
| | | |
| | | // é³é¢é
ç½® |
| | | audioConfig: { |
| | | successPath: '/assets/audio/success.mp3', // å¯¹åº public ä¸çè·¯å¾ |
| | | errorPath: '/assets/audio/error.mp3' |
| | | }, |
| | | successPath: require("@/assets/audio/success.mp3"), |
| | | errorPath: require("@/assets/audio/error.mp3"), |
| | | }, |
| | | // ç¼åé³é¢å®ä¾ï¼é¿å
éå¤å建 |
| | | successAudio: null, |
| | | errorAudio: null, |
| | | |
| | | totalStockSum: 0, |
| | | totalStockCount: 0, |
| | | uniqueUnit: '', |
| | | uniqueUnit: "", |
| | | sumLoading: false, |
| | | sumError: '', |
| | | sumError: "", |
| | | warehouseTypes: [], |
| | | warehouseLoading: false, |
| | | locationTypes: [], |
| | | locationLoading: false, |
| | | form: { |
| | | warehouseType: null, |
| | | locationType: null |
| | | locationType: null, |
| | | }, |
| | | rules: { |
| | | locationType: [ |
| | | { |
| | | validator: this.validateLocationType, |
| | | trigger: 'change' |
| | | } |
| | | trigger: "change", |
| | | }, |
| | | ], |
| | | trayBarcode: [ |
| | | { |
| | | pattern: this.trayBarcodeReg, |
| | | message: 'æçå·æ ¼å¼é误ï¼é为1个大å忝+9个æ°åï¼å¦A000008024ï¼', |
| | | trigger: 'blur' |
| | | } |
| | | message: "æçå·æ ¼å¼é误ï¼é为1个大å忝+9个æ°åï¼å¦A000008024ï¼", |
| | | trigger: "blur", |
| | | }, |
| | | ], |
| | | warehouseType: [ |
| | | { |
| | | message: 'è¯·éæ©ä»åº', |
| | | trigger: 'change' |
| | | } |
| | | ] |
| | | message: "è¯·éæ©ä»åº", |
| | | trigger: "change", |
| | | }, |
| | | ], |
| | | }, |
| | | |
| | | |
| | | // æ°å¢ï¼é®çäºä»¶ç嬿 è®° |
| | | keyPressListenerAdded: false, |
| | | isDialogClosing: false |
| | | } |
| | | isDialogClosing: false, |
| | | }; |
| | | }, |
| | | |
| | | computed: { |
| | | currentWarehouseName() { |
| | | const warehouse = this.warehouseTypes.find(item => item.warehouseType === this.form.warehouseType); |
| | | return warehouse ? warehouse.warehouseTypeDesc : ''; |
| | | const warehouse = this.warehouseTypes.find( |
| | | (item) => item.warehouseType === this.form.warehouseType |
| | | ); |
| | | return warehouse ? warehouse.warehouseTypeDesc : ""; |
| | | }, |
| | | |
| | | |
| | | currentLocationDesc() { |
| | | const location = this.locationTypes.find(item => item.locationType === this.form.locationType) |
| | | return location ? location.locationTypeDesc : '' |
| | | const location = this.locationTypes.find( |
| | | (item) => item.locationType === this.form.locationType |
| | | ); |
| | | return location ? location.locationTypeDesc : ""; |
| | | }, |
| | | |
| | | |
| | | debounceHandleBarcodeSubmit() { |
| | | return debounce(this.handleBarcodeSubmit, 500); |
| | | } |
| | | }, |
| | | }, |
| | | |
| | | |
| | | watch: { |
| | | // çå¬showåéåå |
| | | show(newVal) { |
| | | if (newVal === true) { |
| | | console.log('å¼¹æ¡æå¼ï¼éç½®æ°æ®'); |
| | | console.log("å¼¹æ¡æå¼ï¼éç½®æ°æ®"); |
| | | this.isDialogClosing = false; |
| | | this.resetData(); |
| | | this.$nextTick(() => { |
| | |
| | | }, 300); |
| | | }); |
| | | } else if (newVal === false && !this.isDialogClosing) { |
| | | console.log('å¼¹æ¡å
³éï¼ç§»é¤äºä»¶çå¬'); |
| | | console.log("å¼¹æ¡å
³éï¼ç§»é¤äºä»¶çå¬"); |
| | | this.isDialogClosing = true; |
| | | this.removeKeyPressListener(); // ç§»é¤é®çäºä»¶çå¬ |
| | | this.resetData(); |
| | | } |
| | | }, |
| | | |
| | | |
| | | visible(newVal, oldVal) { |
| | | this.palletVisible = newVal; |
| | | |
| | | if (newVal === true && oldVal === false) { |
| | | console.log('å¼¹æ¡æå¼ï¼éç½®æ°æ®'); |
| | | console.log("å¼¹æ¡æå¼ï¼éç½®æ°æ®"); |
| | | this.resetData(); |
| | | this.$nextTick(() => { |
| | | setTimeout(() => { |
| | |
| | | } |
| | | |
| | | if (newVal === false && oldVal === true) { |
| | | console.log('å¼¹æ¡å
³éï¼éç½®æ°æ®'); |
| | | console.log("å¼¹æ¡å
³éï¼éç½®æ°æ®"); |
| | | this.resetData(); |
| | | } |
| | | }, |
| | | |
| | | |
| | | palletVisible(newVal) { |
| | | this.$emit('update:visible', newVal); |
| | | this.$emit("update:visible", newVal); |
| | | }, |
| | | |
| | | |
| | | docNo(newVal) { |
| | | if (newVal) { |
| | | this.palletForm = { palletCode: '', barcode: '' }; |
| | | this.palletForm = { palletCode: "", barcode: "" }; |
| | | this.backData = []; |
| | | this.$refs.palletForm?.reset(); |
| | | this.fetchUnpalletMaterialDetails(); |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | |
| | | |
| | | mounted() { |
| | | // ä¸å¨mountedæ¶æ·»å çå¬ï¼å¨å¼¹çªæå¼æ¶æ·»å |
| | | }, |
| | | |
| | | |
| | | beforeDestroy() { |
| | | // ç¡®ä¿ç»ä»¶éæ¯æ¶ç§»é¤çå¬ |
| | | this.removeKeyPressListener(); |
| | | this.clearAllTimers(); |
| | | |
| | | this.removeKeyPressListener(); |
| | | this.clearAllTimers(); |
| | | |
| | | //鿝é³é¢å®ä¾ |
| | | this.removeKeyPressListener(); |
| | | this.clearAllTimers(); |
| | | |
| | | //鿝é³é¢å®ä¾ |
| | | this.successAudio = null; |
| | | this.errorAudio = null; |
| | | }, |
| | | |
| | | |
| | | methods: { |
| | | /** |
| | | * åå§åé³é¢å®ä¾ï¼æå è½½ï¼åªåå»ºä¸æ¬¡ï¼ |
| | | * @param {String} type - é³é¢ç±»åï¼success/error |
| | | * @returns {Audio} é³é¢å®ä¾ |
| | | */ |
| | | initAudioInstance(type) { |
| | | if (type === "success" && this.successAudio) { |
| | | return this.successAudio; |
| | | } |
| | | if (type === "error" && this.errorAudio) { |
| | | return this.errorAudio; |
| | | } |
| | | |
| | | const audioPath = |
| | | type === "success" |
| | | ? this.audioConfig.successPath |
| | | : this.audioConfig.errorPath; |
| | | |
| | | const audioInstance = new Audio(audioPath); |
| | | |
| | | // ç¼åé³é¢å®ä¾ |
| | | if (type === "success") { |
| | | this.successAudio = audioInstance; |
| | | } else { |
| | | this.errorAudio = audioInstance; |
| | | } |
| | | |
| | | // é³é¢å 载失败åè°ï¼å¯éï¼ç¨äºè°è¯ï¼ |
| | | audioInstance.onerror = (err) => { |
| | | console.error(`ã${type} é³é¢ãå 载失败`, err); |
| | | }; |
| | | |
| | | return audioInstance; |
| | | }, |
| | | |
| | | /** |
| | | * åå§åé³é¢å®ä¾ï¼æå è½½ï¼åªåå»ºä¸æ¬¡ï¼ |
| | | * @param {String} type - é³é¢ç±»åï¼success/error |
| | | * @returns {Audio} é³é¢å®ä¾ |
| | | */ |
| | | initAudioInstance(type) { |
| | | if (type === 'success' && this.successAudio) { |
| | | return this.successAudio; |
| | | } |
| | | if (type === 'error' && this.errorAudio) { |
| | | return this.errorAudio; |
| | | } |
| | | |
| | | const audioPath = type === 'success' |
| | | ? this.audioConfig.successPath |
| | | : this.audioConfig.errorPath; |
| | | |
| | | const audioInstance = new Audio(audioPath); |
| | | |
| | | // ç¼åé³é¢å®ä¾ |
| | | if (type === 'success') { |
| | | this.successAudio = audioInstance; |
| | | } else { |
| | | this.errorAudio = audioInstance; |
| | | } |
| | | |
| | | // é³é¢å 载失败åè°ï¼å¯éï¼ç¨äºè°è¯ï¼ |
| | | audioInstance.onerror = (err) => { |
| | | console.error(`ã${type} é³é¢ãå 载失败`, err); |
| | | }; |
| | | |
| | | return audioInstance; |
| | | }, |
| | | |
| | | /** |
| | | * ææ¾é³é¢ |
| | | * @param {String} type - é³é¢ç±»åï¼success/error |
| | | */ |
| | | playAudio(type) { |
| | | try { |
| | | const audioInstance = this.initAudioInstance(type); |
| | | |
| | | // éç½®ææ¾è¿åº¦ï¼é¿å
éå¤ææ¾æ¶é³é¢æªç»æï¼ |
| | | audioInstance.currentTime = 0; |
| | | |
| | | // ææ¾é³é¢ï¼è¿å Promise å¤çææ¾ç»æï¼å
¼å®¹é¨åæµè§å¨éå¶ï¼ |
| | | audioInstance.play().catch((err) => { |
| | | console.warn('é³é¢ææ¾å¤±è´¥ï¼å¯è½æ¯æµè§å¨èªå¨ææ¾çç¥éå¶ï¼', err); |
| | | }); |
| | | } catch (err) { |
| | | console.error('ææ¾é³é¢æ¶åçå¼å¸¸', err); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * ææ¾æåé³é¢ |
| | | */ |
| | | playSuccessAudio() { |
| | | this.playAudio('success'); |
| | | }, |
| | | |
| | | /** |
| | | * ææ¾å¤±è´¥é³é¢ |
| | | */ |
| | | playErrorAudio() { |
| | | this.playAudio('error'); |
| | | }, |
| | | * ææ¾é³é¢ |
| | | * @param {String} type - é³é¢ç±»åï¼success/error |
| | | */ |
| | | playAudio(type) { |
| | | try { |
| | | const audioInstance = this.initAudioInstance(type); |
| | | |
| | | // éç½®ææ¾è¿åº¦ï¼é¿å
éå¤ææ¾æ¶é³é¢æªç»æï¼ |
| | | audioInstance.currentTime = 0; |
| | | |
| | | // ææ¾é³é¢ï¼è¿å Promise å¤çææ¾ç»æï¼å
¼å®¹é¨åæµè§å¨éå¶ï¼ |
| | | audioInstance.play().catch((err) => { |
| | | console.warn("é³é¢ææ¾å¤±è´¥ï¼å¯è½æ¯æµè§å¨èªå¨ææ¾çç¥éå¶ï¼", err); |
| | | }); |
| | | } catch (err) { |
| | | console.error("ææ¾é³é¢æ¶åçå¼å¸¸", err); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * ææ¾æåé³é¢ |
| | | */ |
| | | playSuccessAudio() { |
| | | this.playAudio("success"); |
| | | }, |
| | | |
| | | /** |
| | | * ææ¾å¤±è´¥é³é¢ |
| | | */ |
| | | playErrorAudio() { |
| | | this.playAudio("error"); |
| | | }, |
| | | // æ·»å é®çäºä»¶çå¬ |
| | | addKeyPressListener() { |
| | | if (!this.keyPressListenerAdded) { |
| | | document.addEventListener('keypress', this.handleKeyPress); |
| | | document.addEventListener("keypress", this.handleKeyPress); |
| | | this.keyPressListenerAdded = true; |
| | | console.log('é®çäºä»¶çå¬å·²æ·»å '); |
| | | console.log("é®çäºä»¶çå¬å·²æ·»å "); |
| | | } |
| | | }, |
| | | |
| | | |
| | | // ç§»é¤é®çäºä»¶çå¬ |
| | | removeKeyPressListener() { |
| | | if (this.keyPressListenerAdded) { |
| | | document.removeEventListener('keypress', this.handleKeyPress); |
| | | document.removeEventListener("keypress", this.handleKeyPress); |
| | | this.keyPressListenerAdded = false; |
| | | console.log('é®çäºä»¶çå¬å·²ç§»é¤'); |
| | | console.log("é®çäºä»¶çå¬å·²ç§»é¤"); |
| | | } |
| | | }, |
| | | |
| | | |
| | | open() { |
| | | this.show = true; |
| | | this.orderNo = ""; |
| | |
| | | this.initLocationTypes(); |
| | | this.initwarehouseTypes(); |
| | | this.fetchUnpalletMaterialDetails(); |
| | | |
| | | |
| | | // å¼¹çªæå¼æ¶æ·»å é®çäºä»¶çå¬ |
| | | this.$nextTick(() => { |
| | | setTimeout(() => { |
| | |
| | | }, 100); |
| | | }); |
| | | }, |
| | | |
| | | |
| | | validateLocationType(rule, value, callback) { |
| | | if (!this.form.warehouseType) { |
| | | callback(new Error('请å
éæ©ä»åº')); |
| | | } else if (value === null || value === undefined || value === '') { |
| | | callback(new Error('è¯·éæ©ä»åºåºå')); |
| | | callback(new Error("请å
éæ©ä»åº")); |
| | | } else if (value === null || value === undefined || value === "") { |
| | | callback(new Error("è¯·éæ©ä»åºåºå")); |
| | | } else { |
| | | callback(); |
| | | } |
| | |
| | | // è·åæªç»çç©æè¯¦æ
|
| | | fetchUnpalletMaterialDetails() { |
| | | this.unpalletBarcodesLoading = true; |
| | | |
| | | http.post('/api/InboundOrder/UnPalletGroupBarcode?orderNo=' + this.orderNo, {}) |
| | | .then(response => { |
| | | |
| | | http |
| | | .post( |
| | | "/api/InboundOrder/UnPalletGroupBarcode?orderNo=" + this.orderNo, |
| | | {} |
| | | ) |
| | | .then((response) => { |
| | | if (response.status && Array.isArray(response.data)) { |
| | | this.unpalletMaterials = response.data; |
| | | this.unpalletBarcodes = response.data.map(item => item.barcode || ''); |
| | | this.unpalletBarcodes = response.data.map( |
| | | (item) => item.barcode || "" |
| | | ); |
| | | this.totalStockCount = response.data.length; |
| | | } else { |
| | | this.unpalletMaterials = []; |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error('è·åæªç»çç©æå¤±è´¥:', err); |
| | | this.unpalletMaterials = this.unpalletBarcodes.map(barcode => ({ |
| | | .catch((err) => { |
| | | console.error("è·åæªç»çç©æå¤±è´¥:", err); |
| | | this.unpalletMaterials = this.unpalletBarcodes.map((barcode) => ({ |
| | | barcode: barcode, |
| | | materielCode: '-', |
| | | batchNo: '-', |
| | | stockQuantity: '-', |
| | | unit: '-', |
| | | supplyCode: '-', |
| | | warehouseType: '-' |
| | | materielCode: "-", |
| | | batchNo: "-", |
| | | stockQuantity: "-", |
| | | unit: "-", |
| | | supplyCode: "-", |
| | | warehouseType: "-", |
| | | })); |
| | | }) |
| | | .finally(() => { |
| | | this.unpalletBarcodesLoading = false; |
| | | }); |
| | | }, |
| | | |
| | | |
| | | // åå§åä»åºåºåç±»å |
| | | initLocationTypes() { |
| | | this.locationLoading = true; |
| | | |
| | | this.http.post("api/LocationInfo/GetLocationTypes") |
| | | |
| | | this.http |
| | | .post("api/LocationInfo/GetLocationTypes") |
| | | .then(({ data }) => { |
| | | this.locationTypes = data; |
| | | }) |
| | | .catch(e => { |
| | | console.error('è·ååºåç±»å失败:', e); |
| | | this.$message.error('è·ååºåç±»å失败'); |
| | | .catch((e) => { |
| | | console.error("è·ååºåç±»å失败:", e); |
| | | this.$message.error("è·ååºåç±»å失败"); |
| | | }) |
| | | .finally(() => { |
| | | this.locationLoading = false; |
| | | }); |
| | | }, |
| | | |
| | | |
| | | // åå§åä»åºç±»å |
| | | initwarehouseTypes() { |
| | | this.warehouseLoading = true; |
| | | |
| | | this.http.post("api/Warehouse/GetwarehouseTypes") |
| | | |
| | | this.http |
| | | .post("api/Warehouse/GetwarehouseTypes") |
| | | .then(({ data }) => { |
| | | this.warehouseTypes = data; |
| | | }) |
| | | .catch(e => { |
| | | console.error('è·åä»åºç±»å失败:', e); |
| | | this.$message.error('è·åä»åºç±»å失败'); |
| | | .catch((e) => { |
| | | console.error("è·åä»åºç±»å失败:", e); |
| | | this.$message.error("è·åä»åºç±»å失败"); |
| | | }) |
| | | .finally(() => { |
| | | this.warehouseLoading = false; |
| | |
| | | // è·ååºåç»è®¡ |
| | | fetchStockStatistics(orderNo) { |
| | | if (!orderNo) { |
| | | this.sumError = 'åæ®å·ä¸ºç©ºï¼æ æ³ç»è®¡'; |
| | | this.sumError = "åæ®å·ä¸ºç©ºï¼æ æ³ç»è®¡"; |
| | | return Promise.resolve(null); |
| | | } |
| | | |
| | | this.sumLoading = true; |
| | | this.sumError = ''; |
| | | |
| | | return http.post('/api/InboundOrder/UnPalletQuantity?orderNo=' + orderNo, {}) |
| | | .then(response => { |
| | | this.sumError = ""; |
| | | |
| | | return http |
| | | .post("/api/InboundOrder/UnPalletQuantity?orderNo=" + orderNo, {}) |
| | | .then((response) => { |
| | | if (response.data) { |
| | | this.totalStockSum = response.data.stockSumQuantity || 0; |
| | | this.totalStockCount = response.data.stockCount || 0; |
| | | this.uniqueUnit = response.data.uniqueUnit || ''; |
| | | this.uniqueUnit = response.data.uniqueUnit || ""; |
| | | } |
| | | return response.data; |
| | | }) |
| | | .catch(err => { |
| | | console.error('ç»è®¡å 载失败:', err); |
| | | this.sumError = 'ç»è®¡å 载失败'; |
| | | .catch((err) => { |
| | | console.error("ç»è®¡å 载失败:", err); |
| | | this.sumError = "ç»è®¡å 载失败"; |
| | | this.totalStockSum = 0; |
| | | this.totalStockCount = 0; |
| | | throw err; |
| | |
| | | validateForm() { |
| | | return new Promise((resolve) => { |
| | | if (!this.$refs.locationForm) { |
| | | this.error = 'è¡¨åæªåå§å'; |
| | | this.$message.warning('请å
éæ©ä»åºåºå'); |
| | | this.error = "è¡¨åæªåå§å"; |
| | | this.$message.warning("请å
éæ©ä»åºåºå"); |
| | | resolve(false); |
| | | return; |
| | | } |
| | | |
| | | this.$refs.locationForm.validate((valid) => { |
| | | if (valid) { |
| | | this.error = ''; |
| | | this.error = ""; |
| | | resolve(true); |
| | | } else { |
| | | if (!this.form.warehouseType) { |
| | | this.error = '请å
éæ©ä»åº'; |
| | | this.error = "请å
éæ©ä»åº"; |
| | | } else if (!this.form.locationType) { |
| | | this.error = '请å
éæ©ä»åºåºå'; |
| | | this.error = "请å
éæ©ä»åºåºå"; |
| | | } else { |
| | | this.error = 'è¯·æ£æ¥è¡¨å填忝妿£ç¡®'; |
| | | this.error = "è¯·æ£æ¥è¡¨å填忝妿£ç¡®"; |
| | | } |
| | | resolve(false); |
| | | } |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | |
| | | focusTrayInput() { |
| | | if (this.$refs.trayInput && this.$refs.trayInput.$el) { |
| | | const inputEl = this.$refs.trayInput.$el.querySelector('input'); |
| | | const inputEl = this.$refs.trayInput.$el.querySelector("input"); |
| | | if (inputEl) { |
| | | inputEl.focus(); |
| | | this.currentFocus = 'tray'; |
| | | this.scanTarget = 'tray'; |
| | | this.currentFocus = "tray"; |
| | | this.scanTarget = "tray"; |
| | | inputEl.select(); |
| | | } |
| | | } |
| | |
| | | |
| | | focusBarcodeInput() { |
| | | if (this.$refs.barcodeInput && this.$refs.barcodeInput.$el) { |
| | | const inputEl = this.$refs.barcodeInput.$el.querySelector('input'); |
| | | const inputEl = this.$refs.barcodeInput.$el.querySelector("input"); |
| | | if (inputEl) { |
| | | inputEl.focus(); |
| | | this.currentFocus = 'material'; |
| | | this.scanTarget = 'material'; |
| | | this.currentFocus = "material"; |
| | | this.scanTarget = "material"; |
| | | inputEl.select(); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | |
| | | resetData() { |
| | | this.palletGroupedBarcodes = {}; |
| | | this.isSubmitting = false; |
| | | this.trayBarcode = ''; |
| | | this.barcode = ''; |
| | | this.trayBarcode = ""; |
| | | this.barcode = ""; |
| | | this.materials = []; |
| | | this.unpalletBarcodes = []; |
| | | this.unpalletMaterials = []; |
| | | this.loading = false; |
| | | this.error = ''; |
| | | this.scanCode = ''; |
| | | this.error = ""; |
| | | this.scanCode = ""; |
| | | this.lastKeyTime = null; |
| | | this.isManualInput = false; |
| | | this.isScanning = false; |
| | | this.currentFocus = 'warehouse'; |
| | | this.scanTarget = 'tray'; |
| | | this.currentFocus = "warehouse"; |
| | | this.scanTarget = "tray"; |
| | | this.clearAllTimers(); |
| | | this.totalStockSum = 0; |
| | | this.totalStockCount = 0; |
| | | this.sumLoading = false; |
| | | this.sumError = ''; |
| | | this.sumError = ""; |
| | | this.form = { |
| | | warehouseType: null, |
| | | locationType: null |
| | | locationType: null, |
| | | }; |
| | | this.warehouseTypes = []; |
| | | this.locationTypes = []; |
| | | |
| | | |
| | | this.$nextTick(() => { |
| | | if (this.$refs.locationForm) { |
| | | this.$refs.locationForm.clearValidate(); |
| | |
| | | this.scanTimer = null; |
| | | } |
| | | }, |
| | | |
| | | |
| | | handleDialogClose() { |
| | | // å
ç§»é¤é®çäºä»¶çå¬ |
| | | this.removeKeyPressListener(); |
| | |
| | | |
| | | // 确认æé® |
| | | handleConfirm() { |
| | | this.validateForm() |
| | | .then(valid => { |
| | | if (!valid) return; |
| | | |
| | | if (this.materials.length === 0) { |
| | | this.$message.warning('请è³å°æ·»å ä¸ä¸ªç©æ'); |
| | | return; |
| | | } |
| | | this.validateForm().then((valid) => { |
| | | if (!valid) return; |
| | | |
| | | if (!this.trayBarcode) { |
| | | this.$message.warning('请è¾å
¥æçæ¡ç '); |
| | | return; |
| | | } |
| | | if (this.materials.length === 0) { |
| | | this.$message.warning("请è³å°æ·»å ä¸ä¸ªç©æ"); |
| | | return; |
| | | } |
| | | |
| | | const result = { |
| | | warehouseType: this.form.warehouseType, |
| | | warehouseName: this.currentWarehouseName, |
| | | locationType: this.form.locationType, |
| | | locationDesc: this.currentLocationDesc, |
| | | trayBarcode: this.trayBarcode, |
| | | materials: this.materials, |
| | | docNo: this.docNo |
| | | }; |
| | | if (!this.trayBarcode) { |
| | | this.$message.warning("请è¾å
¥æçæ¡ç "); |
| | | return; |
| | | } |
| | | |
| | | this.$emit('back-success', result); |
| | | this.palletVisible = false; |
| | | }); |
| | | const result = { |
| | | warehouseType: this.form.warehouseType, |
| | | warehouseName: this.currentWarehouseName, |
| | | locationType: this.form.locationType, |
| | | locationDesc: this.currentLocationDesc, |
| | | trayBarcode: this.trayBarcode, |
| | | materials: this.materials, |
| | | docNo: this.docNo, |
| | | }; |
| | | |
| | | this.$emit("back-success", result); |
| | | this.palletVisible = false; |
| | | }); |
| | | }, |
| | | |
| | | |
| | | handleTrayInput() { |
| | | this.isManualInput = true; |
| | | this.isScanning = false; |
| | |
| | | |
| | | // å¤çæçæ¡ç æäº¤ |
| | | handleTraySubmit() { |
| | | this.barcode = ''; |
| | | this.barcode = ""; |
| | | this.materials = []; |
| | | this.error = ''; |
| | | this.error = ""; |
| | | |
| | | if (!this.form.warehouseType) { |
| | | this.error = '请å
éæ©ä»åº'; |
| | | this.error = "请å
éæ©ä»åº"; |
| | | return; |
| | | } |
| | | if (!this.form.locationType) { |
| | | this.error = '请å
éæ©ä»åºåºå'; |
| | | this.error = "请å
éæ©ä»åºåºå"; |
| | | return; |
| | | } |
| | | |
| | | this.validateForm() |
| | | .then(valid => { |
| | | if (!valid) return; |
| | | |
| | | const currentTrayBarcode = this.trayBarcode.trim(); |
| | | this.validateForm().then((valid) => { |
| | | if (!valid) return; |
| | | |
| | | if (!currentTrayBarcode) { |
| | | this.error = '请è¾å
¥ææ«ææçæ¡ç '; |
| | | return; |
| | | } |
| | | const currentTrayBarcode = this.trayBarcode.trim(); |
| | | |
| | | this.error = ''; |
| | | if (!currentTrayBarcode) { |
| | | this.error = "请è¾å
¥ææ«ææçæ¡ç "; |
| | | return; |
| | | } |
| | | |
| | | if (!this.trayBarcodeReg.test(currentTrayBarcode)) { |
| | | this.$message("æçå·æ ¼å¼é误"); |
| | | this.focusTrayInput(); |
| | | return; |
| | | } |
| | | this.error = ""; |
| | | |
| | | this.focusBarcodeInput(); |
| | | this.$message.success(`æçæ¡ç 已设置: ${currentTrayBarcode}`); |
| | | }); |
| | | if (!this.trayBarcodeReg.test(currentTrayBarcode)) { |
| | | this.$message("æçå·æ ¼å¼é误"); |
| | | this.focusTrayInput(); |
| | | return; |
| | | } |
| | | |
| | | this.focusBarcodeInput(); |
| | | this.$message.success(`æçæ¡ç 已设置: ${currentTrayBarcode}`); |
| | | }); |
| | | }, |
| | | |
| | | clearTray() { |
| | | this.trayBarcode = ''; |
| | | this.trayBarcode = ""; |
| | | this.materials = []; |
| | | this.focusTrayInput(); |
| | | this.$message({ |
| | | message: 'æçæ¡ç å·²æ¸
é¤', |
| | | type: 'info', |
| | | duration: 2000 |
| | | message: "æçæ¡ç å·²æ¸
é¤", |
| | | type: "info", |
| | | duration: 2000, |
| | | }); |
| | | }, |
| | | |
| | | handleTrayClear() { |
| | | this.error = ''; |
| | | this.error = ""; |
| | | }, |
| | | |
| | | handleClear() { |
| | | this.error = ''; |
| | | this.scanCode = ''; |
| | | this.error = ""; |
| | | this.scanCode = ""; |
| | | this.isManualInput = false; |
| | | this.isScanning = false; |
| | | }, |
| | |
| | | // å¤çç©ææ¡ç æäº¤ |
| | | handleBarcodeSubmit() { |
| | | if (this.isSubmitting) { |
| | | this.$message.warning('æ£å¨å¤çä¸ï¼è¯·ç¨å'); |
| | | this.$message.warning("æ£å¨å¤çä¸ï¼è¯·ç¨å"); |
| | | return; |
| | | } |
| | | |
| | | const currentBarcode = this.barcode.trim(); |
| | | const currentTrayGrouped = this.palletGroupedBarcodes[this.trayBarcode] || []; |
| | | |
| | | const currentTrayGrouped = |
| | | this.palletGroupedBarcodes[this.trayBarcode] || []; |
| | | |
| | | if (currentTrayGrouped.includes(currentBarcode)) { |
| | | this.error = `æ¡ç ${currentBarcode} 已被å½åæçç»çï¼è¯·å¿é夿ä½`; |
| | | this.barcode = ''; |
| | | this.barcode = ""; |
| | | this.focusBarcodeInput(); |
| | | this.playErrorAudio(); |
| | | return; |
| | | } |
| | | |
| | | this.isSubmitting = true; |
| | | |
| | | |
| | | this.validateForm() |
| | | .then(valid => { |
| | | .then((valid) => { |
| | | if (!valid) { |
| | | this.isSubmitting = false; |
| | | this.playErrorAudio(); |
| | | return; |
| | | } |
| | | |
| | | |
| | | if (!this.trayBarcode) { |
| | | this.error = '请å
è¾å
¥æçæ¡ç '; |
| | | this.error = "请å
è¾å
¥æçæ¡ç "; |
| | | this.focusTrayInput(); |
| | | this.isSubmitting = false; |
| | | return; |
| | | } |
| | | |
| | | if (!currentBarcode) { |
| | | this.error = '请è¾å
¥ææ«æç©ææ¡ç '; |
| | | this.error = "请è¾å
¥ææ«æç©ææ¡ç "; |
| | | this.isSubmitting = false; |
| | | return; |
| | | } |
| | | |
| | | this.focusBarcodeInput(); |
| | | this.error = ''; |
| | | this.error = ""; |
| | | this.loading = true; |
| | | |
| | | console.log('ç»ç请æ±åæ°:', { |
| | | console.log("ç»ç请æ±åæ°:", { |
| | | palletCode: this.trayBarcode, |
| | | barcode: currentBarcode, |
| | | locationTypeDesc: this.currentLocationDesc, |
| | | locationType: this.form.locationType, |
| | | warehouseType: this.form.warehouseType |
| | | warehouseType: this.form.warehouseType, |
| | | }); |
| | | |
| | | return this.fetchMaterialData(currentBarcode); |
| | | }) |
| | | .then(materialData => { |
| | | .then((materialData) => { |
| | | if (!materialData || materialData.length === 0) { |
| | | return; |
| | | } |
| | | |
| | | this.materials = []; |
| | | const newBarcodes = []; |
| | | |
| | | materialData.forEach(item => { |
| | | |
| | | materialData.forEach((item) => { |
| | | this.materials.push({ |
| | | ...item, |
| | | trayCode: this.trayBarcode, |
| | | locationType: this.form.locationType, |
| | | locationDesc: this.currentLocationDesc, |
| | | scanTime: this.formatTime(new Date()) |
| | | scanTime: this.formatTime(new Date()), |
| | | }); |
| | | newBarcodes.push(item.barcode); |
| | | }); |
| | |
| | | if (!this.palletGroupedBarcodes[this.trayBarcode]) { |
| | | this.palletGroupedBarcodes[this.trayBarcode] = []; |
| | | } |
| | | this.palletGroupedBarcodes[this.trayBarcode] = [...new Set([...this.palletGroupedBarcodes[this.trayBarcode], ...newBarcodes])]; |
| | | this.palletGroupedBarcodes[this.trayBarcode] = [ |
| | | ...new Set([ |
| | | ...this.palletGroupedBarcodes[this.trayBarcode], |
| | | ...newBarcodes, |
| | | ]), |
| | | ]; |
| | | |
| | | this.orderNo = materialData[0].orderNo; |
| | | |
| | | |
| | | return Promise.all([ |
| | | this.fetchStockStatistics(materialData[0].orderNo), |
| | | this.fetchUnpalletMaterialDetails() |
| | | this.fetchUnpalletMaterialDetails(), |
| | | ]); |
| | | }) |
| | | .then(() => { |
| | | this.barcode = ''; |
| | | this.scanCode = ''; |
| | | this.barcode = ""; |
| | | this.scanCode = ""; |
| | | this.isScanning = false; |
| | | |
| | | this.playSuccessAudio(); |
| | | |
| | | setTimeout(() => { |
| | | this.focusBarcodeInput(); |
| | | }, 100); |
| | | }) |
| | | .catch(err => { |
| | | console.error('å¤çç©ææ¡ç 失败:', err); |
| | | this.error = err.message || 'æ¥è¯¢æ¡ç ä¿¡æ¯å¤±è´¥ï¼è¯·éè¯'; |
| | | .catch((err) => { |
| | | console.error("å¤çç©ææ¡ç 失败:", err); |
| | | this.error = err.message || "æ¥è¯¢æ¡ç ä¿¡æ¯å¤±è´¥ï¼è¯·éè¯"; |
| | | this.focusBarcodeInput(); |
| | | setTimeout(() => { |
| | | const inputEl = this.$refs.barcodeInput?.$el?.querySelector('input'); |
| | | const inputEl = |
| | | this.$refs.barcodeInput?.$el?.querySelector("input"); |
| | | if (inputEl) inputEl.select(); |
| | | }, 100); |
| | | }) |
| | |
| | | |
| | | // APIè¯·æ± |
| | | fetchMaterialData(barcode) { |
| | | return http.post('/api/Inbound/GroupPallet', { |
| | | palletCode: this.trayBarcode, |
| | | barcode: barcode, |
| | | locationTypeDesc: this.currentLocationDesc, |
| | | locationType: this.form.locationType, |
| | | warehouseType: this.form.warehouseType |
| | | }) |
| | | .then(response => { |
| | | return http |
| | | .post("/api/Inbound/GroupPallet", { |
| | | palletCode: this.trayBarcode, |
| | | barcode: barcode, |
| | | locationTypeDesc: this.currentLocationDesc, |
| | | locationType: this.form.locationType, |
| | | warehouseType: this.form.warehouseType, |
| | | }) |
| | | .then((response) => { |
| | | let materialData; |
| | | |
| | | if (typeof response.data === 'string') { |
| | | |
| | | if (typeof response.data === "string") { |
| | | try { |
| | | materialData = JSON.parse(response.data); |
| | | } catch (e) { |
| | | console.error('è§£æååºæ°æ®å¤±è´¥:', e); |
| | | console.error("è§£æååºæ°æ®å¤±è´¥:", e); |
| | | this.playErrorAudio(); // è§£æå¤±è´¥ææ¾éè¯¯é³ |
| | | throw new Error("ååºæ°æ®æ ¼å¼é误"); |
| | | } |
| | | } else { |
| | | materialData = response.data; |
| | | } |
| | | |
| | | |
| | | if (!response.status) { |
| | | this.error = response.message || 'æ¥è¯¢æ¡ç ä¿¡æ¯å¤±è´¥ï¼è¯·éè¯'; |
| | | this.error = response.message || "æ¥è¯¢æ¡ç ä¿¡æ¯å¤±è´¥ï¼è¯·éè¯"; |
| | | this.playErrorAudio(); // æ¥å£è¿åå¤±è´¥ææ¾éè¯¯é³ |
| | | return []; |
| | | } |
| | | |
| | | |
| | | this.playSuccessAudio(); // æ¥å£è¿åæåææ¾æåé³ |
| | | return materialData || []; |
| | | }) |
| | | .catch(error => { |
| | | console.error('APIè°ç¨å¤±è´¥:', error); |
| | | this.$message.error('æ¥å£è¯·æ±å¤±è´¥ï¼è¯·è系管çå'); |
| | | .catch((error) => { |
| | | console.error("APIè°ç¨å¤±è´¥:", error); |
| | | this.$message.error("æ¥å£è¯·æ±å¤±è´¥ï¼è¯·è系管çå"); |
| | | this.playErrorAudio(); // 请æ±å¼å¸¸ææ¾éè¯¯é³ |
| | | throw error; |
| | | }); |
| | | }, |
| | |
| | | if (!this.show || this.isDialogClosing) { |
| | | return; |
| | | } |
| | | |
| | | |
| | | if (this.isManualInput || this.isSubmitting) { |
| | | return; |
| | | } |
| | |
| | | const key = event.key; |
| | | const currentTime = new Date().getTime(); |
| | | |
| | | if (key === 'Enter') { |
| | | if (key === "Enter") { |
| | | event.preventDefault(); |
| | | if (this.scanCode.length > 0) { |
| | | if (this.scanTarget === 'material' && !this.trayBarcode) { |
| | | this.$message.warning('请å
设置æçæ¡ç '); |
| | | this.scanCode = ''; |
| | | if (this.scanTarget === "material" && !this.trayBarcode) { |
| | | this.$message.warning("请å
设置æçæ¡ç "); |
| | | this.scanCode = ""; |
| | | this.lastKeyTime = null; |
| | | return; |
| | | } |
| | | |
| | | this.isScanning = false; |
| | | |
| | | if (this.scanTarget === 'tray') { |
| | | if (this.scanTarget === "tray") { |
| | | this.trayBarcode = this.scanCode; |
| | | this.handleTraySubmit(); |
| | | } else if (this.scanTarget === 'material') { |
| | | } else if (this.scanTarget === "material") { |
| | | this.barcode = this.scanCode; |
| | | this.handleBarcodeSubmit(); |
| | | } |
| | | } |
| | | this.scanCode = ''; |
| | | this.scanCode = ""; |
| | | this.lastKeyTime = null; |
| | | return; |
| | | } |
| | |
| | | // æ ¼å¼åæ¶é´ |
| | | formatTime(date) { |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, '0'); |
| | | const day = String(date.getDate()).padStart(2, '0'); |
| | | const hours = String(date.getHours()).padStart(2, '0'); |
| | | const minutes = String(date.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(date.getSeconds()).padStart(2, '0'); |
| | | const month = String(date.getMonth() + 1).padStart(2, "0"); |
| | | const day = String(date.getDate()).padStart(2, "0"); |
| | | const hours = String(date.getHours()).padStart(2, "0"); |
| | | const minutes = String(date.getMinutes()).padStart(2, "0"); |
| | | const seconds = String(date.getSeconds()).padStart(2, "0"); |
| | | |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | }, |
| | |
| | | // ä»åºåæ¢äºä»¶ |
| | | handleWarehouseChange() { |
| | | this.form.locationType = null; |
| | | this.trayBarcode = ''; |
| | | this.barcode = ''; |
| | | this.trayBarcode = ""; |
| | | this.barcode = ""; |
| | | this.materials = []; |
| | | this.error = ''; |
| | | this.error = ""; |
| | | }, |
| | | |
| | | // åºå忢äºä»¶ |
| | | handleLocationChange() { |
| | | this.trayBarcode = ''; |
| | | this.barcode = ''; |
| | | this.trayBarcode = ""; |
| | | this.barcode = ""; |
| | | this.materials = []; |
| | | this.error = ''; |
| | | } |
| | | } |
| | | } |
| | | this.error = ""; |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .compact-card>>>.el-card__body { |
| | | .compact-card >>> .el-card__body { |
| | | padding: 12px; |
| | | } |
| | | |
| | |
| | | padding: 0 !important; |
| | | } |
| | | |
| | | .compact-header>>>.el-card__header { |
| | | .compact-header >>> .el-card__header { |
| | | padding: 8px 12px; |
| | | } |
| | | |
| | |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .location-section.compact>>>.el-form-item { |
| | | .location-section.compact >>> .el-form-item { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .material-list.compact>>>.el-card { |
| | | .material-list.compact >>> .el-card { |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100%; |
| | | } |
| | | |
| | | .material-list.compact>>>.el-card__body { |
| | | .material-list.compact >>> .el-card__body { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .material-list.compact>>>.el-table { |
| | | .material-list.compact >>> .el-table { |
| | | flex: 1; |
| | | } |
| | | |
| | | .material-list.compact>>>.el-table__body-wrapper { |
| | | .material-list.compact >>> .el-table__body-wrapper { |
| | | overflow-y: auto; |
| | | } |
| | | |
| | |
| | | |
| | | .scan-status { |
| | | font-size: 12px; |
| | | color: #67C23A; |
| | | color: #67c23a; |
| | | } |
| | | |
| | | .scan-indicator { |
| | |
| | | width: 8px; |
| | | height: 8px; |
| | | border-radius: 50%; |
| | | background-color: #67C23A; |
| | | background-color: #67c23a; |
| | | margin-right: 5px; |
| | | animation: pulse 1.5s infinite; |
| | | } |
| | |
| | | } |
| | | |
| | | .warning-text { |
| | | color: #E6A23C; |
| | | color: #e6a23c; |
| | | font-weight: bold; |
| | | } |
| | | |
| | |
| | | |
| | | .loading.compact p { |
| | | margin-top: 5px; |
| | | color: #409EFF; |
| | | color: #409eff; |
| | | font-size: 12px; |
| | | } |
| | | |
| | |
| | | margin: 5px 0; |
| | | } |
| | | |
| | | .error-message.compact>>>.el-alert { |
| | | .error-message.compact >>> .el-alert { |
| | | padding: 6px 12px; |
| | | } |
| | | |
| | |
| | | gap: 4px; |
| | | } |
| | | |
| | | .list-actions>>>.el-tag { |
| | | .list-actions >>> .el-tag { |
| | | height: 24px; |
| | | line-height: 22px; |
| | | padding: 0 6px; |
| | |
| | | } |
| | | |
| | | .material-code { |
| | | font-family: 'Courier New', monospace; |
| | | font-family: "Courier New", monospace; |
| | | font-weight: bold; |
| | | color: #409EFF; |
| | | color: #409eff; |
| | | } |
| | | |
| | | .location-info { |
| | |
| | | align-items: center; |
| | | width: 100%; |
| | | margin: 8px 0; |
| | | border: 1px solid #DCDFE6; |
| | | border: 1px solid #dcdfe6; |
| | | border-radius: 4px; |
| | | overflow: hidden; |
| | | background: #fff; |
| | |
| | | |
| | | .input-label { |
| | | padding: 0 12px; |
| | | background: #F5F7FA; |
| | | border-right: 1px solid #DCDFE6; |
| | | background: #f5f7fa; |
| | | border-right: 1px solid #dcdfe6; |
| | | color: #606266; |
| | | font-size: 13px; |
| | | white-space: nowrap; |
| | |
| | | flex: 1; |
| | | } |
| | | |
| | | .custom-input>>>.el-input__inner { |
| | | .custom-input >>> .el-input__inner { |
| | | border: none; |
| | | border-radius: 0; |
| | | height: 36px; |
| | |
| | | .input-label { |
| | | width: 100%; |
| | | border-right: none; |
| | | border-bottom: 1px solid #DCDFE6; |
| | | border-bottom: 1px solid #dcdfe6; |
| | | margin-bottom: 5px; |
| | | } |
| | | |
| | | .input-container { |
| | | width: 100%; |
| | | border: 1px solid #DCDFE6; |
| | | border: 1px solid #dcdfe6; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .unpallet-barcode-list>>>.el-tag { |
| | | .unpallet-barcode-list >>> .el-tag { |
| | | cursor: pointer; |
| | | max-width: calc(33.333% - 4px); |
| | | overflow: hidden; |
| | |
| | | } |
| | | |
| | | @media (max-width: 768px) { |
| | | .unpallet-barcode-list>>>.el-tag { |
| | | .unpallet-barcode-list >>> .el-tag { |
| | | max-width: calc(50% - 4px); |
| | | } |
| | | } |