From cf1d82548a1bd8155ffe9b486df8167aa9e63a7d Mon Sep 17 00:00:00 2001
From: rk <94314517@qq.com>
Date: 星期四, 02 七月 2026 09:19:06 +0800
Subject: [PATCH] 功能开发
---
server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java | 4
server/services/src/main/java/com/doumee/dao/business/vo/DashboardVO.java | 63 +++++++
server/services/src/main/java/com/doumee/service/business/impl/ReportServiceImpl.java | 23 ++
server/services/src/main/java/com/doumee/core/douyin/dto/DouyinPrepareParam.java | 2
server/services/src/main/java/com/doumee/core/douyin/dto/DouyinBoundProduct.java | 22 ++
server/platform/src/main/java/com/doumee/api/business/ReportController.java | 56 ++++++
server/services/src/main/java/com/doumee/core/douyin/DouyinClient.java | 54 +++++-
server/services/src/main/java/com/doumee/dao/business/vo/PackageSourceStatVO.java | 37 ++++
server/services/src/main/java/com/doumee/dao/business/web/request/GoodsorderBackDTO.java | 2
server/services/src/main/java/com/doumee/service/business/GoodsorderService.java | 9
server/services/src/main/resources/application-dev.yml | 16
server/web/src/main/java/com/doumee/api/web/AccountApi.java | 12 +
server/services/src/main/java/com/doumee/dao/business/model/DouyinVerifyRecord.java | 4
server/services/src/main/java/com/doumee/dao/business/vo/DouyinVerifyRecordPageVO.java | 3
server/web/src/main/java/com/doumee/api/web/DouyinApi.java | 22 ++
server/services/src/main/java/com/doumee/dao/business/vo/BikeUsageStatVO.java | 30 +++
server/web/src/main/java/com/doumee/api/web/ManagerApi.java | 35 +++
server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java | 3
server/services/src/main/java/com/doumee/service/business/DouyinVerifyService.java | 26 ++
server/services/src/main/java/com/doumee/service/business/impl/DouyinVerifyServiceImpl.java | 61 +++++-
server/services/src/main/java/com/doumee/service/business/MemberService.java | 9 +
server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java | 8
server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeStatVO.java | 3
server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java | 22 ++
24 files changed, 486 insertions(+), 40 deletions(-)
diff --git a/server/platform/src/main/java/com/doumee/api/business/ReportController.java b/server/platform/src/main/java/com/doumee/api/business/ReportController.java
new file mode 100644
index 0000000..fbed45d
--- /dev/null
+++ b/server/platform/src/main/java/com/doumee/api/business/ReportController.java
@@ -0,0 +1,56 @@
+package com.doumee.api.business;
+
+import com.doumee.api.BaseController;
+import com.doumee.core.model.ApiResponse;
+import com.doumee.dao.business.vo.BikeUsageStatVO;
+import com.doumee.dao.business.vo.DashboardVO;
+import com.doumee.dao.business.vo.IncomeStatVO;
+import com.doumee.dao.business.vo.PackageSourceStatVO;
+import com.doumee.service.business.ReportService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 鏁版嵁鎶ヨ〃(绠$悊绔柊澧�:杩�30澶╂敹鐩� / 杞﹁締浣跨敤鎯呭喌 / 濂楅鏉ユ簮 / 缁煎悎鐪嬫澘)銆�
+ * <p>涓嶅仛鑿滃崟/鎸夐挳绾ф潈闄愰檺鍒�:鏃� @RequiresPermissions,浠呭彈 Shiro authc 鐧诲綍鏍¢獙淇濇姢,鐧诲綍鍚庡彴鍗冲彲璁块棶銆�
+ * <p>Service 澶嶇敤 services 妯″潡 {@link ReportService}(涓� web 绔� /web/report 鍚屾簮)銆�
+ *
+ * @author rk
+ * @date 2026/06/26
+ */
+@Api(tags = "鏁版嵁鎶ヨ〃(绠$悊绔�)")
+@RestController
+@RequestMapping("/business/report")
+public class ReportController extends BaseController {
+
+ @Autowired
+ private ReportService reportService;
+
+ @ApiOperation("杩�30澶╂敹鐩婄粺璁�(鎸夋棩鏌辩姸鍥�+绱+鐜瘮/鍚屾瘮)")
+ @GetMapping("/incomeStat30")
+ public ApiResponse<IncomeStatVO> incomeStat30() {
+ return ApiResponse.success(reportService.incomeStat30());
+ }
+
+ @ApiOperation("杞﹁締浣跨敤鎯呭喌:鑷杞�/鐢靛姩杞﹀悇鑷娇鐢ㄤ腑涓庣┖闂叉暟閲�")
+ @GetMapping("/bikeUsageStat")
+ public ApiResponse<BikeUsageStatVO> bikeUsageStat() {
+ return ApiResponse.success(reportService.bikeUsageStat());
+ }
+
+ @ApiOperation("濂楅閿�鍞潵婧�:鏈湀/鏈勾缁村害,鎶栭煶鍏戞崲涓庡皬绋嬪簭璐拱鏁伴噺")
+ @GetMapping("/packageSourceStat")
+ public ApiResponse<PackageSourceStatVO> packageSourceStat() {
+ return ApiResponse.success(reportService.packageSourceStat());
+ }
+
+ @ApiOperation("缁煎悎鐪嬫澘:鏈湀/鏄ㄦ棩/浠婃棩鏀剁泭涓庤鍗曟暟,杞﹁締鎬绘暟/浣跨敤涓�/绌洪棽")
+ @GetMapping("/dashboard")
+ public ApiResponse<DashboardVO> dashboard() {
+ return ApiResponse.success(reportService.dashboard());
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/core/douyin/DouyinClient.java b/server/services/src/main/java/com/doumee/core/douyin/DouyinClient.java
index 8f7b418..460e443 100644
--- a/server/services/src/main/java/com/doumee/core/douyin/DouyinClient.java
+++ b/server/services/src/main/java/com/doumee/core/douyin/DouyinClient.java
@@ -27,6 +27,7 @@
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
+import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
@@ -277,15 +278,50 @@
return objectId;
}
try {
- HttpURLConnection conn = (HttpURLConnection) new URL(input).openConnection();
- conn.setInstanceFollowRedirects(true);
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(5000);
- conn.setReadTimeout(5000);
- conn.connect();
- String finalUrl = conn.getURL().toString();
- conn.disconnect();
- return extractObjectId(finalUrl);
+ // 鎵嬪姩璺熼殢閲嶅畾鍚�:HttpURLConnection 鑷姩閲嶅畾鍚戜笉璺ㄥ崗璁�(http鈫攈ttps)涓� getURL() 鏇存柊涓嶇ǔ瀹�,
+ // 鏀逛负閫愯烦璇诲彇 Location 澶�,鏈�缁堜粠钀藉湴闀块摼閲屾彁鍙� object_id
+ String current = input;
+ int maxRedirects = 5;
+ for (int i = 0; i < maxRedirects; i++) {
+ HttpURLConnection conn = (HttpURLConnection) new URL(current).openConnection();
+ conn.setInstanceFollowRedirects(false); // 鎵嬪姩璺熼殢
+ conn.setRequestMethod("GET");
+ conn.setRequestProperty("User-Agent", "Mozilla/5.0");
+ conn.setConnectTimeout(5000);
+ conn.setReadTimeout(5000);
+ int code = conn.getResponseCode();
+ String location = conn.getHeaderField("Location");
+ // 蹇呴』璇诲彇骞跺叧闂敊璇�/杈撳叆娴�,鍚﹀垯杩炴帴璧勬簮娉勬紡
+ try (InputStream is = (code >= 400) ? conn.getErrorStream() : conn.getInputStream()) {
+ if (is != null) {
+ // 涓嶉渶瑕佸唴瀹�,浠呮秷璐规祦浠ラ噴鏀捐繛鎺�
+ byte[] buf = new byte[1024];
+ while (is.read(buf) > 0) {
+ // drain
+ }
+ }
+ }
+ if (code == HttpURLConnection.HTTP_MOVED_PERM
+ || code == HttpURLConnection.HTTP_MOVED_TEMP
+ || code == HttpURLConnection.HTTP_SEE_OTHER
+ || code == 307 || code == 308) {
+ if (StringUtils.isBlank(location)) {
+ // 閲嶅畾鍚戜絾鏃� Location,鏃犳硶缁х画
+ return null;
+ }
+ current = location;
+ continue;
+ }
+ // 闈為噸瀹氬悜:鐢ㄦ渶缁� URL 鎻愬彇 object_id
+ String resolved = location != null ? location : conn.getURL().toString();
+ objectId = extractObjectId(resolved);
+ if (objectId == null) {
+ log.warn("瑙f瀽鎶栭煶鐭摼鏈彁鍙栧埌 object_id,input={},final={}", input, resolved);
+ }
+ return objectId;
+ }
+ log.warn("瑙f瀽鎶栭煶鐭摼瓒呰繃鏈�澶ч噸瀹氬悜娆℃暟,input={}", input);
+ return null;
} catch (Exception e) {
log.error("瑙f瀽鎶栭煶鐭摼寮傚父:{}", input, e);
return null;
diff --git a/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinBoundProduct.java b/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinBoundProduct.java
new file mode 100644
index 0000000..e359155
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinBoundProduct.java
@@ -0,0 +1,22 @@
+package com.doumee.core.douyin.dto;
+
+import com.doumee.dao.business.model.Discount;
+import com.doumee.dao.business.model.DouyinProduct;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 鎶栭煶鍒告牳閿�鍓嶆牎楠岀粨鏋�:鎵胯浇 skuId 鍙嶆煡鍒扮殑鎶栭煶鍟嗗搧 + 缁戝畾鐨勬湰鍦板椁愩��
+ * <p>scanVerify 鍦ㄦ牳閿�鍓嶆牎楠屾椂涓�娆℃�ф煡鍑�,璺ㄥ眰閫忎紶缁� verify 寮�鍗�,閬垮厤閲嶅鏌ヨ銆�
+ *
+ * @author rk
+ * @date 2026/06/26
+ */
+@Data
+@AllArgsConstructor
+public class DouyinBoundProduct {
+ /** 鎶栭煶鍟嗗搧(鐢ㄤ簬鍥炲~鏍搁攢璁板綍鐨勫晢鍝佸揩鐓�:productId/productName) */
+ private DouyinProduct product;
+ /** 缁戝畾鐨勬湰鍦板椁�(鐢ㄤ簬寮�閫氬椁愬崱:discountMember 鎷疯礉婧�) */
+ private Discount discount;
+}
diff --git a/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinPrepareParam.java b/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinPrepareParam.java
index a1ab6d6..afddd27 100644
--- a/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinPrepareParam.java
+++ b/server/services/src/main/java/com/doumee/core/douyin/dto/DouyinPrepareParam.java
@@ -20,6 +20,6 @@
@ApiModelProperty(value = "鍒哥爜鏄庢枃(鎵嬪姩杈撳叆鍦烘櫙),涓� qrContent 浜岄�変竴")
private String code;
- @ApiModelProperty(value = "鏍搁攢鎶栭煶闂ㄥ簵ID", required = true)
+ @ApiModelProperty(value = "鏍搁攢鎶栭煶闂ㄥ簵ID")
private String poiId;
}
diff --git a/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java b/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java
index 3800317..4b638d9 100644
--- a/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java
+++ b/server/services/src/main/java/com/doumee/core/wx/WxMiniUtilService.java
@@ -80,8 +80,8 @@
request.setSubMchid(WxMiniConfig.wxProperties.getSubMchId());
request.setNotifyUrl(WxMiniConfig.wxProperties.getRefundNotifyUrl());
AmountReq amountReq = new AmountReq();
- amountReq.setTotal(refundDTO.getTotalAmount().longValue());
- amountReq.setRefund(refundDTO.getRefundAmount().longValue());
+ amountReq.setTotal(1L);//refundDTO.getTotalAmount().longValue());
+ amountReq.setRefund(1L);//refundDTO.getRefundAmount().longValue());
amountReq.setCurrency("CNY");
request.setAmount(amountReq);
try {
diff --git a/server/services/src/main/java/com/doumee/dao/business/model/DouyinVerifyRecord.java b/server/services/src/main/java/com/doumee/dao/business/model/DouyinVerifyRecord.java
index a1be3d0..58422d0 100644
--- a/server/services/src/main/java/com/doumee/dao/business/model/DouyinVerifyRecord.java
+++ b/server/services/src/main/java/com/doumee/dao/business/model/DouyinVerifyRecord.java
@@ -98,4 +98,8 @@
@ApiModelProperty(value = "鏄惁宸插垹闄� 0鏈垹闄� 1宸插垹闄�")
private Integer isdeleted;
+
+ /** 鏍搁攢寮�閫氱殑濂楅鍗¤鎯�(闈炴暟鎹簱瀛楁,scanVerify 杩斿洖鏃堕檮甯�,渚涘墠绔睍绀哄椁愪俊鎭�) */
+ @com.baomidou.mybatisplus.annotation.TableField(exist = false)
+ private DiscountMember packageInfo;
}
diff --git a/server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeStatVO.java b/server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeStatVO.java
index ac2b4e7..9083fe9 100644
--- a/server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeStatVO.java
+++ b/server/services/src/main/java/com/doumee/dao/business/vo/BikeIncomeStatVO.java
@@ -28,4 +28,7 @@
@ApiModelProperty(value = "鏀跺叆閲戦(鍏�)")
private BigDecimal income;
+
+ @ApiModelProperty(value = "璇ヨ溅鍨嬬殑杞﹁締鏁伴噺(bikes 琛ㄦ湭鍒犻櫎)")
+ private Long bikeCount;
}
diff --git a/server/services/src/main/java/com/doumee/dao/business/vo/BikeUsageStatVO.java b/server/services/src/main/java/com/doumee/dao/business/vo/BikeUsageStatVO.java
new file mode 100644
index 0000000..e9eebf3
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/vo/BikeUsageStatVO.java
@@ -0,0 +1,30 @@
+package com.doumee.dao.business.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 杞﹁締浣跨敤鎯呭喌 VO(绠$悊绔姤琛�:鑷杞�/鐢靛姩杞� 脳 浣跨敤涓�/绌洪棽)銆�
+ * <p>鍙e緞:bikes 鏈垹闄よ溅杈�,type=0 鑷杞� / 1 鐢靛姩杞�;
+ * status=0 绌洪棽 / 1 浣跨敤涓�,3 绂佺敤杞﹁締涓嶈鍏ャ��
+ *
+ * @author rk
+ * @date 2026/06/26
+ */
+@Data
+@ApiModel("杞﹁締浣跨敤鎯呭喌")
+public class BikeUsageStatVO {
+
+ @ApiModelProperty(value = "鑷杞︾┖闂叉暟閲�(status=0)")
+ private Long bikeIdle;
+
+ @ApiModelProperty(value = "鑷杞︿娇鐢ㄤ腑鏁伴噺(status=1)")
+ private Long bikeInUse;
+
+ @ApiModelProperty(value = "鐢靛姩杞︾┖闂叉暟閲�(status=0)")
+ private Long eleBikeIdle;
+
+ @ApiModelProperty(value = "鐢靛姩杞︿娇鐢ㄤ腑鏁伴噺(status=1)")
+ private Long eleBikeInUse;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/vo/DashboardVO.java b/server/services/src/main/java/com/doumee/dao/business/vo/DashboardVO.java
new file mode 100644
index 0000000..9abb8b6
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/vo/DashboardVO.java
@@ -0,0 +1,63 @@
+package com.doumee.dao.business.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * 缁煎悎鐪嬫澘 VO(绠$悊绔姤琛�:鏀剁泭 + 璁㈠崟鏁� + 杞﹁締 + 瀹㈡埛鏁�)銆�
+ * <p>鍙e緞:
+ * <ul>
+ * <li>鏀剁泭:goodsorder type=0 鎶奸噾 + status=4 宸茬粨绠� 鐨� closeMoney 涔嬪拰(鍒嗏啋鍏�),鍚� incomeStat</li>
+ * <li>璁㈠崟鏁�:goodsorder payStatus=1 宸叉敮浠樿鍗曡鏁�</li>
+ * <li>杞﹁締:鏈垹闄よ溅杈嗘�绘暟</li>
+ * <li>瀹㈡埛鏁�:鎬讳細鍛�=鏈垹闄ゅ叏閮�;浠婃棩/鏄ㄦ棩鏂板鎸� member.create_date 钀藉湪瀵瑰簲鍖洪棿</li>
+ * </ul>
+ *
+ * @author rk
+ * @date 2026/06/26
+ */
+@Data
+@ApiModel("缁煎悎鐪嬫澘")
+public class DashboardVO {
+
+ // ---------------- 鏀剁泭(鍏�) ----------------
+
+ @ApiModelProperty(value = "鏈湀鏀剁泭(鍏�)")
+ private BigDecimal monthIncome;
+
+ @ApiModelProperty(value = "鏄ㄦ棩鏀剁泭(鍏�)")
+ private BigDecimal yesterdayIncome;
+
+ @ApiModelProperty(value = "浠婃棩鏀剁泭(鍏�)")
+ private BigDecimal todayIncome;
+
+ // ---------------- 璁㈠崟鏁� ----------------
+
+ @ApiModelProperty(value = "鏈湀璁㈠崟鏁�(宸叉敮浠�)")
+ private Long monthOrderCount;
+
+ @ApiModelProperty(value = "鏄ㄦ棩璁㈠崟鏁�(宸叉敮浠�)")
+ private Long yesterdayOrderCount;
+
+ @ApiModelProperty(value = "浠婃棩璁㈠崟鏁�(宸叉敮浠�)")
+ private Long todayOrderCount;
+
+ // ---------------- 杞﹁締 ----------------
+
+ @ApiModelProperty(value = "杞﹁締鎬绘暟(鏈垹闄�)")
+ private Long totalBikeCount;
+
+ // ---------------- 瀹㈡埛鏁� ----------------
+
+ @ApiModelProperty(value = "瀹㈡埛鎬绘暟(鏈垹闄や細鍛樻�绘暟)")
+ private Long totalMemberCount;
+
+ @ApiModelProperty(value = "鏄ㄦ棩鏂板瀹㈡埛(create_date 钀藉湪鏄ㄦ棩)")
+ private Long yesterdayNewMember;
+
+ @ApiModelProperty(value = "浠婃棩鏂板瀹㈡埛(create_date 鈮� 浠婃棩0鐐�)")
+ private Long todayNewMember;
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/vo/DouyinVerifyRecordPageVO.java b/server/services/src/main/java/com/doumee/dao/business/vo/DouyinVerifyRecordPageVO.java
index 0499e70..50d8bb5 100644
--- a/server/services/src/main/java/com/doumee/dao/business/vo/DouyinVerifyRecordPageVO.java
+++ b/server/services/src/main/java/com/doumee/dao/business/vo/DouyinVerifyRecordPageVO.java
@@ -63,6 +63,9 @@
@ApiModelProperty(value = "鍏戞崲浜�(member.name,鏍搁攢鎿嶄綔浜�=璐拱浼氬憳鏈汉)")
private String exchangerName;
+ @ApiModelProperty(value = "濂楅浣跨敤娆℃暟(璇ュ椁愬崱鍏宠仈鐨� member_rides 璁板綍鏁�;0=鏈娇鐢�)")
+ private Long useCount;
+
@ApiModelProperty(value = "鐘舵�佹枃妗�(宸插厬鎹�/宸叉挙閿�/鏍搁攢澶辫触)")
private String statusName;
}
diff --git a/server/services/src/main/java/com/doumee/dao/business/vo/PackageSourceStatVO.java b/server/services/src/main/java/com/doumee/dao/business/vo/PackageSourceStatVO.java
new file mode 100644
index 0000000..303bc03
--- /dev/null
+++ b/server/services/src/main/java/com/doumee/dao/business/vo/PackageSourceStatVO.java
@@ -0,0 +1,37 @@
+package com.doumee.dao.business.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 濂楅閿�鍞潵婧愮粺璁� VO(绠$悊绔姤琛�:鏈湀/鏈勾 脳 鎶栭煶鍏戞崲/灏忕▼搴忚喘涔�)銆�
+ * <p>鍙e緞:goodsorder type=1 濂楅鍗¤喘涔般�乸ayStatus=1 宸叉敮浠�;
+ * 鎶栭煶鍏戞崲 = payWay 2,灏忕▼搴忚喘涔� = payWay 0(寰俊);鎸� pay_date 闄愬畾鏈湀/鏈勾銆�
+ *
+ * @author rk
+ * @date 2026/06/26
+ */
+@Data
+@ApiModel("濂楅閿�鍞潵婧愮粺璁�")
+public class PackageSourceStatVO {
+
+ @ApiModelProperty(value = "鏈湀濂楅閿�鍞潵婧�")
+ private PeriodCount month;
+
+ @ApiModelProperty(value = "鏈勾濂楅閿�鍞潵婧�")
+ private PeriodCount year;
+
+ /**
+ * 鍗曚釜鏃舵鐨勫椁愰攢鍞潵婧愯鏁�(鎶栭煶鍏戞崲 / 灏忕▼搴忚喘涔�)銆�
+ */
+ @Data
+ @ApiModel("濂楅閿�鍞潵婧愯鏁�")
+ public static class PeriodCount {
+ @ApiModelProperty(value = "鎶栭煶鍏戞崲鏁伴噺(payWay=2)")
+ private Long douyinCount;
+
+ @ApiModelProperty(value = "灏忕▼搴忚喘涔版暟閲�(payWay=0 寰俊)")
+ private Long miniCount;
+ }
+}
diff --git a/server/services/src/main/java/com/doumee/dao/business/web/request/GoodsorderBackDTO.java b/server/services/src/main/java/com/doumee/dao/business/web/request/GoodsorderBackDTO.java
index 4322d84..149717a 100644
--- a/server/services/src/main/java/com/doumee/dao/business/web/request/GoodsorderBackDTO.java
+++ b/server/services/src/main/java/com/doumee/dao/business/web/request/GoodsorderBackDTO.java
@@ -19,7 +19,7 @@
@ApiModelProperty(value = "閫�娆鹃噾棰�")
private BigDecimal money;
- @ApiModelProperty(value = "閫�娆鹃噾棰�")
+ @ApiModelProperty(value = "閫�娆捐鏄�")
private String reason;
@ApiModelProperty(value = "濂楅鍗¢��娆剧被鍨� 0閫�璐ч��娆� 1浠呴��娆�")
diff --git a/server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java b/server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java
index 486d7ab..d2ced6f 100644
--- a/server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java
+++ b/server/services/src/main/java/com/doumee/dao/business/web/response/HomeResponse.java
@@ -2,6 +2,7 @@
import com.doumee.dao.business.model.Ad;
import com.doumee.dao.business.model.Discount;
+import com.doumee.dao.business.model.DiscountMember;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -74,6 +75,8 @@
@ApiModelProperty(value = "鐢佃溅杩愯惀鍖哄煙")
private String eleBusinessArea;
+ @ApiModelProperty(value = "褰撳墠浼氬憳鏈夋晥濂楅(鏈�澶�10鏉�,鎸夎幏寰楁椂闂村�掑簭)")
+ private List<DiscountMember> validDiscountList;
}
diff --git a/server/services/src/main/java/com/doumee/service/business/DouyinVerifyService.java b/server/services/src/main/java/com/doumee/service/business/DouyinVerifyService.java
index d336b75..fc98200 100644
--- a/server/services/src/main/java/com/doumee/service/business/DouyinVerifyService.java
+++ b/server/services/src/main/java/com/doumee/service/business/DouyinVerifyService.java
@@ -1,6 +1,7 @@
package com.doumee.service.business;
import com.doumee.core.douyin.dto.DouyinBaseResp;
+import com.doumee.core.douyin.dto.DouyinBoundProduct;
import com.doumee.core.douyin.dto.DouyinCancelParam;
import com.doumee.core.douyin.dto.DouyinPrepareParam;
import com.doumee.core.douyin.dto.DouyinPrepareResp;
@@ -30,12 +31,37 @@
DouyinVerifyRecord verify(DouyinVerifyParam param, String operator);
/**
+ * 楠屽埜(鏍搁攢),浣跨敤璋冪敤鏂瑰凡鏍¢獙濂界殑濂楅缁戝畾缁撴灉(scanVerify 鏍搁攢鍓嶆牎楠屽悗璋冪敤)銆�
+ * <p>鏍搁攢鎴愬姛鍚庣洿鎺ョ敤 boundProduct 寮�閫氬椁�,涓嶅啀閲嶅鏌ヨ鍟嗗搧/濂楅銆�
+ * @param param 鏍搁攢鍏ュ弬
+ * @param operator 鎿嶄綔浜篒D
+ * @param boundProduct 鏍搁攢鍓嶅凡鏍¢獙鐨勬姈闊冲晢鍝� + 鏈湴濂楅(scanVerify 浼犲叆)
+ */
+ DouyinVerifyRecord verify(DouyinVerifyParam param, String operator, DouyinBoundProduct boundProduct);
+
+ /**
+ * 鏍搁攢鍓嶆牎楠�:鎸� skuId 鏍¢獙鎶栭煶鍟嗗搧鍦ㄥ簱涓斿凡缁戝畾鏈夋晥鏈湴濂楅銆�
+ * <p>scanVerify 鍦ㄦ牳閿�鍓嶈皟鐢�,澶辫触鎶涗笟鍔″紓甯�(鍒稿皻鏈牳閿�,閬垮厤鎶栭煶宸叉牳閿�浣嗘湰鍦版湭寮�鍗$殑涓嶄竴鑷�)銆�
+ * @param skuId 鏍搁攢鍒稿搴旂殑鎶栭煶 SKU ID
+ * @return 鎶栭煶鍟嗗搧 + 缁戝畾鐨勬湰鍦板椁�(渚� verify 寮�鍗″鐢�)
+ */
+ DouyinBoundProduct resolveBoundProduct(String skuId);
+
+ /**
* 鎾ら攢鏍搁攢(鏍搁攢鍚� 1 灏忔椂鍐�),鏇存柊璁板綍鎾ら攢鐘舵��
* @param operator 鎿嶄綔浜篒D(鐢辫皟鐢ㄧ浼犲叆,web 绔彇鐧诲綍浼氬憳ID)
*/
DouyinVerifyRecord cancel(DouyinCancelParam param, String operator);
/**
+ * 鎸� discountMemberId 鎶婂椁愬崱璇︽儏濉埌 record.packageInfo(scanVerify 灞曠ず鐢�)銆�
+ * <p>鏃犲椁愬崱ID鎴栨煡涓嶅埌鏃�,packageInfo 缃� null,涓嶅奖鍝嶄富娴佺▼銆�
+ *
+ * @param record 鏍搁攢璁板綍(鍚� discountMemberId)
+ */
+ void fillPackageInfo(DouyinVerifyRecord record);
+
+ /**
* 鏍搁攢璁板綍鍒嗛〉(web 绔皬绋嬪簭鑷敤,绠�鍗曞垎椤�)
*/
PageData<DouyinVerifyRecord> findPage(PageWrap<DouyinVerifyRecord> pageWrap);
diff --git a/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java b/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java
index a63ecaa..c8fb0ca 100644
--- a/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java
+++ b/server/services/src/main/java/com/doumee/service/business/GoodsorderService.java
@@ -172,9 +172,16 @@
void forceCloseGoodsorder(String orderId);
/**
- * 閫�娆�
+ * 閫�娆�(鐧诲綍浜轰粠 Shiro 涓婁笅鏂囧彇,platform 绔敤)
*/
void backGoodsorder(GoodsorderBackDTO goodsorderBackDTO);
+
+ /**
+ * 閫�娆�(鐧诲綍浜虹敱璋冪敤鏂逛紶鍏�,web 绔� JWT 鍦烘櫙鐢�,creator=缁戝畾鐨勭鐞嗗憳ID)
+ * @param goodsorderBackDTO 閫�娆惧叆鍙�
+ * @param creator 鎿嶄綔浜篒D(閫�娆惧崟 + 濂楅鎿嶄綔鏃ュ織鐨� creator)
+ */
+ void backGoodsorder(GoodsorderBackDTO goodsorderBackDTO, String creator);
List<MemberRides> getMemberRidesForClose(String orderid );
/**
* 鑾峰彇鍙��娆句俊鎭�
diff --git a/server/services/src/main/java/com/doumee/service/business/MemberService.java b/server/services/src/main/java/com/doumee/service/business/MemberService.java
index bc36b2a..2d1a8c5 100644
--- a/server/services/src/main/java/com/doumee/service/business/MemberService.java
+++ b/server/services/src/main/java/com/doumee/service/business/MemberService.java
@@ -143,4 +143,13 @@
AccountResponse wxPhone(WxPhoneRequest wxPhoneRequest);
UserResponse getUserInfo(String memberId);
+
+ /**
+ * 閫�鍑虹櫥褰�:娓呯┖褰撳墠浼氬憳鎵嬫満鍙�(缃┖涓�)銆�
+ * <p>JWT 鏃犵姸鎬�,鏃犳硶鍚婇攢 token;娓� phone 鍚庝細鍛樺洖鍒版湭鎺堟潈鎵嬫満鍙风姸鎬�,
+ * 涓嬫杩涘叆闇�閲嶆柊 wxLogin + wxPhone銆�
+ *
+ * @param memberId 浼氬憳ID
+ */
+ void clearPhone(String memberId);
}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/DouyinVerifyServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/DouyinVerifyServiceImpl.java
index fc14eb8..6211902 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/DouyinVerifyServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/DouyinVerifyServiceImpl.java
@@ -9,6 +9,7 @@
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.douyin.DouyinClient;
import com.doumee.core.douyin.dto.DouyinBaseResp;
+import com.doumee.core.douyin.dto.DouyinBoundProduct;
import com.doumee.core.douyin.dto.DouyinCancelParam;
import com.doumee.core.douyin.dto.DouyinCancelReq;
import com.doumee.core.douyin.dto.DouyinCancelResp;
@@ -135,7 +136,7 @@
*/
@Override
@Transactional(rollbackFor = Exception.class)
- public DouyinVerifyRecord verify(DouyinVerifyParam param, String operator) {
+ public DouyinVerifyRecord verify(DouyinVerifyParam param, String operator, DouyinBoundProduct boundProduct) {
// 鍏ュ弬鏍¢獙
if (param == null || StringUtils.isBlank(param.getVerifyToken())) {
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "verifyToken 涓嶈兘涓虹┖");
@@ -153,6 +154,10 @@
if (StringUtils.isBlank(param.getSkuId())) {
// 鏃� skuId 鍒欐棤娉曞弽鏌ュ椁�(鏍搁攢杩斿洖鏈韩涓嶅惈鍟嗗搧鏍囪瘑),鐩存帴鎷︽埅
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "skuId 涓嶈兘涓虹┖");
+ }
+ if (boundProduct == null || boundProduct.getProduct() == null || boundProduct.getDiscount() == null) {
+ // 鍏滃簳:濂楅缁戝畾缁撴灉缂哄け(scanVerify 搴斿凡鏍¢獙,杩欓噷闃� NPE)
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏈壘鍒拌鍒稿搴旂殑鏈湴濂楅,璇峰厛鍦ㄧ鐞嗙缁戝畾");
}
Date now = new Date();
@@ -204,8 +209,16 @@
}
// 鏍搁攢鎴愬姛:涓哄綋鍓嶇櫥褰曚汉寮�閫氬椁�(浠讳竴姝ュけ璐� 鈫� 鏁村崟鍥炴粴)
- openDiscountForVerify(rec, param, operator);
+ // 娉�:scanVerify 宸插湪鏍搁攢鍓嶆牎楠岃繃濂楅缁戝畾骞堕�忎紶缁撴灉,杩欓噷涓嶅啀閲嶅鏌ヨ
+ openDiscountForVerify(rec, param, boundProduct, operator);
return rec;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public DouyinVerifyRecord verify(DouyinVerifyParam param, String operator) {
+ // 鏃犻鏍¢獙缁撴灉鐨勫吋瀹瑰叆鍙�:鏍搁攢鍓嶅厛鏍¢獙濂楅缁戝畾(鏍搁攢鍔ㄤ綔鍦ㄩ噸杞藉唴瀹屾垚)
+ return verify(param, operator, resolveBoundProduct(param.getSkuId()));
}
/**
@@ -215,19 +228,23 @@
*
* @param rec 鏍搁攢璁板綍(鍚� originCode/certificateId 绛夋姈闊虫爣璇�,寮�閫氬悗鍥炲~濂楅鍗D)
* @param param 鏍搁攢鍏ュ弬(鍚� skuId 鍙嶆煡濂楅銆乸ayAmount 蹇収)
+ * @param boundProduct 鏍搁攢鍓嶅凡鏍¢獙鐨勬姈闊冲晢鍝� + 鏈湴濂楅(閬垮厤閲嶅鏌ヨ)
* @param operator 鎿嶄綔浜� = 濂楅褰掑睘浜�(web 绔櫥褰曚細鍛� id)
*/
- private void openDiscountForVerify(DouyinVerifyRecord rec, DouyinVerifyParam param, String operator) {
- // 鈶� 鍙嶆煡濂楅:skuId 鈫� douyin_product_sku 鈫� product_id 鈫� douyin_product.out_id 鈫� discount
- DouyinProduct product = resolveProduct(param.getSkuId());
- Discount discount = resolveDiscount(product);
+ private void openDiscountForVerify(DouyinVerifyRecord rec, DouyinVerifyParam param,
+ DouyinBoundProduct boundProduct, String operator) {
+ // 鍟嗗搧 + 濂楅宸茬敱 scanVerify 鏍搁攢鍓嶆牎楠�(resolveBoundProduct)鏌ュ嚭骞堕�忎紶,鐩存帴浣跨敤
+ DouyinProduct product = boundProduct.getProduct();
+ Discount discount = boundProduct.getDiscount();
Date now = new Date();
- // 鈶� 闃查噸:鍚屼竴鍒哥爜宸蹭负璇ョ敤鎴峰紑杩囧椁愬崱鍒欒烦杩�(閬垮厤閲嶅鏍搁攢閲嶅紑)
+ // 鈶� 闃查噸:鍚屼竴鍒哥爜宸蹭负璇ョ敤鎴峰紑杩囥�屾甯搞�嶅椁愬崱鍒欒烦杩�(閬垮厤閲嶅鏍搁攢閲嶅紑)銆�
+ // 娉ㄦ剰:宸蹭綔搴�(status=1,濡傛挙閿�鏍搁攢鍚�)鐨勫崱涓嶅弬涓庨槻閲嶁�斺�旀挙閿�鍚庨噸鏂版牳閿�搴旀甯稿紑鏂板崱銆�
DiscountMember existCard = discountMemberMapper.selectOne(new QueryWrapper<DiscountMember>().lambda()
.eq(DiscountMember::getCode, rec.getOriginCode())
.eq(DiscountMember::getMemberId, operator)
+ .eq(DiscountMember::getStatus, Constants.ZERO)
.eq(DiscountMember::getIsdeleted, Constants.ZERO)
.last("limit 1"));
if (existCard != null) {
@@ -340,13 +357,23 @@
private Discount resolveDiscount(DouyinProduct product) {
Discount discount = discountMapper.selectOne(new QueryWrapper<Discount>().lambda()
.eq(Discount::getId, product.getOutId())
- .eq(Discount::getStatus, Constants.ZERO)
.eq(Discount::getIsdeleted, Constants.ZERO)
.last("limit 1"));
if (discount == null) {
throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鏈壘鍒拌鍒稿搴旂殑鏈湴濂楅,璇峰厛鍦ㄧ鐞嗙缁戝畾");
}
return discount;
+ }
+
+ @Override
+ public DouyinBoundProduct resolveBoundProduct(String skuId) {
+ if (StringUtils.isBlank(skuId)) {
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "skuId 涓嶈兘涓虹┖");
+ }
+ // 澶嶇敤鏃㈡湁鏍¢獙閾捐矾:skuId 鈫� 鎶栭煶鍟嗗搧(鍦ㄥ簱 + 宸茬粦 out_id)鈫� 鏈湴濂楅(鏈夋晥)
+ DouyinProduct product = resolveProduct(skuId);
+ Discount discount = resolveDiscount(product);
+ return new DouyinBoundProduct(product, discount);
}
@Override
@@ -389,10 +416,13 @@
rec.setRawResponse(respText);
// 鎾ら攢澶辫触:鏇存柊璁板綍鎻忚堪鍚庢姏鍑�(璁板綍淇濈暀鍘熸牳閿�鐘舵��)
if (!ok) {
+ // 澶辫触鍘熷洜:浼樺厛 extra.description,鏈� sub_description 鏃惰拷鍔�(sub_description 鏇村叿浣�)
String desc = resp == null || resp.getExtra() == null ? "鏃犲搷搴�" : resp.getExtra().getDescription();
- rec.setCancelMsg("鎾ら攢澶辫触:" + desc);
+ String subDesc = resp == null || resp.getExtra() == null ? null : resp.getExtra().getSubDescription();
+ String failMsg = StringUtils.isBlank(subDesc) ? desc : desc + ";" + subDesc;
+ rec.setCancelMsg("鎾ら攢澶辫触:" + failMsg);
douyinVerifyRecordMapper.updateById(rec);
- throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鎾ら攢澶辫触:" + desc);
+ throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "鎾ら攢澶辫触:" + failMsg);
}
// 鎾ら攢鎴愬姛:缃挙閿�鐘舵�併�佹挙閿�鏃堕棿涓庢挙閿�浜�
rec.setCancelStatus(Constants.DOUYIN_VERIFY_CANCEL_STATUS.DONE.getKey());
@@ -403,6 +433,15 @@
// 鍚屾浣滃簾鏈湴宸插紑閫氱殑濂楅鍗�(闃叉鎶栭煶鎾ら攢鍚庡椁愪粛琚娇鐢�);鍙傜収 backGoodsorder 閫�鍗�
cancelDiscountMember(rec, operator, now);
return rec;
+ }
+
+ @Override
+ public void fillPackageInfo(DouyinVerifyRecord record) {
+ // 鏃犲椁愬崱ID鎴栨煡涓嶅埌鏃剁疆 null,涓嶅奖鍝嶄富娴佺▼(scanVerify 鐢ㄤ簬鍓嶇灞曠ず濂楅淇℃伅)
+ if (record == null || StringUtils.isBlank(record.getDiscountMemberId())) {
+ return;
+ }
+ record.setPackageInfo(discountMemberMapper.selectById(record.getDiscountMemberId()));
}
/**
@@ -495,6 +534,8 @@
.selectAs(DouyinProduct::getCategory, DouyinVerifyRecordPageVO::getCategory)
// 鎶栭煶鍒稿悕:discount_member.name(鏈湴寮�閫氬椁愬悕)
.selectAs(DiscountMember::getName, DouyinVerifyRecordPageVO::getCouponName)
+ // 濂楅浣跨敤娆℃暟:瀛愭煡璇㈢粺璁¤濂楅鍗″湪 member_rides 鐨勯獞琛岃褰曟暟(t 涓轰富琛� douyin_verify_record)
+ .select(" ( select count(1) from member_rides where discount_member_id = t.discount_member_id and isdeleted = 0 ) ", DouyinVerifyRecordPageVO::getUseCount)
// 涓夎〃 leftJoin:discount_member(缁� discount_member_id)鈫� member(缁� member_id);douyin_product(缁� product_id)
.leftJoin(DiscountMember.class, DiscountMember::getId, DouyinVerifyRecord::getDiscountMemberId)
.leftJoin(Member.class, Member::getId, DiscountMember::getMemberId)
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java
index 2846a2b..68a49e9 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/GoodsorderServiceImpl.java
@@ -482,6 +482,13 @@
}
}
}
+ // 褰撳墠浼氬憳鏈夋晥濂楅(status=0 姝e父 + isdeleted=0),鎸夎幏寰楁椂闂�(createDate)鍊掑簭,鏈�澶�10鏉�
+ homeResponse.setValidDiscountList(discountMemberMapper.selectList(new QueryWrapper<DiscountMember>().lambda()
+ .eq(DiscountMember::getMemberId, memberId)
+ .eq(DiscountMember::getStatus, Constants.ZERO)
+ .eq(DiscountMember::getIsdeleted, Constants.ZERO)
+ .orderByDesc(DiscountMember::getCreateDate)
+ .last(" limit 10 ")));
return homeResponse;
}
@@ -977,7 +984,16 @@
@Override
public void backGoodsorder(GoodsorderBackDTO goodsorderBackDTO) {
+ // platform 绔�:鐧诲綍浜轰粠 Shiro 涓婁笅鏂囧彇,濮旀墭缁欏甫 creator 鐨勯噸杞芥柟娉�
LoginUserInfo principal = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
+ if (Objects.isNull(principal) || StringUtils.isBlank(principal.getId())) {
+ throw new BusinessException(ResponseStatus.BE_OVERDUE);
+ }
+ backGoodsorder(goodsorderBackDTO, principal.getId());
+ }
+
+ @Override
+ public void backGoodsorder(GoodsorderBackDTO goodsorderBackDTO, String creator) {
if(Objects.isNull(goodsorderBackDTO)
|| StringUtils.isBlank(goodsorderBackDTO.getOrderId())
|| Objects.isNull(goodsorderBackDTO.getBackType())
@@ -1013,7 +1029,7 @@
refundDTO.setRefundAmount(goodsorderBackDTO.getMoney().multiply(new BigDecimal(100)));
refundDTO.setTotalAmount(goodsorder.getMoney());
refundDTO.setMemberId(goodsorder.getMemberId());
- refundDTO.setCreator(principal.getId());
+ refundDTO.setCreator(creator);
refundDTO.setReason(goodsorderBackDTO.getReason());
refundDTO.setType(Constants.REFUND_TYPE.BACK.getKey());
//閫�璐ч��娆� 鏌ョ湅濂楅璁㈠崟鐘舵�� 鏇存柊璁㈠崟淇℃伅
@@ -1033,7 +1049,7 @@
//鎿嶄綔鏃ュ織
DiscountLog discountLog = new DiscountLog();
discountLog.setIsdeleted(Constants.ZERO);
- discountLog.setCreator(principal.getId());
+ discountLog.setCreator(creator);
discountLog.setCreateDate(new Date());
discountLog.setDiscountMemberId(discountMember.getId());
discountLog.setType(Constants.ONE);
@@ -1361,7 +1377,7 @@
request.setOutTradeNo(goodsorder.getId());
request.setNotifyUrl(WxMiniConfig.wxProperties.getNotifyUrl());//杩欎釜鍥炶皟url蹇呴』鏄痟ttps寮�澶寸殑
Amount amount = new Amount();
- amount.setTotal(goodsorder.getMoney().intValue());
+ amount.setTotal(1);//goodsorder.getMoney().intValue());
request.setAmount(amount);
// PrepayResponse res = WxMiniConfig.wxPayService.prepay(request);
// 璺熶箣鍓嶄笅鍗曠ず渚嬩竴鏍凤紝濉厖棰勪笅鍗曞弬鏁�
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
index 9154af3..dbd486b 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -417,5 +417,13 @@
return userResponse;
}
+ @Override
+ public void clearPhone(String memberId) {
+ // 閫�鍑虹櫥褰�:娓呯┖浼氬憳鎵嬫満鍙�(缃┖涓�),淇濈暀鍏朵粬淇℃伅(鍚� sysuser 缁戝畾)
+ memberMapper.update(null, new UpdateWrapper<Member>().lambda()
+ .set(Member::getPhone, StringUtils.EMPTY)
+ .eq(Member::getId, memberId));
+ }
+
}
diff --git a/server/services/src/main/java/com/doumee/service/business/impl/ReportServiceImpl.java b/server/services/src/main/java/com/doumee/service/business/impl/ReportServiceImpl.java
index 8f85057..500d6d9 100644
--- a/server/services/src/main/java/com/doumee/service/business/impl/ReportServiceImpl.java
+++ b/server/services/src/main/java/com/doumee/service/business/impl/ReportServiceImpl.java
@@ -155,7 +155,23 @@
incomeByParam.merge(o.getParamId(), amount, BigDecimal::add);
}
- // 5. 缁勮缁撴灉:杞﹀瀷鍚� + 澶х被 + 鏀跺叆(鍒嗏啋鍏�,2浣�),鎸夋敹鍏ラ檷搴�
+ // 5. 鎸� paramId 缁熻姣忕被杞﹀瀷鐨勮溅杈嗘暟閲�(bikes 琛ㄦ湭鍒犻櫎),涓�娆″垎缁勬煡璇㈤伩鍏� N 娆� count
+ Map<String, Long> bikeCountByParam;
+ if (incomeByParam.isEmpty()) {
+ // 鏃犳湁鏀跺叆鐨勮溅鍨嬫椂璺宠繃鏌ヨ:绌洪泦鍚堜紶缁� in() 浼氱敓鎴� "IN ()",PostgreSQL 璇硶閿欒
+ bikeCountByParam = Collections.emptyMap();
+ } else {
+ bikeCountByParam = bikesMapper.selectList(
+ new QueryWrapper<Bikes>().lambda()
+ .select(Bikes::getParamId)
+ .eq(Bikes::getIsdeleted, Constants.ZERO)
+ .in(Bikes::getParamId, incomeByParam.keySet()))
+ .stream()
+ .filter(b -> b.getParamId() != null)
+ .collect(Collectors.groupingBy(Bikes::getParamId, Collectors.counting()));
+ }
+
+ // 6. 缁勮缁撴灉:杞﹀瀷鍚� + 澶х被 + 鏀跺叆(鍒嗏啋鍏�,2浣�)+ 杞﹁締鏁�,鎸夋敹鍏ラ檷搴�
List<BikeIncomeStatVO> result = new ArrayList<>();
for (Map.Entry<String, BigDecimal> e : incomeByParam.entrySet()) {
BaseParam param = paramMap.get(e.getKey());
@@ -164,6 +180,7 @@
vo.setParamName(param == null ? "鏈煡杞﹀瀷" : param.getName());
vo.setCategory(param == null ? "鏈煡" : categoryOf(param.getType()));
vo.setIncome(e.getValue().divide(CENT_PER_YUAN, 2, BigDecimal.ROUND_HALF_UP));
+ vo.setBikeCount(bikeCountByParam.getOrDefault(e.getKey(), 0L));
result.add(vo);
}
result.sort(Comparator.comparing(BikeIncomeStatVO::getIncome).reversed());
@@ -262,7 +279,7 @@
BigDecimal totalCents = BigDecimal.ZERO;
for (Goodsorder o : orders) {
BigDecimal amount = o.getCloseMoney() == null ? BigDecimal.ZERO : o.getCloseMoney();
- sumByDay.merge(DateUtil.getShortDateStr(o.getPayDate()), amount, BigDecimal::add);
+ sumByDay.merge(DateUtil.getDateLong(o.getPayDate()), amount, BigDecimal::add);
totalCents = totalCents.add(amount);
}
@@ -272,7 +289,7 @@
List<IncomeDailyVO> dailyList = new ArrayList<>();
for (Date d : DateUtil.getDateList(DateUtil.getStartOfDay(start), DateUtil.getStartOfDay(end))) {
IncomeDailyVO vo = new IncomeDailyVO();
- vo.setDate(DateUtil.getShortDateStr(d));
+ vo.setDate(DateUtil.getDateLong(d));
BigDecimal daySum = sumByDay.getOrDefault(vo.getDate(), BigDecimal.ZERO);
// 鍒嗏啋鍏�,2浣嶅皬鏁�
vo.setIncome(daySum.divide(CENT_PER_YUAN, 2, BigDecimal.ROUND_HALF_UP));
diff --git a/server/services/src/main/resources/application-dev.yml b/server/services/src/main/resources/application-dev.yml
index ea92283..cbf46c8 100644
--- a/server/services/src/main/resources/application-dev.yml
+++ b/server/services/src/main/resources/application-dev.yml
@@ -52,14 +52,14 @@
mchKey: W97N53Q71326D6JZ2E9HY5M4VT4BAC8S
# notifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxPayNotify
# refundNotifyUrl: http://xiaopiqiu3.natapp1.cc/api/wxRefundNotify
- notifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxPayNotify
- refundNotifyUrl: https://dmtest.ahapp.net/bike_h5_api/api/wxRefundNotify
-# keyPath: /usr/local/aliConfig/bike/apiclient_cert.p12
-# privateCertPath: /usr/local/aliConfig/bike/apiclient_cert.pem
-# privateKeyPath: /usr/local/aliConfig/bike/apiclient_key.pem
- keyPath: d://apiclient_cert.p12
- privateCertPath: d://apiclient_cert.pem
- privateKeyPath: d://apiclient_key.pem
+ notifyUrl: https://test.doumee.cn/bikeWeb/api/wxPayNotify
+ refundNotifyUrl: https://test.doumee.cn/bikeWeb/api/wxRefundNotify
+ keyPath: /usr/local/jars/bike/apiclient_cert.p12
+ privateCertPath: /usr/local/jars/bike/apiclient_cert.pem
+ privateKeyPath: /usr/local/jars/bike/apiclient_key.pem
+# keyPath: d://apiclient_cert.p12
+# privateCertPath: d://apiclient_cert.pem
+# privateKeyPath: d://apiclient_key.pem
#鏈嶅姟鍟�-------------end---
existsSub: 1
appSecret: 1ceb7c9dff3c4330d653adc3ca55ea24
diff --git a/server/web/src/main/java/com/doumee/api/web/AccountApi.java b/server/web/src/main/java/com/doumee/api/web/AccountApi.java
index 47e9c8d..ea8afae 100644
--- a/server/web/src/main/java/com/doumee/api/web/AccountApi.java
+++ b/server/web/src/main/java/com/doumee/api/web/AccountApi.java
@@ -107,6 +107,18 @@
return ApiResponse.success("鏌ヨ鎴愬姛",userResponse);
}
+ @LoginRequired
+ @ApiOperation(value = "閫�鍑虹櫥褰�", notes = "娓呯┖褰撳墠浼氬憳鎵嬫満鍙�,涓嬫杩涘叆闇�閲嶆柊鎺堟潈")
+ @PostMapping("/logout")
+ @ApiImplicitParams({
+ @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true),
+ })
+ public ApiResponse logout() {
+ // JWT 鏃犵姸鎬�,鏃犳硶鍚婇攢 token;姝ゅ娓呯┖浼氬憳鎵嬫満鍙�,浣垮叾鍥炲埌鏈巿鏉冩墜鏈哄彿鐘舵��
+ memberService.clearPhone(getMemberId());
+ return ApiResponse.success("鎿嶄綔鎴愬姛");
+ }
+
@ApiOperation(value = "娴嬭瘯鐢熸垚浜岀淮鐮�", notes = "灏忕▼搴忕")
@GetMapping("/generateWXMiniCode")
diff --git a/server/web/src/main/java/com/doumee/api/web/DouyinApi.java b/server/web/src/main/java/com/doumee/api/web/DouyinApi.java
index 1559c60..be1cf40 100644
--- a/server/web/src/main/java/com/doumee/api/web/DouyinApi.java
+++ b/server/web/src/main/java/com/doumee/api/web/DouyinApi.java
@@ -7,6 +7,7 @@
import com.doumee.core.constants.ResponseStatus;
import com.doumee.core.douyin.DouyinClient;
import com.doumee.core.douyin.dto.DouyinBaseResp;
+import com.doumee.core.douyin.dto.DouyinBoundProduct;
import com.doumee.core.douyin.dto.DouyinPrepareParam;
import com.doumee.core.douyin.dto.DouyinPrepareResp;
import com.doumee.core.douyin.dto.DouyinShopPoiResp;
@@ -22,6 +23,8 @@
import com.doumee.service.business.DouyinVerifyLogService;
import com.doumee.service.business.DouyinVerifyService;
import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -88,6 +91,9 @@
@PreventRepeat
@ApiOperation("鎵爜涓�姝ユ牳閿�(楠屽埜鍑嗗 + 鏍搁攢鍚堝苟;鍓嶇鍙皟姝ゆ帴鍙�)")
@PostMapping("/scanVerify")
+ @ApiImplicitParams({
+ @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true),
+ })
public ApiResponse<DouyinVerifyRecord> scanVerify(@RequestBody DouyinPrepareParam param) {
String apiPath = "/web/douyin/scanVerify";
String memberId = getMemberId();
@@ -137,13 +143,19 @@
verifyParam.setSkuId(cert.getSku().getSkuId());
verifyParam.setPayAmount(cert.getAmount() == null ? null : cert.getAmount().getPayAmount());
- // 鈶� 鏍搁攢 + 寮�濂楅(鍗曠嫭璁颁竴鏉� VERIFY 鏃ュ織)
+ // 鈶� 鏍搁攢鍓嶆牎楠�:鍟嗗搧鍦ㄥ簱 + 宸茬粦瀹氭湁鏁堝椁�;澶辫触鐩存帴鎷︽埅(鍒稿皻鏈牳閿�,閬垮厤鎶栭煶宸叉牳閿�浣嗘湰鍦版湭寮�鍗�)
+ DouyinBoundProduct boundProduct = douyinVerifyService.resolveBoundProduct(verifyParam.getSkuId());
+
+ // 鈶� 鏍搁攢 + 寮�濂楅(鍗曠嫭璁颁竴鏉� VERIFY 鏃ュ織)
long verifyStart = System.currentTimeMillis();
DouyinVerifyLog verifyLog = baseLog(Constants.DOUYIN_VERIFY_OPERATE_TYPE.VERIFY.getKey(), apiPath, verifyStart);
verifyLog.setRawRequest(JSON.toJSONString(verifyParam));
verifyLog.setPoiId(verifyParam.getPoiId());
try {
- DouyinVerifyRecord rec = douyinVerifyService.verify(verifyParam, memberId);
+ // 閫忎紶鏍搁攢鍓嶆牎楠岀粨鏋�,verify 鍐呬笉鍐嶉噸澶嶆煡璇㈠晢鍝�/濂楅
+ DouyinVerifyRecord rec = douyinVerifyService.verify(verifyParam, memberId, boundProduct);
+ // 闄勫甫鏈寮�閫氱殑濂楅鍗¤鎯�(渚涘墠绔牳閿�鍚庡睍绀哄椁愪俊鎭�)
+ douyinVerifyService.fillPackageInfo(rec);
fillByRecord(verifyLog, rec);
return ApiResponse.success(rec);
} catch (Throwable e) {
@@ -173,6 +185,9 @@
@LoginRequired
@ApiOperation("鏍搁攢璁板綍鍒嗛〉")
@PostMapping("/page")
+ @ApiImplicitParams({
+ @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true),
+ })
public ApiResponse<PageData<DouyinVerifyRecord>> findPage(@RequestBody PageWrap<DouyinVerifyRecord> pageWrap) {
return ApiResponse.success(douyinVerifyService.findPage(pageWrap));
}
@@ -180,6 +195,9 @@
@LoginRequired
@ApiOperation("鏍搁攢璁板綍璇︽儏")
@GetMapping("/{id}")
+ @ApiImplicitParams({
+ @ApiImplicitParam(paramType = "header", dataType = "String", name = "token", value = "鐢ㄦ埛token鍊�", required = true),
+ })
public ApiResponse<DouyinVerifyRecord> findById(@PathVariable String id) {
return ApiResponse.success(douyinVerifyService.findById(id));
}
diff --git a/server/web/src/main/java/com/doumee/api/web/ManagerApi.java b/server/web/src/main/java/com/doumee/api/web/ManagerApi.java
index 614e00b..bf499b2 100644
--- a/server/web/src/main/java/com/doumee/api/web/ManagerApi.java
+++ b/server/web/src/main/java/com/doumee/api/web/ManagerApi.java
@@ -10,6 +10,8 @@
import com.doumee.core.model.PageData;
import com.doumee.core.model.PageWrap;
import com.doumee.dao.business.model.*;
+import com.doumee.dao.business.web.request.GoodsorderBackDTO;
+import com.doumee.dao.business.web.request.GoodsorderCanBanlanceDTO;
import com.doumee.dao.business.web.response.UserResponse;
import com.doumee.dao.system.dto.WebLoginDTO;
import com.doumee.dao.system.model.SystemUser;
@@ -30,6 +32,7 @@
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* Created by IntelliJ IDEA.
@@ -54,6 +57,9 @@
private SystemLoginService systemLoginService;
@Autowired
private SystemUserService systemUserService;
+ /** 璁㈠崟閫�娆�/鍙��娆句俊鎭煡璇�(web 绔� JWT 鍦烘櫙) */
+ @Autowired
+ private GoodsorderService goodsorderService;
@LoginRequired
@PreventRepeat(limit = 10, lockTime = 10000)
@ApiOperation("鐧诲綍绠$悊鍛樿处鍙�")
@@ -130,4 +136,33 @@
return ApiResponse.success(list);
}
+ @LoginRequired
+ @ApiOperation("鑾峰彇鍙��娆句俊鎭�")
+ @GetMapping("/getGoodsorderCanBanlanceDTO")
+ public ApiResponse<GoodsorderCanBanlanceDTO> getGoodsorderCanBanlanceDTO(@RequestParam String orderId) {
+ // 浠呮煡璇�,鏃犵櫥褰曚汉鍐欏叆;鏍¢獙绠$悊鍛�
+ UserResponse user = this.getUserResponse();
+ if (user.getSysuser() == null) {
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED);
+ }
+ return ApiResponse.success(goodsorderService.getGoodsorderCanBanlanceDTO(orderId));
+ }
+
+ @PreventRepeat
+ @LoginRequired
+ @ApiOperation("閫�娆�")
+ @PostMapping("/backGoodsorder")
+ public ApiResponse backGoodsorder(@RequestBody GoodsorderBackDTO goodsorderBackDTO) {
+ // 閫�娆句负绠$悊鍛樻搷浣�:鏍¢獙宸茬粦瀹氱郴缁熺鐞嗗憳,creator 鍙� sysuser.id(涓� platform Shiro 鍙e緞涓�鑷�)
+ UserResponse user = this.getUserResponse();
+ if (user.getSysuser() == null) {
+ throw new BusinessException(ResponseStatus.NOT_ALLOWED);
+ }
+ if (Objects.nonNull(goodsorderBackDTO) && Objects.isNull(goodsorderBackDTO.getBackType())) {
+ goodsorderBackDTO.setBackType(Constants.ONE);
+ }
+ goodsorderService.backGoodsorder(goodsorderBackDTO, user.getSysuser().getId());
+ return ApiResponse.success(null);
+ }
+
}
--
Gitblit v1.9.3