pay.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. <template>
  2. <view class="food-pay">
  3. <view class="content shop-box">
  4. <view class="shop-name">
  5. {{shopName}}
  6. </view>
  7. <view class="address">
  8. {{address}}
  9. </view>
  10. </view>
  11. <view class="content goods-box">
  12. <view class="title">
  13. 订单信息
  14. </view>
  15. <view class="goods-item" v-for="(item,index) in createQuery.products" :key="index">
  16. <view class="left">
  17. <image class="icon" :src="item.imageUrl" mode=""></image>
  18. <view class="name">
  19. {{item.nameCn}}
  20. </view>
  21. <view class="num">
  22. x{{item.quantity}}
  23. </view>
  24. </view>
  25. <view class="right">
  26. ¥{{item.selPrice}}
  27. </view>
  28. </view>
  29. <view class="total-box">
  30. <view class="num">
  31. 共{{createQuery.products.length}}件
  32. </view>
  33. <view class="price">
  34. 小计¥{{total}}
  35. </view>
  36. </view>
  37. </view>
  38. <view class="content">
  39. <view class="item">
  40. <view class="label">
  41. 联系号码
  42. </view>
  43. <input class="value input" :maxlength="11" type="text" placeholder="请填写手机号" v-model="createQuery.phone" />
  44. </view>
  45. </view>
  46. <view class="content">
  47. <view class="item">
  48. <view class="label">
  49. 备注
  50. </view>
  51. <input class="value input" type="text" placeholder="请填写备注" v-model="createQuery.remark" />
  52. </view>
  53. </view>
  54. <view class="type-box content">
  55. <view class="title">
  56. 就餐方式
  57. </view>
  58. <view class="type-btn-box">
  59. <view class="btn" :class="[createQuery.eatType == 0?'active':'']" @click="handleType(0)">
  60. 店内就餐
  61. </view>
  62. <view class="btn" :class="[createQuery.eatType == 1?'active':'']" @click="handleType(1)">
  63. 打包带走
  64. </view>
  65. </view>
  66. </view>
  67. <view class="notice-box content">
  68. <view class="title">
  69. 温馨提示
  70. </view>
  71. <view class="notice">
  72. 1.付款成功后1-10分钟为您出餐
  73. </view>
  74. <view class="notice">
  75. 2.此订单为特价产品,付款成功后将无法退款。请确认后购买
  76. </view>
  77. <view class="notice">
  78. 3.由于门店餐品库存不稳定等因素,存在少量出餐失败的情况,
  79. 会进行退款
  80. </view>
  81. <view class="notice">
  82. 4.出餐失败,3个工作日内自动退款到您微信钱包
  83. </view>
  84. </view>
  85. <view class="btn-box">
  86. <view class="left">
  87. <view class="total">
  88. 合计 <view class="price-box">
  89. <view class="unit">
  90. </view>
  91. <view class="price">
  92. {{total}}
  93. </view>
  94. </view>
  95. </view>
  96. </view>
  97. <button class="btn" @click="handleBuy" :loading="loading">
  98. 去支付
  99. </button>
  100. </view>
  101. </view>
  102. </template>
  103. <script>
  104. import {createOrder} from '@/api/orderFood.js';
  105. import {
  106. creatPayOrder,
  107. queryPayOrder,
  108. payDetails
  109. } from '@/api/payment.js'
  110. export default {
  111. data() {
  112. return {
  113. active:0,
  114. loading:false,
  115. shopName:'',
  116. address:'',
  117. total:0,
  118. createQuery:{
  119. ot:'Kfc',
  120. "channel": "ZhongShu",
  121. "cityId": 0,
  122. "eatType": 0,
  123. "entPara": "",
  124. "goodsName": "",
  125. "imageCnUrl": "",
  126. "mealTime": 0,
  127. "phone": JSON.parse(uni.getStorageSync('userInfo')).phoneNum,
  128. "products": [
  129. {
  130. "imageUrl": "",
  131. "nameCn": "",
  132. "pid": "",
  133. "productId": "",
  134. "quantity": 0,
  135. "selPrice": 0,
  136. }
  137. ],
  138. // "recAddr": {
  139. // "addr": "",
  140. // "contact": "",
  141. // "createTime": "",
  142. // "gender": "",
  143. // "id": "",
  144. // "lat": 0,
  145. // "lon": 0,
  146. // "number": "",
  147. // "phone": "",
  148. // "userId": ""
  149. // },
  150. "remark": "",
  151. "shopId": "",
  152. "shopName": "",
  153. "tableWare": true
  154. },
  155. query: {
  156. "msgType": "wx.unifiedOrder",
  157. "orderDesc": "测试",
  158. "orderNo": "",
  159. "channel":'ZhongShu',
  160. "subOpenId": "",
  161. "userId": ""
  162. },
  163. }
  164. },
  165. methods: {
  166. handleType(val){
  167. this.createQuery.eatType = val
  168. },
  169. handleBuy(){
  170. if (this.loading) return
  171. this.loading = true
  172. uni.showLoading({
  173. title: '支付中'
  174. })
  175. let that = this
  176. createOrder(this.createQuery).then(res => {
  177. this.loading = false
  178. if (res.state == 'Success') {
  179. this.query.orderNo = res.content.orderNo
  180. this.query.subOpenId = JSON.parse(uni.getStorageSync('userInfo')).openId
  181. this.query.orderDesc = '点餐'
  182. creatPayOrder(this.query).then(data => {
  183. that.payData = JSON.parse(data.content.miniPayRequest)
  184. if (data.content.miniPayRequest == null) return uni.hideLoading()
  185. uni.requestPayment({
  186. "provider": "wxpay",
  187. "orderInfo": that.payData,
  188. "appid": that.payData
  189. .appId, // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
  190. "paySign": that.payData.paySign,
  191. "nonceStr": that.payData.nonceStr, // 随机字符串
  192. "package": that.payData.package, // 固定值
  193. // "prepayid": that.payData.package, // 统一下单订单号
  194. "timeStamp": that.payData.timeStamp, // 时间戳(单位:秒)
  195. "signType": that.payData.signType, //签名算法
  196. success(msg) {
  197. console.log('msg', msg, res);
  198. queryPayOrder(that.query.orderNo).then(res1 => {
  199. if (res1.state == 'Success') {
  200. uni.hideLoading()
  201. uni.reLaunch({
  202. url: '/my/order/index'
  203. })
  204. }
  205. })
  206. },
  207. fail(e) {
  208. console.log('err', e);
  209. that.loading = false
  210. uni.hideLoading()
  211. uni.showToast({
  212. title: '取消支付',
  213. icon: 'fail'
  214. })
  215. // 取消支付后
  216. uni.reLaunch({
  217. url:'/my/order/foodOrder/detail?id='+that.query.orderNo
  218. })
  219. }
  220. })
  221. })
  222. // }
  223. }
  224. })
  225. }
  226. },
  227. onLoad() {
  228. let userInfo = JSON.parse(uni.getStorageSync('userInfo'))
  229. this.query.userId = userInfo.userId
  230. let that = this
  231. const eventChannel = this.getOpenerEventChannel();
  232. eventChannel.on('pay', function(data) {
  233. that.createQuery.products = data.products
  234. that.createQuery.shopId = data.shopId
  235. that.createQuery.goodsName = data.products[0].nameCn
  236. that.createQuery.imageCnUrl = data.products[0].imageCnUrl
  237. that.shopName = data.shopName
  238. that.createQuery.shopName = data.shopName
  239. that.address = data.address
  240. that.total = data.total
  241. console.log('data', data);
  242. })
  243. }
  244. }
  245. </script>
  246. <style lang="scss" scoped>
  247. .food-pay{
  248. background: #F9F9F9;
  249. min-height: 100vh;
  250. padding: 20rpx 24rpx;
  251. .content{
  252. margin-bottom: 20rpx;
  253. padding: 24rpx;
  254. border-radius: 16rpx;
  255. background: #fff;
  256. .title{
  257. font-weight: 600;
  258. font-size: 28rpx;
  259. color: #222222;
  260. }
  261. .item{
  262. display: flex;
  263. align-items: center;
  264. justify-content: space-between;
  265. .label{
  266. font-size: 24rpx;
  267. color: #AAAAAA;
  268. }
  269. .value{
  270. font-size: 24rpx;
  271. color: #222222;
  272. }
  273. .input{
  274. text-align: right;
  275. }
  276. }
  277. }
  278. .shop-box{
  279. // margin: 0 30rpx;
  280. // padding: 24rpx 24rpx 30rpx;
  281. background: #fff;
  282. border-radius: 16rpx;
  283. box-sizing: border-box;
  284. .shop-name{
  285. font-weight: 600;
  286. font-size: 32rpx;
  287. color: #181818;
  288. width: 100%;
  289. white-space: nowrap;
  290. overflow: hidden;
  291. text-overflow: ellipsis;
  292. }
  293. .address{
  294. font-weight: 300;
  295. font-size: 24rpx;
  296. color: #AAAAAA;
  297. margin-top: 20rpx;
  298. width: 100%;
  299. white-space: nowrap;
  300. overflow: hidden;
  301. text-overflow: ellipsis;
  302. }
  303. }
  304. .goods-box{
  305. .goods-item{
  306. display: flex;
  307. align-items: center;
  308. justify-content: space-between;
  309. padding: 12rpx 0;
  310. .left{
  311. display: flex;
  312. align-items: center;
  313. .icon{
  314. width: 80rpx;
  315. height: 80rpx;
  316. border-radius: 16rpx 16rpx 16rpx 16rpx;
  317. }
  318. .name{
  319. font-size: 28rpx;
  320. color: #222222;
  321. margin-left: 20rpx;
  322. max-width: 400rpx;
  323. white-space: nowrap;
  324. overflow: hidden;
  325. text-overflow: ellipsis;
  326. }
  327. .num{
  328. font-size: 24rpx;
  329. color: #AAAAAA;
  330. margin-left: 20rpx;
  331. }
  332. }
  333. .right{
  334. font-size: 28rpx;
  335. color: #222222;
  336. }
  337. }
  338. .total-box{
  339. display: flex;
  340. align-items: center;
  341. justify-content: flex-end;
  342. font-size: 28rpx;
  343. color: #222222;
  344. padding-top: 24rpx;
  345. border-top: 1rpx solid #F0F0F0;
  346. .num{
  347. }
  348. .price{
  349. margin-left: 20rpx;
  350. }
  351. }
  352. }
  353. .type-box{
  354. .type-btn-box{
  355. display: flex;
  356. align-items: center;
  357. justify-content: space-between;
  358. margin-top: 20rpx;
  359. .btn{
  360. width: 316rpx;
  361. height: 80rpx;
  362. line-height: 80rpx;
  363. text-align: center;
  364. background: #F6F6F6;
  365. border-radius: 40rpx 40rpx 40rpx 40rpx;
  366. font-weight: bold;
  367. font-size: 28rpx;
  368. color: #AAAAAA;
  369. }
  370. .btn.active{
  371. background: rgba(238,67,32,0.1);
  372. color: #EE4320;
  373. }
  374. }
  375. }
  376. .notice-box{
  377. .notice{
  378. font-size: 24rpx;
  379. color: #AAAAAA;
  380. margin-top: 20rpx;
  381. }
  382. }
  383. .btn-box {
  384. position: fixed;
  385. bottom: 0%;
  386. left: 0%;
  387. z-index: 2;
  388. width: 100%;
  389. display: flex;
  390. align-items: center;
  391. justify-content: space-between;
  392. box-sizing: border-box;
  393. padding: 10rpx 24rpx env(safe-area-inset-bottom);
  394. background: #fff;
  395. border-top: 1rpx solid #EEEEEE;
  396. .left{
  397. display: flex;
  398. align-items: flex-end;
  399. .total{
  400. font-weight: 300;
  401. font-size: 24rpx;
  402. color: #222222;
  403. display: flex;
  404. align-items: flex-end;
  405. margin-left: 6rpx;
  406. .price-box{
  407. display: flex;
  408. align-items: flex-end;
  409. font-weight: 400;
  410. font-size: 32rpx;
  411. color: #FF4D3A;
  412. .unit{
  413. font-size: 20rpx;
  414. }
  415. .price{
  416. font-weight: bold;
  417. }
  418. }
  419. }
  420. }
  421. .btn {
  422. width: 280rpx;
  423. height: 80rpx;
  424. line-height: 80rpx;
  425. text-align: center;
  426. background: $uni-color-primary;
  427. border-radius: 40rpx;
  428. font-weight: 600;
  429. font-size: 28rpx;
  430. color: #FFFFFF;
  431. margin: 0;
  432. }
  433. }
  434. }
  435. </style>