Commit 87f99dc3 authored by lixuan's avatar lixuan

feat: 需求

parent d9aaff3c
Pipeline #147201 failed with stages
in 0 seconds
...@@ -3,6 +3,7 @@ package com.ruoyi.framework.config; ...@@ -3,6 +3,7 @@ package com.ruoyi.framework.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.interceptor.mybatis.DataChangeLogInterceptor;
import org.apache.ibatis.io.VFS; import org.apache.ibatis.io.VFS;
import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
...@@ -125,6 +126,7 @@ public class MyBatisConfig ...@@ -125,6 +126,7 @@ public class MyBatisConfig
typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage); typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
VFS.addImplClass(SpringBootVFS.class); VFS.addImplClass(SpringBootVFS.class);
Interceptor[] interceptors = { Interceptor[] interceptors = {
new DataChangeLogInterceptor(),
new PaginationInterceptor() new PaginationInterceptor()
}; };
final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean(); final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
......
package com.ruoyi.framework.interceptor.mybatis;
import com.ruoyi.system.domain.changerecord.DataChangeRecord;
import com.ruoyi.system.domain.changerecord.annotation.DataChangeLog;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* 数据变更日志拦截器。
*
* <p>拦截所有 {@link Executor#update(MappedStatement, Object)} 调用,读取 Mapper 方法上的
* {@link DataChangeLog} 注解,解析出 subject_id 后向 {@code data_change_record} 表写日志。</p>
*
* <p>关键约束:</p>
* <ol>
* <li>未标注 {@code @DataChangeLog} 的 Mapper 方法不会产生任何额外开销。</li>
* <li>日志写入与原业务 SQL 共用同一个 {@link Executor},天然在同一事务内,失败会一起回滚。</li>
* <li>批量写操作会按 {@code list[*].id} 表达式展开成多条日志。</li>
* <li>预加载场景:{@code @DataChangeLog(preLoadMapper=...)} 可在写操作前先执行一次查询
* (如 mapping 按 house_resource_id 删除时,需要先查出被影响的 business_entity_info_id)。</li>
* <li>受影响行数为 0 时跳过日志写入,避免"查不到的更新"污染统计。</li>
* </ol>
*/
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class DataChangeLogInterceptor implements Interceptor {
private static final Logger log = LoggerFactory.getLogger(DataChangeLogInterceptor.class);
private static final String LOG_INSERT_STATEMENT_ID =
"com.ruoyi.system.mapper.changerecord.DataChangeRecordMapper.batchInsert";
private static final DataChangeLog[] EMPTY = new DataChangeLog[0];
/** 按 MappedStatement id 缓存 @DataChangeLog 列表。 */
private final Map<String, DataChangeLog[]> annotationCache = new ConcurrentHashMap<>();
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object param = args[1];
DataChangeLog[] annotations = resolveAnnotations(ms.getId());
if (annotations.length == 0) {
return invocation.proceed();
}
Executor executor = (Executor) invocation.getTarget();
Map<String, List<?>> preloadResults = runPreload(annotations, param, executor, ms);
Object result = invocation.proceed();
if (result instanceof Integer && (Integer) result == 0) {
return result;
}
List<DataChangeRecord> records = buildRecords(annotations, param, preloadResults);
if (records.isEmpty()) {
return result;
}
try {
MappedStatement logMs = ms.getConfiguration().getMappedStatement(LOG_INSERT_STATEMENT_ID);
Map<String, Object> logParam = new HashMap<>(2);
logParam.put("list", records);
executor.update(logMs, logParam);
} catch (Exception e) {
log.error("写入 data_change_record 失败,业务事务将回滚。ms={}", ms.getId(), e);
throw e;
}
return result;
}
@Override
public Object plugin(Object target) {
if (target instanceof Executor) {
return org.apache.ibatis.plugin.Plugin.wrap(target, this);
}
return target;
}
@Override
public void setProperties(java.util.Properties properties) {
}
private DataChangeLog[] resolveAnnotations(String statementId) {
return annotationCache.computeIfAbsent(statementId, this::loadAnnotations);
}
private DataChangeLog[] loadAnnotations(String statementId) {
int dot = statementId.lastIndexOf('.');
if (dot <= 0) {
return EMPTY;
}
String mapperClassName = statementId.substring(0, dot);
String methodName = statementId.substring(dot + 1);
try {
Class<?> mapperClass = Class.forName(mapperClassName);
for (Method m : mapperClass.getDeclaredMethods()) {
if (!m.getName().equals(methodName)) {
continue;
}
DataChangeLog[] annos = m.getAnnotationsByType(DataChangeLog.class);
if (annos.length > 0) {
return annos;
}
}
} catch (ClassNotFoundException ignore) {
}
return EMPTY;
}
private Map<String, List<?>> runPreload(DataChangeLog[] annotations, Object param, Executor executor,
MappedStatement ms) throws Exception {
Map<String, List<?>> results = new HashMap<>();
for (DataChangeLog anno : annotations) {
String preLoad = anno.preLoadMapper();
if (preLoad.isEmpty() || results.containsKey(preLoad)) {
continue;
}
MappedStatement preLoadMs = ms.getConfiguration().getMappedStatement(preLoad);
@SuppressWarnings("rawtypes")
List queryResult = executor.query(preLoadMs, param, RowBounds.DEFAULT,
(ResultHandler) null);
results.put(preLoad, queryResult);
}
return results;
}
private List<DataChangeRecord> buildRecords(DataChangeLog[] annotations, Object param,
Map<String, List<?>> preloadResults) {
Date now = new Date();
List<DataChangeRecord> records = new ArrayList<>();
for (DataChangeLog anno : annotations) {
List<?> preload = anno.preLoadMapper().isEmpty() ? null : preloadResults.get(anno.preLoadMapper());
List<String> subjectIds = resolveIds(param, anno.idExpr(), preload);
for (String subjectId : subjectIds) {
if (subjectId == null || subjectId.isEmpty()) {
continue;
}
DataChangeRecord r = new DataChangeRecord();
r.setId(UUID.randomUUID().toString().replace("-", ""));
r.setSubjectType(anno.subjectType().name());
r.setSubjectId(subjectId);
r.setOperationType(anno.operation().getCode());
r.setOperationTime(now);
records.add(r);
}
}
return records;
}
private List<String> resolveIds(Object param, String idExpr, List<?> preload) {
if (idExpr == null || idExpr.isEmpty()) {
return Collections.emptyList();
}
if (".".equals(idExpr)) {
return param == null ? Collections.emptyList()
: Collections.singletonList(String.valueOf(param));
}
int starIdx = idExpr.indexOf("[*]");
if (starIdx >= 0) {
String listKey = idExpr.substring(0, starIdx);
String afterStar = idExpr.substring(starIdx + 3);
if (afterStar.startsWith(".")) {
afterStar = afterStar.substring(1);
}
List<?> list;
if ("@preload".equals(listKey)) {
list = preload;
} else {
Object v = getProperty(param, listKey);
list = (v instanceof List) ? (List<?>) v : null;
}
if (list == null || list.isEmpty()) {
return Collections.emptyList();
}
List<String> ids = new ArrayList<>(list.size());
for (Object item : list) {
Object idVal = afterStar.isEmpty() ? item : getProperty(item, afterStar);
if (idVal != null) {
ids.add(String.valueOf(idVal));
}
}
return ids;
}
Object val = getProperty(param, idExpr);
return val == null ? Collections.emptyList() : Collections.singletonList(String.valueOf(val));
}
private Object getProperty(Object obj, String key) {
if (obj == null || key == null || key.isEmpty()) {
return null;
}
if (obj instanceof Map) {
return ((Map<?, ?>) obj).get(key);
}
try {
String getter = "get" + Character.toUpperCase(key.charAt(0)) + key.substring(1);
for (Method m : obj.getClass().getMethods()) {
if (m.getName().equals(getter) && m.getParameterCount() == 0) {
return m.invoke(obj);
}
}
Field f = findField(obj.getClass(), key);
if (f != null) {
f.setAccessible(true);
return f.get(obj);
}
} catch (Exception ignore) {
}
return null;
}
private Field findField(Class<?> cls, String name) {
Class<?> c = cls;
while (c != null && c != Object.class) {
for (Field f : c.getDeclaredFields()) {
if (f.getName().equals(name)) {
return f;
}
}
c = c.getSuperclass();
}
return null;
}
}
package com.ruoyi.system.domain.changerecord;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* 数据变更记录。
*/
@Data
public class DataChangeRecord implements Serializable {
private static final long serialVersionUID = 1L;
/** 记录 id。 */
private String id;
/** 主体类型,取值见 {@link com.ruoyi.system.domain.changerecord.enums.SubjectType}。 */
private String subjectType;
/** 主体 id。 */
private String subjectId;
/** 操作类型,取值见 {@link com.ruoyi.system.domain.changerecord.enums.OperationType}。 */
private Integer operationType;
/** 操作时间。 */
private Date operationTime;
}
package com.ruoyi.system.domain.changerecord.annotation;
import com.ruoyi.system.domain.changerecord.enums.OperationType;
import com.ruoyi.system.domain.changerecord.enums.SubjectType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 数据变更日志注解。
*
* <p>标注在 Mapper 方法上,用于声明该写操作需要向 {@code data_change_record} 写入一条变更记录。</p>
*
* <p>同一个方法可以重复声明多个 {@link DataChangeLog}(例如 mapping 表同时需要记录房源侧和经营主体侧)。</p>
*
* <h3>idExpr 表达式语法</h3>
* <ul>
* <li>{@code "."} — 参数本身即为 subject_id,适用于 {@code void xxx(String id)} 这种单个裸参数的场景。</li>
* <li>{@code "fieldName"} — 从参数中按属性名取值,适用于 POJO 或 Map / {@code @Param("xxx")} 场景。</li>
* <li>{@code "listKey[*].fieldName"} — 从参数中取一个 List 再逐个取字段值,适用于批量操作
* (如 {@code @Param("list") List<HouseResource> list})。</li>
* <li>{@code "@preload[*].fieldName"} — 从 {@link #preLoadMapper()} 指定的查询结果集里逐个取字段值。</li>
* </ul>
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(DataChangeLogs.class)
public @interface DataChangeLog {
/** 主体类型。 */
SubjectType subjectType();
/** 操作类型。 */
OperationType operation();
/** subject_id 取值表达式,详见类注释。 */
String idExpr();
/**
* 预加载 Mapper 方法的全限定名(例如
* {@code com.ruoyi.system.mapper.house.HouseResourceBusinessEntityInfoMappingMapper.selectByHouseResourceId})。
*
* <p>用于"写操作前需要先查出被影响 id"的场景(如 mapping 的 deleteByHouseResourceId)。
* 为空时不触发预加载。预加载结果通过 {@code @preload[*].xxx} 表达式访问。</p>
*/
String preLoadMapper() default "";
}
package com.ruoyi.system.domain.changerecord.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* {@link DataChangeLog} 的容器注解。
*
* <p>Java 通过 {@code @Repeatable} 机制,在同一个方法上写多个 {@code @DataChangeLog}
* 时会被自动包装成此容器注解。</p>
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataChangeLogs {
DataChangeLog[] value();
}
package com.ruoyi.system.domain.changerecord.enums;
/**
* 数据变更记录 - 操作类型。
*
* <p>数据库中使用 tinyint 存储。</p>
*/
public enum OperationType {
INSERT(1),
UPDATE(2),
DELETE(3);
private final int code;
OperationType(int code) {
this.code = code;
}
public int getCode() {
return code;
}
}
package com.ruoyi.system.domain.changerecord.enums;
/**
* 数据变更记录 - 主体类型。
*/
public enum SubjectType {
/** 房源。 */
HOUSE_RESOURCE,
/** 经营主体。 */
BUSINESS_ENTITY_INFO;
}
package com.ruoyi.system.mapper.changerecord;
import com.ruoyi.system.domain.changerecord.DataChangeRecord;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 数据变更记录 Mapper。
*/
public interface DataChangeRecordMapper {
/**
* 批量插入变更记录。
*
* <p>此方法**不需要**标注 {@link com.ruoyi.system.domain.changerecord.annotation.DataChangeLog},
* 它就是用来写日志表本身的,否则会无限递归。</p>
*/
int batchInsert(@Param("list") List<DataChangeRecord> list);
}
package com.ruoyi.system.mapper.house; package com.ruoyi.system.mapper.house;
import com.ruoyi.system.domain.changerecord.annotation.DataChangeLog;
import com.ruoyi.system.domain.changerecord.enums.OperationType;
import com.ruoyi.system.domain.changerecord.enums.SubjectType;
import com.ruoyi.system.domain.house.BusinessEntityInfo; import com.ruoyi.system.domain.house.BusinessEntityInfo;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -9,15 +12,18 @@ import java.util.List; ...@@ -9,15 +12,18 @@ import java.util.List;
public interface BusinessEntityInfoMapper { public interface BusinessEntityInfoMapper {
// 插入业务实体信息 // 插入业务实体信息
@DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.INSERT, idExpr = "id")
void insertBusinessEntityInfo(BusinessEntityInfo businessEntityInfo); void insertBusinessEntityInfo(BusinessEntityInfo businessEntityInfo);
// 根据ID查询业务实体信息 // 根据ID查询业务实体信息
BusinessEntityInfo selectBusinessEntityInfoById(@Param("id") String id); BusinessEntityInfo selectBusinessEntityInfoById(@Param("id") String id);
// 更新业务实体信息 // 更新业务实体信息
@DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.UPDATE, idExpr = "id")
void updateBusinessEntityInfo(BusinessEntityInfo businessEntityInfo); void updateBusinessEntityInfo(BusinessEntityInfo businessEntityInfo);
// 删除业务实体信息 // 删除业务实体信息
@DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.DELETE, idExpr = "id")
void deleteBusinessEntityInfoById(@Param("id") String id); void deleteBusinessEntityInfoById(@Param("id") String id);
// 查询所有业务实体信息 // 查询所有业务实体信息
......
package com.ruoyi.system.mapper.house; package com.ruoyi.system.mapper.house;
import com.ruoyi.system.domain.changerecord.annotation.DataChangeLog;
import com.ruoyi.system.domain.changerecord.enums.OperationType;
import com.ruoyi.system.domain.changerecord.enums.SubjectType;
import com.ruoyi.system.domain.house.BusinessEntitySell; import com.ruoyi.system.domain.house.BusinessEntitySell;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -7,21 +10,36 @@ import java.util.List; ...@@ -7,21 +10,36 @@ import java.util.List;
public interface BusinessEntitySellMapper { public interface BusinessEntitySellMapper {
// 插入业务实体销售信息 // 插入业务实体销售信息;以经营主体侧记录一条修改日志
@DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.UPDATE, idExpr = "businessEntityInfoId")
void insertBusinessEntitySell(BusinessEntitySell businessEntitySell); void insertBusinessEntitySell(BusinessEntitySell businessEntitySell);
// 根据ID查询业务实体销售信息 // 根据ID查询业务实体销售信息
BusinessEntitySell selectBusinessEntitySellById(@Param("id") String id); BusinessEntitySell selectBusinessEntitySellById(@Param("id") String id);
// 更新业务实体销售信息 // 更新业务实体销售信息;以经营主体侧记录一条修改日志
// 使用 preLoad,避免 update 的 <set> 中未带 businessEntityInfoId 时取不到
@DataChangeLog(
subjectType = SubjectType.BUSINESS_ENTITY_INFO,
operation = OperationType.UPDATE,
preLoadMapper = "com.ruoyi.system.mapper.house.BusinessEntitySellMapper.selectBusinessEntitySellById",
idExpr = "@preload[*].businessEntityInfoId"
)
void updateBusinessEntitySell(BusinessEntitySell businessEntitySell); void updateBusinessEntitySell(BusinessEntitySell businessEntitySell);
// 删除业务实体销售信息 // 删除业务实体销售信息;改为逻辑删除后以经营主体侧记录一条修改日志
@DataChangeLog(
subjectType = SubjectType.BUSINESS_ENTITY_INFO,
operation = OperationType.UPDATE,
preLoadMapper = "com.ruoyi.system.mapper.house.BusinessEntitySellMapper.selectBusinessEntitySellById",
idExpr = "@preload[*].businessEntityInfoId"
)
void deleteBusinessEntitySellById(@Param("id") String id); void deleteBusinessEntitySellById(@Param("id") String id);
// 查询所有业务实体销售信息 // 查询所有业务实体销售信息
List<BusinessEntitySell> selectAllBusinessEntitySells(); List<BusinessEntitySell> selectAllBusinessEntitySells();
@DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.UPDATE, idExpr = "businessEntityId")
void deleteBusinessEntitySellByEntityId(@Param("businessEntityId") String businessEntityId); void deleteBusinessEntitySellByEntityId(@Param("businessEntityId") String businessEntityId);
List<BusinessEntitySell> selectBusinessEntitySellByEntityId(@Param("entityId") String entityId); List<BusinessEntitySell> selectBusinessEntitySellByEntityId(@Param("entityId") String entityId);
......
package com.ruoyi.system.mapper.house; package com.ruoyi.system.mapper.house;
import com.ruoyi.system.domain.changerecord.annotation.DataChangeLog;
import com.ruoyi.system.domain.changerecord.enums.OperationType;
import com.ruoyi.system.domain.changerecord.enums.SubjectType;
import com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping; import com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -7,15 +10,31 @@ import java.util.List; ...@@ -7,15 +10,31 @@ import java.util.List;
public interface HouseResourceBusinessEntityInfoMappingMapper { public interface HouseResourceBusinessEntityInfoMappingMapper {
// 新增关联关系;同时给房源侧和经营主体侧各记录一条修改日志
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.UPDATE, idExpr = "houseResourceId")
@DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.UPDATE, idExpr = "businessEntityInfoId")
void insert(HouseResourceBusinessEntityInfoMapping houseResourceBusinessEntityInfoMapping); void insert(HouseResourceBusinessEntityInfoMapping houseResourceBusinessEntityInfoMapping);
void deleteByHouseResourceIdBusinessEntityInfoId(String houseResourceId, String businessEntityInfoId); // 按 (houseResourceId, businessEntityInfoId) 逻辑删除关联;双侧各一条修改日志
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.UPDATE, idExpr = "houseResourceId")
void deleteByHouseResourceId(String houseResourceId); @DataChangeLog(subjectType = SubjectType.BUSINESS_ENTITY_INFO, operation = OperationType.UPDATE, idExpr = "businessEntityInfoId")
void deleteByHouseResourceIdBusinessEntityInfoId(
List<HouseResourceBusinessEntityInfoMapping> selectByBusinessEntityInfoId(String businessEntityInfoId); @Param("houseResourceId") String houseResourceId,
@Param("businessEntityInfoId") String businessEntityInfoId);
List<HouseResourceBusinessEntityInfoMapping> selectByHouseResourceId(String houseResourceId);
// 按 houseResourceId 批量逻辑删除;房源侧直接取参数,经营主体侧需要预查
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.UPDATE, idExpr = "houseResourceId")
@DataChangeLog(
subjectType = SubjectType.BUSINESS_ENTITY_INFO,
operation = OperationType.UPDATE,
preLoadMapper = "com.ruoyi.system.mapper.house.HouseResourceBusinessEntityInfoMappingMapper.selectByHouseResourceId",
idExpr = "@preload[*].businessEntityInfoId"
)
void deleteByHouseResourceId(@Param("houseResourceId") String houseResourceId);
List<HouseResourceBusinessEntityInfoMapping> selectByBusinessEntityInfoId(@Param("businessEntityInfoId") String businessEntityInfoId);
List<HouseResourceBusinessEntityInfoMapping> selectByHouseResourceId(@Param("houseResourceId") String houseResourceId);
List<HouseResourceBusinessEntityInfoMapping> selectByHouseResourceIds(@Param("houseResourceIds") List<String> houseResourceIds); List<HouseResourceBusinessEntityInfoMapping> selectByHouseResourceIds(@Param("houseResourceIds") List<String> houseResourceIds);
} }
package com.ruoyi.system.mapper.house; package com.ruoyi.system.mapper.house;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.system.domain.changerecord.annotation.DataChangeLog;
import com.ruoyi.system.domain.changerecord.enums.OperationType;
import com.ruoyi.system.domain.changerecord.enums.SubjectType;
import com.ruoyi.system.domain.house.HouseResource; import com.ruoyi.system.domain.house.HouseResource;
import com.ruoyi.system.domain.house.vo.*; import com.ruoyi.system.domain.house.vo.*;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
...@@ -10,14 +13,18 @@ import java.util.List; ...@@ -10,14 +13,18 @@ import java.util.List;
public interface HouseResourceMapper { public interface HouseResourceMapper {
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.INSERT, idExpr = "id")
void insertHouseResource(HouseResource houseResource); void insertHouseResource(HouseResource houseResource);
HouseResource selectHouseResourceById(String id); HouseResource selectHouseResourceById(String id);
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.UPDATE, idExpr = "id")
void updateHouseResource(HouseResource houseResource); void updateHouseResource(HouseResource houseResource);
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.DELETE, idExpr = ".")
void deleteHouseResourceById(String id); void deleteHouseResourceById(String id);
@DataChangeLog(subjectType = SubjectType.HOUSE_RESOURCE, operation = OperationType.INSERT, idExpr = "list[*].id")
void batchInsertHouseResources(List<HouseResource> houseResources); void batchInsertHouseResources(List<HouseResource> houseResources);
IPage<HouseResourcePage> selectPage(IPage<HouseResource> page, @Param("query") HouseResourcePageQuery houseResourcePageQuery); IPage<HouseResourcePage> selectPage(IPage<HouseResource> page, @Param("query") HouseResourcePageQuery houseResourcePageQuery);
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.changerecord.DataChangeRecordMapper">
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO data_change_record
(id, subject_type, subject_id, operation_type, operation_time)
VALUES
<foreach collection="list" item="item" separator=",">
(#{item.id}, #{item.subjectType}, #{item.subjectId}, #{item.operationType}, #{item.operationTime})
</foreach>
</insert>
</mapper>
...@@ -787,7 +787,7 @@ ...@@ -787,7 +787,7 @@
<select id="countByFourthCode" resultType="Integer"> <select id="countByFourthCode" resultType="Integer">
select count(*) from house_resource select count(*) from house_resource
where four = #{code} or three = #{code} where delete_flag = 0 and (four = #{code} or three = #{code})
</select> </select>
<select id="selectMaxPosition" resultType="java.lang.Integer"> <select id="selectMaxPosition" resultType="java.lang.Integer">
SELECT MAX(position) SELECT MAX(position)
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
</insert> </insert>
<select id="selectBusinessEntityInfoById" resultMap="BaseResultMap"> <select id="selectBusinessEntityInfoById" resultMap="BaseResultMap">
SELECT * FROM business_entity_info WHERE id = #{id} SELECT * FROM business_entity_info WHERE id = #{id} AND delete_flag = 0
</select> </select>
<update id="updateBusinessEntityInfo" parameterType="com.ruoyi.system.domain.house.BusinessEntityInfo"> <update id="updateBusinessEntityInfo" parameterType="com.ruoyi.system.domain.house.BusinessEntityInfo">
...@@ -58,24 +58,25 @@ ...@@ -58,24 +58,25 @@
WHERE id=#{id} WHERE id=#{id}
</update> </update>
<!-- 改为逻辑删除:保持 <delete> 标签含义,SQL 实际为 UPDATE -->
<delete id="deleteBusinessEntityInfoById"> <delete id="deleteBusinessEntityInfoById">
DELETE FROM business_entity_info WHERE id = #{id} UPDATE business_entity_info SET delete_flag = 1 WHERE id = #{id} AND delete_flag = 0
</delete> </delete>
<select id="selectAllBusinessEntityInfos" resultMap="BaseResultMap"> <select id="selectAllBusinessEntityInfos" resultMap="BaseResultMap">
SELECT * FROM business_entity_info SELECT * FROM business_entity_info WHERE delete_flag = 0
</select> </select>
<select id="selectByName" resultType="com.ruoyi.system.domain.house.BusinessEntityInfo"> <select id="selectByName" resultType="com.ruoyi.system.domain.house.BusinessEntityInfo">
SELECT SELECT
t3.* t3.*
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN house_resource_business_entity_info_mapping t2 ON t1.id = t2.house_resource_id LEFT JOIN house_resource_business_entity_info_mapping t2 ON t1.id = t2.house_resource_id AND t2.delete_flag = 0
LEFT JOIN business_entity_info t3 ON t2.business_entity_info_id = t3.id LEFT JOIN business_entity_info t3 ON t2.business_entity_info_id = t3.id AND t3.delete_flag = 0
WHERE t3.name like concat('%', #{name}, '%') WHERE t3.name like concat('%', #{name}, '%')
</select> </select>
<select id="selectByIdList" resultType="com.ruoyi.system.domain.house.BusinessEntityInfo"> <select id="selectByIdList" resultType="com.ruoyi.system.domain.house.BusinessEntityInfo">
SELECT * FROM business_entity_info WHERE id IN SELECT * FROM business_entity_info WHERE delete_flag = 0 AND id IN
<foreach item="item" index="index" collection="idList" open="(" separator="," close=")"> <foreach item="item" index="index" collection="idList" open="(" separator="," close=")">
#{item} #{item}
</foreach> </foreach>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<!-- 根据ID查询操作 --> <!-- 根据ID查询操作 -->
<select id="selectBusinessEntitySellById" resultMap="BaseResultMap"> <select id="selectBusinessEntitySellById" resultMap="BaseResultMap">
SELECT * FROM business_entity_sell WHERE id = #{id} SELECT * FROM business_entity_sell WHERE id = #{id} AND delete_flag = 0
</select> </select>
<!-- 更新操作 --> <!-- 更新操作 -->
...@@ -34,30 +34,35 @@ ...@@ -34,30 +34,35 @@
<if test="yearTax != null">year_tax=#{yearTax},</if> <if test="yearTax != null">year_tax=#{yearTax},</if>
<if test="compare != null">compare=#{compare},</if> <if test="compare != null">compare=#{compare},</if>
</set> </set>
WHERE id=#{id} WHERE id=#{id} AND delete_flag = 0
</update> </update>
<!-- 删除操作 --> <!-- 删除操作:改为逻辑删除 -->
<delete id="deleteBusinessEntitySellById"> <delete id="deleteBusinessEntitySellById">
DELETE FROM business_entity_sell WHERE id = #{id} UPDATE business_entity_sell SET delete_flag = 1 WHERE id = #{id} AND delete_flag = 0
</delete> </delete>
<!-- 查询所有记录操作 --> <!-- 查询所有记录操作 -->
<select id="selectAllBusinessEntitySells" resultMap="BaseResultMap"> <select id="selectAllBusinessEntitySells" resultMap="BaseResultMap">
SELECT * FROM business_entity_sell SELECT * FROM business_entity_sell WHERE delete_flag = 0
</select> </select>
<!-- 按经营主体批量逻辑删除 -->
<delete id="deleteBusinessEntitySellByEntityId"> <delete id="deleteBusinessEntitySellByEntityId">
DELETE FROM business_entity_sell WHERE business_entity_info_id = #{businessEntityId} UPDATE business_entity_sell SET delete_flag = 1
WHERE business_entity_info_id = #{businessEntityId} AND delete_flag = 0
</delete> </delete>
<select id="selectBusinessEntitySellByEntityId" <select id="selectBusinessEntitySellByEntityId"
resultType="com.ruoyi.system.domain.house.BusinessEntitySell"> resultType="com.ruoyi.system.domain.house.BusinessEntitySell">
SELECT * FROM business_entity_sell WHERE business_entity_info_id = #{entityId} SELECT * FROM business_entity_sell WHERE business_entity_info_id = #{entityId} AND delete_flag = 0
</select> </select>
<select id="selectBusinessEntitySellByEntityIds" <select id="selectBusinessEntitySellByEntityIds"
resultType="com.ruoyi.system.domain.house.BusinessEntitySell"> resultType="com.ruoyi.system.domain.house.BusinessEntitySell">
SELECT * FROM business_entity_sell WHERE business_entity_info_id in <foreach collection="entityIds" item="entityId" open="(" close=")" separator=",">#{entityId}</foreach> SELECT * FROM business_entity_sell
WHERE delete_flag = 0
AND business_entity_info_id in
<foreach collection="entityIds" item="entityId" open="(" close=")" separator=",">#{entityId}</foreach>
</select> </select>
<select id="selectBusinessEntitySellByBusinessEntityInfoId" <select id="selectBusinessEntitySellByBusinessEntityInfoId"
resultType="com.ruoyi.system.domain.house.BusinessEntitySell"> resultType="com.ruoyi.system.domain.house.BusinessEntitySell">
...@@ -65,8 +70,8 @@ ...@@ -65,8 +70,8 @@
t2.* t2.*
FROM FROM
business_entity_info t1 business_entity_info t1
LEFT JOIN business_entity_sell t2 ON t1.id = t2.business_entity_info_id LEFT JOIN business_entity_sell t2 ON t1.id = t2.business_entity_info_id AND t2.delete_flag = 0
WHERE t1.id = #{businessEntityInfoId} AND t2.year = #{year} WHERE t1.id = #{businessEntityInfoId} AND t1.delete_flag = 0 AND t2.year = #{year}
limit 1 limit 1
</select> </select>
<select id="selectBusinessEntityTaxByBusinessEntityInfoId" <select id="selectBusinessEntityTaxByBusinessEntityInfoId"
...@@ -75,8 +80,8 @@ ...@@ -75,8 +80,8 @@
t2.* t2.*
FROM FROM
business_entity_info t1 business_entity_info t1
LEFT JOIN business_entity_sell t2 ON t1.id = t2.business_entity_info_id LEFT JOIN business_entity_sell t2 ON t1.id = t2.business_entity_info_id AND t2.delete_flag = 0
WHERE t1.id = #{businessEntityInfoId} AND t2.year = #{year} WHERE t1.id = #{businessEntityInfoId} AND t1.delete_flag = 0 AND t2.year = #{year}
limit 1 limit 1
</select> </select>
</mapper> </mapper>
...@@ -11,26 +11,37 @@ ...@@ -11,26 +11,37 @@
VALUES VALUES
(#{id,jdbcType=VARCHAR}, #{houseResourceId,jdbcType=VARCHAR}, #{businessEntityInfoId,jdbcType=VARCHAR}) (#{id,jdbcType=VARCHAR}, #{houseResourceId,jdbcType=VARCHAR}, #{businessEntityInfoId,jdbcType=VARCHAR})
</insert> </insert>
<!-- 逻辑删除:按 (house_resource_id, business_entity_info_id) -->
<delete id="deleteByHouseResourceIdBusinessEntityInfoId"> <delete id="deleteByHouseResourceIdBusinessEntityInfoId">
DELETE FROM house_resource_business_entity_info_mapping UPDATE house_resource_business_entity_info_mapping
SET delete_flag = 1
WHERE house_resource_id = #{houseResourceId,jdbcType=VARCHAR} WHERE house_resource_id = #{houseResourceId,jdbcType=VARCHAR}
AND business_entity_info_id = #{businessEntityInfoId,jdbcType=VARCHAR} AND business_entity_info_id = #{businessEntityInfoId,jdbcType=VARCHAR}
AND delete_flag = 0
</delete> </delete>
<!-- 逻辑删除:按 house_resource_id 批量 -->
<delete id="deleteByHouseResourceId"> <delete id="deleteByHouseResourceId">
DELETE FROM house_resource_business_entity_info_mapping UPDATE house_resource_business_entity_info_mapping
SET delete_flag = 1
WHERE house_resource_id = #{houseResourceId,jdbcType=VARCHAR} WHERE house_resource_id = #{houseResourceId,jdbcType=VARCHAR}
AND delete_flag = 0
</delete> </delete>
<select id="selectByBusinessEntityInfoId" <select id="selectByBusinessEntityInfoId"
resultType="com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping"> resultType="com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping">
SELECT * FROM house_resource_business_entity_info_mapping WHERE business_entity_info_id = #{businessEntityInfoId,jdbcType=VARCHAR} SELECT * FROM house_resource_business_entity_info_mapping
WHERE business_entity_info_id = #{businessEntityInfoId,jdbcType=VARCHAR}
AND delete_flag = 0
</select> </select>
<select id="selectByHouseResourceId" <select id="selectByHouseResourceId"
resultType="com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping"> resultType="com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping">
SELECT * FROM house_resource_business_entity_info_mapping WHERE house_resource_id = #{houseResourceId,jdbcType=VARCHAR} SELECT * FROM house_resource_business_entity_info_mapping
WHERE house_resource_id = #{houseResourceId,jdbcType=VARCHAR}
AND delete_flag = 0
</select> </select>
<select id="selectByHouseResourceIds" <select id="selectByHouseResourceIds"
resultType="com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping"> resultType="com.ruoyi.system.domain.house.HouseResourceBusinessEntityInfoMapping">
SELECT * FROM house_resource_business_entity_info_mapping WHERE house_resource_id IN SELECT * FROM house_resource_business_entity_info_mapping
WHERE delete_flag = 0 AND house_resource_id IN
<foreach item="item" index="index" collection="houseResourceIds" open="(" separator="," close=")"> <foreach item="item" index="index" collection="houseResourceIds" open="(" separator="," close=")">
#{item} #{item}
</foreach> </foreach>
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
</insert> </insert>
<select id="selectHouseResourceById" resultType="com.ruoyi.system.domain.house.HouseResource" parameterType="string"> <select id="selectHouseResourceById" resultType="com.ruoyi.system.domain.house.HouseResource" parameterType="string">
SELECT * FROM house_resource WHERE id = #{id} SELECT * FROM house_resource WHERE id = #{id} AND delete_flag = 0
</select> </select>
<update id="updateHouseResource" parameterType="com.ruoyi.system.domain.house.HouseResource"> <update id="updateHouseResource" parameterType="com.ruoyi.system.domain.house.HouseResource">
...@@ -92,9 +92,8 @@ ...@@ -92,9 +92,8 @@
address = #{address}, address = #{address},
lon = #{lon}, lon = #{lon},
lat = #{lat}, lat = #{lat},
remark = #{remark}, remark = #{remark}
delete_flag = #{deleteFlag} WHERE id = #{id} AND delete_flag = 0
WHERE id = #{id}
</update> </update>
<delete id="deleteHouseResourceById" parameterType="string"> <delete id="deleteHouseResourceById" parameterType="string">
...@@ -136,10 +135,11 @@ ...@@ -136,10 +135,11 @@
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0 LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0
LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id AND t3.delete_flag = 0
LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id AND t4.delete_flag = 0
LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id AND t5.delete_flag = 0
<where> <where>
t1.delete_flag = 0
<if test="query.wgType != null"> <if test="query.wgType != null">
and t1.type = #{query.wgType} and t1.type = #{query.wgType}
</if> </if>
...@@ -316,10 +316,11 @@ ...@@ -316,10 +316,11 @@
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0 LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0
LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id AND t3.delete_flag = 0
LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id AND t4.delete_flag = 0
LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id AND t5.delete_flag = 0
<where> <where>
t1.delete_flag = 0
<if test="query.wgType != null"> <if test="query.wgType != null">
and t1.type = #{query.wgType} and t1.type = #{query.wgType}
</if> </if>
...@@ -490,10 +491,11 @@ ...@@ -490,10 +491,11 @@
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0 LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0
LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id AND t3.delete_flag = 0
LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id AND t4.delete_flag = 0
LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id AND t5.delete_flag = 0
<where> <where>
t1.delete_flag = 0
<if test="query.wgType != null"> <if test="query.wgType != null">
and t1.type = #{query.wgType} and t1.type = #{query.wgType}
</if> </if>
...@@ -693,10 +695,11 @@ ...@@ -693,10 +695,11 @@
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0 LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0
LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id AND t3.delete_flag = 0
LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id AND t4.delete_flag = 0
LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id AND t5.delete_flag = 0
<where> <where>
t1.delete_flag = 0
<if test="query.wgType != null"> <if test="query.wgType != null">
and t1.type = #{query.wgType} and t1.type = #{query.wgType}
</if> </if>
...@@ -827,7 +830,7 @@ ...@@ -827,7 +830,7 @@
ORDER BY t1.four, t1.three, t1.two ORDER BY t1.four, t1.three, t1.two
</select> </select>
<select id="selectAll" resultType="com.ruoyi.system.domain.house.HouseResource"> <select id="selectAll" resultType="com.ruoyi.system.domain.house.HouseResource">
SELECT * FROM house_resource SELECT * FROM house_resource WHERE delete_flag = 0
</select> </select>
<select id="selectPageBusinessEntityStatistics" resultType="com.ruoyi.system.domain.house.vo.HouseResourcePage"> <select id="selectPageBusinessEntityStatistics" resultType="com.ruoyi.system.domain.house.vo.HouseResourcePage">
SELECT SELECT
...@@ -837,9 +840,10 @@ ...@@ -837,9 +840,10 @@
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0 LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0
LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id AND t3.delete_flag = 0
LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id AND t4.delete_flag = 0
LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id AND t5.delete_flag = 0
WHERE t1.delete_flag = 0
GROUP BY t1.id, t4.id GROUP BY t1.id, t4.id
</select> </select>
<select id="selectForContrast" resultType="com.ruoyi.system.domain.house.vo.HouseResourcePage"> <select id="selectForContrast" resultType="com.ruoyi.system.domain.house.vo.HouseResourcePage">
...@@ -876,13 +880,13 @@ ...@@ -876,13 +880,13 @@
FROM FROM
house_resource t1 house_resource t1
LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0 LEFT JOIN grid_region t2 ON t2.wg_code = t1.four AND t1.delete_flag = 0
LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id LEFT JOIN house_resource_business_entity_info_mapping t3 ON t3.house_resource_id = t1.id AND t3.delete_flag = 0
LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id LEFT JOIN business_entity_info t4 ON t3.business_entity_info_id = t4.id AND t4.delete_flag = 0
LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id LEFT JOIN business_entity_sell t5 ON t5.business_entity_info_id = t4.id AND t5.delete_flag = 0
WHERE t1.two = #{two} AND t4.NAME = #{name} WHERE t1.delete_flag = 0 AND t1.two = #{two} AND t4.NAME = #{name}
</select> </select>
<select id="selectByIdList" resultType="com.ruoyi.system.domain.house.vo.HouseResourcePage"> <select id="selectByIdList" resultType="com.ruoyi.system.domain.house.vo.HouseResourcePage">
SELECT * FROM house_resource WHERE id IN SELECT * FROM house_resource WHERE delete_flag = 0 AND id IN
<foreach item="item" index="index" collection="idList" open="(" separator="," close=")"> <foreach item="item" index="index" collection="idList" open="(" separator="," close=")">
#{item} #{item}
</foreach> </foreach>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment