pay.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <template>
  2. <view class="login-main">
  3. <view style="width: 100%">
  4. <view style="width: 100%; height: 270rpx">
  5. <image class="img" src="../../static/images/payBack.png" style="width: 100%; height: 100%"></image>
  6. </view>
  7. </view>
  8. <view class="main">
  9. <view class="login-main-content">
  10. <image class="img" :src="shopInfo.shopLogoUrl
  11. ? shopInfo.shopLogoUrl
  12. : '/static/images/error.jpeg'
  13. " mode=""></image>
  14. <h4 class="shopName">
  15. {{ shopInfo ? shopInfo.shopName : "" }}
  16. </h4>
  17. </view>
  18. <view class="login-contont">
  19. <view class="uInput">
  20. <u-input placeholder="请输入金额" border="bottom" :fontSize="40" type="digit"
  21. @change="validateInput($event, 1)" v-model="price" :customStyle="inpustyle">
  22. <span slot="prefix" style="font-size: 30px">¥</span>
  23. </u-input>
  24. </view>
  25. <view class="login-contont-button">
  26. <button class="btn" @click="Pay">立即支付</button>
  27. <view style="padding: 0px 30rpx">
  28. <view style="margin-top: 66rpx; background: #fff7f6">
  29. <u-cell-group :border="false">
  30. <u-cell title="代金券折扣" :value="couponList.length + '个券可使用'" :border="false" isLink
  31. @click="voucher"></u-cell>
  32. </u-cell-group>
  33. </view>
  34. <view style="margin-top: 20rpx; font-size: 26rpx">
  35. 支付成功后,次日将有随机奖励红包以及店铺代金券,可抵现金花,AI天枢云小程序领取
  36. </view>
  37. </view>
  38. </view>
  39. </view>
  40. </view>
  41. <u-popup :show="showPopup" mode="bottom" :round="20">
  42. <view class="coupon-popup">
  43. <view class="popup-header">
  44. <text class="title">店铺代金券</text>
  45. <u-icon name="close" size="22" @click="showPopup = false" />
  46. </view>
  47. <view class="coupon-list">
  48. <view class="coupon-item" :class="item.status === 0 ? 'disabled' : 'active'"
  49. v-for="(item, index) in couponList" :key="index" @click="selectCoupon(index)">
  50. <view class="left">
  51. <view class="tag" :class="item.type === 1 ? 'independent' : 'chain'">
  52. {{ item.type === 1 ? '独立券' : '连锁券' }}
  53. </view>
  54. <view class="price">
  55. <text class="yen">¥</text>
  56. <text class="num">{{ item.price }}</text>
  57. <text class="tip">{{ item.desc }}</text>
  58. </view>
  59. <view class="info">
  60. <text>{{ item.time }}</text>
  61. <text>{{ item.scope }}</text>
  62. </view>
  63. </view>
  64. <view class="right">
  65. <u-radio :checked="selectIndex === index" disabled :custom-style="radioStyle" />
  66. </view>
  67. </view>
  68. </view>
  69. </view>
  70. </u-popup>
  71. </view>
  72. </template>
  73. <script>
  74. import api from "@/api/index.js";
  75. import { requestConfig } from "@/app.config.js";
  76. export default {
  77. data() {
  78. return {
  79. showPopup: false,
  80. requestConfig: requestConfig,
  81. code: "",
  82. appid: "",
  83. value: "",
  84. userInfo: {},
  85. inpustyle: {
  86. fontWeight: "bold",
  87. fontSize: "40px",
  88. },
  89. price: null,
  90. shopId: "",
  91. shopInfo: {},
  92. localUserInfo: {},
  93. couponList: []
  94. };
  95. },
  96. onLoad(options) {
  97. this.shopId = options.shopId;
  98. localStorage.setItem("shopId", this.shopId);
  99. let info = localStorage.getItem("weChatUserInfo");
  100. this.localUserInfo = JSON.parse(info);
  101. if (this.localUserInfo) {
  102. this.getShopInfo();
  103. } else {
  104. this.getInfo();
  105. this.getVoucher();
  106. }
  107. },
  108. methods: {
  109. getVoucher() {
  110. api
  111. .byStore({
  112. storeId: '2018881434293329922',
  113. })
  114. .then((res) => {
  115. if (res.code == 200) {
  116. this.couponList = res.data;
  117. } else {
  118. uni.$u.toast(res.msg);
  119. }
  120. });
  121. },
  122. voucher() {
  123. this.showPopup = true;
  124. },
  125. getInfo() {
  126. let code = this.GetQueryString("code");
  127. localStorage.removeItem("token");
  128. localStorage.removeItem("weChatUserInfo");
  129. api
  130. .weChatH5Login({
  131. code: code,
  132. })
  133. .then((res) => {
  134. console.log(res);
  135. if (res.code == 200) {
  136. this.userInfo = res.data;
  137. localStorage.setItem("token", this.userInfo.token);
  138. localStorage.setItem(
  139. "weChatUserInfo",
  140. JSON.stringify(this.userInfo),
  141. );
  142. if (this.userInfo.bindPhoneStatus == 0) {
  143. this.showPhone = true;
  144. } else {
  145. this.showPhone = false;
  146. }
  147. this.getShopInfo();
  148. } else {
  149. uni.$u.toast("获取微信登录信息失败,请重新登录!");
  150. }
  151. });
  152. },
  153. async getShopInfo() {
  154. api
  155. .getStoreInfoByScan({
  156. shopId: this.shopId,
  157. })
  158. .then((res) => {
  159. if (res.code == 200) {
  160. this.shopInfo = res.data;
  161. } else {
  162. uni.$u.toast(res.msg);
  163. }
  164. });
  165. },
  166. async Pay() {
  167. uni.showLoading({
  168. title: "支付中",
  169. });
  170. if (!this.price) {
  171. uni.$u.toast("请输入支付金额!");
  172. }
  173. api
  174. .payOrder({
  175. shopType: this.shopInfo.shopType,
  176. shopUserId: this.shopInfo.shopUserId,
  177. shopId: this.shopInfo.shopId,
  178. payAmount: Number(this.price),
  179. payWay: 6,
  180. userId: this.localUserInfo.userId
  181. })
  182. .then((res) => {
  183. if (res.code == 200) {
  184. WeixinJSBridge.invoke(
  185. "getBrandWCPayRequest",
  186. {
  187. // 公众号名称,由商户传入
  188. appId: res.data.appId,
  189. // 时间戳,自1970年以来的秒数
  190. timeStamp: res.data.timeStamp,
  191. // 随机串
  192. nonceStr: res.data.nonceStr,
  193. package: res.data.package,
  194. // 微信签名方式:
  195. signType: res.data.signType,
  196. // 微信签名
  197. paySign: res.data.paySign,
  198. },
  199. function (res) {
  200. if (res.err_msg == "get_brand_wcpay_request:ok") {
  201. // 使用以上方式判断前端返回,
  202. // 微信团队郑重提示:
  203. uni.hideLoading();
  204. // window.location.href = requestConfig.redirectOpen;
  205. uni.navigateTo({
  206. url: `/pages/index/paySuccess`,
  207. });
  208. // res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
  209. } else {
  210. uni.hideLoading();
  211. uni.$u.toast("支付失败!");
  212. }
  213. },
  214. );
  215. } else {
  216. uni.$u.toast(res.msg);
  217. }
  218. }).catch((err) => {
  219. uni.hideLoading();
  220. let msg = err.msg || "";
  221. let errStr = msg.match(/[\u4e00-\u9fa5\/]+/)?.[0] || "支付失败";
  222. uni.$u.toast(errStr);
  223. });
  224. },
  225. GetQueryString(name) {
  226. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  227. var r = window.location.search.substr(1).match(reg);
  228. if (r != null) return unescape(r[2]);
  229. return null;
  230. },
  231. validateInput(e, num) {
  232. const inputTypeNum = /[^\d]/g; //数字
  233. // switch (num) {
  234. // case 1:
  235. // //要写nextTick 不然无效
  236. // this.$nextTick(() => {
  237. // this.price = e.replace(inputTypeNum, "");
  238. // });
  239. // break;
  240. // }
  241. },
  242. },
  243. };
  244. </script>
  245. <style lang="scss">
  246. .coupon-popup {
  247. padding: 30rpx;
  248. height: 1000rpx;
  249. box-sizing: border-box;
  250. }
  251. .popup-header {
  252. display: flex;
  253. justify-content: space-between;
  254. align-items: center;
  255. font-size: 32rpx;
  256. font-weight: bold;
  257. margin-bottom: 30rpx;
  258. }
  259. .coupon-list {
  260. height: calc(100% - 100rpx);
  261. overflow-y: auto;
  262. }
  263. .coupon-item {
  264. background: #fff;
  265. border-radius: 16rpx;
  266. padding: 24rpx;
  267. margin-bottom: 20rpx;
  268. display: flex;
  269. justify-content: space-between;
  270. align-items: center;
  271. border: 2rpx solid #eee;
  272. }
  273. .coupon-item.active {
  274. border-color: #ff4d4f;
  275. background: #fffbf4;
  276. }
  277. .coupon-item.disabled {
  278. opacity: 0.5;
  279. }
  280. .left {
  281. flex: 1;
  282. }
  283. .tag {
  284. font-size: 22rpx;
  285. color: #fff;
  286. padding: 4rpx 12rpx;
  287. border-radius: 6rpx;
  288. margin-bottom: 12rpx;
  289. }
  290. .independent {
  291. background: #5c8dff;
  292. }
  293. .chain {
  294. background: #ff7d00;
  295. }
  296. .price {
  297. display: flex;
  298. align-items: baseline;
  299. margin-bottom: 12rpx;
  300. }
  301. .yen {
  302. font-size: 28rpx;
  303. color: #ff4d4f;
  304. }
  305. .num {
  306. font-size: 44rpx;
  307. font-weight: bold;
  308. color: #ff4d4f;
  309. margin: 0 10rpx;
  310. }
  311. .tip {
  312. font-size: 24rpx;
  313. color: #999;
  314. }
  315. .info {
  316. font-size: 24rpx;
  317. color: #999;
  318. line-height: 1.6;
  319. }
  320. .right {
  321. padding-left: 20rpx;
  322. }
  323. ::v-deep .u-cell__title {
  324. flex: none !important;
  325. }
  326. .main {
  327. width: 100%;
  328. background: white;
  329. height: calc(100% - 280rpx);
  330. border-radius: 40rpx;
  331. }
  332. .shopName {
  333. font-weight: bold;
  334. font-size: 36rpx;
  335. color: #333333;
  336. }
  337. /* 修改加载提示框的遮罩层 z-index */
  338. .uni-loading__mask {
  339. z-index: 10076;
  340. }
  341. /* 修改加载提示框本身的 z-index */
  342. .uni-loading {
  343. z-index: 10076;
  344. }
  345. .yzm {
  346. font-weight: 500;
  347. font-size: 28rpx;
  348. color: #00d36d;
  349. }
  350. .popup {
  351. height: 300px;
  352. padding: 20px;
  353. .footer {
  354. margin-top: 150rpx;
  355. .btn {
  356. width: 100%;
  357. background: linear-gradient(152deg, #6f9dfd 0%, #1b71f2 100%);
  358. border-radius: 46rpx;
  359. border: none;
  360. }
  361. }
  362. .main {
  363. margin-top: 20rpx;
  364. }
  365. .header {
  366. margin-bottom: 20rpx;
  367. text-align: center;
  368. .tip {
  369. margin-top: 20rpx;
  370. font-weight: 500;
  371. font-size: 26rpx;
  372. color: #ff8b2f;
  373. }
  374. }
  375. }
  376. .u-radio-group--row {
  377. justify-content: center;
  378. }
  379. .radioText {
  380. font-weight: 500;
  381. font-size: 24rpx;
  382. color: #999999;
  383. line-height: 34rpx;
  384. text-align: left;
  385. font-style: normal;
  386. }
  387. .login-main {
  388. background: url("../../static/images/payBack.png");
  389. background-size: 100% 100%;
  390. width: 100%;
  391. display: flex;
  392. flex-direction: column;
  393. /* justify-content: space-between; */
  394. align-items: center;
  395. height: 100vh;
  396. }
  397. .login-contont-button {
  398. text-align: center;
  399. .btn {
  400. margin-top: 20px;
  401. width: 95%;
  402. height: 90rpx;
  403. background: linear-gradient(152deg, #6f9dfd 0%, #1b71f2 100%);
  404. border-radius: 44rpx;
  405. color: #fff;
  406. }
  407. }
  408. .login-contont {
  409. width: 100%;
  410. height: 600rpx;
  411. margin-top: 100rpx;
  412. .uInput {
  413. padding: 10px 0px;
  414. border-bottom: 0.5px solid #97979740;
  415. }
  416. .login-contont-info {
  417. text-align: center;
  418. .text {
  419. margin-top: 10px;
  420. font-weight: 500;
  421. font-size: 28rpx;
  422. color: #999999;
  423. line-height: 40rpx;
  424. font-style: normal;
  425. }
  426. }
  427. }
  428. .radio {
  429. text-align: center;
  430. margin-top: 10px;
  431. }
  432. .login-main-content {
  433. display: flex;
  434. flex-direction: row;
  435. align-items: center;
  436. padding: 9px 26px;
  437. .img {
  438. // margin-top: 70px;
  439. margin-right: 20rpx;
  440. width: 44rpx;
  441. height: 44rpx;
  442. border-radius: 50%;
  443. }
  444. }
  445. </style>