浏览代码

外协报工+导出

wangxin 1 年之前
父节点
当前提交
8e68a17a9a
共有 24 个文件被更改,包括 1553 次插入179 次删除
  1. 9 0
      pom.xml
  2. 46 0
      src/main/java/cn/ezhizao/common/utils/MyHandler.java
  3. 3 1
      src/main/java/cn/ezhizao/project/business/controller/BizDayworkController.java
  4. 194 174
      src/main/java/cn/ezhizao/project/business/controller/BizOutsourcedOrderController.java
  5. 4 0
      src/main/java/cn/ezhizao/project/business/domain/BizDaywork.java
  6. 4 0
      src/main/java/cn/ezhizao/project/business/domain/BizDayworkItem.java
  7. 3 0
      src/main/java/cn/ezhizao/project/business/domain/BizOutsourcedOrderDetail.java
  8. 2 0
      src/main/java/cn/ezhizao/project/business/mapper/BizCarrierMapper.java
  9. 1 0
      src/main/java/cn/ezhizao/project/business/service/IBizCarrierService.java
  10. 7 0
      src/main/java/cn/ezhizao/project/business/service/IBizDayworkItemService.java
  11. 4 0
      src/main/java/cn/ezhizao/project/business/service/IBizOutsourcedOrderService.java
  12. 5 0
      src/main/java/cn/ezhizao/project/business/service/impl/BizCarrierServiceImpl.java
  13. 49 0
      src/main/java/cn/ezhizao/project/business/service/impl/BizDayworkItemServiceImpl.java
  14. 87 1
      src/main/java/cn/ezhizao/project/business/service/impl/BizOutsourcedOrderServiceImpl.java
  15. 177 0
      src/main/java/cn/ezhizao/project/system/mapper/SysUserMapper.java
  16. 201 0
      src/main/java/cn/ezhizao/project/system/service/ISysUserService.java
  17. 311 0
      src/main/java/cn/ezhizao/project/system/service/impl/SysUserServiceImpl.java
  18. 4 0
      src/main/resources/application-dev.yml
  19. 7 0
      src/main/resources/application-linux.yml
  20. 16 0
      src/main/resources/mybatis/business/BizCarrierMapper.xml
  21. 3 0
      src/main/resources/mybatis/business/BizDayworkMapper.xml
  22. 5 3
      src/main/resources/mybatis/business/BizLotTechnologicalProcessDetailMapper.xml
  23. 3 0
      src/main/resources/mybatis/business/BizTechnologicalProcessDetailMapper.xml
  24. 408 0
      src/main/resources/mybatis/system/SysUserMapper.xml

+ 9 - 0
pom.xml

@@ -39,6 +39,7 @@
         <mybatis-plus.spring.boot.starter.version>3.5.0</mybatis-plus.spring.boot.starter.version>
         <commons.fileupload.version>1.4</commons.fileupload.version>
         <hutool.version>5.8.11</hutool.version>
+        <easyexcel.version>3.3.2</easyexcel.version>
         <spring-cloud-nacos.version>2021.0.1.0</spring-cloud-nacos.version>
         <spring-cloud-feign.version>3.1.3</spring-cloud-feign.version>
     </properties>
@@ -56,6 +57,14 @@
             <version>${spring-cloud-feign.version}</version>
         </dependency>
 
+
+        <!--easyExcel-->
+        <dependency>
+        <groupId>com.alibaba</groupId>
+        <artifactId>easyexcel</artifactId>
+        <version>${easyexcel.version}</version>
+        </dependency>
+
         <!-- Spring-Cloud-Nacos -->
         <dependency>
             <groupId>com.alibaba.cloud</groupId>

+ 46 - 0
src/main/java/cn/ezhizao/common/utils/MyHandler.java

@@ -0,0 +1,46 @@
+package cn.ezhizao.common.utils;
+
+import com.alibaba.excel.metadata.Head;
+import com.alibaba.excel.write.merge.AbstractMergeStrategy;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.RegionUtil;
+
+import java.util.List;
+
+public class MyHandler extends AbstractMergeStrategy {
+    @Override
+    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
+        if(relativeRowIndex==null ||relativeRowIndex==0){
+            return;
+        }
+
+        int rowIndex = cell.getRowIndex();
+        int colIndex = cell.getColumnIndex();
+        sheet=cell.getSheet();
+        Row preRow = sheet.getRow(rowIndex - 1);
+        Cell preCell = preRow.getCell(colIndex);//获取上一行的该格
+        List<CellRangeAddress> list = sheet.getMergedRegions();
+        for (int i = 0; i < list.size(); i++) {
+            CellRangeAddress cellRangeAddress = list.get(i);
+            if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex())) {
+                int lastColIndex = cellRangeAddress.getLastColumn();
+                int firstColIndex = cellRangeAddress.getFirstColumn();
+                int firstRowIndex = cellRangeAddress.getFirstRow();
+                CellRangeAddress cra = new CellRangeAddress(rowIndex, rowIndex, firstColIndex, lastColIndex);
+                sheet.addMergedRegion(cra);
+
+                //设置合并区域cra的边框
+                RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);
+                RegionUtil.setBorderLeft(BorderStyle.THIN, cra, sheet);
+                RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet);
+                RegionUtil.setBorderTop(BorderStyle.THIN, cra, sheet);
+
+                return;
+            }
+        }
+    }
+}

+ 3 - 1
src/main/java/cn/ezhizao/project/business/controller/BizDayworkController.java

@@ -124,9 +124,11 @@ public class BizDayworkController extends BaseController {
             List<BizTechnologicalProcessDetail> processList = new ArrayList<>();
             return getDataTable(processList);
         }
+        dayworkItem.setKeyword(bizDaywork.getKeyword());
+
         //根据当前工序查找之后的工序列表
         //是否单批单改或废品回用
