diff --git a/src/main/java/com/rj/config/MybatisPlusConfig.java b/src/main/java/com/rj/config/MybatisPlusConfig.java index 9261343..bd57276 100644 --- a/src/main/java/com/rj/config/MybatisPlusConfig.java +++ b/src/main/java/com/rj/config/MybatisPlusConfig.java @@ -62,6 +62,7 @@ public class MybatisPlusConfig { ignoreTables.add("ai_prompts"); // AI 提示词全局配置,表无 tenant_id 字段 ignoreTables.add("lb_third_integration_config"); // 每租户一条,按 tenant_id 显式查询,不走插件自动拼接 ignoreTables.add("lb_buy_account"); // 抢单账号跨租户管理;分页/批量抢单按记录 tenant_id 业务处理 + ignoreTables.add("lb_buyer_shopping"); // 买方购物表无 tenant_id 字段 return new TenantLineHandler() { diff --git a/src/main/java/com/rj/controller/LbBuyerShoppingController.java b/src/main/java/com/rj/controller/LbBuyerShoppingController.java new file mode 100644 index 0000000..aaea2a6 --- /dev/null +++ b/src/main/java/com/rj/controller/LbBuyerShoppingController.java @@ -0,0 +1,102 @@ +package com.rj.controller; + +import com.rj.entity.LbBuyerShopping; +import com.rj.service.ILbBuyerShoppingService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.math.BigDecimal; +import java.util.Map; + +/** + * 买方购物表(lb_buyer_shopping)前端控制器 + */ +@RestController +@RequestMapping("/api/lbBuyerShopping") +@Tag(name = "买方购物", description = "lb_buyer_shopping 增删改查与分页") +public class LbBuyerShoppingController { + + @Autowired + private ILbBuyerShoppingService lbBuyerShoppingService; + + @PostMapping("/add") + @Operation(summary = "新增") + public ResponseEntity> add( + @Parameter(description = "实体(id 为外部订单 id,需调用方指定)", required = true) + @RequestBody LbBuyerShopping entity) { + Map result = lbBuyerShoppingService.add(entity); + return toResponse(result); + } + + @PutMapping("/update") + @Operation(summary = "编辑") + public ResponseEntity> update( + @Parameter(description = "实体", required = true) @RequestBody LbBuyerShopping entity) { + Map result = lbBuyerShoppingService.update(entity); + return toResponse(result); + } + + @DeleteMapping("/delete/{id}") + @Operation(summary = "删除") + public ResponseEntity> delete( + @Parameter(description = "主键(订单 id)", required = true) @PathVariable Long id) { + Map result = lbBuyerShoppingService.deleteById(id); + return toResponse(result); + } + + @GetMapping("/list") + @Operation(summary = "分页查询") + public ResponseEntity> list( + @RequestParam(defaultValue = "1") Integer current, + @RequestParam(defaultValue = "10") Integer size, + @RequestParam(required = false) Long sellerId, + @RequestParam(required = false) Long merchandiseId, + @RequestParam(required = false) Long buyerId, + @RequestParam(required = false) String orderSn, + @RequestParam(required = false) String sellerNickname, + @RequestParam(required = false) String sellerMobile, + @RequestParam(required = false) String buyerNickname, + @RequestParam(required = false) String buyerMobile, + @RequestParam(required = false) BigDecimal totalMoneyMin, + @RequestParam(required = false) BigDecimal totalMoneyMax, + @Parameter(description = "创建时间起,格式 yyyy-MM-dd HH:mm:ss") + @RequestParam(required = false) String createdAtStart, + @Parameter(description = "创建时间止,格式 yyyy-MM-dd HH:mm:ss") + @RequestParam(required = false) String createdAtEnd, + @Parameter(description = "购买时间起,格式 yyyy-MM-dd HH:mm:ss") + @RequestParam(required = false) String buyTimeStart, + @Parameter(description = "购买时间止,格式 yyyy-MM-dd HH:mm:ss") + @RequestParam(required = false) String buyTimeEnd, + @Parameter(description = "确认时间起,格式 yyyy-MM-dd HH:mm:ss") + @RequestParam(required = false) String confirmTimeStart, + @Parameter(description = "确认时间止,格式 yyyy-MM-dd HH:mm:ss") + @RequestParam(required = false) String confirmTimeEnd) { + Map result = lbBuyerShoppingService.pageQuery( + current, size, sellerId, merchandiseId, buyerId, orderSn, + sellerNickname, sellerMobile, buyerNickname, buyerMobile, + totalMoneyMin, totalMoneyMax, + createdAtStart, createdAtEnd, buyTimeStart, buyTimeEnd, + confirmTimeStart, confirmTimeEnd); + Boolean success = (Boolean) result.get("success"); + if (success != null && success) { + return ResponseEntity.ok(result); + } + if (result.get("message") != null + && result.get("message").toString().contains("格式错误")) { + return ResponseEntity.badRequest().body(result); + } + return ResponseEntity.internalServerError().body(result); + } + + private ResponseEntity> toResponse(Map result) { + Boolean success = (Boolean) result.get("success"); + if (success != null && success) { + return ResponseEntity.ok(result); + } + return ResponseEntity.badRequest().body(result); + } +} diff --git a/src/main/java/com/rj/entity/LbBuyerShopping.java b/src/main/java/com/rj/entity/LbBuyerShopping.java new file mode 100644 index 0000000..270a30d --- /dev/null +++ b/src/main/java/com/rj/entity/LbBuyerShopping.java @@ -0,0 +1,87 @@ +package com.rj.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 买方购物表 lb_buyer_shopping + */ +@Data +@EqualsAndHashCode(callSuper = false) +@TableName("lb_buyer_shopping") +@Schema(description = "买方购物表") +@JsonIgnoreProperties(ignoreUnknown = true) +public class LbBuyerShopping implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(value = "id", type = IdType.INPUT) + @Schema(description = "订单ID(外部系统主键)") + private Long id; + + @TableField("seller_id") + @Schema(description = "卖家ID") + private Long sellerId; + + @TableField("merchandise_id") + @Schema(description = "商品ID") + private Long merchandiseId; + + @TableField("buyer_id") + @Schema(description = "买家ID") + private Long buyerId; + + @TableField("order_sn") + @Schema(description = "订单号") + private String orderSn; + + @TableField("total_money") + @Schema(description = "订单总金额") + private BigDecimal totalMoney; + + @TableField("new_total") + @Schema(description = "更新后总金额") + private BigDecimal newTotal; + + @TableField("created_at") + @Schema(description = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime createdAt; + + @TableField("buy_time") + @Schema(description = "下单/购买时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime buyTime; + + @TableField("confirm_time") + @Schema(description = "确认时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime confirmTime; + + @TableField("seller_nickname") + @Schema(description = "卖家昵称") + private String sellerNickname; + + @TableField("seller_mobile") + @Schema(description = "卖家手机号") + private String sellerMobile; + + @TableField("buyer_nickname") + @Schema(description = "买家昵称") + private String buyerNickname; + + @TableField("buyer_mobile") + @Schema(description = "买家手机号") + private String buyerMobile; +} diff --git a/src/main/java/com/rj/mapper/LbBuyerShoppingMapper.java b/src/main/java/com/rj/mapper/LbBuyerShoppingMapper.java new file mode 100644 index 0000000..db9684a --- /dev/null +++ b/src/main/java/com/rj/mapper/LbBuyerShoppingMapper.java @@ -0,0 +1,12 @@ +package com.rj.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.rj.entity.LbBuyerShopping; +import org.apache.ibatis.annotations.Mapper; + +/** + * 买方购物表 lb_buyer_shopping Mapper + */ +@Mapper +public interface LbBuyerShoppingMapper extends BaseMapper { +} diff --git a/src/main/java/com/rj/service/ILbBuyerShoppingService.java b/src/main/java/com/rj/service/ILbBuyerShoppingService.java new file mode 100644 index 0000000..7bdb1a3 --- /dev/null +++ b/src/main/java/com/rj/service/ILbBuyerShoppingService.java @@ -0,0 +1,38 @@ +package com.rj.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.rj.entity.LbBuyerShopping; + +import java.math.BigDecimal; +import java.util.Map; + +/** + * 买方购物表 lb_buyer_shopping 服务 + */ +public interface ILbBuyerShoppingService extends IService { + + Map add(LbBuyerShopping entity); + + Map update(LbBuyerShopping entity); + + Map deleteById(Long id); + + Map pageQuery(Integer current, + Integer size, + Long sellerId, + Long merchandiseId, + Long buyerId, + String orderSn, + String sellerNickname, + String sellerMobile, + String buyerNickname, + String buyerMobile, + BigDecimal totalMoneyMin, + BigDecimal totalMoneyMax, + String createdAtStart, + String createdAtEnd, + String buyTimeStart, + String buyTimeEnd, + String confirmTimeStart, + String confirmTimeEnd); +} diff --git a/src/main/java/com/rj/service/impl/LbBuyerShoppingServiceImpl.java b/src/main/java/com/rj/service/impl/LbBuyerShoppingServiceImpl.java new file mode 100644 index 0000000..41f8712 --- /dev/null +++ b/src/main/java/com/rj/service/impl/LbBuyerShoppingServiceImpl.java @@ -0,0 +1,298 @@ +package com.rj.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.rj.entity.LbBuyerShopping; +import com.rj.mapper.LbBuyerShoppingMapper; +import com.rj.service.ILbBuyerShoppingService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DuplicateKeyException; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + +/** + * 买方购物表 lb_buyer_shopping 服务实现 + */ +@Slf4j +@Service +public class LbBuyerShoppingServiceImpl + extends ServiceImpl + implements ILbBuyerShoppingService { + + private static final DateTimeFormatter DATE_TIME_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public Map add(LbBuyerShopping entity) { + Map result = new HashMap<>(); + try { + if (entity.getId() == null) { + result.put("success", false); + result.put("message", "id不能为空"); + return result; + } + trimStringFields(entity); + if (this.getById(entity.getId()) != null) { + result.put("success", false); + result.put("message", "该订单 id 已存在"); + return result; + } + applyDefaults(entity); + if (entity.getCreatedAt() == null) { + entity.setCreatedAt(LocalDateTime.now()); + } + + boolean ok = this.save(entity); + result.put("success", ok); + result.put("message", ok ? "新增成功" : "新增失败"); + if (ok) { + result.put("data", this.getById(entity.getId())); + } + return result; + } catch (DuplicateKeyException e) { + log.warn("买方购物新增重复键, id={}", entity.getId()); + result.put("success", false); + result.put("message", "该订单 id 已存在"); + return result; + } catch (Exception e) { + log.error("买方购物新增异常", e); + result.put("success", false); + result.put("message", "新增异常:" + e.getMessage()); + return result; + } + } + + @Override + public Map update(LbBuyerShopping entity) { + Map result = new HashMap<>(); + try { + if (entity.getId() == null) { + result.put("success", false); + result.put("message", "id不能为空"); + return result; + } + LbBuyerShopping existing = this.getById(entity.getId()); + if (existing == null) { + result.put("success", false); + result.put("message", "记录不存在"); + return result; + } + trimStringFields(entity); + if (entity.getTotalMoney() == null) { + entity.setTotalMoney(existing.getTotalMoney()); + } + + boolean ok = this.updateById(entity); + result.put("success", ok); + result.put("message", ok ? "编辑成功" : "编辑失败"); + if (ok) { + result.put("data", this.getById(entity.getId())); + } + return result; + } catch (Exception e) { + log.error("买方购物编辑异常", e); + result.put("success", false); + result.put("message", "编辑异常:" + e.getMessage()); + return result; + } + } + + @Override + public Map deleteById(Long id) { + Map result = new HashMap<>(); + try { + if (id == null) { + result.put("success", false); + result.put("message", "id不能为空"); + return result; + } + boolean ok = this.removeById(id); + result.put("success", ok); + result.put("message", ok ? "删除成功" : "删除失败"); + return result; + } catch (Exception e) { + log.error("买方购物删除异常", e); + result.put("success", false); + result.put("message", "删除异常:" + e.getMessage()); + return result; + } + } + + @Override + public Map pageQuery(Integer current, + Integer size, + Long sellerId, + Long merchandiseId, + Long buyerId, + String orderSn, + String sellerNickname, + String sellerMobile, + String buyerNickname, + String buyerMobile, + BigDecimal totalMoneyMin, + BigDecimal totalMoneyMax, + String createdAtStart, + String createdAtEnd, + String buyTimeStart, + String buyTimeEnd, + String confirmTimeStart, + String confirmTimeEnd) { + Map result = new HashMap<>(); + try { + if (current == null || current < 1) { + current = 1; + } + if (size == null || size < 1) { + size = 10; + } + + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + if (sellerId != null) { + queryWrapper.eq(LbBuyerShopping::getSellerId, sellerId); + } + if (merchandiseId != null) { + queryWrapper.eq(LbBuyerShopping::getMerchandiseId, merchandiseId); + } + if (buyerId != null) { + queryWrapper.eq(LbBuyerShopping::getBuyerId, buyerId); + } + if (orderSn != null && !orderSn.trim().isEmpty()) { + queryWrapper.like(LbBuyerShopping::getOrderSn, orderSn.trim()); + } + if (sellerNickname != null && !sellerNickname.trim().isEmpty()) { + queryWrapper.like(LbBuyerShopping::getSellerNickname, sellerNickname.trim()); + } + if (sellerMobile != null && !sellerMobile.trim().isEmpty()) { + queryWrapper.like(LbBuyerShopping::getSellerMobile, sellerMobile.trim()); + } + if (buyerNickname != null && !buyerNickname.trim().isEmpty()) { + queryWrapper.like(LbBuyerShopping::getBuyerNickname, buyerNickname.trim()); + } + if (buyerMobile != null && !buyerMobile.trim().isEmpty()) { + queryWrapper.like(LbBuyerShopping::getBuyerMobile, buyerMobile.trim()); + } + if (totalMoneyMin != null) { + queryWrapper.ge(LbBuyerShopping::getTotalMoney, totalMoneyMin); + } + if (totalMoneyMax != null) { + queryWrapper.le(LbBuyerShopping::getTotalMoney, totalMoneyMax); + } + + LocalDateTime createdStart = parseDateTime(createdAtStart); + if (createdAtStart != null && !createdAtStart.trim().isEmpty() && createdStart == null) { + result.put("success", false); + result.put("message", "createdAtStart 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); + return result; + } + LocalDateTime createdEnd = parseDateTime(createdAtEnd); + if (createdAtEnd != null && !createdAtEnd.trim().isEmpty() && createdEnd == null) { + result.put("success", false); + result.put("message", "createdAtEnd 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); + return result; + } + if (createdStart != null) { + queryWrapper.ge(LbBuyerShopping::getCreatedAt, createdStart); + } + if (createdEnd != null) { + queryWrapper.le(LbBuyerShopping::getCreatedAt, createdEnd); + } + + LocalDateTime buyStart = parseDateTime(buyTimeStart); + if (buyTimeStart != null && !buyTimeStart.trim().isEmpty() && buyStart == null) { + result.put("success", false); + result.put("message", "buyTimeStart 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); + return result; + } + LocalDateTime buyEnd = parseDateTime(buyTimeEnd); + if (buyTimeEnd != null && !buyTimeEnd.trim().isEmpty() && buyEnd == null) { + result.put("success", false); + result.put("message", "buyTimeEnd 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); + return result; + } + if (buyStart != null) { + queryWrapper.ge(LbBuyerShopping::getBuyTime, buyStart); + } + if (buyEnd != null) { + queryWrapper.le(LbBuyerShopping::getBuyTime, buyEnd); + } + + LocalDateTime confirmStart = parseDateTime(confirmTimeStart); + if (confirmTimeStart != null && !confirmTimeStart.trim().isEmpty() && confirmStart == null) { + result.put("success", false); + result.put("message", "confirmTimeStart 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); + return result; + } + LocalDateTime confirmEnd = parseDateTime(confirmTimeEnd); + if (confirmTimeEnd != null && !confirmTimeEnd.trim().isEmpty() && confirmEnd == null) { + result.put("success", false); + result.put("message", "confirmTimeEnd 格式错误,请使用 yyyy-MM-dd HH:mm:ss"); + return result; + } + if (confirmStart != null) { + queryWrapper.ge(LbBuyerShopping::getConfirmTime, confirmStart); + } + if (confirmEnd != null) { + queryWrapper.le(LbBuyerShopping::getConfirmTime, confirmEnd); + } + + queryWrapper.orderByDesc(LbBuyerShopping::getBuyTime) + .orderByDesc(LbBuyerShopping::getCreatedAt); + + Page page = this.page(new Page<>(current, size), queryWrapper); + result.put("success", true); + result.put("message", "查询成功"); + result.put("data", page.getRecords()); + result.put("total", page.getTotal()); + result.put("current", page.getCurrent()); + result.put("size", page.getSize()); + result.put("pages", page.getPages()); + return result; + } catch (Exception e) { + log.error("买方购物分页查询异常", e); + result.put("success", false); + result.put("message", "查询异常:" + e.getMessage()); + return result; + } + } + + private void applyDefaults(LbBuyerShopping entity) { + if (entity.getTotalMoney() == null) { + entity.setTotalMoney(BigDecimal.ZERO); + } + } + + private void trimStringFields(LbBuyerShopping entity) { + if (entity.getOrderSn() != null) { + entity.setOrderSn(entity.getOrderSn().trim()); + } + if (entity.getSellerNickname() != null) { + entity.setSellerNickname(entity.getSellerNickname().trim()); + } + if (entity.getSellerMobile() != null) { + entity.setSellerMobile(entity.getSellerMobile().trim()); + } + if (entity.getBuyerNickname() != null) { + entity.setBuyerNickname(entity.getBuyerNickname().trim()); + } + if (entity.getBuyerMobile() != null) { + entity.setBuyerMobile(entity.getBuyerMobile().trim()); + } + } + + private LocalDateTime parseDateTime(String text) { + if (text == null || text.trim().isEmpty()) { + return null; + } + try { + return LocalDateTime.parse(text.trim(), DATE_TIME_FORMATTER); + } catch (Exception e) { + return null; + } + } +}