提交 1ac3bc13 authored 作者: jacksmith1988's avatar jacksmith1988

//add code

上级 425a771c
package me.zohar.runscore.config.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.io.IOException;
......@@ -9,12 +10,13 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@WebFilter(filterName = "CorsFilter")
@Configuration
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
......
......@@ -5,174 +5,176 @@ import lombok.Getter;
/**
* 业务处理错误枚举类
*
*
* @author zohar
* @date 2019年1月7日
*
*/
@Getter
@AllArgsConstructor
public enum BizError {
参数异常("1000", "参数异常"),
参数异常("1000", "参数异常"),
保证金余额不足("1006", "保证金余额不足"),
用户名已存在("1014", "用户名已存在"),
无权查看投注记录("1015", "无权查看投注记录"),
旧的登录密码不正确("1016", "旧的登录密码不正确"),
旧的资金密码不正确("1017", "旧的资金密码不正确"),
资金密码不正确("1017", "资金密码不正确"),
签名不正确("1018", "签名不正确"),
充值订单不存在("1019", "充值订单不存在"),
只有待支付状态的充值订单才能取消("1019", "只有待支付状态的充值订单才能取消"),
发起支付异常("1021", "发起支付异常"),
存款时间不能为空("1019", "存款时间不能为空"),
存款人姓名不能为空("1019", "存款人姓名不能为空"),
银行卡未绑定无法进行提现("1014", "银行卡未绑定无法进行提现"),
只有状态为发起提现的记录才能审核通过("1014", "只有状态为发起提现的记录才能审核通过"),
只有状态为发起提现或审核通过的记录才能进行审核不通过操作("1014", "只有状态为发起提现或审核通过的记录才能进行审核不通过操作"),
只有状态为审核通过的记录才能进行确认到帐操作("1014", "只有状态为审核通过的记录才能进行确认到帐操作"),
邀请码不存在或已失效("1014", "邀请码不存在或已失效"),
未开放注册功能("1014", "未开放注册功能"),
字典项code不能重复("1000", "字典项code不能重复"),
邀请人不存在("1014", "邀请人不存在"),
邀请注册功能已关闭("1014", "邀请注册功能已关闭"),
无权查看数据("1015", "无权查看数据"),
无权删除数据("1015", "无权删除数据"),
商户未接入("1015", "商户未接入"),
系统无可用商户("1015", "系统无可用商户"),
商户订单不存在("1015", "商户订单不存在"),
保证金余额不足("1006", "保证金余额不足"),
不支持该支付类型("1015", "不支持该支付类型"),
用户名已存在("1014", "用户名已存在"),
订单已被接或已取消("1015", "订单已被接或已取消"),
无权查看投注记录("1015", "无权查看投注记录"),
保证金不足无法接单("1015", "保证金不足无法接单"),
旧的登录密码不正确("1016", "旧的登录密码不正确"),
订单状态为已接单或平台已确认支付才能转为确认已支付("1015", "订单状态为已接单或平台已确认支付才能转为确认已支付"),
旧的资金密码不正确("1017", "旧的资金密码不正确"),
订单状态为申述中才能转为确认已支付("1015", "订单状态为申述中才能转为确认已支付"),
资金密码不正确("1017", "资金密码不正确"),
保证金不足无法转为确认已支付("1015", "保证金不足无法转为确认已支付"),
签名不正确("1018", "签名不正确"),
无权确认订单("1015", "无权确认订单"),
充值订单不存在("1019", "充值订单不存在"),
无权获取平台订单收款码信息("1015", "无权获取平台订单收款码信息"),
只有待支付状态的充值订单才能取消("1019", "只有待支付状态的充值订单才能取消"),
无权更新商户订单状态为商户已确认支付("1015", "无权更新商户订单状态为商户已确认支付"),
发起支付异常("1021", "发起支付异常"),
存款时间不能为空("1019", "存款时间不能为空"),
存款人姓名不能为空("1019", "存款人姓名不能为空"),
订单状态为已接单才能转为平台已确认支付("1015", "订单状态为已接单才能转为平台已确认支付"),
银行卡未绑定无法进行提现("1014", "银行卡未绑定无法进行提现"),
只有等待接单状态的商户订单才能取消("1019", "只有等待接单状态的商户订单才能取消"),
只有状态为发起提现的记录才能审核通过("1014", "只有状态为发起提现的记录才能审核通过"),
找不到所属账号无法新增收款码("1019", "找不到所属账号无法新增收款码"),
只有状态为发起提现或审核通过的记录才能进行审核不通过操作("1014", "只有状态为发起提现或审核通过的记录才能进行审核不通过操作"),
订单状态为已接单或平台已确认支付才能申请取消订单("1015", "订单状态为已接单或平台已确认支付才能申请取消订单"),
只有状态为审核通过的记录才能进行确认到帐操作("1014", "只有状态为审核通过的记录才能进行确认到帐操作"),
无权取消订单("1015", "无权取消订单"),
邀请码不存在或已失效("1014", "邀请码不存在或已失效"),
未开放注册功能("1014", "未开放注册功能"),
只有申请取消订单状态的平台订单才能转为未支付取消订单("1019", "只有申请取消订单状态的平台订单才能转为未支付取消订单"),
字典项code不能重复("1000", "字典项code不能重复"),
只能上传图片类型的收款码("1015", "只能上传图片类型的收款码"),
邀请人不存在("1014", "邀请人不存在"),
未设置收款码无法接单("1015", "未设置收款码无法接单"),
邀请注册功能已关闭("1014", "邀请注册功能已关闭"),
无法接单找不到对应金额的收款码("1015", "无法接单,找不到对应金额的收款码"),
无权查看数据("1015", "无权查看数据"),
实际支付金额须小于收款金额("1015", "实际支付金额须小于收款金额"),
无权删除数据("1015", "无权删除数据"),
保证金不足无法手工减保证金("1014", "保证金不足,无法手工减保证金"),
商户未接入("1015", "商户未接入"),
关联账号不存在("1014", "关联账号不存在"),
商户订单不存在("1015", "商户订单不存在"),
不支持该支付类型("1015", "不支持该支付类型"),
订单已被接或已取消("1015", "订单已被接或已取消"),
账号已关联其他商户("1014", "账号已关联其他商户,无法重复关联"),
保证金不足无法接单("1015", "保证金不足无法接单"),
只能关联商户类型的账号("1014", "只能关联商户类型的账号"),
订单状态为已接单或平台已确认支付才能转为确认已支付("1015", "订单状态为已接单或平台已确认支付才能转为确认已支付"),
订单状态为申述中才能转为确认已支付("1015", "订单状态为申述中才能转为确认已支付"),
商户号已使用("1014", "商户号已使用,请使用另外的商户号"),
保证金不足无法转为确认已支付("1015", "保证金不足无法转为确认已支付"),
商户名称已使用("1014", "商户名称已使用,请使用另外的商户名称"),
无权确认订单("1015", "无权确认订单"),
该订单存在未处理的申诉记录不能重复发起("1015", "该订单存在未处理的申诉记录,不能重复发起"),
无权获取平台订单收款码信息("1015", "无权获取平台订单收款码信息"),
申诉类型不合法("1015", "申诉类型不合法"),
无权更新商户订单状态为商户已确认支付("1015", "无权更新商户订单状态为商户已确认支付"),
无权撤销申诉("1015", "无权撤销申诉"),
订单状态为已接单才能转为平台已确认支付("1015", "订单状态为已接单才能转为平台已确认支付"),
当前申诉已完结无法更改处理方式("1015", "当前申诉已完结无法更改处理方式"),
只有等待接单状态的商户订单才能取消("1019", "只有等待接单状态的商户订单才能取消"),
该申诉类型的处理方式不能是改为实际支付金额("1015", "该申诉类型的处理方式不能是改为实际支付金额"),
找不到所属账号无法新增收款码("1019", "找不到所属账号无法新增收款码"),
该申诉类型的处理方式不能是取消订单("1015", "该申诉类型的处理方式不能是取消订单"),
订单状态为已接单或平台已确认支付才能申请取消订单("1015", "订单状态为已接单或平台已确认支付才能申请取消订单"),
只有申诉中的商户订单才能取消订单退款("1019", "只有申诉中的商户订单才能取消订单退款"),
无权取消订单("1015", "无权取消订单"),
当前申诉已完结("1015", "当前申诉已完结"),
只有申请取消订单状态的平台订单才能转为未支付取消订单("1019", "只有申请取消订单状态的平台订单才能转为未支付取消订单"),
不是申诉发起方无权撤销申诉("1015", "不是申诉发起方,无权撤销申诉"),
只能上传图片类型的收款码("1015", "只能上传图片类型的收款码"),
用户已提供截图无法撤销申诉("1015", "用户已提供截图,无法撤销申诉"),
未设置收款码无法接单("1015", "未设置收款码无法接单"),
商户已提供截图无法撤销申诉("1015", "商户已提供截图,无法撤销申诉"),
无法接单找不到对应金额的收款码("1015", "无法接单,找不到对应金额的收款码"),
实际支付金额须小于收款金额("1015", "实际支付金额须小于收款金额"),
无权上传截图("1015", "无权上传截图"),
保证金不足无法手工减保证金("1014", "保证金不足,无法手工减保证金"),
只有待处理的申诉记录才能上传截图("1015", "只有待处理的申诉记录才能上传截图"),
关联账号不存在("1014", "关联账号不存在"),
已有截图不能重复上传("1015", "已有截图不能重复上传"),
账号已关联其他商户("1014", "账号已关联其他商户,无法重复关联"),
不能设置重复的返点("1000", "不能设置重复的返点"),
只能关联商户类型的账号("1014", "只能关联商户类型的账号"),
该返点已存在("1000", "该返点已存在"),
商户号已使用("1014", "商户号已使用,请使用另外的商户号"),
只有管理员或代理才能进行代理开户操作("1000", "只有管理员或代理才能进行代理开户操作"),
商户名称已使用("1014", "商户名称已使用,请使用另外的商户名称"),
下级账号的返点不能大于上级账号("1000", "下级账号的返点不能大于上级账号"),
该订单存在未处理的申诉记录不能重复发起("1015", "该订单存在未处理的申诉记录,不能重复发起"),
该返点未设置("1000", "该返点未设置"),
申诉类型不合法("1015", "申诉类型不合法"),
已达到接单数量上限("1015", "已达到接单数量上限,请先处理待审核的订单"),
无权撤销申诉("1015", "无权撤销申诉"),
未达到接单保证金最低要求("1015", "未达到接单保证金最低要求,请先充值"),
当前申诉已完结无法更改处理方式("1015", "当前申诉已完结无法更改处理方式"),
用户名不存在("1014", "用户名不存在"),
该申诉类型的处理方式不能是改为实际支付金额("1015", "该申诉类型的处理方式不能是改为实际支付金额"),
不是上级账号无权查看该账号及下级的接单记录("1014", "不是上级账号无权查看该账号及下级的接单记录"),
该申诉类型的处理方式不能是取消订单("1015", "该申诉类型的处理方式不能是取消订单"),
不是上级账号无权查看该账号及下级的账号信息("1014", "不是上级账号无权查看该账号及下级的账号信息"),
只有申诉中的商户订单才能取消订单退款("1019", "只有申诉中的商户订单才能取消订单退款"),
不是上级账号无权查看该账号及下级的帐变日志("1014", "不是上级账号无权查看该账号及下级的帐变日志"),
当前申诉已完结("1015", "当前申诉已完结"),
不是上级账号无权查看该账号及下级的充值记录("1014", "不是上级账号无权查看该账号及下级的充值记录"),
不是申诉发起方无权撤销申诉("1015", "不是申诉发起方,无权撤销申诉"),
不是上级账号无权查看该账号及下级的提现记录("1014", "不是上级账号无权查看该账号及下级的提现记录"),
;
用户已提供截图无法撤销申诉("1015", "用户已提供截图,无法撤销申诉"),
商户已提供截图无法撤销申诉("1015", "商户已提供截图,无法撤销申诉"),
无权上传截图("1015", "无权上传截图"),
只有待处理的申诉记录才能上传截图("1015", "只有待处理的申诉记录才能上传截图"),
已有截图不能重复上传("1015", "已有截图不能重复上传"),
不能设置重复的返点("1000", "不能设置重复的返点"),
该返点已存在("1000", "该返点已存在"),
只有管理员或代理才能进行代理开户操作("1000", "只有管理员或代理才能进行代理开户操作"),
下级账号的返点不能大于上级账号("1000", "下级账号的返点不能大于上级账号"),
该返点未设置("1000", "该返点未设置"),
已达到接单数量上限("1015", "已达到接单数量上限,请先处理待审核的订单"),
未达到接单保证金最低要求("1015", "未达到接单保证金最低要求,请先充值"),
用户名不存在("1014", "用户名不存在"),
不是上级账号无权查看该账号及下级的接单记录("1014", "不是上级账号无权查看该账号及下级的接单记录"),
不是上级账号无权查看该账号及下级的账号信息("1014", "不是上级账号无权查看该账号及下级的账号信息"),
不是上级账号无权查看该账号及下级的帐变日志("1014", "不是上级账号无权查看该账号及下级的帐变日志"),
不是上级账号无权查看该账号及下级的充值记录("1014", "不是上级账号无权查看该账号及下级的充值记录"),
不是上级账号无权查看该账号及下级的提现记录("1014", "不是上级账号无权查看该账号及下级的提现记录"),;
private String code;
private String code;
private String msg;
private String msg;
}
......@@ -124,6 +124,8 @@ public class Constant {
public static final String 账变日志类型_奖励金返点 = "12";
public static final String 账变日志类型_订单结算 = "13";
public static final String 充提日志订单类型_充值 = "1";
public static final String 充提日志订单类型_提现 = "2";
......
package me.zohar.runscore.merchant.domain;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.Column;
......@@ -77,4 +78,10 @@ public class Merchant {
@JoinColumn(name = "relevance_account_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private UserAccount relevanceAccount;
private BigDecimal alipayRate;
private BigDecimal wechatRate;
private BigDecimal bankcardRate;
}
......@@ -32,139 +32,149 @@ import me.zohar.runscore.useraccount.domain.UserAccount;
@DynamicUpdate(true)
public class MerchantOrder {
/**
* 主键id
*/
@Id
@Column(name = "id", length = 32)
private String id;
/**
* 订单号
*/
private String orderNo;
/**
* 收款渠道
*/
private String gatheringChannelCode;
/**
* 收款金额
*/
private Double gatheringAmount;
/**
* 提交时间
*/
private Date submitTime;
/**
* 有效时间
*/
private Date usefulTime;
/**
* 订单状态
*/
private String orderState;
/**
* 备注
*/
private String note;
@Column(name = "merchant_id", length = 32)
private String merchantId;
/**
* 接单人账号id
*/
@Column(name = "received_account_id", length = 32)
private String receivedAccountId;
/**
* 接单时间
*/
private Date receivedTime;
private String gatheringCodeStorageId;
/**
* 商户确认时间
*/
private Date platformConfirmTime;
/**
* 处理时间
*/
private Date dealTime;
/**
* 确认时间
*/
private Date confirmTime;
/**
* 奖励金
*/
private Double bounty;
/**
* 乐观锁版本号
*/
@Version
private Long version;
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private Merchant merchant;
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "received_account_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private UserAccount receivedAccount;
@Column(name = "pay_info_id", length = 32)
private String payInfoId;
@NotFound(action = NotFoundAction.IGNORE)
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pay_info_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private MerchantOrderPayInfo payInfo;
public void updateBounty(Double bounty) {
this.setBounty(bounty);
}
public void merchantConfirmToPaid() {
this.setOrderState(Constant.商户订单状态_商户已确认支付);
this.setPlatformConfirmTime(new Date());
}
public void confirmToPaid(String note) {
this.setOrderState(Constant.商户订单状态_已支付);
this.setConfirmTime(new Date());
this.setDealTime(this.getConfirmTime());
this.setNote(note);
}
public void updateReceived(String receivedAccountId, String gatheringCodeStorageId) {
this.setReceivedAccountId(receivedAccountId);
this.setGatheringCodeStorageId(gatheringCodeStorageId);
this.setOrderState(Constant.商户订单状态_已接单);
this.setReceivedTime(new Date());
}
public void customerCancelOrderRefund() {
this.setOrderState(Constant.商户订单状态_客服取消订单退款);
this.setConfirmTime(new Date());
this.setDealTime(this.getConfirmTime());
}
public void updateUsefulTime(Date usefulTime) {
this.setUsefulTime(usefulTime);
}
/**
* 主键id
*/
@Id
@Column(name = "id", length = 32)
private String id;
/**
* 订单号
*/
private String orderNo;
/**
* 收款渠道
*/
private String gatheringChannelCode;
/**
* 收款金额
*/
private Double gatheringAmount;
/**
* 提交时间
*/
private Date submitTime;
/**
* 有效时间
*/
private Date usefulTime;
/**
* 订单状态
*/
private String orderState;
/**
* 备注
*/
private String note;
@Column(name = "merchant_id", length = 32)
private String merchantId;
/**
* 接单人账号id
*/
@Column(name = "received_account_id", length = 32)
private String receivedAccountId;
/**
* 接单时间
*/
private Date receivedTime;
private String gatheringCodeStorageId;
/**
* 商户确认时间
*/
private Date platformConfirmTime;
/**
* 处理时间
*/
private Date dealTime;
/**
* 确认时间
*/
private Date confirmTime;
/**
* 奖励金
*/
private Double bounty;
/**
* 扣除手续费的金额
*/
private Double settleAmount;
/**
* 乐观锁版本号
*/
@Version
private Long version;
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "merchant_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private Merchant merchant;
@NotFound(action = NotFoundAction.IGNORE)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "received_account_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private UserAccount receivedAccount;
@Column(name = "pay_info_id", length = 32)
private String payInfoId;
@NotFound(action = NotFoundAction.IGNORE)
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "pay_info_id", updatable = false, insertable = false, foreignKey = @ForeignKey(value = ConstraintMode.NO_CONSTRAINT))
private MerchantOrderPayInfo payInfo;
public void updateSettleAmount(Double settleAmount) {
this.setSettleAmount(settleAmount);
}
public void updateBounty(Double bounty) {
this.setBounty(bounty);
}
public void merchantConfirmToPaid() {
this.setOrderState(Constant.商户订单状态_商户已确认支付);
this.setPlatformConfirmTime(new Date());
}
public void confirmToPaid(String note) {
this.setOrderState(Constant.商户订单状态_已支付);
this.setConfirmTime(new Date());
this.setDealTime(this.getConfirmTime());
this.setNote(note);
}
public void updateReceived(String receivedAccountId, String gatheringCodeStorageId) {
this.setReceivedAccountId(receivedAccountId);
this.setGatheringCodeStorageId(gatheringCodeStorageId);
this.setOrderState(Constant.商户订单状态_已接单);
this.setReceivedTime(new Date());
}
public void customerCancelOrderRefund() {
this.setOrderState(Constant.商户订单状态_客服取消订单退款);
this.setConfirmTime(new Date());
this.setDealTime(this.getConfirmTime());
}
public void updateUsefulTime(Date usefulTime) {
this.setUsefulTime(usefulTime);
}
}
package me.zohar.runscore.merchant.service;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
......@@ -28,6 +22,7 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import com.zengtengpeng.annotation.Lock;
......@@ -113,7 +108,6 @@ public class MerchantOrderService {
private OrderRebateRepo orderRebateRepo;
@Transactional(readOnly = true)
public MerchantOrderDetailsVO findMerchantOrderDetailsById(@NotBlank String orderId) {
MerchantOrderDetailsVO vo = MerchantOrderDetailsVO.convertFor(merchantOrderRepo.getOne(orderId));
......@@ -202,7 +196,7 @@ public class MerchantOrderService {
@Transactional(readOnly = true)
public GatheringCode getGatheringCode(String receivedAccountId, String gatheringChannelCode,
Double gatheringAmount) {
Double gatheringAmount) {
ReceiveOrderSetting merchantOrderSetting = platformOrderSettingRepo.findTopByOrderByLatelyUpdateTime();
if (merchantOrderSetting.getUnfixedGatheringCodeReceiveOrder()) {
GatheringCode gatheringCode = gatheringCodeRepo
......@@ -219,7 +213,7 @@ public class MerchantOrderService {
return gatheringCode;
}
}
return null;
return new GatheringCode();
}
@Transactional
......@@ -234,7 +228,8 @@ public class MerchantOrderService {
}
platformOrder.confirmToPaid(null);
merchantOrderRepo.save(platformOrder);
receiveOrderBountySettlement(platformOrder);
merchantSettlement(platformOrder);
// receiveOrderBountySettlement(platformOrder);
}
/**
......@@ -251,7 +246,51 @@ public class MerchantOrderService {
}
platformOrder.confirmToPaid(note);
merchantOrderRepo.save(platformOrder);
receiveOrderBountySettlement(platformOrder);
merchantSettlement(platformOrder);
// receiveOrderBountySettlement(platformOrder);
}
/**
* 商户加钱
*/
@Transactional
public void merchantSettlement(MerchantOrder merchantOrder) {
UserAccount userAccount = merchantOrder.getReceivedAccount();
Merchant merchant = merchantOrder.getMerchant();
BigDecimal rate = new BigDecimal(0);
switch (merchantOrder.getGatheringChannelCode()) {
case Constant.支付渠道_微信码:
rate = Optional.ofNullable(merchant.getWechatRate()).orElse(new BigDecimal(0));
break;
case Constant.支付渠道_支付宝码:
rate = Optional.ofNullable(merchant.getAlipayRate()).orElse(new BigDecimal(0));
break;
case Constant.支付渠道_银行卡:
rate = Optional.ofNullable(merchant.getBankcardRate()).orElse(new BigDecimal(0));
break;
default:
break;
}
double rateFee = NumberUtil.round(merchantOrder.getGatheringAmount() * rate.doubleValue(), 4)
.doubleValue();
double merchantSettleAmount = merchantOrder.getGatheringAmount() - rateFee;
merchantOrder.updateSettleAmount(merchantSettleAmount);
//商户结算
UserAccount merchantAccount = merchant.getRelevanceAccount();
double cashDeposit = merchantAccount.getCashDeposit() + merchantSettleAmount;
merchantAccount.setCashDeposit(NumberUtil.round(cashDeposit, 4).doubleValue());
userAccountRepo.save(merchantAccount);
accountChangeLogRepo.save(AccountChangeLog.buildWithMerchantSettle(userAccount, merchantOrder));
}
/**
......@@ -419,8 +458,9 @@ public class MerchantOrderService {
merchantOrderPayInfoRepo.save(payInfo);
//todo this is temporary code 这里要匹配有资源的用户接单
List<UserAccount> userAccounts = userAccountRepo.findAllByAccountType(Constant.账号类型_会员);
;
List<UserAccount> userAccounts = userAccountRepo.findAllByAccountTypeAndState(Constant.账号类型_会员, Constant.账号状态_启用).orElseThrow(() -> new BizException(BizError.系统无可用商户));
this.receiveOrder(userAccounts.get(RandomUtil.randomInt(0, userAccounts.size())).getId(), merchantOrder.getId());
return MerchantOrderVO.convertFor(merchantOrder);
......@@ -446,7 +486,7 @@ public class MerchantOrderService {
String gatheringCodeStorageId = getGatheringCodeStorageId(userAccountId,
platformOrder.getGatheringChannelCode(), platformOrder.getGatheringAmount());
//支付宝和微信才有收款码
if (StrUtil.isBlank(gatheringCodeStorageId) && !platformOrder.getGatheringChannelCode().equals(Constant.支付渠道_银行卡) ) {
if (StrUtil.isBlank(gatheringCodeStorageId) && !platformOrder.getGatheringChannelCode().equals(Constant.支付渠道_银行卡)) {
throw new BizException(BizError.无法接单找不到对应金额的收款码);
}
// 校验用户是否达到接单上限,若达到上限,则不能接单
......
......@@ -11,6 +11,7 @@ import com.fasterxml.jackson.annotation.JsonFormat;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.Data;
import me.zohar.runscore.constants.Constant;
import me.zohar.runscore.dictconfig.ConfigHolder;
import me.zohar.runscore.dictconfig.DictHolder;
import me.zohar.runscore.merchant.domain.MerchantOrder;
......@@ -136,7 +137,14 @@ public class MerchantOrderVO {
if (StrUtil.isNotBlank(merchantOrder.getReceivedAccountId()) && merchantOrder.getReceivedAccount() != null) {
vo.setReceiverUserName(merchantOrder.getReceivedAccount().getUserName());
}
vo.setPayUrl(ConfigHolder.getConfigValue("merchantOrderPayUrl") + vo.getOrderNo());
if(merchantOrder.getGatheringChannelCode().equals(Constant.支付渠道_银行卡))
{
vo.setPayUrl(ConfigHolder.getConfigValue("merchantOrderPayUrlForCard") + vo.getOrderNo());
}else
{
vo.setPayUrl(ConfigHolder.getConfigValue("merchantOrderPayUrl") + vo.getOrderNo());
}
vo.setPayInfo(MerchantOrderPayInfoVO.convertFor(merchantOrder.getPayInfo()));
return vo;
}
......
......@@ -35,6 +35,6 @@ public class TotalAccountReceiveOrderSituation {
private Long paidOrderNum;
private Double rebateAmount;
//private Double rebateAmount;
}
......@@ -302,4 +302,24 @@ public class AccountChangeLog {
return log;
}
/**
* 构建商户结算账变日志
*
* @param userAccount
* @param merchantOrder
* @return
*/
public static AccountChangeLog buildWithMerchantSettle(UserAccount userAccount, MerchantOrder merchantOrder) {
AccountChangeLog log = new AccountChangeLog();
log.setId(IdUtils.getId());
log.setOrderNo(merchantOrder.getId());
log.setAccountChangeTime(new Date());
log.setAccountChangeTypeCode(Constant.账变日志类型_订单结算);
log.setAccountChangeAmount(NumberUtil.round(merchantOrder.getSettleAmount(), 4).doubleValue());
log.setCashDeposit(userAccount.getCashDeposit());
log.setUserAccountId(userAccount.getId());
return log;
}
}
......@@ -4,15 +4,18 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import java.util.List;
import java.util.Optional;
import me.zohar.runscore.useraccount.domain.UserAccount;
public interface UserAccountRepo extends JpaRepository<UserAccount, String>, JpaSpecificationExecutor<UserAccount> {
UserAccount findByUserName(String userName);
Long countByInviterId(String inviterId);
List<UserAccount> findAllByAccountType(String accountType);
UserAccount findByUserName(String userName);
Long countByInviterId(String inviterId);
List<UserAccount> findAllByAccountType(String accountType);
Optional<List<UserAccount>> findAllByAccountTypeAndState(String accountType, String state);
}
......@@ -86,4 +86,9 @@ public class PageController {
return "pay";
}
@GetMapping("/bankpay")
public String bankpay() {
return "bankpay";
}
}
package me.zohar.runscore.config.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.io.IOException;
......@@ -9,12 +10,13 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@WebFilter(filterName = "CorsFilter")
@Configuration
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
......
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta name="renderer" content="webkit">
<title>支付</title>
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-resource/1.5.1/vue-resource.min.js"></script>
<script src="https://cdn.bootcss.com/layer/2.3/layer.js"></script>
<script src="https://cdn.bootcss.com/dayjs/1.7.8/dayjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/clipboard.js/1.5.12/clipboard.min.js"></script>
<style type="text/css">
@charset "UTF-8";
[v-cloak] {
display: none;
}
html, body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial,
sans-serif;
font-weight: 400;
overflow-x: hidden;
overflow-y: auto;
background: #f4f6f8;
font-size: 14px;
color: #616161;
}
.container {
max-width: 650px;
margin: 0 auto;
}
.header {
background: #fff;
border-bottom: 1px solid #eee;
height: 130px;
padding-top: 1px;
text-align: center;
margin-bottom: 15px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.04);
}
.header .logo {
width: 123px;
height: 130px;
margin: 0 auto;
background: url(union.png) no-repeat;
background-size: cover;
}
.header .logo.union {
background-image: url(union.png);
}
.mainbody {
margin: 0 auto;
margin-top: 15px;
padding-bottom: 10px;
text-align: center;
color: #333;
padding-top: 6px;
background: #fff;
background-size: auto 6px;
min-height: 400px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
}
.realprice {
font-size: 26px;
margin-top: 5px;
margin-bottom: 5px;
}
.discountprice {
color: #ff6600;
margin-bottom: 10px;
}
.qrcode {
width: 200px;
height: 200px;
margin: 20px auto;
position: relative;
}
.qrcode img {
width: 100%;
height: 100%;
}
.qrcode .logo {
position: absolute;
top: 50%;
left: 50%;
height: 30px;
width: 30px;
margin-left: -15px;
margin-top: -15px;
background: #fff url("wechat.png") no-repeat center center;
background-size: cover;
border-radius: 3px;
}
.qrcode .logo.logo-alipay {
background-image: url("alipay.png");
}
.qrcode .expired {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
opacity: .95;
background: #fff url("expired.png") center center no-repeat;
}
.qrcode .paid {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
opacity: .95;
background: #fff url("paid.png") center center no-repeat;
}
.warning {
color: #f00;
}
.success {
color: #05af19;
}
.remainseconds {
width: 200px;
margin: 0 auto;
text-align: center;
}
.remainseconds .time {
width: 55px;
height: 90px;
}
.remainseconds .time b {
font-size: 40px;
font-weight: 300;
}
.remainseconds .time b, .remainseconds .time em {
display: block;
}
.remainseconds .time em {
font-style: normal;
color: #888;
}
@media ( max-width : 375px) {
.container {
padding: 0;
}
.remainseconds {
padding: 0 35px 10px 35px;
height: 80px;
}
.remainseconds .time {
height: 100%;
}
.remainseconds .time b {
font-size: 36px;
}
}
@media ( max-width : 320px) {
.remainseconds {
padding: 0 35px 10px 35px;
height: 87px;
}
.remainseconds .time {
height: 100%;
}
.remainseconds .time b {
font-size: 36px;
}
.container {
padding: 0;
}
.qrcode {
width: 200px;
height: 200px;
}
.realprice {
font-size: 36px;
}
}
.minutes {
float: left;
}
.seconds {
float: left;
}
.colon {
float: left;
width: 20px;
font-size: 30px;
line-height: 50px;
font-family: Vernada, 'Microsoft Yahei';
}
.tips {
background: #fff;
padding: 5px 0;
line-height: 25px;
overflow: hidden;
display: block;
clear: both;
}
.help {
line-height: 25px;
text-align: center;
font-size: 14px;
}
.footer {
height: 60px;
line-height: 60px;
text-align: center;
font-size: 12px;
}
.overdue {
position: absolute;
width: 100%;
margin: 0 auto;
top: 260px;
display: none;
}
</style>
</head>
<body>
<div id="pay" class="container" v-cloak>
<div class="mainbody">
<div class="realprice">
<span>{{orderInfo.gatheringAmount}}</span>
</div>
<h1 class="text-center text-success" style="color: #468847;" v-show="paySuccessFlag">
<strong>支付成功</strong>
</h1>
<div class="qrcode" v-show="!paySuccessFlag">
<div v-show="!overdueFlag">
银行:<b>{{orderInfo.gatheringCode.bankAddress}}</b><br>
户主:<span id="username"><b>{{orderInfo.gatheringCode.bankUsername}}</b></span>
<button class="app_btn" data-clipboard-action="copy" data-clipboard-target="#username" id="copy_btn1">复制</button>
<br>
卡号:<span id="bankcode"><b>{{orderInfo.gatheringCode.bankCode}}</b></span>
<button class="app_btn" data-clipboard-action="copy" data-clipboard-target="#bankcode" id="copy_btn2">复制</button>
<br>
</div>
<!-- <img class="image" :src="orderInfo.gatheringCodeStorageId != null ? '/storage/fetch/' + orderInfo.gatheringCodeStorageId : 'images/pay/loading.gif'" style="width: 200px; height: 200px;" v-show="!overdueFlag">-->
<img class="image" src="images/pay/overdue.png" style="width: 200px; height: 200px;" v-show="overdueFlag">
</div>
<div class="remainseconds">
<p>
有效时间: <span id="leftTime" style="color: red;">{{countdownMinute}}:{{countdownSecond}}</span><br>过期请重新发起支付
</p>
</div>
<div class="tips">
<p style="color: red; font-weight: bold;">卡信息仅当次有效,请勿重复支付</p>
<!-- <p>请使用{{orderInfo.gatheringChannelName}}扫一扫</p>-->
<!-- <p>或</p>-->
<!-- <p>截屏后打开{{orderInfo.gatheringChannelName}}扫一扫,从相册中选择图片</p>-->
</div>
<div class="help">
任何问题请联系客服<br> 订单号:<span>{{orderNo}}</span>
</div>
</div>
</div>
<script type="text/javascript">
// 在点击复制按钮上new一个 Clipboard 对象
let clipboard1 = new Clipboard('.app_btn');
//然后设置复制成功的回调监听
clipboard1.on('success', function (e) {
// 复制成功时
// 清除选中的文字的选择状态
e.clearSelection();
alert('复制成功')
});
/*let clipboard2 = new Clipboard('#copy_btn2');
//然后设置复制成功的回调监听
clipboard2.on('success', function (e) {
// 复制成功时
// 清除选中的文字的选择状态
e.clearSelection();
alert('复制成功')
});*/
Vue.http.interceptors.push(function(request) {
return function(response) {
if (response.body.code != 200) {
response.ok = false;
layer.alert(response.body.msg, {
title : '提示',
icon : 7,
time : 3000
});
}
};
});
var payVM = new Vue({
el : '#pay',
data : {
orderNo : '',
overdueFlag : false,
residueSecond : '',
countdownHour : '',
countdownMinute : '--',
countdownSecond : '--',
countdownInterval : null,
paySuccessFlag : false,
checkPaySuccessInterval : null,
orderInfo : {},
},
computed : {},
created : function() {
var orderNo = this.getQueryString('orderNo');
if (orderNo == null || orderNo == '') {
layer.alert('无效的订单号', {
title : '提示',
icon : 7,
time : 3000
});
return;
}
this.orderNo = orderNo;
this.firstLoadGatheringCode();
},
methods : {
firstLoadGatheringCode : function() {
var that = this;
that.$http.get('/api/getOrderGatheringCode', {
params : {
orderNo : that.orderNo
}
}).then(function(res) {
that.orderInfo = res.body.data;
if (that.orderInfo.orderState == '4') {
that.paySuccessFlag = true;
that.toReturnUrl();
return;
}
that.overdueFlag = !dayjs(that.orderInfo.usefulTime).isAfter(dayjs());
if (!that.overdueFlag) {
that.residueSecond = dayjs(that.orderInfo.usefulTime).diff(dayjs(res.body.timestamp), 'second');
that.countdown();
if (that.orderInfo.orderState == '1') {
that.loadGatheringCode();
}
}
});
},
toReturnUrl : function() {
var that = this;
setTimeout(function() {
window.location.href = that.orderInfo.returnUrl;
}, 2000);
},
loadGatheringCode : function() {
var that = this;
that.loadGatheringCodeInterval = window.setInterval(function() {
if (that.orderInfo.orderState == '2' || that.orderInfo.orderState == '4') {
if (that.loadGatheringCodeInterval != null) {
window.clearInterval(that.loadGatheringCodeInterval);
that.loadGatheringCodeInterval = null;
}
return;
}
that.loadGatheringCodeInner();
}, 3000);
},
loadGatheringCodeInner : function() {
var that = this;
that.$http.get('/api/getOrderGatheringCode', {
params : {
orderNo : that.orderNo
}
}).then(function(res) {
that.orderInfo = res.body.data;
if (that.orderInfo.orderState == '2' || that.orderInfo.orderState == '4') {
that.residueSecond = dayjs(that.orderInfo.usefulTime).diff(dayjs(res.body.timestamp), 'second');
that.checkPaySuccess();
}
});
},
checkPaySuccess : function() {
var that = this;
that.checkPaySuccessInterval = window.setInterval(function() {
if (that.orderInfo.orderState == '4') {
that.paySuccessFlag = true;
that.toReturnUrl();
if (that.checkPaySuccessInterval != null) {
window.clearInterval(that.checkPaySuccessInterval);
that.checkPaySuccessInterval = null;
}
if (that.countdownInterval != null) {
window.clearInterval(that.countdownInterval);
that.countdownInterval = null;
}
return;
}
that.checkPaySuccessInner();
}, 3000);
},
checkPaySuccessInner : function() {
var that = this;
that.$http.get('/api/getOrderGatheringCode', {
params : {
orderNo : that.orderNo
}
}).then(function(res) {
that.orderInfo = res.body.data;
});
},
countdown : function() {
var that = this;
that.countdownInterval = window.setInterval(function() {
var residueSecond = that.residueSecond;
that.updateCountdownClock(residueSecond);
residueSecond--;
that.residueSecond = residueSecond;
if (residueSecond < 0) {
window.clearInterval(that.countdownInterval);
that.countdownInterval = null;
if (that.loadGatheringCodeInterval != null) {
window.clearInterval(that.loadGatheringCodeInterval);
that.loadGatheringCodeInterval = null;
}
that.overdueFlag = true;
}
}, 1000);
},
/**
* 更新倒计时
*/
updateCountdownClock : function(residueSecond) {
var that = this;
var countdownHour = 0;
var countdownMinute = 0;
var countdownSecond = 0;
if (residueSecond > 0) {
countdownHour = parseInt(residueSecond / (60 * 60) % 24);
countdownMinute = parseInt(residueSecond / 60 % 60);
countdownSecond = parseInt(residueSecond % 60);
}
if (countdownHour < 10) {
countdownHour = '0' + countdownHour;
}
if (countdownMinute < 10) {
countdownMinute = '0' + countdownMinute;
}
if (countdownSecond < 10) {
countdownSecond = '0' + countdownSecond;
}
that.countdownHour = countdownHour;
that.countdownMinute = countdownMinute;
that.countdownSecond = countdownSecond;
console.log(that.countdownSecond);
},
getQueryString : function(name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = window.location.search.substr(1).match(reg);
if (r != null)
return unescape(r[2]);
return null;
}
}
});
</script>
</body>
</html>
\ No newline at end of file
......@@ -18,7 +18,7 @@
<li class="nav-item" v-bind:class="{'active': currentPathName == '/appeal-record'}" v-on:click="navTo('/appeal-record')"><a class="nav-link">申诉记录</a></li>
</ul>
<form class="form-inline" style="float: right;">
<span style="padding-right: 20px;">商户端:{{userName}}</span>
<span style="padding-right: 20px;">商户端:{{userName}} 当前余额:{{cashDeposit}}</span>
<button type="button" class="btn btn-light btn-sm" v-on:click="logout">退出登录</button>
</form>
</nav>
......@@ -41,7 +41,8 @@
el : '#header',
data : {
userName : '',
currentPathName : ''
currentPathName : '',
cashDeposit:''
},
computed : {},
created : function() {
......@@ -63,6 +64,7 @@
that.isLoggedInFlag = false;
} else {
that.userName = res.body.data.userName;
that.cashDeposit = res.body.data.cashDeposit;
}
});
},
......
package me.zohar.runscore.config.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.io.IOException;
......@@ -9,12 +10,13 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@WebFilter(filterName = "CorsFilter")
@Configuration
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
......
......@@ -866,7 +866,7 @@ CREATE TABLE `v_merchant_everyday_statistical` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ----------------------------
/*-- ----------------------------
-- Table structure for v_merchant_month_statistical
-- ----------------------------
DROP TABLE IF EXISTS `v_merchant_month_statistical`;
......@@ -901,7 +901,7 @@ CREATE TABLE `v_merchant_total_statistical` (
`trade_amount` double DEFAULT NULL,
PRIMARY KEY (`merchant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
*/
-- ----------------------------
-- Table structure for v_rebate_situation
-- ----------------------------
......
/*
MySQL Backup
Database: runscore
Backup Time: 2021-11-13 10:39:45
*/
SET FOREIGN_KEY_CHECKS=0;
DROP VIEW IF EXISTS `runscore`.`v_merchant_month_statistical`;
DROP VIEW IF EXISTS `runscore`.`v_merchant_today_statistical`;
DROP VIEW IF EXISTS `runscore`.`v_merchant_total_statistical`;
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v_merchant_month_statistical` AS select `po`.`merchant_id` AS `merchant_id`,round(sum(`po`.`gathering_amount`),4) AS `gathering_amount`,count(1) AS `order_num`,round(sum((case when (`po`.`order_state` = '4') then `po`.`gathering_amount` else 0 end)),4) AS `trade_amount`,sum((case when (`po`.`order_state` = '4') then 1 else 0 end)) AS `paid_order_num` from (`merchant_order` `po` left join `merchant` `ua` on((`po`.`merchant_id` = `ua`.`id`))) where ((`po`.`received_account_id` is not null) and (`po`.`submit_time` >= str_to_date(date_format(curdate(),'%Y-%m-01 00:00:00'),'%Y-%m-%d %H:%i:%s')) and (`po`.`submit_time` < (str_to_date(date_format(curdate(),'%Y-%m-01 00:00:00'),'%Y-%m-%d %H:%i:%s') + interval 1 month))) group by `po`.`merchant_id`;
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v_merchant_today_statistical` AS select `po`.`merchant_id` AS `merchant_id`,round(sum(`po`.`gathering_amount`),4) AS `gathering_amount`,count(1) AS `order_num`,round(sum((case when (`po`.`order_state` = '4') then `po`.`gathering_amount` else 0 end)),4) AS `trade_amount`,sum((case when (`po`.`order_state` = '4') then 1 else 0 end)) AS `paid_order_num` from (`merchant_order` `po` left join `merchant` `ua` on((`po`.`merchant_id` = `ua`.`id`))) where ((`po`.`received_account_id` is not null) and (`po`.`received_time` >= str_to_date(date_format(now(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s')) and (`po`.`received_time` < (str_to_date(date_format(now(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s') + interval 1 day))) group by `po`.`merchant_id`;
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `v_merchant_total_statistical` AS select `po`.`merchant_id` AS `merchant_id`,round(sum(`po`.`gathering_amount`),4) AS `gathering_amount`,count(1) AS `order_num`,round(sum((case when (`po`.`order_state` = '4') then `po`.`gathering_amount` else 0 end)),4) AS `trade_amount`,sum((case when (`po`.`order_state` = '4') then 1 else 0 end)) AS `paid_order_num` from (`merchant_order` `po` left join `merchant` `ua` on((`po`.`merchant_id` = `ua`.`id`))) where (`po`.`received_account_id` is not null) group by `po`.`merchant_id`;
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论