mirror of
https://github.com/getrebuild/rebuild.git
synced 2025-03-13 07:33:18 +08:00
parent
49211c8e69
commit
d73df479b0
12 changed files with 103 additions and 64 deletions
|
@ -483,7 +483,7 @@ public class PrivilegesManager {
|
|||
* @param entry
|
||||
* @return
|
||||
* @see ZeroPrivileges
|
||||
* @see ZeroPermission
|
||||
* @see InternalPermission
|
||||
*/
|
||||
public boolean allow(ID user, ZeroEntry entry) {
|
||||
Boolean a = userAllow(user);
|
||||
|
@ -497,7 +497,7 @@ public class PrivilegesManager {
|
|||
}
|
||||
|
||||
if (role.hasPrivileges(entry.name())) {
|
||||
return role.getPrivileges(entry.name()).allowed(ZeroPermission.ZERO);
|
||||
return role.getPrivileges(entry.name()).allowed(InternalPermission.ZERO);
|
||||
}
|
||||
return entry.getDefaultVal();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,21 @@ import cn.devezhao.bizz.privileges.impl.BizzPermission;
|
|||
* @see BizzPermission
|
||||
* @since 10/12/2018
|
||||
*/
|
||||
public class ZeroPermission {
|
||||
public class InternalPermission {
|
||||
|
||||
/**
|
||||
* 扩展权限
|
||||
*/
|
||||
public static final Permission ZERO = new BizzPermission("ZERO", 0, true);
|
||||
|
||||
/**
|
||||
* 删除前触发的动作
|
||||
*/
|
||||
public static final Permission DELETE_BEFORE = new BizzPermission("DELETE_BEFORE", 0, false);
|
||||
|
||||
/**
|
||||
* 审批
|
||||
*/
|
||||
public static final Permission APPROVAL = new BizzPermission("APPROVAL", 0, false);
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ import com.rebuild.core.metadata.easymeta.DisplayType;
|
|||
import com.rebuild.core.metadata.easymeta.EasyField;
|
||||
import com.rebuild.core.metadata.easymeta.EasyMetaFactory;
|
||||
import com.rebuild.core.privileges.UserService;
|
||||
import com.rebuild.core.privileges.bizz.InternalPermission;
|
||||
import com.rebuild.core.privileges.bizz.User;
|
||||
import com.rebuild.core.service.BaseService;
|
||||
import com.rebuild.core.service.DataSpecificationException;
|
||||
|
@ -723,5 +724,9 @@ public class GeneralEntityService extends ObservableService implements EntitySer
|
|||
triggerManual.onApproved(
|
||||
OperatingContext.create(opUser, BizzPermission.UPDATE, before, approvalRecord));
|
||||
}
|
||||
|
||||
// 手动记录历史
|
||||
new RevisionHistoryObserver().onApprovalManual(
|
||||
OperatingContext.create(opUser, InternalPermission.APPROVAL, before, approvalRecord));
|
||||
}
|
||||
}
|
|
@ -7,7 +7,6 @@ See LICENSE and COMMERCIAL in the project root for license information.
|
|||
|
||||
package com.rebuild.core.service.general;
|
||||
|
||||
import cn.devezhao.bizz.privileges.Permission;
|
||||
import cn.devezhao.bizz.privileges.impl.BizzPermission;
|
||||
import cn.devezhao.persist4j.PersistManagerFactory;
|
||||
import cn.devezhao.persist4j.Record;
|
||||
|
@ -15,6 +14,7 @@ import cn.devezhao.persist4j.engine.ID;
|
|||
import com.rebuild.core.Application;
|
||||
import com.rebuild.core.UserContextHolder;
|
||||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.privileges.bizz.InternalPermission;
|
||||
import com.rebuild.core.service.BaseService;
|
||||
import com.rebuild.core.service.NoRecordFoundException;
|
||||
import com.rebuild.core.service.ServiceSpec;
|
||||
|
@ -36,11 +36,6 @@ import java.util.*;
|
|||
@Slf4j
|
||||
public abstract class ObservableService extends Observable implements ServiceSpec {
|
||||
|
||||
/**
|
||||
* 删除前触发的动作
|
||||
*/
|
||||
public static final Permission DELETE_BEFORE = new BizzPermission("DELETE_BEFORE", 0, false);
|
||||
|
||||
final protected ServiceSpec delegateService;
|
||||
|
||||
/**
|
||||
|
@ -100,7 +95,7 @@ public abstract class ObservableService extends Observable implements ServiceSpe
|
|||
|
||||
// 删除前触发,做一些状态保持
|
||||
setChanged();
|
||||
notifyObservers(OperatingContext.create(currentUser, DELETE_BEFORE, deleted, null));
|
||||
notifyObservers(OperatingContext.create(currentUser, InternalPermission.DELETE_BEFORE, deleted, null));
|
||||
}
|
||||
|
||||
int affected = delegateService.delete(recordId);
|
||||
|
|
|
@ -9,6 +9,7 @@ package com.rebuild.core.service.general;
|
|||
|
||||
import cn.devezhao.bizz.privileges.impl.BizzPermission;
|
||||
import cn.devezhao.commons.ThreadPool;
|
||||
import com.rebuild.core.privileges.bizz.InternalPermission;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Observable;
|
||||
|
@ -52,7 +53,7 @@ public abstract class OperatingObserver implements Observer {
|
|||
onCreate(ctx);
|
||||
} else if (ctx.getAction() == BizzPermission.UPDATE) {
|
||||
onUpdate(ctx);
|
||||
} else if (ctx.getAction() == ObservableService.DELETE_BEFORE) {
|
||||
} else if (ctx.getAction() == InternalPermission.DELETE_BEFORE) {
|
||||
onDeleteBefore(ctx);
|
||||
} else if (ctx.getAction() == BizzPermission.DELETE) {
|
||||
onDelete(ctx);
|
||||
|
|
|
@ -135,7 +135,7 @@ public class RecordDifference {
|
|||
|| EntityHelper.CreatedOn.equalsIgnoreCase(fieldName)
|
||||
|| EntityHelper.CreatedBy.equalsIgnoreCase(fieldName)
|
||||
|| EntityHelper.QuickCode.equalsIgnoreCase((fieldName))
|
||||
|| MetadataHelper.isApprovalField(fieldName)
|
||||
|| (MetadataHelper.isApprovalField(fieldName) && !EntityHelper.ApprovalState.equalsIgnoreCase(fieldName))
|
||||
|| field.getType() == FieldType.PRIMARY;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ import com.rebuild.core.Application;
|
|||
import com.rebuild.core.metadata.EntityHelper;
|
||||
import com.rebuild.core.metadata.MetadataHelper;
|
||||
import com.rebuild.core.privileges.UserService;
|
||||
import com.rebuild.core.privileges.bizz.InternalPermission;
|
||||
import com.rebuild.core.service.approval.ApprovalState;
|
||||
import com.rebuild.core.service.general.recyclebin.RecycleBinCleanerJob;
|
||||
import com.rebuild.core.service.trigger.RobotTriggerObserver;
|
||||
import com.rebuild.core.service.trigger.TriggerSource;
|
||||
|
@ -37,18 +39,12 @@ public class RevisionHistoryObserver extends OperatingObserver {
|
|||
// 激活
|
||||
if (RecycleBinCleanerJob.isEnableRevisionHistory()) {
|
||||
super.updateByAction(ctx);
|
||||
} else if (ctx.getAction() != ObservableService.DELETE_BEFORE) {
|
||||
} else if (ctx.getAction() != InternalPermission.DELETE_BEFORE) {
|
||||
log.warn("RevisionHistory inactivated! {} {} by {}",
|
||||
ctx.getAction().getName(), ctx.getAnyRecord().getPrimary(), ctx.getOperator());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略的
|
||||
*
|
||||
* @param ctx
|
||||
* @return
|
||||
*/
|
||||
private boolean isIgnore(OperatingContext ctx) {
|
||||
int entity = ctx.getAnyRecord().getEntity().getEntityCode();
|
||||
return entity == EntityHelper.FeedsComment || entity == EntityHelper.ProjectTaskComment;
|
||||
|
@ -139,7 +135,22 @@ public class RevisionHistoryObserver extends OperatingObserver {
|
|||
return record;
|
||||
}
|
||||
|
||||
// TODO 异步无法获知是否关联操作
|
||||
/**
|
||||
* 审批通过/撤销
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void onApprovalManual(OperatingContext context) {
|
||||
Record revision = newRevision(context, true);
|
||||
if (context.getAfterRecord().getInt(EntityHelper.ApprovalState) == ApprovalState.APPROVED.getState()) {
|
||||
revision.setInt("revisionType", 991);
|
||||
} else {
|
||||
revision.setInt("revisionType", 992);
|
||||
}
|
||||
Application.getCommonsService().create(revision);
|
||||
}
|
||||
|
||||
// FIXME 异步无法获知是否关联操作
|
||||
@Override
|
||||
protected boolean isAsync() {
|
||||
return false;
|
||||
|
|
|
@ -327,9 +327,7 @@ public class QiniuCloud {
|
|||
*/
|
||||
public static long getStorageSize() {
|
||||
Long size = (Long) Application.getCommonsCache().getx("_StorageSize");
|
||||
if (size != null) {
|
||||
return size;
|
||||
}
|
||||
if (size != null) return size;
|
||||
|
||||
if (QiniuCloud.instance().available()) {
|
||||
size = QiniuCloud.instance().stats();
|
||||
|
|
|
@ -84,12 +84,18 @@ public class ConfigurationController extends BaseController {
|
|||
return RespBody.errorl("无效主页地址/域名");
|
||||
}
|
||||
|
||||
String dPortalOfficePreviewUrl = defaultIfBlank(data, ConfigurationItem.PortalOfficePreviewUrl);
|
||||
if (StringUtils.isNotBlank(dPortalOfficePreviewUrl) && !RegexUtils.isUrl(dPortalOfficePreviewUrl)) {
|
||||
return RespBody.errorl("无效文档预览服务地址");
|
||||
}
|
||||
|
||||
// 验证数字参数
|
||||
ConfigurationItem[] validNumbers = new ConfigurationItem[] {
|
||||
ConfigurationItem.RecycleBinKeepingDays,
|
||||
ConfigurationItem.RevisionHistoryKeepingDays,
|
||||
ConfigurationItem.DBBackupsKeepingDays,
|
||||
ConfigurationItem.PasswordExpiredDays
|
||||
ConfigurationItem.PasswordExpiredDays,
|
||||
ConfigurationItem.PortalUploadMaxSize,
|
||||
};
|
||||
for (ConfigurationItem item : validNumbers) {
|
||||
String number = defaultIfBlank(data, item);
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
.syscfg.edit a.img-thumbnail:hover b {
|
||||
display: inline-block;
|
||||
}
|
||||
.syscfg a[target='_blank']:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.bgimg-img {
|
||||
display: inline-block;
|
||||
|
@ -93,22 +96,23 @@
|
|||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[[${bundle.L('主页地址/域名')}]]
|
||||
<p>[[${bundle.L('所有外部链接将以此作为前缀')}]]</p>
|
||||
</td>
|
||||
<td data-id="HomeURL" th:data-value="${HomeURL}">[[${HomeURL}]]</td>
|
||||
<td>[[${bundle.L('主页地址/域名')}]]</td>
|
||||
<td data-id="HomeURL" th:data-value="${HomeURL}" th:data-form-text="${bundle.L('所有外部链接将以此作为前缀')}">[[${HomeURL}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('默认语言')}]]</td>
|
||||
<td data-id="DefaultLanguage" th:data-value="${DefaultLanguage}" id="_DefaultLanguage">[[${DefaultLanguage}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[[${bundle.L('页脚')}]]
|
||||
<p class="link">[(${bundle.L('仅适用于外部页面,支持 [MD 语法](https://getrebuild.com/docs/markdown-guide#%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95)')})]</p>
|
||||
<td>[[${bundle.L('页脚')}]]</td>
|
||||
<td
|
||||
data-id="PageFooter"
|
||||
th:data-value="${PageFooter}"
|
||||
data-optional="true"
|
||||
th:data-form-text="${bundle.L('仅适用于外部页面,支持 [MD 语法](https://getrebuild.com/docs/markdown-guide#%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95)')}"
|
||||
>
|
||||
<pre class="unstyle">[[${PageFooter ?:bundle.L('无')}]]</pre>
|
||||
</td>
|
||||
<td data-id="PageFooter" th:data-value="${PageFooter}" data-optional="true"><pre class="unstyle">[[${PageFooter ?:bundle.L('无')}]]</pre></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('登录页每日一图')}]]</td>
|
||||
|
@ -139,11 +143,14 @@
|
|||
<td data-id="FileSharable" th:data-value="${FileSharable}">[[${FileSharable ? bundle.L('是') : bundle.L('否')}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
[[${bundle.L('公开注册')}]]
|
||||
<p class="link">[(${bundle.L('允许用户 [自助注册](https://getrebuild.com/docs/admin/users#3.%20%E8%87%AA%E5%8A%A9%E6%B3%A8%E5%86%8C)')})]</p>
|
||||
<td>[[${bundle.L('公开注册')}]]</td>
|
||||
<td
|
||||
data-id="OpenSignUp"
|
||||
th:data-value="${OpenSignUp}"
|
||||
th:data-form-text="${bundle.L('允许用户 [自助注册](https://getrebuild.com/docs/admin/users#3.%20%E8%87%AA%E5%8A%A9%E6%B3%A8%E5%86%8C)')}"
|
||||
>
|
||||
[[${OpenSignUp ? bundle.L('是') : bundle.L('否')}]]
|
||||
</td>
|
||||
<td data-id="OpenSignUp" th:data-value="${OpenSignUp}">[[${OpenSignUp ? bundle.L('是') : bundle.L('否')}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('登录验证码显示模式')}]]</td>
|
||||
|
@ -169,7 +176,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('启用两步验证')}]] <sup class="rbv"></sup></td>
|
||||
<td th:data-id="${commercial > 1 ? 'Login2FAMode' : ''}" th:data-value="${Login2FAMode}" th:data-form-text="${bundle.L('请确保邮件/短信配置正确,否则无法发送/接收验证码,导致无法登录')}">
|
||||
<td
|
||||
th:data-id="${commercial > 1 ? 'Login2FAMode' : ''}"
|
||||
th:data-value="${Login2FAMode}"
|
||||
th:data-form-text="${bundle.L('请确保邮件/短信配置正确,否则无法发送/接收验证码,导致无法登录')}"
|
||||
>
|
||||
<th:block th:if="${Login2FAMode == '0'}">[[${bundle.L('不启用')}]]</th:block>
|
||||
<th:block th:if="${Login2FAMode == '1'}">[[${bundle.L('手机或邮箱')}]]</th:block>
|
||||
<th:block th:if="${Login2FAMode == '2'}">[[${bundle.L('仅手机')}]]</th:block>
|
||||
|
@ -197,40 +208,33 @@
|
|||
>
|
||||
<pre class="unstyle">[[${AllowUsesIp ?:bundle.L('不限')}]]</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="bosskey-show">
|
||||
<td>[[${bundle.L('同一用户允许多地登录')}]] <sup class="rbv"></sup></td>
|
||||
<td th:data-id="${commercial > 0 ? 'MultipleSessions' : ''}" th:data-value="${MultipleSessions}">[[${MultipleSessions ? bundle.L('是') : bundle.L('否')}]]</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h5>[[${bundle.L('数据安全')}]]</h5>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="40%">
|
||||
[[${bundle.L('数据自动备份')}]]
|
||||
<p>[[${bundle.L('每日 0 点备份到数据目录,请预留足够磁盘空间')}]]</p>
|
||||
<td width="40%">[[${bundle.L('数据自动备份')}]]</td>
|
||||
<td data-id="DBBackupsEnable" th:data-value="${DBBackupsEnable}" th:data-form-text="${bundle.L('每日 0 点备份到数据目录,请预留足够磁盘空间')}">
|
||||
[[${DBBackupsEnable ? bundle.L('是') : bundle.L('否')}]]
|
||||
</td>
|
||||
<td data-id="DBBackupsEnable" th:data-value="${DBBackupsEnable}">[[${DBBackupsEnable ? bundle.L('是') : bundle.L('否')}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('备份保留时间')}]]</td>
|
||||
<td data-id="DBBackupsKeepingDays" th:data-value="${DBBackupsKeepingDays}">
|
||||
[[${DBBackupsKeepingDays}]] [[${bundle.L('天')}]]
|
||||
</td>
|
||||
<td data-id="DBBackupsKeepingDays" th:data-value="${DBBackupsKeepingDays}">[[${DBBackupsKeepingDays}]] [[${bundle.L('天')}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('变更历史保留时间')}]]</td>
|
||||
<td data-id="RevisionHistoryKeepingDays" th:data-value="${RevisionHistoryKeepingDays}">
|
||||
[[${RevisionHistoryKeepingDays}]] [[${bundle.L('天')}]]
|
||||
</td>
|
||||
<td data-id="RevisionHistoryKeepingDays" th:data-value="${RevisionHistoryKeepingDays}">[[${RevisionHistoryKeepingDays}]] [[${bundle.L('天')}]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>[[${bundle.L('回收站保留时间')}]]</td>
|
||||
<td data-id="RecycleBinKeepingDays" th:data-value="${RecycleBinKeepingDays}">
|
||||
[[${RecycleBinKeepingDays}]] [[${bundle.L('天')}]]
|
||||
</td>
|
||||
<td data-id="RecycleBinKeepingDays" th:data-value="${RecycleBinKeepingDays}">[[${RecycleBinKeepingDays}]] [[${bundle.L('天')}]]</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -241,6 +245,18 @@
|
|||
<td width="40%">[[${bundle.L('在视图页显示修改历史')}]]</td>
|
||||
<td data-id="ShowViewHistory" th:data-value="${ShowViewHistory}">[[${ShowViewHistory ? bundle.L('是') : bundle.L('否')}]]</td>
|
||||
</tr>
|
||||
<tr class="bosskey-show">
|
||||
<td>[[${bundle.L('文件上传大小限制')}]]</td>
|
||||
<td data-id="PortalUploadMaxSize" th:data-value="${PortalUploadMaxSize}" data-optional="true">[[${PortalUploadMaxSize}]] MB</td>
|
||||
</tr>
|
||||
<tr class="bosskey-show">
|
||||
<td>[[${bundle.L('文档预览服务地址')}]]</td>
|
||||
<td data-id="PortalOfficePreviewUrl" th:data-value="${PortalOfficePreviewUrl}" data-optional="true">[[${PortalOfficePreviewUrl ?:bundle.L('默认')}]]</td>
|
||||
</tr>
|
||||
<tr class="bosskey-show">
|
||||
<td>[[${bundle.L('百度地图 AK')}]]</td>
|
||||
<td data-id="PortalBaiduMapAk" th:data-value="${PortalBaiduMapAk}" data-optional="true">[[${PortalBaiduMapAk ?:bundle.L('默认')}]]</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="edit-footer">
|
||||
|
|
|
@ -46,6 +46,8 @@ const RevTypes = {
|
|||
16: $L('分派'),
|
||||
32: $L('共享'),
|
||||
64: $L('取消共享'),
|
||||
991: $L('审批通过'),
|
||||
992: $L('审批撤销')
|
||||
}
|
||||
|
||||
class DataList extends React.Component {
|
||||
|
|
|
@ -514,11 +514,11 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
)
|
||||
})
|
||||
} else {
|
||||
this.post2(state, null, true)
|
||||
this.post2(state, null)
|
||||
}
|
||||
}
|
||||
|
||||
post2(state, rejectNode, showAlert) {
|
||||
post2(state, rejectNode) {
|
||||
const aformData = {}
|
||||
if (this.state.aform && state === 10) {
|
||||
const fd = this._rbform.__FormData
|
||||
|
@ -563,16 +563,7 @@ class ApprovalApproveForm extends ApprovalUsersForm {
|
|||
})
|
||||
}
|
||||
|
||||
if (showAlert) {
|
||||
RbAlert.create(state === 11 ? $L('确认驳回此审批?') : $L('确认同意此审批?'), {
|
||||
onConfirm: function () {
|
||||
this.hide()
|
||||
fn()
|
||||
},
|
||||
})
|
||||
} else {
|
||||
fn()
|
||||
}
|
||||
fn()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue