chenrui
2025-02-27 146edfb05602373ad5b36771e1ede1e395d8ab62
Merge branch 'dev' of http://114.132.189.42:9002/r/lims-ruoyi-after into dev_cr
已修改29个文件
已添加1个文件
891 ■■■■■ 文件已修改
basic-server/src/main/java/com/ruoyi/basic/controller/StandardTemplateController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/service/impl/StandardTemplateServiceImpl.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessComplainController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessDealController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessEvaluateController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodSearchNewController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodVerifyController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessReportController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessTotalSampleController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessTotaldealController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/src/main/java/com/ruoyi/process/mapper/ProcessReportMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsOrderMapper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java 444 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/mapper/InsOrderMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
inspect-server/src/main/resources/static/report-template.docx 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/banner.txt 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/GZipUtil.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
basic-server/src/main/java/com/ruoyi/basic/controller/StandardTemplateController.java
@@ -56,8 +56,7 @@
    @ApiOperation(value = "编辑模板编制")
    @GetMapping("/getEditTemplatePreparation")
    public Result<?> getEditTemplatePreparation(@RequestParam("id") Integer id) {
        StandardTemplate byId = standardTemplateService.getById(id);
        return Result.success(byId.getThing());
        return Result.success(standardTemplateService.getStandTempThingById(id));
    }
    @ApiOperation(value = "复制原始记录模板")
basic-server/src/main/java/com/ruoyi/basic/service/impl/StandardTemplateServiceImpl.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.numgen.NumberGenerator;
import com.ruoyi.common.utils.GZipUtil;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.basic.mapper.StandardTemplateMapper;
import com.ruoyi.basic.pojo.StandardTemplate;
@@ -45,12 +46,19 @@
                    StandardTemplate::getNumber);
            standardTemplate.setNumber(giveCode);
        }
        if (StringUtils.isNotBlank(standardTemplate.getThing())) {
            standardTemplate.setThing(GZipUtil.compress(standardTemplate.getThing()));
        } else {
            standardTemplate.setThing(null);
        }
        return standardTemplateMapper.insert(standardTemplate);
    }
    @Override
    public int upStandardTemplate(StandardTemplate standardTemplate) {
        if(standardTemplate.getThing().equals("")){
        if (StringUtils.isNotBlank(standardTemplate.getThing())) {
            standardTemplate.setThing(GZipUtil.compress(standardTemplate.getThing()));
        } else {
            standardTemplate.setThing(null);
        }
        return standardTemplateMapper.updateById(standardTemplate);
@@ -74,19 +82,8 @@
        if(standardTemplate==null){
            return null;
        }else{
            return standardTemplate.getThing();
            return GZipUtil.uncompress(standardTemplate.getThing());
        }
        // æŸ¥è¯¢åŽ‹ç¼©åŽçš„æ•°æ®
//        String thing = standardTemplateMapper.selectCompressThing(templateId);
//        if (StringUtils.isNotBlank(thing)) {
//            try {
//                return DecompressMySQLData.decompress(java.util.Base64.getDecoder().decode(thing));
//            } catch (Exception e) {
//                throw new RuntimeException(e);
//            }
//        } else {
//            return null;
//        }
    }
    @Override
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessComplainController.java
@@ -48,7 +48,7 @@
    }
    @ApiOperation(value = "投诉详情")
    @PostMapping("/getProcessComplain")
    @GetMapping("/getProcessComplain")
    public Result getProcessComplain(Long id) {
        return Result.success(processComplainService.getProcessComplain(id));
    }
@@ -60,9 +60,8 @@
    }
    @ApiOperation(value = "导出列表")
    @PostMapping("/exportProcessComplain")
    public void exportProcessComplain(@RequestBody Map<String, Object> data,HttpServletResponse response) throws Exception {
        ProcessComplain processComplain = JackSonUtil.unmarshal(JackSonUtil.marshal(data.get("entity")), ProcessComplain.class);
    @GetMapping("/exportProcessComplain")
    public void exportProcessComplain(ProcessComplain processComplain,HttpServletResponse response) throws Exception {
        processComplainService.exportProcessComplain(processComplain,response);
    }
}
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessDealController.java
@@ -29,7 +29,7 @@
    private ProcessDealService processDealService;
    @ApiOperation(value = "查询检测或校准物品的处置详情")
    @PostMapping("/pageProcessDeal")
    @GetMapping("/pageProcessDeal")
    public Result pageProcessDeal(ProcessDeal processDeal, Page page) throws Exception {
        return Result.success(processDealService.pageProcessDeal(page, processDeal));
    }
@@ -53,7 +53,7 @@
    }
    @ApiOperation(value = "查看检测或校准物品的处置")
    @PostMapping("/getProcessDeal")
    @GetMapping("/getProcessDeal")
    public Result getProcessDeal(Integer id) {
        return Result.success(processDealService.getById(id));
    }
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessEvaluateController.java
@@ -30,7 +30,7 @@
    private ProcessEvaluateService processEvaluateService;
    @ApiOperation(value = "查询测量不确定度的评定列表")
    @PostMapping("/pageProcessEvaluate")
    @GetMapping("/pageProcessEvaluate")
    public Result pageProcessEvaluate(ProcessEvaluate processEvaluate,Page page) throws Exception {
        return Result.success(processEvaluateService.pageProcessEvaluate(page, processEvaluate));
    }
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodSearchNewController.java
@@ -78,7 +78,7 @@
     * @return
     */
    @ApiOperation(value = "导入标准查新")
    @GetMapping("/importMethodSearchNew")
    @PostMapping("/importMethodSearchNew")
    public Result importMethodSearchNew(MultipartFile file){
        return Result.success(processMethodSearchNewService.importMethodSearchNew(file));
    }
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessMethodVerifyController.java
@@ -47,7 +47,7 @@
     * @return
     */
    @ApiOperation(value = "标准方法更新验证列表")
    @PostMapping("/pagesMethodVerify")
    @GetMapping("/pagesMethodVerify")
    public Result<IPage<ProcessMethodVerify>> pagesMethodVerify(ProcessMethodVerifyDto methodVerifyDto,Page page) throws Exception {
        return Result.success(processMethodVerifyService.pagesMethodVerify(page, methodVerifyDto));
    }
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessReportController.java
@@ -7,10 +7,7 @@
import com.ruoyi.process.service.ProcessReportService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
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 org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.Map;
@@ -32,7 +29,7 @@
    private ProcessReportService processReportService;
    @ApiOperation(value = "查询检验报告发放登记列表")
    @PostMapping("/pageProcessReport")
    @GetMapping("/pageProcessReport")
    public Result pageProcessReport(ProcessReport processReport , Page page) throws Exception {
        return Result.success(processReportService.pageProcessReport(page, processReport));
    }
