1
0

index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. <template>
  2. <app-layout>
  3. <view>
  4. <view class="scan-head dir-top-nowrap main-center">
  5. <view class="order-name">订单金额</view>
  6. <view class="scan-price dir-left-nowrap cross-bottom" @click="openPriceModel">
  7. <view class="order-key">¥</view>
  8. <view class="order-value">{{list.price}}</view>
  9. </view>
  10. <view class="scan-line"></view>
  11. <!-- 优惠 -->
  12. <view class="dir-left-nowrap cross-center scan-offer">
  13. <view class="box-grow-1">订单优惠</view>
  14. <view class="box-grow-0">
  15. <view v-if="list.preferential_money > 0" class="red">
  16. -¥{{list.preferential_money}}
  17. </view>
  18. <view v-else-if="list.price > 0" class="gray">暂无优惠</view>
  19. </view>
  20. </view>
  21. <!-- 优惠券 -->
  22. <view class="dir-left-nowrap cross-center scan-offer">
  23. <view class="box-grow-1">优惠劵</view>
  24. <view class="box-grow-0 coupon-right">
  25. <view v-if="list.coupon_id" @click="setCoupon" class="red">
  26. -¥{{list.coupon_preferential_money}}
  27. </view>
  28. <view v-else-if="list.price > 0 && list.can_coupon_num > 0" class="gray"
  29. @click="setCoupon">选择优惠券
  30. </view>
  31. <view v-else-if="list.price > 0" class="gray">暂无可用优惠券</view>
  32. </view>
  33. <view class="box-grow-0 cross-center">
  34. <icon class="icon-right"></icon>
  35. </view>
  36. </view>
  37. <!-- 积分抵扣 -->
  38. <view v-if="list.price > 0 && activity && integral.user_integral_num >= integral.member_integral && list.integral_deduction > 0"
  39. class="dir-left-nowrap cross-center scan-offer">
  40. <view class="box-grow-1 cross-center dir-left-nowrap">
  41. <view>
  42. <text>使用{{list.use_integral_num}}积分抵扣</text>
  43. <text class="red">{{list.integral_deduction}}</text>
  44. <text>元</text>
  45. </view>
  46. <view @click="getIntegralInfo" class="main-center cross-center">
  47. <icon class="scan-integral-icon"></icon>
  48. </view>
  49. </view>
  50. <view class="box-grow-0" @click="handleUseIntegral">
  51. <icon v-if="list.use_integral == 1" class="scan-integral-switch check"></icon>
  52. <icon v-else class="scan-integral-switch uncheck"></icon>
  53. </view>
  54. </view>
  55. <!-- 备注 -->
  56. <view class="dir-left-nowrap scan-offer">
  57. <input @input="bindTextBlur" :value="remark" class="scan-input" placeholder="添加备注"/>
  58. </view>
  59. <view class="scan-line"></view>
  60. <view class="scan-remark cross-center dir-left-nowrap main-center">
  61. <view class="key">应付金额</view>
  62. <view class="value">¥{{list.pay_price}}</view>
  63. </view>
  64. </view>
  65. <view class="main-center cross-center scan-btn">
  66. <app-button @click="submit"
  67. color="#ffffff"
  68. font-size="32"
  69. height="88"
  70. width="702"
  71. :background="list.price > 0 ? '#ff4544': '#cdcdcd'"
  72. :disabled="list.price <= 0"
  73. round>已与店员确认,立即买单
  74. </app-button>
  75. </view>
  76. <view class="scan-end" v-if="activity.rules">
  77. <view class="dir-left-nowrap cross-center">
  78. <view class="icon"></view>
  79. <view>规则说明</view>
  80. </view>
  81. <text space="nbsp">{{activity.rules}}</text>
  82. </view>
  83. </view>
  84. <!-- MODEL -->
  85. <view v-if="price_modal" class="scan-modal show bt">
  86. <view class="scan-modal-bg"></view>
  87. <view class="scan-modal-pic main-center">
  88. <view class="info-model cross-center dir-top-nowrap">
  89. <view class="order-title">订单金额</view>
  90. <view class="info-box dir-left-nowrap cross-center">
  91. <input focus class="info-input" @input="setTempInput" :value="tmp_price" type="digit"
  92. placeholder-class="place" placeholder="输入支付金额"/>
  93. <view>元</view>
  94. </view>
  95. <view class="info-end dir-left-nowrap cross-center">
  96. <view @click="closePriceModel" class="box-grow-1 main-center cross-center">取消</view>
  97. <view class="box-grow-0 info-line"></view>
  98. <view @click="calcPrice" class="box-grow-1 red main-center cross-center">确认</view>
  99. </view>
  100. </view>
  101. </view>
  102. </view>
  103. </app-layout>
  104. </template>
  105. <script>
  106. export default {
  107. name: "index",
  108. components: {},
  109. data() {
  110. return {
  111. page_loading: true,
  112. tmp_price: '',
  113. edit_status: true,
  114. price_modal: false,
  115. activity: null,
  116. remark: '',
  117. integral: {
  118. user_integral_num: '0',
  119. },
  120. list: {
  121. price: '',
  122. pay_price: 0.00,
  123. use_integral: 0,
  124. activity_id: 0,
  125. coupon_id: 0,
  126. can_coupon_num: 0,
  127. integral_explain: [],
  128. },
  129. clear: false,
  130. }
  131. },
  132. onShow: function () {
  133. const self = this;
  134. const userCoupon = self.$store.state.scanCode.userCoupon;
  135. if (userCoupon) {
  136. if (userCoupon == -1) {
  137. self.list.coupon_id = 0
  138. } else {
  139. self.list.coupon_id = userCoupon.id;
  140. }
  141. self.calcPrice();
  142. } else {
  143. self.list.coupon_id = 0
  144. }
  145. if (self.clear) {
  146. [
  147. self.edit_status,
  148. self.clear,
  149. self.remark,
  150. self.tmp_price,
  151. self.list,
  152. ] = [
  153. true,
  154. false,
  155. '',
  156. '',
  157. {
  158. price: '',
  159. pay_price: 0.00,
  160. use_integral: 0,
  161. activity_id: 0,
  162. coupon_id: 0,
  163. can_coupon_num: 0,
  164. integral_explain: [],
  165. }
  166. ]
  167. }
  168. },
  169. onLoad: function (options) {
  170. const self = this;
  171. self.$store.commit('scanCode/mutSetUserCoupon', 0);
  172. self.clear = true;
  173. if (options.price) {
  174. [self.edit_status, self.tmp_price] = [false, options.price];
  175. self.calcPrice();
  176. }
  177. self.$showLoading({text: '加载中'});
  178. self.$request({
  179. url: self.$api.scan_code_pay.index
  180. }).then(info => {
  181. self.$hideLoading();
  182. if (info.code === 0) {
  183. [
  184. self.activity,
  185. self.goods,
  186. self.integral,
  187. self.setting
  188. ] = [
  189. info.data.activity,
  190. info.data.goods,
  191. info.data.integral,
  192. info.data.setting
  193. ];
  194. }
  195. }).catch(info => {
  196. self.$hideLoading();
  197. })
  198. },
  199. methods: {
  200. openPriceModel() {
  201. if (!this.edit_status) return;
  202. this.price_modal = true;
  203. },
  204. closePriceModel() {
  205. this.price_modal = false;
  206. },
  207. setTempInput: function (e) {
  208. this.tmp_price = e.detail.value;
  209. },
  210. //总价
  211. calcPrice: function () {
  212. const self = this;
  213. self.price_modal = false;
  214. self.$showLoading({text: '加载中'});
  215. self.$request({
  216. url: self.$api.scan_code_pay.preview,
  217. data: {
  218. price: self.tmp_price,
  219. coupon_id: self.list.coupon_id,
  220. use_integral: self.list.use_integral,
  221. },
  222. method: 'POST',
  223. }).then(info => {
  224. self.$hideLoading();
  225. if (info.code === 0) {
  226. [self.list, self.tmp_price] = [info.data, info.data.price];
  227. } else {
  228. uni.showToast({icon: 'none', title: info.msg});
  229. }
  230. }).catch(info => {
  231. self.$hideLoading();
  232. })
  233. },
  234. //UseIntegral
  235. handleUseIntegral() {
  236. const self = this;
  237. let list = self.list;
  238. list.use_integral = list.use_integral == 1 ? 0 : 1;
  239. self.calcPrice();
  240. },
  241. //Remark
  242. bindTextBlur: function (e) {
  243. this.remark = e.detail.value;
  244. },
  245. //Integral
  246. getIntegralInfo: function (e) {
  247. let content = '';
  248. this.list.integral_explain.map(v => {
  249. content += '消费满' + v.consume_money + '元,';
  250. content += '积分最多可抵' + v.integral_deduction + '元';
  251. content += '\r\n';
  252. });
  253. uni.showModal({
  254. title: '积分抵扣说明',
  255. content: content.trim(),
  256. showCancel: false
  257. })
  258. },
  259. //navigate
  260. setCoupon: function (e) {
  261. this.clear = false;
  262. uni.navigateTo({
  263. url: '/plugins/scan_code/index/coupon?price=' + this.list.price + '&coupon_id=' + this.list.coupon_id,
  264. });
  265. },
  266. submit: function (e) {
  267. const self = this;
  268. if (!self.list.price) return
  269. self.$showLoading({text: '正在提交'});
  270. self.$request({
  271. url: self.$api.scan_code_pay.submit,
  272. method: 'post',
  273. data: {
  274. price: self.list.price,
  275. coupon_id: self.list.coupon_id,
  276. use_integral: self.list.use_integral,
  277. remark: self.remark,
  278. },
  279. }).then(e => {
  280. self.$hideLoading();
  281. if (e.code === 0) {
  282. self.$payment.pay(e.data.pay_id).then(payMsg => {
  283. self.$store.commit('scanCode/mutSetUserCoupon', '');
  284. // 支付成功
  285. uni.showModal({
  286. title: '提示',
  287. content: "支付成功",
  288. showCancel: false,
  289. success() {
  290. uni.navigateTo({
  291. url: '/pages/order-submit/pay-result?payment_order_union_id=' + e.data.pay_id + '&plugin=scan_code_pay'
  292. })
  293. self.clear = true;
  294. },
  295. });
  296. }).catch(payMsg => {
  297. // 支付失败
  298. self.$showLoading({text: '取消中'});
  299. self.$request({
  300. url: self.$api.scan_code_pay.cancel,
  301. data: {
  302. pay_id: e.data.pay_id,
  303. },
  304. method: 'POST',
  305. }).then(info => {
  306. self.$hideLoading();
  307. }).catch(info => {
  308. self.$hideLoading();
  309. uni.showModal({title: '提示', content: info.msg});
  310. })
  311. });
  312. } else {
  313. uni.showModal({title: '提示', content: info.msg});
  314. }
  315. }).catch(e => {
  316. self.$hideLoading();
  317. });
  318. },
  319. }
  320. }
  321. </script>
  322. <style scoped lang="scss">
  323. .red {
  324. color: #ff4544;
  325. }
  326. .gray {
  327. color: #999999;
  328. }
  329. .scan-head {
  330. margin: #{20rpx} #{24rpx} 0 #{24rpx};
  331. background: #fff;
  332. border-radius: #{16rpx};
  333. padding: #{48rpx} #{40rpx} 0 #{40rpx};
  334. font-size: #{28rpx};
  335. color: #353535;
  336. .scan-line {
  337. height: 1px;
  338. margin-top: #{38rpx};
  339. background: #e2e2e2;
  340. }
  341. .scan-price {
  342. margin-top: #{32rpx};
  343. .order-key {
  344. font-size: #{50rpx};
  345. }
  346. .order-value {
  347. font-size: #{80rpx};
  348. padding-left: #{28rpx};
  349. height: #{98rpx};
  350. }
  351. }
  352. }
  353. .scan-offer {
  354. color: #666666;
  355. font-size: #{28rpx};
  356. margin-top: #{40rpx};
  357. .coupon-right {
  358. padding-right: #{12rpx};
  359. }
  360. .icon-right {
  361. background-size: 100% auto;
  362. background-repeat: no-repeat;
  363. background-image: url("../../../static/image/icon/arrow-right.png");
  364. width: #{12rpx};
  365. height: #{22rpx};
  366. }
  367. }
  368. .scan-integral-icon {
  369. height: #{36rpx};
  370. width: #{36rpx};
  371. background-image: url("../../../static/image/icon/warning.png");
  372. background-repeat: no-repeat;
  373. background-size: 100% auto;
  374. margin-left: #{20rpx};
  375. }
  376. .scan-integral-switch {
  377. width: #{44rpx};
  378. height: #{44rpx};
  379. background-size: 100% auto;
  380. background-repeat: no-repeat;
  381. float: left;
  382. }
  383. .scan-integral-switch.check {
  384. margin-left: #{5rpx};
  385. background-image: url("../../../static/image/icon/icon-checkbox-checked-a.png");
  386. }
  387. .scan-integral-switch.uncheck {
  388. margin-left: #{5rpx};
  389. background-image: url("../../../static/image/icon/icon-uncheck.png");
  390. }
  391. .scan-input {
  392. width: 100%;
  393. font-size: #{28rpx};
  394. color: #666;
  395. }
  396. .scan-remark {
  397. height: #{106rpx};
  398. .key {
  399. margin-left: auto;
  400. color: #353535;
  401. font-size: #{28rpx};
  402. }
  403. .value {
  404. margin-left: #{10rpx};
  405. color: #ff4544;
  406. font-size: #{36rpx};
  407. }
  408. }
  409. .scan-end {
  410. color: #666;
  411. background: #fff;
  412. margin: 0 #{24rpx};
  413. font-size: #{28rpx};
  414. border-radius: #{16rpx};
  415. padding: #{40rpx};
  416. text {
  417. word-break: break-all;
  418. text-align: justify;
  419. }
  420. }
  421. .scan-end > view {
  422. margin-bottom: #{12rpx};
  423. }
  424. .scan-end .icon {
  425. height: #{26rpx};
  426. width: #{8rpx};
  427. border-radius: #{4rpx};
  428. background: #ff4544;
  429. margin-right: #{16rpx};
  430. }
  431. .scan-btn {
  432. margin: #{40rpx} auto;
  433. }
  434. .scan-modal {
  435. position: fixed;
  436. left: 0;
  437. top: 0;
  438. width: 100%;
  439. height: 100%;
  440. z-index: 2001;
  441. transition: 200ms;
  442. }
  443. .scan-modal.show {
  444. visibility: visible;
  445. opacity: 1;
  446. }
  447. .scan-modal.bt {
  448. -webkit-animation-name: fadeIn; /*动画名称*/
  449. -webkit-animation-duration: 0.25s; /*动画持续时间*/
  450. -webkit-animation-iteration-count: 1; /*动画次数*/
  451. -webkit-animation-delay: 0s; /*延迟时间*/
  452. }
  453. .scan-modal .scan-modal-bg {
  454. background: rgba(0, 0, 0, 0.8);
  455. position: fixed;
  456. left: 0;
  457. top: 0;
  458. width: 100%;
  459. height: 100%;
  460. z-index: 1;
  461. }
  462. .scan-modal .scan-modal-pic {
  463. position: fixed;
  464. left: 0;
  465. top: #{188rpx};
  466. width: 100%;
  467. height: 100%;
  468. z-index: 1;
  469. }
  470. .scan-modal .scan-modal-close image {
  471. width: #{50rpx};
  472. height: #{50rpx};
  473. margin-top: #{50rpx};
  474. }
  475. .scan-modal .info-model {
  476. height: #{360rpx};
  477. width: #{620rpx};
  478. background: #fff;
  479. border-radius: #{16rpx};
  480. }
  481. .scan-modal .order-title {
  482. margin: #{48rpx} 0
  483. }
  484. .scan-modal .place {
  485. color: #cdcdcd
  486. }
  487. .scan-modal .info-box {
  488. height: #{88rpx};
  489. width: #{400rpx};
  490. margin-bottom: #{48rpx};
  491. border-radius: #{8rpx};
  492. padding: 0 #{24rpx};
  493. border: 1px solid #e2e2e2;
  494. }
  495. .scan-modal .info-input {
  496. font-size: #{32rpx};
  497. color: #353535;
  498. }
  499. .scan-modal .info-line {
  500. height: #{32rpx} !important;
  501. width: 1px !important;
  502. background: #e2e2e2;
  503. }
  504. .scan-modal .info-end {
  505. color: #666666;
  506. height: #{88rpx};
  507. font-size: #{32rpx};
  508. border-top: #{1rpx} solid #e2e2e2;
  509. width: 100%;
  510. }
  511. .scan-modal .info-end view {
  512. height: 100%;
  513. width: 100%;
  514. }
  515. </style>