mirror of
https://github.com/getrebuild/rebuild.git
synced 2024-09-20 07:25:54 +08:00
Fix 3.7 beta3 (#773)
* beta3 * fix: timezone * fix: CreateTask * Update approval-design.js * fix: getNetworkDate * feat: GeneralTriggerAction * be * fix ntext-action * Update @rbv * search classification useSimple37 * PickListDataController * user filters
This commit is contained in:
parent
6bbae5fd17
commit
423ed96126
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
||||||
Subproject commit e8fd1ab442671e30786486004933d0f31b903086
|
Subproject commit 036ee5c7436fe11eba8f8717e25414d82a017941
|
|
@ -6,7 +6,7 @@ EXPOSE 18080
|
||||||
|
|
||||||
COPY ./target/rebuild.jar /app/rebuild/rebuild-boot.jar
|
COPY ./target/rebuild.jar /app/rebuild/rebuild-boot.jar
|
||||||
|
|
||||||
#COPY ./.deploy/SourceHanSansK-Regular.ttf /app/rebuild/
|
#COPY ./.deploy/SourceHanSansK-Regular.ttf /app/rebuild/.rebuild/
|
||||||
|
|
||||||
WORKDIR /app/rebuild/
|
WORKDIR /app/rebuild/
|
||||||
|
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -10,7 +10,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.rebuild</groupId>
|
<groupId>com.rebuild</groupId>
|
||||||
<artifactId>rebuild</artifactId>
|
<artifactId>rebuild</artifactId>
|
||||||
<version>3.7.0-beta2</version>
|
<version>3.7.0-beta3</version>
|
||||||
<name>rebuild</name>
|
<name>rebuild</name>
|
||||||
<description>Building your business-systems freely!</description>
|
<description>Building your business-systems freely!</description>
|
||||||
<url>https://getrebuild.com/</url>
|
<url>https://getrebuild.com/</url>
|
||||||
|
|
|
@ -75,11 +75,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
||||||
/**
|
/**
|
||||||
* Rebuild Version
|
* Rebuild Version
|
||||||
*/
|
*/
|
||||||
public static final String VER = "3.7.0-beta2";
|
public static final String VER = "3.7.0-beta3";
|
||||||
/**
|
/**
|
||||||
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
|
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
|
||||||
*/
|
*/
|
||||||
public static final int BUILD = 3070002;
|
public static final int BUILD = 3070003;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// Driver for DB
|
// Driver for DB
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class UserImporter extends HeavyTask<Integer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("Cannot create new user : " + loginName, ex);
|
log.error("Cannot create new user : {}", loginName, ex);
|
||||||
} finally {
|
} finally {
|
||||||
this.addCompleted();
|
this.addCompleted();
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,9 +142,10 @@ public abstract class ObservableService extends SafeObservable implements Servic
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取原始用户
|
* 获取原始调用用户
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
|
* @see UserContextHolder#replaceUser(ID)
|
||||||
*/
|
*/
|
||||||
protected ID getCurrentUser() {
|
protected ID getCurrentUser() {
|
||||||
return UserContextHolder.getReplacedUser();
|
return UserContextHolder.getReplacedUser();
|
||||||
|
|
|
@ -9,8 +9,10 @@ package com.rebuild.core.service.project;
|
||||||
|
|
||||||
import cn.devezhao.persist4j.PersistManagerFactory;
|
import cn.devezhao.persist4j.PersistManagerFactory;
|
||||||
import cn.devezhao.persist4j.engine.ID;
|
import cn.devezhao.persist4j.engine.ID;
|
||||||
|
import com.rebuild.core.UserContextHolder;
|
||||||
import com.rebuild.core.configuration.ConfigBean;
|
import com.rebuild.core.configuration.ConfigBean;
|
||||||
import com.rebuild.core.metadata.EntityHelper;
|
import com.rebuild.core.metadata.EntityHelper;
|
||||||
|
import com.rebuild.core.privileges.UserService;
|
||||||
import com.rebuild.core.service.DataSpecificationException;
|
import com.rebuild.core.service.DataSpecificationException;
|
||||||
import com.rebuild.core.service.general.ObservableService;
|
import com.rebuild.core.service.general.ObservableService;
|
||||||
import com.rebuild.core.support.i18n.Language;
|
import com.rebuild.core.support.i18n.Language;
|
||||||
|
@ -43,7 +45,8 @@ public abstract class BaseTaskService extends ObservableService {
|
||||||
? ProjectManager.instance.getProjectByX(taskOrProject, null)
|
? ProjectManager.instance.getProjectByX(taskOrProject, null)
|
||||||
: ProjectManager.instance.getProject(taskOrProject, null);
|
: ProjectManager.instance.getProject(taskOrProject, null);
|
||||||
|
|
||||||
if (c == null || !c.get("members", Set.class).contains(user)) {
|
if (c == null ||
|
||||||
|
!(c.get("members", Set.class).contains(user) || UserService.SYSTEM_USER.equals(user))) {
|
||||||
throw new DataSpecificationException(Language.L("非项目成员禁止操作"));
|
throw new DataSpecificationException(Language.L("非项目成员禁止操作"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,4 +56,10 @@ public abstract class BaseTaskService extends ObservableService {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ID getCurrentUser() {
|
||||||
|
// 注意父级的方法含义
|
||||||
|
return UserContextHolder.getUser();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,10 @@ public class RobotTriggerManager implements ConfigManager {
|
||||||
recordId, StringUtils.join(TRIGGERS_CHAIN_4DEBUG.get(), "\n > "));
|
recordId, StringUtils.join(TRIGGERS_CHAIN_4DEBUG.get(), "\n > "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ActionContext ctx = new ActionContext(recordId, entity,
|
||||||
|
// JSONUtils.EMPTY_OBJECT, EntityHelper.newUnsavedId(EntityHelper.RobotTriggerConfig));
|
||||||
|
// actions.add(new GeneralTriggerAction(ctx));
|
||||||
|
|
||||||
return actions.toArray(new TriggerAction[0]);
|
return actions.toArray(new TriggerAction[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
|
|
||||||
package com.rebuild.core.support;
|
package com.rebuild.core.support;
|
||||||
|
|
||||||
|
import cn.devezhao.commons.CalendarUtils;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.rebuild.utils.OkHttpUtils;
|
import com.rebuild.utils.OkHttpUtils;
|
||||||
|
@ -18,6 +19,7 @@ import okhttp3.Request;
|
||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -36,22 +38,31 @@ public class SysbaseSupport {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public String submit() {
|
public String submit() {
|
||||||
StringBuilder logConf = new StringBuilder("RebuildConfiguration :\n----------\n");
|
StringBuilder confLog = new StringBuilder("RebuildConfiguration :\n----------\n");
|
||||||
for (ConfigurationItem item : ConfigurationItem.values()) {
|
for (ConfigurationItem item : ConfigurationItem.values()) {
|
||||||
String v = RebuildConfiguration.get(item);
|
String v = RebuildConfiguration.get(item);
|
||||||
logConf.append(StringUtils.rightPad(item.name(), 31)).append(" : ").append(v == null ? "" : v).append("\n");
|
confLog.append(StringUtils.rightPad(item.name(), 31)).append(" : ").append(v == null ? "" : v).append("\n");
|
||||||
}
|
}
|
||||||
log.warn(logConf.append("----------").toString());
|
log.warn(confLog.append("----------").toString());
|
||||||
|
|
||||||
|
StringBuilder osLog = new StringBuilder("OS/VM Info :\n----------\n");
|
||||||
|
osLog.append(StringUtils.rightPad("OS", 31)).append(" : ").append(SystemUtils.OS_NAME).append("/").append(SystemUtils.OS_VERSION).append("\n");
|
||||||
|
osLog.append(StringUtils.rightPad("VM", 31)).append(" : ").append(SystemUtils.JAVA_VM_NAME).append("/").append(SystemUtils.JAVA_VERSION).append(SystemUtils.OS_VERSION).append("\n");
|
||||||
|
osLog.append(StringUtils.rightPad("TimeZone", 31)).append(" : ").append(CalendarUtils.DEFAULT_TIME_ZONE).append("\n");
|
||||||
|
osLog.append(StringUtils.rightPad("Date", 31)).append(" : ").append(CalendarUtils.now()).append("\n");
|
||||||
|
osLog.append(StringUtils.rightPad("Headless", 31)).append(" : ").append(SystemUtils.isJavaAwtHeadless()).append("\n");
|
||||||
|
|
||||||
|
log.warn(osLog.append("----------").toString());
|
||||||
|
|
||||||
File logFile = SysbaseHeartbeat.getLogbackFile();
|
File logFile = SysbaseHeartbeat.getLogbackFile();
|
||||||
|
|
||||||
JSONObject resJson;
|
JSONObject resJson;
|
||||||
try {
|
try {
|
||||||
String res = upload(logFile, "https://getrebuild.com/api/misc/request-support");
|
String res = upload(logFile, "https://getrebuild.com/api/misc/request-support");
|
||||||
log.info("Upload support-file : {}", res);
|
log.info("Upload file of support : {}", res);
|
||||||
resJson = (JSONObject) JSON.parse(res);
|
resJson = (JSONObject) JSON.parse(res);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("Upload support-file failed", e);
|
log.error("Upload file of support fails", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import java.net.URLConnection;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -129,8 +130,13 @@ public class OshiUtils {
|
||||||
for (String u : FROMURLS) {
|
for (String u : FROMURLS) {
|
||||||
try {
|
try {
|
||||||
URLConnection conn = new URL(u).openConnection();
|
URLConnection conn = new URL(u).openConnection();
|
||||||
long l = conn.getDate();
|
final long L = conn.getDate();
|
||||||
return new Date(l);
|
|
||||||
|
if (L > 0) {
|
||||||
|
Calendar c = CalendarUtils.getInstance();
|
||||||
|
c.setTimeInMillis(L);
|
||||||
|
return c.getTime();
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.warn("Cannot fetch date from : {}", u, ex);
|
log.warn("Cannot fetch date from : {}", u, ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
package com.rebuild.web.admin.bizz;
|
package com.rebuild.web.admin.bizz;
|
||||||
|
|
||||||
import cn.devezhao.persist4j.engine.ID;
|
import cn.devezhao.persist4j.engine.ID;
|
||||||
|
import com.rebuild.core.support.integration.SMSender;
|
||||||
import com.rebuild.web.EntityController;
|
import com.rebuild.web.EntityController;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
@ -32,6 +33,7 @@ public class BizzPageView extends EntityController {
|
||||||
ModelAndView mv = createModelAndView(
|
ModelAndView mv = createModelAndView(
|
||||||
"/admin/bizuser/user-view", "User", getRequestUser(request));
|
"/admin/bizuser/user-view", "User", getRequestUser(request));
|
||||||
mv.getModel().put("id", id);
|
mv.getModel().put("id", id);
|
||||||
|
mv.getModel().put("serviceMail", SMSender.availableMail());
|
||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
package com.rebuild.web.commons;
|
package com.rebuild.web.commons;
|
||||||
|
|
||||||
import cn.devezhao.commons.CodecUtils;
|
import cn.devezhao.commons.CodecUtils;
|
||||||
|
import cn.devezhao.commons.identifier.ComputerIdentifier;
|
||||||
import cn.devezhao.commons.web.ServletUtils;
|
import cn.devezhao.commons.web.ServletUtils;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.rebuild.core.Application;
|
import com.rebuild.core.Application;
|
||||||
|
@ -70,7 +71,7 @@ public class ErrorPageView extends BaseController {
|
||||||
mv.getModel().put("MemoryUsageJvm", OshiUtils.getJvmMemoryUsed());
|
mv.getModel().put("MemoryUsageJvm", OshiUtils.getJvmMemoryUsed());
|
||||||
mv.getModel().put("SystemLoad", OshiUtils.getSystemLoad());
|
mv.getModel().put("SystemLoad", OshiUtils.getSystemLoad());
|
||||||
mv.getModelMap().put("isAdminVerified", AppUtils.isAdminVerified(request));
|
mv.getModelMap().put("isAdminVerified", AppUtils.isAdminVerified(request));
|
||||||
mv.getModelMap().put("SN", License.SN() + "/" + OshiUtils.getLocalIp() + "/" + ServerStatus.STARTUP_ONCE);
|
mv.getModelMap().put("SN", License.SN() + "/" + ComputerIdentifier.generateIdentifierKey() + "/" + OshiUtils.getLocalIp() + "/" + ServerStatus.STARTUP_ONCE);
|
||||||
|
|
||||||
final String specDisks = request.getParameter("disks");
|
final String specDisks = request.getParameter("disks");
|
||||||
if (specDisks != null) {
|
if (specDisks != null) {
|
||||||
|
|
|
@ -27,6 +27,7 @@ import com.rebuild.core.service.query.AdvFilterParser;
|
||||||
import com.rebuild.core.support.general.FieldValueHelper;
|
import com.rebuild.core.support.general.FieldValueHelper;
|
||||||
import com.rebuild.core.support.i18n.I18nUtils;
|
import com.rebuild.core.support.i18n.I18nUtils;
|
||||||
import com.rebuild.core.support.i18n.Language;
|
import com.rebuild.core.support.i18n.Language;
|
||||||
|
import com.rebuild.core.support.integration.SMSender;
|
||||||
import com.rebuild.utils.JSONUtils;
|
import com.rebuild.utils.JSONUtils;
|
||||||
import com.rebuild.web.BaseController;
|
import com.rebuild.web.BaseController;
|
||||||
import com.rebuild.web.IdParam;
|
import com.rebuild.web.IdParam;
|
||||||
|
@ -61,11 +62,8 @@ public class FeedsListController extends BaseController {
|
||||||
public ModelAndView pageIndex(@PathVariable String type, HttpServletRequest request) {
|
public ModelAndView pageIndex(@PathVariable String type, HttpServletRequest request) {
|
||||||
ModelAndView mv = createModelAndView("/feeds/home");
|
ModelAndView mv = createModelAndView("/feeds/home");
|
||||||
mv.getModel().put("feedsType", type);
|
mv.getModel().put("feedsType", type);
|
||||||
|
mv.getModel().put("serviceMail", SMSender.availableMail());
|
||||||
User user = Application.getUserStore().getUser(getRequestUser(request));
|
mv.getModel().put("serviceSms", SMSender.availableSMS());
|
||||||
mv.getModel().put("UserEmail", user.getEmail());
|
|
||||||
mv.getModel().put("UserMobile", StringUtils.defaultIfBlank(user.getWorkphone(), ""));
|
|
||||||
|
|
||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,13 +35,13 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/commons/metadata/")
|
@RequestMapping("/commons/metadata/")
|
||||||
public class PicklistDataController extends BaseController {
|
public class PickListDataController extends BaseController {
|
||||||
|
|
||||||
// for PickList/MultiSelect/State
|
// for PickList/MultiSelect/State
|
||||||
@GetMapping({"picklist", "field-options"})
|
@GetMapping({"picklist", "field-options"})
|
||||||
public JSON fetchOptions(HttpServletRequest request) {
|
public JSON fetchOptions(HttpServletRequest request) {
|
||||||
String entity = getParameterNotNull(request, "entity");
|
final String entity = getParameterNotNull(request, "entity");
|
||||||
String field = getParameterNotNull(request, "field");
|
final String field = getParameterNotNull(request, "field");
|
||||||
|
|
||||||
Field fieldMeta = getRealField(entity, field);
|
Field fieldMeta = getRealField(entity, field);
|
||||||
DisplayType dt = EasyMetaFactory.getDisplayType(fieldMeta);
|
DisplayType dt = EasyMetaFactory.getDisplayType(fieldMeta);
|
|
@ -171,7 +171,7 @@ public class ReferenceSearchController extends EntityController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搜索分类字段
|
* 搜索分类字段
|
||||||
* @see PicklistDataController#fetchClassification(HttpServletRequest)
|
* @see PickListDataController#fetchClassification(HttpServletRequest)
|
||||||
*/
|
*/
|
||||||
@GetMapping("classification")
|
@GetMapping("classification")
|
||||||
public JSON searchClassification(@EntityParam Entity entity, HttpServletRequest request) {
|
public JSON searchClassification(@EntityParam Entity entity, HttpServletRequest request) {
|
||||||
|
@ -183,9 +183,12 @@ public class ReferenceSearchController extends EntityController {
|
||||||
if (useClassification == null) return JSONUtils.EMPTY_ARRAY;
|
if (useClassification == null) return JSONUtils.EMPTY_ARRAY;
|
||||||
|
|
||||||
String q = StringUtils.trim(getParameter(request, "q"));
|
String q = StringUtils.trim(getParameter(request, "q"));
|
||||||
|
int openLevel = ClassificationManager.instance.getOpenLevel(fieldMeta);
|
||||||
|
// 直接显示
|
||||||
|
boolean useSimple37 = StringUtils.isBlank(q) && openLevel == 0;
|
||||||
|
|
||||||
// 为空则加载最近使用的
|
// 为空则加载最近使用的
|
||||||
if (StringUtils.isBlank(q)) {
|
if (StringUtils.isBlank(q) && !useSimple37) {
|
||||||
String type = "d" + useClassification + ":" + ClassificationManager.instance.getOpenLevel(fieldMeta);
|
String type = "d" + useClassification + ":" + ClassificationManager.instance.getOpenLevel(fieldMeta);
|
||||||
ID[] used = RecentlyUsedHelper.gets(user, "ClassificationData", type);
|
ID[] used = RecentlyUsedHelper.gets(user, "ClassificationData", type);
|
||||||
|
|
||||||
|
@ -196,14 +199,19 @@ public class ReferenceSearchController extends EntityController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String sqlWhere;
|
||||||
|
if (useSimple37) {
|
||||||
|
sqlWhere = String.format("dataId = '%s' and parent is null order by code,fullName",
|
||||||
|
useClassification.toLiteral());
|
||||||
|
} else {
|
||||||
q = CommonsUtils.escapeSql(q);
|
q = CommonsUtils.escapeSql(q);
|
||||||
int openLevel = ClassificationManager.instance.getOpenLevel(fieldMeta);
|
sqlWhere = String.format(
|
||||||
String sqlWhere = String.format(
|
|
||||||
"dataId = '%s' and level = %d and (fullName like '%%%s%%' or quickCode like '%%%s%%' or code like '%s%%') order by code,fullName",
|
"dataId = '%s' and level = %d and (fullName like '%%%s%%' or quickCode like '%%%s%%' or code like '%s%%') order by code,fullName",
|
||||||
useClassification.toLiteral(), openLevel, q, q, q);
|
useClassification.toLiteral(), openLevel, q, q, q);
|
||||||
|
}
|
||||||
|
|
||||||
List<Object> result = resultSearch(
|
List<Object> result = resultSearch(
|
||||||
sqlWhere, MetadataHelper.getEntity(EntityHelper.ClassificationData), 20);
|
sqlWhere, MetadataHelper.getEntity(EntityHelper.ClassificationData), useSimple37 ? 2000 : 20);
|
||||||
return (JSON) JSON.toJSON(result);
|
return (JSON) JSON.toJSON(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
border-color: #38adff;
|
border-color: #38adff;
|
||||||
color: #38adff;
|
color: #38adff;
|
||||||
}
|
}
|
||||||
|
.ufilters {
|
||||||
|
display: inline-block;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -60,11 +65,17 @@
|
||||||
<button class="btn btn-secondary" type="button"><i class="icon zmdi zmdi-search"></i></button>
|
<button class="btn btn-secondary" type="button"><i class="icon zmdi zmdi-search"></i></button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="float-left ml-2" style="margin-top: 8px">
|
<div class="float-left ml-2">
|
||||||
<label class="custom-control custom-checkbox custom-control-inline custom-control-sm">
|
<a class="ufilters" href="###filters" data-toggle="dropdown">
|
||||||
<input class="custom-control-input" type="checkbox" id="showAllUsers" />
|
<i class="icon mdi mdi-account-filter fs-15"></i>
|
||||||
<span class="custom-control-label">[[${bundle.L('显示全部用户')}]]</span>
|
<span>[[${bundle.L('全部用户')}]]</span>
|
||||||
</label>
|
</a>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<a class="dropdown-item" data-filter="0">[[${bundle.L('全部用户')}]]</a>
|
||||||
|
<a class="dropdown-item" data-filter="1">[[${bundle.L('可用用户')}]]</a>
|
||||||
|
<a class="dropdown-item" data-filter="2">[[${bundle.L('未激活的')}]]</a>
|
||||||
|
<a class="dropdown-item" data-filter="3">[[${bundle.L('已禁用的')}]]</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -96,6 +96,7 @@
|
||||||
entity: ['User', '[[${entityLabel}]]', '[[${entityIcon}]]'],
|
entity: ['User', '[[${entityLabel}]]', '[[${entityIcon}]]'],
|
||||||
recordId: '[[${id}]]',
|
recordId: '[[${id}]]',
|
||||||
onViewEditable: false,
|
onViewEditable: false,
|
||||||
|
serviceMail: '[[${serviceMail}]]',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<th:block th:replace="~{/_include/forms}" />
|
<th:block th:replace="~{/_include/forms}" />
|
||||||
|
|
|
@ -128,6 +128,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
.chart.index > .data-item strong {
|
.chart.index > .data-item strong {
|
||||||
font-size: 3.1rem;
|
font-size: 3.1rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chart.index > .data-item .with p,
|
.chart.index > .data-item .with p,
|
||||||
|
|
|
@ -134,7 +134,6 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
color: #999;
|
color: #999;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
top: 1px;
|
top: 1px;
|
||||||
right: -5px;
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,3 +592,8 @@ textarea.formula-code + .fields-vars {
|
||||||
.send-notification .select2 {
|
.send-notification .select2 {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.create-task .user-selector,
|
||||||
|
.create-task .form-control {
|
||||||
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
|
@ -128,7 +128,6 @@ body {
|
||||||
top: 5px;
|
top: 5px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.4s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.rbview-form .type-NTEXT.editable .ntext-action {
|
.rbview-form .type-NTEXT.editable .ntext-action {
|
||||||
|
@ -154,7 +153,8 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.rbview-form .type-NTEXT .ps-container.ntext-expand {
|
.rbview-form .type-NTEXT .ps-container.ntext-expand {
|
||||||
max-height: unset !important;
|
max-height: 1000px !important;
|
||||||
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rbview-form .type-NTEXT .ps-container.ntext-expand + .ntext-action .mdi-arrow-expand::before {
|
.rbview-form .type-NTEXT .ps-container.ntext-expand + .ntext-action .mdi-arrow-expand::before {
|
||||||
|
|
|
@ -713,7 +713,7 @@ class ApproverNodeConfig extends StartNodeConfig {
|
||||||
<select className="form-control form-control-sm" name="expiresAuto1ValueType">
|
<select className="form-control form-control-sm" name="expiresAuto1ValueType">
|
||||||
<option value="D">{$L('天后')}</option>
|
<option value="D">{$L('天后')}</option>
|
||||||
<option value="H">{$L('小时后')}</option>
|
<option value="H">{$L('小时后')}</option>
|
||||||
<option value="I">{$L('分钟后')}</option>
|
{/*<option value="I">{$L('分钟后')}</option>*/}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -61,7 +61,7 @@ class ReportList extends ConfigList {
|
||||||
</td>
|
</td>
|
||||||
<td className="actions">
|
<td className="actions">
|
||||||
<a className="icon" title={$L('预览')} href={`${rb.baseUrl}/admin/data/report-templates/preview?id=${item[0]}`} target="_blank">
|
<a className="icon" title={$L('预览')} href={`${rb.baseUrl}/admin/data/report-templates/preview?id=${item[0]}`} target="_blank">
|
||||||
<i className="zmdi zmdi-eye" />
|
<i className="zmdi mdi mdi-file-eye-outline" />
|
||||||
</a>
|
</a>
|
||||||
<a className="icon" title={$L('下载模板')} href={`${rb.baseUrl}/admin/data/report-templates/download?id=${item[0]}`} target="_blank">
|
<a className="icon" title={$L('下载模板')} href={`${rb.baseUrl}/admin/data/report-templates/download?id=${item[0]}`} target="_blank">
|
||||||
<i className="zmdi zmdi-download" />
|
<i className="zmdi zmdi-download" />
|
||||||
|
@ -303,7 +303,7 @@ class ReportEditor extends ConfigFormDlg {
|
||||||
|
|
||||||
$(this._$outputType).find('input:eq(0)').attr('checked', true)
|
$(this._$outputType).find('input:eq(0)').attr('checked', true)
|
||||||
|
|
||||||
const $pw = $(`<a class="btn btn-secondary ml-2"><i class="icon zmdi zmdi-eye mr-1"></i>${$L('预览')}</a>`)
|
const $pw = $(`<a class="btn btn-secondary ml-2"><i class="icon mdi mdi-file-eye-outline mr-1"></i>${$L('预览')}</a>`)
|
||||||
$(this._btns).find('.btn-primary').after($pw)
|
$(this._btns).find('.btn-primary').after($pw)
|
||||||
$pw.on('click', () => {
|
$pw.on('click', () => {
|
||||||
if (this.props.id) {
|
if (this.props.id) {
|
||||||
|
|
|
@ -16,9 +16,29 @@ RbForm.postAfter = function (data, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RbList.queryBefore = function (query) {
|
RbList.queryBefore = function (query) {
|
||||||
if (!$val('#showAllUsers')) {
|
const filter = ~~$('.ufilters span').attr('data-filter')
|
||||||
|
if (filter === 1) {
|
||||||
query.filterAnd = {
|
query.filterAnd = {
|
||||||
items: [{ field: 'isDisabled', op: 'EQ', value: 'F' }],
|
items: [
|
||||||
|
{ field: 'isDisabled', op: 'EQ', value: 'F' },
|
||||||
|
{ field: 'deptId.isDisabled', op: 'EQ', value: 'F' },
|
||||||
|
{ field: 'roleId.isDisabled', op: 'EQ', value: 'F' },
|
||||||
|
],
|
||||||
|
equation: 'AND',
|
||||||
|
}
|
||||||
|
} else if (filter === 2) {
|
||||||
|
query.filterAnd = {
|
||||||
|
items: [
|
||||||
|
{ field: 'isDisabled', op: 'EQ', value: 'T' },
|
||||||
|
{ field: 'deptId.isDisabled', op: 'EQ', value: 'T' },
|
||||||
|
{ field: 'roleId.isDisabled', op: 'EQ', value: 'T' },
|
||||||
|
{ field: 'deptId', op: 'NL' },
|
||||||
|
{ field: 'roleId', op: 'NL' },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
} else if (filter === 3) {
|
||||||
|
query.filterAnd = {
|
||||||
|
items: [{ field: 'isDisabled', op: 'EQ', value: 'T' }],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return query
|
return query
|
||||||
|
@ -36,7 +56,12 @@ $(document).ready(() => {
|
||||||
$('.J_imports').on('click', () => renderRbcomp(<UserImport />))
|
$('.J_imports').on('click', () => renderRbcomp(<UserImport />))
|
||||||
$('.J_resign').on('click', () => renderRbcomp(<UserResigntion />))
|
$('.J_resign').on('click', () => renderRbcomp(<UserResigntion />))
|
||||||
|
|
||||||
$('#showAllUsers').on('change', () => {
|
$('.ufilters')
|
||||||
|
.next()
|
||||||
|
.find('a[data-filter]')
|
||||||
|
.on('click', function () {
|
||||||
|
const $f = $(this)
|
||||||
|
$('.ufilters span').text($f.text()).attr('data-filter', $f.data('filter'))
|
||||||
RbListPage._RbList.reload()
|
RbListPage._RbList.reload()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -79,7 +104,8 @@ class UserImport extends RbModalHandler {
|
||||||
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-0">
|
||||||
<input className="custom-control-input" type="checkbox" ref={(c) => (this._$notify = c)} />
|
<input className="custom-control-input" type="checkbox" ref={(c) => (this._$notify = c)} />
|
||||||
<span className="custom-control-label">
|
<span className="custom-control-label">
|
||||||
{$L('导入成功后发送邮件通知用户')} {window.__PageConfig.serviceMail !== 'true' && <span>({$L('不可用')})</span>}
|
{$L('导入成功后发送邮件通知用户')}
|
||||||
|
{!$isTrue(window.__PageConfig.serviceMail) && <span className="fs-12 text-danger ml-1">({$L('不可用')})</span>}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -53,7 +53,10 @@ $(document).ready(function () {
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-2">
|
<label className="custom-control custom-control-sm custom-checkbox custom-control-inline mb-2">
|
||||||
<input className="custom-control-input" type="checkbox" defaultChecked />
|
<input className="custom-control-input" type="checkbox" defaultChecked />
|
||||||
<span className="custom-control-label"> {$L('发送邮件通知')}</span>
|
<span className="custom-control-label">
|
||||||
|
{$L('发送邮件通知')}
|
||||||
|
{!$isTrue(window.__PageConfig.serviceMail) && <span className="fs-12 text-danger ml-1">({$L('不可用')})</span>}
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</RF>
|
</RF>
|
||||||
|
|
|
@ -602,8 +602,7 @@ class ScheduleOptions extends React.Component {
|
||||||
state = { ...this.props }
|
state = { ...this.props }
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const email = window.__USER_EMAIL
|
const wpc = window.__PageConfig
|
||||||
const mobile = window.__USER_MOBILE
|
|
||||||
return (
|
return (
|
||||||
<div className="feed-options schedule">
|
<div className="feed-options schedule">
|
||||||
<dl className="row">
|
<dl className="row">
|
||||||
|
@ -619,18 +618,18 @@ class ScheduleOptions extends React.Component {
|
||||||
<input className="custom-control-input" name="remindOn" type="checkbox" value={1} disabled={this.props.readonly} />
|
<input className="custom-control-input" name="remindOn" type="checkbox" value={1} disabled={this.props.readonly} />
|
||||||
<span className="custom-control-label">{$L('通知')}</span>
|
<span className="custom-control-label">{$L('通知')}</span>
|
||||||
</label>
|
</label>
|
||||||
<label className="custom-control custom-checkbox custom-control-inline" title={email}>
|
<label className="custom-control custom-checkbox custom-control-inline">
|
||||||
<input className="custom-control-input" name="remindOn" type="checkbox" value={2} disabled={this.props.readonly} />
|
<input className="custom-control-input" name="remindOn" type="checkbox" value={2} disabled={this.props.readonly} />
|
||||||
<span className="custom-control-label">
|
<span className="custom-control-label">
|
||||||
{$L('邮件')}
|
{$L('邮件')}
|
||||||
{!email && <span className="text-danger fs-12"> ({$L('不可用')})</span>}
|
{!$isTrue(wpc.serviceMail) && <span className="text-danger fs-12"> ({$L('不可用')})</span>}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
<label className="custom-control custom-checkbox custom-control-inline" title={mobile}>
|
<label className="custom-control custom-checkbox custom-control-inline">
|
||||||
<input className="custom-control-input" name="remindOn" type="checkbox" value={4} disabled={this.props.readonly} />
|
<input className="custom-control-input" name="remindOn" type="checkbox" value={4} disabled={this.props.readonly} />
|
||||||
<span className="custom-control-label">
|
<span className="custom-control-label">
|
||||||
{$L('短信')}
|
{$L('短信')}
|
||||||
{!mobile && <span className="text-danger fs-12"> ({$L('不可用')})</span>}
|
{!$isTrue(wpc.serviceSms) && <span className="text-danger fs-12"> ({$L('不可用')})</span>}
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -2123,8 +2123,6 @@ const EasyAction = {
|
||||||
|
|
||||||
_List.addButton(item)
|
_List.addButton(item)
|
||||||
})
|
})
|
||||||
// Min btn
|
|
||||||
if ($('.dataTables_oper > .btn').length > 6) $('.dataTables_oper').addClass('compact')
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleOp(item) {
|
handleOp(item) {
|
||||||
|
|
|
@ -1374,7 +1374,7 @@ class RbFormNText extends RbFormElement {
|
||||||
{WrapHtml(text2)}
|
{WrapHtml(text2)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`ntext-action ${window.__LAB_SHOWNTEXTACTION ? '' : 'hide'}`}>
|
<div className={`ntext-action ${window.__LAB_SHOWNTEXTACTION || this.props.useCode ? '' : 'hide'}`}>
|
||||||
<a title={$L('展开/收起')} onClick={() => $(this._textarea).toggleClass('ntext-expand')}>
|
<a title={$L('展开/收起')} onClick={() => $(this._textarea).toggleClass('ntext-expand')}>
|
||||||
<i className="mdi mdi-arrow-expand" />
|
<i className="mdi mdi-arrow-expand" />
|
||||||
</a>
|
</a>
|
||||||
|
@ -1390,18 +1390,6 @@ class RbFormNText extends RbFormElement {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
super.componentDidMount()
|
super.componentDidMount()
|
||||||
this.props.onView && this.onEditModeChanged(true)
|
this.props.onView && this.onEditModeChanged(true)
|
||||||
|
|
||||||
if (this._actionCopy) {
|
|
||||||
const that = this
|
|
||||||
const initCopy = function () {
|
|
||||||
$clipboard($(that._actionCopy), that.state.value)
|
|
||||||
}
|
|
||||||
if (window.ClipboardJS) {
|
|
||||||
initCopy()
|
|
||||||
} else {
|
|
||||||
$getScript('/assets/lib/clipboard.min.js', initCopy)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UNSAFE_componentWillUpdate(nextProps, nextState) {
|
UNSAFE_componentWillUpdate(nextProps, nextState) {
|
||||||
|
@ -1424,6 +1412,18 @@ class RbFormNText extends RbFormElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.props.useMdedit && !destroy) this._initMde()
|
if (this.props.useMdedit && !destroy) this._initMde()
|
||||||
|
|
||||||
|
if (this._actionCopy) {
|
||||||
|
const that = this
|
||||||
|
const initCopy = function () {
|
||||||
|
$clipboard($(that._actionCopy), that.state.value)
|
||||||
|
}
|
||||||
|
if (window.ClipboardJS) {
|
||||||
|
initCopy()
|
||||||
|
} else {
|
||||||
|
$getScript('/assets/lib/clipboard.min.js', initCopy)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(val) {
|
setValue(val) {
|
||||||
|
|
|
@ -643,17 +643,19 @@ class UserSelector extends React.Component {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.props.defaultValue) {
|
this.props.defaultValue && this._renderValue(this.props.defaultValue)
|
||||||
let dv = this.props.defaultValue
|
}
|
||||||
if ($type(this.props.defaultValue) === 'string') dv = dv.split(',')
|
|
||||||
|
|
||||||
$.post('/commons/search/user-selector', JSON.stringify(dv), (res) => {
|
_renderValue(value) {
|
||||||
|
let s = value
|
||||||
|
if ($type(s) === 'string') s = s.split(',')
|
||||||
|
|
||||||
|
$.post('/commons/search/user-selector', JSON.stringify(s), (res) => {
|
||||||
if (res.error_code === 0 && res.data.length > 0) {
|
if (res.error_code === 0 && res.data.length > 0) {
|
||||||
this.setState({ selected: res.data })
|
this.setState({ selected: res.data })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
$(this._$scroller).perfectScrollbar('destroy')
|
$(this._$scroller).perfectScrollbar('destroy')
|
||||||
|
@ -780,6 +782,11 @@ class UserSelector extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
val() {
|
val() {
|
||||||
|
// v3.7 set
|
||||||
|
if (arguments[0]) {
|
||||||
|
this._renderValue(arguments[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
return this.getSelected()
|
return this.getSelected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -861,7 +861,6 @@ var $initReferenceSelect2 = function (el, option) {
|
||||||
},
|
},
|
||||||
theme: 'default ' + (option.appendClass || ''),
|
theme: 'default ' + (option.appendClass || ''),
|
||||||
})
|
})
|
||||||
|
|
||||||
return $el
|
return $el
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class TriggerList extends ConfigList {
|
||||||
</td>
|
</td>
|
||||||
<td className="actions">
|
<td className="actions">
|
||||||
<a className="icon" title={$L('触发过程')} onClick={() => this.handleShowChain(item[0])}>
|
<a className="icon" title={$L('触发过程')} onClick={() => this.handleShowChain(item[0])}>
|
||||||
<i className="zmdi mdi mdi-vector-polyline mdi-rotate-180" />
|
<i className="zmdi mdi mdi-vector-polyline" />
|
||||||
</a>
|
</a>
|
||||||
<a className="icon" title={$L('修改')} onClick={() => this.handleEdit(item)}>
|
<a className="icon" title={$L('修改')} onClick={() => this.handleEdit(item)}>
|
||||||
<i className="zmdi zmdi-edit" />
|
<i className="zmdi zmdi-edit" />
|
||||||
|
|
|
@ -101,8 +101,10 @@
|
||||||
</div>
|
</div>
|
||||||
<th:block th:replace="~{/_include/footer}" />
|
<th:block th:replace="~{/_include/footer}" />
|
||||||
<script>
|
<script>
|
||||||
__USER_EMAIL = '[[${UserEmail}]]'
|
window.__PageConfig = {
|
||||||
__USER_MOBILE = '[[${UserMobile}]]'
|
serviceMail: '[[${serviceMail}]]',
|
||||||
|
serviceSms: '[[${serviceSms}]]',
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<script th:src="@{/assets/js/feeds/announcement.js}" type="text/babel"></script>
|
<script th:src="@{/assets/js/feeds/announcement.js}" type="text/babel"></script>
|
||||||
<script th:src="@{/assets/js/feeds/feeds-post.js}" type="text/babel"></script>
|
<script th:src="@{/assets/js/feeds/feeds-post.js}" type="text/babel"></script>
|
||||||
|
|
|
@ -7,6 +7,7 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
||||||
|
|
||||||
package com.rebuild.utils;
|
package com.rebuild.utils;
|
||||||
|
|
||||||
|
import cn.devezhao.commons.CalendarUtils;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -38,6 +39,7 @@ class OshiUtilsTest {
|
||||||
@Test
|
@Test
|
||||||
void getNetworkDate() {
|
void getNetworkDate() {
|
||||||
System.out.println(OshiUtils.getNetworkDate());
|
System.out.println(OshiUtils.getNetworkDate());
|
||||||
|
System.out.println(CalendarUtils.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue