diff --git a/youchain-system/src/main/java/com/youchain/basicdata/domain/Item.java b/youchain-system/src/main/java/com/youchain/basicdata/domain/Item.java index ecdcc38..5828f3d 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/domain/Item.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/domain/Item.java @@ -144,7 +144,7 @@ public class Item extends BaseEntity implements Serializable { private Long sourceId; @Column(name = "`extend_d1`") - @ApiModelProperty(value = "默认容器装载数") + @ApiModelProperty(value = "单台用量") private Double extendD1=0d; @Column(name = "`extend_d2`") diff --git a/youchain-system/src/main/java/com/youchain/basicdata/repository/ItemRepository.java b/youchain-system/src/main/java/com/youchain/basicdata/repository/ItemRepository.java index 60832c2..d86f0b2 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/repository/ItemRepository.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/repository/ItemRepository.java @@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Query; import java.util.List; +import java.util.Set; /** * @author houjianlan @@ -28,6 +29,9 @@ import java.util.List; * @date 2023-08-16 **/ public interface ItemRepository extends JpaRepository, JpaSpecificationExecutor { - @Query(value = "FROM Item i WHERE i.code = ?1 ") + @Query(value = "from Item i where i.code = :code ") Item findByItemCode(String code); + + @Query(value = "from Item i where i.code in :itemCodes ") + List findByCodes(Set itemCodes); } diff --git a/youchain-system/src/main/java/com/youchain/basicdata/rest/ItemController.java b/youchain-system/src/main/java/com/youchain/basicdata/rest/ItemController.java index 9b1cd6f..22dddb3 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/rest/ItemController.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/rest/ItemController.java @@ -1,18 +1,18 @@ /* -* Copyright 2019-2020 Zheng Jie -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ + * Copyright 2019-2020 Zheng Jie + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.youchain.basicdata.rest; import cn.hutool.poi.excel.BigExcelWriter; @@ -20,7 +20,9 @@ import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import com.youchain.annotation.AnonymousAccess; import com.youchain.annotation.Log; +import com.youchain.basicdata.domain.Area; import com.youchain.basicdata.domain.Item; +import com.youchain.basicdata.domain.Point; import com.youchain.basicdata.domain.StockType; import com.youchain.basicdata.service.ItemService; import com.youchain.basicdata.service.StockTypeService; @@ -28,15 +30,17 @@ import com.youchain.basicdata.service.dto.ItemDto; import com.youchain.basicdata.service.dto.ItemQueryCriteria; import com.youchain.basicdata.service.dto.StockTypeQueryCriteria; import com.youchain.config.FileProperties; +import com.youchain.config.thread.ThreadPoolExecutorUtil; import com.youchain.exception.handler.ApiError; +import com.youchain.exception.handler.ApiResult; +import com.youchain.modules.system.domain.Dept; import com.youchain.modules.system.domain.DictDetail; import com.youchain.modules.system.service.DictDetailService; import com.youchain.modules.system.service.DictService; import com.youchain.modules.system.service.dto.DictDetailDto; import com.youchain.modules.system.service.dto.DictDto; import com.youchain.modules.system.service.dto.DictQueryCriteria; -import com.youchain.utils.FileUtil; -import com.youchain.utils.UserUtils; +import com.youchain.utils.*; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Pageable; import lombok.RequiredArgsConstructor; @@ -50,18 +54,21 @@ import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; import javax.servlet.http.HttpServletResponse; import javax.transaction.Transactional; +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.OK; + /** -* @website https://eladmin.vip -* @author houjianlan -* @date 2023-08-16 -**/ + * @author houjianlan + * @website https://eladmin.vip + * @date 2023-08-16 + **/ @RestController @RequiredArgsConstructor @Api(tags = "item管理") @@ -71,8 +78,7 @@ public class ItemController { private final ItemService itemService; private final FileProperties properties; - private final StockTypeService stockTypeService; - private final DictDetailService dictDetailService; + @Log("导出数据") @ApiOperation("导出数据") @@ -84,13 +90,13 @@ public class ItemController { @GetMapping @ApiOperation("查询item") - public ResponseEntity queryItem(ItemQueryCriteria criteria, Pageable pageable){ - return new ResponseEntity<>(itemService.queryAll(criteria,pageable), HttpStatus.OK); + public ResponseEntity queryItem(ItemQueryCriteria criteria, Pageable pageable) { + return new ResponseEntity<>(itemService.queryAll(criteria, pageable), HttpStatus.OK); } @GetMapping("/itemList") @ApiOperation("查询所有的物料数据") - public ResponseEntity> queryItemList(ItemQueryCriteria criteria, Pageable pageable){ + public ResponseEntity> queryItemList(ItemQueryCriteria criteria, Pageable pageable) { return new ResponseEntity<>(itemService.queryAll(criteria), HttpStatus.OK); } @@ -99,79 +105,31 @@ public class ItemController { @Log("新增item") @ApiOperation("新增item") @PreAuthorize("@el.check('item:add')") - public ResponseEntity createItem(@Validated @RequestBody Item resources){ + public ResponseEntity createItem(@Validated @RequestBody Item resources) { resources.setDept(UserUtils.getDept()); - return new ResponseEntity<>(itemService.create(resources),HttpStatus.CREATED); + return new ResponseEntity<>(itemService.create(resources), HttpStatus.CREATED); } @PostMapping(value = "/import_data") + @Log("导入物料") @ApiOperation("导入物料") - @Transactional - @AnonymousAccess - public ResponseEntity createSysAppUpdate( @RequestParam("file") MultipartFile multipartFile) { - FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize()); - String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); - String type = FileUtil.getFileType(suffix); - log.error("--" + properties.getPath().getPath() + type + File.separator); - File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator); - log.error("--" + file.getPath()); - - Map map_stock = stockTypeService.queryAll(); - DictQueryCriteria dictQueryCriteria=new DictQueryCriteria(); - dictQueryCriteria.setBlurry("item_unit"); - Map map_dic = dictDetailService.getDictDetailByName("item_unit"); - DictQueryCriteria itemTypeDc=new DictQueryCriteria(); - itemTypeDc.setBlurry("item_type"); - Map item_type_dic = dictDetailService.getDictDetailByName("item_type"); - ExcelReader reader = ExcelUtil.getReader(file); - int i=0; - int edit_len=0; - int new_len=0; - try{ - List> readAll = reader.readAll(); - for ( i = 0; i < readAll.size(); i++) { - Item item = new Item(); - String code=readAll.get(i).get("物料代码").toString().trim(); - item.setCode(code); - item.setName("" + readAll.get(i).get("物料名称")); - //容器类型 - String unit=readAll.get(i).get("单位")+""; - item.setUnit(map_dic.get(unit).getValue()); - String packNumber=readAll.get(i).get("默认容器装载数").toString().trim(); - item.setPackNumber(Integer.parseInt(packNumber)); - String itemType=readAll.get(i).get("物料类型")+""; - item.setGoodType(item_type_dic.get(itemType).getValue()); - item.setLength(Double.parseDouble("" + readAll.get(i).get("长"))); - item.setWidth(Double.parseDouble("" + readAll.get(i).get("宽"))); - item.setHeight(Double.parseDouble("" + readAll.get(i).get("高"))); - ItemQueryCriteria itemQueryCriteria=new ItemQueryCriteria(); - itemQueryCriteria.setCode(code); - List itemDto_list=itemService.queryAll(itemQueryCriteria); - if(itemDto_list.size()<=0){ - new_len++; - log.error("不存在--" + readAll.get(i).get("编码")+"--"); - itemService.create(item); - }else{ - edit_len++; - log.error("存在--" + readAll.get(i).get("编码")+"--"); - item.setId(itemDto_list.get(0).getId()); - itemService.update(item); - } - } - }catch (Exception e){ - ApiError apiError = ApiError.errorJosn(HttpStatus.BAD_REQUEST.value(), "导入异常---第"+(i+1)+"行:"+e.toString()); - return new ResponseEntity(apiError, HttpStatus.valueOf(apiError.getStatus())); + @PreAuthorize("@el.check('point:importPoint')") + public ResponseEntity importItem(@RequestParam("file") MultipartFile multipartFile) { + //编码、名称、物料类型 + try { + String result = itemService.impoertItem(multipartFile); + return successRequest(result); + } catch (Exception e) { + return badRequest("导入失败:" + e.getMessage()); } - ApiError apiError = ApiError.errorJosn(HttpStatus.OK.value(), "导入成功:"+(i)+"行 新增("+new_len+")修改("+edit_len+")"); - return new ResponseEntity(apiError, HttpStatus.valueOf(apiError.getStatus())); - } + @PutMapping @Log("修改item") @ApiOperation("修改item") @PreAuthorize("@el.check('item:edit')") - public ResponseEntity updateItem(@Validated @RequestBody Item resources){ + public ResponseEntity updateItem(@Validated @RequestBody Item resources) { itemService.update(resources); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } @@ -184,4 +142,12 @@ public class ItemController { itemService.deleteAll(ids); return new ResponseEntity<>(HttpStatus.OK); } + + private ResponseEntity badRequest(String message) { + return new ResponseEntity<>(message, HttpStatus.BAD_REQUEST); + } + + private ResponseEntity successRequest(Object object) { + return new ResponseEntity<>(object, HttpStatus.OK); + } } diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/ItemService.java b/youchain-system/src/main/java/com/youchain/basicdata/service/ItemService.java index 9dde0b5..79380df 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/service/ItemService.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/service/ItemService.java @@ -28,26 +28,29 @@ import org.springframework.web.multipart.MultipartFile; import java.util.Map; import java.util.List; import java.io.IOException; +import java.util.Set; import javax.servlet.http.HttpServletResponse; /** + * @author houjianlan * @website https://eladmin.vip * @description 服务接口 - * @author houjianlan * @date 2023-08-07 **/ public interface ItemService { /** * 查询数据分页 + * * @param criteria 条件 * @param pageable 分页参数 - * @return Map + * @return Map */ - Map queryAll(ItemQueryCriteria criteria, Pageable pageable); + Map queryAll(ItemQueryCriteria criteria, Pageable pageable); /** * 查询所有数据不分页 + * * @param criteria 条件参数 * @return List */ @@ -55,6 +58,7 @@ public interface ItemService { /** * 根据ID查询 + * * @param id ID * @return ItemDto */ @@ -62,6 +66,7 @@ public interface ItemService { /** * 根据ID查询 + * * @param id ID * @return ItemDto */ @@ -71,45 +76,64 @@ public interface ItemService { /** * 创建 + * * @param resources / * @return ItemDto */ ItemDto create(Item resources); - /** * 编辑 + * * @param resources / */ void update(Item resources); /** * 多选删除 + * * @param ids / */ void deleteAll(Long[] ids); /** * 导出数据 - * @param all 待导出的数据 + * + * @param all 待导出的数据 * @param response / * @throws IOException / */ void download(List all, HttpServletResponse response) throws IOException; /** - *dto转实体 + * dto转实体 + * * @param itemDto * @return */ Item toEntity(ItemDto itemDto); /** - *查找物料是否存在 + * 查找物料是否存在 + * * @param itemCode * @return */ Item existItem(String itemCode); - -} \ No newline at end of file + + /** + * 根据物料编码查询物料信息 + * + * @param itemCodes + * @return + */ + Map findByCodes(Set itemCodes); + + /** + * 导入物料 + * @param multipartFile + */ + String impoertItem(MultipartFile multipartFile); + +} diff --git a/youchain-system/src/main/java/com/youchain/basicdata/service/impl/ItemServiceImpl.java b/youchain-system/src/main/java/com/youchain/basicdata/service/impl/ItemServiceImpl.java index ac5d796..4f073a5 100644 --- a/youchain-system/src/main/java/com/youchain/basicdata/service/impl/ItemServiceImpl.java +++ b/youchain-system/src/main/java/com/youchain/basicdata/service/impl/ItemServiceImpl.java @@ -15,13 +15,16 @@ */ package com.youchain.basicdata.service.impl; +import cn.hutool.poi.excel.ExcelReader; +import cn.hutool.poi.excel.ExcelUtil; +import com.youchain.basicdata.domain.Area; import com.youchain.basicdata.domain.Item; import com.youchain.basicdata.domain.Point; import com.youchain.basicdata.service.dto.ItemSmallDto; -import com.youchain.utils.FileUtil; -import com.youchain.utils.PageUtil; -import com.youchain.utils.QueryHelp; -import com.youchain.utils.ValidationUtil; +import com.youchain.config.FileProperties; +import com.youchain.config.thread.ThreadPoolExecutorUtil; +import com.youchain.modules.system.domain.Dept; +import com.youchain.utils.*; import lombok.RequiredArgsConstructor; import com.youchain.basicdata.repository.ItemRepository; import com.youchain.basicdata.service.ItemService; @@ -33,18 +36,17 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import java.util.List; -import java.util.Map; +import java.io.File; +import java.util.*; import java.io.IOException; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; import javax.persistence.EntityManager; import javax.persistence.Query; import javax.servlet.http.HttpServletResponse; -import java.util.ArrayList; -import java.util.LinkedHashMap; import org.springframework.data.domain.Example; - -import java.util.Optional; +import org.springframework.web.multipart.MultipartFile; /** * @author houjianlan @@ -59,6 +61,8 @@ public class ItemServiceImpl implements ItemService { private final ItemRepository itemRepository; private final ItemMapper itemMapper; private final EntityManager entityMapper; + private final FileProperties properties; + private final BatchCreateOrUpdate batchCreateOrUpdate; @Override public Map queryAll(ItemQueryCriteria criteria, Pageable pageable) { @@ -175,4 +179,95 @@ public class ItemServiceImpl implements ItemService { return item.isPresent() ? item.get() : null; } + @Override + public Map findByCodes(Set itemCodes) { + List items = itemRepository.findByCodes(itemCodes); + Map itemMap = new HashMap<>(); + for (Item item : items) { + itemMap.put(item.getCode(), item); + } + return itemMap; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public String impoertItem(MultipartFile multipartFile) { + //编码、名称、物料类型 + FileUtil.checkSize(properties.getMaxSize(), multipartFile.getSize()); + String suffix = FileUtil.getExtensionName(multipartFile.getOriginalFilename()); + String type = FileUtil.getFileType(suffix); + File file = FileUtil.upload(multipartFile, properties.getPath().getPath() + type + File.separator); + Dept dept = UserUtils.getDept(); + ExcelReader reader = ExcelUtil.getReader(file); + List> readAll = reader.readAll(); + Set itemCodes = new HashSet<>();//物料集合 + for (Map record : readAll) { + String itemCode = record.get("编码").toString().trim(); + if (!StringUtils.isEmpty(itemCode)) { + itemCodes.add(itemCode); + } + } + + + //获取已存在的物料 + Map existingPoint = findByCodes(itemCodes); + + + List itemsToCreate = new ArrayList<>();//新增物料集合 + List itemsToUpdate = new ArrayList<>();//修改物料集合 + for (Map record : readAll) { + String itemCode = record.get("编码").toString().trim(); + //判断是否已存在点位 + if (existingPoint.containsKey(itemCode)) { + Item item = existingPoint.get(itemCode); + //更新点位 + itemsToUpdate.add(updateItems(item, dept, record)); + } else { + //新增点位 + itemsToCreate.add(createItem(dept, record)); + } + } + + //异步处理 + ExecutorService executor = ThreadPoolExecutorUtil.getPoll("item-import-job"); + CompletableFuture createFuture = CompletableFuture.runAsync(() -> { + //批量新增物料 + if (!itemsToCreate.isEmpty()) { + batchCreateOrUpdate.batchCreate(itemsToCreate); + } + }, executor); + + CompletableFuture updateFuture = CompletableFuture.runAsync(() -> { + //批量更新物料 + if (!itemsToUpdate.isEmpty()) { + batchCreateOrUpdate.batchUpdate(itemsToUpdate); + } + }, executor); + // 等待所有操作完成 + CompletableFuture.allOf(createFuture, updateFuture).join(); + executor.shutdown();//关闭线程池 + return ("导入成功:" + " 新增(" + itemsToCreate.size() + ")修改(" + itemsToUpdate.size() + ")"); + } + + private Item updateItems(Item item, Dept dept, Map record) { + item.setDept(dept); + item.setName(record.get("名称").toString().trim()); + item.setExtendD1(record.get("单台用量") == null ? 0 : Double.parseDouble(record.get("单台用量").toString())); + item.setUnit(record.get("单位").toString().trim()); + item.setGoodType(record.get("物料类型") == null ? "" : record.get("物料类型").toString().trim()); + return item; + } + + private Item createItem(Dept dept, Map record) { + Item item = new Item(); + item.setCode(record.get("编码").toString().trim()); + item.setName(record.get("名称").toString().trim()); + item.setExtendD1(record.get("单台用量") == null ? 0 : Double.parseDouble(record.get("单台用量").toString())); + item.setUnit(record.get("单位").toString().trim()); + item.setGoodType(record.get("物料类型") == null ? "" : record.get("物料类型").toString().trim()); + item.setDept(dept); + item.setEnabled(true); + return item; + } + }