productDetail.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. <template>
  2. <view class="pages">
  3. <!-- head -->
  4. <view class="scrollPage-header">
  5. <view :style="{height:statusBarHeight+'px'}"></view>
  6. <view class="header-title">
  7. <view class="header-left" @click="goBack">
  8. <uni-icons type="arrowleft" size="20"></uni-icons>
  9. <text>{{isShare?'首页':'返回'}}</text>
  10. </view>
  11. <view class="header-right"></view>
  12. </view>
  13. </view>
  14. <!-- 内容 -->
  15. <view class="scrollPage-content">
  16. <view class="product-info" v-if="detail">
  17. <view :style="{height:statusBarHeight+'px'}"></view>
  18. <u-swiper mode="number" :border-radius="0" img-mode="aspectFit" :interval="3000" :height="450" :list="imgList" @click="viewImg"></u-swiper>
  19. <view class="product-info-text">
  20. <view class="product-info-text-title">
  21. {{detail.productName}}
  22. <!-- <view class="copyText" @click="copy(detail.productName)">复制</view> -->
  23. <uni-tag style="margin-left: 10px;" size="mini" :circle="true" v-if="detail.status==0 || detail.dealerScopeFlag==0" :text="detail.status==0?'已下架':'已售罄'"></uni-tag>
  24. </view>
  25. <view class="product-info-text-attr">
  26. <view class="product-info-price flex align_center" v-if="!hasLogin">
  27. ¥***
  28. </view>
  29. <view class="flex align_center" v-else>
  30. <view class="product-info-price">
  31. ¥<text>{{detail.priceStr[0]}}</text>.{{detail.priceStr[1]}}
  32. </view>
  33. <view class="flex align_center rebate-tag" v-if="detail.promoType=='BUY_PROD_GIVE_VALID'">
  34. 返<text>{{detail.resultValue}}</text>元
  35. </view>
  36. <view class="flex align_center rebate-tag" v-if="detail.promoType=='BUY_PROD_GIVE_PROD'">
  37. 买{{detail.conditionValue}}赠{{detail.resultValue}}
  38. </view>
  39. <view class="flex align_center tejia-tag" v-if="detail.promoType=='PROMO_PROD'">
  40. 特价<text>¥{{detail.orginPrice}}</text>
  41. </view>
  42. </view>
  43. <view class="product-info-nums">
  44. <view class="share">
  45. <button open-type="share"><u-icon :size='24' name="zhuanfa"></u-icon> 分享</button>
  46. </view>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. <u-divider bg-color="">商品详情</u-divider>
  52. <view class="product-info-guige" v-if="detail&&detail.product">
  53. <view class="row">品牌:<text>{{detail.product.productBrandName||'--'}}</text></view>
  54. <view class="row">原厂编码:<text>{{detail.product.origCode||'--'}} </text> <view class="copyText" v-if="detail.product.origCode" @click="copy(detail.product.origCode)">复制</view></view>
  55. <view class="row">产品编码:<text>{{detail.product.code||'--'}}</text> <view class="copyText" v-if="detail.product.code" @click="copy(detail.product.code)">复制</view></view>
  56. <view class="row">条形码:<text>{{detail.product.qrCode||'--'}}</text> <view class="copyText" v-if="detail.product.qrCode" @click="copy(detail.product.qrCode)">复制</view></view>
  57. <view class="row">商品尺寸:<text>{{detail.product.size||'--'}}</text></view>
  58. <view class="row-ban">计量单位:<text>{{detail.product.unit||'--'}}</text></view>
  59. <view class="row-ban">重量:<text>{{detail.product.weight||'--'}}</text></view>
  60. <view class="row-ban">包装数:<text>{{ (detail.product.packQty) || '--' }}{{ detail.product.packQty ? detail.product.unit : '' }}/{{ detail.product.packQtyUnit||'--' }}</text></view>
  61. </view>
  62. <view class="flex align_center row-info">
  63. <view class="flex"><u-icon :size='24' name="checkbox-mark"></u-icon> <view class="txt">由汽配啇发货</view></view>
  64. <view class="flex"><u-icon :size='24' name="checkbox-mark"></u-icon> <view class="txt">退换货及售后请联系汽配啇</view></view>
  65. </view>
  66. <view class="product-info-content">
  67. <rich-text v-if="detail && detail.product && detail.product.description" :nodes="detail.product.description"></rich-text>
  68. <view v-else style="font-size: 12px;color: #999;text-align: center;">暂无产品介绍</view>
  69. </view>
  70. </view>
  71. <!-- 底部栏 -->
  72. <view class="scrollPage-footer">
  73. <view class="scrollPage-footer-box">
  74. <view class="footer-left">
  75. <view v-if="isShare" class="footer-left-item" @click="goBack">
  76. <u-icon :size='50' color="#666" name="home"></u-icon>
  77. <text class="footer-left-item-text">首页</text>
  78. </view>
  79. <view class="footer-left-item" @click="toCart">
  80. <u-icon :size='50' color="#666" name="shopping-cart"></u-icon>
  81. <text class="footer-left-item-text">购物车</text>
  82. <text class="badge" v-if="totalNum">{{totalNum>99?'99+':totalNum}}</text>
  83. </view>
  84. </view>
  85. <view class="footer-right">
  86. <view class="footer-right-item" @click="toAddCart">
  87. <text>加入购物车</text>
  88. </view>
  89. <view class="footer-right-item" @click="toBuy">
  90. <text>立即购买</text>
  91. </view>
  92. </view>
  93. </view>
  94. <view :style="{height:safeAreaBottom+'px'}"></view>
  95. </view>
  96. <!-- 购物车动画 -->
  97. <uni-cart-animation ref="cartAnimation" @animationfinish="animationfinish"></uni-cart-animation>
  98. <!-- 立即购买和付款 -->
  99. <page-container
  100. :show="showPopu"
  101. :round="true"
  102. :z-index="100"
  103. position="bottom"
  104. customStyle="border-radius:15px 15px 0 0;"
  105. @beforeleave="beforeClosePopu"
  106. @afterleave="closePopu">
  107. <!-- 确认订单 -->
  108. <view class="popu-content" v-if="detail&&!showPay">
  109. <view class="popu-close" @click="cancelBuy">
  110. <uni-icons size="26" type="closeempty"></uni-icons>
  111. </view>
  112. <view class="pupu-box">
  113. <view class="popu-content-img">
  114. <image style="width: 80px; height: 80px;" mode="aspectFit" :src="detail.productMsg||'/static/def_imgs.png'"></image>
  115. </view>
  116. <view class="popu-content-info">
  117. <view class="popu-content-info-title">
  118. <text class="ellipsis-two">{{detail.productName}}</text>
  119. </view>
  120. <view class="popu-content-info-code">
  121. <text class="ellipsis-two">{{detail.product.code}}</text>
  122. </view>
  123. <view class="popu-content-box">
  124. <view class="popu-content-price" v-if="hasLogin">
  125. ¥<text>{{detail.priceStr[0]}}</text>.{{detail.priceStr[1]}}
  126. </view>
  127. <view class="popu-content-price" v-else>¥***</view>
  128. <view class="flex align_center rebate-tag" v-if="hasLogin&&detail.promoType=='BUY_PROD_GIVE_VALID'">
  129. 返<text>{{detail.resultValue}}</text>元
  130. </view>
  131. <view class="flex align_center rebate-tag" v-if="hasLogin&&detail.promoType=='BUY_PROD_GIVE_PROD'">
  132. 买{{detail.conditionValue}}赠{{detail.resultValue}}
  133. </view>
  134. <view class="flex align_center tejia-tag" v-if="hasLogin&&detail.promoType=='PROMO_PROD'">
  135. 特价<text>¥{{detail.orginPrice}}</text>
  136. </view>
  137. </view>
  138. <view style="margin-top: 10px;" class="popu-content-num flex align_center justify_end">
  139. <text>数量</text>
  140. <view class="flex align_center qty-box">
  141. <view class="qty-btn" @click="changeQty(qty-1)" :class="(qty <= 1)?'qty-disabled':''">-</view>
  142. <view class="qty-num" @click="$refs.showPopu.open()" :style="{width:Number(qty).toString().length*8+10+'px'}">
  143. {{qty}}
  144. </view>
  145. <view class="qty-btn" @click="changeQty(qty+1)" :class="(qty >= 999)?'qty-disabled':''">+</view>
  146. </view>
  147. </view>
  148. </view>
  149. </view>
  150. <view class="pupu-box gift-box" v-if="giftNum">
  151. <view class="popu-content-img">
  152. <image style="width: 58px; height: 58px;" mode="aspectFit" :src="detail.productMsg||'/static/def_imgs.png'"></image>
  153. </view>
  154. <view class="popu-content-info">
  155. <view class="popu-content-info-title flex align_center">
  156. <view class="flex align_center rebate-tag">
  157. 赠品
  158. </view>
  159. <view class="ellipsis-two">{{detail.productName}}</view>
  160. </view>
  161. <view class="popu-content-box">
  162. <view class="popu-content-num flex align_center">
  163. <text>X</text> {{giftNum}}
  164. </view>
  165. </view>
  166. </view>
  167. </view>
  168. <view class="pupu-box-item">
  169. <view class="flex align_center justify_between" v-if="shelfInfo">
  170. <text>配送商:{{shelfInfo.dealerName}}</text>
  171. <view @click="callPhone()"><uni-icons size="18" type="phone" color="dodgerblue"></uni-icons><text style="font-size:12px;">拨打</text></view>
  172. </view>
  173. <!-- <view class="flex align_center justify_between" v-if="shelfInfo">
  174. <text>支付方式:在线支付</text>
  175. <view><uni-icons size="18" type="right" color="dodgerblue"></uni-icons></view>
  176. </view> -->
  177. </view>
  178. <view class="popu-content-btn">
  179. <view class="popu-content-btn-item cartbtn" v-if="isAddCart" @click="submitCart($event)">加入购物车</view>
  180. <view class="popu-content-btn-item okbtn" v-if="!isAddCart" @click="toBuy">
  181. {{hasPay?'立即支付':'确定采购'}}
  182. <text class="payAmount">¥{{payAmount}}</text>
  183. </view>
  184. </view>
  185. </view>
  186. <!-- 确认付款 -->
  187. <view class="popu-content" v-if="payInfo&&showPay">
  188. <view class="popu-close" @click="cancelPay">
  189. <uni-icons size="26" type="closeempty"></uni-icons>
  190. </view>
  191. <view class="pupu-box-pay-item">
  192. <view class="popu-content-amount flex align_center justify_center">
  193. <view>¥{{payInfo.totalAmount}}</view>
  194. </view>
  195. <view class="flex align_center justify_between" v-if="payInfo.totalSpecialGiveAmount>0">
  196. <text>总优惠</text>
  197. <view class="popu-content-price">¥{{payInfo.totalSpecialGiveAmount}}</view>
  198. </view>
  199. <view class="flex align_center justify_between" v-if="payInfo.totalTicketGiveAmount>0">
  200. <text>代金券</text>
  201. <view class="popu-content-price">¥{{payInfo.totalTicketGiveAmount}}</view>
  202. </view>
  203. <view style="height: 10px;"></view>
  204. <view class="popu-content-title flex align_center justify_between">
  205. <text>付款方式</text>
  206. <view></view>
  207. </view>
  208. <view class="popu-content-pay flex align_center justify_between">
  209. <view class="flex align_center"><uni-icons size="20" type="weixin" color="#4CAF50"></uni-icons> <text style="margin-left: 5px;">微信支付</text></view>
  210. <view><uni-icons size="22" type="checkbox-filled" color="red"></uni-icons></view>
  211. </view>
  212. </view>
  213. <view class="popu-content-btn">
  214. <view class="popu-content-btn-item okbtn" @click="confirmPay">确定付款</view>
  215. </view>
  216. </view>
  217. </page-container>
  218. <!-- 修改数量弹框 -->
  219. <uni-popup ref="showPopu" type="center" style="z-index: 1500;" :maskClick="false">
  220. <view class="popu-nums-content">
  221. <view class="popu-close" @click="$refs.showPopu.close()">
  222. <uni-icons size="26" type="closeempty"></uni-icons>
  223. </view>
  224. <view class="popu-content-title flex align_center justify_center"><text>修改商品数量</text></view>
  225. <view class="popu-content-num flex align_center justify_center">
  226. <uni-number-box v-model="qty" :size="28" :input-width="280" :input-height="70" :min="1" :max="999"></uni-number-box>
  227. </view>
  228. <view class="popu-content-btn">
  229. <view class="popu-content-btn-item okbtn" @click="$refs.showPopu.close()">确定</view>
  230. </view>
  231. </view>
  232. </uni-popup>
  233. </view>
  234. </template>
  235. <script>
  236. import {
  237. mapState,
  238. mapMutations,
  239. } from 'vuex'
  240. import { addCart, getCartCount } from '@/api/cart.js'
  241. import { getShopDetail } from '@/api/shop.js'
  242. import { purchaseSave, purchaseCheck, purchasePay } from '@/api/purchase.js'
  243. import { toAuthStore, toLogin } from "@/utils/index.js"
  244. export default {
  245. data() {
  246. return {
  247. loading: false,
  248. showPopu: false, // 弹框
  249. statusBarHeight: 0, // 状态栏高度
  250. safeAreaBottom: 0, // 底部安全区域高度
  251. imgList: [],
  252. shopProductSn: null,
  253. detail: null,
  254. qty: 1,// 数量
  255. isShare: false ,// 是否从分享打开的
  256. busPos:{
  257. x: 10,
  258. y:uni.getSystemInfoSync().windowHeight - 30
  259. },
  260. submitOk: false, // 是否成功
  261. cacelOk: false, // 是否取消
  262. refashOk: false, // 是否刷新页面
  263. showPay: false, // 是否显示付款信息
  264. isAddCart: false, // 是否加入购物车
  265. payData: null, // 支付参数
  266. }
  267. },
  268. onLoad(option) {
  269. this.isShare = !!option.share
  270. // 计算安全区域
  271. this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight
  272. this.safeAreaBottom = uni.getSystemInfoSync().safeAreaInsets.bottom
  273. this.shopProductSn = option.sn
  274. // 获取产品详情
  275. this.getDetail()
  276. },
  277. // 分享
  278. onShareAppMessage(e){
  279. return {
  280. title: this.detail ? this.detail.productName : '商品名称',
  281. path: '/pagesB/shopiing/productDetail?sn='+this.shopProductSn+'&share=1',
  282. imageUrl:this.detail ? this.detail.productMsg : '',
  283. type: '1'
  284. }
  285. },
  286. computed: {
  287. ...mapState(['hasLogin']),
  288. // 登录用户信息
  289. userInfo(){
  290. return this.$store.state.vuex_userInfo
  291. },
  292. // 货架经销商信息
  293. shelfInfo(){
  294. return this.$store.state.vuex_storeShelf
  295. },
  296. //是否开启线上支付
  297. hasPay(){
  298. const shelfInfo = this.shelfInfo
  299. return shelfInfo&&shelfInfo.payOnlineFlag&&shelfInfo.payOnlineFlag=='1'
  300. },
  301. // 最小支付金额
  302. minPayAmount(){
  303. const shelfInfo = this.shelfInfo
  304. return shelfInfo&&shelfInfo.minAmount ? shelfInfo.minAmount : 0
  305. },
  306. // 经销商电话
  307. dealerPhone(){
  308. const shelfInfo = this.shelfInfo
  309. return shelfInfo&&shelfInfo.contactMobile ? shelfInfo.contactMobile : ''
  310. },
  311. totalNum(){
  312. return this.hasLogin&&this.userInfo.sysUserFlag == '1' ? this.$store.state.vuex_cartTotal : 0
  313. },
  314. // 赠品数量
  315. giftNum(){
  316. return this.detail && this.detail.promoType=='BUY_PROD_GIVE_PROD' ? Math.floor(this.qty / this.detail.conditionValue)*this.detail.resultValue : 0
  317. },
  318. // 支付总金额
  319. payAmount(){
  320. const price = this.detail && this.detail.priceStr ? this.detail.priceStr.join('.') : 0
  321. return price ? Number(price*this.qty).toFixed(2) : 0
  322. },
  323. // 付款信息
  324. payInfo(){
  325. return this.$store.state.vuex_tempOrderData
  326. }
  327. },
  328. methods: {
  329. // 返回
  330. goBack(){
  331. if(this.isShare){
  332. uni.reLaunch({
  333. url: '/pages/index/index'
  334. })
  335. }else{
  336. uni.navigateBack()
  337. }
  338. },
  339. // 复制
  340. copy(text){
  341. uni.setClipboardData({
  342. data: text,
  343. success: function () {
  344. uni.showToast({
  345. title: '复制成功'
  346. })
  347. }
  348. })
  349. },
  350. viewImg(index){
  351. uni.previewImage({
  352. urls: this.imgList
  353. })
  354. },
  355. // 联系经销商
  356. callPhone() {
  357. if(this.dealerPhone!=''){
  358. uni.makePhoneCall({
  359. phoneNumber: this.dealerPhone
  360. })
  361. }
  362. },
  363. // 产品详情
  364. getDetail(){
  365. uni.showLoading({
  366. title: '加载中'
  367. })
  368. const storeShelf = this.$store.state.vuex_storeShelf
  369. const dealerSn = this.hasLogin && this.userInfo && this.userInfo.sysUserFlag == '1'&&storeShelf ? storeShelf.dealerSn : ''
  370. // 获取产品详情
  371. getShopDetail({
  372. shopProductSn: this.shopProductSn,
  373. dealerSn: dealerSn
  374. }).then(res => {
  375. if(res.status == 200){
  376. this.detail = res.data
  377. if(res.data){
  378. if(res.data.productPicList){
  379. res.data.productPicList.forEach(item => {
  380. this.imgList.push(item.imageUrl||'/static/def_imgs.png')
  381. })
  382. }else{
  383. this.imgList.push(res.data.productMsg||'/static/def_imgs.png')
  384. }
  385. const a = res.data.shopPromoProduct
  386. let bprice = res.data.price
  387. if(a){
  388. res.data.promoType = a.promoType
  389. res.data.resultValue = a.resultValue
  390. res.data.conditionValue = a.conditionValue
  391. res.data.discountType = a.discountType
  392. res.data.promoProductSn = a.promoProductSn
  393. res.data.promoSn = a.promoSn
  394. res.data.orginPrice = res.data.price
  395. // 特价
  396. if(res.data.promoType=='PROMO_PROD'){
  397. bprice =res.data.conditionValue
  398. }
  399. }
  400. res.data.priceStr = Number(bprice).toFixed(2).toString().split('.')
  401. }
  402. }
  403. uni.hideLoading()
  404. })
  405. },
  406. animationfinish(){
  407. this.loading = false
  408. },
  409. changeQty(value) {
  410. const max = 999
  411. const v = value > max ? max : (value==''||value==0?1:value)
  412. this.qty = v
  413. },
  414. // 加入购物车
  415. toAddCart(){
  416. // 未登录
  417. if(this.hasLogin){
  418. // 游客未认证
  419. if(this.userInfo.sysUserFlag == '0'){
  420. toAuthStore()
  421. }else{
  422. // 打开确认数量弹框
  423. this.isAddCart = true
  424. this.showPopu = true
  425. }
  426. }else{
  427. toLogin()
  428. }
  429. },
  430. // 确定加入购物车
  431. submitCart(event){
  432. if(this.loading){
  433. return
  434. }
  435. this.loading = true
  436. this.$refs.cartAnimation.touchOnGoods(event,this.busPos);
  437. // 加入购物车
  438. addCart({
  439. qty: this.qty,
  440. price: this.detail.price,
  441. productSn: this.detail.productSn
  442. }).then(res => {
  443. if(res.status == 200){
  444. uni.$emit('refashCart')
  445. this.showPopu = false
  446. }
  447. })
  448. },
  449. // 打开购物车页面
  450. toCart(){
  451. if(this.hasLogin){
  452. // 游客未认证
  453. if(this.userInfo.sysUserFlag == '0'){
  454. toAuthStore()
  455. }else{
  456. uni.navigateTo({
  457. url: '/pagesB/cart/index'
  458. })
  459. }
  460. }else{
  461. toLogin()
  462. }
  463. },
  464. // 立即购买
  465. toBuy(){
  466. if(this.hasLogin){
  467. // 游客未认证
  468. if(this.userInfo.sysUserFlag == '0'){
  469. toAuthStore()
  470. }else{
  471. if(this.detail.status==0 || this.detail.dealerScopeFlag==0){
  472. uni.showModal({
  473. content: '此商品已'+(this.detail.status==0?'下架':'售罄'),
  474. showCancel:false,
  475. confirmText:'知道了'
  476. })
  477. }else{
  478. // 打开数量选择弹框
  479. if(!this.showPopu){
  480. this.showPopu = true
  481. }else{
  482. if(this.hasPay && this.minPayAmount>this.payAmount){
  483. uni.showModal({
  484. content: '支付金额不能小于'+this.minPayAmount+'元!',
  485. showCancel:false,
  486. confirmText:'知道了'
  487. })
  488. }else{
  489. // 去结算生产订单
  490. this.creatOrder()
  491. }
  492. }
  493. }
  494. }
  495. }else{
  496. toLogin()
  497. }
  498. },
  499. // 取消立即购买
  500. cancelBuy(){
  501. this.resetPage()
  502. },
  503. // 去结算
  504. creatOrder(){
  505. uni.showLoading({
  506. title: '提交中...',
  507. mask: true
  508. })
  509. const _this = this
  510. purchaseCheck({detailList: [{
  511. productSn:this.detail.productSn,
  512. productCode:this.detail.productCode,
  513. qty: this.qty,
  514. price:this.detail.price,
  515. promoSn: this.detail.promoSn
  516. }]}).then(res => {
  517. uni.hideLoading()
  518. if(res.status == 200){
  519. const successList = res.data.successList ? res.data.successList.map(item => {
  520. return {
  521. productSn:item.productSn,
  522. productCode: item.productCode,
  523. qty: item.qty,
  524. price:item.price,
  525. promoSn: item.promoSn
  526. }
  527. }) : []
  528. const removeList = res.data.removeList ? res.data.removeList.map(item => item.productCode) : []
  529. const selloutList = res.data.selloutList ? res.data.selloutList.map(item => item.productCode) : []
  530. // 有已下架或已售罄产品提示
  531. if(removeList.length || selloutList.length){
  532. uni.showModal({
  533. title: '提示',
  534. content: (removeList.length ? `产品${removeList.join(',')}已下架,`:'')+(selloutList.length?`产品${selloutList.join(',')}已售罄,`:'')+`不可采购。`+(successList.length?'是否继续采购其他产品?':''),
  535. showCancel: successList.length,
  536. confirmText: successList.length?'确定':'知道了',
  537. success(ret) {
  538. if(ret.confirm && successList.length){
  539. _this.submitForm(successList)
  540. }
  541. }
  542. })
  543. }else{
  544. const promoChangeFlag = res.data.promoChangeFlag
  545. // 活动变更
  546. if(promoChangeFlag){
  547. uni.showModal({
  548. title: '提示',
  549. content: '促销活动已变更,请刷新?',
  550. confirmText:'确定刷新',
  551. success(ret) {
  552. if(ret.confirm){
  553. _this.showPopu = false
  554. _this.refashOk = true
  555. }
  556. }
  557. })
  558. return
  559. }
  560. // 直接提交
  561. _this.submitForm(successList)
  562. }
  563. }else{
  564. uni.showToast({
  565. title: res.message,
  566. icon: 'none'
  567. })
  568. }
  569. })
  570. },
  571. // 创建订单
  572. submitForm(detailList){
  573. uni.showLoading({
  574. title: '提交中...',
  575. mask: true
  576. })
  577. purchaseSave({
  578. detailList: detailList
  579. }).then(res => {
  580. if(res.status == 200){
  581. res.data.detailList = []
  582. this.$store.state.vuex_tempOrderData = res.data
  583. // 这里判断是否开通支付,如果开通打开确认付款弹框
  584. if(this.hasPay){
  585. // 计算待付款剩余倒计时
  586. res.data.timestamp = (new Date(res.data.createDate.replace(/-/g,'/')).getTime() + 1800000 - new Date().getTime())/1000
  587. purchasePay({
  588. bizSn:res.data.purchaseSn,
  589. bizNo:res.data.purchaseNo,
  590. bizType:'PURCHASE',
  591. payUserOpenId: this.$store.state.vuex_openid || uni.getStorageSync('openid')
  592. }).then(res=>{
  593. this.showPay = true
  594. this.payData = res.data?res.data.payRequestRest:null
  595. uni.hideLoading()
  596. })
  597. }else{
  598. // 未开通支付,创建成功,跳转到订单详情页
  599. this.showPopu = false
  600. this.submitOk = true
  601. uni.hideLoading()
  602. }
  603. }else{
  604. uni.hideLoading()
  605. uni.showToast({
  606. title: res.message,
  607. icon: 'none'
  608. })
  609. }
  610. })
  611. },
  612. // 关闭之前
  613. beforeClosePopu(){
  614. console.log(this.showPay,this.submitOk,this.cacelOk)
  615. // 正在支付
  616. if(this.showPay&&!this.submitOk&&!this.cacelOk){
  617. this.showPay = false
  618. this.cancelPay()
  619. }
  620. },
  621. // 关闭确定订单弹窗后
  622. closePopu(){
  623. this.showPopu = false
  624. // 刷新页面
  625. if(this.refashOk){
  626. this.qty = 1
  627. this.getDetail()
  628. }else{
  629. // 开通了支付
  630. if(this.hasPay){
  631. // 付款
  632. if(this.showPay){
  633. // 确定取消付款或付款失败
  634. if(this.cacelOk){
  635. this.cacelOk = false
  636. }
  637. // 确定付款成功
  638. if(this.submitOk){
  639. this.submitOk = false
  640. }
  641. // 去订单详情页
  642. this.toOrderDetial()
  643. }else{
  644. // 取消立即购买
  645. this.resetPage()
  646. }
  647. }else{
  648. // 未开通支付
  649. // 去订单详情页
  650. if(this.submitOk){
  651. this.submitOk = false
  652. this.toOrderDetial()
  653. }else{
  654. // 取消采购
  655. this.resetPage()
  656. }
  657. }
  658. }
  659. },
  660. // 确认付款
  661. confirmPay(){
  662. const _this = this
  663. // 确认付款
  664. const data = _this.payData
  665. console.log(data)
  666. if(data){
  667. uni.requestPayment({
  668. provider: 'wxpay',
  669. timeStamp: data.timeStamp,
  670. nonceStr: data.nonceStr,
  671. package: data.package,
  672. signType: data.signType,
  673. paySign: data.paySign,
  674. success: (res) =>{
  675. _this.payComplete(1,true)
  676. },
  677. fail: (err)=> {
  678. console.log('fail:',err);
  679. _this.payComplete(err.errMsg.indexOf("cancel")>=0 ? 2 : 0,false)
  680. }
  681. });
  682. }else{
  683. _this.payComplete(0,false)
  684. }
  685. },
  686. payComplete(type,data){
  687. uni.showToast({
  688. mask: true,
  689. title: type==1 ? '支付成功' : (type==2?'支付取消':'支付失败'),
  690. icon: 'none'
  691. })
  692. this.showPopu = false
  693. this.submitOk = true
  694. },
  695. // 确认取消付款弹框
  696. cancelPay(){
  697. const _this = this
  698. uni.showModal({
  699. title: '确定取消支付吗?',
  700. content: '您的订单在30分钟内未支付将被取消,请尽快完成支付。',
  701. confirmText: '继续支付',
  702. cancelText: '取消支付',
  703. success(ret) {
  704. // 确定取消,跳转到订单详情页
  705. if(ret.cancel){
  706. // 支付弹框打开中
  707. if(_this.showPopu){
  708. console.log(0)
  709. _this.showPopu = false
  710. _this.cacelOk = true
  711. }else{
  712. console.log(1)
  713. // 未打开直接跳转
  714. _this.toOrderDetial()
  715. }
  716. }
  717. if(ret.confirm){
  718. console.log(2)
  719. // 继续支付
  720. _this.showPopu = true
  721. _this.showPay = true
  722. _this.cacelOk = false
  723. }
  724. }
  725. })
  726. },
  727. // 重置页面
  728. resetPage(){
  729. this.qty = 1
  730. this.isAddCart = false
  731. this.showPopu = false
  732. this.showPay = false
  733. this.cacelOk = false
  734. this.submitOk = false
  735. setTimeout(()=>{
  736. uni.hideLoading()
  737. },300)
  738. },
  739. // 订单详情页
  740. toOrderDetial(){
  741. this.resetPage()
  742. // 跳转到订单详情页面
  743. uni.navigateTo({
  744. url: "/pagesB/procureOrder/orderDetail?purchaseSn="+this.$store.state.vuex_tempOrderData.purchaseSn
  745. })
  746. }
  747. }
  748. }
  749. </script>
  750. <style lang="less">
  751. .pages {
  752. height: 100vh;
  753. display: flex;
  754. flex-direction: column;
  755. .scrollPage-header{
  756. z-index: 1;
  757. width: 100%;
  758. position:fixed;
  759. left: 0;
  760. top: 0;
  761. .header-title{
  762. display: flex;
  763. align-items: center;
  764. justify-content: space-between;
  765. padding: 0 10px;
  766. height: 44px;
  767. .header-left{
  768. display: flex;
  769. align-items: center;
  770. text{
  771. font-size: 14px;
  772. color: #333333;
  773. }
  774. background-color: rgba(255,255,255,0.6);
  775. box-shadow: 0px 1px 0px 0px #E6E6E6;
  776. border-radius: 50px;
  777. padding: 3px 6px 3px;
  778. }
  779. .header-right{
  780. width: 50px;
  781. }
  782. }
  783. }
  784. .copyText{
  785. background-color: #efefef;
  786. border-radius: 100rpx;
  787. padding: 0 20rpx;
  788. color: #03A9F4;
  789. font-size: 20rpx;
  790. display: inline-block;
  791. margin-left: 20rpx;
  792. height: 44rpx;
  793. line-height: 44rpx;
  794. }
  795. .scrollPage-content{
  796. flex: 1;
  797. overflow-y: auto;
  798. .product-info{
  799. background:#fff;
  800. margin-bottom: 10px;
  801. .product-info-text{
  802. padding: 10px;
  803. .product-info-text-title{
  804. font-weight: bold;
  805. color: #333333;
  806. line-height: 22px;
  807. margin-bottom: 5px;
  808. }
  809. .product-info-text-attr{
  810. display: flex;
  811. align-items: center;
  812. justify-content: space-between;
  813. .product-info-price{
  814. color: red;
  815. display: flex;
  816. align-items: baseline;
  817. font-size: 12px;
  818. text{
  819. font-size: 38rpx;
  820. }
  821. }
  822. .product-info-nums{
  823. font-size: 12px;
  824. color: #999999;
  825. >view{
  826. display: flex;
  827. align-items: center;
  828. }
  829. .share{
  830. button{
  831. width: auto;
  832. padding: 0;
  833. border: 0;
  834. background: none;
  835. line-height: normal;
  836. margin: 0;
  837. display: inline;
  838. font-size: 12px;
  839. color: #999;
  840. &::after{
  841. border:none;
  842. }
  843. /deep/ .u-icon{
  844. margin-right: 3px;
  845. }
  846. }
  847. }
  848. }
  849. }
  850. }
  851. }
  852. .product-info-guige{
  853. display: flex;
  854. flex-wrap: wrap;
  855. justify-content: space-between;
  856. background:#fff;
  857. margin: 10px 0 0;
  858. padding: 10px;
  859. line-height: 28px;
  860. .row{
  861. width: 100%;
  862. }
  863. .row-ban{
  864. width: 50%;
  865. }
  866. >view{
  867. color: #999;
  868. text{
  869. color: #333333;
  870. }
  871. }
  872. }
  873. .row-info{
  874. width: 100%;
  875. background: #fff;
  876. font-size: 24rpx;
  877. text-align: center;
  878. margin: 20rpx 0;
  879. padding: 15rpx;
  880. .txt{
  881. margin-left: 10rpx;
  882. color: #666;
  883. font-weight: bold;
  884. }
  885. > view{
  886. padding: 0 10px;
  887. }
  888. }
  889. .product-info-content{
  890. background:#fff;
  891. margin-bottom: 10px;
  892. padding: 10px;
  893. line-height: 28px;
  894. }
  895. }
  896. .rebate-tag{
  897. background: #ffe7df;
  898. color: #E91E63;
  899. padding: 2px 5px;
  900. font-size: 10px;
  901. border-radius: 3px;
  902. margin-left: 6px;
  903. }
  904. .tejia-tag{
  905. color: #E91E63;
  906. margin-left: 6px;
  907. font-size: 12px;
  908. text{
  909. font-size: 12px;
  910. color: #999;
  911. margin-left: 5px;
  912. text-decoration: line-through;
  913. }
  914. }
  915. .scrollPage-footer{
  916. background-color: #FFFFFF;
  917. width: 100%;
  918. position: fixed;
  919. left: 0;
  920. bottom: 0;
  921. .scrollPage-footer-box{
  922. display: flex;
  923. align-items: center;
  924. justify-content: space-between;
  925. height: 45px;
  926. }
  927. .footer-left{
  928. display: flex;
  929. align-items: center;
  930. justify-content: space-between;
  931. width: 35%;
  932. .footer-left-item{
  933. display: flex;
  934. flex-direction: column;
  935. align-items: center;
  936. justify-content: center;
  937. padding: 0 15px;
  938. position: relative;
  939. .footer-left-item-text{
  940. font-size: 12px;
  941. color: #666666;
  942. }
  943. .badge{
  944. background: #f44336;
  945. color: #fff;
  946. position: absolute;
  947. right: 5px;
  948. top: -8px;
  949. font-size: 12px;
  950. display: flex;
  951. align-items: center;
  952. justify-content: center;
  953. border-radius: 50rpx;
  954. padding: 0 10rpx;
  955. }
  956. }
  957. }
  958. .footer-right{
  959. width: 60%;
  960. height: 80%;
  961. display: flex;
  962. align-items: center;
  963. border-radius: 50px;
  964. overflow: hidden;
  965. margin: 0 5px;
  966. .footer-right-item{
  967. height: 100%;
  968. display: flex;
  969. flex-direction: column;
  970. align-items: center;
  971. justify-content: center;
  972. width: 50%;
  973. font-size: 14px;
  974. color: #FFFFFF;
  975. }
  976. .footer-right-item:first-child{
  977. background-color: #FF9900;
  978. }
  979. .footer-right-item:last-child{
  980. background-color: #FF0000;
  981. }
  982. }
  983. }
  984. .popu-nums-content{
  985. background-color: #FFFFFF;
  986. border-radius: 10px;
  987. width: 300px;
  988. display: flex;
  989. flex-direction: column;
  990. align-items: center;
  991. padding: 10px 15px;
  992. .popu-close{
  993. padding: 10px;
  994. position: absolute;
  995. right: 0;
  996. top: 0;
  997. z-index: 1000;
  998. }
  999. .popu-content-title{
  1000. padding: 10px;
  1001. font-size: 16px;
  1002. }
  1003. .popu-content-num{
  1004. font-size: 24rpx;
  1005. color: #999999;
  1006. padding: 10px 0;
  1007. > text{
  1008. margin-right: 10px;
  1009. font-size: 10px;
  1010. }
  1011. }
  1012. .popu-content-btn{
  1013. width: 100%;
  1014. display: flex;
  1015. align-items: center;
  1016. justify-content: space-around;
  1017. margin: 20px 0 10px;
  1018. .popu-content-btn-item{
  1019. width: 40%;
  1020. height: 32px;
  1021. font-size: 14px;
  1022. display: flex;
  1023. align-items: center;
  1024. justify-content: center;
  1025. border-radius: 100px;
  1026. }
  1027. .cancelBtn{
  1028. background-color: #f8f8f8;
  1029. color: #666;
  1030. }
  1031. .okbtn{
  1032. background-color: #f70000;
  1033. color: #FFFFFF;
  1034. }
  1035. }
  1036. }
  1037. .popu-content{
  1038. display: flex;
  1039. flex-direction: column;
  1040. align-items: center;
  1041. padding: 10px 15px;
  1042. .popu-close{
  1043. padding: 10px;
  1044. position: absolute;
  1045. right: 0;
  1046. top: 0;
  1047. z-index: 1000;
  1048. }
  1049. .qty-box{
  1050. display: flex;
  1051. .qty-btn{
  1052. display: flex;
  1053. align-items: center;
  1054. justify-content: center;
  1055. width: 22px;
  1056. height: 20px;
  1057. border-radius: 50px;
  1058. font-size: 18px;
  1059. color: #066cff;
  1060. &.qty-disabled{
  1061. color: #999;
  1062. }
  1063. }
  1064. .qty-num{
  1065. width: 24px;
  1066. height: 20px;
  1067. line-height: 20px;
  1068. text-align: center;
  1069. background-color: #efefef;
  1070. margin: 0 3px;
  1071. border-radius: 3px;
  1072. font-size: 12px;
  1073. input{
  1074. width: 100%;
  1075. height: 100%;
  1076. text-align: center;
  1077. color: #333;
  1078. }
  1079. }
  1080. }
  1081. .pupu-box{
  1082. display: flex;
  1083. justify-content: space-between;
  1084. margin-top: 35px;
  1085. width: 100%;
  1086. }
  1087. .popu-content-img{
  1088. border-radius: 6px;
  1089. border: 1px solid #eee;
  1090. overflow: hidden;
  1091. width: 80px;
  1092. height: 80px;
  1093. }
  1094. .popu-content-info{
  1095. padding: 0 0 0 10px;
  1096. flex-grow: 1;
  1097. overflow: hidden;
  1098. width: 50%;
  1099. .popu-content-info-title{
  1100. font-size: 14px;
  1101. }
  1102. .popu-content-info-code{
  1103. font-size: 12px;
  1104. color: #00aaff;
  1105. margin-top: 5px;
  1106. }
  1107. }
  1108. .gift-box{
  1109. padding-left: 8%;
  1110. margin-top: 10px;
  1111. border-top: 1px solid #eee;
  1112. padding-top: 10px;
  1113. .popu-content-img{
  1114. width: 58px;
  1115. height: 58px;
  1116. }
  1117. .popu-content-info-title{
  1118. font-size: 12px;
  1119. color: #666;
  1120. }
  1121. .popu-content-box{
  1122. margin-top: 0;
  1123. }
  1124. .popu-content-num{
  1125. padding:5px 15px;
  1126. >text{
  1127. font-size: 10px;
  1128. }
  1129. }
  1130. .rebate-tag{
  1131. margin: 0 5px 0 0;
  1132. background: #ff0000;
  1133. color: #fff;
  1134. flex-grow: 1;
  1135. display: flex;
  1136. justify-content: center;
  1137. }
  1138. .ellipsis-two{
  1139. width: 80%;
  1140. flex-grow: 1;
  1141. }
  1142. }
  1143. .popu-content-box{
  1144. display: flex;
  1145. align-items: baseline;
  1146. margin-top: 5px;
  1147. .popu-content-price{
  1148. color: red;
  1149. display: flex;
  1150. align-items: baseline;
  1151. font-size: 12px;
  1152. text{
  1153. font-size: 38rpx;
  1154. }
  1155. }
  1156. }
  1157. .pupu-box-item,.pupu-box-pay-item{
  1158. width: 100%;
  1159. padding-top: 20px;
  1160. > view{
  1161. padding: 10px 0;
  1162. }
  1163. }
  1164. .pupu-box-pay-item{
  1165. > view{
  1166. padding: 6px 0;
  1167. }
  1168. .popu-content-amount{
  1169. font-size: 28px;
  1170. color: red;
  1171. }
  1172. .popu-content-title{
  1173. font-weight: bold;
  1174. }
  1175. }
  1176. .popu-content-num{
  1177. > text{
  1178. margin-right: 10px;
  1179. }
  1180. }
  1181. .popu-content-btn{
  1182. width: 100%;
  1183. display: flex;
  1184. align-items: center;
  1185. justify-content: space-around;
  1186. margin: 30px 0 20px;
  1187. .popu-content-btn-item{
  1188. width: 30%;
  1189. height: 34px;
  1190. font-size: 14px;
  1191. display: flex;
  1192. align-items: center;
  1193. justify-content: center;
  1194. border-radius: 100px;
  1195. }
  1196. .cancelBtn{
  1197. background-color: #f8f8f8;
  1198. color: #666;
  1199. }
  1200. .okbtn{
  1201. background-color: #f70000;
  1202. color: #FFFFFF;
  1203. width: 65%;
  1204. .payAmount{
  1205. margin-left: 5px;
  1206. }
  1207. }
  1208. .cartbtn{
  1209. background-color: #ffa60c;
  1210. color: #FFFFFF;
  1211. width: 65%;
  1212. }
  1213. }
  1214. }
  1215. }
  1216. </style>