diff --git a/src/main/java/com/ffii/fpsms/modules/master/service/WarehouseService.kt b/src/main/java/com/ffii/fpsms/modules/master/service/WarehouseService.kt index 89363a5..5a26401 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/service/WarehouseService.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/service/WarehouseService.kt @@ -120,6 +120,7 @@ open class WarehouseService( val sheet: Sheet = workbook.getSheetAt(0); // Columns + val COLUMN_REF_INDEX = 0; val COLUMN_WAREHOSE_INDEX = 1; val COLUMN_ZONE_INDEX = 2; val COLUMN_SLOT_INDEX = 3; @@ -131,12 +132,13 @@ open class WarehouseService( val START_ROW_INDEX = 5; - // 第一步:收集所有 Excel 数据(包含行索引,用于调试) + // first step: collect all Excel data (contains row index, for debugging) data class ExcelWarehouseDataWithRow( val rowIndex: Int, val warehouse: String, val area: String, - val slot: String + val slot: String, + val ref: String? ) val excelDataList = mutableListOf() @@ -150,6 +152,7 @@ open class WarehouseService( } try { + val ref = ExcelUtils.getStringValue(row.getCell(COLUMN_REF_INDEX))?.trim() val warehouse = ExcelUtils.getStringValue(row.getCell(COLUMN_WAREHOSE_INDEX))?.trim() val area = ExcelUtils.getStringValue(row.getCell(COLUMN_ZONE_INDEX))?.trim() val slot = ExcelUtils.getStringValue(row.getCell(COLUMN_SLOT_INDEX))?.trim() @@ -159,7 +162,7 @@ open class WarehouseService( continue } - excelDataList.add(ExcelWarehouseDataWithRow(i, warehouse, area, slot)) + excelDataList.add(ExcelWarehouseDataWithRow(i, warehouse, area, slot,ref)) } catch (e: Exception) { logger.error("Read Error (Row ${i + 1}): ${e.message}") skippedRows++ @@ -168,25 +171,26 @@ open class WarehouseService( logger.info("Total rows in Excel: ${sheet.lastRowNum - START_ROW_INDEX + 1}, Valid rows collected: ${excelDataList.size}, Skipped: $skippedRows") - // 第二步:计算 order 映射(使用 ExcelWarehouseData) - val excelDataForOrder = excelDataList.map { - ExcelWarehouseData(it.warehouse, it.area, it.slot) + // second step: calculate order map (using ExcelWarehouseData) + val excelDataForOrder = excelDataList.map { + ExcelWarehouseData(it.warehouse, it.area, it.slot, it.ref ?: "${it.rowIndex}") // 如果 ref 为空,使用 rowIndex } val orderMap = calculateOrderMap(excelDataForOrder) logger.info("Order map size: ${orderMap.size}") - // 第三步:在循环中使用 orderMap 匹配 + // third step: use orderMap to match in the loop var updateCount = 0 var createCount = 0 var skippedInSecondLoop = 0 - val processedKeys = mutableSetOf() + // val processedKeys = mutableSetOf() for (i in START_ROW_INDEX.. + // calculate order map: receive Excel data list, return Map private fun calculateOrderMap(excelDataList: List): Map { data class WarehouseWithSort( - val data: ExcelWarehouseData, - val sortValue: Long, - val uniqueKey: String + val ref: String, // ref as unique identifier + val warehouse: String, + val area: String, + val slot: String, + val sortValue: Long ) - + + val sortedWarehouses = excelDataList.map { data -> val slot = data.slot.toIntOrNull() ?: 0 val sortValue = calculateSortValue(data.warehouse, data.area, slot) - val uniqueKey = "${data.warehouse}-${data.area}-${data.slot}" - WarehouseWithSort(data, sortValue, uniqueKey) - }.sortedBy { it.sortValue } - - // 分配连续的 order(1, 2, 3...),类似 ROW_NUMBER() + // use ref as unique identifier (ref is stored in rowIndex field) + val ref = data.rowIndex + WarehouseWithSort(ref, data.warehouse, data.area, data.slot, sortValue) + }.sortedBy { it.sortValue } // sort by sortValue + + // assign consecutive order (1, 2, 3...), return Map return sortedWarehouses.mapIndexed { index, warehouseWithSort -> - warehouseWithSort.uniqueKey to (index + 1) // 唯一标识 -> order + warehouseWithSort.ref to (index + 1) // ref -> order }.toMap() } - // 计算单个仓库的排序值(与 MySQL 逻辑一致) + + // calculate sort value for a single warehouse (consistent with MySQL logic) private fun calculateSortValue(warehouseStr: String, areaStr: String, slot: Int): Long { - // 提取楼层号 + // extract floor number val floorNumber = if (warehouseStr.length >= 2) { warehouseStr.substring(1, 2).toIntOrNull() ?: 99 } else 99 - // 提取字母部分 + // extract letter part val letterPart = if (areaStr.startsWith("#") && areaStr.length >= 2) { areaStr.substring(1, 2) } else null - // 计算楼层排序值 + // calculate floor sort value val floorOrder = when (floorNumber) { 2 -> 1 3 -> 2 @@ -322,7 +325,7 @@ open class WarehouseService( else -> 99 } - // 计算字母排序值(与 MySQL 逻辑一致) + // calculate letter sort value (consistent with MySQL logic) val letterOrder = when { letterPart == null -> 9999 letterPart in listOf("C", "B", "A", "E", "F", "G", "H", "I", "N", "M", "L", "P", "Q", "R", "S", "Y", "O", "K", "D") -> { @@ -336,7 +339,7 @@ open class WarehouseService( else -> 1000 + letterPart[0].code } - // 计算总排序值:楼层 * 10000 + 字母 * 100 + slot + // calculate total sort value: floor * 10000 + letter * 100 + slot return floorOrder * 10000L + letterOrder * 100L + slot } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveWarehouseRequest.kt b/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveWarehouseRequest.kt index 39872ea..6db8353 100644 --- a/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveWarehouseRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/master/web/models/SaveWarehouseRequest.kt @@ -28,5 +28,6 @@ data class NewWarehouseRequest( data class ExcelWarehouseData( val warehouse: String, val area: String, - val slot: String + val slot: String, + val rowIndex: String )