7 Commits
dadafbe214
...
ede69a52b6
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
ede69a52b6 |
11月21日字符串提示
|
4 days ago |
|
|
369bb47638 |
Merge branch 'refs/heads/huangqizheng/feature-20251119150446-退款合并后' into milestone-20251104-现金管理二期
|
4 days ago |
|
|
d7e72a37aa |
11.21 导出映射
|
4 days ago |
|
|
24b31976dc |
11-21 小黄车消费记录,未筛选
|
4 days ago |
|
|
07827f2ce1 |
Merge branch 'refs/heads/huangqizheng/feature-20251119150446-退款合并后' into milestone-20251104-现金管理二期
|
4 days ago |
|
|
79b86fed80 |
11.21 消息推送
|
4 days ago |
|
|
0541172f7a |
11-21 每日获取最新的产品列表
|
5 days ago |
23 changed files with 531 additions and 51 deletions
-
2src/main/java/com/example/demo/DemoApplication.java
-
89src/main/java/com/example/demo/Util/ProductRemoteClient.java
-
74src/main/java/com/example/demo/config/MarketConverter.java
-
82src/main/java/com/example/demo/config/OrderStatusConverter.java
-
60src/main/java/com/example/demo/config/RefundModelConverter.java
-
6src/main/java/com/example/demo/controller/coin/GeneralController.java
-
29src/main/java/com/example/demo/domain/DTO/ProductDTO.java
-
13src/main/java/com/example/demo/domain/vo/bean/BeanConsumeCart.java
-
5src/main/java/com/example/demo/domain/vo/bean/BeanConsumeCartVo.java
-
21src/main/java/com/example/demo/domain/vo/cash/CashRecordDTO.java
-
3src/main/java/com/example/demo/mapper/bean/BeanConsumeMapper.java
-
7src/main/java/com/example/demo/mapper/coin/BeanRechargeMapper1.java
-
11src/main/java/com/example/demo/mapper/coin/GeneralMapper.java
-
2src/main/java/com/example/demo/service/coin/GeneralService.java
-
5src/main/java/com/example/demo/serviceImpl/bean/BeanConsumeServiceImpl.java
-
2src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java
-
48src/main/java/com/example/demo/serviceImpl/coin/GeneralServiceImpl.java
-
46src/main/java/com/example/demo/serviceImpl/coin/RechargeActivityCenterServiceImpl.java
-
19src/main/resources/cashMapper/CashRefundMapper.xml
-
9src/main/resources/cashMapper/MessageMapper.xml
-
6src/main/resources/jindouMapper/BeanConsumeMapper.xml
-
10src/main/resources/mapper/BeanRechargeMapper1.xml
-
33src/main/resources/mapper/GeneralMapper.xml
@ -0,0 +1,89 @@ |
|||||
|
package com.example.demo.Util; |
||||
|
|
||||
|
import com.example.demo.domain.DTO.ProductDTO; |
||||
|
import lombok.RequiredArgsConstructor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.http.HttpStatus; |
||||
|
import org.springframework.http.ResponseEntity; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.web.client.ResourceAccessException; |
||||
|
import org.springframework.web.client.RestClientException; |
||||
|
import org.springframework.web.client.RestTemplate; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
import java.util.Collections; |
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.Objects; |
||||
|
import java.util.stream.Collectors; |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
@RequiredArgsConstructor |
||||
|
public class ProductRemoteClient { |
||||
|
|
||||
|
private final RestTemplate restTemplate; |
||||
|
|
||||
|
/** |
||||
|
* 获取远端全部商品(全量) |
||||
|
*/ |
||||
|
public List<ProductDTO> fetchAll() { |
||||
|
// 1. 去掉 url 尾部空格 |
||||
|
String url = "https://api.homilychart.com/live_mall/api/product/all"; |
||||
|
|
||||
|
// 2. 构造日志 |
||||
|
log.info("[ProductRemote] 开始拉取远端全量商品"); |
||||
|
|
||||
|
try { |
||||
|
// 3. 指定返回类型,避免 Map Raw Type 警告 |
||||
|
ResponseEntity<Map> resp = |
||||
|
restTemplate.getForEntity(url, Map.class); |
||||
|
|
||||
|
// 4. 状态码校验 |
||||
|
if (resp.getStatusCode() != HttpStatus.OK || resp.getBody() == null) { |
||||
|
throw new RuntimeException("远端返回异常,状态码:" + resp.getStatusCode()); |
||||
|
} |
||||
|
|
||||
|
// 5. 安全取值 |
||||
|
Object dataObj = resp.getBody().get("data"); |
||||
|
if (!(dataObj instanceof List)) { |
||||
|
throw new RuntimeException("远端 data 字段不是数组"); |
||||
|
} |
||||
|
|
||||
|
List<Map<String, Object>> data = (List<Map<String, Object>>) dataObj; |
||||
|
|
||||
|
// 6. 空数组直接返回,避免 NPE |
||||
|
if (data.isEmpty()) { |
||||
|
log.warn("[ProductRemote] 远端返回空数组"); |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
|
||||
|
// 7. 映射 + 空指针保护 |
||||
|
long now = System.currentTimeMillis(); |
||||
|
return data.stream() |
||||
|
.filter(Objects::nonNull) // 过滤 null 元素 |
||||
|
.map(m -> { |
||||
|
ProductDTO dto = new ProductDTO(); |
||||
|
dto.setId((Integer) m.get("id")); |
||||
|
dto.setName((String) m.get("name")); |
||||
|
dto.setCover((String) m.get("cover")); |
||||
|
Object priceObj = m.get("price"); |
||||
|
dto.setPrice(priceObj != null ? new BigDecimal(priceObj.toString()) : BigDecimal.ZERO); |
||||
|
dto.setUpdatedAt(now); |
||||
|
return dto; |
||||
|
}) |
||||
|
.collect(Collectors.toList()); |
||||
|
|
||||
|
} catch (ResourceAccessException e) { |
||||
|
// 网络/超时异常 |
||||
|
log.error("拉取商品失败,真实原因:", e); |
||||
|
throw new RuntimeException("拉取商品失败:" + e.getMessage(), e); |
||||
|
} catch (RestClientException e) { |
||||
|
// 4xx/5xx/解析异常 |
||||
|
log.error("[ProductRemote] 远端异常:{}", e.getMessage()); |
||||
|
throw new RuntimeException("拉取商品失败:远端返回异常", e); |
||||
|
} catch (Exception e) { |
||||
|
// 兜底 |
||||
|
log.error("[ProductRemote] 未知异常", e); |
||||
|
throw new RuntimeException("拉取商品失败:未知错误", e); |
||||
|
}} |
||||
|
} |
||||
@ -0,0 +1,74 @@ |
|||||
|
package com.example.demo.config; |
||||
|
|
||||
|
import com.alibaba.excel.converters.Converter; |
||||
|
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
|
import com.alibaba.excel.metadata.GlobalConfiguration; |
||||
|
import com.alibaba.excel.metadata.data.ReadCellData; |
||||
|
import com.alibaba.excel.metadata.data.WriteCellData; |
||||
|
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 所属地区转换器:Integer(地区ID)→ 地区名称(EasyExcel导出用) |
||||
|
*/ |
||||
|
public class MarketConverter implements Converter<Integer> { |
||||
|
|
||||
|
// 地区ID → 地区名称 映射表(从数据库表中提取) |
||||
|
private static final Map<Integer, String> MARKET_MAP = new HashMap<>(); |
||||
|
|
||||
|
static { |
||||
|
// 初始化映射关系(严格对应数据库表中的id和name) |
||||
|
MARKET_MAP.put(1, "Capt"); |
||||
|
MARKET_MAP.put(2, "公司"); |
||||
|
MARKET_MAP.put(3, "市场部"); |
||||
|
MARKET_MAP.put(4, "新加坡"); |
||||
|
MARKET_MAP.put(5, "马来西亚"); |
||||
|
MARKET_MAP.put(9, "研发部"); |
||||
|
MARKET_MAP.put(999, "总部"); |
||||
|
MARKET_MAP.put(24016, "加拿大"); |
||||
|
MARKET_MAP.put(24018, "泰国"); |
||||
|
MARKET_MAP.put(24022, "越南HCM"); |
||||
|
MARKET_MAP.put(24027, "韩国"); |
||||
|
MARKET_MAP.put(24028, "深圳运营"); |
||||
|
MARKET_MAP.put(24030, "非网"); |
||||
|
MARKET_MAP.put(24031, "其他"); |
||||
|
MARKET_MAP.put(24032, "市场部"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 支持的Java类型(Integer,与market字段类型一致) |
||||
|
*/ |
||||
|
@Override |
||||
|
public Class<?> supportJavaTypeKey() { |
||||
|
return Integer.class; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Excel单元格数据类型(字符串,显示地区名称) |
||||
|
*/ |
||||
|
@Override |
||||
|
public CellDataTypeEnum supportExcelTypeKey() { |
||||
|
return CellDataTypeEnum.STRING; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出时:Integer地区ID → 地区名称 |
||||
|
*/ |
||||
|
@Override |
||||
|
public WriteCellData<?> convertToExcelData(Integer marketId, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
|
// 未匹配到的ID,显示“未知地区(ID值)”,便于排查异常 |
||||
|
String marketName = MARKET_MAP.getOrDefault(marketId, "未知地区(" + marketId + ")"); |
||||
|
return new WriteCellData<>(marketName); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导入时:地区名称 → Integer地区ID(可选实现,如需导入可启用) |
||||
|
*/ |
||||
|
@Override |
||||
|
public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
|
// 若需支持导入,可实现反向映射;此处仅导出用,返回null即可 |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
package com.example.demo.config; |
||||
|
|
||||
|
import com.alibaba.excel.converters.Converter; |
||||
|
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
|
import com.alibaba.excel.metadata.GlobalConfiguration; |
||||
|
import com.alibaba.excel.metadata.data.ReadCellData; |
||||
|
import com.alibaba.excel.metadata.data.WriteCellData; |
||||
|
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 订单状态转换器:Integer值 → 中文描述(EasyExcel导出用) |
||||
|
*/ |
||||
|
public class OrderStatusConverter implements Converter<Integer> { |
||||
|
|
||||
|
// 状态值 → 中文描述 映射表(严格对应注释中的状态) |
||||
|
private static final Map<Integer, String> STATUS_MAP = new HashMap<>(); |
||||
|
|
||||
|
static { |
||||
|
// 初始化映射关系(复制注释中的状态,避免遗漏) |
||||
|
STATUS_MAP.put(0, "线下财务待审核"); |
||||
|
STATUS_MAP.put(1, "线下财务审核通过待填手续费"); |
||||
|
STATUS_MAP.put(2, "线下财务审核驳回"); |
||||
|
STATUS_MAP.put(5, "手动撤回待编辑提交"); |
||||
|
STATUS_MAP.put(3, "link线上财务复核待填手续费"); |
||||
|
STATUS_MAP.put(4, "收款流程全部结束"); |
||||
|
STATUS_MAP.put(6, "退款"); |
||||
|
STATUS_MAP.put(10, "地区财务待审核"); |
||||
|
STATUS_MAP.put(11, "地区财务手动撤回待编辑提交"); |
||||
|
STATUS_MAP.put(12, "地区财务驳回"); |
||||
|
STATUS_MAP.put(20, "地区负责人待审核"); |
||||
|
STATUS_MAP.put(22, "地区负责人驳回"); |
||||
|
STATUS_MAP.put(30, "总部财务待审核"); |
||||
|
STATUS_MAP.put(32, "总部财务驳回"); |
||||
|
STATUS_MAP.put(40, "执行人待处理"); |
||||
|
STATUS_MAP.put(41, "执行人已处理,退款结束"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 支持的Java类型(Integer,与status字段类型一致) |
||||
|
*/ |
||||
|
@Override |
||||
|
public Class<?> supportJavaTypeKey() { |
||||
|
return Integer.class; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Excel单元格数据类型(字符串,显示中文描述) |
||||
|
*/ |
||||
|
@Override |
||||
|
public CellDataTypeEnum supportExcelTypeKey() { |
||||
|
return CellDataTypeEnum.STRING; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出时:Integer状态值 → 中文描述 |
||||
|
*/ |
||||
|
@Override |
||||
|
public WriteCellData<?> convertToExcelData(Integer status, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
|
// 未匹配到的状态,显示“未知状态”(避免导出空值) |
||||
|
String statusDesc = STATUS_MAP.getOrDefault(status, "未知状态(" + status + ")"); |
||||
|
return new WriteCellData<>(statusDesc); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导入时:中文描述 → Integer状态值(可选实现,如需导入可启用) |
||||
|
*/ |
||||
|
@Override |
||||
|
public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
|
String statusDesc = cellData.getStringValue(); |
||||
|
// 反向映射:根据中文描述找状态值(如果需要导入功能) |
||||
|
for (Map.Entry<Integer, String> entry : STATUS_MAP.entrySet()) { |
||||
|
if (entry.getValue().equals(statusDesc)) { |
||||
|
return entry.getKey(); |
||||
|
} |
||||
|
} |
||||
|
// 未匹配到返回null或自定义默认值 |
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
package com.example.demo.config; |
||||
|
|
||||
|
import com.alibaba.excel.converters.Converter; |
||||
|
import com.alibaba.excel.enums.CellDataTypeEnum; |
||||
|
import com.alibaba.excel.metadata.GlobalConfiguration; |
||||
|
import com.alibaba.excel.metadata.data.ReadCellData; |
||||
|
import com.alibaba.excel.metadata.data.WriteCellData; |
||||
|
import com.alibaba.excel.metadata.property.ExcelContentProperty; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* 退款方式转换器:0→全额,1→部分(EasyExcel导出用) |
||||
|
*/ |
||||
|
public class RefundModelConverter implements Converter<Integer> { |
||||
|
|
||||
|
// 退款方式映射表(严格对应:0=全额,1=部分) |
||||
|
private static final Map<Integer, String> REFUND_MODEL_MAP = new HashMap<>(); |
||||
|
|
||||
|
static { |
||||
|
REFUND_MODEL_MAP.put(0, "全额"); |
||||
|
REFUND_MODEL_MAP.put(1, "部分"); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public Class<?> supportJavaTypeKey() { |
||||
|
return Integer.class; // 支持的Java类型(与refundModel字段类型一致) |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public CellDataTypeEnum supportExcelTypeKey() { |
||||
|
return CellDataTypeEnum.STRING; // Excel显示为字符串(中文描述) |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导出时:Integer值 → 中文描述 |
||||
|
*/ |
||||
|
@Override |
||||
|
public WriteCellData<?> convertToExcelData(Integer refundModel, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
|
// 未匹配到的异常值(如2、null等)显示“未知退款方式”,便于排查 |
||||
|
String desc = REFUND_MODEL_MAP.getOrDefault(refundModel, "未知退款方式(" + (refundModel == null ? "null" : refundModel) + ")"); |
||||
|
return new WriteCellData<>(desc); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 导入时:中文描述 → Integer值(可选实现,如需导入可启用) |
||||
|
*/ |
||||
|
@Override |
||||
|
public Integer convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { |
||||
|
String desc = cellData.getStringValue(); |
||||
|
// 反向映射:根据中文找对应数值 |
||||
|
for (Map.Entry<Integer, String> entry : REFUND_MODEL_MAP.entrySet()) { |
||||
|
if (entry.getValue().equals(desc)) { |
||||
|
return entry.getKey(); |
||||
|
} |
||||
|
} |
||||
|
return null; // 未匹配返回null(可根据业务调整默认值) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
package com.example.demo.domain.DTO; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Data; |
||||
|
import lombok.NoArgsConstructor; |
||||
|
import org.apache.poi.hpsf.Decimal; |
||||
|
|
||||
|
import java.math.BigDecimal; |
||||
|
|
||||
|
/** |
||||
|
* @program: gold-java |
||||
|
* @ClassName ProductDTO |
||||
|
* @description: |
||||
|
* @author: Ethan |
||||
|
* @create: 2025−11-21 10:54 |
||||
|
* @Version 1.0 |
||||
|
**/ |
||||
|
|
||||
|
@Data |
||||
|
@AllArgsConstructor |
||||
|
@NoArgsConstructor |
||||
|
public class ProductDTO { |
||||
|
private Integer id; //id |
||||
|
private String name; //商品名 |
||||
|
private String cover; |
||||
|
private BigDecimal price; //价格 |
||||
|
private Long updatedAt; |
||||
|
private Long syncTime; //更新 |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue