pay.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. <template>
  2. <view class="container">
  3. <button class="order" @click="toOrder()">订单查询</button>
  4. <!-- 遮罩层 -->
  5. <view
  6. class="mark"
  7. v-show="showSearch || showLeaveMess"
  8. @click="markClose()"
  9. ></view>
  10. <view class="messageBg1"></view>
  11. <view class="messageBg2"></view>
  12. <view class="messageCard">
  13. <view class="item-form">
  14. <view class="item">
  15. <text class="ite">收费单位 </text>
  16. <text class="content">南昌交通学院</text>
  17. </view>
  18. <view class="item">
  19. <text class="ite">姓名 </text>
  20. <text class="content">{{ studentName }}</text>
  21. </view>
  22. <view class="item">
  23. <text class="ite">学号 </text>
  24. <text class="content">{{ studentNo }}</text>
  25. </view>
  26. <view class="item">
  27. <text class="ite">专业 </text>
  28. <text class="content">{{ majorName }}</text>
  29. </view>
  30. <view class="item">
  31. <text class="ite">班级 </text>
  32. <text class="content">{{ className }}</text>
  33. </view>
  34. <view class="item">
  35. <text class="ite">缴费学年 </text>
  36. <text class="content">{{ years }}</text>
  37. </view>
  38. <view class="item-pay" v-for="item in Arr">
  39. <text class="ite">{{ item.id }} </text>
  40. <text class="content">¥{{ item.money }}</text>
  41. </view>
  42. <view class="item">
  43. <text class="ite">总金额 </text>
  44. <text class="content">¥{{ realPayAmount }}</text>
  45. </view>
  46. </view>
  47. <!-- 支付成功显示 -->
  48. <button
  49. @click="getPay()"
  50. hover-class="button-hover"
  51. :disabled="btDisabled"
  52. :style="bgColor"
  53. v-if="payStatu1"
  54. >
  55. 支付
  56. </button>
  57. <!-- 支付失败显示 -->
  58. <text class="okPay" v-if="payStatu2">已支付</text>
  59. <view class="bottom-a">
  60. <navigator
  61. url="#"
  62. open-type="navigate"
  63. hover-class="navigator-hover"
  64. @click="toSearch"
  65. >
  66. 帮人代缴
  67. </navigator>
  68. <navigator
  69. url="#"
  70. open-type="navigate"
  71. hover-class="navigator-hover"
  72. @click="toLeaveMess"
  73. >
  74. 信息有误?点击反馈
  75. </navigator>
  76. </view>
  77. </view>
  78. <!-- 代缴查询学生信息弹窗 -->
  79. <view class="pop-up" v-show="showSearch">
  80. <view class="top">
  81. <text>代缴人信息</text>
  82. <view class="close" @click="close1">
  83. <view class="image"></view>
  84. </view>
  85. </view>
  86. <view class="name">
  87. <text>姓 名</text>
  88. <input
  89. v-model="SeaStudentName"
  90. type="text"
  91. placeholder="请输入姓名"
  92. placeholder-style="color:rgba(0, 0, 0, 0.29);"
  93. />
  94. </view>
  95. <view class="studentNo">
  96. <text>学 号</text>
  97. <input
  98. v-model="SeaStudentNo"
  99. type="text"
  100. placeholder="请输入学号"
  101. placeholder-style="color:rgba(0, 0, 0, 0.29);"
  102. />
  103. </view>
  104. <view class="remark"> 备注:新生输入身份证号代替学号,老生输入学号 </view>
  105. <view class="confirm">
  106. <button hover-class="button-hover" @click="close1">取消</button>
  107. <button hover-class="button-hover" @click="searchDetailMess">
  108. 确认
  109. </button>
  110. </view>
  111. </view>
  112. <!-- 信息有误反馈弹窗 -->
  113. <view class="leaveMess" v-show="showLeaveMess">
  114. <view class="top">
  115. <text>信息反馈</text>
  116. <view class="close" @click="close2">
  117. <view class="image"></view>
  118. </view>
  119. </view>
  120. <view class="name">
  121. <text>姓&#12288;名 :</text>
  122. <input
  123. type="text"
  124. placeholder="请输入姓名"
  125. v-model="feedbackPersonName"
  126. placeholder-style="color: #B3B3B3;"
  127. />
  128. </view>
  129. <view class="tel">
  130. <text>联系人 :</text>
  131. <input
  132. type="text"
  133. placeholder="请输入联系人手机号码"
  134. v-model="feedbackPersonPhone"
  135. placeholder-style="color: #B3B3B3;"
  136. />
  137. </view>
  138. <text class="title">反馈信息 :</text>
  139. <textarea
  140. placeholder=""
  141. placeholder-class="textarea-placeholder"
  142. maxlength="512"
  143. v-model="feedbackInfo"
  144. />
  145. <button hover-class="button-hover" @click="putMess">提交</button>
  146. </view>
  147. </view>
  148. </template>
  149. <script>
  150. export default {
  151. data() {
  152. return {
  153. showLeaveMess: false, //显示信息有误反馈弹窗
  154. showSearch: false, //显示帮人代缴查询弹窗
  155. studentName: "", //姓名
  156. studentNo: "", //学号
  157. SeaStudentNo: "", //代缴查询学号
  158. SeaStudentName: "", //代缴查询姓名
  159. majorName: "", //专业
  160. className: "", //班级
  161. years: "", //缴费学年
  162. realPayAmount: "", //总金额
  163. Arr: [], //缴费明细数组
  164. payStatu1: true, //未支付
  165. payStatu2: false, //已支付
  166. btDisabled: false,
  167. bgColor: "background: #298def;",
  168. homeUrl: "https://jtishfw.ncjti.edu.cn/jiaofei/backendApi", //线上服务器域名
  169. notifyUrl:
  170. "https://jtishfw.ncjti.edu.cn/jiaofei/backendApi/pay/jxnxs/notify/", //农商行地址
  171. orderNo: "", //订单号
  172. //信息有误反馈
  173. feedbackPersonName: "",
  174. feedbackPersonPhone: "",
  175. feedbackInfo: "",
  176. //微信支付参数
  177. appId: "",
  178. timeStamp: "",
  179. nonceStr: "",
  180. package: "",
  181. signType: "",
  182. paySign: "",
  183. };
  184. },
  185. onLoad(options) {
  186. this.getDetailMess(); //获取用户详细信息
  187. },
  188. methods: {
  189. //显示代缴查询弹窗
  190. toSearch() {
  191. this.showSearch = true;
  192. },
  193. //关闭代缴查询弹窗
  194. close1() {
  195. this.showSearch = false;
  196. },
  197. //关闭信息有误反馈弹窗
  198. close2() {
  199. this.showLeaveMess = false;
  200. },
  201. //信息有误反馈弹窗
  202. toLeaveMess() {
  203. this.showLeaveMess = true;
  204. },
  205. //关闭遮罩层
  206. markClose() {
  207. this.showLeaveMess = false;
  208. this.showSearch = false;
  209. },
  210. //换取详情信息
  211. getDetailMess() {
  212. let that = this;
  213. let cardNumber = localStorage.getItem("cardNumber");
  214. let url = that.homeUrl + "/tuitionpayment/payableinfo/payableInfo";
  215. uni.showToast({
  216. title: "信息加载中",
  217. icon: "loading",
  218. mask: true,
  219. duration: 1000,
  220. });
  221. uni.request({
  222. url: url,
  223. data: {},
  224. header: {
  225. card_number: cardNumber,
  226. Accept: "application/json",
  227. "Content-Type": " application/x-www-form-urlencoded;charset=utf-8",
  228. "X-Requested-With": "XMLHttpRequest",
  229. },
  230. method: "GET",
  231. sslVerify: true,
  232. success: ({ data, statusCode, header }) => {
  233. let res = data.data;
  234. that.studentName = res.studentName;
  235. that.studentNo = res.studentNo;
  236. that.majorName = res.majorName;
  237. that.className = res.className;
  238. that.years = res.years;
  239. that.realPayAmount = res.realPayAmount;
  240. that.getPayDetail(res.payItemDetail);
  241. if (res.pay) {
  242. that.payStatu1 = false;
  243. that.payStatu2 = true;
  244. } else {
  245. that.payStatu1 = true;
  246. that.payStatu2 = false;
  247. }
  248. that.getOpenId();
  249. },
  250. fail: (error) => {},
  251. });
  252. },
  253. //获取学费明细
  254. getPayDetail(len) {
  255. //获取明细款项名称数组
  256. var arr = len.match(/[^\\u4e00-\\u9fa5]+/g);
  257. //过滤
  258. var itemIdArr = arr.filter(function (value) {
  259. return value !== ".";
  260. });
  261. //获取明细金额数组
  262. var itemMoneyArr = len.match(/([0-9]+\.[0-9]+)+/g);
  263. //拼接成对象数组
  264. var item = [];
  265. for (var i in (itemIdArr, itemMoneyArr)) {
  266. var c = {
  267. id: itemIdArr[i],
  268. money: itemMoneyArr[i],
  269. };
  270. item.push(c);
  271. }
  272. this.Arr = item;
  273. },
  274. //获取openId
  275. getOpenId() {
  276. let openId = localStorage.getItem("openId");
  277. if (!openId) {
  278. let openId = this.getQueryString("openId");
  279. let error = this.getQueryString("error");
  280. let errorMsg = this.getQueryString("errorMsg");
  281. let homeWeb = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd87cbe1db0437303&redirect_uri=${this.homeUrl}/wechat/pub/auth&response_type=code&scope=snsapi_base&state=pages/Pay/pay#wechat_redire`;
  282. if (error) {
  283. uni.showToast({
  284. title: errorMsg,
  285. icon: "error",
  286. mask: true,
  287. duration: 1000,
  288. });
  289. } else if (!openId) {
  290. window.location.href = homeWeb;
  291. } else {
  292. localStorage.setItem("openId", openId);
  293. }
  294. }
  295. },
  296. //支付
  297. getPay() {
  298. this.btDisabled = !this.btDisabled;
  299. this.bgColor = " background: #b3b3b3;";
  300. setTimeout(() => {
  301. this.btDisabled = !this.btDisabled;
  302. this.bgColor = " background: #298def;";
  303. }, 4000);
  304. uni.showToast({
  305. title: "支付中,请稍等",
  306. icon: "loading",
  307. mask: true,
  308. duration: 2000,
  309. });
  310. this.getOrderNo(); //获取订单号
  311. },
  312. //获取订单号
  313. getOrderNo() {
  314. let that = this;
  315. let cardNumber = localStorage.getItem("cardNumber");
  316. if (cardNumber == null) {
  317. uni.showToast({
  318. title: "cardNumber为空,请重新授权",
  319. icon: "error",
  320. mask: true,
  321. duration: 1500,
  322. });
  323. setTimeout(() => this.toBlank, 2000);
  324. }
  325. let url =
  326. that.homeUrl + `/tuitionpayment/payorder/${that.studentNo}/create`;
  327. uni.request({
  328. url: url,
  329. data: {},
  330. header: {
  331. card_number: cardNumber,
  332. Accept: "application/json",
  333. "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
  334. "X-Requested-With": "XMLHttpRequest",
  335. },
  336. method: "POST",
  337. sslVerify: true,
  338. success: ({ data, statusCode, header }) => {
  339. let res = data.data;
  340. that.orderNo = res.orderNo;
  341. if (!data.success) {
  342. //接口错误提示框
  343. uni.showToast({
  344. title: data.message,
  345. icon: "error",
  346. mask: true,
  347. duration: 2000,
  348. });
  349. } else {
  350. that.getPayMethod();
  351. }
  352. },
  353. fail: (error) => {},
  354. });
  355. },
  356. //获取支付方式
  357. getPayMethod() {
  358. let url = this.homeUrl + "/payMethodSetting/currentPay";
  359. uni.request({
  360. url: url,
  361. data: {},
  362. header: {
  363. Accept: "application/json",
  364. "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
  365. "X-Requested-With": "XMLHttpRequest",
  366. },
  367. method: "GET",
  368. sslVerify: true,
  369. success: ({ data, statusCode, header }) => {
  370. let res = data.data;
  371. if (data.success) {
  372. if (res.currentPayMethod === "1") {
  373. this.getwxParam(); //建行支付
  374. } else {
  375. this.nsPay(); //农商行支付
  376. }
  377. } else {
  378. //接口错误提示框
  379. uni.showToast({
  380. title: data.message,
  381. icon: "error",
  382. mask: true,
  383. duration: 1000,
  384. });
  385. }
  386. },
  387. fail: (error) => {},
  388. });
  389. },
  390. //获取微信支付参数
  391. getwxParam() {
  392. let that = this;
  393. let cardNumber = localStorage.getItem("cardNumber");
  394. let openId = localStorage.getItem("openId");
  395. let url = that.homeUrl + "/pay/ccb/getJsApiParam";
  396. uni.request({
  397. url: url,
  398. data: {
  399. orderNo: that.orderNo,
  400. openId: openId,
  401. },
  402. header: {
  403. card_number: cardNumber,
  404. Accept: "application/json",
  405. "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
  406. "X-Requested-With": "XMLHttpRequest",
  407. },
  408. method: "GET",
  409. sslVerify: true,
  410. success: ({ data, statusCode, header }) => {
  411. if (!data.success) {
  412. //接口返回错误提示框
  413. uni.showToast({
  414. title: data.message,
  415. icon: "error",
  416. mask: true,
  417. duration: 2000,
  418. });
  419. } else {
  420. let res = data.data;
  421. that.appId = res.appId;
  422. that.timeStamp = res.timeStamp;
  423. that.nonceStr = res.nonceStr;
  424. that.package = res.package;
  425. that.signType = res.signType;
  426. that.paySign = res.paySign;
  427. that.wxPay(); //吊起微信支付
  428. }
  429. },
  430. fail: (error) => {},
  431. });
  432. },
  433. //吊起微信支付
  434. wxPay() {
  435. let that = this;
  436. function onBridgeReady() {
  437. WeixinJSBridge.invoke(
  438. "getBrandWCPayRequest",
  439. {
  440. appId: that.appId, //公众号ID,由商户传入
  441. timeStamp: that.timeStamp, //时间戳,自1970年以来的秒数
  442. nonceStr: that.nonceStr, //随机串
  443. package: that.package,
  444. signType: that.signType, //微信签名方式:
  445. paySign: that.paySign, //微信签名
  446. },
  447. function (res) {
  448. if (res.err_msg == "get_brand_wcpay_request:ok") {
  449. // 使用以上方式判断前端返回,微信团队郑重提示:
  450. //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
  451. }
  452. }
  453. );
  454. }
  455. if (typeof WeixinJSBridge == "undefined") {
  456. if (document.addEventListener) {
  457. document.addEventListener(
  458. "WeixinJSBridgeReady",
  459. onBridgeReady,
  460. false
  461. );
  462. } else if (document.attachEvent) {
  463. document.attachEvent("WeixinJSBridgeReady", onBridgeReady);
  464. document.attachEvent("onWeixinJSBridgeReady", onBridgeReady);
  465. }
  466. } else {
  467. onBridgeReady();
  468. }
  469. },
  470. //拉起农商行支付
  471. nsPay() {
  472. let O = "5494ec3310685daa218382619dd20e27";
  473. let out_no = this.orderNo;
  474. let amount = this.realPayAmount;
  475. let appoint_notify = this.notifyUrl;
  476. let mainUrl = `https://q.jxnxs.com/newpay?O=${O}&out_no=${out_no}&amount=${amount}&appoint_notify=${appoint_notify}`;
  477. window.location.href = mainUrl;
  478. },
  479. //获取当前URL指定参数
  480. getQueryString(name) {
  481. let url = window.location.href; // 获取URL
  482. let pattern = new RegExp("[\?\&]" + name + "=([^\&]+)", "i"); // 正则匹配URL
  483. let matcher = pattern.exec(url);
  484. if (matcher == null || matcher.length < 1) {
  485. return false;
  486. }
  487. return decodeURIComponent(matcher[1]); // 输出指定的参数值 中文也可以
  488. },
  489. //代缴费
  490. searchDetailMess() {
  491. if (!this.SeaStudentNo || !this.SeaStudentName) {
  492. uni.showToast({
  493. title: "学号或姓名不能为空",
  494. icon: "error",
  495. mask: true,
  496. duration: 1000,
  497. });
  498. } else {
  499. let that = this;
  500. let cardNumber = localStorage.getItem("cardNumber");
  501. let url =
  502. that.homeUrl +
  503. `/tuitionpayment/payableinfo/payableInfo/${that.SeaStudentNo}/${that.SeaStudentName}`;
  504. uni.request({
  505. url: url,
  506. header: {
  507. card_number: cardNumber,
  508. Accept: "application/json",
  509. "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
  510. "X-Requested-With": "XMLHttpRequest",
  511. },
  512. method: "GET",
  513. sslVerify: true,
  514. success: ({ data, statusCode, header }) => {
  515. if (!data.success) {
  516. //接口返回错误提示框
  517. uni.showToast({
  518. title: data.message,
  519. icon: "error",
  520. mask: true,
  521. duration: 1000,
  522. });
  523. } else {
  524. uni.showToast({
  525. title: "信息加载中",
  526. icon: "loading",
  527. mask: true,
  528. duration: 500,
  529. });
  530. that.showSearch = !that.showSearch;
  531. let res = data.data;
  532. that.studentName = res.studentName;
  533. that.studentNo = res.studentNo;
  534. that.years = res.years;
  535. that.majorName = res.majorName;
  536. that.className = res.className;
  537. that.realPayAmount = res.realPayAmount;
  538. that.getPayDetail(res.payItemDetail);
  539. that.SeaStudentNo = "";
  540. that.SeaStudentName = "";
  541. if (res.pay) {
  542. that.payStatu1 = false;
  543. that.payStatu2 = true;
  544. } else {
  545. that.payStatu1 = true;
  546. that.payStatu2 = false;
  547. }
  548. }
  549. },
  550. fail: (error) => {},
  551. });
  552. }
  553. },
  554. //提交反馈信息
  555. putMess() {
  556. let that = this;
  557. let cardNumber = localStorage.getItem("cardNumber");
  558. let url = that.homeUrl + "/tuitionpayment/feedbackmsg/save";
  559. uni.request({
  560. url: url,
  561. data: {
  562. feedbackPersonName: that.feedbackPersonName,
  563. feedbackPersonPhone: that.feedbackPersonPhone,
  564. feedbackInfo: that.feedbackInfo,
  565. },
  566. header: {
  567. card_number: cardNumber,
  568. Accept: "application/json",
  569. "Content-Type": "application/json; charset=utf-8",
  570. "X-Requested-With": "XMLHttpRequest",
  571. },
  572. method: "POST",
  573. sslVerify: true,
  574. success: ({ data, statusCode, header }) => {
  575. if (data.success) {
  576. uni.showToast({
  577. title: "提交成功,静待处理",
  578. icon: "success",
  579. mask: true,
  580. duration: 1000,
  581. });
  582. that.close2();
  583. that.feedbackPersonName = "";
  584. that.feedbackPersonPhone = "";
  585. that.feedbackInfo = "";
  586. } else {
  587. uni.showToast({
  588. title: data.message,
  589. icon: "error",
  590. mask: true,
  591. duration: 1000,
  592. });
  593. }
  594. },
  595. fail: (error) => {},
  596. });
  597. },
  598. //跳转订单页面
  599. toOrder() {
  600. uni.navigateTo({ url: "/pages/order/order" });
  601. },
  602. //跳转空白页面重新授权拿cardNumber
  603. toBlank() {
  604. uni.navigateTo({ url: "/pages/blankIndex/blankIndex" });
  605. },
  606. },
  607. };
  608. </script>
  609. <style lang="scss" scoped>
  610. @import url("./css/pay.min.css");
  611. </style>