浏览代码

外部导入

DLC 1 月之前
父节点
当前提交
f26116c8a8

+ 15 - 0
qcs-common/src/main/java/com/rongwei/bscommon/sys/dao/QcsMainCostDao.java

@@ -33,4 +33,19 @@ public interface QcsMainCostDao extends BaseDao<QcsMainCostDo> {
 
     @Update("update qcs_recovery_amount set STATUS='已提交',SUBMITDATE=NOW() where ID=#{id}")
     void tjAmountData(@Param("id") String id);
+
+    @Update("update qcs_main_detail set DELETED='1',MODIFYDATE=NOW() where DELETED='0' and MAINID=#{mainid}")
+    void delMainDetail(@Param("mainid") String mainid);
+
+    @Update("update qcs_loss_detail set DELETED='1',MODIFYDATE=NOW() where DELETED='0' and MAINID=#{mainid}")
+    void delLossDetail(@Param("mainid") String mainid);
+
+    @Select("select LOSSTYPE,REASON from qcs_type_res where DELETED='0'")
+    List<Map<String, Object>> getTypeRess();
+
+    @Update("update qcs_main_cost set DELETED='1',MODIFYDATE=NOW() where ID=#{id}")
+    void delMainCost(@Param("id") String id);
+
+    @Update("update qcs_column_config set DELETED='1',MODIFYDATE=NOW() where DELETED='0' and LOSSID=#{mainid}")
+    void delColConfig(@Param("mainid") String mainid);
 }

+ 1 - 1
qcs-common/src/main/java/com/rongwei/bscommon/sys/dao/SlaveDao.java

@@ -22,6 +22,6 @@ public interface SlaveDao {
 
     @Select("select t.ID as PARTNOID,t.DTDRAWINGNO,t.DTPARTNAME,t.DTSERIALID,l.DLPROJID,l.DLPROJNAME from t_design_task t\n" +
             "left join t_drawing_list l on l.DLSERIALID=t.DTSERIALID\n" +
-            "where t.DELETED='0' and IFNULL(t.DTDRAWINGNO,'')!='' and IFNULL(t.DTPARTNAME,'')!=''")
+            "where t.DELETED='0' and IFNULL(t.DTDRAWINGNO,'')!='' and IFNULL(t.DTPARTNAME,'')!='' and IFNULL(l.DLPROJID,'')!='' and IFNULL(l.DLPROJNAME,'')!=''")
     List<QcsPartNoDo> getAllPartnos();
 }

+ 2 - 1
qcs-common/src/main/java/com/rongwei/bscommon/sys/service/QcsMainCostService.java

@@ -6,6 +6,7 @@ import com.rongwei.rwcommon.base.R;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.text.ParseException;
 import java.util.Map;
 
@@ -18,5 +19,5 @@ public interface QcsMainCostService extends IService<QcsMainCostDo> {
 
     R importMainCost(MultipartFile file, String costType, String unitId) throws IOException, ParseException;
 
-    R importLossMainCost(MultipartFile file, String costType, String unitId) throws IOException, ParseException;
+    R importLossMainCost(MultipartFile file, String costType, String unitId) throws IOException, ParseException, NoSuchMethodException, InvocationTargetException, IllegalAccessException;
 }

+ 128 - 45
qcs-common/src/main/java/com/rongwei/bscommon/sys/service/impl/QcsMainCostServiceImpl.java

@@ -9,6 +9,7 @@ import com.rongwei.bscommon.sys.service.QcsLossDetailService;
 import com.rongwei.bscommon.sys.service.QcsMainCostService;
 import com.rongwei.bscommon.sys.service.QcsMainDetailService;
 import com.rongwei.bscommon.sys.utils.ExcelUtils;
+import com.rongwei.bscommon.sys.utils.StringUtil;
 import com.rongwei.bsentity.domain.*;
 import com.rongwei.rwadmincommon.system.domain.SysOrganizationDo;
 import com.rongwei.rwadmincommon.system.service.SysOrganizationService;
