Browse Source

升级orm

dev
myf 6 days ago
parent
commit
e331b14af0
  1. 2
      application-tenant/tenant-admin/pom.xml
  2. 2
      common/common-association/pom.xml
  3. 47
      common/common-association/src/main/java/apelet/association/controller/OnlineFormExtController.java
  4. 248
      common/common-association/src/main/java/apelet/association/plugin/quotation/ContractPlugin.java
  5. 2
      common/common-qy/pom.xml
  6. 2
      pom.xml

2
application-tenant/tenant-admin/pom.xml

@ -156,7 +156,7 @@ @@ -156,7 +156,7 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-orm</artifactId>
<version>1.0.2</version>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>apelet</groupId>

2
common/common-association/pom.xml

@ -52,7 +52,7 @@ @@ -52,7 +52,7 @@
<dependency>
<artifactId>common-orm</artifactId>
<groupId>apelet</groupId>
<version>1.0.2</version>
<version>1.0.3</version>
</dependency>
<dependency>
<artifactId>common-msg-notice</artifactId>

47
common/common-association/src/main/java/apelet/association/controller/OnlineFormExtController.java

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
package apelet.association.controller;
import apelet.common.core.annotation.MyRequestBody;
import apelet.common.core.object.ResponseResult;
import apelet.common.online.controller.OnlineFormController;
import apelet.common.online.dto.OnlineFormDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 在线表单新增/修改独立接口
* 仅提供对外的独立入口业务逻辑不做任何改动直接调用 OnlineFormController add/update
*/
@RestController
@RequestMapping({"/onlineFormExt"})
public class OnlineFormExtController {
/**
* 在线表单控制器复用其已有的新增/修改逻辑含事务校验日志等
*/
@Autowired
private OnlineFormController onlineFormController;
/**
* 新增在线表单
*
* @param onlineFormDto 表单信息
* @return 新增成功后的表单主键 formId
*/
@PostMapping({"/add"})
public ResponseResult<Long> add(@MyRequestBody OnlineFormDto onlineFormDto) {
return onlineFormController.add(onlineFormDto);
}
/**
* 修改在线表单
*
* @param onlineFormDto 表单信息
* @return 无业务数据返回
*/
@PostMapping({"/update"})
public ResponseResult<Void> update(@MyRequestBody OnlineFormDto onlineFormDto) {
return onlineFormController.update(onlineFormDto);
}
}

248
common/common-association/src/main/java/apelet/association/plugin/quotation/ContractPlugin.java

