pay.vue 9.8 KB

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