@@ -26,6 +27,8 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.ParseException;
@@ -106,6 +109,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
             qcsMainCostDo1.setBasename(qcsMainCostDo.getBasename());
             qcsMainCostDo1.setYearmonth(qcsMainCostDo.getYearmonth());
             qcsMainCostDo1.setCosttype("1");
+            qcsMainCostDo1.setRoption(params.get("dataSource"));
 
             //明细数据
             List<QcsSubjectConfigDo> qcsSubjectConfigDos1 = qcsSubjectConfigDos.stream().filter(s -> s.getSecsubject().equals("预防成本")).collect(Collectors.toList());
@@ -116,6 +120,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                 qcsMainDetailDo.setThrsubject(qcsSubjectConfigDo.getThrsubject());
                 qcsMainDetailDo.setFousubject(qcsSubjectConfigDo.getFousubject());
                 qcsMainDetailDo.setSort(qcsSubjectConfigDo.getSort());
+                qcsMainDetailDo.setRoption(params.get("dataSource"));
                 qcsMainDetailDoList.add(qcsMainDetailDo);
             }
         }
@@ -139,6 +144,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
             qcsMainCostDo2.setBasename(qcsMainCostDo.getBasename());
             qcsMainCostDo2.setYearmonth(qcsMainCostDo.getYearmonth());
             qcsMainCostDo2.setCosttype("2");
+            qcsMainCostDo2.setRoption(params.get("dataSource"));
 
             //明细数据
             List<QcsSubjectConfigDo> qcsSubjectConfigDos2 = qcsSubjectConfigDos.stream().filter(s -> s.getSecsubject().equals("鉴定成本")).collect(Collectors.toList());
@@ -149,6 +155,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                 qcsMainDetailDo.setThrsubject(qcsSubjectConfigDo.getThrsubject());
                 qcsMainDetailDo.setFousubject(qcsSubjectConfigDo.getFousubject());
                 qcsMainDetailDo.setSort(qcsSubjectConfigDo.getSort());
+                qcsMainDetailDo.setRoption(params.get("dataSource"));
                 qcsMainDetailDoList.add(qcsMainDetailDo);
             }
         }
@@ -204,6 +211,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
             qcsMainCostDo3.setBasename(qcsMainCostDo.getBasename());
             qcsMainCostDo3.setYearmonth(qcsMainCostDo.getYearmonth());
             qcsMainCostDo3.setCosttype("3");
+            qcsMainCostDo3.setRoption(params.get("dataSource"));
 
             //明细
 //            QcsLossDetailDo qcsLossDetailDo3 = new QcsLossDetailDo();
@@ -263,6 +271,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
             qcsMainCostDo4.setBasename(qcsMainCostDo.getBasename());
             qcsMainCostDo4.setYearmonth(qcsMainCostDo.getYearmonth());
             qcsMainCostDo4.setCosttype("4");
+            qcsMainCostDo4.setRoption(params.get("dataSource"));
 
             //明细
 //            QcsLossDetailDo qcsLossDetailDo4 = new QcsLossDetailDo();
@@ -470,6 +479,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
         String yearMonth = "";
         String costId = SecurityUtil.getUUID();
         List<String> hasThrSub = new ArrayList<>();//已存在的三级科目
