Browse Source

Merge branch 'milestone-20250727-金币重构三期' of http://39.101.133.168:8807/huangqizhen/gold-java into lijianlin/feature-20250728171217-三期金豆消费相关

lijianlin/feature-20250728171217-三期金豆消费相关
lijianlin 2 weeks ago
parent
commit
29055ed4b7
  1. 23
      src/main/java/com/example/demo/Export/RefundConverter.java
  2. 1
      src/main/java/com/example/demo/Mysql/MysqlService.java
  3. 517
      src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java
  4. 21
      src/main/java/com/example/demo/config/Mysql1DataSourceConfig.java
  5. 2
      src/main/java/com/example/demo/controller/coin/RefundController.java
  6. 3
      src/main/java/com/example/demo/domain/vo/coin/ConsumeUser.java
  7. 6
      src/main/java/com/example/demo/domain/vo/coin/GoldDetail.java
  8. 2
      src/main/java/com/example/demo/domain/vo/coin/RechargeUser.java
  9. 2
      src/main/java/com/example/demo/domain/vo/coin/RefundUser.java
  10. 3
      src/main/java/com/example/demo/mapper/coin/ConsumeMapper.java
  11. 3
      src/main/java/com/example/demo/mapper/coin/RechargeMapper.java
  12. 1
      src/main/java/com/example/demo/mapper/coin/RefundMapper.java
  13. 52
      src/main/java/com/example/demo/serviceImpl/coin/RefundServiceImpl.java
  14. 4
      src/main/java/com/example/demo/serviceImpl/coin/RoleServiceImpl.java
  15. 16
      src/main/java/com/example/demo/serviceImpl/coin/StatisticsServiceImpl.java
  16. 1
      src/main/resources/application-prod.yml
  17. 2
      src/main/resources/application.yml
  18. 3
      src/main/resources/mapper/AuditMapper.xml
  19. 3
      src/main/resources/mapper/GoldDetailMapper.xml
  20. 18
      src/main/resources/mapper/RechargeMapper.xml
  21. 10
      src/main/resources/mapper/RefundMapper.xml

23
src/main/java/com/example/demo/Export/RefundConverter.java

@ -0,0 +1,23 @@
package com.example.demo.Export;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
public class RefundConverter implements Converter<Integer> {
@Override
public Class<?> supportJavaTypeKey() {
return Integer.class; // 支持的字段类型
}
@Override
public WriteCellData<?> convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) {
// 0 映射为 "否"1 映射为 "是"
String result = (value != null && value == 1) ? "是" : "否";
return new WriteCellData<>(result);
}
}

1
src/main/java/com/example/demo/Mysql/MysqlService.java

@ -8,5 +8,4 @@ package com.example.demo.Mysql;/**
**/public interface MysqlService { **/public interface MysqlService {
void getSqlserverData() throws Exception; void getSqlserverData() throws Exception;
void getSqlserverData2() throws Exception;
} }

517
src/main/java/com/example/demo/Mysql/MysqlServiceImpl.java

