微信支付后端、前端相关代码
This commit is contained in:
parent
2a4b5697af
commit
f275302a41
@ -67,7 +67,7 @@ public class BsGoodsController extends BaseController {
|
||||
/**
|
||||
* 新增商品
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:goods:add')")
|
||||
// @PreAuthorize("@ss.hasPermi('system:goods:add')")
|
||||
@Log(title = "商品", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody BsGoods bsGoods) {
|
||||
|
@ -82,18 +82,20 @@ public class BsOrderController extends BaseController
|
||||
/**
|
||||
* 新增订单
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:order:add')")
|
||||
// @PreAuthorize("@ss.hasPermi('system:order:add')")
|
||||
@Log(title = "订单", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody BsOrder bsOrder)
|
||||
{
|
||||
return toAjax(bsOrderService.insertBsOrder(bsOrder));
|
||||
// return toAjax(bsOrderService.insertBsOrder(bsOrder));
|
||||
int result = bsOrderService.insertBsOrder(bsOrder);
|
||||
return result > 0 ? AjaxResult.success("orderNo", bsOrder.getOrderNo()) : AjaxResult.error("订单新增失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改订单
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('system:order:edit')")
|
||||
// @PreAuthorize("@ss.hasPermi('system:order:edit')")
|
||||
@Log(title = "订单", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody BsOrder bsOrder)
|
||||
@ -111,4 +113,13 @@ public class BsOrderController extends BaseController
|
||||
{
|
||||
return toAjax(bsOrderService.deleteBsOrderByIds(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支付
|
||||
*/
|
||||
@GetMapping("/getPayStatus/{orderNo}")
|
||||
public AjaxResult getPayStatus(@PathVariable("orderNo") String orderNo)
|
||||
{
|
||||
return success(bsOrderService.getPayStatus(orderNo));
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.ruoyi.system.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
@ -9,7 +10,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
|
||||
|
||||
/**
|
||||
* 订单对象 bs_order
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2024-10-25
|
||||
*/
|
||||
@ -20,19 +21,28 @@ public class BsOrder extends BaseEntity
|
||||
/** 主键 */
|
||||
private Long id;
|
||||
|
||||
/** 订单号 */
|
||||
@Excel(name = "订单号")
|
||||
/** 商户单号 */
|
||||
@Excel(name = "商户单号")
|
||||
private String orderNo;
|
||||
|
||||
/** 订单号 */
|
||||
@Excel(name = "交易流水号")
|
||||
private String transactionId;
|
||||
|
||||
/** 1:微信,2:支付宝 */
|
||||
@Excel(name = "1:微信,2:支付宝")
|
||||
private Long channel;
|
||||
|
||||
/** 支付时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@Excel(name = "支付时间", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "支付时间", width = 50, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date payTime;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "创建时间", width = 50, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/** 商品名称 */
|
||||
@Excel(name = "商品名称")
|
||||
private String goodsName;
|
||||
@ -43,85 +53,127 @@ public class BsOrder extends BaseEntity
|
||||
|
||||
/** 订单价格 */
|
||||
@Excel(name = "订单价格")
|
||||
private String price;
|
||||
private BigDecimal price;
|
||||
|
||||
/** 购买人id */
|
||||
@Excel(name = "购买人id")
|
||||
private String createId;
|
||||
|
||||
public void setId(Long id)
|
||||
/** 支付状态 */
|
||||
@Excel(name = "支付状态")
|
||||
private int payStatus;
|
||||
|
||||
/** 购买人openid */
|
||||
@Excel(name = "购买人openid")
|
||||
private String openid;
|
||||
|
||||
public void setId(Long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Long getId()
|
||||
public Long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
public void setOrderNo(String orderNo)
|
||||
public void setOrderNo(String orderNo)
|
||||
{
|
||||
this.orderNo = orderNo;
|
||||
}
|
||||
|
||||
public String getOrderNo()
|
||||
public String getOrderNo()
|
||||
{
|
||||
return orderNo;
|
||||
}
|
||||
public void setChannel(Long channel)
|
||||
public void setChannel(Long channel)
|
||||
{
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public Long getChannel()
|
||||
public Long getChannel()
|
||||
{
|
||||
return channel;
|
||||
}
|
||||
public void setPayTime(Date payTime)
|
||||
public void setPayTime(Date payTime)
|
||||
{
|
||||
this.payTime = payTime;
|
||||
}
|
||||
|
||||
public Date getPayTime()
|
||||
public Date getPayTime()
|
||||
{
|
||||
return payTime;
|
||||
}
|
||||
public void setGoodsName(String goodsName)
|
||||
public void setGoodsName(String goodsName)
|
||||
{
|
||||
this.goodsName = goodsName;
|
||||
}
|
||||
|
||||
public String getGoodsName()
|
||||
public String getGoodsName()
|
||||
{
|
||||
return goodsName;
|
||||
}
|
||||
public void setGoodsmin(Long goodsmin)
|
||||
public void setGoodsmin(Long goodsmin)
|
||||
{
|
||||
this.goodsmin = goodsmin;
|
||||
}
|
||||
|
||||
public Long getGoodsmin()
|
||||
public Long getGoodsmin()
|
||||
{
|
||||
return goodsmin;
|
||||
}
|
||||
public void setPrice(String price)
|
||||
public void setPrice(BigDecimal price)
|
||||
{
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getPrice()
|
||||
public BigDecimal getPrice()
|
||||
{
|
||||
return price;
|
||||
}
|
||||
public void setCreateId(String createId)
|
||||
public void setCreateId(String createId)
|
||||
{
|
||||
this.createId = createId;
|
||||
}
|
||||
|
||||
public String getCreateId()
|
||||
public String getCreateId()
|
||||
{
|
||||
return createId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public int getPayStatus() {
|
||||
return payStatus;
|
||||
}
|
||||
|
||||
public void setPayStatus(int payStatus) {
|
||||
this.payStatus = payStatus;
|
||||
}
|
||||
|
||||
public String getOpenid() {
|
||||
return openid;
|
||||
}
|
||||
|
||||
public void setOpenid(String openid) {
|
||||
this.openid = openid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
@ -134,6 +186,9 @@ public class BsOrder extends BaseEntity
|
||||
.append("price", getPrice())
|
||||
.append("createId", getCreateId())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("payStatus", getPayStatus())
|
||||
.append("openid", getOpenid())
|
||||
.append("transactionId", getTransactionId())
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
@ -66,4 +66,12 @@ public interface BsOrderMapper
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteBsOrderByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 判断是否支付
|
||||
*
|
||||
* @param orderNo 商家订单号号
|
||||
* @return 结果
|
||||
*/
|
||||
public int getPayStatus(String orderNo);
|
||||
}
|
||||
|
@ -66,4 +66,12 @@ public interface IBsOrderService
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteBsOrderById(Long id);
|
||||
|
||||
/**
|
||||
* 判断是否支付
|
||||
*
|
||||
* @param orderNo 商家订单号号
|
||||
* @return 结果
|
||||
*/
|
||||
public int getPayStatus(String orderNo);
|
||||
}
|
||||
|
@ -106,4 +106,15 @@ public class BsOrderServiceImpl implements IBsOrderService
|
||||
{
|
||||
return bsOrderMapper.deleteBsOrderById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否支付
|
||||
*
|
||||
* @param orderNo 商家订单号号
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int getPayStatus(String orderNo) {
|
||||
return bsOrderMapper.getPayStatus(orderNo);
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,13 @@ import com.ruoyi.common.wx.PayService;
|
||||
import com.ruoyi.common.wx.StreamUtils;
|
||||
import com.ruoyi.common.wx.WxPayDTO;
|
||||
import com.ruoyi.common.wx.WxPayProperties;
|
||||
import com.ruoyi.system.domain.BsOrder;
|
||||
import com.ruoyi.system.service.IBsOrderService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@ -20,6 +23,8 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -38,18 +43,23 @@ public class WechatPayController {
|
||||
@Resource // 注入WxPayProperties,用于获取微信支付的配置信息
|
||||
private WxPayProperties wxPayProperties;
|
||||
|
||||
@Anonymous
|
||||
@Autowired
|
||||
private IBsOrderService bsOrderService;
|
||||
|
||||
@Anonymous
|
||||
@ApiOperation(value = "微信native下单,返回支付二维码") // 描述该API的功能
|
||||
@GetMapping("/nativePay") // 定义GET请求的路径为/pay/nativePay
|
||||
public Object nativePay(@RequestParam("orderNumber") String orderNumber) {
|
||||
// todo 业务操作-根据订单编号查询订单信息
|
||||
//根据订单编号查询订单信息
|
||||
BsOrder bsOrder = bsOrderService.selectBsOrderByOrderNo(orderNumber);
|
||||
// 将订单信息中的数据存到WxPayDTO
|
||||
WxPayDTO payDTO = new WxPayDTO(); // 创建WxPayDTO对象用于存储支付信息
|
||||
payDTO.setBody("商品描述"); // 设置商品描述
|
||||
payDTO.setBody(bsOrder.getGoodsName()); // 设置商品描述
|
||||
|
||||
// 订单总金额,单位为分
|
||||
payDTO.setTotalFee(1); // 设置订单总金额(1分)
|
||||
BigDecimal price = bsOrder.getPrice();
|
||||
final int total = price.multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
|
||||
payDTO.setTotalFee(total); // 设置订单总金额(1分)
|
||||
|
||||
// 支付回调地址
|
||||
payDTO.setNotifyUrl(wxPayProperties.getNotifyUrl()); // 设置支付成功后的回调地址
|
||||
@ -81,7 +91,7 @@ public class WechatPayController {
|
||||
// todo 业务操作-根据订单编号查询订单信息
|
||||
// 将订单信息中的数据存到WxPayDTO
|
||||
WxPayDTO payDTO = new WxPayDTO(); // 创建WxPayDTO对象用于存储支付信息
|
||||
payDTO.setBody("支付测试"); // 设置商品描述
|
||||
payDTO.setBody("支付测试2"); // 设置商品描述
|
||||
|
||||
// 订单总金额,单位为分
|
||||
payDTO.setTotalFee(1); // 设置订单总金额(1分)
|
||||
@ -117,7 +127,7 @@ public class WechatPayController {
|
||||
// todo 业务操作-根据订单编号查询订单信息
|
||||
// 将订单信息中的数据存到WxPayDTO
|
||||
WxPayDTO payDTO = new WxPayDTO(); // 创建WxPayDTO对象用于存储支付信息
|
||||
payDTO.setBody("商品描述"); // 设置商品描述
|
||||
payDTO.setBody("支付测试3"); // 设置商品描述
|
||||
|
||||
// 订单总金额,单位为分
|
||||
payDTO.setTotalFee(1); // 设置订单总金额(1分)
|
||||
@ -148,10 +158,12 @@ public class WechatPayController {
|
||||
return url; // 返回H5支付链接
|
||||
}
|
||||
|
||||
@Anonymous
|
||||
@ApiOperation(value = "微信支付回调") // 描述该API的功能
|
||||
@PostMapping("/wxCallback") // 定义POST请求的路径为/pay/wxCallback
|
||||
public Object wxCallback(HttpServletRequest request, HttpServletResponse response) {
|
||||
ServletInputStream inputStream = null; // 定义输入流用于接收请求体
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
try {
|
||||
inputStream = request.getInputStream(); // 获取请求体的输入流
|
||||
String notifyXml = StreamUtils.inputStream2String(inputStream, "utf-8"); // 将输入流转换为字符串
|
||||
@ -165,6 +177,14 @@ public class WechatPayController {
|
||||
// 判断支付是否成功
|
||||
if ("SUCCESS".equals(notifyMap.get("result_code"))) { // 如果支付结果为成功
|
||||
// todo 修改订单状态
|
||||
BsOrder order = new BsOrder();
|
||||
order.setChannel(1L);
|
||||
order.setPayStatus(1);
|
||||
order.setTransactionId(notifyMap.get("transaction_id"));
|
||||
order.setOpenid(notifyMap.get("openid"));
|
||||
order.setOrderNo(notifyMap.get("out_trade_no"));
|
||||
order.setPayTime(sdf.parse(notifyMap.get("time_end")));
|
||||
int i = bsOrderService.updateBsOrder(order);
|
||||
|
||||
// 支付成功:给微信发送我已接收通知的响应 创建响应对象
|
||||
Map<String, String> returnMap = new HashMap<>(); // 创建返回的Map
|
||||
@ -174,9 +194,11 @@ public class WechatPayController {
|
||||
String returnXml = WXPayUtil.mapToXml(returnMap); // 将Map转换为XML格式
|
||||
response.setContentType("text/xml"); // 设置响应的内容类型为XML
|
||||
log.info("支付成功"); // 打印支付成功日志
|
||||
System.out.println("支付成功");
|
||||
return returnXml; // 返回成功的XML响应
|
||||
} else {
|
||||
// 保存回调信息,方便排除问题
|
||||
System.out.println("支付失败");
|
||||
}
|
||||
// 创建响应对象:微信接收到校验失败的结果后,会反复的调用当前回调函数
|
||||
Map<String, String> returnMap = new HashMap<>(); // 创建返回的Map
|
||||
|
@ -5,33 +5,51 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<mapper namespace="com.ruoyi.system.mapper.BsOrderMapper">
|
||||
|
||||
<resultMap type="BsOrder" id="BsOrderResult">
|
||||
<result property="id" column="id" />
|
||||
<result property="orderNo" column="order_no" />
|
||||
<result property="channel" column="channel" />
|
||||
<result property="payTime" column="pay_time" />
|
||||
<result property="goodsName" column="goods_name" />
|
||||
<result property="goodsmin" column="goodsmin" />
|
||||
<result property="price" column="price" />
|
||||
<result property="createId" column="create_id" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="id" column="id"/>
|
||||
<result property="orderNo" column="order_no"/>
|
||||
<result property="channel" column="channel"/>
|
||||
<result property="transactionId" column="transaction_id"/>
|
||||
<result property="payTime" column="pay_time"/>
|
||||
<result property="goodsName" column="goods_name"/>
|
||||
<result property="goodsmin" column="goodsmin"/>
|
||||
<result property="price" column="price"/>
|
||||
<result property="createId" column="create_id"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="payStatus" column="payStatus"/>
|
||||
<result property="openid" column="openid"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectBsOrderVo">
|
||||
select id, order_no, channel, pay_time, goods_name, goodsmin, price, create_id, create_time from bs_order
|
||||
</sql>
|
||||
select
|
||||
id,
|
||||
order_no,
|
||||
channel,
|
||||
transaction_id,
|
||||
pay_time,
|
||||
goods_name,
|
||||
goodsmin,
|
||||
price,
|
||||
create_id,
|
||||
create_time,
|
||||
payStatus,
|
||||
openid
|
||||
from bs_order </sql>
|
||||
|
||||
<select id="selectBsOrderList" parameterType="BsOrder" resultMap="BsOrderResult">
|
||||
<include refid="selectBsOrderVo"/>
|
||||
<where>
|
||||
<if test="orderNo != null and orderNo != ''"> and order_no = #{orderNo}</if>
|
||||
<if test="orderNo != null and orderNo != ''"> and order_no = #{orderNo}</if>
|
||||
<if test="channel != null "> and channel = #{channel}</if>
|
||||
<if test="payTime != null "> and pay_time = #{payTime}</if>
|
||||
<if test="goodsName != null and goodsName != ''"> and goods_name like concat('%', #{goodsName}, '%')</if>
|
||||
<if test="transactionId != null "> and transaction_id = #{transactionId}</if>
|
||||
<if test="payTime != null "> and DATE(pay_time) = #{payTime}</if>
|
||||
<if test="goodsName != null and goodsName != ''"> and goods_name like concat('%', #{goodsName}, '%')</if>
|
||||
<if test="goodsmin != null "> and goodsmin = #{goodsmin}</if>
|
||||
<if test="price != null and price != ''"> and price = #{price}</if>
|
||||
<if test="createId != null and createId != ''"> and create_id = #{createId}</if>
|
||||
<if test="price != null and price != ''"> and price = #{price}</if>
|
||||
<if test="createId != null and createId != ''"> and create_id = #{createId}</if>
|
||||
<if test="createTime != null "> and create_time = #{createTime}</if>
|
||||
<if test="openid != null and openid != ''"> and openid = #{openid}</if>
|
||||
</where>
|
||||
ORDER BY pay_time DESC
|
||||
</select>
|
||||
|
||||
<select id="selectBsOrderById" parameterType="Long" resultMap="BsOrderResult">
|
||||
@ -49,23 +67,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="orderNo != null">order_no,</if>
|
||||
<if test="channel != null">channel,</if>
|
||||
<if test="transactionId != null">transaction_id,</if>
|
||||
<if test="payTime != null">pay_time,</if>
|
||||
<if test="goodsName != null">goods_name,</if>
|
||||
<if test="goodsmin != null">goodsmin,</if>
|
||||
<if test="price != null">price,</if>
|
||||
<if test="createId != null">create_id,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
</trim>
|
||||
<if test="payStatus != null">payStatus,</if>
|
||||
<if test="openid != null">openid,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="orderNo != null">#{orderNo},</if>
|
||||
<if test="channel != null">#{channel},</if>
|
||||
<if test="transactionId != null">#{transactionId},</if>
|
||||
<if test="payTime != null">#{payTime},</if>
|
||||
<if test="goodsName != null">#{goodsName},</if>
|
||||
<if test="goodsmin != null">#{goodsmin},</if>
|
||||
<if test="price != null">#{price},</if>
|
||||
<if test="createId != null">#{createId},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
</trim>
|
||||
<if test="payStatus != null">#{payStatus},</if>
|
||||
<if test="openid != null">#{openid},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateBsOrder" parameterType="BsOrder">
|
||||
@ -73,14 +97,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="orderNo != null">order_no = #{orderNo},</if>
|
||||
<if test="channel != null">channel = #{channel},</if>
|
||||
<if test="transactionId != null">transaction_id = #{transactionId},</if>
|
||||
<if test="payTime != null">pay_time = #{payTime},</if>
|
||||
<if test="goodsName != null">goods_name = #{goodsName},</if>
|
||||
<if test="goodsmin != null">goodsmin = #{goodsmin},</if>
|
||||
<if test="price != null">price = #{price},</if>
|
||||
<if test="createId != null">create_id = #{createId},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="payStatus != null">payStatus = #{payStatus},</if>
|
||||
<if test="openid != null">openid = #{openid},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
where order_no = #{orderNo}
|
||||
</update>
|
||||
|
||||
<update id="updatePayStatus" parameterType="int">
|
||||
update bs_order set payStatus = #{payStatus} where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteBsOrderById" parameterType="Long">
|
||||
@ -93,4 +124,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<select id="getPayStatus" parameterType="String" resultType="int">
|
||||
select payStatus from bs_order where
|
||||
<if test="orderNo != null"> order_no = #{orderNo} </if>
|
||||
</select>
|
||||
</mapper>
|
||||
|
@ -111,7 +111,7 @@ public class SecurityConfig
|
||||
.authorizeHttpRequests((requests) -> {
|
||||
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
|
||||
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
|
||||
requests.antMatchers("/login", "/register", "/captchaImage","/system/goods/**","/system/designType/**","/system/type/**","/system/order/**","/system/note/**").permitAll()
|
||||
requests.antMatchers("/login", "/register", "/captchaImage","/system/goods/**","/system/designType/**","/system/type/**","/system/order/**","/system/note/**","/pay/**").permitAll()
|
||||
// 静态资源,可匿名访问
|
||||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
|
@ -49,6 +49,7 @@
|
||||
"js-cookie": "3.0.1",
|
||||
"jsencrypt": "3.0.0-rc.1",
|
||||
"nprogress": "0.2.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"quill": "2.0.2",
|
||||
"screenfull": "5.0.2",
|
||||
"sortablejs": "1.10.2",
|
||||
@ -57,6 +58,7 @@
|
||||
"vue-count-to": "1.0.13",
|
||||
"vue-cropper": "0.5.5",
|
||||
"vue-meta": "2.4.0",
|
||||
"vue-qr": "^4.0.9",
|
||||
"vue-router": "3.4.9",
|
||||
"vuedraggable": "2.24.3",
|
||||
"vuex": "3.6.0"
|
||||
|
@ -50,3 +50,18 @@ export function delOrder(id) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
//根据订单编号获取支付二维码
|
||||
export function orderPay(orderNo) {
|
||||
return request({
|
||||
url: '/pay/nativePay?orderNumber=' + orderNo,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getPayStatus(orderNo) {
|
||||
return request({
|
||||
url: '/system/order/getPayStatus/' + orderNo,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
BIN
ruoyi-ui/src/assets/images/moren.png
Normal file
BIN
ruoyi-ui/src/assets/images/moren.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
@ -38,6 +38,8 @@ import VueMeta from 'vue-meta'
|
||||
// 字典数据组件
|
||||
import DictData from '@/components/DictData'
|
||||
import * as ElementUI from "element-ui";
|
||||
import VueQr from 'vue-qr'
|
||||
|
||||
|
||||
// 全局方法挂载
|
||||
Vue.prototype.getDicts = getDicts
|
||||
@ -58,6 +60,7 @@ Vue.component('Editor', Editor)
|
||||
Vue.component('FileUpload', FileUpload)
|
||||
Vue.component('ImageUpload', ImageUpload)
|
||||
Vue.component('ImagePreview', ImagePreview)
|
||||
Vue.component('VueQr', VueQr)
|
||||
|
||||
Vue.use(directive)
|
||||
Vue.use(plugins)
|
||||
@ -79,6 +82,7 @@ Vue.use(Element, {
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
|
@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
|
||||
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
const whiteList = ['/login', '/register','/cus','/cusDetails','/cusDetPay','/userOrder','/note']
|
||||
const whiteList = ['/login', '/register','/cus','/cusDetails','/cusDetPay','/userOrder','/note','/payMent']
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
NProgress.start()
|
||||
|
@ -81,6 +81,11 @@ export const constantRoutes = [
|
||||
component: () => import('@/views/system/userFront/payBefore'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/payMent',
|
||||
component: () => import('@/views/system/userFront/payMent'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/userOrder',
|
||||
component: () => import('@/views/system/userFront/order'),
|
||||
|
@ -4,7 +4,7 @@
|
||||
<el-form-item label="订单号" prop="orderNo">
|
||||
<el-input
|
||||
v-model="queryParams.orderNo"
|
||||
placeholder="请输入订单号"
|
||||
placeholder="请输入商户单号"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
@ -28,10 +28,10 @@
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="购买人id" prop="createId">
|
||||
<el-form-item label="openid" prop="openid">
|
||||
<el-input
|
||||
v-model="queryParams.createId"
|
||||
placeholder="请输入购买人id"
|
||||
v-model="queryParams.openid"
|
||||
placeholder="请输入openid"
|
||||
clearable
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
@ -90,24 +90,30 @@
|
||||
|
||||
<el-table v-loading="loading" :data="orderList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="订单号" align="center" prop="orderNo" />
|
||||
<el-table-column label="商户单号" align="center" prop="orderNo" />
|
||||
<el-table-column label="交易流水号" align="center" prop="transactionId" />
|
||||
<el-table-column label="支付方式" align="center" prop="channel" >
|
||||
<template slot-scope="scope">
|
||||
{{ getPaymentMethod(scope.row.channel) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支付时间" align="center" prop="payTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.payTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" align="center" prop="goodsName" />
|
||||
<el-table-column label="商品id" align="center" prop="goodsmin" />
|
||||
<el-table-column label="订单价格" align="center" prop="price" />
|
||||
<el-table-column label="购买人id" align="center" prop="createId" />
|
||||
<el-table-column label="订单状态" align="center" prop="payStatus">
|
||||
<template slot-scope="scope">
|
||||
{{ getPayStatus(scope.row.channel) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="openid" align="center" prop="openid" />
|
||||
<el-table-column label="支付时间" align="center" prop="payTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.payTime, '{y}-{m}-{d}:{h}:{m}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}:{h}:{m}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
@ -202,14 +208,18 @@ export default {
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
id: null,
|
||||
orderNo: null,
|
||||
channel: null,
|
||||
transactionId: null,
|
||||
payTime: null,
|
||||
goodsName: null,
|
||||
goodsmin: null,
|
||||
price: null,
|
||||
createId: null,
|
||||
createTime: null
|
||||
createTime: null,
|
||||
payStatus: null,
|
||||
openid: null
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
@ -226,7 +236,9 @@ export default {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listOrder(this.queryParams).then(response => {
|
||||
console.log('order',this.queryParams)
|
||||
this.orderList = response.rows;
|
||||
console.log('res',response)
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
@ -242,12 +254,15 @@ export default {
|
||||
id: null,
|
||||
orderNo: null,
|
||||
channel: null,
|
||||
transactionId: null,
|
||||
payTime: null,
|
||||
goodsName: null,
|
||||
goodsmin: null,
|
||||
price: null,
|
||||
createId: null,
|
||||
createTime: null
|
||||
createTime: null,
|
||||
payStatus: null,
|
||||
openid: null
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
@ -328,6 +343,14 @@ export default {
|
||||
default:
|
||||
return '未知支付方式';
|
||||
}
|
||||
},
|
||||
getPayStatus(channel) {
|
||||
switch (channel) {
|
||||
case 1:
|
||||
return '已支付';
|
||||
case 2:
|
||||
return '未支付';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -214,7 +214,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
if (!fileUrl.startsWith('http')) {
|
||||
fileUrl = 'http://127.0.0.1:8080' + fileUrl;
|
||||
fileUrl = 'http://127.0.0.1:40506' + fileUrl;
|
||||
}
|
||||
|
||||
axios({
|
||||
|
@ -77,7 +77,8 @@
|
||||
<!-- <router-link :to="{ path: `/cusDetails/${item.id}` }">-->
|
||||
<router-link :to="{ path: '/cusDetails', query: { id: item.id } }">
|
||||
<el-card :body-style="{ padding: '5px' }">
|
||||
<el-image :src="`http://127.0.0.1:8080${item.cover}`" class="image" />
|
||||
<!-- <el-image :src="`http://127.0.0.1:40506${item.cover}`" class="image" />-->
|
||||
<el-image :src="item.cover ? `http://127.0.0.1:40506${item.cover}` : defaultImage" class="image" @error="item.cover = defaultImage"/>
|
||||
<div style="padding: 8px;">
|
||||
<span>{{ item.name }}</span>
|
||||
<div class="bottom clearfix" style="display: flex;justify-content: center;align-items: center">
|
||||
@ -183,7 +184,8 @@ export default {
|
||||
name: null,
|
||||
type: null,
|
||||
},
|
||||
technicalType: null
|
||||
technicalType: null,
|
||||
defaultImage: require('@/assets/images/moren.png'),
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
@ -17,7 +17,11 @@
|
||||
<!-- 内容区域 -->
|
||||
<el-main class="content">
|
||||
<div class="product-info">
|
||||
<el-image :src="`http://127.0.0.1:8080${goods.cover}`" class="product-image" />
|
||||
<el-image
|
||||
:src="imageUrl"
|
||||
class="product-image"
|
||||
@error="handleImageError"
|
||||
/>
|
||||
<div class="product-details">
|
||||
<h3>{{ goods.name }}</h3>
|
||||
<p class="price">¥{{ goods.price }}</p>
|
||||
@ -45,6 +49,8 @@
|
||||
|
||||
<script>
|
||||
import {getGoods} from "@/api/system/goods";
|
||||
import {addOrder, orderPay} from "@/api/system/order";
|
||||
import { Loading } from 'element-ui';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -54,19 +60,20 @@ export default {
|
||||
goods: [],
|
||||
goodsId: null, // 用于存储接收的商品ID
|
||||
|
||||
logoUrl: 'path/to/logo.png', // Logo 图片路径
|
||||
product: {
|
||||
image: 'path/to/product-image.png', // 产品图片路径
|
||||
name: '基于Java(SpringBoot)科研管理系统', // 产品名称
|
||||
price: 199.90 // 产品价格
|
||||
}
|
||||
orderNo: null,
|
||||
form:{},
|
||||
payUrl: null,
|
||||
loading: null,
|
||||
imageUrl: '',
|
||||
defaultImage: require('@/assets/images/moren.png'),
|
||||
|
||||
};
|
||||
},
|
||||
created() {
|
||||
// this.goodsId = this.$route.params.id;
|
||||
this.goodsId = this.$route.query.id;
|
||||
this.getGood(this.goodsId);
|
||||
console.log('goodsId',this.goodsId)
|
||||
|
||||
},
|
||||
methods: {
|
||||
|
||||
@ -74,17 +81,43 @@ export default {
|
||||
getGood(id) {
|
||||
getGoods(id).then(response => {
|
||||
this.goods = response.data;
|
||||
this.imageUrl = `http://127.0.0.1:40506${this.goods.cover}` || this.defaultImage; // 设置图片地址
|
||||
this.getOrderNo();
|
||||
console.log('good',response)
|
||||
});
|
||||
},
|
||||
handleImageError() {
|
||||
// 设置为默认图片
|
||||
this.imageUrl = this.defaultImage;
|
||||
},
|
||||
getOrderNo(){
|
||||
this.form.payStatus = 2
|
||||
this.form.price = this.goods.price
|
||||
this.form.goodsName = this.goods.name
|
||||
this.form.goodsmin = this.goods.id
|
||||
addOrder(this.form).then(response => {
|
||||
console.log('form',this.form)
|
||||
console.log('res',response)
|
||||
this.orderNo = response.data;
|
||||
console.log('订单号',this.orderNo)
|
||||
});
|
||||
|
||||
|
||||
|
||||
},
|
||||
|
||||
pay(method) {
|
||||
if (method === 'wechat') {
|
||||
// 微信支付逻辑
|
||||
alert('跳转到微信支付页面');
|
||||
orderPay(this.orderNo).then(response => {
|
||||
this.payUrl = response;
|
||||
console.log('res',response)
|
||||
console.log('支付地址',this.payUrl)
|
||||
this.loading = true;
|
||||
this.$router.push({ path: '/payMent', query: { url: this.payUrl, orderNo: this.orderNo } });
|
||||
}).catch(error => {
|
||||
console.error('支付失败', error);
|
||||
}).finally(() => {
|
||||
this.loading.close(); // 关闭加载动画
|
||||
});
|
||||
|
||||
} else if (method === 'alipay') {
|
||||
// 支付宝支付逻辑
|
||||
alert('跳转到支付宝支付页面');
|
||||
|
194
ruoyi-ui/src/views/system/userFront/payMent.vue
Normal file
194
ruoyi-ui/src/views/system/userFront/payMent.vue
Normal file
@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<div class="app">
|
||||
<!-- 顶部导航栏 -->
|
||||
<el-header class="navbar">
|
||||
<div class="user-actions">
|
||||
<el-menu mode="horizontal" background-color="#333" text-color="#fff" active-text-color="#ffd04b">
|
||||
<el-menu-item>
|
||||
<router-link to="/cus">首页</router-link>
|
||||
</el-menu-item>
|
||||
<el-menu-item>
|
||||
<router-link to="/userOrder">订单查询</router-link>
|
||||
</el-menu-item>
|
||||
</el-menu>
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<el-main class="content">
|
||||
|
||||
<div class="payment" v-if="payStatus === 2">
|
||||
<p>请扫描以下二维码以完成支付:</p>
|
||||
<img :src="qrCodeUrl" alt="支付二维码" />
|
||||
</div>
|
||||
<div class="payment" v-else-if="payStatus === 1">
|
||||
<p>支付成功,请保留好支付记录,谢谢!</p>
|
||||
</div>
|
||||
|
||||
<div class="payment">
|
||||
<p class="warning">支付完成后会自动获取项目文件下载(最好使用电脑浏览器打开支付,以便于支付成功后项目的下载和安装)</p>
|
||||
</div>
|
||||
</el-main>
|
||||
|
||||
<!-- 备注信息 -->
|
||||
<el-footer class="footer">
|
||||
<p class="warning">注意!如果支付成功后,因分享网链接失效导致无法跳转或下载设计,请联系客服,会为您发送设计。</p>
|
||||
<p class="tip"> (购买无需注册登录)请注意,虚拟内容商品,购买后不支持退货、转让、退换,请斟酌确认。</p>
|
||||
</el-footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {toDataURL} from 'qrcode'
|
||||
import {getPayStatus} from "@/api/system/order";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
payUrl: null,
|
||||
qrCodeUrl: null,
|
||||
orderNo: null,
|
||||
payStatus:null,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.payUrl = this.$route.query.url;
|
||||
this.orderNo = this.$route.query.orderNo;
|
||||
console.log('接收到的支付链接:', this.payUrl);
|
||||
console.log('接收到的订单号:', this.orderNo);
|
||||
this.generateQrCode()
|
||||
this.payStatus = 2;
|
||||
// 启动支付状态检查
|
||||
this.checkPayStatus();
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 清除定时器以防内存泄漏
|
||||
clearInterval(this.checkInterval);
|
||||
},
|
||||
methods: {
|
||||
async generateQrCode() {
|
||||
if (this.payUrl) {
|
||||
try {
|
||||
const options = {
|
||||
width: 300,
|
||||
height: 300
|
||||
};
|
||||
this.qrCodeUrl = await toDataURL(this.payUrl,options);
|
||||
} catch (error) {
|
||||
console.error('生成二维码失败:', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
whilePayStatus(){
|
||||
while(this.payStatus() === 2){
|
||||
getPayStatus(this.orderNo).then(response => {
|
||||
this.payStatus = response.data;
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
checkPayStatus() {
|
||||
this.checkInterval = setInterval(() => {
|
||||
getPayStatus(this.orderNo).then(response => {
|
||||
this.payStatus = response.data;
|
||||
if (this.payStatus === 1) {
|
||||
// 支付成功,停止检查
|
||||
clearInterval(this.checkInterval);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('获取支付状态失败:', error);
|
||||
});
|
||||
}, 2000); // 每5秒检查一次支付状态
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面布局样式 */
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: #333;
|
||||
padding: 10px;
|
||||
}
|
||||
.navbar {
|
||||
background-color: #333;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
|
||||
.menu {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: #f5f5f5;
|
||||
padding: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
width: 300px;
|
||||
height: auto;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.product-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 24px;
|
||||
color: red;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.payment {
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.payment p {
|
||||
margin-bottom: 10px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.warning {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue
Block a user