From 56efd0aa54e2c5cea81ff9b28855bca520dee475 Mon Sep 17 00:00:00 2001
From: mitao <2763622819@qq.com>
Date: 星期五, 17 十月 2025 16:42:43 +0800
Subject: [PATCH] 无形广告资产接口

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetInventoryTaskServiceImpl.java |  502 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 481 insertions(+), 21 deletions(-)

diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetInventoryTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetInventoryTaskServiceImpl.java
index a74e2a6..ba48eb4 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetInventoryTaskServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/AssetInventoryTaskServiceImpl.java
@@ -1,29 +1,48 @@
 package com.ruoyi.system.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.entity.TDept;
+import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.SecurityUtils;
-import com.ruoyi.system.dto.asset.AddInventoryTaskDTO;
+import com.ruoyi.system.constants.AssetDeptConstant;
+import com.ruoyi.system.dto.asset.AssetInventoryTaskDTO;
+import com.ruoyi.system.dto.asset.AssetInventoryTaskItemDTO;
+import com.ruoyi.system.dto.asset.AssetInventoryTaskItemUpdateDTO;
+import com.ruoyi.system.dto.asset.AssetInventoryUserUpdateDTO;
+import com.ruoyi.system.emums.AssetInventoryTaskStatusEnum;
 import com.ruoyi.system.mapper.AssetInventoryTaskMapper;
-import com.ruoyi.system.mapper.TDeptMapper;
+import com.ruoyi.system.model.AssetInventoryRecord;
 import com.ruoyi.system.model.AssetInventoryTask;
 import com.ruoyi.system.model.AssetInventoryTaskItem;
 import com.ruoyi.system.query.AssertInventoryQuery;
+import com.ruoyi.system.query.InventoryTaskQuery;
+import com.ruoyi.system.service.AssetInventoryRecordService;
 import com.ruoyi.system.service.AssetInventoryTaskItemService;
 import com.ruoyi.system.service.AssetInventoryTaskService;
+import com.ruoyi.system.service.ISysUserService;
+import com.ruoyi.system.service.TDeptService;
+import com.ruoyi.system.vo.asset.AssetInventoryTaskDetailVO;
 import com.ruoyi.system.vo.asset.AssetInventoryTaskVO;
+import com.ruoyi.system.vo.asset.AssetMainInventoryVO;
+import com.ruoyi.system.vo.asset.InventoryTaskStatisticsVO;
+import com.ruoyi.system.vo.asset.InventoryTaskTabVO;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -38,13 +57,19 @@
  * @author WuGuanFengYue
  * @since 2025-09-15
  */
