pay.vue 17 KB

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