orderConfirm.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881
  1. <template>
  2. <view>
  3. <ujp-navbar title="确认订单"></ujp-navbar>
  4. <!-- 地址 -->
  5. <view class="address">
  6. <!-- 填写地址 -->
  7. <view class="fill-address" @click="showPopup">
  8. <view class="icon">
  9. <img src="@/assets/img/riFill-add-circle-fill@3x.png" alt="">
  10. </view>
  11. <view class="text">
  12. 填写收货地址
  13. <!-- https://blog.csdn.net/a472066275/article/details/103401969
  14. -->
  15. </view>
  16. <view class="right-icon">
  17. <u-icon name="arrow-right" color="#cccccc" size="24"></u-icon>
  18. </view>
  19. </view>
  20. <!-- 获取地址 -->
  21. <view class="get-address" v-if="false">
  22. <view class="icon">
  23. <img src="@/assets/img/riFill-wechat-fill@3x.png" alt="">
  24. </view>
  25. <view class="text">
  26. 一键获取微信地址
  27. </view>
  28. <view class="right-icon">
  29. <u-icon name="arrow-right" color="#cccccc" size="24"></u-icon>
  30. </view>
  31. </view>
  32. </view>
  33. <!-- 已填写 -->
  34. <view class="filled" @click="showPopup">
  35. <view class="filled-address">
  36. <view class="address1" v-if="false">
  37. 湖北省荆州市沙市区朝阳街道
  38. </view>
  39. <view class="address2">
  40. {{deliveryAddress?deliveryAddress:'未填写详细地址'}}
  41. </view>
  42. <view class="infos">
  43. <view class="name">
  44. {{receiver?receiver:'未填写收货人姓名'}}
  45. </view>
  46. <view class="tel">
  47. {{contactPhone?contactPhone:'未填写收货人手机号'}}
  48. </view>
  49. </view>
  50. </view>
  51. <view class="icon">
  52. <u-icon name="arrow-right" color="#cccccc" size="24"></u-icon>
  53. </view>
  54. </view>
  55. <!-- 商品信息 -->
  56. <view class="commodity-infos">
  57. <!-- 图片 -->
  58. <view class="picture">
  59. <img v-if="info.mallProduct.pic" :src="info.mallProduct.pic" alt="">
  60. <img v-else src="@/assets/img/chargesite_default.png" ></img>
  61. </view>
  62. <!-- 信息 -->
  63. <view class="infos">
  64. <view class="title">
  65. {{info.mallProduct.name}}
  66. </view>
  67. <view class="name">
  68. </view>
  69. <view class="price">
  70. {{info.mallProductPrice}}元
  71. </view>
  72. </view>
  73. <!-- 数量 -->
  74. <view class="amount">
  75. </view>
  76. </view>
  77. <!-- 订单金额 -->
  78. <view class="order-amount" v-if="priceAttrList.length">
  79. <view class="title">
  80. 选配
  81. </view>
  82. <view class="infos">
  83. <template v-for="(item,i) in priceAttrList" >
  84. <view class="infos-item" :key="i">
  85. <view class="item-title">
  86. {{item.attribute.name}}
  87. </view>
  88. <view class="item-value item-value-end">
  89. <view v-for="(option , oindex) in item.options" :key="i+'__'+oindex">
  90. {{option.label}} <span style="margin-left: 8px;" v-if="option.price">{{option.price}}元</span>
  91. </view>
  92. </view>
  93. </view>
  94. </template>
  95. </view>
  96. </view>
  97. <!-- 订单金额 -->
  98. <view class="order-amount">
  99. <view class="title">
  100. 订单金额
  101. </view>
  102. <view class="infos">
  103. <view class="item">
  104. <view class="item-title">
  105. 商品金额
  106. </view>
  107. <view class="item-value">
  108. {{info.mallProductPrice}}元
  109. </view>
  110. </view>
  111. <view class="item" v-if="false">
  112. <view class="item-title">
  113. 优惠金额
  114. </view>
  115. <view class="item-value">
  116. 0元
  117. </view>
  118. </view>
  119. <view class="item">
  120. <view class="item-title">
  121. 运费
  122. </view>
  123. <view class="item-value">
  124. 包邮
  125. </view>
  126. </view>
  127. <view class="item">
  128. <view class="item-title">
  129. 合计
  130. </view>
  131. <view class="item-value">
  132. {{mallProductOrder.price}}元
  133. </view>
  134. </view>
  135. </view>
  136. </view>
  137. <!-- 支付方式 -->
  138. <view class="payment">
  139. <view class="title">
  140. 支付方式
  141. </view>
  142. <radio-group @change="radioChange">
  143. <view class="way">
  144. <view class="way-name">
  145. <text><img src="@/assets/img/riFill-wechat-pay-fill@3x.png" alt=""></text>
  146. 微信支付
  147. </view>
  148. <view class="way-radio">
  149. <label class="radio">
  150. <radio value="0" name="abc" :checked="submitType === '0'" /><text></text>
  151. </label>
  152. </view>
  153. </view>
  154. <view class="way">
  155. <view class="way-name">
  156. <text><img src="@/assets/img/ze-alipay Copy@3x.png" alt=""></text>
  157. 支付宝
  158. </view>
  159. <view class="way-radio">
  160. <label class="radio">
  161. <radio value="1" name="abc" :checked="submitType === '1'" /><text></text>
  162. </label>
  163. </view>
  164. </view>
  165. </radio-group>
  166. </view>
  167. <!-- 底部 -->
  168. <view class="bottom">
  169. <view class="unpaid">
  170. 待支付: {{mallProductOrder.price}}元
  171. </view>
  172. <view class="btn" @click="submit">
  173. <button class="submit">
  174. 提交订单
  175. </button>
  176. </view>
  177. </view>
  178. <!-- 填写收货地址 -->
  179. <u-popup v-model="show" mode="center" :closeable="true">
  180. <view class="address-popup">
  181. <view class="headline">
  182. 填写收货地址
  183. </view>
  184. <view class="infos">
  185. <view class="item">
  186. <view class="item-title">
  187. 收货人
  188. </view>
  189. <view class="item-value" style="border-bottom: 1px solid #9E9E9E;">
  190. <input type="text" v-model="receiverTemp" placeholder="请输入收货人姓名">
  191. </view>
  192. </view>
  193. <view class="item">
  194. <view class="item-title">
  195. 手机号码
  196. </view>
  197. <view class="item-value" style="border-bottom: 1px solid #9E9E9E;">
  198. <input type="text" v-model="contactPhoneTemp" placeholder="请输入收货人手机号">
  199. </view>
  200. </view>
  201. <view class="item" v-if="false">
  202. <view class="item-title">
  203. 所在区域
  204. </view>
  205. <view class="item-value" style="border: 1px solid #9E9E9E;">
  206. <input type="text" placeholder="请选择省/市/区">
  207. </view>
  208. <view class="icon">
  209. <u-icon name="arrow-right" color="#cccccc" size="24"></u-icon>
  210. </view>
  211. </view>
  212. <view class="item">
  213. 详细地址
  214. <view class="icon" @click="getPoint">
  215. <view class="img">
  216. <img src="@/assets/img/riLine-map-pin-line@3x.png" alt="">定位
  217. </view>
  218. <view class="text">
  219. </view>
  220. </view>
  221. </view>
  222. <view class="item" style="border: 1px solid #9E9E9E;">
  223. <u-input type="textarea" placeholder="请输入详细地址" v-model="deliveryAddressTemp">
  224. </u-input>
  225. </view>
  226. </view>
  227. <!-- 保存 -->
  228. <button class="save" @click="closePopup">保存并使用</button>
  229. </view>
  230. </u-popup>
  231. <u-modal v-model="showModel" :show-cancel-button="true" @confirm="confirm"
  232. confirm-text="支付成功?" title="扫码支付">
  233. <view style="
  234. text-align: center;
  235. ">
  236. <img id="qrcode2" :src="qrCodeImg">
  237. </view>
  238. <view style="
  239. text-align: center;
  240. ">请使用支付宝扫码</view>
  241. </u-modal>
  242. <img id="qrcode" style="display: none;">
  243. </view>
  244. </template>
  245. <script>
  246. import * as WxJsApi from '@/utils/wxJsApi.js'
  247. import * as API from '@/apis/mall.js'
  248. import {
  249. wxPayJs
  250. } from '@/utils/wxpay'
  251. import QRCode from 'qrcodejs2'
  252. import {
  253. newDate,checkPhone,
  254. convertCanvasToImage,
  255. } from '@/utils'
  256. import MapLoader from '@/utils/AMap'
  257. export default {
  258. data() {
  259. return {
  260. show:false,
  261. id:"",
  262. opinions:"",
  263. mallProductOrder:{},
  264. priceAttrList:{},
  265. info:{
  266. mallProduct:{},
  267. mallProductAttributeList:[],
  268. mallProductOptionList:[],
  269. mallProductPrice:0,
  270. },
  271. receiver:"",
  272. contactPhone:"",
  273. deliveryAddress:"",
  274. receiverTemp:"",
  275. contactPhoneTemp:"",
  276. deliveryAddressTemp:"",
  277. submitForm:{},
  278. submitType:"0",
  279. qrCodeImg: "",
  280. showModel:false,
  281. outOrderNo:"",
  282. }
  283. },
  284. onLoad(op) {
  285. this.personInfo = this.carhelp.getPersonInfo()
  286. if (op.id) {
  287. this.id = op.id;
  288. this.opinions=op.opinions
  289. this.onLoadApi()
  290. this.getDetail()
  291. }
  292. },
  293. methods: {
  294. getPoint() {
  295. var _this = this;
  296. WxJsApi.getLocation().then((res) => {
  297. var lnglatXY =[parseFloat(res.longitude),parseFloat(res.latitude)]
  298. if (res.errMsg != 'getLocation:ok') {
  299. uni.showToast({
  300. title: res
  301. })
  302. } else {
  303. }
  304. MapLoader().then(AMap => {
  305. AMap.service('AMap.Geocoder', function() {
  306. let geocoder = new AMap.Geocoder({});
  307. geocoder.getAddress(lnglatXY, function(status, result) {
  308. console.log(lnglatXY);
  309. console.log(status, result);
  310. if (status === 'complete' && result.info === 'OK') {
  311. var address = result.regeocode.formattedAddress;
  312. console.log(address);
  313. _this.deliveryAddressTemp = address;
  314. } else {
  315. uni.showToast({
  316. title: '无法获取定位'
  317. })
  318. }
  319. });
  320. });
  321. }).catch(error => {
  322. uni.showToast({
  323. title: error,
  324. icon: "none"
  325. })
  326. })
  327. }).catch(error => {
  328. uni.showToast({
  329. title: error,
  330. icon: "none"
  331. })
  332. })
  333. },
  334. confirm() {
  335. uni.redirectTo({
  336. url: "/pages/store/paymentSuccess?id=" + this.outOrderNo
  337. })
  338. },
  339. radioChange: function(evt) {
  340. this.submitType=evt.detail.value
  341. },
  342. init(){
  343. if(this.deliveryAddress){
  344. }else{
  345. this.showPopup()
  346. }
  347. },
  348. showPopup(){
  349. this.show=true;
  350. this.receiverTemp=this.receiver
  351. this.contactPhoneTemp=this.contactPhone
  352. this.deliveryAddressTemp=this.deliveryAddress
  353. },
  354. closePopup(){
  355. this.show=false;
  356. this.receiver=this.receiverTemp
  357. this.contactPhone=this.contactPhoneTemp
  358. this.deliveryAddress=this.deliveryAddressTemp
  359. },
  360. submit(){
  361. var type=this.submitType
  362. if(!this.receiver){
  363. uni.showToast({
  364. title: "请输入收货人姓名"
  365. })
  366. return
  367. }
  368. if(!this.contactPhone){
  369. uni.showToast({
  370. title: "请输入收货人手机号码"
  371. })
  372. return
  373. }
  374. var checkPhoneResult = checkPhone(this.contactPhone);
  375. if (checkPhoneResult !== true) {
  376. uni.showToast({
  377. title: checkPhoneResult,
  378. })
  379. return;
  380. }
  381. if(!this.deliveryAddress){
  382. uni.showToast({
  383. title: "请输入详细地址"
  384. })
  385. return
  386. }
  387. if (type == 0) {
  388. this.wxpy()
  389. }
  390. if (type == 1) {
  391. this.alpy()
  392. }
  393. },
  394. alpy() {
  395. uni.showLoading({
  396. title: "加载中",
  397. mask: true,
  398. })
  399. var listcanvas = document.getElementsByTagName('canvas')
  400. if (listcanvas.length > 0) {
  401. document.getElementById("qrcode").removeChild(document.getElementsByTagName('canvas')[0]);
  402. }
  403. API.tradePrecreatePay({
  404. productId: this.id,
  405. opinions:this.opinions,
  406. buyNum:1,
  407. receiver:this.receiver,
  408. contactPhone:this.contactPhone,
  409. deliveryAddress:this.deliveryAddress,
  410. }).then((response) => {
  411. let qrcode = new QRCode('qrcode', {
  412. width: 200,
  413. height: 200,
  414. text: response.data.qr_code,
  415. correctLevel: QRCode.CorrectLevel.M,
  416. })
  417. this.outOrderNo = response.data.outOrderNo;
  418. var canvas = document.getElementsByTagName('canvas')[0];
  419. this.qrCodeImg = convertCanvasToImage(canvas);
  420. uni.hideLoading()
  421. this.showModel = true
  422. }).catch(error => {
  423. uni.showToast({
  424. title: error
  425. })
  426. })
  427. },
  428. wxpy() {
  429. API.wxJsapiPay({
  430. productId: this.id,
  431. opinions:this.opinions,
  432. buyNum:1,
  433. receiver:this.receiver,
  434. contactPhone:this.contactPhone,
  435. deliveryAddress:this.deliveryAddress,
  436. }).then((response) => {
  437. this.submitForm = response.data
  438. wxPayJs(this.submitForm);
  439. }).catch(error => {
  440. uni.showToast({
  441. title: error
  442. })
  443. })
  444. },
  445. getDetail(){
  446. uni.showLoading({
  447. title: "加载中",
  448. mask: true,
  449. })
  450. API.mallDetails({
  451. id:this.id
  452. }).then((res) => {
  453. uni.hideLoading();
  454. this.info=res.data
  455. }).catch(error => {
  456. uni.showToast({
  457. title: error,
  458. icon: "none"
  459. })
  460. })
  461. },
  462. onLoadApi(){
  463. uni.showLoading({
  464. title: "加载中",
  465. mask: true,
  466. })
  467. API.orderMessage({
  468. productId:this.id,
  469. opinions:this.opinions,
  470. buyNum:1,
  471. }).then((res) => {
  472. uni.hideLoading();
  473. this.mallProductOrder=res.data.mallProductOrder;
  474. this.priceAttrList=res.data.priceAttrList;
  475. this.receiver=this.personInfo.realName
  476. this.contactPhone=this.personInfo.phone
  477. if(res.data.lastReceiver){
  478. this.receiver=res.data.lastReceiver
  479. this.contactPhone=res.data.lastContactPhone
  480. this.deliveryAddress=res.data.lastDeliveryAddress
  481. }
  482. this.init();
  483. }).catch(error => {
  484. uni.showToast({
  485. title: error,
  486. icon: "none"
  487. })
  488. })
  489. }
  490. }
  491. }
  492. </script>
  493. <style lang="scss" scoped>
  494. page {
  495. padding-bottom: 100px;
  496. }
  497. //地址
  498. .address {
  499. background-color: #fff;
  500. margin: 24rpx;
  501. border-radius: 8px;
  502. .fill-address,
  503. .get-address {
  504. padding: 24rpx;
  505. display: flex;
  506. align-items: center;
  507. .icon {
  508. width: 40rpx;
  509. height: 40rpx;
  510. img {
  511. width: 100%;
  512. height: 100%;
  513. }
  514. }
  515. .text {
  516. color: rgba(16, 16, 16, 1);
  517. margin-left: 8rpx;
  518. }
  519. .right-icon {
  520. margin-left: auto;
  521. }
  522. }
  523. }
  524. .item-value-end{
  525. text-align: end;
  526. }
  527. // 已填写
  528. .filled {
  529. background-color: #fff;
  530. margin: 24rpx;
  531. padding: 24rpx;
  532. border-radius: 8px;
  533. display: flex;
  534. justify-content: space-between;
  535. align-items: center;
  536. .filled-address {
  537. .address1 {
  538. color: rgba(51, 51, 51, 1);
  539. font-size: 24rpx;
  540. }
  541. .address2 {
  542. color: rgba(51, 51, 51, 1);
  543. margin-top: 16rpx;
  544. font-weight: bold;
  545. }
  546. .infos {
  547. display: flex;
  548. font-size: 12px;
  549. margin-top: 16rpx;
  550. .tel {
  551. margin-left: 16rpx;
  552. }
  553. }
  554. }
  555. }
  556. // 商品信息
  557. .commodity-infos {
  558. background-color: #fff;
  559. margin: 24rpx;
  560. padding: 24rpx;
  561. display: flex;
  562. align-items: center;
  563. // 图片
  564. .picture {
  565. width: 152rpx;
  566. height: 152rpx;
  567. border-radius: 4px;
  568. img {
  569. width: 100%;
  570. height: 100%;
  571. }
  572. }
  573. // 信息
  574. .infos {
  575. margin-left: 16rpx;
  576. .title {
  577. color: rgba(51, 51, 51, 1);
  578. font-size: 32rpx;
  579. font-weight: bold;
  580. }
  581. .name {
  582. color: rgba(119, 119, 119, 1);
  583. font-size: 24rpx;
  584. margin-top: 8rpx;
  585. }
  586. .price {
  587. color: rgba(16, 16, 16, 1);
  588. font-size: 32rpx;
  589. margin-top: 24rpx;
  590. }
  591. }
  592. // 数量
  593. .amount {
  594. color: rgba(51, 51, 51, 1);
  595. font-size: 32rpx;
  596. margin-left: auto;
  597. }
  598. }
  599. // 订单金额
  600. .order-amount {
  601. margin: 24rpx;
  602. padding: 32rpx 24rpx;
  603. background-color: #fff;
  604. .title {
  605. color: rgba(51, 51, 51, 1);
  606. font-size: 32rpx;
  607. margin-bottom: 32rpx;
  608. font-weight: bold;
  609. }
  610. .item {
  611. display: flex;
  612. justify-content: space-between;
  613. align-items: center;
  614. margin-top: 24rpx;
  615. .item-title {
  616. color: rgba(51, 51, 51, 1);
  617. }
  618. .item-value {
  619. color: rgba(51, 51, 51, 1);
  620. font-size: 32rpx;
  621. font-weight: bold;
  622. }
  623. }
  624. }
  625. // 支付方式
  626. .payment {
  627. margin: 24rpx;
  628. padding: 32rpx 24rpx;
  629. background-color: #fff;
  630. .title {
  631. color: rgba(51, 51, 51, 1);
  632. font-size: 32rpx;
  633. margin-bottom: 32rpx;
  634. font-weight: bold;
  635. }
  636. .way {
  637. display: flex;
  638. justify-content: space-between;
  639. align-items: center;
  640. margin-top: 24rpx;
  641. .way-name {
  642. display: flex;
  643. align-items: center;
  644. text {
  645. margin-right: 16rpx;
  646. img {
  647. width: 48rpx;
  648. height: 48rpx;
  649. vertical-align: middle;
  650. }
  651. }
  652. }
  653. ::v-deep.uni-radio-input-checked {
  654. background-color: #00b962 !important;
  655. }
  656. ::v-deep.uni-radio-input {
  657. width: 40rpx !important;
  658. height: 40rpx !important;
  659. }
  660. }
  661. }
  662. // 底部
  663. .bottom {
  664. position: fixed;
  665. bottom: 0;
  666. left: 0;
  667. right: 0;
  668. background-color: #fff;
  669. padding: 24rpx 32rpx;
  670. display: flex;
  671. align-items: center;
  672. justify-content: space-between;
  673. .unpaid {
  674. color: rgba(16, 16, 16, 1);
  675. font-size: 40rpx;
  676. font-weight: bold;
  677. }
  678. .submit {
  679. width: 338rpx;
  680. height: 96rpx;
  681. background-color: rgba(0, 185, 98, 1);
  682. color: rgba(255, 255, 255, 1);
  683. font-size: 36rpx;
  684. border-radius: 50px;
  685. }
  686. }
  687. // 填写地址
  688. .address-popup{
  689. padding: 48rpx;
  690. width: 640rpx;
  691. border-radius: 8px;
  692. .headline{
  693. text-align: center;
  694. color: rgba(51, 51, 51, 1);
  695. font-size: 36rpx;
  696. font-weight: bold;
  697. }
  698. .infos{
  699. margin-top: 70rpx;
  700. .item{
  701. display: flex;
  702. align-items: center;
  703. margin-bottom: 48rpx;
  704. .item-title{
  705. width: 112rpx;
  706. color: rgba(16, 16, 16, 1);
  707. }
  708. .item-value{
  709. display: flex;
  710. align-items: center;
  711. margin-left: 40rpx;
  712. display: flex;
  713. }
  714. .item-value-end{
  715. text-align: end;
  716. }
  717. }
  718. .icon{
  719. text-align: center;
  720. color: rgba(22, 119, 255, 1);
  721. margin-left: auto;
  722. img{
  723. width: 32rpx;
  724. height: 32rpx;
  725. }
  726. .text{
  727. font-size: 20rpx
  728. }
  729. }
  730. }
  731. // 保存
  732. .save{
  733. border-radius: 4px;
  734. background-color: rgba(0, 185, 98, 1);
  735. color: rgba(255, 255, 255, 1);
  736. font-size: 16px;
  737. height: 80rpx;
  738. }
  739. }
  740. ::v-deep.u-mode-center-box{
  741. border-radius: 8px !important;
  742. }
  743. uni-input{
  744. font-size: 14px;
  745. color: #777777;
  746. }
  747. </style>