From 8b752b0501b7235d3dc43fef1d4c6e4b05fe91a7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 31 Aug 2025 14:49:15 +0000
Subject: [PATCH 1/3] Initial plan
From a40a92b96b37999f2b8a0b5f89f5ddfc8b6adfb4 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 31 Aug 2025 15:01:42 +0000
Subject: [PATCH 2/3] Add basic Mini Program customer service management
 interfaces
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
---
 .../wx/miniapp/api/WxMaKefuService.java       | 128 ++++++++++++++++++
 .../wx/miniapp/api/WxMaService.java           |   7 +
 .../miniapp/api/impl/BaseWxMaServiceImpl.java |   6 +
 .../miniapp/api/impl/WxMaKefuServiceImpl.java |  92 +++++++++++++
 .../wx/miniapp/bean/kefu/WxMaKfInfo.java      |  79 +++++++++++
 .../wx/miniapp/bean/kefu/WxMaKfList.java      |  35 +++++
 .../wx/miniapp/bean/kefu/WxMaKfSession.java   |  43 ++++++
 .../miniapp/bean/kefu/WxMaKfSessionList.java  |  61 +++++++++
 .../kefu/request/WxMaKfAccountRequest.java    |  49 +++++++
 .../kefu/request/WxMaKfSessionRequest.java    |  43 ++++++
 10 files changed, 543 insertions(+)
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaKefuService.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImpl.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfInfo.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfList.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfSession.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfSessionList.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfAccountRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfSessionRequest.java
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaKefuService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaKefuService.java
new file mode 100644
index 000000000..b8b5a0380
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaKefuService.java
@@ -0,0 +1,128 @@
+package cn.binarywang.wx.miniapp.api;
+
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfInfo;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfList;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSession;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSessionList;
+import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfAccountRequest;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 
+ * 小程序客服管理接口.
+ * 不同于 WxMaCustomserviceWorkService (企业微信客服绑定) 和 WxMaMsgService.sendKefuMsg (发送客服消息),
+ * 此接口专门处理小程序客服账号管理、会话管理等功能。
+ * 
+ * 注意:小程序客服管理接口与公众号客服管理接口在API端点和功能上有所不同。
+ * 
+ *
+ * @author Binary Wang
+ */
+public interface WxMaKefuService {
+
+  /**
+   * 
+   * 获取客服基本信息
+   * 详情请见:获取客服基本信息
+   * 接口url格式:https://api.weixin.qq.com/cgi-bin/customservice/getkflist?access_token=ACCESS_TOKEN
+   * 
+   *
+   * @return 客服列表
+   * @throws WxErrorException 异常
+   */
+  WxMaKfList kfList() throws WxErrorException;
+
+  /**
+   * 
+   * 添加客服账号
+   * 详情请见:添加客服账号
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/add?access_token=ACCESS_TOKEN
+   * 
+   *
+   * @param request 客服账号信息
+   * @return 是否成功
+   * @throws WxErrorException 异常
+   */
+  boolean kfAccountAdd(WxMaKfAccountRequest request) throws WxErrorException;
+
+  /**
+   * 
+   * 修改客服账号
+   * 详情请见:修改客服账号
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/update?access_token=ACCESS_TOKEN
+   * 
+   *
+   * @param request 客服账号信息
+   * @return 是否成功
+   * @throws WxErrorException 异常
+   */
+  boolean kfAccountUpdate(WxMaKfAccountRequest request) throws WxErrorException;
+
+  /**
+   * 
+   * 删除客服账号
+   * 详情请见:删除客服账号
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfaccount/del?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
+   * 
+   *
+   * @param kfAccount 客服账号
+   * @return 是否成功
+   * @throws WxErrorException 异常
+   */
+  boolean kfAccountDel(String kfAccount) throws WxErrorException;
+
+  /**
+   * 
+   * 创建会话
+   * 详情请见:创建会话
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfsession/create?access_token=ACCESS_TOKEN
+   * 
+   *
+   * @param openid 用户openid
+   * @param kfAccount 客服账号
+   * @return 是否成功
+   * @throws WxErrorException 异常
+   */
+  boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException;
+
+  /**
+   * 
+   * 关闭会话
+   * 详情请见:关闭会话
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfsession/close?access_token=ACCESS_TOKEN
+   * 
+   *
+   * @param openid 用户openid
+   * @param kfAccount 客服账号
+   * @return 是否成功
+   * @throws WxErrorException 异常
+   */
+  boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException;
+
+  /**
+   * 
+   * 获取客户的会话状态
+   * 详情请见:获取客户的会话状态
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfsession/getsession?access_token=ACCESS_TOKEN&openid=OPENID
+   * 
+   *
+   * @param openid 用户openid
+   * @return 会话信息
+   * @throws WxErrorException 异常
+   */
+  WxMaKfSession kfSessionGet(String openid) throws WxErrorException;
+
+  /**
+   * 
+   * 获取客服的会话列表
+   * 详情请见:获取客服的会话列表
+   * 接口url格式:https://api.weixin.qq.com/customservice/kfsession/getsessionlist?access_token=ACCESS_TOKEN&kf_account=KFACCOUNT
+   * 
+   *
+   * @param kfAccount 客服账号
+   * @return 会话列表
+   * @throws WxErrorException 异常
+   */
+  WxMaKfSessionList kfSessionList(String kfAccount) throws WxErrorException;
+
+}
\ 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..cadff9564 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
@@ -285,6 +285,13 @@ WxMaApiResponse execute(
    */
   WxMaCustomserviceWorkService getCustomserviceWorkService();
 
+  /**
+   * 获取小程序客服管理服务。
+   *
+   * @return                 客服管理服务对象WxMaKefuService
+   */
+  WxMaKefuService getKefuService();
+
   /**
    * 获取jsapi操作相关服务对象。
    *
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..c7e9f5687 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
@@ -113,6 +113,7 @@ public abstract class BaseWxMaServiceImpl implements WxMaService, RequestH
   private final WxMaAnalysisService analysisService = new WxMaAnalysisServiceImpl(this);
   private final WxMaCodeService codeService = new WxMaCodeServiceImpl(this);
   private final WxMaCustomserviceWorkService customserviceWorkService = new WxMaCustomserviceWorkServiceImpl(this);
+  private final WxMaKefuService maKefuService = new WxMaKefuServiceImpl(this);
   private final WxMaInternetService internetService = new WxMaInternetServiceImpl(this);
   private final WxMaSettingService settingService = new WxMaSettingServiceImpl(this);
   private final WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this);
@@ -657,6 +658,11 @@ public WxMaCustomserviceWorkService getCustomserviceWorkService() {
     return this.customserviceWorkService;
   }
 
+  @Override
+  public WxMaKefuService getKefuService() {
+    return this.maKefuService;
+  }
+
   @Override
   public WxMaJsapiService getJsapiService() {
     return this.jsapiService;
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImpl.java
new file mode 100644
index 000000000..2fa39603a
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImpl.java
@@ -0,0 +1,92 @@
+package cn.binarywang.wx.miniapp.api.impl;
+
+import cn.binarywang.wx.miniapp.api.WxMaKefuService;
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfInfo;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfList;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSession;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSessionList;
+import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfAccountRequest;
+import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfSessionRequest;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 小程序客服管理服务实现.
+ *
+ * @author Binary Wang
+ */
+@RequiredArgsConstructor
+public class WxMaKefuServiceImpl implements WxMaKefuService {
+
+  // 小程序客服管理接口URL
+  private static final String KFLIST_GET_URL = "https://api.weixin.qq.com/cgi-bin/customservice/getkflist";
+  private static final String KFACCOUNT_ADD_URL = "https://api.weixin.qq.com/customservice/kfaccount/add";
+  private static final String KFACCOUNT_UPDATE_URL = "https://api.weixin.qq.com/customservice/kfaccount/update";
+  private static final String KFACCOUNT_DEL_URL = "https://api.weixin.qq.com/customservice/kfaccount/del?kf_account=%s";
+  private static final String KFSESSION_CREATE_URL = "https://api.weixin.qq.com/customservice/kfsession/create";
+  private static final String KFSESSION_CLOSE_URL = "https://api.weixin.qq.com/customservice/kfsession/close";
+  private static final String KFSESSION_GET_URL = "https://api.weixin.qq.com/customservice/kfsession/getsession?openid=%s";
+  private static final String KFSESSION_LIST_URL = "https://api.weixin.qq.com/customservice/kfsession/getsessionlist?kf_account=%s";
+
+  private final WxMaService service;
+
+  @Override
+  public WxMaKfList kfList() throws WxErrorException {
+    String responseContent = this.service.get(KFLIST_GET_URL, null);
+    return WxMaKfList.fromJson(responseContent);
+  }
+
+  @Override
+  public boolean kfAccountAdd(WxMaKfAccountRequest request) throws WxErrorException {
+    String responseContent = this.service.post(KFACCOUNT_ADD_URL, request.toJson());
+    return responseContent != null;
+  }
+
+  @Override
+  public boolean kfAccountUpdate(WxMaKfAccountRequest request) throws WxErrorException {
+    String responseContent = this.service.post(KFACCOUNT_UPDATE_URL, request.toJson());
+    return responseContent != null;
+  }
+
+  @Override
+  public boolean kfAccountDel(String kfAccount) throws WxErrorException {
+    String url = String.format(KFACCOUNT_DEL_URL, kfAccount);
+    String responseContent = this.service.get(url, null);
+    return responseContent != null;
+  }
+
+  @Override
+  public boolean kfSessionCreate(String openid, String kfAccount) throws WxErrorException {
+    WxMaKfSessionRequest request = WxMaKfSessionRequest.builder()
+        .kfAccount(kfAccount)
+        .openid(openid)
+        .build();
+    String responseContent = this.service.post(KFSESSION_CREATE_URL, request.toJson());
+    return responseContent != null;
+  }
+
+  @Override
+  public boolean kfSessionClose(String openid, String kfAccount) throws WxErrorException {
+    WxMaKfSessionRequest request = WxMaKfSessionRequest.builder()
+        .kfAccount(kfAccount)
+        .openid(openid)
+        .build();
+    String responseContent = this.service.post(KFSESSION_CLOSE_URL, request.toJson());
+    return responseContent != null;
+  }
+
+  @Override
+  public WxMaKfSession kfSessionGet(String openid) throws WxErrorException {
+    String url = String.format(KFSESSION_GET_URL, openid);
+    String responseContent = this.service.get(url, null);
+    return WxMaKfSession.fromJson(responseContent);
+  }
+
+  @Override
+  public WxMaKfSessionList kfSessionList(String kfAccount) throws WxErrorException {
+    String url = String.format(KFSESSION_LIST_URL, kfAccount);
+    String responseContent = this.service.get(url, null);
+    return WxMaKfSessionList.fromJson(responseContent);
+  }
+}
\ No newline at end of file
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfInfo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfInfo.java
new file mode 100644
index 000000000..476056d51
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfInfo.java
@@ -0,0 +1,79 @@
+package cn.binarywang.wx.miniapp.bean.kefu;
+
+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
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMaKfInfo implements Serializable {
+  private static final long serialVersionUID = -7916302137791763175L;
+
+  /**
+   * 客服账号.
+   */
+  @SerializedName("kf_account")
+  private String kfAccount;
+
+  /**
+   * 客服昵称.
+   */
+  @SerializedName("kf_nick")
+  private String kfNick;
+
+  /**
+   * 客服密码.
+   */
+  @SerializedName("kf_id")
+  private String kfId;
+
+  /**
+   * 客服头像.
+   */
+  @SerializedName("kf_headimgurl")
+  private String kfHeadImgUrl;
+
+  /**
+   * 如果客服帐号已绑定了客服人员微信号,则此处显示微信号.
+   */
+  @SerializedName("kf_wx")
+  private String kfWx;
+
+  /**
+   * 如果客服帐号尚未绑定微信号,但是已经发起了一个绑定邀请,则此处显示绑定邀请的微信号.
+   */
+  @SerializedName("invite_wx")
+  private String inviteWx;
+
+  /**
+   * 邀请的状态,有等待确认"waiting",被拒绝"rejected",过期"expired".
+   */
+  @SerializedName("invite_expire_time")
+  private Long inviteExpireTime;
+
+  /**
+   * 邀请的过期时间,为unix时间戳.
+   */
+  @SerializedName("invite_status")
+  private String inviteStatus;
+
+  public static WxMaKfInfo fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaKfInfo.class);
+  }
+
+  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/kefu/WxMaKfList.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfList.java
new file mode 100644
index 000000000..8dd87a172
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfList.java
@@ -0,0 +1,35 @@
+package cn.binarywang.wx.miniapp.bean.kefu;
+
+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
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMaKfList implements Serializable {
+  private static final long serialVersionUID = 6416633293297389972L;
+
+  @SerializedName("kf_list")
+  private List kfList;
+
+  public static WxMaKfList fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaKfList.class);
+  }
+
+  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/kefu/WxMaKfSession.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfSession.java
new file mode 100644
index 000000000..60c010499
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfSession.java
@@ -0,0 +1,43 @@
+package cn.binarywang.wx.miniapp.bean.kefu;
+
+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
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMaKfSession implements Serializable {
+  private static final long serialVersionUID = -6987567952389036965L;
+
+  /**
+   * 正在接待的客服,为空表示没有人在接待.
+   */
+  @SerializedName("kf_account")
+  private String kfAccount;
+
+  /**
+   * 会话接入的时间.
+   */
+  @SerializedName("createtime")
+  private Long createTime;
+
+  public static WxMaKfSession fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaKfSession.class);
+  }
+
+  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/kefu/WxMaKfSessionList.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfSessionList.java
new file mode 100644
index 000000000..e172e2e4e
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/WxMaKfSessionList.java
@@ -0,0 +1,61 @@
+package cn.binarywang.wx.miniapp.bean.kefu;
+
+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
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMaKfSessionList implements Serializable {
+  private static final long serialVersionUID = -1538600729426188776L;
+
+  @SerializedName("sessionlist")
+  private List sessionList;
+
+  @Data
+  @Builder
+  @NoArgsConstructor
+  @AllArgsConstructor
+  public static class SessionInfo implements Serializable {
+    private static final long serialVersionUID = -2077261313274513580L;
+
+    /**
+     * 粉丝的openid.
+     */
+    @SerializedName("openid")
+    private String openid;
+
+    /**
+     * 会话创建时间,UNIX时间戳.
+     */
+    @SerializedName("createtime")
+    private Long createTime;
+
+    /**
+     * 粉丝的最后一条消息的时间,UNIX时间戳.
+     */
+    @SerializedName("latest_time")
+    private Long latestTime;
+  }
+
+  public static WxMaKfSessionList fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaKfSessionList.class);
+  }
+
+  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/kefu/request/WxMaKfAccountRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfAccountRequest.java
new file mode 100644
index 000000000..0ad891363
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfAccountRequest.java
@@ -0,0 +1,49 @@
+package cn.binarywang.wx.miniapp.bean.kefu.request;
+
+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
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMaKfAccountRequest implements Serializable {
+  private static final long serialVersionUID = -4953504451749066635L;
+
+  /**
+   * 客服账号.
+   */
+  @SerializedName("kf_account")
+  private String kfAccount;
+
+  /**
+   * 客服昵称.
+   */
+  @SerializedName("kf_nick")
+  private String kfNick;
+
+  /**
+   * 客服密码.
+   */
+  @SerializedName("kf_pwd")
+  private String kfPwd;
+
+  public String toJson() {
+    return WxMaGsonBuilder.create().toJson(this);
+  }
+
+  public static WxMaKfAccountRequest fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaKfAccountRequest.class);
+  }
+}
\ No newline at end of file
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfSessionRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfSessionRequest.java
new file mode 100644
index 000000000..f8180f926
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/kefu/request/WxMaKfSessionRequest.java
@@ -0,0 +1,43 @@
+package cn.binarywang.wx.miniapp.bean.kefu.request;
+
+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
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WxMaKfSessionRequest implements Serializable {
+  private static final long serialVersionUID = -3278295399203344398L;
+
+  /**
+   * 客服账号.
+   */
+  @SerializedName("kf_account")
+  private String kfAccount;
+
+  /**
+   * 用户openid.
+   */
+  @SerializedName("openid")
+  private String openid;
+
+  public String toJson() {
+    return WxMaGsonBuilder.create().toJson(this);
+  }
+
+  public static WxMaKfSessionRequest fromJson(String json) {
+    return WxMaGsonBuilder.create().fromJson(json, WxMaKfSessionRequest.class);
+  }
+}
\ No newline at end of file
From f50612b6fa4966105874e8a3337803a2ddc1b668 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 31 Aug 2025 15:05:58 +0000
Subject: [PATCH 3/3] Complete Mini Program customer service management
 implementation with tests and documentation
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
---
 MINIAPP_KEFU_SERVICE.md                       | 80 ++++++++++++++++++
 .../api/impl/WxMaKefuServiceImplTest.java     | 60 +++++++++++++
 .../wx/miniapp/demo/WxMaKefuServiceDemo.java  | 84 +++++++++++++++++++
 3 files changed, 224 insertions(+)
 create mode 100644 MINIAPP_KEFU_SERVICE.md
 create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImplTest.java
 create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaKefuServiceDemo.java
