aggregates) {
+ this.aggregates = aggregates;
+ }
+
+ public DataSourceResult() {
+ }
+
+ public boolean equals(final Object o) {
+ if (o == this) {
+ return true;
+ } else if (!(o instanceof DataSourceResult)) {
+ return false;
+ } else {
+ DataSourceResult> other = (DataSourceResult)o;
+ if (!other.canEqual(this)) {
+ return false;
+ } else if (this.getTotal() != other.getTotal()) {
+ return false;
+ } else {
+ Object this$data = this.getData();
+ Object other$data = other.getData();
+ if (this$data == null) {
+ if (other$data != null) {
+ return false;
+ }
+ } else if (!this$data.equals(other$data)) {
+ return false;
+ }
+
+ Object this$aggregates = this.getAggregates();
+ Object other$aggregates = other.getAggregates();
+ if (this$aggregates == null) {
+ if (other$aggregates != null) {
+ return false;
+ }
+ } else if (!this$aggregates.equals(other$aggregates)) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+
+ protected boolean canEqual(final Object other) {
+ return other instanceof DataSourceResult;
+ }
+
+ public int hashCode() {
+ int PRIME = 59;
+ int result = 1;
+ long $total = this.getTotal();
+ result = result * 59 + (int)($total >>> 32 ^ $total);
+ Object $data = this.getData();
+ result = result * 59 + ($data == null ? 43 : $data.hashCode());
+ Object $aggregates = this.getAggregates();
+ result = result * 59 + ($aggregates == null ? 43 : $aggregates.hashCode());
+ return result;
+ }
+
+ public String toString() {
+ return "DataSourceResult(total=" + this.getTotal() + ", data=" + this.getData() + ", aggregates=" + this.getAggregates() + ")";
+ }
+}
diff --git a/backend/src/main/java/com/yfd/platform/common/DynamicSQLMapper.java b/backend/src/main/java/com/yfd/platform/common/DynamicSQLMapper.java
new file mode 100644
index 0000000..adefb25
--- /dev/null
+++ b/backend/src/main/java/com/yfd/platform/common/DynamicSQLMapper.java
@@ -0,0 +1,262 @@
+package com.yfd.platform.common;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 通用动态 SQL Mapper。
+ *
+ * 说明:
+ *
+ * 1. 该接口通过注解 SQL 直接执行动态查询,适用于“表名/联表 SQL/查询列”需要运行期决定的场景;
+ * 2. 带 {@code QueryWrapper} 的方法统一使用 {@code ew.customSqlSegment} 追加条件;
+ * 3. 传入的 {@code sql}/{@code select}/{@code tableName} 属于动态片段,请在上层确保来源可信,避免注入风险。
+ */
+@Mapper
+public interface DynamicSQLMapper {
+
+ /**
+ * 分页执行完整 SQL(SQL 内可使用 map 参数)。
+ */
+ @Select({""})
+ List