+@Slf4j
 @Service
 @RequiredArgsConstructor(onConstructor_ = {@Lazy})
 public class AssetInventoryTaskServiceImpl extends ServiceImpl<AssetInventoryTaskMapper, AssetInventoryTask> implements AssetInventoryTaskService {
 
-    private final TDeptMapper tDeptMapper;
-
+    private final TDeptService deptService;
     private final AssetInventoryTaskItemService assetInventoryTaskItemService;
+    private final ISysUserService sysUserService;
+    private final AssetInventoryRecordService inventoryRecordService;
+
+    // 静态常量,避免重复创建
+    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+    private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);
 
     @Override
     public IPage<AssetInventoryTaskVO> getInventoryTaskPage(AssertInventoryQuery query) {
@@ -71,7 +96,7 @@
         // 5. 批量查询部门信息
         List<TDept> depts = deptIds.isEmpty() ?
                 Collections.emptyList() :
-                tDeptMapper.selectBatchIds(deptIds);
+                deptService.listByIds(deptIds);
 
         // 6. 构建部门ID->名称的映射Map
         Map<Integer, String> deptNameMap = depts.stream()
@@ -94,27 +119,30 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean createInventoryTask(AddInventoryTaskDTO dto) {
-        // 1. DTO转Entity
+    public boolean createInventoryTask(AssetInventoryTaskDTO dto) {
+        // 1. 提前获取当前用户信息,避免重复调用
+        SysUser currentUser = SecurityUtils.getLoginUser().getUser();
+        Integer currentUserId = Math.toIntExact(currentUser.getUserId());
+
+        // 2. DTO转Entity
         AssetInventoryTask task = new AssetInventoryTask();
         BeanUtil.copyProperties(dto, task);
 
-        // 2. 设置默认值
-        SysUser currentUser = SecurityUtils.getLoginUser().getUser();
-        task.setUserId(Math.toIntExact(currentUser.getUserId()));
+        // 3. 设置默认值
+        task.setUserId(currentUserId);
         task.setStatus(0); // 未开始状态
         task.setCreateTime(LocalDateTime.now());
         task.setCreateBy(currentUser.getUserName());
         task.setDisabled(false);
 
-        // 3. 保存主任务
+        // 4. 保存主任务
         boolean saved = this.save(task);
         if (!saved) {
             throw new RuntimeException("保存盘点任务失败");
         }
 
-        // 4. 批量创建资产明细
-        List<AssetInventoryTaskItem> items = buildTaskItems(task.getId(), dto.getAssetMainIds());
+        // 5. 批量创建资产明细
+        List<AssetInventoryTaskItem> items = buildTaskItems(task.getId(), dto.getAssetMains(), currentUserId);
         return assetInventoryTaskItemService.saveBatch(items);
     }
 
@@ -122,22 +150,454 @@
      * 构建盘点任务资产明细列表
      *
      * @param taskId 盘点任务ID
-     * @param assetMainIds 资产ID列表
+     * @param assetMains 资产盘点项列表
+     * @param currentUserId 当前用户ID
      * @return 资产明细列表
      */
-    private List<AssetInventoryTaskItem> buildTaskItems(Integer taskId, List<Integer> assetMainIds) {
-        SysUser currentUser = SecurityUtils.getLoginUser().getUser();
-        Integer currentUserId = Math.toIntExact(currentUser.getUserId());
+    private List<AssetInventoryTaskItem> buildTaskItems(Integer taskId,
+                                                       List<AssetInventoryTaskDTO.AssetMainDTO> assetMains,
+                                                       Integer currentUserId) {
+        // 参数验证
+        if (taskId == null) {
+            throw new IllegalArgumentException("盘点任务ID不能为空");
+        }
 
-        return assetMainIds.stream()
-                .map(assetId -> {
+        if (assetMains == null || assetMains.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        return assetMains.stream()
+                .filter(Objects::nonNull) // 过滤掉null元素
+                .filter(assetMain -> assetMain.getAssetMainId() != null) // 过滤掉assetMainId为null的元素
+                .map(assetMain -> {
                     AssetInventoryTaskItem item = new AssetInventoryTaskItem();
                     item.setInventoryTaskId(taskId);
-                    item.setAssetMainId(assetId);
-                    item.setUserId(currentUserId);
+                    item.setAssetMainId(assetMain.getAssetMainId());
+                    // 如果DTO中指定了盘点人ID,使用指定的;否则使用当前用户
+                    item.setUserId(assetMain.getUserId() != null ? assetMain.getUserId() : currentUserId);
                     item.setResultStatus(0); // 未盘点状态
                     return item;
                 })
                 .collect(Collectors.toList());
     }
+
+    @Override
+    public void deleteById(Integer id) {
+        this.removeById(id);
+        assetInventoryTaskItemService.lambdaUpdate()
+                .eq(AssetInventoryTaskItem::getInventoryTaskId, id)
+                .remove();
+    }
+
+    @Override
+    public List<InventoryTaskTabVO> getInventoryTaskTabData() {
+        // 数据权限:超级管理员/资产管理部、董事长、总经理查看所有数据,其他部门查看当前及下级部门的数据
+        Long userId = SecurityUtils.getUserId();
+        boolean isAdmin = SecurityUtils.isAdmin(userId);
+        boolean hasNoPermission = isAdmin;
+        if (!isAdmin) {
+            try {
+                // 获取当前用户的部门名称
+                String deptName = sysUserService.selectUserById(userId).getDept().getDeptName();
+
+                // 非超级管理员且非资产管理部,设置部门权限
+                if (!AssetDeptConstant.ASSET_INVENTORY_DEPT_NAMES.contains(deptName)) {
+                    hasNoPermission =  true;
+                }
+            } catch (Exception e) {
+                // 如果获取部门信息失败
+            }
+        }
+        // 1. 查询所有有效的盘点任务,支持筛选条件
+        LambdaQueryWrapper<AssetInventoryTask> taskWrapper = new LambdaQueryWrapper<>();
+        taskWrapper.eq(AssetInventoryTask::getDisabled, false)
+                .ne(AssetInventoryTask::getStatus, AssetInventoryTaskStatusEnum.CANCELED.getCode())
+                   .orderByDesc(AssetInventoryTask::getCreateTime);
+        // 按部门筛选
+        if (hasNoPermission) {
+            //没有权限,根据盘点人查询任务列表
+            taskWrapper.apply("EXISTS (SELECT 1 FROM asset_inventory_task_item item WHERE item.inventory_task_id = id AND item.user_id = {0})", Math.toIntExact(userId));
+        }
+
+        try {
+            SysUser currentUser = SecurityUtils.getLoginUser().getUser();
+            taskWrapper.eq(AssetInventoryTask::getUserId, Math.toIntExact(currentUser.getUserId()));
+        } catch (Exception e) {
+            // 如果获取用户信息失败,不应用筛选条件
+            log.warn("获取当前用户信息失败,不应用'我的任务'筛选条件", e);
+        }
+
+        List<AssetInventoryTask> tasks = this.list(taskWrapper);
+        if (tasks.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // 2. 收集任务ID并查询相关的任务项
+        List<Integer> taskIds = tasks.stream()
+                .map(AssetInventoryTask::getId)
+                .collect(Collectors.toList());
+
+        LambdaQueryWrapper<AssetInventoryTaskItem> itemWrapper = new LambdaQueryWrapper<>();
+        itemWrapper.in(AssetInventoryTaskItem::getInventoryTaskId, taskIds);
+        List<AssetInventoryTaskItem> items = assetInventoryTaskItemService.list(itemWrapper);
+
+        // 3. 按任务ID分组统计任务项
+        Map<Integer, List<AssetInventoryTaskItem>> itemGroupMap = items.stream()
+                .collect(Collectors.groupingBy(AssetInventoryTaskItem::getInventoryTaskId));
+
+        // 4. 批量查询部门信息
+        List<Integer> deptIds = tasks.stream()
+                .map(AssetInventoryTask::getDeptId)
+                .filter(Objects::nonNull)
+                .distinct()
+                .collect(Collectors.toList());
+
+        List<TDept> depts = deptIds.isEmpty() ?
+                Collections.emptyList() :
+                deptService.listByIds(deptIds);
+
+        Map<Integer, String> deptNameMap = depts.stream()
+                .collect(Collectors.toMap(TDept::getId, TDept::getDeptName));
+
+        // 5. 构建返回结果,使用优化的统计方法
+        return tasks.stream().map(task -> {
+            InventoryTaskTabVO vo = new InventoryTaskTabVO();
+            vo.setId(task.getId());
+            vo.setTaskName(task.getTaskName());
+            vo.setStatus(task.getStatus());
+            vo.setExecuteDate(task.getExecuteDate() != null ? task.getExecuteDate().format(DATE_FORMATTER) : null);
+            vo.setDeptName(task.getDeptId() != null ? deptNameMap.get(task.getDeptId()) : null);
+
+            // 使用优化的统计方法计算任务数据
+            List<AssetInventoryTaskItem> taskItems = itemGroupMap.getOrDefault(task.getId(), Collections.emptyList());
+            calculateTaskStatistics(taskItems,vo);
+            return vo;
+        }).collect(Collectors.toList());
+    }
+
+    /**
+     * 计算任务统计数据
+     *
+     * @param taskItems 任务项列表
+     * @return 统计数据
+     */
+    private void calculateTaskStatistics(List<AssetInventoryTaskItem> taskItems,InventoryTaskTabVO vo) {
+        if (taskItems.isEmpty()) {
+            vo.setCompletedCount(0);
+            vo.setPendingCount(0);
+            vo.setProgressPercentage(BigDecimal.ZERO);
+
+        }
+
+        // 已完成数量:resultStatus != 0 (1-正常,2-异常都算已完成)
+        long completedCount = taskItems.stream()
+                .filter(item -> item.getResultStatus() != null && item.getResultStatus() != 0)
+                .count();
+
+        long totalCount = taskItems.size();
+        long pendingCount = totalCount - completedCount;
+
+        // 计算进度百分比,使用预定义常量
+        BigDecimal progress = totalCount > 0 ?
+            HUNDRED.multiply(BigDecimal.valueOf(completedCount))
+                   .divide(BigDecimal.valueOf(totalCount), 2, RoundingMode.HALF_UP) :
+            BigDecimal.ZERO;
+        vo.setCompletedCount((int) completedCount);
+        vo.setPendingCount((int) pendingCount);
+        vo.setProgressPercentage(progress);
+    }
+
+    @Override
+    public AssetInventoryTaskDetailVO getDetail(Integer id) {
+        // 1. 参数验证
+        if (id == null) {
+            throw new IllegalArgumentException("盘点任务ID不能为空");
+        }
+
+        // 2. 查询任务基本信息
+        AssetInventoryTask task = this.getById(id);
+        if (task == null || task.getDisabled()) {
+            throw new IllegalArgumentException("盘点任务不存在或已被禁用");
+        }
+
+        // 3. 查询部门信息
+        String deptName = null;
+        if (task.getDeptId() != null) {
+            TDept dept = deptService.getById(task.getDeptId());
+            deptName = dept != null ? dept.getDeptName() : null;
+        }
+
+        // 4. 查询资产列表
+        List<AssetMainInventoryVO> assetList = baseMapper.getAssetMainInventoryList(id);
+
+        // 5. 查询盘点人姓名并拼接
+        List<String> userNames = baseMapper.getInventoryUserNames(id);
+        String userNamesStr = userNames != null && !userNames.isEmpty() ?
+                String.join(",", userNames) : "";
+
+        // 6. 构建返回结果
+        AssetInventoryTaskDetailVO detailVO = new AssetInventoryTaskDetailVO();
+        detailVO.setId(task.getId());
+        detailVO.setDeptId(task.getDeptId());
+        detailVO.setDeptName(deptName);
+        detailVO.setExecuteDate(task.getExecuteDate() );
+        detailVO.setUserNames(userNamesStr);
+        detailVO.setAssetMainInventoryVOS(assetList);
+
+        return detailVO;
+    }
+
+    @Override
+    public IPage<AssetMainInventoryVO> getListByTaskId(InventoryTaskQuery query) {
+        return baseMapper.getAssetMainInventoryPageList(new Page<>(query.getPageNum(), query.getPageSize()), query);
+    }
+
+    @Override
+    public InventoryTaskStatisticsVO getInventoryTaskStatistics(Integer taskId) {
+        // 参数验证
+        if (taskId == null) {
+            throw new ServiceException("盘点任务ID不能为空");
+        }
+
+        // 验证任务是否存在
+        AssetInventoryTask task = this.getById(taskId);
+        if (task == null || task.getDisabled()) {
+            throw new ServiceException("盘点任务不存在或已被禁用");
+        }
+
+        // 查询统计数据
+        InventoryTaskStatisticsVO statistics = baseMapper.getInventoryTaskStatistics(taskId);
+
+        // 如果查询结果为null,返回空统计数据对象
+        return statistics != null ? statistics : InventoryTaskStatisticsVO.empty();
+    }
+
+    @Override
+    public void start(Integer id) {
+        AssetInventoryTask assetInventoryTask = this.getById(id);
+        if (Objects.isNull(assetInventoryTask)) {
+            throw new ServiceException("盘点任务不存在");
+        }
+        assetInventoryTask.setStatus(1); //进行中
+        assetInventoryTask.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
+        this.updateById(assetInventoryTask);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateInventoryUser(AssetInventoryUserUpdateDTO dto) {
+        log.info("开始修改盘点人,参数:{}", dto);
+
+        // 1. 检查盘点任务是否存在且状态允许修改
+        AssetInventoryTask task = this.getById(dto.getTaskId());
+        if (Objects.isNull(task)) {
+            throw new ServiceException("盘点任务不存在");
+        }
+
+        // 2. 检查盘点任务状态,只有未开始状态(0)才允许修改盘点人
+        if (task.getStatus() != null && task.getStatus() != 0) {
+            String statusText = task.getStatus() == 1 ? "进行中" : "已完成";
+            throw new ServiceException("盘点任务状态为" + statusText + ",不允许修改盘点人");
+        }
+
+        // 3. 查询并更新对应的资产盘点项
+        LambdaQueryWrapper<AssetInventoryTaskItem> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(AssetInventoryTaskItem::getInventoryTaskId, dto.getTaskId())
+               .in(AssetInventoryTaskItem::getAssetMainId, dto.getAssetIds());
+
+        List<AssetInventoryTaskItem> taskItems = assetInventoryTaskItemService.list(wrapper);
+        if (CollUtil.isEmpty(taskItems)) {
+            throw new ServiceException("未找到对应的盘点资产项");
+        }
+
+        // 4. 更新盘点人
+        String currentUserName = SecurityUtils.getLoginUser().getUser().getNickName();
+        taskItems.forEach(item->item.setUserId(dto.getUserId()));
+        boolean updated = assetInventoryTaskItemService.updateBatchById(taskItems);
+
+        if (!updated) {
+            throw new ServiceException("修改盘点人失败");
+        }
+
+        log.info("成功修改盘点人,任务ID:{},资产ID:{},新盘点人ID:{},操作人:{}",
+                dto.getTaskId(), dto.getAssetIds(), dto.getUserId(), currentUserName);
+    }
+
+    /**
+     * 为盘亏资产创建出库记录
+     *
+     * @param taskItem 盘点任务项
+     */
+    private void createInventoryRecordForLoss(AssetInventoryTaskItem taskItem) {
+        try {
+            // 获取当前用户信息
+            SysUser currentUser = SecurityUtils.getLoginUser().getUser();
+
+            // 创建出库记录
+            AssetInventoryRecord record = new AssetInventoryRecord();
+            record.setAssetMainId(taskItem.getAssetMainId());
+            record.setType(1); // 1-出库
+            record.setRemarks("盘点盘亏出库");
+            record.setCreateTime(LocalDateTime.now());
+            record.setCreateBy(currentUser.getUserName());
+            record.setDisabled(false);
+
+            // 保存记录
+            boolean saved = inventoryRecordService.save(record);
+            if (!saved) {
+                log.error("保存盘点盘亏出库记录失败,资产ID:{}", taskItem.getAssetMainId());
+                throw new ServiceException("保存盘点盘亏出库记录失败");
+            }
+
+            log.info("成功创建盘点盘亏出库记录,资产ID:{},盘点项ID:{},操作人:{}",
+                    taskItem.getAssetMainId(), taskItem.getId(), currentUser.getUserName());
+
+        } catch (Exception e) {
+            log.error("创建盘点盘亏出库记录异常,盘点项ID:{},资产ID:{}",
+                    taskItem.getId(), taskItem.getAssetMainId(), e);
+            throw new ServiceException("创建盘点盘亏出库记录失败:" + e.getMessage());
+        }
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void handleResult(List<AssetInventoryTaskItemDTO> dtoList) {
+        Map<Integer, Integer> taskItemMap = dtoList.stream()
+                .collect(Collectors.toMap(AssetInventoryTaskItemDTO::getAssetInventoryTaskItemId, AssetInventoryTaskItemDTO::getDeal));
+        List<AssetInventoryTaskItem> assetInventoryTaskItems = assetInventoryTaskItemService.listByIds(taskItemMap.keySet());
+
+        for (AssetInventoryTaskItem assetInventoryTaskItem : assetInventoryTaskItems) {
+            Integer deal = taskItemMap.get(assetInventoryTaskItem.getId());
+            assetInventoryTaskItem.setDeal(deal);
+
+            // 如果处理方式为盘亏,创建出库记录
+            if (deal != null && deal == 1) {
+                createInventoryRecordForLoss(assetInventoryTaskItem);
+            }
+        }
+        assetInventoryTaskItemService.updateBatchById(assetInventoryTaskItems);
+
+        // 更新任务状态为已完成(盘点结果处理完成)
+        if (CollUtil.isNotEmpty(dtoList) && CollUtil.isNotEmpty(assetInventoryTaskItems)) {
+            // 获取任务ID(从第一个盘点项获取)
+            Integer taskId = assetInventoryTaskItems.get(0).getInventoryTaskId();
+            updateTaskStatusToCompleted(taskId);
+        }
+    }
+
+    /**
+     * 直接更新任务状态为已完成
+     *
+     * @param taskId 盘点任务ID
+     */
+    private void updateTaskStatusToCompleted(Integer taskId) {
+        // 参数验证
+        if (taskId == null) {
+            log.warn("任务ID为空,无法更新任务状态");
+            return;
+        }
+
+        // 检查任务是否存在
+        AssetInventoryTask task = this.getById(taskId);
+        if (task == null) {
+            log.warn("任务不存在,任务ID:{}", taskId);
+            return;
+        }
+
+        // 检查任务是否已经是已完成状态
+        if (task.getStatus() != null && task.getStatus().equals(AssetInventoryTaskStatusEnum.COMPLETED.getCode())) {
+            log.debug("任务已经是已完成状态,任务ID:{}", taskId);
+            return;
+        }
+
+        // 更新任务状态为已完成
+        task.setStatus(AssetInventoryTaskStatusEnum.COMPLETED.getCode());
+        task.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
+        this.updateById(task);
+        log.info("盘点任务状态更新为已完成,任务ID:{},任务名称:{},操作人:{}",
+                taskId, task.getTaskName(), task.getUpdateBy());
+    }
+
+    @Override
+    public boolean cancel(Integer id) {
+        AssetInventoryTask assetInventoryTask = this.getById(id);
+        if (Objects.nonNull(assetInventoryTask) && !assetInventoryTask.getStatus() .equals(AssetInventoryTaskStatusEnum.COMPLETED.getCode())) {
+            assetInventoryTask.setStatus(AssetInventoryTaskStatusEnum.CANCELED.getCode()); //已取消
+            assetInventoryTask.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
+            return this.updateById(assetInventoryTask);
+        }
+        return false;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void saveInventory(List<AssetInventoryTaskItemUpdateDTO> dtoList) {
+        Map<Integer, AssetInventoryTaskItemUpdateDTO> dtoMap = dtoList.stream()
+                .collect(Collectors.toMap(AssetInventoryTaskItemUpdateDTO::getAssetInventoryTaskItemId, dto -> dto));
+        List<AssetInventoryTaskItem> assetInventoryTaskItems = assetInventoryTaskItemService.listByIds(dtoMap.keySet());
+
+        for (AssetInventoryTaskItem assetInventoryTaskItem : assetInventoryTaskItems) {
+            AssetInventoryTaskItemUpdateDTO dto = dtoMap.get(assetInventoryTaskItem.getId());
+            assetInventoryTaskItem.setResultStatus(dto.getResultStatus());
+            assetInventoryTaskItem.setRealDeptName(dto.getRealDeptName());
+            assetInventoryTaskItem.setRealUserName(dto.getRealUserName());
+            assetInventoryTaskItem.setExceptionExplain(dto.getExceptionExplain());
+        }
+        assetInventoryTaskItemService.updateBatchById(assetInventoryTaskItems);
+
+        // 检查并更新任务状态(保存盘点数据完成)
+        if (CollUtil.isNotEmpty(dtoList) && CollUtil.isNotEmpty(assetInventoryTaskItems)) {
+            // 获取任务ID(从第一个盘点项获取)
+            Integer taskId = assetInventoryTaskItems.get(0).getInventoryTaskId();
+            checkAndUpdateTaskCompletionStatus(taskId);
+        }
+    }
+
+    /**
+     * 检查并更新任务完成状态
+     * 如果任务的所有盘点项都为正常状态,则将任务状态更新为已完成
+     *
+     * @param taskId                  盘点任务ID
+     */
+    private void checkAndUpdateTaskCompletionStatus(Integer taskId) {
+        // 参数验证
+        if (taskId == null) {
+            log.warn("任务ID为空,无法检查任务完成状态");
+            return;
+        }
+
+        // 1. 检查任务是否存在
+        AssetInventoryTask task = this.getById(taskId);
+        if (task == null) {
+            log.warn("任务不存在,任务ID:{}", taskId);
+            return;
+        }
+
+        // 2. 查询任务的所有盘点项
+        LambdaQueryWrapper<AssetInventoryTaskItem> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(AssetInventoryTaskItem::getInventoryTaskId, taskId);
+        List<AssetInventoryTaskItem> allTaskItems = assetInventoryTaskItemService.list(wrapper);
+
+        // 3. 检查是否所有项都已完成且为正常状态(resultStatus = 1)
+        boolean allNormal = !allTaskItems.isEmpty() &&
+                allTaskItems.stream()
+                        .allMatch(item -> item.getResultStatus() != null && item.getResultStatus() == 1);
+
+        // 4. 如果都正常,更新任务状态为已完成
+        if (allNormal) {
+            // 检查任务是否已经是已完成状态
+            if (task.getStatus() != null && !task.getStatus().equals(AssetInventoryTaskStatusEnum.COMPLETED.getCode())) {
+                task.setStatus(AssetInventoryTaskStatusEnum.COMPLETED.getCode());
+                task.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
+                this.updateById(task);
+                log.info("盘点任务已完成,任务ID:{},任务名称:{},操作人:{}",
+                        taskId, task.getTaskName(), task.getUpdateBy());
+            } else {
+                log.debug("任务已经是已完成状态,任务ID:{}", taskId);
+            }
+        } else {
+            log.debug("任务未完全完成,跳过状态更新,任务ID:{},盘点项总数:{}",
+                    taskId, allTaskItems.size());
+        }
+    }
 }

--
Gitblit v1.7.1