pay.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  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" v-model="price"
  21. :customStyle="inpustyle">
  22. <span slot="prefix" style="font-size: 30px">¥</span>
  23. </u-input>
  24. </view>
  25. <view style="padding: 20rpx" v-if="voucherRadio">
  26. <text style="font-size: 25rpx;">抵扣代金券后,实付金额</text><text
  27. style="color: orange;font-size: 40rpx;margin-left: 10rpx;"> {{ payment }}</text>
  28. </view>
  29. <view class="login-contont-button">
  30. <button class="btn" @tap="Pay">立即支付</button>
  31. <view style="padding: 0px 30rpx">
  32. <view style="margin-top: 66rpx; background: #fff7f6">
  33. <u-cell-group :border="false">
  34. <u-cell title="代金券折扣" :border="false" isLink @tap="voucher">
  35. <template slot="value">
  36. <text style="color: orange;">{{ CellText }}</text>
  37. </template>
  38. </u-cell>
  39. </u-cell-group>
  40. </view>
  41. <view style="margin-top: 20rpx; font-size: 26rpx">
  42. 支付成功后,次日将有随机奖励红包以及店铺代金券,可抵现金花,AI天枢云小程序领取
  43. </view>
  44. </view>
  45. </view>
  46. </view>
  47. </view>
  48. <u-popup :show="showPopup" mode="bottom" :round="20">
  49. <view class="coupon-popup">
  50. <view class="popup-header">
  51. <text class="title">店铺代金券</text>
  52. <u-icon name="close" size="22" @tap="showPopup = false" />
  53. </view>
  54. <view class="coupon-list">
  55. <u-radio-group v-model="voucherRadio" placement="column" @change="groupChange" iconSize="30"
  56. size="40">
  57. <view class="coupon-item" :class="item.status === 0 ? 'disabled' : 'active'"
  58. v-for="(item, index) in couponList" :key="index" @tap="selectCoupon(index)">
  59. <view class="left">
  60. <view class="tag" :class="item.voucherType === 1 ? 'independent' : 'chain'">
  61. {{ item.voucherType === 1 ? '独立券' : item.voucherType === 2 ? '连锁券' : '联合券' }}
  62. </view>
  63. <view class="price">
  64. <text class="yen">¥</text>
  65. <text class="num">{{ item.amount }}</text>
  66. <text class="tip">{{ item.voucherRule == 1 ? '无门槛' : '满' + item.minOrderAmount + '减'
  67. +
  68. item.discountAmount }}</text>
  69. </view>
  70. <view class="info">
  71. <text>{{ item.createTime }}</text>
  72. <!-- <text>{{ item.scope }}</text> -->
  73. </view>
  74. </view>
  75. <view class="right">
  76. <u-radio :name="item.id" iconSize="30" />
  77. </view>
  78. </view>
  79. </u-radio-group>
  80. </view>
  81. </view>
  82. </u-popup>
  83. </view>
  84. </template>
  85. <script>
  86. import api from "@/api/index.js";
  87. import { requestConfig } from "@/app.config.js";
  88. export default {
  89. data() {
  90. return {
  91. showPopup: false,
  92. requestConfig: requestConfig,
  93. code: "",
  94. appid: "",
  95. value: "",
  96. userInfo: {},
  97. inpustyle: {
  98. fontWeight: "bold",
  99. fontSize: "40px",
  100. },
  101. price: null,
  102. shopId: "",
  103. storeId: "",
  104. shopInfo: {},
  105. localUserInfo: {},
  106. voucherRadio: null,
  107. couponList: [
  108. // {
  109. // "amount": 2,
  110. // "applyAllProducts": 1,
  111. // "applyProductIds": [],
  112. // "bizType": 14,
  113. // "claimTime": "2026-04-11 09:56:51",
  114. // "createTime": "2026-04-11 09:56:51",
  115. // "discountAmount": null,
  116. // "endTime": "2026-04-30 10:33:38",
  117. // "id": "2042783907267350530",
  118. // "isApply": 0,
  119. // "minOrderAmount": null,
  120. // "orderNo": "",
  121. // "productIds": [],
  122. // "ruleDisplay": "无门槛",
  123. // "startTime": "2026-04-10 10:33:26",
  124. // "status": 1,
  125. // "storeCount": 1,
  126. // "storeId": "2018881434293329922",
  127. // "storeList": [
  128. // {
  129. // "isCreator": 1,
  130. // "storeId": "2018881434293329922",
  131. // "storeName": "医药one店",
  132. // "voucherId": "2042068417733718017"
  133. // }
  134. // ],
  135. // "storeName": "",
  136. // "unApplyReason": "",
  137. // "updateTime": "2026-04-11 09:56:47",
  138. // "useTime": null,
  139. // "userId": "1965353825816576001",
  140. // "voucherId": "2042068417733718017",
  141. // "voucherName": "2元代金券",
  142. // "voucherRule": 1,
  143. // "voucherType": 3,
  144. // "voucherTypeDesc": "联合券"
  145. // },
  146. // {
  147. // "amount": 2,
  148. // "applyAllProducts": 1,
  149. // "applyProductIds": [],
  150. // "bizType": 14,
  151. // "claimTime": "2026-04-11 09:56:50",
  152. // "createTime": "2026-04-11 09:56:50",
  153. // "discountAmount": null,
  154. // "endTime": "2026-04-16 21:21:31",
  155. // "id": "2042783902674587650",
  156. // "isApply": 0,
  157. // "minOrderAmount": null,
  158. // "orderNo": "",
  159. // "productIds": [],
  160. // "ruleDisplay": "无门槛",
  161. // "startTime": "2026-04-07 15:14:37",
  162. // "status": 1,
  163. // "storeCount": 1,
  164. // "storeId": "2018881434293329922",
  165. // "storeList": [
  166. // {
  167. // "isCreator": 1,
  168. // "storeId": "2018881434293329922",
  169. // "storeName": "医药one店",
  170. // "voucherId": "2042139544933875713"
  171. // }
  172. // ],
  173. // "storeName": "",
  174. // "unApplyReason": "",
  175. // "updateTime": "2026-04-11 09:56:46",
  176. // "useTime": null,
  177. // "userId": "1965353825816576001",
  178. // "voucherId": "2042139544933875713",
  179. // "voucherName": "联合券",
  180. // "voucherRule": 1,
  181. // "voucherType": 3,
  182. // "voucherTypeDesc": "联合券"
  183. // }
  184. ],
  185. CellText: "暂无代金券",
  186. payment: ""
  187. };
  188. },
  189. onLoad(options) {
  190. this.shopId = options.shopId;
  191. this.storeId = options.storeId;
  192. localStorage.setItem("shopId", this.shopId);
  193. localStorage.setItem("storeId", this.storeId);
  194. let info = localStorage.getItem("weChatUserInfo");
  195. this.localUserInfo = JSON.parse(info);
  196. if (this.localUserInfo) {
  197. this.getShopInfo();
  198. this.getVoucher();
  199. } else {
  200. this.getInfo();
  201. }
  202. },
  203. methods: {
  204. groupChange(e) {
  205. this.showPopup = false;
  206. let targetObj = this.couponList.find(item => item.id === e)
  207. if (targetObj.voucherRule === 1) {
  208. this.CellText = `- ¥${targetObj.amount}`
  209. } else {
  210. this.CellText = `满${targetObj.minOrderAmount}减${targetObj.discountAmount}`
  211. }
  212. this.payment = this.price - targetObj.amount
  213. console.log(this.price - targetObj.amount);
  214. },
  215. getVoucher() {
  216. api
  217. .availableList({
  218. storeId: this.storeId,
  219. })
  220. .then((res) => {
  221. if (res.code == 200) {
  222. if (res.data.length > 0) {
  223. this.couponList = res.data.filter(item => item.applyAllProducts !== 0)
  224. this.CellText = '可使用' + this.couponList.length + '个'
  225. } else {
  226. this.CellText = '暂无代金券'
  227. }
  228. } else {
  229. uni.$u.toast(res.msg);
  230. }
  231. });
  232. },
  233. voucher() {
  234. if (!this.price) {
  235. uni.$u.toast("请输入支付金额!");
  236. return
  237. }
  238. if (this.couponList.length == 0) {
  239. uni.$u.toast("暂无代金券");
  240. return;
  241. } else {
  242. this.showPopup = true;
  243. }
  244. },
  245. getInfo() {
  246. let code = this.GetQueryString("code");
  247. localStorage.removeItem("token");
  248. localStorage.removeItem("weChatUserInfo");
  249. api
  250. .weChatH5Login({
  251. code: code,
  252. grant_type: "mp",
  253. })
  254. .then((res) => {
  255. if (res.code == 200) {
  256. this.userInfo = res.data;
  257. localStorage.setItem("token", this.userInfo.access_token);
  258. localStorage.setItem(
  259. "weChatUserInfo",
  260. JSON.stringify(this.userInfo),
  261. );
  262. this.getShopInfo();
  263. this.getVoucher();
  264. } else {
  265. uni.$u.toast("获取微信登录信息失败,请重新登录!");
  266. }
  267. });
  268. },
  269. async getShopInfo() {
  270. api
  271. .getStoreInfoByScan({
  272. shopId: this.shopId,
  273. })
  274. .then((res) => {
  275. if (res.code == 200) {
  276. this.shopInfo = res.data;
  277. } else {
  278. uni.$u.toast(res.msg);
  279. }
  280. });
  281. },
  282. async Pay() {
  283. uni.showLoading({
  284. title: "支付中",
  285. });
  286. console.log(this.price);
  287. if (!this.price) {
  288. uni.$u.toast("请输入支付金额!");
  289. return
  290. }
  291. api
  292. .payOrder({
  293. shopType: this.shopInfo.shopType,
  294. shopUserId: this.shopInfo.shopUserId,
  295. shopId: this.shopInfo.shopId,
  296. payAmount: Number(this.payment) || Number(this.price),
  297. payWay: 6,
  298. // userId: this.localUserInfo.userId
  299. })
  300. .then((res) => {
  301. if (res.code == 200) {
  302. WeixinJSBridge.invoke(
  303. "getBrandWCPayRequest",
  304. {
  305. // 公众号名称,由商户传入
  306. appId: res.data.appId,
  307. // 时间戳,自1970年以来的秒数
  308. timeStamp: res.data.timeStamp,
  309. // 随机串
  310. nonceStr: res.data.nonceStr,
  311. package: res.data.package,
  312. // 微信签名方式:
  313. signType: res.data.signType,
  314. // 微信签名
  315. paySign: res.data.paySign,
  316. },
  317. function (res) {
  318. if (res.err_msg == "get_brand_wcpay_request:ok") {
  319. uni.hideLoading();
  320. uni.navigateTo({
  321. url: `/pages/index/paySuccess`,
  322. });
  323. } else {
  324. uni.hideLoading();
  325. uni.$u.toast("支付失败!");
  326. }
  327. },
  328. );
  329. } else {
  330. uni.$u.toast(res.msg);
  331. }
  332. }).catch((err) => {
  333. uni.hideLoading();
  334. let msg = err.msg || "";
  335. let errStr = msg.match(/[\u4e00-\u9fa5\/]+/)?.[0] || "支付失败";
  336. uni.$u.toast(errStr);
  337. });
  338. },
  339. GetQueryString(name) {
  340. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  341. var r = window.location.search.substr(1).match(reg);
  342. if (r != null) return unescape(r[2]);
  343. return null;
  344. },
  345. },
  346. };
  347. </script>
  348. <style lang="scss">
  349. .coupon-popup {
  350. padding: 30rpx;
  351. height: 1000rpx;
  352. box-sizing: border-box;
  353. }
  354. .popup-header {
  355. display: flex;
  356. justify-content: space-between;
  357. align-items: center;
  358. font-size: 32rpx;
  359. font-weight: bold;
  360. margin-bottom: 30rpx;
  361. }
  362. .coupon-list {
  363. height: calc(100% - 100rpx);
  364. overflow-y: auto;
  365. }
  366. .coupon-item {
  367. background: #fff;
  368. border-radius: 16rpx;
  369. padding: 24rpx;
  370. margin-bottom: 20rpx;
  371. display: flex;
  372. justify-content: space-between;
  373. align-items: center;
  374. border: 2rpx solid #eee;
  375. }
  376. .coupon-item.active {
  377. // border-color: #ff4d4f;
  378. background: #fffbf4;
  379. }
  380. .coupon-item.disabled {
  381. opacity: 0.5;
  382. }
  383. .left {
  384. flex: 1;
  385. }
  386. .tag {
  387. font-size: 22rpx;
  388. color: #fff;
  389. padding: 4rpx 12rpx;
  390. border-radius: 6rpx;
  391. margin-bottom: 12rpx;
  392. }
  393. .independent {
  394. width: 70rpx;
  395. background: #5c8dff;
  396. }
  397. .chain {
  398. width: 70rpx;
  399. background: #ff7d00;
  400. }
  401. .price {
  402. display: flex;
  403. align-items: baseline;
  404. margin-bottom: 12rpx;
  405. }
  406. .yen {
  407. font-size: 28rpx;
  408. color: #ff4d4f;
  409. }
  410. .num {
  411. font-size: 44rpx;
  412. font-weight: bold;
  413. color: #ff4d4f;
  414. margin: 0 10rpx;
  415. }
  416. .tip {
  417. font-size: 24rpx;
  418. color: #999;
  419. }
  420. .info {
  421. font-size: 24rpx;
  422. color: #999;
  423. line-height: 1.6;
  424. }
  425. .right {
  426. padding-left: 20rpx;
  427. }
  428. ::v-deep .u-cell__title {
  429. flex: none !important;
  430. }
  431. .main {
  432. width: 100%;
  433. background: white;
  434. height: calc(100% - 280rpx);
  435. border-radius: 40rpx;
  436. }
  437. .shopName {
  438. font-weight: bold;
  439. font-size: 36rpx;
  440. color: #333333;
  441. }
  442. /* 修改加载提示框的遮罩层 z-index */
  443. .uni-loading__mask {
  444. z-index: 10076;
  445. }
  446. /* 修改加载提示框本身的 z-index */
  447. .uni-loading {
  448. z-index: 10076;
  449. }
  450. .yzm {
  451. font-weight: 500;
  452. font-size: 28rpx;
  453. color: #00d36d;
  454. }
  455. .popup {
  456. height: 300px;
  457. padding: 20px;
  458. .footer {
  459. margin-top: 150rpx;
  460. .btn {
  461. width: 100%;
  462. background: linear-gradient(152deg, #6f9dfd 0%, #1b71f2 100%);
  463. border-radius: 46rpx;
  464. border: none;
  465. }
  466. }
  467. .main {
  468. margin-top: 20rpx;
  469. }
  470. .header {
  471. margin-bottom: 20rpx;
  472. text-align: center;
  473. .tip {
  474. margin-top: 20rpx;
  475. font-weight: 500;
  476. font-size: 26rpx;
  477. color: #ff8b2f;
  478. }
  479. }
  480. }
  481. .u-radio-group--row {
  482. justify-content: center;
  483. }
  484. .radioText {
  485. font-weight: 500;
  486. font-size: 24rpx;
  487. color: #999999;
  488. line-height: 34rpx;
  489. text-align: left;
  490. font-style: normal;
  491. }
  492. .login-main {
  493. background: url("../../static/images/payBack.png");
  494. background-size: 100% 100%;
  495. width: 100%;
  496. display: flex;
  497. flex-direction: column;
  498. /* justify-content: space-between; */
  499. align-items: center;
  500. height: 100vh;
  501. }
  502. .login-contont-button {
  503. text-align: center;
  504. .btn {
  505. margin-top: 20px;
  506. width: 95%;
  507. height: 90rpx;
  508. background: linear-gradient(152deg, #6f9dfd 0%, #1b71f2 100%);
  509. border-radius: 44rpx;
  510. color: #fff;
  511. }
  512. }
  513. .login-contont {
  514. width: 100%;
  515. height: 600rpx;
  516. margin-top: 100rpx;
  517. .uInput {
  518. padding: 10px 0px;
  519. border-bottom: 0.5px solid #97979740;
  520. }
  521. .login-contont-info {
  522. text-align: center;
  523. .text {
  524. margin-top: 10px;
  525. font-weight: 500;
  526. font-size: 28rpx;
  527. color: #999999;
  528. line-height: 40rpx;
  529. font-style: normal;
  530. }
  531. }
  532. }
  533. .radio {
  534. text-align: center;
  535. margin-top: 10px;
  536. }
  537. .login-main-content {
  538. display: flex;
  539. flex-direction: row;
  540. align-items: center;
  541. padding: 9px 26px;
  542. .img {
  543. // margin-top: 70px;
  544. margin-right: 20rpx;
  545. width: 62rpx;
  546. height: 62rpx;
  547. border-radius: 50%;
  548. }
  549. }
  550. </style>