diff --git a/@rbv b/@rbv index c2f072f6e..d6da52b48 160000 --- a/@rbv +++ b/@rbv @@ -1 +1 @@ -Subproject commit c2f072f6ed0ee3c576c81d96e51ef8b147b29be7 +Subproject commit d6da52b4833a867f059c276b1927a8a8b551232b diff --git a/README.md b/README.md index fbead20b8..feeddf175 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ 1. [新增] 限时审批 2. [新增] 新建任务(触发器) -3. [新增] 地图图表 +3. [新增] 地图等多个图表 4. [新增] 自动明细记录导入(记录转换) 5. [新增] 数据列表之卡片模式 6. [新增] 多个 FrontJS 函数 diff --git a/pom.xml b/pom.xml index e83e4a851..6d4401abb 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.rebuild rebuild - 3.7.0-beta4 + 3.7.0 rebuild Building your business-systems freely! https://getrebuild.com/ diff --git a/src/main/java/com/rebuild/core/Application.java b/src/main/java/com/rebuild/core/Application.java index e7f70385c..4315ac4a9 100644 --- a/src/main/java/com/rebuild/core/Application.java +++ b/src/main/java/com/rebuild/core/Application.java @@ -75,11 +75,11 @@ public class Application implements ApplicationListener /** * Rebuild Version */ - public static final String VER = "3.7.0-beta4"; + public static final String VER = "3.7.0"; /** * Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2} */ - public static final int BUILD = 3070004; + public static final int BUILD = 3070005; static { // Driver for DB diff --git a/src/main/java/com/rebuild/core/service/dataimport/DataImporter.java b/src/main/java/com/rebuild/core/service/dataimport/DataImporter.java index 3dc9c1739..e0fd6c274 100644 --- a/src/main/java/com/rebuild/core/service/dataimport/DataImporter.java +++ b/src/main/java/com/rebuild/core/service/dataimport/DataImporter.java @@ -217,7 +217,7 @@ public class DataImporter extends HeavyTask { } } - log.info("Checking repeated : " + wheres); + log.info("Checking repeated : {}", wheres); if (wheres.isEmpty()) return null; Entity entity = data.getEntity(); diff --git a/src/main/java/com/rebuild/core/service/dataimport/RecordCheckout.java b/src/main/java/com/rebuild/core/service/dataimport/RecordCheckout.java index 127567b30..fec3f749a 100644 --- a/src/main/java/com/rebuild/core/service/dataimport/RecordCheckout.java +++ b/src/main/java/com/rebuild/core/service/dataimport/RecordCheckout.java @@ -15,9 +15,6 @@ import cn.devezhao.persist4j.Record; import cn.devezhao.persist4j.engine.ID; import cn.devezhao.persist4j.record.FieldValueException; import cn.devezhao.persist4j.record.RecordVisitor; -import cn.hutool.core.date.DateException; -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.rebuild.core.Application; import com.rebuild.core.configuration.general.ClassificationManager; @@ -273,20 +270,7 @@ public class RecordCheckout { protected Date checkoutDateValue(Cell cell) { Date date = cell.asDate(); if (date != null) return date; - - String date2str = cell.asString(); - - try { - DateTime dt = DateUtil.parse(date2str); - if (dt != null) date = dt.toJdkDate(); - } catch (DateException ignored) { - } - - // 2017/11/19 11:07 - if (date == null && date2str.contains("/")) { - date = cell.asDate(new String[]{"yyyy/M/d H:m:s", "yyyy/M/d H:m", "yyyy/M/d"}); - } - return date; + return CommonsUtils.parseDate(cell.asString()); } protected LocalTime checkoutTimeValue(Cell cell) { diff --git a/src/main/java/com/rebuild/core/service/datareport/EasyExcelGenerator.java b/src/main/java/com/rebuild/core/service/datareport/EasyExcelGenerator.java index 21fd2ce0f..400706a9f 100644 --- a/src/main/java/com/rebuild/core/service/datareport/EasyExcelGenerator.java +++ b/src/main/java/com/rebuild/core/service/datareport/EasyExcelGenerator.java @@ -32,6 +32,7 @@ import com.rebuild.core.metadata.easymeta.MultiValue; import com.rebuild.core.metadata.impl.EasyFieldConfigProps; import com.rebuild.core.privileges.UserHelper; import com.rebuild.core.service.approval.ApprovalState; +import com.rebuild.core.service.query.QueryHelper; import com.rebuild.core.support.RebuildConfiguration; import com.rebuild.core.support.SetUser; import com.rebuild.core.support.general.BarCodeSupport; @@ -341,25 +342,18 @@ public class EasyExcelGenerator extends SetUser { } } - for (final String fieldName : varsMap.values()) { + for (Map.Entry e : varsMap.entrySet()) { + final String fieldName = e.getValue(); if (fieldName == null) continue; - EasyField easyField = EasyMetaFactory.valueOf(MetadataHelper.getLastJoinField(entity, fieldName)); - DisplayType dt = easyField.getDisplayType(); - - // 替换成变量名 - String varName = fieldName; - for (Map.Entry e : varsMap.entrySet()) { - if (fieldName.equalsIgnoreCase(e.getValue())) { - varName = e.getKey(); - break; - } - } - + String varName = e.getKey(); if (varName.startsWith(NROW_PREFIX)) { varName = varName.substring(1); } + EasyField easyField = EasyMetaFactory.valueOf(MetadataHelper.getLastJoinField(entity, fieldName)); + DisplayType dt = easyField.getDisplayType(); + // FIXME v3.2 图片仅支持导出第一张 if (!dt.isExportable() && dt != DisplayType.IMAGE) { data.put(varName, unsupportFieldTip); @@ -386,9 +380,7 @@ public class EasyExcelGenerator extends SetUser { String format = easyField.getExtraAttr(EasyFieldConfigProps.DECIMAL_FORMAT); int scale = StringUtils.isBlank(format) ? 2 : format.split("\\.")[1].length(); // Keep Type -// fieldValue = ObjectUtils.round(((BigDecimal) fieldValue).doubleValue(), scale); fieldValue = ((BigDecimal) fieldValue).setScale(scale, RoundingMode.HALF_UP); - } else { fieldValue = FieldValueHelper.wrapFieldValue(fieldValue, easyField, Boolean.TRUE); } @@ -420,6 +412,9 @@ public class EasyExcelGenerator extends SetUser { } } } + + // v3.7.0 + fieldValue = ValueConvertFunc.convert(easyField, fieldValue, varName); } data.put(varName, fieldValue); @@ -490,22 +485,27 @@ public class EasyExcelGenerator extends SetUser { return phName.length() > PH__KEEP.length() ? phName.substring(PH__KEEP.length() + 1) : ""; } - // 列表序号 - if (phName.equals(PH__NUMBER)) { - return phNumber; + + switch (phName) { + case PH__NUMBER: + return phNumber; + case PH__CURRENTUSER: + return UserHelper.getName(getUser()); + case PH__CURRENTBIZUNIT: + return Objects.requireNonNull(UserHelper.getDepartment(getUser())).getName(); + case PH__CURRENTDATE: + return CalendarUtils.getUTCDateFormat().format(CalendarUtils.now()); + case PH__CURRENTDATETIME: + return CalendarUtils.getUTCDateTimeFormat().format(CalendarUtils.now()); } - if (phName.equals(PH__CURRENTUSER)) { - return UserHelper.getName(getUser()); - } - if (phName.equals(PH__CURRENTBIZUNIT)) { - return Objects.requireNonNull(UserHelper.getDepartment(getUser())).getName(); - } - if (phName.equals(PH__CURRENTDATE)) { - return CalendarUtils.getUTCDateFormat().format(CalendarUtils.now()); - } - if (phName.equals(PH__CURRENTDATETIME)) { - return CalendarUtils.getUTCDateTimeFormat().format(CalendarUtils.now()); + + // v3.7 + if (phName.startsWith(PH__CURRENTUSER)) { + String useField = phName.substring(PH__CURRENTUSER.length() + 1); + Object useValue = QueryHelper.queryFieldValue(getUser(), useField); + return useValue == null ? null : useValue.toString(); } + return null; } diff --git a/src/main/java/com/rebuild/core/service/datareport/FixsMergeStrategy.java b/src/main/java/com/rebuild/core/service/datareport/FixsMergeStrategy.java index da888a471..e2b480060 100644 --- a/src/main/java/com/rebuild/core/service/datareport/FixsMergeStrategy.java +++ b/src/main/java/com/rebuild/core/service/datareport/FixsMergeStrategy.java @@ -9,12 +9,12 @@ package com.rebuild.core.service.datareport; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.merge.AbstractMergeStrategy; +import com.esotericsoftware.minlog.Log; +import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.RegionUtil; import java.util.List; @@ -24,6 +24,7 @@ import java.util.List; * @author devezhao * @since 2021/4/3 */ +@Slf4j public class FixsMergeStrategy extends AbstractMergeStrategy { @Override @@ -32,30 +33,67 @@ public class FixsMergeStrategy extends AbstractMergeStrategy { return; } +// int rowIndex = cell.getRowIndex(); +// int colIndex = cell.getColumnIndex(); +// sheet = cell.getSheet(); +// Row prevRow = sheet.getRow(rowIndex - 1); +// if (prevRow == null) return; +// Cell prevCell = prevRow.getCell(colIndex); +// List craList = sheet.getMergedRegions(); +// CellStyle cs = cell.getCellStyle(); +// cell.setCellStyle(cs); +// +// for (CellRangeAddress cellRangeAddress : craList) { +// if (cellRangeAddress.containsRow(prevCell.getRowIndex()) && cellRangeAddress.containsColumn(prevCell.getColumnIndex())) { +// int lastColIndex = cellRangeAddress.getLastColumn(); +// int firstColIndex = cellRangeAddress.getFirstColumn(); +// CellRangeAddress cra = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), firstColIndex, lastColIndex); +// sheet.addMergedRegion(cra); +// +// // 复制线框样式 +// RegionUtil.setBorderBottom(cs.getBorderBottom(), cra, sheet); +// RegionUtil.setBorderLeft(cs.getBorderLeft(), cra, sheet); +// RegionUtil.setBorderRight(cs.getBorderRight(), cra, sheet); +// RegionUtil.setBorderTop(cs.getBorderTop(), cra, sheet); +// +// break; +// } +// } + + try { + merge37(sheet, cell, head, relativeRowIndex); + } catch (Exception ex) { + log.warn("Cannot merge cell", ex); + } + } + + // v3.7 + // THANKS https://github.com/alibaba/easyexcel/issues/2963#issuecomment-1432827475 + private void merge37(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) { int rowIndex = cell.getRowIndex(); int colIndex = cell.getColumnIndex(); - sheet = cell.getSheet(); - Row prevRow = sheet.getRow(rowIndex - 1); - if (prevRow == null) return; - Cell prevCell = prevRow.getCell(colIndex); - List craList = sheet.getMergedRegions(); - CellStyle cs = cell.getCellStyle(); - cell.setCellStyle(cs); + Sheet thisSheet = cell.getSheet(); + Row preRow = thisSheet.getRow(rowIndex - 1); + Row thisRow = thisSheet.getRow(rowIndex); + Cell preCell = preRow.getCell(colIndex); + Cell tmpCell; + List list = thisSheet.getMergedRegions(); - for (CellRangeAddress cellRangeAddress : craList) { - if (cellRangeAddress.containsRow(prevCell.getRowIndex()) && cellRangeAddress.containsColumn(prevCell.getColumnIndex())) { + for (int i = 0; i < list.size(); i++) { + CellRangeAddress cellRangeAddress = list.get(i); + if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex())) { int lastColIndex = cellRangeAddress.getLastColumn(); int firstColIndex = cellRangeAddress.getFirstColumn(); CellRangeAddress cra = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), firstColIndex, lastColIndex); - sheet.addMergedRegion(cra); - - // 复制线框样式 - RegionUtil.setBorderBottom(cs.getBorderBottom(), cra, sheet); - RegionUtil.setBorderLeft(cs.getBorderLeft(), cra, sheet); - RegionUtil.setBorderRight(cs.getBorderRight(), cra, sheet); - RegionUtil.setBorderTop(cs.getBorderTop(), cra, sheet); - - break; + thisSheet.addMergedRegion(cra); + for (int j = firstColIndex; j <= lastColIndex; j++) { + tmpCell = thisRow.getCell(j); + if (tmpCell == null) { + tmpCell = thisRow.createCell(j); + } + tmpCell.setCellStyle(preRow.getCell(j).getCellStyle()); + } + return; } } } diff --git a/src/main/java/com/rebuild/core/service/datareport/TemplateExtractor33.java b/src/main/java/com/rebuild/core/service/datareport/TemplateExtractor33.java index a537f44fd..8e51739a9 100644 --- a/src/main/java/com/rebuild/core/service/datareport/TemplateExtractor33.java +++ b/src/main/java/com/rebuild/core/service/datareport/TemplateExtractor33.java @@ -37,16 +37,15 @@ public class TemplateExtractor33 extends TemplateExtractor { // 明细字段 public static final String DETAIL_PREFIX = NROW_PREFIX + "detail"; - // $ + // $ 前缀 public static final String NROW_PREFIX2 = "$"; public static final String DETAIL_PREFIX2 = NROW_PREFIX2 + "detail"; public static final String APPROVAL_PREFIX2 = NROW_PREFIX2 + "approval"; - // 排序 private static final String SORT_ASC = ":asc"; private static final String SORT_DESC = ":desc"; - private Map sortFields = new HashMap<>(); + private Map sortFields = new HashMap<>(); private Set inShapeVars = new HashSet<>(); /** @@ -66,16 +65,18 @@ public class TemplateExtractor33 extends TemplateExtractor { Map map = new HashMap<>(); for (final String varName : vars) { + String thatName = ValueConvertFunc.splitName(varName); + // 列表型字段 - if (varName.startsWith(NROW_PREFIX) || varName.startsWith(NROW_PREFIX2)) { - final String listField = varName.substring(1).replace("$", "."); + if (thatName.startsWith(NROW_PREFIX) || thatName.startsWith(NROW_PREFIX2)) { + final String listField = thatName.substring(1).replace("$", "."); // 占位 if (isPlaceholder(listField)) { map.put(varName, null); } // 审批流程 - else if (varName.startsWith(APPROVAL_PREFIX) || varName.startsWith(APPROVAL_PREFIX2)) { + else if (thatName.startsWith(APPROVAL_PREFIX) || thatName.startsWith(APPROVAL_PREFIX2)) { String stepNodeField = listField.substring(APPROVAL_PREFIX.length()); if (approvalEntity != null && MetadataHelper.getLastJoinField(approvalEntity, stepNodeField) != null) { map.put(varName, stepNodeField); @@ -84,7 +85,7 @@ public class TemplateExtractor33 extends TemplateExtractor { } } // 明细实体 - else if (varName.startsWith(DETAIL_PREFIX) || varName.startsWith(DETAIL_PREFIX2)) { + else if (thatName.startsWith(DETAIL_PREFIX) || thatName.startsWith(DETAIL_PREFIX2)) { String detailField = listField.substring(DETAIL_PREFIX.length()); detailField = getFieldNameWithSort(DETAIL_PREFIX, detailField); @@ -117,10 +118,10 @@ public class TemplateExtractor33 extends TemplateExtractor { } } - } else if (MetadataHelper.getLastJoinField(entity, varName) != null) { - map.put(varName, varName); + } else if (MetadataHelper.getLastJoinField(entity, thatName) != null) { + map.put(varName, thatName); } else { - map.put(varName, transformRealField(entity, varName)); + map.put(varName, transformRealField(entity, thatName)); } } return map; diff --git a/src/main/java/com/rebuild/core/service/datareport/ValueConvertFunc.java b/src/main/java/com/rebuild/core/service/datareport/ValueConvertFunc.java new file mode 100644 index 000000000..39b369e01 --- /dev/null +++ b/src/main/java/com/rebuild/core/service/datareport/ValueConvertFunc.java @@ -0,0 +1,141 @@ +/*! +Copyright (c) REBUILD and/or its owners. All rights reserved. + +rebuild is dual-licensed under commercial and open source licenses (GPLv3). +See LICENSE and COMMERCIAL in the project root for license information. +*/ + +package com.rebuild.core.service.datareport; + +import cn.devezhao.commons.CalendarUtils; +import cn.hutool.core.convert.Convert; +import com.deepoove.poi.data.PictureRenderData; +import com.deepoove.poi.data.Pictures; +import com.rebuild.core.metadata.easymeta.DisplayType; +import com.rebuild.core.metadata.easymeta.EasyDecimal; +import com.rebuild.core.metadata.easymeta.EasyField; +import com.rebuild.utils.CommonsUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.DecimalFormat; +import java.util.Date; + +/** + * @author devezhao + * @since 2024/6/25 + */ +@Slf4j +public class ValueConvertFunc { + + // # 函数 + protected static final String FUNC_SPLITER = "#"; + + /** + * @param field + * @param value + * @param varName + * @return + */ + public static Object convert(EasyField field, Object value, String varName) { + String thatFunc = splitFunc(varName); + if (thatFunc == null) return value; + + final DisplayType type = field.getDisplayType(); + if (type == DisplayType.NUMBER || type == DisplayType.DECIMAL) { + if ("CHINESEYUAN".equals(thatFunc)) { + return Convert.digitToChinese((Number) value); + } + if ("THOUSANDS".equals(thatFunc)) { + String format = "##,##0"; + if (type == DisplayType.DECIMAL) { + int scale = ((EasyDecimal) field).getScale(); + if (scale > 0) { + format += "." + StringUtils.leftPad("", scale, "0"); + } + } + return new DecimalFormat(format).format(value); + } + + } else if (type == DisplayType.DATE || type == DisplayType.DATETIME) { + if ("CHINESEDATE".equals(thatFunc)) { + Date d = CommonsUtils.parseDate(value.toString()); + if (d == null) return value; + + int len = field.wrapValue(CalendarUtils.now()).toString().length(); + if (len <= 10) len += 1; // yyyy-MM-dd + else len += 2; + + String format = CalendarUtils.CN_DATETIME_FORMAT.substring(0, len); + return CalendarUtils.getDateFormat(format).format(d); + } + + } + return value; + } + + /** + * 转换图片 + * + * @param value + * @param varName + * @return + */ + public static PictureRenderData convertPictureWithSize(byte[] value, String varName) { + Pictures.PictureBuilder builder = Pictures.ofBytes(value); + + String thatFunc = splitFunc(varName); + if (thatFunc == null) return builder.create(); + + if (thatFunc.startsWith("SIZE") && thatFunc.length() > 4) { + String[] wh = thatFunc.substring(4).split("\\*"); + int width = NumberUtils.toInt(wh[0]); + int height = -1; + + // 指定宽度,高度自适应 + if (wh.length == 1) { + try (InputStream is = new ByteArrayInputStream(value)) { + BufferedImage bi = ImageIO.read(is); + int originWidth = bi.getWidth(); + int originHeight = bi.getHeight(); + if (originWidth > 0 && originHeight > 0) { + double scale = width * 1.0 / originWidth; + height = (int) (originHeight * scale); + } + + } catch (IOException e) { + log.error(null, e); + } + } else { + height = NumberUtils.toInt(wh[1]); + } + + if (height < 0) height = width; + builder = Pictures.ofBytes(value).size(width, height); + } + + return builder.create(); + } + + /** + * @param varName + * @return + */ + public static String splitName(String varName) { + return varName.split("#")[0].trim(); + } + + /** + * @param varName + * @return + */ + public static String splitFunc(String varName) { + return varName.contains(FUNC_SPLITER) ? varName.split("#")[1].trim() : null; + } +} diff --git a/src/main/java/com/rebuild/core/service/trigger/TriggerResult.java b/src/main/java/com/rebuild/core/service/trigger/TriggerResult.java index 8dbad7c7c..72d1f4184 100644 --- a/src/main/java/com/rebuild/core/service/trigger/TriggerResult.java +++ b/src/main/java/com/rebuild/core/service/trigger/TriggerResult.java @@ -11,6 +11,7 @@ import cn.devezhao.persist4j.engine.ID; import com.alibaba.fastjson.JSONAware; import com.alibaba.fastjson.JSONObject; import com.rebuild.utils.JSONUtils; +import lombok.Getter; import java.util.Collection; @@ -20,6 +21,7 @@ import java.util.Collection; * @author RB * @since 2022/09/26 */ +@Getter public class TriggerResult implements JSONAware { // 状态 1=成功, 2=警告, 3=错误 @@ -30,6 +32,7 @@ public class TriggerResult implements JSONAware { final private Collection affected; private TriggerSource chain; + private boolean breakNext; protected TriggerResult(int level, String message, Collection affected) { this.level = level; @@ -37,28 +40,25 @@ public class TriggerResult implements JSONAware { this.affected = affected; } - protected void setChain(TriggerSource chain) { + public void setChain(TriggerSource chain) { this.chain = chain; } + public void setBreakNext(boolean breakNext) { + this.breakNext = breakNext; + } + public boolean hasAffected() { return affected != null && !affected.isEmpty(); } - public int getLevel() { - return level; - } - - public String getMessage() { - return message; - } - @Override public String toJSONString() { JSONObject res = JSONUtils.toJSONObject("level", level); if (message != null) res.put("message", message); if (affected != null) res.put("affected", affected); if (chain != null) res.put("chain", chain.toString()); + if (breakNext) res.put("break", true); return res.toJSONString(); } @@ -67,6 +67,8 @@ public class TriggerResult implements JSONAware { return toJSONString(); } + // -- + /** * @param affected * @return diff --git a/src/main/java/com/rebuild/core/support/integration/SMSender.java b/src/main/java/com/rebuild/core/support/integration/SMSender.java index 267e6d054..9e5ae0711 100644 --- a/src/main/java/com/rebuild/core/support/integration/SMSender.java +++ b/src/main/java/com/rebuild/core/support/integration/SMSender.java @@ -110,8 +110,8 @@ public class SMSender { * @param attach * @param useTemplate * @param specAccount - * @return returns null if failed or SENDID - * @throws ConfigurationException If mail-account unset + * @return + * @throws ConfigurationException */ public static String sendMail(String to, String subject, String content, File[] attach, boolean useTemplate, String[] specAccount) throws ConfigurationException { if (specAccount == null || specAccount.length < 6 @@ -121,7 +121,7 @@ public class SMSender { } if (Application.devMode()) { - log.info("[dev] FAKE SEND EMAIL : {}, {}, {}", to, subject, content); + log.info("[dev] FAKE SEND EMAIL. T:{}, S:{}, M:{}, F:{}", to, subject, content, attach); return null; } @@ -326,7 +326,7 @@ public class SMSender { } if (Application.devMode()) { - log.warn("[dev] FAKE SEND SMS : {}, {}", to, content); + log.warn("[dev] FAKE SEND SMS. T:{}, M:{}", to, content); return null; } diff --git a/src/main/java/com/rebuild/utils/CommonsUtils.java b/src/main/java/com/rebuild/utils/CommonsUtils.java index 0b2338d6f..519007a0b 100644 --- a/src/main/java/com/rebuild/utils/CommonsUtils.java +++ b/src/main/java/com/rebuild/utils/CommonsUtils.java @@ -7,9 +7,13 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.utils; +import cn.devezhao.commons.CalendarUtils; import cn.devezhao.commons.ObjectUtils; import cn.devezhao.commons.ReflectUtils; import cn.devezhao.persist4j.engine.NullValue; +import cn.hutool.core.date.DateException; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import com.rebuild.core.Application; import com.rebuild.core.BootApplication; import com.rebuild.core.RebuildException; @@ -30,6 +34,7 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collection; +import java.util.Date; import java.util.Objects; import java.util.UUID; import java.util.regex.Pattern; @@ -334,4 +339,36 @@ public class CommonsUtils { throw new SecurityException("Attack path detected : " + escapeHtml(filepath)); } } + + /** + * 日期转换 + * + * @param source + * @return + */ + public static Date parseDate(String source) { + if ("yyyy".length() == source.length()) { + return CalendarUtils.parse(source, "yyyy"); + } + if ("yyyy-MM".length() == source.length()) { + return CalendarUtils.parse(source, "yyyy-MM"); + } + + try { + DateTime dt = DateUtil.parse(source); + if (dt != null) return dt.toJdkDate(); + } catch (DateException ignored) { + } + + // 2017/11/19 11:07 + if (source.contains("/")) { + String[] fs = new String[]{"yyyy/M/d H:m:s", "yyyy/M/d H:m", "yyyy/M/d"}; + for (String format : fs) { + Date d = CalendarUtils.parse(source, format); + if (d != null) return d; + } + } + + return null; + } } diff --git a/src/main/resources/web/assets/js/charts/charts.js b/src/main/resources/web/assets/js/charts/charts.js index 592a3b14b..a6fd05340 100644 --- a/src/main/resources/web/assets/js/charts/charts.js +++ b/src/main/resources/web/assets/js/charts/charts.js @@ -219,8 +219,13 @@ class ChartIndex extends BaseChart { const N1 = this._num(data.index.data) const N2 = this._num(data.index.data2) clazz2 = N1 >= N2 ? 'ge' : 'le' - rate2 = (((N1 - N2) * 1.0) / N2) * 100 - rate2 = `${Math.abs(rate2).toFixed(2)}%` + // eslint-disable-next-line eqeqeq + if (N2 == 0) { + rate2 = '100.00%' + } else { + rate2 = (((N1 - N2) * 1.0) / N2) * 100 + rate2 = `${Math.abs(rate2).toFixed(2)}%` + } } const chartdata = ( diff --git a/src/main/resources/web/assets/js/general/rb-forms.append.js b/src/main/resources/web/assets/js/general/rb-forms.append.js index b7687369e..847f060d0 100644 --- a/src/main/resources/web/assets/js/general/rb-forms.append.js +++ b/src/main/resources/web/assets/js/general/rb-forms.append.js @@ -310,7 +310,7 @@ class BaiduMap extends React.Component { const map = new _BMapGL.Map(that._mapid) map.addControl(new _BMapGL.ZoomControl()) map.addControl(new _BMapGL.ScaleControl()) - // map.addControl(new _BMapGL.LocationControl()) + map.addControl(new _BMapGL.LocationControl()) // 滚动缩放 if (that.props.disableScrollWheelZoom !== true) map.enableScrollWheelZoom()