소스 검색

Merge branch 'master_liaozeyong' of http://121.40.253.172:3000/pengyue/jsh_erp into master_huangjunjie

# Conflicts:
#	src/main/java/com/jsh/erp/controller/pda/PdaController.java
huang 1 개월 전
부모
커밋
bd0c8d6838
25개의 변경된 파일1021개의 추가작업 그리고 42개의 파일을 삭제
  1. 5 1
      docs/new_sql.sql
  2. 41 0
      src/main/java/com/jsh/erp/config/JacksonConfig.java
  3. 149 1
      src/main/java/com/jsh/erp/controller/pda/PdaController.java
  4. 96 9
      src/main/java/com/jsh/erp/controller/stocktaking/StocktakingController.java
  5. 1 1
      src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingDTO.java
  6. 30 0
      src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingItemQueryDTO.java
  7. 20 0
      src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingQueryDTO.java
  8. 2 1
      src/main/java/com/jsh/erp/datasource/entities/Material.java
  9. 13 1
      src/main/java/com/jsh/erp/datasource/entities/TaskStocktaking.java
  10. 3 0
      src/main/java/com/jsh/erp/datasource/entities/TaskStocktakingItem.java
  11. 5 0
      src/main/java/com/jsh/erp/datasource/entities/User.java
  12. 9 1
      src/main/java/com/jsh/erp/datasource/mappers/TaskStocktakingItemMapper.java
  13. 10 0
      src/main/java/com/jsh/erp/datasource/mappers/TaskStocktakingMapper.java
  14. 24 0
      src/main/java/com/jsh/erp/datasource/pda/dto/PDATaskStocktakingDTO.java
  15. 25 0
      src/main/java/com/jsh/erp/datasource/pda/dto/PDATaskStocktakingItemDTO.java
  16. 52 0
      src/main/java/com/jsh/erp/datasource/pda/vo/PDATaskStocktakingItemVO.java
  17. 53 0
      src/main/java/com/jsh/erp/datasource/pda/vo/PDATaskStocktakingVO.java
  18. 30 0
      src/main/java/com/jsh/erp/datasource/vo/TaskStocktakingItemVO.java
  19. 12 2
      src/main/java/com/jsh/erp/datasource/vo/TaskStocktakingVO.java
  20. 5 0
      src/main/java/com/jsh/erp/service/TaskStocktakingItemService.java
  21. 38 2
      src/main/java/com/jsh/erp/service/TaskStocktakingService.java
  22. 14 0
      src/main/java/com/jsh/erp/service/impl/TaskStocktakingItemServiceImpl.java
  23. 207 17
      src/main/java/com/jsh/erp/service/impl/TaskStocktakingServiceImpl.java
  24. 98 6
      src/main/resources/mapper_xml/TaskStocktakingItemMapper.xml
  25. 79 0
      src/main/resources/mapper_xml/TaskStocktakingMapper.xml

+ 5 - 1
docs/new_sql.sql

