From 8bb2a4505b4525a21f81a3e3b8da17aa3d0ac1d1 Mon Sep 17 00:00:00 2001 From: RB Date: Thu, 30 Jun 2022 20:41:03 +0800 Subject: [PATCH] Fix 2.9.3 (#476) * some fix * detail AutoTransform * fix: h5 captcha * fix: auto-share * fix avatar cache * open: ref-detail, field label * fix bool style in protable * better : field-formula * fix: imports owningUser * post passwd --- @rbv | 2 +- pom.xml | 2 +- .../java/com/rebuild/core/Application.java | 4 +-- .../general/FormBuilderContextHolder.java | 24 ++++++++++------- .../configuration/general/FormsBuilder.java | 6 ++--- .../core/service/dataimport/DataImporter.java | 13 +++++----- .../service/dataimport/RecordCheckout.java | 18 +++++++++++-- .../service/general/GeneralEntityService.java | 25 +++++++++++------- .../GeneralEntityServiceContextHolder.java | 8 +++--- .../general/transform/RecordTransfomer.java | 2 +- .../trigger/impl/AggregationEvaluator.java | 17 +++++++++--- .../core/service/trigger/impl/AutoAssign.java | 4 +-- .../core/service/trigger/impl/AutoShare.java | 2 +- .../rebuild/core/support/SystemDiagnosis.java | 4 +-- .../admin/metadata/FormDesignController.java | 13 ++++------ .../rebuild/web/commons/FileDownloader.java | 20 +++++++++----- .../web/general/GeneralModelController.java | 2 +- .../java/com/rebuild/web/user/UserAvatar.java | 4 ++- .../web/user/UserSettingsController.java | 13 +++++----- .../web/user/signup/LoginController.java | 20 +++++++++----- .../web/admin/metadata/entities.html | 9 ++++--- .../web/admin/metadata/field-edit.html | 2 +- .../resources/web/admin/metadata/fields.html | 2 +- src/main/resources/web/assets/css/rb-page.css | 14 +++++----- .../resources/web/assets/css/triggers.css | 2 +- .../web/assets/js/metadata/entity-new.js | 4 ++- .../web/assets/js/metadata/field-formula.js | 26 ++++++++++++------- .../web/assets/js/metadata/field-new.js | 3 +-- src/main/resources/web/assets/js/rb-forms.js | 21 ++++++++------- .../resources/web/assets/js/user-settings.js | 12 ++++----- 30 files changed, 180 insertions(+), 118 deletions(-) diff --git a/@rbv b/@rbv index 277f6eb15..20c457c31 160000 --- a/@rbv +++ b/@rbv @@ -1 +1 @@ -Subproject commit 277f6eb150627c53654dd02238870b7e138c2f53 +Subproject commit 20c457c31c7c569bc5590d495447e62f8a1b6cb8 diff --git a/pom.xml b/pom.xml index 8452ded17..794c15562 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.rebuild rebuild - 2.9.2 + 2.9.3 rebuild Building your business-systems freely! diff --git a/src/main/java/com/rebuild/core/Application.java b/src/main/java/com/rebuild/core/Application.java index 93c842d1b..41a601e95 100644 --- a/src/main/java/com/rebuild/core/Application.java +++ b/src/main/java/com/rebuild/core/Application.java @@ -65,11 +65,11 @@ public class Application implements ApplicationListener /** * Rebuild Version */ - public static final String VER = "2.9.2"; + public static final String VER = "2.9.3"; /** * Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2} */ - public static final int BUILD = 2090209; + public static final int BUILD = 2090210; static { // Driver for DB diff --git a/src/main/java/com/rebuild/core/configuration/general/FormBuilderContextHolder.java b/src/main/java/com/rebuild/core/configuration/general/FormBuilderContextHolder.java index 36a5b4dcf..20b13e358 100644 --- a/src/main/java/com/rebuild/core/configuration/general/FormBuilderContextHolder.java +++ b/src/main/java/com/rebuild/core/configuration/general/FormBuilderContextHolder.java @@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.core.configuration.general; import cn.devezhao.persist4j.engine.ID; +import org.springframework.core.NamedThreadLocal; /** * 主/明细实体权限处理。创建明细实体必须指定主实体,以便验证权限 @@ -17,17 +18,22 @@ import cn.devezhao.persist4j.engine.ID; */ public class FormBuilderContextHolder { - private static final ThreadLocal MAINID_OF_DETAIL = new ThreadLocal<>(); + private static final ThreadLocal MAINID_OF_DETAIL = new NamedThreadLocal<>("MainId from details"); - public static void setMainIdOfDetail(ID mainId) { - MAINID_OF_DETAIL.set(mainId); + /** + * @param mainid + */ + public static void setMainIdOfDetail(ID mainid) { + MAINID_OF_DETAIL.set(mainid); } - public static ID getMainIdOfDetail() { - return MAINID_OF_DETAIL.get(); - } - - public static void clear() { - MAINID_OF_DETAIL.remove(); + /** + * @param once + * @return + */ + public static ID getMainIdOfDetail(boolean once) { + ID mainid = MAINID_OF_DETAIL.get(); + if (mainid != null && once) MAINID_OF_DETAIL.remove(); + return mainid; } } diff --git a/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java b/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java index 369ccbd42..eeb5b1e63 100644 --- a/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java +++ b/src/main/java/com/rebuild/core/configuration/general/FormsBuilder.java @@ -110,7 +110,7 @@ public class FormsBuilder extends FormsManager { // 新建 if (record == null) { if (hasMainEntity != null) { - ID mainid = FormBuilderContextHolder.getMainIdOfDetail(); + ID mainid = FormBuilderContextHolder.getMainIdOfDetail(false); Assert.notNull(mainid, "Call `FormBuilderContextHolder#setMainIdOfDetail` first!"); approvalState = EntityHelper.isUnsavedId(mainid) ? null : getHadApproval(hasMainEntity, mainid); @@ -237,7 +237,7 @@ public class FormsBuilder extends FormsManager { // 明细实体 - ID mainid = FormBuilderContextHolder.getMainIdOfDetail(); + ID mainid = FormBuilderContextHolder.getMainIdOfDetail(false); if (mainid == null) { Field dtmField = MetadataHelper.getDetailToMainField(entity); Object[] o = Application.getQueryFactory().uniqueNoFilter(recordId, dtmField.getName()); @@ -475,7 +475,7 @@ public class FormsBuilder extends FormsManager { * @param user4Desensitized 不传则不脱敏 * @return * @see FieldValueHelper#wrapFieldValue(Object, EasyField) - * @see com.rebuild.core.support.general.DataListWrapper#wrapFieldValue(Object, Field) + * @see com.rebuild.core.support.general.DataListWrapper#wrapFieldValue(Object, Field, String) */ public Object wrapFieldValue(Record data, EasyField field, ID user4Desensitized) { Object value = data.getObjectValue(field.getName()); 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 7c9214cd2..201cbca5b 100644 --- a/src/main/java/com/rebuild/core/service/dataimport/DataImporter.java +++ b/src/main/java/com/rebuild/core/service/dataimport/DataImporter.java @@ -37,7 +37,6 @@ import java.util.*; public class DataImporter extends HeavyTask { final private ImportRule rule; - private ID owningUser; final private List traceLogs = new ArrayList<>(); private String cellTraces = null; @@ -54,7 +53,7 @@ public class DataImporter extends HeavyTask { final List rows = new DataFileParser(rule.getSourceFile()).parse(); this.setTotal(rows.size() - 1); - owningUser = rule.getDefaultOwningUser() != null ? rule.getDefaultOwningUser() : getUser(); + final ID defaultOwning = rule.getDefaultOwningUser() != null ? rule.getDefaultOwningUser() : getUser(); GeneralEntityServiceContextHolder.setSkipSeriesValue(); for (final Cell[] row : rows) { @@ -69,7 +68,7 @@ public class DataImporter extends HeavyTask { } try { - Record record = checkoutRecord(row); + Record record = checkoutRecord(row, defaultOwning); if (record == null) { traceLogs.add(new Object[] { fc.getRowNo(), "SKIP" }); } else { @@ -98,11 +97,13 @@ public class DataImporter extends HeavyTask { } /** + * * @param row + * @param defaultOwning * @return */ - protected Record checkoutRecord(Cell[] row) { - Record recordHub = EntityHelper.forNew(rule.getToEntity().getEntityCode(), this.owningUser); + protected Record checkoutRecord(Cell[] row, ID defaultOwning) { + Record recordHub = EntityHelper.forNew(rule.getToEntity().getEntityCode(), defaultOwning); // 解析数据 RecordCheckout recordCheckout = new RecordCheckout(rule.getFiledsMapping()); @@ -124,7 +125,7 @@ public class DataImporter extends HeavyTask { if (repeat != null && rule.getRepeatOpt() == ImportRule.REPEAT_OPT_UPDATE) { // 更新 - checkout = EntityHelper.forUpdate(repeat, this.owningUser); + checkout = EntityHelper.forUpdate(repeat, defaultOwning); for (Iterator iter = recordHub.getAvailableFieldIterator(); iter.hasNext(); ) { String field = iter.next(); if (MetadataHelper.isCommonsField(field)) continue; 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 8039b293e..8d4623c10 100644 --- a/src/main/java/com/rebuild/core/service/dataimport/RecordCheckout.java +++ b/src/main/java/com/rebuild/core/service/dataimport/RecordCheckout.java @@ -27,6 +27,7 @@ import com.rebuild.core.metadata.EntityHelper; import com.rebuild.core.metadata.MetadataSorter; import com.rebuild.core.metadata.easymeta.*; import com.rebuild.core.metadata.impl.MetadataModificationException; +import com.rebuild.core.privileges.bizz.User; import com.rebuild.core.support.i18n.Language; import com.rebuild.core.support.state.StateManager; import lombok.extern.slf4j.Slf4j; @@ -72,7 +73,20 @@ public class RecordCheckout { Object value = checkoutFieldValue(field, cellValue, true); if (value != null) { - record.setObjectValue(field.getName(), value); + if (field.getName().equalsIgnoreCase(EntityHelper.OwningUser)) { + User owning = Application.getUserStore().getUser((ID) value); + if (owning.getOwningDept() == null) { + putTraceLog(cellValue, Language.L(EasyMetaFactory.getDisplayType(field))); + } else { + // 用户部门联动 + record.setObjectValue(field.getName(), value); + record.setID(EntityHelper.OwningDept, (ID) owning.getOwningDept().getIdentity()); + } + + } else { + record.setObjectValue(field.getName(), value); + } + } else { putTraceLog(cellValue, Language.L(EasyMetaFactory.getDisplayType(field))); } @@ -182,7 +196,7 @@ public class RecordCheckout { final String val = cell.asString(); final Entity refEntity = field.getReferenceEntity(); - // 支持ID + // 支持 ID if (ID.isId(val) && ID.valueOf(val).getEntityCode().intValue() == refEntity.getEntityCode()) { ID checkId = ID.valueOf(val); Object exists = Application.getQueryFactory().uniqueNoFilter(checkId, refEntity.getPrimaryField().getName()); diff --git a/src/main/java/com/rebuild/core/service/general/GeneralEntityService.java b/src/main/java/com/rebuild/core/service/general/GeneralEntityService.java index b09e9e300..9164c0de3 100644 --- a/src/main/java/com/rebuild/core/service/general/GeneralEntityService.java +++ b/src/main/java/com/rebuild/core/service/general/GeneralEntityService.java @@ -274,12 +274,15 @@ public class GeneralEntityService extends ObservableService implements EntitySer final ID currentUser = UserContextHolder.getUser(); final String entityName = MetadataHelper.getEntityName(record); - // 如用户无更新权限,则降级为只读共享 - if ((rights & BizzPermission.UPDATE.getMask()) != 0) { - if (!Application.getPrivilegesManager().allowUpdate(to, record.getEntityCode()) /* 目标用户无基础更新权限 */ - || !Application.getPrivilegesManager().allow(currentUser, record, BizzPermission.UPDATE, true) /* 操作用户无记录更新权限 */) { - rights = BizzPermission.READ.getMask(); - log.warn("Downgrade share rights to READ(8) : {}", record); + boolean fromTriggerNoDowngrade = GeneralEntityServiceContextHolder.isFromTrigger(false); + if (!fromTriggerNoDowngrade) { + // 如用户无更新权限,则降级为只读共享 + if ((rights & BizzPermission.UPDATE.getMask()) != 0) { + if (!Application.getPrivilegesManager().allowUpdate(to, record.getEntityCode()) /* 目标用户无基础更新权限 */ + || !Application.getPrivilegesManager().allow(currentUser, record, BizzPermission.UPDATE, true) /* 操作用户无记录更新权限 */) { + rights = BizzPermission.READ.getMask(); + log.warn("Downgrade share rights to READ(8) : {}", record); + } } } @@ -311,10 +314,12 @@ public class GeneralEntityService extends ObservableService implements EntitySer log.debug("The record has been shared and has the same rights, ignore : {}", record); } - // 可以共享给自己 -// } else if (to.equals(Application.getRecordOwningCache().getOwningUser(record))) { -// log.debug("Share to the same user as the record, ignore : {}", record); } else { +// // 可以共享给自己 +// if (to.equals(Application.getRecordOwningCache().getOwningUser(record))) { +// log.debug("Share to the same user as the record, ignore : {}", record); +// } + delegateService.create(sharedAfter); affected = 1; shareChange = true; @@ -391,7 +396,7 @@ public class GeneralEntityService extends ObservableService implements EntitySer return Collections.emptyMap(); } - final boolean fromTriggerNoFilter = GeneralEntityServiceContextHolder.isFromTriggersOnce(); + final boolean fromTriggerNoFilter = GeneralEntityServiceContextHolder.isFromTrigger(false); Map> entityRecordsMap = new HashMap<>(); Entity mainEntity = MetadataHelper.getEntity(recordMain.getEntityCode()); diff --git a/src/main/java/com/rebuild/core/service/general/GeneralEntityServiceContextHolder.java b/src/main/java/com/rebuild/core/service/general/GeneralEntityServiceContextHolder.java index 539b79e34..25f3aeed8 100644 --- a/src/main/java/com/rebuild/core/service/general/GeneralEntityServiceContextHolder.java +++ b/src/main/java/com/rebuild/core/service/general/GeneralEntityServiceContextHolder.java @@ -66,17 +66,17 @@ public class GeneralEntityServiceContextHolder { * * @param recordId */ - public static void setFromTriggers(ID recordId) { + public static void setFromTrigger(ID recordId) { FROM_TRIGGERS.set(recordId); } /** * @return - * @see #setFromTriggers(ID) + * @see #setFromTrigger(ID) */ - public static boolean isFromTriggersOnce() { + public static boolean isFromTrigger(boolean once) { ID recordId = FROM_TRIGGERS.get(); - if (recordId != null) FROM_TRIGGERS.remove(); + if (recordId != null && once) FROM_TRIGGERS.remove(); return recordId != null; } diff --git a/src/main/java/com/rebuild/core/service/general/transform/RecordTransfomer.java b/src/main/java/com/rebuild/core/service/general/transform/RecordTransfomer.java index 4cadd8786..184b70966 100644 --- a/src/main/java/com/rebuild/core/service/general/transform/RecordTransfomer.java +++ b/src/main/java/com/rebuild/core/service/general/transform/RecordTransfomer.java @@ -147,7 +147,7 @@ public class RecordTransfomer extends SetUser { int fillbackMode = transConfig.getIntValue("fillbackMode"); // 仅更新,无业务规则 - if (fillbackMode == 3) { + if (fillbackMode == 3 || fillbackMode == 0) { Application.getCommonsService().update(updateSource, false); } // 忽略审批状态(进行中)强制更新 diff --git a/src/main/java/com/rebuild/core/service/trigger/impl/AggregationEvaluator.java b/src/main/java/com/rebuild/core/service/trigger/impl/AggregationEvaluator.java index 699a8603a..472dca4d4 100644 --- a/src/main/java/com/rebuild/core/service/trigger/impl/AggregationEvaluator.java +++ b/src/main/java/com/rebuild/core/service/trigger/impl/AggregationEvaluator.java @@ -8,6 +8,8 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.core.service.trigger.impl; import cn.devezhao.persist4j.Entity; +import cn.devezhao.persist4j.Field; +import cn.devezhao.persist4j.dialect.FieldType; import cn.devezhao.persist4j.metadata.MissingMetaExcetion; import com.alibaba.fastjson.JSONObject; import com.rebuild.core.Application; @@ -80,12 +82,20 @@ public class AggregationEvaluator { Set matchsVars = ContentWithFieldVars.matchsVars(formula); List fields = new ArrayList<>(); + Set nonNumericFields = new HashSet<>(); for (String m : matchsVars) { String[] fieldAndFunc = m.split(MetadataHelper.SPLITER_RE); - if (MetadataHelper.getLastJoinField(sourceEntity, fieldAndFunc[0]) == null) { + Field field; + if ((field = MetadataHelper.getLastJoinField(sourceEntity, fieldAndFunc[0])) == null) { throw new MissingMetaExcetion(fieldAndFunc[0], sourceEntity.getName()); } fields.add(fieldAndFunc); + + // 数字型 + if (fieldAndFunc.length > 1 || field.getType() == FieldType.LONG || field.getType() == FieldType.DECIMAL); + else { + nonNumericFields.add("nn:" + fieldAndFunc[0]); + } } if (fields.isEmpty()) { log.warn("No fields found in formula : {}", formula); @@ -134,8 +144,9 @@ public class AggregationEvaluator { } else { continue; } - - Object value = useSourceData[i] == null ? 0 : useSourceData[i]; + + Object value = useSourceData[i]; + if (value == null) value = nonNumericFields.contains("nn:" + field[0]) ? "" : 0; envMap.put(fieldKey, value); } diff --git a/src/main/java/com/rebuild/core/service/trigger/impl/AutoAssign.java b/src/main/java/com/rebuild/core/service/trigger/impl/AutoAssign.java index db37f91ff..c39188646 100644 --- a/src/main/java/com/rebuild/core/service/trigger/impl/AutoAssign.java +++ b/src/main/java/com/rebuild/core/service/trigger/impl/AutoAssign.java @@ -98,7 +98,7 @@ public class AutoAssign extends TriggerAction { } PrivilegesGuardContextHolder.setSkipGuard(recordId); - GeneralEntityServiceContextHolder.setFromTriggers(recordId); + GeneralEntityServiceContextHolder.setFromTrigger(recordId); try { Application.getEntityService(actionContext.getSourceEntity().getEntityCode()) @@ -111,7 +111,7 @@ public class AutoAssign extends TriggerAction { } finally { PrivilegesGuardContextHolder.getSkipGuardOnce(); - GeneralEntityServiceContextHolder.isFromTriggersOnce(); + GeneralEntityServiceContextHolder.isFromTrigger(true); } } } diff --git a/src/main/java/com/rebuild/core/service/trigger/impl/AutoShare.java b/src/main/java/com/rebuild/core/service/trigger/impl/AutoShare.java index 164b47190..d4f7d1115 100644 --- a/src/main/java/com/rebuild/core/service/trigger/impl/AutoShare.java +++ b/src/main/java/com/rebuild/core/service/trigger/impl/AutoShare.java @@ -66,7 +66,7 @@ public class AutoShare extends AutoAssign { final EntityService es = Application.getEntityService(actionContext.getSourceEntity().getEntityCode()); for (ID toUser : toUsers) { PrivilegesGuardContextHolder.setSkipGuard(recordId); - GeneralEntityServiceContextHolder.setFromTriggers(recordId); + GeneralEntityServiceContextHolder.setFromTrigger(recordId); try { es.share(recordId, toUser, cascades, shareRights); diff --git a/src/main/java/com/rebuild/core/support/SystemDiagnosis.java b/src/main/java/com/rebuild/core/support/SystemDiagnosis.java index dedd56eaf..829b0d25e 100644 --- a/src/main/java/com/rebuild/core/support/SystemDiagnosis.java +++ b/src/main/java/com/rebuild/core/support/SystemDiagnosis.java @@ -32,7 +32,7 @@ public class SystemDiagnosis { public static final String DatabaseBackupFail = "DatabaseBackupFail"; public static final String DataFileBackupFail = "DataFileBackupFail"; - public static String _DENIEDMSG = null; + volatile public static String _DENIEDMSG = null; public void diagnose() { ServerStatus.getLastStatus(true); @@ -58,12 +58,12 @@ public class SystemDiagnosis { if (usersMsg == null) dangers.remove(UsersMsg); else dangers.put(UsersMsg, usersMsg); - // MULTIPLE RUNNING INSTANCES DETECTED! _DENIEDMSG = echoValidity.getString("deniedMsg"); } else { dangers.remove(AdminMsg); dangers.remove(UsersMsg); + _DENIEDMSG = null; } Application.getCommonsCache().putx(CKEY_DANGERS, dangers, CommonsCache.TS_DAY); diff --git a/src/main/java/com/rebuild/web/admin/metadata/FormDesignController.java b/src/main/java/com/rebuild/web/admin/metadata/FormDesignController.java index 335937a19..225a980c7 100644 --- a/src/main/java/com/rebuild/web/admin/metadata/FormDesignController.java +++ b/src/main/java/com/rebuild/web/admin/metadata/FormDesignController.java @@ -9,8 +9,8 @@ package com.rebuild.web.admin.metadata; import cn.devezhao.commons.web.ServletUtils; import cn.devezhao.persist4j.Entity; -import cn.devezhao.persist4j.Field; import cn.devezhao.persist4j.Record; +import cn.devezhao.persist4j.engine.ID; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; @@ -23,7 +23,6 @@ import com.rebuild.core.metadata.MetadataHelper; import com.rebuild.core.metadata.easymeta.EasyField; import com.rebuild.core.metadata.easymeta.EasyMetaFactory; import com.rebuild.core.privileges.UserHelper; -import com.rebuild.core.privileges.UserService; import com.rebuild.web.BaseController; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Controller; @@ -63,6 +62,7 @@ public class FormDesignController extends BaseController { @RequestMapping({"form-update"}) public void sets(@PathVariable String entity, HttpServletRequest request, HttpServletResponse response) { + final ID user = getRequestUser(request); JSON formJson = ServletUtils.getRequestJson(request); // 修改字段名称 @@ -88,13 +88,10 @@ public class FormDesignController extends BaseController { List willUpdate = new ArrayList<>(); Entity entityMeta = MetadataHelper.getEntity(entity); for (Map.Entry e : newLabels.entrySet()) { - Field fieldMeta = entityMeta.getField(e.getKey()); - EasyField fieldEasy = EasyMetaFactory.valueOf(fieldMeta); - if (fieldEasy.isBuiltin() || fieldEasy.getMetaId() == null) { - continue; - } + EasyField fieldEasy = EasyMetaFactory.valueOf(entityMeta.getField(e.getKey())); + if (fieldEasy.getMetaId() == null) continue; - Record fieldRecord = EntityHelper.forUpdate(fieldEasy.getMetaId(), UserService.SYSTEM_USER, false); + Record fieldRecord = EntityHelper.forUpdate(fieldEasy.getMetaId(), user, false); fieldRecord.setString("fieldLabel", e.getValue()); willUpdate.add(fieldRecord); } diff --git a/src/main/java/com/rebuild/web/commons/FileDownloader.java b/src/main/java/com/rebuild/web/commons/FileDownloader.java index 7631de3f4..12c709854 100644 --- a/src/main/java/com/rebuild/web/commons/FileDownloader.java +++ b/src/main/java/com/rebuild/web/commons/FileDownloader.java @@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.web.commons; import cn.devezhao.commons.CodecUtils; +import cn.devezhao.commons.ObjectUtils; import cn.devezhao.commons.web.ServletUtils; import cn.devezhao.persist4j.engine.ID; import com.rebuild.api.user.AuthTokenManager; @@ -35,8 +36,12 @@ import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; -import java.io.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; /** * 文件下载/查看 @@ -100,8 +105,8 @@ public class FileDownloader extends BaseController { BufferedImage bi = ImageIO.read(img); if (bi == null) { - log.debug("None image type : {}", filePath); - writeStream(new FileInputStream(img), response); + log.debug("Unsupport image type : {}", filePath); + writeStream(Files.newInputStream(img.toPath()), response); return; } @@ -146,10 +151,10 @@ public class FileDownloader extends BaseController { private int parseWidth(String imageView2) { if (!imageView2.contains("/w/")) { return 1000; + } else { + String w = imageView2.split("/w/")[1].split("/")[0]; + return ObjectUtils.toInt(w, 1000); } - - String w = imageView2.split("/w/")[1].split("/")[0]; - return Integer.parseInt(w); } @GetMapping(value = {"download/**", "access/**"}) @@ -240,7 +245,7 @@ public class FileDownloader extends BaseController { long size = FileUtils.sizeOf(file); response.setHeader("Content-Length", String.valueOf(size)); - try (InputStream fis = new FileInputStream(file)) { + try (InputStream fis = Files.newInputStream(file.toPath())) { return writeStream(fis, response); } } @@ -319,4 +324,5 @@ public class FileDownloader extends BaseController { if (attname != null) url += "&attname=" + CodecUtils.urlEncode(attname); resp.sendRedirect(AppUtils.getContextPath(url)); } + } diff --git a/src/main/java/com/rebuild/web/general/GeneralModelController.java b/src/main/java/com/rebuild/web/general/GeneralModelController.java index dab2b50be..87b623144 100644 --- a/src/main/java/com/rebuild/web/general/GeneralModelController.java +++ b/src/main/java/com/rebuild/web/general/GeneralModelController.java @@ -131,7 +131,7 @@ public class GeneralModelController extends EntityController { return model; } finally { - FormBuilderContextHolder.clear(); + FormBuilderContextHolder.getMainIdOfDetail(true); } } diff --git a/src/main/java/com/rebuild/web/user/UserAvatar.java b/src/main/java/com/rebuild/web/user/UserAvatar.java index 5cfd6f94e..027361015 100644 --- a/src/main/java/com/rebuild/web/user/UserAvatar.java +++ b/src/main/java/com/rebuild/web/user/UserAvatar.java @@ -45,6 +45,8 @@ import java.io.IOException; @RequestMapping("/account") public class UserAvatar extends BaseController { + public static final String SK_DAVATAR = "davatarTime"; + @GetMapping("/user-avatar") public void renderAvatat(HttpServletRequest request, HttpServletResponse response) throws IOException { renderUserAvatar(getRequestUser(request), request, response); @@ -137,7 +139,7 @@ public class UserAvatar extends BaseController { record.setString("avatarUrl", uploadName); Application.getBean(UserService.class).update(record); - ServletUtils.setSessionAttribute(request, "davatarTime", System.currentTimeMillis()); + ServletUtils.setSessionAttribute(request, SK_DAVATAR, System.currentTimeMillis()); return RespBody.ok(uploadName); } diff --git a/src/main/java/com/rebuild/web/user/UserSettingsController.java b/src/main/java/com/rebuild/web/user/UserSettingsController.java index 83eeaa6b8..98afe55c4 100644 --- a/src/main/java/com/rebuild/web/user/UserSettingsController.java +++ b/src/main/java/com/rebuild/web/user/UserSettingsController.java @@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information. package com.rebuild.web.user; import cn.devezhao.commons.EncryptUtils; +import cn.devezhao.commons.web.ServletUtils; import cn.devezhao.persist4j.Record; import cn.devezhao.persist4j.engine.ID; import com.alibaba.fastjson.JSONObject; @@ -113,15 +114,15 @@ public class UserSettingsController extends EntityController { return RespBody.ok(); } - @RequestMapping("/user/save-passwd") + @PostMapping("/user/save-passwd") public RespBody savePasswd(HttpServletRequest request) { final ID user = getRequestUser(request); - String oldp = getParameterNotNull(request, "oldp"); - String newp = getParameterNotNull(request, "newp"); - Object[] o = Application.createQuery("select password from User where userId = ?") - .setParameter(1, user) - .unique(); + JSONObject p = (JSONObject) ServletUtils.getRequestJson(request); + String oldp = p.getString("oldp"); + String newp = p.getString("newp"); + + Object[] o = Application.getQueryFactory().uniqueNoFilter(user, "password"); if (o == null || !StringUtils.equals((String) o[0], EncryptUtils.toSHA256Hex(oldp))) { return RespBody.errorl("原密码输入有误"); } diff --git a/src/main/java/com/rebuild/web/user/signup/LoginController.java b/src/main/java/com/rebuild/web/user/signup/LoginController.java index a7235c304..0c0d69878 100644 --- a/src/main/java/com/rebuild/web/user/signup/LoginController.java +++ b/src/main/java/com/rebuild/web/user/signup/LoginController.java @@ -30,6 +30,7 @@ import com.rebuild.core.support.i18n.Language; import com.rebuild.core.support.integration.SMSender; import com.rebuild.utils.AES; import com.rebuild.utils.AppUtils; +import com.rebuild.web.user.UserAvatar; import com.wf.captcha.utils.CaptchaUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; @@ -157,9 +158,13 @@ public class LoginController extends LoginAction { public RespBody userLogin(HttpServletRequest request, HttpServletResponse response) { String vcode = getParameter(request, "vcode"); Boolean needVcode = (Boolean) ServletUtils.getSessionAttribute(request, SK_NEED_VCODE); - if (needVcode != null && needVcode - && (StringUtils.isBlank(vcode) || !CaptchaUtil.ver(vcode, request))) { - return RespBody.errorl("验证码错误"); + if ((needVcode != null && needVcode) || StringUtils.isNotBlank(vcode)) { + if (StringUtils.isBlank(vcode)) { + ServletUtils.setSessionAttribute(request, SK_NEED_VCODE, true); + return RespBody.error("VCODE"); + } else if (!CaptchaUtil.ver(vcode, request)) { + return RespBody.errorl("验证码错误"); + } } final String user = getParameterNotNull(request, "user"); @@ -176,11 +181,14 @@ public class LoginController extends LoginAction { return RespBody.error(hasError); } - // 清理 + // 清理验证码 getLoginRetryTimes(user, -1); ServletUtils.setSessionAttribute(request, SK_NEED_VCODE, null); + // 头像缓存 + ServletUtils.setSessionAttribute(request, UserAvatar.SK_DAVATAR, System.currentTimeMillis()); final User loginUser = Application.getUserStore().getUser(user); + final boolean isMobile = AppUtils.isRbMobile(request); Map resMap = new HashMap<>(); @@ -193,14 +201,14 @@ public class LoginController extends LoginAction { Application.getCommonsCache().putx("2FA" + userToken, loginUser.getId(), CommonsCache.TS_HOUR / 4); // 15m resMap.put("login2FaUserToken", userToken); - if (AppUtils.isRbMobile(request)) { + if (isMobile) { request.getSession().invalidate(); } return RespBody.ok(resMap); } - if (AppUtils.isRbMobile(request)) { + if (isMobile) { resMap = loginSuccessedH5(request, response, loginUser.getId()); } else { Integer ed = loginSuccessed( diff --git a/src/main/resources/web/admin/metadata/entities.html b/src/main/resources/web/admin/metadata/entities.html index de986e195..b237bd55a 100644 --- a/src/main/resources/web/admin/metadata/entities.html +++ b/src/main/resources/web/admin/metadata/entities.html @@ -24,12 +24,13 @@ font-size: 32px; color: #4285f4; } - .card.entity .badge { + .card.entity i.badge { position: absolute; top: 11px; right: 11px; - font-size: 11px; text-transform: uppercase; + font-style: normal; + padding-bottom: 0; } .card.entity span { margin-top: 2px; @@ -156,8 +157,8 @@ $t.find('.icon').addClass(`zmdi-${item.icon}`) $t.find('span').text(item.entityLabel) $t.find('p').text(item.comments || '-') - if (item.builtin) $(`${$L('内置')}`).appendTo($t.find('a.card')) - if (!!item.detailEntity) $(`${$L('明细')}`).appendTo($t.find('a.card')) + if (item.builtin) $(`${$L('内置')}`).appendTo($t.find('a.card')) + if (!!item.detailEntity) $(`${$L('明细')}`).appendTo($t.find('a.card')) return $t } diff --git a/src/main/resources/web/admin/metadata/field-edit.html b/src/main/resources/web/admin/metadata/field-edit.html index f7856677a..e5692368a 100644 --- a/src/main/resources/web/admin/metadata/field-edit.html +++ b/src/main/resources/web/admin/metadata/field-edit.html @@ -349,7 +349,7 @@