| | |
| | | > |
| | | <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-select> |
| | | </el-form-item> |
| | | </el-form> |
| | | </div> |
| | | |
| | | <!-- ä»åºåºåéæ© - ç´§åå¸å± --> |
| | | <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="è¯·éæ©ä»åºåºå" |
| | | placeholder="请å
éæ©ä»åº" |
| | | clearable |
| | | filterable |
| | | @change="handleLocationChange" |
| | |
| | | <!-- æçä¿¡æ¯æ¾ç¤º - ç´§åå¸å± --> |
| | | <div class="tray-info compact" v-if="trayBarcode"> |
| | | <i class="el-icon-s-management"></i> å½åæç®±: {{ trayBarcode }} |
| | | <span class="location-info" v-if="form.warehouseType"> |
| | | | ä»åº: {{ currentWarehouseName }} |
| | | </span> |
| | | <span class="location-info" v-if="form.locationType"> |
| | | | ä»åºåºå: {{ currentLocationDesc }} |
| | | </span> |
| | |
| | | <span><i class="el-icon-scanner"></i> æ«ç åºå</span> |
| | | <span class="scan-status"> |
| | | <span class="scan-indicator"></span> |
| | | {{ form.locationType ? 'æ«ç 就绪' : '请å
éæ©ä»åºåºå' }} |
| | | {{ form.locationType && form.warehouseType ? 'æ«ç 就绪' : '请å
éæ©ä»åºåä»åºåºå' }} |
| | | </span> |
| | | </div> |
| | | |
| | |
| | | v-model="trayBarcode" |
| | | placeholder="è¯·æ«ææè¾å
¥æç®±ç åæå车é®" |
| | | clearable |
| | | :disabled="!form.locationType" |
| | | :disabled="!form.locationType || !form.warehouseType" |
| | | @keyup.enter.native="handleTraySubmit" |
| | | @clear="handleTrayClear" |
| | | @input="handleTrayInput" |
| | |
| | | @click="handleTraySubmit" |
| | | type="primary" |
| | | icon="el-icon-position" |
| | | :disabled="!form.locationType || !trayBarcode" |
| | | :disabled="!form.locationType || !trayBarcode || !form.warehouseType" |
| | | size="medium" |
| | | > |
| | | 确认 |
| | |
| | | v-model="barcode" |
| | | placeholder="è¯·æ«ææè¾å
¥ç©ææ¡ç åæå车é®" |
| | | clearable |
| | | :disabled="!form.locationType || !trayBarcode" |
| | | :disabled="!form.locationType || !trayBarcode || !form.warehouseType" |
| | | @keyup.enter.native="handleBarcodeSubmit" |
| | | @clear="handleClear" |
| | | @input="handleBarcodeInput" |
| | |
| | | @click="handleBarcodeSubmit" |
| | | type="primary" |
| | | icon="el-icon-search" |
| | | :disabled="!form.locationType || !trayBarcode || !barcode" |
| | | :disabled="!form.locationType || !trayBarcode || !barcode || !from.warehouseType" |
| | | size="medium" |
| | | > |
| | | {{ loading ? 'æ¥è¯¢ä¸...' : 'æ¥è¯¢' }} |
| | |
| | | </div> |
| | | |
| | | <div class="input-tips compact-tips"> |
| | | <p>æç¤ºï¼è¯·å
éæ©ä»åºåºåï¼ç¶åè¾å
¥æç®±ç ï¼æåè¾å
¥ç©ææ¡ç </p> |
| | | <p v-if="!form.locationType" class="warning-text">â ï¸ è¯·å
éæ©ä»åºåºå</p> |
| | | <p v-if="form.locationType && !trayBarcode" class="warning-text">â ï¸ è¯·å
è¾å
¥æç®±ç </p> |
| | | <p>æç¤ºï¼è¯·å
éæ©ä»åº â éæ©ä»åºåºå â è¾å
¥æç®±ç â è¾å
¥ç©ææ¡ç </p> |
| | | <p v-if="!form.warehouseType" class="warning-text">â ï¸ è¯·å
éæ©ä»åº</p> |
| | | <p v-if="!form.locationType && !form.warehouseType" class="warning-text">â ï¸ è¯·å
éæ©ä»åºåºå</p> |
| | | <p v-if="form.warehouseType && form.locationType && !trayBarcode" class="warning-text">â ï¸ è¯·å
è¾å
¥æç®±ç </p> |
| | | </div> |
| | | |
| | | </el-card> |
| | |
| | | <el-tag type="primary" size="small">æªç»ç {{ totalStockCount }}</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.locationType">请å
éæ©ä»åºåºå</p> |
| | | <p v-else-if="!trayBarcode">请å
è¾å
¥æç®±æ¡ç </p> |
| | | <p v-else>ææ ç©ææ°æ®ï¼è¯·æ«ææè¾å
¥ç©ææ¡ç </p> |
| | |
| | | <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="warehouseCode" label="ä»åº" min-width="120" 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> |
| | |
| | | loading: false, |
| | | error: '', |
| | | debugMode: false, |
| | | currentFocus: 'tray', |
| | | currentFocus: 'warehouse', |
| | | |
| | | // æ«ç æªç¸å
³åé |
| | | scanCode: '', |
| | |
| | | uniqueUnit: '', |
| | | sumLoading: false, |
| | | sumError: '', |
| | | |
| | | // ä»åºç¸å
³åé |
| | | warehouseTypes: [], |
| | | warehouseLoading: false, |
| | | // ä»åºåºåç¸å
³åé |
| | | locationTypes: [], |
| | | locationLoading: false, |
| | | form: { |
| | | warehouseType: null, |
| | | locationType: null |
| | | }, |
| | | rules: { |
| | |
| | | validator: this.validateLocationType, |
| | | trigger: 'change' |
| | | } |
| | | ] |
| | | } |
| | | ], |
| | | warehouseType: [ |
| | | { |
| | | massage:'è¯·éæ©ä»åº', |
| | | trigger: 'change' |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | computed: { |
| | |
| | | set(newVal) { this.$emit('update:visible', newVal); } |
| | | }, |
| | | currentDocNo() { return this.docNo; }, |
| | | // å½åéæ©çä»åºåç§° |
| | | currentWarehouseName() { |
| | | 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) |
| | |
| | | this.$nextTick(() => { |
| | | setTimeout(() => { |
| | | // this.focusTrayInput(); |
| | | this.initLocationTypes(); // åå§åä»åºåºå |
| | | this.initwarehouseTypes(); // åå§åä»åº |
| | | this.initLocationTypes(); // åå§åä»åºåºå |
| | | this.fetchStockStatistics(); // å è½½ç»è®¡æ°æ® |
| | | }, 300); |
| | | }); |
| | |
| | | } |
| | | } |
| | | }, |
| | | 'form.warehouseType'(newVal) { |
| | | if (newVal) { |
| | | this.form.locationType = null; |
| | | } else { |
| | | this.locationTypes = []; |
| | | } |
| | | }, |
| | | |
| | | mounted() { |
| | | |
| | |
| | | */ |
| | | validateLocationType(rule, value, callback) { |
| | | // æ£æ¥å¼æ¯å¦ä¸ºnullãundefinedæç©ºå符串ï¼ä½å
许æ°å0 |
| | | if (value === null || value === undefined || value === '') { |
| | | if (!this.form.warehouseType) { |
| | | callback(new Error('请å
éæ©ä»åº')); |
| | | } else if (value === null || value === undefined || value === '') { |
| | | callback(new Error('è¯·éæ©ä»åºåºå')); |
| | | } else { |
| | | // å¼ä¸º0æå
¶ä»ææå¼é½éè¿éªè¯ |
| | | callback(); |
| | | } |
| | | }, |
| | |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * åå§åä»åºæ°æ® |
| | | */ |
| | | async initwarehouseTypes() { |
| | | this.warehouseLoading = true; |
| | | this.error = ''; |
| | | |
| | | try { |
| | | const response = await http.post('/api/Warehouse/GetwarehouseTypes'); |
| | | |
| | | if (response.status && Array.isArray(response.data)) { |
| | | this.warehouseTypes = response.data; |
| | | if (this.warehouseTypes.length === 0) { |
| | | this.error = 'æªè·åå°ä»åºæ°æ®'; |
| | | } else { |
| | | // 妿æé»è®¤åºåï¼å¯ä»¥å¨è¿é设置 |
| | | // this.form.locationType = this.locationTypes[0].locationType; |
| | | } |
| | | } else { |
| | | this.error = 'è·åä»åºæ°æ®å¤±è´¥'; |
| | | } |
| | | } catch (error) { |
| | | console.error('è·åä»åºå¤±è´¥:', error); |
| | | this.error = `è·åä»åºå¤±è´¥: ${error.message || 'ç½ç»é误'}`; |
| | | } finally { |
| | | this.warehouseLoading = false; |
| | | } |
| | | }, |
| | | |
| | | |
| | | /** |
| | | * ä»åºåºååæ´å¤ç |
| | | */ |
| | |
| | | if (!errorMsg && (value === 0 || value)) { |
| | | console.log('ä»åºåºåéªè¯éè¿:', value); |
| | | // åºåéæ©åï¼èªå¨èç¦å°æçè¾å
¥æ¡ |
| | | this.focusTrayInput(); |
| | | this.focusLocationSelect(); |
| | | } |
| | | }); |
| | | }, 100); |
| | | } |
| | | }); |
| | | }, |
| | | // æ°å¢ï¼æ¥è¯¢å端åºåç»è®¡æ°æ®ï¼è°ç¨ä¹åç SumQuantity æ¥å£ï¼ |
| | | |
| | | /** |
| | | * ä»åºåæ´å¤ç |
| | | */ |
| | | handleWarehouseChange(value) { |
| | | console.log('éæ©ä»åº:', value, 'ç±»å:', typeof value, this.currentWarehouseName); |
| | | |
| | | // ç«å³æ¸
é¤éè¯¯ä¿¡æ¯ |
| | | this.error = ''; |
| | | |
| | | // æå¨è§¦å表åéªè¯æ´æ° |
| | | this.$nextTick(() => { |
| | | if (this.$refs.locationForm) { |
| | | // æ¸
é¤è¯¥å段çéªè¯ç¶æï¼ç¶åéæ°éªè¯ |
| | | this.$refs.locationForm.clearValidate('warehouseType'); |
| | | |
| | | // çæå»¶è¿åéæ°éªè¯ï¼ç¡®ä¿DOMå·²æ´æ° |
| | | setTimeout(() => { |
| | | this.$refs.locationForm.validateField('warehouseType', (errorMsg) => { |
| | | if (!errorMsg && (value === 0 || value)) { |
| | | console.log('ä»åºéªè¯éè¿:', value); |
| | | this.focusLocationSelect(); |
| | | } |
| | | }); |
| | | }, 100); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | async fetchStockStatistics() { |
| | | // åæ®å·ä¸ºç©ºæ¶ä¸æ¥è¯¢ |
| | | if (!this.docNo) { |
| | |
| | | resolve(true); |
| | | } else { |
| | | // æå¨æ£æ¥locationTypeï¼æ£ç¡®å¤çå¼ä¸º0çæ
åµ |
| | | if (this.form.locationType === null || this.form.locationType === undefined || this.form.locationType === '') { |
| | | if(!this.from.warehouseType){ |
| | | this.error='请å
éæ©ä»åº'; |
| | | } |
| | | else if(this.form.locationType === null || this.form.locationType === undefined || this.form.locationType === '') { |
| | | this.error = '请å
éæ©ä»åºåºå'; |
| | | //this.$message.warning('请å
éæ©ä»åºåºå'); |
| | | } else { |
| | |
| | | }); |
| | | }); |
| | | }, |
| | | focusWarehouseSelect() { |
| | | if (this.$refs.locationForm) { |
| | | const selectEl = this.$el.querySelector('.location-select:first-child .el-input__inner'); |
| | | if (selectEl) { |
| | | selectEl.focus(); |
| | | this.currentFocus = 'warehouse'; |
| | | } |
| | | } |
| | | }, |
| | | // èç¦å°ä»åºåºåéæ© |
| | | focusLocationSelect() { |
| | | if (this.$refs.locationForm) { |
| | | const selectEl = this.$el.querySelector('.el-select .el-input__inner'); |
| | | const selectEl = this.$el.querySelector('.location-select:nth-child(2) .el-input__inner'); |
| | | if (selectEl) { |
| | | selectEl.focus(); |
| | | this.currentFocus = 'location'; |
| | |
| | | this.lastKeyTime = null; |
| | | this.isManualInput = false; |
| | | this.isScanning = false; |
| | | this.currentFocus = 'location'; |
| | | this.currentFocus = 'warehouse'; |
| | | this.scanTarget = 'tray'; |
| | | this.clearAllTimers(); |
| | | this.totalStockSum = 0; |
| | | this.totalStockCount = 0; |
| | | this.sumLoading = false; |
| | | this.sumError = ''; |
| | | this.form.locationType = null; |
| | | this.form={ |
| | | warehouseType:null, |
| | | locationType:null |
| | | } |
| | | this.warehouseTypes=[]; |
| | | this.locationTypes=[]; |
| | | // æ¸
é¤è¡¨åéªè¯ç¶æ |
| | | this.$nextTick(() => { |
| | | if (this.$refs.locationForm) { |
| | |
| | | // 使ç¨setTimeoutç¡®ä¿DOMå®å
¨æ¸²æååèç¦ |
| | | this.$nextTick(() => { |
| | | setTimeout(() => { |
| | | this.initwarehouseTypes(); |
| | | this.initLocationTypes(); // åå§åä»åºåºå |
| | | // ç¡®ä¿è¡¨åå¼ç¨åå¨ååèç¦ |
| | | if (this.$refs.locationForm) { |
| | | this.focusLocationSelect(); |
| | | this.focusWarehouseSelect(); |
| | | } else { |
| | | // å¦æè¡¨åå¼ç¨è¿ä¸åå¨ï¼ç¨åéè¯ |
| | | setTimeout(() => { |
| | | this.focusLocationSelect(); |
| | | this.focusWarehouseSelect(); |
| | | }, 500); |
| | | } |
| | | }, 300); |
| | |
| | | } |
| | | |
| | | const result = { |
| | | warehouseType:this.form.warehouseType, |
| | | warehouseName:this.currentWarehouseName, |
| | | locationType: this.form.locationType, |
| | | locationDesc: this.currentLocationDesc, |
| | | trayBarcode: this.trayBarcode, |
| | |
| | | // å¤çæçæ¡ç æäº¤ |
| | | async handleTraySubmit() { |
| | | // å
ç´æ¥æ£æ¥locationTypeï¼é¿å
表åéªè¯ç弿¥é®é¢ |
| | | if (!this.form.warehouseType) { |
| | | this.error = '请å
éæ©ä»åº'; |
| | | return; |
| | | } |
| | | if (!this.form.locationType) { |
| | | this.error = '请å
éæ©ä»åºåºå'; |
| | | //this.$message.warning('请å
éæ©ä»åºåºå'); |
| | |
| | | orderNo: this.docNo, |
| | | barcodes: barcode, |
| | | locationTypeDesc: this.currentLocationDesc, |
| | | locationType: this.form.locationType // æ·»å ä»åºåºåä¿¡æ¯ |
| | | locationType: this.form.locationType, // æ·»å ä»åºåºåä¿¡æ¯ |
| | | warehouseType:this.form.warehouseType |
| | | } |
| | | ); |
| | | |