|
@@ -16,13 +16,20 @@ import com.haha.common.constant.CommonConstants;
|
|
|
import com.haha.common.constant.SyncConstants;
|
|
import com.haha.common.constant.SyncConstants;
|
|
|
import com.haha.common.exception.BusinessException;
|
|
import com.haha.common.exception.BusinessException;
|
|
|
import com.haha.common.utils.EntityLabelUtils;
|
|
import com.haha.common.utils.EntityLabelUtils;
|
|
|
|
|
+import com.haha.entity.DeviceInventory;
|
|
|
|
|
+import com.haha.entity.InventoryLog;
|
|
|
import com.haha.entity.LayerTemplate;
|
|
import com.haha.entity.LayerTemplate;
|
|
|
|
|
+import com.haha.entity.Product;
|
|
|
import com.haha.mapper.LayerTemplateMapper;
|
|
import com.haha.mapper.LayerTemplateMapper;
|
|
|
import com.haha.sdk.HahaClient;
|
|
import com.haha.sdk.HahaClient;
|
|
|
import com.haha.sdk.api.GoodsApi;
|
|
import com.haha.sdk.api.GoodsApi;
|
|
|
|
|
+import com.haha.service.DeviceInventoryService;
|
|
|
|
|
+import com.haha.service.InventoryLogService;
|
|
|
import com.haha.service.LayerTemplateService;
|
|
import com.haha.service.LayerTemplateService;
|
|
|
|
|
+import com.haha.service.ProductService;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
@@ -48,6 +55,12 @@ public class LayerTemplateServiceImpl extends ServiceImpl<LayerTemplateMapper, L
|
|
|
private final HahaClient hahaClient;
|
|
private final HahaClient hahaClient;
|
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private DeviceInventoryService deviceInventoryService;
|
|
|
|
|
+
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private ProductService productService;
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 分页查询层模版列表
|
|
* 分页查询层模版列表
|
|
|
* 支持按设备ID、同步状态、模板名称进行筛选
|
|
* 支持按设备ID、同步状态、模板名称进行筛选
|
|
@@ -319,7 +332,14 @@ public class LayerTemplateServiceImpl extends ServiceImpl<LayerTemplateMapper, L
|
|
|
log.info("更新层模版记录: deviceId={}", deviceId);
|
|
log.info("更新层模版记录: deviceId={}", deviceId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 步骤6: 更新同步状态为"已同步"并记录时间
|
|
|
|
|
|
|
+ // 步骤6: 从层模版数据初始化库存(仅对尚不存在的商品创建 stock=0 记录)
|
|
|
|
|
+ try {
|
|
|
|
|
+ initInventoryFromTemplate(deviceId, apiData);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("层模版同步后初始化库存失败: deviceId={}", deviceId, e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 步骤7: 更新同步状态为"已同步"并记录时间
|
|
|
updateSyncStatus(deviceId, SyncConstants.STATUS_SYNCED, LocalDateTime.now());
|
|
updateSyncStatus(deviceId, SyncConstants.STATUS_SYNCED, LocalDateTime.now());
|
|
|
|
|
|
|
|
log.info("层模版同步成功: deviceId={}", deviceId);
|
|
log.info("层模版同步成功: deviceId={}", deviceId);
|
|
@@ -905,4 +925,92 @@ public class LayerTemplateServiceImpl extends ServiceImpl<LayerTemplateMapper, L
|
|
|
}
|
|
}
|
|
|
return IMAGE_DOMAIN_PREFIX + picUrl;
|
|
return IMAGE_DOMAIN_PREFIX + picUrl;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从层模版API数据中提取商品编码,为不存在的商品创建库存记录(stock=0)
|
|
|
|
|
+ * 仅在库存记录不存在时创建,已存在的记录不受影响
|
|
|
|
|
+ */
|
|
|
|
|
+ private void initInventoryFromTemplate(String deviceId, Map<String, Object> apiData) {
|
|
|
|
|
+ // 提取所有商品编码
|
|
|
|
|
+ java.util.Set<String> productCodes = new java.util.HashSet<>();
|
|
|
|
|
+
|
|
|
|
|
+ if (apiData.containsKey("products")) {
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ Map<String, Object> products = (Map<String, Object>) apiData.get("products");
|
|
|
|
|
+ extractCodesFromFloors(products.get("left"), productCodes);
|
|
|
|
|
+ extractCodesFromFloors(products.get("right"), productCodes);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (productCodes.isEmpty()) {
|
|
|
|
|
+ log.info("层模版中无商品配置,跳过库存初始化: deviceId={}", deviceId);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("从层模版提取到 {} 个商品编码,开始初始化库存: deviceId={}", productCodes.size(), deviceId);
|
|
|
|
|
+ int created = 0;
|
|
|
|
|
+ int skipped = 0;
|
|
|
|
|
+
|
|
|
|
|
+ for (String code : productCodes) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ Product product = productService.getProductByCode(code);
|
|
|
|
|
+ if (product == null) {
|
|
|
|
|
+ log.debug("商品编码在本地库中不存在,跳过: code={}, deviceId={}", code, deviceId);
|
|
|
|
|
+ skipped++;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ DeviceInventory existing = deviceInventoryService.getByDeviceAndProduct(deviceId, product.getId());
|
|
|
|
|
+ if (existing != null) {
|
|
|
|
|
+ log.debug("库存记录已存在,跳过: deviceId={}, productCode={}", deviceId, code);
|
|
|
|
|
+ skipped++;
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ DeviceInventory inventory = new DeviceInventory();
|
|
|
|
|
+ inventory.setDeviceId(deviceId);
|
|
|
|
|
+ inventory.setProductId(product.getId());
|
|
|
|
|
+ inventory.setProductCode(code);
|
|
|
|
|
+ inventory.setProductName(product.getName());
|
|
|
|
|
+ inventory.setStock(0);
|
|
|
|
|
+ inventory.setWarningThreshold(5);
|
|
|
|
|
+ inventory.setCreateTime(LocalDateTime.now());
|
|
|
|
|
+ inventory.setUpdateTime(LocalDateTime.now());
|
|
|
|
|
+ deviceInventoryService.save(inventory);
|
|
|
|
|
+ created++;
|
|
|
|
|
+
|
|
|
|
|
+ log.info("初始化库存记录: deviceId={}, productCode={}, productName={}, stock=0",
|
|
|
|
|
+ deviceId, code, product.getName());
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.error("初始化单条库存记录失败: deviceId={}, productCode={}", deviceId, code, e);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ log.info("库存初始化完成: deviceId={}, 创建={}, 跳过={}", deviceId, created, skipped);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 从层数据(left/right floors)中提取商品编码
|
|
|
|
|
+ */
|
|
|
|
|
+ private void extractCodesFromFloors(Object floorsObj, java.util.Set<String> codeSet) {
|
|
|
|
|
+ if (floorsObj == null) return;
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<FloorConfig> floors = objectMapper.convertValue(floorsObj,
|
|
|
|
|
+ new TypeReference<List<FloorConfig>>() {});
|
|
|
|
|
+
|
|
|
|
|
+ if (floors != null) {
|
|
|
|
|
+ for (FloorConfig floor : floors) {
|
|
|
|
|
+ if (floor.getGoods() != null) {
|
|
|
|
|
+ for (GoodsItem goods : floor.getGoods()) {
|
|
|
|
|
+ if (goods.getKey() != null && !goods.getKey().isEmpty()) {
|
|
|
|
|
+ codeSet.add(goods.getKey());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("解析层商品数据失败: {}", e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|