pay.vue 18 KB

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