| | |
| | | @TableField("bank_number") |
| | | @ApiModelProperty(value = "银行卡号", required = true) |
| | | private String bankNumber; |
| | | /** |
| | | * 持卡人名称 |
| | | */ |
| | | @TableField("user_name") |
| | | @ApiModelProperty(value = "持卡人名称", required = true) |
| | | private String userName; |
| | | @ApiModelProperty("账户类型(对私账户201,对公账户204)") |
| | | @TableField("receiverAccountType") |
| | | private Integer receiverAccountType; |
| | | @ApiModelProperty("收款方开户行编号") |
| | | @TableField("receiverBankChannelNo") |
| | | private String receiverBankChannelNo; |
| | | } |
| | |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "变动类型(4=兑换商品,12=他人赠送,13=赠与他人,16=取消订单,17=充值 )") |
| | | @Excel(name = "变动类型", readConverterExp = "4=兑换商品,12=他人赠送,13=赠与他人,16=取消订单,17=充值 ") |
| | | @Excel(name = "变动类型", readConverterExp = "4=兑换商品,12=他人赠送,13=赠与他人,16=取消订单,17=充值 18=提现 19=提现失败回退积分 ") |
| | | @TableField("type") |
| | | private Integer type; |
| | | |
New file |
| | |
| | | package com.ruoyi.account.api.model; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import java.io.Serializable; |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户提现记录 |
| | | * </p> |
| | | * |
| | | * @author lingma |
| | | * @since 2025-04-05 |
| | | */ |
| | | @Data |
| | | @TableName("t_user_withdraw") |
| | | @ApiModel(value = "UserWithdraw对象", description = "用户提现记录") |
| | | public class UserWithdraw implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | @ApiModelProperty(value = "主键") |
| | | @TableId("id") |
| | | private Long id; |
| | | |
| | | |
| | | @ApiModelProperty(value = "uid") |
| | | @TableField(exist = false) |
| | | |
| | | private String uid; |
| | | @ApiModelProperty(value = "用户id") |
| | | @TableField("app_user_id") |
| | | private Long appUserId; |
| | | |
| | | @ApiModelProperty(value = "提现金额") |
| | | @TableField("money") |
| | | private BigDecimal money; |
| | | |
| | | @ApiModelProperty(value = "消耗积分") |
| | | @TableField("integral") |
| | | private Integer integral; |
| | | |
| | | @ApiModelProperty(value = "审核状态(0=待审核,1=审核通过,2=审核失败)") |
| | | @TableField("audit_status") |
| | | private Integer auditStatus; |
| | | |
| | | @ApiModelProperty(value = "审核人id") |
| | | @TableField("audit_user_id") |
| | | private Long auditUserId; |
| | | |
| | | @ApiModelProperty(value = "审核时间") |
| | | @TableField("audit_time") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime auditTime; |
| | | |
| | | @ApiModelProperty(value = "审核结果") |
| | | @TableField("audit_msg") |
| | | private String auditMsg; |
| | | |
| | | @ApiModelProperty(value = "状态(1=申请中,2=已到账)") |
| | | @TableField("status") |
| | | private Integer status; |
| | | |
| | | @ApiModelProperty(value = "到账时间") |
| | | @TableField("arrival_time") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime arrivalTime; |
| | | |
| | | @ApiModelProperty(value = "删除(0=否,1=是)") |
| | | @TableField("del_flag") |
| | | private Integer delFlag; |
| | | |
| | | @ApiModelProperty(value = "添加时间") |
| | | @TableField("create_time") |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | | @TableField(exist = false) |
| | | @ApiModelProperty(value = "联系电话") |
| | | private String phone; |
| | | @TableField(exist = false) |
| | | @ApiModelProperty(value = "用户名称") |
| | | private String name; |
| | | @ApiModelProperty("收款银行卡号") |
| | | @TableField("receiverAccountNoEnc") |
| | | private String receiverAccountNoEnc; |
| | | |
| | | @ApiModelProperty("收款银行卡持卡人名称") |
| | | @TableField("receiverNameEnc") |
| | | private String receiverNameEnc; |
| | | |
| | | @ApiModelProperty("账户类型(对私账户201,对公账户204)") |
| | | @TableField("receiverAccountType") |
| | | private Integer receiverAccountType; |
| | | @ApiModelProperty(value = "提现单号") |
| | | @TableField("code") |
| | | private String code; |
| | | @ApiModelProperty(value = "提现流水号") |
| | | @TableField("order_number") |
| | | private String orderNumber; |
| | | @ApiModelProperty("收款方开户行编号") |
| | | @TableField("receiverBankChannelNo") |
| | | private String receiverBankChannelNo; |
| | | } |
| | |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>commons-httpclient</groupId> |
| | | <artifactId>commons-httpclient</artifactId> |
| | | <version>3.1</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.ruoyi</groupId> |
| | | <artifactId>ruoyi-api-order</artifactId> |
| | | </dependency> |
| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.ruoyi.account.api.model.AppUserBank; |
| | | import com.ruoyi.account.dto.SaveWithdrawalAccount; |
| | | import com.ruoyi.account.service.AppUserBankService; |
| | | import com.ruoyi.common.core.utils.bean.BeanUtils; |
| | | import com.ruoyi.common.core.web.domain.AjaxResult; |
| | |
| | | @ResponseBody |
| | | @PostMapping("/saveAppUserBank") |
| | | @ApiOperation(value = "保存银行卡") |
| | | public AjaxResult saveAppUserBank(@RequestBody AppUserBank appUserBank){ |
| | | public AjaxResult saveAppUserBank(@RequestBody SaveWithdrawalAccount appUserBank){ |
| | | LoginUser loginUserApplet = tokenService.getLoginUserApplet(); |
| | | |
| | | AppUserBank bank = appUserBankService.getOne(new LambdaQueryWrapper<AppUserBank>() |
| | | .eq(AppUserBank::getAppUserId, loginUserApplet.getUserid())); |
| | | if (bank == null){ |
| | | appUserBank.setAppUserId(loginUserApplet.getUserid()); |
| | | appUserBankService.saveOrUpdate(appUserBank); |
| | | AppUserBank bank1 = new AppUserBank(); |
| | | bank1.setAppUserId(loginUserApplet.getUserid()); |
| | | bank1.setBankNumber(appUserBank.getReceiverAccountNoEnc()); |
| | | bank1.setUserName(appUserBank.getReceiverNameEnc()); |
| | | bank1.setReceiverAccountType(appUserBank.getReceiverAccountType()); |
| | | appUserBankService.saveOrUpdate(bank1); |
| | | }else { |
| | | appUserBank.setId(bank.getId()); |
| | | appUserBank.setAppUserId(bank.getAppUserId()); |
| | | appUserBankService.updateById(appUserBank); |
| | | bank.setAppUserId(loginUserApplet.getUserid()); |
| | | bank.setBankNumber(appUserBank.getReceiverAccountNoEnc()); |
| | | bank.setUserName(appUserBank.getReceiverNameEnc()); |
| | | bank.setReceiverAccountType(appUserBank.getReceiverAccountType()); |
| | | appUserBankService.updateById(bank); |
| | | } |
| | | return AjaxResult.success(); |
| | | } |
| | |
| | | import com.ruoyi.account.mapper.AppUserMapper; |
| | | import com.ruoyi.account.service.*; |
| | | import com.ruoyi.account.util.ObsUploadUtil; |
| | | import com.ruoyi.account.util.UUIDUtil; |
| | | import com.ruoyi.account.util.weChat.EnvVersion; |
| | | import com.ruoyi.account.util.weChat.WeChatUtil; |
| | | import com.ruoyi.account.vo.*; |
| | | import com.ruoyi.common.core.constant.CacheConstants; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.exception.ServiceException; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.poi.ExcelUtil; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | |
| | | import com.ruoyi.order.feignClient.RemoteOrderGoodsClient; |
| | | import com.ruoyi.order.model.Order; |
| | | import com.ruoyi.other.api.domain.Shop; |
| | | import com.ruoyi.other.api.domain.ShopBalanceStatement; |
| | | import com.ruoyi.other.api.domain.ShopWithdraw; |
| | | import com.ruoyi.other.api.feignClient.ShopClient; |
| | | import com.ruoyi.system.api.domain.SysConfig; |
| | | import com.ruoyi.system.api.domain.SysUser; |
| | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.net.URLDecoder; |
| | | import java.net.URLEncoder; |
| | | import java.text.SimpleDateFormat; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.temporal.ChronoUnit; |
| | |
| | | @Resource |
| | | private AppUserService appUserService; |
| | | @Resource |
| | | private IUserWithdrawService userWithdrawService; |
| | | @Resource |
| | | private UserPointService userPointService; |
| | | @Resource |
| | | private AppUserBankService appUserBankService; |
| | | @Resource |
| | | private AppUserMapper appUserMapper; |
| | | @Resource |
| | | private ShopClient shopClient; |
| | |
| | | @Value("${file.upload.location}") |
| | | private String filePath; |
| | | |
| | | @PostMapping("/verifyBankInfo") |
| | | @ApiOperation(value = "用户提现前校验银行卡信息") |
| | | public R<Boolean> mobileLogin() { |
| | | LoginUser loginUserApplet = tokenService.getLoginUserApplet(); |
| | | AppUser appUser = appUserService.getById(loginUserApplet.getUserid()); |
| | | AppUserBank bank = appUserBankService.lambdaQuery().eq(AppUserBank::getAppUserId, appUser.getId()).last("limit 1") |
| | | .one(); |
| | | if (bank == null){ |
| | | return R.ok(false); |
| | | }else{ |
| | | return R.ok(true); |
| | | } |
| | | } |
| | | @ApiOperation(value = "提现申请") |
| | | @GetMapping("/withdrawalApplication") |
| | | @ResponseBody |
| | | public R withdrawalApplication(@ApiParam("提现金额") @RequestParam BigDecimal money) { |
| | | LoginUser loginUser = tokenService.getLoginUserApplet(); |
| | | SysConfig data = sysConfigClient.getInfo(8L).getData(); |
| | | AppUser appUser = appUserService.getById(loginUser.getUserid()); |
| | | SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); |
| | | String code = sdf.format(new Date()) + UUIDUtil.getNumberRandom(5); |
| | | money=money.setScale(2, BigDecimal.ROUND_HALF_DOWN); |
| | | if (money.compareTo(BigDecimal.ZERO)==0){ |
| | | throw new ServiceException("提现金额必须大于零"); |
| | | } |
| | | Integer rate = Integer.valueOf(data.getConfigValue()); |
| | | BigDecimal availablePoint = new BigDecimal(appUser.getAvailablePoint()); |
| | | BigDecimal unMoney = availablePoint.divide(BigDecimal.valueOf(rate), 2, RoundingMode.HALF_DOWN); |
| | | if (unMoney.compareTo( money)<0){ |
| | | throw new ServiceException("提现金额不能大于可提现金额,当前可提现金额为:"+unMoney); |
| | | } |
| | | AppUserBank bank = appUserBankService.lambdaQuery().eq(AppUserBank::getAppUserId, appUser.getId()).last("limit 1") |
| | | .one(); |
| | | if(bank==null){ |
| | | throw new ServiceException("请完善账户信息后再申请提现!"); |
| | | } |
| | | if(!org.springframework.util.StringUtils.hasLength(bank.getBankNumber())){ |
| | | throw new ServiceException("请完善银行卡后再申请提现!"); |
| | | } |
| | | // 增加用户提现积分变动记录 |
| | | UserPoint one = userPointService.lambdaQuery().eq(UserPoint::getAppUserId, appUser.getId()) |
| | | .orderByDesc(UserPoint::getCreateTime).last("limit 1").one(); |
| | | UserWithdraw userWithdraw = new UserWithdraw(); |
| | | userWithdraw.setAppUserId(appUser.getId()); |
| | | userWithdraw.setMoney(money); |
| | | BigDecimal multiply = money.multiply(BigDecimal.valueOf(rate)); |
| | | appUser.setAvailablePoint(appUser.getAvailablePoint()-multiply.setScale(0, RoundingMode.HALF_UP).intValue()); |
| | | if (multiply.compareTo(new BigDecimal(appUser.getAvailablePoint()))>0){ |
| | | throw new ServiceException("积分不足!"); |
| | | } |
| | | userWithdraw.setIntegral(Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())); |
| | | userWithdraw.setAuditStatus(0); |
| | | userWithdraw.setStatus(1); |
| | | userWithdraw.setCode(code); |
| | | userWithdraw.setCreateTime(LocalDateTime.now()); |
| | | if (one.getBalance() - Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())<0){ |
| | | throw new ServiceException("积分不足!"); |
| | | } |
| | | userWithdraw.setReceiverAccountNoEnc(bank.getBankNumber()); |
| | | userWithdraw.setReceiverNameEnc(bank.getUserName()); |
| | | userWithdraw.setReceiverBankChannelNo(bank.getReceiverBankChannelNo()); |
| | | userWithdraw.setReceiverAccountType(201); |
| | | userWithdrawService.save(userWithdraw); |
| | | UserPoint userPoint = new UserPoint(); |
| | | userPoint.setType(18); |
| | | userPoint.setVariablePoint(Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())); |
| | | userPoint.setHistoricalPoint(one.getBalance()); |
| | | userPoint.setBalance(one.getBalance() - Integer.valueOf(multiply.setScale(0, RoundingMode.HALF_UP).toString())); |
| | | userPoint.setCreateTime(LocalDateTime.now()); |
| | | userPoint.setAppUserId(appUser.getId()); |
| | | userPoint.setObjectId(userWithdraw.getId()); |
| | | userPointService.save(userPoint); |
| | | appUserService.updateById(appUser); |
| | | return R.ok(); |
| | | } |
| | | |
| | | @ResponseBody |
| | | @PostMapping("/mobileLogin") |
New file |
| | |
| | | package com.ruoyi.account.controller; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.account.api.model.AppUser; |
| | | import com.ruoyi.account.api.model.UserPoint; |
| | | import com.ruoyi.account.api.model.UserWithdraw; |
| | | import com.ruoyi.account.mapper.UserPointMapper; |
| | | import com.ruoyi.account.mapper.UserWithdrawMapper; |
| | | import com.ruoyi.account.service.AppUserService; |
| | | import com.ruoyi.account.service.IUserWithdrawService; |
| | | import com.ruoyi.account.service.UserPointService; |
| | | import com.ruoyi.account.util.BankCode; |
| | | import com.ruoyi.account.util.HttpRequester; |
| | | import com.ruoyi.account.util.HttpRespons; |
| | | import com.ruoyi.account.util.withdraw.HttpUtilWithdraw; |
| | | import com.ruoyi.account.vo.*; |
| | | import com.ruoyi.common.core.domain.R; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.common.core.utils.poi.ExcelUtil; |
| | | import com.ruoyi.common.core.web.controller.BaseController; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import com.ruoyi.common.security.service.TokenService; |
| | | import com.ruoyi.common.security.utils.SecurityUtils; |
| | | import com.ruoyi.order.feignClient.OrderClient; |
| | | import com.ruoyi.order.model.Order; |
| | | import com.ruoyi.other.api.domain.Shop; |
| | | import com.ruoyi.other.api.domain.ShopBalanceStatement; |
| | | import com.ruoyi.other.api.domain.ShopWithdraw; |
| | | import com.ruoyi.system.api.model.LoginUser; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiParam; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.LocalTime; |
| | | import java.time.YearMonth; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | | * 前端控制器 |
| | | * </p> |
| | | * |
| | | * @author luodangjia |
| | | * @since 2024-11-21 |
| | | */ |
| | | @RestController |
| | | @RequestMapping("/user-point") |
| | | @Api(tags = "用户提现列表") |
| | | public class UserWithdrawController extends BaseController { |
| | | @Resource |
| | | private IUserWithdrawService userWithdrawService; |
| | | @Resource |
| | | private UserPointService userPointService; |
| | | @Resource |
| | | private UserWithdrawMapper userWithdrawMapper; |
| | | @Resource |
| | | private AppUserService appUserService; |
| | | @Resource |
| | | private TokenService tokenService; |
| | | @GetMapping("/shop/list") |
| | | @ApiOperation(value = "用户提现申请列表") |
| | | public R<IPage<UserWithdraw>> shoplist(@ApiParam("页码") @RequestParam Integer pageNum, |
| | | @ApiParam("每一页数据大小") Integer pageSize, |
| | | @ApiParam("用户手机号") String phone, |
| | | @ApiParam("审核状态(0=待审核,1=审核通过,2=审核失败)")Integer auditStatus) { |
| | | //模糊查询手机号 |
| | | List<Long> appUserIds=new ArrayList<>(); |
| | | if (StringUtils.isNotEmpty(phone)) { |
| | | QueryWrapper<AppUser> queryWrapper=new QueryWrapper<>(); |
| | | queryWrapper.like(StringUtils.isNotEmpty(phone),"phone", phone); |
| | | appUserIds=appUserService.list(queryWrapper).stream().map(AppUser::getId).collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(appUserIds)) { |
| | | return R.ok(new PageInfo<>()); |
| | | } |
| | | } |
| | | PageInfo<UserWithdraw> page=new PageInfo<>(pageNum,pageSize); |
| | | List<UserWithdraw> list =userWithdrawMapper.page(page,appUserIds,auditStatus); |
| | | for (UserWithdraw userWithdraw : list) { |
| | | userWithdraw.setUid(userWithdraw.getId().toString()); |
| | | } |
| | | page.setRecords(list); |
| | | return R.ok(page); |
| | | } |
| | | /** |
| | | * 审核 |
| | | */ |
| | | @GetMapping("/audit") |
| | | @ApiOperation("提现审核") |
| | | public R<Void> audit(@ApiParam("审核状态 1=通过 2=失败") @RequestParam Integer auditstatus, |
| | | @ApiParam("提现id") Long id, |
| | | @ApiParam("审核失败备注") String auditMsg |
| | | ) throws IOException { |
| | | LoginUser loginUser = tokenService.getLoginUser(); |
| | | |
| | | UserWithdraw userWithdraw = userWithdrawService.getById(id); |
| | | if(0 != userWithdraw.getAuditStatus()){ |
| | | return R.fail("不能重复审核"); |
| | | } |
| | | AppUser appUser = appUserService.getById(userWithdraw.getAppUserId()); |
| | | if(1 == auditstatus){ |
| | | // 打款 |
| | | String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&" + |
| | | "cardNo="+userWithdraw.getReceiverAccountNoEnc()+"&cardBinCheck=true"; |
| | | HashMap<String, String> hashMap = new HashMap<>(); |
| | | HttpRequester hr = new HttpRequester(); |
| | | HttpRespons HP = hr.sendPost(url, hashMap); |
| | | System.out.println("接收返回参数:" + HP.getContent()); |
| | | com.alibaba.fastjson.JSONObject resPay = com.alibaba.fastjson.JSONObject.parseObject(HP.getContent()); |
| | | System.err.println(resPay); |
| | | if (resPay.getString("validated")==null){ |
| | | System.err.println("不合法的银行卡号"); |
| | | } |
| | | String bankCode = resPay.getString("bank"); |
| | | String bankName = BankCode.getBankNameByCode(bankCode); // 返回ABC枚举实例 |
| | | System.err.println(bankName); |
| | | String withdraw = HttpUtilWithdraw.userWithdraw(userWithdraw, bankName); |
| | | if (!withdraw.equals("success")){ |
| | | return R.fail("打款失败,原因:"+withdraw); |
| | | } |
| | | |
| | | userWithdraw.setStatus(2); |
| | | userWithdraw.setArrivalTime(LocalDateTime.now()); |
| | | userWithdrawService.updateById(userWithdraw); |
| | | } |
| | | if(2 == auditstatus){ |
| | | //审核不通过 |
| | | //回退积分和添加变动明细 |
| | | UserPoint userPoint = new UserPoint(); |
| | | userPoint.setType(19); |
| | | UserPoint one = userPointService.lambdaQuery().eq(UserPoint::getAppUserId, appUser.getId()) |
| | | .orderByDesc(UserPoint::getCreateTime).last("limit 1").one(); |
| | | userPoint.setVariablePoint(userWithdraw.getIntegral()); |
| | | userPoint.setHistoricalPoint(one.getBalance()); |
| | | userPoint.setBalance(one.getBalance() + userWithdraw.getIntegral()); |
| | | userPoint.setCreateTime(LocalDateTime.now()); |
| | | userPoint.setAppUserId(appUser.getId()); |
| | | userPoint.setObjectId(userWithdraw.getId()); |
| | | userPointService.save(userPoint); |
| | | // 回退积分 |
| | | appUser.setAvailablePoint(appUser.getAvailablePoint()+userWithdraw.getIntegral()); |
| | | appUserService.updateById(appUser); |
| | | } |
| | | userWithdraw.setAuditStatus(auditstatus); |
| | | userWithdraw.setAuditUserId(loginUser.getUserid()); |
| | | userWithdraw.setAuditTime(LocalDateTime.now()); |
| | | userWithdraw.setAuditMsg(auditMsg); |
| | | userWithdrawService.updateById(userWithdraw); |
| | | return R.ok(); |
| | | } |
| | | } |
| | | |
New file |
| | |
| | | package com.ruoyi.account.dto; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author zhibing.pu |
| | | * @Date 2025/1/1 11:54 |
| | | */ |
| | | @Data |
| | | public class SaveWithdrawalAccount { |
| | | |
| | | |
| | | @ApiModelProperty("收款银行卡号") |
| | | private String receiverAccountNoEnc; |
| | | |
| | | @ApiModelProperty("收款银行卡持卡人名称") |
| | | private String receiverNameEnc; |
| | | |
| | | @ApiModelProperty("账户类型(对私账户201,对公账户204)") |
| | | private Integer receiverAccountType; |
| | | |
| | | @ApiModelProperty("收款账户联行号") |
| | | private String receiverBankChannelNo; |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.account.api.model.UserWithdraw; |
| | | import com.ruoyi.common.core.web.page.PageInfo; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户提现记录 Mapper 接口 |
| | | * </p> |
| | | * |
| | | * @author lingma |
| | | * @since 2025-04-05 |
| | | */ |
| | | @Mapper |
| | | public interface UserWithdrawMapper extends BaseMapper<UserWithdraw> { |
| | | |
| | | List<UserWithdraw> page(PageInfo<UserWithdraw> page, @Param("appUserIds")List<Long> appUserIds, @Param("auditStatus")Integer auditStatus); |
| | | |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.service; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.account.api.model.UserWithdraw; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户提现记录 服务类 |
| | | * </p> |
| | | * |
| | | * @author lingma |
| | | * @since 2025-04-05 |
| | | */ |
| | | public interface IUserWithdrawService extends IService<UserWithdraw> { |
| | | |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.account.api.model.UserWithdraw; |
| | | import com.ruoyi.account.mapper.UserWithdrawMapper; |
| | | import com.ruoyi.account.service.IUserWithdrawService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | /** |
| | | * <p> |
| | | * 用户提现记录 服务实现类 |
| | | * </p> |
| | | * |
| | | * @author lingma |
| | | * @since 2025-04-05 |
| | | */ |
| | | @Service |
| | | public class UserWithdrawServiceImpl extends ServiceImpl<UserWithdrawMapper, UserWithdraw> implements IUserWithdrawService { |
| | | |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.util; |
| | | |
| | | /** |
| | | * 银行代码枚举类 |
| | | * 用于通过银行简称获取对应的银行名称 |
| | | */ |
| | | public enum BankCode { |
| | | SRCB("SRCB", "深圳农村商业银行"), |
| | | BGB("BGB", "广西北部湾银行"), |
| | | SHRCB("SHRCB", "上海农村商业银行"), |
| | | BJBANK("BJBANK", "北京银行"), |
| | | WHCCB("WHCCB", "威海市商业银行"), |
| | | BOZK("BOZK", "周口银行"), |
| | | KORLABANK("KORLABANK", "库尔勒市商业银行"), |
| | | SPABANK("SPABANK", "平安银行"), |
| | | SDEB("SDEB", "顺德农商银行"), |
| | | HURCB("HURCB", "湖北省农村信用社"), |
| | | WRCB("WRCB", "无锡农村商业银行"), |
| | | BOCY("BOCY", "朝阳银行"), |
| | | CZBANK("CZBANK", "浙商银行"), |
| | | HDBANK("HDBANK", "邯郸银行"), |
| | | BOC("BOC", "中国银行"), |
| | | BOD("BOD", "东莞银行"), |
| | | CCB("CCB", "中国建设银行"), |
| | | ZYCBANK("ZYCBANK", "遵义市商业银行"), |
| | | SXCB("SXCB", "绍兴银行"), |
| | | GZRCU("GZRCU", "贵州省农村信用社"), |
| | | ZJKCCB("ZJKCCB", "张家口市商业银行"), |
| | | BOJZ("BOJZ", "锦州银行"), |
| | | BOP("BOP", "平顶山银行"), |
| | | HKB("HKB", "汉口银行"), |
| | | SPDB("SPDB", "上海浦东发展银行"), |
| | | NXRCU("NXRCU", "宁夏黄河农村商业银行"), |
| | | NYNB("NYNB", "广东南粤银行"), |
| | | GRCB("GRCB", "广州农商银行"), |
| | | BOSZ("BOSZ", "苏州银行"), |
| | | HZCB("HZCB", "杭州银行"), |
| | | HSBK("HSBK", "衡水银行"), |
| | | HBC("HBC", "湖北银行"), |
| | | JXBANK("JXBANK", "嘉兴银行"), |
| | | HRXJB("HRXJB", "华融湘江银行"), |
| | | BODD("BODD", "丹东银行"), |
| | | AYCB("AYCB", "安阳银行"), |
| | | EGBANK("EGBANK", "恒丰银行"), |
| | | CDB("CDB", "国家开发银行"), |
| | | TCRCB("TCRCB", "江苏太仓农村商业银行"), |
| | | NJCB("NJCB", "南京银行"), |
| | | ZZBANK("ZZBANK", "郑州银行"), |
| | | DYCB("DYCB", "德阳商业银行"), |
| | | YBCCB("YBCCB", "宜宾市商业银行"), |
| | | SCRCU("SCRCU", "四川省农村信用"), |
| | | KLB("KLB", "昆仑银行"), |
| | | LSBANK("LSBANK", "莱商银行"), |
| | | YDRCB("YDRCB", "尧都农商行"), |
| | | CCQTGB("CCQTGB", "重庆三峡银行"), |
| | | FDB("FDB", "富滇银行"), |
| | | JSRCU("JSRCU", "江苏省农村信用联合社"), |
| | | JNBANK("JNBANK", "济宁银行"), |
| | | CMB("CMB", "招商银行"), |
| | | JINCHB("JINCHB", "晋城银行JCBANK"), |
| | | FXCB("FXCB", "阜新银行"), |
| | | WHRCB("WHRCB", "武汉农村商业银行"), |
| | | HBYCBANK("HBYCBANK", "湖北银行宜昌分行"), |
| | | TZCB("TZCB", "台州银行"), |
| | | TACCB("TACCB", "泰安市商业银行"), |
| | | XCYH("XCYH", "许昌银行"), |
| | | CEB("CEB", "中国光大银行"), |
| | | NXBANK("NXBANK", "宁夏银行"), |
| | | HSBANK("HSBANK", "徽商银行"), |
| | | JJBANK("JJBANK", "九江银行"), |
| | | NHQS("NHQS", "农信银清算中心"), |
| | | MTBANK("MTBANK", "浙江民泰商业银行"), |
| | | LANGFB("LANGFB", "廊坊银行"), |
| | | ASCB("ASCB", "鞍山银行"), |
| | | KSRB("KSRB", "昆山农村商业银行"), |
| | | YXCCB("YXCCB", "玉溪市商业银行"), |
| | | DLB("DLB", "大连银行"), |
| | | DRCBCL("DRCBCL", "东莞农村商业银行"), |
| | | GCB("GCB", "广州银行"), |
| | | NBBANK("NBBANK", "宁波银行"), |
| | | BOYK("BOYK", "营口银行"), |
| | | SXRCCU("SXRCCU", "陕西信合"), |
| | | GLBANK("GLBANK", "桂林银行"), |
| | | BOQH("BOQH", "青海银行"), |
| | | CDRCB("CDRCB", "成都农商银行"), |
| | | QDCCB("QDCCB", "青岛银行"), |
| | | HKBEA("HKBEA", "东亚银行"), |
| | | HBHSBANK("HBHSBANK", "湖北银行黄石分行"), |
| | | WZCB("WZCB", "温州银行"), |
| | | TRCB("TRCB", "天津农商银行"), |
| | | QLBANK("QLBANK", "齐鲁银行"), |
| | | GDRCC("GDRCC", "广东省农村信用社联合社"), |
| | | ZJTLCB("ZJTLCB", "浙江泰隆商业银行"), |
| | | GZB("GZB", "赣州银行"), |
| | | GYCB("GYCB", "贵阳市商业银行"), |
| | | CQBANK("CQBANK", "重庆银行"), |
| | | DAQINGB("DAQINGB", "龙江银行"), |
| | | CGNB("CGNB", "南充市商业银行"), |
| | | SCCB("SCCB", "三门峡银行"), |
| | | CSRCB("CSRCB", "常熟农村商业银行"), |
| | | SHBANK("SHBANK", "上海银行"), |
| | | JLBANK("JLBANK", "吉林银行"), |
| | | CZRCB("CZRCB", "常州农村信用联社"), |
| | | BANKWF("BANKWF", "潍坊银行"), |
| | | ZRCBANK("ZRCBANK", "张家港农村商业银行"), |
| | | FJHXBC("FJHXBC", "福建海峡银行"), |
| | | ZJNX("ZJNX", "浙江省农村信用社联合社"), |
| | | LZYH("LZYH", "兰州银行"), |
| | | JSB("JSB", "晋商银行"), |
| | | BOHAIB("BOHAIB", "渤海银行"), |
| | | CZCB("CZCB", "浙江稠州商业银行"), |
| | | YQCCB("YQCCB", "阳泉银行"), |
| | | SJBANK("SJBANK", "盛京银行"), |
| | | XABANK("XABANK", "西安银行"), |
| | | BSB("BSB", "包商银行"), |
| | | JSBANK("JSBANK", "江苏银行"), |
| | | FSCB("FSCB", "抚顺银行"), |
| | | HNRCU("HNRCU", "河南省农村信用"), |
| | | COMM("COMM", "交通银行"), |
| | | XTB("XTB", "邢台银行"), |
| | | CITIC("CITIC", "中信银行"), |
| | | HXBANK("HXBANK", "华夏银行"), |
| | | HNRCC("HNRCC", "湖南省农村信用社"), |
| | | DYCCB("DYCCB", "东营市商业银行"), |
| | | ORBANK("ORBANK", "鄂尔多斯银行"), |
| | | BJRCB("BJRCB", "北京农村商业银行"), |
| | | XYBANK("XYBANK", "信阳银行"), |
| | | ZGCCB("ZGCCB", "自贡市商业银行"), |
| | | CDCB("CDCB", "成都银行"), |
| | | HANABANK("HANABANK", "韩亚银行"), |
| | | CMBC("CMBC", "中国民生银行"), |
| | | LYBANK("LYBANK", "洛阳银行"), |
| | | GDB("GDB", "广东发展银行"), |
| | | ZBCB("ZBCB", "齐商银行"), |
| | | CBKF("CBKF", "开封市商业银行"), |
| | | H3CB("H3CB", "内蒙古银行"), |
| | | CIB("CIB", "兴业银行"), |
| | | CRCBANK("CRCBANK", "重庆农村商业银行"), |
| | | SZSBK("SZSBK", "石嘴山银行"), |
| | | DZBANK("DZBANK", "德州银行"), |
| | | SRBANK("SRBANK", "上饶银行"), |
| | | LSCCB("LSCCB", "乐山市商业银行"), |
| | | JXRCU("JXRCU", "江西省农村信用"), |
| | | ICBC("ICBC", "中国工商银行"), |
| | | JZBANK("JZBANK", "晋中市商业银行"), |
| | | HZCCB("HZCCB", "湖州市商业银行"), |
| | | NHB("NHB", "南海农村信用联社"), |
| | | XXBANK("XXBANK", "新乡银行"), |
| | | JRCB("JRCB", "江苏江阴农村商业银行"), |
| | | YNRCC("YNRCC", "云南省农村信用社"), |
| | | ABC("ABC", "中国农业银行"), |
| | | GXRCU("GXRCU", "广西省农村信用"), |
| | | PSBC("PSBC", "中国邮政储蓄银行"), |
| | | BZMD("BZMD", "驻马店银行"), |
| | | ARCU("ARCU", "安徽省农村信用社"), |
| | | GSRCU("GSRCU", "甘肃省农村信用"), |
| | | LYCB("LYCB", "辽阳市商业银行"), |
| | | JLRCU("JLRCU", "吉林农信"), |
| | | URMQCCB("URMQCCB", "乌鲁木齐市商业银行"), |
| | | XLBANK("XLBANK", "中山小榄村镇银行"), |
| | | CSCB("CSCB", "长沙银行"), |
| | | JHBANK("JHBANK", "金华银行"), |
| | | BHB("BHB", "河北银行"), |
| | | NBYZ("NBYZ", "鄞州银行"), |
| | | LSBC("LSBC", "临商银行"), |
| | | BOCD("BOCD", "承德银行"), |
| | | SDRCU("SDRCU", "山东农信"), |
| | | NCB("NCB", "南昌银行"), |
| | | TCCB("TCCB", "天津银行"), |
| | | WJRCB("WJRCB", "吴江农商银行"), |
| | | CBBQS("CBBQS", "城市商业银行资金清算中心"), |
| | | HBRCU("HBRCU", "河北省农村信用社"); |
| | | |
| | | private final String code; |
| | | private final String name; |
| | | |
| | | BankCode(String code, String name) { |
| | | this.code = code; |
| | | this.name = name; |
| | | } |
| | | |
| | | public String getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public String getName() { |
| | | return name; |
| | | } |
| | | |
| | | /** |
| | | * 根据银行简称获取银行名称 |
| | | * @param code 银行简称 |
| | | * @return 银行名称,如果未找到返回null |
| | | */ |
| | | public static String getBankNameByCode(String code) { |
| | | for (BankCode bankCode : values()) { |
| | | if (bankCode.getCode().equals(code)) { |
| | | return bankCode.getName(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 根据银行简称获取枚举实例 |
| | | * @param code 银行简称 |
| | | * @return BankCode枚举实例,如果未找到返回null |
| | | */ |
| | | public static BankCode getBankByCode(String code) { |
| | | for (BankCode bankCode : values()) { |
| | | if (bankCode.getCode().equals(code)) { |
| | | return bankCode; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.util; |
| | | |
| | | import java.io.BufferedReader; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | | import java.net.HttpURLConnection; |
| | | import java.net.URL; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.Charset; |
| | | import java.util.Map; |
| | | import java.util.Vector; |
| | | |
| | | public class HttpRequester { |
| | | private String defaultContentEncoding; |
| | | |
| | | public HttpRequester() { |
| | | this.defaultContentEncoding = Charset.defaultCharset().name(); |
| | | } |
| | | |
| | | /** |
| | | * 发送POST请求 |
| | | * |
| | | * @param urlString |
| | | * URL地址 |
| | | * @return 响应对象 |
| | | * @throws IOException |
| | | */ |
| | | public HttpRespons sendPost(String urlString) throws IOException { |
| | | return this.send(urlString, "POST", null, null); |
| | | } |
| | | |
| | | /** |
| | | * 发送POST请求 |
| | | * |
| | | * @param urlString |
| | | * URL地址 |
| | | * @param params |
| | | * 参数集合 |
| | | * @return 响应对象 |
| | | * @throws IOException |
| | | */ |
| | | public HttpRespons sendPost(String urlString, Map<String, String> params) |
| | | throws IOException { |
| | | |
| | | for(String key : params.keySet()) { |
| | | if(params.get(key)!=null&&!"".equals(params.get(key))) { |
| | | params.put(key, (String)URLEncoder.encode(params.get(key),"utf-8")) ;//(String) 强制类型转换 |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | return this.send(urlString, "POST", params, null); |
| | | } |
| | | |
| | | /** |
| | | * 发送POST请求 |
| | | * |
| | | * @param urlString |
| | | * URL地址 |
| | | * @param params |
| | | * 参数集合 |
| | | * @param propertys |
| | | * 请求属性 |
| | | * @return 响应对象 |
| | | * @throws IOException |
| | | */ |
| | | public HttpRespons sendPost(String urlString, Map<String, String> params, |
| | | Map<String, String> propertys) throws IOException { |
| | | return this.send(urlString, "POST", params, propertys); |
| | | } |
| | | |
| | | /** |
| | | * 发送HTTP请求 |
| | | * |
| | | * @param urlString |
| | | * @return 响映对象 |
| | | * @throws IOException |
| | | */ |
| | | private HttpRespons send(String urlString, String method, |
| | | Map<String, String> parameters, Map<String, String> propertys) |
| | | throws IOException { |
| | | HttpURLConnection urlConnection = null; |
| | | |
| | | if (method.equalsIgnoreCase("GET") && parameters != null) { |
| | | StringBuffer param = new StringBuffer(); |
| | | int i = 0; |
| | | for (String key : parameters.keySet()) { |
| | | if (i == 0) |
| | | param.append("?"); |
| | | else |
| | | param.append("&"); |
| | | param.append(key).append("=").append(parameters.get(key)); |
| | | i++; |
| | | } |
| | | urlString += param; |
| | | } |
| | | URL url = new URL(urlString); |
| | | urlConnection = (HttpURLConnection) url.openConnection(); |
| | | |
| | | urlConnection.setRequestMethod(method); |
| | | urlConnection.setDoOutput(true); |
| | | urlConnection.setDoInput(true); |
| | | urlConnection.setUseCaches(false); |
| | | |
| | | if (propertys != null) |
| | | for (String key : propertys.keySet()) { |
| | | urlConnection.addRequestProperty(key, propertys.get(key)); |
| | | } |
| | | |
| | | if (method.equalsIgnoreCase("POST") && parameters != null) { |
| | | StringBuffer param = new StringBuffer(); |
| | | for (String key : parameters.keySet()) { |
| | | param.append("&"); |
| | | param.append(key).append("=").append(parameters.get(key)); |
| | | } |
| | | urlConnection.getOutputStream().write(param.toString().getBytes()); |
| | | urlConnection.getOutputStream().flush(); |
| | | urlConnection.getOutputStream().close(); |
| | | } |
| | | |
| | | return this.makeContent(urlString, urlConnection); |
| | | } |
| | | |
| | | /** |
| | | * 得到响应对象 |
| | | * |
| | | * @param urlConnection |
| | | * @return 响应对象 |
| | | * @throws IOException |
| | | */ |
| | | private HttpRespons makeContent(String urlString, |
| | | HttpURLConnection urlConnection) throws IOException { |
| | | HttpRespons httpResponser = new HttpRespons(); |
| | | try { |
| | | InputStream in = urlConnection.getInputStream(); |
| | | BufferedReader bufferedReader = new BufferedReader( |
| | | new InputStreamReader(in)); |
| | | httpResponser.contentCollection = new Vector<String>(); |
| | | StringBuffer temp = new StringBuffer(); |
| | | String line = bufferedReader.readLine(); |
| | | while (line != null) { |
| | | httpResponser.contentCollection.add(line); |
| | | temp.append(line).append("\r\n"); |
| | | line = bufferedReader.readLine(); |
| | | } |
| | | bufferedReader.close(); |
| | | |
| | | String ecod = urlConnection.getContentEncoding(); |
| | | if (ecod == null) |
| | | ecod = this.defaultContentEncoding; |
| | | |
| | | httpResponser.urlString = urlString; |
| | | |
| | | httpResponser.defaultPort = urlConnection.getURL().getDefaultPort(); |
| | | httpResponser.file = urlConnection.getURL().getFile(); |
| | | httpResponser.host = urlConnection.getURL().getHost(); |
| | | httpResponser.path = urlConnection.getURL().getPath(); |
| | | httpResponser.port = urlConnection.getURL().getPort(); |
| | | httpResponser.protocol = urlConnection.getURL().getProtocol(); |
| | | httpResponser.query = urlConnection.getURL().getQuery(); |
| | | httpResponser.ref = urlConnection.getURL().getRef(); |
| | | httpResponser.userInfo = urlConnection.getURL().getUserInfo(); |
| | | |
| | | httpResponser.content = new String(temp.toString().getBytes(), ecod); |
| | | httpResponser.contentEncoding = ecod; |
| | | httpResponser.code = urlConnection.getResponseCode(); |
| | | httpResponser.message = urlConnection.getResponseMessage(); |
| | | httpResponser.contentType = urlConnection.getContentType(); |
| | | httpResponser.method = urlConnection.getRequestMethod(); |
| | | httpResponser.connectTimeout = urlConnection.getConnectTimeout(); |
| | | httpResponser.readTimeout = urlConnection.getReadTimeout(); |
| | | |
| | | return httpResponser; |
| | | } catch (IOException e) { |
| | | throw e; |
| | | } finally { |
| | | if (urlConnection != null) |
| | | urlConnection.disconnect(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 默认的响应字符集 |
| | | */ |
| | | public String getDefaultContentEncoding() { |
| | | return this.defaultContentEncoding; |
| | | } |
| | | |
| | | /** |
| | | * 设置默认的响应字符集 |
| | | */ |
| | | public void setDefaultContentEncoding(String defaultContentEncoding) { |
| | | this.defaultContentEncoding = defaultContentEncoding; |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
New file |
| | |
| | | package com.ruoyi.account.util; |
| | | |
| | | |
| | | |
| | | import org.apache.commons.httpclient.HttpClient; |
| | | import org.apache.commons.httpclient.methods.InputStreamRequestEntity; |
| | | import org.apache.commons.httpclient.methods.PostMethod; |
| | | import org.apache.commons.httpclient.methods.RequestEntity; |
| | | |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.Vector; |
| | | |
| | | |
| | | |
| | | public class HttpRespons { |
| | | String urlString; |
| | | |
| | | int defaultPort; |
| | | |
| | | String file; |
| | | |
| | | String host; |
| | | |
| | | String path; |
| | | |
| | | int port; |
| | | |
| | | String protocol; |
| | | |
| | | String query; |
| | | |
| | | String ref; |
| | | |
| | | String userInfo; |
| | | |
| | | String contentEncoding; |
| | | |
| | | String content; |
| | | |
| | | String contentType; |
| | | |
| | | int code; |
| | | |
| | | String message; |
| | | |
| | | String method; |
| | | |
| | | int connectTimeout; |
| | | |
| | | int readTimeout; |
| | | |
| | | Vector<String> contentCollection; |
| | | |
| | | public String getContent() { |
| | | return content; |
| | | } |
| | | |
| | | public String getContentType() { |
| | | return contentType; |
| | | } |
| | | |
| | | public int getCode() { |
| | | return code; |
| | | } |
| | | |
| | | public String getMessage() { |
| | | return message; |
| | | } |
| | | |
| | | public Vector<String> getContentCollection() { |
| | | return contentCollection; |
| | | } |
| | | |
| | | public String getContentEncoding() { |
| | | return contentEncoding; |
| | | } |
| | | |
| | | public String getMethod() { |
| | | return method; |
| | | } |
| | | |
| | | public int getConnectTimeout() { |
| | | return connectTimeout; |
| | | } |
| | | |
| | | public int getReadTimeout() { |
| | | return readTimeout; |
| | | } |
| | | |
| | | public String getUrlString() { |
| | | return urlString; |
| | | } |
| | | |
| | | public int getDefaultPort() { |
| | | return defaultPort; |
| | | } |
| | | |
| | | public String getFile() { |
| | | return file; |
| | | } |
| | | |
| | | public String getHost() { |
| | | return host; |
| | | } |
| | | |
| | | public String getPath() { |
| | | return path; |
| | | } |
| | | |
| | | public int getPort() { |
| | | return port; |
| | | } |
| | | |
| | | public String getProtocol() { |
| | | return protocol; |
| | | } |
| | | |
| | | public String getQuery() { |
| | | return query; |
| | | } |
| | | |
| | | public String getRef() { |
| | | return ref; |
| | | } |
| | | |
| | | public String getUserInfo() { |
| | | return userInfo; |
| | | } |
| | | |
| | | |
| | | public static String post(String params,String requestUrl) throws IOException { |
| | | // try { |
| | | //HttpRequester request = new HttpRequester(); |
| | | // request.setDefaultContentEncoding("utf-8"); |
| | | byte[] requestBytes = params.getBytes("utf-8"); // 将参数转为二进制流 |
| | | HttpClient httpClient = new HttpClient(); // 客户端实例化 |
| | | PostMethod postMethod = new PostMethod(requestUrl); |
| | | //设置请求头Authorization |
| | | // postMethod.setRequestHeader("Authorization", "Basic " + authorization); |
| | | // 设置请求头 Content-Type |
| | | postMethod.setRequestHeader("Content-Type", "application/json"); |
| | | InputStream inputStream = new ByteArrayInputStream(requestBytes, 0,requestBytes.length); |
| | | RequestEntity requestEntity = new InputStreamRequestEntity(inputStream, |
| | | requestBytes.length, "application/json; charset=utf-8"); // 请求体 |
| | | postMethod.setRequestEntity(requestEntity); |
| | | httpClient.executeMethod(postMethod);// 执行请求 |
| | | InputStream soapResponseStream = postMethod.getResponseBodyAsStream();// 获取返回的流 |
| | | byte[] datas = null; |
| | | try { |
| | | datas = readInputStream(soapResponseStream);// 从输入流中读取数据 |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | String result = new String(datas, "UTF-8");// 将二进制流转为String |
| | | // 打印返回结果 |
| | | // System.out.println(result); |
| | | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 从输入流中读取数据 |
| | | * |
| | | * @param inStream |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static byte[] readInputStream(InputStream inStream) throws Exception { |
| | | ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| | | byte[] buffer = new byte[1024]; |
| | | int len = 0; |
| | | while ((len = inStream.read(buffer)) != -1) { |
| | | outStream.write(buffer, 0, len); |
| | | } |
| | | byte[] data = outStream.toByteArray(); |
| | | outStream.close(); |
| | | inStream.close(); |
| | | return data; |
| | | } |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.util; |
| | | |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * 定义生成随机码的工具类 |
| | | */ |
| | | public class UUIDUtil { |
| | | |
| | | private int i = 1; |
| | | |
| | | |
| | | /** |
| | | * 定义生成原生的UUID随机码 |
| | | * |
| | | * @return |
| | | */ |
| | | public static String getNativeUUID() { |
| | | return UUID.randomUUID().toString(); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 生成32位随机码 |
| | | * |
| | | * @return |
| | | */ |
| | | public static String getRandomCode() { |
| | | return UUIDUtil.getNativeUUID().replaceAll("-", ""); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取给定长度的随机码 |
| | | * |
| | | * @param num |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static String getRandomCode(Integer num) throws Exception { |
| | | String str = null; |
| | | if (0 < num) { |
| | | if (num % 32 > 0) { |
| | | Integer s = num / 32; |
| | | Integer l = num % 32; |
| | | StringBuffer sb = new StringBuffer(); |
| | | for (int i = 0; i < s; i++) { |
| | | sb.append(UUIDUtil.getRandomCode()); |
| | | } |
| | | sb.append(UUIDUtil.getRandomCode().substring(0, l)); |
| | | str = sb.toString(); |
| | | } else if (num % 32 == 0) { |
| | | Integer s = num / 32; |
| | | StringBuffer sb = new StringBuffer(); |
| | | for (int i = 0; i < s; i++) { |
| | | sb.append(UUIDUtil.getRandomCode()); |
| | | } |
| | | str = sb.toString(); |
| | | } else { |
| | | str = UUIDUtil.getRandomCode().substring(0, num); |
| | | } |
| | | } else { |
| | | throw new Exception("参数只能大于0"); |
| | | } |
| | | return str; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 获取根据当前时间的字符串数据 |
| | | * |
| | | * @return |
| | | */ |
| | | public synchronized static String getTimeStr() { |
| | | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmssS"); |
| | | return simpleDateFormat.format(new Date()); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * @Description: 获取数字随机码 |
| | | * @Author pzb |
| | | * @Date 2021/8/11 16:52 |
| | | * @Param |
| | | * @Return |
| | | * @Exception |
| | | */ |
| | | public static String getNumberRandom(Integer num) { |
| | | if (null == num) { |
| | | num = 32; |
| | | } |
| | | StringBuffer sb = new StringBuffer(); |
| | | for (int i = 0; i < num; i++) { |
| | | sb.append(Double.valueOf(Math.random() * 10).intValue()); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.util.withdraw; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | import com.ruoyi.account.api.model.UserWithdraw; |
| | | import com.ruoyi.common.core.utils.StringUtils; |
| | | import com.ruoyi.other.api.domain.ShopWithdraw; |
| | | import org.apache.http.HttpResponse; |
| | | import org.apache.http.client.HttpClient; |
| | | import org.apache.http.client.config.RequestConfig; |
| | | import org.apache.http.client.methods.CloseableHttpResponse; |
| | | import org.apache.http.client.methods.HttpGet; |
| | | import org.apache.http.client.methods.HttpPost; |
| | | import org.apache.http.conn.ClientConnectionManager; |
| | | import org.apache.http.conn.scheme.Scheme; |
| | | import org.apache.http.conn.scheme.SchemeRegistry; |
| | | import org.apache.http.conn.ssl.DefaultHostnameVerifier; |
| | | import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
| | | import org.apache.http.conn.ssl.SSLSocketFactory; |
| | | import org.apache.http.entity.StringEntity; |
| | | import org.apache.http.impl.client.CloseableHttpClient; |
| | | import org.apache.http.impl.client.DefaultHttpClient; |
| | | import org.apache.http.impl.client.HttpClients; |
| | | |
| | | import javax.net.ssl.SSLContext; |
| | | import javax.net.ssl.TrustManager; |
| | | import javax.net.ssl.X509TrustManager; |
| | | import java.io.*; |
| | | import java.net.URLEncoder; |
| | | import java.nio.charset.StandardCharsets; |
| | | import java.security.KeyManagementException; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | import java.security.cert.X509Certificate; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /** |
| | | * 三方提现工具类 |
| | | */ |
| | | public class HttpUtilWithdraw { |
| | | |
| | | //设置请求和传输超时时间 |
| | | private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).build(); |
| | | //初始化需要用到的参数 |
| | | private static final String CLIENT_TYPE = "1"; |
| | | private static final String CLIENT_VERSION = "1.0.0"; |
| | | private static final String APP_CONFIG_ID = "8597918391594056444"; |
| | | private static final String API_KEY = "jo_pay_S4UIWYjWmy46d9yX9N2QWZffD"; |
| | | private static final String API_SECRET = "cad03aaf2019530090d642aa9b2f0cbb"; |
| | | |
| | | private static final String STRING_KEY = "pay_open_api_vwHXa2ay1Dv7E${clientType}${clientVersion}${apiKey}${apiSecret}${timestamp}"; |
| | | private static final String URL = "https://pay.new.jieoukeji.cn/jo-pay-open-api"; |
| | | private static final String PATH = "/v1/safe/withdraw";//示例接口:获取银行卡信息 |
| | | private static final Pattern VALUE_PATTERN = Pattern.compile("\\$\\{([^}]*)\\}"); |
| | | |
| | | public static void main(String[] args) throws IOException { |
| | | long timestamp = System.currentTimeMillis(); |
| | | Map<String,String> headers = new HashMap<>(6); |
| | | headers.put("client-type",CLIENT_TYPE); |
| | | headers.put("client-version",CLIENT_VERSION); |
| | | headers.put("api-secret",API_SECRET); |
| | | headers.put("api-key",API_KEY); |
| | | headers.put("access-timestamp",String.valueOf(timestamp)); |
| | | headers.put("Content-Type","application/json"); |
| | | //拼接字符串,签名开头保留,${} 全替换为header参数 |
| | | headers.put("access-sign",getSign(STRING_KEY,timestamp)); |
| | | //开始请求API接口 |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("orderCode", "09127389681694"); |
| | | param.put("cardNo", "6228480469852935177"); |
| | | param.put("name", "周帅"); |
| | | param.put("withdrawType", "1"); |
| | | param.put("accountType", "00"); |
| | | param.put("bankName", "中国农业银行"); |
| | | // param.put("brachBankCode", "123546345674573457"); |
| | | param.put("money", "0.1"); |
| | | param.put("appConfigId", APP_CONFIG_ID); |
| | | try { |
| | | String results = post(URL+PATH,headers, param); |
| | | //返回结果JSON字符串 |
| | | System.out.println(results); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | |
| | | |
| | | // String url = "https://ccdcapi.alipay.com/validateAndCacheCardInfo.json?_input_charset=utf-8&" + |
| | | // "cardNo=" + "6228480469852935177" + "&cardBinCheck=true"; |
| | | // HashMap<String, String> hashMap = new HashMap<>(); |
| | | // HttpRequester hr = new HttpRequester(); |
| | | // HttpRespons HP = hr.sendPost(url, hashMap); |
| | | // System.out.println("接收返回参数:" + HP.getContent()); |
| | | // JSONObject resPay = JSONObject.parseObject(HP.getContent()); |
| | | // System.err.println(resPay); |
| | | // if (resPay.getString("validated") == null) { |
| | | // System.err.println("不合法的银行卡号"); |
| | | // } |
| | | // String bankName = BankCode.getBankNameByCode("ABC"); // 返回ABC枚举实例 |
| | | // System.err.println(bankName); |
| | | } |
| | | |
| | | public static String withdraw(ShopWithdraw shopWithdraw, String bankName) { |
| | | long timestamp = System.currentTimeMillis(); |
| | | Map<String, String> headers = new HashMap<>(6); |
| | | headers.put("client-type", CLIENT_TYPE); |
| | | headers.put("client-version", CLIENT_VERSION); |
| | | headers.put("api-secret", API_SECRET); |
| | | headers.put("api-key", API_KEY); |
| | | headers.put("access-timestamp", String.valueOf(timestamp)); |
| | | headers.put("Content-Type", "application/json"); |
| | | //拼接字符串,签名开头保留,${} 全替换为header参数 |
| | | headers.put("access-sign", getSign(STRING_KEY, timestamp)); |
| | | //开始请求API接口 |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("orderCode", shopWithdraw.getCode()); |
| | | param.put("cardNo", shopWithdraw.getReceiverAccountNoEnc()); |
| | | param.put("name", shopWithdraw.getReceiverNameEnc()); |
| | | param.put("withdrawType", "1"); |
| | | if (shopWithdraw.getReceiverAccountType().equals(204)) { |
| | | param.put("accountType", "01"); |
| | | param.put("bankName", bankName); |
| | | param.put("brachBankCode", shopWithdraw.getReceiverBankChannelNo()); |
| | | } else { |
| | | param.put("accountType", "00"); |
| | | } |
| | | param.put("money", shopWithdraw.getMoney()); |
| | | param.put("appConfigId", APP_CONFIG_ID); |
| | | try { |
| | | String results = post(URL + PATH, headers, param); |
| | | //返回结果JSON字符串 |
| | | System.out.println(results); |
| | | JSONObject jsonObject = JSONObject.parseObject(results); |
| | | if (jsonObject.getString("result").equals("true")){ |
| | | return "success"; |
| | | }else{ |
| | | return jsonObject.getString("message"); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return "打款失败"; |
| | | } |
| | | public static String userWithdraw(UserWithdraw userWithdraw, String bankName) { |
| | | long timestamp = System.currentTimeMillis(); |
| | | Map<String, String> headers = new HashMap<>(6); |
| | | headers.put("client-type", CLIENT_TYPE); |
| | | headers.put("client-version", CLIENT_VERSION); |
| | | headers.put("api-secret", API_SECRET); |
| | | headers.put("api-key", API_KEY); |
| | | headers.put("access-timestamp", String.valueOf(timestamp)); |
| | | headers.put("Content-Type", "application/json"); |
| | | //拼接字符串,签名开头保留,${} 全替换为header参数 |
| | | headers.put("access-sign", getSign(STRING_KEY, timestamp)); |
| | | //开始请求API接口 |
| | | Map<String, Object> param = new HashMap<>(); |
| | | param.put("orderCode", userWithdraw.getCode()); |
| | | param.put("cardNo", userWithdraw.getReceiverAccountNoEnc()); |
| | | param.put("name", userWithdraw.getReceiverNameEnc()); |
| | | param.put("withdrawType", "1"); |
| | | if (userWithdraw.getReceiverAccountType().equals(204)) { |
| | | param.put("accountType", "01"); |
| | | param.put("bankName", bankName); |
| | | param.put("brachBankCode", userWithdraw.getReceiverBankChannelNo()); |
| | | } else { |
| | | param.put("accountType", "00"); |
| | | } |
| | | param.put("money", userWithdraw.getMoney()); |
| | | param.put("appConfigId", APP_CONFIG_ID); |
| | | try { |
| | | String results = post(URL + PATH, headers, param); |
| | | //返回结果JSON字符串 |
| | | System.out.println(results); |
| | | JSONObject jsonObject = JSONObject.parseObject(results); |
| | | if (jsonObject.getString("result").equals("true")){ |
| | | return "success"; |
| | | }else{ |
| | | return jsonObject.getString("message"); |
| | | } |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | return "打款失败"; |
| | | } |
| | | |
| | | /** |
| | | * 发起post请求,请求参数以Map集合形式传入 |
| | | * |
| | | * @param httpUrl |
| | | * @param body |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static String post(String httpUrl, Map<String, String> headers, Map<String, Object> body) { |
| | | CloseableHttpClient httpclient = createSSLClientDefault(); |
| | | BufferedReader in; |
| | | HttpPost httpPost = new HttpPost(httpUrl); |
| | | try { |
| | | httpPost.setHeader("Accept", "application/json"); |
| | | for (Map.Entry<String, String> headerMap : headers.entrySet()) { |
| | | httpPost.addHeader(headerMap.getKey(), headerMap.getValue()); |
| | | } |
| | | httpPost.setConfig(requestConfig); |
| | | StringEntity entity = new StringEntity(JSON.toJSONString(body), StandardCharsets.UTF_8); |
| | | entity.setContentType("application/json"); |
| | | httpPost.setEntity(entity); |
| | | |
| | | CloseableHttpResponse response = httpclient.execute(httpPost); |
| | | InputStream content = response.getEntity().getContent(); |
| | | in = new BufferedReader(new InputStreamReader(content, StandardCharsets.UTF_8)); |
| | | StringBuilder sb = new StringBuilder(); |
| | | String line; |
| | | while ((line = in.readLine()) != null) { |
| | | sb.append(line); |
| | | } |
| | | return sb.toString(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | try { |
| | | httpclient.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 发起get请求,请求参数以Map集合形式传入 |
| | | * |
| | | * @param httpUrl |
| | | * @param params |
| | | * @return |
| | | * @throws Exception |
| | | */ |
| | | public static String get(String httpUrl, Map<String, String> headers, Map<String, String> params) { |
| | | CloseableHttpClient httpclient = createSSLClientDefault(); |
| | | BufferedReader in; |
| | | List<String> paramList = new ArrayList<>(); |
| | | for (Map.Entry<String, String> param : params.entrySet()) { |
| | | paramList.add(param.getKey() + "=" + param.getValue()); |
| | | } |
| | | HttpGet httpGet = new HttpGet(httpUrl + "?" + String.join("&", paramList)); |
| | | try { |
| | | httpGet.setHeader("Accept", "application/json"); |
| | | for (Map.Entry<String, String> headerMap : headers.entrySet()) { |
| | | httpGet.addHeader(headerMap.getKey(), headerMap.getValue()); |
| | | } |
| | | httpGet.setConfig(requestConfig); |
| | | |
| | | CloseableHttpResponse response = httpclient.execute(httpGet); |
| | | InputStream content = response.getEntity().getContent(); |
| | | in = new BufferedReader(new InputStreamReader(content, StandardCharsets.UTF_8)); |
| | | StringBuilder sb = new StringBuilder(); |
| | | String line; |
| | | while ((line = in.readLine()) != null) { |
| | | sb.append(line); |
| | | } |
| | | return sb.toString(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } finally { |
| | | try { |
| | | httpclient.close(); |
| | | } catch (IOException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static CloseableHttpClient createSSLClientDefault() { |
| | | try { |
| | | // SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { |
| | | // 在JSSE中,证书信任管理器类就是实现了接口X509TrustManager的类。我们可以自己实现该接口,让它信任我们指定的证书。 |
| | | // 创建SSLContext对象,并使用我们指定的信任管理器初始化 |
| | | // 信任所有 |
| | | X509TrustManager x509mgr = new X509TrustManager() { |
| | | // 该方法检查客户端的证书,若不信任该证书则抛出异常 |
| | | @Override |
| | | public void checkClientTrusted(X509Certificate[] xcs, String string) { |
| | | } |
| | | |
| | | // 该方法检查服务端的证书,若不信任该证书则抛出异常 |
| | | @Override |
| | | public void checkServerTrusted(X509Certificate[] xcs, String string) { |
| | | } |
| | | |
| | | // 返回受信任的X509证书数组。 |
| | | @Override |
| | | public X509Certificate[] getAcceptedIssuers() { |
| | | return null; |
| | | } |
| | | }; |
| | | SSLContext sslContext = SSLContext.getInstance(SSLConnectionSocketFactory.TLS); |
| | | sslContext.init(null, new TrustManager[]{x509mgr}, null); |
| | | // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象 |
| | | SSLConnectionSocketFactory sslSf = new SSLConnectionSocketFactory(sslContext, new DefaultHostnameVerifier()); |
| | | // HttpsURLConnection对象就可以正常连接HTTPS了,无论其证书是否经权威机构的验证,只要实现了接口X509TrustManager的类MyX509TrustManager信任该证书。 |
| | | return HttpClients.custom().setSSLSocketFactory(sslSf).build(); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | } |
| | | // 创建默认的httpClient实例. |
| | | return HttpClients.createDefault(); |
| | | } |
| | | |
| | | /** |
| | | * 获取签名前准备参数 |
| | | * |
| | | * @param format |
| | | * @param timestamp |
| | | * @return |
| | | */ |
| | | public static String getSign(String format, long timestamp) { |
| | | JSONObject dataSign = new JSONObject(); |
| | | dataSign.put("clientType", CLIENT_TYPE); |
| | | dataSign.put("clientVersion", CLIENT_VERSION); |
| | | dataSign.put("apiSecret", API_SECRET); |
| | | dataSign.put("apiKey", API_KEY); |
| | | dataSign.put("timestamp", timestamp); |
| | | String formatData = getFormatData(dataSign, format); |
| | | return md5(formatData); |
| | | } |
| | | |
| | | /** |
| | | * 拼接替换生成签名前字符串 |
| | | * |
| | | * @return |
| | | */ |
| | | public static String getFormatData(JSONObject data, String format) { |
| | | |
| | | System.err.println(data); |
| | | System.err.println(format); |
| | | Matcher matcher = VALUE_PATTERN.matcher(format); |
| | | while (true) { |
| | | while (matcher.find()) { |
| | | String sign = matcher.group(); |
| | | String key = matcher.group(1); |
| | | if (ObjectUtils.isNotEmpty(key)) { |
| | | format = format.replace(sign, data.containsKey(key) && ObjectUtils.isNotEmpty(data.getString(key)) && !"null".equalsIgnoreCase(data.getString(key)) ? data.getString(key) : ""); |
| | | } else { |
| | | format = format.replace(sign, ""); |
| | | } |
| | | } |
| | | return format; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 生成md5,小写 |
| | | * |
| | | * @param message |
| | | * @return |
| | | */ |
| | | public static String md5(String message) { |
| | | try { |
| | | // 1 创建一个提供信息摘要算法的对象,初始化为md5算法对象 |
| | | MessageDigest md = MessageDigest.getInstance("MD5"); |
| | | |
| | | // 2 将消息变成byte数组 |
| | | byte[] input = message.getBytes(); |
| | | |
| | | // 3 计算后获得字节数组,这就是那128位了 |
| | | byte[] buff = md.digest(input); |
| | | |
| | | // 4 把数组每一字节(一个字节占八位)换成16进制连成md5字符串 |
| | | return byte2hex(buff); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 二进制转十六进制字符串 |
| | | * |
| | | * @param bytes |
| | | * @return |
| | | */ |
| | | private static String byte2hex(byte[] bytes) { |
| | | StringBuilder sign = new StringBuilder(); |
| | | for (int i = 0; i < bytes.length; i++) { |
| | | String hex = Integer.toHexString(bytes[i] & 0xFF); |
| | | if (hex.length() == 1) { |
| | | sign.append("0"); |
| | | } |
| | | sign.append(hex.toLowerCase()); |
| | | } |
| | | return sign.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 调用apiPost方法 |
| | | * |
| | | * @return |
| | | */ |
| | | public static HttpResponse doPost(String host, String path, String method, |
| | | Map<String, String> headers, |
| | | Map<String, String> querys, |
| | | String body) |
| | | throws Exception { |
| | | HttpClient httpClient = wrapClient(host); |
| | | |
| | | HttpPost request = new HttpPost(buildUrl(host, path, querys)); |
| | | for (Map.Entry<String, String> e : headers.entrySet()) { |
| | | request.addHeader(e.getKey(), e.getValue()); |
| | | } |
| | | |
| | | if (StringUtils.isNotBlank(body)) { |
| | | request.setEntity(new StringEntity(body, "utf-8")); |
| | | } |
| | | return httpClient.execute(request); |
| | | } |
| | | |
| | | public static HttpClient wrapClient(String host) { |
| | | HttpClient httpClient = new DefaultHttpClient(); |
| | | if (host.startsWith("https://")) { |
| | | sslClient(httpClient); |
| | | } |
| | | |
| | | return httpClient; |
| | | } |
| | | |
| | | public static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException { |
| | | StringBuilder sbUrl = new StringBuilder(); |
| | | sbUrl.append(host); |
| | | if (!StringUtils.isBlank(path)) { |
| | | sbUrl.append(path); |
| | | } |
| | | if (null != querys) { |
| | | StringBuilder sbQuery = new StringBuilder(); |
| | | for (Map.Entry<String, String> query : querys.entrySet()) { |
| | | if (0 < sbQuery.length()) { |
| | | sbQuery.append("&"); |
| | | } |
| | | if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) { |
| | | sbQuery.append(query.getValue()); |
| | | } |
| | | if (!StringUtils.isBlank(query.getKey())) { |
| | | sbQuery.append(query.getKey()); |
| | | if (!StringUtils.isBlank(query.getValue())) { |
| | | sbQuery.append("="); |
| | | sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8")); |
| | | } |
| | | } |
| | | } |
| | | if (0 < sbQuery.length()) { |
| | | sbUrl.append("?").append(sbQuery); |
| | | } |
| | | } |
| | | |
| | | return sbUrl.toString(); |
| | | } |
| | | |
| | | private static void sslClient(HttpClient httpClient) { |
| | | try { |
| | | SSLContext ctx = SSLContext.getInstance("TLS"); |
| | | X509TrustManager tm = new X509TrustManager() { |
| | | @Override |
| | | public X509Certificate[] getAcceptedIssuers() { |
| | | return null; |
| | | } |
| | | |
| | | @Override |
| | | public void checkClientTrusted(X509Certificate[] xcs, String str) { |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public void checkServerTrusted(X509Certificate[] xcs, String str) { |
| | | |
| | | } |
| | | }; |
| | | ctx.init(null, new TrustManager[]{tm}, null); |
| | | SSLSocketFactory ssf = new SSLSocketFactory(ctx); |
| | | ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); |
| | | ClientConnectionManager ccm = httpClient.getConnectionManager(); |
| | | SchemeRegistry registry = ccm.getSchemeRegistry(); |
| | | registry.register(new Scheme("https", 443, ssf)); |
| | | } catch (KeyManagementException ex) { |
| | | throw new RuntimeException(ex); |
| | | } catch (NoSuchAlgorithmException ex) { |
| | | throw new RuntimeException(ex); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.ruoyi.account.util.withdraw; |
| | | |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * 三方提现回调DTO |
| | | */ |
| | | @Data |
| | | public class WithdrawCallBackDTO { |
| | | |
| | | @ApiModelProperty(value = "数据签名,") |
| | | private String sign; |
| | | @ApiModelProperty(value = "打款订单号") |
| | | private String orderCode; |
| | | @ApiModelProperty(value = "交易流水号") |
| | | private String tradeNo; |
| | | @ApiModelProperty(value = "打款金额") |
| | | private BigDecimal money; |
| | | @ApiModelProperty(value = "订单状态 0待支付 1已支付 2处理中 4交易失败") |
| | | private Integer status; |
| | | @ApiModelProperty(value = "打款时间") |
| | | private LocalDateTime time; |
| | | @ApiModelProperty(value = "订单状态信息") |
| | | private String message; |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="com.ruoyi.account.mapper.UserWithdrawMapper"> |
| | | |
| | | <!-- 通用查询映射结果 --> |
| | | <resultMap id="BaseResultMap" type="com.ruoyi.account.api.model.UserWithdraw"> |
| | | <id column="id" property="id" /> |
| | | <result column="app_user_id" property="appUserId" /> |
| | | <result column="money" property="money" /> |
| | | <result column="integral" property="integral" /> |
| | | <result column="audit_status" property="auditStatus" /> |
| | | <result column="audit_user_id" property="auditUserId" /> |
| | | <result column="audit_time" property="auditTime" /> |
| | | <result column="audit_msg" property="auditMsg" /> |
| | | <result column="status" property="status" /> |
| | | <result column="arrival_time" property="arrivalTime" /> |
| | | <result column="del_flag" property="delFlag" /> |
| | | <result column="create_time" property="createTime" /> |
| | | </resultMap> |
| | | |
| | | <!-- 通用查询结果列 --> |
| | | <sql id="Base_Column_List"> |
| | | id, app_user_id, money, integral, audit_status, audit_user_id, audit_time, audit_msg, status, arrival_time, del_flag, create_time |
| | | </sql> |
| | | <select id="page" resultType="com.ruoyi.account.api.model.UserWithdraw"> |
| | | select t1.*,t2.phone,t2.name from |
| | | t_user_withdraw t1 |
| | | left join t_app_user t2 on t1.app_user_id = t2.id |
| | | </select> |
| | | |
| | | </mapper> |