ezhizao_zx 3 mesi fa
parent
commit
c073eda59f

+ 24 - 13
src/main/java/cn/ezhizao/project/system/controller/SysLoginController.java

@@ -9,8 +9,12 @@ import cn.ezhizao.framework.security.service.SysLoginService;
 import cn.ezhizao.framework.security.service.SysPermissionService;
 import cn.ezhizao.framework.web.controller.BaseController;
 import cn.ezhizao.framework.web.domain.AjaxResult;
+import cn.ezhizao.project.system.domain.SysDept;
+import cn.ezhizao.project.system.domain.SysDeptUser;
 import cn.ezhizao.project.system.domain.SysMenu;
 import cn.ezhizao.project.system.domain.SysUser;
+import cn.ezhizao.project.system.service.ISysDeptService;
+import cn.ezhizao.project.system.service.ISysDeptUserService;
 import cn.ezhizao.project.system.service.ISysMenuService;
 import cn.ezhizao.project.tenant.domain.BizTenant;
 import cn.ezhizao.project.tenant.service.IBizTenantService;
@@ -20,6 +24,7 @@ import javax.annotation.Resource;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * 登录验证
@@ -27,8 +32,7 @@ import java.util.Set;
  * @author ruoyi
  */
 @RestController
-public class SysLoginController extends BaseController
-{
+public class SysLoginController extends BaseController {
     @Resource
     private SysLoginService loginService;
 
@@ -40,6 +44,10 @@ public class SysLoginController extends BaseController
 
     @Resource
     private SysPermissionService permissionService;
+    @Resource
+    private ISysDeptUserService deptUserService;
+    @Resource
+    private ISysDeptService deptService;
 
     /**
      * 登录方法
@@ -49,8 +57,7 @@ public class SysLoginController extends BaseController
      */
     @Log(title = "登录", businessType = BusinessType.SELECT)
     @PostMapping("/login")
-    public AjaxResult login(@RequestBody LoginBody loginBody)
-    {
+    public AjaxResult login(@RequestBody LoginBody loginBody) {
         AjaxResult ajax = AjaxResult.success();
         // 正常登录
         Map<String, Object> loginResult = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
@@ -67,8 +74,7 @@ public class SysLoginController extends BaseController
      */
     @Log(title = "用户信息查询", businessType = BusinessType.SELECT)
     @GetMapping("getInfo")
-    public AjaxResult getInfo()
-    {
+    public AjaxResult getInfo() {
         SysUser user = SecurityUtils.getLoginUser().getUser();
         // 角色集合
         Set<String> roles = permissionService.getRolePermission(user);
@@ -78,6 +84,10 @@ public class SysLoginController extends BaseController
         ajax.put("user", user);
         ajax.put("roles", roles);
         ajax.put("permissions", permissions);
+        List<SysDeptUser> userDepts = deptUserService.query().eq("user_id", user.getUserId()).list();
+        List<SysDept> depts = deptService.selectDeptList(new SysDept());
+        depts = depts.stream().filter(e -> userDepts.stream().anyMatch(t -> t.getDeptId().equals(e.getDeptId()))).collect(Collectors.toList());
+        ajax.put("depts", depts);
         return ajax;
     }
 
@@ -88,8 +98,7 @@ public class SysLoginController extends BaseController
      */
     @Log(title = "获取路由信息", businessType = BusinessType.SELECT)
     @GetMapping("getRouters")
-    public AjaxResult getRouters()
-    {
+    public AjaxResult getRouters() {
         Long userId = SecurityUtils.getUserId();
         List<SysMenu> menus = menuService.selectMenuTreeByUserId(userId);
         return AjaxResult.success(menuService.buildMenus(menus));
@@ -97,28 +106,30 @@ public class SysLoginController extends BaseController
 
     /**
      * 根据用户名获取租户列表
+     *
      * @param userName
      * @return
      */
     @Log(title = "根据用户名获取租户列表", businessType = BusinessType.SELECT)
     @GetMapping("/snms/getTenantList/{userName}")
-    public AjaxResult getTenantList(@PathVariable("userName") String userName){
+    public AjaxResult getTenantList(@PathVariable("userName") String userName) {
         List<BizTenant> bizTenantList = loginService.getTenantList(userName);
-        if(bizTenantList ==null|| bizTenantList.size()==0){
+        if (bizTenantList == null || bizTenantList.size() == 0) {
             return error("未找到企业信息!请先注册并认证企业信息");
-        }else{
+        } else {
             return success(bizTenantList);
         }
     }
 
     /**
      * 根据企业名称 模糊查询租户
+     *
      * @param orgName
      * @return
      */
     @Log(title = "根据企业名称 模糊查询租户", businessType = BusinessType.SELECT)
     @GetMapping("/snms/getTenantListByOrgName/{orgName}")
-    public AjaxResult getTenantListByOrgName(@PathVariable("orgName") String orgName){
-        return success(tenantService.query().like("org_name",orgName).list());
+    public AjaxResult getTenantListByOrgName(@PathVariable("orgName") String orgName) {
+        return success(tenantService.query().like("org_name", orgName).list());
     }
 }

+ 4 - 0
src/main/java/cn/ezhizao/project/system/controller/SysUserController.java

@@ -244,6 +244,10 @@ public class SysUserController extends BaseController {
             ajax.put(AjaxResult.DATA_TAG, sysUser);
             ajax.put("postIds", postService.selectPostListByUserId(userId));
             ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
+//            List<SysDeptUser> user = deptUserService.query().eq("user_id", userId).list();
+//            List<SysDept> depts = deptService.selectDeptList(new SysDept());
+//            depts = depts.stream().filter(e -> user.stream().anyMatch(t -> t.getDeptId().equals(e.getDeptId()))).collect(Collectors.toList());
+//            ajax.put("depts", depts);
         }
         return ajax;
     }

+ 154 - 0
src/main/java/cn/ezhizao/project/websocket/WebSocketExport.java

@@ -0,0 +1,154 @@
+package cn.ezhizao.project.websocket;
+
+import cn.ezhizao.project.websocket.domain.BizProcessInspecion;
+import cn.ezhizao.project.websocket.service.TaskService;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.websocket.*;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.util.Date;
+import java.util.concurrent.ConcurrentHashMap;
+
+//前端请求的路径
+
+@ServerEndpoint(value = "/wsExport/{userId}", encoders = {ServerEncoder.class})
+@Component
+public class WebSocketExport {
+    private static final Logger log = LoggerFactory.getLogger(WebSocketUser.class);
+    /**
+     * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
+     */
+    private static int onlineCount = 0;
+    /**
+     * concurrent包的线程安全,用来存放每个客户端对应的MyWebSocket对象。
+     */
+    private static ConcurrentHashMap<String, WebSocketExport> webSocketMap = new ConcurrentHashMap<>();
+    /**
+     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
+     */
+    private Session session;
+    /**
+     * 接收userId
+     */
+    private String userId = "";
+    private String type = "";
+    @Resource
+    TaskService taskService;
+
+//
+//    private static DataInformationServiceImpl dataInformationService;
+//    @Resource
+//    public void setDataInformationService(DataInformationServiceImpl dataInformationService) {
+//        WebSocketUser.dataInformationService = dataInformationService;
+//    }
+
+    /**
+     * 连接建立成功调用的方法
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("userId") String userId) {
+        this.session = session;
+        this.userId = userId;
+        this.type = type;
+        if (webSocketMap.containsKey(userId)) {
+            webSocketMap.remove(userId);
+            webSocketMap.put(userId, this);
+            //加入set中
+        } else {
+            webSocketMap.put(userId, this);
+            //加入set中
+            addOnlineCount();
+            //在线数加1
+        }
+        log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());
+    }
+
+    /**
+     * 连接关闭调用的方法
+     */
+    @OnClose
+    public void onClose() {
+        if (webSocketMap.containsKey(userId)) {
+            webSocketMap.remove(userId);
+            //从set中删除
+            subOnlineCount();
+        }
+        log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
+    }
+
+    /**
+     * 收到客户端消息后调用的方法
+     *
+     * @param message 客户端发送过来的消息
+     */
+    @OnMessage
+    public void onMessage(String message, Session session) {
+        log.info("用户消息:" + userId + ",报文:" + message);
+        //可以群发消息
+        //消息保存到数据库、redis
+        if (StringUtils.isNotBlank(message)) {
+            try {
+//                //解析发送的报文
+//                JSONObject jsonObject = JSON.parseObject(message);
+                JSONObject j = JSON.parseObject(message);
+                BizProcessInspecion i = j.toJavaObject(BizProcessInspecion.class);
+//                taskService.processTaskAsync(i);
+                // 导出excel
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * @param session
+     * @param error
+     */
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
+        error.printStackTrace();
+    }
+
+    /**
+     * 实现服务器主动推送
+     */
+    public void sendMessage(String message) throws IOException {
+        log.info("服务器消息推送:" + message);
+        this.session.getBasicRemote().sendText(message);
+    }
+
+    /**
+     * 发送自定义消息
+     */
+    public static void sendInfo(String message, @PathParam("userId") String userId) throws IOException {
+        log.info("发送消息到:" + userId + ",报文:" + message);
+        if (StringUtils.isNotBlank(userId) && webSocketMap.containsKey(userId)) {
+            webSocketMap.get(userId).sendMessage(message);
+        } else {
+            log.error("用户" + userId + ",不在线!");
+//            webSocketMap.get(userId).sendMessage("用户" + userId + ",不在线!");
+        }
+    }
+
+    public static synchronized int getOnlineCount() {
+        return onlineCount;
+    }
+
+    public static synchronized void addOnlineCount() {
+        WebSocketExport.onlineCount++;
+    }
+
+    public static synchronized void subOnlineCount() {
+        WebSocketExport.onlineCount--;
+    }
+
+} 

+ 38 - 0
src/main/java/cn/ezhizao/project/websocket/controller/AsyncExportController.java

@@ -0,0 +1,38 @@
+package cn.ezhizao.project.websocket.controller;
+
+import cn.ezhizao.framework.aspectj.lang.annotation.Log;
+import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
+import cn.ezhizao.framework.web.controller.BaseController;
+import cn.ezhizao.framework.web.domain.AjaxResult;
+import cn.ezhizao.project.websocket.domain.BizProcessInspecion;
+import cn.ezhizao.project.websocket.service.TaskService;
+import com.alibaba.fastjson2.JSONObject;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@RestController
+@RequestMapping("/business/asyncExport")
+public class AsyncExportController extends BaseController {
+    @Resource
+    private TaskService taskService;
+//    @Resource
+//    private WebSocketUser webSocketUser;
+
+//    @PreAuthorize("@ss.hasPermi('business:asyncExport:export')")
+    @Log(title = "外协审核导出", businessType = BusinessType.EXPORT)
+    @PostMapping("/processInspectionexport")
+    public AjaxResult export(HttpServletResponse response, @RequestBody BizProcessInspecion bizProcessInspecion) throws IOException {
+        taskService.processTaskAsync(bizProcessInspecion, getUserId());
+        JSONObject result = new JSONObject();
+        result.put("status", "start");
+//        WebSocketUser.sendInfo(result.toJSONString(), String.valueOf(getUserId()));
+        // 开始导出
+        return success();
+    }
+}

+ 12 - 0
src/main/java/cn/ezhizao/project/websocket/domain/BizExportTask.java

@@ -0,0 +1,12 @@
+package cn.ezhizao.project.websocket.domain;
+
+import lombok.Data;
+
+@Data
+public class BizExportTask {
+    private String taskId;
+    private ExportTaskStatus status = ExportTaskStatus.CREATED;
+    private int currentPage;
+    private int totalPages;
+    private String tempFilePath;
+}

+ 204 - 0
src/main/java/cn/ezhizao/project/websocket/domain/BizProcessInspecion.java

@@ -0,0 +1,204 @@
+package cn.ezhizao.project.websocket.domain;
+
+import cn.ezhizao.framework.aspectj.lang.annotation.Excel;
+import cn.ezhizao.framework.web.domain.BaseEntity;
+import cn.ezhizao.project.system.domain.SysUser;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 序检主对象 biz_process_inspecion
+ *
+ * @author ezhizao
+ * @date 2024-04-24
+ */
+@Data
+@TableName(value = "biz_process_inspecion")
+public class BizProcessInspecion extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** 租户(厂别)id */
+    @ApiModelProperty(value = "${comment}")
+    private Long tenantId;
+
+    /** 用户id */
+    @ApiModelProperty(value = "${comment}")
+    private Long userId;
+
+    /** 员工编码 */
+    @Excel(name = "员工编码")
+    @ApiModelProperty(value = "员工编码")
+    private String userName;
+
+    /** 员工姓名 */
+    @Excel(name = "员工姓名")
+    @ApiModelProperty(value = "员工姓名")
+    private String nickName;
+
+    @Excel(name = "箱号Id")
+    @ApiModelProperty(value = "箱号Id")
+    private Long carrierId;
+
+    @Excel(name = "箱号code")
+    @ApiModelProperty(value = "箱号code")
+    private String carrierCode;
+
+    /** daywork的id */
+    @ApiModelProperty(value = "员工姓名")
+    private Long dayworkId;
+
+    /** dayworkItemId */
+    private Long dayworkItemId;
+
+    @TableField(exist = true)
+    private String remark;
+
+    /** 计划单id */
+    @ApiModelProperty(value = "员工姓名")
+    private Long productionPlanId;
+
+    /** 计划单明细id */
+    @ApiModelProperty(value = "员工姓名")
+    private Long productionPlanDetailId;
+
+    /** 子计划id */
+    @ApiModelProperty(value = "员工姓名")
+    private Long productionPlanDetailSubDetailId;
+
+    /** 批次id */
+    @ApiModelProperty(value = "员工姓名")
+    private Long lotId;
+
+    /** 批次号 */
+    @Excel(name = "批次号")
+    @ApiModelProperty(value = "批次号")
+    private String lotCode;
+
+    /** 工段id(当前工段的id) */
+    @ApiModelProperty(value = "批次号")
+    private Long deptId;
+
+    /** 产品id */
+    @ApiModelProperty(value = "批次号")
+    private Long productId;
+
+    /** 工艺id(通过工艺id,获取版本号) */
+    @ApiModelProperty(value = "批次号")
+    private Long technologicalProcessId;
+
+    /** 废品量 */
+    @Excel(name = "废品量")
+    @ApiModelProperty(value = "废品量")
+    private Integer rejectNum;
+
+    /** 检测量 */
+    @Excel(name = "检测量")
+    @ApiModelProperty(value = "检测量")
+    private Integer examiningNum;
+
+    /** 开始时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "开始时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @ApiModelProperty(value = "开始时间")
+    private Date startTime;
+
+    /** 结束时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "结束时间", width = 30, dateFormat = "yyyy-MM-dd")
+    @ApiModelProperty(value = "结束时间")
+    private Date endTime;
+
+    /** 批次生产状态(0:未开始,1:进行中,2:已完成) */
+    @Excel(name = "批次生产状态", readConverterExp = "0=:未开始,1:进行中,2:已完成")
+    @ApiModelProperty(value = "批次生产状态")
+    private Integer status;
+
+
+    /** 产品描述 */
+    private String productDescription;
+
+    @TableField(exist = false)
+    private SysUser user;
+
+    @TableField(exist = false)
+    private String keyword;
+
+    private Long returnReceiptDetailId;
+    @ApiModelProperty("第一修改人")
+    private Long firstUpdaterId;
+
+    @ApiModelProperty("不合格数量")
+    private Integer disqualificationNum;
+
+    @ApiModelProperty("质检箱解绑")
+    private Integer isInspectionCarrierChanged;
+
+    @ApiModelProperty("质检箱解绑时间")
+    private Date inspectionCarrierChangedTime;
+
+    @ApiModelProperty("外协序检工序")
+    private String processNames;
+
+    @ApiModelProperty("审核人")
+    private Long reviewerId;
+
+    @ApiModelProperty("外协单id")
+    private Long outsourceOrderDetailId;
+    @ApiModelProperty("外协单id")
+    private Long outsourceOrderId;
+    @TableField(exist = false)
+    private String processAlias;
+    @TableField(exist = false)
+    private String technologyVersion;
+    @TableField(exist = false)
+    private String deptName;
+    @TableField(exist = false)
+    private String drawingNumber;
+
+    @ApiModelProperty("复检时间")
+    private Date recheckDate;
+    @ApiModelProperty("自动外协检查")
+    private Integer isAuto;
+    @ApiModelProperty("外协检查单号")
+    private String outsourcedInspectionNo;
+    @ApiModelProperty("外协检查审核状态")
+    private Integer auditStatus;
+    @ApiModelProperty("是否为外协序检")
+    private Integer isOutsourcedInspection;
+    @TableField(exist = false)
+    private String supplierName;
+    @TableField(exist = false)
+    private String mnemonicCode;
+    @TableField(exist = false)
+    private Integer materialLoss;
+    @TableField(exist = false)
+    private String processName;
+
+    @TableField(exist = false)
+    private String technicianCode;
+
+    @TableField(exist = false)
+    private String technicianName;
+    private String type;
+    private String equipmentDetailCode;
+    private Long equipmentDetailId;
+    private Integer inspectionStatus;
+    @TableField(exist = false)
+    private String outsourcedOrderDetailFormCode;
+    @TableField(exist = false)
+    private String returnReceiptDetailFormCode;
+    private Integer adoptStatus;
+    @TableField(exist = false)
+    private Integer start;
+    @TableField(exist = false)
+    private Integer pageSize;
+
+
+}

+ 27 - 0
src/main/java/cn/ezhizao/project/websocket/domain/BizProcessInspectionExport.java

@@ -0,0 +1,27 @@
+package cn.ezhizao.project.websocket.domain;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BizProcessInspectionExport {
+    private String supplierName;
+    private String mnemonicCode;
+    private Integer productNum;
+    private Integer auditNum;
+    private String productDescription;
+    private String lotCode;
+    private Integer materialLoss;
+    private String processAlias;
+    private String auditStatus;
+    private Date startTime;
+    private Date endTime;
+    private Date outsourceDate;
+    private Date returnReceiptDate;
+    private Date auditDate;
+    private Date balanceDate;
+    private String outsourcedOrderDetailFormCode;
+    private String returnReceiptDetailFormCode;
+    private Integer carrierNum;
+}

+ 9 - 0
src/main/java/cn/ezhizao/project/websocket/domain/ExportTaskStatus.java

@@ -0,0 +1,9 @@
+package cn.ezhizao.project.websocket.domain;
+
+public enum ExportTaskStatus {
+    CREATED,
+    PROCESSING,
+    PAUSED,
+    COMPLETED,
+    CANCELLED
+}

+ 20 - 0
src/main/java/cn/ezhizao/project/websocket/mapper/BizProcessInspecionMapper.java

@@ -0,0 +1,20 @@
+package cn.ezhizao.project.websocket.mapper;
+
+import cn.ezhizao.project.websocket.domain.BizProcessInspecion;
+import cn.ezhizao.project.websocket.domain.BizProcessInspectionExport;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+import java.util.List;
+
+/**
+ * 序检主Mapper接口
+ *
+ * @author ezhizao
+ * @date 2024-04-24
+ */
+public interface BizProcessInspecionMapper extends BaseMapper<BizProcessInspecion> {
+
+    List<BizProcessInspectionExport> getExportList(BizProcessInspecion bizProcessInspecion);
+
+    Long getCountForExport(BizProcessInspecion bizProcessInspecion);
+}

+ 52 - 0
src/main/java/cn/ezhizao/project/websocket/service/AsyncTaskService.java

@@ -0,0 +1,52 @@
+package cn.ezhizao.project.websocket.service;
+
+import cn.ezhizao.project.websocket.domain.BizExportTask;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+public class AsyncTaskService {
+    private final Map<String, BizExportTask> taskStore = new ConcurrentHashMap<>();
+    @Async
+    public void processTask(String taskId) {
+//        BizExportTask task = createNewTask(taskId, request);
+//
+//        try (SXSSFWorkbook workbook = new SXSSFWorkbook(1000)) {
+//            while (task.getCurrentPage() < task.getTotalPages()) {
+//                // 检查任务状态
+//                if (checkPausedOrCancelled(task)) break;
+//
+//                // 处理当前分页
+//                List<Data> data = fetchData(task.getCurrentPage(), request);
+//                writeToSheet(workbook, data);
+//
+//                // 更新进度
+//                task.setCurrentPage(task.getCurrentPage() + 1);
+//                updateProgress(taskId, calculateProgress(task));
+//            }
+//
+//            // 处理最终状态
+//            if (task.getStatus() == ExportTaskStatus.PAUSED) {
+//                saveTempFile(workbook, task); // 保存临时文件
+//            } else if (task.getStatus() == ExportTaskStatus.PROCESSING) {
+//                completeTask(task, workbook);
+//            }
+//        }
+    }
+
+//    private boolean checkPausedOrCancelled(ExportTask task) {
+//        synchronized (task.getTaskId().intern()) {
+//            if (task.getStatus() == ExportTaskStatus.PAUSED) {
+//                return true;
+//            }
+//            if (task.getStatus() == ExportTaskStatus.CANCELLED) {
+//                cleanupTask(task);
+//                return true;
+//            }
+//        }
+//        return false;
+//    }
+}

+ 139 - 0
src/main/java/cn/ezhizao/project/websocket/service/TaskService.java

@@ -0,0 +1,139 @@
+package cn.ezhizao.project.websocket.service;
+
+import cn.ezhizao.common.utils.uuid.SnowflakeIdWorker;
+import cn.ezhizao.project.websocket.WebSocketUser;
+import cn.ezhizao.project.websocket.domain.BizProcessInspecion;
+import cn.ezhizao.project.websocket.domain.BizProcessInspectionExport;
+import cn.ezhizao.project.websocket.mapper.BizProcessInspecionMapper;
+import cn.hutool.poi.excel.ExcelUtil;
+import cn.hutool.poi.excel.ExcelWriter;
+import com.alibaba.fastjson2.JSONObject;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@Service
+public class TaskService {
+    //    @Resource
+//    WebSocketUser webSocketUser;
+    @Resource
+    BizProcessInspecionMapper bizProcessInspecionMapper;
+    @Value("${file.upload.path}")
+    private String filePath;
+    @Value("${file.upload.url}")
+    private String uploadUrl;
+
+    @Resource
+    SnowflakeIdWorker snowflakeIdWorker;
+
+    @Async
+//    @Log(title = "导出外协审核列表", businessType = BusinessType.EXPORT)
+    public void processTaskAsync(BizProcessInspecion bizProcessInspecion, Long userId) {
+        try {
+            // 获取所有整年的检查的数量
+            Long count = bizProcessInspecionMapper.getCountForExport(bizProcessInspecion);
+            // 判断行数
+            int pageSize = 1000;
+            int pageNum = 0;
+            int rowIndex = 0;
+            ExcelWriter writer = ExcelUtil.getWriter(true);
+            // 文件导出位置
+            File file = new File(filePath + "/excel");
+            JSONObject result = new JSONObject();
+            // 判断文件夹是否存在,假设不存在则创建
+            if (!file.exists() && !file.isDirectory()) {
+                file.mkdir();
+            }
+            // 分页
+            // 循环
+            // 存到excel中
+//            while(rowIndex < 30000) {
+//                pageNum = 0;
+            for (; pageNum < (count % 1000 > 0 ? (count / 1000 + 1) : count / 1000); pageNum++) {
+                bizProcessInspecion.setStart(pageNum * pageSize);
+                bizProcessInspecion.setPageSize(pageSize);
+                List<BizProcessInspectionExport> exportList = bizProcessInspecionMapper.getExportList(bizProcessInspecion);
+                rowIndex = insertToSheet(writer, rowIndex, exportList);
+                // 每页发送消息到前端告知完成状态
+                result.put("progress", BigDecimal.valueOf((long) rowIndex - 1).divide(BigDecimal.valueOf(count), 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
+                WebSocketUser.sendInfo(result.toJSONString(), String.valueOf(userId));
+            }
+//            }
+            // excel输出到文件夹
+            // 完成后保存到本地
+            String fileName = String.valueOf(snowflakeIdWorker.nextId());
+            FileOutputStream out = new FileOutputStream(file.getAbsolutePath() + "/" + fileName + ".xlsx");
+            writer.flush(out);
+            writer.close();
+            result.put("progress", 100);
+            result.put("url", "/profile/upload" + "/excel/" + fileName + ".xlsx");
+            WebSocketUser.sendInfo(result.toJSONString(), String.valueOf(userId));
+        } catch (Exception e) {
+            // 处理错误
+            JSONObject err = new JSONObject();
+            err.put("err", "保存出错");
+            try {
+                WebSocketUser.sendInfo(err.toJSONString(), String.valueOf(userId));
+            } catch (IOException ex) {
+                throw new RuntimeException(ex);
+            }
+            throw new RuntimeException("导出错误");
+        }
+    }
+
+    public Integer insertToSheet(ExcelWriter writer, Integer rowIndex, List<BizProcessInspectionExport> data) {
+        if (rowIndex == 0) {
+            // 输出第一行表头
+            writer.writeCellValue(0, rowIndex, "单位编码");
+            writer.writeCellValue(1, rowIndex, "单位简称");
+            writer.writeCellValue(2, rowIndex, "产品描述");
+            writer.writeCellValue(3, rowIndex, "批号");
+            writer.writeCellValue(4, rowIndex, "发出量");
+            writer.writeCellValue(5, rowIndex, "投入数量");
+            writer.writeCellValue(6, rowIndex, "收回量");
+            writer.writeCellValue(7, rowIndex, "料损数量");
+            writer.writeCellValue(8, rowIndex, "工序简称");
+            writer.writeCellValue(9, rowIndex, "发出日期");
+            writer.writeCellValue(10, rowIndex, "收回日期");
+            writer.writeCellValue(11, rowIndex, "审核日期");
+            writer.writeCellValue(12, rowIndex, "结算日期");
+            writer.writeCellValue(13, rowIndex, "发出单号");
+            writer.writeCellValue(14, rowIndex, "收回单号");
+            writer.writeCellValue(15, rowIndex, "箱数");
+            writer.writeCellValue(16, rowIndex, "审核状态");
+            return insertToSheet(writer, rowIndex + 1, data);
+        } else {
+            AtomicInteger i = new AtomicInteger();
+            data.forEach(l -> {
+                writer.writeCellValue(0, rowIndex + i.get(), l.getMnemonicCode());
+                writer.writeCellValue(1, rowIndex + i.get(), l.getSupplierName());
+                writer.writeCellValue(2, rowIndex + i.get(), l.getProductDescription());
+                writer.writeCellValue(3, rowIndex + i.get(), l.getLotCode());
+                writer.writeCellValue(4, rowIndex + i.get(), l.getProductNum());
+                writer.writeCellValue(5, rowIndex + i.get(), l.getProductNum());
+                writer.writeCellValue(6, rowIndex + i.get(), l.getAuditNum());
+                writer.writeCellValue(7, rowIndex + i.get(), l.getMaterialLoss());
+                writer.writeCellValue(8, rowIndex + i.get(), l.getProcessAlias());
+                writer.writeCellValue(9, rowIndex + i.get(), l.getOutsourceDate());
+                writer.writeCellValue(10, rowIndex + i.get(), l.getReturnReceiptDate());
+                writer.writeCellValue(11, rowIndex + i.get(), l.getAuditDate());
+                writer.writeCellValue(12, rowIndex + i.get(), l.getBalanceDate());
+                writer.writeCellValue(13, rowIndex + i.get(), l.getOutsourcedOrderDetailFormCode());
+                writer.writeCellValue(14, rowIndex + i.get(), l.getReturnReceiptDetailFormCode());
+                writer.writeCellValue(15, rowIndex + i.get(), l.getCarrierNum());
+                writer.writeCellValue(16, rowIndex + i.get(), l.getAuditStatus());
+                i.getAndIncrement();
+            });
+            return rowIndex + data.size();
+        }
+    }
+}

+ 57 - 0
src/main/resources/mybatis/websocket/BizProcessInspecionMapper.xml

@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.ezhizao.project.websocket.mapper.BizProcessInspecionMapper">
+    <resultMap id="ExportResult" type="cn.ezhizao.project.websocket.domain.BizProcessInspectionExport">
+    </resultMap>
+
+    <select id="getExportList" parameterType="BizProcessInspecion" resultMap="ExportResult">
+        select bs.code as mnemonic_code, bs.name as supplier_name, bod.product_num, brr.audit_num, bod.lot_code
+        , (case when bod.product_num &lt; brr.audit_num then 0 else bod.product_num - brr.audit_num end) as material_loss
+        , brr.process_alias, brr.new_carrier_count as carrier_num
+        , (case when bpi.audit_status = 1 then '已审核' else '未审核' end) as audit_status, bpi.start_time, bpi.end_time, bpi.reject_num, bpi.lot_code, bpi.product_description, bod.form_code as outsourcedOrder_detail_form_code, bod.form_date as outsource_date, brr.form_code as return_receipt_detail_form_code, brr.form_date as return_receipt_date, (case when bpi.audit_status = 1 then bpi.update_time else null end) as audit_date, (select boa.update_time from biz_outsource_balance_account boa where boa.status = 1 and boa.process_inspection_id = bpi.id order by update_time desc limit 1) as balance_date from biz_process_inspecion bpi
+        left join biz_outsourced_order_detail bod on bod.id = bpi.outsource_order_detail_id left join biz_return_receipt_detail brr on brr.id = bpi.return_receipt_detail_id
+        left join biz_supplier bs on bs.id = bod.supplier_id
+        <trim prefix=" WHERE" suffix="" suffixOverrides="AND">
+            recheck_date is null and is_outsourced_inspection = 1 and bpi.deleted = 0
+            <if test="lotCode != null  and lotCode != ''">AND bpi.lot_code like concat ('%',#{lotCode},'%')</if>
+            <if test="userId != null  ">AND bpi.user_id = #{userId}</if>
+            <if test="status != null ">AND bpi.status = #{status}</if>
+            <if test="startTime != null"> AND DATE(bpi.start_time) &gt;= #{startTime}</if>
+            <if test="endTime != null"> AND DATE(bpi.start_time) &lt;= #{endTime}</if>
+            <!--            <if test="startTime != null"> AND t.date_format(t.start_time, '%Y-%m-%d') = date_format(#{startTime}, '%Y-%m-%d')</if>-->
+            <if test="supplierName != null">AND exists (select supplier_name from biz_outsourced_order_detail o where o.id = bpi.outsource_order_detail_id and o.supplier_name like concat('%', #{supplierName}, '%'))</if>
+            <if test="returnReceiptDetailFormCode != null ">AND rrd.form_code like concat('%', #{returnReceiptDetailFormCode}, '%') </if>
+            <if test="outsourcedOrderDetailFormCode != null ">AND bod.form_code like concat('%', #{outsourcedOrderDetailFormCode}, '%') </if>
+            <if test="auditStatus != null ">AND bpi.audit_status = #{auditStatus}</if>
+            <if test="keyword != null  and keyword !='' ">AND (bpi.lot_code LIKE CONCAT('%',#{keyword},'%') OR bpi.carrier_code
+                LIKE CONCAT('%',#{keyword},'%') OR
+                bpi.product_description LIKE CONCAT('%',#{keyword},'%'))</if>
+        </trim>
+        <if test="start != null and pageSize != null">
+            limit #{start}, #{pageSize}
+        </if>
+    </select>
+    <select id="getCountForExport" resultType="java.lang.Long" parameterType="BizProcessInspecion">
+        select count(1) from biz_process_inspecion bpi
+        left join biz_outsourced_order_detail bod on bod.id = bpi.outsource_order_detail_id left join biz_return_receipt_detail brr on brr.id = bpi.return_receipt_detail_id
+        left join biz_supplier bs on bs.id = bod.supplier_id
+        <trim prefix=" WHERE" suffix="" suffixOverrides="AND">
+            recheck_date is null and is_outsourced_inspection = 1 and bpi.deleted = 0
+            <if test="lotCode != null  and lotCode != ''">AND bpi.lot_code like concat ('%',#{lotCode},'%')</if>
+            <if test="userId != null  ">AND bpi.user_id = #{userId}</if>
+            <if test="status != null ">AND bpi.status = #{status}</if>
+            <if test="startTime != null"> AND DATE(bpi.start_time) &gt;= #{startTime}</if>
+            <if test="endTime != null"> AND DATE(bpi.start_time) &lt;= #{endTime}</if>
+            <!--            <if test="startTime != null"> AND t.date_format(t.start_time, '%Y-%m-%d') = date_format(#{startTime}, '%Y-%m-%d')</if>-->
+            <if test="supplierName != null">AND exists (select supplier_name from biz_outsourced_order_detail o where o.id = bpi.outsource_order_detail_id and o.supplier_name like concat('%', #{supplierName}, '%'))</if>
+            <if test="returnReceiptDetailFormCode != null ">AND rrd.form_code like concat('%', #{returnReceiptDetailFormCode}, '%') </if>
+            <if test="outsourcedOrderDetailFormCode != null ">AND bod.form_code like concat('%', #{outsourcedOrderDetailFormCode}, '%') </if>
+            <if test="auditStatus != null ">AND bpi.audit_status = #{auditStatus}</if>
+            <if test="keyword != null  and keyword !='' ">AND (bpi.lot_code LIKE CONCAT('%',#{keyword},'%') OR bpi.carrier_code
+                LIKE CONCAT('%',#{keyword},'%') OR
+                bpi.product_description LIKE CONCAT('%',#{keyword},'%'))</if>
+        </trim>
+    </select>
+</mapper>