@@ -44,13 +41,13 @@
    }
    @ApiOperation(value = "删除检验报告发放登记")
    @PostMapping("/delProcessReport")
    @DeleteMapping("/delProcessReport")
    public Result delProcessReport(Long id) {
        return Result.success(processReportService.removeById(id));
    }
    @ApiOperation(value = "查看检验报告发放登记详情")
    @PostMapping("/getProcessReport")
    @GetMapping("/getProcessReport")
    public Result getProcessReport(Long id)  {
        return Result.success(processReportService.getById(id));
    }
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessTotalSampleController.java
@@ -35,19 +35,24 @@
    @ApiOperation(value = "提交样品接收")
    @PostMapping("/submitProcessTotalSample")
    public Result submitProcessTotalSample(Integer id) {
    public Result submitProcessTotalSample(@RequestBody Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        return Result.success(processTotalSampleService.submitProcessTotalSample(id));
    }
    @ApiOperation(value = "审核样品接收")
    @PostMapping("/checkProcessTotalSample")
    public Result checkProcessTotalSample(Integer id, String state) {
    public Result checkProcessTotalSample(@RequestBody Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        String state = (String) param.get("state");
        return Result.success(processTotalSampleService.checkProcessTotalSample(id, state));
    }
    @ApiOperation(value = "批准样品接收")
    @PostMapping("/ratifyProcessTotalSample")
    public Result ratifyProcessTotalSample(Integer id,String state) {
    public Result ratifyProcessTotalSample(@RequestBody Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        String state = (String) param.get("state");
        return Result.success(processTotalSampleService.ratifyProcessTotalSample(id,state));
    }
cnas-process/src/main/java/com/ruoyi/process/controller/ProcessTotaldealController.java
@@ -35,19 +35,24 @@
    @ApiOperation(value = "提交检测或校准物品的处置")
    @PostMapping("/submitProcessTotaldeal")
    public Result submitProcessTotaldeal(Integer id) {
    public Result submitProcessTotaldeal(@RequestBody Map<String, Integer> param) {
        Integer id = param.get("id");
        return Result.success(processTotaldealService.submitProcessTotaldeal(id));
    }
    @ApiOperation(value = "审核检测或校准物品的处置")
    @PostMapping("/checkProcessTotaldeal")
    public Result checkProcessTotaldeal(Integer id, String state) {
    public Result checkProcessTotaldeal(@RequestBody Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        String state = (String) param.get("state");
        return Result.success(processTotaldealService.checkProcessTotaldeal(id, state));
    }
    @ApiOperation(value = "批准检测或校准物品的处置")
    @PostMapping("/ratifyProcessTotaldeal")
    public Result ratifyProcessTotaldeal(Integer id,String state) {
    public Result ratifyProcessTotaldeal(@RequestBody Map<String, Object> param) {
        Integer id = (Integer) param.get("id");
        String state = (String) param.get("state");
        return Result.success(processTotaldealService.ratifyProcessTotaldeal(id,state));
    }
cnas-process/src/main/java/com/ruoyi/process/mapper/ProcessReportMapper.java
@@ -21,5 +21,5 @@
    IPage<ProcessReport> pageProcessReport(Page page, @Param("ew") QueryWrapper<ProcessReport> queryWrappers);
    List<ProcessReport> getIds(List<Integer> ids);
    List<ProcessReport> getIds(@Param("ids") List<Integer> ids);
}
inspect-server/src/main/java/com/ruoyi/inspect/mapper/InsOrderMapper.java
@@ -38,7 +38,7 @@
    List<CostStatisticsDto> selectCostStatistics2(@Param("ew") QueryWrapper<CostStatisticsDto> ew);
    List<Map<String, String>> selectDeviceList(@Param("names") Set<String> names);
    List<Map<String, String>> selectDeviceList(@Param("managementNumbers") Set<String> managementNumbers);
    List<SampleDefectsFatherVo> selectSampleDefects(Page page, @Param("inspectionItems") String inspectionItems, @Param("orderNumber") String orderNumber);
    Long getCount(@Param("inspectionItems") String inspectionItems, @Param("orderNumber") String orderNumber);
inspect-server/src/main/java/com/ruoyi/inspect/pojo/InsOrderStandardTemplate.java
@@ -4,6 +4,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Date;
/**
@@ -44,11 +45,11 @@
    @TableField(fill = FieldFill.INSERT)
    @ApiModelProperty("创建时间")
    private Date createTime;
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @ApiModelProperty("修改时间")
    private Date updateTime;
    private LocalDateTime updateTime;
    @ApiModelProperty("模板编号")
    private String number;
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderPlanServiceImpl.java
@@ -34,7 +34,6 @@
import com.ruoyi.common.constant.InsOrderTypeConstants;
import com.ruoyi.common.core.domain.entity.Custom;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.*;
import com.ruoyi.framework.exception.ErrorException;
@@ -42,6 +41,7 @@
import com.ruoyi.inspect.mapper.*;
import com.ruoyi.inspect.pojo.*;
import com.ruoyi.inspect.service.*;
import com.ruoyi.inspect.util.HackLoopTableRenderPolicy;
import com.ruoyi.inspect.vo.InsOrderPlanTaskSwitchVo;
import com.ruoyi.inspect.vo.InsOrderPlanVO;
import com.ruoyi.performance.mapper.AuxiliaryOutputWorkingHoursMapper;
@@ -55,6 +55,7 @@
import com.ruoyi.system.service.InformationNotificationService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -590,8 +591,27 @@
        return insSampleUserMapper.insert(insSampleUser);
    }
    /**
     * æŸ¥è¯¢æ¨¡æ¿å†…容
     * @param order
     * @param insProducts
     */
    private void getTemplateThing(InsOrder order, List<InsProduct> insProducts) {
        Set<Integer> set = new HashSet<>();
        // æ£€éªŒé¡¹åˆ†ç±»+检验项+检验子项的拼接
        List<String> itemNameList = insProducts.stream().map(insProduct -> {
            String itemName = "";
            if (StringUtils.isNotBlank(insProduct.getInspectionItemClass())) {
                itemName += insProduct.getInspectionItemClass().trim();
            }
            if (StringUtils.isNotBlank(insProduct.getInspectionItem())) {
                itemName += insProduct.getInspectionItem().trim();
            }
            if (StringUtils.isNotBlank(insProduct.getInspectionItemSubclass())) {
                itemName += insProduct.getInspectionItemSubclass().trim();
            }
            return itemName;
        }).collect(Collectors.toList());
        // æŸ¥è¯¢è®¢å•状态判断是否是查历史模板
        if (order.getIsFirstSubmit() != null && order.getIsFirstSubmit().equals(1)) {
            InsOrderState insOrderState = insOrderStateMapper.selectOne(Wrappers.<InsOrderState>lambdaQuery()
@@ -611,7 +631,11 @@
                                .eq(InsOrderStandardTemplate::getInsOrderId, order.getId()));
                        thing = one.getThing();
                        if (StrUtil.isNotEmpty(thing)) {
                            thing = GZipUtil.uncompress(thing);
                            JSONObject sheet = JSON.parseObject(JSON.toJSONString(JSON.parseArray(JSON.toJSONString(JSON.parseObject(thing).get("data"))).get(0)));
                            // æ¸…除没有关联的检验项
                            eliminateItem(sheet, itemNameList);
                            JSONObject config = JSON.parseObject(JSON.toJSONString(sheet.get("config")));
                            List<JSONObject> cellData = JSON.parseArray(JSON.toJSONString(sheet.get("celldata")), JSONObject.class);
                            Map<String, Object> style = new HashMap<>();
@@ -636,6 +660,8 @@
            }
            if (StrUtil.isNotEmpty(thing)) {
                JSONObject sheet = JSON.parseObject(JSON.toJSONString(JSON.parseArray(JSON.toJSONString(JSON.parseObject(thing).get("data"))).get(0)));
                // æ¸…除没有关联的检验项
                eliminateItem(sheet, itemNameList);
                JSONObject config = JSON.parseObject(JSON.toJSONString(sheet.get("config")));
                List<JSONObject> cellData = JSON.parseArray(JSON.toJSONString(sheet.get("celldata")), JSONObject.class);
                Map<String, Object> style = new HashMap<>();
@@ -646,6 +672,90 @@
                product.setTemplateName(standardTemplateService.getStandTempNameById(product.getTemplateId()));
            }
        }
    }
    /**
     * æ¸…除没有使用的检验项
     * @param sheet
     * @param itemNameList
     */
    private static void eliminateItem(JSONObject sheet, List<String> itemNameList) {
        // èŽ·å–åˆ° æ£€éªŒé¡¹åˆ†ç±»+检验项+检验子项的拼接,如果模板里的信息跟接口返回的检验项信息能够匹配则展示出来
        // å¾ªçŽ¯è¡Œæ•°åˆ¤æ–­æ˜¯å¦
        JSONArray dataListJSONArray = sheet.getJSONArray("data");
        // æ·»åŠ åæ ‡map
        Map<String, String> coordinatesMap = new HashMap<>();
        // éœ€è¦ç§»é™¤çš„索引
        List<Integer> deleteIndex = new ArrayList<>();
        // å¾ªçŽ¯åˆ—
        for (int r = 0; r < dataListJSONArray.size(); r++) {
            JSONArray dataList = dataListJSONArray.getJSONArray(r);
            // å¾ªçŽ¯è¡Œ
            String itemName = "";
            // åˆ¤æ–­æ˜¯å¦æ˜¾ç¤º
            boolean isShow = false;
            for (int c = 0; c < dataList.size(); c++) {
                // æŸ¥è¯¢æ‰¹æ³¨
                JSONObject jsonObject = dataList.getJSONObject(c);
                try {
                    if (jsonObject.getJSONObject("ps").getString("value").equals("检验项分类")) {
                        String value = jsonObject.getString("v").trim();
                        itemName += value;
                        // æ·»åŠ åæ ‡
                        String coordinates = coordinatesJoint(r, c);
                        coordinatesMap.put(coordinates, value);
                        isShow = true;
                    } else if (jsonObject.getJSONObject("ps").getString("value").equals("检验项")) {
                        String value = jsonObject.getString("v").trim();
                        itemName += value;
                        // æ·»åŠ åæ ‡
                        String coordinates = coordinatesJoint(r, c);
                        coordinatesMap.put(coordinates, value);
                        isShow = true;
                    } else if (jsonObject.getJSONObject("ps").getString("value").equals("检验子项")) {
                        String value = jsonObject.getString("v").trim();
                        itemName += value;
                        // æ·»åŠ åæ ‡
                        String coordinates = coordinatesJoint(r, c);
                        coordinatesMap.put(coordinates, value);
                        isShow = true;
                    }
                } catch (Exception e) {
                    // åˆ¤æ–­æ˜¯å¦æœ‰mc合并单元格
                    if (jsonObject != null && jsonObject.getJSONObject("mc") != null) {
                        // æŸ¥è¯¢åæ ‡è¿›è¡Œæ·»åŠ 
                        String value = coordinatesMap.get(coordinatesJoint(jsonObject.getJSONObject("mc").getInteger("r"), jsonObject.getJSONObject("mc").getInteger("c")));
                        if (StringUtils.isNotBlank(value) && !itemName.contains(value)) {
                            itemName += value;
                        }
                    }
                }
            }
            // åˆ¤æ–­è¯¥è®¢å•是否有改检验项, æ²¡æœ‰å‰”除
            if (isShow) {
                if (!itemNameList.contains(itemName)) {
                    dataListJSONArray.remove(r);
                    r--;
                }
            }
        }
    }
    /**
     * åæ ‡æ‹¼æŽ¥
     * @param r æ¨ªåæ ‡
     * @param c çºµåæ ‡
     * @return
     */
    private static String coordinatesJoint(int r, int c) {
        String coordinates = "";
        coordinates = "r:" + r + ",c:" + c;
        return coordinates;
    }
    @Override
@@ -1880,6 +1990,8 @@
                    put("seal1", null);
                }});
        try {
            // ä¿®æ”¹æ¢è¡Œå’Œåˆå¹¶é—®é¢˜
            updaeMerge(template.getXWPFDocument(), true);
            String name = insReport.getCode().replace("/", "") + "-J.docx";
            template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl + "/" + name)));
            insReport.setUrl("/word/" + name);
