规范化类的名称

This commit is contained in:
2026-06-03 13:04:26 +08:00
parent c40d7aabcb
commit 6ce698eecc
8 changed files with 183 additions and 105 deletions

View File

@@ -1,7 +1,7 @@
package com.rj.controller; package com.rj.controller;
import com.rj.entity.FanManagement; import com.rj.entity.LbFanManagement;
import com.rj.service.IFanManagementService; import com.rj.service.ILbFanManagementService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
@@ -12,39 +12,40 @@ import org.springframework.web.bind.annotation.*;
import java.util.Map; import java.util.Map;
/** /**
* 粉丝管理fan_management前端控制器 * 粉丝管理lb_fan_management前端控制器
*/ */
@RestController @RestController
@RequestMapping("/api/fanManagement") @RequestMapping("/api/lbFanManagement")
@Tag(name = "粉丝管理", description = "fan_management 增删改查与分页") @Tag(name = "粉丝管理", description = "lb_fan_management 增删改查与分页")
public class FanManagementController { public class LbFanManagementController {
@Autowired @Autowired
private IFanManagementService fanManagementService; private ILbFanManagementService lbFanManagementService;
@PostMapping("/add") @PostMapping("/add")
@Operation(summary = "新增粉丝") @Operation(summary = "新增粉丝")
public ResponseEntity<Map<String, Object>> add( public ResponseEntity<Map<String, Object>> add(
@Parameter(description = "粉丝实体(id 必填", required = true) @Parameter(description = "粉丝实体(tenant_id、id 必填id_tenant_id 可省略,自动生成 id_tenantId", required = true)
@RequestBody FanManagement entity) { @RequestBody LbFanManagement entity) {
Map<String, Object> result = fanManagementService.add(entity); Map<String, Object> result = lbFanManagementService.add(entity);
return toResponse(result); return toResponse(result);
} }
@PutMapping("/update") @PutMapping("/update")
@Operation(summary = "修改粉丝") @Operation(summary = "修改粉丝")
public ResponseEntity<Map<String, Object>> update( public ResponseEntity<Map<String, Object>> update(
@Parameter(description = "粉丝实体(id 必填", required = true) @Parameter(description = "粉丝实体(tenant_id、id 必填;也可用 id_tenant_id 定位", required = true)
@RequestBody FanManagement entity) { @RequestBody LbFanManagement entity) {
Map<String, Object> result = fanManagementService.update(entity); Map<String, Object> result = lbFanManagementService.update(entity);
return toResponse(result); return toResponse(result);
} }
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete")
@Operation(summary = "删除粉丝") @Operation(summary = "删除粉丝")
public ResponseEntity<Map<String, Object>> delete( public ResponseEntity<Map<String, Object>> delete(
@Parameter(description = "粉丝ID", required = true) @PathVariable Long id) { @Parameter(description = "唯一IDid_tenant_id格式 id_tenantId", required = true)
Map<String, Object> result = fanManagementService.deleteById(id); @RequestParam String idTenantId) {
Map<String, Object> result = lbFanManagementService.deleteByIdTenantId(idTenantId);
return toResponse(result); return toResponse(result);
} }
@@ -61,7 +62,7 @@ public class FanManagementController {
@RequestParam(required = false) String createdAtStart, @RequestParam(required = false) String createdAtStart,
@Parameter(description = "创建时间止,格式 yyyy-MM-dd HH:mm:ss") @Parameter(description = "创建时间止,格式 yyyy-MM-dd HH:mm:ss")
@RequestParam(required = false) String createdAtEnd) { @RequestParam(required = false) String createdAtEnd) {
Map<String, Object> result = fanManagementService.pageQuery( Map<String, Object> result = lbFanManagementService.pageQuery(
current, size, nickname, mobile, shareNumMin, shareNumMax, current, size, nickname, mobile, shareNumMin, shareNumMax,
createdAtStart, createdAtEnd); createdAtStart, createdAtEnd);
Boolean success = (Boolean) result.get("success"); Boolean success = (Boolean) result.get("success");

View File

@@ -14,28 +14,32 @@ import java.io.Serializable;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/** /**
* 粉丝管理表 fan_management * 粉丝管理表 lb_fan_management
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@TableName("fan_management") @TableName("lb_fan_management")
@Schema(description = "粉丝管理") @Schema(description = "粉丝管理")
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class FanManagement implements Serializable { public class LbFanManagement implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 粉丝 id {@link #tenantId} 组成复合主键 {@code (tenant_id, id)} * 唯一主键格式{@code {id}_{tenantId}} {@code 98817_xxx-tenant-uuid}
*/ */
@TableId(value = "id", type = IdType.INPUT) @TableId(value = "id_tenant_id", type = IdType.INPUT)
@Schema(description = "粉丝ID复合主键之一,须与 tenantId 一起使用") @Schema(description = "唯一IDid_tenantId新增时可不传由服务端生成")
private Long id; private String idTenantId;
@TableField("tenant_id") @TableField("tenant_id")
@Schema(description = "租户ID") @Schema(description = "租户ID")
private String tenantId; private String tenantId;
@TableField("id")
@Schema(description = "粉丝ID可跨租户重复")
private Long id;
@TableField("avatar") @TableField("avatar")
@Schema(description = "头像路径") @Schema(description = "头像路径")
private String avatar; private String avatar;

View File

@@ -1,12 +0,0 @@
package com.rj.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rj.entity.FanManagement;
import org.apache.ibatis.annotations.Mapper;
/**
* 粉丝管理表 Mapper
*/
@Mapper
public interface FanManagementMapper extends BaseMapper<FanManagement> {
}

View File

@@ -0,0 +1,12 @@
package com.rj.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rj.entity.LbFanManagement;
import org.apache.ibatis.annotations.Mapper;
/**
* 粉丝管理表 lb_fan_management Mapper
*/
@Mapper
public interface LbFanManagementMapper extends BaseMapper<LbFanManagement> {
}

View File

@@ -1,20 +1,20 @@
package com.rj.service; package com.rj.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.rj.entity.FanManagement; import com.rj.entity.LbFanManagement;
import java.util.Map; import java.util.Map;
/** /**
* 粉丝管理服务 * 粉丝管理服务
*/ */
public interface IFanManagementService extends IService<FanManagement> { public interface ILbFanManagementService extends IService<LbFanManagement> {
Map<String, Object> add(FanManagement entity); Map<String, Object> add(LbFanManagement entity);
Map<String, Object> update(FanManagement entity); Map<String, Object> update(LbFanManagement entity);
Map<String, Object> deleteById(Long id); Map<String, Object> deleteByIdTenantId(String idTenantId);
Map<String, Object> pageQuery(Integer current, Map<String, Object> pageQuery(Integer current,
Integer size, Integer size,

View File

@@ -3,11 +3,12 @@ package com.rj.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rj.entity.FanManagement; import com.rj.entity.LbFanManagement;
import com.rj.mapper.FanManagementMapper; import com.rj.mapper.LbFanManagementMapper;
import com.rj.service.IFanManagementService; import com.rj.service.ILbFanManagementService;
import com.rj.tenant.TenantContextHolder; import com.rj.tenant.TenantContextHolder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -20,30 +21,38 @@ import java.util.Map;
*/ */
@Slf4j @Slf4j
@Service @Service
public class FanManagementServiceImpl public class LbFanManagementServiceImpl
extends ServiceImpl<FanManagementMapper, FanManagement> extends ServiceImpl<LbFanManagementMapper, LbFanManagement>
implements IFanManagementService { implements ILbFanManagementService {
private static final DateTimeFormatter DATE_TIME_FORMATTER = private static final DateTimeFormatter DATE_TIME_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override @Override
public Map<String, Object> add(FanManagement entity) { public Map<String, Object> add(LbFanManagement entity) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
try { try {
if (entity.getId() == null) { trimStringFields(entity);
fillTenantIdIfAbsent(entity);
Map<String, Object> keyError = validateCompositeKey(entity);
if (keyError != null) {
return keyError;
}
Map<String, Object> idTenantError = fillAndValidateIdTenantId(entity);
if (idTenantError != null) {
return idTenantError;
}
if (existsByIdTenantId(entity.getIdTenantId())) {
result.put("success", false); result.put("success", false);
result.put("message", "粉丝ID不能为空"); result.put("message", "唯一ID已存在" + entity.getIdTenantId());
return result; return result;
} }
trimStringFields(entity);
if (entity.getShareNum() == null) { if (entity.getShareNum() == null) {
entity.setShareNum(0); entity.setShareNum(0);
} }
if (entity.getCreatedAt() == null) { if (entity.getCreatedAt() == null) {
entity.setCreatedAt(LocalDateTime.now()); entity.setCreatedAt(LocalDateTime.now());
} }
fillTenantIdIfAbsent(entity);
boolean ok = this.save(entity); boolean ok = this.save(entity);
result.put("success", ok); result.put("success", ok);
@@ -52,6 +61,11 @@ public class FanManagementServiceImpl
result.put("data", entity); result.put("data", entity);
} }
return result; return result;
} catch (DuplicateKeyException e) {
log.warn("粉丝管理新增重复键, idTenantId={}", entity.getIdTenantId());
result.put("success", false);
result.put("message", "唯一ID已存在" + entity.getIdTenantId());
return result;
} catch (Exception e) { } catch (Exception e) {
log.error("粉丝管理新增异常", e); log.error("粉丝管理新增异常", e);
result.put("success", false); result.put("success", false);
@@ -61,22 +75,38 @@ public class FanManagementServiceImpl
} }
@Override @Override
public Map<String, Object> update(FanManagement entity) { public Map<String, Object> update(LbFanManagement entity) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
try { try {
if (entity.getId() == null) {
result.put("success", false);
result.put("message", "粉丝ID不能为空");
return result;
}
trimStringFields(entity); trimStringFields(entity);
fillTenantIdIfAbsent(entity); fillTenantIdIfAbsent(entity);
Map<String, Object> keyError = validateCompositeKey(entity);
if (keyError != null) {
return keyError;
}
Map<String, Object> idTenantError = fillAndValidateIdTenantId(entity);
if (idTenantError != null) {
return idTenantError;
}
LbFanManagement existing = this.getById(entity.getIdTenantId());
if (existing == null) {
result.put("success", false);
result.put("message", "记录不存在id_tenant_id=" + entity.getIdTenantId());
return result;
}
if (entity.getCreatedAt() == null) {
entity.setCreatedAt(existing.getCreatedAt());
}
// 唯一主键与联合键字段不可变更
entity.setIdTenantId(existing.getIdTenantId());
entity.setTenantId(existing.getTenantId());
entity.setId(existing.getId());
boolean ok = this.updateById(entity); boolean ok = this.updateById(entity);
result.put("success", ok); result.put("success", ok);
result.put("message", ok ? "修改成功" : "修改失败,记录可能不存在"); result.put("message", ok ? "修改成功" : "修改失败");
if (ok) { if (ok) {
result.put("data", getOneByIdAndTenant(entity.getId(), entity.getTenantId())); result.put("data", this.getById(entity.getIdTenantId()));
} }
return result; return result;
} catch (Exception e) { } catch (Exception e) {
@@ -88,20 +118,21 @@ public class FanManagementServiceImpl
} }
@Override @Override
public Map<String, Object> deleteById(Long id) { public Map<String, Object> deleteByIdTenantId(String idTenantId) {
Map<String, Object> result = new HashMap<>(); Map<String, Object> result = new HashMap<>();
try { try {
if (id == null) { if (idTenantId == null || idTenantId.trim().isEmpty()) {
result.put("success", false); result.put("success", false);
result.put("message", "粉丝ID不能为空"); result.put("message", "唯一IDid_tenant_id不能为空");
return result; return result;
} }
boolean ok = this.removeById(id); String key = idTenantId.trim();
boolean ok = this.removeById(key);
result.put("success", ok); result.put("success", ok);
result.put("message", ok ? "删除成功" : "删除失败,记录可能不存在"); result.put("message", ok ? "删除成功" : "删除失败,记录可能不存在");
return result; return result;
} catch (Exception e) { } catch (Exception e) {
log.error("粉丝管理删除异常, id={}", id, e); log.error("粉丝管理删除异常, idTenantId={}", idTenantId, e);
result.put("success", false); result.put("success", false);
result.put("message", "删除异常:" + e.getMessage()); result.put("message", "删除异常:" + e.getMessage());
return result; return result;
@@ -126,18 +157,18 @@ public class FanManagementServiceImpl
size = 10; size = 10;
} }
LambdaQueryWrapper<FanManagement> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<LbFanManagement> queryWrapper = new LambdaQueryWrapper<>();
if (nickname != null && !nickname.trim().isEmpty()) { if (nickname != null && !nickname.trim().isEmpty()) {
queryWrapper.like(FanManagement::getNickname, nickname.trim()); queryWrapper.like(LbFanManagement::getNickname, nickname.trim());
} }
if (mobile != null && !mobile.trim().isEmpty()) { if (mobile != null && !mobile.trim().isEmpty()) {
queryWrapper.like(FanManagement::getMobile, mobile.trim()); queryWrapper.like(LbFanManagement::getMobile, mobile.trim());
} }
if (shareNumMin != null) { if (shareNumMin != null) {
queryWrapper.ge(FanManagement::getShareNum, shareNumMin); queryWrapper.ge(LbFanManagement::getShareNum, shareNumMin);
} }
if (shareNumMax != null) { if (shareNumMax != null) {
queryWrapper.le(FanManagement::getShareNum, shareNumMax); queryWrapper.le(LbFanManagement::getShareNum, shareNumMax);
} }
LocalDateTime start = parseDateTime(createdAtStart); LocalDateTime start = parseDateTime(createdAtStart);
@@ -153,14 +184,14 @@ public class FanManagementServiceImpl
return result; return result;
} }
if (start != null) { if (start != null) {
queryWrapper.ge(FanManagement::getCreatedAt, start); queryWrapper.ge(LbFanManagement::getCreatedAt, start);
} }
if (end != null) { if (end != null) {
queryWrapper.le(FanManagement::getCreatedAt, end); queryWrapper.le(LbFanManagement::getCreatedAt, end);
} }
queryWrapper.orderByDesc(FanManagement::getCreatedAt); queryWrapper.orderByDesc(LbFanManagement::getCreatedAt);
Page<FanManagement> page = this.page(new Page<>(current, size), queryWrapper); Page<LbFanManagement> page = this.page(new Page<>(current, size), queryWrapper);
result.put("success", true); result.put("success", true);
result.put("message", "查询成功"); result.put("message", "查询成功");
result.put("data", page.getRecords()); result.put("data", page.getRecords());
@@ -177,16 +208,53 @@ public class FanManagementServiceImpl
} }
} }
private FanManagement getOneByIdAndTenant(Long id, String tenantId) { /**
LambdaQueryWrapper<FanManagement> q = new LambdaQueryWrapper<>(); * 生成唯一IDid + '_' + tenant_id
q.eq(FanManagement::getId, id); */
if (tenantId != null && !tenantId.trim().isEmpty()) { public static String buildIdTenantId(Long id, String tenantId) {
q.eq(FanManagement::getTenantId, tenantId.trim()); return id + "_" + tenantId;
}
return this.getOne(q, false);
} }
private void fillTenantIdIfAbsent(FanManagement entity) { private Map<String, Object> validateCompositeKey(LbFanManagement entity) {
Map<String, Object> result = new HashMap<>();
if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) {
result.put("success", false);
result.put("message", "租户ID不能为空");
return result;
}
if (entity.getId() == null) {
result.put("success", false);
result.put("message", "粉丝ID不能为空");
return result;
}
return null;
}
/**
* 填充 id_tenant_id并与传入值校验一致
*/
private Map<String, Object> fillAndValidateIdTenantId(LbFanManagement entity) {
Map<String, Object> result = new HashMap<>();
String expected = buildIdTenantId(entity.getId(), entity.getTenantId());
if (entity.getIdTenantId() == null || entity.getIdTenantId().trim().isEmpty()) {
entity.setIdTenantId(expected);
return null;
}
String actual = entity.getIdTenantId().trim();
if (!expected.equals(actual)) {
result.put("success", false);
result.put("message", "id_tenant_id 与 id、tenant_id 不一致,应为:" + expected);
return result;
}
entity.setIdTenantId(actual);
return null;
}
private boolean existsByIdTenantId(String idTenantId) {
return this.getById(idTenantId) != null;
}
private void fillTenantIdIfAbsent(LbFanManagement entity) {
if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) { if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) {
String tenantId = TenantContextHolder.getTenantId(); String tenantId = TenantContextHolder.getTenantId();
if (tenantId != null && !tenantId.trim().isEmpty()) { if (tenantId != null && !tenantId.trim().isEmpty()) {
@@ -195,7 +263,10 @@ public class FanManagementServiceImpl
} }
} }
private void trimStringFields(FanManagement entity) { private void trimStringFields(LbFanManagement entity) {
if (entity.getIdTenantId() != null) {
entity.setIdTenantId(entity.getIdTenantId().trim());
}
if (entity.getTenantId() != null) { if (entity.getTenantId() != null) {
entity.setTenantId(entity.getTenantId().trim()); entity.setTenantId(entity.getTenantId().trim());
} }

View File

@@ -1,22 +0,0 @@
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `fan_management`;
CREATE TABLE `fan_management` (
`id` BIGINT NOT NULL COMMENT '粉丝ID外部系统主键如 98817',
`tenant_id` VARCHAR(36) NULL DEFAULT NULL COMMENT '租户ID关联 tenant.id',
`avatar` VARCHAR(512) NULL DEFAULT NULL COMMENT '头像路径',
`nickname` VARCHAR(100) NULL DEFAULT NULL COMMENT '昵称(可为脱敏手机号,如 137****6199',
`mobile` VARCHAR(32) NULL DEFAULT NULL COMMENT '手机号',
`created_at` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
`share_num` INT NOT NULL DEFAULT 0 COMMENT '分享次数',
PRIMARY KEY (`tenant_id`, `id`) USING BTREE,
KEY `idx_fm_mobile` (`tenant_id`, `mobile`) USING BTREE,
KEY `idx_fm_created_at` (`tenant_id`, `created_at`) USING BTREE
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci
COMMENT='粉丝管理'
ROW_FORMAT=DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;

View File

@@ -0,0 +1,24 @@
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `lb_fan_management`;
CREATE TABLE `lb_fan_management` (
`id_tenant_id` VARCHAR(128) NOT NULL COMMENT '唯一ID格式id_tenantId如 98817_xxx-tenant-uuid',
`tenant_id` VARCHAR(36) NOT NULL COMMENT '租户ID',
`id` BIGINT NOT NULL COMMENT '粉丝ID外部业务ID仅 id 不唯一,可跨租户重复',
`avatar` VARCHAR(512) NULL DEFAULT NULL COMMENT '头像路径',
`nickname` VARCHAR(100) NULL DEFAULT NULL COMMENT '昵称(可为脱敏手机号,如 137****6199',
`mobile` VARCHAR(32) NULL DEFAULT NULL COMMENT '手机号',
`created_at` DATETIME NULL DEFAULT NULL COMMENT '创建时间',
`share_num` INT NOT NULL DEFAULT 0 COMMENT '分享次数',
PRIMARY KEY (`id_tenant_id`) USING BTREE,
UNIQUE KEY `uk_lfm_tenant_id` (`tenant_id`, `id`) USING BTREE,
KEY `idx_lfm_mobile` (`tenant_id`, `mobile`) USING BTREE,
KEY `idx_lfm_created_at` (`tenant_id`, `created_at`) USING BTREE
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_0900_ai_ci
COMMENT='粉丝管理(唯一主键 id_tenant_id = id + _ + tenant_id'
ROW_FORMAT=DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;