Merge remote-tracking branch 'origin/master'

This commit is contained in:
齐天大圣 2024-05-10 16:54:19 +08:00
commit 2515d22ede
12 changed files with 481 additions and 17 deletions

View File

@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fuint.api.fuyou.entity.Const;
import com.fuint.api.fuyou.entity.MerchantConfig;
import com.fuint.api.fuyou.entity.ReceiveParameterPos;
import com.fuint.api.fuyou.service.FyPayService;
import com.fuint.api.fuyou.service.MerchantConfigRecordService;
import com.fuint.api.fuyou.service.MerchantConfigService;
@ -31,6 +32,9 @@ import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/api/fyPay")
public class FyPayController {
@Autowired
@Lazy
private FyPayService fyPayService;
@Autowired
@Lazy
private OilOrderService orderService;
@ -109,4 +113,58 @@ public class FyPayController {
cardFuelRecordService.fuleRechargeFinallDeal(orderNo);
}
}
@GetMapping("/test")
public String test() throws Exception {
ReceiveParameterPos receiveParameterPos = new ReceiveParameterPos();
receiveParameterPos.setPayType("WECHAT");
receiveParameterPos.setContent("ceshi");
receiveParameterPos.setOrderNo("20240509fdskjhv003");
receiveParameterPos.setStoreId(141);
receiveParameterPos.setGoodsMoney(0.01);
fyPayService.mainScan(receiveParameterPos);
return "succse";
}
// 接收支付平台异步通知的接口
@PostMapping("/notifyScan")
public String notifyUrlScan(HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("----------------收到支付回调--------"+request.getParameter("req"));
String notifyData = request.getParameter("req");
String decode = URLDecoder.decode(notifyData, Const.charset);
Map<String, String> reqMap = Utils.xmlStr2Map(decode);
if (reqMap.get("result_msg").equals("SUCCESS")){
String orderNo = reqMap.get("mchnt_order_no");
String transactionId = reqMap.get("transaction_id");
String settleOrderAmt = reqMap.get("settle_order_amt");
String orderLock = "orderLock_notify"+orderNo;
if (redisLock.tryLock(orderLock,5000, TimeUnit.MILLISECONDS)){
// 业务逻辑 判断订单状态
// AllOrderInfo allOrderInfo = allOrderInfoService.selectAllOrderInfoByOrderNo(orderNo);
// if (ObjectUtil.isNotEmpty(allOrderInfo)){
// allOrderInfo.setPayMoney(Double.valueOf(settleOrderAmt)/100);
// allOrderInfo.setTransactionId(transactionId);
// allOrderInfo.setStatus("paid");
// allOrderInfo.setPayTime(new Date());
// allOrderInfoService.updateAllOrderInfo(allOrderInfo);
//
// // 修改配置收款账户余额信息
// MerchantConfig merchantConfig = merchantConfigService.selectMeChByIdIsUse(allOrderInfo.getStoreId());
// Double beforeAmount = merchantConfig.getAmount();
// Double afterAmount = beforeAmount + allOrderInfo.getPayMoney();
// merchantConfig.setAmount(afterAmount);
// merchantConfigService.updateMerch(merchantConfig);
// merchantConfigRecordService.updateMerchantConfigRecordByOrderNo(orderNo,"yes");
// }
//
// updateOrderStatus(orderNo,allOrderInfo.getType());
//// 修改订单支付状态
// redisLock.unlock(orderLock);
}
// transaction_id 加锁
return "1";
}else {
return "0";
}
}
}

View File

@ -146,4 +146,39 @@ public class Builder {
return map;
}
/**
* 主扫
*
* @return
*/
public static Map<String, String> buildFuiou25() {
Map<String, String> map = new HashMap<>();
map.put("version", Const.version);
map.put("ins_cd", Const.ins_cd);
map.put("mchnt_cd", Const.mchnt_cd);
map.put("term_id", Const.term_id);
map.put("random_str", randomNumberGenerator.nextBytes().toHex());
map.put("sign", "");
map.put("order_type", Const.order_type);
map.put("goods_des", Const.goods_des);
map.put("goods_detail", "");
map.put("addn_inf", "");
SimpleDateFormat sdf_no = new SimpleDateFormat("yyyyMMddHHmmssSSS");
Calendar calendar = Calendar.getInstance();
// sdf_no.format(calendar.getTime()) + (int) (random.nextDouble() * 100000)
map.put("mchnt_order_no", "");
map.put("curr_type", "CNY");
map.put("order_amt", "1");
map.put("term_ip", Const.term_ip);
SimpleDateFormat sdf_ts = new SimpleDateFormat("yyyyMMddHHmmss");
map.put("txn_begin_ts", sdf_ts.format(calendar.getTime()));
map.put("goods_tag", "");
map.put("notify_url", Const.notify_url_scan);
map.put("reserved_expire_minute", "5");
return map;
}
}

