/*!
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.Entity;
import cn.devezhao.persist4j.Field;
import cn.devezhao.persist4j.Filter;
import cn.devezhao.persist4j.PersistManagerFactory;
import cn.devezhao.persist4j.Query;
import cn.devezhao.persist4j.Record;
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.ActionType;
import com.rebuild.core.service.trigger.RobotTriggerManager;
import com.rebuild.core.service.trigger.RobotTriggerManual;
import com.rebuild.core.service.trigger.RobotTriggerObserver;
import com.rebuild.core.service.trigger.TriggerAction;
import com.rebuild.core.service.trigger.TriggerWhen;
import com.rebuild.core.service.trigger.impl.AutoApproval;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.core.support.task.TaskExecutors;
import com.rebuild.utils.CommonsUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 业务实体核心服务,所有业务实体都应该使用此类(或子类)
* <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;
boolean lazyAutoTransformForDetails = false;
if (hasDetails) {
// fix: v3.2.2
TriggerAction[] hasAutoApprovalTriggers = getSpecTriggers(
record.getEntity(), ActionType.AUTOAPPROVAL, TriggerWhen.CREATE, TriggerWhen.UPDATE);
lazyAutoApprovalForDetails = hasAutoApprovalTriggers.length > 0;
// FIXME 此判断可能无意义,待进一步测试后确定是否保留
if (!lazyAutoApprovalForDetails) {
TriggerAction[] hasOnApprovedTriggers = getSpecTriggers(
record.getEntity().getDetailEntity(), null, TriggerWhen.APPROVED);
lazyAutoApprovalForDetails = hasOnApprovedTriggers.length > 0;
}
// 自动审批延迟执行,因为明细尚未保存好
if (lazyAutoApprovalForDetails) AutoApproval.setLazyAutoApproval();
TriggerAction[] hasAutoTransformTriggers = getSpecTriggers(
record.getEntity(), ActionType.AUTOTRANSFORM, TriggerWhen.CREATE, TriggerWhen.UPDATE);
lazyAutoTransformForDetails = hasAutoTransformTriggers.length > 0;
// 记录转换延迟执行,因为明细尚未保存好
if (lazyAutoTransformForDetails) CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.AutoTransform#setLazyAutoTransform");
}
try {
record = record.getPrimary() == null ? create(record) : update(record);
if (!hasDetails) return record;
// 主记录+明细记录处理
final String dtfField = 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(dtfField, mainid); // for check
List<Record> repeated = getAndCheckRepeated(d, 20);
if (!repeated.isEmpty()) {
throw new RepeatedRecordsException(repeated);
}
}
if (d.getPrimary() == null) {
d.setID(dtfField, mainid);
create(d);
} else {
update(d);
}
}
return record;
} finally {
if (lazyAutoApprovalForDetails) {
AutoApproval.executeLazyAutoApproval();
}
if (lazyAutoTransformForDetails) {
CommonsUtils.invokeMethod("com.rebuild.rbv.trigger.AutoTransform#executeLazyAutoTransform");
}
}
}
/**
* 优先使用 `#createOrUpdate(Record) `
*/
@Override
public Record create(Record record) {
appendDefaultValue(record);
checkModifications(record, BizzPermission.CREATE);
setSeriesValue(record);
return super.create(record);
}
/**
* 优先使用 `#createOrU
没有合适的资源?快使用搜索试试~ 我知道了~
RB企业管理系统 / rebuild-CRM-ERP-库存生产管理系统
共1023个文件
java:606个
js:131个
png:92个
需积分: 5 1 下载量 99 浏览量
2023-05-20
14:26:15
上传
评论
收藏 7.21MB RAR 举报
温馨提示
项目特色 REBUILD 通过创新的业务流程引擎帮助你快速搭建各类企业管理系统,全图形化配置无需了解技术。 REBUILD 侧重于业务需求实现,而非基础技术框架或项目启动模板,通过 REBUILD 可以真正实现零代码快速搭建!无需编程、无需编译代码,甚至无需了解任何技术。 V3.3 新特性 本次更新为你带来众多功能增强与优化。 [新增] 标签字段 [新增] 顶部一级菜单 [新增] 普通用户支持数据导入 [新增] 文件支持目录权限配置 [新增] 触发器字段聚合新增“连接”聚合方式(支持多引用字段) [新增] 触发器字段更新支持“源字段为空时置空目标字段”选项 [优化] 明细编辑支持一次选择多个记录并带入 [优化] 30+ 细节/BUG/安全性更新
资源推荐
资源详情
资源评论
收起资源包目录
RB企业管理系统 / rebuild-CRM-ERP-库存生产管理系统 (1023个子文件)
CODEOWNERS 24B
COMMERCIAL 178B
nginx-rebuild.conf 698B
rb-base.css 437KB
materialdesignicons.min.css 321KB
bootstrap.min.css 138KB
rb-page.css 88KB
material-design-iconic-font.min.css 69KB
animate.min.css 60KB
mprogress.min.css 24KB
view-page.css 17KB
select2.css 17KB
select2.min.css 15KB
approvals.css 12KB
feeds.css 12KB
bootstrap-datetimepicker.min.css 11KB
simplemde.min.css 11KB
gridstack.css 10KB
charts.css 10KB
triggers.css 10KB
bootstrap-slider.min.css 9KB
chart-design.css 8KB
introjs.min.css 8KB
form-design.css 6KB
project-tasks.css 6KB
task-view.css 5KB
dashboard.css 5KB
meta-edit.css 5KB
rebuild-tour.css 5KB
perfect-scrollbar.min.css 5KB
files.css 4KB
cropper.min.css 4KB
list-page.css 3KB
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 34KB
system-cfg.html 18KB
role-privileges.html 13KB
chart-design.html 13KB
trigger-design.html 12KB
user-settings.html 10KB
entity-advanced.html 9KB
data-imports-body.html 9KB
record-list.html 9KB
submail.html 9KB
detail-list.html 8KB
transform-design.html 8KB
login.html 8KB
project-editor.html 8KB
form-design.html 8KB
fields.html 7KB
entity-edit.html 7KB
record-view.html 7KB
nav-left-admin.html 7KB
entity-new.html 7KB
wxwork.html 6KB
home.html 6KB
messages.html 6KB
user-list.html 6KB
entity-overview.html 6KB
nav-top.html 6KB
entities.html 6KB
nav-settings.html 6KB
auto-fillin.html 5KB
project-tasks.html 5KB
forgot-passwd.html 5KB
dingtalk.html 5KB
detail-view.html 5KB
user-view.html 5KB
home.html 5KB
docs.html 5KB
dept-list.html 5KB
sso-saml.html 5KB
approval-list.html 4KB
server-status.html 4KB
storage-qiniu.html 4KB
report-templates.html 4KB
trigger-list.html 4KB
reference-search.html 4KB
install.html 4KB
entities-sheet.html 4KB
attachment.html 4KB
transform-list.html 4KB
team-view.html 4KB
field-new.html 3KB
approval-design.html 3KB
共 1023 条
- 1
- 2
- 3
- 4
- 5
- 6
- 11
资源评论
野生的狒狒
- 粉丝: 2503
- 资源: 2142
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功