mirror of
https://github.com/getrebuild/rebuild.git
synced 2025-09-08 07:36:52 +08:00
Fix 4.0.3 (#890)
* be: DockerInstaller * be: docker * 4.0.3 * be * Update RebuildException.java * ND tips * Update DepartmentService.java * fix: 审批统计数量 * fix: style * fix:使用 RecordTransfomer39 修复表单回填/计算后端问题 * fix: 表单折叠隐藏字段 * Update trigger.FIELDWRITEBACK.js --------- Co-authored-by: devezhao <zhaofang123@gmail.com>
This commit is contained in:
parent
49c315cf65
commit
f49dc27c89
22 changed files with 183 additions and 4417 deletions
|
@ -4,7 +4,7 @@ RUN apk add ttf-dejavu
|
|||
RUN apk add wget
|
||||
|
||||
RUN mkdir -p /app/rebuild/.rebuild/
|
||||
ADD ./rebuild-boot-4.0.0.jar /app/rebuild/rebuild-boot.jar
|
||||
ADD ./rebuild.jar /app/rebuild/rebuild-boot.jar
|
||||
ADD https://www.qn-cdn.getrebuild.com/pub/deploy/SourceHanSansK-Regular.ttf /app/rebuild/.rebuild/
|
||||
|
||||
EXPOSE 18080
|
||||
|
|
|
@ -3,11 +3,11 @@ services:
|
|||
image: mysql:5.7
|
||||
environment:
|
||||
MYSQL_ROOT_HOST: "%"
|
||||
MYSQL_ROOT_PASSWORD: "rebuildP4wd"
|
||||
MYSQL_ROOT_PASSWORD: "rebuild!P4wd"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
healthcheck:
|
||||
test: [ "CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD" ]
|
||||
test: [ "CMD", "mysqladmin", "ping", "-h", "mysql", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD" ]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 10
|
||||
|
@ -15,7 +15,7 @@ services:
|
|||
- app_network
|
||||
|
||||
rebuild:
|
||||
image: getrebuild/rebuild:4.0.2
|
||||
image: getrebuild/rebuild:latest
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
|
@ -23,8 +23,7 @@ services:
|
|||
command:
|
||||
- >
|
||||
mkdir -p /app/rebuild/.rebuild &&
|
||||
wget -O /app/rebuild/.rebuild/.rebuild https://www.qn-cdn.getrebuild.com/pub/deploy/.rebuild &&
|
||||
java -Dinitialize=yes -Duser.timezone=Asia/Shanghai -DDataDirectory=/app/rebuild/.rebuild -jar /app/rebuild/rebuild-boot.jar
|
||||
java -Dinitialize=docker -Duser.timezone=Asia/Shanghai -DSN= -DDataDirectory=/app/rebuild/.rebuild -jar /app/rebuild/rebuild-boot.jar
|
||||
ports:
|
||||
- "18080:18080"
|
||||
volumes:
|
||||
|
|
4249
.deploy/package-lock.json
generated
4249
.deploy/package-lock.json
generated
File diff suppressed because it is too large
Load diff
2
@rbv
2
@rbv
|
@ -1 +1 @@
|
|||
Subproject commit b93ade10867b9c370870d8feffa2e429f503ea6b
|
||||
Subproject commit 07ba14147145a9fb9646563605427f680ac82d13
|
2
pom.xml
2
pom.xml
|
@ -10,7 +10,7 @@
|
|||
</parent>
|
||||
<groupId>com.rebuild</groupId>
|
||||
<artifactId>rebuild</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.3</version>
|
||||
<name>rebuild</name>
|
||||
<description>Building your business-systems freely!</description>
|
||||
<url>https://getrebuild.com/</url>
|
||||
|
|
|
@ -75,11 +75,11 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
/**
|
||||
* Rebuild Version
|
||||
*/
|
||||
public static final String VER = "4.0.2";
|
||||
public static final String VER = "4.0.3";
|
||||
/**
|
||||
* Rebuild Build [MAJOR]{1}[MINOR]{2}[PATCH]{2}[BUILD]{2}
|
||||
*/
|
||||
public static final int BUILD = 4000208;
|
||||
public static final int BUILD = 4000309;
|
||||
|
||||
static {
|
||||
// Driver for DB
|
||||
|
@ -134,46 +134,9 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
final Timer timer = new Timer("Boot-Timer");
|
||||
|
||||
try {
|
||||
// v4.0.2 for Docker
|
||||
DockerInstaller di = new DockerInstaller();
|
||||
final boolean isNeedInitialize = di.isNeedInitialize();
|
||||
if (isNeedInitialize) {
|
||||
log.info("Initializing REBUILD for Docker container ...");
|
||||
di.install();
|
||||
}
|
||||
|
||||
if (Installer.isInstalled()) {
|
||||
started = init();
|
||||
|
||||
if (started) {
|
||||
final long timeCost = System.currentTimeMillis() - time;
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
String localUrl = BootApplication.getLocalUrl(null);
|
||||
String banner = RebuildBanner.formatSimple(
|
||||
"REBUILD (" + VER + ") started successfully in " + timeCost + " ms.",
|
||||
" License : " + License.queryAuthority().values(),
|
||||
"Access URLs : ",
|
||||
" Local : " + localUrl,
|
||||
" External : " + localUrl.replace("localhost", OshiUtils.getLocalIp()),
|
||||
" Public : " + RebuildConfiguration.getHomeUrl());
|
||||
log.info(banner);
|
||||
|
||||
if (!License.isCommercial()) {
|
||||
String thanks = RebuildBanner.formatSimple(
|
||||
"**********",
|
||||
"感谢使用 REBUILD!",
|
||||
"您当前使用的是免费版本,如果 REBUILD 对贵公司业务有帮助,请考虑购买商业授权版本,帮助我们可持续发展!",
|
||||
"查看详情 https://getrebuild.com/#pricing-plans",
|
||||
"**********");
|
||||
System.out.println(thanks);
|
||||
}
|
||||
}
|
||||
}, 999);
|
||||
|
||||
if (isNeedInitialize) di.installAfter();
|
||||
}
|
||||
if (started) printStartup(timer, System.currentTimeMillis() - time);
|
||||
|
||||
} else {
|
||||
timer.schedule(new TimerTask() {
|
||||
|
@ -184,6 +147,14 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
"Install : " + BootApplication.getLocalUrl("/setup/install")));
|
||||
}
|
||||
}, 999);
|
||||
|
||||
// v4.0.3 for Docker
|
||||
DockerInstaller di = new DockerInstaller();
|
||||
if (di.isNeedInitialize()) {
|
||||
log.info("Initializing REBUILD for Docker container ...");
|
||||
di.install();
|
||||
printStartup(timer, System.currentTimeMillis() - time);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
|
@ -205,6 +176,34 @@ public class Application implements ApplicationListener<ApplicationStartedEvent>
|
|||
}
|
||||
}
|
||||
|
||||
// 打印启动信息
|
||||
private void printStartup(Timer timer, long timeCost) {
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
String localUrl = BootApplication.getLocalUrl(null);
|
||||
String banner = RebuildBanner.formatSimple(
|
||||
"REBUILD (" + VER + ") started successfully in " + timeCost + " ms.",
|
||||
" License : " + License.queryAuthority().values(),
|
||||
"Access URLs : ",
|
||||
" Local : " + localUrl,
|
||||
" External : " + localUrl.replace("localhost", OshiUtils.getLocalIp()),
|
||||
" Public : " + RebuildConfiguration.getHomeUrl());
|
||||
log.info(banner);
|
||||
|
||||
if (!License.isCommercial()) {
|
||||
String thanks = RebuildBanner.formatSimple(
|
||||
"\n **********",
|
||||
"感谢使用 REBUILD!",
|
||||
"您当前使用的是免费版本,如果 REBUILD 对贵公司业务有帮助,请考虑购买商业授权版本,帮助我们可持续发展!",
|
||||
"查看详情 https://getrebuild.com/#pricing-plans",
|
||||
"**********");
|
||||
log.info(thanks);
|
||||
}
|
||||
}
|
||||
}, 999);
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统初始化
|
||||
*
|
||||
|
|
|
@ -17,6 +17,7 @@ public class RebuildException extends RuntimeException {
|
|||
private static final long serialVersionUID = -889444005870894361L;
|
||||
|
||||
public RebuildException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public RebuildException(String message) {
|
||||
|
|
|
@ -56,6 +56,11 @@ public class DepartmentService extends BaseService {
|
|||
|
||||
@Override
|
||||
public Record update(Record record) {
|
||||
if (ROOT_DEPT.equals(record.getPrimary())) {
|
||||
Boolean b = record.getBoolean("isDisabled");
|
||||
if (b != null && b) throw new OperationDeniedException("内置部门不能禁用");
|
||||
}
|
||||
|
||||
checkAdminGuard(BizzPermission.UPDATE, record.getPrimary());
|
||||
|
||||
// 检查父子循环依赖
|
||||
|
|
|
@ -7,10 +7,10 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
|
||||
package com.rebuild.core.service.dashboard.charts.builtin;
|
||||
|
||||
import cn.devezhao.commons.ObjectUtils;
|
||||
import cn.devezhao.persist4j.Entity;
|
||||
import cn.devezhao.persist4j.engine.ID;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rebuild.core.Application;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
|
@ -28,9 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 审批列表/统计
|
||||
|
@ -61,38 +59,43 @@ public class ApprovalList extends ChartData implements BuiltinChart {
|
|||
|
||||
@Override
|
||||
public JSON build() {
|
||||
final int viewState = ObjectUtils.toInt(getExtraParams().get("state"), ApprovalState.DRAFT.getState());
|
||||
final String baseWhere = "where isCanceled = 'F' and isWaiting = 'F' and approver = ?" +
|
||||
" and approvalId <> '' and recordId <> '' and ";
|
||||
// FIXME 存在一定性能问题
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("state1", queryByState(ApprovalState.DRAFT.getState()));
|
||||
data.put("state10", queryByState(ApprovalState.APPROVED.getState()));
|
||||
data.put("state11", queryByState(ApprovalState.REJECTED.getState()));
|
||||
return data;
|
||||
}
|
||||
|
||||
Object[][] array = Application.createQueryNoFilter(
|
||||
"select createdBy,modifiedOn,recordId,approvalId from RobotApprovalStep " +
|
||||
baseWhere + " state = ? order by modifiedOn desc")
|
||||
protected List<Object[]> queryByState(int viewState) {
|
||||
String sql = "select createdBy,modifiedOn,recordId,approvalId from RobotApprovalStep" +
|
||||
" where isCanceled = 'F' and isWaiting = 'F' and approver = ? and approvalId <> '' and recordId <> '' and state = ?" +
|
||||
" order by modifiedOn desc";
|
||||
Object[][] array = Application.createQueryNoFilter(sql)
|
||||
.setParameter(1, getUser())
|
||||
.setParameter(2, viewState)
|
||||
.setLimit(500) // 最多显示
|
||||
.array();
|
||||
|
||||
List<Object> rearray = new ArrayList<>();
|
||||
int removed = 0;
|
||||
List<Object[]> stateList = new ArrayList<>();
|
||||
for (Object[] o : array) {
|
||||
final ID recordId = (ID) o[2];
|
||||
String label;
|
||||
try {
|
||||
label = FieldValueHelper.getLabel(recordId);
|
||||
} catch (NoRecordFoundException ignored) {
|
||||
removed++;
|
||||
// 已删除
|
||||
continue;
|
||||
}
|
||||
|
||||
final ApprovalState currentState = ApprovalHelper.getApprovalState(recordId);
|
||||
// 已取消
|
||||
ApprovalState currentState = ApprovalHelper.getApprovalState(recordId);
|
||||
if (currentState == ApprovalState.CANCELED) {
|
||||
removed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
FlowNode currentNode = null;
|
||||
if (currentState == ApprovalState.PROCESSING) {
|
||||
if (viewState == ApprovalState.PROCESSING.getState()) {
|
||||
try {
|
||||
ApprovalProcessor approvalProcessor = new ApprovalProcessor(recordId, (ID) o[3]);
|
||||
currentNode = approvalProcessor.getCurrentNode();
|
||||
|
@ -103,7 +106,7 @@ public class ApprovalList extends ChartData implements BuiltinChart {
|
|||
|
||||
Entity e = MetadataHelper.getEntity(recordId.getEntityCode());
|
||||
ID s = ApprovalHelper.getSubmitter(recordId, (ID) o[3]);
|
||||
rearray.add(new Object[]{
|
||||
stateList.add(new Object[]{
|
||||
s,
|
||||
UserHelper.getName(s),
|
||||
I18nUtils.formatDate((Date) o[1]),
|
||||
|
@ -116,27 +119,6 @@ public class ApprovalList extends ChartData implements BuiltinChart {
|
|||
});
|
||||
}
|
||||
|
||||
Object[][] stats = Application.createQueryNoFilter(
|
||||
"select state,count(state) from RobotApprovalStep " + baseWhere + " state < ? group by state")
|
||||
.setParameter(1, this.getUser())
|
||||
.setParameter(2, ApprovalState.CANCELED.getState())
|
||||
.array();
|
||||
// 排除删除和无效的(可能导致不同状态下数据不一致)
|
||||
if (removed > 0) {
|
||||
for (Object[] o : stats) {
|
||||
if ((Integer) o[0] == viewState) {
|
||||
o[1] = ObjectUtils.toInt(o[1]) - removed;
|
||||
if ((Integer) o[1] < 0) {
|
||||
o[1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> ret = new HashMap<>();
|
||||
ret.put("data", rearray);
|
||||
ret.put("stats", stats);
|
||||
ret.put("overLimit", array.length >= 500);
|
||||
return (JSON) JSON.toJSON(ret);
|
||||
return stateList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ public class RecordTransfomer37 extends RecordTransfomer {
|
|||
super(targetEntity, transConfig, skipGuard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID transform(ID sourceRecordId) {
|
||||
return this.transform(sourceRecordId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID transform(ID sourceRecordId, ID specMainId) {
|
||||
// 主
|
||||
|
|
|
@ -35,6 +35,8 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* v3.9 新增转换为新记录或已存在记录
|
||||
*
|
||||
* @author Zixin
|
||||
* @since 2024/4/8
|
||||
*/
|
||||
|
@ -52,6 +54,16 @@ public class RecordTransfomer39 extends RecordTransfomer37 {
|
|||
this.transid = transid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID transform(ID sourceRecordId) {
|
||||
return this.transform(sourceRecordId, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ID transform(ID sourceRecordId, ID specMainId) {
|
||||
return this.transform(sourceRecordId, specMainId, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*
|
||||
|
|
|
@ -9,10 +9,17 @@ package com.rebuild.core.support.setup;
|
|||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.rebuild.core.Application;
|
||||
import com.rebuild.core.support.RebuildConfiguration;
|
||||
import com.rebuild.utils.JSONUtils;
|
||||
import com.rebuild.utils.OshiUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Properties;
|
||||
|
||||
import static com.rebuild.core.support.ConfigurationItem.CacheHost;
|
||||
|
||||
/**
|
||||
* Docker 安装
|
||||
|
@ -32,7 +39,7 @@ public class DockerInstaller extends Installer {
|
|||
JSONObject installProps = new JSONObject();
|
||||
JSONObject databaseProps = JSONUtils.toJSONObject(
|
||||
new String[]{"dbName", "dbHost", "dbPort", "dbUser", "dbPassword"},
|
||||
new String[]{"rebuild40", "mysql", "3306", "root", "rebuildP4wd"});
|
||||
new String[]{"rebuild40", "mysql", "3306", "root", "rebuild!P4wd"});
|
||||
if (Application.devMode()) {
|
||||
databaseProps.put("dbHost", "localhost");
|
||||
databaseProps.put("dbUser", "rebuild");
|
||||
|
@ -45,28 +52,27 @@ public class DockerInstaller extends Installer {
|
|||
@Override
|
||||
public void install() throws Exception {
|
||||
this.installDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public void installAfter() {
|
||||
try {
|
||||
this.installClassificationAsync();
|
||||
} catch (Exception ex) {
|
||||
log.error("Error installing classification data", ex);
|
||||
Properties installProps = buildConnectionProps(null);
|
||||
installProps.put(CONF_PREFIX + CacheHost.name(), "0");
|
||||
File dest = RebuildConfiguration.getFileOfData(INSTALL_FILE);
|
||||
try (OutputStream os = Files.newOutputStream(dest.toPath())) {
|
||||
installProps.store(os, "REBUILD INSTALLER MAGIC FOR DOCKER !!! DO NOT EDIT !!!");
|
||||
log.info("Saved installation file : {}", dest);
|
||||
}
|
||||
|
||||
this.refresh();
|
||||
|
||||
this.installClassificationAsync();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要安装
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isNeedInitialize() {
|
||||
if (!OshiUtils.isDockerEnv()) return false;
|
||||
if (!BooleanUtils.toBoolean(System.getProperty("initialize"))) return false;
|
||||
|
||||
if (Installer.isInstalled()) {
|
||||
return !isRbDatabase();
|
||||
}
|
||||
return false;
|
||||
if (Installer.isInstalled()) return false;
|
||||
return OshiUtils.isDockerEnv() && "docker".equals(System.getProperty("initialize"));
|
||||
}
|
||||
}
|
|
@ -132,11 +132,10 @@ public class Installer implements InstallState {
|
|||
installProps.put(CONF_PREFIX + CachePassword.name(), String.format("AES(%s)", AES.encrypt(cachePasswd)));
|
||||
}
|
||||
} else {
|
||||
// Use ehcache
|
||||
// Ehcache
|
||||
installProps.put(CONF_PREFIX + CacheHost.name(), "0");
|
||||
}
|
||||
|
||||
// Save install state (file)
|
||||
File dest = RebuildConfiguration.getFileOfData(INSTALL_FILE);
|
||||
try {
|
||||
FileUtils.deleteQuietly(dest);
|
||||
|
@ -149,7 +148,6 @@ public class Installer implements InstallState {
|
|||
throw new SetupException(e);
|
||||
}
|
||||
|
||||
// Refresh
|
||||
try {
|
||||
refresh();
|
||||
} catch (Exception ex) {
|
||||
|
@ -157,7 +155,6 @@ public class Installer implements InstallState {
|
|||
throw ex;
|
||||
}
|
||||
|
||||
// Clean cached
|
||||
clearAllCache();
|
||||
|
||||
if (!dbNew) return;
|
||||
|
@ -174,17 +171,13 @@ public class Installer implements InstallState {
|
|||
log.error("Error installing business module", ex);
|
||||
}
|
||||
|
||||
try {
|
||||
this.installClassificationAsync();
|
||||
} catch (Exception ex) {
|
||||
log.error("Error installing classification data", ex);
|
||||
}
|
||||
this.installClassificationAsync();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新配置
|
||||
*/
|
||||
private void refresh() throws Exception {
|
||||
protected void refresh() throws Exception {
|
||||
// 重配置
|
||||
Application.getBean(BootEnvironmentPostProcessor.class).postProcessEnvironment(null, null);
|
||||
|
||||
|
@ -248,7 +241,7 @@ public class Installer implements InstallState {
|
|||
* @param dbName
|
||||
* @return
|
||||
*/
|
||||
private Properties buildConnectionProps(String dbName) {
|
||||
protected Properties buildConnectionProps(String dbName) {
|
||||
final JSONObject dbProps = installProps.getJSONObject("databaseProps");
|
||||
if (dbName == null) {
|
||||
dbName = dbProps == null ? null : dbProps.getString("dbName");
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.apache.commons.lang.SystemUtils;
|
|||
*/
|
||||
public class RebuildBanner {
|
||||
|
||||
static final String COMMON_BANNER = "" +
|
||||
static final String COMMON_BANNER =
|
||||
"\n Version : " + Application.VER +
|
||||
"\n OS : " + SystemUtils.OS_NAME + " (" + SystemUtils.OS_ARCH + ")" +
|
||||
"\n JVM : " + SystemUtils.JAVA_VM_NAME + " (" + SystemUtils.JAVA_VERSION + ")" +
|
||||
|
|
|
@ -38,6 +38,7 @@ import com.rebuild.core.privileges.UserHelper;
|
|||
import com.rebuild.core.rbstore.MetaschemaExporter;
|
||||
import com.rebuild.core.service.general.QuickCodeReindexTask;
|
||||
import com.rebuild.core.service.general.series.SeriesGeneratorFactory;
|
||||
import com.rebuild.core.support.License;
|
||||
import com.rebuild.core.support.RebuildConfiguration;
|
||||
import com.rebuild.core.support.general.FieldValueHelper;
|
||||
import com.rebuild.core.support.task.TaskExecutors;
|
||||
|
@ -209,6 +210,11 @@ public class MetaEntityController extends EntityController {
|
|||
if (useMain.getMainEntity() != null) {
|
||||
return RespBody.errorl("明细实体不能作为主实体");
|
||||
}
|
||||
|
||||
if (useMain.getDetailEntity() != null && !License.isCommercial()) {
|
||||
return RespBody.errorl(
|
||||
"免费版不支持%s功能 [(查看详情)](https://getrebuild.com/docs/rbv-features)", "多明细");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -127,7 +127,7 @@ public class LoginController extends LoginAction {
|
|||
} else {
|
||||
mv.getModel().put("ssoDingtalk", "#");
|
||||
mv.getModel().put("ssoWxwork", "#");
|
||||
// mv.getModel().put("ssoFeishu", "#");
|
||||
mv.getModel().put("ssoFeishu", "#");
|
||||
}
|
||||
|
||||
mv.getModelMap().put("UsersMsg", SysbaseHeartbeat.getUsersDanger());
|
||||
|
|
|
@ -147,6 +147,7 @@ div.dataTables_wrapper div.dataTables_oper.compact .btn-space {
|
|||
.page-aside.widgets .tab-container {
|
||||
min-width: 229px;
|
||||
}
|
||||
.rb-aside .page-head,
|
||||
.rb-aside .main-content {
|
||||
margin-left: 230px;
|
||||
}
|
||||
|
|
|
@ -1004,6 +1004,10 @@ a.link.link-icon::after {
|
|||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.form-layout .collapsed-hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.rbform > .row.form {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
|
|
|
@ -866,18 +866,28 @@ class ApprovalList extends BaseChart {
|
|||
constructor(props) {
|
||||
super(props)
|
||||
this.__approvalForms = {}
|
||||
this.state.viewState = 1
|
||||
}
|
||||
|
||||
renderChart(data) {
|
||||
let statsTotal = 0
|
||||
this._lastStats = this._lastStats || data.stats
|
||||
this._lastStats.forEach((item) => (statsTotal += item[1]))
|
||||
renderChart(data, viewState) {
|
||||
viewState = viewState || 1
|
||||
|
||||
const stats = (
|
||||
let stats = []
|
||||
let statsTotal = 0
|
||||
Object.keys(APPROVAL_STATES).forEach((state) => {
|
||||
let len = (data['state' + state] || []).length
|
||||
stats.push([~~state, len])
|
||||
statsTotal += len
|
||||
})
|
||||
|
||||
if (statsTotal === 0) {
|
||||
this.renderError($L('暂无数据'))
|
||||
return
|
||||
}
|
||||
|
||||
const statsComp = (
|
||||
<div className="progress-wrap sticky">
|
||||
<div className="progress">
|
||||
{this._lastStats.map((item) => {
|
||||
{stats.map((item) => {
|
||||
const s = APPROVAL_STATES[item[0]]
|
||||
if (!s || s[1] <= 0) return null
|
||||
|
||||
|
@ -885,26 +895,22 @@ class ApprovalList extends BaseChart {
|
|||
return (
|
||||
<div
|
||||
key={s[0]}
|
||||
className={`progress-bar bg-${s[0]} ${this.state.viewState === item[0] && 'active'}`}
|
||||
// title={`${s[1]} : ${item[1]} (${p})`}
|
||||
className={`progress-bar bg-${s[0]} ${viewState === item[0] && 'active'}`}
|
||||
style={{ width: p }}
|
||||
onClick={() => this._changeState(item[0])}>
|
||||
onClick={() => {
|
||||
this.renderChart(data, item[0])
|
||||
}}>
|
||||
{s[1]} ({item[1]})
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<p className="m-0 mt-1 fs-11 text-muted text-right hide">{$L('审批统计')}</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (statsTotal === 0) {
|
||||
this.renderError($L('暂无数据'))
|
||||
return
|
||||
}
|
||||
|
||||
const table =
|
||||
(data.data || []).length === 0 ? (
|
||||
const viewData = data['state' + viewState] || []
|
||||
const tableComp =
|
||||
viewData.length === 0 ? (
|
||||
<div className="chart-undata must-center">
|
||||
<i className="zmdi zmdi-check icon text-success" /> {$L('你已完成所有审批')}
|
||||
</div>
|
||||
|
@ -919,7 +925,7 @@ class ApprovalList extends BaseChart {
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.data.map((item, idx) => {
|
||||
{viewData.map((item, idx) => {
|
||||
let expType = isNaN(item[8]) ? null : item[8]
|
||||
if (expType !== null) expType = item[8] > 0 ? 2 : 1
|
||||
return (
|
||||
|
@ -942,20 +948,20 @@ class ApprovalList extends BaseChart {
|
|||
<span className="cell-detail-description">{item[6]}</span>
|
||||
</td>
|
||||
<td className="actions text-right text-nowrap">
|
||||
{this.state.viewState === 1 && (
|
||||
{viewState === 1 && (
|
||||
<button className="btn btn-secondary btn-sm" onClick={() => this.approve(item[3], item[5], item[7])}>
|
||||
{$L('审批')}
|
||||
</button>
|
||||
)}
|
||||
{this.state.viewState === 10 && <span className="text-success">{$L('通过')}</span>}
|
||||
{this.state.viewState === 11 && <span className="text-danger">{$L('驳回')}</span>}
|
||||
{viewState === 10 && <span className="text-success">{$L('通过')}</span>}
|
||||
{viewState === 11 && <span className="text-danger">{$L('驳回')}</span>}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
{data.overLimit && (
|
||||
{viewData.length >= 500 && (
|
||||
<div className="m-2 text-center text-warning">
|
||||
<i className="mdi mdi-information-outline" /> {$L('最多显示最近 500 条记录')}
|
||||
</div>
|
||||
|
@ -965,8 +971,8 @@ class ApprovalList extends BaseChart {
|
|||
|
||||
const chartdata = (
|
||||
<div className="chart ApprovalList">
|
||||
{stats}
|
||||
{table}
|
||||
{statsComp}
|
||||
{tableComp}
|
||||
</div>
|
||||
)
|
||||
this.setState({ chartdata: chartdata }, () => {
|
||||
|
@ -975,14 +981,14 @@ class ApprovalList extends BaseChart {
|
|||
.find('.ApprovalList')
|
||||
.css('height', $tb.height() - 5)
|
||||
.perfectScrollbar()
|
||||
this._$tb = $tb
|
||||
})
|
||||
}
|
||||
|
||||
resize() {
|
||||
$setTimeout(
|
||||
() => {
|
||||
if (this._$tb) this._$tb.find('.ApprovalList').css('height', this._$tb.height() - 5)
|
||||
const $tb = $(this._$body)
|
||||
if ($tb) $tb.find('.ApprovalList').css('height', $tb.height() - 5)
|
||||
},
|
||||
400,
|
||||
`resize-chart-${this.state.id}`
|
||||
|
@ -990,31 +996,27 @@ class ApprovalList extends BaseChart {
|
|||
}
|
||||
|
||||
approve(record, approval, entity) {
|
||||
event.preventDefault()
|
||||
window.event && window.event.preventDefault()
|
||||
if (this.__approvalForms[record]) {
|
||||
this.__approvalForms[record].show()
|
||||
} else {
|
||||
const that = this
|
||||
const close = function () {
|
||||
if (that.__approvalForms[record]) that.__approvalForms[record].hide(true)
|
||||
that.loadChartData()
|
||||
}
|
||||
// eslint-disable-next-line react/jsx-no-undef
|
||||
renderRbcomp(<ApprovalApproveForm id={record} approval={approval} entity={entity} call={close} />, function () {
|
||||
that.__approvalForms[record] = this
|
||||
that._lastStats = null
|
||||
})
|
||||
renderRbcomp(
|
||||
<ApprovalApproveForm
|
||||
id={record}
|
||||
approval={approval}
|
||||
entity={entity}
|
||||
call={() => {
|
||||
if (that.__approvalForms[record]) that.__approvalForms[record].hide(true)
|
||||
that.loadChartData()
|
||||
}}
|
||||
/>,
|
||||
function () {
|
||||
that.__approvalForms[record] = this
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
_changeState(state) {
|
||||
if (state === this.state.viewState) state = 1
|
||||
this.setState({ viewState: state }, () => this.loadChartData())
|
||||
}
|
||||
|
||||
buildDataUrl() {
|
||||
return `${super.buildDataUrl()}&state=${this.state.viewState}`
|
||||
}
|
||||
}
|
||||
|
||||
// ~ 我的日程
|
||||
|
|
|
@ -3127,8 +3127,8 @@ class RbFormDivider extends React.Component {
|
|||
let $next = $(this._$formLine)
|
||||
while (($next = $next.next()).length > 0) {
|
||||
if ($next.hasClass('form-line') || $next.hasClass('footer')) break
|
||||
$next.toggleClass('hide')
|
||||
if (collapsed === null) collapsed = $next.hasClass('hide')
|
||||
$next.toggleClass('collapsed-hide')
|
||||
if (collapsed === null) collapsed = $next.hasClass('collapsed-hide')
|
||||
}
|
||||
this.setState({ collapsed })
|
||||
}
|
||||
|
|
|
@ -93,7 +93,6 @@ class EntityNew2 extends RbModalHandler {
|
|||
{this.state.entities &&
|
||||
this.state.entities.map((item) => {
|
||||
if (item.mainEntity) return null
|
||||
if (item.detailEntity && rb.commercial < 10) return null
|
||||
return (
|
||||
<option key={item.entityName} value={item.entityName}>
|
||||
{item.entityLabel}
|
||||
|
@ -270,7 +269,7 @@ class EntityNew2 extends RbModalHandler {
|
|||
location.href = `${rb.baseUrl}/admin/entity/${res.data}/base`
|
||||
} else {
|
||||
$btn.button('reset')
|
||||
RbHighbar.error(res.error_msg)
|
||||
RbHighbar.error(WrapHtml(res.error_msg))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -252,8 +252,9 @@ class ContentFieldWriteback extends ActionContentSpec {
|
|||
templateResult: function (res) {
|
||||
const text = res.text.split(' (N)')
|
||||
const $span = $('<span></span>').text(text[0])
|
||||
if (text.length > 1) $('<span class="badge badge-default badge-pill">N</span>').appendTo($span)
|
||||
else if (res.children && res.children.length > 0) $('<sup class="rbv ml-1"></sup>').appendTo($span)
|
||||
if (text.length > 1 || (res.children && res.children.length > 0)) {
|
||||
$('<span class="badge badge-default badge-pill">N</span>').appendTo($span)
|
||||
}
|
||||
return $span
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue