pay.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  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" @click="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 @click="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" @click="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" @click="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. })
  253. .then((res) => {
  254. if (res.code == 200) {
  255. this.userInfo = res.data;
  256. localStorage.setItem("token", this.userInfo.access_token);
  257. localStorage.setItem(
  258. "weChatUserInfo",
  259. JSON.stringify(this.userInfo),
  260. );
  261. this.getShopInfo();
  262. this.getVoucher();
  263. } else {
  264. uni.$u.toast("获取微信登录信息失败,请重新登录!");
  265. }
  266. });
  267. },
  268. async getShopInfo() {
  269. api
  270. .getStoreInfoByScan({
  271. shopId: this.shopId,
  272. })
  273. .then((res) => {
  274. if (res.code == 200) {
  275. this.shopInfo = res.data;
  276. } else {
  277. uni.$u.toast(res.msg);
  278. }
  279. });
  280. },
  281. async Pay() {
  282. uni.showLoading({
  283. title: "支付中",
  284. });
  285. console.log(this.price);
  286. if (!this.price) {
  287. uni.$u.toast("请输入支付金额!");
  288. return
  289. }
  290. api
  291. .payOrder({
  292. shopType: this.shopInfo.shopType,
  293. shopUserId: this.shopInfo.shopUserId,
  294. shopId: this.shopInfo.shopId,
  295. payAmount: Number(this.payment) || Number(this.price),
  296. payWay: 6,
  297. // userId: this.localUserInfo.userId
  298. })
  299. .then((res) => {
  300. if (res.code == 200) {
  301. WeixinJSBridge.invoke(
  302. "getBrandWCPayRequest",
  303. {
  304. // 公众号名称,由商户传入
  305. appId: res.data.appId,
  306. // 时间戳,自1970年以来的秒数
  307. timeStamp: res.data.timeStamp,
  308. // 随机串
  309. nonceStr: res.data.nonceStr,
  310. package: res.data.package,
  311. // 微信签名方式:
  312. signType: res.data.signType,
  313. // 微信签名
  314. paySign: res.data.paySign,
  315. },
  316. function (res) {
  317. if (res.err_msg == "get_brand_wcpay_request:ok") {
  318. uni.hideLoading();
  319. uni.navigateTo({
  320. url: `/pages/index/paySuccess`,
  321. });
  322. } else {
  323. uni.hideLoading();
  324. uni.$u.toast("支付失败!");
  325. }
  326. },
  327. );
  328. } else {
  329. uni.$u.toast(res.msg);
  330. }
  331. }).catch((err) => {
  332. uni.hideLoading();
  333. let msg = err.msg || "";
  334. let errStr = msg.match(/[\u4e00-\u9fa5\/]+/)?.[0] || "支付失败";
  335. uni.$u.toast(errStr);
  336. });
  337. },
  338. GetQueryString(name) {
  339. var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
  340. var r = window.location.search.substr(1).match(reg);
  341. if (r != null) return unescape(r[2]);
  342. return null;
  343. },
  344. },
  345. };
  346. </script>
  347. <style lang="scss">
  348. .coupon-popup {
  349. padding: 30rpx;
  350. height: 1000rpx;
  351. box-sizing: border-box;
  352. }
  353. .popup-header {
  354. display: flex;
  355. justify-content: space-between;
  356. align-items: center;
  357. font-size: 32rpx;
  358. font-weight: bold;
  359. margin-bottom: 30rpx;
  360. }
  361. .coupon-list {
  362. height: calc(100% - 100rpx);
  363. overflow-y: auto;
  364. }
  365. .coupon-item {
  366. background: #fff;
  367. border-radius: 16rpx;
  368. padding: 24rpx;
  369. margin-bottom: 20rpx;
  370. display: flex;
  371. justify-content: space-between;
  372. align-items: center;
  373. border: 2rpx solid #eee;
  374. }
  375. .coupon-item.active {
  376. // border-color: #ff4d4f;
  377. background: #fffbf4;
  378. }
  379. .coupon-item.disabled {
  380. opacity: 0.5;
  381. }
  382. .left {
  383. flex: 1;
  384. }
  385. .tag {
  386. font-size: 22rpx;
  387. color: #fff;
  388. padding: 4rpx 12rpx;
  389. border-radius: 6rpx;
  390. margin-bottom: 12rpx;
  391. }
  392. .independent {
  393. width: 70rpx;
  394. background: #5c8dff;
  395. }
  396. .chain {
  397. width: 70rpx;
  398. background: #ff7d00;
  399. }
  400. .price {
  401. display: flex;
  402. align-items: baseline;
  403. margin-bottom: 12rpx;
  404. }
  405. .yen {
  406. font-size: 28rpx;
  407. color: #ff4d4f;
  408. }
  409. .num {
  410. font-size: 44rpx;
  411. font-weight: bold;
  412. color: #ff4d4f;
  413. margin: 0 10rpx;
  414. }
  415. .tip {
  416. font-size: 24rpx;
  417. color: #999;
  418. }
  419. .info {
  420. font-size: 24rpx;
  421. color: #999;
  422. line-height: 1.6;
  423. }
  424. .right {
  425. padding-left: 20rpx;
  426. }
  427. ::v-deep .u-cell__title {
  428. flex: none !important;
  429. }
  430. .main {
  431. width: 100%;
  432. background: white;
  433. height: calc(100% - 280rpx);
  434. border-radius: 40rpx;
  435. }
  436. .shopName {
  437. font-weight: bold;
  438. font-size: 36rpx;
  439. color: #333333;
  440. }
  441. /* 修改加载提示框的遮罩层 z-index */
  442. .uni-loading__mask {
  443. z-index: 10076;
  444. }
  445. /* 修改加载提示框本身的 z-index */
  446. .uni-loading {
  447. z-index: 10076;
  448. }
  449. .yzm {
  450. font-weight: 500;
  451. font-size: 28rpx;
  452. color: #00d36d;
  453. }
  454. .popup {
  455. height: 300px;
  456. padding: 20px;
  457. .footer {
  458. margin-top: 150rpx;
  459. .btn {
  460. width: 100%;
  461. background: linear-gradient(152deg, #6f9dfd 0%, #1b71f2 100%);
  462. border-radius: 46rpx;
  463. border: none;
  464. }
  465. }
  466. .main {
  467. margin-top: 20rpx;
  468. }
  469. .header {
  470. margin-bottom: 20rpx;
  471. text-align: center;
  472. .tip {
  473. margin-top: 20rpx;
  474. font-weight: 500;
  475. font-size: 26rpx;
  476. color: #ff8b2f;
  477. }
  478. }
  479. }
  480. .u-radio-group--row {
  481. justify-content: center;
  482. }
  483. .radioText {
  484. font-weight: 500;
  485. font-size: 24rpx;
  486. color: #999999;
  487. line-height: 34rpx;
  488. text-align: left;
  489. font-style: normal;
  490. }
  491. .login-main {
  492. background: url("../../static/images/payBack.png");
  493. background-size: 100% 100%;
  494. width: 100%;
  495. display: flex;
  496. flex-direction: column;
  497. /* justify-content: space-between; */
  498. align-items: center;
  499. height: 100vh;
  500. }
  501. .login-contont-button {
  502. text-align: center;
  503. .btn {
  504. margin-top: 20px;
  505. width: 95%;
  506. height: 90rpx;
  507. background: linear-gradient(152deg, #6f9dfd 0%, #1b71f2 100%);
  508. border-radius: 44rpx;
  509. color: #fff;
  510. }
  511. }
  512. .login-contont {
  513. width: 100%;
  514. height: 600rpx;
  515. margin-top: 100rpx;
  516. .uInput {
  517. padding: 10px 0px;
  518. border-bottom: 0.5px solid #97979740;
  519. }
  520. .login-contont-info {
  521. text-align: center;
  522. .text {
  523. margin-top: 10px;
  524. font-weight: 500;
  525. font-size: 28rpx;
  526. color: #999999;
  527. line-height: 40rpx;
  528. font-style: normal;
  529. }
  530. }
  531. }
  532. .radio {
  533. text-align: center;
  534. margin-top: 10px;
  535. }
  536. .login-main-content {
  537. display: flex;
  538. flex-direction: row;
  539. align-items: center;
  540. padding: 9px 26px;
  541. .img {
  542. // margin-top: 70px;
  543. margin-right: 20rpx;
  544. width: 44rpx;
  545. height: 44rpx;
  546. border-radius: 50%;
  547. }
  548. }
  549. </style>