package com.kucun.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kucun.Service.AppService;
import com.kucun.Service.DynamicRepositoryService;
import com.kucun.data.entity.;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
@RestController
@RequestMapping(“/app”)
public class AppController {
@Autowired private AppService appService; @Autowired private ObjectMapper objectMapper; private Map<String, Class<?>> ENTITY_MAP ; @Autowired public AppController( DynamicRepositoryService dynamicRepositoryService, AppService appService, ObjectMapper objectMapper ) { this.ENTITY_MAP = dynamicRepositoryService.getStringClassMap(); this.appService = appService; this.objectMapper = objectMapper; } // ====================== 数据查询 ====================== @GetMapping("/all") public Information getAllData( @RequestParam(value = "since",required=false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Date since ) { System.out.println("since:"+since); try { if(since == null) return appService.getAllData(); else return appService.getUpdatesSince(since); } catch (Exception e) { // TODO: handle exception return Information.NewFail(e.getMessage()); } } // 添加保存全部数据的API端点 @PostMapping("/save-all") public Information saveAllData(@RequestBody Map<String, List<?>> allData) { try { return appService.saveAllData(allData); } catch (Exception e) { return Information.NewFail("保存全部数据失败: " + e.getMessage()); } } @GetMapping("/all/{entityType}") public Information getEntityData(@PathVariable String entityType, @RequestParam(value = "since",required=false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) Date since) { return appService.getEntityData(entityType.toLowerCase()); } // ====================== CRUD操作 ====================== @PostMapping("/add/{entityType}") public Information addEntity( @PathVariable String entityType, @RequestBody @Valid Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "add"); } @PostMapping("/select/{entityType}") public Information queryEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "select"); } @PostMapping("/delete/{entityType}") public Information deleteEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "delete"); } @PostMapping("/update/{entityType}") public Information updateEntity( @PathVariable String entityType, @RequestBody Map<String, Object> requestBody ) { return handleEntityOperation(entityType, requestBody, "update"); } // ====================== 核心辅助方法 ====================== private Information handleEntityOperation( String entityType, Map<String, Object> requestBody, String operation ) { String normalizedType = entityType.toLowerCase(); // 特殊处理 Dingdan_bancai if ("dingdan_bancai".equals(normalizedType)) { try { Dingdan_bancai entity = objectMapper.convertValue(requestBody, Dingdan_bancai.class); // 从请求体中提取用户ID并设置到临时字段 if (requestBody.containsKey("currentUserId")) { entity.setCurrentUserId(((Integer) requestBody.get("currentUserId"))); } return appService.handleDingdanBancaiOperation( entity, operation); } catch (Exception e) { return Information.NewFail(operation + "操作失败: " + e.getMessage()); } } Class<?> entityClass = ENTITY_MAP.get(normalizedType); if (entityClass == null) { return Information.NewFail("不支持的实体类型: " + entityType); } try { Object entity = objectMapper.convertValue(requestBody, entityClass); //System.out.println(Information.NewSuccess(requestBody).DataJson()); switch (operation) { case "add": return appService.addEntity(entity); case "select": return appService.queryEntity((EntityBasis) entity); case "delete": // 确保实体实现了EntityBasis接口 if (entity instanceof EntityBasis) { return appService.deleteEntity((EntityBasis) entity); } else { return Information.NewFail("删除操作需要实体实现EntityBasis接口"); } case "update": return appService.updateEntity(entity); default: return Information.NewFail("无效的操作类型"); } } catch (Exception e) { return Information.NewFail(operation + "操作失败: " + e.getMessage()); } }
}package com.kucun.Service;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import com.kucun.data.entity.;
import com.kucun.dataDo.;
/**
*
*
*
*/
@Service
public class AppService {
// 自动注入所有依赖 @Autowired private KucunRepository kucunRepository; @Autowired private DynamicRepositoryService repositoryService; @Autowired private EntityDependencyService dependencyService; /** * 获取所有实体类型的数据 * @return 包含所有实体数据的Map * * */ public Information getAllData() { Map<String, Object> response = new HashMap<>(); repositoryService.getRepositoryNameMap().forEach((key, repo) -> response.put(key + "s", repo.findAll()) ); return Information.NewSuccess(response); } /** * 获取自指定时间以来的所有更新 * @param since 时间戳 * @return 按实体类型分组的更新数据 */ public Information getUpdatesSince(Date since) { Map<String, List<?>> updates = new HashMap<>(); Map<String, CustomRepository<?, ?>> repoMap = repositoryService.getRepositoryNameMap(); repoMap.forEach((entityName, repo) -> { // 使用反射查询大于指定时间的记录 List<?> results = repositoryService.findUpdatedSince(entityName, since); if (!results.isEmpty()) { updates.put(entityName+'s', results); } }); return Information.NewSuccess(updates); } /** * 获取指定实体类型的所有数据 * @param entityName 实体名称 * @return 实体数据列表 * * */ public Information getEntityData(String entityName) { JpaRepository<?, ?> repo = repositoryService.getJpaRepository(entityName); return Information.NewSuccess(repo.findAll()); } /** * 添加新实体 * @param entity 要添加的实体对象 * @return 添加结果 * * */ public Information addEntity(@Valid Object entity) { try { // 处理关联字段 handleAssociations(entity); // 获取对应的Repository并保存 JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entity.getClass()); //System.out.println(Information.NewSuccess(entity).DataJson()); if(entity instanceof User) { if(((User) entity).getPass()!=null) { String psass=((User) entity).getPass(); ((User) entity).setPass(PasswordService.hashPassword(psass)); } } Object savedEntity = repo.save(entity); // 如果是板材,初始化库存 if (savedEntity instanceof Bancai) { initializeKucunForBancai((Bancai) savedEntity); } return Information.NewSuccess(savedEntity); } catch (Exception ex) { return Information.Newfail(500, "创建失败: " + ex.getMessage(), null); } } /** * 更新实体 * @param entity 包含ID的实体对象 * @return 更新结果 * * */ public Information updateEntity(Object entity) { if (entity == null) { return Information.Newfail(403, "参数为空", null); } // 获取ID字段 Field idField=null; try { idField = getIdField(entity); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { idField.setAccessible(true); Object idValue = idField.get(entity); if (idValue == null) { return Information.Newfail(403, "ID为空", null); } // 获取Repository和现有实体 JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entity.getClass()); Object existingEntity = repo.findById((Serializable) idValue) .orElseThrow(() -> new RuntimeException("实体不存在")); if(entity instanceof User) { if(((User) entity).getPass()!=null) { String psass=((User) entity).getPass(); ((User) entity).setPass(PasswordService.hashPassword(psass)); } } // 复制非空属性并保存 copyNonNullProperties(entity, existingEntity); return Information.NewSuccess(repo.save(existingEntity)); } catch (Exception ex) { ex.fillInStackTrace(); return Information.Newfail(500, "更新失败: " + ex.getMessage(), null); } } /** * 删除实体 * @param entity 要删除的实体 * @return 删除结果 */ public Information deleteEntity(EntityBasis entity) { if (entity == null) { return Information.NewFail("删除对象不能为空"); } try { String entityName = entity.getClass().getSimpleName().toLowerCase(); JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entityName); // 先加载完整实体(关键步骤) Object managedEntity = repo.findById(entity.getId()) .orElseThrow(() -> new EntityNotFoundException("实体不存在")); if(entity instanceof Bancai) { Kucun k=kucunRepository.findByBancai((Bancai)entity); if(k!=null&&k.getShuliang()>0) { return Information.NewFail("库存不为零,无法删除"); } if(k!=null) { Field deletedField = k.getClass().getDeclaredField("deleted"); deletedField.setAccessible(true); deletedField.set(k, true); Field deletedAtField = k.getClass().getDeclaredField("deletedAt"); deletedAtField.setAccessible(true); deletedAtField.set(k, new Date()); kucunRepository.save(k); } } // 检查依赖关系 if (dependencyService.hasDependencies(entity.getClass(), entity.getId())) { return Information.NewFail("该记录已被引用,无法删除"); } // 使用实体对象删除(触发级联操作) Field deletedField = managedEntity.getClass().getDeclaredField("deleted"); deletedField.setAccessible(true); deletedField.set(managedEntity, true); Field deletedAtField = managedEntity.getClass().getDeclaredField("deletedAt"); deletedAtField.setAccessible(true); deletedAtField.set(managedEntity, new Date()); repo.save(managedEntity); return Information.NewSuccess("删除成功"); } catch (Exception e) { return Information.NewFail("删除错误: " + e.getMessage()); } }/** * 动态查询实体 * @param entity 包含查询条件的实体对象 * @return 查询结果 */ public <T extends EntityBasis> Information queryEntity(T entity) { if (entity == null) { return Information.NewFail("查询参数不能为空"); } try { JpaRepository<T, ?> repo = (JpaRepository<T, ?>) repositoryService.getJpaRepository(entity.getClass()); // 创建基础查询条件 ExampleMatcher matcher = ExampleMatcher.matching() .withIgnoreNullValues() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING); if(entity.getDeleted()==null) { // 添加软删除过滤条件 if (entity instanceof EntityBasis) { // 动态设置deleted=false条件 Field deletedField = EntityBasis.class.getDeclaredField("deleted"); deletedField.setAccessible(true); deletedField.set(entity, false); } } Example<T> example = Example.of(entity, matcher); return Information.NewSuccess(repo.findAll(example)); } catch (Exception e) { return Information.NewFail("查询失败: " + e.getMessage()); } } // ====================== 私有辅助方法 ====================== /** * 为板材初始化库存 * @param bancai 板材对象 */ private void initializeKucunForBancai(Bancai bancai) throws Exception { Kucun kucun = new Kucun(null, bancai, 0); bancai.setKucun(kucunRepository.save(kucun)); } /** * 处理实体关联关系 * @param entity 要处理的实体 */ private void handleAssociations(Object entity) throws Exception { for (Field field : entity.getClass().getDeclaredFields()) { field.setAccessible(true); Object value = field.get(entity); if (value == null) continue; // 处理 JPA 实体关联 if (value instanceof EntityBasis) { EntityBasis associated = (EntityBasis) value; JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(associated.getClass().getSimpleName().toLowerCase()); // 只处理已存在实体(不创建新关联) if (associated.getId() != null) { Object managedEntity = repo.findById(associated.getId()) .orElseThrow(() -> new Exception("关联实体不存在")); field.set(entity, managedEntity); } } // 处理集合关联 else if (value instanceof Collection) { List<Object> managedEntities = new ArrayList<>(); for (Object item : (Collection<?>) value) { if (item instanceof EntityBasis) { EntityBasis eb = (EntityBasis) item; JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(eb.getClass().getSimpleName().toLowerCase()); if (eb.getId() != null) { managedEntities.add(repo.findById(eb.getId()) .orElseThrow(() -> new Exception("关联实体不存在"))); } } } if (!managedEntities.isEmpty()) { field.set(entity, managedEntities); } } } } /** * 处理实体关联关系 * @param entity 要处理的实体 */ private void handleAssociationss(Object entity) throws Exception { for (Field field : entity.getClass().getDeclaredFields()) { field.setAccessible(true); Object value = field.get(entity); if(value instanceof EntityBasis) { } } } /** * 复制非空属性 * @param source 源对象 * @param target 目标对象 */ private void copyNonNullProperties(Object source, Object target) throws IllegalAccessException { for (Field field : source.getClass().getDeclaredFields()) { field.setAccessible(true); Object value = field.get(source); // 跳过关联字段和ID字段 if (value != null && !(value instanceof EntityBasis) && !(value instanceof Collection) && !field.getName().equals("id")) { try { Field targetField = target.getClass().getDeclaredField(field.getName()); targetField.setAccessible(true); targetField.set(target, value); } catch (NoSuchFieldException ignored) {} } } }
/*
* 获取实体类的id字段(支持父类查找)
* @param entity 实体对象
* @return Field对象或null
*/
public static Field getIdField(Object entity) {
if (entity == null) {
return null;
}
Class<?> clazz = entity.getClass(); // 递归查找类及其父类的id字段 while (clazz != null && clazz != Object.class) { try { Field idField = clazz.getDeclaredField("id"); idField.setAccessible(true); return idField; } catch (NoSuchFieldException e) { // 继续向上查找父类 clazz = clazz.getSuperclass(); } catch (SecurityException e) { e.printStackTrace(); return null; } } return null;
}
// ====================== 专用方法处理 Dingdan_bancai ======================
@Transactional
public Information handleDingdanBancaiOperation(
Dingdan_bancai entity,
String operation
) {
try {
// 获取对应的Repository
JpaRepository<Object, Serializable> repo =
(JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(“dingdan_bancai”);
switch (operation) { case "add": Dingdan_bancai savedEntity = (Dingdan_bancai) repo.save(entity); updateKucunAndCreateJinhuo(savedEntity, savedEntity.getShuliang()); return Information.NewSuccess(savedEntity); case "update": // 先获取现有实体以计算差异 Dingdan_bancai existing = (Dingdan_bancai) repo.findById(entity.getId()) .orElseThrow(() -> new EntityNotFoundException("实体不存在")); int quantityDifference = entity.getShuliang() - existing.getShuliang(); Dingdan_bancai updatedEntity = (Dingdan_bancai) repo.save(entity); if (quantityDifference != 0) { updateKucunAndCreateJinhuo(updatedEntity, quantityDifference); } return Information.NewSuccess(updatedEntity); default: return Information.NewFail("不支持的操作类型: " + operation); } } catch (Exception ex) { return Information.NewFail(operation + "操作失败: " + ex.getMessage()); }
}
// 更新库存并创建进货记录
private void updateKucunAndCreateJinhuo(Dingdan_bancai db, int quantityChange) {
// 1. 更新库存
Bancai bancai = db.getBancai();
Kucun kucun = kucunRepository.findByBancai(bancai);
if (kucun == null) { kucun = new Kucun(null, bancai, 0); } kucun.setShuliang(kucun.getShuliang() + quantityChange); kucunRepository.save(kucun); // 2. 创建进货记录 Jinhuo jinhuo = new Jinhuo(); jinhuo.setDingdan_bancai(db); jinhuo.setShuliang(quantityChange); jinhuo.setDate(new Date()); // 使用临时字段设置用户 if (db.getCurrentUserId() != null) { User user = new User(); user.setId(db.getCurrentUserId()); jinhuo.setUser(user); } ((JinhuoRepository)repositoryService.getJpaRepository(jinhuo.getClass())).save( jinhuo);
}
// … existing code …
/**
* 保存所有实体类型的数据
* @param allData 包含所有实体数据的Map,key为实体类型名+“s”,value为实体列表
* @return 保存结果
*/
@Transactional
public Information saveAllData(Map<String, List<?>> allData) {
Map<String, Object> response = new HashMap<>();
allData.forEach((key, entities) -> { String entityName = key.endsWith("s") ? key.substring(0, key.length() - 1) : key; // 获取实体类类型 Class<?> entityClass = repositoryService.getEntityClass(entityName); if (entityClass != null) { // 类型安全转换 List<?> convertedList = entities.stream() .filter(entityClass::isInstance) .map(entityClass::cast) .collect(Collectors.toList()); // 保存实体 List<?> savedEntities = repositoryService.saveEntities( entityName, convertedList ); response.put(key, savedEntities); } else { response.put(key + "_error", "实体类型未注册"); } }); return Information.NewSuccess(response); }
// … existing code …
}---@startuml
' 基础类与接口
abstract class EntityBasis {
+ Integer id
+ Date lastUpdated
+ Boolean deleted
+ Date deletedAt
+ getId()
+ setId(Integer)
}
interface EntityBasisId {
+ getId()
+ setId(Integer)
}
abstract class SimpleEntity {
+ Integer id
+ String name
}
' 实体类定义
class Mupi {
+ Boolean you
+ String name
+ List<Bancai> bancaisForMupi1
+ List<Bancai> bancaisForMupi2
}
class User {
+ String name
+ String andy
+ String pass
+ int role
+ int incumbency
}
class Chanpin_zujian {
+ Double one_howmany
+ Double zujianshu
}
class WechatUser {
+ String openid
+ String sessionKey
+ String nickname
+ String avatarUrl
+ String phoneNumber
+ Long userId
+ Date createTime
+ Integer status
}
class Kucun {
+ Integer shuliang
}
class Dingdan_chanpin {
+ Integer shuliang
}
class Information {
+ Integer Status
+ String text
+ Object data
}
class Zujian {
+ String name
+ List<Chanpin_zujian> chanping_zujian
}
class Dingdan_bancai {
+ Integer shuliang
+ Integer currentUserId
}
class Dingdan {
+ String number
+ Date xiadan
+ Date jiaohuo
+ List<Dingdan_chanpin> dingdan_chanpin
}
class Jinhuo {
+ Integer shuliang
+ Date date
+ String text
+ Integer theTypeOfOperation
}
class Caizhi {
+ String name
+ List<Bancai> bancai
}
class Bancai {
+ Double houdu
}
' 继承关系
EntityBasis --|> EntityBasisId
SimpleEntity --|> EntityBasisId
Mupi --|> EntityBasis
User --|> EntityBasis
Chanpin_zujian --|> EntityBasis
WechatUser --|> EntityBasis
Kucun --|> EntityBasis
Dingdan_chanpin --|> EntityBasis
Zujian --|> EntityBasis
Dingdan_bancai --|> EntityBasis
Dingdan --|> EntityBasis
Jinhuo --|> EntityBasis
Caizhi --|> EntityBasis
Bancai --|> EntityBasis
' 关联关系
' 一对一
Bancai -- Kucun : 1:1 (kucun)
' 一对多/多对一
Chanpin "1" -- "*" Chanpin_zujian : 包含 (chanpin_zujian)
Zujian "1" -- "*" Chanpin_zujian : 关联 (chanping_zujian)
Bancai "1" -- "*" Chanpin_zujian : 被使用 (bancai)
Dingdan "1" -- "*" Dingdan_chanpin : 包含 (dingdan_chanpin)
Chanpin "1" -- "*" Dingdan_chanpin : 被订购 (chanpin)
Dingdan "1" -- "*" Dingdan_bancai : 包含 (dingdan)
Chanpin "1" -- "*" Dingdan_bancai : 关联 (chanpin)
Zujian "1" -- "*" Dingdan_bancai : 关联 (zujian)
Bancai "1" -- "*" Dingdan_bancai : 被订购 (bancai)
User "1" -- "*" Jinhuo : 操作 (user)
Dingdan_bancai "1" -- "*" Jinhuo : 关联 (dingdan_bancai)
' 单向关联
WechatUser -- User : 绑定 (userId)
@enduml----用php脚本实现api,远程虚拟主机运行
最新发布