View File

@ -48,11 +48,15 @@ public class Const {
public static String INS_PUBLIC_KEYS="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCj1SsMt4S9SMcNpXrcQ9ET4hHdX0UX/1RTdD9GzxzSDwTEsLQuUNaX0VP8NQ7NWvMdgCYnST74oV81ht0GQd3aax6fyXjDETYC5tq0sHkJxwtiynTcssPBjM2LipTeY6Sv8cUS1MPnvRX2Cs1RXkB8ZdUp9dCaNnTxFOPJGB1E4wIDAQAB";
public static String NOTIFY_PUBLIC_KEYS="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbBAl3xSB7YeUnze4yYZmnTeT7OtXZr0sP10TsDVRH2SY/VEjgS9KPmHMmVeKZT3+6xKsUvulgVyie46GGtZPrnoh+glF1gzsYAXJ7dvR/R5nYO5VvfwK/ChPFTiKhbTtO4OKtchgBZuqCbsemG+gFIiVJo37dY0Kg0zISmFHdOQIDAQAB";
//异步通知(回调地址)
//小程序异步通知(回调地址)
public static String notify_url = "https://www.tuofeng.cc/oilAdmin/api/fyPay/notify";
// public static String notify_url = "https://8q4f124343.yicp.fun/api/fyPay/notify";
//下单
//主扫异步通知(回调地址)
// public static String notify_url_scan = "https://www.tuofeng.cc/oilAdmin/api/fyPay/notifyScan";
public static String notify_url_scan = "https://8q4f124343.yicp.fun/api/fyPay/notifyScan";
//主扫下单
public static String fuiou_21_url = "https://fundwx.fuiou.com/preCreate";
//扫码
public static String fuiou_22_url = "https://fundwx.fuiou.com/micropay";
@ -79,4 +83,6 @@ public class Const {
public static String fuiou_33_url = "https://spay-cloud.fuioupay.com/commonRefund";
//生产地址 查询
public static String fuiou_34_url = "https://spay-cloud.fuioupay.com/commonQuery";
//主扫
public static String fuiou_35_url = "https://spay-cloud.fuioupay.com/preCreate";
}

View File

@ -0,0 +1,42 @@
package com.fuint.api.fuyou.entity;
import lombok.Data;
/**
* 接收的参数
*/
@Data
public class ReceiveParameterPos {
/**
* 用户二维码code值
*/
private String authCode;
/**
* 订单号与业务表统一
*/
private String orderNo;
/**
* 类型1油品2商品3储值卡4积分5囤油卡6油品加商品(收银台订单)7挂账订单
*/
private String type;
/**
* 店铺id
*/
private Integer storeId;
/**
* 原价 不需要做(*100)的处理
*/
private Double goodsMoney;
/**
* 付款方式数据字典
*/
private String payType;
/**
* 用户id
*/
private Integer userId;
/**
* 订单描述
*/
private String content;
}

View File

@ -1,6 +1,7 @@
package com.fuint.api.fuyou.service;
import com.fuint.api.fuyou.entity.ReceiveParameter;
import com.fuint.api.fuyou.entity.ReceiveParameterPos;
import java.util.Map;
@ -32,4 +33,20 @@ public interface FyPayService {
* @throws Exception
*/
public Map<String, String> refund(Map<String, String> map) throws Exception;
/**
* 条码支付pos端
* @param receiveParameterPos
* @return
*/
public Map<String, Object> posPay(ReceiveParameterPos receiveParameterPos) throws Exception;
/**
* 查询订单交易状态pos端
* @return
* @throws Exception
*/
public Map<String, String> queryOrderPos(ReceiveParameterPos receiveParameterPos,String insCd,String mchntCd) throws Exception;
Map<String, String> mainScan(ReceiveParameterPos receiveParameterPos) throws Exception;
}

View File

@ -1,5 +1,6 @@
package com.fuint.api.fuyou.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
@ -621,4 +622,149 @@ public class FyPayServiceImpl implements FyPayService {
return resMap;
}
@Override
public Map<String, Object> posPay(ReceiveParameterPos receiveParameterPos) {
Map<String, Object> res = new HashMap<>();
try {
// 查询商户配置信息
MerchantConfig merchantConfig = merchantConfigService.selectMeChByIdIsUse(receiveParameterPos.getStoreId());
if (ObjectUtil.isEmpty(merchantConfig)){
res.put("code","error");
res.put("msg","暂未配置商户信息");
return res;
}
String publicKey = merchantConfig.getPublicKey();
String privateKey = merchantConfig.getPrivateKey();
Const.INS_PUBLIC_KEY = publicKey;
Const.INS_PRIVATE_KEY = privateKey;
String allAmount = String.valueOf(receiveParameterPos.getGoodsMoney()*100);
Map<String, String> map = Builder.buildFuiou22();
map.put("auth_code",receiveParameterPos.getAuthCode());
map.put("mchnt_order_no",receiveParameterPos.getOrderNo());
map.put("order_type",receiveParameterPos.getPayType());
map.put("order_amt", allAmount);
map.put("ins_cd", merchantConfig.getInsCd());
map.put("mchnt_cd", merchantConfig.getMchntCd());
map.put("goods_des", receiveParameterPos.getContent());
// 请求报文
String reqBody = Message.requestMsg(map);
// 响应报文
String rspXml = Message.responseMsg(reqBody,Const.fuiou_31_url);
//响应报文验签
Map<String, String> resMap = Utils.xmlStr2Map(rspXml);
String str = resMap.get("sign");
String resultCode = resMap.get("result_code");
if (!resultCode.equals("000000")){
throw new RuntimeException(resMap.get("result_msg"));
}
if (Utils.verifySign(resMap, str)){
ThreadUtil.execAsync(() -> {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try {
Map<String, String> orderQueryRes = queryOrderPos(receiveParameterPos,merchantConfig.getInsCd(),merchantConfig.getMchntCd());
if(!orderQueryRes.get("msg").equals("unpaid")){
timer.cancel();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//定时器 不延时 立即开始 0.5s一次
}, 0, 500);
Thread.currentThread().interrupt();
});
}else {
throw new Exception("验签失败,请联系管理员!");
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
public Map<String, String> queryOrderPos(ReceiveParameterPos receiveParameterPos,String insCd,String mchntCd) {
Map<String, String> resMap =new HashMap<>();
resMap.put("msg","error");
try {
Map<String, String> map = Builder.buildFuiou30();
map.put("mchnt_order_no",receiveParameterPos.getOrderNo());
map.put("order_type",receiveParameterPos.getType());
map.put("ins_cd", insCd);
map.put("mchnt_cd", mchntCd);
// 请求报文
String reqBody = Message.requestMsg(map);
// 响应报文
String rspXml = Message.responseMsg(reqBody,Const.fuiou_34_url);
//响应报文验签
Map<String, String> reqMap = Utils.xmlStr2Map(rspXml);
String str = reqMap.get("sign");
if (Utils.verifySign(reqMap, str)){
if (reqMap.get("trans_stat").equals("SUCCESS")){
resMap.put("msg","success");
}else if (reqMap.get("trans_stat").equals("USERPAYING")){
resMap.put("msg","unpaid");
}else {
resMap.put("msg","payFail");
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
@Override
public Map<String, String> mainScan(ReceiveParameterPos receiveParameterPos) throws Exception {
Map<String, String> res = new HashMap<>();
// 查询商户配置信息
MerchantConfig merchantConfig = merchantConfigService.selectMeChByIdIsUse(receiveParameterPos.getStoreId());
if (ObjectUtil.isEmpty(merchantConfig)){
res.put("code","error");
res.put("msg","暂未配置商户信息");
return res;
}
Map<String, String> map = Builder.buildFuiou25();
map.put("version", "1");
map.put("ins_cd", merchantConfig.getInsCd());
map.put("mchnt_cd", merchantConfig.getMchntCd());
map.put("term_id", "88888888");
map.put("mchnt_order_no",receiveParameterPos.getOrderNo());
map.put("random_str", "orderNo");
map.put("order_type",receiveParameterPos.getPayType());
map.put("goods_des", receiveParameterPos.getContent());
double amount = receiveParameterPos.getGoodsMoney() * 100;
map.put("order_amt", String.valueOf((int) amount));
String nowtime = DateUtil.format(new Date(), "yyyyMMddHHmmss");
map.put("txn_begin_ts",nowtime);
String publicKey = merchantConfig.getPublicKey();
String privateKey = merchantConfig.getPrivateKey();
Const.INS_PUBLIC_KEY = publicKey;
Const.INS_PRIVATE_KEY = privateKey;
// 请求报文
String reqBody = Message.requestMsg(map);
// 响应报文
String rspXml = Message.responseMsg(reqBody,Const.fuiou_35_url);
//响应报文验签
Map<String, String> resMap = Utils.xmlStr2Map(rspXml);
String str = resMap.get("sign");
if (Utils.verifySign(resMap, str)){
System.out.println(resMap);
}
return resMap;
}
}

View File

@ -20,4 +20,11 @@ public interface AllOrderInfoMapper extends BaseMapper<AllOrderInfo> {
String sumPayMoney( @Param("allOrderInfo") AllOrderInfo allOrderInfo);
// 根据storeId List查询总流水
BigDecimal allStream(@Param("list") List<MtStore> mtStoreList);
/**
* 根据支付状态查询订单笔数
* @param allOrderInfo
* @return
*/
Integer selectByPayStatusNum(AllOrderInfo allOrderInfo);
}

View File

@ -82,4 +82,32 @@
and date_format(pay_time,'%y%m%d') &lt;= date_format(#{allOrderInfo.params.endTime},'%y%m%d')
</if>
</select>
<select id="selectByPayStatusNum" resultType="java.lang.Integer"
parameterType="com.fuint.business.order.entity.AllOrderInfo">
select
count(aoi.pay_money)
from all_order_info aoi
where aoi.store_id = #{allOrderInfo.storeId}
<if test="allOrderInfo.status != null and allOrderInfo.status != ''">
and aoi.status = #{allOrderInfo.status}
</if>
<if test="allOrderInfo.type != null and allOrderInfo.type != ''">
and aoi.type = #{allOrderInfo.type}
</if>
<if test="allOrderInfo.orderNo != null and allOrderInfo.orderNo != ''">
and aoi.order_no = #{allOrderInfo.orderNo}
</if>
<if test="allOrderInfo.payChannel != null and allOrderInfo.payChannel != ''">
and aoi.pay_channel = #{allOrderInfo.payChannel}
</if>
<if test="allOrderInfo.payType != null and allOrderInfo.payType != ''">
and aoi.pay_type = #{allOrderInfo.payType}
</if>
<if test="allOrderInfo.params.beginTime != null and allOrderInfo.params.beginTime != ''"><!-- 开始时间检索 -->
and date_format(pay_time,'%y%m%d') &gt;= date_format(#{allOrderInfo.params.beginTime},'%y%m%d')
</if>
<if test="allOrderInfo.params.endTime != null and allOrderInfo.params.endTime != ''"><!-- 结束时间检索 -->
and date_format(pay_time,'%y%m%d') &lt;= date_format(#{allOrderInfo.params.endTime},'%y%m%d')
</if>
</select>
</mapper>

View File

@ -190,4 +190,20 @@ public interface OilOrderService extends IService<OilOrder> {
void addGoodsSaleStatistic(Integer goodsId,Integer goodsNum,Integer storeId,Boolean isMember);
OilOrderVo getInfoByTime(Date time,Integer tankId);
// pos端
/**
* 添加订单信息 条码支付
* @param oilOrderVo
* @return
*/
int addOrderPos(OilOrderVo oilOrderVo);
/**
* 添加订单信息 主扫
* @param oilOrderVo
* @return
*/
int addOrderPosScan(OilOrderVo oilOrderVo) throws Exception;
}

View File

@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuint.api.fuyou.entity.MerchantConfig;
import com.fuint.api.fuyou.entity.ReceiveParameter;
import com.fuint.api.fuyou.entity.ReceiveParameterPos;
import com.fuint.api.fuyou.service.FyPayService;
import com.fuint.api.fuyou.service.MerchantConfigService;
import com.fuint.api.fuyou.service.OilConfigService;
@ -1917,4 +1918,60 @@ return stringDoubleMap;
List<OilGun> oilGuns = oilGunService.selectOilGunByTankId(tankId);
return baseMapper.getInfoByTime(time,oilGuns);
}
// pos端
@Override
public int addOrderPos(OilOrderVo oilOrderVo) {
AccountInfo nowAccountInfo = TokenUtil.getNowAccountInfo();
// 根据日期生成订单信息
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String timestamp = dateFormat.format(new Date());
String randomString = UUID.randomUUID().toString().replace("-","").substring(0,6);
String orderNo = "2345"+timestamp+randomString;
oilOrderVo.setOrderNo(orderNo);
oilOrderVo.setStoreId(nowAccountInfo.getStoreId());
oilOrderVo.setStaffId(nowAccountInfo.getStaffId());
Double oilNum = oilOrderVo.getOrderAmount() / oilOrderVo.getOilPrice();
oilOrderVo.setOilNum(oilNum);
oilOrderVo.setTerminal("POS");
oilOrderVo.setOrderType("主订单");
if (oilOrderVo.getPayType().equals("CASH")){
oilOrderVo.setOrderStatus("paid");
oilOrderVo.setPayTime(new Date());
}else {
oilOrderVo.setOrderStatus("unpaid");
}
int row = baseMapper.insert(oilOrderVo);
return row;
}
@Override
public int addOrderPosScan(OilOrderVo oilOrderVo) throws Exception {
AccountInfo nowAccountInfo = TokenUtil.getNowAccountInfo();
// 根据日期生成订单信息
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
String timestamp = dateFormat.format(new Date());
String randomString = UUID.randomUUID().toString().replace("-","").substring(0,6);
String orderNo = "2345"+timestamp+randomString;
oilOrderVo.setOrderNo(orderNo);
oilOrderVo.setStoreId(nowAccountInfo.getStoreId());
oilOrderVo.setStaffId(nowAccountInfo.getStaffId());
oilOrderVo.setTerminal("POS");
oilOrderVo.setOrderStatus("unpaid");
oilOrderVo.setOrderType("主订单");
int row = baseMapper.insert(oilOrderVo);
ReceiveParameterPos receiveParameterPos = new ReceiveParameterPos();
receiveParameterPos.setPayType(oilOrderVo.getPayType());
receiveParameterPos.setType("1");
receiveParameterPos.setContent("油品订单");
receiveParameterPos.setOrderNo(orderNo);
receiveParameterPos.setStoreId(oilOrderVo.getStoreId());
receiveParameterPos.setStoreId(oilOrderVo.getUserId());
receiveParameterPos.setGoodsMoney(oilOrderVo.getPayAmount());
Map<String, String> mainScan = fyPayService.mainScan(receiveParameterPos);
return row;
}
}

View File

@ -55,6 +55,8 @@ public class ShiroConfig {
filterMap.put("/backendApi/store/loginVerification","anon");
//小程序支付回调地址
filterMap.put("/api/fyPay/notify","anon");
//主扫支付回调地址
filterMap.put("/api/fyPay/notifyScan","anon");

View File

@ -272,6 +272,8 @@
await this.getTheJudgmentIsTheSame();
await this.isJoined()
this.isRecharge()
// this.getAddress()
// this.getUserAuthority()
// this.getIndexBanner()
},
components: {
@ -406,27 +408,75 @@
let _this = this;
// this.getAddress();
uni.getSetting({
async success(res) {
if (!res.authSetting['scope.userLocation']) {
// uni.authorize({
// scope: 'scope.userLocation',
// success() {
// //
// // _this.isExistStoreId()
// },
// fail() {
// //
// }
// })
await _this.getAddress(uni.getStorageSync("storeId"));
success(res) {
if (res.authSetting['scope.userLocation']==false) {
// uni.clearStorageSync();
// _this.getStorageSize()
_this.showRefuseLocationPermission()
} else {
//
// _this.isExistStoreId()
await _this.getAddress(uni.getStorageSync("storeId"));
_this.getAddress(uni.getStorageSync("storeId"));
}
},
fail(err) {
console.log('jujuel', err);
},
complete(ress) {
},
withSubscriptions(resx) {
console.log('4', resx);
}
})
},
//
showRefuseLocationPermission() {
const that = this;
wx.showModal({
title: "提示",
content: "需要获取用户位置权限",
confirmText: "前往设置",
showCancel: false,
success(res) {
if (res.confirm) {
uni.openSetting({
success(res){
console.log("打开设置成功", res);
if (res.authSetting['scope.userLocation']) {
console.log('成功授权userLocation')
that.getAddress()
} else {
console.log('用户未授权userLocation')
// ()
that.showRefuseLocationPermission()
}
},
fail(err){
console.log("打开设置失败", err)
}
})
}
}
})
},
getStorageSize() {
let that = this;
uni.getStorageInfo({
success(res) {
console.log(res)
console.log(res.keys);
console.log(res.limitSize);
let size = res.currentSize;
if (size < 1024) {
that.storageSize = size + ' B';
} else if (size / 1024 >= 1 && size / 1024 / 1024 < 1) {
that.storageSize = Math.floor(size / 1024 * 100) / 100 + ' KB';
} else if (size / 1024 / 1024 >= 1) {
that.storageSize = Math.floor(size / 1024 / 1024 * 100) / 100 + ' M';
}
}
})
},