建設(shè)企業(yè)網(wǎng)站進(jìn)去無法顯示怎么在百度上免費(fèi)做廣告
目錄
一、展示投資列表
(一)需求
(二)后端
(三)前端
二、充值功能
(一)需求
1、需求描述
2、流程
(二)充值
1、后端
2、前端
(三)回調(diào)接口
1、定義回調(diào)接口
2、增加交易流水
(四)接口調(diào)用冪等性
1、接口冪等性原則
2、解決方案
一、展示投資列表
(一)需求
標(biāo)的形成后,客戶可在客戶端看到標(biāo)的列表,投資者可以通過點(diǎn)擊標(biāo)的了解詳情并投資心儀標(biāo)的
(二)后端
LendController中創(chuàng)建list方法
@Api(tags = "標(biāo)的")
@RestController
@RequestMapping("/api/core/lend")
@Slf4j
public class LendController {@Resourceprivate LendService lendService;@ApiOperation("獲取標(biāo)的列表")@GetMapping("/list")public R list() {List<Lend> lendList = lendService.selectList();return R.ok().data("lendList", lendList);}
}
(三)前端
pages/lend/index.vue
腳本
此處使用了服務(wù)器端渲染
<template><!--列表--><div class="page-filter wrap"><div class="breadcrumbs"><a href="index.html">首頁(yè)</a>><span class="cur">散標(biāo)投資列表</span></div><div class="invest-filter" data-target="sideMenu"><div class="filter-inner clearfix"><div class="filter-item"><div class="hd"><h3>篩選投資項(xiàng)目</h3><label><input id="filterMulti" name="multiple_choice" type="checkbox" />多選</label></div><div class="bd"><dl><dt>項(xiàng)目類型</dt><dd><ul><li class="n1"><ahref="javascript:url('post_type','');"id="post_type_"class="active">不限</a></li><li class="n2"><ahref="javascript:url('post_type','car');"id="post_type_car">車易貸</a></li><li class="n3"><ahref="javascript:url('post_type','house');"id="post_type_house">房易貸</a></li><li class="n4"><ahref="javascript:url('post_type','bridge');"id="post_type_bridge">贖樓貸</a></li><li class="n5"><ahref="javascript:url('post_type','worth');"id="post_type_worth">債權(quán)貸</a></li></ul></dd></dl><dl><dt>年利率</dt><dd><ul><li class="n1"><ahref="javascript:url('borrow_interestrate','');"id="borrow_interestrate_"class="active">不限</a></li><li class="n2"><aid="borrow_interestrate_1"href="javascript:url('borrow_interestrate','1');">12%以下</a></li><li class="n3"><aid="borrow_interestrate_2"href="javascript:url('borrow_interestrate','2');">12%-14%</a></li><li class="n4"><aid="borrow_interestrate_3"href="javascript:url('borrow_interestrate','3');">14%-16%</a></li><li class="n5"><aid="borrow_interestrate_4"href="javascript:url('borrow_interestrate','4');">16%及以上</a></li></ul></dd></dl><dl><dt>期限</dt><dd><ul><li class="n1"><ahref="javascript:url('spread_month','');"id="spread_month_"class="active">不限</a></li><li class="n2"><aid="spread_month_1"href="javascript:url('spread_month','1');">1月以下</a></li><li class="n3"><aid="spread_month_2"href="javascript:url('spread_month','2');">1-3月</a></li><li class="n4"><aid="spread_month_3"href="javascript:url('spread_month','3');">3-6月</a></li><li class="n5"><aid="spread_month_4"href="javascript:url('spread_month','4');">6-12月</a></li><li class="n6"><aid="spread_month_5"href="javascript:url('spread_month','5');">12月及以上</a></li></ul></dd></dl><dl class="repayment"><dt>還款方式</dt><dd><ul><li class="n1"><ahref="javascript:url('repay_style','');"id="repay_style_"class="active">不限</a></li><li class="n2"><aid="repay_style_end"href="javascript:url('repay_style','end');">到期還本付息</a></li><li class="n2"><aid="repay_style_endmonth"href="javascript:url('repay_style','endmonth');">按月付息,到期還本</a></li><li class="n2"><aid="repay_style_month"href="javascript:url('repay_style','month');">等額本息</a></li></ul></dd></dl></div></div><div class="common-problem"><h3>常見問題</h3><ul><li><a href="#">什么是債權(quán)貸?</a></li><li><a href="#">關(guān)于"債權(quán)貸"產(chǎn)品的說明</a></li><li><a href="#">金融理財(cái)收費(fèi)標(biāo)準(zhǔn)</a></li><li><a href="#">債權(quán)貸和房易貸、車易貸有什么區(qū)別?</a></li></ul></div></div></div><div class="invest-list mrt30 clearfix"><div class="hd"><h3>投資列表</h3><div class="count"><ul><li class="line">散標(biāo)投資交易金額 <span class="f20 bold">73.54億元</span></li><li>累計(jì)賺取收益 <span class="f20 bold">2.52億元</span></li></ul></div></div><div class="bd"><div class="invest-table clearfix"><div class="title clearfix"><ul><li class="col-330">借款標(biāo)題</li><li class="col-180"><a href="javascript:url('order','account_up');" class="">借款金額</a></li><li class="col-110"><a href="javascript:url('order','apr_up');" class="">年利率</a></li><li class="col-150"><a href="javascript:url('order','period_up');" class="">借款期限</a></li><li class="col-150">還款方式</li><li class="col-120"><a href="javascript:url('order','scale_up');" class="">借款進(jìn)度</a></li><li class="col-120-t">操作</li></ul></div><!------------投資列表--------------><div class="item" v-for="lend in lendList" :key="lend.id"><ul><li class="col-330 col-t"><NuxtLink :to="'/lend/' + lend.id" target="_blank"><i class="icon icon-zhai"></i></NuxtLink><NuxtLinkclass="f18":to="'/lend/' + lend.id":title="lend.title"target="_blank">{{ lend.title }}</NuxtLink></li><li class="col-180"><span class="f20 c-333"> {{ lend.amount }}元 </span></li><li class="col-110 relative"><span class="f20 c-orange">{{ lend.lendYearRate * 100 }}%</span></li><li class="col-150"><span class="f20 c-333">{{ lend.period }}個(gè)月</span></li><li class="col-150">{{ lend.params.returnMethod }}</li><li class="col-120"><div class="circle"><div class="left progress-bar"><!-- <div:class="'progress-bgPic progress-bfb' +Math.floor((lend.investAmount / lend.amount) * 10)"> --><div:class="'progress-bgPic progress-bfb' +Math.floor((lend.investAmount / lend.amount) * 10)"><div class="show-bar">{{ (lend.investAmount / lend.amount) * 100 }}%</div></div></div></div></li><li class="col-120-2"><NuxtLinkclass="ui-btn btn-gray":to="'/lend/' + lend.id"target="_blank">{{ lend.params.status }}</NuxtLink></li></ul></div><!------------投資列表--------------></div></div></div></div>
</template><script>
import '~/assets/css/index.css'
import '~/assets/css/detail.css'
export default {async asyncData({ $axios }) {console.log('服務(wù)器端獲取遠(yuǎn)程數(shù)據(jù)。。。。。。。。。。。。。。。。')let response = await $axios.$get('/api/core/lend/list')return {lendList: response.data.lendList,}},
}
</script>
二、充值功能
(一)需求
1、需求描述
標(biāo)的產(chǎn)生后,平臺(tái)展示標(biāo)的,投資人就可以在平臺(tái)投資標(biāo)的,獲取收益;投資人投資標(biāo)的必須滿足以下條件:
充值過程與綁定過程一致,也是在平臺(tái)發(fā)送充值請(qǐng)求,跳轉(zhuǎn)到資金托管平臺(tái)(匯付寶),在資金托管平臺(tái)(匯付寶)完成充值,然后同步或異步返回或通知平臺(tái)
操作表:user_account(用戶賬戶表) ====> trans_flow(交易流水表)
用戶輸入充值后,點(diǎn)擊確認(rèn),此時(shí)我們需要有一個(gè)方法返回一個(gè)表單且需自動(dòng)提交(攜帶匯付寶需要的參數(shù)且不能讓客戶看到表單,因此需要自動(dòng)提交),然后匯付寶會(huì)調(diào)用我們的回調(diào)方法,在回調(diào)方法中,我們需要更新用戶賬戶表并在交易流水表中產(chǎn)生一個(gè)記錄
匯付寶攜帶參數(shù)說明
?
?
2、流程
step1:用戶在個(gè)人中心點(diǎn)擊 “充值”?
step2:尚融寶展示賬戶充值頁(yè)面
step3:用戶填寫充值金額,點(diǎn)擊“充值”按鈕
step4:跳轉(zhuǎn)到匯付寶頁(yè)面(資金托管接口調(diào)用)
?
?step5:匯付寶驗(yàn)證用戶交易密碼
?
step6:匯付寶修改賬號(hào)資金余額(更新user_account記錄中的amount的值,這一步匯付寶做)
step7:異步回調(diào)
(1)賬戶金額更改
(2)添加交易流水
step8:用戶點(diǎn)擊“返回平臺(tái)”,返回尚融寶
?
(二)充值
1、后端
controller
UserAccountController?
@Api(tags = "會(huì)員賬戶")
@RestController
@RequestMapping("/api/core/userAccount")
@Slf4j
public class UserAccountController {@Resourceprivate UserAccountService userAccountService;@ApiOperation("充值")@PostMapping("/auth/commitCharge/{chargeAmt}")public R commitCharge(@ApiParam(value = "充值金額", required = true)@PathVariable BigDecimal chargeAmt, HttpServletRequest request) {String token = request.getHeader("token");Long userId = JwtUtils.getUserId(token);String formStr = userAccountService.commitCharge(chargeAmt, userId);return R.ok().data("formStr", formStr);}
}
service
接口:UserAccountService
String commitCharge(BigDecimal chargeAmt, Long userId);
實(shí)現(xiàn):UserAccountServiceImpl
@Resource
private UserInfoMapper userInfoMapper;@Override
public String commitCharge(BigDecimal chargeAmt, Long userId) {UserInfo userInfo = userInfoMapper.selectById(userId);String bindCode = userInfo.getBindCode();//判斷賬戶綁定狀態(tài)Assert.notEmpty(bindCode, ResponseEnum.USER_NO_BIND_ERROR);Map<String, Object> paramMap = new HashMap<>();paramMap.put("agentId", HfbConst.AGENT_ID);paramMap.put("agentBillNo", LendNoUtils.getNo());paramMap.put("bindCode", bindCode);paramMap.put("chargeAmt", chargeAmt);paramMap.put("feeAmt", new BigDecimal("0"));paramMap.put("notifyUrl", HfbConst.RECHARGE_NOTIFY_URL);//檢查常量是否正確paramMap.put("returnUrl", HfbConst.RECHARGE_RETURN_URL);paramMap.put("timestamp", RequestHelper.getTimestamp());String sign = RequestHelper.getSign(paramMap);paramMap.put("sign", sign);//構(gòu)建充值自動(dòng)提交表單String formStr = FormHelper.buildForm(HfbConst.RECHARGE_URL, paramMap);return formStr;
}
?
2、前端
pages/user/recharge.vue
methods: {commitCharge() {this.$alert('<div style="size: 18px;color: red;">您即將前往匯付寶充值</div>','前往匯付寶資金托管平臺(tái)',{dangerouslyUseHTMLString: true,confirmButtonText: '立即前往',callback: (action) => {if (action === 'confirm') {this.$axios.$post('/api/core/userAccount/auth/commitCharge/' + this.chargeAmt).then((response) => {document.write(response.data.formStr)})}},})},
},
(三)回調(diào)接口
1、定義回調(diào)接口
controller
UserAccountController中創(chuàng)建回調(diào)方法?
@ApiOperation(value = "用戶充值異步回調(diào)")
@PostMapping("/notify")
public String notify(HttpServletRequest request) {Map<String, Object> paramMap = RequestHelper.switchMap(request.getParameterMap());log.info("用戶充值異步回調(diào):" + JSON.toJSONString(paramMap));//校驗(yàn)簽名if(RequestHelper.isSignEquals(paramMap)) {//充值成功交易if("0001".equals(paramMap.get("resultCode"))) {return userAccountService.notify(paramMap);} else {log.info("用戶充值異步回調(diào)充值失敗:" + JSON.toJSONString(paramMap));return "success";}} else {log.info("用戶充值異步回調(diào)簽名錯(cuò)誤:" + JSON.toJSONString(paramMap));return "fail";}
}
service
接口:UserAccountService
String notify(Map<String, Object> paramMap);
實(shí)現(xiàn):UserAccountServiceImpl
@Transactional(rollbackFor = Exception.class)
@Override
public String notify(Map<String, Object> paramMap) {log.info("充值成功:" + JSONObject.toJSONString(paramMap));String bindCode = (String)paramMap.get("bindCode"); //充值人綁定協(xié)議號(hào)String chargeAmt = (String)paramMap.get("chargeAmt"); //充值金額//優(yōu)化baseMapper.updateAccount(bindCode, new BigDecimal(chargeAmt), new BigDecimal(0));//增加交易流水//TODOreturn "success";
}
mapper
接口:UserAccountMapper
void updateAccount(@Param("bindCode")String bindCode,@Param("amount")BigDecimal amount,@Param("freezeAmount")BigDecimal freezeAmount);
?XML:UserAccountMapper.xml
<update id="updateAccount">updateuser_accountsetamount = amount + #{amount},freeze_amount = freeze_amount + #{freezeAmount}whereuser_id = (select id from user_info where bind_code = #{bindCode})
</update>
?2、增加交易流水
增加枚舉TransTypeEnum
@AllArgsConstructor
@Getter
public enum TransTypeEnum {RECHARGE(1,"充值"),INVEST_LOCK(2,"投標(biāo)鎖定"),INVEST_UNLOCK(3,"放款解鎖"),CANCEL_LEND(4,"撤標(biāo)"),BORROW_BACK(5,"放款到賬"),RETURN_DOWN(6,"還款扣減"),INVEST_BACK(7,"出借回款"),WITHDRAW(8,"提現(xiàn)"),;private Integer transType ;private String transTypeName;public static String getTransTypeName(int transType) {for (TransTypeEnum obj : TransTypeEnum.values()) {if (transType == obj.getTransType().intValue()) {return obj.getTransTypeName();}}return "";}}
創(chuàng)建BO對(duì)象
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TransFlowBO {private String agentBillNo;private String bindCode;private BigDecimal amount;private TransTypeEnum transTypeEnum;private String memo;
}
?service
接口:TransFlowService
void saveTransFlow(TransFlowBO transFlowBO);
實(shí)現(xiàn):TransFlowServiceImpl
@Resource
private UserInfoMapper userInfoMapper;@Override
public void saveTransFlow(TransFlowBO transFlowBO) {//獲取用戶基本信息 user_infoQueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();userInfoQueryWrapper.eq("bind_code", transFlowBO.getBindCode());UserInfo userInfo = userInfoMapper.selectOne(userInfoQueryWrapper);//存儲(chǔ)交易流水?dāng)?shù)據(jù)TransFlow transFlow = new TransFlow();transFlow.setUserId(userInfo.getId());transFlow.setUserName(userInfo.getName());transFlow.setTransNo(transFlowBO.getAgentBillNo());transFlow.setTransType(transFlowBO.getTransTypeEnum().getTransType());transFlow.setTransTypeName(transFlowBO.getTransTypeEnum().getTransTypeName());transFlow.setTransAmount(transFlowBO.getAmount());transFlow.setMemo(transFlowBO.getMemo());baseMapper.insert(transFlow);
}
?完整的回調(diào)函數(shù)notify
@Resource
private TransFlowService transFlowService;@Transactional(rollbackFor = Exception.class)
@Override
public String notify(Map<String, Object> paramMap) {log.info("充值成功:" + JSONObject.toJSONString(paramMap));String bindCode = (String)paramMap.get("bindCode"); //充值人綁定協(xié)議號(hào)String chargeAmt = (String)paramMap.get("chargeAmt"); //充值金額//優(yōu)化baseMapper.updateAccount(bindCode, new BigDecimal(chargeAmt), new BigDecimal(0));//增加交易流水String agentBillNo = (String)paramMap.get("agentBillNo"); //商戶充值訂單號(hào)TransFlowBO transFlowBO = new TransFlowBO(agentBillNo,bindCode,new BigDecimal(chargeAmt),TransTypeEnum.RECHARGE,"充值");transFlowService.saveTransFlow(transFlowBO);return "success";
}
(四)接口調(diào)用冪等性
1、接口冪等性原則
接口冪等性就是用戶對(duì)于同一操作發(fā)起的一次請(qǐng)求或者多次請(qǐng)求的結(jié)果是一致的,不會(huì)因?yàn)槎啻握{(diào)用而產(chǎn)生了副作用。
舉個(gè)最簡(jiǎn)單的例子,那就是支付,用戶購(gòu)買商品后支付,支付扣款成功,但是返回結(jié)果的時(shí)候網(wǎng)絡(luò)異常,此時(shí)錢已經(jīng)扣了,用戶再次點(diǎn)擊按鈕,此時(shí)會(huì)進(jìn)行第二次扣款,返回結(jié)果成功,用戶查詢余額返發(fā)現(xiàn)多扣錢了,流水記錄也變成了兩條...這就沒有保證接口的冪等性
回調(diào)重試
匯付寶向尚融寶發(fā)起回調(diào),如果沒有收到正確的響應(yīng) "success",則尚融寶會(huì)發(fā)起重試
匯付寶中的相關(guān)代碼如下:
@Slf4j
public class NotifyThread implements Runnable {private int count = 1;private String notifyUrl;private Map<String, Object> paramMap;public NotifyThread(){}public NotifyThread(String notifyUrl, Map<String, Object> paramMap) {this.notifyUrl = notifyUrl;this.paramMap = paramMap;}@Overridepublic void run() {task();}private void task() {String result = SignUtil.sendRequest(paramMap,notifyUrl);log.info(notifyUrl + ":" + result + " count:" + count);if(!"success".equals(result)) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//ScheduledTask.queue.offer(new NotifyVo(notifyUrl, paramMap));count++;if(count <= 5) {task();log.info("失敗重試:" + JSON.toJSONString(this));}}}
}
存在的問題:當(dāng)回調(diào)重試時(shí),金額和流水會(huì)重復(fù)增加
?
?
2、解決方案
① 設(shè)置唯一索引
設(shè)置了唯一索引后,即使回調(diào)重復(fù)執(zhí)行,遇到唯一索引,就會(huì)拋出異常,從而使事務(wù)回滾。
但很顯然,我們不能光靠報(bào)錯(cuò)回滾數(shù)據(jù)庫(kù)事務(wù)來防止接口冪等性?
② 判斷流水是否存在
判斷流水如果存在,則從業(yè)務(wù)方法中直接退出
接口:TransFlowService
boolean isSaveTransFlow(String agentBillNo);
實(shí)現(xiàn):TransFlowServiceImpl
@Override
public boolean isSaveTransFlow(String agentBillNo) {QueryWrapper<TransFlow> queryWrapper = new QueryWrapper();queryWrapper.eq("trans_no", agentBillNo);int count = baseMapper.selectCount(queryWrapper);if(count > 0) {return true;}return false;
}
調(diào)用 :UserAccountServiceImpl
@Transactional(rollbackFor = Exception.class)
@Override
public void notify(Map<String, Object> paramMap) {log.info("充值成功:" + JSONObject.toJSONString(paramMap));//判斷交易流水是否存在String agentBillNo = (String)paramMap.get("agentBillNo"); //商戶充值訂單號(hào)boolean isSave = transFlowService.isSaveTransFlow(agentBillNo);if(isSave){log.warn("冪等性返回");return;}......//增加交易流水//agentBillNo = (String)paramMap.get("agentBillNo"); //商戶充值訂單號(hào)}