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()