@@ -57,10 +57,13 @@ CREATE TABLE `task_stocktaking` (
     `task_type` varchar(255) DEFAULT NULL COMMENT '任务类型',
     `depot_id` bigint DEFAULT NULL COMMENT '仓库ID',
     `number` varchar(255) DEFAULT NULL COMMENT '任务单号',
+    `category_count` int DEFAULT NULL COMMENT '种类数',
     `material_count` int DEFAULT NULL COMMENT '商品数',
     `task_status` int DEFAULT NULL COMMENT '任务状态',
     `position_range` varchar(255) DEFAULT NULL COMMENT '库位范围',
     `delete_flag` tinyint DEFAULT NULL COMMENT '删除标志(0:否,1是)',
+    `oper_time` datetime DEFAULT NULL COMMENT '盘点时间',
+    `oper_by` bigint DEFAULT NULL COMMENT '盘点人',
     PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='盘点任务表';
 
@@ -78,8 +81,9 @@ CREATE TABLE `task_stocktaking_item` (
     `new_position` varchar(255) DEFAULT NULL COMMENT '新仓位货架',
     `new_inventory` decimal(24,6) DEFAULT NULL COMMENT '新库存数',
     `difference_count` int DEFAULT NULL COMMENT '差异数量',
-    `difference_reasion` varchar(255) DEFAULT NULL COMMENT '差异原因',
+    `difference_reason` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '差异原因',
     `delete_flag` varchar(1) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT '0' COMMENT '删除标记,0未删除,1删除',
     `oper_time` datetime DEFAULT NULL COMMENT '操作时间',
+    `status` int DEFAULT '1' COMMENT '盘点状态(1.未盘,2.盘盈,3.盘亏 4.无差异)',
     PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='盘点任务关联商品表';

+ 41 - 0
src/main/java/com/jsh/erp/config/JacksonConfig.java

@@ -0,0 +1,41 @@
+package com.jsh.erp.config;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.util.TimeZone;
+
+/**
+ * Jackson配置
+ *
+ * @author ruoyi
+ *
+ */
+@Configuration
+public class JacksonConfig
+{
+    @Bean
+    public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter()
+    {
+        final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
+        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
+        final ObjectMapper objectMapper = builder.build();
+        SimpleModule simpleModule = new SimpleModule();
+        // Long 转为 String 防止 js 丢失精度
+        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
+        //simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
+        objectMapper.registerModule(simpleModule);
+        // 忽略 transient 关键词属性
+        objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
+        // 设置时区
+        objectMapper.setTimeZone(TimeZone.getDefault());
+        return new MappingJackson2HttpMessageConverter(objectMapper);
+    }
+}

+ 149 - 1
src/main/java/com/jsh/erp/controller/pda/PdaController.java

@@ -1,5 +1,9 @@
 package com.jsh.erp.controller.pda;
 
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.jsh.erp.base.AjaxResult;
 import com.jsh.erp.base.BaseController;
@@ -7,9 +11,17 @@ import com.jsh.erp.base.TableDataInfo;
 import com.jsh.erp.datasource.entities.DepotHead;
 import com.jsh.erp.datasource.entities.MaterialVo4Unit;
 import com.jsh.erp.datasource.entities.Supplier;
+import com.jsh.erp.datasource.entities.*;
 import com.jsh.erp.datasource.pda.dto.PDADepotHeadDTO;
+import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingDTO;
+import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO;
 import com.jsh.erp.datasource.pda.vo.PDADepotHeadVO;
 import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
+import com.jsh.erp.datasource.vo.SpinnerVO;
+import com.jsh.erp.datasource.vo.TaskStocktakingVO;
+import com.jsh.erp.datasource.vo.TreeNode;
 import com.jsh.erp.query.LambdaQueryWrapperX;
 import com.jsh.erp.service.*;
 import io.swagger.annotations.Api;
@@ -18,6 +30,8 @@ import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
 import java.util.List;
 
 @RestController
@@ -37,6 +51,21 @@ public class PdaController extends BaseController {
     @Resource
     private MaterialService materialService;
 
+    @Resource
+    private TaskStocktakingService taskStocktakingService;
+
+    @Resource
+    private TaskStocktakingItemService taskStocktakingItemService;
+
+    @Resource
+    private UserService userService;
+
+    @Resource
+    private MaterialCategoryService materialCategoryService;
+
+    @Resource
+    private MaterialExtendService materialExtendService;
+
     /**
      * 采购入库
      * @return
@@ -101,12 +130,131 @@ public class PdaController extends BaseController {
         return getDataTable(list);
     }
 
-    @ApiOperation("用于返回字段说明")
+    @ApiOperation("盘点任务列表")
+    @PostMapping("/taskStocktakingList")
+    public TableDataInfo taskStocktakingList(@RequestBody PDATaskStocktakingDTO pdaTaskStocktakingDTO) {
+        startPage();
+        List<PDATaskStocktakingVO> list = taskStocktakingService.pdaList(pdaTaskStocktakingDTO.getNumber(), pdaTaskStocktakingDTO.getStatus());
+        return getDataTable(list);
+    }
+
+    @ApiOperation(value = "盘点任务详情-商品列表")
+    @PostMapping("/taskStocktakingItemList")
+    public TableDataInfo taskStocktakingItemList(@RequestBody PDATaskStocktakingItemDTO pdaTaskStocktakingItemDTO){
+        startPage();
+        List<PDATaskStocktakingItemVO> list = taskStocktakingService.pdaItemList(pdaTaskStocktakingItemDTO);
+        return getDataTable(list);
+    }
+
+    @ApiOperation("盘点任务详情")
+    @GetMapping("/taskStocktakingDetail/{taskId}")
+    public AjaxResult taskStocktakingDetail(@PathVariable("taskId") Long taskId) throws Exception{
+        TaskStocktakingVO taskStocktakingVO = taskStocktakingService.pdaDetail(taskId);
+        return AjaxResult.success(taskStocktakingVO);
+    }
+
+    /**
+     * 获取商品类别树数据
+     * @Param:
+     * @return com.alibaba.fastjson.JSONArray
+     */
+    @ApiOperation(value = "获取商品类别树数据")
+    @GetMapping(value = "/getMaterialCategoryTree")
+    public JSONArray getMaterialCategoryTree(@RequestParam("id") Long id) throws Exception{
+        JSONArray arr=new JSONArray();
+        List<TreeNode> materialCategoryTree = materialCategoryService.getMaterialCategoryTree(id);
+        if(materialCategoryTree!=null&&materialCategoryTree.size()>0){
+            for(TreeNode node:materialCategoryTree){
+                String str= JSON.toJSONString(node);
+                JSONObject obj=JSON.parseObject(str);
+                arr.add(obj) ;
+            }
+        }
+        return arr;
+    }
+
+    @ApiOperation("开始任务")
+    @GetMapping("/startTask/{id}")
+    public AjaxResult startTask(@PathVariable("id") Long id){
+
+        taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>()
+                .set("task_status", 2)
+                .eq("id", id));
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("任务完成")
+    @GetMapping("/taskComplete/{id}")
+    public AjaxResult taskComplete(@PathVariable("id") Long id) throws Exception {
+        User currentUser = userService.getCurrentUser();
+        taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().set("task_status", 3)
+                .set("oper_time", new Date())
+                .set("oper_by", currentUser.getId())
+                .eq("id", id));
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("盘点")
+    @PostMapping("/stocktaking")
+    public AjaxResult stocktaking(@RequestBody TaskStocktakingItem taskStocktakingItem) throws Exception{
+        User currentUser = userService.getCurrentUser();
+        MaterialExtend materialExtend = materialExtendService.getMaterialExtend(taskStocktakingItem.getMaterialItemId());
+        if (materialExtend == null) {
+            return AjaxResult.error("商品信息不存在");
+        }
+        UpdateWrapper<TaskStocktakingItem> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.eq("id", taskStocktakingItem.getId())
+                .set("creator", currentUser.getId())
+                .set("oper_time", new Date());
+        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getNewInventory())) {
+            updateWrapper.set("new_inventory", taskStocktakingItem.getNewInventory());
+            BigDecimal subtract = taskStocktakingItem.getNewInventory().subtract(materialExtend.getInventory());
+            updateWrapper.set("difference_count", subtract);
+            //差异数量,设置盘点状态为1.未盘,2.盘盈,3.盘亏 4.无差异
+            if (subtract.compareTo(BigDecimal.ZERO) > 0) {
+                updateWrapper.set("status", 2);
+            } else if (subtract.compareTo(BigDecimal.ZERO) < 0) {
+                updateWrapper.set("status", 3);
+            } else {
+                updateWrapper.set("status", 4);
+            }
+        }
+        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getNewPosition())) {
+            updateWrapper.set("new_position", taskStocktakingItem.getNewPosition());
+        }
+        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getDifferenceCount())) {
+            updateWrapper.set("difference_count", taskStocktakingItem.getDifferenceCount());
+        }
+        if (ObjectUtil.isNotEmpty(taskStocktakingItem.getDifferenceReason())){
+            updateWrapper.set("difference_reason", taskStocktakingItem.getDifferenceReason());
+        }
+        taskStocktakingItemService.update(updateWrapper);
+        return AjaxResult.success();
+    }
+
+
+    @ApiOperation("负责人下拉列表")
+    @GetMapping("/creatorSpinnerList/{taskId}")
+    public AjaxResult creatorSpinnerList(@PathVariable("taskId") Long taskId) {
+        List<SpinnerVO> spinnerVOList = taskStocktakingItemService.creatorSpinnerList(taskId);
+        return AjaxResult.success(spinnerVOList);
+    }
+
+    @ApiOperation("订单-用于返回字段说明")
     @GetMapping("test")
     public AjaxResult test(PDADepotItemVO pdaDepotItemVO) {
         return AjaxResult.success();
     }
 