-        startPage();
+//        startPage();
         if(daywork.getIsAmend()==1|| daywork.getIsWasteRecycling()==1){
             List<BizLotTechnologicalProcessDetail> processList = bizLotTechnologicalProcessDetailService.getProcessList(dayworkItem);
             return getDataTable(processList);

+ 194 - 174
src/main/java/cn/ezhizao/project/business/controller/BizOutsourcedOrderController.java

@@ -1,9 +1,11 @@
 package cn.ezhizao.project.business.controller;
 
+import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.StringTokenizer;
 import java.util.stream.Collectors;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletResponse;
@@ -11,6 +13,7 @@ import javax.servlet.http.HttpServletResponse;
 import cn.ezhizao.framework.redis.RedisCache;
 import cn.ezhizao.project.business.domain.*;
 import cn.ezhizao.project.business.service.*;
+import cn.ezhizao.project.system.domain.SysUser;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.GetMapping;
@@ -30,15 +33,14 @@ import cn.ezhizao.framework.web.page.TableDataInfo;
 
 /**
  * 外协单主
-带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子Controller
+ * 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子Controller
  *
  * @author 庄德政
  * date    2024-04-26
  */
 @RestController
 @RequestMapping("/business/outsource")
-public class BizOutsourcedOrderController extends BaseController
-{
+public class BizOutsourcedOrderController extends BaseController {
     @Resource
     private IBizOutsourcedOrderService bizOutsourcedOrderService;
 
@@ -58,19 +60,18 @@ public class BizOutsourcedOrderController extends BaseController
     private IBizCarrierService iBizCarrierService;
 
     @Resource
-    private  IBizDayworkCarrierService iBizDayworkCarrierService;
+    private IBizDayworkCarrierService iBizDayworkCarrierService;
 
     @Resource
     private RedisCache redisCache;
 
     /**
      * 查询外协单主
-带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子列表
+     * 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子列表
      */
     @PreAuthorize("@ss.hasPermi('business:outsource:list')")
     @GetMapping("/list")
-    public TableDataInfo list(BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException
-    {
+    public TableDataInfo list(BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException {
         setTenantId(bizOutsourcedOrder);
         startPage();
         List<BizOutsourcedOrder> list = bizOutsourcedOrderService.getList(bizOutsourcedOrder);
@@ -83,261 +84,280 @@ public class BizOutsourcedOrderController extends BaseController
     @PreAuthorize("@ss.hasPermi('business:outsource:export')")
     @Log(title = "外协单主带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
-    public void export(HttpServletResponse response, BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException
-    {
-        setTenantId(bizOutsourcedOrder);
-        List<BizOutsourcedOrder> list = bizOutsourcedOrderService.getList(bizOutsourcedOrder);
-        ExcelUtil<BizOutsourcedOrder> util = new ExcelUtil<BizOutsourcedOrder>(BizOutsourcedOrder.class);
-        util.exportExcel(response, list, "外协单主带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子数据");
+    public void export(HttpServletResponse response,  BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException, IOException {
+        bizOutsourcedOrder = bizOutsourcedOrderService.getById(bizOutsourcedOrder);
+        BizOutsourcedOrderDetail bizOutsourcedOrderDetail = new BizOutsourcedOrderDetail();
+        bizOutsourcedOrderDetail.setMasterId(bizOutsourcedOrder.getId());
+        List<BizOutsourcedOrderDetail> outsourcedOrderDetails = bizOutsourcedOrderDetailService.getList(bizOutsourcedOrderDetail);
+        bizOutsourcedOrder.setDetails(outsourcedOrderDetails);
+        bizOutsourcedOrderService.exportTemplateProvinceAreaData(response, bizOutsourcedOrder);
     }
 
+
     /**
      * 获取外协单主
-带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子详细信息
+     * 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子详细信息
      */
     @PreAuthorize("@ss.hasPermi('business:outsource:query')")
     @GetMapping(value = "/{id}")
-    public AjaxResult getInfo(@PathVariable("id") Long id)
-    {
-        BizOutsourcedOrder bizOutsourcedOrder= bizOutsourcedOrderService.getById(id);
-        BizOutsourcedOrderDetail bizOutsourcedOrderDetail=new BizOutsourcedOrderDetail();
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        BizOutsourcedOrder bizOutsourcedOrder = bizOutsourcedOrderService.getById(id);
+        BizOutsourcedOrderDetail bizOutsourcedOrderDetail = new BizOutsourcedOrderDetail();
         bizOutsourcedOrderDetail.setMasterId(id);
-        List<BizOutsourcedOrderDetail> outsourcedOrderDetails=bizOutsourcedOrderDetailService.getList(bizOutsourcedOrderDetail);
+        List<BizOutsourcedOrderDetail> outsourcedOrderDetails = bizOutsourcedOrderDetailService.getList(bizOutsourcedOrderDetail);
+        //因为新箱子保存的时候,是用“id|code,id|code”的字符串形式存储的所以查询的时候需要进行拆分
+        //如果保存的时候没有选择新箱子则会把旧箱号复制到新箱号中,所有不会有“|”所以下方需要进行判断
+        outsourcedOrderDetails.forEach(detail -> {
+            // 将字符串拆分转为对象
+            List<BizCarrier> carriers = new ArrayList<>();
+            // 因为需要显示箱号,所以需要拆分出code重新拼接到NewCarrier
+            List<String> codeList = new ArrayList<>();
+            // 为了减少前段的逻辑,所以需要先将拆分后的id也拼接起来
+            List<Long> carrierIds = new ArrayList<>();
+
+            //使用 StringTokenizer 来分割字符串
+            StringTokenizer tokenizer = new StringTokenizer(detail.getNewCarrier(), ",");
+            while (tokenizer.hasMoreTokens()) {
+                String token = tokenizer.nextToken();
+                // 检查当前 token 是否包含 "|" 字符 如果没有表示不是新箱,则跳过当前 token
+                if (token.contains("|")) {
+                    String[] idCode = token.split("\\|"); // 安全地分割 token
+                    if (idCode.length == 2) {
+                        codeList.add(idCode[1]);
+                        carrierIds.add(Long.parseLong(idCode[0]));
+                        BizCarrier bizCarrier = new BizCarrier();
+                        bizCarrier.setId(Long.parseLong(idCode[0]));
+                        bizCarrier.setCode(idCode[1]);
+                        carriers.add(bizCarrier);
+                    }
+                }
+            }
+            detail.setNewCarriers(carriers);
+            detail.setCarrierIds(carrierIds);
+            if(codeList.size()>0){
+                detail.setNewCarrier(String.join(",", codeList));
+            }
+
+        });
         bizOutsourcedOrder.setDetails(outsourcedOrderDetails);
         return success(bizOutsourcedOrder);
     }
 
     @PreAuthorize("@ss.hasPermi('business:outsource:query')")
     @GetMapping(value = "/carrierForOutsource")
-    public TableDataInfo carrierForOutsource(BizCarrier carrier)
-    {
-        startPage();
-        return getDataTable(iBizCarrierService.query().eq("category_id",1783783697558847489L).eq("deleted",0).list());
+    public TableDataInfo carrierForOutsource(BizCarrier carrier) {
+        carrier.setNotInUse(1);
+        List<BizCarrier> list = iBizCarrierService.getListFromOutsource(carrier);
+        return getDataTable(list);
     }
 
     /**
      * 新增外协单主
-带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子
+     * 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子
      */
     @PreAuthorize("@ss.hasPermi('business:outsource:add')")
     @Log(title = "外协单主带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子", businessType = BusinessType.INSERT)
     @PostMapping("/add")
     @Transactional
-    public AjaxResult add(@RequestBody BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException
-    {
+    public AjaxResult add(@RequestBody BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException {
         setTenantId(bizOutsourcedOrder);
 
         //若有id,则说将之前的明细删除不生成新的单号
-        if(bizOutsourcedOrder.getId()!=null){
-            List<Long> ids=new ArrayList<>();
+        if (bizOutsourcedOrder.getId() != null) {
+            List<Long> ids = new ArrayList<>();
             ids.add(bizOutsourcedOrder.getId());
             //先将之前的明细删除
             bizOutsourcedOrderDetailService.removeByMasterIds(ids);
             bizOutsourcedOrderDetailProcessService.removeByMasterIds(ids);
-        }else{
+        } else {
             /* 生成单号 */
-            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); // 定义日期格式
-            String formattedDate =dateFormat.format(bizOutsourcedOrder.getFormDate());
-            String codeValue =("WX"+formattedDate+"001");
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yy"); // 定义日期格式
+            String formattedDate = dateFormat.format(new Date());
+            String codeValue;
             String codeType = "outsourcedOrderCode";
             //查询redis中外协单号的值
-            List<String> previous = redisCache.hasKey(codeType) ? redisCache.getCacheObject(codeType) : new ArrayList<>();
+             String previous = redisCache.hasKey(codeType) ? redisCache.getCacheObject(codeType) :"";
             //若不存在,则直接存入
-            if (previous.size()==0) {
-                previous.add(codeValue);
-            }else{
-                //存在则检查是否有相同的值
-                for (String item : previous) {//如果有相同的值则找到最新的值进行+1
-                    if (item.equals(codeValue)) {
-                        codeValue = previous.get(previous.size() - 1);
-                        int lastFourDigits = Integer.parseInt(codeValue.substring(10, 13));
-                        lastFourDigits += 1; // 加1
-                        codeValue = codeValue.substring(0, 10) + String.format("%03d", lastFourDigits);
-                    }
-                }
-                previous.add(codeValue);
+            if (previous.isEmpty()) {
+                previous = ("WFD" + formattedDate + "000001");
+            } else {
+                codeValue=previous;
+                int lastFourDigits = Integer.parseInt(codeValue.substring(10, 13));
+                lastFourDigits += 1; // 加1
+                codeValue = codeValue.substring(0, 10) + String.format("%03d", lastFourDigits);
+                previous=codeValue;
             }
             //存到redis中
             redisCache.setCacheObject(codeType, previous);
-            bizOutsourcedOrder.setFormCode(previous.get(previous.size()-1));
+            bizOutsourcedOrder.setFormCode(previous);
         }
         bizOutsourcedOrderService.saveOrUpdate(bizOutsourcedOrder);
-
-        List<BizOutsourcedOrderDetail> outsourcedOrderDetails=bizOutsourcedOrder.getDetails();
-        outsourcedOrderDetails=bizOutsourcedOrderDetailService.batchSave(outsourcedOrderDetails,bizOutsourcedOrder);
-
+        //新增明细信息
+        List<BizOutsourcedOrderDetail> outsourcedOrderDetails = bizOutsourcedOrder.getDetails();
+        outsourcedOrderDetails.forEach(detail -> {
+            if (detail.getNewCarriers().size() > 0) {
+                /**
+                 * 因为是暂存,暂存的时候不解绑原先的箱子,所以在暂存的时候需要保存新箱号的id和code所以用新箱号id和code用‘|’分割每组用逗号分割
+                 * 取出来的时候再进行拆分
+                 */
+                //这一步将绑定的新箱子以“id|code”一组,以英文“,”分割(例:1|A,2|B,3|C)
+                String formattedString = detail.getNewCarriers().stream()
+                        .map(item -> item.getId() + "|" + item.getCode())
+                        .collect(Collectors.joining(","));
+                //赋值给新箱号
+                detail.setNewCarrier(formattedString);
+            }
+        });
+        outsourcedOrderDetails = bizOutsourcedOrderDetailService.batchSave(outsourcedOrderDetails, bizOutsourcedOrder);
         return success(bizOutsourcedOrderDetailProcessService.batchSave(outsourcedOrderDetails));
     }
 
     /**
      * 修改外协单主
-带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子
+     * 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子
      */
     @PreAuthorize("@ss.hasPermi('business:outsource:edit')")
     @Log(title = "外协单主带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子", businessType = BusinessType.UPDATE)
     @PutMapping
     @Transactional
-    public AjaxResult submitOrder(@RequestBody BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException
-    {
+    public AjaxResult submitOrder(@RequestBody BizOutsourcedOrder bizOutsourcedOrder) throws NoSuchFieldException, IllegalAccessException {
         setTenantId(bizOutsourcedOrder);
         //若有id,则说将之前的明细删除不生成新的单号
-        if(bizOutsourcedOrder.getId()!=null){
-            List<Long> ids=new ArrayList<>();
+        if (bizOutsourcedOrder.getId() != null) {
+            List<Long> ids = new ArrayList<>();
             ids.add(bizOutsourcedOrder.getId());
             //先将之前的明细删除
             bizOutsourcedOrderDetailService.removeByMasterIds(ids);
             bizOutsourcedOrderDetailProcessService.removeByMasterIds(ids);
-        }else {
+        } else {
             /* 生成单号 */
-            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); // 定义日期格式
-            String formattedDate = dateFormat.format(bizOutsourcedOrder.getFormDate());
-            String codeValue = ("WX" + formattedDate + "001");
+            SimpleDateFormat dateFormat = new SimpleDateFormat("yy"); // 定义日期格式
+            String formattedDate = dateFormat.format(new Date());
+            String codeValue;
             String codeType = "outsourcedOrderCode";
             //查询redis中外协单号的值
-            List<String> previous = redisCache.hasKey(codeType) ? redisCache.getCacheObject(codeType) : new ArrayList<>();
+            String previous = redisCache.hasKey(codeType) ? redisCache.getCacheObject(codeType) :"";
             //若不存在,则直接存入
-            if (previous.size() == 0) {
-                previous.add(codeValue);
+            if (previous.isEmpty()) {
+                previous = ("WFD" + formattedDate + "000001");
             } else {
-                //存在则检查是否有相同的值
-                for (String item : previous) {//如果有相同的值则找到最新的值进行+1
-                    if (item.equals(codeValue)) {
-                        codeValue = previous.get(previous.size() - 1);
-                        int lastFourDigits = Integer.parseInt(codeValue.substring(10, 13));
-                        lastFourDigits += 1; // 加1
-                        codeValue = codeValue.substring(0, 10) + String.format("%03d", lastFourDigits);
-                    }
-                }
-                previous.add(codeValue);
+                codeValue=previous;
+                int lastFourDigits = Integer.parseInt(codeValue.substring(10, 13));
+                lastFourDigits += 1; // 加1
+                codeValue = codeValue.substring(0, 10) + String.format("%03d", lastFourDigits);
+                previous=codeValue;
             }
-
             //存到redis中
             redisCache.setCacheObject(codeType, previous);
-            bizOutsourcedOrder.setFormCode(previous.get(previous.size() - 1));
+            bizOutsourcedOrder.setFormCode(previous);
         }
         bizOutsourcedOrder.setIsSubmit(1);
-
         //修改主表信息
         bizOutsourcedOrderService.saveOrUpdate(bizOutsourcedOrder);
         //新增明细信息
-        List<BizOutsourcedOrderDetail> outsourcedOrderDetails=bizOutsourcedOrder.getDetails();
+        List<BizOutsourcedOrderDetail> outsourcedOrderDetails = bizOutsourcedOrder.getDetails();
 
-        /**********查询周转新信息修改周转状态,新增一条外协部门报工信息,将对应daywork状态修改为进行中************/
-        List<BizDayworkItem> dayworkItems=new ArrayList<>();//原周转信息集合
-        List<BizDayworkItem> newDayworkItems=new ArrayList<>();//新增报工信息集合
-
-        //修改报工信息
-        outsourcedOrderDetails.forEach(detail->{
-            //查询周转信息
-            BizDayworkItem bizDayworkItem=new BizDayworkItem();
-            bizDayworkItem.setDayworkId(detail.getDayworkId());
-            bizDayworkItem= bizDayworkService.getItemListFromOutsourced(bizDayworkItem).get(0);
-            //修改状态
-            bizDayworkItem.setStatus("7");
-            dayworkItems.add(bizDayworkItem);
-
-            //每一道工序新增一条报工信息
-            BizDayworkItem finalBizDayworkItem = bizDayworkItem;
-            detail.getProcesses().forEach(process->{
-                //新的报工信息
-                BizDayworkItem newBizDayworkItem=new BizDayworkItem();
-                newBizDayworkItem.setDayworkId(detail.getDayworkId());
-                newBizDayworkItem.setLotId(detail.getLotId());
-                newBizDayworkItem.setProcessId(process.getProcessId());
-                newBizDayworkItem.setProcessStepNumber(process.getProcessStepNumber());
-                newBizDayworkItem.setStatus("1");
-                newBizDayworkItem.setProdNum(finalBizDayworkItem.getProdNum());
-                newBizDayworkItem.setDeptId(finalBizDayworkItem.getDeptId());
-                newBizDayworkItem.setDeptName(finalBizDayworkItem.getDeptName());
-                newBizDayworkItem.setDeptCode(finalBizDayworkItem.getDeptCode());
-                newBizDayworkItem.setProductionPlanDetailId(finalBizDayworkItem.getProductionPlanDetailId());
-                newBizDayworkItem.setTechnologicalProcessId(finalBizDayworkItem.getTechnologicalProcessId());
-                newBizDayworkItem.setTechnologicalProcessDetailId(process.getTechnologicalProcessDetailId());
-                newBizDayworkItem.setIsWx(1);
-                newDayworkItems.add(newBizDayworkItem);
-            });
-        });
-
-        bizDayworkItemService.saveOrUpdateBatch(dayworkItems);
-        bizDayworkItemService.saveBatch(newDayworkItems);
+        //将周转信息修改为7,添加外协报工信息
+        bizDayworkItemService.updateDayworkItemForOutsource(outsourcedOrderDetails);
 
         //判断是否使用新箱子
-        if(bizOutsourcedOrder.getPackagingMethod().equals("1")){
-            //解绑原来箱子
-            List<Long> dayworkIds=outsourcedOrderDetails.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
+        //根据 detail.getNewCarriers()判断是否绑定了新箱子,如果有数据表示绑定新箱子,找出对应的dayworkId,解绑对应的箱子
+        List<Long> dayworkIds = outsourcedOrderDetails.stream().filter(detail -> detail.getNewCarriers().size() > 0).map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
+        if(dayworkIds.size()>0){
             iBizDayworkCarrierService.removeByDayworkIds(dayworkIds);
-
-            List<BizDayworkCarrier> carrierList=new ArrayList<>();
-            //绑定新箱子
-            outsourcedOrderDetails.forEach(detail->{
-                detail.getNewCarriers().forEach(carrier->{
-                    BizDayworkCarrier bizDayworkCarrier=new BizDayworkCarrier();
+        }
+        //绑定的新箱子集合
+        List<BizDayworkCarrier> carrierList = new ArrayList<>();
+        //绑定新箱子
+        outsourcedOrderDetails.forEach(detail -> {
+            /**
+             * 与暂存逻辑类似,但因为是彻底保存提交了,所以需要解绑原先的箱子,并且在没有新箱子时,需要将原先箱号复制到新箱号中
+             */
+            if (detail.getNewCarriers().size() > 0) {
+                //这一步将绑定的新箱子以“id|code”一组,以英文“,”分割(例:1|A,2|B,3|C)
+                String formattedString = detail.getNewCarriers().stream()
+                        .map(item -> item.getId() + "|" + item.getCode())
+                        .collect(Collectors.joining(","));
+                //赋值给新箱号
+                detail.setNewCarrier(formattedString);
+                //将新箱号绑定至dayworkId
+                detail.getNewCarriers().forEach(carrier -> {
+                    BizDayworkCarrier bizDayworkCarrier = new BizDayworkCarrier();
                     bizDayworkCarrier.setCarrierId(carrier.getId());
                     bizDayworkCarrier.setCarrierCode(carrier.getCode());
                     bizDayworkCarrier.setDayworkId(detail.getDayworkId());
                     bizDayworkCarrier.setLotId(detail.getLotId());
                     carrierList.add(bizDayworkCarrier);
                 });
-            });
-            iBizDayworkCarrierService.saveBatch(carrierList);
-        }
-        outsourcedOrderDetails=bizOutsourcedOrderDetailService.batchSave(outsourcedOrderDetails,bizOutsourcedOrder);
+            } else {
+                //将原箱号复制到新新箱号
+                detail.setNewCarrier(detail.getOriginalCarrier());
+            }
+        });
+        iBizDayworkCarrierService.saveBatch(carrierList);
+        outsourcedOrderDetails = bizOutsourcedOrderDetailService.batchSave(outsourcedOrderDetails, bizOutsourcedOrder);
         return toAjax(bizOutsourcedOrderDetailProcessService.batchSave(outsourcedOrderDetails));
     }
 
     /**
      * 删除外协单主
-带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子
+     * 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子
      */
     @PreAuthorize("@ss.hasPermi('business:outsource:remove')")
     @Log(title = "外协单主带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子", businessType = BusinessType.DELETE)
-	@DeleteMapping("/{ids}")
+    @DeleteMapping("/{ids}")
     @Transactional
-    public AjaxResult remove(@PathVariable List<Long> ids)
-    {
-        //查找需要删除的从表信息
-        List<BizOutsourcedOrderDetail> outsourcedOrderDetails =bizOutsourcedOrderDetailService.query().in("master_id",ids).list();
-        List<Long> dayworkIds=outsourcedOrderDetails.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
-
-        /*查询需要删除的外协工序信息,因为可能出现二次外协周转不能删除所有的外协报工,所以要查询当前外协需要加工的工序*/
-        List<BizOutsourcedOrderDetailProcess> bizOutsourcedOrderDetailProcessList=bizOutsourcedOrderDetailProcessService.query().in("master_id",ids).list();
+    public AjaxResult remove(@PathVariable List<Long> ids) {
+        /**
+         *删除工能暂时不可删除已经提交的数据,如果后续想要删除,将下方代码解开
+         *解开后要加上:如果使用的是新箱子,则需要解绑箱子并将对应的周转报工删除
+         *不删除只解绑箱子会出现错误,删除后可在手机端重新绑定箱子进行周转(也可使用别的方式进行绑定)
+         */
 
-        //判断是否已经报工,如果存在投入数则表示已经报工不能删除
-        for (BizOutsourcedOrderDetailProcess process : bizOutsourcedOrderDetailProcessList) {
-            if(process.getProductionNum()>0){
-                throw new RuntimeException("【"+process.getLotCode()+"】批次存在已报工的工序,不能删除");
-            }
-        }
-
-        List<Long> processIds=bizOutsourcedOrderDetailProcessList.stream().map(BizOutsourcedOrderDetailProcess::getTechnologicalProcessDetailId).collect(Collectors.toList());
-        //找到对应的外协所有报工信息
-        List<BizDayworkItem> bizDayworkItemList=bizDayworkItemService.getListByDayworkIdsForOutsourced(dayworkIds);
-
-        // 使用流来筛选出当前的信息
-        List<BizDayworkItem> filteredList = bizDayworkItemList.stream()
-                .filter(item -> processIds.contains(item.getTechnologicalProcessDetailId()))
-                .collect(Collectors.toList());
-        //删除报工信息
-        List<Long> dayworkItemIds= filteredList.stream().map(BizDayworkItem::getId).collect(Collectors.toList());
-        bizDayworkItemService.removeBatchByIds(dayworkItemIds);
-
-        //修改对应的周转信息,将周转信息改为待周转
-        bizDayworkItemList= bizDayworkItemService.selectLatestItemByDayworkIds(dayworkIds);
-
-        bizDayworkItemList.forEach(item->{
-            item.setStatus("4");
-        });
-
-        List<Long> removeIds=outsourcedOrderDetails.stream().filter(detail -> detail.getPackagingMethod().equals("1")).map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
-        if(removeIds.size()>0) {
-            iBizDayworkCarrierService.removeByDayworkIds(removeIds);
-        }
-
-        //此方法待定
-        iBizDayworkCarrierService.updateByDayworkIds(outsourcedOrderDetails);
-
-        //修改周转信息
-        bizDayworkItemService.saveOrUpdateBatch(bizDayworkItemList);
+        //查找需要删除的从表信息
+//        List<BizOutsourcedOrderDetail> outsourcedOrderDetails =bizOutsourcedOrderDetailService.query().in("master_id",ids).list();
+//        List<Long> dayworkIds=outsourcedOrderDetails.stream().map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
+//
+//        /*查询需要删除的外协工序信息,因为可能出现二次外协周转不能删除所有的外协报工,所以要查询当前外协需要加工的工序*/
+//        List<BizOutsourcedOrderDetailProcess> bizOutsourcedOrderDetailProcessList=bizOutsourcedOrderDetailProcessService.query().in("master_id",ids).list();
+//
+//        //判断是否已经报工,如果存在投入数则表示已经报工不能删除
+//        for (BizOutsourcedOrderDetailProcess process : bizOutsourcedOrderDetailProcessList) {
+//            if(process.getProductionNum()>0){
+//                throw new RuntimeException("【"+process.getLotCode()+"】批次存在已报工的工序,不能删除");
+//            }
+//        }
+//
+//        List<Long> processIds=bizOutsourcedOrderDetailProcessList.stream().map(BizOutsourcedOrderDetailProcess::getTechnologicalProcessDetailId).collect(Collectors.toList());
+//        //找到对应的外协所有报工信息
+//        List<BizDayworkItem> bizDayworkItemList=bizDayworkItemService.getListByDayworkIdsForOutsourced(dayworkIds);
+//
+//        // 使用流来筛选出当前的信息
+//        List<BizDayworkItem> filteredList = bizDayworkItemList.stream()
+//                .filter(item -> processIds.contains(item.getTechnologicalProcessDetailId()))
+//                .collect(Collectors.toList());
+//        //删除报工信息
+//        List<Long> dayworkItemIds= filteredList.stream().map(BizDayworkItem::getId).collect(Collectors.toList());
+//        bizDayworkItemService.removeBatchByIds(dayworkItemIds);
+//
+//        //修改对应的周转信息,将周转信息改为待周转
+//        bizDayworkItemList= bizDayworkItemService.selectLatestItemByDayworkIds(dayworkIds);
+//
+//        bizDayworkItemList.forEach(item->{
+//            item.setStatus("4");
+//        });
+//
+//        List<Long> removeIds=outsourcedOrderDetails.stream().filter(detail -> detail.getPackagingMethod().equals("1")).map(BizOutsourcedOrderDetail::getDayworkId).collect(Collectors.toList());
+//        if(removeIds.size()>0) {
+//            iBizDayworkCarrierService.removeByDayworkIds(removeIds);
+//        }
+//
+//        //此方法待定
+//        iBizDayworkCarrierService.updateByDayworkIds(outsourcedOrderDetails);
+//
+//
+//        //修改周转信息
+//        bizDayworkItemService.saveOrUpdateBatch(bizDayworkItemList);
         //删除明细信息
         bizOutsourcedOrderDetailService.removeByMasterIds(ids);
         //删除明细对应的工序

+ 4 - 0
src/main/java/cn/ezhizao/project/business/domain/BizDaywork.java

@@ -236,6 +236,10 @@ public class BizDaywork extends BaseEntity {
     @TableField(exist = false)
     private Long fromId;
 
+    //外协发出单查找工序数据时的关键字
+    @TableField(exist = false)
+    private String keyword;
+
     public BizDaywork() {}
 
     public BizDaywork(BizDaywork copy) {

+ 4 - 0
src/main/java/cn/ezhizao/project/business/domain/BizDayworkItem.java

@@ -238,6 +238,10 @@ public class BizDayworkItem extends BaseEntity {
 
     @TableField(exist = false)
     private List<Long> dayworkIds;
+
+    //外协发出单查找工序数据时的关键字
+    @TableField(exist = false)
+    private String keyword;
     public BizDayworkItem() {}
 
     public BizDayworkItem(BizDayworkItem copy) {

+ 3 - 0
src/main/java/cn/ezhizao/project/business/domain/BizOutsourcedOrderDetail.java

@@ -121,6 +121,9 @@ public class BizOutsourcedOrderDetail extends BaseEntity
     @TableField(exist = false)
     private List<BizCarrier>  newCarriers;
 
+    @TableField(exist = false)
+    private List<Long>  carrierIds;
+
     /** 外协工序名称字符串,以英文逗号分割 **/
     private String  processNames;
 

+ 2 - 0
src/main/java/cn/ezhizao/project/business/mapper/BizCarrierMapper.java

@@ -28,4 +28,6 @@ public interface BizCarrierMapper extends BaseMapper<BizCarrier> {
      * @return 影响数量
      */
     public int unAbandoned(Long id);
+
+    List<BizCarrier> getListFromOutsource(BizCarrier carrier);
 }

+ 1 - 0
src/main/java/cn/ezhizao/project/business/service/IBizCarrierService.java

@@ -30,4 +30,5 @@ public interface IBizCarrierService extends IService<BizCarrier> {
 
     public List<BizCarrier> getList(BizCarrier bizCarrier);
 
+    List<BizCarrier> getListFromOutsource(BizCarrier carrier);
 }

+ 7 - 0
src/main/java/cn/ezhizao/project/business/service/IBizDayworkItemService.java

@@ -1,6 +1,7 @@
 package cn.ezhizao.project.business.service;
 
 import cn.ezhizao.project.business.domain.BizDayworkItem;
+import cn.ezhizao.project.business.domain.BizOutsourcedOrderDetail;
 import cn.ezhizao.project.business.domain.BizProductionResourceGroupDetail;
 import cn.ezhizao.project.system.domain.SysDept;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -52,4 +53,10 @@ public interface IBizDayworkItemService extends IService<BizDayworkItem>
     int updateTechnologicalProcessDetailId(Long dayWorkId);
 
     List<BizDayworkItem> selectLatestItemByDayworkIds(List<Long> dayworkIds);
+
+    void updateDayworkItemForOutsource(List<BizOutsourcedOrderDetail> outsourcedOrderDetails );
+
+
+
+
 }

+ 4 - 0
src/main/java/cn/ezhizao/project/business/service/IBizOutsourcedOrderService.java

@@ -1,9 +1,12 @@
 package cn.ezhizao.project.business.service;
 
+import java.io.IOException;
 import java.util.List;
 import com.baomidou.mybatisplus.extension.service.IService;
 import cn.ezhizao.project.business.domain.BizOutsourcedOrder;
 
+import javax.servlet.http.HttpServletResponse;
+
 /**
  * 外协单主  带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子Service接口
  *
@@ -27,4 +30,5 @@ public interface IBizOutsourcedOrderService extends IService<BizOutsourcedOrder>
      */
     int physicalDelete(BizOutsourcedOrder bizOutsourcedOrder);
 
+    void exportTemplateProvinceAreaData(HttpServletResponse response, BizOutsourcedOrder bizOutsourcedOrder) throws IOException;
 }

+ 5 - 0
src/main/java/cn/ezhizao/project/business/service/impl/BizCarrierServiceImpl.java

@@ -49,4 +49,9 @@ public class BizCarrierServiceImpl extends ServiceImpl<BizCarrierMapper, BizCarr
     public List<BizCarrier> getList(BizCarrier bizCarrier) {
         return bizCarrierMapper.getList(bizCarrier);
     }
+
+    @Override
+    public List<BizCarrier> getListFromOutsource(BizCarrier carrier) {
+        return bizCarrierMapper.getListFromOutsource(carrier);
+    }
 }

+ 49 - 0
src/main/java/cn/ezhizao/project/business/service/impl/BizDayworkItemServiceImpl.java

@@ -1,14 +1,19 @@
 package cn.ezhizao.project.business.service.impl;
 
 import cn.ezhizao.project.business.domain.BizDayworkItem;
+import cn.ezhizao.project.business.domain.BizOutsourcedOrderDetail;
 import cn.ezhizao.project.business.domain.BizProductionResourceGroupDetail;
 import cn.ezhizao.project.business.mapper.BizDayworkItemMapper;
+import cn.ezhizao.project.business.mapper.BizDayworkMapper;
 import cn.ezhizao.project.business.service.IBizDayworkItemService;
 import cn.ezhizao.project.system.domain.SysDept;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -21,6 +26,8 @@ import java.util.List;
 public class BizDayworkItemServiceImpl extends ServiceImpl<BizDayworkItemMapper, BizDayworkItem> implements IBizDayworkItemService {
     @Resource
     private BizDayworkItemMapper bizDayworkItemMapper;
+    @Resource
+    private BizDayworkMapper bizDayworkMapper;
 
     /**
      * 查询报工记录列表
@@ -94,5 +101,47 @@ public class BizDayworkItemServiceImpl extends ServiceImpl<BizDayworkItemMapper,
         return bizDayworkItemMapper.selectLatestItemByDayworkIds(dayworkIds);
     }
 
+    @Override
+    @Transactional
+    public void updateDayworkItemForOutsource(List<BizOutsourcedOrderDetail> outsourcedOrderDetails) {
+        /**********查询周转新信息修改周转状态,新增一条外协部门报工信息,将对应daywork状态修改为进行中************/
+        List<BizDayworkItem> dayworkItems = new ArrayList<>();//原周转信息集合
+        List<BizDayworkItem> newDayworkItems = new ArrayList<>();//新增报工信息集合
+
+        //修改报工信息
+        outsourcedOrderDetails.forEach(detail -> {
+            //查询周转信息
+            BizDayworkItem bizDayworkItem = new BizDayworkItem();
+            bizDayworkItem.setDayworkId(detail.getDayworkId());
+            bizDayworkItem = bizDayworkMapper.getItemListFromOutsourced(bizDayworkItem).get(0);
+            //修改状态
+            bizDayworkItem.setStatus("7");
+            dayworkItems.add(bizDayworkItem);
+
+            //每一道工序新增一条报工信息
+            BizDayworkItem finalBizDayworkItem = bizDayworkItem;
+            detail.getProcesses().forEach(process -> {
+                //新的报工信息
+                BizDayworkItem newBizDayworkItem = new BizDayworkItem();
+                newBizDayworkItem.setDayworkId(detail.getDayworkId());
+                newBizDayworkItem.setLotId(detail.getLotId());
+                newBizDayworkItem.setProcessId(process.getProcessId());
+                newBizDayworkItem.setProcessStepNumber(process.getProcessStepNumber());
+                newBizDayworkItem.setStatus("1");
+                newBizDayworkItem.setProdNum(detail.getProductNum());
+                newBizDayworkItem.setDeptId(finalBizDayworkItem.getDeptId());
+                newBizDayworkItem.setDeptName(finalBizDayworkItem.getDeptName());
+                newBizDayworkItem.setStartTime(new Date());
+                newBizDayworkItem.setDeptCode(finalBizDayworkItem.getDeptCode());
+                newBizDayworkItem.setProductionPlanDetailId(finalBizDayworkItem.getProductionPlanDetailId());
+                newBizDayworkItem.setTechnologicalProcessId(finalBizDayworkItem.getTechnologicalProcessId());
+                newBizDayworkItem.setTechnologicalProcessDetailId(process.getTechnologicalProcessDetailId());
+                newBizDayworkItem.setIsWx(1);
+                newDayworkItems.add(newBizDayworkItem);
+            });
+        });
+        saveOrUpdateBatch(dayworkItems);
+        saveBatch(newDayworkItems);
+    }
 
 }

+ 87 - 1
src/main/java/cn/ezhizao/project/business/service/impl/BizOutsourcedOrderServiceImpl.java

@@ -1,8 +1,22 @@
 package cn.ezhizao.project.business.service.impl;
 
-import java.util.List;
+import java.io.IOException;
+import java.util.*;
 import javax.annotation.Resource;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+
+import cn.ezhizao.common.utils.MyHandler;
+import cn.ezhizao.project.business.domain.BizOutsourcedOrderDetail;
+import cn.ezhizao.project.system.domain.SysUser;
+import cn.ezhizao.project.system.mapper.SysUserMapper;
+import cn.hutool.core.io.IoUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.metadata.fill.FillConfig;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import cn.ezhizao.project.business.mapper.BizOutsourcedOrderMapper;
 import cn.ezhizao.project.business.domain.BizOutsourcedOrder;
@@ -21,6 +35,12 @@ public class BizOutsourcedOrderServiceImpl  extends ServiceImpl<BizOutsourcedOrd
     @Resource
     private BizOutsourcedOrderMapper bizOutsourcedOrderMapper;
 
+    @Resource
+    private SysUserMapper sysUserMapper;
+
+    @Value("${file.excelTemplate.url}")
+    private  String templatePath;
+
     /**
      * 查询外协单主
 带箱方式,是整单的。如果换新箱子,明细中,都需要更换箱子列表
@@ -44,4 +64,70 @@ public class BizOutsourcedOrderServiceImpl  extends ServiceImpl<BizOutsourcedOrd
     @Override
     public int physicalDelete(BizOutsourcedOrder bizOutsourcedOrder){ return bizOutsourcedOrderMapper.physicalDelete(bizOutsourcedOrder); }
 
+
+    @Override
+    public void exportTemplateProvinceAreaData(HttpServletResponse response, BizOutsourcedOrder bizOutsourcedOrder) throws IOException {
+        List<BizOutsourcedOrderDetail> result = bizOutsourcedOrder.getDetails();
+        //因为新箱子保存的时候,是用“id|code,id|code”的字符串形式存储的所以查询的时候需要进行拆分
+        //如果保存的时候没有选择新箱子则会把旧箱号复制到新箱号中,所有不会有“|”所以下方需要进行判断
+        result.forEach(item->{
+            // 因为需要显示箱号,所以需要拆分出code重新拼接到NewCarrier
+            List<String> codeList = new ArrayList<>();
+            //使用 StringTokenizer 来分割字符串
+            StringTokenizer tokenizer = new StringTokenizer(item.getNewCarrier(), ",");
+            while (tokenizer.hasMoreTokens()) {
+                String token = tokenizer.nextToken();
+                // 检查当前 token 是否包含 "|" 字符 如果没有表示不是新箱,则跳过当前 token
+                if (token.contains("|")) {
+                    String[] idCode = token.split("\\|"); // 安全地分割 token
+                    if (idCode.length == 2) {
+                        codeList.add(idCode[1]);
+
+                    }
+                }else{
+                    codeList.add(token);
+                }
+            }
+            item.setNewCarrier(String.join(",", codeList));
+        });
+        SysUser  sysUser = sysUserMapper.selectUserById(bizOutsourcedOrder.getCreatorId());
+
+        String template = "outsourcedSend";
+        String templateFilePath =  templatePath + template + ".xlsx";
+        //本地导出
+        //excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build();
+        //流输出
+        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
+                .withTemplate(templateFilePath)
+                .build();
+
+        WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(new MyHandler()).build();
+
+        //配置多组数据填充完后,需要换行,防止覆盖模板中的单组数据模板
+        FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();
+        // 直接写入list数据
+        excelWriter.fill(result, fillConfig, writeSheet);
+        // 写入自定义的表头
+        Map<String, Object> map = new HashMap<>();
+        map.put("formCode",bizOutsourcedOrder.getFormCode());
+        map.put("supplierName",bizOutsourcedOrder.getSupplierName());
+        map.put("formDate",bizOutsourcedOrder.getFormDate());
+        map.put("name",sysUser.getNickName());
+        map.put("remark",bizOutsourcedOrder.getRemark());
+        excelWriter.fill(map, writeSheet);
+        excelWriter.finish();
+
+        response.setContentType("application/vnd.ms-excel;charset=utf-8");
+        //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
+        response.setHeader("Content-Disposition", "attachment;filename=test.xlsx");
+        ServletOutputStream out = null;
+        try {
+            out = response.getOutputStream();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        //此处记得关闭输出Servlet流
+        IoUtil.close(out);
+    }
+
 }

+ 177 - 0
src/main/java/cn/ezhizao/project/system/mapper/SysUserMapper.java

@@ -0,0 +1,177 @@
+package cn.ezhizao.project.system.mapper;
+
+import cn.ezhizao.project.system.domain.SysUser;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 用户表 数据层
+ *
+ * @author ruoyi
+ */
+public interface SysUserMapper {
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param sysUser 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectUserList(SysUser sysUser);
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param sysUser 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectTenantList(SysUser sysUser);
+
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param sysUser 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectEmployeeList(SysUser sysUser);
+
+
+    /**
+     * 根据ids查询用户列表
+     *
+     * @param userIds 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectUserListByIds(Long[] userIds);
+
+    /**
+     * 根据条件分页查询已配用户角色列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectAllocatedList(SysUser user);
+
+    /**
+     * 根据条件分页查询未分配用户角色列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    public List<SysUser> selectUnallocatedList(SysUser user);
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    public SysUser selectUserByUserName(String userName);
+
+    /**
+     * @param userName
+     * @param tenantId
+     * @return
+     */
+    public SysUser selectUserByUserNameAndTenantId(String userName, String tenantId);
+
+
+    /**
+     * 通过用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户对象信息
+     */
+    public SysUser selectUserById(Long userId);
+
+    /**
+     * 新增用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int insertUser(SysUser user);
+
+    /**
+     * 修改用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    public int updateUser(SysUser user);
+
+    /**
+     * 修改用户头像
+     *
+     * @param userName 用户名
+     * @param avatar   头像地址
+     * @return 结果
+     */
+    public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
+
+    public List<SysUser> getListByDeptId(List<Long> ids);
+
+    /**
+     * 重置用户密码
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @return 结果
+     */
+    public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
+
+    /**
+     * 通过用户ID删除用户
+     *
+     * @param userId 用户ID
+     * @return 结果
+     */
+    public int deleteUserById(Long userId);
+
+    /**
+     * 批量删除用户信息
+     *
+     * @param userIds 需要删除的用户ID
+     * @return 结果
+     */
+    public int deleteUserByIds(List<Long> userIds);
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param userName 用户名称
+     * @return 结果
+     */
+    public SysUser checkUserNameUnique(String userName);
+
+    /**
+     * 校验手机号码是否唯一
+     *
+     * @param phoneNumber 手机号码
+     * @return 结果
+     */
+    public SysUser checkPhoneUnique(String phoneNumber);
+
+    /**
+     * 校验email是否唯一
+     *
+     * @param email 用户邮箱
+     * @return 结果
+     */
+    public SysUser checkEmailUnique(String email);
+
+    List<SysUser> selectUserListByIds(List<Long> userIds);
+
+    /**
+     * 根据userName查询userId
+     */
+    public SysUser getUserByCode(String userName);
+
+    /**
+     * 根据工段id获取用户信息
+     * @param userName,nickname 用户信息
+     * @return 用户信息
+     */
+    public List<SysUser> selectUserItemByDeptId(@Param("userName") String userName,@Param("nickName") String nickName);
+
+    List<SysUser> listByLikeNickNameOrUserName(SysUser user);
+}

+ 201 - 0
src/main/java/cn/ezhizao/project/system/service/ISysUserService.java

@@ -0,0 +1,201 @@
+package cn.ezhizao.project.system.service;
+
+import cn.ezhizao.project.system.domain.SysUser;
+
+import java.util.List;
+
+/**
+ * 用户 业务层
+ *
+ * @author ruoyi
+ */
+public interface ISysUserService
+{
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUser> selectUserList(SysUser user);
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUser> selectTenantList(SysUser user);
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUser> selectEmployeeList(SysUser user);
+
+    /**
+     * 根据ids查询用户列表
+     *
+     * @param userIds 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUser> selectUserListByIds(List<Long> userIds);
+
+    /**
+     * 根据条件分页查询已分配用户角色列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUser> selectAllocatedList(SysUser user);
+
+    /**
+     * 根据条件分页查询未分配用户角色列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    List<SysUser> selectUnallocatedList(SysUser user);
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    SysUser selectUserByUserName(String userName);
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @param tenantId 租户id
+     * @return 用户对象信息
+     */
+    SysUser selectUserByUserNameAndTenantId(String userName, String tenantId);
+
+    /**
+     * 通过用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户对象信息
+     */
+    SysUser selectUserById(Long userId);
+
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    String checkUserNameUnique(SysUser user);
+
+    /**
+     * 校验手机号码是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    String checkPhoneUnique(SysUser user);
+
+    /**
+     * 校验email是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    String checkEmailUnique(SysUser user);
+
+    /**
+     * 校验用户是否允许操作
+     *
+     * @param user 用户信息
+     */
+    void checkUserAllowed(SysUser user);
+
+    /**
+     * 校验用户是否有数据权限
+     *
+     * @param userId 用户id
+     */
+    void checkUserDataScope(Long userId);
+
+
+    /**
+     * 注册用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    boolean registerUser(SysUser user);
+
+
+    /**
+     * 通过部门ID查询用户
+     *
+     * @param deptId 部门ID
+     * @return 用户信息集合信息
+     */
+    List<SysUser> getListByDept(List<Long> deptId);
+
+    /**
+     * 修改用户状态
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    int updateUserStatus(SysUser user);
+
+    /**
+     * 修改用户基本信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    int updateUserProfile(SysUser user);
+
+    /**
+     * 修改用户头像
+     *
+     * @param userName 用户名
+     * @param avatar 头像地址
+     * @return 结果
+     */
+    boolean updateUserAvatar(String userName, String avatar);
+
+    /**
+     * 重置用户密码
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    int resetPwd(SysUser user);
+
+    /**
+     * 重置用户密码
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @return 结果
+     */
+    int resetUserPwd(String userName, String password);
+
+
+    /**
+     * 根据用户名获取用户信息
+     * @param userName 用户编码
+     * @return 用户信息
+     */
+    SysUser getUserByCode(String userName);
+
+    /**
+     *  查询用户信息
+     * @param userName
+     * @param nickName
+     * @return
+     */
+    List<SysUser> selectUserItemByDeptId(String userName,String nickName);
+
+    List<SysUser> listByLikeNickNameOrUserName(SysUser user);
+}

+ 311 - 0
src/main/java/cn/ezhizao/project/system/service/impl/SysUserServiceImpl.java

@@ -0,0 +1,311 @@
+package cn.ezhizao.project.system.service.impl;
+
+import cn.ezhizao.common.constant.UserConstants;
+import cn.ezhizao.common.exception.ServiceException;
+import cn.ezhizao.common.utils.SecurityUtils;
+import cn.ezhizao.common.utils.StringUtils;
+import cn.ezhizao.common.utils.bean.BeanValidators;
+import cn.ezhizao.common.utils.spring.SpringUtils;
+import cn.ezhizao.framework.aspectj.lang.annotation.DataScope;
+import cn.ezhizao.project.system.domain.SysRole;
+import cn.ezhizao.project.system.domain.SysUser;
+import cn.ezhizao.project.system.mapper.SysUserMapper;
+import cn.ezhizao.project.system.service.ISysUserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Validator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 用户 业务层处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysUserServiceImpl implements ISysUserService {
+
+    @Resource
+    private SysUserMapper userMapper;
+
+    @Resource
+    private HttpServletRequest request;
+
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<SysUser> selectUserList(SysUser user) {
+        return userMapper.selectUserList(user);
+    }
+    /**
+     * 根据条件分页查询用户列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    public List<SysUser> selectTenantList(SysUser user) {
+        return userMapper.selectTenantList(user);
+    }
+
+    /**
+     * 根据条件分页查询员工列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<SysUser> selectEmployeeList(SysUser user) {
+        return userMapper.selectEmployeeList(user);
+    }
+
+    /**
+     * 根据条件分页查询用户列表列表
+     *
+     * @param userIds 用户信息list
+     * @return 用户信息集合信息
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<SysUser> selectUserListByIds(List<Long> userIds) {
+        return userMapper.selectUserListByIds(userIds);
+    }
+
+    /**
+     * 根据条件分页查询已分配用户角色列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<SysUser> selectAllocatedList(SysUser user) {
+        return userMapper.selectAllocatedList(user);
+    }
+
+    /**
+     * 根据条件分页查询未分配用户角色列表
+     *
+     * @param user 用户信息
+     * @return 用户信息集合信息
+     */
+    @Override
+    @DataScope(deptAlias = "d", userAlias = "u")
+    public List<SysUser> selectUnallocatedList(SysUser user) {
+        return userMapper.selectUnallocatedList(user);
+    }
+
+    /**
+     * 通过用户名查询用户
+     *
+     * @param userName 用户名
+     * @return 用户对象信息
+     */
+    @Override
+    public SysUser selectUserByUserName(String userName) {
+        return userMapper.selectUserByUserName(userName);
+    }
+
+    @Override
+    public SysUser selectUserByUserNameAndTenantId(String userName, String tenantId) {
+        return userMapper.selectUserByUserNameAndTenantId(userName, tenantId);
+    }
+
+
+    /**
+     * 通过用户ID查询用户
+     *
+     * @param userId 用户ID
+     * @return 用户对象信息
+     */
+    @Override
+    public SysUser selectUserById(Long userId) {
+        return userMapper.selectUserById(userId);
+    }
+
+
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public String checkUserNameUnique(SysUser user) {
+        String tenantId = request.getHeader("tenantId");
+        Long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
+        SysUser info = userMapper.checkUserNameUnique(user.getUserName());
+        if (StringUtils.isNotNull(info) && info.getUserId().longValue() != userId.longValue()) {
+
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+    /**
+     * 校验用户名称是否唯一
+     *
+     * @param user 用户信息
+     * @return 字符串
+     */
+    @Override
+    public String checkPhoneUnique(SysUser user) {
+        long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
+        SysUser info = userMapper.checkPhoneUnique(user.getPhoneNumber());
+        if (StringUtils.isNotNull(info) && info.getUserId() != userId) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+    /**
+     * 校验email是否唯一
+     *
+     * @param user 用户信息
+     * @return 字符串
+     */
+    @Override
+    public String checkEmailUnique(SysUser user) {
+        long userId = StringUtils.isNull(user.getUserId()) ? -1L : user.getUserId();
+        SysUser info = userMapper.checkEmailUnique(user.getEmail());
+        if (StringUtils.isNotNull(info) && info.getUserId() != userId) {
+            return UserConstants.NOT_UNIQUE;
+        }
+        return UserConstants.UNIQUE;
+    }
+
+    /**
+     * 校验用户是否允许操作
+     *
+     * @param user 用户信息
+     */
+    @Override
+    public void checkUserAllowed(SysUser user) {
+        if (StringUtils.isNotNull(user.getUserId()) && user.isAdmin()) {
+            throw new ServiceException("不允许操作超级管理员用户");
+        }
+    }
+
+    /**
+     * 校验用户是否有数据权限
+     *
+     * @param userId 用户id
+     */
+    @Override
+    public void checkUserDataScope(Long userId) {
+        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
+            SysUser user = new SysUser();
+            user.setUserId(userId);
+            List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
+            if (StringUtils.isEmpty(users)) {
+                throw new ServiceException("没有权限访问用户数据!");
+            }
+        }
+    }
+
+
+
+    /**
+     * 注册用户信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public boolean registerUser(SysUser user) {
+        return userMapper.insertUser(user) > 0;
+    }
+
+
+    @Override
+    public List<SysUser> getListByDept(List<Long> deptId) {
+        return userMapper.getListByDeptId(deptId);
+    }
+
+    /**
+     * 修改用户状态
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public int updateUserStatus(SysUser user) {
+        return userMapper.updateUser(user);
+    }
+
+    /**
+     * 修改用户基本信息
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public int updateUserProfile(SysUser user) {
+        return userMapper.updateUser(user);
+    }
+
+    /**
+     * 修改用户头像
+     *
+     * @param userName 用户名
+     * @param avatar   头像地址
+     * @return 结果
+     */
+    @Override
+    public boolean updateUserAvatar(String userName, String avatar) {
+        return userMapper.updateUserAvatar(userName, avatar) > 0;
+    }
+
+    /**
+     * 重置用户密码
+     *
+     * @param user 用户信息
+     * @return 结果
+     */
+    @Override
+    public int resetPwd(SysUser user) {
+        return userMapper.updateUser(user);
+    }
+
+    /**
+     * 重置用户密码
+     *
+     * @param userName 用户名
+     * @param password 密码
+     * @return 结果
+     */
+    @Override
+    public int resetUserPwd(String userName, String password) {
+        return userMapper.resetUserPwd(userName, password);
+    }
+
+
+    @Override
+    public SysUser getUserByCode(String userName) {
+        return userMapper.getUserByCode(userName);
+    }
+
+    @Override
+    public List<SysUser> selectUserItemByDeptId(String userName,String nickName) {
+        return userMapper.selectUserItemByDeptId(userName,nickName);
+    }
+
+    @Override
+    public List<SysUser> listByLikeNickNameOrUserName(SysUser user) {
+        return userMapper.listByLikeNickNameOrUserName(user);
+    }
+}

+ 4 - 0
src/main/resources/application-dev.yml

@@ -82,3 +82,7 @@ spring:
 # 文件上传
 ruoyi:
     profile: D:/Ezhizao/identity/
+
+file:
+    excelTemplate:
+        url: D:/Ezhizao/dms/templates/

+ 7 - 0
src/main/resources/application-linux.yml

@@ -88,4 +88,11 @@ spring:
 # 文件上传
 ruoyi:
     profile: /home/files/dms/
+    # 文件上传
+file:
+    excelTemplate:
+        url: /home/files/dms/templates/
+
+
+
 

+ 16 - 0
src/main/resources/mybatis/business/BizCarrierMapper.xml

@@ -23,9 +23,25 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             </if>
 
         </trim>
+    </select>
+
+    <select id="getListFromOutsource" resultMap="BizCarrierResult" parameterType="cn.ezhizao.project.business.domain.BizCarrier">
+        select t1.id,t1.category_id,t1.code,t1.qc_code,t1.remark,t1.tenant_id,t1.is_allow_more,COALESCE((SELECT t2.is_abandoned FROM biz_carrier_reject t2 WHERE t1.id = t2.carrier_id ORDER BY t2.create_time DESC LIMIT 1), 0) AS is_abandoned
+        FROM biz_carrier t1
+        <trim prefix=" WHERE" suffix="" suffixOverrides="AND">
+            deleted = 0 AND is_abandoned =0
+            <if test="categoryId != null  and categoryId != 0"> AND t1.category_id = #{categoryId}</if>
+            <if test="code != null  and code != ''"> AND  t1.code=#{code}</if>
+            <!--  未关联任何生产单  -->
+            <if test="notInUse == 1">
+                AND not exists (select 1 from biz_daywork_carrier t where t.is_changed = 0 and t.carrier_id = t1.id)
+            </if>
 
+        </trim>
     </select>
 
+
+
     <update id="unAbandoned">
         update biz_carrier
         <set>

+ 3 - 0
src/main/resources/mybatis/business/BizDayworkMapper.xml

@@ -233,6 +233,9 @@
                 AND t2.description LIKE CONCAT('%', #{productDescription}, '%')
             </if>
             <if test="lotCode != null and lotCode != ''">AND t1.lot_code LIKE CONCAT('%', #{lotCode}, '%')</if>
+            <if test="keyword != null  and keyword != ''">AND (t1.lot_code LIKE concat('%', #{keyword}, '%')or
+                t2.description LIKE concat('%', #{keyword}, '%'))
+            </if>
             <if test="isSupplierProducts == 1 and supplierId != null and supplierId != ''">
                 AND t1.product_id IN (SELECT product_id FROM biz_supplier_product WHERE supplier_id=#{supplierId} AND deleted=0)
             </if>

+ 5 - 3
src/main/resources/mybatis/business/BizLotTechnologicalProcessDetailMapper.xml

@@ -22,9 +22,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         SELECT * FROM biz_lot_technological_process_detail
         <trim prefix=" WHERE" suffix="" suffixOverrides="AND">
             deleted = 0
-            <if test="lotTechnologicalProcessId != null">AND lot_technological_process_id = #{lotTechnologicalProcessId}</if>
-            <if test="processStepNumber != null  processStepNumber!=''">AND process_step_number > #{processStepNumber}</if>
-
+            <if test="technologicalProcessId != null">AND lot_technological_process_id = #{technologicalProcessId}</if>
+            <if test="processStepNumber != null  and processStepNumber!=''">AND process_step_number > #{processStepNumber}</if>
+            <if test="keyword != null  and keyword != ''">AND (process_key LIKE concat('%', #{keyword}, '%')or
+                process_alias LIKE concat('%', #{keyword}, '%'))
+            </if>
         </trim>
         order by process_step_number
     </select>

+ 3 - 0
src/main/resources/mybatis/business/BizTechnologicalProcessDetailMapper.xml

@@ -41,6 +41,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             deleted = 0 and tenant_id != 9
             <if test="technologicalProcessId!= null"> AND technological_process_id = #{technologicalProcessId}</if>
             <if test="processStepNumber != null and processStepNumber!=''">AND process_step_number > #{processStepNumber}</if>
+            <if test="keyword != null  and keyword != ''">AND (process_key LIKE concat('%', #{keyword}, '%')or
+                process_alias LIKE concat('%', #{keyword}, '%'))
+            </if>
         </trim>
         order by process_step_number
     </select>

+ 408 - 0
src/main/resources/mybatis/system/SysUserMapper.xml

@@ -0,0 +1,408 @@
+<?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.system.mapper.SysUserMapper">
+
+	<resultMap type="SysUser" id="SysUserResult">
+		<id     property="userId"              column="user_id"      />
+		<result property="tenantId"            column="tenant_id"      />
+		<result property="userName"            column="user_name"    />
+		<result property="userType"            column="user_type"    />
+		<result property="nickName"            column="nick_name"    />
+		<result property="email"               column="email"        />
+		<result property="phoneNumber"         column="phone_number"  />
+		<result property="sex"                 column="sex"          />
+		<result property="avatar"       	   column="avatar"       />
+		<result property="password"     	   column="password"     />
+		<result property="status"       	   column="status"       />
+		<result property="delFlag"      	   column="del_flag"     />
+		<result property="loginIp"      	   column="login_ip"     />
+		<result property="loginDate"    	   column="login_date"   />
+		<result property="createBy"     	   column="create_by"    />
+		<result property="createTime"  		   column="create_time"  />
+		<result property="updateBy"            column="update_by"    />
+		<result property="updateTime"          column="update_time"  />
+		<result property="remark"              column="remark"       />
+		<collection  property="roles"   javaType="java.util.List"  resultMap="RoleResult" />
+	</resultMap>
+
+	<resultMap id="RoleResult" type="SysRole">
+		<id     property="roleId"       column="role_id"        />
+		<result property="roleName"     column="role_name"      />
+		<result property="roleKey"      column="role_key"       />
+		<result property="roleSort"     column="role_sort"      />
+		<result property="dataScope"    column="data_scope"    />
+		<result property="status"       column="role_status"    />
+	</resultMap>
+
+	<sql id="selectUserTenantVo">
+		SELECT u.user_id, u.tenant_id, IFNULL(t.org_name, '超级管理员') AS tenant_name, u.user_type,u.user_name, u.nick_name, u.email,u.contract_company_name, u.contract_company_id, u.avatar, u.phone_number, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, u.usage_company_id,
+		u.usage_company_name,
+			   r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status
+		FROM sys_user u
+		         LEFT JOIN biz_tenant t ON t.id = u.tenant_id
+				 LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id
+				 LEFT JOIN sys_role r ON r.role_id = ur.role_id
+	</sql>
+	<select id="getListByDeptId" parameterType="java.util.List" resultMap="SysUserResult">
+        SELECT u.*,
+            -- 用于前端控制是否进入编辑状态
+            0 AS is_edit,
+            deptUser.is_leader,
+            deptUser.is_part_time,
+            deptUser.is_dispatcher,
+			deptUser.is_formman,
+			deptUser.is_yardman,
+		    deptUser.id
+        FROM sys_user u
+		JOIN (SELECT * FROM sys_dept_user WHERE deleted = 0 AND dept_id in
+		<foreach collection="ids" item="deptId" open="(" separator="," close=")">
+		#{deptId}
+	</foreach>) AS deptUser
+			ON u.user_id = deptUser.user_id
+        WHERE
+			u.del_flag = '0' AND
+			u.user_type = '02'
+    </select>
+
+	<select id="selectUserItemByDeptId"  resultMap="SysUserResult">
+		SELECT u.* FROM sys_user u left join sys_dept_user d on u.user_id = d.user_id
+		WHERE u.del_flag = '0' AND d.deleted ='0' AND u.user_type = '02'
+		<if test="userName != null and userName != ''">
+			AND u.user_name LIKE concat('%', #{userName}, '%')
+		</if>
+		<if test="nickName != null and nickName != ''">
+			AND u.nick_name LIKE concat('%', #{nickName}, '%')
+		</if>
+
+	</select>
+	<select id="getUserByCode" parameterType="SysUser" resultMap="SysUserResult">
+		SELECT * FROM sys_user WHERE del_flag = 0 AND user_name = #{userName}
+	</select>
+
+	<!-- 用户列表 selectUserList -->
+	<select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">
+		SELECT distinct u.user_id,
+		       u.nick_name,
+		       u.user_name,
+		       u.email,
+		       u.avatar,
+		       u.phone_number,
+		       u.sex,
+		       u.status,
+		       u.del_flag,
+		       u.login_ip,
+		       u.login_date,
+		       u.create_by,
+		       u.create_time,
+		       u.usage_company_id,
+		       u.usage_company_name,
+		       u.contract_company_id,
+		       u.contract_company_name,
+		       u.remark FROM sys_user u left join sys_dept_user d on u.user_id = d.user_id
+		WHERE u.del_flag = '0' and d.deleted = 0
+		<if test="userId != null and userId != 0">
+			AND u.user_id = #{userId}
+		</if>
+		<if test="tenantId != null and tenantId != 0">
+			AND u.tenant_id = #{tenantId}
+		</if>
+		<if test="deptId != null and deptId != 0">
+			AND d.dept_id = #{deptId}
+		</if>
+		<if test="userName != null and userName != ''">
+			AND u.user_name LIKE concat('%', #{userName}, '%')
+		</if>
+		<if test="nickName != null and nickName != ''">
+			AND u.nick_name LIKE concat('%', #{nickName}, '%')
+		</if>
+		<if test="status != null and status != ''">
+			AND u.status = #{status}
+		</if>
+		<if test="userType != null and userType != ''">
+			AND u.user_type = #{userType}
+		</if>
+		<if test="phoneNumber != null and phoneNumber != ''">
+			AND u.phone_number LIKE concat('%', #{phoneNumber}, '%')
+		</if>
+		<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
+			AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+		</if>
+		<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
+			AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+		</if>
+		<!-- 数据范围过滤 -->
+		${params.dataScope}
+	</select>
+	<select id="selectTenantList" parameterType="SysUser" resultMap="SysUserResult">
+		SELECT distinct u.user_id,
+		u.nick_name,
+		u.user_name,
+		u.email,
+		u.avatar,
+		u.phone_number,
+		u.sex,
+		u.status,
+		u.del_flag,
+		u.login_ip,
+		u.login_date,
+		u.create_by,
+		u.create_time,
+		u.usage_company_id,
+		u.usage_company_name,
+		u.contract_company_id,
+		u.contract_company_name,
+		u.remark FROM sys_user u
+		WHERE u.del_flag = '0'
+		<if test="userId != null and userId != 0">
+			AND u.user_id = #{userId}
+		</if>
+		<if test="tenantId != null and tenantId != 0">
+			AND u.tenant_id = #{tenantId}
+		</if>
+		<if test="deptId != null and deptId != 0">
+			AND d.dept_id = #{deptId}
+		</if>
+		<if test="userName != null and userName != ''">
+			AND u.user_name LIKE concat('%', #{userName}, '%')
+		</if>
+		<if test="nickName != null and nickName != ''">
+			AND u.nick_name LIKE concat('%', #{nickName}, '%')
+		</if>
+		<if test="status != null and status != ''">
+			AND u.status = #{status}
+		</if>
+		<if test="userType != null and userType != ''">
+			AND u.user_type = #{userType}
+		</if>
+		<if test="phoneNumber != null and phoneNumber != ''">
+			AND u.phone_number LIKE concat('%', #{phoneNumber}, '%')
+		</if>
+		<!-- 数据范围过滤 -->
+		${params.dataScope}
+	</select>
+	<!-- 员工列表 selectEmployeeList -->
+	<select id="selectEmployeeList" parameterType="SysUser" resultMap="SysUserResult">
+		SELECT
+		   u.tenant_id,
+		   u.user_type,
+		   u.user_id,
+		   u.nick_name,
+		   u.user_name,
+		   u.contract_company_name,
+		   u.contract_company_id,
+		   u.email,
+		   u.avatar,
+		   u.phone_number,
+		   u.sex,
+		   u.status,
+		   u.del_flag,
+		   u.login_ip,
+		   u.login_date,
+		   u.create_by,
+		   u.create_time,
+		   u.remark,
+		u.usage_company_id,
+		u.usage_company_name
+		FROM sys_user u
+		WHERE u.del_flag = '0' AND u.user_type='02'
+		<if test="userId != null and userId != 0">
+			AND u.user_id = #{userId}
+		</if>
+		<if test="tenantId != null and tenantId != 0">
+			AND tenant_id = #{tenantId}
+		</if>
+		<if test="userName != null and userName != ''">
+			AND u.user_name LIKE concat('%', #{userName}, '%')
+		</if>
+		<if test="nickName != null and nickName != ''">
+			AND u.nick_name LIKE concat('%', #{nickName}, '%')
+		</if>
+		<if test="status != null and status != ''">
+			AND u.status = #{status}
+		</if>
+		<if test="phoneNumber != null and phoneNumber != ''">
+			AND u.phone_number LIKE concat('%', #{phoneNumber}, '%')
+		</if>
+		<if test="params.beginTime != null and params.beginTime != ''"><!-- 开始时间检索 -->
+			AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')
+		</if>
+		<if test="params.endTime != null and params.endTime != ''"><!-- 结束时间检索 -->
+			AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
+		</if>
+		<!-- 数据范围过滤 -->
+		${params.dataScope}
+	</select>
+
+	<select id="selectAllocatedList" parameterType="SysUser" resultMap="SysUserResult">
+		SELECT distinct u.user_id,u.user_name, u.nick_name, u.email, u.phone_number, u.status, u.create_time
+		FROM sys_user u
+		LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id
+		LEFT JOIN sys_role r ON r.role_id = ur.role_id
+		WHERE u.del_flag = '0' AND r.role_id = #{roleId}
+		<if test="userName != null and userName != ''">
+			AND u.user_name LIKE concat('%', #{userName}, '%')
+		</if>
+		<if test="nickName != null and nickName != ''">
+			AND u.nick_name LIKE concat('%', #{nickName}, '%')
+		</if>
+		<if test="tenantId != null  and tenantId != 0"> AND u.tenant_id = #{tenantId}</if>
+		<!-- 数据范围过滤 -->
+		${params.dataScope}
+	</select>
+
+	<select id="selectUnallocatedList" parameterType="SysUser" resultMap="SysUserResult">
+		SELECT distinct u.user_id, u.user_name, u.nick_name, u.email, u.phone_number, u.status, u.create_time
+		FROM sys_user u
+		LEFT JOIN biz_user_tenant ut ON ut.user_id = u.user_id
+		LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id
+		LEFT JOIN sys_role r ON r.role_id = ur.role_id
+		WHERE u.del_flag = '0' AND (r.role_id != #{roleId} or r.role_id IS NULL) and u.user_id != 1 and u.user_id !=2 and u.user_type = '02'
+		AND u.user_id NOT IN (SELECT u.user_id FROM sys_user u INNER JOIN sys_user_role ur ON u.user_id = ur.user_id AND ur.role_id = #{roleId})
+		<if test="userName != null and userName != ''">
+			AND u.user_name LIKE concat('%', #{userName}, '%')
+		</if>
+		<if test="nickName != null and nickName != ''">
+			AND u.nick_name LIKE concat('%', #{nickName}, '%')
+		</if>
+		<if test="tenantId != null  and tenantId != 0"> AND u.tenant_id = #{tenantId}</if>
+		<!-- 数据范围过滤 -->
+		${params.dataScope}
+	</select>
+
+	<select id="selectUserByUserName" parameterType="String" resultMap="SysUserResult">
+		<include refid="selectUserTenantVo"/>
+		WHERE u.user_name = #{userName} AND u.del_flag = '0'
+	</select>
+
+	<select id="selectUserByUserNameAndTenantId" parameterType="String" resultMap="SysUserResult">
+		<include refid="selectUserTenantVo"/>
+		WHERE u.user_name = #{userName} AND u.tenant_id = #{tenantId} AND u.del_flag = '0'
+	</select>
+
+	<select id="selectUserById" parameterType="Long" resultMap="SysUserResult">
+		<include refid="selectUserTenantVo"/>
+		WHERE u.user_id = #{userId}
+	</select>
+
+	<select id="checkUserNameUnique"  resultMap="SysUserResult">
+		SELECT user_id, user_name FROM sys_user WHERE user_name = #{userName} AND del_flag = '0'
+		LIMIT 1
+	</select>
+
+	<select id="selectUserListByIds" parameterType="Long" resultMap="SysUserResult">
+		<include refid="selectUserTenantVo"/>
+		WHERE u.user_id in
+		<foreach collection="list" item="userId" open="(" separator="," close=")">
+			#{userId}
+		</foreach>
+	</select>
+
+	<select id="checkPhoneUnique" parameterType="String" resultMap="SysUserResult">
+		SELECT user_id, phone_number FROM sys_user WHERE phone_number = #{phoneNumber} AND del_flag = '0' limit 1
+	</select>
+
+	<select id="checkEmailUnique" parameterType="String" resultMap="SysUserResult">
+		SELECT user_id, email FROM sys_user WHERE email = #{email} AND del_flag = '0' limit 1
+	</select>
+	<select id="listByLikeNickNameOrUserName" resultMap="SysUserResult">
+        SELECT * FROM sys_user
+        <trim prefix=" WHERE" suffix="" suffixOverrides="AND">
+			del_flag = '0' and user_type='02' and user_id !=1 and user_id != 2
+			<if test="userName != null  and userName != ''"> AND user_name like concat('%', #{userName}, '%')</if>
+			<if test="nickName != null  and nickName != ''"> AND nick_name like concat('%', #{nickName}, '%')</if>
+        </trim>
+    </select>
+
+	<insert id="insertUser" parameterType="SysUser" useGeneratedKeys="true" keyProperty="userId" >
+		INSERT INTO sys_user(
+		<if test="userId != null and userId != 0">user_id,</if>
+		<if test="userName != null and userName != ''">user_name,</if>
+		<if test="nickName != null and nickName != ''">nick_name,</if>
+		<if test="email != null and email != ''">email,</if>
+		<if test="tenantId != null and tenantId != ''">tenant_id,</if>
+		<if test="avatar != null and avatar != ''">avatar,</if>
+		<if test="phoneNumber != null and phoneNumber != ''">phone_number,</if>
+		<if test="sex != null and sex != ''">sex,</if>
+		<if test="password != null and password != ''">password,</if>
+		<if test="status != null and status != ''">status,</if>
+		<if test="createBy != null and createBy != ''">create_by,</if>
+		<if test="remark != null and remark != ''">remark,</if>
+		<if test="userType != null and userType != ''">user_type,</if>
+		<if test="contractCompanyName != null and contractCompanyName != ''">contract_company_name,</if>
+		<if test="contractCompanyId != null and contractCompanyId != ''">contract_company_id,</if>
+		<if test="usageCompanyId != null and usageCompanyId != 0">usage_company_id,</if>
+		<if test="usageCompanyName != null and usageCompanyName != ''">usage_company_name,</if>
+		create_time
+		)VALUES(
+		<if test="userId != null and userId != ''">#{userId},</if>
+		<if test="userName != null and userName != ''">#{userName},</if>
+		<if test="nickName != null and nickName != ''">#{nickName},</if>
+		<if test="email != null and email != ''">#{email},</if>
+		<if test="tenantId != null and tenantId != ''">#{tenantId},</if>
+		<if test="avatar != null and avatar != ''">#{avatar},</if>
+		<if test="phoneNumber != null and phoneNumber != ''">#{phoneNumber},</if>
+		<if test="sex != null and sex != ''">#{sex},</if>
+		<if test="password != null and password != ''">#{password},</if>
+		<if test="status != null and status != ''">#{status},</if>
+		<if test="createBy != null and createBy != ''">#{createBy},</if>
+		<if test="remark != null and remark != ''">#{remark},</if>
+		<if test="userType != null and userType != ''">#{userType},</if>
+		<if test="contractCompanyName != null and contractCompanyName != ''">#{contractCompanyName},</if>
+		<if test="contractCompanyId != null and contractCompanyId != ''">#{contractCompanyId},</if>
+		<if test="usageCompanyId != null and usageCompanyId != 0">#{usageCompanyId},</if>
+		<if test="usageCompanyName != null and usageCompanyName != ''">#{usageCompanyName},</if>
+		sysdate()
+		)
+	</insert>
+
+	<update id="updateUser" parameterType="SysUser">
+		UPDATE sys_user
+		<set>
+			<if test="userName != null and userName != ''">user_name = #{userName},</if>
+			<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
+			<if test="email != null ">email = #{email},</if>
+			<if test="phoneNumber != null ">phone_number = #{phoneNumber},</if>
+			<if test="tenantId != null ">tenant_id=#{tenantId},</if>
+			<if test="sex != null and sex != ''">sex = #{sex},</if>
+			<if test="avatar != null and avatar != ''">avatar = #{avatar},</if>
+			<if test="password != null and password != ''">password = #{password},</if>
+			<if test="status != null and status != ''">status = #{status},</if>
+			<if test="loginIp != null and loginIp != ''">login_ip = #{loginIp},</if>
+			<if test="loginDate != null">login_date = #{loginDate},</if>
+			<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
+			<if test="remark != null">remark = #{remark},</if>
+			<if test="contractCompanyName != null and contractCompanyName != ''">contract_company_name = #{contractCompanyName},</if>
+			<if test="contractCompanyId != null and contractCompanyId != ''">contract_company_id = #{contractCompanyId},</if>
+			<if test="usageCompanyId != null and usageCompanyId != 0">usage_company_id = #{usageCompanyId},</if>
+			<if test="usageCompanyName != null and usageCompanyName != ''">usage_company_name = #{usageCompanyName},</if>
+			update_time = sysdate()
+		</set>
+		WHERE user_id = #{userId}
+	</update>
+
+	<update id="updateUserStatus" parameterType="SysUser">
+		UPDATE sys_user SET status = #{status} WHERE user_id = #{userId}
+	</update>
+
+	<update id="updateUserAvatar" parameterType="SysUser">
+		UPDATE sys_user SET avatar = #{avatar} WHERE user_name = #{userName}
+	</update>
+
+	<update id="resetUserPwd" parameterType="SysUser">
+		UPDATE sys_user SET password = #{password} WHERE user_name = #{userName}
+	</update>
+
+	<delete id="deleteUserById" parameterType="Long">
+		UPDATE sys_user SET del_flag = '2' WHERE user_id = #{userId}
+	</delete>
+
+	<delete id="deleteUserByIds" parameterType="Long">
+		UPDATE sys_user SET del_flag = '2' WHERE user_id in
+		<foreach collection="list" item="userId" open="(" separator="," close=")">
+			#{userId}
+		</foreach>
+	</delete>
+
+</mapper>