add 付费资源

This commit is contained in:
王鹏
2025-12-05 14:18:36 +08:00
parent de0fea0dbd
commit c390e4a033
8 changed files with 124 additions and 19 deletions

View File

@@ -19,6 +19,8 @@ public class CreateOrderReq {
private Long points;
private Long resourceId;
public Long getUserId() {
return userId;
}
@@ -42,4 +44,12 @@ public class CreateOrderReq {
public void setPoints(Long points) {
this.points = points;
}
public Long getResourceId() {
return resourceId;
}
public void setResourceId(Long resourceId) {
this.resourceId = resourceId;
}
}

View File

@@ -79,6 +79,17 @@ public class AppBlogArticle extends BaseEntity
private List<String> picList;
/** 关联的资源对象 */
private AppResource appResource;
public AppResource getAppResource() {
return appResource;
}
public void setAppResource(AppResource appResource) {
this.appResource = appResource;
}
public String getOrderType() {
return orderType;
}

View File

@@ -32,6 +32,10 @@ public class AppPayOrder extends BaseEntity
@Excel(name = "用户ID")
private Long userId;
/** 资源ID */
@Excel(name = "资源ID")
private Long resourceId;
/** openid */
@Excel(name = "openid")
private String openId;
@@ -135,6 +139,14 @@ public class AppPayOrder extends BaseEntity
return payTime;
}
public Long getResourceId() {
return resourceId;
}
public void setResourceId(Long resourceId) {
this.resourceId = resourceId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -142,6 +154,7 @@ public class AppPayOrder extends BaseEntity
.append("orderNo", getOrderNo())
.append("tradeNo", getTradeNo())
.append("userId", getUserId())
.append("resourceId", getResourceId())
.append("openId", getOpenId())
.append("amount", getAmount())
.append("points", getPoints())

View File

@@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.app.domain.AppIntegralRecord;
import com.ruoyi.app.domain.AppPayOrder;
import com.ruoyi.app.domain.AppResource;
import com.ruoyi.app.mapper.AppIntegralRecordMapper;
import com.ruoyi.app.mapper.AppPayOrderMapper;
import com.ruoyi.app.mapper.AppResourceMapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.OrderNoGenerator;
import com.ruoyi.common.wx.*;
@@ -59,6 +61,8 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private AppResourceMapper appResourceMapper;
@Autowired
private AppPayOrderMapper appPayOrderMapper;
@Autowired
private AppIntegralRecordMapper appIntegralRecordMapper;
@@ -72,13 +76,21 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
@Override
public Response createOrder(CreateOrderReq req) {
SysUser sysUser = sysUserMapper.selectUserById(req.getUserId());
AppResource appResource = null;
if (!Objects.isNull(req.getResourceId())) {
appResource = appResourceMapper.selectAppResourceById(req.getResourceId());
}
String openId = sysUser.getUserName();
String orderNo = OrderNoGenerator.generatePayOrderNo();
// 创建本地订单
// 这里做本地业务相关的处理,包括生成一个订单号传递给微信,等于通过这个值来形成两边的数据对应。后续微信那边会返回他们的订单编号,也建议存在自己这边的数据库里。
PayOrderInfo order = new PayOrderInfo();
order.setOutTradeNo(orderNo);
order.setDescription("积分充值");
if (Objects.isNull(appResource)) {
order.setDescription("积分充值");
} else {
order.setDescription("购买资源:" + appResource.getResourceTitle());
}
order.setAmount(new BigDecimal(req.getAmount()));
// 请求微信支付相关配置
@@ -127,19 +139,20 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
}
// 保存订单信息
saveOrder(orderNo, req.getAmount(), req.getPoints(), req.getUserId(), openId);
saveOrder(orderNo, req.getAmount(), req.getPoints(), req.getUserId(), req.getResourceId(), openId);
return Response.success(response);
}
private void saveOrder(String orderNo, Long amount, Long points, Long userId, String openId) {
private void saveOrder(String orderNo, Long amount, Long points, Long userId, Long resourceId, String openId) {
AppPayOrder order = appPayOrderMapper.selectAppPayOrderByOrderNo(orderNo);
if(Objects.isNull(order)){
if (Objects.isNull(order)) {
order = new AppPayOrder();
}
order.setOrderNo(orderNo);
order.setAmount(amount);
order.setPoints(points);
order.setUserId(userId);
order.setResourceId(resourceId);
order.setOpenId(openId);
order.setStatus(0);
order.setCreateTime(new Date());
@@ -221,7 +234,9 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
order.setPayTime(new Date());
appPayOrderMapper.updateAppPayOrder(order);
// 更新充值积分
updateUserPoints(order.getUserId(), order.getPoints());
if (order.getPoints() != 0) {
updateUserPoints(order.getUserId(), order.getPoints());
}
returnMap.put("code", "SUCCESS");
returnMap.put("message", "成功");
@@ -234,6 +249,7 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
if (sysUser == null) {
throw new RuntimeException("用户不存在");
}
AppIntegralRecord appIntegralRecord = new AppIntegralRecord();
appIntegralRecord.setUserId(userId);
appIntegralRecord.setIntegralNumber(points);
@@ -241,6 +257,7 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
appIntegralRecord.setIsAdd(0L);
appIntegralRecord.setIntegralTime(new Date());
appIntegralRecordMapper.insertAppIntegralRecord(appIntegralRecord);
// 更新用户积分
sysUser.setIntegral(sysUser.getIntegral() + points.intValue());
sysUserMapper.updateUser(sysUser);
}
@@ -279,7 +296,7 @@ public class WxMiniappPayServiceImpl implements WxMiniappPayService {
// TODO 修改订单信息
return Response.success(result.getTradeStateDesc());
} catch (ServiceException e) {
} catch (ServiceException e) {
log.error("根据支付订单号查询订单订单查询失败发送HTTP请求成功返回异常返回码{},返回信息:", e.getErrorCode(), e);
return Response.error("订单查询失败");
} catch (MalformedMessageException e) {

View File

@@ -25,25 +25,65 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="weight" column="weight" />
</resultMap>
<resultMap type="AppBlogArticle" id="AppBlogArticleWithResourceResult" extends="AppBlogArticleResult">
<association property="appResource" javaType="AppResource">
<id property="id" column="resource_id" />
<result property="resourceTitle" column="resource_title" />
<result property="showImg" column="resource_show_img" />
<result property="explain" column="resource_explain" />
<result property="resourceType" column="resource_type" />
<result property="keyword" column="resource_keyword" />
<result property="isShow" column="resource_is_show" />
<result property="isAd" column="resource_is_ad" />
<result property="adNumber" column="resource_ad_number" />
<result property="downNum" column="resource_down_num" />
<result property="weight" column="resource_weight" />
<result property="delFlag" column="resource_del_flag" />
<result property="createBy" column="resource_create_by" />
<result property="createTime" column="resource_create_time" />
<result property="remark" column="resource_remark" />
</association>
</resultMap>
<sql id="selectAppBlogArticleVo">
select id, title, content_info, article_type, keyword, show_img, app_resource_id, look_number, weight, love_number, is_recommendation, is_show, is_ad, ad_number, del_flag, create_by, create_time, remark from app_blog_article
</sql>
<select id="selectAppBlogArticleList" parameterType="AppBlogArticle" resultMap="AppBlogArticleResult">
<include refid="selectAppBlogArticleVo"/>
<select id="selectAppBlogArticleList" parameterType="AppBlogArticle" resultMap="AppBlogArticleWithResourceResult">
select
a.id, a.title, a.content_info, a.article_type, a.keyword, a.show_img, a.app_resource_id,
a.look_number, a.weight, a.love_number, a.is_recommendation, a.is_show, a.is_ad,
a.ad_number, a.del_flag, a.create_by, a.create_time, a.remark,
r.id as resource_id,
r.resource_title,
r.show_img as resource_show_img,
r.explain as resource_explain,
r.resource_type,
r.keyword as resource_keyword,
r.is_show as resource_is_show,
r.is_ad as resource_is_ad,
r.ad_number as resource_ad_number,
r.down_num as resource_down_num,
r.weight as resource_weight,
r.del_flag as resource_del_flag,
r.create_by as resource_create_by,
r.create_time as resource_create_time,
r.remark as resource_remark
from app_blog_article a
left join app_resource r on a.app_resource_id = r.id
<where>
<if test="title != null and title != ''"> and title like concat('%', #{title}, '%')</if>
<if test="contentInfo != null and contentInfo != ''"> and content_info like concat('%', #{contentInfo}, '%')</if>
<if test="articleType != null "> and article_type = #{articleType}</if>
<if test="appResourceId != null "> and app_resource_id = #{appResourceId}</if>
<if test="isRecommendation != null "> and is_recommendation = #{isRecommendation}</if>
<if test="isShow != null "> and is_show = #{isShow}</if>
<if test="weight != null "> and weight = #{weight}</if>
<if test="keyword != null and keyword != ''"> and (keyword like concat('%', #{keyword}, '%') or title like concat('%', #{keyword}, '%'))</if>
<if test="title != null and title != ''"> and a.title like concat('%', #{title}, '%')</if>
<if test="contentInfo != null and contentInfo != ''"> and a.content_info like concat('%', #{contentInfo}, '%')</if>
<if test="articleType != null "> and a.article_type = #{articleType}</if>
<if test="appResourceId != null "> and a.app_resource_id = #{appResourceId}</if>
<if test="isRecommendation != null "> and a.is_recommendation = #{isRecommendation}</if>
<if test="isShow != null "> and a.is_show = #{isShow}</if>
<if test="weight != null "> and a.weight = #{weight}</if>
<if test="keyword != null and keyword != ''"> and (a.keyword like concat('%', #{keyword}, '%') or a.title like concat('%', #{keyword}, '%'))</if>
</where>
<choose>
<when test="orderType == 'look_number'"> ORDER BY look_number desc, create_time desc</when >
<otherwise> ORDER BY weight desc, create_time desc</otherwise >
<when test="orderType == 'look_number'"> ORDER BY a.look_number desc, a.create_time desc</when >
<otherwise> ORDER BY a.weight desc, a.create_time desc</otherwise >
</choose>
</select>

View File

@@ -9,6 +9,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="orderNo" column="order_no" />
<result property="tradeNo" column="trade_no" />
<result property="userId" column="user_id" />
<result property="resourceId" column="resource_id" />
<result property="openId" column="open_id" />
<result property="amount" column="amount" />
<result property="points" column="points" />
@@ -18,7 +19,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectAppPayOrderVo">
select id, order_no, trade_no, user_id, open_id, amount, points, status, create_time, pay_time from app_pay_order
select id, order_no, trade_no, user_id, resource_id, open_id, amount, points, status, create_time, pay_time from app_pay_order
</sql>
<select id="selectAppPayOrderList" parameterType="AppPayOrder" resultMap="AppPayOrderResult">
@@ -49,6 +50,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="orderNo != null and orderNo != ''">order_no,</if>
<if test="tradeNo != null and tradeNo != ''">trade_no,</if>
<if test="userId != null">user_id,</if>
<if test="resourceId != null">resource_id,</if>
<if test="openId != null and openId != ''">open_id,</if>
<if test="amount != null">amount,</if>
<if test="points != null">points,</if>
@@ -60,6 +62,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="orderNo != null and orderNo != ''">#{orderNo},</if>
<if test="tradeNo != null and tradeNo != ''">#{tradeNo},</if>
<if test="userId != null">#{userId},</if>
<if test="resourceId != null">#{resourceId},</if>
<if test="openId != null and openId != ''">#{openId},</if>
<if test="amount != null">#{amount},</if>
<if test="points != null">#{points},</if>
@@ -75,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="orderNo != null and orderNo != ''">order_no = #{orderNo},</if>
<if test="tradeNo != null and tradeNo != ''">trade_no = #{tradeNo},</if>
<if test="userId != null">user_id = #{userId},</if>
<if test="resourceId != null">resource_id = #{resourceId},</if>
<if test="openId != null and openId != ''">open_id = #{openId},</if>
<if test="amount != null">amount = #{amount},</if>
<if test="points != null">points = #{points},</if>

View File

@@ -109,6 +109,7 @@
<el-table-column label="商户单号" align="center" prop="orderNo" />
<el-table-column label="交易单号" align="center" prop="tradeNo" />
<el-table-column label="用户ID" align="center" prop="userId" />
<el-table-column label="资源ID" align="center" prop="resourceId" />
<el-table-column label="openid" align="center" prop="openId" />
<el-table-column label="支付金额(元)" align="center" prop="amount" />
<el-table-column label="积分数量" align="center" prop="points" />
@@ -162,6 +163,9 @@
<el-form-item label="用户ID" prop="userId">
<el-input v-model="form.userId" placeholder="请输入用户ID" />
</el-form-item>
<el-form-item label="资源ID" prop="resourceId">
<el-input v-model="form.resourceId" placeholder="请输入资源ID" />
</el-form-item>
<el-form-item label="openid" prop="openId">
<el-input v-model="form.openId" placeholder="请输入openid" />
</el-form-item>
@@ -291,6 +295,7 @@ export default {
orderNo: null,
tradeNo: null,
userId: null,
resourceId: null,
openId: null,
amount: null,
points: null,

View File

@@ -67,6 +67,7 @@
<el-tag v-if="scope.row.isAd == 0" type="success">免费</el-tag>
<el-tag v-if="scope.row.isAd == 1" type="info">看广告</el-tag>
<el-tag v-if="scope.row.isAd == 2" type="danger">积分兑换</el-tag>
<el-tag v-if="scope.row.isAd == 3" type="warning">付费</el-tag>
</template>
</el-table-column>
<el-table-column label="兑换积分" align="center" prop="adNumber">
@@ -126,12 +127,16 @@
<el-radio :label="0">免费</el-radio>
<el-radio :label="1">看广告</el-radio>
<el-radio :label="2">积分兑换</el-radio>
<el-radio :label="3">付费</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.isAd == 2" label="兑换积分" prop="adNumber">
<el-input v-model="form.adNumber" placeholder="请输入需要兑换多少积分解锁" />
</el-form-item>
<el-form-item v-if="form.isAd == 3" label="付费金额" prop="adNumber">
<el-input v-model="form.adNumber" placeholder="请输入需要付费多少金额解锁" />
</el-form-item>
<el-form-item label="权重" prop="weight">
<el-input v-model="form.weight" placeholder="请输入权重" />
</el-form-item>