pay.vue 18 KB

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