/*!
Copyright (c) REBUILD <https://getrebuild.com/> and/or its owners. All rights reserved.
rebuild is dual-licensed under commercial and open source licenses (GPLv3).
See LICENSE and COMMERCIAL in the project root for license information.
*/
package com.rebuild.core.service.general;
import cn.devezhao.bizz.privileges.Permission;
import cn.devezhao.bizz.privileges.impl.BizzPermission;
import cn.devezhao.persist4j.*;
import cn.devezhao.persist4j.engine.ID;
import com.rebuild.core.Application;
import com.rebuild.core.RebuildException;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.metadata.DeleteRecord;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.metadata.MetadataSorter;
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;
import com.rebuild.core.service.NoRecordFoundException;
import com.rebuild.core.service.approval.ApprovalHelper;
import com.rebuild.core.service.approval.ApprovalState;
import com.rebuild.core.service.general.recyclebin.RecycleStore;
import com.rebuild.core.service.general.series.SeriesGeneratorFactory;
import com.rebuild.core.service.notification.NotificationObserver;
import com.rebuild.core.service.query.QueryHelper;
import com.rebuild.core.service.trigger.*;
import com.rebuild.core.service.trigger.impl.AutoApproval;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.core.support.task.TaskExecutors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.*;
/**
* 业务实体核心服务,所有业务实体都应该使用此类(或子类)
* <br>- 有业务验证
* <br>- 会带有系统设置规则的执行
* <br>- 会开启一个事务,详见 <tt>application-bean.xml</tt> 配置
*
* <p>如有需要,其他实体可根据自身业务继承并复写</p>
*
* FIXME 删除主记录时会关联删除明细记录(持久层实现),但明细记录不会触发业务规则
*
* @author Zixin (RB)
* @since 11/06/2017
*/
@Slf4j
@Service
public class GeneralEntityService extends ObservableService implements EntityService {
// 有明细
public static final String HAS_DETAILS = "$DETAILS$";
protected GeneralEntityService(PersistManagerFactory aPMFactory) {
super(aPMFactory);
// 通知
addObserver(new NotificationObserver());
// 触发器
addObserver(new RobotTriggerObserver());
}
@Override
public int getEntityCode() {
return 0;
}
// 此方法具备明细实体批处理能力
// 此方法具备重复检查能力
@Override
public Record createOrUpdate(Record record) {
@SuppressWarnings("unchecked")
final List<Record> details = (List<Record>) record.removeValue(HAS_DETAILS);
final int rcm = GeneralEntityServiceContextHolder.getRepeatedCheckModeOnce();
if (rcm == GeneralEntityServiceContextHolder.RCM_CHECK_MAIN
|| rcm == GeneralEntityServiceContextHolder.RCM_CHECK_ALL) {
List<Record> repeated = getAndCheckRepeated(record, 20);
if (!repeated.isEmpty()) {
throw new RepeatedRecordsException(repeated);
}
}
// 含明细
final boolean hasDetails = details != null && !details.isEmpty();
boolean lazyAutoApprovalForDetails = false;
if (hasDetails) {
TriggerAction[] hasTriggers = getSpecTriggers(
record.getEntity().getDetailEntity(), null, TriggerWhen.APPROVED);
lazyAutoApprovalForDetails = hasTriggers.length > 0;
// 自动审批延迟执行,因为明细尚未保存好
if (lazyAutoApprovalForDetails) AutoApproval.setLazyAutoApproval();
}
try {
record = super.createOrUpdate(record);
if (!hasDetails) return record;
// 主记录+明细记录处理
final String dtf = MetadataHelper.getDetailToMainField(record.getEntity().getDetailEntity()).getName();
final ID mainid = record.getPrimary();
final boolean checkDetailsRepeated = rcm == GeneralEntityServiceContextHolder.RCM_CHECK_DETAILS
|| rcm == GeneralEntityServiceContextHolder.RCM_CHECK_ALL;
// 先删除
for (Record d : details) {
if (d instanceof DeleteRecord) delete(d.getPrimary());
}
// 再保存
for (Record d : details) {
if (d instanceof DeleteRecord) continue;
if (checkDetailsRepeated) {
d.setID(dtf, mainid); // for check
List<Record> repeated = getAndCheckRepeated(d, 20);
if (!repeated.isEmpty()) {
throw new RepeatedRecordsException(repeated);
}
}
if (d.getPrimary() == null) {
d.setID(dtf, mainid);
create(d);
} else {
update(d);
}
}
return record;
} finally {
if (lazyAutoApprovalForDetails) {
AutoApproval.executeLazyAutoApproval();
}
}
}
@Override
public Record create(Record record) {
appendDefaultValue(record);
checkModifications(record, BizzPermission.CREATE);
setSeriesValue(record);
return super.create(record);
}
@Override
public Record update(Record record) {
if (!checkModifications(record, BizzPermission.UPDATE)) {
return record;
}
// 先更新
record = super.update(record);
// 主记录修改时传导给明细(若有),以便触发分组聚合触发器
// FIXME 此时明细可能尚未做好更新,因此是无意义的更新
TriggerAction[] hasTriggers = getSpecTriggers(record.getEntity().getDetailEntity(),
ActionType.GROUPAGGREGATION, TriggerWhen.UPDATE);
if (hasTriggers.length > 0) {
RobotTriggerManual triggerManual = new RobotTriggerManual();
ID opUser = UserService.SYSTEM_USER;
for (ID did : QueryHelper.detailIdsNoFilter(record.getPrimary())) {
Record dUpdate = EntityHelper.forUpdate(did, opUser, false);
triggerManual.onUpdate(
OperatingContext.create(opUser, BizzPermission.UPDATE, dUpdate, dUpdate));
}
}
return record;
}
@Override
public int delete(ID record) {
return delete(record, null);
}
@Override
public int delete(ID record, String[] cascades) {
final ID currentUser = UserContextHolder.getUser();
final RecycleStore recycleBin = useRecycleStore(record);
this.deleteInternal(record);
int affected = 1;
Map<String, Set<ID>> recordsOfCascaded = getCascadedRecords(record, cascades, BizzPermission.DELETE);
for (Map.Entry<String, Set<ID>> e : recordsOfCascaded.entrySet()) {
log.info("Cascading delete - {} > {} ", e.getKey(), e.getValue());
for (ID id : e.getValue()) {
if (Application.getPrivilegesManager().allowDelete(currentUser, id)) {
if (recycleBin != null) recycleBin.add(id, record);
int deleted = 0;
try {
deleted = this.deleteInternal(id);
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
rebuild-master.zip (995个子文件)
CODEOWNERS 24B
COMMERCIAL 178B
nginx-rebuild.conf 647B
rb-base.css 437KB
materialdesignicons.min.css 321KB
bootstrap.min.css 138KB
rb-page.css 84KB
material-design-iconic-font.min.css 69KB
animate.min.css 60KB
mprogress.min.css 24KB
select2.css 17KB
view-page.css 16KB
select2.min.css 15KB
approvals.css 12KB
feeds.css 12KB
bootstrap-datetimepicker.min.css 11KB
simplemde.min.css 11KB
gridstack.css 10KB
bootstrap-slider.min.css 9KB
triggers.css 9KB
charts.css 8KB
introjs.min.css 8KB
chart-design.css 8KB
form-design.css 6KB
project-tasks.css 6KB
task-view.css 5KB
dashboard.css 5KB
perfect-scrollbar.min.css 5KB
meta-edit.css 4KB
files.css 4KB
cropper.min.css 4KB
rebuild-tour.css 2KB
jquery-ui.min.css 2KB
classification.css 2KB
dataimports-test.csv 770B
materialdesignicons-webfont.eot 1.19MB
Material-Design-Iconic-Font.eot 41KB
spring.factories 99B
rb-loading.gif 7KB
role_1.gif 159B
role_2.gif 154B
role_0.gif 153B
role_3.gif 152B
role_4.gif 110B
s.gif 43B
.gitattributes 93B
.gitignore 466B
preview.html 520KB
field-edit.html 30KB
system-cfg.html 18KB
role-privileges.html 13KB
chart-design.html 12KB
trigger-design.html 12KB
data-imports.html 10KB
user-settings.html 10KB
entity-advanced.html 9KB
record-list.html 9KB
detail-list.html 9KB
submail.html 8KB
transform-editor.html 8KB
login.html 8KB
entity-edit.html 8KB
project-editor.html 8KB
record-view.html 8KB
fields.html 7KB
form-design.html 7KB
nav-left-admin.html 7KB
entity-new.html 7KB
home.html 6KB
wxwork.html 6KB
messages.html 6KB
entity-overview.html 6KB
entities.html 6KB
user-list.html 6KB
nav-top.html 6KB
project-tasks.html 5KB
auto-fillin.html 5KB
forgot-passwd.html 5KB
dingtalk.html 5KB
nav-settings.html 5KB
detail-view.html 5KB
docs.html 5KB
user-view.html 5KB
home.html 5KB
dept-list.html 5KB
sso-saml.html 5KB
show-fields.html 4KB
server-status.html 4KB
storage-qiniu.html 4KB
report-templates.html 4KB
attachment.html 4KB
trigger-list.html 4KB
team-view.html 4KB
transform-list.html 4KB
reference-search.html 4KB
approval-list.html 4KB
field-new.html 3KB
team-list.html 3KB
install.html 3KB
header.html 3KB
共 995 条
- 1
- 2
- 3
- 4
- 5
- 6
- 10
资源评论
m0_72731342
- 粉丝: 2
- 资源: 1832
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功