bug修改
This commit is contained in:
1 parent
1d7f665550
commit
17d293ec0a
10 files changed
+190
-18
No files matched your search
+9
-7
@@ -18,8 +18,12 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable<Integer> {
|
||||
WALLET(1, "钱包"),
|
||||
BANK(2, "银行卡"),
|
||||
WECHAT(3, "微信"), // 手动打款
|
||||
ALIPAY(4, "支付宝"),
|
||||
WECHAT_API(5, "支付宝零钱"), // 自动打款,通过微信转账 API
|
||||
ALIPAY(4, "支付宝"), // 手动打款
|
||||
/**
|
||||
* 历史命名 WECHAT_API;App 端佣金提现实际传 type=5 + 支付宝账号,运营后台手动打款。
|
||||
* 切勿再走微信转账 API。
|
||||
*/
|
||||
WECHAT_API(5, "支付宝"),
|
||||
;
|
||||
|
||||
public static final Integer[] ARRAYS = Arrays.stream(values()).map(BrokerageWithdrawTypeEnum::getType).toArray(Integer[]::new);
|
||||
@@ -39,13 +43,11 @@ public enum BrokerageWithdrawTypeEnum implements ArrayValuable<Integer> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否通过支付平台的 API 打款
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 是否
|
||||
* 是否通过支付平台的 API 打款。
|
||||
* 当前业务均为运营手动打款,不再走微信/支付宝自动转账。
|
||||
*/
|
||||
public static boolean isApi(Integer type) {
|
||||
return WECHAT_API.getType().equals(type);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -1,10 +1,15 @@
|
||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage;
|
||||
|
||||
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayTransferNotifyReqDTO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawExcelVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRejectReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO;
|
||||
@@ -22,9 +27,15 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||
@@ -81,6 +92,39 @@ public class BrokerageWithdrawController {
|
||||
return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap));
|
||||
}
|
||||
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出佣金提现 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:query')")
|
||||
@ApiAccessLog(operateType = EXPORT)
|
||||
public void exportBrokerageWithdrawExcel(@Valid BrokerageWithdrawPageReqVO pageVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
PageResult<BrokerageWithdrawDO> pageResult = brokerageWithdrawService.getBrokerageWithdrawPage(pageVO);
|
||||
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
|
||||
convertSet(pageResult.getList(), BrokerageWithdrawDO::getUserId));
|
||||
|
||||
List<BrokerageWithdrawExcelVO> excelList = new ArrayList<>(pageResult.getList().size());
|
||||
for (BrokerageWithdrawDO row : pageResult.getList()) {
|
||||
BrokerageWithdrawExcelVO excel = new BrokerageWithdrawExcelVO();
|
||||
excel.setId(row.getId());
|
||||
excel.setUserId(row.getUserId());
|
||||
excel.setUserNickname(Optional.ofNullable(userMap.get(row.getUserId()))
|
||||
.map(MemberUserRespDTO::getNickname).orElse(null));
|
||||
excel.setPriceYuan(row.getPrice() == null ? "0" : MoneyUtils.fenToYuanStr(row.getPrice()));
|
||||
excel.setFeePriceYuan(row.getFeePrice() == null ? "0" : MoneyUtils.fenToYuanStr(row.getFeePrice()));
|
||||
excel.setTypeName("支付宝");
|
||||
excel.setAccountNo(row.getAccountNo());
|
||||
excel.setName(row.getName());
|
||||
excel.setStatus(row.getStatus());
|
||||
excel.setAuditReason(row.getAuditReason());
|
||||
excel.setAuditTime(row.getAuditTime());
|
||||
excel.setCreateTime(row.getCreateTime());
|
||||
excel.setRemark(row.getRemark());
|
||||
excelList.add(excel);
|
||||
}
|
||||
ExcelUtils.write(response, "佣金提现.xls", "数据", BrokerageWithdrawExcelVO.class, excelList);
|
||||
}
|
||||
|
||||
// TODO @luchi:update-transferred,url 改成这个。和 update-paid 、update-refunded 保持一致
|
||||
@PostMapping("/update-transfer")
|
||||
@Operation(summary = "更新转账订单为转账成功") // 由 pay-module 支付服务,进行回调,可见 PayNotifyJob
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw;
|
||||
|
||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
||||
import cn.iocoder.yudao.module.trade.enums.DictTypeConstants;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 佣金提现 Excel VO
|
||||
*/
|
||||
@Data
|
||||
public class BrokerageWithdrawExcelVO {
|
||||
|
||||
@ExcelProperty("编号")
|
||||
private Long id;
|
||||
|
||||
@ExcelProperty("用户编号")
|
||||
private Long userId;
|
||||
|
||||
@ExcelProperty("用户昵称")
|
||||
private String userNickname;
|
||||
|
||||
@ExcelProperty("提现金额(元)")
|
||||
private String priceYuan;
|
||||
|
||||
@ExcelProperty("手续费(元)")
|
||||
private String feePriceYuan;
|
||||
|
||||
@ExcelProperty("提现方式")
|
||||
private String typeName;
|
||||
|
||||
@ExcelProperty("支付宝账号")
|
||||
private String accountNo;
|
||||
|
||||
@ExcelProperty("真实姓名")
|
||||
private String name;
|
||||
|
||||
@ExcelProperty(value = "状态", converter = DictConvert.class)
|
||||
@DictFormat(DictTypeConstants.BROKERAGE_WITHDRAW_STATUS)
|
||||
private Integer status;
|
||||
|
||||
@ExcelProperty("审核原因")
|
||||
private String auditReason;
|
||||
|
||||
@ExcelProperty("审核时间")
|
||||
private LocalDateTime auditTime;
|
||||
|
||||
@ExcelProperty("申请时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ExcelProperty("备注")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
+6
@@ -30,6 +30,12 @@ public class AppBrokerageWithdrawRespVO {
|
||||
@Schema(description = "提现时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "审核驳回原因", example = "信息不完整")
|
||||
private String auditReason;
|
||||
|
||||
@Schema(description = "转账失败原因", example = "用户未确认收款")
|
||||
private String transferErrorMsg;
|
||||
|
||||
// ========== 微信转账专属 ==========
|
||||
|
||||
@Schema(description = "转账单编号", example = "1024")
|
||||
|
||||
+5
-8
@@ -124,17 +124,14 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||
.setUserId(withdraw.getUserId()).setUserType(UserTypeEnum.MEMBER.getValue())
|
||||
.setBizType(PayWalletBizTypeEnum.BROKERAGE_WITHDRAW.getType()).setBizId(withdraw.getId().toString())
|
||||
.setPrice(withdraw.getPrice()));
|
||||
// 1.2 微信 API
|
||||
} else if (BrokerageWithdrawTypeEnum.WECHAT_API.getType().equals(withdraw.getType())) {
|
||||
// TODO @luchi:这里,要加个转账单号的记录;另外,调用 API 转账,是立马成功,还是有延迟的哈?
|
||||
createPayTransfer(withdraw);
|
||||
// 1.3 剩余类型,都是手动打款,所以不处理
|
||||
// 1.2 历史 type=5 曾走微信转账 API;现业务为支付宝账号提现,统一手动打款
|
||||
// 若再走 createPayTransfer,无小程序 openid 会 NPE → 管理端「系统异常」
|
||||
} else {
|
||||
// TODO 可优化:未来可以考虑,接入支付宝、银联等 API 转账,实现自动打款
|
||||
log.info("[auditBrokerageWithdrawSuccess][withdraw({}) 类型({}) 手动打款,无需处理]", withdraw.getId(), withdraw.getType());
|
||||
log.info("[auditBrokerageWithdrawSuccess][withdraw({}) 类型({}) 手动打款,账号={}]",
|
||||
withdraw.getId(), withdraw.getType(), withdraw.getAccountNo());
|
||||
}
|
||||
|
||||
// 2. 非支付 API,则直接体现成功
|
||||
// 2. 非支付 API,则直接提现成功
|
||||
if (!BrokerageWithdrawTypeEnum.isApi(withdraw.getType())) {
|
||||
brokerageWithdrawMapper.updateByIdAndStatus(withdraw.getId(), BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus(),
|
||||
new BrokerageWithdrawDO().setStatus(BrokerageWithdrawStatusEnum.WITHDRAW_SUCCESS.getStatus()));
|
||||
|
||||
+5
@@ -29,6 +29,11 @@ public interface ChatApi {
|
||||
*/
|
||||
boolean createOrUpdate(@Valid ChatCreateOrUpdateUserReqVO dto);
|
||||
|
||||
/**
|
||||
* 封禁聊天用户并推送下线
|
||||
*/
|
||||
boolean banUser(Long userId, String reason);
|
||||
|
||||
/**
|
||||
* 根据userId查询用户详情
|
||||
*/
|
||||
|
||||
+30
@@ -121,6 +121,36 @@ public class ChatApiImpl implements ChatApi {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 封禁聊天用户并推送下线
|
||||
*/
|
||||
@Override
|
||||
public boolean banUser(Long userId, String reason) {
|
||||
if (userId == null) {
|
||||
return false;
|
||||
}
|
||||
ChatApiTool.API api = setApiConfig(ChatApiTool.USER_BAN);
|
||||
try {
|
||||
ChatBanUserReqVO dto = new ChatBanUserReqVO(userId, reason);
|
||||
String body = JSONUtil.toJsonStr(dto);
|
||||
String res = HttpRequest.post(api.getFullPath()).header(apiCountersign(body)).body(body).execute().body();
|
||||
log.debug("封禁聊天用户,res:{}", res);
|
||||
if (ObjectUtil.isEmpty(res)) {
|
||||
log.error("封禁聊天用户,res为空");
|
||||
return false;
|
||||
}
|
||||
ChatBaseRespVO baseRes = JSONUtil.toBean(res, ChatBaseRespVO.class);
|
||||
if (ObjectUtil.isEmpty(baseRes) || !baseRes.isSuccess()) {
|
||||
log.error("封禁聊天用户,返回错误,res:{}", res);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
log.error("封禁聊天用户,意外的错误,userId={}", userId, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据userId查询用户详情
|
||||
*/
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ public class ChatApiTool {
|
||||
public static final API USER_LOGIN = API.builder().summary("用户登录").url("/third/user/login").method(HttpMethod.POST).build();
|
||||
public static final API USER_GET = API.builder().summary("根据userId查询用户详情").url("/third/user/getUserByUserId").method(HttpMethod.POST).build();
|
||||
public static final API USER_SAVE_OR_UPDATE = API.builder().summary("创建或者更新用户").url("/third/user/createOrUpdate").method(HttpMethod.POST).build();
|
||||
public static final API USER_BAN = API.builder().summary("封禁用户并踢下线").url("/third/user/ban").method(HttpMethod.POST).build();
|
||||
public static final API GET_USER_ONLINE_STATUS_BY_ID = API.builder().summary("查询用户在线状态").url("/third/user/getUserOnlineStatusById").method(HttpMethod.POST).build();
|
||||
|
||||
// 朋友圈
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.member.client.vo.chat.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(description = "封禁聊天用户")
|
||||
public class ChatBanUserReqVO {
|
||||
|
||||
@NotNull(message = "用户id不可为空")
|
||||
@Schema(description = "用户id")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "封禁原因")
|
||||
private String reason;
|
||||
}
|
||||
+11
-3
@@ -478,7 +478,7 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理会员全部 OAuth2 access + refresh,App 下次请求会 401 并退出登录。
|
||||
* 清理会员全部 OAuth2 access + refresh,并通知 IM 立刻踢下线。
|
||||
*/
|
||||
private void kickMemberLogin(Long userId) {
|
||||
try {
|
||||
@@ -487,6 +487,11 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||
log.warn("踢出会员登录态失败, userId={}", userId, e);
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
chatApi.banUser(userId, "账号已被禁用");
|
||||
} catch (Exception e) {
|
||||
log.warn("通知聊天服务封禁用户失败, userId={}", userId, e);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -577,12 +582,15 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||
|
||||
/**
|
||||
* 获取用户的微信信息
|
||||
* 有微信号即可解锁;二维码为可选展示字段。
|
||||
*/
|
||||
@Override
|
||||
public MemberWechatBO getMemberWechat(Long memberId) {
|
||||
MemberUserDO detail = memberUserMapper.selectById(memberId);
|
||||
if (ObjectUtil.isEmpty(detail)) return null;
|
||||
if (ObjectUtil.isEmpty(detail.getWechatNum()) || ObjectUtil.isEmpty(detail.getWechatQrCode())) {
|
||||
if (ObjectUtil.isEmpty(detail)) {
|
||||
return null;
|
||||
}
|
||||
if (ObjectUtil.isEmpty(detail.getWechatNum())) {
|
||||
return null;
|
||||
}
|
||||
MemberWechatBO result = new MemberWechatBO();
|
||||
|
||||
Reference in new issue
Block a user