diff --git a/MINIAPP_KEFU_SERVICE.md b/MINIAPP_KEFU_SERVICE.md
new file mode 100644
index 000000000..96cf4c383
--- /dev/null
+++ b/MINIAPP_KEFU_SERVICE.md
@@ -0,0 +1,80 @@
+# WeChat Mini Program Customer Service Management
+
+This document describes the new customer service management functionality added to the WxJava Mini Program SDK.
+
+## Overview
+
+Previously, the mini program module only had:
+- `WxMaCustomserviceWorkService` - For binding mini programs to enterprise WeChat customer service
+- `WxMaMsgService.sendKefuMsg()` - For sending customer service messages
+
+The new `WxMaKefuService` adds comprehensive customer service management capabilities:
+
+## Features
+
+### Customer Service Account Management
+- `kfList()` - Get list of customer service accounts
+- `kfAccountAdd()` - Add new customer service account  
+- `kfAccountUpdate()` - Update customer service account
+- `kfAccountDel()` - Delete customer service account
+
+### Session Management
+- `kfSessionCreate()` - Create customer service session
+- `kfSessionClose()` - Close customer service session
+- `kfSessionGet()` - Get customer session status
+- `kfSessionList()` - Get customer service session list
+
+## Usage Example
+
+```java
+// Get the customer service management service
+WxMaKefuService kefuService = wxMaService.getKefuService();
+
+// Add a new customer service account
+WxMaKfAccountRequest request = WxMaKfAccountRequest.builder()
+    .kfAccount("service001@example")
+    .kfNick("Customer Service 001")
+    .kfPwd("password123")
+    .build();
+boolean result = kefuService.kfAccountAdd(request);
+
+// Create a session between user and customer service
+boolean sessionResult = kefuService.kfSessionCreate("user_openid", "service001@example");
+
+// Get customer service list
+WxMaKfList kfList = kefuService.kfList();
+```
+
+## Bean Classes
+
+### Request Objects
+- `WxMaKfAccountRequest` - For customer service account operations
+- `WxMaKfSessionRequest` - For session operations
+
+### Response Objects  
+- `WxMaKfInfo` - Customer service account information
+- `WxMaKfList` - List of customer service accounts
+- `WxMaKfSession` - Session information
+- `WxMaKfSessionList` - List of sessions
+
+## API Endpoints
+
+The service uses the following WeChat Mini Program API endpoints:
+- `https://api.weixin.qq.com/cgi-bin/customservice/getkflist` - Get customer service list
+- `https://api.weixin.qq.com/customservice/kfaccount/add` - Add customer service account
+- `https://api.weixin.qq.com/customservice/kfaccount/update` - Update customer service account
+- `https://api.weixin.qq.com/customservice/kfaccount/del` - Delete customer service account
+- `https://api.weixin.qq.com/customservice/kfsession/create` - Create session
+- `https://api.weixin.qq.com/customservice/kfsession/close` - Close session
+- `https://api.weixin.qq.com/customservice/kfsession/getsession` - Get session
+- `https://api.weixin.qq.com/customservice/kfsession/getsessionlist` - Get session list
+
+## Integration
+
+The service is automatically available through the main `WxMaService` interface:
+
+```java
+WxMaKefuService kefuService = wxMaService.getKefuService();
+```
+
+This fills the gap mentioned in the original issue and provides full customer service management capabilities for WeChat Mini Programs.
\ No newline at end of file
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImplTest.java
new file mode 100644
index 000000000..456aca93f
--- /dev/null
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaKefuServiceImplTest.java
@@ -0,0 +1,60 @@
+package cn.binarywang.wx.miniapp.api.impl;
+
+import cn.binarywang.wx.miniapp.api.WxMaKefuService;
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfList;
+import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfAccountRequest;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * 小程序客服管理服务测试.
+ *
+ * @author Binary Wang
+ */
+public class WxMaKefuServiceImplTest {
+
+  @Test
+  public void testKfList() throws WxErrorException {
+    WxMaService service = mock(WxMaService.class);
+    when(service.get(anyString(), any())).thenReturn("{\"kf_list\":[]}");
+
+    WxMaKefuService kefuService = new WxMaKefuServiceImpl(service);
+    WxMaKfList result = kefuService.kfList();
+
+    Assert.assertNotNull(result);
+    Assert.assertNotNull(result.getKfList());
+    Assert.assertEquals(result.getKfList().size(), 0);
+  }
+
+  @Test
+  public void testKfAccountAdd() throws WxErrorException {
+    WxMaService service = mock(WxMaService.class);
+    when(service.post(anyString(), anyString())).thenReturn("{\"errcode\":0}");
+
+    WxMaKefuService kefuService = new WxMaKefuServiceImpl(service);
+    WxMaKfAccountRequest request = WxMaKfAccountRequest.builder()
+        .kfAccount("test@kfaccount")
+        .kfNick("测试客服")
+        .kfPwd("password")
+        .build();
+
+    boolean result = kefuService.kfAccountAdd(request);
+    Assert.assertTrue(result);
+  }
+
+  @Test
+  public void testKfSessionCreate() throws WxErrorException {
+    WxMaService service = mock(WxMaService.class);
+    when(service.post(anyString(), anyString())).thenReturn("{\"errcode\":0}");
+
+    WxMaKefuService kefuService = new WxMaKefuServiceImpl(service);
+    boolean result = kefuService.kfSessionCreate("test_openid", "test@kfaccount");
+    Assert.assertTrue(result);
+  }
+}
\ No newline at end of file
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaKefuServiceDemo.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaKefuServiceDemo.java
new file mode 100644
index 000000000..1d62fd9be
--- /dev/null
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/demo/WxMaKefuServiceDemo.java
@@ -0,0 +1,84 @@
+package cn.binarywang.wx.miniapp.demo;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfList;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSession;
+import cn.binarywang.wx.miniapp.bean.kefu.WxMaKfSessionList;
+import cn.binarywang.wx.miniapp.bean.kefu.request.WxMaKfAccountRequest;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 小程序客服管理功能使用示例.
+ * 
+ * @author Binary Wang
+ */
+public class WxMaKefuServiceDemo {
+
+  private final WxMaService wxMaService;
+
+  public WxMaKefuServiceDemo(WxMaService wxMaService) {
+    this.wxMaService = wxMaService;
+  }
+
+  /**
+   * 演示客服账号管理功能
+   */
+  public void demonstrateCustomerServiceManagement() throws WxErrorException {
+    // 1. 获取客服列表
+    WxMaKfList kfList = wxMaService.getKefuService().kfList();
+    System.out.println("当前客服数量: " + kfList.getKfList().size());
+
+    // 2. 添加新客服账号
+    WxMaKfAccountRequest addRequest = WxMaKfAccountRequest.builder()
+        .kfAccount("service001@example")
+        .kfNick("客服001")
+        .kfPwd("password123")
+        .build();
+    
+    boolean addResult = wxMaService.getKefuService().kfAccountAdd(addRequest);
+    System.out.println("添加客服账号结果: " + addResult);
+
+    // 3. 更新客服账号信息
+    WxMaKfAccountRequest updateRequest = WxMaKfAccountRequest.builder()
+        .kfAccount("service001@example")
+        .kfNick("高级客服001")
+        .build();
+    
+    boolean updateResult = wxMaService.getKefuService().kfAccountUpdate(updateRequest);
+    System.out.println("更新客服账号结果: " + updateResult);
+  }
+
+  /**
+   * 演示客服会话管理功能
+   */
+  public void demonstrateSessionManagement() throws WxErrorException {
+    String userOpenid = "user_openid_example";
+    String kfAccount = "service001@example";
+
+    // 1. 创建客服会话
+    boolean createResult = wxMaService.getKefuService().kfSessionCreate(userOpenid, kfAccount);
+    System.out.println("创建会话结果: " + createResult);
+
+    // 2. 获取用户会话状态
+    WxMaKfSession session = wxMaService.getKefuService().kfSessionGet(userOpenid);
+    System.out.println("用户当前会话客服: " + session.getKfAccount());
+
+    // 3. 获取客服的会话列表
+    WxMaKfSessionList sessionList = wxMaService.getKefuService().kfSessionList(kfAccount);
+    System.out.println("客服当前会话数量: " + sessionList.getSessionList().size());
+
+    // 4. 关闭客服会话
+    boolean closeResult = wxMaService.getKefuService().kfSessionClose(userOpenid, kfAccount);
+    System.out.println("关闭会话结果: " + closeResult);
+  }
+
+  /**
+   * 演示客服账号删除功能
+   */
+  public void demonstrateAccountDeletion() throws WxErrorException {
+    String kfAccount = "service001@example";
+    
+    boolean deleteResult = wxMaService.getKefuService().kfAccountDel(kfAccount);
+    System.out.println("删除客服账号结果: " + deleteResult);
+  }
+}
\ No newline at end of file