@ -3,24 +3,266 @@ package apelet.association.plugin.quotation; @@ -3,24 +3,266 @@ package apelet.association.plugin.quotation;
import apelet.association.utils.WordDocUtil;
import apelet.common.core.object.ObjectValue;
import apelet.common.online.abstractplugin.ListPlugin;
import apelet.common.online.abstractplugin.model.ListColumn;
import apelet.common.online.dto.OnlineFilterDto;
import apelet.common.online.model.constant.FieldFilterType;
import apelet.common.orm.impl.Filter;
import apelet.common.orm.impl.FilterItem;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/*
合同列表界面设置过滤条件
合同列表界面插件
列表数据由 getSql 自定义 SQL 查询 contract 并拼接列表顶部的查询条件
注意走自定义 SQL 列表的列由 getColumns 定义框架按 ListColumn
customFieldName 把查询结果映射到表格列上因此 getSql SELECT 出来的
列名含别名必须与 getColumns 里的 customFieldName 完全一致
*/
public class ContractPlugin extends ListPlugin {
/**
* 列表查询字段
* 字段名/别名必须与 getColumns ListColumn customFieldName 完全一致
* 框架按该名称把查询结果映射到表格列上
* 其中 delivery_person产品服务交付负责人在库里存的是用户ID这里关联用户表取姓名
*/
private static final String LIST_FIELDS =
"c.id, c.number, c.name, c.signing_date, c.delivery_date, c.get_date, "
+ "u.show_name AS delivery_person, "
+ "c.subcontractor, c.price, c.qty, c.payment_progress";
/**
* 合同列表查询 SQL
* 注意一旦返回自定义 SQL框架会走 ListDataSqlService 分支
* 该分支不会使用 getFilter() getSorter()因此过滤条件与排序都必须写在 SQL
*
* @param objectValue 当前事件数据对象
* @return 合同列表查询 SQL
*/
@Override
public String getSql(ObjectValue objectValue) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(LIST_FIELDS).append(" FROM contract c ");
// 负责人字段存的是用户ID,左连接用户表取姓名(用户不存在时该列为空)
sql.append("LEFT JOIN xy_sys_user u ON u.id = c.delivery_person ");
// 已删除、已作废的合同不显示
sql.append("WHERE c.deleted_flag = 1");
// 拼接列表顶部录入的查询条件
sql.append(buildConditionSql());
// 固定按创建时间倒序,保证翻页结果稳定
sql.append(" ORDER BY c.create_time DESC, c.id DESC");
return sql.toString();
}
/**
* 数据过滤条件
* getSql 自定义 SQL 时框架不会调用本方法此处仅为不使用自定义 SQL 时保持一致
*/
@Override
protected Filter getFilter() {
Filter filter = new Filter();
filter.add(new FilterItem("status", FilterItem.equals, "3"));
filter.add(new FilterItem("deleted_flag", FilterItem.equals, 1));
return filter;
}
/**
* 列表列定义
* 走自定义 SQL 表格列由本方法返回的列定义渲染
* 因此这里的 customFieldName 必须与 getSql SELECT 的列名/别名完全一致
*
* @param objectValue 当前事件数据对象
* @return 列表列定义集合
*/
@Override
public List<ListColumn> getColumns(ObjectValue objectValue) {
List<ListColumn> columns = new ArrayList<>();
// 主键:隐藏列,供行定位、打开详情等操作使用
columns.add(buildColumn("id", "主键", 0, false));
// 以下列顺序与列表界面上配置的列顺序保持一致
columns.add(buildColumn("signing_date", "合同签订日期", 160, true));
columns.add(buildColumn("delivery_date", "产品服务交付日期", 170, true));
columns.add(buildColumn("get_date", "收款计划", 160, true));
columns.add(buildColumn("delivery_person", "产品服务交付负责人", 180, true));
columns.add(buildColumn("subcontractor", "分包商", 200, true));
columns.add(buildColumn("price", "分包价格", 120, true));
columns.add(buildColumn("number", "编码", 180, true));
columns.add(buildColumn("name", "名称", 200, true));
columns.add(buildColumn("qty", "总报价", 120, true));
columns.add(buildColumn("payment_progress", "付款进度", 120, true));
return columns;
}
/**
* 构造一个列表列定义
*
* @param fieldName 字段名必须与 getSql 查询出的列名/别名一致
* @param showName 列显示名称
* @param width 列宽 0 表示使用默认宽度
* @param show 该列是否显示
* @return 列定义对象
*/
private ListColumn buildColumn(String fieldName, String showName, int width, boolean show) {
ListColumn column = new ListColumn();
column.setCustomFieldName(fieldName);
column.setShowName(showName);
// 自定义 SQL 查出的列不参与点击打开表单,也不可编辑
column.setClickOpen(false);
column.setShowColumn(show);
if (width > 0) {
column.setColumnWidth(width);
}
return column;
}
/**
* 把列表顶部的查询条件拼接成 SQL AND 片段
* 目前列表只有名称一个查询条件这里按框架的过滤类型通用处理
*
* @return 形如 " AND c.name LIKE '%关键字%'" 的片段无条件时返回空串
*/
private String buildConditionSql() {
Object filterObj = this.getDto().getListParams().get("filterDtoList");
if (!(filterObj instanceof List)) {
return "";
}
StringBuilder condition = new StringBuilder();
for (Object item : (List<?>) filterObj) {
if (!(item instanceof OnlineFilterDto)) {
continue;
}
OnlineFilterDto filterDto = (OnlineFilterDto) item;
// 列名做白名单校验,避免拼接 SQL 时被注入
String columnName = filterDto.getColumnName();
if (columnName == null || !columnName.matches("[A-Za-z0-9_]+")) {
continue;
}
// 查询条件都来自主表,统一加表别名
String column = "c." + columnName;
Integer filterType = filterDto.getFilterType();
if (filterType == null) {
filterType = FieldFilterType.EQUAL_FILTER;
}
// 范围过滤:起止值分别拼 >= 与 <=
if (filterType == FieldFilterType.RANGE_FILTER) {
condition.append(buildRangeSql(column, filterDto));
continue;
}
// 列表过滤:拼 IN (...)
if (filterType == FieldFilterType.IN_LIST_FILTER) {
condition.append(buildInSql(column, filterDto.getColumnValueList()));
continue;
}
// 模糊过滤:前后加通配符
if (filterType == FieldFilterType.LIKE_FILTER || filterType == FieldFilterType.MULTI_LIKE) {
String keyword = toPlainText(filterDto.getColumnValue());
if (keyword != null) {
condition.append(" AND ").append(column)
.append(" LIKE '%").append(keyword.replace("'", "''")).append("%'");
}
continue;
}
// 其余情况按等于过滤处理
String value = toSqlValue(filterDto.getColumnValue());
if (value != null) {
condition.append(" AND ").append(column).append(" = ").append(value);
}
}
return condition.toString();
}
/**
* 拼接范围过滤条件
*
* @param column 带表别名的列名
* @param filterDto 过滤参数
* @return 形如 " AND c.xxx >= '2026-01-01'" 的片段
*/
private String buildRangeSql(String column, OnlineFilterDto filterDto) {
StringBuilder sql = new StringBuilder();
String start = toSqlValue(filterDto.getColumnValueStart());
if (start != null) {
sql.append(" AND ").append(column).append(" >= ").append(start);
}
String end = toSqlValue(filterDto.getColumnValueEnd());
if (end != null) {
sql.append(" AND ").append(column).append(" <= ").append(end);
}
return sql.toString();
}
/**
* 拼接 IN 过滤条件
*
* @param column 带表别名的列名
* @param valueList 取值集合
* @return 形如 " AND c.xxx IN ('1', '2')" 的片段集合为空时返回空串
*/
private String buildInSql(String column, Set<?> valueList) {
if (valueList == null || valueList.isEmpty()) {
return "";
}
StringBuilder values = new StringBuilder();
for (Object value : valueList) {
String literal = toSqlValue(value);
if (literal == null) {
continue;
}
if (values.length() > 0) {
values.append(", ");
}
values.append(literal);
}
if (values.length() == 0) {
return "";
}
return " AND " + column + " IN (" + values + ")";
}
/**
* 把过滤值转成 SQL 字面量数字与布尔直接输出其余按字符串加引号并转义单引号
*
* @param value 过滤值
* @return SQL 字面量值为空时返回 null表示该条件忽略
*/
private String toSqlValue(Object value) {
if (value == null) {
return null;
}
if (value instanceof Number || value instanceof Boolean) {
return value.toString();
}
String text = String.valueOf(value);
if (text.isEmpty()) {
return null;
}
return "'" + text.replace("'", "''") + "'";
}
/**
* 取出过滤值的纯文本形式空值返回 null
*
* @param value 过滤值
* @return 文本内容为空时返回 null
*/
private String toPlainText(Object value) {
if (value == null) {
return null;
}
String text = String.valueOf(value);
return text.isEmpty() ? null : text;
}
/**
* 合同导出按当前表单数据渲染 Word 模板
*
* @param widgetVariableName 按钮标识
* @param objectValue 当前事件数据对象
*/
@Override
public void buttonTriggered(String widgetVariableName, ObjectValue objectValue) {
if (widgetVariableName.equals("合同导出")) {

2
common/common-qy/pom.xml

@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-orm</artifactId>
<version>1.0.2</version>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>apelet</groupId>

2
pom.xml

@ -289,7 +289,7 @@ @@ -289,7 +289,7 @@
<dependency>
<groupId>apelet</groupId>
<artifactId>common-orm</artifactId>
<version>1.0.2</version>
<version>1.0.3</version>
</dependency>
</dependencies>
</dependencyManagement>

Loading…
Cancel
Save