From 3d744e3f85959e30f9ced8c88092f231525bc1c3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 Aug 2025 14:51:44 +0000 Subject: [PATCH 1/3] Initial plan From eab5466b3d1a272e957201a57355313500a02473 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:07:14 +0000 Subject: [PATCH 2/3] Implement WeChat Mini Program complaint handling service with all core APIs Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wx/miniapp/api/WxMaComplaintService.java | 159 +++++++++++++++++ .../wx/miniapp/api/WxMaService.java | 9 + .../miniapp/api/impl/BaseWxMaServiceImpl.java | 6 + .../api/impl/WxMaComplaintServiceImpl.java | 99 +++++++++++ .../complaint/WxMaComplaintDetailRequest.java | 38 ++++ .../complaint/WxMaComplaintDetailResult.java | 166 ++++++++++++++++++ .../WxMaComplaintNotifyUrlRequest.java | 38 ++++ .../WxMaComplaintNotifyUrlResult.java | 37 ++++ .../bean/complaint/WxMaComplaintRequest.java | 68 +++++++ .../bean/complaint/WxMaComplaintResult.java | 156 ++++++++++++++++ .../bean/complaint/WxMaCompleteRequest.java | 38 ++++ .../WxMaNegotiationHistoryRequest.java | 58 ++++++ .../WxMaNegotiationHistoryResult.java | 88 ++++++++++ .../bean/complaint/WxMaResponseRequest.java | 79 +++++++++ .../miniapp/constant/WxMaApiUrlConstants.java | 30 ++++ 15 files changed, 1069 insertions(+) create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaComplaintService.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaComplaintServiceImpl.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailRequest.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailResult.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlRequest.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlResult.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintResult.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaCompleteRequest.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryResult.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaResponseRequest.java diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaComplaintService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaComplaintService.java new file mode 100644 index 000000000..bd12f6085 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaComplaintService.java @@ -0,0 +1,159 @@ +package cn.binarywang.wx.miniapp.api; + +import cn.binarywang.wx.miniapp.bean.complaint.*; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +/** + * 小程序交易投诉接口 + * + * @author Binary Wang + * created on 2025-01-01 + */ +public interface WxMaComplaintService { + + /** + *
+   * 查询投诉单列表API
+   * 商户可通过调用此接口,查询指定时间段的所有用户投诉信息,以分页输出查询结果。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaComplaintRequest} 查询投诉单列表请求数据 + * @return {@link WxMaComplaintResult} 微信返回的投诉单列表 + * @throws WxErrorException the wx error exception + */ + WxMaComplaintResult queryComplaints(WxMaComplaintRequest request) throws WxErrorException; + + /** + *
+   * 查询投诉单详情API
+   * 商户可通过调用此接口,查询指定投诉单的用户投诉详情,包含投诉内容、投诉关联订单、投诉人联系方式等信息,方便商户处理投诉。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaComplaintDetailRequest} 投诉单详情请求数据 + * @return {@link WxMaComplaintDetailResult} 微信返回的投诉单详情 + * @throws WxErrorException the wx error exception + */ + WxMaComplaintDetailResult getComplaint(WxMaComplaintDetailRequest request) throws WxErrorException; + + /** + *
+   * 查询投诉协商历史API
+   * 商户可通过调用此接口,查询指定投诉的用户商户协商历史,以分页输出查询结果,方便商户根据处理历史来制定后续处理方案。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaNegotiationHistoryRequest} 请求数据 + * @return {@link WxMaNegotiationHistoryResult} 微信返回结果 + * @throws WxErrorException the wx error exception + */ + WxMaNegotiationHistoryResult queryNegotiationHistorys(WxMaNegotiationHistoryRequest request) throws WxErrorException; + + /** + *
+   * 创建投诉通知回调地址API
+   * 商户通过调用此接口创建投诉通知回调URL,当用户产生新投诉且投诉状态已变更时,微信会通过回调URL通知商户。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaComplaintNotifyUrlRequest} 请求数据 + * @return {@link WxMaComplaintNotifyUrlResult} 微信返回结果 + * @throws WxErrorException the wx error exception + */ + WxMaComplaintNotifyUrlResult addComplaintNotifyUrl(WxMaComplaintNotifyUrlRequest request) throws WxErrorException; + + /** + *
+   * 查询投诉通知回调地址API
+   * 商户通过调用此接口查询投诉通知的回调URL。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @return {@link WxMaComplaintNotifyUrlResult} 微信返回结果 + * @throws WxErrorException the wx error exception + */ + WxMaComplaintNotifyUrlResult getComplaintNotifyUrl() throws WxErrorException; + + /** + *
+   * 更新投诉通知回调地址API
+   * 商户通过调用此接口更新投诉通知的回调URL。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaComplaintNotifyUrlRequest} 请求数据 + * @return {@link WxMaComplaintNotifyUrlResult} 微信返回结果 + * @throws WxErrorException the wx error exception + */ + WxMaComplaintNotifyUrlResult updateComplaintNotifyUrl(WxMaComplaintNotifyUrlRequest request) throws WxErrorException; + + /** + *
+   * 删除投诉通知回调地址API
+   * 当商户不再需要推送通知时,可通过调用此接口删除投诉通知的回调URL,取消通知回调。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @throws WxErrorException the wx error exception + */ + void deleteComplaintNotifyUrl() throws WxErrorException; + + /** + *
+   * 提交回复API
+   * 商户可通过调用此接口,提交回复内容。其中上传图片凭证需首先调用商户上传反馈图片接口,得到图片id,再将id填入请求。
+   * 回复可配置文字链,传入跳转链接文案和跳转链接字段,用户点击即可跳转对应页面
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaResponseRequest} 请求数据 + * @throws WxErrorException the wx error exception + */ + void submitResponse(WxMaResponseRequest request) throws WxErrorException; + + /** + *
+   * 反馈处理完成API
+   * 商户可通过调用此接口,反馈投诉单已处理完成。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param request {@link WxMaCompleteRequest} 请求数据 + * @throws WxErrorException the wx error exception + */ + void complete(WxMaCompleteRequest request) throws WxErrorException; + + /** + *
+   * 商户上传反馈图片API
+   * 商户可通过调用此接口上传反馈图片凭证,上传成功后可在提交回复时使用。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param imageFile 需要上传的图片文件 + * @return String 微信返回的媒体文件标识Id + * @throws WxErrorException the wx error exception + * @throws IOException IO异常 + */ + String uploadResponseImage(File imageFile) throws WxErrorException, IOException; + + /** + *
+   * 商户上传反馈图片API
+   * 商户可通过调用此接口上传反馈图片凭证,上传成功后可在提交回复时使用。
+   * 文档详见: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ * + * @param inputStream 需要上传的图片文件流 + * @param fileName 需要上传的图片文件名 + * @return String 微信返回的媒体文件标识Id + * @throws WxErrorException the wx error exception + * @throws IOException IO异常 + */ + String uploadResponseImage(InputStream inputStream, String fileName) throws WxErrorException, IOException; +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java index ef3a46bad..1b556da81 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java @@ -605,4 +605,13 @@ WxMaApiResponse execute( * @return 同城配送服务对象WxMaIntracityService */ WxMaIntracityService getIntracityService(); + + /** + * 获取交易投诉服务对象。 + *
+ * 文档:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html + * + * @return 交易投诉服务对象WxMaComplaintService + */ + WxMaComplaintService getComplaintService(); } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java index ec33dede0..28acb3847 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/BaseWxMaServiceImpl.java @@ -165,6 +165,7 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH new WxMaExpressDeliveryReturnServiceImpl(this); private final WxMaPromotionService wxMaPromotionService = new WxMaPromotionServiceImpl(this); private final WxMaIntracityService intracityService = new WxMaIntracityServiceImpl(this); + private final WxMaComplaintService complaintService = new WxMaComplaintServiceImpl(this); private Map configMap = new HashMap<>(); private int retrySleepMillis = 1000; @@ -1030,4 +1031,9 @@ private String aesDecodeResponse(WxMaApiResponse response, String aad, SecretKey public WxMaIntracityService getIntracityService() { return this.intracityService; } + + @Override + public WxMaComplaintService getComplaintService() { + return this.complaintService; + } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaComplaintServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaComplaintServiceImpl.java new file mode 100644 index 000000000..c534bd693 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaComplaintServiceImpl.java @@ -0,0 +1,99 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaComplaintService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.complaint.*; +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.JsonObject; +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.common.bean.CommonUploadParam; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.fs.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.UUID; + +import static cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants.Complaint.*; + +/** + * 小程序交易投诉接口实现 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@RequiredArgsConstructor +public class WxMaComplaintServiceImpl implements WxMaComplaintService { + private static final String JSON_CONTENT_TYPE = "application/json"; + private final WxMaService wxMaService; + + @Override + public WxMaComplaintResult queryComplaints(WxMaComplaintRequest request) throws WxErrorException { + String responseContent = this.wxMaService.post(QUERY_COMPLAINTS_URL, request.toJson()); + return WxMaGsonBuilder.create().fromJson(responseContent, WxMaComplaintResult.class); + } + + @Override + public WxMaComplaintDetailResult getComplaint(WxMaComplaintDetailRequest request) throws WxErrorException { + String responseContent = this.wxMaService.post(GET_COMPLAINT_URL, request.toJson()); + return WxMaGsonBuilder.create().fromJson(responseContent, WxMaComplaintDetailResult.class); + } + + @Override + public WxMaNegotiationHistoryResult queryNegotiationHistorys(WxMaNegotiationHistoryRequest request) throws WxErrorException { + String responseContent = this.wxMaService.post(QUERY_NEGOTIATION_HISTORY_URL, request.toJson()); + return WxMaGsonBuilder.create().fromJson(responseContent, WxMaNegotiationHistoryResult.class); + } + + @Override + public WxMaComplaintNotifyUrlResult addComplaintNotifyUrl(WxMaComplaintNotifyUrlRequest request) throws WxErrorException { + String responseContent = this.wxMaService.post(ADD_COMPLAINT_NOTIFY_URL, request.toJson()); + return WxMaGsonBuilder.create().fromJson(responseContent, WxMaComplaintNotifyUrlResult.class); + } + + @Override + public WxMaComplaintNotifyUrlResult getComplaintNotifyUrl() throws WxErrorException { + String responseContent = this.wxMaService.get(GET_COMPLAINT_NOTIFY_URL, null); + return WxMaGsonBuilder.create().fromJson(responseContent, WxMaComplaintNotifyUrlResult.class); + } + + @Override + public WxMaComplaintNotifyUrlResult updateComplaintNotifyUrl(WxMaComplaintNotifyUrlRequest request) throws WxErrorException { + String responseContent = this.wxMaService.post(UPDATE_COMPLAINT_NOTIFY_URL, request.toJson()); + return WxMaGsonBuilder.create().fromJson(responseContent, WxMaComplaintNotifyUrlResult.class); + } + + @Override + public void deleteComplaintNotifyUrl() throws WxErrorException { + this.wxMaService.post(DELETE_COMPLAINT_NOTIFY_URL, "{}"); + } + + @Override + public void submitResponse(WxMaResponseRequest request) throws WxErrorException { + this.wxMaService.post(SUBMIT_RESPONSE_URL, request.toJson()); + } + + @Override + public void complete(WxMaCompleteRequest request) throws WxErrorException { + this.wxMaService.post(COMPLETE_COMPLAINT_URL, request.toJson()); + } + + @Override + public String uploadResponseImage(File imageFile) throws WxErrorException, IOException { + String result = this.wxMaService.upload(UPLOAD_RESPONSE_IMAGE_URL, + CommonUploadParam.fromFile("image", imageFile)); + JsonObject jsonResult = WxMaGsonBuilder.create().fromJson(result, JsonObject.class); + return jsonResult.get("media_id").getAsString(); + } + + @Override + public String uploadResponseImage(InputStream inputStream, String fileName) throws WxErrorException, IOException { + try { + return this.uploadResponseImage(FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileName)); + } catch (IOException e) { + throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e); + } + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailRequest.java new file mode 100644 index 000000000..759f7392b --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailRequest.java @@ -0,0 +1,38 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 小程序投诉单详情请求实体 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class WxMaComplaintDetailRequest implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+   * 字段名:投诉单号
+   * 是否必填:是
+   * 描述:投诉单对应的投诉单号
+   * 
+ */ + @SerializedName("complaint_id") + private String complaintId; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailResult.java new file mode 100644 index 000000000..52a0be170 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintDetailResult.java @@ -0,0 +1,166 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.bean.WxMaBaseResponse; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.List; + +/** + * 小程序投诉单详情结果 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMaComplaintDetailResult extends WxMaBaseResponse { + + /** + *
+   * 字段名:投诉单号
+   * 是否必填:是
+   * 描述:投诉单对应的投诉单号
+   * 
+ */ + @SerializedName("complaint_id") + private String complaintId; + + /** + *
+   * 字段名:投诉时间
+   * 是否必填:是
+   * 描述:用户提交投诉的时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE
+   * 
+ */ + @SerializedName("complaint_time") + private String complaintTime; + + /** + *
+   * 字段名:投诉详情
+   * 是否必填:是
+   * 描述:用户提交的投诉详情
+   * 
+ */ + @SerializedName("complaint_detail") + private String complaintDetail; + + /** + *
+   * 字段名:投诉状态
+   * 是否必填:是
+   * 描述:投诉单状态:WAITING_MERCHANT_RESPONSE-等待商户回复 MERCHANT_RESPONSED-商户已回复 WAITING_USER_RESPONSE-等待用户回复 USER_RESPONSED-用户已回复 COMPLAINT_COMPLETED-投诉已完成
+   * 
+ */ + @SerializedName("complaint_state") + private String complaintState; + + /** + *
+   * 字段名:投诉人openid
+   * 是否必填:是
+   * 描述:投诉人在小程序的openid
+   * 
+ */ + @SerializedName("openid") + private String openid; + + /** + *
+   * 字段名:投诉人联系方式
+   * 是否必填:否
+   * 描述:投诉人联系方式,可能为空
+   * 
+ */ + @SerializedName("phone_number") + private String phoneNumber; + + /** + *
+   * 字段名:被投诉订单信息
+   * 是否必填:是
+   * 描述:被投诉的订单信息
+   * 
+ */ + @SerializedName("complaint_order_info") + private ComplaintOrderInfo complaintOrderInfo; + + /** + *
+   * 字段名:投诉材料
+   * 是否必填:否
+   * 描述:用户上传的投诉相关的图片凭证
+   * 
+ */ + @SerializedName("complaint_media_list") + private List complaintMediaList; + + /** + * 被投诉订单信息 + */ + @Data + public static class ComplaintOrderInfo implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+     * 字段名:商户订单号
+     * 是否必填:是
+     * 描述:商户系统内部订单号
+     * 
+ */ + @SerializedName("transaction_id") + private String transactionId; + + /** + *
+     * 字段名:微信订单号
+     * 是否必填:是
+     * 描述:微信支付系统生成的订单号
+     * 
+ */ + @SerializedName("out_trade_no") + private String outTradeNo; + + /** + *
+     * 字段名:订单金额
+     * 是否必填:是
+     * 描述:订单金额,单位为分
+     * 
+ */ + @SerializedName("amount") + private Integer amount; + } + + /** + * 投诉材料 + */ + @Data + public static class ComplaintMedia implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+     * 字段名:媒体文件业务类型
+     * 是否必填:是
+     * 描述:媒体文件对应的业务类型:USER_COMPLAINT_IMAGE-用户投诉图片
+     * 
+ */ + @SerializedName("media_type") + private String mediaType; + + /** + *
+     * 字段名:媒体文件请求URL
+     * 是否必填:是
+     * 描述:微信返回的媒体文件请求URL,通过该URL可以获取到对应的媒体文件(图片、视频等)
+     * 
+ */ + @SerializedName("media_url") + private String mediaUrl; + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlRequest.java new file mode 100644 index 000000000..6af338c97 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlRequest.java @@ -0,0 +1,38 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 小程序投诉通知回调URL请求实体 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class WxMaComplaintNotifyUrlRequest implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+   * 字段名:通知地址
+   * 是否必填:是
+   * 描述:通知地址,仅支持https
+   * 
+ */ + @SerializedName("url") + private String url; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlResult.java new file mode 100644 index 000000000..7771998b8 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintNotifyUrlResult.java @@ -0,0 +1,37 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.bean.WxMaBaseResponse; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 小程序投诉通知回调URL结果 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMaComplaintNotifyUrlResult extends WxMaBaseResponse { + + /** + *
+   * 字段名:通知地址
+   * 是否必填:是
+   * 描述:通知地址,仅支持https
+   * 
+ */ + @SerializedName("url") + private String url; + + /** + *
+   * 字段名:签名串
+   * 是否必填:是
+   * 描述:用于验证通知消息的签名串
+   * 
+ */ + @SerializedName("signature") + private String signature; +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java new file mode 100644 index 000000000..78e6effa1 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java @@ -0,0 +1,68 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 小程序交易投诉查询请求实体 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class WxMaComplaintRequest implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+   * 字段名:开始日期
+   * 是否必填:是
+   * 描述:查询的起始时间,格式为YYYY-MM-DD,例如2021-01-01
+   * 
+ */ + @SerializedName("begin_date") + private String beginDate; + + /** + *
+   * 字段名:结束日期
+   * 是否必填:是
+   * 描述:查询的结束时间,格式为YYYY-MM-DD,例如2021-01-31
+   * 
+ */ + @SerializedName("end_date") + private String endDate; + + /** + *
+   * 字段名:分页大小
+   * 是否必填:否
+   * 描述:单次拉取条目,最大为50,不传默认为10
+   * 
+ */ + @SerializedName("limit") + private Integer limit = 10; + + /** + *
+   * 字段名:分页开始位置
+   * 是否必填:否
+   * 描述:该次请求的分页开始位置,从0开始计数,例如offset=10,表示从第11条记录开始返回,不传默认为0
+   * 
+ */ + @SerializedName("offset") + private Integer offset = 0; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintResult.java new file mode 100644 index 000000000..0e4208fdc --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintResult.java @@ -0,0 +1,156 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.bean.WxMaBaseResponse; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.List; + +/** + * 小程序交易投诉查询结果 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMaComplaintResult extends WxMaBaseResponse { + + /** + *
+   * 字段名:投诉单信息
+   * 是否必填:是
+   * 描述:查询返回的投诉单信息
+   * 
+ */ + @SerializedName("data") + private List data; + + /** + *
+   * 字段名:总数
+   * 是否必填:是
+   * 描述:总投诉单条数,用于分页展示
+   * 
+ */ + @SerializedName("total_count") + private Integer totalCount; + + /** + * 投诉单信息 + */ + @Data + public static class Complaint implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+     * 字段名:投诉单号
+     * 是否必填:是
+     * 描述:投诉单对应的投诉单号
+     * 
+ */ + @SerializedName("complaint_id") + private String complaintId; + + /** + *
+     * 字段名:投诉时间
+     * 是否必填:是
+     * 描述:用户提交投诉的时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE
+     * 
+ */ + @SerializedName("complaint_time") + private String complaintTime; + + /** + *
+     * 字段名:投诉详情
+     * 是否必填:是
+     * 描述:用户提交的投诉详情
+     * 
+ */ + @SerializedName("complaint_detail") + private String complaintDetail; + + /** + *
+     * 字段名:投诉状态
+     * 是否必填:是
+     * 描述:投诉单状态:WAITING_MERCHANT_RESPONSE-等待商户回复 MERCHANT_RESPONSED-商户已回复 WAITING_USER_RESPONSE-等待用户回复 USER_RESPONSED-用户已回复 COMPLAINT_COMPLETED-投诉已完成
+     * 
+ */ + @SerializedName("complaint_state") + private String complaintState; + + /** + *
+     * 字段名:投诉人openid
+     * 是否必填:是
+     * 描述:投诉人在小程序的openid
+     * 
+ */ + @SerializedName("openid") + private String openid; + + /** + *
+     * 字段名:投诉人联系方式
+     * 是否必填:否
+     * 描述:投诉人联系方式,可能为空
+     * 
+ */ + @SerializedName("phone_number") + private String phoneNumber; + + /** + *
+     * 字段名:被投诉订单信息
+     * 是否必填:是
+     * 描述:被投诉的订单信息
+     * 
+ */ + @SerializedName("complaint_order_info") + private ComplaintOrderInfo complaintOrderInfo; + } + + /** + * 被投诉订单信息 + */ + @Data + public static class ComplaintOrderInfo implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+     * 字段名:商户订单号
+     * 是否必填:是
+     * 描述:商户系统内部订单号
+     * 
+ */ + @SerializedName("transaction_id") + private String transactionId; + + /** + *
+     * 字段名:微信订单号
+     * 是否必填:是
+     * 描述:微信支付系统生成的订单号
+     * 
+ */ + @SerializedName("out_trade_no") + private String outTradeNo; + + /** + *
+     * 字段名:订单金额
+     * 是否必填:是
+     * 描述:订单金额,单位为分
+     * 
+ */ + @SerializedName("amount") + private Integer amount; + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaCompleteRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaCompleteRequest.java new file mode 100644 index 000000000..71d106602 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaCompleteRequest.java @@ -0,0 +1,38 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 小程序反馈处理完成请求实体 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class WxMaCompleteRequest implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+   * 字段名:投诉单号
+   * 是否必填:是
+   * 描述:投诉单对应的投诉单号
+   * 
+ */ + @SerializedName("complaint_id") + private String complaintId; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java new file mode 100644 index 000000000..c8e23bdc3 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java @@ -0,0 +1,58 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 小程序查询投诉协商历史请求实体 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class WxMaNegotiationHistoryRequest implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+   * 字段名:投诉单号
+   * 是否必填:是
+   * 描述:投诉单对应的投诉单号
+   * 
+ */ + @SerializedName("complaint_id") + private String complaintId; + + /** + *
+   * 字段名:分页大小
+   * 是否必填:否
+   * 描述:单次拉取条目,最大为50,不传默认为10
+   * 
+ */ + @SerializedName("limit") + private Integer limit = 10; + + /** + *
+   * 字段名:分页开始位置
+   * 是否必填:否
+   * 描述:该次请求的分页开始位置,从0开始计数,例如offset=10,表示从第11条记录开始返回,不传默认为0
+   * 
+ */ + @SerializedName("offset") + private Integer offset = 0; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryResult.java new file mode 100644 index 000000000..194daca9f --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryResult.java @@ -0,0 +1,88 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.bean.WxMaBaseResponse; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serializable; +import java.util.List; + +/** + * 小程序查询投诉协商历史结果 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMaNegotiationHistoryResult extends WxMaBaseResponse { + + /** + *
+   * 字段名:协商历史
+   * 是否必填:是
+   * 描述:协商历史记录
+   * 
+ */ + @SerializedName("data") + private List data; + + /** + *
+   * 字段名:总数
+   * 是否必填:是
+   * 描述:总协商历史条数,用于分页展示
+   * 
+ */ + @SerializedName("total_count") + private Integer totalCount; + + /** + * 协商历史 + */ + @Data + public static class NegotiationHistory implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+     * 字段名:操作时间
+     * 是否必填:是
+     * 描述:操作时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE
+     * 
+ */ + @SerializedName("operate_time") + private String operateTime; + + /** + *
+     * 字段名:操作类型
+     * 是否必填:是
+     * 描述:操作类型:USER_CREATE_COMPLAINT-用户提交投诉 USER_CONTINUE_COMPLAINT-用户继续投诉 MERCHANT_RESPONSE-商户回复 MERCHANT_CONFIRM_COMPLETE-商户确认完成处理
+     * 
+ */ + @SerializedName("operate_type") + private String operateType; + + /** + *
+     * 字段名:操作内容
+     * 是否必填:是
+     * 描述:具体的操作内容
+     * 
+ */ + @SerializedName("operate_details") + private String operateDetails; + + /** + *
+     * 字段名:图片凭证
+     * 是否必填:否
+     * 描述:操作过程中上传的图片凭证
+     * 
+ */ + @SerializedName("image_list") + private List imageList; + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaResponseRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaResponseRequest.java new file mode 100644 index 000000000..b4033c4f3 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaResponseRequest.java @@ -0,0 +1,79 @@ +package cn.binarywang.wx.miniapp.bean.complaint; + +import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 小程序提交回复请求实体 + * + * @author Binary Wang + * created on 2025-01-01 + */ +@Data +@Builder(builderMethodName = "newBuilder") +@NoArgsConstructor +@AllArgsConstructor +public class WxMaResponseRequest implements Serializable { + private static final long serialVersionUID = 3244929701614280806L; + + /** + *
+   * 字段名:投诉单号
+   * 是否必填:是
+   * 描述:投诉单对应的投诉单号
+   * 
+ */ + @SerializedName("complaint_id") + private String complaintId; + + /** + *
+   * 字段名:回复内容
+   * 是否必填:是
+   * 描述:具体的回复内容,长度不超过200字符
+   * 
+ */ + @SerializedName("response_content") + private String responseContent; + + /** + *
+   * 字段名:回复图片
+   * 是否必填:否
+   * 描述:回复的图片凭证,最多可传5张图片,由图片上传接口返回
+   * 
+ */ + @SerializedName("response_images") + private List responseImages; + + /** + *
+   * 字段名:跳转链接
+   * 是否必填:否
+   * 描述:点击跳转链接
+   * 
+ */ + @SerializedName("jump_url") + private String jumpUrl; + + /** + *
+   * 字段名:跳转链接文案
+   * 是否必填:否
+   * 描述:跳转链接文案,在response_content中展示的跳转链接文案,长度不超过10个字符
+   * 
+ */ + @SerializedName("jump_url_text") + private String jumpUrlText; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} \ No newline at end of file diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java index 79806dbd8..ea9b123fb 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaApiUrlConstants.java @@ -964,4 +964,34 @@ public interface Intracity { String GET_CITY = "https://api.weixin.qq.com/cgi-bin/express/intracity/getcity"; } + + /** + * 小程序交易投诉接口 + * + *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/business-capabilities/guarantee/complaint.html
+   * 
+ */ + public interface Complaint { + /** 查询投诉单列表 */ + String QUERY_COMPLAINTS_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/list"; + /** 查询投诉单详情 */ + String GET_COMPLAINT_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/detail"; + /** 查询投诉协商历史 */ + String QUERY_NEGOTIATION_HISTORY_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/negotiation/history"; + /** 创建投诉通知回调地址 */ + String ADD_COMPLAINT_NOTIFY_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/notify/add"; + /** 查询投诉通知回调地址 */ + String GET_COMPLAINT_NOTIFY_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/notify/get"; + /** 更新投诉通知回调地址 */ + String UPDATE_COMPLAINT_NOTIFY_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/notify/update"; + /** 删除投诉通知回调地址 */ + String DELETE_COMPLAINT_NOTIFY_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/notify/delete"; + /** 提交回复 */ + String SUBMIT_RESPONSE_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/response"; + /** 反馈处理完成 */ + String COMPLETE_COMPLAINT_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/complete"; + /** 上传反馈图片 */ + String UPLOAD_RESPONSE_IMAGE_URL = "https://api.weixin.qq.com/cgi-bin/miniapp/complaint/upload"; + } } From 4baa9b5371c5203883751f8b9c3a8da43714fbfb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 31 Aug 2025 15:10:41 +0000 Subject: [PATCH 3/3] Fix @Builder.Default warnings in complaint service bean classes Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wx/miniapp/bean/complaint/WxMaComplaintRequest.java | 2 ++ .../miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java index 78e6effa1..9ac45e0c1 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaComplaintRequest.java @@ -50,6 +50,7 @@ public class WxMaComplaintRequest implements Serializable { * */ @SerializedName("limit") + @Builder.Default private Integer limit = 10; /** @@ -60,6 +61,7 @@ public class WxMaComplaintRequest implements Serializable { * */ @SerializedName("offset") + @Builder.Default private Integer offset = 0; public String toJson() { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java index c8e23bdc3..a03742b6a 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/complaint/WxMaNegotiationHistoryRequest.java @@ -40,6 +40,7 @@ public class WxMaNegotiationHistoryRequest implements Serializable { * */ @SerializedName("limit") + @Builder.Default private Integer limit = 10; /** @@ -50,6 +51,7 @@ public class WxMaNegotiationHistoryRequest implements Serializable { * */ @SerializedName("offset") + @Builder.Default private Integer offset = 0; public String toJson() {