@@ -1894,8 +2006,6 @@
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // ä¿®æ”¹æ¢è¡Œå’Œåˆå¹¶é—®é¢˜
        updaeMerge(insReport, null, true);
    }
    /**
@@ -2263,10 +2373,19 @@
        tables.forEach(table -> {
            table.put("tableSize", tables.size() + 1);
        });
        // è®¾å¤‡ä¿¡æ¯
        List<Map<String, String>> deviceList = null;
        if (deviceSet.size() != 0) {
        if (CollectionUtils.isNotEmpty(deviceSet)) {
            deviceList = insOrderMapper.selectDeviceList(deviceSet);
        }
        if (CollectionUtils.isNotEmpty(deviceList)) {
            int count = 1;
            for (Map<String, String> stringMap : deviceList) {
                stringMap.put("index", String.valueOf(count));
                count++;
            }
        }
        Map<String, String> codeStr = new HashMap<>();
        codeStr.put("报告编号", insReport.getCode());
        codeStr.put("样品名称", insOrder.getSample());
@@ -2274,7 +2393,6 @@
        codeStr.put("发放日期", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        String modelStr = CollUtil.join(models, "\n");
        String finalModelStr = modelStr;
        // æ£€æµ‹ç±»åž‹
        String orderType = null;
@@ -2288,11 +2406,10 @@
        String formType = iSysDictTypeService.selectLabelByDict(DictDataConstants.FORM_TYPE, insOrder.getFormType());
        // æ ·å“çŠ¶æ€
        String sampleStatus = iSysDictTypeService.selectLabelByDict(DictDataConstants.SAMPLE_STATUS_LIST, insOrder.getSampleStatus());;
        String sampleStatus = iSysDictTypeService.selectLabelByDict(DictDataConstants.SAMPLE_STATUS_LIST, insOrder.getSampleStatus());
        ;
        ConfigureBuilder builder = Configure.builder();
        builder.useSpringEL(true);
        List<Map<String, String>> finalDeviceList = deviceList;
        // å…¬å¸ä¿¡æ¯
        Custom custom = customMapper.selectById(insOrder.getCompanyId());
        // æŸ¥è¯¢åˆ¤æ–­æ˜¯å¦æœ‰ä¸åˆ¤å®šé¡¹ç›®,和全都是判定项
@@ -2382,12 +2499,18 @@
        environment = (ObjectUtils.isNotEmpty(insOrder.getTemperature()) ? insOrder.getTemperature() + "℃ " : "") + (ObjectUtils.isNotEmpty(insOrder.getHumidity()) ? insOrder.getHumidity() + "%" : "");
        String finalEnvironment = environment;
        LocalDateTime finalSendTime = sendTime;
        String finalResultCh = resultCh;
        String finalResultEn = resultEn;
        String finalOrderType = orderType;
        List<Map<String, String>> finalDeviceList = deviceList;
        String finalModelStr = modelStr;
        InputStream inputStream = this.getClass().getResourceAsStream("/static/report-template.docx");
        XWPFTemplate template = XWPFTemplate.compile(inputStream, builder.build()).render(
        Configure configure = Configure.builder()
                .bind("deviceList", new HackLoopTableRenderPolicy())
                .build();
        XWPFTemplate template = XWPFTemplate.compile(inputStream, configure).render(
                new HashMap<String, Object>() {{
                    put("order", insOrder);
                    put("report", insReport);
@@ -2422,6 +2545,8 @@
                    put("sampleStatus", sampleStatus);
                }});
        try {
            // ä¿®æ”¹æ¢è¡Œå’Œåˆå¹¶é—®é¢˜
            updaeMerge(template.getXWPFDocument(), false);
            String name = insReport.getCode().replace("/", "") + ".docx";
            template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl + "/" + name)));
            insReport.setUrl("/word/" + name);
@@ -2434,8 +2559,6 @@
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // ä¿®æ”¹æ¢è¡Œå’Œåˆå¹¶é—®é¢˜
        updaeMerge(insReport, deviceList, false);
    }
    /**
@@ -2506,188 +2629,165 @@
    /**
     * åˆå¹¶å•元格
     * @param insReport
     * @param deviceList
     */
    private void updaeMerge(InsReport insReport, List<Map<String, String>> deviceList, boolean isSmall) {
    private void updaeMerge(XWPFDocument document, boolean isSmall) {
        // å¤„理合并单元格的问题
        String path = wordUrl + insReport.getUrl().replaceFirst("/word", "");
        try {
            // èŽ·å–æ–‡æ¡£ä¸­çš„æ‰€æœ‰è¡¨æ ¼
            FileInputStream stream = new FileInputStream(path);
            XWPFDocument document = new XWPFDocument(stream);
            List<XWPFTable> xwpfTables = document.getTables();
            // éåŽ†è¡¨æ ¼ï¼Œä½†è·³è¿‡ç¬¬ä¸€ä¸ªè¡¨æ ¼ï¼ˆå¦‚æžœdeviceList为null,则额外跳过第二个)
            for (int i = 1; i < xwpfTables.size() - (deviceList == null ? 1 : 2); i++) {
                // åˆ›å»ºä¸€ä¸ªHashSet来存储唯一的字符串(这里基于"∑"分割后的第二部分)
                Set<String> set1 = new HashSet<>();
                // åˆ›å»ºä¸€ä¸ªHashMap来存储每个唯一字符串及其对应的单元格位置信息
                Map<String, Map<String, Integer>> maps = new HashMap<>();
                // éåŽ†å½“å‰è¡¨æ ¼çš„æ‰€æœ‰è¡Œ
                for (int j = 0; j < xwpfTables.get(i).getRows().size(); j++) {
                    // éåŽ†å½“å‰è¡Œçš„æ‰€æœ‰å•å…ƒæ ¼
                    for (int k = 0; k < xwpfTables.get(i).getRows().get(j).getTableCells().size(); k++) {
                        // æ£€æŸ¥å•元格文本中是否包含"∑"
                        if (xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().indexOf("∑") > -1) {
                            String[] split = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑");
                            // å¦‚果分割后的第二部分是新的(即之前未出现过),则添加到set1并创建位置信息map
                            if (set1.add(split[1])) {
                                Map<String, Integer> map = new HashMap<>();
                                // å­˜å‚¨èµ·å§‹è¡Œã€èµ·å§‹åˆ—、结束行(当前行)、结束列(当前列)
                                map.put("sr", j);
                                map.put("sc", k);
                                map.put("er", j + 0);
                                map.put("ec", k + 0);
                                maps.put(split[1], map);
                            } else {
                                // å¦‚果已存在,则更新结束行或结束列
                                Map<String, Integer> map1 = maps.get(split[1]);
                                if (j == map1.get("sr")) {
                                    map1.put("ec", map1.get("ec") + 1);
                                } else if (k == map1.get("sc")) {
                                    map1.put("er", map1.get("er") + 1);
                                }
        // èŽ·å–æ–‡æ¡£ä¸­çš„æ‰€æœ‰è¡¨æ ¼
        List<XWPFTable> xwpfTables = document.getTables();
        // éåŽ†è¡¨æ ¼
        for (int i = 1; i < xwpfTables.size(); i++) {
            // åˆ›å»ºä¸€ä¸ªHashSet来存储唯一的字符串(这里基于"∑"分割后的第二部分)
            Set<String> set1 = new HashSet<>();
            // åˆ›å»ºä¸€ä¸ªHashMap来存储每个唯一字符串及其对应的单元格位置信息
            Map<String, Map<String, Integer>> maps = new HashMap<>();
            // éåŽ†å½“å‰è¡¨æ ¼çš„æ‰€æœ‰è¡Œ
            for (int j = 0; j < xwpfTables.get(i).getRows().size(); j++) {
                // éåŽ†å½“å‰è¡Œçš„æ‰€æœ‰å•å…ƒæ ¼
                for (int k = 0; k < xwpfTables.get(i).getRows().get(j).getTableCells().size(); k++) {
                    // æ£€æŸ¥å•元格文本中是否包含"∑"
                    if (xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().indexOf("∑") > -1) {
                        String[] split = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑");
                        // å¦‚果分割后的第二部分是新的(即之前未出现过),则添加到set1并创建位置信息map
                        if (set1.add(split[1])) {
                            Map<String, Integer> map = new HashMap<>();
                            // å­˜å‚¨èµ·å§‹è¡Œã€èµ·å§‹åˆ—、结束行(当前行)、结束列(当前列)
                            map.put("sr", j);
                            map.put("sc", k);
                            map.put("er", j + 0);
                            map.put("ec", k + 0);
                            maps.put(split[1], map);
                        } else {
                            // å¦‚果已存在,则更新结束行或结束列
                            Map<String, Integer> map1 = maps.get(split[1]);
                            if (j == map1.get("sr")) {
                                map1.put("ec", map1.get("ec") + 1);
                            } else if (k == map1.get("sc")) {
                                map1.put("er", map1.get("er") + 1);
                            }
                            // åˆ¤æ–­å°é«˜æŠ¥å‘Šè¿˜æ˜¯å¤§æŠ¥å‘Š
                            if (isSmall) {
                                // èŽ·å–å•å…ƒæ ¼
                                XWPFTableCell cell = xwpfTables.get(i).getRows().get(j).getTableCells().get(k);
                                XWPFParagraph paragraph = cell.getParagraphArray(0);
                                String originalText = paragraph.getText();
                                String newText = originalText.split("∑")[0];
                                List<XWPFRun> runs = paragraph.getRuns();
                                for (XWPFRun run : runs) {
                                    run.setText("", 0); // æ¸…空 run ä¸­çš„æ–‡æœ¬
                                }
                                if (!runs.isEmpty()) {
                                    XWPFRun run = runs.get(0);
                                    run.setText(newText);
                                    // å¤åˆ¶æ ·å¼
                                    run.setFontFamily(paragraph.getRuns().get(0).getFontFamily());
                                    run.setFontSize(paragraph.getRuns().get(0).getFontSize());
                                    run.setBold(paragraph.getRuns().get(0).isBold());
                                    run.setItalic(paragraph.getRuns().get(0).isItalic());
                                    run.setUnderline(paragraph.getRuns().get(0).getUnderline());
                                    run.setColor(paragraph.getRuns().get(0).getColor());
                                }
                                cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                                paragraph.setAlignment(ParagraphAlignment.CENTER);
                            } else {
                                // ç§»é™¤åŒ…含"∑"的段落,并重新设置单元格文本和样式
                                String str = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑")[0];
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setText(str);
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
                        }
                        // åˆ¤æ–­å°é«˜æŠ¥å‘Šè¿˜æ˜¯å¤§æŠ¥å‘Š
                        if (isSmall) {
                            // èŽ·å–å•å…ƒæ ¼
                            XWPFTableCell cell = xwpfTables.get(i).getRows().get(j).getTableCells().get(k);
                            XWPFParagraph paragraph = cell.getParagraphArray(0);
                            String originalText = paragraph.getText();
                            String newText = originalText.split("∑")[0];
                            List<XWPFRun> runs = paragraph.getRuns();
                            for (XWPFRun run : runs) {
                                run.setText("", 0); // æ¸…空 run ä¸­çš„æ–‡æœ¬
                            }
                            if (!runs.isEmpty()) {
                                XWPFRun run = runs.get(0);
                                run.setText(newText);
                                // å¤åˆ¶æ ·å¼
                                run.setFontFamily(paragraph.getRuns().get(0).getFontFamily());
                                run.setFontSize(paragraph.getRuns().get(0).getFontSize());
                                run.setBold(paragraph.getRuns().get(0).isBold());
                                run.setItalic(paragraph.getRuns().get(0).isItalic());
                                run.setUnderline(paragraph.getRuns().get(0).getUnderline());
                                run.setColor(paragraph.getRuns().get(0).getColor());
                            }
                            cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                            paragraph.setAlignment(ParagraphAlignment.CENTER);
                        } else {
                            // ç§»é™¤åŒ…含"∑"的段落,并重新设置单元格文本和样式
                            String str = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑")[0];
                            xwpfTables.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                            xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setText(str);
                            xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                            xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
                        }
                    }
                }
            }
                // å•元格排序, é¿å…æ ¼å¼é”™ä¹±
                List<Map.Entry<String, Map<String, Integer>>> entries = new ArrayList<>(maps.entrySet());
                entries.sort((o1, o2) -> o1.getValue().get("sc") - o2.getValue().get("sc"));
            // å•元格排序, é¿å…æ ¼å¼é”™ä¹±
            List<Map.Entry<String, Map<String, Integer>>> entries = new ArrayList<>(maps.entrySet());
            entries.sort((o1, o2) -> o1.getValue().get("sc") - o2.getValue().get("sc"));
                // æŒ‰ç…§é¡ºåºæ·»åŠ è¿›é›†åˆ
                List<String> list = new ArrayList<>();
                for (Map.Entry<String, Map<String, Integer>> entry : entries) {
                    list.add(entry.getKey());
                }
            // æŒ‰ç…§é¡ºåºæ·»åŠ è¿›é›†åˆ
            List<String> list = new ArrayList<>();
            for (Map.Entry<String, Map<String, Integer>> entry : entries) {
                list.add(entry.getKey());
            }
                for (int a = list.size() - 1; a >= 0; a--) {
                    Map<String, Integer> v = maps.get(list.get(a));
                    for (int j = 0; j < v.get("er") - v.get("sr") + 1; j++) {
                        if (v.get("ec") > v.get("sc")) {
                            try {
                                TableTools.mergeCellsHorizonal(xwpfTables.get(i), v.get("sr") + j, v.get("sc"), v.get("ec"));
                            } catch (Exception e) {
                            }
                        }
                    }
                    if (v.get("er") > v.get("sr")) {
            for (int a = list.size() - 1; a >= 0; a--) {
                Map<String, Integer> v = maps.get(list.get(a));
                for (int j = 0; j < v.get("er") - v.get("sr") + 1; j++) {
                    if (v.get("ec") > v.get("sc")) {
                        try {
                            TableTools.mergeCellsVertically(xwpfTables.get(i), v.get("sc"), v.get("sr"), v.get("er"));
                            TableTools.mergeCellsHorizonal(xwpfTables.get(i), v.get("sr") + j, v.get("sc"), v.get("ec"));
                        } catch (Exception e) {
                        }
                    }
                }
                if (v.get("er") > v.get("sr")) {
                    try {
                        TableTools.mergeCellsVertically(xwpfTables.get(i), v.get("sc"), v.get("sr"), v.get("er"));
                    } catch (Exception e) {
                    }
                }
            }
            FileOutputStream fileOutputStream = new FileOutputStream(path);
            document.write(fileOutputStream);
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //处理中英文换行的问题
        try {
            FileInputStream stream1 = new FileInputStream(path);
            XWPFDocument document1 = new XWPFDocument(stream1);
            List<XWPFTable> xwpfTables1 = document1.getTables();
            for (int i = 1; i < xwpfTables1.size() - (deviceList == null ? 1 : 2); i++) {
                for (int j = 0; j < xwpfTables1.get(i).getRows().size(); j++) {
                    for (int k = 0; k < xwpfTables1.get(i).getRows().get(j).getTableCells().size(); k++) {
                        if (xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText().contains("@")) {
                            if (isSmall) {
                                // èŽ·å–åŽŸæœ‰æ®µè½çš„ç¬¬ä¸€ä¸ª XWPFRun
                                String text = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText();
                                XWPFParagraph oldParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getParagraphs().get(0);
                                XWPFRun oldRun = oldParagraph.getRuns().get(0);
                                // ä¿å­˜åŽŸæœ‰æ ·å¼
                                String fontFamily = oldRun.getFontFamily();
                                int fontSize = oldRun.getFontSize();
                                boolean isBold = oldRun.isBold();
                                boolean isItalic = oldRun.isItalic();
                                boolean isUnderline = oldRun.getUnderline() != UnderlinePatterns.NONE;
                                // åˆ é™¤åŽŸæœ‰æ®µè½
                                xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                                // æ·»åŠ æ–°æ®µè½
                                XWPFParagraph newParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).addParagraph();
                                XWPFRun newRun = newParagraph.createRun();
                                // åº”用保存的样式
                                newRun.setFontFamily(fontFamily);
                                newRun.setFontSize(fontSize);
                                newRun.setBold(isBold);
                                newRun.setItalic(isItalic);
                                if (isUnderline) {
                                    newRun.setUnderline(UnderlinePatterns.SINGLE);
                                }
                                // è®¾ç½®æ–°æ–‡æœ¬
                                String[] split = text.split("@");
                                newRun.setText(split[0]);
                                if (split.length > 1) {
                                    newRun.addBreak();
                                    newRun.setText(split[1]);
                                }
                                // è®¾ç½®æ®µè½å¯¹é½æ–¹å¼
                                newParagraph.setAlignment(ParagraphAlignment.CENTER);
                            } else {
                                String text = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText();
                                String[] split = text.split("@");
                                xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                                XWPFParagraph xwpfParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).addParagraph();
                                XWPFRun run = xwpfParagraph.createRun();
                                run.setText(split[0]);
                                if (ObjectUtils.isNotNull(split[1])) {
                                    run.addBreak();
                                    run.setText(split[1]);
                                }
                                xwpfParagraph.setAlignment(ParagraphAlignment.CENTER);
        List<XWPFTable> xwpfTables1 = document.getTables();
        for (int i = 1; i < xwpfTables1.size(); i++) {
            for (int j = 0; j < xwpfTables1.get(i).getRows().size(); j++) {
                for (int k = 0; k < xwpfTables1.get(i).getRows().get(j).getTableCells().size(); k++) {
                    if (xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText().contains("@")) {
                        if (isSmall) {
                            // èŽ·å–åŽŸæœ‰æ®µè½çš„ç¬¬ä¸€ä¸ª XWPFRun
                            String text = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText();
                            XWPFParagraph oldParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getParagraphs().get(0);
                            XWPFRun oldRun = oldParagraph.getRuns().get(0);
                            // ä¿å­˜åŽŸæœ‰æ ·å¼
                            String fontFamily = oldRun.getFontFamily();
                            int fontSize = oldRun.getFontSize();
                            boolean isBold = oldRun.isBold();
                            boolean isItalic = oldRun.isItalic();
                            boolean isUnderline = oldRun.getUnderline() != UnderlinePatterns.NONE;
                            // åˆ é™¤åŽŸæœ‰æ®µè½
                            xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                            // æ·»åŠ æ–°æ®µè½
                            XWPFParagraph newParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).addParagraph();
                            XWPFRun newRun = newParagraph.createRun();
                            // åº”用保存的样式
                            newRun.setFontFamily(fontFamily);
                            newRun.setFontSize(fontSize);
                            newRun.setBold(isBold);
                            newRun.setItalic(isItalic);
                            if (isUnderline) {
                                newRun.setUnderline(UnderlinePatterns.SINGLE);
                            }
                            // è®¾ç½®æ–°æ–‡æœ¬
                            String[] split = text.split("@");
                            newRun.setText(split[0]);
                            if (split.length > 1) {
                                newRun.addBreak();
                                newRun.setText(split[1]);
                            }
                            // è®¾ç½®æ®µè½å¯¹é½æ–¹å¼
                            newParagraph.setAlignment(ParagraphAlignment.CENTER);
                        } else {
                            String text = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText();
                            String[] split = text.split("@");
                            xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                            XWPFParagraph xwpfParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).addParagraph();
                            XWPFRun run = xwpfParagraph.createRun();
                            run.setText(split[0]);
                            if (ObjectUtils.isNotNull(split[1])) {
                                run.addBreak();
                                run.setText(split[1]);
                            }
                            xwpfParagraph.setAlignment(ParagraphAlignment.CENTER);
                        }
                    }
                }
            }
            FileOutputStream fileOutputStream1 = new FileOutputStream(path);
            document1.write(fileOutputStream1);
            fileOutputStream1.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
inspect-server/src/main/java/com/ruoyi/inspect/service/impl/InsOrderServiceImpl.java
@@ -444,16 +444,6 @@
        Map<String, Object> map = new HashMap<>();
        InsOrder insOrder = insOrderMapper.selectById(id);
        List<SampleProductDto> list = insSampleMapper.getInsOrderAndSample(id, laboratory);
        for (SampleProductDto sampleProductDto : list) {
            List<Integer> ids = sampleProductDto.getInsProduct().stream().map(InsProduct::getId).collect(Collectors.toList());
            List<InsProductUser> insProductUsers = insProductUserMapper.selectList(Wrappers.<InsProductUser>lambdaQuery()
                    .in(InsProductUser::getInsProductId, ids));
            if (CollectionUtils.isNotEmpty(insProductUsers)) {
                List<Integer> userIds = insProductUsers.stream().map(InsProductUser::getCreateUser).distinct().collect(Collectors.toList());
                String collect = userMapper.selectBatchIds(userIds).stream().map(User::getName).collect(Collectors.joining(","));
                sampleProductDto.setCheckName(collect);
            }
        }
        map.put("insOrder", insOrder);
        map.put("sampleProduct", list);
        //查询所有记录模版去重
inspect-server/src/main/resources/mapper/InsOrderMapper.xml
@@ -241,7 +241,7 @@
        latest_traceability
        from device
        where device.management_number in
        <foreach collection="names" index="index" open="(" separator="," close=")" item="val">
        <foreach collection="managementNumbers" index="index" open="(" separator="," close=")" item="val">
            #{val}
        </foreach>
    </select>
inspect-server/src/main/resources/static/report-template.docx
Binary files differ
ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -14,7 +14,7 @@
{
    public static void main(String[] args)
    {
//        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(RuoYiApplication.class, args);
        System.out.println("<=====================>LIMS系统启动成功<=====================>");
    }
}
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysMenuController.java
@@ -1,6 +1,8 @@
package com.ruoyi.web.controller.system;
import java.util.List;
import com.ruoyi.common.core.domain.TreeSelect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -72,6 +74,8 @@
    public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
    {
        List<SysMenu> menus = menuService.selectMenuList(getUserId());
        // æ·»åŠ åªçœ‹æˆ‘
        menuService.addIsRersonal(menus, roleId);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
ruoyi-admin/src/main/resources/banner.txt
@@ -1,24 +1,7 @@
Application Version: ${ruoyi.version}
Spring Boot Version: ${spring-boot.version}
////////////////////////////////////////////////////////////////////
//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//             ä½›ç¥–保佑       æ°¸ä¸å®•机      æ°¸æ— BUG               //
////////////////////////////////////////////////////////////////////
██      â–ˆâ–ˆâ€â–ˆâ–ˆâ–ˆâ€   â–ˆâ–ˆâ–ˆâ€â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ€
██      â–ˆâ–ˆâ€â–ˆâ–ˆâ–ˆâ–ˆâ€ â–ˆâ–ˆâ–ˆâ–ˆâ€â–ˆâ–ˆâ€â€â€â€â€â€
██      â–ˆâ–ˆâ€â–ˆâ–ˆâ€â–ˆâ–ˆâ–ˆâ–ˆâ€â–ˆâ–ˆâ€â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ€
██      â–ˆâ–ˆâ€â–ˆâ–ˆâ€â€â–ˆâ–ˆâ€â€â–ˆâ–ˆâ€â€â€â€â€â€â–ˆâ–ˆâ€
███████ ██ ██  â€â€â€ â–ˆâ–ˆâ€â–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ–ˆâ€
                   â€â€â€â€â€â€â€â€â€â€â€
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/TreeSelect.java
@@ -27,6 +27,9 @@
    /** æ˜¯å¦å¯ä»¥é€‰æ‹©ä»…看我, 0:否, 1:是 */
    private Integer isRersonalButton;
    /** æ˜¯å¦ç¡®è®¤åªçœ‹æˆ‘, 0:否, 1:是 */
    private Integer isRersonal;
    /** èŠ‚ç‚¹ç¦ç”¨ */
    private boolean disabled = false;
@@ -52,6 +55,7 @@
        this.id = menu.getMenuId();
        this.label = menu.getMenuName();
        this.isRersonalButton = menu.getIsRersonalButton();
        this.isRersonal = menu.getIsRersonal();
        this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
    }
@@ -95,7 +99,7 @@
        this.children = children;
    }
    public Integer geIsRersonalButton()
    public Integer getIsRersonalButton()
    {
        return isRersonalButton;
    }
@@ -104,4 +108,14 @@
    {
        this.isRersonalButton = isRersonalButton;
    }
    public Integer getIsRersonal()
    {
        return isRersonal;
    }
    public void setIsRersonal(Integer isRersonalButton)
    {
        this.isRersonal = isRersonal;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysMenu.java
@@ -69,6 +69,10 @@
    /** æ˜¯å¦å¯ä»¥é€‰æ‹©ä»…看我, 0:否, 1:是 */
    private Integer isRersonalButton;
    /** ä»…看我, 0:否, 1:是 */
    private Integer isRersonal;
    /** å­èœå• */
    private List<SysMenu> children = new ArrayList<SysMenu>();
@@ -249,6 +253,16 @@
        this.isRersonalButton = isRersonalButton;
    }
    public Integer getIsRersonal()
    {
        return isRersonal;
    }
    public void setIsRersonal(Integer isRersonal)
    {
        this.isRersonal = isRersonal;
    }
    public List<SysMenu> getChildren()
    {
        return children;
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/SysRole.java
@@ -12,7 +12,7 @@
/**
 * è§’色表 sys_role
 *
 *
 * @author ruoyi
 */
public class SysRole extends BaseEntity
@@ -57,6 +57,9 @@
    /** èœå•组 */
    private Long[] menuIds;
    /** åªçœ‹æˆ‘菜单组 */
    private Long[] isRersonalMenuIds;
    /** éƒ¨é—¨ç»„(数据权限) */
    private Long[] deptIds;
@@ -199,6 +202,17 @@
        this.menuIds = menuIds;
    }
    public Long[] getIsRersonalMenuIds()
    {
        return isRersonalMenuIds;
    }
    public void setIsRersonalMenuIds(Long[] isRersonalMenuIds)
    {
        this.isRersonalMenuIds = isRersonalMenuIds;
    }
    public Long[] getDeptIds()
    {
        return deptIds;
ruoyi-common/src/main/java/com/ruoyi/common/utils/GZipUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
package com.ruoyi.common.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
 * åŽ‹ç¼©è§£åŽ‹å·¥å…·ç±»
 */
public class GZipUtil {
    /**
     * åŽ‹ç¼©
     * @param str
     * @return
     */
    public static String compress(String str) {
        if (str == null || str.trim().length() == 0) {
            return null;
        }
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             GZIPOutputStream gzip = new GZIPOutputStream(out)) {
            gzip.write(str.getBytes("utf-8"));
            gzip.close();
            return new String(out.toByteArray(), "iso-8859-1");
        } catch (Exception e) {
            e.printStackTrace();
            return str;
        }
    }
    /**
     * è§£åŽ‹
     * @param str
     * @return
     */
    public static String uncompress(String str) {
        if (str == null || str.trim().length() == 0) {
            return null;
        }
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes("iso-8859-1"))){
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[1024];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            return new String(out.toByteArray(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
            return str;
        }
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysRoleMenu.java
@@ -5,16 +5,19 @@
/**
 * è§’色和菜单关联 sys_role_menu
 *
 *
 * @author ruoyi
 */
public class SysRoleMenu
{
    /** è§’色ID */
    private Long roleId;
    /** èœå•ID */
    private Long menuId;
    /** æ˜¯å¦åªçœ‹æˆ‘0否, 1是 */
    private Integer isRersonal;
    public Long getRoleId()
    {
@@ -36,6 +39,16 @@
        this.menuId = menuId;
    }
    public Integer getIsRersonal()
    {
        return isRersonal;
    }
    public void setIsRersonal(Integer isRersonal)
    {
        this.isRersonal = isRersonal;
    }
    @Override
    public String toString() {
        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysRoleMenuMapper.java
@@ -51,4 +51,11 @@
     * @return
     */
    SysRoleVo selectRoleMenu(@Param("permsName") String permsName, @Param("userId") Long userId);
    /**
     * æŸ¥è¯¢åªçœ‹æˆ‘菜单id
     * @param roleId
     * @return
     */
    List<Long> selectIsRersonalMenu(@Param("roleId") Long roleId);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/ISysMenuService.java
@@ -8,14 +8,14 @@
/**
 * èœå• ä¸šåС层
 *
 *
 * @author ruoyi
 */
public interface ISysMenuService
{
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
     */
@@ -23,7 +23,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     *
     * @param menu èœå•信息
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
@@ -32,7 +32,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID查询权限
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return æƒé™åˆ—表
     */
@@ -40,7 +40,7 @@
    /**
     * æ ¹æ®è§’色ID查询权限
     *
     *
     * @param roleId è§’色ID
     * @return æƒé™åˆ—表
     */
@@ -48,7 +48,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID查询菜单树信息
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
     */
@@ -56,7 +56,7 @@
    /**
     * æ ¹æ®è§’色ID查询菜单树信息
     *
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­èœå•列表
     */
@@ -64,7 +64,7 @@
    /**
     * æž„建前端路由所需要的菜单
     *
     *
     * @param menus èœå•列表
     * @return è·¯ç”±åˆ—表
     */
@@ -72,7 +72,7 @@
    /**
     * æž„建前端所需要树结构
     *
     *
     * @param menus èœå•列表
     * @return æ ‘结构列表
     */
@@ -80,7 +80,7 @@
    /**
     * æž„建前端所需要下拉树结构
     *
     *
     * @param menus èœå•列表
     * @return ä¸‹æ‹‰æ ‘结构列表
     */
@@ -88,7 +88,7 @@
    /**
     * æ ¹æ®èœå•ID查询信息
     *
     *
     * @param menuId èœå•ID
     * @return èœå•信息
     */
@@ -96,7 +96,7 @@
    /**
     * æ˜¯å¦å­˜åœ¨èœå•子节点
     *
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ true å­˜åœ¨ false ä¸å­˜åœ¨
     */
@@ -104,7 +104,7 @@
    /**
     * æŸ¥è¯¢èœå•是否存在角色
     *
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ true å­˜åœ¨ false ä¸å­˜åœ¨
     */
@@ -112,7 +112,7 @@
    /**
     * æ–°å¢žä¿å­˜èœå•信息
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -120,7 +120,7 @@
    /**
     * ä¿®æ”¹ä¿å­˜èœå•信息
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -128,7 +128,7 @@
    /**
     * åˆ é™¤èœå•管理信息
     *
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
@@ -136,9 +136,16 @@
    /**
     * æ ¡éªŒèœå•名称是否唯一
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
    public boolean checkMenuNameUnique(SysMenu menu);
    /**
     * æ·»åŠ åªçœ‹æˆ‘
     * @param menus
     * @param roleId
     */
    void addIsRersonal(List<SysMenu> menus, Long roleId);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysMenuServiceImpl.java
@@ -27,7 +27,7 @@
/**
 * èœå• ä¸šåŠ¡å±‚å¤„ç†
 *
 *
 * @author ruoyi
 */
@Service
@@ -46,7 +46,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return èœå•列表
     */
@@ -58,7 +58,7 @@
    /**
     * æŸ¥è¯¢ç³»ç»Ÿèœå•列表
     *
     *
     * @param menu èœå•信息
     * @return èœå•列表
     */
@@ -81,7 +81,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID查询权限
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return æƒé™åˆ—表
     */
@@ -102,7 +102,7 @@
    /**
     * æ ¹æ®è§’色ID查询权限
     *
     *
     * @param roleId è§’色ID
     * @return æƒé™åˆ—表
     */
@@ -123,7 +123,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID查询菜单
     *
     *
     * @param userId ç”¨æˆ·åç§°
     * @return èœå•列表
     */
@@ -144,7 +144,7 @@
    /**
     * æ ¹æ®è§’色ID查询菜单树信息
     *
     *
     * @param roleId è§’色ID
     * @return é€‰ä¸­èœå•列表
     */
@@ -157,7 +157,7 @@
    /**
     * æž„建前端路由所需要的菜单
     *
     *
     * @param menus èœå•列表
     * @return è·¯ç”±åˆ—表
     */
@@ -215,7 +215,7 @@
    /**
     * æž„建前端所需要树结构
     *
     *
     * @param menus èœå•列表
     * @return æ ‘结构列表
     */
@@ -243,7 +243,7 @@
    /**
     * æž„建前端所需要下拉树结构
     *
     *
     * @param menus èœå•列表
     * @return ä¸‹æ‹‰æ ‘结构列表
     */
@@ -256,7 +256,7 @@
    /**
     * æ ¹æ®èœå•ID查询信息
     *
     *
     * @param menuId èœå•ID
     * @return èœå•信息
     */
@@ -268,7 +268,7 @@
    /**
     * æ˜¯å¦å­˜åœ¨èœå•子节点
     *
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
@@ -281,7 +281,7 @@
    /**
     * æŸ¥è¯¢èœå•使用数量
     *
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
@@ -294,7 +294,7 @@
    /**
     * æ–°å¢žä¿å­˜èœå•信息
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -306,7 +306,7 @@
    /**
     * ä¿®æ”¹ä¿å­˜èœå•信息
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -318,7 +318,7 @@
    /**
     * åˆ é™¤èœå•管理信息
     *
     *
     * @param menuId èœå•ID
     * @return ç»“æžœ
     */
@@ -330,7 +330,7 @@
    /**
     * æ ¡éªŒèœå•名称是否唯一
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -347,8 +347,25 @@
    }
    /**
     * æ·»åŠ åªçœ‹æˆ‘
     * @param menus
     * @param roleId
     */
    @Override
    public void addIsRersonal(List<SysMenu> menus, Long roleId) {
        // æŸ¥è¯¢åªçœ‹æˆ‘菜单id
        List<Long> menuIds = roleMenuMapper.selectIsRersonalMenu(roleId);
        for (SysMenu menu : menus) {
            if (menuIds.contains(menu.getMenuId())) {
                menu.setIsRersonal(1);
            }
        }
    }
    /**
     * èŽ·å–è·¯ç”±åç§°
     *
     *
     * @param menu èœå•信息
     * @return è·¯ç”±åç§°
     */
@@ -364,7 +381,7 @@
    /**
     * èŽ·å–è·¯ç”±åç§°ï¼Œå¦‚æ²¡æœ‰é…ç½®è·¯ç”±åç§°åˆ™å–è·¯ç”±åœ°å€
     *
     *
     * @param routerName è·¯ç”±åç§°
     * @param path è·¯ç”±åœ°å€
     * @return è·¯ç”±åç§°ï¼ˆé©¼å³°æ ¼å¼ï¼‰
@@ -377,7 +394,7 @@
    /**
     * èŽ·å–è·¯ç”±åœ°å€
     *
     *
     * @param menu èœå•信息
     * @return è·¯ç”±åœ°å€
     */
@@ -405,7 +422,7 @@
    /**
     * èŽ·å–ç»„ä»¶ä¿¡æ¯
     *
     *
     * @param menu èœå•信息
     * @return ç»„件信息
     */
@@ -429,7 +446,7 @@
    /**
     * æ˜¯å¦ä¸ºèœå•内部跳转
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -441,7 +458,7 @@
    /**
     * æ˜¯å¦ä¸ºå†…链组件
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -452,7 +469,7 @@
    /**
     * æ˜¯å¦ä¸ºparent_view组件
     *
     *
     * @param menu èœå•信息
     * @return ç»“æžœ
     */
@@ -463,7 +480,7 @@
    /**
     * æ ¹æ®çˆ¶èŠ‚ç‚¹çš„ID获取所有子节点
     *
     *
     * @param list åˆ†ç±»è¡¨
     * @param parentId ä¼ å…¥çš„父节点ID
     * @return String
@@ -486,7 +503,7 @@
    /**
     * é€’归列表
     *
     *
     * @param list åˆ†ç±»è¡¨
     * @param t å­èŠ‚ç‚¹
     */
@@ -532,7 +549,7 @@
    /**
     * å†…链域名特殊字符替换
     *
     *
     * @return æ›¿æ¢åŽçš„内链域名
     */
    public String innerLinkReplaceEach(String path)
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysRoleServiceImpl.java
@@ -5,6 +5,9 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -27,7 +30,7 @@
/**
 * è§’色 ä¸šåŠ¡å±‚å¤„ç†
 *
 *
 * @author ruoyi
 */
@Service
@@ -47,7 +50,7 @@
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢è§’色数据
     *
     *
     * @param role è§’色信息
     * @return è§’色数据集合信息
     */
@@ -60,7 +63,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID查询角色
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return è§’色列表
     */
@@ -85,7 +88,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID查询权限
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return æƒé™åˆ—表
     */
@@ -106,7 +109,7 @@
    /**
     * æŸ¥è¯¢æ‰€æœ‰è§’色
     *
     *
     * @return è§’色列表
     */
    @Override
@@ -117,7 +120,7 @@
    /**
     * æ ¹æ®ç”¨æˆ·ID获取角色选择框列表
     *
     *
     * @param userId ç”¨æˆ·ID
     * @return é€‰ä¸­è§’色ID列表
     */
@@ -129,7 +132,7 @@
    /**
     * é€šè¿‡è§’色ID查询角色
     *
     *
     * @param roleId è§’色ID
     * @return è§’色对象信息
     */
@@ -141,7 +144,7 @@
    /**
     * æ ¡éªŒè§’色名称是否唯一
     *
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
@@ -159,7 +162,7 @@
    /**
     * æ ¡éªŒè§’色权限是否唯一
     *
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
@@ -177,7 +180,7 @@
    /**
     * æ ¡éªŒè§’色是否允许操作
     *
     *
     * @param role è§’色信息
     */
    @Override
@@ -191,7 +194,7 @@
    /**
     * æ ¡éªŒè§’色是否有数据权限
     *
     *
     * @param roleIds è§’色id
     */
    @Override
@@ -214,7 +217,7 @@
    /**
     * é€šè¿‡è§’色ID查询角色使用数量
     *
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
@@ -226,7 +229,7 @@
    /**
     * æ–°å¢žä¿å­˜è§’色信息
     *
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
@@ -241,7 +244,7 @@
    /**
     * ä¿®æ”¹ä¿å­˜è§’色信息
     *
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
@@ -258,7 +261,7 @@
    /**
     * ä¿®æ”¹è§’色状态
     *
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
@@ -270,7 +273,7 @@
    /**
     * ä¿®æ”¹æ•°æ®æƒé™ä¿¡æ¯
     *
     *
     * @param role è§’色信息
     * @return ç»“æžœ
     */
@@ -288,7 +291,7 @@
    /**
     * æ–°å¢žè§’色菜单信息
     *
     *
     * @param role è§’色对象
     */
    public int insertRoleMenu(SysRole role)
@@ -301,7 +304,16 @@
            SysRoleMenu rm = new SysRoleMenu();
            rm.setRoleId(role.getRoleId());
            rm.setMenuId(menuId);
            // åˆ¤æ–­æ˜¯å¦æœ‰åªçœ‹æˆ‘权限
            if (ArrayUtils.isNotEmpty(role.getIsRersonalMenuIds())) {
                for (Long isRersonalMenuId : role.getIsRersonalMenuIds()) {
                    if (isRersonalMenuId.equals(menuId)) {
                        rm.setIsRersonal(1);
                    }
                }
            }
            list.add(rm);
        }
        if (list.size() > 0)
        {
@@ -336,7 +348,7 @@
    /**
     * é€šè¿‡è§’色ID删除角色
     *
     *
     * @param roleId è§’色ID
     * @return ç»“æžœ
     */
@@ -353,7 +365,7 @@
    /**
     * æ‰¹é‡åˆ é™¤è§’色信息
     *
     *
     * @param roleIds éœ€è¦åˆ é™¤çš„角色ID
     * @return ç»“æžœ
     */
@@ -380,7 +392,7 @@
    /**
     * å–消授权用户角色
     *
     *
     * @param userRole ç”¨æˆ·å’Œè§’色关联信息
     * @return ç»“æžœ
     */
@@ -392,7 +404,7 @@
    /**
     * æ‰¹é‡å–消授权用户角色
     *
     *
     * @param roleId è§’色ID
     * @param userIds éœ€è¦å–消授权的用户数据ID
     * @return ç»“æžœ
@@ -405,7 +417,7 @@
    /**
     * æ‰¹é‡é€‰æ‹©æŽˆæƒç”¨æˆ·è§’色
     *
     *
     * @param roleId è§’色ID
     * @param userIds éœ€è¦æŽˆæƒçš„用户数据ID
     * @return ç»“æžœ
ruoyi-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml
@@ -26,6 +26,14 @@
        group by sm.menu_id
    </select>
    <!-- æŸ¥è¯¢åªçœ‹æˆ‘菜单id -->
    <select id="selectIsRersonalMenu" resultType="java.lang.Long">
        select menu_id
        from sys_role_menu
        where role_id = #{roleId}
        and is_rersonal = 1
    </select>
    <delete id="deleteRoleMenuByRoleId" parameterType="Long">
        delete from sys_role_menu where role_id=#{roleId}
    </delete>
@@ -38,9 +46,9 @@
     </delete>
    <insert id="batchRoleMenu">
        insert into sys_role_menu(role_id, menu_id) values
        insert into sys_role_menu(role_id, menu_id, is_rersonal) values
        <foreach item="item" index="index" collection="list" separator=",">
            (#{item.roleId},#{item.menuId})
            (#{item.roleId},#{item.menuId},#{item.isRersonal})
        </foreach>
    </insert>