+    @ApiOperation("盘点-用于字段返回说明")
+    @GetMapping("taskTest")
+    public AjaxResult taskTest(PDATaskStocktakingVO pdaTaskStocktakingVO){
+        return AjaxResult.success();
+    }
+
+    /**
+     * PDA订单提交
+     */
     @PostMapping ("/orderSubmit")
     @ApiOperation(value = "订单提交")
     public AjaxResult orderSubmit(@RequestBody PDADepotHeadDTO pdaDepotHeadDTO) {

+ 96 - 9
src/main/java/com/jsh/erp/controller/stocktaking/StocktakingController.java

@@ -1,23 +1,30 @@
 package com.jsh.erp.controller.stocktaking;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.jsh.erp.base.AjaxResult;
 import com.jsh.erp.base.BaseController;
 import com.jsh.erp.base.TableDataInfo;
 import com.jsh.erp.datasource.dto.TaskStocktakingDTO;
 import com.jsh.erp.datasource.dto.TaskStocktakingItemDTO;
+import com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO;
+import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO;
 import com.jsh.erp.datasource.entities.TaskStocktaking;
 import com.jsh.erp.datasource.entities.TaskStocktakingItem;
+import com.jsh.erp.datasource.entities.User;
 import com.jsh.erp.datasource.vo.SpinnerVO;
-import com.jsh.erp.query.LambdaQueryWrapperX;
+import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 import com.jsh.erp.service.TaskStocktakingItemService;
 import com.jsh.erp.service.TaskStocktakingService;
 import com.jsh.erp.service.UserService;
+import com.jsh.erp.utils.DateUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 
 @RestController
@@ -36,16 +43,19 @@ public class StocktakingController extends BaseController {
 
     @ApiOperation("盘点任务列表")
     @PostMapping("/list")
-    public TableDataInfo list(){
+    public TableDataInfo list(@RequestBody TaskStocktakingQueryDTO taskStocktakingQueryDTO){
         startPage();
-        List<TaskStocktaking> list = taskStocktakingService.list();
+        List<TaskStocktakingVO> list = taskStocktakingService.listBy(taskStocktakingQueryDTO);
         return getDataTable(list);
     }
 
     @ApiOperation("新增盘点任务")
     @PostMapping("/add")
     public AjaxResult add(@RequestBody TaskStocktakingDTO taskStocktakingDTO) {
-        taskStocktakingService.add(taskStocktakingDTO);
+        boolean b = taskStocktakingService.add(taskStocktakingDTO);
+        if (!b){
+            return AjaxResult.error("创建失败,请联系系统管理员");
+        }
         return AjaxResult.success();
     }
 
@@ -61,6 +71,7 @@ public class StocktakingController extends BaseController {
      * @param id
      * @return
      */
+    @ApiOperation("任务详情")
     @GetMapping("/detail/{id}")
     public AjaxResult detail(@PathVariable("id") Long id) throws Exception{
         return AjaxResult.success(taskStocktakingService.detail(id));
@@ -68,27 +79,103 @@ public class StocktakingController extends BaseController {
 
     /**
      * 任务详情-商品列表
-     * @param taskStocktakingId 任务ID
+     * @param taskStocktakingItemQueryDTO 筛选数据
      * @return
      */
-    @GetMapping("/detailByItemList/{taskStocktakingId}")
-    public AjaxResult detailByItemList(@PathVariable("taskStocktakingId") Long taskStocktakingId) {
-        return AjaxResult.success(taskStocktakingService.listByTaskStocktakingId(taskStocktakingId));
+    @ApiOperation("任务详情-商品列表")
+    @PostMapping("/detailByItemList")
+    public AjaxResult detailByItemList(@RequestBody TaskStocktakingItemQueryDTO taskStocktakingItemQueryDTO) {
+        if (ObjectUtil.isEmpty(taskStocktakingItemQueryDTO.getTaskStocktakingId())) {
+            return AjaxResult.error("请选择盘点任务");
+        }
+        return AjaxResult.success(taskStocktakingService.listByTaskStocktakingId(taskStocktakingItemQueryDTO));
+    }
+
+    @ApiOperation("任务详情-修改")
+    @PostMapping("/detailUpdate")
+    public AjaxResult detailUpdate(@RequestBody TaskStocktakingDTO taskStocktakingDTO) {
+        boolean b = taskStocktakingService.detailUpdate(taskStocktakingDTO);
+        if (!b){
+            return AjaxResult.error("修改失败,请联系系统管理员");
+        }
+        return AjaxResult.success();
     }
 
     /**
      * 任务详情-商品列表-编辑
      * @return
      */
+    @ApiOperation("任务详情-商品-编辑")
     @PostMapping("/itemUpdate")
-    public AjaxResult itemUpdate(@RequestBody TaskStocktakingItemDTO taskStocktakingItemDTO) {
+    public AjaxResult itemUpdate(@RequestBody TaskStocktakingItemDTO taskStocktakingItemDTO) throws Exception {
+        User currentUser = userService.getCurrentUser();
         taskStocktakingItemService.update(new UpdateWrapper<TaskStocktakingItem>()
                 .set("new_inventory", taskStocktakingItemDTO.getNewInventory())
                 .set("new_position", taskStocktakingItemDTO.getNewPosition())
                 .set("difference_count", taskStocktakingItemDTO.getDifferenceCount())
                 .set("difference_reason", taskStocktakingItemDTO.getDifferenceReason())
+                .set("creator", currentUser.getId())
+                .set("oper_time", DateUtils.getTime())
                 .eq("id", taskStocktakingItemDTO.getId()));
         return AjaxResult.success();
     }
 
+    /**
+     * 任务详情-商品-删除
+     * @param id 商品ID
+     * @return
+     */
+    @ApiOperation("任务详情-商品-删除")
+    @GetMapping("/itemDelete/{id}")
+    public AjaxResult itemDelete(@PathVariable("id") Long id) {
+        taskStocktakingItemService.update(new UpdateWrapper<TaskStocktakingItem>().set("delete_flag", true).eq("id", id));
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("取消任务")
+    @GetMapping("/taskCancel/{ids}")
+    public AjaxResult taskCancel(@PathVariable("ids") Long[] ids) {
+        Arrays.asList(ids).forEach(id -> {
+            taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().eq("id", id).set("task_status", "4"));
+        });
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("删除任务")
+    @GetMapping("/taskDelete/{ids}")
+    public AjaxResult taskDelete(@PathVariable("ids") Long[] ids) {
+        Arrays.asList(ids).forEach(id -> {
+            taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().eq("id", id).set("delete_flag", true));
+        });
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("开始任务")
+    @GetMapping("/startTask/{id}")
+    public AjaxResult startTask(@PathVariable("id") Long id) {
+        taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().set("task_status", 2).eq("id", id));
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("完成任务")
+    @GetMapping("/taskComplete/{id}")
+    public AjaxResult taskComplete(@PathVariable("id") Long id) throws Exception {
+        User currentUser = userService.getCurrentUser();
+        taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().set("task_status", 3)
+                .set("oper_time", new Date())
+                .set("oper_by", currentUser.getId())
+                .eq("id", id));
+        return AjaxResult.success();
+    }
+
+    @ApiOperation("任务更新库存")
+    @GetMapping("/taskUpdateStock/{ids}")
+    public AjaxResult updateStock(@PathVariable("ids") Long[] ids) {
+        for (Long id : ids) {
+            taskStocktakingService.update(new UpdateWrapper<TaskStocktaking>().set("task_status", 5).eq("id", id));
+        }
+        return AjaxResult.success();
+    }
+
+
 }

+ 1 - 1
src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingDTO.java

@@ -16,6 +16,6 @@ import java.util.List;
 public class TaskStocktakingDTO extends TaskStocktaking {
 
     @ApiModelProperty("商品扩展ID集合")
-    private List<Long> materialExtendIdList;
+    private List<String> materialExtendIdList;
 
 }

+ 30 - 0
src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingItemQueryDTO.java

@@ -0,0 +1,30 @@
+package com.jsh.erp.datasource.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+public class TaskStocktakingItemQueryDTO {
+
+    @ApiModelProperty("盘点任务ID")
+    private Long taskStocktakingId;
+
+    @ApiModelProperty("商品类别ID")
+    private Long categoryId;
+
+    @ApiModelProperty("商品名称")
+    private Integer materialName;
+
+    @ApiModelProperty("批次号")
+    private String batchNumber;
+
+    @ApiModelProperty("仓库货架")
+    private Long position;
+
+    @ApiModelProperty("是否存在差异 1:是,2:否,其他是全部")
+    private String isDifference;
+
+
+}

+ 20 - 0
src/main/java/com/jsh/erp/datasource/dto/TaskStocktakingQueryDTO.java

@@ -0,0 +1,20 @@
+package com.jsh.erp.datasource.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class TaskStocktakingQueryDTO {
+
+    @ApiModelProperty("任务状态 1.未开始,2.进行中,3.已完成,4.已取消")
+    private Integer taskStatus;
+
+    @ApiModelProperty("任务单号")
+    private String number;
+
+    @ApiModelProperty("盘点仓库ID")
+    private Long depotId;
+
+    @ApiModelProperty("创建人")
+    private String createName;
+
+
+}

+ 2 - 1
src/main/java/com/jsh/erp/datasource/entities/Material.java

@@ -1,12 +1,12 @@
 package com.jsh.erp.datasource.entities;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
 
 import java.math.BigDecimal;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -86,6 +86,7 @@ public class Material {
     @ApiModelProperty("无动销提醒周期")
     private String movingPinReminderCycle;
 
+    @TableField(exist = false)
     private List<MaterialExtend> list;
 
 

+ 13 - 1
src/main/java/com/jsh/erp/datasource/entities/TaskStocktaking.java

@@ -1,5 +1,6 @@
 package com.jsh.erp.datasource.entities;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
@@ -26,6 +27,7 @@ public class TaskStocktaking {
     private Long createBy;
 
     @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date createTime;
 
     @ApiModelProperty("任务类型 1.全盘,2.抽盘")
@@ -37,10 +39,13 @@ public class TaskStocktaking {
     @ApiModelProperty("任务单号")
     private String number;
 
+    @ApiModelProperty("种类数")
+    private Integer categoryCount;
+
     @ApiModelProperty("商品数")
     private int materialCount;
 
-    @ApiModelProperty("任务状态 0.未开始,1.进行中,2.已完成,3.已取消")
+    @ApiModelProperty("任务状态 1.未开始,2.进行中,3.已完成,4.已取消,5.已更新")
     private Integer taskStatus;
 
     @ApiModelProperty("盘点范围")
@@ -49,4 +54,11 @@ public class TaskStocktaking {
     @ApiModelProperty("删除标记,0.未删除,1.已删除")
     private boolean deleteFlag;
 
+    @ApiModelProperty("盘点人")
+    private Long operBy;
+
+    @ApiModelProperty("盘点时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date operTime;
+
 }

+ 3 - 0
src/main/java/com/jsh/erp/datasource/entities/TaskStocktakingItem.java

@@ -41,6 +41,9 @@ public class TaskStocktakingItem {
     @ApiModelProperty("差异原因")
     private String differenceReason;
 
+    @ApiModelProperty("盘点状态:1.未盘,2.盘盈,3.盘亏 4.无差异 其余为全部")
+    private Integer status;
+
     @ApiModelProperty("删除标记,0.未删除,1.已删除")
     private boolean deleteFlag;
 

+ 5 - 0
src/main/java/com/jsh/erp/datasource/entities/User.java

@@ -1,5 +1,10 @@
 package com.jsh.erp.datasource.entities;
 
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+@Data
+@TableName(value = "jsh_user")
 public class User {
     private Long id;
 

+ 9 - 1
src/main/java/com/jsh/erp/datasource/mappers/TaskStocktakingItemMapper.java

@@ -1,6 +1,10 @@
 package com.jsh.erp.datasource.mappers;
 
+import com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO;
 import com.jsh.erp.datasource.entities.TaskStocktakingItem;
+import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO;
+import com.jsh.erp.datasource.vo.SpinnerVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
 import org.apache.ibatis.annotations.Param;
 
@@ -8,6 +12,10 @@ import java.util.List;
 
 public interface TaskStocktakingItemMapper extends BaseMapperX<TaskStocktakingItem> {
 
-    List<TaskStocktakingItemVO> listByTaskStocktakingId(@Param("taskStocktakingId") Long taskStocktakingId);
+    List<TaskStocktakingItemVO> listByTaskStocktakingId(TaskStocktakingItemQueryDTO taskStocktakingItemQueryDTO);
+
+    List<PDATaskStocktakingItemVO> pdaList(PDATaskStocktakingItemDTO pdaTaskStocktakingItemDTO);
+
+    List<SpinnerVO> creatorSpinnerList(@Param("taskId") Long taskId);
 
 }

+ 10 - 0
src/main/java/com/jsh/erp/datasource/mappers/TaskStocktakingMapper.java

@@ -1,6 +1,16 @@
 package com.jsh.erp.datasource.mappers;
 
+import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO;
 import com.jsh.erp.datasource.entities.TaskStocktaking;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
+import com.jsh.erp.datasource.vo.TaskStocktakingVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 public interface TaskStocktakingMapper extends BaseMapperX<TaskStocktaking> {
+
+    List<TaskStocktakingVO> listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO);
+
+    List<PDATaskStocktakingVO> pdaList(@Param("number") String number , @Param("taskStatus") Integer taskStatus);
 }

+ 24 - 0
src/main/java/com/jsh/erp/datasource/pda/dto/PDATaskStocktakingDTO.java

@@ -0,0 +1,24 @@
+package com.jsh.erp.datasource.pda.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+public class PDATaskStocktakingDTO {
+
+    @ApiModelProperty("任务状态 1.未开始,2.进行中,3.已完成,4.已取消")
+    private Integer status;
+
+    @ApiModelProperty("任务单号")
+    private String number;
+
+    @ApiModelProperty("用户id")
+    private Long userId;
+
+    @ApiModelProperty("商品种类ID")
+    private Long categoryId;
+
+    @ApiModelProperty("库位")
+    private String position;
+
+}

+ 25 - 0
src/main/java/com/jsh/erp/datasource/pda/dto/PDATaskStocktakingItemDTO.java

@@ -0,0 +1,25 @@
+package com.jsh.erp.datasource.pda.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class PDATaskStocktakingItemDTO {
+
+    @ApiModelProperty("任务ID")
+    private String taskId;
+
+    @ApiModelProperty("库位")
+    private List<String> positionList;
+
+    @ApiModelProperty("盘点人ID")
+    private List<Long> userIdList;
+
+    @ApiModelProperty("商品种类ID")
+    private List<Long> categoryIdList;
+
+    @ApiModelProperty("商品盘点类型:1.未盘,2.盘盈,3.盘亏 4.无差异 其余为全部")
+    private List<String> statusList;
+}

+ 52 - 0
src/main/java/com/jsh/erp/datasource/pda/vo/PDATaskStocktakingItemVO.java

@@ -0,0 +1,52 @@
+package com.jsh.erp.datasource.pda.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 盘点任务明细
+ */
+@Data
+@Accessors(chain = true)
+public class PDATaskStocktakingItemVO {
+
+    @ApiModelProperty("主键ID")
+    private Long id;
+
+    @ApiModelProperty("库位")
+    private String position;
+
+    @ApiModelProperty("商品总类")
+    private String categoryName;
+
+    @ApiModelProperty("商品ID")
+    private Long materialItemId;
+
+    @ApiModelProperty("商品名称")
+    private String materialName;
+
+    @ApiModelProperty("商品规格")
+    private String standard;
+
+    @ApiModelProperty("盘点人名称")
+    private String createName;
+
+    @ApiModelProperty("盘点时间")
+    private Date operTime;
+
+    @ApiModelProperty("库存数")
+    private Integer inventory;
+
+    @ApiModelProperty("商品单位")
+    private String commodityUnit;
+
+    @ApiModelProperty("盘点库存数")
+    private Integer newInventory;
+
+    @ApiModelProperty("盘点状态:1.未盘,2.盘盈,3.盘亏 4.无差异 其余为全部")
+    private Integer status;
+
+}

+ 53 - 0
src/main/java/com/jsh/erp/datasource/pda/vo/PDATaskStocktakingVO.java

@@ -0,0 +1,53 @@
+package com.jsh.erp.datasource.pda.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class PDATaskStocktakingVO {
+
+    @ApiModelProperty("任务ID")
+    private Long id;
+
+    @ApiModelProperty("任务名称")
+    private String taskName;
+
+    @ApiModelProperty("任务单号")
+    private String number;
+
+    @ApiModelProperty("仓库名称")
+    private String depotName;
+
+    @ApiModelProperty("创建人名称")
+    private String createByName;
+
+    @ApiModelProperty("负责人名称")
+    private String creatorName;
+
+    @ApiModelProperty("种类数")
+    private Integer categoryCount;
+
+    @ApiModelProperty("商品数")
+    private Integer materialCount;
+
+    @ApiModelProperty("盘点人名称")
+    private String operName;
+
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+    @ApiModelProperty("盘点时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date operTime;
+
+    @ApiModelProperty("任务状态 1.未开始,2.进行中,3.已完成,4.已取消")
+    private Integer taskStatus;
+
+    @ApiModelProperty("盘点范围")
+    private String positionRange;
+
+}

+ 30 - 0
src/main/java/com/jsh/erp/datasource/vo/TaskStocktakingItemVO.java

@@ -1,5 +1,6 @@
 package com.jsh.erp.datasource.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
@@ -20,6 +21,34 @@ public class TaskStocktakingItemVO {
     @ApiModelProperty("任务ID")
     private Long taskStocktakingId;
 
+    @ApiModelProperty("商品名称")
+    private String materialName;
+
+    @ApiModelProperty("系统编码")
+    private String systemSku;
+
+    @ApiModelProperty("商品单位")
+    private String commodityUnit;
+
+    @ApiModelProperty("生产日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date productionDate;
+
+    @ApiModelProperty("供应商名称")
+    private String supplierName;
+
+    @ApiModelProperty("商品编码")
+    private String barCode;
+
+    @ApiModelProperty("库存数量")
+    private String inventory;
+
+    @ApiModelProperty("仓库名称")
+    private String depotName;
+
+    @ApiModelProperty("商品种类名称")
+    private String categoryName;
+
     @ApiModelProperty("商品ID")
     private Long materialItemId;
 
@@ -27,6 +56,7 @@ public class TaskStocktakingItemVO {
     private Long creator;
 
     @ApiModelProperty("操作时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date operTime;
 
     @ApiModelProperty("新仓位货架")

+ 12 - 2
src/main/java/com/jsh/erp/datasource/vo/TaskStocktakingVO.java

@@ -5,8 +5,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.experimental.Accessors;
 
-import java.util.List;
-
 /**
  * 盘点任务
  */
@@ -23,4 +21,16 @@ public class TaskStocktakingVO extends TaskStocktaking {
     @ApiModelProperty("仓库名称")
     private String depotName;
 
+    @ApiModelProperty("完成操作次数")
+    private Long finishCount;
+
+    @ApiModelProperty("商品总数量")
+    private Long itemCount;
+
+    @ApiModelProperty("差异率")
+    private double differenceRate;
+
+    @ApiModelProperty("准确率")
+    private double accuracyRate;
+
 }

+ 5 - 0
src/main/java/com/jsh/erp/service/TaskStocktakingItemService.java

@@ -2,6 +2,11 @@ package com.jsh.erp.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jsh.erp.datasource.entities.TaskStocktakingItem;
+import com.jsh.erp.datasource.vo.SpinnerVO;
+
+import java.util.List;
 
 public interface TaskStocktakingItemService extends IService<TaskStocktakingItem> {
+
+    List<SpinnerVO> creatorSpinnerList(Long taskId);
 }

+ 38 - 2
src/main/java/com/jsh/erp/service/TaskStocktakingService.java

@@ -2,7 +2,12 @@ package com.jsh.erp.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.jsh.erp.datasource.dto.TaskStocktakingDTO;
+import com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO;
+import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO;
 import com.jsh.erp.datasource.entities.TaskStocktaking;
+import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 
@@ -11,6 +16,12 @@ import java.util.List;
 public interface TaskStocktakingService extends IService<TaskStocktaking> {
 
     /**
+     *
+     * @return
+     */
+    List<TaskStocktakingVO> listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO);
+
+    /**
      * 新增任务
      * @param taskStocktakingDTO
      * @return
@@ -24,11 +35,36 @@ public interface TaskStocktakingService extends IService<TaskStocktaking> {
     TaskStocktakingVO detail(Long id) throws Exception;
 
     /**
+     * 任务详情-修改
+     * @param taskStocktakingDTO
+     * @return
+     */
+    boolean detailUpdate(TaskStocktakingDTO taskStocktakingDTO);
+
+    /**
      * 任务详情-商品明细
-     * @param taskStocktakingId 盘点任务ID
+     * @param taskStocktakingItemQueryDTO 筛选参数
      * @return
      */
-    List<TaskStocktakingItemVO> listByTaskStocktakingId(Long taskStocktakingId);
+    List<TaskStocktakingItemVO> listByTaskStocktakingId(TaskStocktakingItemQueryDTO taskStocktakingItemQueryDTO);
+
+    /**
+     * PDA-盘点任务列表
+     * @param number 盘点单号或者任务名称
+     * @param taskStatus 盘点任务状态
+     * @return
+     */
+    List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus);
+
+    /**
+     * PAD-盘点任务详情
+     * @param id 盘点任务ID
+     * @return
+     * @throws Exception
+     */
+    TaskStocktakingVO pdaDetail(Long id) throws Exception;
+
+    List<PDATaskStocktakingItemVO> pdaItemList(PDATaskStocktakingItemDTO pdaTaskStocktakingItemDTO);
 
 
 }

+ 14 - 0
src/main/java/com/jsh/erp/service/impl/TaskStocktakingItemServiceImpl.java

@@ -3,9 +3,23 @@ package com.jsh.erp.service.impl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jsh.erp.datasource.entities.TaskStocktakingItem;
 import com.jsh.erp.datasource.mappers.TaskStocktakingItemMapper;
+import com.jsh.erp.datasource.vo.SpinnerVO;
 import com.jsh.erp.service.TaskStocktakingItemService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 @Service
+@RequiredArgsConstructor
+@Slf4j
 public class TaskStocktakingItemServiceImpl extends ServiceImpl<TaskStocktakingItemMapper, TaskStocktakingItem> implements TaskStocktakingItemService {
+
+    private final TaskStocktakingItemMapper taskStocktakingItemMapper;
+
+    @Override
+    public List<SpinnerVO> creatorSpinnerList(Long taskId) {
+        return taskStocktakingItemMapper.creatorSpinnerList(taskId);
+    }
 }

+ 207 - 17
src/main/java/com/jsh/erp/service/impl/TaskStocktakingServiceImpl.java

@@ -1,27 +1,36 @@
 package com.jsh.erp.service.impl;
 
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jsh.erp.datasource.dto.TaskStocktakingDTO;
+import com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO;
+import com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO;
 import com.jsh.erp.datasource.entities.*;
-import com.jsh.erp.datasource.mappers.MaterialExtendMapper;
-import com.jsh.erp.datasource.mappers.TaskStocktakingItemMapper;
-import com.jsh.erp.datasource.mappers.TaskStocktakingMapper;
-import com.jsh.erp.datasource.mappers.UserMapper;
+import com.jsh.erp.datasource.mappers.*;
+import com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO;
+import com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
 import com.jsh.erp.datasource.vo.TaskStocktakingVO;
 import com.jsh.erp.query.LambdaQueryWrapperX;
 import com.jsh.erp.service.DepotService;
+import com.jsh.erp.service.SequenceService;
 import com.jsh.erp.service.TaskStocktakingService;
+import com.jsh.erp.service.UserService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -39,22 +48,75 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
 
     private final TaskStocktakingItemMapper taskStocktakingItemMapper;
 
+    private final TaskStocktakingMapper taskStocktakingMapper;
+
+    private final MaterialMapper materialMapper;
+
+    private final UserService userService;
+
+    private final SequenceService sequenceService;
+
+    @Override
+    public List<TaskStocktakingVO> listBy(TaskStocktakingQueryDTO taskStocktakingQueryDTO) {
+        return taskStocktakingMapper.listBy(taskStocktakingQueryDTO);
+    }
+
     /**
      * 创建盘点任务
      * @param taskStocktakingDTO
      * @return
      */
     @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
     public boolean add(TaskStocktakingDTO taskStocktakingDTO) {
-        //商品库位范围处理
-        List<String> collect;
-        if (taskStocktakingDTO.getTaskType() == 1) {
-            collect = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO)).stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
-        } else {
-            collect = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getId, taskStocktakingDTO.getMaterialExtendIdList())).stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
+        try {
+            List<String> collect;
+            List<MaterialExtend> materialExtendList;
+            //全盘,抽盘,处理任务明细
+            if (taskStocktakingDTO.getTaskType() == 1) {
+                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory));
+                collect = materialExtendList
+                        .stream()
+                        .map(MaterialExtend::getPosition)
+                        .collect(Collectors.toList());
+                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList());
+                List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().eq(Material::getId, materialIdList));
+                List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
+                taskStocktakingDTO.setCategoryCount(categoryIdList.size());
+                taskStocktakingDTO.setMaterialCount(materialExtendList.size());
+            } else {
+                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
+                collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
+                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList());
+                List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
+                List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
+                taskStocktakingDTO.setCategoryCount(categoryIdList.size());
+                taskStocktakingDTO.setMaterialCount(materialExtendList.size());
+            }
+            //处理商品库位范围处理
+            String positionRange = extractRangePair(collect);
+            taskStocktakingDTO.setPositionRange(positionRange);
+            User currentUser = userService.getCurrentUser();
+            taskStocktakingDTO.setCreateBy(currentUser.getId());
+            taskStocktakingDTO.setCreateTime(new Date());
+            taskStocktakingDTO.setTaskStatus(1);
+            //生成单据编号
+            taskStocktakingDTO.setNumber("PDRW"+sequenceService.buildOnlyNumber());
+            //生成任务
+            this.save(taskStocktakingDTO);
+            //生成任务明细
+            List<TaskStocktakingItem> taskStocktakingItemList = new ArrayList<>();
+            materialExtendList.forEach(item -> {
+                TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
+                taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId());
+                taskStocktakingItem.setMaterialItemId(item.getId());
+                taskStocktakingItemList.add(taskStocktakingItem);
+            });
+            taskStocktakingItemMapper.insertBatch(taskStocktakingItemList);
+        } catch (Exception e) {
+            log.error("创建盘点任务失败", e);
+            return false;
         }
-        String positionRange = extractRangePair(collect);
-        this.save(taskStocktakingDTO);
         return true;
     }
 
@@ -71,10 +133,14 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
         BeanUtils.copyProperties(one, taskStocktakingVO);
         //获取负责人名称
         User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getCreator()));
-        taskStocktakingVO.setCreatorName(user.getLoginName());
+        if (user != null) {
+            taskStocktakingVO.setCreatorName(user.getLoginName());
+        }
         //获取创建人名称
         User user1 = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getId, one.getCreateBy()));
-        taskStocktakingVO.setCreateByName(user1.getLoginName());
+        if (user1 != null) {
+            taskStocktakingVO.setCreateByName(user1.getLoginName());
+        }
         //获取仓库名称
         Depot depot = depotService.getDepot(one.getDepotId());
         taskStocktakingVO.setDepotName(depot.getName());
@@ -83,13 +149,137 @@ public class TaskStocktakingServiceImpl extends ServiceImpl<TaskStocktakingMappe
     }
 
     /**
+     * 任务详情-修改
+     * @param taskStocktakingDTO
+     * @return
+     */
+    @Override
+    public boolean detailUpdate(TaskStocktakingDTO taskStocktakingDTO) {
+        try {
+            List<String> collect;
+            List<MaterialExtend> materialExtendList;
+            //全盘,抽盘,处理任务明细
+            if (taskStocktakingDTO.getTaskType() == 1) {
+                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().ne(MaterialExtend::getInventory, BigDecimal.ZERO).isNotNull(MaterialExtend::getInventory));
+                collect = materialExtendList
+                        .stream()
+                        .map(MaterialExtend::getPosition)
+                        .collect(Collectors.toList());
+                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).distinct().collect(Collectors.toList());
+                List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().eq(Material::getId, materialIdList));
+                List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
+                taskStocktakingDTO.setCategoryCount(categoryIdList.size());
+                taskStocktakingDTO.setMaterialCount(materialExtendList.size());
+            } else {
+                materialExtendList = materialExtendMapper.selectList(new LambdaQueryWrapper<MaterialExtend>().in(MaterialExtend::getBatchNumber, taskStocktakingDTO.getMaterialExtendIdList()));
+                collect = materialExtendList.stream().map(MaterialExtend::getPosition).collect(Collectors.toList());
+                List<Long> materialIdList = materialExtendList.stream().map(MaterialExtend::getMaterialId).collect(Collectors.toList());
+                List<Material> materialList = materialMapper.selectList(new LambdaQueryWrapperX<Material>().in(Material::getId, materialIdList));
+                List<Long> categoryIdList = materialList.stream().map(Material::getCategoryId).distinct().collect(Collectors.toList());
+                taskStocktakingDTO.setCategoryCount(categoryIdList.size());
+                taskStocktakingDTO.setMaterialCount(materialExtendList.size());
+            }
+            //处理商品库位范围处理
+            String positionRange = extractRangePair(collect);
+            taskStocktakingDTO.setPositionRange(positionRange);
+            User currentUser = userService.getCurrentUser();
+            taskStocktakingDTO.setCreateBy(currentUser.getId());
+            taskStocktakingDTO.setCreateTime(new Date());
+            taskStocktakingDTO.setTaskStatus(1);
+            //生成任务
+            this.updateById(taskStocktakingDTO);
+            List<Long> taskStocktakingItemIdList = taskStocktakingItemMapper.selectList(new LambdaQueryWrapperX<TaskStocktakingItem>().eq(TaskStocktakingItem::getTaskStocktakingId, taskStocktakingDTO.getId())).stream().map(TaskStocktakingItem::getId).collect(Collectors.toList());
+            //生成任务明细
+            List<TaskStocktakingItem> addTaskStocktakingItemList = new ArrayList<>();
+            materialExtendList.forEach(item -> {
+                if (!taskStocktakingItemIdList.contains(item.getId())) {
+                    TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
+                    taskStocktakingItem.setTaskStocktakingId(taskStocktakingDTO.getId());
+                    taskStocktakingItem.setMaterialItemId(item.getId());
+                    addTaskStocktakingItemList.add(taskStocktakingItem);
+                }
+            });
+            List<Long> materialExtendIdList = materialExtendList.stream().map(MaterialExtend::getId).collect(Collectors.toList());
+            taskStocktakingItemIdList.forEach(item -> {
+                if (!materialExtendIdList.contains(item)) {
+                    TaskStocktakingItem taskStocktakingItem = new TaskStocktakingItem();
+                    taskStocktakingItem.setId(item);
+                    taskStocktakingItem.setDeleteFlag(true);
+                    taskStocktakingItemMapper.updateById(taskStocktakingItem);
+                }
+            });
+            if (addTaskStocktakingItemList.size() > 0) {
+                taskStocktakingItemMapper.insertBatch(addTaskStocktakingItemList);
+            }
+        } catch (Exception e) {
+            log.error("修改盘点任务失败", e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
      * 任务详情-商品明细
-     * @param taskStocktakingId 盘点任务ID
+     * @param taskStocktakingItemQueryDTO 筛选参数
+     * @return
+     */
+    @Override
+    public List<TaskStocktakingItemVO> listByTaskStocktakingId(TaskStocktakingItemQueryDTO taskStocktakingItemQueryDTO) {
+        return taskStocktakingItemMapper.listByTaskStocktakingId(taskStocktakingItemQueryDTO);
+    }
+
+    /**
+     * PDA-盘点任务列表
+     * @param number 盘点单号或者任务名称
+     * @param taskStatus 盘点任务状态
      * @return
      */
     @Override
-    public List<TaskStocktakingItemVO> listByTaskStocktakingId(Long taskStocktakingId) {
-        return taskStocktakingItemMapper.listByTaskStocktakingId(taskStocktakingId);
+    public List<PDATaskStocktakingVO> pdaList(String number , Integer taskStatus) {
+        return taskStocktakingMapper.pdaList(number , taskStatus);
+    }
+
+    /**
+     * PDA-盘点任务详情
+     * @param id 盘点任务ID
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public TaskStocktakingVO pdaDetail(Long id) throws Exception{
+        TaskStocktakingVO detail = detail(id);
+        List<TaskStocktakingItem> itemList = taskStocktakingItemMapper.selectList(new LambdaQueryWrapper<TaskStocktakingItem>().eq(TaskStocktakingItem::getTaskStocktakingId, id));
+        //已操作数量
+        long finishCount = itemList.stream().filter(item -> item.getCreator() != null).count();
+        //商品总数量
+        long itemCount = itemList.size();
+        //商品差异条数
+        long itemDifferenceCount = itemList.stream().filter(item -> item.getCreator() != null
+                && item.getDifferenceCount() != null
+                && item.getDifferenceCount() > 0).count();
+        //差异率
+        double differenceRate = 0;
+        //准确率
+        double accuracyRate = 0;
+        if (itemDifferenceCount > 0) {
+            differenceRate = BigDecimal.valueOf(itemCount)
+                    .divide(BigDecimal.valueOf(itemDifferenceCount), 4, RoundingMode.HALF_UP)
+                    .doubleValue();
+            BigDecimal subtract = BigDecimal.valueOf(finishCount).subtract(BigDecimal.valueOf(itemDifferenceCount));
+            if (!subtract.equals(BigDecimal.ZERO)) {
+                accuracyRate = subtract.divide(BigDecimal.valueOf(itemCount), 4, RoundingMode.HALF_UP).doubleValue();
+            }
+        }
+        detail.setItemCount(itemCount);
+        detail.setDifferenceRate(differenceRate);
+        detail.setAccuracyRate(accuracyRate);
+        detail.setFinishCount(finishCount);
+        return detail;
+    }
+
+    @Override
+    public List<PDATaskStocktakingItemVO> pdaItemList(PDATaskStocktakingItemDTO pdaTaskStocktakingItemDTO) {
+        return taskStocktakingItemMapper.pdaList(pdaTaskStocktakingItemDTO);
     }
 
     /**

+ 98 - 6
src/main/resources/mapper_xml/TaskStocktakingItemMapper.xml

@@ -2,14 +2,69 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.jsh.erp.datasource.mappers.TaskStocktakingItemMapper">
 
-    <select id="listByTaskStocktakingId" resultType="com.jsh.erp.datasource.vo.TaskStocktakingItemVO">
+    <select id="pdaList" parameterType="com.jsh.erp.datasource.pda.dto.PDATaskStocktakingItemDTO" resultType="com.jsh.erp.datasource.pda.vo.PDATaskStocktakingItemVO">
         SELECT
-            m.`name` AS category_name,
+        tsi.id AS id,
+        tsi.material_item_id AS material_item_id,
+        me.position AS position,
+        mc.`name` AS category_name,
+        m.`name` AS material_name,
+        m.standard AS standard,
+        u.username AS create_name,
+        tsi.oper_time AS oper_time,
+        me.inventory AS inventory,
+        me.commodity_unit AS commodity_unit,
+        tsi.new_inventory AS new_inventory,
+        tsi.new_position AS new_position,
+        tsi.status AS status
+        FROM
+        task_stocktaking_item tsi
+        LEFT JOIN jsh_material_extend me ON tsi.material_item_id = me.id
+        LEFT JOIN jsh_material m ON me.material_id = m.id
+        LEFT JOIN jsh_material_category mc ON m.category_id = mc.id
+        LEFT JOIN jsh_user u ON u.id = tsi.creator
+        <where>
+            tsi.delete_flag = 0
+            AND tsi.task_stocktaking_id = #{taskId}
+            <if test="userIdList != null and userIdList.size > 0">
+                AND tsi.creator IN
+                <foreach collection="userIdList" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="categoryIdList != null and categoryIdList.size > 0">
+                AND m.category_id IN
+                <foreach collection="categoryIdList" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+            <if test="positionList != null and positionList.size > 0">
+                AND
+                <foreach collection="positionList" item="item" open="(" separator="OR" close=")">
+                     me.position LIKE CONCAT('%',#{item},'%')
+                </foreach>
+            </if>
+            <if test="statusList != null and statusList.size > 0">
+                AND tsi.status IN
+                <foreach collection="statusList" item="item" open="(" separator="," close=")">
+                    #{item}
+                </foreach>
+            </if>
+        </where>
+        ORDER BY
+        tsi.oper_time DESC,
+        tsi.id DESC
+    </select>
+
+    <select id="listByTaskStocktakingId" parameterType="com.jsh.erp.datasource.dto.TaskStocktakingItemQueryDTO" resultType="com.jsh.erp.datasource.vo.TaskStocktakingItemVO">
+        SELECT
+            tsi.id AS id,
+            mc.`name` AS category_name,
             m.`name` AS material_name,
             m.system_sku AS system_sku,
-            m.commodity_unit AS commodity_unit,
+            me.commodity_unit AS commodity_unit,
             me.production_date AS production_date,
-            s.`name` AS supplier_name,
+            s.supplier AS supplier_name,
             me.bar_code AS bar_code,
             me.inventory AS inventory,
             d.`name` AS depot_name,
@@ -23,9 +78,46 @@
                 LEFT JOIN jsh_material m ON me.material_id = m.id
                 LEFT JOIN jsh_material_category mc ON mc.id = m.category_id
                 LEFT JOIN jsh_supplier s ON me.supplier_id = s.id
-                LEFT JOIN jsh_depot d AS me.depot_id = d.id
+                LEFT JOIN jsh_depot d ON me.depot_id = d.id
+        <where>
+            tsi.delete_flag = 0
+            AND tsi.task_stocktaking_id = #{taskStocktakingId}
+            <if test="categoryId != null and categoryId != ''">
+                AND m.category_id = #{categoryId}
+            </if>
+            <if test="materialName != null and materialName != ''">
+                AND m.`name` LIKE CONCAT('%',#{materialName},'%')
+            </if>
+            <if test="batchNumber != null and batchNumber != ''">
+                AND me.batch_number = #{batchNumber}
+            </if>
+            <if test="position != null and position != ''">
+                AND me.position = #{position}
+            </if>
+            <if test="isDifference != null and isDifference == '1'">
+                AND tsi.new_inventory = me.inventory
+            </if>
+            <if test="isDifference != null and isDifference == '2'">
+                AND tsi.new_inventory != 0
+                AND tsi.new_inventory != me.inventory
+            </if>
+        </where>
+        ORDER BY
+            tsi.oper_time DESC,
+            tsi.id DESC
+    </select>
+
+    <select id="creatorSpinnerList" resultType="com.jsh.erp.datasource.vo.SpinnerVO">
+        SELECT
+            tsi.creator AS value,
+            u.username AS label
+        FROM
+            task_stocktaking_item tsi
+            LEFT JOIN jsh_user u ON tsi.creator = u.id
         WHERE
-            tsi.task_stocktaking_id = #{taskStocktakingId}
+            tsi.delete_flag = 0
+            AND tsi.creator IS NOT NULL
+            AND tsi.task_stocktaking_id = #{taskId};
     </select>
 
 </mapper>

+ 79 - 0
src/main/resources/mapper_xml/TaskStocktakingMapper.xml

@@ -2,4 +2,83 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.jsh.erp.datasource.mappers.TaskStocktakingMapper">
 
+    <select id="pdaList" parameterType="com.jsh.erp.datasource.pda.dto.PDATaskStocktakingDTO" resultType="com.jsh.erp.datasource.pda.vo.PDATaskStocktakingVO">
+        SELECT
+            ts.id AS id,
+            ts.task_name AS task_name,
+            ts.number AS number,
+            d.`name` AS depot_name,
+            ju.username AS create_name,
+            u.username AS creator_name,
+            ts.category_count AS category_count,
+            ts.material_count AS material_count,
+            ts.position_range AS position_range,
+            ts.create_time AS create_time,
+            ts.oper_time AS oper_time,
+            ou.username AS oper_name,
+            ts.task_status AS task_status
+        FROM
+            task_stocktaking ts
+                LEFT JOIN jsh_depot d ON ts.depot_id = d.id
+                LEFT JOIN jsh_user ju ON ts.create_by = ju.id
+                LEFT JOIN jsh_user ou ON ts.oper_by = ou.id
+                LEFT JOIN jsh_user u ON ts.creator = u.id
+        <where>
+            ts.delete_flag = 0
+            <if test="number != null and number != ''">
+                AND (ts.task_name LIKE CONCAT('%',#{taskName},'%') OR ts.number LIKE CONCAT('%',#{number},'%'))
+            </if>
+            <if test="taskStatus != null and taskStatus != 0">
+                AND ts.task_status = #{taskStatus}
+            </if>
+            ORDER BY
+                ts.create_time DESC,
+                ts.id DESC
+        </where>
+    </select>
+
+    <select id="listBy" parameterType="com.jsh.erp.datasource.dto.TaskStocktakingQueryDTO" resultType="com.jsh.erp.datasource.vo.TaskStocktakingVO">
+        SELECT
+            ts.id AS id,
+            ts.number AS number,
+            ts.task_name AS task_name,
+            ts.task_type AS task_type,
+            d.`name` AS depot_name,
+            ts.position_range AS position_range,
+            ju.username AS create_by_name,
+            ts.create_time AS create_time,
+            u.username AS creator_name,
+            ts.task_status AS task_status,
+            ts.oper_time AS oper_time,
+            count(tsi.id) AS item_count,
+            count(tsi.id) AS material_count
+        FROM
+            task_stocktaking ts
+                LEFT JOIN jsh_depot d ON ts.depot_id = d.id
+                LEFT JOIN jsh_user ju ON ts.create_by = ju.id
+                LEFT JOIN jsh_user ou ON ts.oper_by = ou.id
+                LEFT JOIN jsh_user u ON ts.creator = u.id
+                LEFT JOIN task_stocktaking_item tsi ON ts.id = tsi.task_stocktaking_id
+        <where>
+            ts.delete_flag = 0
+            <if test="number != null and number != ''">
+                AND ts.number LIKE CONCAT('%',#{number},'%')
+            </if>
+            <if test="taskStatus != null and taskStatus != 0">
+                AND ts.task_status = #{taskStatus}
+            </if>
+            <if test="depotId != null and depotId !=''">
+                AND ts.depot_id = #{depotId}
+            </if>
+            <if test="createName != null and createName !=''">
+                AND ju.username LIKE CONCAT('%',#{createName},'%')
+            </if>
+        GROUP BY
+            ts.id
+        ORDER BY
+            ts.create_time DESC,
+            ts.id DESC
+        </where>
+    </select>
+
 </mapper>