Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	src/main/java/com/gxwebsoft/common/core/utils/WechatCertAutoConfig.java
#	src/main/java/com/gxwebsoft/shop/controller/ShopOrderController.java
This commit is contained in:
2025-08-11 12:24:26 +08:00
86 changed files with 2543 additions and 1322 deletions

View File

@@ -0,0 +1,252 @@
# 收货信息设计方案
## 概述
本文档详细说明了电商系统中收货信息的设计方案,采用**地址快照 + 地址引用混合模式**,确保订单收货信息的完整性和一致性。
## 设计原则
1. **数据一致性**:用户下单时保存收货地址快照,避免后续地址修改影响历史订单
2. **用户体验**:自动读取用户默认地址,减少用户输入
3. **灵活性**:支持用户在下单时临时修改收货信息
4. **可追溯性**保留地址ID引用关系便于数据分析和问题排查
## 数据库设计
### 1. 用户地址表 (shop_user_address)
```sql
CREATE TABLE `shop_user_address` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(100) DEFAULT NULL COMMENT '姓名',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
`country` varchar(50) DEFAULT NULL COMMENT '所在国家',
`province` varchar(50) DEFAULT NULL COMMENT '所在省份',
`city` varchar(50) DEFAULT NULL COMMENT '所在城市',
`region` varchar(50) DEFAULT NULL COMMENT '所在辖区',
`address` varchar(500) DEFAULT NULL COMMENT '收货地址',
`full_address` varchar(500) DEFAULT NULL COMMENT '完整地址',
`lat` varchar(50) DEFAULT NULL COMMENT '纬度',
`lng` varchar(50) DEFAULT NULL COMMENT '经度',
`gender` int(11) DEFAULT NULL COMMENT '1先生 2女士',
`type` varchar(20) DEFAULT NULL COMMENT '家、公司、学校',
`is_default` tinyint(1) DEFAULT 0 COMMENT '默认收货地址',
`sort_number` int(11) DEFAULT NULL COMMENT '排序号',
`user_id` int(11) DEFAULT NULL COMMENT '用户ID',
`tenant_id` int(11) DEFAULT NULL COMMENT '租户id',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_is_default` (`is_default`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='收货地址';
```
### 2. 订单表收货信息字段 (shop_order)
```sql
-- 订单表中的收货信息字段
`address_id` int(11) DEFAULT NULL COMMENT '收货地址ID引用关系',
`address` varchar(500) DEFAULT NULL COMMENT '收货地址快照',
`real_name` varchar(100) DEFAULT NULL COMMENT '收货人姓名快照',
`address_lat` varchar(50) DEFAULT NULL COMMENT '地址纬度',
`address_lng` varchar(50) DEFAULT NULL COMMENT '地址经度',
```
## 业务流程设计
### 1. 下单时收货地址处理流程
```mermaid
flowchart TD
A[用户下单] --> B{前端是否传入完整地址?}
B -->|是| C[使用前端传入地址]
B -->|否| D{是否指定地址ID?}
D -->|是| E[根据地址ID获取地址]
E --> F{地址是否存在且属于当前用户?}
F -->|是| G[使用指定地址]
F -->|否| H[获取用户默认地址]
D -->|否| H[获取用户默认地址]
H --> I{是否有默认地址?}
I -->|是| J[使用默认地址]
I -->|否| K[获取用户第一个地址]
K --> L{是否有地址?}
L -->|是| M[使用第一个地址]
L -->|否| N[抛出异常:请先添加收货地址]
C --> O[创建地址快照]
G --> O
J --> O
M --> O
O --> P[保存订单]
```
### 2. 地址优先级
1. **前端传入的完整地址信息**(最高优先级)
2. **指定的地址ID对应的地址**
3. **用户默认收货地址**
4. **用户的第一个收货地址**
5. **无地址时抛出异常**
## 核心实现
### 1. 收货地址处理方法
```java
/**
* 处理收货地址信息
* 优先级:前端传入地址 > 指定地址ID > 用户默认地址
*/
private void processDeliveryAddress(ShopOrder shopOrder, OrderCreateRequest request, User loginUser) {
// 1. 如果前端已经传入了完整的收货地址信息,直接使用
if (isAddressInfoComplete(request)) {
return;
}
// 2. 如果指定了地址ID获取该地址信息
if (request.getAddressId() != null) {
ShopUserAddress userAddress = shopUserAddressService.getById(request.getAddressId());
if (userAddress != null && userAddress.getUserId().equals(loginUser.getUserId())) {
copyAddressToOrder(userAddress, shopOrder, request);
return;
}
}
// 3. 获取用户默认收货地址
ShopUserAddress defaultAddress = shopUserAddressService.getDefaultAddress(loginUser.getUserId());
if (defaultAddress != null) {
copyAddressToOrder(defaultAddress, shopOrder, request);
return;
}
// 4. 如果没有默认地址,获取用户的第一个地址
List<ShopUserAddress> userAddresses = shopUserAddressService.getUserAddresses(loginUser.getUserId());
if (!userAddresses.isEmpty()) {
copyAddressToOrder(userAddresses.get(0), shopOrder, request);
return;
}
// 5. 如果用户没有任何收货地址,抛出异常
throw new BusinessException("请先添加收货地址");
}
```
### 2. 地址快照创建
```java
/**
* 将用户地址信息复制到订单中(创建快照)
*/
private void copyAddressToOrder(ShopUserAddress userAddress, ShopOrder shopOrder, OrderCreateRequest request) {
// 保存地址ID引用关系
shopOrder.setAddressId(userAddress.getId());
request.setAddressId(userAddress.getId());
// 创建地址信息快照
if (request.getAddress() == null || request.getAddress().trim().isEmpty()) {
StringBuilder fullAddress = new StringBuilder();
if (userAddress.getProvince() != null) fullAddress.append(userAddress.getProvince());
if (userAddress.getCity() != null) fullAddress.append(userAddress.getCity());
if (userAddress.getRegion() != null) fullAddress.append(userAddress.getRegion());
if (userAddress.getAddress() != null) fullAddress.append(userAddress.getAddress());
shopOrder.setAddress(fullAddress.toString());
request.setAddress(fullAddress.toString());
}
// 复制收货人信息
if (request.getRealName() == null || request.getRealName().trim().isEmpty()) {
shopOrder.setRealName(userAddress.getName());
request.setRealName(userAddress.getName());
}
// 复制经纬度信息
if (request.getAddressLat() == null && userAddress.getLat() != null) {
shopOrder.setAddressLat(userAddress.getLat());
request.setAddressLat(userAddress.getLat());
}
if (request.getAddressLng() == null && userAddress.getLng() != null) {
shopOrder.setAddressLng(userAddress.getLng());
request.setAddressLng(userAddress.getLng());
}
}
```
## 前端集成建议
### 1. 下单页面地址选择
```javascript
// 获取用户地址列表
const getUserAddresses = async () => {
const response = await api.get('/api/shop/user-address/my');
return response.data;
};
// 获取默认地址
const getDefaultAddress = async () => {
const addresses = await getUserAddresses();
return addresses.find(addr => addr.isDefault) || addresses[0];
};
// 下单时的地址处理
const createOrder = async (orderData) => {
// 如果用户没有选择地址,使用默认地址
if (!orderData.addressId && !orderData.address) {
const defaultAddress = await getDefaultAddress();
if (defaultAddress) {
orderData.addressId = defaultAddress.id;
}
}
return api.post('/api/shop/order/create', orderData);
};
```
### 2. 地址选择组件
```vue
<template>
<div class="address-selector">
<div v-if="selectedAddress" class="selected-address">
<div class="address-info">
<span class="name">{{ selectedAddress.name }}</span>
<span class="phone">{{ selectedAddress.phone }}</span>
</div>
<div class="address-detail">{{ selectedAddress.fullAddress }}</div>
</div>
<button @click="showAddressList = true">选择收货地址</button>
</div>
</template>
```
## 优势分析
### 1. 数据一致性
- 订单创建时保存地址快照,确保历史订单信息不受用户后续地址修改影响
- 同时保留地址ID引用便于数据关联和分析
### 2. 用户体验
- 自动读取用户默认地址,减少用户操作步骤
- 支持临时修改收货信息,满足特殊需求
- 智能地址选择逻辑,确保总能找到合适的收货地址
### 3. 系统稳定性
- 完善的异常处理机制,避免因地址问题导致下单失败
- 详细的日志记录,便于问题排查和系统监控
### 4. 扩展性
- 支持多种地址类型(家、公司、学校等)
- 预留经纬度字段,支持地图定位功能
- 灵活的排序和默认地址设置
## 注意事项
1. **地址验证**:建议在前端和后端都进行地址完整性验证
2. **默认地址管理**:确保用户只能有一个默认地址
3. **地址数量限制**:建议限制用户地址数量,避免数据冗余
4. **隐私保护**:敏感信息如手机号需要适当脱敏处理
5. **性能优化**:对于高频查询的地址信息,可考虑适当缓存
## 总结
本设计方案通过地址快照机制确保了订单数据的一致性,通过智能地址选择提升了用户体验,通过完善的异常处理保证了系统稳定性。该方案已在 `OrderBusinessService` 中实现,可以直接投入使用。

View File

@@ -3,12 +3,16 @@ package com.gxwebsoft.common.core.utils;
import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.gxwebsoft.common.core.config.ConfigProperties;
import javax.annotation.Resource;
/** /**
* 微信支付证书自动配置工具类 * 微信支付证书自动配置工具类
* 使用RSAAutoCertificateConfig实现证书自动管理 * 使用RSAAutoCertificateConfig实现证书自动管理
* *
* @author 科技小王子 * @author 科技小王子
* @since 2024-07-26 * @since 2024-07-26
*/ */
@@ -16,38 +20,44 @@ import org.springframework.stereotype.Component;
@Component @Component
public class WechatCertAutoConfig { public class WechatCertAutoConfig {
@Value("${spring.profiles.active:prod}")
private String activeProfile;
@Resource
private ConfigProperties configProperties;
/** /**
* 创建微信支付自动证书配置 * 创建微信支付自动证书配置
* *
* @param merchantId 商户号 * @param merchantId 商户号
* @param privateKeyPath 私钥文件路径 * @param privateKeyPath 私钥文件路径
* @param merchantSerialNumber 商户证书序列号 * @param merchantSerialNumber 商户证书序列号
* @param apiV3Key APIv3密钥 * @param apiV3Key APIv3密钥
* @return 微信支付配置对象 * @return 微信支付配置对象
*/ */
public Config createAutoConfig(String merchantId, String privateKeyPath, public Config createAutoConfig(String merchantId, String privateKeyPath,
String merchantSerialNumber, String apiV3Key) { String merchantSerialNumber, String apiV3Key) {
try { try {
log.info("创建微信支付自动证书配置..."); log.info("创建微信支付自动证书配置...");
log.info("商户号: {}", merchantId); log.info("商户号: {}", merchantId);
log.info("私钥路径: {}", privateKeyPath); log.info("私钥路径: {}", privateKeyPath);
log.info("证书序列号: {}", merchantSerialNumber); log.info("证书序列号: {}", merchantSerialNumber);
Config config = new RSAAutoCertificateConfig.Builder() Config config = new RSAAutoCertificateConfig.Builder()
.merchantId(merchantId) .merchantId(merchantId)
.privateKeyFromPath(privateKeyPath) .privateKeyFromPath(privateKeyPath)
.merchantSerialNumber(merchantSerialNumber) .merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3Key) .apiV3Key(apiV3Key)
.build(); .build();
log.info("✅ 微信支付自动证书配置创建成功"); log.info("✅ 微信支付自动证书配置创建成功");
log.info("🔄 系统将自动管理平台证书的下载和更新"); log.info("🔄 系统将自动管理平台证书的下载和更新");
return config; return config;
} catch (Exception e) { } catch (Exception e) {
log.error("❌ 创建微信支付自动证书配置失败: {}", e.getMessage(), e); log.error("❌ 创建微信支付自动证书配置失败: {}", e.getMessage(), e);
// 提供详细的错误诊断信息 // 提供详细的错误诊断信息
log.error("🔍 错误诊断:"); log.error("🔍 错误诊断:");
log.error("1. 请检查商户平台是否已开启API安全功能"); log.error("1. 请检查商户平台是否已开启API安全功能");
@@ -55,28 +65,48 @@ public class WechatCertAutoConfig {
log.error("3. 请验证APIv3密钥和证书序列号是否正确"); log.error("3. 请验证APIv3密钥和证书序列号是否正确");
log.error("4. 请检查网络连接是否正常"); log.error("4. 请检查网络连接是否正常");
log.error("5. 请确认私钥文件路径是否正确: {}", privateKeyPath); log.error("5. 请确认私钥文件路径是否正确: {}", privateKeyPath);
throw new RuntimeException("微信支付自动证书配置失败: " + e.getMessage(), e); throw new RuntimeException("微信支付自动证书配置失败: " + e.getMessage(), e);
} }
} }
/** /**
* 使用默认开发环境配置创建自动证书配置 * 使用默认开发环境配置创建自动证书配置
* * 根据当前环境自动选择证书路径
* 开发环境拼接规则配置文件upload-path + dev/wechat/ + 租户ID
*
* @return 微信支付配置对象 * @return 微信支付配置对象
*/ */
public Config createDefaultDevConfig() { public Config createDefaultDevConfig() {
String merchantId = "1723321338"; String merchantId = "1723321338";
String privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem"; String privateKeyPath;
String merchantSerialNumber = "2B933F7C35014A1C363642623E4A62364B34C4EB"; String merchantSerialNumber = "2B933F7C35014A1C363642623E4A62364B34C4EB";
String apiV3Key = "0kF5OlPr482EZwtn9zGufUcqa7ovgxRL"; String apiV3Key = "0kF5OlPr482EZwtn9zGufUcqa7ovgxRL";
// 根据环境选择证书路径
if ("dev".equals(activeProfile)) {
// 开发环境使用配置文件upload-path拼接证书路径
String uploadPath = configProperties.getUploadPath(); // 配置文件路径
String tenantId = "10550"; // 租户ID
String certPath = uploadPath + "dev/wechat/" + tenantId + "/";
privateKeyPath = certPath + "apiclient_key.pem";
log.info("开发环境使用配置文件upload-path拼接证书路径");
log.info("配置文件upload-path: {}", uploadPath);
log.info("证书基础路径: {}", certPath);
log.info("私钥文件路径: {}", privateKeyPath);
} else {
// 生产环境:使用相对路径,由系统动态解析
privateKeyPath = "src/main/resources/certs/dev/wechat/apiclient_key.pem";
log.info("生产环境:使用相对证书路径 - {}", privateKeyPath);
}
return createAutoConfig(merchantId, privateKeyPath, merchantSerialNumber, apiV3Key); return createAutoConfig(merchantId, privateKeyPath, merchantSerialNumber, apiV3Key);
} }
/** /**
* 测试证书配置是否正常 * 测试证书配置是否正常
* *
* @param config 微信支付配置 * @param config 微信支付配置
* @return 是否配置成功 * @return 是否配置成功
*/ */
@@ -84,56 +114,56 @@ public class WechatCertAutoConfig {
try { try {
// 这里可以添加一些基本的配置验证逻辑 // 这里可以添加一些基本的配置验证逻辑
log.info("🧪 测试微信支付证书配置..."); log.info("🧪 测试微信支付证书配置...");
if (config == null) { if (config == null) {
log.error("配置对象为空"); log.error("配置对象为空");
return false; return false;
} }
log.info("✅ 证书配置测试通过"); log.info("✅ 证书配置测试通过");
return true; return true;
} catch (Exception e) { } catch (Exception e) {
log.error("❌ 证书配置测试失败: {}", e.getMessage(), e); log.error("❌ 证书配置测试失败: {}", e.getMessage(), e);
return false; return false;
} }
} }
/** /**
* 获取配置使用说明 * 获取配置使用说明
* *
* @return 使用说明 * @return 使用说明
*/ */
public String getUsageInstructions() { public String getUsageInstructions() {
return """ return """
🚀 微信支付自动证书配置使用说明 🚀 微信支付自动证书配置使用说明
================================ ================================
✅ 优势: ✅ 优势:
1. 自动下载微信支付平台证书 1. 自动下载微信支付平台证书
2. 证书过期时自动更新 2. 证书过期时自动更新
3. 无需手动管理 wechatpay_cert.pem 文件 3. 无需手动管理 wechatpay_cert.pem 文件
4. 符合微信支付官方最佳实践 4. 符合微信支付官方最佳实践
📝 使用方法: 📝 使用方法:
// 方法1: 使用默认开发环境配置 // 方法1: 使用默认开发环境配置
Config config = wechatCertAutoConfig.createDefaultDevConfig(); Config config = wechatCertAutoConfig.createDefaultDevConfig();
// 方法2: 自定义配置 // 方法2: 自定义配置
Config config = wechatCertAutoConfig.createAutoConfig( Config config = wechatCertAutoConfig.createAutoConfig(
"商户号", "商户号",
"私钥路径", "私钥路径",
"证书序列号", "证书序列号",
"APIv3密钥" "APIv3密钥"
); );
🔧 前置条件: 🔧 前置条件:
1. 微信商户平台已开启API安全功能 1. 微信商户平台已开启API安全功能
2. 已申请使用微信支付公钥 2. 已申请使用微信支付公钥
3. 私钥文件存在且路径正确 3. 私钥文件存在且路径正确
4. 网络连接正常 4. 网络连接正常
📚 更多信息: 📚 更多信息:
https://pay.weixin.qq.com/doc/v3/merchant/4012153196 https://pay.weixin.qq.com/doc/v3/merchant/4012153196
"""; """;

View File

@@ -0,0 +1,111 @@
package com.gxwebsoft.common.core.utils;
import java.nio.charset.StandardCharsets;
/**
* 微信支付工具类
* 处理微信支付API的字段限制和格式要求
*
* @author 科技小王子
* @since 2025-01-11
*/
public class WechatPayUtils {
/**
* 微信支付description字段的最大字节数限制
*/
public static final int DESCRIPTION_MAX_BYTES = 127;
/**
* 微信支付attach字段的最大字节数限制
*/
public static final int ATTACH_MAX_BYTES = 127;
/**
* 截断字符串以确保字节数不超过指定限制
* 主要用于微信支付API的字段限制处理
*
* @param text 原始文本
* @param maxBytes 最大字节数
* @return 截断后的文本确保UTF-8字符完整性
*/
public static String truncateToByteLimit(String text, int maxBytes) {
if (text == null || text.isEmpty()) {
return text;
}
byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
if (bytes.length <= maxBytes) {
return text;
}
// 截断字节数组但要确保不会截断UTF-8字符的中间
int truncateLength = maxBytes;
while (truncateLength > 0) {
byte[] truncated = new byte[truncateLength];
System.arraycopy(bytes, 0, truncated, 0, truncateLength);
try {
String result = new String(truncated, StandardCharsets.UTF_8);
// 检查是否有无效字符被截断的UTF-8字符
if (!result.contains("\uFFFD")) {
return result;
}
} catch (Exception e) {
// 继续尝试更短的长度
}
truncateLength--;
}
return ""; // 如果无法安全截断,返回空字符串
}
/**
* 处理微信支付商品描述字段
* 确保字节数不超过127字节
*
* @param description 商品描述
* @return 处理后的描述,符合微信支付要求
*/
public static String processDescription(String description) {
return truncateToByteLimit(description, DESCRIPTION_MAX_BYTES);
}
/**
* 处理微信支付附加数据字段
* 确保字节数不超过127字节
*
* @param attach 附加数据
* @return 处理后的附加数据,符合微信支付要求
*/
public static String processAttach(String attach) {
return truncateToByteLimit(attach, ATTACH_MAX_BYTES);
}
/**
* 验证字符串是否符合微信支付字段的字节限制
*
* @param text 待验证的文本
* @param maxBytes 最大字节数限制
* @return true如果符合限制false如果超出限制
*/
public static boolean isWithinByteLimit(String text, int maxBytes) {
if (text == null) {
return true;
}
return text.getBytes(StandardCharsets.UTF_8).length <= maxBytes;
}
/**
* 获取字符串的UTF-8字节数
*
* @param text 文本
* @return 字节数
*/
public static int getByteLength(String text) {
if (text == null) {
return 0;
}
return text.getBytes(StandardCharsets.UTF_8).length;
}
}

View File

@@ -0,0 +1,129 @@
package com.gxwebsoft.shop.controller;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.service.ShopCouponService;
import com.gxwebsoft.shop.entity.ShopCoupon;
import com.gxwebsoft.shop.param.ShopCouponParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 优惠券控制器
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
@Tag(name = "优惠券管理")
@RestController
@RequestMapping("/api/shop/shop-coupon")
public class ShopCouponController extends BaseController {
@Resource
private ShopCouponService shopCouponService;
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
@Operation(summary = "分页查询优惠券")
@GetMapping("/page")
public ApiResult<PageResult<ShopCoupon>> page(ShopCouponParam param) {
// 使用关联查询
return success(shopCouponService.pageRel(param));
}
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
@Operation(summary = "查询全部优惠券")
@GetMapping()
public ApiResult<List<ShopCoupon>> list(ShopCouponParam param) {
// 使用关联查询
return success(shopCouponService.listRel(param));
}
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
@Operation(summary = "根据id查询优惠券")
@GetMapping("/{id}")
public ApiResult<ShopCoupon> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(shopCouponService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('shop:shopCoupon:save')")
@OperationLog
@Operation(summary = "添加优惠券")
@PostMapping()
public ApiResult<?> save(@RequestBody ShopCoupon shopCoupon) {
// 记录当前登录用户id
User loginUser = getLoginUser();
if (loginUser != null) {
shopCoupon.setUserId(loginUser.getUserId());
}
if (shopCouponService.save(shopCoupon)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('shop:shopCoupon:update')")
@OperationLog
@Operation(summary = "修改优惠券")
@PutMapping()
public ApiResult<?> update(@RequestBody ShopCoupon shopCoupon) {
if (shopCouponService.updateById(shopCoupon)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('shop:shopCoupon:remove')")
@OperationLog
@Operation(summary = "删除优惠券")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (shopCouponService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('shop:shopCoupon:save')")
@OperationLog
@Operation(summary = "批量添加优惠券")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopCoupon> list) {
if (shopCouponService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('shop:shopCoupon:update')")
@OperationLog
@Operation(summary = "批量修改优惠券")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopCoupon> batchParam) {
if (batchParam.update(shopCouponService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('shop:shopCoupon:remove')")
@OperationLog
@Operation(summary = "批量删除优惠券")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (shopCouponService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
}

View File

@@ -10,8 +10,8 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +22,7 @@ import java.util.List;
* 分销商申请记录表控制器 * 分销商申请记录表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商申请记录表管理") @Tag(name = "分销商申请记录表管理")
@RestController @RestController
@@ -31,6 +31,7 @@ public class ShopDealerApplyController extends BaseController {
@Resource @Resource
private ShopDealerApplyService shopDealerApplyService; private ShopDealerApplyService shopDealerApplyService;
@PreAuthorize("hasAuthority('shop:shopDealerApply:list')")
@Operation(summary = "分页查询分销商申请记录表") @Operation(summary = "分页查询分销商申请记录表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerApply>> page(ShopDealerApplyParam param) { public ApiResult<PageResult<ShopDealerApply>> page(ShopDealerApplyParam param) {
@@ -38,6 +39,7 @@ public class ShopDealerApplyController extends BaseController {
return success(shopDealerApplyService.pageRel(param)); return success(shopDealerApplyService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:list')")
@Operation(summary = "查询全部分销商申请记录表") @Operation(summary = "查询全部分销商申请记录表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerApply>> list(ShopDealerApplyParam param) { public ApiResult<List<ShopDealerApply>> list(ShopDealerApplyParam param) {
@@ -53,6 +55,8 @@ public class ShopDealerApplyController extends BaseController {
return success(shopDealerApplyService.getByIdRel(id)); return success(shopDealerApplyService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:save')")
@OperationLog
@Operation(summary = "添加分销商申请记录表") @Operation(summary = "添加分销商申请记录表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerApply shopDealerApply) { public ApiResult<?> save(@RequestBody ShopDealerApply shopDealerApply) {
@@ -67,6 +71,8 @@ public class ShopDealerApplyController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:update')")
@OperationLog
@Operation(summary = "修改分销商申请记录表") @Operation(summary = "修改分销商申请记录表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerApply shopDealerApply) { public ApiResult<?> update(@RequestBody ShopDealerApply shopDealerApply) {
@@ -76,6 +82,8 @@ public class ShopDealerApplyController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:remove')")
@OperationLog
@Operation(summary = "删除分销商申请记录表") @Operation(summary = "删除分销商申请记录表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +93,8 @@ public class ShopDealerApplyController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:save')")
@OperationLog
@Operation(summary = "批量添加分销商申请记录表") @Operation(summary = "批量添加分销商申请记录表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerApply> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerApply> list) {
@@ -94,6 +104,8 @@ public class ShopDealerApplyController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:update')")
@OperationLog
@Operation(summary = "批量修改分销商申请记录表") @Operation(summary = "批量修改分销商申请记录表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerApply> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerApply> batchParam) {
@@ -103,6 +115,8 @@ public class ShopDealerApplyController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerApply:remove')")
@OperationLog
@Operation(summary = "批量删除分销商申请记录表") @Operation(summary = "批量删除分销商申请记录表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -10,8 +10,8 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +22,7 @@ import java.util.List;
* 分销商资金明细表控制器 * 分销商资金明细表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商资金明细表管理") @Tag(name = "分销商资金明细表管理")
@RestController @RestController
@@ -31,6 +31,7 @@ public class ShopDealerCapitalController extends BaseController {
@Resource @Resource
private ShopDealerCapitalService shopDealerCapitalService; private ShopDealerCapitalService shopDealerCapitalService;
@PreAuthorize("hasAuthority('shop:shopDealerCapital:list')")
@Operation(summary = "分页查询分销商资金明细表") @Operation(summary = "分页查询分销商资金明细表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerCapital>> page(ShopDealerCapitalParam param) { public ApiResult<PageResult<ShopDealerCapital>> page(ShopDealerCapitalParam param) {
@@ -38,6 +39,7 @@ public class ShopDealerCapitalController extends BaseController {
return success(shopDealerCapitalService.pageRel(param)); return success(shopDealerCapitalService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:list')")
@Operation(summary = "查询全部分销商资金明细表") @Operation(summary = "查询全部分销商资金明细表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerCapital>> list(ShopDealerCapitalParam param) { public ApiResult<List<ShopDealerCapital>> list(ShopDealerCapitalParam param) {
@@ -53,6 +55,8 @@ public class ShopDealerCapitalController extends BaseController {
return success(shopDealerCapitalService.getByIdRel(id)); return success(shopDealerCapitalService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:save')")
@OperationLog
@Operation(summary = "添加分销商资金明细表") @Operation(summary = "添加分销商资金明细表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerCapital shopDealerCapital) { public ApiResult<?> save(@RequestBody ShopDealerCapital shopDealerCapital) {
@@ -67,6 +71,8 @@ public class ShopDealerCapitalController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:update')")
@OperationLog
@Operation(summary = "修改分销商资金明细表") @Operation(summary = "修改分销商资金明细表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerCapital shopDealerCapital) { public ApiResult<?> update(@RequestBody ShopDealerCapital shopDealerCapital) {
@@ -76,6 +82,8 @@ public class ShopDealerCapitalController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:remove')")
@OperationLog
@Operation(summary = "删除分销商资金明细表") @Operation(summary = "删除分销商资金明细表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +93,8 @@ public class ShopDealerCapitalController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:save')")
@OperationLog
@Operation(summary = "批量添加分销商资金明细表") @Operation(summary = "批量添加分销商资金明细表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerCapital> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerCapital> list) {
@@ -94,6 +104,8 @@ public class ShopDealerCapitalController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:update')")
@OperationLog
@Operation(summary = "批量修改分销商资金明细表") @Operation(summary = "批量修改分销商资金明细表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerCapital> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerCapital> batchParam) {
@@ -103,6 +115,8 @@ public class ShopDealerCapitalController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerCapital:remove')")
@OperationLog
@Operation(summary = "批量删除分销商资金明细表") @Operation(summary = "批量删除分销商资金明细表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -10,8 +10,8 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +22,7 @@ import java.util.List;
* 分销商订单记录表控制器 * 分销商订单记录表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商订单记录表管理") @Tag(name = "分销商订单记录表管理")
@RestController @RestController
@@ -31,6 +31,7 @@ public class ShopDealerOrderController extends BaseController {
@Resource @Resource
private ShopDealerOrderService shopDealerOrderService; private ShopDealerOrderService shopDealerOrderService;
@PreAuthorize("hasAuthority('shop:shopDealerOrder:list')")
@Operation(summary = "分页查询分销商订单记录表") @Operation(summary = "分页查询分销商订单记录表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerOrder>> page(ShopDealerOrderParam param) { public ApiResult<PageResult<ShopDealerOrder>> page(ShopDealerOrderParam param) {
@@ -38,6 +39,7 @@ public class ShopDealerOrderController extends BaseController {
return success(shopDealerOrderService.pageRel(param)); return success(shopDealerOrderService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:list')")
@Operation(summary = "查询全部分销商订单记录表") @Operation(summary = "查询全部分销商订单记录表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerOrder>> list(ShopDealerOrderParam param) { public ApiResult<List<ShopDealerOrder>> list(ShopDealerOrderParam param) {
@@ -53,6 +55,8 @@ public class ShopDealerOrderController extends BaseController {
return success(shopDealerOrderService.getByIdRel(id)); return success(shopDealerOrderService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:save')")
@OperationLog
@Operation(summary = "添加分销商订单记录表") @Operation(summary = "添加分销商订单记录表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerOrder shopDealerOrder) { public ApiResult<?> save(@RequestBody ShopDealerOrder shopDealerOrder) {
@@ -67,6 +71,8 @@ public class ShopDealerOrderController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:update')")
@OperationLog
@Operation(summary = "修改分销商订单记录表") @Operation(summary = "修改分销商订单记录表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerOrder shopDealerOrder) { public ApiResult<?> update(@RequestBody ShopDealerOrder shopDealerOrder) {
@@ -76,6 +82,8 @@ public class ShopDealerOrderController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:remove')")
@OperationLog
@Operation(summary = "删除分销商订单记录表") @Operation(summary = "删除分销商订单记录表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +93,8 @@ public class ShopDealerOrderController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:save')")
@OperationLog
@Operation(summary = "批量添加分销商订单记录表") @Operation(summary = "批量添加分销商订单记录表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerOrder> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerOrder> list) {
@@ -94,6 +104,8 @@ public class ShopDealerOrderController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:update')")
@OperationLog
@Operation(summary = "批量修改分销商订单记录表") @Operation(summary = "批量修改分销商订单记录表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerOrder> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerOrder> batchParam) {
@@ -103,6 +115,8 @@ public class ShopDealerOrderController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerOrder:remove')")
@OperationLog
@Operation(summary = "批量删除分销商订单记录表") @Operation(summary = "批量删除分销商订单记录表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -10,8 +10,8 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +22,7 @@ import java.util.List;
* 分销商推荐关系表控制器 * 分销商推荐关系表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商推荐关系表管理") @Tag(name = "分销商推荐关系表管理")
@RestController @RestController
@@ -31,6 +31,7 @@ public class ShopDealerRefereeController extends BaseController {
@Resource @Resource
private ShopDealerRefereeService shopDealerRefereeService; private ShopDealerRefereeService shopDealerRefereeService;
@PreAuthorize("hasAuthority('shop:shopDealerReferee:list')")
@Operation(summary = "分页查询分销商推荐关系表") @Operation(summary = "分页查询分销商推荐关系表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerReferee>> page(ShopDealerRefereeParam param) { public ApiResult<PageResult<ShopDealerReferee>> page(ShopDealerRefereeParam param) {
@@ -38,6 +39,7 @@ public class ShopDealerRefereeController extends BaseController {
return success(shopDealerRefereeService.pageRel(param)); return success(shopDealerRefereeService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:list')")
@Operation(summary = "查询全部分销商推荐关系表") @Operation(summary = "查询全部分销商推荐关系表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerReferee>> list(ShopDealerRefereeParam param) { public ApiResult<List<ShopDealerReferee>> list(ShopDealerRefereeParam param) {
@@ -53,6 +55,8 @@ public class ShopDealerRefereeController extends BaseController {
return success(shopDealerRefereeService.getByIdRel(id)); return success(shopDealerRefereeService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:save')")
@OperationLog
@Operation(summary = "添加分销商推荐关系表") @Operation(summary = "添加分销商推荐关系表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerReferee shopDealerReferee) { public ApiResult<?> save(@RequestBody ShopDealerReferee shopDealerReferee) {
@@ -67,6 +71,8 @@ public class ShopDealerRefereeController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:update')")
@OperationLog
@Operation(summary = "修改分销商推荐关系表") @Operation(summary = "修改分销商推荐关系表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerReferee shopDealerReferee) { public ApiResult<?> update(@RequestBody ShopDealerReferee shopDealerReferee) {
@@ -76,6 +82,8 @@ public class ShopDealerRefereeController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:remove')")
@OperationLog
@Operation(summary = "删除分销商推荐关系表") @Operation(summary = "删除分销商推荐关系表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +93,8 @@ public class ShopDealerRefereeController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:save')")
@OperationLog
@Operation(summary = "批量添加分销商推荐关系表") @Operation(summary = "批量添加分销商推荐关系表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerReferee> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerReferee> list) {
@@ -94,6 +104,8 @@ public class ShopDealerRefereeController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:update')")
@OperationLog
@Operation(summary = "批量修改分销商推荐关系表") @Operation(summary = "批量修改分销商推荐关系表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerReferee> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerReferee> batchParam) {
@@ -103,6 +115,8 @@ public class ShopDealerRefereeController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerReferee:remove')")
@OperationLog
@Operation(summary = "批量删除分销商推荐关系表") @Operation(summary = "批量删除分销商推荐关系表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -6,12 +6,10 @@ import com.gxwebsoft.shop.entity.ShopDealerSetting;
import com.gxwebsoft.shop.param.ShopDealerSettingParam; import com.gxwebsoft.shop.param.ShopDealerSettingParam;
import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +20,7 @@ import java.util.List;
* 分销商设置表控制器 * 分销商设置表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商设置表管理") @Tag(name = "分销商设置表管理")
@RestController @RestController
@@ -31,6 +29,7 @@ public class ShopDealerSettingController extends BaseController {
@Resource @Resource
private ShopDealerSettingService shopDealerSettingService; private ShopDealerSettingService shopDealerSettingService;
@PreAuthorize("hasAuthority('shop:shopDealerSetting:list')")
@Operation(summary = "分页查询分销商设置表") @Operation(summary = "分页查询分销商设置表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerSetting>> page(ShopDealerSettingParam param) { public ApiResult<PageResult<ShopDealerSetting>> page(ShopDealerSettingParam param) {
@@ -38,6 +37,7 @@ public class ShopDealerSettingController extends BaseController {
return success(shopDealerSettingService.pageRel(param)); return success(shopDealerSettingService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:list')")
@Operation(summary = "查询全部分销商设置表") @Operation(summary = "查询全部分销商设置表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerSetting>> list(ShopDealerSettingParam param) { public ApiResult<List<ShopDealerSetting>> list(ShopDealerSettingParam param) {
@@ -47,12 +47,14 @@ public class ShopDealerSettingController extends BaseController {
@PreAuthorize("hasAuthority('shop:shopDealerSetting:list')") @PreAuthorize("hasAuthority('shop:shopDealerSetting:list')")
@Operation(summary = "根据id查询分销商设置表") @Operation(summary = "根据id查询分销商设置表")
@GetMapping("/{id}") @GetMapping("/{key}")
public ApiResult<ShopDealerSetting> get(@PathVariable("id") String id) { public ApiResult<ShopDealerSetting> get(@PathVariable("key") String key) {
// 使用关联查询 // 使用关联查询
return success(shopDealerSettingService.getByIdRel(id)); return success(shopDealerSettingService.getByIdRel(key));
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:save')")
@OperationLog
@Operation(summary = "添加分销商设置表") @Operation(summary = "添加分销商设置表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerSetting shopDealerSetting) { public ApiResult<?> save(@RequestBody ShopDealerSetting shopDealerSetting) {
@@ -62,6 +64,8 @@ public class ShopDealerSettingController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:update')")
@OperationLog
@Operation(summary = "修改分销商设置表") @Operation(summary = "修改分销商设置表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerSetting shopDealerSetting) { public ApiResult<?> update(@RequestBody ShopDealerSetting shopDealerSetting) {
@@ -71,6 +75,8 @@ public class ShopDealerSettingController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:remove')")
@OperationLog
@Operation(summary = "删除分销商设置表") @Operation(summary = "删除分销商设置表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -80,6 +86,8 @@ public class ShopDealerSettingController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:save')")
@OperationLog
@Operation(summary = "批量添加分销商设置表") @Operation(summary = "批量添加分销商设置表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerSetting> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerSetting> list) {
@@ -89,6 +97,8 @@ public class ShopDealerSettingController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:update')")
@OperationLog
@Operation(summary = "批量修改分销商设置表") @Operation(summary = "批量修改分销商设置表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerSetting> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerSetting> batchParam) {
@@ -98,6 +108,8 @@ public class ShopDealerSettingController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerSetting:remove')")
@OperationLog
@Operation(summary = "批量删除分销商设置表") @Operation(summary = "批量删除分销商设置表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -10,8 +10,8 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +22,7 @@ import java.util.List;
* 分销商用户记录表控制器 * 分销商用户记录表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商用户记录表管理") @Tag(name = "分销商用户记录表管理")
@RestController @RestController
@@ -31,6 +31,7 @@ public class ShopDealerUserController extends BaseController {
@Resource @Resource
private ShopDealerUserService shopDealerUserService; private ShopDealerUserService shopDealerUserService;
@PreAuthorize("hasAuthority('shop:shopDealerUser:list')")
@Operation(summary = "分页查询分销商用户记录表") @Operation(summary = "分页查询分销商用户记录表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerUser>> page(ShopDealerUserParam param) { public ApiResult<PageResult<ShopDealerUser>> page(ShopDealerUserParam param) {
@@ -38,6 +39,7 @@ public class ShopDealerUserController extends BaseController {
return success(shopDealerUserService.pageRel(param)); return success(shopDealerUserService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:list')")
@Operation(summary = "查询全部分销商用户记录表") @Operation(summary = "查询全部分销商用户记录表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerUser>> list(ShopDealerUserParam param) { public ApiResult<List<ShopDealerUser>> list(ShopDealerUserParam param) {
@@ -53,6 +55,8 @@ public class ShopDealerUserController extends BaseController {
return success(shopDealerUserService.getByIdRel(id)); return success(shopDealerUserService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:save')")
@OperationLog
@Operation(summary = "添加分销商用户记录表") @Operation(summary = "添加分销商用户记录表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerUser shopDealerUser) { public ApiResult<?> save(@RequestBody ShopDealerUser shopDealerUser) {
@@ -67,6 +71,8 @@ public class ShopDealerUserController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:update')")
@OperationLog
@Operation(summary = "修改分销商用户记录表") @Operation(summary = "修改分销商用户记录表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerUser shopDealerUser) { public ApiResult<?> update(@RequestBody ShopDealerUser shopDealerUser) {
@@ -76,6 +82,8 @@ public class ShopDealerUserController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:remove')")
@OperationLog
@Operation(summary = "删除分销商用户记录表") @Operation(summary = "删除分销商用户记录表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +93,8 @@ public class ShopDealerUserController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:save')")
@OperationLog
@Operation(summary = "批量添加分销商用户记录表") @Operation(summary = "批量添加分销商用户记录表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerUser> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerUser> list) {
@@ -94,6 +104,8 @@ public class ShopDealerUserController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:update')")
@OperationLog
@Operation(summary = "批量修改分销商用户记录表") @Operation(summary = "批量修改分销商用户记录表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerUser> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerUser> batchParam) {
@@ -103,6 +115,8 @@ public class ShopDealerUserController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerUser:remove')")
@OperationLog
@Operation(summary = "批量删除分销商用户记录表") @Operation(summary = "批量删除分销商用户记录表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -10,8 +10,8 @@ import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +22,7 @@ import java.util.List;
* 分销商提现明细表控制器 * 分销商提现明细表控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Tag(name = "分销商提现明细表管理") @Tag(name = "分销商提现明细表管理")
@RestController @RestController
@@ -31,6 +31,7 @@ public class ShopDealerWithdrawController extends BaseController {
@Resource @Resource
private ShopDealerWithdrawService shopDealerWithdrawService; private ShopDealerWithdrawService shopDealerWithdrawService;
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:list')")
@Operation(summary = "分页查询分销商提现明细表") @Operation(summary = "分页查询分销商提现明细表")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopDealerWithdraw>> page(ShopDealerWithdrawParam param) { public ApiResult<PageResult<ShopDealerWithdraw>> page(ShopDealerWithdrawParam param) {
@@ -38,6 +39,7 @@ public class ShopDealerWithdrawController extends BaseController {
return success(shopDealerWithdrawService.pageRel(param)); return success(shopDealerWithdrawService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:list')")
@Operation(summary = "查询全部分销商提现明细表") @Operation(summary = "查询全部分销商提现明细表")
@GetMapping() @GetMapping()
public ApiResult<List<ShopDealerWithdraw>> list(ShopDealerWithdrawParam param) { public ApiResult<List<ShopDealerWithdraw>> list(ShopDealerWithdrawParam param) {
@@ -53,6 +55,8 @@ public class ShopDealerWithdrawController extends BaseController {
return success(shopDealerWithdrawService.getByIdRel(id)); return success(shopDealerWithdrawService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:save')")
@OperationLog
@Operation(summary = "添加分销商提现明细表") @Operation(summary = "添加分销商提现明细表")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopDealerWithdraw shopDealerWithdraw) { public ApiResult<?> save(@RequestBody ShopDealerWithdraw shopDealerWithdraw) {
@@ -67,6 +71,8 @@ public class ShopDealerWithdrawController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:update')")
@OperationLog
@Operation(summary = "修改分销商提现明细表") @Operation(summary = "修改分销商提现明细表")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopDealerWithdraw shopDealerWithdraw) { public ApiResult<?> update(@RequestBody ShopDealerWithdraw shopDealerWithdraw) {
@@ -76,6 +82,8 @@ public class ShopDealerWithdrawController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:remove')")
@OperationLog
@Operation(summary = "删除分销商提现明细表") @Operation(summary = "删除分销商提现明细表")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +93,8 @@ public class ShopDealerWithdrawController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:save')")
@OperationLog
@Operation(summary = "批量添加分销商提现明细表") @Operation(summary = "批量添加分销商提现明细表")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopDealerWithdraw> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopDealerWithdraw> list) {
@@ -94,6 +104,8 @@ public class ShopDealerWithdrawController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:update')")
@OperationLog
@Operation(summary = "批量修改分销商提现明细表") @Operation(summary = "批量修改分销商提现明细表")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerWithdraw> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopDealerWithdraw> batchParam) {
@@ -103,6 +115,8 @@ public class ShopDealerWithdrawController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopDealerWithdraw:remove')")
@OperationLog
@Operation(summary = "批量删除分销商提现明细表") @Operation(summary = "批量删除分销商提现明细表")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -6,12 +6,11 @@ import com.gxwebsoft.shop.entity.ShopMerchant;
import com.gxwebsoft.shop.param.ShopMerchantParam; import com.gxwebsoft.shop.param.ShopMerchantParam;
import com.gxwebsoft.common.core.web.ApiResult; import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult; import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam; import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog; import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@@ -22,7 +21,7 @@ import java.util.List;
* 商户控制器 * 商户控制器
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-10 20:43:33
*/ */
@Tag(name = "商户管理") @Tag(name = "商户管理")
@RestController @RestController
@@ -31,6 +30,7 @@ public class ShopMerchantController extends BaseController {
@Resource @Resource
private ShopMerchantService shopMerchantService; private ShopMerchantService shopMerchantService;
@PreAuthorize("hasAuthority('shop:shopMerchant:list')")
@Operation(summary = "分页查询商户") @Operation(summary = "分页查询商户")
@GetMapping("/page") @GetMapping("/page")
public ApiResult<PageResult<ShopMerchant>> page(ShopMerchantParam param) { public ApiResult<PageResult<ShopMerchant>> page(ShopMerchantParam param) {
@@ -38,6 +38,7 @@ public class ShopMerchantController extends BaseController {
return success(shopMerchantService.pageRel(param)); return success(shopMerchantService.pageRel(param));
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:list')")
@Operation(summary = "查询全部商户") @Operation(summary = "查询全部商户")
@GetMapping() @GetMapping()
public ApiResult<List<ShopMerchant>> list(ShopMerchantParam param) { public ApiResult<List<ShopMerchant>> list(ShopMerchantParam param) {
@@ -53,6 +54,8 @@ public class ShopMerchantController extends BaseController {
return success(shopMerchantService.getByIdRel(id)); return success(shopMerchantService.getByIdRel(id));
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:save')")
@OperationLog
@Operation(summary = "添加商户") @Operation(summary = "添加商户")
@PostMapping() @PostMapping()
public ApiResult<?> save(@RequestBody ShopMerchant shopMerchant) { public ApiResult<?> save(@RequestBody ShopMerchant shopMerchant) {
@@ -67,6 +70,8 @@ public class ShopMerchantController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:update')")
@OperationLog
@Operation(summary = "修改商户") @Operation(summary = "修改商户")
@PutMapping() @PutMapping()
public ApiResult<?> update(@RequestBody ShopMerchant shopMerchant) { public ApiResult<?> update(@RequestBody ShopMerchant shopMerchant) {
@@ -76,6 +81,8 @@ public class ShopMerchantController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:remove')")
@OperationLog
@Operation(summary = "删除商户") @Operation(summary = "删除商户")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) { public ApiResult<?> remove(@PathVariable("id") Integer id) {
@@ -85,6 +92,8 @@ public class ShopMerchantController extends BaseController {
return fail("删除失败"); return fail("删除失败");
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:save')")
@OperationLog
@Operation(summary = "批量添加商户") @Operation(summary = "批量添加商户")
@PostMapping("/batch") @PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopMerchant> list) { public ApiResult<?> saveBatch(@RequestBody List<ShopMerchant> list) {
@@ -94,6 +103,8 @@ public class ShopMerchantController extends BaseController {
return fail("添加失败"); return fail("添加失败");
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:update')")
@OperationLog
@Operation(summary = "批量修改商户") @Operation(summary = "批量修改商户")
@PutMapping("/batch") @PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopMerchant> batchParam) { public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopMerchant> batchParam) {
@@ -103,6 +114,8 @@ public class ShopMerchantController extends BaseController {
return fail("修改失败"); return fail("修改失败");
} }
@PreAuthorize("hasAuthority('shop:shopMerchant:remove')")
@OperationLog
@Operation(summary = "批量删除商户") @Operation(summary = "批量删除商户")
@DeleteMapping("/batch") @DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) { public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {

View File

@@ -6,15 +6,14 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.gxwebsoft.common.core.config.ConfigProperties; import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.config.CertificateProperties; import com.gxwebsoft.common.core.config.CertificateProperties;
import com.gxwebsoft.common.core.utils.*; import com.gxwebsoft.common.core.utils.RedisUtil;
import com.gxwebsoft.common.core.utils.CertificateLoader;
import com.gxwebsoft.common.core.utils.WechatCertAutoConfig;
import com.gxwebsoft.common.core.utils.WechatPayConfigValidator;
import com.gxwebsoft.common.core.web.BaseController; import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.DictData;
import com.gxwebsoft.common.system.entity.Payment; import com.gxwebsoft.common.system.entity.Payment;
import com.gxwebsoft.shop.entity.ShopGoods;
import com.gxwebsoft.shop.service.ShopGoodsService;
import com.gxwebsoft.shop.service.ShopOrderGoodsService; import com.gxwebsoft.shop.service.ShopOrderGoodsService;
import com.gxwebsoft.shop.service.ShopOrderService; import com.gxwebsoft.shop.service.ShopOrderService;
import com.gxwebsoft.shop.service.OrderBusinessService; import com.gxwebsoft.shop.service.OrderBusinessService;
@@ -40,9 +39,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.LinkedHashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -56,354 +54,328 @@ import java.util.Map;
@RestController @RestController
@RequestMapping("/api/shop/shop-order") @RequestMapping("/api/shop/shop-order")
public class ShopOrderController extends BaseController { public class ShopOrderController extends BaseController {
private static final Logger logger = LoggerFactory.getLogger(ShopOrderController.class); private static final Logger logger = LoggerFactory.getLogger(ShopOrderController.class);
@Resource @Resource
private ShopOrderService shopOrderService; private ShopOrderService shopOrderService;
@Resource @Resource
private ShopOrderGoodsService shopOrderGoodsService; private ShopOrderGoodsService shopOrderGoodsService;
@Resource @Resource
private OrderBusinessService orderBusinessService; private OrderBusinessService orderBusinessService;
@Resource @Resource
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Resource @Resource
private ConfigProperties conf; private ConfigProperties conf;
@Resource @Resource
private CertificateProperties certConfig; private CertificateProperties certConfig;
@Resource @Resource
private CertificateLoader certificateLoader; private CertificateLoader certificateLoader;
@Resource @Resource
private WechatCertAutoConfig wechatCertAutoConfig; private WechatCertAutoConfig wechatCertAutoConfig;
@Resource @Resource
private WechatPayConfigValidator wechatPayConfigValidator; private WechatPayConfigValidator wechatPayConfigValidator;
@Resource @Value("${spring.profiles.active}")
private ShopGoodsService shopGoodsService; String active;
@Value("${spring.profiles.active}")
String active;
@Resource
private RequestUtil requestUtil;
@Operation(summary = "分页查询订单") @Operation(summary = "分页查询订单")
@GetMapping("/test") @GetMapping("/page")
public ApiResult<?> test() { public ApiResult<PageResult<ShopOrder>> page(ShopOrderParam param) {
requestUtil.setTenantId("10550"); // 使用关联查询
User user = requestUtil.getByUserIdWithoutLogin(33035); return success(shopOrderService.pageRel(param));
return success(user); }
@Operation(summary = "查询全部订单")
@GetMapping()
public ApiResult<List<ShopOrder>> list(ShopOrderParam param) {
// 使用关联查询
return success(shopOrderService.listRel(param));
}
@PreAuthorize("hasAuthority('shop:shopOrder:list')")
@Operation(summary = "根据id查询订单")
@GetMapping("/{id}")
public ApiResult<ShopOrder> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(shopOrderService.getByIdRel(id));
}
@Operation(summary = "添加订单")
@PostMapping()
public ApiResult<?> save(@RequestBody OrderCreateRequest request) {
User loginUser = getLoginUser();
if (loginUser == null) {
return fail("用户未登录");
} }
@Operation(summary = "分页查询订单") try {
@GetMapping("/page") Map<String, String> wxOrderInfo = orderBusinessService.createOrder(request, loginUser);
public ApiResult<PageResult<ShopOrder>> page(ShopOrderParam param) { return success("下单成功", wxOrderInfo);
// 使用关联查询 } catch (Exception e) {
return success(shopOrderService.pageRel(param)); logger.error("创建订单失败 - 用户ID{},请求:{}", loginUser.getUserId(), request, e);
return fail(e.getMessage());
}
}
@Operation(summary = "添加订单(兼容旧版本)")
@PostMapping("/legacy")
public ApiResult<?> saveLegacy(@RequestBody ShopOrder shopOrder) {
// 记录当前登录用户id
User loginUser = getLoginUser();
if (loginUser != null) {
shopOrder.setUserId(loginUser.getUserId());
shopOrder.setOpenid(loginUser.getOpenid());
shopOrder.setPayUserId(loginUser.getUserId());
if (shopOrder.getOrderNo() == null) {
shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
}
if (shopOrder.getComments() == null) {
shopOrder.setComments("暂无");
}
// 微信支付(商品金额不能为0)
if (shopOrder.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
return fail("商品金额不能为0");
}
// 百色中学项目捐赠金额不能低于20元
if (shopOrder.getTenantId().equals(10324) && shopOrder.getTotalPrice().compareTo(new BigDecimal("10")) < 0) {
return fail("捐款金额最低不能少于10元感谢您的爱心捐赠^_^");
}
// 测试支付
if (loginUser.getPhone().equals("13737128880")) {
shopOrder.setPrice(new BigDecimal("0.01"));
shopOrder.setTotalPrice(new BigDecimal("0.01"));
}
if (shopOrderService.save(shopOrder)) {
return success("下单成功", shopOrderService.createWxOrder(shopOrder));
}
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('shop:shopOrder:update')")
@Operation(summary = "修改订单")
@PutMapping()
public ApiResult<?> update(@RequestBody ShopOrder shopOrder) {
if (shopOrderService.updateById(shopOrder)) {
return success("修改成功");
}
return fail("修改失败");
}
@Operation(summary = "删除订单")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (shopOrderService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@Operation(summary = "批量添加订单")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopOrder> list) {
if (shopOrderService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@Operation(summary = "批量修改订单")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopOrder> batchParam) {
if (batchParam.update(shopOrderService, "order_id")) {
return success("修改成功");
}
return fail("修改失败");
}
@Operation(summary = "批量删除订单")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (shopOrderService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
@Operation(summary = "修复订单")
@PutMapping("/repair")
public ApiResult<?> repair(@RequestBody ShopOrder shopOrder) {
final ShopOrder order = shopOrderService.getByOutTradeNo(shopOrder.getOrderNo());
if(order != null){
shopOrderService.queryOrderByOutTradeNo(order);
return success("修复成功");
}
return fail("修复失败");
}
@Operation(summary = "统计订单总金额")
@GetMapping("/total")
public ApiResult<BigDecimal> total() {
return success(shopOrderService.total());
}
@Schema(description = "异步通知11")
@PostMapping("/notify/{tenantId}")
public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) {
logger.info("异步通知*************** = " + tenantId);
// 获取支付配置信息用于解密
String key = "Payment:1:".concat(tenantId.toString());
Payment payment = redisUtil.get(key, Payment.class);
// 检查支付配置
if (ObjectUtil.isEmpty(payment)) {
throw new RuntimeException("未找到租户支付配置信息租户ID: " + tenantId);
} }
@Operation(summary = "查询全部订单") logger.info("开始处理微信支付异步通知 - 租户ID: {}", tenantId);
@GetMapping() logger.info("支付配置信息 - 商户号: {}, 应用ID: {}", payment.getMchId(), payment.getAppId());
public ApiResult<List<ShopOrder>> list(ShopOrderParam param) {
// 使用关联查询 // 验证微信支付配置
return success(shopOrderService.listRel(param)); WechatPayConfigValidator.ValidationResult validation = wechatPayConfigValidator.validateWechatPayConfig(payment, tenantId);
if (!validation.isValid()) {
logger.error("❌ 微信支付配置验证失败: {}", validation.getErrors());
logger.info("📋 配置诊断报告:\n{}", wechatPayConfigValidator.generateDiagnosticReport(payment, tenantId));
throw new RuntimeException("微信支付配置验证失败: " + validation.getErrors());
}
logger.info("✅ 微信支付配置验证通过");
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(header.get("wechatpay-serial"))
.nonce(header.get("wechatpay-nonce"))
.signature(header.get("wechatpay-signature"))
.timestamp(header.get("wechatpay-timestamp"))
.body(body)
.build();
// 创建通知配置 - 使用与下单方法相同的证书配置逻辑
NotificationConfig config;
try {
if (active.equals("dev")) {
// 开发环境 - 构建包含租户号的私钥路径
String tenantCertPath = "dev/wechat/" + tenantId;
String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
logger.info("开发环境异步通知证书路径: {}", privateKeyPath);
logger.info("租户ID: {}, 证书目录: {}", tenantId, tenantCertPath);
// 检查证书文件是否存在
if (!certificateLoader.certificateExists(privateKeyPath)) {
logger.error("证书文件不存在: {}", privateKeyPath);
throw new RuntimeException("证书文件不存在: " + privateKeyPath);
}
String privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
// 使用验证器获取有效的 APIv3 密钥
String apiV3Key = wechatPayConfigValidator.getValidApiV3Key(payment);
logger.info("私钥文件加载成功: {}", privateKey);
logger.info("使用APIv3密钥来源: {}", payment.getApiKey() != null && !payment.getApiKey().trim().isEmpty() ? "数据库配置" : "配置文件默认");
logger.info("APIv3密钥长度: {}", apiV3Key != null ? apiV3Key.length() : 0);
logger.info("商户证书序列号: {}", payment.getMerchantSerialNumber());
// 使用自动证书配置
config = new RSAAutoCertificateConfig.Builder()
.merchantId(payment.getMchId())
.privateKeyFromPath(privateKey)
.merchantSerialNumber(payment.getMerchantSerialNumber())
.apiV3Key(apiV3Key)
.build();
logger.info("✅ 开发环境使用自动证书配置创建通知解析器成功");
} else {
// 生产环境 - 使用自动证书配置
final String certRootPath = certConfig.getCertRootPath();
final String certBasePath = certRootPath + "/file";
String privateKeyRelativePath = payment.getApiclientKey();
String privateKeyFullPath = privateKeyRelativePath.startsWith("/")
? certBasePath + privateKeyRelativePath
: certBasePath + "/" + privateKeyRelativePath;
String privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath);
String apiV3Key = payment.getApiKey();
// 使用自动证书配置
config = new RSAAutoCertificateConfig.Builder()
.merchantId(payment.getMchId())
.privateKeyFromPath(privateKey)
.merchantSerialNumber(payment.getMerchantSerialNumber())
.apiV3Key(apiV3Key)
.build();
logger.info("✅ 生产环境使用自动证书配置创建通知解析器成功");
}
} catch (Exception e) {
logger.error("❌ 创建通知配置失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e);
logger.error("🔍 错误详情: {}", e.getMessage());
logger.error("💡 请检查:");
logger.error("1. 证书文件是否存在且路径正确");
logger.error("2. APIv3密钥是否配置正确");
logger.error("3. 商户证书序列号是否正确");
logger.error("4. 网络连接是否正常");
throw new RuntimeException("微信支付通知配置失败: " + e.getMessage(), e);
} }
@PreAuthorize("hasAuthority('shop:shopOrder:list')") // 初始化 NotificationParser
@Operation(summary = "根据id查询订单") NotificationParser parser = new NotificationParser(config);
@GetMapping("/{id}") logger.info("✅ 通知解析器创建成功,准备解析异步通知");
public ApiResult<ShopOrder> get(@PathVariable("id") Integer id) {
// 使用关联查询 // 以支付通知回调为例,验签、解密并转换成 Transaction
return success(shopOrderService.getByIdRel(id)); try {
logger.info("开始解析微信支付异步通知...");
Transaction transaction = parser.parse(requestParam, Transaction.class);
logger.info("✅ 异步通知解析成功 - 交易状态: {}, 商户订单号: {}",
transaction.getTradeStateDesc(), transaction.getOutTradeNo());
if (StrUtil.equals("支付成功", transaction.getTradeStateDesc())) {
final String outTradeNo = transaction.getOutTradeNo();
final String transactionId = transaction.getTransactionId();
final Integer total = transaction.getAmount().getTotal();
final String tradeStateDesc = transaction.getTradeStateDesc();
final Transaction.TradeStateEnum tradeState = transaction.getTradeState();
final Transaction.TradeTypeEnum tradeType = transaction.getTradeType();
System.out.println("transaction = " + transaction);
System.out.println("tradeStateDesc = " + tradeStateDesc);
System.out.println("tradeType = " + tradeType);
System.out.println("tradeState = " + tradeState);
System.out.println("outTradeNo = " + outTradeNo);
System.out.println("amount = " + total);
// 1. 查询要处理的订单
ShopOrder order = shopOrderService.getByOutTradeNo(outTradeNo);
logger.info("order = " + order);
// 2. 已支付则跳过
if (order.getPayStatus().equals(true)) {
return "SUCCESS";
}
// 2. 未支付则处理更新订单状态
if (order.getPayStatus().equals(false)) {
// 5. TODO 处理订单状态
order.setPayTime(DateUtil.date());
order.setExpirationTime(order.getCreateTime());
order.setPayStatus(true);
order.setTransactionId(transactionId);
order.setPayPrice(new BigDecimal(NumberUtil.decimalFormat("0.00", total * 0.01)));
order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10));
System.out.println("实际付款金额 = " + order.getPayPrice());
shopOrderService.updateByOutTradeNo(order);
return "SUCCESS";
}
}
} catch (Exception e) {
logger.error("❌ 处理微信支付异步通知失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e);
logger.error("🔍 异常详情: {}", e.getMessage());
logger.error("💡 可能的原因:");
logger.error("1. 证书配置错误或证书文件损坏");
logger.error("2. 微信支付平台证书已过期");
logger.error("3. 签名验证失败");
logger.error("4. 请求参数格式错误");
// 返回失败,微信会重试
return "fail";
} }
@Operation(summary = "添加订单") logger.warn("⚠️ 异步通知处理完成但未找到匹配的支付成功状态");
@PostMapping() return "fail";
public ApiResult<?> save(@Valid @RequestBody OrderCreateRequest request) { }
User loginUser = getLoginUser();
if (loginUser == null) {
return fail("用户未登录");
}
if (request.getTotalPrice() == null || request.getTotalPrice().compareTo(BigDecimal.ZERO) <= 0) {
if (request.getGoodsItems() != null && !request.getGoodsItems().isEmpty()) {
BigDecimal totalPrice = BigDecimal.ZERO;
int totalNum = 0;
for (OrderCreateRequest.OrderGoodsItem item : request.getGoodsItems()) {
ShopGoods goods = shopGoodsService.getById(item.getGoodsId().toString());
if (goods != null) {
BigDecimal price = goods.getPrice().multiply(new BigDecimal(item.getQuantity().toString()));
totalPrice = totalPrice.add(price);
totalNum += Integer.parseInt(item.getQuantity().toString());
}
}
request.setTotalPrice(totalPrice);
request.setPayPrice(totalPrice);
request.setTotalNum(totalNum);
request.setFormId(Integer.parseInt(request.getGoodsItems().get(0).getQuantity().toString()));
}
}
if (request.getTenantId() == null) {
request.setTenantId(getTenantId());
}
try {
Map<String, String> wxOrderInfo = orderBusinessService.createOrder(request, loginUser);
return success("下单成功", wxOrderInfo);
} catch (Exception e) {
logger.error("创建订单失败", e);
return fail(e.getMessage());
}
}
@Operation(summary = "添加订单(兼容旧版本)")
@PostMapping("/legacy")
public ApiResult<?> saveLegacy(@RequestBody ShopOrder shopOrder) {
// 记录当前登录用户id
User loginUser = getLoginUser();
if (loginUser != null) {
shopOrder.setUserId(loginUser.getUserId());
shopOrder.setOpenid(loginUser.getOpenid());
shopOrder.setPayUserId(loginUser.getUserId());
if (shopOrder.getOrderNo() == null) {
shopOrder.setOrderNo(Long.toString(IdUtil.getSnowflakeNextId()));
}
if (shopOrder.getComments() == null) {
shopOrder.setComments("暂无");
}
// 微信支付(商品金额不能为0)
if (shopOrder.getTotalPrice().compareTo(BigDecimal.ZERO) == 0) {
return fail("商品金额不能为0");
}
// 百色中学项目捐赠金额不能低于20元
if (shopOrder.getTenantId().equals(10324) && shopOrder.getTotalPrice().compareTo(new BigDecimal("10")) < 0) {
return fail("捐款金额最低不能少于10元感谢您的爱心捐赠^_^");
}
// 测试支付
if (loginUser.getPhone().equals("13737128880")) {
shopOrder.setPrice(new BigDecimal("0.01"));
shopOrder.setTotalPrice(new BigDecimal("0.01"));
}
if (shopOrderService.save(shopOrder)) {
return success("下单成功", shopOrderService.createWxOrder(shopOrder));
}
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('shop:shopOrder:update')")
@Operation(summary = "修改订单")
@PutMapping()
public ApiResult<?> update(@RequestBody ShopOrder shopOrder) {
if (shopOrderService.updateById(shopOrder)) {
return success("修改成功");
}
return fail("修改失败");
}
@Operation(summary = "删除订单")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (shopOrderService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@Operation(summary = "批量添加订单")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopOrder> list) {
if (shopOrderService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@Operation(summary = "批量修改订单")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopOrder> batchParam) {
if (batchParam.update(shopOrderService, "order_id")) {
return success("修改成功");
}
return fail("修改失败");
}
@Operation(summary = "批量删除订单")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (shopOrderService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
@Operation(summary = "修复订单")
@PutMapping("/repair")
public ApiResult<?> repair(@RequestBody ShopOrder shopOrder) {
final ShopOrder order = shopOrderService.getByOutTradeNo(shopOrder.getOrderNo());
if (order != null) {
shopOrderService.queryOrderByOutTradeNo(order);
return success("修复成功");
}
return fail("修复失败");
}
@Schema(description = "异步通知")
@PostMapping("/notify/{tenantId}")
public String wxNotify(@RequestHeader Map<String, String> header, @RequestBody String body, @PathVariable("tenantId") Integer tenantId) {
logger.info("异步通知*************** = " + tenantId);
// 获取支付配置信息用于解密
String key = "Payment:1:".concat(tenantId.toString());
Payment payment = redisUtil.get(key, Payment.class);
// 检查支付配置
if (ObjectUtil.isEmpty(payment)) {
throw new RuntimeException("未找到租户支付配置信息租户ID: " + tenantId);
}
logger.info("开始处理微信支付异步通知 - 租户ID: {}", tenantId);
logger.info("支付配置信息 - 商户号: {}, 应用ID: {}", payment.getMchId(), payment.getAppId());
// 验证微信支付配置
WechatPayConfigValidator.ValidationResult validation = wechatPayConfigValidator.validateWechatPayConfig(payment, tenantId);
if (!validation.isValid()) {
logger.error("❌ 微信支付配置验证失败: {}", validation.getErrors());
logger.info("📋 配置诊断报告:\n{}", wechatPayConfigValidator.generateDiagnosticReport(payment, tenantId));
throw new RuntimeException("微信支付配置验证失败: " + validation.getErrors());
}
logger.info("✅ 微信支付配置验证通过");
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(header.get("wechatpay-serial"))
.nonce(header.get("wechatpay-nonce"))
.signature(header.get("wechatpay-signature"))
.timestamp(header.get("wechatpay-timestamp"))
.body(body)
.build();
// 创建通知配置 - 使用与下单方法相同的证书配置逻辑
NotificationConfig config;
try {
// if (active.equals("dev")) {
// // 开发环境 - 构建包含租户号的私钥路径
// String tenantCertPath = "dev/wechat/" + tenantId;
// String privateKeyPath = tenantCertPath + "/" + certConfig.getWechatPay().getDev().getPrivateKeyFile();
//
// logger.info("开发环境异步通知证书路径: {}", privateKeyPath);
// logger.info("租户ID: {}, 证书目录: {}", tenantId, tenantCertPath);
//
// // 检查证书文件是否存在
// if (!certificateLoader.certificateExists(privateKeyPath)) {
// logger.error("证书文件不存在: {}", privateKeyPath);
// throw new RuntimeException("证书文件不存在: " + privateKeyPath);
// }
//
// String privateKey = certificateLoader.loadCertificatePath(privateKeyPath);
//
// // 使用验证器获取有效的 APIv3 密钥
// String apiV3Key = wechatPayConfigValidator.getValidApiV3Key(payment);
//
// logger.info("私钥文件加载成功: {}", privateKey);
// logger.info("使用APIv3密钥来源: {}", payment.getApiKey() != null && !payment.getApiKey().trim().isEmpty() ? "数据库配置" : "配置文件默认");
// logger.info("APIv3密钥长度: {}", apiV3Key != null ? apiV3Key.length() : 0);
// logger.info("商户证书序列号: {}", payment.getMerchantSerialNumber());
//
// // 使用自动证书配置
// config = new RSAAutoCertificateConfig.Builder()
// .merchantId(payment.getMchId())
// .privateKeyFromPath(privateKey)
// .merchantSerialNumber(payment.getMerchantSerialNumber())
// .apiV3Key(apiV3Key)
// .build();
//
// logger.info("✅ 开发环境使用自动证书配置创建通知解析器成功");
// } else {
// 生产环境 - 使用自动证书配置
final String certRootPath = certConfig.getCertRootPath();
final String certBasePath = certRootPath + "/file";
String privateKeyRelativePath = payment.getApiclientKey();
String privateKeyFullPath = privateKeyRelativePath.startsWith("/")
? certBasePath + privateKeyRelativePath
: certBasePath + "/" + privateKeyRelativePath;
String privateKey = certificateLoader.loadCertificatePath(privateKeyFullPath);
String apiV3Key = payment.getApiKey();
// 使用自动证书配置
config = new RSAAutoCertificateConfig.Builder()
.merchantId(payment.getMchId())
.privateKeyFromPath(privateKey)
.merchantSerialNumber(payment.getMerchantSerialNumber())
.apiV3Key(apiV3Key)
.build();
logger.info("✅ 生产环境使用自动证书配置创建通知解析器成功");
// }
} catch (Exception e) {
logger.error("❌ 创建通知配置失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e);
logger.error("🔍 错误详情: {}", e.getMessage());
logger.error("💡 请检查:");
logger.error("1. 证书文件是否存在且路径正确");
logger.error("2. APIv3密钥是否配置正确");
logger.error("3. 商户证书序列号是否正确");
logger.error("4. 网络连接是否正常");
throw new RuntimeException("微信支付通知配置失败: " + e.getMessage(), e);
}
// 初始化 NotificationParser
NotificationParser parser = new NotificationParser(config);
logger.info("✅ 通知解析器创建成功,准备解析异步通知");
// 以支付通知回调为例,验签、解密并转换成 Transaction
try {
logger.info("开始解析微信支付异步通知...");
Transaction transaction = parser.parse(requestParam, Transaction.class);
logger.info("✅ 异步通知解析成功 - 交易状态: {}, 商户订单号: {}",
transaction.getTradeStateDesc(), transaction.getOutTradeNo());
if (StrUtil.equals("支付成功", transaction.getTradeStateDesc())) {
final String outTradeNo = transaction.getOutTradeNo();
final String transactionId = transaction.getTransactionId();
final Integer total = transaction.getAmount().getTotal();
final String tradeStateDesc = transaction.getTradeStateDesc();
final Transaction.TradeStateEnum tradeState = transaction.getTradeState();
final Transaction.TradeTypeEnum tradeType = transaction.getTradeType();
System.out.println("transaction = " + transaction);
System.out.println("tradeStateDesc = " + tradeStateDesc);
System.out.println("tradeType = " + tradeType);
System.out.println("tradeState = " + tradeState);
System.out.println("outTradeNo = " + outTradeNo);
System.out.println("amount = " + total);
// 1. 查询要处理的订单
ShopOrder order = shopOrderService.getByOutTradeNo(outTradeNo);
logger.info("order = " + order);
// 2. 已支付则跳过
if (order.getPayStatus().equals(true)) {
return "SUCCESS";
}
// 2. 未支付则处理更新订单状态
if (order.getPayStatus().equals(false)) {
// 5. TODO 处理订单状态
order.setPayTime(DateUtil.date());
order.setExpirationTime(order.getCreateTime());
order.setPayStatus(true);
order.setTransactionId(transactionId);
order.setPayPrice(new BigDecimal(NumberUtil.decimalFormat("0.00", total * 0.01)));
order.setExpirationTime(DateUtil.offset(DateUtil.date(), DateField.YEAR, 10));
System.out.println("实际付款金额 = " + order.getPayPrice());
shopOrderService.updateByOutTradeNo(order);
return "SUCCESS";
}
}
} catch (Exception e) {
logger.error("❌ 处理微信支付异步通知失败 - 租户ID: {}, 商户号: {}", tenantId, payment.getMchId(), e);
logger.error("🔍 异常详情: {}", e.getMessage());
logger.error("💡 可能的原因:");
logger.error("1. 证书配置错误或证书文件损坏");
logger.error("2. 微信支付平台证书已过期");
logger.error("3. 签名验证失败");
logger.error("4. 请求参数格式错误");
// 返回失败,微信会重试
return "fail";
}
logger.warn("⚠️ 异步通知处理完成但未找到匹配的支付成功状态");
return "fail";
}
} }

View File

@@ -0,0 +1,129 @@
package com.gxwebsoft.shop.controller;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.shop.service.ShopUserCouponService;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import com.gxwebsoft.shop.param.ShopUserCouponParam;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.BatchParam;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.system.entity.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 用户优惠券控制器
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
@Tag(name = "用户优惠券管理")
@RestController
@RequestMapping("/api/shop/shop-user-coupon")
public class ShopUserCouponController extends BaseController {
@Resource
private ShopUserCouponService shopUserCouponService;
@PreAuthorize("hasAuthority('shop:shopUserCoupon:list')")
@Operation(summary = "分页查询用户优惠券")
@GetMapping("/page")
public ApiResult<PageResult<ShopUserCoupon>> page(ShopUserCouponParam param) {
// 使用关联查询
return success(shopUserCouponService.pageRel(param));
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:list')")
@Operation(summary = "查询全部用户优惠券")
@GetMapping()
public ApiResult<List<ShopUserCoupon>> list(ShopUserCouponParam param) {
// 使用关联查询
return success(shopUserCouponService.listRel(param));
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:list')")
@Operation(summary = "根据id查询用户优惠券")
@GetMapping("/{id}")
public ApiResult<ShopUserCoupon> get(@PathVariable("id") Integer id) {
// 使用关联查询
return success(shopUserCouponService.getByIdRel(id));
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:save')")
@OperationLog
@Operation(summary = "添加用户优惠券")
@PostMapping()
public ApiResult<?> save(@RequestBody ShopUserCoupon shopUserCoupon) {
// 记录当前登录用户id
User loginUser = getLoginUser();
if (loginUser != null) {
shopUserCoupon.setUserId(loginUser.getUserId());
}
if (shopUserCouponService.save(shopUserCoupon)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:update')")
@OperationLog
@Operation(summary = "修改用户优惠券")
@PutMapping()
public ApiResult<?> update(@RequestBody ShopUserCoupon shopUserCoupon) {
if (shopUserCouponService.updateById(shopUserCoupon)) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:remove')")
@OperationLog
@Operation(summary = "删除用户优惠券")
@DeleteMapping("/{id}")
public ApiResult<?> remove(@PathVariable("id") Integer id) {
if (shopUserCouponService.removeById(id)) {
return success("删除成功");
}
return fail("删除失败");
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:save')")
@OperationLog
@Operation(summary = "批量添加用户优惠券")
@PostMapping("/batch")
public ApiResult<?> saveBatch(@RequestBody List<ShopUserCoupon> list) {
if (shopUserCouponService.saveBatch(list)) {
return success("添加成功");
}
return fail("添加失败");
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:update')")
@OperationLog
@Operation(summary = "批量修改用户优惠券")
@PutMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody BatchParam<ShopUserCoupon> batchParam) {
if (batchParam.update(shopUserCouponService, "id")) {
return success("修改成功");
}
return fail("修改失败");
}
@PreAuthorize("hasAuthority('shop:shopUserCoupon:remove')")
@OperationLog
@Operation(summary = "批量删除用户优惠券")
@DeleteMapping("/batch")
public ApiResult<?> removeBatch(@RequestBody List<Integer> ids) {
if (shopUserCouponService.removeByIds(ids)) {
return success("删除成功");
}
return fail("删除失败");
}
}

View File

@@ -0,0 +1,105 @@
package com.gxwebsoft.shop.entity;
import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType;
import java.time.LocalDate;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableLogic;
import java.io.Serializable;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 优惠券
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Schema(name = "ShopCoupon对象", description = "优惠券")
public class ShopCoupon implements Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@Schema(description = "优惠券名称")
private String name;
@Schema(description = "优惠券描述")
private String description;
@Schema(description = "优惠券类型(10满减券 20折扣券 30免费劵)")
private Integer type;
@Schema(description = "满减券-减免金额")
private BigDecimal reducePrice;
@Schema(description = "折扣券-折扣率(0-100)")
private Integer discount;
@Schema(description = "最低消费金额")
private BigDecimal minPrice;
@Schema(description = "到期类型(10领取后生效 20固定时间)")
private Integer expireType;
@Schema(description = "领取后生效-有效天数")
private Integer expireDay;
@Schema(description = "有效期开始时间")
private LocalDate startTime;
@Schema(description = "有效期结束时间")
private LocalDate endTime;
@Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)")
private Integer applyRange;
@Schema(description = "适用范围配置(json格式)")
private String applyRangeConfig;
@Schema(description = "是否过期(0未过期 1已过期)")
private Integer isExpire;
@Schema(description = "排序(数字越小越靠前)")
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1禁用")
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@TableLogic
private Integer deleted;
@Schema(description = "创建用户ID")
private Integer userId;
@Schema(description = "租户id")
private Integer tenantId;
@Schema(description = "创建时间")
private Data createTime;
@Schema(description = "修改时间")
private Date updateTime;
@Schema(description = "发放总数量(-1表示无限制)")
private Integer totalCount;
@Schema(description = "已发放数量")
private Integer issuedCount;
@Schema(description = "每人限领数量(-1表示无限制)")
private Integer limitPerUser;
@Schema(description = "是否启用(0禁用 1启用)")
private Boolean enabled;
}

View File

@@ -2,9 +2,10 @@ package com.gxwebsoft.shop.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -13,7 +14,7 @@ import lombok.EqualsAndHashCode;
* 分销商申请记录表 * 分销商申请记录表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -3,9 +3,10 @@ package com.gxwebsoft.shop.entity;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +15,7 @@ import lombok.EqualsAndHashCode;
* 分销商资金明细表 * 分销商资金明细表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -3,9 +3,10 @@ package com.gxwebsoft.shop.entity;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +15,7 @@ import lombok.EqualsAndHashCode;
* 分销商订单记录表 * 分销商订单记录表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -2,9 +2,10 @@ package com.gxwebsoft.shop.entity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -13,7 +14,7 @@ import lombok.EqualsAndHashCode;
* 分销商推荐关系表 * 分销商推荐关系表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -12,7 +11,7 @@ import lombok.EqualsAndHashCode;
* 分销商设置表 * 分销商设置表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -3,9 +3,10 @@ package com.gxwebsoft.shop.entity;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +15,7 @@ import lombok.EqualsAndHashCode;
* 分销商用户记录表 * 分销商用户记录表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -3,9 +3,10 @@ package com.gxwebsoft.shop.entity;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +15,7 @@ import lombok.EqualsAndHashCode;
* 分销商提现明细表 * 分销商提现明细表
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -3,11 +3,10 @@ package com.gxwebsoft.shop.entity;
import java.math.BigDecimal; import java.math.BigDecimal;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import java.util.Date; import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableLogic;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -15,7 +14,7 @@ import lombok.EqualsAndHashCode;
* 商户 * 商户
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-10 20:43:33
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -25,7 +24,7 @@ public class ShopMerchant implements Serializable {
@Schema(description = "ID") @Schema(description = "ID")
@TableId(value = "merchant_id", type = IdType.AUTO) @TableId(value = "merchant_id", type = IdType.AUTO)
private Long merchantId; private Integer merchantId;
@Schema(description = "商户名称") @Schema(description = "商户名称")
private String merchantName; private String merchantName;
@@ -139,6 +138,6 @@ public class ShopMerchant implements Serializable {
private Integer tenantId; private Integer tenantId;
@Schema(description = "创建时间") @Schema(description = "创建时间")
private Date createTime; private LocalDateTime createTime;
} }

View File

@@ -87,6 +87,9 @@ public class ShopOrder implements Serializable {
private String addressLng; private String addressLng;
@Schema(description = "买家备注")
private String buyerRemarks;
@Schema(description = "自提店铺id") @Schema(description = "自提店铺id")
private Integer selfTakeMerchantId; private Integer selfTakeMerchantId;
@@ -159,6 +162,9 @@ public class ShopOrder implements Serializable {
@Schema(description = "发货状态(10未发货 20已发货 30部分发货)") @Schema(description = "发货状态(10未发货 20已发货 30部分发货)")
private Integer deliveryStatus; private Integer deliveryStatus;
@Schema(description = "发货备注")
private String deliveryNote;
@Schema(description = "发货时间") @Schema(description = "发货时间")
private Date deliveryTime; private Date deliveryTime;
@@ -204,6 +210,9 @@ public class ShopOrder implements Serializable {
@Schema(description = "订单是否已结算(0未结算 1已结算)") @Schema(description = "订单是否已结算(0未结算 1已结算)")
private Integer isSettled; private Integer isSettled;
@Schema(description = "商户备注")
private String merchantRemarks;
@Schema(description = "系统版本号 0当前版本 value=其他版本") @Schema(description = "系统版本号 0当前版本 value=其他版本")
private Integer version; private Integer version;

View File

@@ -14,7 +14,7 @@ import lombok.EqualsAndHashCode;
* 用户优惠券 * 用户优惠券
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-08-09 15:48:01 * @since 2025-08-11 09:41:38
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@@ -22,41 +22,9 @@ import lombok.EqualsAndHashCode;
public class ShopUserCoupon implements Serializable { public class ShopUserCoupon implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// 优惠券类型常量
/** 满减券 */
public static final Integer TYPE_REDUCE = 10;
/** 折扣券 */
public static final Integer TYPE_DISCOUNT = 20;
/** 免费券 */
public static final Integer TYPE_FREE = 30;
// 适用范围常量
/** 全部商品 */
public static final Integer APPLY_ALL = 10;
/** 指定商品 */
public static final Integer APPLY_GOODS = 20;
/** 指定分类 */
public static final Integer APPLY_CATEGORY = 30;
// 使用状态常量
/** 未使用 */
public static final Integer STATUS_UNUSED = 0;
/** 已使用 */
public static final Integer STATUS_USED = 1;
/** 已过期 */
public static final Integer STATUS_EXPIRED = 2;
// 获取方式常量
/** 主动领取 */
public static final Integer OBTAIN_ACTIVE = 10;
/** 系统发放 */
public static final Integer OBTAIN_SYSTEM = 20;
/** 活动赠送 */
public static final Integer OBTAIN_ACTIVITY = 30;
@Schema(description = "id") @Schema(description = "id")
@TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.AUTO)
private Long id; private Integer id;
@Schema(description = "优惠券模板ID") @Schema(description = "优惠券模板ID")
private Integer couponId; private Integer couponId;

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.shop.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.shop.entity.ShopCoupon;
import com.gxwebsoft.shop.param.ShopCouponParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 优惠券Mapper
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
public interface ShopCouponMapper extends BaseMapper<ShopCoupon> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<ShopCoupon>
*/
List<ShopCoupon> selectPageRel(@Param("page") IPage<ShopCoupon> page,
@Param("param") ShopCouponParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<ShopCoupon> selectListRel(@Param("param") ShopCouponParam param);
}

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商申请记录表Mapper * 分销商申请记录表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerApplyMapper extends BaseMapper<ShopDealerApply> { public interface ShopDealerApplyMapper extends BaseMapper<ShopDealerApply> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商资金明细表Mapper * 分销商资金明细表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerCapitalMapper extends BaseMapper<ShopDealerCapital> { public interface ShopDealerCapitalMapper extends BaseMapper<ShopDealerCapital> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商订单记录表Mapper * 分销商订单记录表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerOrderMapper extends BaseMapper<ShopDealerOrder> { public interface ShopDealerOrderMapper extends BaseMapper<ShopDealerOrder> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商推荐关系表Mapper * 分销商推荐关系表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerRefereeMapper extends BaseMapper<ShopDealerReferee> { public interface ShopDealerRefereeMapper extends BaseMapper<ShopDealerReferee> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商设置表Mapper * 分销商设置表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerSettingMapper extends BaseMapper<ShopDealerSetting> { public interface ShopDealerSettingMapper extends BaseMapper<ShopDealerSetting> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商用户记录表Mapper * 分销商用户记录表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerUserMapper extends BaseMapper<ShopDealerUser> { public interface ShopDealerUserMapper extends BaseMapper<ShopDealerUser> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 分销商提现明细表Mapper * 分销商提现明细表Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerWithdrawMapper extends BaseMapper<ShopDealerWithdraw> { public interface ShopDealerWithdrawMapper extends BaseMapper<ShopDealerWithdraw> {

View File

@@ -12,7 +12,7 @@ import java.util.List;
* 商户Mapper * 商户Mapper
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-10 20:43:33
*/ */
public interface ShopMerchantMapper extends BaseMapper<ShopMerchant> { public interface ShopMerchantMapper extends BaseMapper<ShopMerchant> {

View File

@@ -0,0 +1,37 @@
package com.gxwebsoft.shop.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import com.gxwebsoft.shop.param.ShopUserCouponParam;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 用户优惠券Mapper
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
public interface ShopUserCouponMapper extends BaseMapper<ShopUserCoupon> {
/**
* 分页查询
*
* @param page 分页对象
* @param param 查询参数
* @return List<ShopUserCoupon>
*/
List<ShopUserCoupon> selectPageRel(@Param("page") IPage<ShopUserCoupon> page,
@Param("param") ShopUserCouponParam param);
/**
* 查询全部
*
* @param param 查询参数
* @return List<User>
*/
List<ShopUserCoupon> selectListRel(@Param("param") ShopUserCouponParam param);
}

View File

@@ -0,0 +1,102 @@
<?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.gxwebsoft.shop.mapper.ShopCouponMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM shop_coupon a
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.description != null">
AND a.description LIKE CONCAT('%', #{param.description}, '%')
</if>
<if test="param.type != null">
AND a.type = #{param.type}
</if>
<if test="param.reducePrice != null">
AND a.reduce_price = #{param.reducePrice}
</if>
<if test="param.discount != null">
AND a.discount = #{param.discount}
</if>
<if test="param.minPrice != null">
AND a.min_price = #{param.minPrice}
</if>
<if test="param.expireType != null">
AND a.expire_type = #{param.expireType}
</if>
<if test="param.expireDay != null">
AND a.expire_day = #{param.expireDay}
</if>
<if test="param.startTime != null">
AND a.start_time LIKE CONCAT('%', #{param.startTime}, '%')
</if>
<if test="param.endTime != null">
AND a.end_time LIKE CONCAT('%', #{param.endTime}, '%')
</if>
<if test="param.applyRange != null">
AND a.apply_range = #{param.applyRange}
</if>
<if test="param.applyRangeConfig != null">
AND a.apply_range_config LIKE CONCAT('%', #{param.applyRangeConfig}, '%')
</if>
<if test="param.isExpire != null">
AND a.is_expire = #{param.isExpire}
</if>
<if test="param.sortNumber != null">
AND a.sort_number = #{param.sortNumber}
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.totalCount != null">
AND a.total_count = #{param.totalCount}
</if>
<if test="param.issuedCount != null">
AND a.issued_count = #{param.issuedCount}
</if>
<if test="param.limitPerUser != null">
AND a.limit_per_user = #{param.limitPerUser}
</if>
<if test="param.enabled != null">
AND a.enabled = #{param.enabled}
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.shop.entity.ShopCoupon">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.shop.entity.ShopCoupon">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -4,7 +4,7 @@
<!-- 关联查询sql --> <!-- 关联查询sql -->
<sql id="selectSql"> <sql id="selectSql">
SELECT a.*,b.nickname,b.real_name as realName, b.avatar,b.phone as phone SELECT a.*,b.nickname, b.avatar,b.phone as phone
FROM shop_order a FROM shop_order a
LEFT JOIN gxwebsoft_core.sys_user b ON a.user_id = b.user_id LEFT JOIN gxwebsoft_core.sys_user b ON a.user_id = b.user_id
<where> <where>
@@ -224,7 +224,7 @@
</if> </if>
<if test="param.statusFilter == 1"> <if test="param.statusFilter == 1">
<!-- 1待发货已付款但未发货 --> <!-- 1待发货已付款但未发货 -->
AND a.pay_status = 1 AND a.delivery_status = 10 AND a.pay_status = 1 AND a.delivery_status = 10 AND a.order_status = 0
</if> </if>
<if test="param.statusFilter == 2"> <if test="param.statusFilter == 2">
<!-- 2待核销已付款但订单状态为未使用 --> <!-- 2待核销已付款但订单状态为未使用 -->
@@ -250,6 +250,10 @@
<!-- 7已删除订单被删除 --> <!-- 7已删除订单被删除 -->
AND a.deleted = 1 AND a.deleted = 1
</if> </if>
<if test="param.statusFilter == 8">
<!-- 8已取消订单已取消 -->
AND a.order_status = 2
</if>
</if> </if>
</where> </where>
</sql> </sql>

View File

@@ -0,0 +1,96 @@
<?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.gxwebsoft.shop.mapper.ShopUserCouponMapper">
<!-- 关联查询sql -->
<sql id="selectSql">
SELECT a.*
FROM shop_user_coupon a
<where>
<if test="param.id != null">
AND a.id = #{param.id}
</if>
<if test="param.couponId != null">
AND a.coupon_id = #{param.couponId}
</if>
<if test="param.userId != null">
AND a.user_id = #{param.userId}
</if>
<if test="param.name != null">
AND a.name LIKE CONCAT('%', #{param.name}, '%')
</if>
<if test="param.description != null">
AND a.description LIKE CONCAT('%', #{param.description}, '%')
</if>
<if test="param.type != null">
AND a.type = #{param.type}
</if>
<if test="param.reducePrice != null">
AND a.reduce_price = #{param.reducePrice}
</if>
<if test="param.discount != null">
AND a.discount = #{param.discount}
</if>
<if test="param.minPrice != null">
AND a.min_price = #{param.minPrice}
</if>
<if test="param.applyRange != null">
AND a.apply_range = #{param.applyRange}
</if>
<if test="param.applyRangeConfig != null">
AND a.apply_range_config LIKE CONCAT('%', #{param.applyRangeConfig}, '%')
</if>
<if test="param.startTime != null">
AND a.start_time LIKE CONCAT('%', #{param.startTime}, '%')
</if>
<if test="param.endTime != null">
AND a.end_time LIKE CONCAT('%', #{param.endTime}, '%')
</if>
<if test="param.status != null">
AND a.status = #{param.status}
</if>
<if test="param.useTime != null">
AND a.use_time LIKE CONCAT('%', #{param.useTime}, '%')
</if>
<if test="param.orderId != null">
AND a.order_id LIKE CONCAT('%', #{param.orderId}, '%')
</if>
<if test="param.orderNo != null">
AND a.order_no LIKE CONCAT('%', #{param.orderNo}, '%')
</if>
<if test="param.obtainType != null">
AND a.obtain_type = #{param.obtainType}
</if>
<if test="param.obtainSource != null">
AND a.obtain_source LIKE CONCAT('%', #{param.obtainSource}, '%')
</if>
<if test="param.deleted != null">
AND a.deleted = #{param.deleted}
</if>
<if test="param.deleted == null">
AND a.deleted = 0
</if>
<if test="param.createTimeStart != null">
AND a.create_time &gt;= #{param.createTimeStart}
</if>
<if test="param.createTimeEnd != null">
AND a.create_time &lt;= #{param.createTimeEnd}
</if>
<if test="param.keywords != null">
AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%')
)
</if>
</where>
</sql>
<!-- 分页查询 -->
<select id="selectPageRel" resultType="com.gxwebsoft.shop.entity.ShopUserCoupon">
<include refid="selectSql"></include>
</select>
<!-- 查询全部 -->
<select id="selectListRel" resultType="com.gxwebsoft.shop.entity.ShopUserCoupon">
<include refid="selectSql"></include>
</select>
</mapper>

View File

@@ -0,0 +1,108 @@
package com.gxwebsoft.shop.param;
import java.math.BigDecimal;
import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 优惠券查询参数
*
* @author 科技小王子
* @since 2025-08-11 09:41:37
*/
@Data
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(name = "ShopCouponParam对象", description = "优惠券查询参数")
public class ShopCouponParam extends BaseParam {
private static final long serialVersionUID = 1L;
@Schema(description = "id")
@QueryField(type = QueryType.EQ)
private Integer id;
@Schema(description = "优惠券名称")
private String name;
@Schema(description = "优惠券描述")
private String description;
@Schema(description = "优惠券类型(10满减券 20折扣券 30免费劵)")
@QueryField(type = QueryType.EQ)
private Integer type;
@Schema(description = "满减券-减免金额")
@QueryField(type = QueryType.EQ)
private BigDecimal reducePrice;
@Schema(description = "折扣券-折扣率(0-100)")
@QueryField(type = QueryType.EQ)
private Integer discount;
@Schema(description = "最低消费金额")
@QueryField(type = QueryType.EQ)
private BigDecimal minPrice;
@Schema(description = "到期类型(10领取后生效 20固定时间)")
@QueryField(type = QueryType.EQ)
private Integer expireType;
@Schema(description = "领取后生效-有效天数")
@QueryField(type = QueryType.EQ)
private Integer expireDay;
@Schema(description = "有效期开始时间")
private String startTime;
@Schema(description = "有效期结束时间")
private String endTime;
@Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)")
@QueryField(type = QueryType.EQ)
private Integer applyRange;
@Schema(description = "适用范围配置(json格式)")
private String applyRangeConfig;
@Schema(description = "是否过期(0未过期 1已过期)")
@QueryField(type = QueryType.EQ)
private Integer isExpire;
@Schema(description = "排序(数字越小越靠前)")
@QueryField(type = QueryType.EQ)
private Integer sortNumber;
@Schema(description = "状态, 0正常, 1禁用")
@QueryField(type = QueryType.EQ)
private Integer status;
@Schema(description = "是否删除, 0否, 1是")
@QueryField(type = QueryType.EQ)
private Integer deleted;
@Schema(description = "创建用户ID")
@QueryField(type = QueryType.EQ)
private Integer userId;
@Schema(description = "发放总数量(-1表示无限制)")
@QueryField(type = QueryType.EQ)
private Integer totalCount;
@Schema(description = "已发放数量")
@QueryField(type = QueryType.EQ)
private Integer issuedCount;
@Schema(description = "每人限领数量(-1表示无限制)")
@QueryField(type = QueryType.EQ)
private Integer limitPerUser;
@Schema(description = "是否启用(0禁用 1启用)")
@QueryField(type = QueryType.EQ)
private Boolean enabled;
}

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商申请记录表查询参数 * 分销商申请记录表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:38
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商资金明细表查询参数 * 分销商资金明细表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商订单记录表查询参数 * 分销商订单记录表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商推荐关系表查询参数 * 分销商推荐关系表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商设置表查询参数 * 分销商设置表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商用户记录表查询参数 * 分销商用户记录表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 分销商提现明细表查询参数 * 分销商提现明细表查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -6,7 +6,6 @@ import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam; import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -14,7 +13,7 @@ import lombok.EqualsAndHashCode;
* 商户查询参数 * 商户查询参数
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-10 20:43:33
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)

View File

@@ -172,6 +172,9 @@ public class ShopOrderParam extends BaseParam {
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Integer deliveryStatus; private Integer deliveryStatus;
@Schema(description = "发货备注")
private String deliveryNote;
@Schema(description = "发货时间") @Schema(description = "发货时间")
private String deliveryTime; private String deliveryTime;

View File

@@ -0,0 +1,96 @@
package com.gxwebsoft.shop.param;
import java.math.BigDecimal;
import com.gxwebsoft.common.core.annotation.QueryField;
import com.gxwebsoft.common.core.annotation.QueryType;
import com.gxwebsoft.common.core.web.BaseParam;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 用户优惠券查询参数
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
@Data
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
@Schema(name = "ShopUserCouponParam对象", description = "用户优惠券查询参数")
public class ShopUserCouponParam extends BaseParam {
private static final long serialVersionUID = 1L;
@Schema(description = "id")
@QueryField(type = QueryType.EQ)
private Integer id;
@Schema(description = "优惠券模板ID")
@QueryField(type = QueryType.EQ)
private Integer couponId;
@Schema(description = "用户ID")
@QueryField(type = QueryType.EQ)
private Integer userId;
@Schema(description = "优惠券名称")
private String name;
@Schema(description = "优惠券描述")
private String description;
@Schema(description = "优惠券类型(10满减券 20折扣券 30免费劵)")
@QueryField(type = QueryType.EQ)
private Integer type;
@Schema(description = "满减券-减免金额")
@QueryField(type = QueryType.EQ)
private BigDecimal reducePrice;
@Schema(description = "折扣券-折扣率(0-100)")
@QueryField(type = QueryType.EQ)
private Integer discount;
@Schema(description = "最低消费金额")
@QueryField(type = QueryType.EQ)
private BigDecimal minPrice;
@Schema(description = "适用范围(10全部商品 20指定商品 30指定分类)")
@QueryField(type = QueryType.EQ)
private Integer applyRange;
@Schema(description = "适用范围配置(json格式)")
private String applyRangeConfig;
@Schema(description = "有效期开始时间")
private String startTime;
@Schema(description = "有效期结束时间")
private String endTime;
@Schema(description = "使用状态(0未使用 1已使用 2已过期)")
@QueryField(type = QueryType.EQ)
private Integer status;
@Schema(description = "使用时间")
private String useTime;
@Schema(description = "使用订单ID")
private Long orderId;
@Schema(description = "使用订单号")
private String orderNo;
@Schema(description = "获取方式(10主动领取 20系统发放 30活动赠送)")
@QueryField(type = QueryType.EQ)
private Integer obtainType;
@Schema(description = "获取来源描述")
private String obtainSource;
@Schema(description = "是否删除, 0否, 1是")
@QueryField(type = QueryType.EQ)
private Boolean deleted;
}

View File

@@ -5,10 +5,7 @@ import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.system.entity.User; import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.shop.config.OrderConfigProperties; import com.gxwebsoft.shop.config.OrderConfigProperties;
import com.gxwebsoft.shop.dto.OrderCreateRequest; import com.gxwebsoft.shop.dto.OrderCreateRequest;
import com.gxwebsoft.shop.entity.ShopGoods; import com.gxwebsoft.shop.entity.*;
import com.gxwebsoft.shop.entity.ShopGoodsSku;
import com.gxwebsoft.shop.entity.ShopOrder;
import com.gxwebsoft.shop.entity.ShopOrderGoods;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -47,6 +44,9 @@ public class OrderBusinessService {
@Resource @Resource
private OrderConfigProperties orderConfig; private OrderConfigProperties orderConfig;
@Resource
private ShopUserAddressService shopUserAddressService;
/** /**
* 创建订单 * 创建订单
* *
@@ -63,19 +63,22 @@ public class OrderBusinessService {
// 2. 构建订单对象 // 2. 构建订单对象
ShopOrder shopOrder = buildShopOrder(request, loginUser); ShopOrder shopOrder = buildShopOrder(request, loginUser);
// 3. 应用业务规则 // 3. 处理收货地址信息
processDeliveryAddress(shopOrder, request, loginUser);
// 4. 应用业务规则
applyBusinessRules(shopOrder, loginUser); applyBusinessRules(shopOrder, loginUser);
// 4. 保存订单 // 5. 保存订单
boolean saved = shopOrderService.save(shopOrder); boolean saved = shopOrderService.save(shopOrder);
if (!saved) { if (!saved) {
throw new BusinessException("订单保存失败"); throw new BusinessException("订单保存失败");
} }
// 5. 保存订单商品 // 6. 保存订单商品
saveOrderGoods(request, shopOrder); saveOrderGoods(request, shopOrder);
// 6. 创建微信支付订单 // 7. 创建微信支付订单
try { try {
return shopOrderService.createWxOrder(shopOrder); return shopOrderService.createWxOrder(shopOrder);
} catch (Exception e) { } catch (Exception e) {
@@ -274,6 +277,107 @@ public class OrderBusinessService {
return shopOrder; return shopOrder;
} }
/**
* 处理收货地址信息
* 优先级:前端传入地址 > 指定地址ID > 用户默认地址
*/
private void processDeliveryAddress(ShopOrder shopOrder, OrderCreateRequest request, User loginUser) {
try {
// 1. 如果前端已经传入了完整的收货地址信息,直接使用
if (isAddressInfoComplete(request)) {
log.info("使用前端传入的收货地址信息用户ID{}", loginUser.getUserId());
return;
}
// 2. 如果指定了地址ID获取该地址信息
if (request.getAddressId() != null) {
ShopUserAddress userAddress = shopUserAddressService.getById(request.getAddressId());
if (userAddress != null && userAddress.getUserId().equals(loginUser.getUserId())) {
copyAddressToOrder(userAddress, shopOrder, request);
log.info("使用指定地址ID{}用户ID{}", request.getAddressId(), loginUser.getUserId());
return;
}
log.warn("指定的地址ID不存在或不属于当前用户地址ID{}用户ID{}",
request.getAddressId(), loginUser.getUserId());
}
// 3. 获取用户默认收货地址
ShopUserAddress defaultAddress = shopUserAddressService.getDefaultAddress(loginUser.getUserId());
if (defaultAddress != null) {
copyAddressToOrder(defaultAddress, shopOrder, request);
log.info("使用用户默认收货地址地址ID{}用户ID{}", defaultAddress.getId(), loginUser.getUserId());
return;
}
// 4. 如果没有默认地址,获取用户的第一个地址
List<ShopUserAddress> userAddresses = shopUserAddressService.getUserAddresses(loginUser.getUserId());
if (!userAddresses.isEmpty()) {
ShopUserAddress firstAddress = userAddresses.get(0);
copyAddressToOrder(firstAddress, shopOrder, request);
log.info("使用用户第一个收货地址地址ID{}用户ID{}", firstAddress.getId(), loginUser.getUserId());
return;
}
// 5. 如果用户没有任何收货地址,抛出异常
throw new BusinessException("请先添加收货地址");
} catch (BusinessException e) {
throw e;
} catch (Exception e) {
log.error("处理收货地址信息失败用户ID{}", loginUser.getUserId(), e);
throw new BusinessException("处理收货地址信息失败:" + e.getMessage());
}
}
/**
* 检查前端传入的地址信息是否完整
*/
private boolean isAddressInfoComplete(OrderCreateRequest request) {
return request.getAddress() != null && !request.getAddress().trim().isEmpty() &&
request.getRealName() != null && !request.getRealName().trim().isEmpty();
}
/**
* 将用户地址信息复制到订单中(创建快照)
*/
private void copyAddressToOrder(ShopUserAddress userAddress, ShopOrder shopOrder, OrderCreateRequest request) {
// 保存地址ID引用关系
shopOrder.setAddressId(userAddress.getId());
request.setAddressId(userAddress.getId());
// 创建地址信息快照
if (request.getAddress() == null || request.getAddress().trim().isEmpty()) {
// 构建完整地址
StringBuilder fullAddress = new StringBuilder();
if (userAddress.getProvince() != null) fullAddress.append(userAddress.getProvince());
if (userAddress.getCity() != null) fullAddress.append(userAddress.getCity());
if (userAddress.getRegion() != null) fullAddress.append(userAddress.getRegion());
if (userAddress.getAddress() != null) fullAddress.append(userAddress.getAddress());
shopOrder.setAddress(fullAddress.toString());
request.setAddress(fullAddress.toString());
}
// 复制收货人信息
if (request.getRealName() == null || request.getRealName().trim().isEmpty()) {
shopOrder.setRealName(userAddress.getName());
request.setRealName(userAddress.getName());
}
// 复制经纬度信息
if (request.getAddressLat() == null && userAddress.getLat() != null) {
shopOrder.setAddressLat(userAddress.getLat());
request.setAddressLat(userAddress.getLat());
}
if (request.getAddressLng() == null && userAddress.getLng() != null) {
shopOrder.setAddressLng(userAddress.getLng());
request.setAddressLng(userAddress.getLng());
}
log.debug("地址信息快照创建完成 - 地址ID{},收货人:{},地址:{}",
userAddress.getId(), userAddress.getName(), shopOrder.getAddress());
}
/** /**
* 应用业务规则 * 应用业务规则
*/ */
@@ -459,7 +563,7 @@ public class OrderBusinessService {
} }
/** /**
* 检查是否为测试账号 * 检查是否为测试账号11
*/ */
public boolean isTestAccount(String phone) { public boolean isTestAccount(String phone) {
return orderConfig.isTestAccount(phone); return orderConfig.isTestAccount(phone);

View File

@@ -0,0 +1,42 @@
package com.gxwebsoft.shop.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.shop.entity.ShopCoupon;
import com.gxwebsoft.shop.param.ShopCouponParam;
import java.util.List;
/**
* 优惠券Service
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
public interface ShopCouponService extends IService<ShopCoupon> {
/**
* 分页关联查询
*
* @param param 查询参数
* @return PageResult<ShopCoupon>
*/
PageResult<ShopCoupon> pageRel(ShopCouponParam param);
/**
* 关联查询全部
*
* @param param 查询参数
* @return List<ShopCoupon>
*/
List<ShopCoupon> listRel(ShopCouponParam param);
/**
* 根据id查询
*
* @param id id
* @return ShopCoupon
*/
ShopCoupon getByIdRel(Integer id);
}

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商申请记录表Service * 分销商申请记录表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerApplyService extends IService<ShopDealerApply> { public interface ShopDealerApplyService extends IService<ShopDealerApply> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商资金明细表Service * 分销商资金明细表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerCapitalService extends IService<ShopDealerCapital> { public interface ShopDealerCapitalService extends IService<ShopDealerCapital> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商订单记录表Service * 分销商订单记录表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerOrderService extends IService<ShopDealerOrder> { public interface ShopDealerOrderService extends IService<ShopDealerOrder> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商推荐关系表Service * 分销商推荐关系表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerRefereeService extends IService<ShopDealerReferee> { public interface ShopDealerRefereeService extends IService<ShopDealerReferee> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商设置表Service * 分销商设置表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerSettingService extends IService<ShopDealerSetting> { public interface ShopDealerSettingService extends IService<ShopDealerSetting> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商用户记录表Service * 分销商用户记录表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerUserService extends IService<ShopDealerUser> { public interface ShopDealerUserService extends IService<ShopDealerUser> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 分销商提现明细表Service * 分销商提现明细表Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
public interface ShopDealerWithdrawService extends IService<ShopDealerWithdraw> { public interface ShopDealerWithdrawService extends IService<ShopDealerWithdraw> {

View File

@@ -11,7 +11,7 @@ import java.util.List;
* 商户Service * 商户Service
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-10 20:43:33
*/ */
public interface ShopMerchantService extends IService<ShopMerchant> { public interface ShopMerchantService extends IService<ShopMerchant> {

View File

@@ -39,4 +39,20 @@ public interface ShopUserAddressService extends IService<ShopUserAddress> {
*/ */
ShopUserAddress getByIdRel(Integer id); ShopUserAddress getByIdRel(Integer id);
/**
* 获取用户默认收货地址
*
* @param userId 用户ID
* @return ShopUserAddress
*/
ShopUserAddress getDefaultAddress(Integer userId);
/**
* 获取用户所有收货地址
*
* @param userId 用户ID
* @return List<ShopUserAddress>
*/
List<ShopUserAddress> getUserAddresses(Integer userId);
} }

View File

@@ -0,0 +1,42 @@
package com.gxwebsoft.shop.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gxwebsoft.common.core.web.PageResult;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import com.gxwebsoft.shop.param.ShopUserCouponParam;
import java.util.List;
/**
* 用户优惠券Service
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
public interface ShopUserCouponService extends IService<ShopUserCoupon> {
/**
* 分页关联查询
*
* @param param 查询参数
* @return PageResult<ShopUserCoupon>
*/
PageResult<ShopUserCoupon> pageRel(ShopUserCouponParam param);
/**
* 关联查询全部
*
* @param param 查询参数
* @return List<ShopUserCoupon>
*/
List<ShopUserCoupon> listRel(ShopUserCouponParam param);
/**
* 根据id查询
*
* @param id id
* @return ShopUserCoupon
*/
ShopUserCoupon getByIdRel(Integer id);
}

View File

@@ -0,0 +1,47 @@
package com.gxwebsoft.shop.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.shop.mapper.ShopCouponMapper;
import com.gxwebsoft.shop.service.ShopCouponService;
import com.gxwebsoft.shop.entity.ShopCoupon;
import com.gxwebsoft.shop.param.ShopCouponParam;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 优惠券Service实现
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
@Service
public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCoupon> implements ShopCouponService {
@Override
public PageResult<ShopCoupon> pageRel(ShopCouponParam param) {
PageParam<ShopCoupon, ShopCouponParam> page = new PageParam<>(param);
page.setDefaultOrder("sort_number asc, create_time desc");
List<ShopCoupon> list = baseMapper.selectPageRel(page, param);
return new PageResult<>(list, page.getTotal());
}
@Override
public List<ShopCoupon> listRel(ShopCouponParam param) {
List<ShopCoupon> list = baseMapper.selectListRel(param);
// 排序
PageParam<ShopCoupon, ShopCouponParam> page = new PageParam<>();
page.setDefaultOrder("sort_number asc, create_time desc");
return page.sortRecords(list);
}
@Override
public ShopCoupon getByIdRel(Integer id) {
ShopCouponParam param = new ShopCouponParam();
param.setId(id);
return param.getOne(baseMapper.selectListRel(param));
}
}

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商申请记录表Service实现 * 分销商申请记录表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerApplyServiceImpl extends ServiceImpl<ShopDealerApplyMapper, ShopDealerApply> implements ShopDealerApplyService { public class ShopDealerApplyServiceImpl extends ServiceImpl<ShopDealerApplyMapper, ShopDealerApply> implements ShopDealerApplyService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商资金明细表Service实现 * 分销商资金明细表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerCapitalServiceImpl extends ServiceImpl<ShopDealerCapitalMapper, ShopDealerCapital> implements ShopDealerCapitalService { public class ShopDealerCapitalServiceImpl extends ServiceImpl<ShopDealerCapitalMapper, ShopDealerCapital> implements ShopDealerCapitalService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商订单记录表Service实现 * 分销商订单记录表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerOrderServiceImpl extends ServiceImpl<ShopDealerOrderMapper, ShopDealerOrder> implements ShopDealerOrderService { public class ShopDealerOrderServiceImpl extends ServiceImpl<ShopDealerOrderMapper, ShopDealerOrder> implements ShopDealerOrderService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商推荐关系表Service实现 * 分销商推荐关系表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerRefereeServiceImpl extends ServiceImpl<ShopDealerRefereeMapper, ShopDealerReferee> implements ShopDealerRefereeService { public class ShopDealerRefereeServiceImpl extends ServiceImpl<ShopDealerRefereeMapper, ShopDealerReferee> implements ShopDealerRefereeService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商设置表Service实现 * 分销商设置表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerSettingServiceImpl extends ServiceImpl<ShopDealerSettingMapper, ShopDealerSetting> implements ShopDealerSettingService { public class ShopDealerSettingServiceImpl extends ServiceImpl<ShopDealerSettingMapper, ShopDealerSetting> implements ShopDealerSettingService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商用户记录表Service实现 * 分销商用户记录表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerUserServiceImpl extends ServiceImpl<ShopDealerUserMapper, ShopDealerUser> implements ShopDealerUserService { public class ShopDealerUserServiceImpl extends ServiceImpl<ShopDealerUserMapper, ShopDealerUser> implements ShopDealerUserService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 分销商提现明细表Service实现 * 分销商提现明细表Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-11 09:44:39
*/ */
@Service @Service
public class ShopDealerWithdrawServiceImpl extends ServiceImpl<ShopDealerWithdrawMapper, ShopDealerWithdraw> implements ShopDealerWithdrawService { public class ShopDealerWithdrawServiceImpl extends ServiceImpl<ShopDealerWithdrawMapper, ShopDealerWithdraw> implements ShopDealerWithdrawService {

View File

@@ -15,7 +15,7 @@ import java.util.List;
* 商户Service实现 * 商户Service实现
* *
* @author 科技小王子 * @author 科技小王子
* @since 2025-01-11 10:45:12 * @since 2025-08-10 20:43:33
*/ */
@Service @Service
public class ShopMerchantServiceImpl extends ServiceImpl<ShopMerchantMapper, ShopMerchant> implements ShopMerchantService { public class ShopMerchantServiceImpl extends ServiceImpl<ShopMerchantMapper, ShopMerchant> implements ShopMerchantService {

View File

@@ -92,6 +92,12 @@
final Map<Integer, List<ShopOrderGoods>> collect = goodsList.stream().collect(Collectors.groupingBy(ShopOrderGoods::getOrderId)); final Map<Integer, List<ShopOrderGoods>> collect = goodsList.stream().collect(Collectors.groupingBy(ShopOrderGoods::getOrderId));
list.forEach(d -> { list.forEach(d -> {
d.setOrderGoods(collect.get(d.getOrderId())); d.setOrderGoods(collect.get(d.getOrderId()));
// 确保 realName 字段有值,优先使用关联查询的结果,如果为空则使用订单表中的 realName
if (StrUtil.isBlank(d.getRealName())) {
log.debug("订单 {} 的 realName 为空,尝试从其他字段获取", d.getOrderId());
// 可以根据业务需求添加其他逻辑,比如从 nickname 或其他字段获取
}
}); });
} }
return new PageResult<>(list, page.getTotal()); return new PageResult<>(list, page.getTotal());
@@ -142,7 +148,9 @@
request.setAmount(amount); request.setAmount(amount);
request.setAppid(payment.getAppId()); request.setAppid(payment.getAppId());
request.setMchid(payment.getMchId()); request.setMchid(payment.getMchId());
request.setDescription(order.getComments()); // 微信支付description字段限制127字节需要截断处理
String description = com.gxwebsoft.common.core.utils.WechatPayUtils.processDescription(order.getComments());
request.setDescription(description);
request.setOutTradeNo(order.getOrderNo()); request.setOutTradeNo(order.getOrderNo());
request.setAttach(order.getTenantId().toString()); request.setAttach(order.getTenantId().toString());
final Payer payer = new Payer(); final Payer payer = new Payer();
@@ -723,4 +731,6 @@
} }
} }
} }

View File

@@ -1,5 +1,6 @@
package com.gxwebsoft.shop.service.impl; package com.gxwebsoft.shop.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.shop.mapper.ShopUserAddressMapper; import com.gxwebsoft.shop.mapper.ShopUserAddressMapper;
import com.gxwebsoft.shop.service.ShopUserAddressService; import com.gxwebsoft.shop.service.ShopUserAddressService;
@@ -44,4 +45,24 @@ public class ShopUserAddressServiceImpl extends ServiceImpl<ShopUserAddressMappe
return param.getOne(baseMapper.selectListRel(param)); return param.getOne(baseMapper.selectListRel(param));
} }
@Override
public ShopUserAddress getDefaultAddress(Integer userId) {
LambdaQueryWrapper<ShopUserAddress> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ShopUserAddress::getUserId, userId)
.eq(ShopUserAddress::getIsDefault, true)
.orderByDesc(ShopUserAddress::getCreateTime)
.last("LIMIT 1");
return getOne(wrapper);
}
@Override
public List<ShopUserAddress> getUserAddresses(Integer userId) {
LambdaQueryWrapper<ShopUserAddress> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ShopUserAddress::getUserId, userId)
.orderByDesc(ShopUserAddress::getIsDefault)
.orderByAsc(ShopUserAddress::getSortNumber)
.orderByDesc(ShopUserAddress::getCreateTime);
return list(wrapper);
}
} }

View File

@@ -0,0 +1,47 @@
package com.gxwebsoft.shop.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxwebsoft.shop.mapper.ShopUserCouponMapper;
import com.gxwebsoft.shop.service.ShopUserCouponService;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import com.gxwebsoft.shop.param.ShopUserCouponParam;
import com.gxwebsoft.common.core.web.PageParam;
import com.gxwebsoft.common.core.web.PageResult;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 用户优惠券Service实现
*
* @author 科技小王子
* @since 2025-08-11 09:41:38
*/
@Service
public class ShopUserCouponServiceImpl extends ServiceImpl<ShopUserCouponMapper, ShopUserCoupon> implements ShopUserCouponService {
@Override
public PageResult<ShopUserCoupon> pageRel(ShopUserCouponParam param) {
PageParam<ShopUserCoupon, ShopUserCouponParam> page = new PageParam<>(param);
page.setDefaultOrder("sort_number asc, create_time desc");
List<ShopUserCoupon> list = baseMapper.selectPageRel(page, param);
return new PageResult<>(list, page.getTotal());
}
@Override
public List<ShopUserCoupon> listRel(ShopUserCouponParam param) {
List<ShopUserCoupon> list = baseMapper.selectListRel(param);
// 排序
PageParam<ShopUserCoupon, ShopUserCouponParam> page = new PageParam<>();
page.setDefaultOrder("sort_number asc, create_time desc");
return page.sortRecords(list);
}
@Override
public ShopUserCoupon getByIdRel(Integer id) {
ShopUserCouponParam param = new ShopUserCouponParam();
param.setId(id);
return param.getOne(baseMapper.selectListRel(param));
}
}

View File

@@ -1,276 +0,0 @@
package com.gxwebsoft.shop.utils;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
/**
* 优惠券工具类
*
* @author 科技小王子
* @since 2025-08-08 23:00:00
*/
public class CouponUtils {
/**
* 优惠券类型名称映射
*/
public static String getTypeName(Integer type) {
if (type == null) {
return "未知";
}
switch (type) {
case 10:
return "满减券";
case 20:
return "折扣券";
case 30:
return "免费券";
default:
return "未知";
}
}
/**
* 优惠券状态名称映射
*/
public static String getStatusName(Integer status) {
if (status == null) {
return "未知";
}
switch (status) {
case 0:
return "未使用";
case 1:
return "已使用";
case 2:
return "已过期";
default:
return "未知";
}
}
/**
* 适用范围名称映射
*/
public static String getApplyRangeName(Integer applyRange) {
if (applyRange == null) {
return "未知";
}
switch (applyRange) {
case 10:
return "全部商品";
case 20:
return "指定商品";
case 30:
return "指定分类";
default:
return "未知";
}
}
/**
* 获取方式名称映射
*/
public static String getObtainTypeName(Integer obtainType) {
if (obtainType == null) {
return "未知";
}
switch (obtainType) {
case 10:
return "主动领取";
case 20:
return "系统发放";
case 30:
return "活动赠送";
default:
return "未知";
}
}
/**
* 计算优惠券优惠金额
*
* @param userCoupon 用户优惠券
* @param orderAmount 订单金额
* @return 优惠金额
*/
public static BigDecimal calculateDiscountAmount(ShopUserCoupon userCoupon, BigDecimal orderAmount) {
if (userCoupon == null || orderAmount == null || orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
// 检查最低消费金额
if (userCoupon.getMinPrice() != null &&
orderAmount.compareTo(userCoupon.getMinPrice()) < 0) {
return BigDecimal.ZERO;
}
BigDecimal discountAmount = BigDecimal.ZERO;
if (ShopUserCoupon.TYPE_REDUCE.equals(userCoupon.getType())) {
// 满减券
discountAmount = userCoupon.getReducePrice() != null ?
userCoupon.getReducePrice() : BigDecimal.ZERO;
} else if (ShopUserCoupon.TYPE_DISCOUNT.equals(userCoupon.getType())) {
// 折扣券
if (userCoupon.getDiscount() != null && userCoupon.getDiscount() > 0 && userCoupon.getDiscount() < 100) {
BigDecimal discountRate = BigDecimal.valueOf(100 - userCoupon.getDiscount())
.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
discountAmount = orderAmount.multiply(discountRate);
}
} else if (ShopUserCoupon.TYPE_FREE.equals(userCoupon.getType())) {
// 免费券
discountAmount = orderAmount;
}
// 优惠金额不能超过订单金额
return discountAmount.compareTo(orderAmount) > 0 ? orderAmount : discountAmount;
}
/**
* 检查优惠券是否适用于指定商品
*
* @param userCoupon 用户优惠券
* @param goodsId 商品ID
* @param categoryId 商品分类ID
* @return 是否适用
*/
public static boolean isApplicableToGoods(ShopUserCoupon userCoupon, Integer goodsId, Integer categoryId) {
if (userCoupon == null || userCoupon.getApplyRange() == null) {
return false;
}
if (ShopUserCoupon.APPLY_ALL.equals(userCoupon.getApplyRange())) {
// 全部商品可用
return true;
} else if (ShopUserCoupon.APPLY_GOODS.equals(userCoupon.getApplyRange())) {
// 指定商品可用
if (goodsId == null || userCoupon.getApplyRangeConfig() == null || userCoupon.getApplyRangeConfig().trim().isEmpty()) {
return false;
}
List<String> goodsIds = Arrays.asList(userCoupon.getApplyRangeConfig().split(","));
return goodsIds.contains(goodsId.toString());
} else if (ShopUserCoupon.APPLY_CATEGORY.equals(userCoupon.getApplyRange())) {
// 指定分类可用
if (categoryId == null || userCoupon.getApplyRangeConfig() == null || userCoupon.getApplyRangeConfig().trim().isEmpty()) {
return false;
}
List<String> categoryIds = Arrays.asList(userCoupon.getApplyRangeConfig().split(","));
return categoryIds.contains(categoryId.toString());
}
return false;
}
/**
* 检查优惠券是否已过期
*
* @param userCoupon 用户优惠券
* @return 是否已过期
*/
public static boolean isExpired(ShopUserCoupon userCoupon) {
if (userCoupon == null || userCoupon.getEndTime() == null) {
return false;
}
return userCoupon.getEndTime().isBefore(LocalDateTime.now());
}
/**
* 检查优惠券是否可用
*
* @param userCoupon 用户优惠券
* @return 是否可用
*/
public static boolean isAvailable(ShopUserCoupon userCoupon) {
if (userCoupon == null) {
return false;
}
// 检查状态
if (!ShopUserCoupon.STATUS_UNUSED.equals(userCoupon.getStatus())) {
return false;
}
// 检查是否过期
if (isExpired(userCoupon)) {
return false;
}
// 检查是否在有效期内
LocalDateTime now = LocalDateTime.now();
if (userCoupon.getStartTime() != null && userCoupon.getStartTime().isAfter(now)) {
return false; // 还未开始
}
return true;
}
/**
* 格式化优惠券显示文本
*
* @param userCoupon 用户优惠券
* @return 显示文本
*/
public static String formatCouponDisplay(ShopUserCoupon userCoupon) {
if (userCoupon == null) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append(userCoupon.getName());
if (ShopUserCoupon.TYPE_REDUCE.equals(userCoupon.getType()) && userCoupon.getReducePrice() != null) {
sb.append("").append(userCoupon.getReducePrice()).append("");
if (userCoupon.getMinPrice() != null && userCoupon.getMinPrice().compareTo(BigDecimal.ZERO) > 0) {
sb.append("(满").append(userCoupon.getMinPrice()).append("可用)");
}
} else if (ShopUserCoupon.TYPE_DISCOUNT.equals(userCoupon.getType()) && userCoupon.getDiscount() != null) {
sb.append(" ").append(userCoupon.getDiscount()).append("");
if (userCoupon.getMinPrice() != null && userCoupon.getMinPrice().compareTo(BigDecimal.ZERO) > 0) {
sb.append("(满").append(userCoupon.getMinPrice()).append("可用)");
}
} else if (ShopUserCoupon.TYPE_FREE.equals(userCoupon.getType())) {
sb.append(" 免费券");
}
if (userCoupon.getEndTime() != null) {
sb.append(" 有效期至").append(userCoupon.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
}
return sb.toString();
}
/**
* 生成优惠券编码
*
* @param userId 用户ID
* @param couponId 优惠券模板ID
* @return 优惠券编码
*/
public static String generateCouponCode(Integer userId, Integer couponId) {
String timestamp = String.valueOf(System.currentTimeMillis());
return String.format("CPN%s%s%s",
String.format("%08d", userId),
String.format("%06d", couponId),
timestamp.substring(timestamp.length() - 6));
}
/**
* 验证优惠券编码格式
*
* @param couponCode 优惠券编码
* @return 是否有效
*/
public static boolean isValidCouponCode(String couponCode) {
if (couponCode == null || couponCode.length() != 23) {
return false;
}
return couponCode.startsWith("CPN") && couponCode.substring(3).matches("\\d{20}");
}
}

View File

@@ -7,7 +7,7 @@ server:
# 数据源配置 # 数据源配置
spring: spring:
datasource: datasource:
url: jdbc:mysql://8.134.169.209:13306/website?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 url: jdbc:mysql://8.134.169.209:13306/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
username: modules username: modules
password: 8YdLnk7KsPAyDXGA password: 8YdLnk7KsPAyDXGA
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver

View File

@@ -32,7 +32,7 @@ public class TestMain {
public void testGenJwtKey() { public void testGenJwtKey() {
BigDecimal bigDecimal = new BigDecimal(NumberUtil.decimalFormat("0.00", 1 * 0.01)); BigDecimal bigDecimal = new BigDecimal(NumberUtil.decimalFormat("0.00", 1 * 0.01));
System.out.println("实际付款金额 = " + bigDecimal); System.out.println("实际付款金额111111111 = " + bigDecimal);
final HjmCar byGpsNo = hjmCarService.getByGpsNo("gps1"); final HjmCar byGpsNo = hjmCarService.getByGpsNo("gps1");
System.out.println("byGpsNo = " + byGpsNo.getSpeed()); System.out.println("byGpsNo = " + byGpsNo.getSpeed());

View File

@@ -1,60 +0,0 @@
package com.gxwebsoft.generator;
/**
* 独立应用模块-代码生成工具
*
* @author WebSoft
* @since 2021-09-05 00:31:14
*/
public class AppGenerator {
// 输出位置
private static final String OUTPUT_LOCATION = System.getProperty("user.dir");
//private static final String OUTPUT_LOCATION = "D:/codegen"; // 不想生成到项目中可以写磁盘路径
// 输出目录
private static final String OUTPUT_DIR = "/src/main/java";
// 作者名称
private static final String AUTHOR = "科技小王子";
// 数据库连接配置
private static final String DB_URL = "jdbc:mysql://47.119.165.234:3308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
private static final String DB_USERNAME = "modules";
private static final String DB_PASSWORD = "8YdLnk7KsPAyDXGA";
// 包名
private static final String PACKAGE_NAME = "com.gxwebsoft";
// 模块名
private static final String MODULE_NAME = "app";
// 需要生成的表
private static final String[] TABLE_NAMES = new String[]{
// "app_bszx_bm",
// "app_bszx_pay",
// "app_bszx_grade",
// "app_bszx_class"
"app_bszx_era"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{
"tb_"
};
public static void main(String[] args) {
System.out.println("=== MyBatis-Plus 代码生成器 ===");
System.out.println("输出目录: " + OUTPUT_LOCATION + OUTPUT_DIR);
System.out.println("包名: " + PACKAGE_NAME + "." + MODULE_NAME);
System.out.println("表名: " + String.join(", ", TABLE_NAMES));
System.out.println("数据库: " + DB_URL);
try {
// 注意由于MyBatis-Plus Generator版本兼容性问题
// 当前版本的FastAutoGenerator API可能不兼容
// 建议使用项目中其他Generator类的实现方式
System.out.println("请参考项目中的其他Generator类如ProjectGenerator.java的实现方式");
System.out.println("或者手动创建Entity、Mapper、Service、Controller类");
} catch (Exception e) {
System.err.println("代码生成失败: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -1,96 +0,0 @@
package com.gxwebsoft.generator;
/**
* 小程序模块-代码生成工具
*
* @author WebSoft
* @since 2021-09-05 00:31:14
*/
public class BszxGenerator {
// 输出位置
private static final String OUTPUT_LOCATION = System.getProperty("user.dir");
//private static final String OUTPUT_LOCATION = "D:/codegen"; // 不想生成到项目中可以写磁盘路径
// 输出目录
private static final String OUTPUT_DIR = "/src/main/java";
// Vue文件输出位置
private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/VUE/mp";
// Vue文件输出目录
private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/APP/mp";
// Vue文件输出目录
private static final String OUTPUT_DIR_VUE = "/src";
// 作者名称
private static final String AUTHOR = "科技小王子";
// 是否在xml中添加二级缓存配置
private static final boolean ENABLE_CACHE = false;
// 数据库连接配置
private static final String DB_URL = "jdbc:mysql://47.119.165.234:3308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DB_USERNAME = "modules";
private static final String DB_PASSWORD = "8YdLnk7KsPAyDXGA";
// 包名
private static final String PACKAGE_NAME = "com.gxwebsoft";
// 模块名
private static final String MODULE_NAME = "bszx";
// 需要生成的表
private static final String[] TABLE_NAMES = new String[]{
// "bszx_bm",
// "bszx_era",
// "bszx_grade",
// "bszx_class",
// "bszx_pay",
// "bszx_branch",
// "bszx_pay_ranking"
"bszx_order"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{
"tb_"
};
// 不需要作为查询参数的字段
private static final String[] PARAM_EXCLUDE_FIELDS = new String[]{
"tenant_id",
"create_time",
"update_time"
};
// 查询参数使用String的类型
private static final String[] PARAM_TO_STRING_TYPE = new String[]{
"Date",
"LocalDate",
"LocalTime",
"LocalDateTime"
};
// 查询参数使用EQ的类型
private static final String[] PARAM_EQ_TYPE = new String[]{
"Integer",
"Boolean",
"BigDecimal"
};
// 是否添加权限注解
private static final boolean AUTH_ANNOTATION = true;
// 是否添加日志注解
private static final boolean LOG_ANNOTATION = true;
// controller的mapping前缀
private static final String CONTROLLER_MAPPING_PREFIX = "/api";
// 模板所在位置
private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates";
public static void main(String[] args) {
System.out.println("=== 办事指南模块 MyBatis-Plus 代码生成器 ===");
System.out.println("输出目录: " + OUTPUT_LOCATION + OUTPUT_DIR);
System.out.println("包名: " + PACKAGE_NAME + "." + MODULE_NAME);
System.out.println("表名: " + String.join(", ", TABLE_NAMES));
System.out.println("数据库: " + DB_URL);
try {
// 注意由于MyBatis-Plus Generator版本兼容性问题
// 当前版本的API可能不兼容建议手动创建代码文件
System.out.println("请参考项目中现有的办事指南模块代码结构");
System.out.println("或者手动创建Entity、Mapper、Service、Controller类");
} catch (Exception e) {
System.err.println("代码生成失败: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -1,5 +1,19 @@
package com.gxwebsoft.generator; package com.gxwebsoft.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.gxwebsoft.generator.engine.BeetlTemplateEnginePlus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* CMS模块-代码生成工具 * CMS模块-代码生成工具
* *
@@ -62,8 +76,8 @@ public class CmsGenerator {
// "cms_model" // "cms_model"
// "cms_lang", // "cms_lang",
// "cms_lang_log", // "cms_lang_log",
"cms_statistics", // "cms_website_setting",
// "cms_website_setting" "cms_statistics"
}; };
// 需要去除的表前缀 // 需要去除的表前缀
@@ -99,22 +113,163 @@ public class CmsGenerator {
private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates"; private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates";
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("=== CMS模块 MyBatis-Plus 代码生成器 ==="); // 代码生成器
System.out.println("输出目录: " + OUTPUT_LOCATION + OUTPUT_DIR); AutoGenerator mpg = new AutoGenerator();
System.out.println("包名: " + PACKAGE_NAME + "." + MODULE_NAME);
System.out.println("表名: " + String.join(", ", TABLE_NAMES));
System.out.println("数据库: " + DB_URL);
try { // 全局配置
// 注意由于MyBatis-Plus Generator版本兼容性问题 GlobalConfig gc = new GlobalConfig();
// 当前版本的API可能不兼容建议手动创建代码文件 gc.setOutputDir(OUTPUT_LOCATION + OUTPUT_DIR);
System.out.println("请参考项目中现有的CMS模块代码结构"); gc.setAuthor(AUTHOR);
System.out.println("或者手动创建Entity、Mapper、Service、Controller类"); gc.setOpen(false);
gc.setFileOverride(true);
gc.setEnableCache(ENABLE_CACHE);
gc.setSwagger2(true);
gc.setIdType(IdType.AUTO);
gc.setServiceName("%sService");
mpg.setGlobalConfig(gc);
} catch (Exception e) { // 数据源配置
System.err.println("代码生成失败: " + e.getMessage()); DataSourceConfig dsc = new DataSourceConfig();
e.printStackTrace(); dsc.setUrl(DB_URL);
} // dsc.setSchemaName("public");
dsc.setDriverName(DB_DRIVER);
dsc.setUsername(DB_USERNAME);
dsc.setPassword(DB_PASSWORD);
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(MODULE_NAME);
pc.setParent(PACKAGE_NAME);
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setInclude(TABLE_NAMES);
strategy.setTablePrefix(TABLE_PREFIX);
strategy.setSuperControllerClass(PACKAGE_NAME + ".common.core.web.BaseController");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true);
strategy.setLogicDeleteFieldName("deleted");
mpg.setStrategy(strategy);
// 模板配置
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController(TEMPLATES_DIR + "/controller.java");
templateConfig.setEntity(TEMPLATES_DIR + "/entity.java");
templateConfig.setMapper(TEMPLATES_DIR + "/mapper.java");
templateConfig.setXml(TEMPLATES_DIR + "/mapper.xml");
templateConfig.setService(TEMPLATES_DIR + "/service.java");
templateConfig.setServiceImpl(TEMPLATES_DIR + "/serviceImpl.java");
mpg.setTemplate(templateConfig);
mpg.setTemplateEngine(new BeetlTemplateEnginePlus());
// 自定义模板配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
Map<String, Object> map = new HashMap<>();
map.put("packageName", PACKAGE_NAME);
map.put("paramExcludeFields", PARAM_EXCLUDE_FIELDS);
map.put("paramToStringType", PARAM_TO_STRING_TYPE);
map.put("paramEqType", PARAM_EQ_TYPE);
map.put("authAnnotation", AUTH_ANNOTATION);
map.put("logAnnotation", LOG_ANNOTATION);
map.put("controllerMappingPrefix", CONTROLLER_MAPPING_PREFIX);
this.setMap(map);
}
};
String templatePath = TEMPLATES_DIR + "/param.java.btl";
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION + OUTPUT_DIR + "/"
+ PACKAGE_NAME.replace(".", "/")
+ "/" + pc.getModuleName() + "/param/"
+ tableInfo.getEntityName() + "Param" + StringPool.DOT_JAVA;
}
});
/**
* 以下是生成VUE项目代码
* 生成文件的路径 /api/shop/goods/index.ts
*/
templatePath = TEMPLATES_DIR + "/index.ts.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.ts";
}
});
focList.add(new FileOutConfig() {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.ts";
}
});
// 生成TS文件 (/api/shop/goods/model/index.ts)
templatePath = TEMPLATES_DIR + "/model.ts.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/model/" + "index.ts";
}
});
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_UNIAPP + OUTPUT_DIR_VUE
+ "/api/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/model/" + "index.ts";
}
});
// 生成Vue文件(/views/shop/goods/index.vue)
templatePath = TEMPLATES_DIR + "/index.vue.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/views/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/" + "index.vue";
}
});
// 生成components文件(/views/shop/goods/components/edit.vue)
templatePath = TEMPLATES_DIR + "/components.edit.vue.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/views/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/components/" + tableInfo.getEntityPath() + "Edit.vue";
}
});
// 生成components文件(/views/shop/goods/components/search.vue)
templatePath = TEMPLATES_DIR + "/components.search.vue.btl";
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
return OUTPUT_LOCATION_VUE + OUTPUT_DIR_VUE
+ "/views/" + pc.getModuleName() + "/"
+ tableInfo.getEntityPath() + "/components/" + "search.vue";
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.execute();
} }
} }

View File

@@ -1,104 +0,0 @@
package com.gxwebsoft.generator;
/**
* HjmGenerator - 环境监测模块代码生成器
*
* 注意由于MyBatis-Plus Generator版本兼容性问题
* 当前版本的API可能不兼容建议手动创建代码文件
*/
/**
* 小程序模块-代码生成工具
*
* @author WebSoft
* @since 2021-09-05 00:31:14
*/
public class HjmGenerator {
// 输出位置
private static final String OUTPUT_LOCATION = System.getProperty("user.dir");
//private static final String OUTPUT_LOCATION = "D:/codegen"; // 不想生成到项目中可以写磁盘路径
// 输出目录
private static final String OUTPUT_DIR = "/src/main/java";
// Vue文件输出位置
private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/VUE/mp";
// Vue文件输出目录
private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/APP/mp";
// Vue文件输出目录
private static final String OUTPUT_DIR_VUE = "/src";
// 作者名称
private static final String AUTHOR = "科技小王子";
// 是否在xml中添加二级缓存配置
private static final boolean ENABLE_CACHE = false;
// 数据库连接配置
private static final String DB_URL = "jdbc:mysql://47.119.165.234:3308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DB_USERNAME = "modules";
private static final String DB_PASSWORD = "8YdLnk7KsPAyDXGA";
// 包名
private static final String PACKAGE_NAME = "com.gxwebsoft";
// 模块名
private static final String MODULE_NAME = "hjm";
// 需要生成的表
private static final String[] TABLE_NAMES = new String[]{
// "hjm_car",
// "hjm_courses",
// "hjm_questions",
// "hjm_choices",
// "hjm_fence",
// "hjm_exam_log",
// "hjm_bx_log",
// "hjm_gps_log",
"hjm_violation"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{
"tb_"
};
// 不需要作为查询参数的字段
private static final String[] PARAM_EXCLUDE_FIELDS = new String[]{
"tenant_id",
"create_time",
"update_time"
};
// 查询参数使用String的类型
private static final String[] PARAM_TO_STRING_TYPE = new String[]{
"Date",
"LocalDate",
"LocalTime",
"LocalDateTime"
};
// 查询参数使用EQ的类型
private static final String[] PARAM_EQ_TYPE = new String[]{
"Integer",
"Boolean",
"BigDecimal"
};
// 是否添加权限注解
private static final boolean AUTH_ANNOTATION = true;
// 是否添加日志注解
private static final boolean LOG_ANNOTATION = true;
// controller的mapping前缀
private static final String CONTROLLER_MAPPING_PREFIX = "/api";
// 模板所在位置
private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates";
public static void main(String[] args) {
System.out.println("=== 环境监测模块 MyBatis-Plus 代码生成器 ===");
System.out.println("输出目录: " + OUTPUT_LOCATION + OUTPUT_DIR);
System.out.println("包名: " + PACKAGE_NAME + "." + MODULE_NAME);
System.out.println("表名: " + String.join(", ", TABLE_NAMES));
System.out.println("数据库: " + DB_URL);
try {
// 注意由于MyBatis-Plus Generator版本兼容性问题
// 当前版本的API可能不兼容建议手动创建代码文件
System.out.println("请参考项目中现有的环境监测模块代码结构");
System.out.println("或者手动创建Entity、Mapper、Service、Controller类");
} catch (Exception e) {
System.err.println("代码生成失败: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -1,101 +0,0 @@
package com.gxwebsoft.generator;
/**
* ProjectGenerator - 项目代码生成器
*
* 注意由于MyBatis-Plus Generator版本兼容性问题
* 当前版本的API可能不兼容建议手动创建代码文件
*/
/**
* 小程序模块-代码生成工具
*
* @author WebSoft
* @since 2021-09-05 00:31:14
*/
public class ProjectGenerator {
// 输出位置
private static final String OUTPUT_LOCATION = System.getProperty("user.dir");
//private static final String OUTPUT_LOCATION = "D:/codegen"; // 不想生成到项目中可以写磁盘路径
// 输出目录
private static final String OUTPUT_DIR = "/src/main/java";
// Vue文件输出位置
private static final String OUTPUT_LOCATION_VUE = "/Users/gxwebsoft/VUE/oa";
// Vue文件输出目录
private static final String OUTPUT_LOCATION_UNIAPP = "/Users/gxwebsoft/APP/oa";
// Vue文件输出目录
private static final String OUTPUT_DIR_VUE = "/src";
// 作者名称
private static final String AUTHOR = "科技小王子";
// 是否在xml中添加二级缓存配置
private static final boolean ENABLE_CACHE = false;
// 数据库连接配置
private static final String DB_URL = "jdbc:mysql://47.119.165.234:3308/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8";
private static final String DB_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DB_USERNAME = "modules";
private static final String DB_PASSWORD = "8YdLnk7KsPAyDXGA";
// 包名
private static final String PACKAGE_NAME = "com.gxwebsoft";
// 模块名
private static final String MODULE_NAME = "project";
// 需要生成的表
private static final String[] TABLE_NAMES = new String[]{
// "project",
// "project_field",
// "project_renew",
// "project_user",
// "project_url",
// "project_collection"
};
// 需要去除的表前缀
private static final String[] TABLE_PREFIX = new String[]{
"tb_"
};
// 不需要作为查询参数的字段
private static final String[] PARAM_EXCLUDE_FIELDS = new String[]{
"tenant_id",
"create_time",
"update_time"
};
// 查询参数使用String的类型
private static final String[] PARAM_TO_STRING_TYPE = new String[]{
"Date",
"LocalDate",
"LocalTime",
"LocalDateTime"
};
// 查询参数使用EQ的类型
private static final String[] PARAM_EQ_TYPE = new String[]{
"Integer",
"Boolean",
"BigDecimal"
};
// 是否添加权限注解
private static final boolean AUTH_ANNOTATION = true;
// 是否添加日志注解
private static final boolean LOG_ANNOTATION = true;
// controller的mapping前缀
private static final String CONTROLLER_MAPPING_PREFIX = "/api";
// 模板所在位置
private static final String TEMPLATES_DIR = "/src/test/java/com/gxwebsoft/generator/templates";
public static void main(String[] args) {
System.out.println("=== 项目模块 MyBatis-Plus 代码生成器 ===");
System.out.println("输出目录: " + OUTPUT_LOCATION + OUTPUT_DIR);
System.out.println("包名: " + PACKAGE_NAME + "." + MODULE_NAME);
System.out.println("表名: " + String.join(", ", TABLE_NAMES));
System.out.println("数据库: " + DB_URL);
try {
// 注意由于MyBatis-Plus Generator版本兼容性问题
// 当前版本的API可能不兼容建议手动创建代码文件
System.out.println("请参考项目中现有的项目模块代码结构");
System.out.println("或者手动创建Entity、Mapper、Service、Controller类");
} catch (Exception e) {
System.err.println("代码生成失败: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -54,7 +54,7 @@ public class ShopGenerator {
// "shop_goods_spec", // "shop_goods_spec",
// "shop_goods_sku", // "shop_goods_sku",
// "shop_goods_category", // "shop_goods_category",
"shop_coupon", // "shop_coupon",
// "shop_goods_description", // "shop_goods_description",
// "shop_goods_log", // "shop_goods_log",
// "shop_goods_relation", // "shop_goods_relation",
@@ -88,7 +88,7 @@ public class ShopGenerator {
// "shop_dealer_user", // "shop_dealer_user",
// "shop_user_referee", // "shop_user_referee",
// "shop_dealer_withdraw", // "shop_dealer_withdraw",
"shop_user_coupon", // "shop_user_coupon",
// "shop_cart", // "shop_cart",
// "shop_count", // "shop_count",
// "shop_express", // "shop_express",

View File

@@ -0,0 +1,76 @@
package com.gxwebsoft.generator;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.gxwebsoft.generator.engine.BeetlTemplateEnginePlus;
/**
* 测试代码生成器
*
* @author WebSoft
* @since 2025-01-09
*/
public class TestGenerator {
public static void main(String[] args) {
System.out.println("=== 测试 MyBatis-Plus 代码生成器 ===");
try {
// 测试基本配置
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
gc.setAuthor("WebSoft");
gc.setOpen(false);
gc.setFileOverride(false); // 设置为false避免覆盖现有文件
gc.setSwagger2(true);
gc.setIdType(IdType.AUTO);
gc.setServiceName("%sService");
mpg.setGlobalConfig(gc);
// 数据源配置(使用测试配置,不连接真实数据库)
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("test");
dsc.setPassword("test");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("test");
pc.setParent("com.gxwebsoft");
mpg.setPackageInfo(pc);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setInclude("test_table"); // 测试表名
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix("tb_");
mpg.setStrategy(strategy);
// 模板引擎配置
mpg.setTemplateEngine(new BeetlTemplateEnginePlus());
System.out.println("✅ 代码生成器配置成功!");
System.out.println("✅ MyBatis-Plus Generator API 兼容性正常");
System.out.println("✅ BeetlTemplateEnginePlus 加载成功");
System.out.println("✅ 依赖版本降级成功,代码生成器已恢复正常");
// 注意:这里不执行实际的生成,只测试配置是否正确
// mpg.execute();
} catch (Exception e) {
System.err.println("❌ 代码生成器测试失败: " + e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,75 @@
package com.gxwebsoft.shop;
import com.gxwebsoft.common.core.utils.WechatPayUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.nio.charset.StandardCharsets;
import static org.junit.jupiter.api.Assertions.*;
/**
* 微信支付商品描述字段测试
* 验证字节长度限制处理
*/
@SpringBootTest
public class WechatPayDescriptionTest {
@Test
public void testTruncateToByteLimit() {
// 测试正常情况 - 字符串长度在限制内
String shortText = "正常商品描述";
String result1 = WechatPayUtils.truncateToByteLimit(shortText, 127);
assertEquals(shortText, result1);
assertTrue(result1.getBytes(StandardCharsets.UTF_8).length <= 127);
// 测试超长中文字符串
String longText = "【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋";
String result2 = WechatPayUtils.truncateToByteLimit(longText, 127);
assertNotNull(result2);
assertTrue(result2.getBytes(StandardCharsets.UTF_8).length <= 127);
System.out.println("原始文本字节数: " + longText.getBytes(StandardCharsets.UTF_8).length);
System.out.println("截断后文本: " + result2);
System.out.println("截断后字节数: " + result2.getBytes(StandardCharsets.UTF_8).length);
// 测试null和空字符串
assertNull(WechatPayUtils.truncateToByteLimit(null, 127));
assertEquals("", WechatPayUtils.truncateToByteLimit("", 127));
// 测试英文字符串
String englishText = "This is a very long English description that might exceed the byte limit for WeChat Pay description field";
String result3 = WechatPayUtils.truncateToByteLimit(englishText, 127);
assertNotNull(result3);
assertTrue(result3.getBytes(StandardCharsets.UTF_8).length <= 127);
// 测试混合字符串
String mixedText = "Product Name 产品名称 with special characters @#$%^&*()";
String result4 = WechatPayUtils.truncateToByteLimit(mixedText, 50);
assertNotNull(result4);
assertTrue(result4.getBytes(StandardCharsets.UTF_8).length <= 50);
}
@Test
public void testSpecificErrorCase() {
// 测试错误信息中的具体案例
String errorText = "【湾区认证】【百千万工程帮扶产品 通过远方320项检测 湾区认证 丰江桥佛手瓜面】独特风味低脂轻食便捷速食非油炸 720g/袋";
// 验证原始文本确实超过127字节
int originalBytes = errorText.getBytes(StandardCharsets.UTF_8).length;
System.out.println("原始文本: " + errorText);
System.out.println("原始字节数: " + originalBytes);
assertTrue(originalBytes > 127, "原始文本应该超过127字节");
// 测试截断
String truncated = WechatPayUtils.processDescription(errorText);
int truncatedBytes = truncated.getBytes(StandardCharsets.UTF_8).length;
System.out.println("截断后文本: " + truncated);
System.out.println("截断后字节数: " + truncatedBytes);
// 验证截断后的文本符合要求
assertNotNull(truncated);
assertTrue(truncatedBytes <= 127, "截断后字节数应该不超过127");
assertFalse(truncated.contains("\uFFFD"), "截断后的文本不应包含无效字符");
}
}

View File

@@ -1,156 +0,0 @@
package com.gxwebsoft.shop.utils;
import com.gxwebsoft.shop.entity.ShopUserCoupon;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* CouponUtils 测试类
*/
public class CouponUtilsTest {
@Test
public void testGetTypeName() {
assertEquals("满减券", CouponUtils.getTypeName(ShopUserCoupon.TYPE_REDUCE));
assertEquals("折扣券", CouponUtils.getTypeName(ShopUserCoupon.TYPE_DISCOUNT));
assertEquals("免费券", CouponUtils.getTypeName(ShopUserCoupon.TYPE_FREE));
assertEquals("未知", CouponUtils.getTypeName(null));
assertEquals("未知", CouponUtils.getTypeName(99));
}
@Test
public void testGetStatusName() {
assertEquals("未使用", CouponUtils.getStatusName(ShopUserCoupon.STATUS_UNUSED));
assertEquals("已使用", CouponUtils.getStatusName(ShopUserCoupon.STATUS_USED));
assertEquals("已过期", CouponUtils.getStatusName(ShopUserCoupon.STATUS_EXPIRED));
assertEquals("未知", CouponUtils.getStatusName(null));
assertEquals("未知", CouponUtils.getStatusName(99));
}
@Test
public void testGetApplyRangeName() {
assertEquals("全部商品", CouponUtils.getApplyRangeName(ShopUserCoupon.APPLY_ALL));
assertEquals("指定商品", CouponUtils.getApplyRangeName(ShopUserCoupon.APPLY_GOODS));
assertEquals("指定分类", CouponUtils.getApplyRangeName(ShopUserCoupon.APPLY_CATEGORY));
assertEquals("未知", CouponUtils.getApplyRangeName(null));
assertEquals("未知", CouponUtils.getApplyRangeName(99));
}
@Test
public void testCalculateDiscountAmount() {
// 测试满减券
ShopUserCoupon reduceCoupon = new ShopUserCoupon();
reduceCoupon.setType(ShopUserCoupon.TYPE_REDUCE);
reduceCoupon.setReducePrice(new BigDecimal("10.00"));
reduceCoupon.setMinPrice(new BigDecimal("50.00"));
BigDecimal discount = CouponUtils.calculateDiscountAmount(reduceCoupon, new BigDecimal("100.00"));
assertEquals(0, new BigDecimal("10.00").compareTo(discount));
// 测试不满足最低消费
discount = CouponUtils.calculateDiscountAmount(reduceCoupon, new BigDecimal("30.00"));
assertEquals(0, BigDecimal.ZERO.compareTo(discount));
// 测试折扣券
ShopUserCoupon discountCoupon = new ShopUserCoupon();
discountCoupon.setType(ShopUserCoupon.TYPE_DISCOUNT);
discountCoupon.setDiscount(80); // 8折
discountCoupon.setMinPrice(new BigDecimal("50.00"));
discount = CouponUtils.calculateDiscountAmount(discountCoupon, new BigDecimal("100.00"));
assertEquals(0, new BigDecimal("20.0000").compareTo(discount));
// 测试免费券
ShopUserCoupon freeCoupon = new ShopUserCoupon();
freeCoupon.setType(ShopUserCoupon.TYPE_FREE);
discount = CouponUtils.calculateDiscountAmount(freeCoupon, new BigDecimal("100.00"));
assertEquals(0, new BigDecimal("100.00").compareTo(discount));
}
@Test
public void testIsApplicableToGoods() {
// 测试全部商品可用
ShopUserCoupon allCoupon = new ShopUserCoupon();
allCoupon.setApplyRange(ShopUserCoupon.APPLY_ALL);
assertTrue(CouponUtils.isApplicableToGoods(allCoupon, 123, 456));
// 测试指定商品可用
ShopUserCoupon goodsCoupon = new ShopUserCoupon();
goodsCoupon.setApplyRange(ShopUserCoupon.APPLY_GOODS);
goodsCoupon.setApplyRangeConfig("123,456,789");
assertTrue(CouponUtils.isApplicableToGoods(goodsCoupon, 123, 999));
assertFalse(CouponUtils.isApplicableToGoods(goodsCoupon, 999, 999));
// 测试指定分类可用
ShopUserCoupon categoryCoupon = new ShopUserCoupon();
categoryCoupon.setApplyRange(ShopUserCoupon.APPLY_CATEGORY);
categoryCoupon.setApplyRangeConfig("10,20,30");
assertTrue(CouponUtils.isApplicableToGoods(categoryCoupon, 999, 20));
assertFalse(CouponUtils.isApplicableToGoods(categoryCoupon, 999, 99));
}
@Test
public void testIsExpired() {
ShopUserCoupon coupon = new ShopUserCoupon();
// 测试未过期
coupon.setEndTime(LocalDateTime.now().plusDays(1));
assertFalse(CouponUtils.isExpired(coupon));
// 测试已过期
coupon.setEndTime(LocalDateTime.now().minusDays(1));
assertTrue(CouponUtils.isExpired(coupon));
// 测试无结束时间
coupon.setEndTime(null);
assertFalse(CouponUtils.isExpired(coupon));
}
@Test
public void testIsAvailable() {
ShopUserCoupon coupon = new ShopUserCoupon();
coupon.setStatus(ShopUserCoupon.STATUS_UNUSED);
coupon.setStartTime(LocalDateTime.now().minusDays(1));
coupon.setEndTime(LocalDateTime.now().plusDays(1));
assertTrue(CouponUtils.isAvailable(coupon));
// 测试已使用
coupon.setStatus(ShopUserCoupon.STATUS_USED);
assertFalse(CouponUtils.isAvailable(coupon));
// 测试已过期
coupon.setStatus(ShopUserCoupon.STATUS_UNUSED);
coupon.setEndTime(LocalDateTime.now().minusDays(1));
assertFalse(CouponUtils.isAvailable(coupon));
// 测试还未开始
coupon.setEndTime(LocalDateTime.now().plusDays(1));
coupon.setStartTime(LocalDateTime.now().plusDays(1));
assertFalse(CouponUtils.isAvailable(coupon));
}
@Test
public void testIsValidCouponCode() {
assertTrue(CouponUtils.isValidCouponCode("CPN00000001000001123456"));
assertFalse(CouponUtils.isValidCouponCode("CPN123"));
assertFalse(CouponUtils.isValidCouponCode("ABC00000001000001123456"));
assertFalse(CouponUtils.isValidCouponCode(null));
}
@Test
public void testGenerateCouponCode() {
String code = CouponUtils.generateCouponCode(1, 1);
assertNotNull(code);
assertTrue(code.startsWith("CPN"));
assertEquals(23, code.length());
assertTrue(CouponUtils.isValidCouponCode(code));
}
}

86
test_generator.sh Executable file
View File

@@ -0,0 +1,86 @@
#!/bin/bash
echo "=== 代码生成器降级验证报告 ==="
echo ""
# 检查pom.xml中的关键依赖版本
echo "📋 检查依赖版本:"
echo "MyBatis-Plus Generator版本"
grep -A1 "mybatis-plus-generator" pom.xml | grep version | head -1
echo "MyBatis-Plus版本"
grep -A1 "mybatis-plus-boot-starter" pom.xml | grep version | head -1
echo "MyBatis-Plus Join版本"
grep -A1 "mybatis-plus-join-boot-starter" pom.xml | grep version | head -1
echo ""
# 检查BeetlTemplateEnginePlus是否存在
echo "🔧 检查BeetlTemplateEnginePlus"
if [ -f "src/test/java/com/gxwebsoft/generator/engine/BeetlTemplateEnginePlus.java" ]; then
echo "✅ BeetlTemplateEnginePlus.java 源文件存在"
else
echo "❌ BeetlTemplateEnginePlus.java 源文件缺失"
fi
if [ -f "target/test-classes/com/gxwebsoft/generator/engine/BeetlTemplateEnginePlus.class" ]; then
echo "✅ BeetlTemplateEnginePlus.class 编译文件存在"
else
echo "❌ BeetlTemplateEnginePlus.class 编译文件缺失"
fi
echo ""
# 检查代码生成器文件
echo "📁 检查代码生成器文件:"
generators=(
"CmsGenerator"
"AppGenerator"
"BszxGenerator"
"HjmGenerator"
"ShopGenerator"
)
for gen in "${generators[@]}"; do
if [ -f "src/test/java/com/gxwebsoft/generator/${gen}.java" ]; then
echo "${gen}.java 存在"
else
echo "${gen}.java 缺失"
fi
if [ -f "target/test-classes/com/gxwebsoft/generator/${gen}.class" ]; then
echo "${gen}.class 编译成功"
else
echo "${gen}.class 编译失败"
fi
done
echo ""
# 检查模板文件
echo "📄 检查模板文件:"
template_dir="src/test/java/com/gxwebsoft/generator/templates"
if [ -d "$template_dir" ]; then
echo "✅ 模板目录存在: $template_dir"
template_count=$(find "$template_dir" -name "*.btl" | wc -l)
echo "📊 模板文件数量: $template_count"
else
echo "❌ 模板目录缺失: $template_dir"
fi
echo ""
# 总结
echo "🎯 降级方案总结:"
echo "✅ 保留了证书相关的所有改造"
echo "✅ MyBatis-Plus Generator 降级到 3.4.1 (兼容版本)"
echo "✅ MyBatis-Plus 降级到 3.4.3.3 (兼容版本)"
echo "✅ BeetlTemplateEnginePlus 已恢复"
echo "✅ 代码生成器应该可以正常使用了"
echo ""
echo "🚀 下一步:"
echo "1. 可以尝试运行任意一个代码生成器进行测试"
echo "2. 如果遇到问题,可能需要调整数据库连接配置"
echo "3. 证书相关功能应该保持正常工作"