@ -61,24 +61,25 @@ public class MysqlServiceImpl implements MysqlService {
@Override @Override
// @Scheduled(cron = "0 0 * * * ?") // 每小时执行一次
@Transactional(transactionManager = "mysqlTransactionManager") // 👈 保证插入和用户更新在一个事务
public void getSqlserverData() throws Exception { public void getSqlserverData() throws Exception {
logger.info("开始从 SQL Server 同步数据到 MySQL"); logger.info("开始从 SQL Server 同步数据到 MySQL");
try (Connection sqlServerConn = sqlserver1DataSource.getConnection(); try (Connection sqlServerConn = sqlserver1DataSource.getConnection();
Connection mysqlConn = mysql1DataSource.getConnection()) { Connection mysqlConn = mysql1DataSource.getConnection()) {
logger.info("开始查询数据..."); logger.info("开始查询数据...");
// 定义分页参数
int pageSize = 100; int pageSize = 100;
int offset = 0; int offset = 0;
boolean hasMoreData = true; boolean hasMoreData = true;
// 查询 SQL Server 数据的 SQL 语句
// 👇 恢复动态时间查询原注释掉的硬编码时间已移除
String querySql = """ String querySql = """
SELECT SELECT
id, gtype, jwcode, free, core_jb, buy_jb, cz_time, cz_user, cz_bz, operation_platform, goods_name\s
id, gtype, jwcode, free, core_jb, buy_jb, cz_time, cz_user, cz_bz, operation_platform, goods_name
FROM FROM
hwhcGold.dbo.user_gold_records hwhcGold.dbo.user_gold_records
WHERE cz_time > ? WHERE cz_time > ?
@ -87,300 +88,95 @@ public class MysqlServiceImpl implements MysqlService {
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY; OFFSET ? ROWS FETCH NEXT ? ROWS ONLY;
"""; """;
// 插入 MySQL 数据的 SQL 语句
String insertSql = "INSERT IGNORE INTO user_gold_record (order_code, jwcode, sum_gold, permanent_gold, free_june, free_december, " +
"task_gold, pay_platform, goods_name, refund_type, refund_model, remark, type, admin_id, " +
"audit_status, create_time, flag, update_time, audit_time, is_refund,uid) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
String insertSql = """
INSERT IGNORE INTO user_gold_record
(order_code, jwcode, sum_gold, permanent_gold, free_june, free_december,
task_gold, pay_platform, goods_name, refund_type, refund_model, remark, type, admin_id,
audit_status, create_time, flag, update_time, audit_time, is_refund, uid)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""";
while (hasMoreData) { while (hasMoreData) {
try (PreparedStatement sqlServerStmt = sqlServerConn.prepareStatement(querySql)) { try (PreparedStatement sqlServerStmt = sqlServerConn.prepareStatement(querySql)) {
sqlServerStmt.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now().minusHours(1))); // 获取最近一小时的数据
sqlServerStmt.setInt(2, offset); // 设置 OFFSET
sqlServerStmt.setInt(3, pageSize); // 设置 FETCH NEXT
// 👇 恢复动态时间参数
sqlServerStmt.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now().minusHours(1)));
sqlServerStmt.setInt(2, offset);
sqlServerStmt.setInt(3, pageSize);
ResultSet resultSet = sqlServerStmt.executeQuery(); ResultSet resultSet = sqlServerStmt.executeQuery();
// 如果没有数据了退出循环
if (!resultSet.next()) { if (!resultSet.next()) {
hasMoreData = false;
logger.info("无更多数据,offset={}", offset);
break; break;
} }
logger.info("查询到 {} 条数据", pageSize);
// 👇 步骤1收集本批次所有记录
List<RecordData> batchRecords = new ArrayList<>();
List<String> batchUids = new ArrayList<>();
try (PreparedStatement mysqlStmt = mysqlConn.prepareStatement(insertSql)) {
do { do {
int gtype = resultSet.getInt("gtype");
Integer jwcode = resultSet.getInt("jwcode");
int free = resultSet.getInt("free");
int core_jb = resultSet.getInt("core_jb");
int buy_jb = resultSet.getInt("buy_jb");
Timestamp created_at = resultSet.getTimestamp("cz_time");
String name = resultSet.getString("cz_user");
String remark = resultSet.getString("cz_bz");
String operation_platform = resultSet.getString("operation_platform");
String goods_name = resultSet.getString("goods_name");
String uid = resultSet.getString("id");
String timestampPart = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
String orderNumber = UUID.randomUUID().toString().replaceAll("-", "");
RecordData data = extractRecordData(resultSet); // 👈 抽取数据
batchRecords.add(data);
batchUids.add(data.uid);
} while (resultSet.next());
if (StringUtils.isNumeric(name)) {;
System.out.println("name是数字"+ name);
Integer admin_id = Integer.valueOf(adminService.getId(name));
mysqlStmt.setInt(14, admin_id);
} else {
mysqlStmt.setInt(14, 99999);
}
logger.info("本批次共 {} 条记录", batchRecords.size());
// 👇 步骤2批量查询哪些 uid 已存在性能优化
Set<String> existingUids = getExistingUids(mysqlConn, batchUids);
logger.info("已存在记录数: {}", existingUids.size());
Random random = new Random();
int randomNumber = random.nextInt(900) + 100;
// 👇 步骤3准备批量插入
try (PreparedStatement mysqlStmt = mysqlConn.prepareStatement(insertSql)) {
// 根据 gtype 设置不同的值
mysqlStmt.setString(10, null);
mysqlStmt.setNull(11, java.sql.Types.INTEGER);
if (validFourTypes.contains(gtype)) {
for (RecordData data : batchRecords) {
if (validFourTypes.contains(data.gtype)) {
logger.debug("跳过 validFourTypes 类型记录,gtype={}, uid={}", data.gtype, data.uid);
continue; continue;
} }
if (validZeroTypes.contains(gtype)) {
mysqlStmt.setInt(13, 0);
mysqlStmt.setNull(20, java.sql.Types.INTEGER);
mysqlStmt.setString(1, "ERPCZ_" +orderNumber );
}
if (validOneTypes.contains(gtype)) {
mysqlStmt.setInt(13, 1);
mysqlStmt.setInt(20, 0);
mysqlStmt.setString(1, "ERPXF_" + orderNumber);
}
if (validTwoTypes.contains(gtype)) {
mysqlStmt.setInt(13, 2);
mysqlStmt.setInt(20, 0);
mysqlStmt.setString(1, "ERPTK_" +orderNumber);
mysqlStmt.setString(10, "退款商品");
mysqlStmt.setInt(11, 0);
}
if (validThreeTypes.contains(gtype)) {
mysqlStmt.setInt(13, 3);
mysqlStmt.setNull(20, java.sql.Types.INTEGER);
mysqlStmt.setString(1, "ERPQT_" +orderNumber);
if ("4".equals(data.operation_platform)) {
logger.debug("跳过 operation_platform=4 的记录,uid={}", data.uid);
continue;
} }
mysqlStmt.setInt(2, jwcode);
mysqlStmt.setInt(3, free + core_jb + buy_jb);
mysqlStmt.setInt(4, buy_jb);
if (currentMonth.getValue() >= 7) {
mysqlStmt.setInt(6, free);
mysqlStmt.setInt(5, 0);
}
if (currentMonth.getValue() < 7) {
mysqlStmt.setInt(6, 0);
mysqlStmt.setInt(5, free);
}
mysqlStmt.setInt(7, core_jb);
if ("1".equals(operation_platform)) {
mysqlStmt.setString(8, "ERP");
} else if ("2".equals(operation_platform)) {
mysqlStmt.setString(8, "HomilyLink");
} else if ("3".equals(operation_platform)) {
mysqlStmt.setString(8, "HomilyChart");
} else if ("4".equals(operation_platform)) {
// 👇 跳过已存在的记录避免重复更新用户余额
if (existingUids.contains(data.uid)) {
logger.debug("跳过重复记录,uid={}", data.uid);
continue; continue;
} else if ("0".equals(operation_platform)) {
mysqlStmt.setString(8, "初始化金币");
} else {
mysqlStmt.setString(8, "其他");
}
mysqlStmt.setString(9, goods_name);
mysqlStmt.setString(12, remark);
mysqlStmt.setInt(15, 3);
mysqlStmt.setTimestamp(16, created_at);
if (remark != null && remark.contains("测试") && remark.contains("员工")) {
mysqlStmt.setInt(17, 0);
} else {
mysqlStmt.setInt(17, 1);
} }
mysqlStmt.setTimestamp(18, created_at);
mysqlStmt.setTimestamp(19, created_at);
mysqlStmt.setString(21, uid);
mysqlStmt.addBatch();
// 更新用户信息逻辑
logger.info("查询用户是否存在");
User user = userService.selectAllUser(String.valueOf(jwcode));
if (ObjectUtils.isEmpty(user)) {
logger.info("用户不存在");
user = new User();
List<String> country = Collections.singletonList("未知");
BaseDES des = new BaseDES();
String desjwcode = des.encrypt(String.valueOf(jwcode));
// 👇 设置插入参数
setStatementParams(mysqlStmt, data);
// 创建 JSON 请求体
Map<String, String> requestBody = new HashMap<>();
requestBody.put("jwcode", desjwcode);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 创建 HttpEntity
HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestBody, headers);
// 发送 POST 请求
try {
ResponseEntity<Map> response = restTemplate.exchange(
"http://hwapi.rzfwq.com/hwjnApp/hwhc-login/hwhclogin/hc/login/clent/info",
HttpMethod.POST, entity, Map.class);
mysqlStmt.addBatch();
// 检查响应状态码
if (response.getStatusCode().is2xxSuccessful()) {
Map<String, Object> responseBody = response.getBody();
if (responseBody != null) {
// 获取 data 部分
Map<String, Object> data = (Map<String, Object>) responseBody.get("data");
if (data != null) {
// 提取 name country
name = (String) data.get("name");
country = (List<String>) data.get("country");
// 打印获取到的数据
System.out.println("Name: " + name);
System.out.println("Country: " + country);
} else {
System.out.println("Data is null");
}
} else {
System.out.println("Response body is null");
}
} else {
System.out.println("Request failed with status code: " + response.getStatusCode());
}
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
// 设置默认的 country
country = Collections.singletonList("未知");
// 👇 只有新记录才更新用户余额关键修复
updateUserBalance(mysqlConn, data);
} }
String market = String.join(",", marketService.getMarketIds(country));
user.setJwcode(jwcode);
user.setName(name);
user.setMarket(market);
logger.info("新添用户");
userService.addUser(user);
logger.info("用户添加成功");
user = userService.selectAllUser(String.valueOf(jwcode));
// 👇 执行批量插入
int[] results = mysqlStmt.executeBatch();
logger.info("成功插入新记录 {} 条", results.length);
} }
if (currentMonth.getValue() >= 7) {
if (user.getCurrentFreeJune().add(BigDecimal.valueOf(free)).compareTo(BigDecimal.ZERO) >= 0) {
user.setCurrentFreeJune(user.getCurrentFreeJune().add(BigDecimal.valueOf(free)));
} else {
BigDecimal remaining = user.getCurrentFreeJune().add(BigDecimal.valueOf(free));
user.setCurrentFreeJune(BigDecimal.ZERO);
user.setCurrentFreeDecember(user.getCurrentFreeDecember().add(remaining));
}
}
if (currentMonth.getValue() < 7) {
if (user.getCurrentFreeDecember().add(BigDecimal.valueOf(free)).compareTo(BigDecimal.ZERO) >= 0) {
user.setCurrentFreeDecember(user.getCurrentFreeDecember().add(BigDecimal.valueOf(free)));
} else {
BigDecimal remaining = user.getCurrentFreeDecember().add(BigDecimal.valueOf(free));
user.setCurrentFreeDecember(BigDecimal.ZERO);
user.setCurrentFreeJune(remaining);
}
}
user.setCurrentPermanentGold(user.getCurrentPermanentGold().add(BigDecimal.valueOf(buy_jb)));
user.setCurrentTaskGold(user.getCurrentTaskGold().add(BigDecimal.valueOf(core_jb)));
if (validZeroTypes.contains(gtype)) {
user.setRechargeNum(user.getRechargeNum() + 1);
user.setSumPermanentGold(user.getSumPermanentGold().add(BigDecimal.valueOf(buy_jb)));
user.setSumTaskGold(user.getSumTaskGold().add(BigDecimal.valueOf(core_jb)));
if (currentMonth.getValue() >= 7) {
user.setSumFreeJune(user.getSumFreeJune().add(BigDecimal.valueOf(free)));
}
if (currentMonth.getValue() < 7) {
user.setSumFreeDecember(user.getSumFreeDecember().add(BigDecimal.valueOf(free)));
}
}
if (validOneTypes.contains(gtype)) {
user.setConsumeNum(user.getConsumeNum() + 1);
user.setSumConsumePermanent(user.getSumConsumePermanent().add(BigDecimal.valueOf(buy_jb)));
user.setSumConsumeTask(user.getSumConsumeTask().add(BigDecimal.valueOf(core_jb)));
user.setSumConsumeFree(user.getSumConsumeFree().add(BigDecimal.valueOf(free)));
}
userService.updateAllGold(user);
} while (resultSet.next());
// 批量插入 MySQL
mysqlStmt.executeBatch();
logger.info("已成功插入 {} 条数据", pageSize);
}
}
// 更新分页参数
offset += pageSize; offset += pageSize;
} }
}
logger.info("数据同步完成");
logger.info("✅ 数据同步完成");
} catch (SQLException e) { } catch (SQLException e) {
logger.error("数据连接失败", e.getMessage());
throw new RuntimeException("数据链接失败", e);
logger.error("数据库操作失败", e);
throw new RuntimeException("同步失败", e);
} }
} }
@Override
public void getSqlserverData2() throws Exception {
logger.info("开始从 MySQL 同步数据到 MySQL(分页处理)");
Timestamp startTime = Timestamp.valueOf(LocalDateTime.now().minusHours(1));
int pageSize = 100;
int pageNumber = 0;
int totalProcessed = 0;
try (
Connection sourceConn = sqlserver1DataSource.getConnection();
Connection targetConn = mysql1DataSource.getConnection()
) {
// 关闭自动提交手动控制事务
targetConn.setAutoCommit(false);
// 分页查询 SQLMySQL 使用 LIMIT offset, size
String querySql = """
SELECT gtype, jwcode, free, core_jb, buy_jb, cz_time, cz_user, cz_bz, operation_platform, goods_name,flag
FROM user_gold_records
where cz_time >'2025-08-10 07:11:04'
ORDER BY cz_time ASC
LIMIT ? OFFSET ?
""";
String insertSql = """
INSERT INTO user_gold_record
(order_code, jwcode, sum_gold, permanent_gold, free_june, free_december,
task_gold, pay_platform, goods_name, refund_type, refund_model, remark, type, admin_id,
audit_status, create_time, flag, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""";
try (
PreparedStatement queryStmt = sourceConn.prepareStatement(querySql);
PreparedStatement insertStmt = targetConn.prepareStatement(insertSql)
) {
while (true) {
int offset = pageNumber * pageSize;
queryStmt.setInt(1, pageSize);
queryStmt.setInt(2, offset);
List<RecordData> batchData = new ArrayList<>();
try (ResultSet rs = queryStmt.executeQuery()) {
boolean hasData = false;
while (rs.next()) {
hasData = true;
static class RecordData {
int gtype, jwcode, free, core_jb, buy_jb;
Timestamp cz_time;
String cz_user, cz_bz, operation_platform, goods_name, uid;
String orderNumber; // 预生成避免重复计算
}
private RecordData extractRecordData(ResultSet rs) throws SQLException {
RecordData data = new RecordData(); RecordData data = new RecordData();
data.gtype = rs.getInt("gtype"); data.gtype = rs.getInt("gtype");
data.jwcode = rs.getInt("jwcode"); data.jwcode = rs.getInt("jwcode");
@ -392,106 +188,82 @@ public class MysqlServiceImpl implements MysqlService {
data.cz_bz = rs.getString("cz_bz"); data.cz_bz = rs.getString("cz_bz");
data.operation_platform = rs.getString("operation_platform"); data.operation_platform = rs.getString("operation_platform");
data.goods_name = rs.getString("goods_name"); data.goods_name = rs.getString("goods_name");
data.uid = rs.getString("id");
batchData.add(data);
}
// 预生成订单号避免在循环中重复生成
String timestampPart = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
String uuidPart = UUID.randomUUID().toString().replaceAll("-", "");
data.orderNumber = timestampPart + "_" + uuidPart;
if (!hasData || batchData.isEmpty()) {
logger.info("无更多数据可同步,共处理 {} 条", totalProcessed);
break;
}
return data;
} }
// 清空上一批
insertStmt.clearBatch();
private Set<String> getExistingUids(Connection conn, List<String> uids) throws SQLException {
if (uids.isEmpty()) return Collections.emptySet();
// 处理当前批次100条以内
for (RecordData data : batchData) {
buildInsertStatement(insertStmt, data);
insertStmt.addBatch();
}
// 执行批量插入
insertStmt.executeBatch();
targetConn.commit();
totalProcessed += batchData.size();
logger.info("第 {} 页,插入 {} 条记录,累计 {}", pageNumber, batchData.size(), totalProcessed);
String placeholders = String.join(",", Collections.nCopies(uids.size(), "?"));
String sql = "SELECT uid FROM user_gold_record WHERE uid IN (" + placeholders + ")";
// 更新用户信息可优化为批量
for (RecordData data : batchData) {
updateUserGold(data);
Set<String> existing = new HashSet<>();
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
for (int i = 0; i < uids.size(); i++) {
stmt.setString(i + 1, uids.get(i));
} }
pageNumber++;
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
existing.add(rs.getString("uid"));
} }
} catch (Exception e) {
targetConn.rollback();
logger.error("同步批次失败,事务回滚", e);
throw e;
} }
logger.info("✅ 数据同步完成,共处理 {} 条记录", totalProcessed);
} catch (SQLException e) {
logger.error("数据库连接或操作失败", e);
throw new RuntimeException("MySQL 同步失败", e);
} }
return existing;
} }
private void setStatementParams(PreparedStatement stmt, RecordData data) throws SQLException {
String name = data.cz_user;
// 封装插入逻辑
private void buildInsertStatement(PreparedStatement stmt, RecordData data) throws SQLException {
String timestampPart = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
Random random = new Random();
int randomNumber = random.nextInt(900) + 100;
// admin_id
String czUser = data.cz_user;
// 1. 先判空
if (czUser != null && StringUtils.isNumeric(czUser)) {
// 设置 admin_id
if (StringUtils.isNumeric(name)) {
try { try {
// 2. 调用服务获取 ID
String adminIdStr = adminService.getId(czUser); // 可能返回 null 或字符串
// 3. 再次判空并转为 Integer
String adminIdStr = adminService.getId(name);
if (adminIdStr != null && StringUtils.isNumeric(adminIdStr)) { if (adminIdStr != null && StringUtils.isNumeric(adminIdStr)) {
Integer admin_id = Integer.parseInt(adminIdStr); // 安全转换
stmt.setInt(14, admin_id);
stmt.setInt(14, Integer.parseInt(adminIdStr));
} else { } else {
// adminService 返回 null 或非数字视为无效 admin
stmt.setInt(14, 99999); stmt.setInt(14, 99999);
} }
} catch (Exception e) { } catch (Exception e) {
// 防御性兜底
logger.warn("解析 admin_id 失败,cz_user={}", czUser, e);
logger.warn("解析 admin_id 失败,cz_user={}", name, e);
stmt.setInt(14, 99999); stmt.setInt(14, 99999);
} }
} else { } else {
// cz_user null 或非数字
stmt.setInt(14, 99999); stmt.setInt(14, 99999);
} }
// refund_type, refund_model
stmt.setString(10, null); stmt.setString(10, null);
stmt.setNull(11, Types.INTEGER); stmt.setNull(11, Types.INTEGER);
// 根据 gtype 设置 type order_code
if (validFourTypes.contains(data.gtype)) { if (validFourTypes.contains(data.gtype)) {
return; // 跳过
throw new IllegalArgumentException("不应处理 validFourTypes 类型,应在上层过滤"); // 安全兜底
} }
if (validZeroTypes.contains(data.gtype)) { if (validZeroTypes.contains(data.gtype)) {
stmt.setInt(13, 0); stmt.setInt(13, 0);
stmt.setString(1, "ERPCZ" + timestampPart + randomNumber);
stmt.setNull(20, Types.INTEGER);
stmt.setString(1, "ERPCZ_" + data.orderNumber);
} else if (validOneTypes.contains(data.gtype)) { } else if (validOneTypes.contains(data.gtype)) {
stmt.setInt(13, 1); stmt.setInt(13, 1);
stmt.setString(1, "ERPXF" + timestampPart + randomNumber);
stmt.setInt(20, 0);
stmt.setString(1, "ERPXF_" + data.orderNumber);
} else if (validTwoTypes.contains(data.gtype)) { } else if (validTwoTypes.contains(data.gtype)) {
stmt.setInt(13, 2); stmt.setInt(13, 2);
stmt.setString(1, "ERPTK" + timestampPart + randomNumber);
stmt.setInt(20, 0);
stmt.setString(1, "ERPTK_" + data.orderNumber);
stmt.setString(10, "退款商品"); stmt.setString(10, "退款商品");
stmt.setInt(11, 0); stmt.setInt(11, 0);
} else if (validThreeTypes.contains(data.gtype)) { } else if (validThreeTypes.contains(data.gtype)) {
stmt.setInt(13, 3); stmt.setInt(13, 3);
stmt.setString(1, "ERPQT" + timestampPart + randomNumber);
stmt.setNull(20, Types.INTEGER);
stmt.setString(1, "ERPQT_" + data.orderNumber);
} }
stmt.setInt(2, data.jwcode); stmt.setInt(2, data.jwcode);
@ -508,6 +280,7 @@ public class MysqlServiceImpl implements MysqlService {
stmt.setInt(7, data.core_jb); stmt.setInt(7, data.core_jb);
// pay_platform
String platform = data.operation_platform; String platform = data.operation_platform;
if ("1".equals(platform)) { if ("1".equals(platform)) {
stmt.setString(8, "ERP"); stmt.setString(8, "ERP");
@ -516,7 +289,7 @@ public class MysqlServiceImpl implements MysqlService {
} else if ("3".equals(platform)) { } else if ("3".equals(platform)) {
stmt.setString(8, "HomilyChart"); stmt.setString(8, "HomilyChart");
} else if ("4".equals(platform)) { } else if ("4".equals(platform)) {
return; // 跳过这条数据
throw new IllegalArgumentException("不应处理 platform=4,应在上层过滤");
} else if ("0".equals(platform)) { } else if ("0".equals(platform)) {
stmt.setString(8, "初始化金币"); stmt.setString(8, "初始化金币");
} else { } else {
@ -527,69 +300,63 @@ public class MysqlServiceImpl implements MysqlService {
stmt.setString(12, data.cz_bz); stmt.setString(12, data.cz_bz);
stmt.setInt(15, 3); stmt.setInt(15, 3);
stmt.setTimestamp(16, data.cz_time); stmt.setTimestamp(16, data.cz_time);
stmt.setInt(17, data.flag);
if (data.cz_bz != null && data.cz_bz.contains("测试") && data.cz_bz.contains("员工")) {
stmt.setInt(17, 0);
} else {
stmt.setInt(17, 1);
}
stmt.setTimestamp(18, data.cz_time); stmt.setTimestamp(18, data.cz_time);
stmt.setTimestamp(19, data.cz_time);
stmt.setString(21, data.uid);
} }
// 更新用户金币逻辑
private void updateUserGold(RecordData data) throws Exception {
private void updateUserBalance(Connection conn, RecordData data) throws Exception {
logger.info("处理用户余额更新,jwcode={}", data.jwcode);
User user = userService.selectAllUser(String.valueOf(data.jwcode)); User user = userService.selectAllUser(String.valueOf(data.jwcode));
BigDecimal freeBD = BigDecimal.valueOf(data.free); BigDecimal freeBD = BigDecimal.valueOf(data.free);
BigDecimal buyJbBD = BigDecimal.valueOf(data.buy_jb); BigDecimal buyJbBD = BigDecimal.valueOf(data.buy_jb);
BigDecimal coreJbBD = BigDecimal.valueOf(data.core_jb); BigDecimal coreJbBD = BigDecimal.valueOf(data.core_jb);
if (ObjectUtils.isEmpty(user)) { if (ObjectUtils.isEmpty(user)) {
logger.info("用户不存在");
logger.info("用户不存在,jwcode={}", data.jwcode);
user = new User(); user = new User();
List<String> country = Collections.singletonList("未知"); List<String> country = Collections.singletonList("未知");
String name = "未知"; String name = "未知";
try {
BaseDES des = new BaseDES(); BaseDES des = new BaseDES();
String desjwcode = des.encrypt(String.valueOf(data.jwcode)); String desjwcode = des.encrypt(String.valueOf(data.jwcode));
// System.out.println("desjwcode:"+desjwcode);
// 创建 JSON 请求体
Map<String, String> requestBody = new HashMap<>(); Map<String, String> requestBody = new HashMap<>();
requestBody.put("jwcode", desjwcode); requestBody.put("jwcode", desjwcode);
// 设置请求头
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
// 创建 HttpEntity
HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestBody, headers); HttpEntity<Map<String, String>> entity = new HttpEntity<>(requestBody, headers);
// 发送 POST 请求
try {
ResponseEntity<Map> response = restTemplate.exchange( ResponseEntity<Map> response = restTemplate.exchange(
"http://hwapi.rzfwq.com/hwjnApp/hwhc-login/hwhclogin/hc/login/clent/info", "http://hwapi.rzfwq.com/hwjnApp/hwhc-login/hwhclogin/hc/login/clent/info",
HttpMethod.POST, entity, Map.class); HttpMethod.POST, entity, Map.class);
// 检查响应状态码
if (response.getStatusCode().is2xxSuccessful()) { if (response.getStatusCode().is2xxSuccessful()) {
Map<String, Object> responseBody = response.getBody(); Map<String, Object> responseBody = response.getBody();
if (responseBody != null) { if (responseBody != null) {
// 获取data部分
Map<String, Object> data1 = (Map<String, Object>) responseBody.get("data");
if (data1 != null) {
// 提取name和country
name = (String) data1.get("name");
country = (List<String>) data1.get("country");
// 打印获取到的数据
System.out.println("Name: " + name);
System.out.println("Country: " + country);
} else {
System.out.println("Data is null");
Map<String, Object> dataMap = (Map<String, Object>) responseBody.get("data");
if (dataMap != null) {
name = (String) dataMap.get("name");
Object countryObj = dataMap.get("country");
if (countryObj instanceof List) {
country = (List<String>) countryObj;
}
logger.info("获取用户信息成功: name={}, country={}", name, country);
} }
} else {
System.out.println("Response body is null");
} }
} else {
System.out.println("Request failed with status code: " + response.getStatusCode());
} }
} catch (Exception e) { } catch (Exception e) {
System.out.println("Error: " + e.getMessage());
// 设置默认的 country
logger.warn("获取用户信息失败,jwcode={}", data.jwcode, e);
country = Collections.singletonList("未知"); country = Collections.singletonList("未知");
} }
@ -597,20 +364,38 @@ public class MysqlServiceImpl implements MysqlService {
user.setJwcode(data.jwcode); user.setJwcode(data.jwcode);
user.setName(name); user.setName(name);
user.setMarket(market); user.setMarket(market);
logger.info("新添用户");
userService.addUser(user); userService.addUser(user);
logger.info("用户添加成功");
logger.info("用户创建成功,jwcode={}", data.jwcode);
// 重新查询确保数据完整
user = userService.selectAllUser(String.valueOf(data.jwcode)); user = userService.selectAllUser(String.valueOf(data.jwcode));
} }
// 更新当前金币
if (currentMonth.getValue() >= 7) { if (currentMonth.getValue() >= 7) {
user.setCurrentFreeJune(user.getCurrentFreeJune().add(freeBD));
BigDecimal newFreeJune = user.getCurrentFreeJune().add(freeBD);
if (newFreeJune.compareTo(BigDecimal.ZERO) >= 0) {
user.setCurrentFreeJune(newFreeJune);
} else { } else {
user.setCurrentFreeDecember(user.getCurrentFreeDecember().add(freeBD));
BigDecimal remaining = newFreeJune;
user.setCurrentFreeJune(BigDecimal.ZERO);
user.setCurrentFreeDecember(user.getCurrentFreeDecember().add(remaining));
}
} else {
BigDecimal newFreeDec = user.getCurrentFreeDecember().add(freeBD);
if (newFreeDec.compareTo(BigDecimal.ZERO) >= 0) {
user.setCurrentFreeDecember(newFreeDec);
} else {
BigDecimal remaining = newFreeDec;
user.setCurrentFreeDecember(BigDecimal.ZERO);
user.setCurrentFreeJune(remaining);
}
} }
user.setCurrentPermanentGold(user.getCurrentPermanentGold().add(buyJbBD)); user.setCurrentPermanentGold(user.getCurrentPermanentGold().add(buyJbBD));
user.setCurrentTaskGold(user.getCurrentTaskGold().add(coreJbBD)); user.setCurrentTaskGold(user.getCurrentTaskGold().add(coreJbBD));
// 更新统计字段
if (validZeroTypes.contains(data.gtype)) { if (validZeroTypes.contains(data.gtype)) {
user.setRechargeNum(user.getRechargeNum() + 1); user.setRechargeNum(user.getRechargeNum() + 1);
user.setSumPermanentGold(user.getSumPermanentGold().add(buyJbBD)); user.setSumPermanentGold(user.getSumPermanentGold().add(buyJbBD));
@ -628,12 +413,16 @@ public class MysqlServiceImpl implements MysqlService {
} }
userService.updateAllGold(user); userService.updateAllGold(user);
logger.info("用户余额更新成功,jwcode={}", data.jwcode);
}
private boolean checkRecordExists(Connection conn, String uid) throws SQLException {
String sql = "SELECT 1 FROM user_gold_record WHERE uid = ? LIMIT 1";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setString(1, uid);
try (ResultSet rs = stmt.executeQuery()) {
return rs.next();
} }
// 内部类封装查询结果
static class RecordData {
int gtype, jwcode, free, core_jb, buy_jb, flag;
Timestamp cz_time;
String cz_user, cz_bz, operation_platform, goods_name;
} }
} }
}

21
src/main/java/com/example/demo/config/Mysql1DataSourceConfig.java

@ -11,6 +11,8 @@ import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -21,7 +23,24 @@ public class Mysql1DataSourceConfig {
@Bean(name = "mysql1DataSource") @Bean(name = "mysql1DataSource")
@ConfigurationProperties(prefix = "spring.datasource.mysql1") @ConfigurationProperties(prefix = "spring.datasource.mysql1")
public DataSource mysql1DataSource() { public DataSource mysql1DataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
// 1. 先用 builder 创建出来
HikariDataSource ds = DataSourceBuilder
.create()
.type(HikariDataSource.class)
.build(); // 这里已经把 yml 里的 url/username/password 装好了
// 2. 再补连接初始化 SQL每次拿到连接自动执行
ds.setConnectionInitSql(
"SET SESSION profiling=0,long_query_time=10,sql_mode='TRADITIONAL';");
// 3. 如有需要还可继续补 ds.setMaximumPoolSize()
return ds;
// return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
@Bean(name = "mysqlTransactionManager")
public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysql1DataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} }
@Bean(name = "mysql1SqlSessionFactory") @Bean(name = "mysql1SqlSessionFactory")
// @Primary // @Primary

2
src/main/java/com/example/demo/controller/coin/RefundController.java

@ -135,6 +135,7 @@ public class RefundController {
try { try {
return refundService.add(refundUser); return refundService.add(refundUser);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
return Result.error("请检查数据的格式"); return Result.error("请检查数据的格式");
} }
} }
@ -150,6 +151,7 @@ public class RefundController {
return Result.success(refundService.selectBy(page.getPageNum(), page.getPageSize(), page.getRefundUser())); return Result.success(refundService.selectBy(page.getPageNum(), page.getPageSize(), page.getRefundUser()));
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
return Result.error("请检查筛选数据的格式"); return Result.error("请检查筛选数据的格式");
} }

3
src/main/java/com/example/demo/domain/vo/coin/ConsumeUser.java

@ -2,6 +2,7 @@ package com.example.demo.domain.vo.coin;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.example.demo.Export.RefundConverter;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.validation.constraints.PositiveOrZero; import jakarta.validation.constraints.PositiveOrZero;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -56,7 +57,7 @@ public class ConsumeUser implements Serializable {
private Integer adminId; //提交人Id private Integer adminId; //提交人Id
@ExcelProperty("提交人") @ExcelProperty("提交人")
private String adminName; //提交人姓名 private String adminName; //提交人姓名
@ExcelProperty("是否退款 0-否 1-是")
@ExcelProperty(value = "是否退款", converter = RefundConverter.class)
private Integer isRefund; //是否退款 private Integer isRefund; //是否退款
@ExcelProperty("消耗时间") @ExcelProperty("消耗时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")

6
src/main/java/com/example/demo/domain/vo/coin/GoldDetail.java

@ -67,5 +67,11 @@ public class GoldDetail {
private List<String> markets; private List<String> markets;
@ExcelIgnore @ExcelIgnore
private Integer flag;// 是否为员工号 0员工号 1非员工号 private Integer flag;// 是否为员工号 0员工号 1非员工号
@ExcelIgnore
private String orderCode;
@ExcelIgnore
private Integer isRefund;
@ExcelIgnore
private String goodsName;
} }

2
src/main/java/com/example/demo/domain/vo/coin/RechargeUser.java

@ -59,6 +59,8 @@ public class RechargeUser {
@ExcelProperty("充值平台") @ExcelProperty("充值平台")
private String payPlatform; // 充值方式 private String payPlatform; // 充值方式
@ExcelProperty("是否已退款 0-未退款,1-已退款")
private Integer isRefund; //是否已退款
@ExcelIgnore @ExcelIgnore
private String voucher; // 支付凭证 private String voucher; // 支付凭证

2
src/main/java/com/example/demo/domain/vo/coin/RefundUser.java

@ -79,4 +79,6 @@ public class RefundUser {
private Integer flag; //是否为员工号 private Integer flag; //是否为员工号
@ExcelIgnore @ExcelIgnore
private Integer type; private Integer type;
@ExcelIgnore
private Integer isRefund;
} }

3
src/main/java/com/example/demo/mapper/coin/ConsumeMapper.java

@ -3,6 +3,7 @@ package com.example.demo.mapper.coin;
import com.example.demo.domain.entity.UserGoldRecord; import com.example.demo.domain.entity.UserGoldRecord;
import com.example.demo.domain.vo.coin.ConsumeUser; import com.example.demo.domain.vo.coin.ConsumeUser;
import com.example.demo.domain.vo.coin.Gold; import com.example.demo.domain.vo.coin.Gold;
import com.example.demo.domain.vo.coin.RefundUser;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List; import java.util.List;
@ -36,7 +37,7 @@ public interface ConsumeMapper {
void updateIsRefund(String orderCode); void updateIsRefund(String orderCode);
//获得订单号 //获得订单号
List<ConsumeUser> selectOrderCodeByJwcode(String jwcode,String orderCode);
List<ConsumeUser> selectOrderCodeByJwcode(RefundUser refundUser);
void updateUserGold(UserGoldRecord userGoldRecord); void updateUserGold(UserGoldRecord userGoldRecord);

3
src/main/java/com/example/demo/mapper/coin/RechargeMapper.java

@ -2,6 +2,7 @@ package com.example.demo.mapper.coin;
import com.example.demo.domain.entity.UserGoldRecord; import com.example.demo.domain.entity.UserGoldRecord;
import com.example.demo.domain.vo.coin.ConsumeUser;
import com.example.demo.domain.vo.coin.Gold; import com.example.demo.domain.vo.coin.Gold;
import com.example.demo.domain.vo.coin.RechargeUser; import com.example.demo.domain.vo.coin.RechargeUser;
import com.example.demo.domain.vo.coin.RefundUser; import com.example.demo.domain.vo.coin.RefundUser;
@ -28,4 +29,6 @@ public interface RechargeMapper {
void add(UserGoldRecord userGoldRecord); void add(UserGoldRecord userGoldRecord);
Gold sumGold(RechargeUser rechargeUser); Gold sumGold(RechargeUser rechargeUser);
List<RechargeUser> selectOrderCodeByJwcode(RefundUser refundUser);
} }

1
src/main/java/com/example/demo/mapper/coin/RefundMapper.java

@ -26,6 +26,7 @@ public interface RefundMapper {
//获取筛选后的订单 //获取筛选后的订单
List<RefundUser> selectBy(RefundUser refundUser); List<RefundUser> selectBy(RefundUser refundUser);
//添加退款订单 //添加退款订单
void add(UserGoldRecord userGoldRecord); void add(UserGoldRecord userGoldRecord);

52
src/main/java/com/example/demo/serviceImpl/coin/RefundServiceImpl.java

@ -1,10 +1,7 @@
package com.example.demo.serviceImpl.coin; package com.example.demo.serviceImpl.coin;
import com.example.demo.domain.entity.UserGoldRecord; import com.example.demo.domain.entity.UserGoldRecord;
import com.example.demo.mapper.coin.ConsumeMapper;
import com.example.demo.mapper.coin.MarketMapper;
import com.example.demo.mapper.coin.RefundMapper;
import com.example.demo.mapper.coin.UserMapper;
import com.example.demo.mapper.coin.*;
import com.example.demo.service.coin.MarketService; import com.example.demo.service.coin.MarketService;
import com.example.demo.service.coin.RefundService; import com.example.demo.service.coin.RefundService;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
@ -46,6 +43,8 @@ public class RefundServiceImpl implements RefundService {
@Autowired @Autowired
private MarketMapper marketMapper; private MarketMapper marketMapper;
@Autowired
private RechargeMapper rechargeMapper;
//查找全部退款 //查找全部退款
@Override @Override
@ -102,13 +101,15 @@ public class RefundServiceImpl implements RefundService {
return Result.error("用户不存在"); return Result.error("用户不存在");
} }
UserGoldRecord userGoldRecord = new UserGoldRecord(); UserGoldRecord userGoldRecord = new UserGoldRecord();
if(refundUser.getGoodsName()==null|| refundUser.getGoodsName().isEmpty()){
return Result.error("商品名称不能为空");
}
if(refundUser.getOrderCode()==null|| refundUser.getOrderCode().isEmpty()){ if(refundUser.getOrderCode()==null|| refundUser.getOrderCode().isEmpty()){
return Result.error("订单号不能为空"); return Result.error("订单号不能为空");
} }
String goodsName = refundUser.getGoodsName();
String goodsName = "";
if(refundUser.getGoodsName()==null|| refundUser.getGoodsName().isEmpty()){
goodsName = "空";
}else {
goodsName = refundUser.getGoodsName();
}
String orderCode = refundUser.getOrderCode(); String orderCode = refundUser.getOrderCode();
userGoldRecord.setGoodsName(goodsName); // 商品A userGoldRecord.setGoodsName(goodsName); // 商品A
userGoldRecord.setOrderCode("TK_" + orderCode); // TKXF202506281545524400006580 userGoldRecord.setOrderCode("TK_" + orderCode); // TKXF202506281545524400006580
@ -173,18 +174,34 @@ public class RefundServiceImpl implements RefundService {
userGoldRecord.setType((byte) 2); userGoldRecord.setType((byte) 2);
userGoldRecord.setAuditStatus(0); userGoldRecord.setAuditStatus(0);
userGoldRecord.setCreateTime(new Date()); userGoldRecord.setCreateTime(new Date());
List<ConsumeUser> list = consumeMapper.selectOrderCodeByJwcode(userGoldRecord.getJwcode().toString(), orderCode);
userGoldRecord.setUpdateTime(new Date());
List<ConsumeUser> list1 = consumeMapper.selectOrderCodeByJwcode(refundUser);
List<RechargeUser> list2 = rechargeMapper.selectOrderCodeByJwcode(refundUser);
if(Objects.equals(refundUser.getRefundType(), "商品退款")){
//消费订单号校验 //消费订单号校验
if (list == null || list.isEmpty()) {
if (list1 == null || list1.isEmpty()) {
return Result.error("该用户没有该订单号"); return Result.error("该用户没有该订单号");
} else if (list.size() == 1) {
ConsumeUser consumeUser = list.getFirst();
} else if (list1.size() == 1) {
ConsumeUser consumeUser = list1.getFirst();
if (consumeUser.getIsRefund().equals(1)) { if (consumeUser.getIsRefund().equals(1)) {
return Result.error("该订单已被退款");
return Result.error("该订单已被退款或待审核");
} }
} else { } else {
return Result.error("订单重复"); return Result.error("订单重复");
} }
}else{
//充值订单号校验
if (list2 == null || list2.isEmpty()) {
return Result.error("该用户没有该订单号");
} else if (list2.size() == 1) {
RechargeUser rechargeUser = list2.getFirst();
if (rechargeUser.getIsRefund().equals(1)) {
return Result.error("该订单已被退款或待审核");
}
} else {
return Result.error("订单重复");
}
}
refundMapper.add(userGoldRecord); refundMapper.add(userGoldRecord);
consumeMapper.updateIsRefund(orderCode); consumeMapper.updateIsRefund(orderCode);
return Result.success(); return Result.success();
@ -214,15 +231,22 @@ public class RefundServiceImpl implements RefundService {
String orderCode = record.getOrderCode() != null ? record.getOrderCode() : "无订单号"; String orderCode = record.getOrderCode() != null ? record.getOrderCode() : "无订单号";
String goodsName = record.getGoodsName() != null ? record.getGoodsName() : "无商品名"; String goodsName = record.getGoodsName() != null ? record.getGoodsName() : "无商品名";
BigDecimal permanentGold = record.getPermanentGold() != null ? record.getPermanentGold() : BigDecimal.ZERO;
BigDecimal freeGold = record.getFreeGold() != null ? record.getFreeGold() : BigDecimal.ZERO;
BigDecimal taskGold = record.getTaskGold() != null ? record.getTaskGold() : BigDecimal.ZERO;
// 计算总和
// 拼接格式订单号_商品名例如XF20250629_商品BC // 拼接格式订单号_商品名例如XF20250629_商品BC
String combined = orderCode + "_" + goodsName; String combined = orderCode + "_" + goodsName;
RefundUser newRefundUser = new RefundUser(); RefundUser newRefundUser = new RefundUser();
newRefundUser.setOrderCode(orderCode); newRefundUser.setOrderCode(orderCode);
newRefundUser.setGoodsName(goodsName); newRefundUser.setGoodsName(goodsName);
newRefundUser.setSumGold(record.getPermanentGold().add(record.getFreeGold()).add(record.getTaskGold()));
newRefundUser.setSumGold(permanentGold.add(freeGold).add(taskGold));
newRefundUser.setPermanentGold(record.getPermanentGold()); newRefundUser.setPermanentGold(record.getPermanentGold());
newRefundUser.setFreeGold(record.getFreeGold()); newRefundUser.setFreeGold(record.getFreeGold());
newRefundUser.setTaskGold(record.getTaskGold()); newRefundUser.setTaskGold(record.getTaskGold());
newRefundUser.setIsRefund(record.getIsRefund());
newRefundUser.setType(record.getType());
list.add(newRefundUser); list.add(newRefundUser);
} }
return list; return list;

4
src/main/java/com/example/demo/serviceImpl/coin/RoleServiceImpl.java

@ -68,7 +68,7 @@ public class RoleServiceImpl implements RoleService {
if (roleVo.getFatherId() == null || roleVo.getFatherId() != 2) { if (roleVo.getFatherId() == null || roleVo.getFatherId() != 2) {
for (Integer menuId : roleVo.getMenuIds()) { for (Integer menuId : roleVo.getMenuIds()) {
if (menuId == 9) {
if (menuId == 11) {
return Result.error("上级角色非管理员用户不能赋予权限管理"); return Result.error("上级角色非管理员用户不能赋予权限管理");
} }
} }
@ -144,7 +144,7 @@ public class RoleServiceImpl implements RoleService {
if (roleVo.getFatherId() != null) { if (roleVo.getFatherId() != null) {
if (roleVo.getFatherId() != 2) { if (roleVo.getFatherId() != 2) {
for (Integer menuId : roleVo.getMenuIds()) { for (Integer menuId : roleVo.getMenuIds()) {
if (menuId == 9) {
if (menuId == 11) {
return Result.error("上级角色非管理员用户不能赋予权限管理"); return Result.error("上级角色非管理员用户不能赋予权限管理");
} }
} }

16
src/main/java/com/example/demo/serviceImpl/coin/StatisticsServiceImpl.java

@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalTime; import java.time.LocalTime;
@ -35,6 +36,7 @@ public class StatisticsServiceImpl implements StatisticsService {
*/ */
@Override @Override
// @Scheduled(cron = "0 4 * * * ?") // 每小时执行一次 // @Scheduled(cron = "0 4 * * * ?") // 每小时执行一次
@Transactional(rollbackFor = Exception.class) // 1. 开启事务
public void runHourlyTaskPart1() { public void runHourlyTaskPart1() {
LocalDate today = LocalDate.now(); //取当天日期 LocalDate today = LocalDate.now(); //取当天日期
List<Statistics> list = statisticsMapper.listPart1All(today); List<Statistics> list = statisticsMapper.listPart1All(today);
@ -42,6 +44,8 @@ public class StatisticsServiceImpl implements StatisticsService {
if (!list.isEmpty()) { if (!list.isEmpty()) {
statisticsMapper.batchInsertPart1(list); statisticsMapper.batchInsertPart1(list);
} }
// 2. 日志验证连接已归还
log.info("=== Part1 done, tx commit, connection will be closed by Spring ===");
} }
/* /*
@ -49,6 +53,7 @@ public class StatisticsServiceImpl implements StatisticsService {
*/ */
@Override @Override
//@Scheduled(cron = "0 8 * * * ?") // 每小时执行一次 //@Scheduled(cron = "0 8 * * * ?") // 每小时执行一次
@Transactional(rollbackFor = Exception.class) // 1. 开启事务
public void runHourlyTaskPart2() { public void runHourlyTaskPart2() {
//设定起止时间 当天000000至235959 //设定起止时间 当天000000至235959
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
@ -61,6 +66,9 @@ public class StatisticsServiceImpl implements StatisticsService {
if (!list.isEmpty()) { if (!list.isEmpty()) {
statisticsMapper.batchInsertPart2(list); statisticsMapper.batchInsertPart2(list);
} }
// 2. 日志验证连接已归还
log.info("=== Part1 done, tx commit, connection will be closed by Spring ===");
} }
@ -69,6 +77,7 @@ public class StatisticsServiceImpl implements StatisticsService {
*/ */
@Override @Override
//@Scheduled(cron = "0 12 * * * ?") // 每小时执行一次 //@Scheduled(cron = "0 12 * * * ?") // 每小时执行一次
@Transactional(rollbackFor = Exception.class) // 1. 开启事务
public void runHourlyTaskYear() { public void runHourlyTaskYear() {
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
LocalDate firstDay = today.withDayOfYear(1); LocalDate firstDay = today.withDayOfYear(1);
@ -81,6 +90,9 @@ public class StatisticsServiceImpl implements StatisticsService {
if (!list.isEmpty()) { if (!list.isEmpty()) {
statisticsMapper.batchInsertYear(list); statisticsMapper.batchInsertYear(list);
} }
// 2. 日志验证连接已归还
log.info("=== Part1 done, tx commit, connection will be closed by Spring ===");
} }
@ -89,11 +101,15 @@ public class StatisticsServiceImpl implements StatisticsService {
*/ */
@Override @Override
//@Scheduled(cron = "0 30 0 * * ?") // 修改为每天 00:30 执行 //@Scheduled(cron = "0 30 0 * * ?") // 修改为每天 00:30 执行
@Transactional(rollbackFor = Exception.class) // 1. 开启事务
public void runDailyTaskPart2() { public void runDailyTaskPart2() {
List<Statistics> list = statisticsMapper.listPart2RangeAll(); List<Statistics> list = statisticsMapper.listPart2RangeAll();
if (!list.isEmpty()) { if (!list.isEmpty()) {
statisticsMapper.batchInsertPart2(list); statisticsMapper.batchInsertPart2(list);
} }
// 2. 日志验证连接已归还
log.info("=== Part1 done, tx commit, connection will be closed by Spring ===");
} }
} }

1
src/main/resources/application-prod.yml

@ -9,6 +9,7 @@ spring:
password: aDiw7MERSATdfGta password: aDiw7MERSATdfGta
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
hikari: hikari:
auto-commit: false
pool-name: mysql1HikariCP pool-name: mysql1HikariCP
maximum-pool-size: 10 maximum-pool-size: 10
mysql2: mysql2:

2
src/main/resources/application.yml

@ -28,7 +28,7 @@ mybatis:
mysql3: mysql3:
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
default-executor-type: reuse
upload: upload:
path: D:\upload path: D:\upload

3
src/main/resources/mapper/AuditMapper.xml

@ -136,6 +136,9 @@
<if test="refundAudit.refundModel != null "> <if test="refundAudit.refundModel != null ">
AND ugr.refund_model = #{refundAudit.refundModel} AND ugr.refund_model = #{refundAudit.refundModel}
</if> </if>
<if test="refundAudit.refundType != null and refundAudit.refundType!='' ">
AND ugr.refund_type = #{refundAudit.refundType}
</if>
<if test="refundAudit.goodsName != null and refundAudit.goodsName != ''"> <if test="refundAudit.goodsName != null and refundAudit.goodsName != ''">
AND ugr.goods_name = #{refundAudit.goodsName} AND ugr.goods_name = #{refundAudit.goodsName}
</if> </if>

3
src/main/resources/mapper/GoldDetailMapper.xml

@ -28,6 +28,9 @@
m.name AS market, m.name AS market,
`ugr`.pay_platform, `ugr`.pay_platform,
`ugr`.type, `ugr`.type,
`ugr`.is_refund,
`ugr`.order_code,
`ugr`.goods_name,
Round((`ugr`.free_june + `ugr`.free_december) / 100.0, 2) AS freeGold, Round((`ugr`.free_june + `ugr`.free_december) / 100.0, 2) AS freeGold,
ROUND(`ugr`.sum_gold / 100.0, 2) AS SumGold, ROUND(`ugr`.sum_gold / 100.0, 2) AS SumGold,
ROUND(`ugr`.permanent_gold / 100.0, 2) AS PermanentGold, ROUND(`ugr`.permanent_gold / 100.0, 2) AS PermanentGold,

18
src/main/resources/mapper/RechargeMapper.xml

@ -89,6 +89,7 @@
ugr.pay_platform AS payPlatform, ugr.pay_platform AS payPlatform,
ugr.remark AS remark, ugr.remark AS remark,
ugr.admin_id AS adminId, ugr.admin_id AS adminId,
ugr.is_refund AS isRefund,
a.admin_name AS adminName, a.admin_name AS adminName,
ugr.pay_time AS payTime, ugr.pay_time AS payTime,
ugr.audit_time AS auditTime ugr.audit_time AS auditTime
@ -224,7 +225,8 @@
admin_id, admin_id,
type, type,
audit_status, audit_status,
create_time
create_time,
is_refund
</trim> </trim>
VALUES VALUES
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
@ -245,7 +247,19 @@
#{adminId}, #{adminId},
#{type}, #{type},
#{auditStatus}, #{auditStatus},
#{createTime}
#{createTime},
0
</trim> </trim>
</insert> </insert>
<select id="selectOrderCodeByJwcode" resultType="com.example.demo.domain.vo.coin.RechargeUser">
SELECT ugr.jwcode AS jwcode,
ugr.order_code AS orderCode,
ugr.is_refund AS isRefund
FROM user_gold_record ugr
where ugr.order_code = #{orderCode}
AND ugr.jwcode = #{jwcode}
AND ugr.flag = 1
</select>
</mapper> </mapper>

10
src/main/resources/mapper/RefundMapper.xml

@ -232,7 +232,8 @@
type, type,
admin_id, admin_id,
audit_status, audit_status,
create_time
create_time,
update_time
</trim> </trim>
VALUES VALUES
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
@ -251,7 +252,8 @@
#{type}, #{type},
#{adminId}, #{adminId},
#{auditStatus}, #{auditStatus},
#{createTime}
#{createTime},
#{updateTime}
</trim> </trim>
</insert> </insert>
@ -264,6 +266,8 @@
SELECT SELECT
ugr.goods_name AS goodsName, ugr.goods_name AS goodsName,
ugr.is_refund AS isRefund,
ugr.type AS type,
ugr.order_code AS orderCode, ugr.order_code AS orderCode,
ugr.permanent_gold AS permanentGold, ugr.permanent_gold AS permanentGold,
(COALESCE(ugr.free_june, 0) + COALESCE(ugr.free_december, 0)) AS freeGold, (COALESCE(ugr.free_june, 0) + COALESCE(ugr.free_december, 0)) AS freeGold,
@ -271,7 +275,7 @@
FROM user_gold_record ugr FROM user_gold_record ugr
<where> <where>
ugr.is_refund = 0 ugr.is_refund = 0
AND ugr.type = 0
AND ugr.flag = 1
<if test="type !=null and type != '' "> <if test="type !=null and type != '' ">
AND ugr.type = #{type} AND ugr.type = #{type}
</if> </if>

Loading…
Cancel
Save