基于单片机的医疗废物远程监管系统设计
2026/4/6 21:22:00
家人们谁懂啊!当初做付费问答系统时,光“付费解锁逻辑”就纠结了整整一周——一开始直接用数据库字段控制查看权限,结果用户付费后刷新页面又看不了答案,导师看了说“支付状态同步有问题”😫 后来踩遍所有坑才搞懂支付回调和解锁机制,今天把知识付费系统从内容管理、支付集成到权限控制的核心细节说透,学弟学妹们不用再为支付逻辑烦恼!
刚开始我把付费问答做成“论坛+打赏功能”,花两周搞了“复杂积分体系”,结果导师一句“核心是付费解锁、内容变现、问答闭环、支付安全”直接打回重改!
系统主要有三类核心用户:管理员、提问者、回答者:
管理员端(平台管理核心):
提问者端(需求方核心):
回答者端(供给方核心):
导师必问“支付流程安全吗”,从3个角度回答:
采用Spring Boot 2.7 + MySQL 8.0 + Redis + 支付宝沙箱 + Vue 2,支付流程完整且安全!
| 技术工具 | 为什么选它 | 付费场景适配点 | 避坑提醒! |
|---|---|---|---|
| Spring Boot 2.7 | 快速集成支付SDK | 支付相关starter成熟 | 别用太新版本 |
| MySQL 8.0 | 事务支持完善 | 支付事务必须原子性 | 用InnoDB引擎 |
| Redis | 缓存支付状态 | 防止重复支付、缓存解锁状态 | 配置持久化 |
| 支付宝沙箱 | 模拟真实支付 | 答辩演示用,免费用 | 别用生产环境秘钥 |
| Vue 2 + Element UI | 组件丰富 | 支付页面、内容列表 | 地图用高德API |
# application.yml 支付配置alipay:app-id:你的沙箱APP_IDmerchant-private-key:私钥alipay-public-key:支付宝公钥gateway:https://openapi.alipaydev.com/gateway.donotify-url:/api/pay/alipay/notify# 回调地址return-url:/pay/success# 返回地址这是系统“最易出错点”,我当初支付状态字段设计简单,结果出现各种异常状态!
-- 问题表CREATETABLE`question`(`id`int(11)NOTNULLAUTO_INCREMENT,`title`varchar(200)NOTNULL,`content`text,`user_id`int(11)NOTNULL,`reward_amount`decimal(10,2)DEFAULT'0.00',`status`tinyint(1)DEFAULT'1'COMMENT'1待回答/2已回答/3已关闭',`is_paid`tinyint(1)DEFAULT'0'COMMENT'是否付费问题',`view_price`decimal(10,2)DEFAULT'0.00'COMMENT'查看价格',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 回答表(付费内容核心)CREATETABLE`answer`(`id`int(11)NOTNULLAUTO_INCREMENT,`question_id`int(11)NOTNULL,`user_id`int(11)NOTNULL,`content`text,`is_anonymous`tinyint(1)DEFAULT'0',`is_accepted`tinyint(1)DEFAULT'0'COMMENT'是否被采纳',`like_count`int(11)DEFAULT'0',`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 支付订单表(核心!)CREATETABLE`payment_order`(`id`int(11)NOTNULLAUTO_INCREMENT,`order_no`varchar(50)NOTNULLCOMMENT'订单号',`user_id`int(11)NOTNULL,`amount`decimal(10,2)NOTNULL,`status`tinyint(1)NOTNULLDEFAULT'0'COMMENT'0待支付/1已支付/2已退款/3支付失败',`pay_type`tinyint(1)DEFAULT'1'COMMENT'1支付宝/2微信',`item_type`tinyint(1)NOTNULLCOMMENT'1查看答案/2悬赏问题/3订阅',`item_id`int(11)NOTNULLCOMMENT'关联ID',`trade_no`varchar(100)DEFAULTNULLCOMMENT'支付平台交易号',`pay_time`datetimeDEFAULTNULL,`create_time`datetimeDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`),UNIQUEKEY`uk_order_no`(`order_no`),KEY`idx_user_item`(`user_id`,`item_type`,`item_id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 用户查看记录表(权限控制)CREATETABLE`user_view_record`(`id`int(11)NOTNULLAUTO_INCREMENT,`user_id`int(11)NOTNULL,`item_type`tinyint(1)NOTNULL,`item_id`int(11)NOTNULL,`payment_id`int(11)DEFAULTNULLCOMMENT'关联支付订单',`view_time`datetimeDEFAULTCURRENT_TIMESTAMP,`expire_time`datetimeDEFAULTNULLCOMMENT'过期时间',PRIMARYKEY(`id`),UNIQUEKEY`uk_user_item`(`user_id`,`item_type`,`item_id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;-- 用户付费后解锁内容的逻辑STARTTRANSACTION;-- 1. 检查是否已支付SELECT*FROMpayment_orderWHEREuser_id=1001ANDitem_type=1ANDitem_id=123ANDstatus=1;-- 已支付-- 2. 如果没有记录,插入查看记录(带过期时间)INSERTINTOuser_view_record(user_id,item_type,item_id,payment_id,expire_time)VALUES(1001,1,123,456,DATE_ADD(NOW(),INTERVAL30DAY))ONDUPLICATEKEYUPDATEview_time=NOW();-- 3. 更新问题查看次数UPDATEquestionSETview_count=view_count+1WHEREid=123;COMMIT;只需搞定3个核心模块,答辩足够出彩:
// 支付服务核心逻辑@ServicepublicclassPaymentService{publicPaymentResultcreateOrder(IntegeruserId,PaymentRequestrequest){// 1. 生成订单号StringorderNo=generateOrderNo();// 2. 创建订单记录PaymentOrderorder=newPaymentOrder();order.setOrderNo(orderNo);order.setUserId(userId);order.setAmount(request.getAmount());order.setItemType(request.getItemType());order.setItemId(request.getItemId());order.setStatus(0);// 待支付paymentOrderMapper.insert(order);// 3. 调用支付接口(支付宝为例)AlipayTradePagePayRequestpayRequest=newAlipayTradePagePayRequest();payRequest.setReturnUrl(alipayProperties.getReturnUrl());payRequest.setNotifyUrl(alipayProperties.getNotifyUrl());// 4. 设置支付参数payRequest.setBizContent(JSON.toJSONString(newAlipayTradeModel(orderNo,request.getAmount(),"付费查看答案")));// 5. 生成支付页面Stringform=alipayClient.pageExecute(payRequest).getBody();returnPaymentResult.success(orderNo,form);}// 支付回调处理@TransactionalpublicbooleanhandlePayNotify(PayNotifyRequestnotify){// 1. 验证签名if(!verifySignature(notify)){returnfalse;}// 2. 查询订单PaymentOrderorder=paymentOrderMapper.selectByOrderNo(notify.getOrderNo());if(order==null||order.getStatus()!=0){returnfalse;}// 3. 更新订单状态order.setStatus(1);// 已支付order.setTradeNo(notify.getTradeNo());order.setPayTime(newDate());paymentOrderMapper.updateById(order);// 4. 解锁内容(异步处理)unlockContentAsync(order.getUserId(),order.getItemType(),order.getItemId(),order.getId());returntrue;}}// 权限检查服务@ServicepublicclassPermissionService{publicbooleancanViewAnswer(IntegeruserId,IntegeranswerId){// 1. 获取答案对应的问题Answeranswer=answerMapper.selectById(answerId);if(answer==null){returnfalse;}Questionquestion=questionMapper.selectById(answer.getQuestionId());// 2. 免费问题直接查看if(!question.getIsPaid()){returntrue;}// 3. 问题发布者直接查看if(question.getUserId().equals(userId)){returntrue;}// 4. 回答者查看自己的回答if(answer.getUserId().equals(userId)){returntrue;}// 5. 检查是否已付费UserViewRecordrecord=viewRecordMapper.selectByUserAndItem(userId,1,answerId);if(record!=null&&record.getExpireTime().after(newDate())){returntrue;// 在有效期内}// 6. 检查是否有有效支付订单IntegerpaymentId=paymentOrderMapper.checkValidPayment(userId,1,answerId);returnpaymentId!=null;}}<template> <div class="pay-container"> <!-- 支付信息 --> <div class="pay-info"> <h3>支付确认</h3> <p>查看答案:{{ answer.title }}</p> <p class="price">¥{{ answer.viewPrice }}</p> </div> <!-- 支付方式选择 --> <div class="pay-methods"> <el-radio-group v-model="payMethod"> <el-radio label="alipay">支付宝支付</el-radio> <el-radio label="wechat">微信支付</el-radio> </el-radio-group> </div> <!-- 支付按钮 --> <el-button type="primary" @click="handlePay" :loading="paying"> 确认支付 ¥{{ answer.viewPrice }} </el-button> </div> </template> <script> export default { data() { return { answer: {}, payMethod: 'alipay', paying: false } }, methods: { async handlePay() { this.paying = true try { // 1. 创建支付订单 const orderRes = await this.$http.post('/api/payment/create', { itemType: 1, itemId: this.$route.params.id, amount: this.answer.viewPrice, payType: this.payMethod }) // 2. 根据支付方式处理 if (this.payMethod === 'alipay') { // 支付宝:渲染支付表单 this.renderAlipayForm(orderRes.data.payForm) } else { // 微信支付:显示二维码 this.showWechatQR(orderRes.data.codeUrl) } } catch (error) { this.$message.error('支付失败:' + error.message) } finally { this.paying = false } }, renderAlipayForm(formHtml) { const div = document.createElement('div') div.innerHTML = formHtml document.body.appendChild(div) div.querySelector('form').submit() } } } </script>| 测试场景 | 操作步骤 | 预期结果 | 重要性 |
|---|---|---|---|
| 重复支付 | 用户对同一内容多次支付 | 只有第一次成功,后续提示“已购买” | 避免重复扣款 |
| 支付回调异常 | 模拟支付成功但回调失败 | 系统有对账机制,能恢复状态 | 保证数据一致性 |
| 网络中断支付 | 支付过程中断网 | 支持重新发起支付,原订单可继续支付 | 用户体验 |
| 退款流程 | 用户申请退款 | 支持部分退款,更新订单状态 | 合规要求 |
抓住“支付安全”和“内容权限”两个核心,把支付流程、权限控制、状态管理三个难点做扎实。
需要精简版源码(带支付流程)、测试用例、答辩PPT模板的同学,评论区扣“付费问答”,我私发你!
点赞收藏,付费问答毕设不迷路~祝大家顺利毕业!💰💡