+        QcsMainCostDo oldMainCostDo = null;//未提交的旧数据
         for (int i = 0; i <= lastRowNum; i++) {
             Row row = sheet.getRow(i);
             if (ExcelUtils.isRowEmpty(row) || i == 1) {
@@ -490,8 +500,11 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                         LocalDate date = LocalDate.parse(dateArr[1], inputFormatter);
                         yearMonth = outputFormatter.format(date);
                         List<QcsMainCostDo> qcsMainCostDos = qcsMainCostDao.getMainCosts(unitId, yearMonth);
-                        if (qcsMainCostDos.size() > 0) {
-                            return R.error(sysOrganizationDo.getFullname() + "已存在" + yearMonth + "的数据");
+                        oldMainCostDo = qcsMainCostDos.stream().filter(m -> m.getCosttype().equals(costType)).findAny().orElse(null);
+                        if (oldMainCostDo != null) {
+                            if (oldMainCostDo.getStatus().equals("已提交")) {
+                                return R.error(sysOrganizationDo.getFullname() + "已存在" + yearMonth + "提交的数据");
+                            }
                         }
                     } catch (DateTimeParseException e) {
                         return R.error("填表日期格式不正确");
@@ -549,6 +562,12 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
         } else if (hasThrSub.size() == 0 || hasThrSub.size() != qcsSubjectConfigDos.size()) {
             return R.error("三级科目与系统科目配置表里不匹配");
         } else {
+            //删掉未提交的数据
+            if (oldMainCostDo != null) {
+                qcsMainCostDao.delMainCost(oldMainCostDo.getId());
+                qcsMainCostDao.delMainDetail(oldMainCostDo.getId());
+            }
+
             SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
             qcsMainCostDo.setId(costId);
             qcsMainCostDo.setRoption("导入");
@@ -564,6 +583,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                 otherMap.put("formId", costId);
                 otherMap.put("insertFlag", "0");
                 otherMap.put("tjFlag", "0");
+                otherMap.put("dataSource", "导入");
                 setOtherCost(otherMap);
 
                 return R.ok();
@@ -575,8 +595,7 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
 
     //内外部数据导入
     @Override
-    @Transactional
-    public R importLossMainCost(MultipartFile file, String costType, String unitId) throws IOException, ParseException {
+    public R importLossMainCost(MultipartFile file, String costType, String unitId) throws IOException, ParseException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
         StringBuilder allStrBuilder = new StringBuilder();
         QueryWrapper<SysOrganizationDo> entity = new QueryWrapper<SysOrganizationDo>().eq("DELETED", 0).eq("ID", unitId);
         SysOrganizationDo sysOrganizationDo = sysOrganizationService.getOne(entity);
@@ -584,12 +603,15 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
         List<QcsLossDetailDo> qcsLossDetailDoList = new ArrayList<>();
         List<QcsSubjectConfigDo> qcsSubjectConfigDos = qcsMainCostDao.getSubjectConfig("and COSTTYPE='" + costType + "'");//科目配置
         List<QcsPartNoDo> allPartnos = slaveDao.getAllPartnos();//工号及图号信息
+        List<Map<String, Object>> typeResMap = qcsMainCostDao.getTypeRess();
 
         Sheet sheet = new XSSFWorkbook(file.getInputStream()).getSheetAt(0);
         int lastRowNum = sheet.getLastRowNum();
         String yearMonth = "";
         String costId = SecurityUtil.getUUID();
         List<String> hasThrSub = new ArrayList<>();//已存在的三级科目
+        Map<Integer, String> subIndex = new HashMap<>();//三级科目对应的字段位置
+        QcsMainCostDo oldMainCostDo = null;//未提交的旧数据
         for (int i = 0; i <= lastRowNum; i++) {
             Row row = sheet.getRow(i);
             if (ExcelUtils.isRowEmpty(row) || i == 1) {
@@ -610,8 +632,11 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                         LocalDate date = LocalDate.parse(dateArr[1], inputFormatter);
                         yearMonth = outputFormatter.format(date);
                         List<QcsMainCostDo> qcsMainCostDos = qcsMainCostDao.getMainCosts(unitId, yearMonth);
-                        if (qcsMainCostDos.size() > 0) {
-                            return R.error(sysOrganizationDo.getFullname() + "已存在" + yearMonth + "的数据");
+                        oldMainCostDo = qcsMainCostDos.stream().filter(m -> m.getCosttype().equals(costType)).findAny().orElse(null);
+                        if (oldMainCostDo != null) {
+                            if (oldMainCostDo.getStatus().equals("已提交")) {
+                                return R.error(sysOrganizationDo.getFullname() + "已存在" + yearMonth + "提交的数据");
+                            }
                         }
                     } catch (DateTimeParseException e) {
                         return R.error("填表日期格式不正确");
@@ -627,11 +652,18 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                     if (thrSubStr.equals("合计金额(元)") || hasThrSub.size() == qcsSubjectConfigDos.size()) {
                         break;
                     }
-                    String[] thrSubArr = thrSubStr.split("\\(");
-                    if (!subjectConfigDo.getThrsubject().equals(thrSubArr[0])) {
-                        stringBuilder.append(thrSubStr + ",");
+
+                    if (StringUtils.isNotEmpty(thrSubStr)) {
+                        String[] thrSubArr = thrSubStr.split("\\(");
+                        QcsSubjectConfigDo existSubDo = qcsSubjectConfigDos.stream().filter(sc -> sc.getThrsubject().equals(thrSubArr[0])).findAny().orElse(null);
+                        if (existSubDo == null) {
+                            stringBuilder.append("第" + (thrSubIndex + 1) + "列" + thrSubStr + ",");
+                        } else {
+                            hasThrSub.add(thrSubArr[0]);
+                            subIndex.put(thrSubIndex, "ubject" + existSubDo.getSort());
+                        }
                     } else {
-                        hasThrSub.add(thrSubArr[0]);
+                        stringBuilder.append("第" + (thrSubIndex + 1) + "列科目名称不能为空,");
                     }
                     thrSubIndex++;
                 }
@@ -642,36 +674,46 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                 }
             } else {
                 StringBuilder stringBuilder = new StringBuilder();
+                QcsLossDetailDo qcsLossDetailDo = new QcsLossDetailDo();
+                qcsLossDetailDo.setRoption("导入");
 
                 //项目工号
                 String procode = row.getCell(0).toString().replaceAll("\\s+", "");
+                List<QcsPartNoDo> codeParts = new ArrayList<>();
                 if (StringUtils.isEmpty(procode)) {
                     stringBuilder.append("项目工号不能为空,");
-                    continue;
                 } else if (procode.equals("小计")) {
                     break;
-                }
-
-                QcsLossDetailDo qcsLossDetailDo = new QcsLossDetailDo();
-                List<QcsPartNoDo> codeParts = allPartnos.stream().filter(c -> c.getDlprojid().equals(procode)).collect(Collectors.toList());
-                if (codeParts.size() == 0) {
-                    stringBuilder.append("项目工号" + procode + "不存在,");
-                    continue;
                 } else {
-                    qcsLossDetailDo.setId(SecurityUtil.getUUID());
-                    qcsLossDetailDo.setMainid(costId);
-                    qcsLossDetailDo.setProid(codeParts.get(0).getDtserialid());
-                    qcsLossDetailDo.setProcode(procode);
-                    qcsLossDetailDo.setProname(codeParts.get(0).getDlprojname());
+                    if (StringUtil.isScience(procode)) {
+                        BigDecimal formatProjectCode = new BigDecimal(procode);
+                        procode = formatProjectCode.setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString();
+                    }
+
+                    String finalProcode = procode;
+                    codeParts = allPartnos.stream().filter(c -> c.getDlprojid().equals(finalProcode)).collect(Collectors.toList());
+                    if (codeParts.size() == 0) {
+                        stringBuilder.append("项目工号" + procode + "不存在,");
+                    } else {
+                        qcsLossDetailDo.setId(SecurityUtil.getUUID());
+                        qcsLossDetailDo.setMainid(costId);
+                        qcsLossDetailDo.setProid(codeParts.get(0).getDtserialid());
+                        qcsLossDetailDo.setProcode(procode);
+                        qcsLossDetailDo.setProname(codeParts.get(0).getDlprojname());
+                    }
                 }
 
                 //部件图号
                 String partno = row.getCell(2).toString().replaceAll("\\s+", "");
                 if (StringUtils.isNotEmpty(partno)) {
-                    List<QcsPartNoDo> partNos = codeParts.stream().filter(p -> p.getDtdrawingno().equals(partno)).collect(Collectors.toList());
+                    if (StringUtil.isScience(partno)) {
+                        BigDecimal formatProjectCode = new BigDecimal(partno);
+                        partno = formatProjectCode.setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString();
+                    }
+                    String finalPartno = partno;
+                    List<QcsPartNoDo> partNos = codeParts.stream().filter(p -> p.getDtdrawingno().equals(finalPartno)).collect(Collectors.toList());
                     if (partNos.size() == 0) {
-                        stringBuilder.append("部件图号" + partno + "不存在,");
-                        continue;
+                        stringBuilder.append("部件图号" + partno + "与项目工号" + procode + "不匹配,");
                     } else {
                         qcsLossDetailDo.setPartnoid(partNos.get(0).getPartnoid());
                         qcsLossDetailDo.setPartno(partno);
@@ -685,10 +727,8 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                     List<String> lossType = new ArrayList<>(Arrays.asList("修改单", "检查报告", "整改单", "事故单"));
                     if (costType.equals("3") && !lossType.contains(losstype)) {
                         stringBuilder.append("类别不正确,");
-                        continue;
                     } else if (costType.equals("4") && !losstype.equals("事故单")) {
                         stringBuilder.append("外部损失的类别必须为事故单,");
-                        continue;
                     } else {
                         qcsLossDetailDo.setLosstype(losstype);
                     }
@@ -697,14 +737,32 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                 //编号
                 String lossno = row.getCell(5).toString().replaceAll("\\s+", "");
                 if (StringUtils.isNotEmpty(lossno)) {
+                    if (StringUtil.isScience(lossno)) {
+                        BigDecimal formatProjectCode = new BigDecimal(lossno);
+                        lossno = formatProjectCode.setScale(0, BigDecimal.ROUND_HALF_UP).toPlainString();
+                    }
                     qcsLossDetailDo.setLossno(lossno);
                 }
 
                 if (costType.equals("3")) {
                     //修改原因
                     String modifyreason = row.getCell(6).toString().replaceAll("\\s+", "");
-                    if (StringUtils.isNotEmpty(modifyreason)) {
-
+                    if (StringUtils.isNotEmpty(modifyreason) && StringUtils.isNotEmpty(losstype)) {
+                        if (typeResMap == null) {
+                            return R.error("系统没有维护类别与原因关系数据");
+                        } else {
+                            List<Map<String, Object>> typeRes = typeResMap.stream()
+                                    .filter(map -> {
+                                        Object loType = map.get("LOSSTYPE");
+                                        Object resson = map.get("REASON");
+                                        return loType.equals(losstype) && resson.equals(modifyreason);
+                                    }).collect(Collectors.toList());
+                            if (typeRes.size() == 0) {
+                                stringBuilder.append("类别与原因关系不对,");
+                            } else {
+                                qcsLossDetailDo.setModifyreason(modifyreason);
+                            }
+                        }
                     }
                 } else {
                     //事故问题概述
@@ -713,10 +771,28 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
                 }
 
                 //三级科目
-
+                int thrSubIndex = 7;
+                for (QcsSubjectConfigDo subjectConfigDo : qcsSubjectConfigDos) {
+                    String amountStr = row.getCell(thrSubIndex).toString().replaceAll("\\s+", "");
+                    BigDecimal amount = null;
+                    if (amountStr != null && StringUtils.isNotEmpty(amountStr)) {
+                        String toAmount = convertToTwoDecimalPlaces(amountStr);
+                        if (toAmount.equals("金额要为数字,")) {
+                            stringBuilder.append(toAmount);
+                        } else {
+                            amount = new BigDecimal(toAmount);
+                        }
+                    }
+                    String columnName = "setS" + subIndex.get(thrSubIndex);
+                    Method method = QcsLossDetailDo.class.getMethod(columnName, BigDecimal.class);
+                    method.invoke(qcsLossDetailDo, amount);
+                    thrSubIndex++;
+                }
 
                 if (StringUtils.isNotBlank(stringBuilder.toString())) {
                     allStrBuilder.append("第").append(i + 1).append("行").append(stringBuilder.deleteCharAt(stringBuilder.length() - 1)).append("<br>");
+                } else {
+                    qcsLossDetailDoList.add(qcsLossDetailDo);
                 }
             }
         }
@@ -727,6 +803,13 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
         } else if (hasThrSub.size() == 0 || hasThrSub.size() != qcsSubjectConfigDos.size()) {
             return R.error("三级科目与系统科目配置表里不匹配");
         } else {
+            //删掉未提交的数据
+            if (oldMainCostDo != null) {
+                qcsMainCostDao.delMainCost(oldMainCostDo.getId());
+                qcsMainCostDao.delLossDetail(oldMainCostDo.getId());
+                qcsMainCostDao.delColConfig(oldMainCostDo.getId());
+            }
+
             SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
             qcsMainCostDo.setId(costId);
             qcsMainCostDo.setRoption("导入");
@@ -735,20 +818,20 @@ public class QcsMainCostServiceImpl extends ServiceImpl<QcsMainCostDao, QcsMainC
             qcsMainCostDo.setYearmonth(format.parse(yearMonth));
             qcsMainCostDo.setCosttype(costType);
 
-            return R.ok();
-//            Boolean bool1 = qcsMainCostService.save(qcsMainCostDo);
-//            Boolean bool2 = qcsLossDetailService.saveBatch(qcsLossDetailDoList);
-//            if (bool1 && bool2) {
-//                Map<String, String> otherMap = new HashMap<>();
-//                otherMap.put("formId", costId);
-//                otherMap.put("insertFlag", "1");
-//                otherMap.put("tjFlag", "0");
-//                setOtherCost(otherMap);
-//
-//                return R.ok();
-//            } else {
-//                return R.error("数据导入异常");
-//            }
+//            return R.ok();
+            Boolean bool1 = qcsMainCostService.save(qcsMainCostDo);
+            Boolean bool2 = qcsLossDetailService.saveBatch(qcsLossDetailDoList);
+            if (bool1 && bool2) {
+                Map<String, String> otherMap = new HashMap<>();
+                otherMap.put("formId", costId);
+                otherMap.put("insertFlag", "1");
+                otherMap.put("tjFlag", "0");
+                setOtherCost(otherMap);
+
+                return R.ok();
+            } else {
+                return R.error("数据导入异常");
+            }
         }
     }
 

+ 354 - 0
qcs-common/src/main/java/com/rongwei/bscommon/sys/utils/StringUtil.java

@@ -0,0 +1,354 @@
+package com.rongwei.bscommon.sys.utils;
+
+import org.apache.commons.lang3.BooleanUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
+import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author bootdo
+ */
+public class StringUtil extends org.apache.commons.lang3.StringUtils {
+
+    public static final char UNDERLINE = '_';
+    // 科学计数法的正则表达式
+    private static String scientificNotationPattern = "^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$";
+
+    /**
+     * 驼峰格式字符串转换为下划线格式字符串
+     *
+     * @param param
+     * @return
+     */
+    public static String camelToUnderline(String param) {
+        if (param == null || "".equals(param.trim())) {
+            return "";
+        }
+        int len = param.length();
+        StringBuilder sb = new StringBuilder(len);
+        for (int i = 0; i < len; i++) {
+            char c = param.charAt(i);
+            if (Character.isUpperCase(c)) {
+                sb.append(UNDERLINE);
+                sb.append(Character.toLowerCase(c));
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+
+    /**
+     * 下划线格式字符串转换为驼峰格式字符串
+     *
+     * @param param
+     * @return
+     */
+    public static String underlineToCamel(String param) {
+        if (param == null || "".equals(param.trim())) {
+            return "";
+        }
+        int len = param.length();
+        StringBuilder sb = new StringBuilder(len);
+        for (int i = 0; i < len; i++) {
+            char c = param.charAt(i);
+            if (c == UNDERLINE) {
+                if (++i < len) {
+                    sb.append(Character.toUpperCase(param.charAt(i)));
+                }
+            } else {
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 下划线格式字符串转换为驼峰格式字符串2
+     *
+     * @param param
+     * @return
+     */
+    public static String underlineToCamel2(String param) {
+        if (param == null || "".equals(param.trim())) {
+            return "";
+        }
+        StringBuilder sb = new StringBuilder(param);
+        Matcher mc = Pattern.compile("_").matcher(param);
+        int i = 0;
+        while (mc.find()) {
+            int position = mc.end() - (i++);
+            sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 得到二位数的序号
+     *
+     * @param num
+     * @return
+     */
+    public static String getNextCode(Integer num) {
+        if (num == null || num == 0) {
+            return "001";
+        } else if (num > 0 && num < 9) {
+            return "00" + (num + 1) + "";
+        } else if (num == 9) {
+            return "010";
+        } else if (num >= 10 && num < 98) {
+            return "0" + (num + 1) + "";
+        } else if (num == 99) {
+            return "100";
+        } else {
+            return (num + 1) + "";
+        }
+    }
+
+
+    /**
+     * 将传入的对象转换为字符串,当传入的对象为null时返回默认值
+     * bw.ren  2019年6月3日09:46:33
+     *
+     * @param o
+     * @param dv
+     * @return
+     */
+    public static String safeToString(Object o, String dv) {
+        String r = dv;
+        if (o != null) {
+            r = String.valueOf(o);
+        }
+        return r;
+    }
+
+    /**
+     * 获得用户远程地址
+     */
+    public static String getRemoteAddr(HttpServletRequest request) {
+        String remoteAddr = request.getHeader("X-Real-IP");
+        if (isNotBlank(remoteAddr)) {
+            remoteAddr = request.getHeader("X-Forwarded-For");
+        } else if (isNotBlank(remoteAddr)) {
+            remoteAddr = request.getHeader("Proxy-Client-IP");
+        } else if (isNotBlank(remoteAddr)) {
+            remoteAddr = request.getHeader("WL-Proxy-Client-IP");
+        }
+        return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
+    }
+
+    /**
+     * 如果对象为空,则使用defaultVal值
+     * see: ObjectUtils.toString(obj, defaultVal)
+     *
+     * @param obj
+     * @param defaultVal
+     * @return
+     */
+    public static String toString(final Object obj, final String defaultVal) {
+        return obj == null ? defaultVal : obj.toString();
+    }
+
+    /**
+     * 转换为Boolean类型
+     * 'true', 'on', 'y', 't', 'yes' or '1' (case insensitive) will return true. Otherwise, false is returned.
+     */
+    public static Boolean toBoolean(final Object val) {
+        if (val == null) {
+            return false;
+        }
+        return BooleanUtils.toBoolean(val.toString()) || "1".equals(val.toString());
+    }
+
+    public static boolean isNumericzidai(String str) {
+        Pattern pattern = Pattern.compile("-?[0-9]+\\.?[0-9]*");
+        Matcher isNum = pattern.matcher(str);
+        if (!isNum.matches()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 正则:手机号(简单), 1字头+10位数字即可.
+     *
+     * @param in
+     * @return
+     */
+    public static boolean validateMobilePhone(String in) {
+        Pattern pattern = Pattern.compile("^[1]\\d{10}$");
+        return pattern.matcher(in).matches();
+    }
+
+    /**
+     * 正则:邮箱
+     *
+     * @param in
+     * @return
+     */
+    public static boolean validateEmail(String in) {
+        Pattern pattern = Pattern.compile("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
+        return pattern.matcher(in).matches();
+    }
+
+
+    /**
+     * 是否是数字
+     *
+     * @param value
+     */
+    public static boolean isNum(String value) {
+        Pattern p = null;//正则表达式
+        Matcher m = null;//操作符表达式
+        boolean b = false;
+        p = p.compile("^([+-]?)\\d*\\.?\\d+$");
+        m = p.matcher(value);
+        b = m.matches();
+        return b;
+    }
+
+    /**
+     * 根据正则截取字符串
+     *
+     * @return
+     */
+    public static String InterceptString(String projectName) {
+        Pattern pattern = Pattern.compile(".*?(?=\\()");
+        Matcher matcher = pattern.matcher(projectName);
+        while (matcher.find()) {
+            return matcher.group();
+        }
+        return null;
+    }
+
+
+    /**
+     * 判断是否是身份证号
+     *
+     * @param cardNo
+     * @return
+     */
+    public static boolean isCard(String cardNo) {
+        String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
+                "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
+        boolean matches = cardNo.matches(regularExpression);
+        //判断第18位校验值
+        if (matches) {
+            if (cardNo.length() == 18) {
+                try {
+                    char[] charArray = cardNo.toCharArray();
+                    //前十七位加权因子
+                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
+                    //这是除以11后,可能产生的11位余数对应的验证码
+                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
+                    int sum = 0;
+                    for (int i = 0; i < idCardWi.length; i++) {
+                        int current = Integer.parseInt(String.valueOf(charArray[i]));
+                        int count = current * idCardWi[i];
+                        sum += count;
+                    }
+                    char idCardLast = charArray[17];
+                    int idCardMod = sum % 11;
+                    if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
+                        return true;
+                    } else {
+                        System.out.println("身份证最后一位:" + String.valueOf(idCardLast).toUpperCase() +
+                                "错误,正确的应该是:" + idCardY[idCardMod].toUpperCase());
+                        return false;
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    System.out.println("异常:" + cardNo);
+                    return false;
+                }
+            }
+        }
+        return matches;
+    }
+
+    public static void main(String[] args) {
+        boolean a = containsCodeCharacters("哈哈哈");
+        System.out.print(a);
+    }
+
+    /**
+     * 根据正则截取字符串
+     *
+     * @return
+     */
+    public static int getArrayElementPosition(String[] actualWeldInfo, String actualWeld) {
+        Arrays.sort(actualWeldInfo);
+        int position = Arrays.binarySearch(actualWeldInfo, actualWeld);
+        return position;
+    }
+
+    /**
+     * 格式化字符串中的小数点
+     */
+    public static String formatDecimal(String str) {
+        str = str.replaceAll("[.](.*)", "");
+        return str;
+    }
+
+    /**
+     * 四舍五入小数
+     */
+    public static String formatDecimalFiveIn(String str) {
+        str = String.valueOf(Math.round(Float.parseFloat(str)));
+        return str;
+    }
+
+//        public static void main(String args[]){
+////            String[] intArray = new String[]{"a","b","c","d","e","f","g","h","i","j",};
+////            String actualWeld = "vt1684_pt793_50_500,vt1684_ut793_30_300,vt1684_rt793_60_600,vt1684_mt793_60_600";
+////            String[] actualWeldInfo = actualWeld.split(",");
+////            Arrays.sort(actualWeldInfo);
+////            int positon = Arrays.binarySearch(actualWeldInfo, "vt1684_pt793_50_500");
+////            System.out.println("position is:"+positon);
+//            String actualWeld = formatDecimal(String.valueOf(1000.98));
+//            System.out.print(actualWeld);
+//        }
+
+    public static int querySpecificCharacter(String flawInspectCode) {
+        int count = 0;
+        int strLength = flawInspectCode.length();
+        String searchChar = "R";
+        flawInspectCode = flawInspectCode.replace(searchChar, "");
+        int newLength = flawInspectCode.length();
+        count = strLength - newLength;
+        return count;
+    }
+
+    public static String getUUID() {
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        return uuid;
+    }
+
+    /**
+     * 判断是否是科学计数法
+     *
+     * @param ret
+     * @return
+     */
+    public static boolean isScience(String ret) {
+        return ret.matches(scientificNotationPattern);
+    }
+
+    /**
+     * 校验字符串中是否包含非法字符
+     *
+     * @param input
+     * @return
+     */
+    public static boolean containsCodeCharacters(String input) {
+        // 定义需要检查的特殊字符的正则表达式
+        String regex = "<|>|\\|\\\"|'|\\\\|&";
+        // 使用正则表达式检查字符串中是否包含这些字符
+        return input.matches(".*[" + regex + "].*");
+    }
+
+}

+ 4 - 0
qcs-entity/src/main/java/com/rongwei/bsentity/domain/QcsLossDetailDo.java

@@ -20,6 +20,10 @@ public class QcsLossDetailDo extends BaseDo implements Serializable {
      * ID
      */
     private String id;
+    /**
+     * ROPTION
+     */
+    private String roption;
 
     /**
      * 主表ID