diff --git a/flyfish-approval/pom.xml b/flyfish-approval/pom.xml
new file mode 100644
index 0000000..a44af21
--- /dev/null
+++ b/flyfish-approval/pom.xml
@@ -0,0 +1,30 @@
+
+
+
+ flyfish-framework
+ com.flyfish.framework
+ 0.0.1-SNAPSHOT
+
+ 4.0.0
+
+ flyfish-approval
+
+
+ 8
+ 8
+
+
+
+
+ org.springframework.data
+ spring-data-mongodb
+
+
+ com.flyfish.framework
+ flyfish-web
+ ${project.version}
+
+
+
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/auditor/ApproveRecordAuditor.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/auditor/ApproveRecordAuditor.java
new file mode 100644
index 0000000..928bff3
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/auditor/ApproveRecordAuditor.java
@@ -0,0 +1,26 @@
+package com.flyfish.framework.approval.auditor;
+
+import com.flyfish.framework.approval.domain.record.ApproveRecord;
+import com.flyfish.framework.auditor.ReactiveBeanAuditor;
+import org.springframework.stereotype.Component;
+import reactor.core.publisher.Mono;
+
+@Component
+public class ApproveRecordAuditor implements ReactiveBeanAuditor {
+
+ /**
+ * 对实体进行审查,并补全相关字段
+ *
+ * @param data 原数据
+ * @return 结果
+ */
+ @Override
+ public Mono audit(ApproveRecord data) {
+ if (null != data.getAction()) {
+ if (null == data.getApproved()) {
+ data.setApproved(true);
+ }
+ }
+ return Mono.just(data);
+ }
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/controller/ApproveRecordController.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/controller/ApproveRecordController.java
new file mode 100644
index 0000000..0e3b4ff
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/controller/ApproveRecordController.java
@@ -0,0 +1,75 @@
+package com.flyfish.framework.approval.controller;
+
+import com.flyfish.framework.approval.domain.ApprovalDomain;
+import com.flyfish.framework.approval.domain.record.ApproveRecord;
+import com.flyfish.framework.approval.domain.record.ApproveRecordListVo;
+import com.flyfish.framework.approval.domain.record.ApproveRecordQo;
+import com.flyfish.framework.approval.domain.todo.ApprovalListVo;
+import com.flyfish.framework.approval.service.ModuleDelegateService;
+import com.flyfish.framework.bean.Result;
+import com.flyfish.framework.configuration.annotations.CurrentUser;
+import com.flyfish.framework.configuration.annotations.PagedQuery;
+import com.flyfish.framework.controller.reactive.ReactiveBaseController;
+import com.flyfish.framework.domain.base.Vo;
+import com.flyfish.framework.domain.po.User;
+import org.springframework.web.bind.annotation.*;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 审批记录控制器
+ *
+ * @author wangyu
+ */
+@RestController
+@RequestMapping("approves")
+public class ApproveRecordController extends ReactiveBaseController {
+
+ @Resource
+ private ModuleDelegateService moduleDelegateService;
+
+ /**
+ * 查询视图
+ *
+ * @return 结果
+ */
+ @GetMapping("records")
+ public Mono>>> views(@PagedQuery ApproveRecordQo qo) {
+ return reactiveService.getPageList(qo)
+ .map(Result::accept)
+ .map(result -> result.mapList((ApproveRecord item) -> new ApproveRecordListVo().from(item)));
+ }
+
+ /**
+ * 查询待办列表
+ *
+ * @param qo 查询实体
+ * @param user 用户
+ * @return 结果
+ */
+ @GetMapping("todos")
+ public Mono>>> todos(@PagedQuery ApproveRecordQo qo, @CurrentUser User user) {
+ qo.setApprover(user.getId());
+ qo.setApproved(false);
+ return reactiveService.getPageList(qo)
+ .map(Result::accept)
+ .map(result -> result.mapList((ApproveRecord item) -> new ApprovalListVo().from(item)));
+ }
+
+ /**
+ * 通用审批
+ *
+ * @param module 模块
+ * @param dataId 数据id
+ * @return 结果
+ */
+ @PostMapping("approval/{module}/{dataId}")
+ public Mono> approval(@PathVariable String module, @PathVariable String dataId,
+ @RequestBody ApproveRecord record) {
+ record.setModule(module);
+ record.setDataId(dataId);
+ return moduleDelegateService.approval(record).map(Result::ok);
+ }
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomain.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomain.java
new file mode 100644
index 0000000..47d3a5f
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/ApprovalDomain.java
@@ -0,0 +1,27 @@
+package com.flyfish.framework.approval.domain;
+
+import com.flyfish.framework.approval.enums.ApproveStatus;
+import com.flyfish.framework.domain.authorized.AuthorizedDomain;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * 审批支持,必然是带权限的实体
+ *
+ * @author wangyu
+ */
+@Getter
+@Setter
+public abstract class ApprovalDomain extends AuthorizedDomain {
+
+ // 审批状态
+ private ApproveStatus approveStatus;
+
+ // 审批人,按序依次审批
+ private List approvers;
+
+ // 下个审批人
+ private String nextApprover;
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java
new file mode 100644
index 0000000..e099c08
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecord.java
@@ -0,0 +1,39 @@
+package com.flyfish.framework.approval.domain.record;
+
+import com.flyfish.framework.approval.enums.ApproveAction;
+import com.flyfish.framework.domain.base.AuditDomain;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+/**
+ * 审批记录
+ *
+ * @author wangyu
+ */
+@Document(collection = "approve-records")
+@Getter
+@Setter
+public class ApproveRecord extends AuditDomain {
+
+ // 是否已审批
+ private Boolean approved;
+
+ // 模块
+ private String module;
+
+ // 模块名称
+ private String moduleName;
+
+ // 数据id
+ private String dataId;
+
+ // 审批人
+ private String approver;
+
+ // 审批动作
+ private ApproveAction action;
+
+ // 审批意见
+ private String opinion;
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordListVo.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordListVo.java
new file mode 100644
index 0000000..0dc87e4
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordListVo.java
@@ -0,0 +1,41 @@
+package com.flyfish.framework.approval.domain.record;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.flyfish.framework.domain.base.Vo;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 审批记录列表vo
+ *
+ * @author wangyu
+ */
+@Data
+public class ApproveRecordListVo implements Vo {
+
+ private String id;
+
+ private String name;
+
+ private String approver;
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+ private Date approveTime;
+
+ private String action;
+
+ private String opinion;
+
+ @Override
+ public Vo from(ApproveRecord po) {
+ ApproveRecordListVo vo = new ApproveRecordListVo();
+ vo.setId(po.getId());
+ vo.setName(po.getName());
+ vo.setApprover(po.getModifier());
+ vo.setApproveTime(po.getModifyTime());
+ vo.setAction(po.getAction().getName());
+ vo.setOpinion(po.getOpinion());
+ return vo;
+ }
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java
new file mode 100644
index 0000000..c253845
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/record/ApproveRecordQo.java
@@ -0,0 +1,33 @@
+package com.flyfish.framework.approval.domain.record;
+
+import com.flyfish.framework.builder.CriteriaBuilder;
+import com.flyfish.framework.domain.base.NameLikeQo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 审批记录查询实体
+ *
+ * @author wangyu
+ */
+@Getter
+@Setter
+public class ApproveRecordQo extends NameLikeQo {
+
+ // 所属模块
+ private String module;
+
+ // 所属数据id
+ private String dataId;
+
+ // 是否审批
+ private Boolean approved;
+
+ // 审批人
+ private String approver;
+
+ @Override
+ public CriteriaBuilder criteriaBuilder() {
+ return super.criteriaBuilder().with("module", "dataId", "approved", "approver");
+ }
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/todo/ApprovalListVo.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/todo/ApprovalListVo.java
new file mode 100644
index 0000000..70ee8c2
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/domain/todo/ApprovalListVo.java
@@ -0,0 +1,42 @@
+package com.flyfish.framework.approval.domain.todo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.flyfish.framework.approval.domain.record.ApproveRecord;
+import com.flyfish.framework.domain.base.Vo;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 待审批列表vo
+ *
+ * @author wangyu
+ */
+@Data
+public class ApprovalListVo implements Vo {
+
+ private String id;
+
+ private String module;
+
+ private String moduleName;
+
+ private String dataId;
+
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
+ private Date createTime;
+
+ private String creator;
+
+ @Override
+ public Vo from(ApproveRecord po) {
+ ApprovalListVo vo = new ApprovalListVo();
+ vo.setId(po.getId());
+ vo.setCreator(po.getCreator());
+ vo.setCreateTime(po.getCreateTime());
+ vo.setModule(po.getModule());
+ vo.setModuleName(po.getModuleName());
+ vo.setDataId(po.getDataId());
+ return vo;
+ }
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/enums/ApproveAction.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/enums/ApproveAction.java
new file mode 100644
index 0000000..105344d
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/enums/ApproveAction.java
@@ -0,0 +1,14 @@
+package com.flyfish.framework.approval.enums;
+
+import com.flyfish.framework.enums.NamedEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@Getter
+@AllArgsConstructor
+public enum ApproveAction implements NamedEnum {
+
+ AGREE("同意"), REJECT("驳回"), REJECT_ALL("驳回到发起人");
+
+ private final String name;
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/enums/ApproveStatus.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/enums/ApproveStatus.java
new file mode 100644
index 0000000..48d8958
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/enums/ApproveStatus.java
@@ -0,0 +1,18 @@
+package com.flyfish.framework.approval.enums;
+
+import com.flyfish.framework.enums.NamedEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 审批状态
+ * @author wangyu
+ */
+@Getter
+@AllArgsConstructor
+public enum ApproveStatus implements NamedEnum {
+
+ PENDING("待审批"), APPROVING("审批中"), APPROVED("已审批"), REJECTED("已拒绝");
+
+ private final String name;
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/repository/ApproveRecordRepository.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/repository/ApproveRecordRepository.java
new file mode 100644
index 0000000..fc16cc5
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/repository/ApproveRecordRepository.java
@@ -0,0 +1,11 @@
+package com.flyfish.framework.approval.repository;
+
+import com.flyfish.framework.approval.domain.record.ApproveRecord;
+import com.flyfish.framework.repository.DefaultReactiveRepository;
+
+/**
+ * 审批记录仓库
+ * @author wangyu
+ */
+public interface ApproveRecordRepository extends DefaultReactiveRepository {
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/service/ApproveRecordService.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/service/ApproveRecordService.java
new file mode 100644
index 0000000..5aff31a
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/service/ApproveRecordService.java
@@ -0,0 +1,14 @@
+package com.flyfish.framework.approval.service;
+
+import com.flyfish.framework.approval.domain.record.ApproveRecord;
+import com.flyfish.framework.service.impl.BaseReactiveServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * 审批记录服务
+ *
+ * @author wangyu
+ */
+@Service
+public class ApproveRecordService extends BaseReactiveServiceImpl {
+}
diff --git a/flyfish-approval/src/main/java/com/flyfish/framework/approval/service/ModuleDelegateService.java b/flyfish-approval/src/main/java/com/flyfish/framework/approval/service/ModuleDelegateService.java
new file mode 100644
index 0000000..8c9b322
--- /dev/null
+++ b/flyfish-approval/src/main/java/com/flyfish/framework/approval/service/ModuleDelegateService.java
@@ -0,0 +1,52 @@
+package com.flyfish.framework.approval.service;
+
+import com.flyfish.framework.approval.domain.ApprovalDomain;
+import com.flyfish.framework.approval.domain.record.ApproveRecord;
+import com.flyfish.framework.domain.base.DomainService;
+import com.flyfish.framework.service.BaseReactiveService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * rest模块代理服务
+ * 代理所有带审批的bean服务,用于模糊审批
+ *
+ * @author wangyu
+ */
+@Service
+public class ModuleDelegateService {
+
+ // 审批的服务们
+ private Map> approvalServices;
+
+ @Autowired(required = false)
+ public void setApprovalServices(List> services) {
+ this.approvalServices = services.stream()
+ .collect(Collectors.toMap(DomainService::getCollectionName, s -> s));
+ }
+
+ /**
+ * 获取服务
+ *
+ * @param module 模块
+ * @return 结果
+ */
+ public BaseReactiveService getService(String module) {
+ return approvalServices.get(module);
+ }
+
+ /**
+ * 提交审批
+ * @param record 记录
+ * @return 结果
+ */
+ public Mono approval(ApproveRecord record) {
+ getService(record.getModule()).getById(record.getDataId())
+ .map(domain -> domain)
+ }
+}
diff --git a/flyfish-common/src/main/java/com/flyfish/framework/bean/Result.java b/flyfish-common/src/main/java/com/flyfish/framework/bean/Result.java
index 927374b..0890b3f 100644
--- a/flyfish-common/src/main/java/com/flyfish/framework/bean/Result.java
+++ b/flyfish-common/src/main/java/com/flyfish/framework/bean/Result.java
@@ -11,6 +11,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
+import java.util.stream.Collectors;
/**
* 请求结果
@@ -139,11 +140,18 @@ public class Result {
public Result map(Function function) {
if (this.data != null) {
this.data = (T) function.apply(this.data);
- return (Result) this;
}
return (Result) this;
}
+ public Result> mapList(Function function) {
+ if (this.data instanceof List) {
+ List list = (List) this.data;
+ this.data = (T) list.stream().map(function).collect(Collectors.toList());
+ }
+ return (Result>) this;
+ }
+
public Mono> flatMap(Function> function) {
return Mono.defer(() -> function.apply(data))
.map(mapped -> {
diff --git a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java b/flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java
index 53f4da1..041fe8e 100644
--- a/flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java
+++ b/flyfish-data/src/main/java/com/flyfish/framework/domain/base/DomainService.java
@@ -4,4 +4,11 @@ package com.flyfish.framework.domain.base;
* 占位,标记service
*/
public interface DomainService {
+
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ String getCollectionName();
}
diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java
index 0f5b7c8..80bf8e9 100644
--- a/flyfish-data/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java
+++ b/flyfish-data/src/main/java/com/flyfish/framework/repository/QueryModelExecutor.java
@@ -89,4 +89,11 @@ public interface QueryModelExecutor {
* @return {@literal true} if the data store contains elements that match the given {@link Qo}.
*/
boolean exists(Qo query);
+
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ String getCollectionName();
}
diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java
index ff30e7e..f5a03d5 100644
--- a/flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java
+++ b/flyfish-data/src/main/java/com/flyfish/framework/repository/ReactiveQueryModelExecutor.java
@@ -99,4 +99,11 @@ public interface ReactiveQueryModelExecutor {
* @return 结果
*/
Mono deleteAll(Qo qo);
+
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ String getCollectionName();
}
diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java
index e41e27b..52840c1 100644
--- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java
+++ b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultReactiveRepositoryImpl.java
@@ -177,4 +177,14 @@ public class DefaultReactiveRepositoryImpl extends SimpleReact
entityInformation.getCollectionName()))
.then(Mono.empty());
}
+
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ @Override
+ public String getCollectionName() {
+ return entityInformation.getCollectionName();
+ }
}
diff --git a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java
index 91059c1..e3b4ae3 100644
--- a/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java
+++ b/flyfish-data/src/main/java/com/flyfish/framework/repository/impl/DefaultRepositoryImpl.java
@@ -169,4 +169,14 @@ public class DefaultRepositoryImpl extends SimpleMongoReposito
.orElse(false);
}
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ @Override
+ public String getCollectionName() {
+ return entityInformation.getCollectionName();
+ }
+
}
diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java b/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java
index fbcf4f8..a44f3ce 100644
--- a/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java
+++ b/flyfish-web/src/main/java/com/flyfish/framework/service/BaseReactiveService.java
@@ -4,6 +4,7 @@ import com.flyfish.framework.bean.SyncVo;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.DomainService;
import com.flyfish.framework.domain.base.Qo;
+import com.flyfish.framework.repository.DefaultReactiveRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import reactor.core.publisher.Flux;
diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java
index 63908f5..06954c3 100644
--- a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java
+++ b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseReactiveServiceImpl.java
@@ -404,5 +404,15 @@ public class BaseReactiveServiceImpl implements BaseReactiveSe
public > R getRepository() {
return CastUtils.cast(repository);
}
+
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ @Override
+ public String getCollectionName() {
+ return getRepository().getCollectionName();
+ }
}
diff --git a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java
index 2e5eb1c..ea4af62 100644
--- a/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java
+++ b/flyfish-web/src/main/java/com/flyfish/framework/service/impl/BaseServiceImpl.java
@@ -7,7 +7,6 @@ import com.flyfish.framework.domain.authorized.AuthorizedDomain;
import com.flyfish.framework.domain.base.AuditDomain;
import com.flyfish.framework.domain.base.Domain;
import com.flyfish.framework.domain.base.Qo;
-import com.flyfish.framework.repository.DefaultReactiveRepository;
import com.flyfish.framework.repository.DefaultRepository;
import com.flyfish.framework.service.BaseService;
import com.flyfish.framework.utils.Assert;
@@ -372,7 +371,17 @@ public class BaseServiceImpl implements BaseService {
}
@SuppressWarnings("unchecked")
- public > R getRepository() {
+ public > R getRepository() {
return (R) repository;
}
+
+ /**
+ * 获取集合名称
+ *
+ * @return 结果
+ */
+ @Override
+ public String getCollectionName() {
+ return getRepository().getCollectionName();
+ }
}
diff --git a/pom.xml b/pom.xml
index 82d0e4c..2ef27f8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,7 @@
flyfish-logging
flyfish-dict
flyfish-form
+ flyfish-approval