Pārlūkot izejas kodu

商品下架页面完成/重新封装请求

dxz1228 2 gadi atpakaļ
vecāks
revīzija
f84eb395e3

+ 5 - 2
src/apis/merchant.ts

@@ -1,9 +1,12 @@
1
-import { defHttp } from '~/utils/http'
1
+import { defHttp} from '~/utils/http'
2 2
 import type {MerchantCategoryModel, MerchantDetailModel, StoreParams, StoreResult} from "~/apis/model/storeModel";
3 3
 import type {PageModel} from "~/apis/model/pageModel";
4 4
 import type {ZibubaojianResult} from "~/apis/model/zibubaojian.model";
5 5
 import type {VipAreaResult} from "~/apis/model/vip-area.model";
6 6
 
7
+import {detailHttp} from '~/utils/http'
8
+
9
+
7 10
 enum API {
8 11
     GET_SELECT_MERCHANT = '/gateway/wares_service/waresServiceMerchant/selectMerchant',
9 12
     GET_SELECT_MERCHANT_SORT = '/gateway/wares_service/waresServiceMerchant/selectMerchantSort',
@@ -79,7 +82,7 @@ export function getProductList(id: string,page=1,limit=10): Promise<ZibubaojianR
79 82
  * @param id
80 83
  */
81 84
 export function getProductDetail(id: string) {
82
-    return defHttp.get({
85
+    return detailHttp.get({
83 86
         url: API.GET_PRODUCT_DETAIL + `/${id}`,
84 87
     })
85 88
 }

+ 41 - 4
src/apis/model/product.model.ts

@@ -54,7 +54,7 @@ export interface IProductDetail {
54 54
     // 现价销售价格
55 55
     salePrice: number
56 56
     // 原价
57
-    price: number
57
+    price: string
58 58
     // 分销URL
59 59
     spreadUrl: string
60 60
     // 商品图
@@ -100,6 +100,12 @@ export interface HomeProduct {
100 100
         getEndTime: string
101 101
     }[]
102 102
 }
103
+//抖音商品状态+商品详情
104
+export interface DyProductDetailsModel{
105
+    status:number
106
+    message:string
107
+    data:DyProductDetailModel
108
+}
103 109
 
104 110
 /**
105 111
  * 抖音商品详情
@@ -268,7 +274,12 @@ export type PDDProductDetailModel = {
268 274
     yanglao: string//养老金
269 275
     pddlink: PddLink//链接
270 276
 }
271
-
277
+//附加状态
278
+export type  PDDProductDetailModels= {
279
+    message:string
280
+    status:number
281
+    data:PDDProductDetailModel
282
+}
272 283
 export type PddLink = {
273 284
     mobile_url: string
274 285
     url: string
@@ -319,6 +330,13 @@ export type VipProductModel = {
319 330
     price: string
320 331
 }
321 332
 
333
+//唯品会商品状态+商品详情
334
+export interface VipProductResults{
335
+    status:number
336
+    message:string
337
+    data:VipProductResult
338
+} 
339
+
322 340
 export interface VipProductResult {
323 341
     returnCode: string
324 342
     result: Array<VipProductDetailModel>
@@ -327,13 +345,16 @@ export interface VipProductResult {
327 345
     wphlink: WphlinkModel
328 346
 }
329 347
 
348
+
330 349
 export interface WphlinkModel {
331 350
     url: string
332 351
     longUrl: string
333 352
     ulUrl: string
334 353
     vipQuickAppUrl: string
335 354
 }
336
-
355
+/**
356
+ * 唯品会商品详情
357
+ */
337 358
 export interface VipProductDetailModel {
338 359
     // 商品原价
339 360
     marketPrice: string
@@ -414,6 +435,13 @@ export interface PrepayInfoModel {
414 435
     isPrepay: string
415 436
 }
416 437
 
438
+//苏宁商品状态+商品详情
439
+export interface SuNingProductDetailsModel {
440
+    status:number
441
+    data:SuNingProductDetailModel
442
+    message:string
443
+} 
444
+
417 445
 /**
418 446
  * 苏宁商品详情
419 447
  */
@@ -470,7 +498,11 @@ export type SuNingProductModel = {
470 498
  * 淘宝商品详情
471 499
  */
472 500
 export interface TaobaoProductDetailModel {
473
-    waresDetail: TaobaoWaresDetail
501
+    status:number
502
+    message:string
503
+    data: {
504
+        waresDetail:TaobaoWaresDetail
505
+    }
474 506
 }
475 507
 
476 508
 export interface TaobaoWaresDetail {
@@ -519,6 +551,11 @@ export type TaobaoProductThirdPartyWaresModel = {
519 551
     coupon_share_url: string
520 552
 }
521 553
 
554
+export interface JdgProductDetailModel{
555
+    status:number
556
+    message:string
557
+    data:JdProductDetailModel[]
558
+}
522 559
 export interface JdProductDetailModel {
523 560
     // 京东商品原标题
524 561
     goodsName: string

+ 16 - 15
src/apis/product.ts

@@ -1,12 +1,13 @@
1
-import {defHttp} from "~/utils/http";
1
+import {defHttp, detailHttp} from "~/utils/http";
2 2
 import type {
3 3
     DyLiveModel, DyLiveProductModel, DyProductDetailModel,
4
+    DyProductDetailsModel,
4 5
     DyProductModel, JdProductDetailModel,
5
-    JdProductModel, PDDProductDetailModel, PDDProductModel, ProductDetailModel,
6
+    JdProductModel, JdgProductDetailModel, PDDProductDetailModel, PDDProductDetailModels, PDDProductModel, ProductDetailModel,
6 7
     ProductParams,
7 8
     SearchProductParams,
8
-    SearchProductResult, SuNingProductDetailModel, SuNingProductModel, TaobaoProductDetailModel,
9
-    TaobaoProductResult, VipProductModel, VipProductParams, VipProductResult
9
+    SearchProductResult, SuNingProductDetailModel, SuNingProductDetailsModel, SuNingProductModel, TaobaoProductDetailModel,
10
+    TaobaoProductResult, VipProductModel, VipProductParams, VipProductResult, VipProductResults
10 11
 } from "~/apis/model/product.model";
11 12
 import {resolveUnref} from "@vueuse/core";
12 13
 
@@ -123,8 +124,8 @@ export function searchProductList(params: SearchProductParams): Promise<SearchPr
123 124
  * 京东商品详情
124 125
  * @param skuId
125 126
  */
126
-export  function getJdProductDetail(skuId: string): Promise<Array<JdProductDetailModel>> {
127
-    return defHttp.get({
127
+export  function getJdProductDetail(skuId: string): Promise<JdgProductDetailModel> {
128
+    return detailHttp.get({
128 129
         url: API.JD_DETAIL,
129 130
         data: {
130 131
             skuId
@@ -187,8 +188,8 @@ export function searchVipProduct(params: ProductParams): Promise<Array<VipProduc
187 188
  * 唯品商品详情
188 189
  * @param params
189 190
  */
190
-export function getVipProductDetail(goodsId: string): Promise<VipProductResult> {
191
-    return defHttp.get({
191
+export function getVipProductDetail(goodsId: string): Promise<VipProductResults> {
192
+    return detailHttp.get({
192 193
         url: API.VIP_DETAIL,
193 194
         data: {
194 195
             goodsId
@@ -197,8 +198,8 @@ export function getVipProductDetail(goodsId: string): Promise<VipProductResult>
197 198
     })
198 199
 }
199 200
 
200
-export function getSuProductDetail(id: string): Promise<SuNingProductDetailModel> {
201
-    return defHttp.get({
201
+export function getSuProductDetail(id: string): Promise<SuNingProductDetailsModel> {
202
+    return detailHttp.get({
202 203
         url: `${API.SU_DETAIL}/${id}`,
203 204
 
204 205
     })
@@ -231,7 +232,7 @@ export function searchSuProduct(params: ProductParams): Promise<Array<SuNingProd
231 232
 }
232 233
 
233 234
 export function getTaobaoProductDetail(id: string): Promise<TaobaoProductDetailModel> {
234
-    return defHttp.post({
235
+    return detailHttp.post({
235 236
         url: API.TAOBAO_DETAIL,
236 237
         data: {
237 238
             id
@@ -276,8 +277,8 @@ export function getPddProductList(params: ProductParams): Promise<Array<PDDProdu
276 277
  * 拼多多商品详情
277 278
  * @param goodsId
278 279
  */
279
-export function getPddProductDetail(goodsId: string): Promise<PDDProductDetailModel> {
280
-    return defHttp.get({
280
+export function getPddProductDetail(goodsId: string): Promise<PDDProductDetailModels> {
281
+    return detailHttp.get({
281 282
         url: API.PDD_DETAIL,
282 283
         data: {
283 284
             goodsId
@@ -349,8 +350,8 @@ export function searchDyProduct(params: ProductParams):Promise<Array<DyProductMo
349 350
  * 抖音商品详情
350 351
  * @param goodsId
351 352
  */
352
-export function getDyProductDetail(goodsId: string): Promise<DyProductDetailModel> {
353
-    return defHttp.get({
353
+export function getDyProductDetail(goodsId: string): Promise<DyProductDetailsModel> {
354
+    return detailHttp.get({
354 355
         url: API.DY_DETAIL,
355 356
         data: {
356 357
             goodsId

+ 1 - 1
src/components/CXBBackTop/CXBBackTop.vue

@@ -40,7 +40,7 @@ const scrollToTop = function () {
40 40
   border-radius: 50%;
41 41
   z-index: 999;
42 42
   right: 15px;
43
-  bottom: 60px;
43
+  bottom: 20%;
44 44
 }
45 45
 .backTopImg{
46 46
   width: 40px;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 887 - 1
src/pages.json


+ 104 - 145
src/pages/order_addcart/index.vue

@@ -1,8 +1,8 @@
1 1
 <script lang="ts" setup>
2
-import {getRecommendList ,getProductDetail} from "~/apis/merchant";
2
+import { getRecommendList, getProductDetail } from "~/apis/merchant";
3 3
 import MerchantProductCard from "~/pages/store/home/components/MerchantProductCard.vue";
4
-import {deleteCartItem, getCartCount, getCartList,xcxBanding} from "~/apis/user";
5
-import type {ShoppingResult} from "~/apis/model/shopping.model";
4
+import { deleteCartItem, getCartCount, getCartList, xcxBanding } from "~/apis/user";
5
+import type { ShoppingResult } from "~/apis/model/shopping.model";
6 6
 import FPrice from "~/components/FPrice/FPrice.vue";
7 7
 import FButton from "~/components/FButton/FButton.vue";
8 8
 import CXBYaojinTag from "~/components/CXBYaojinTag/CXBYaojinTag.vue";
@@ -12,12 +12,12 @@ import {
12 12
   SuNingProductModel,
13 13
   TaobaoProductThirdPartyWaresModel, VipProductModel
14 14
 } from "~/apis/model/product.model";
15
-import {DcProductModel} from "~/apis/model/dacang.model";
16
-import {createShopping , changeProdoctSku} from "~/apis/order.api";
17
-import {encodeBase64} from "~/utils/http/helper";
18
-import {CDN_URL} from "~/config/app";
19
-import {uniq} from "lodash-es";
20
-import {cartChange} from "~/apis/order.api";
15
+import { DcProductModel } from "~/apis/model/dacang.model";
16
+import { createShopping, changeProdoctSku } from "~/apis/order.api";
17
+import { encodeBase64 } from "~/utils/http/helper";
18
+import { CDN_URL } from "~/config/app";
19
+import { uniq } from "lodash-es";
20
+import { cartChange } from "~/apis/order.api";
21 21
 import type CXBBackTop from "~/components/CXBBackTop/CXBBackTop.vue";
22 22
 import CXBSkuPopup from "~/components/CXBSkuPopup/CXBSkuPopup.vue";
23 23
 const gouwucheImage = CDN_URL + '/static/assets/gouwuche.png'
@@ -38,7 +38,7 @@ const state = reactive({
38 38
   selectAllIndeterminate: false,
39 39
 
40 40
   cart_id: [],
41
-  changeSkuCart_id:'0',
41
+  changeSkuCart_id: '0',
42 42
   isManage: true,
43 43
 
44 44
   currentType: '',
@@ -46,6 +46,11 @@ const state = reactive({
46 46
   isShowSku: false,
47 47
   cartNum: 1,
48 48
   currentSku: {},
49
+  //新增
50
+  shareImage: '',
51
+  isRelation: '',
52
+  shareId: '',
53
+  status:'',
49 54
 })
50 55
 
51 56
 const detail: any = ref(null)
@@ -57,7 +62,7 @@ function onSelectedSku(item) {
57 62
 
58 63
 function handleCreateShopping() {
59 64
   // console.log(state.flag)
60
-  console.log(state.currentSku.unique,'切换sku展示的商品',state)
65
+  console.log(state.currentSku.unique, '切换sku展示的商品', state)
61 66
   changeProdoctSku(
62 67
     // product_attr_unique: JSON.stringify(state.currentSku),
63 68
     // detail.value.unique
@@ -101,7 +106,7 @@ function handleCountChange(val) {
101 106
   // console.log(val)
102 107
   // detail.value.
103 108
   // if (val > 0) {
104
-    state.cartNum = val
109
+  state.cartNum = val
105 110
   // }
106 111
 }
107 112
 
@@ -269,13 +274,13 @@ function shopCheck(shopItem) {
269 274
 
270 275
 function handleShopTitleClick(shopItem) {
271 276
   if (shopItem.allCheck) {
272
-        shopItem.list.forEach((good, index) => {
273
-          good.check = true
274
-        })
277
+    shopItem.list.forEach((good, index) => {
278
+      good.check = true
279
+    })
275 280
   } else {
276
-        shopItem.list.forEach((good, index) => {
277
-          good.check = false
278
-        })
281
+    shopItem.list.forEach((good, index) => {
282
+      good.check = false
283
+    })
279 284
   }
280 285
 }
281 286
 function cartAllCheck(type: 'single' | 'all') {
@@ -458,13 +463,13 @@ function handleDelete() {
458 463
 
459 464
 
460 465
 function handleProductItemClick(
461
-    item:
462
-        JdProductModel
463
-        & DcProductModel
464
-        & DyProductModel
465
-        & SuNingProductModel
466
-        & TaobaoProductThirdPartyWaresModel
467
-        & VipProductModel
466
+  item:
467
+    JdProductModel
468
+    & DcProductModel
469
+    & DyProductModel
470
+    & SuNingProductModel
471
+    & TaobaoProductThirdPartyWaresModel
472
+    & VipProductModel
468 473
 ) {
469 474
   // function navigateToDetail(params) {
470 475
   //   let otherDetailUrl = `/pages/store/product/other`
@@ -495,83 +500,76 @@ function handleNumberChange(num, goodItem) {
495 500
 const headerClass = ref('')
496 501
 onPageScroll((page) => {
497 502
   // console.log('滚轮事件触发了',page.scrollTop.toFixed());
498
-  
503
+
499 504
   // console.log(page.scrollTop.toFixed(),'距离顶部的距离')
500 505
   Scroll_X.value = Number(page.scrollTop.toFixed())
501
-  if (page.scrollTop >= 76 ) {
506
+  if (page.scrollTop >= 76) {
502 507
     headerClass.value = 'bg-white !text-gray-900'
503 508
   } else {
504 509
     headerClass.value = ''
505 510
   }
506 511
 })
507
-const openTestLog1 = (a)=>{
508
-  console.log('商品的id',a.product_id)
512
+const openTestLog1 = (a) => {
513
+  console.log('商品的id', a.product_id)
509 514
   console.log('测试点击sku,多规模');
510 515
   state.isShowSku = true
511
-  
516
+
512 517
 }
513 518
 
514 519
 function openTestLog(element) {
515 520
   state.isShowSku = true
516 521
   state.changeSkuCart_id = element.cart_id
517
-console.log('用户点击sku,展示商品id和购物车id',element.product_id,element.cart_id)
518
-getProductDetail(element.product_id).then(res => {
519
-  console.log(res.sku,'点击sku,展示返回的res')
520
-  detail.value = res
521
-  // console.log(detail.value,'点击sku获取的商品信息,存储的detail')
522
-  state.shareImage = detail.value.image
523
-  if (res && res.mer_id && res.mer_id === '148') {
524
-    if (detail.value && detail.value.price ) {
525
-      detail.value.price = detail.value.price * 30
522
+  console.log('用户点击sku,展示商品id和购物车id', element.product_id, element.cart_id)
523
+  getProductDetail(element.product_id).then(res => {
524
+    console.log(res.data, '点击sku,展示返回的res')
525
+    detail.value = res.data
526
+    // console.log(detail.value,'点击sku获取的商品信息,存储的detail')
527
+    state.shareImage = detail.value.image
528
+    if (res && res.mer_id && res.mer_id === '148') {
529
+      if (detail.value && detail.value.price) {
530
+        detail.value.price = detail.value.price * 30
531
+      }
532
+    }
533
+    state.isRelation = res.isRelation
534
+    if (res.merchant_type == 2) {
535
+      xcxBanding({
536
+        mer_id: res.mer_id,
537
+        share_id: state.shareId
538
+      }).then(res => {
539
+        console.info(res)
540
+      })
526 541
     }
527
-  }
528
-  state.isRelation = res.isRelation
529
-  if (res.merchant_type == 2) {
530
-    xcxBanding({
531
-      mer_id: res.mer_id,
532
-      share_id: state.shareId
533
-    }).then(res => {
534
-      console.info(res)
535
-    })
536
-  }
537 542
 
538
-  // if (detail.value.mer_id === '148') {
539
-  // }
540
-  uni.hideLoading()
541
-}).catch(error => {
542
-  // console.log(error)
543
-  uni.showToast({
544
-    icon: "none",
545
-    title: error
546
-  }).then( () => {
547
-    setTimeout(() => {
548
-      uni.navigateBack()
549
-    }, 500)
543
+    // if (detail.value.mer_id === '148') {
544
+    // }
545
+    uni.hideLoading()
546
+  }).catch(error => {
547
+    // console.log(error)
548
+    uni.showToast({
549
+      icon: "none",
550
+      title: error
551
+    }).then(() => {
552
+      setTimeout(() => {
553
+        uni.navigateBack()
554
+      }, 500)
555
+    })
550 556
   })
551
-})
552 557
 }
553
-const closeTestLog = ()=>{
558
+const closeTestLog = () => {
554 559
   console.log('测试点击sku,多规模');
555 560
 
556 561
 }
557 562
 </script>
558 563
 <template>
559 564
   <div class="">
560
-    <div
561
-        v-if="hasShopping"
562
-        class="bg-white h-10 fixed top-0 w-full z-1 flex justify-end "
563
-    >
565
+    <div v-if="hasShopping" class="bg-white h-10 fixed top-0 w-full z-1 flex justify-end ">
564 566
       <div class="pr-3">
565
-        <FButton size="small"
566
-                 @click="handleManageCart"
567
-        >
568
-          <div>{{ state.isManage ? '管理' : '完成'}}</div>
567
+        <FButton size="small" @click="handleManageCart">
568
+          <div>{{ state.isManage ? '管理' : '完成' }}</div>
569 569
         </FButton>
570 570
       </div>
571 571
     </div>
572
-    <div
573
-        v-if="!hasShopping"
574
-        class="flex flex-col justify-center items-center bg-white rounded-lg gap-3 text-xs py-8">
572
+    <div v-if="!hasShopping" class="flex flex-col justify-center items-center bg-white rounded-lg gap-3 text-xs py-8">
575 573
       <div>
576 574
         <image :src="gouwucheImage" mode="widthFix" class="w-20 h-20"></image>
577 575
       </div>
@@ -581,66 +579,42 @@ const closeTestLog = ()=>{
581 579
     </div>
582 580
     <div v-else class="mt-10">
583 581
 
584
-      <div
585
-          v-if="shopping && shopping.list"
586
-          class="flex flex-col gap-4 p-3"
587
-      >
588
-        <div
589
-            v-for="(shopItem, index) in shopping.list"
590
-            :key="index"
591
-            class="bg-white rounded-lg  "
592
-        >
593
-          <div
594
-              class="f-hairline-bottom flex  items-center font-bold p-3"
595
-          >
582
+      <div v-if="shopping && shopping.list" class="flex flex-col gap-4 p-3">
583
+        <div v-for="(shopItem, index) in shopping.list" :key="index" class="bg-white rounded-lg  ">
584
+          <div class="f-hairline-bottom flex  items-center font-bold p-3">
596 585
             <div @tap.stop="handleShopTitleClick(shopItem)">
597 586
 
598
-            <nut-checkbox v-model="shopItem.allCheck"
599
-                          @change="(checked) => shopCheck( shopItem)"
600
-                          label="全选"
601
-                          class="!text-primary"
602
-            >
603
-              {{ shopItem.mer_name }}
604
-            </nut-checkbox>
587
+              <nut-checkbox v-model="shopItem.allCheck" @change="(checked) => shopCheck(shopItem)" label="全选"
588
+                class="!text-primary">
589
+                {{ shopItem.mer_name }}
590
+              </nut-checkbox>
605 591
             </div>
606 592
 
607 593
           </div>
608
-          <div v-for="(goodItem, goodIndex) in shopItem.list"
609
-               :key="goodIndex"
610
-               class="flex f-hairline-bottom p-3 gap-2"
611
-          >
594
+          <div v-for="(goodItem, goodIndex) in shopItem.list" :key="goodIndex" class="flex f-hairline-bottom p-3 gap-2">
612 595
             <div class="flex">
613
-              <nut-checkbox v-model="goodItem.check"
614
-                            @change="handleGoodsItemCheck"
615
-                            label="单选"
616
-                            class="!text-primary"
617
-              ></nut-checkbox>
618
-              <image
619
-                  @click="handleProductItemClick(goodItem)"
620
-                  :src="goodItem.product.image"
621
-                  mode="aspectFill" class="w-18 h-18 rounded"
622
-              ></image>
596
+              <nut-checkbox v-model="goodItem.check" @change="handleGoodsItemCheck" label="单选"
597
+                class="!text-primary"></nut-checkbox>
598
+              <image @click="handleProductItemClick(goodItem)" :src="goodItem.product.image" mode="aspectFill"
599
+                class="w-18 h-18 rounded"></image>
623 600
             </div>
624 601
 
625 602
             <div class="flex flex-col gap-1 w-full">
626
-              <div
627
-                  @click="handleProductItemClick(goodItem)"
628
-                  class="text-overflow line-clamp-2 text-xs">{{ goodItem.product.store_name }}</div>
603
+              <div @click="handleProductItemClick(goodItem)" class="text-overflow line-clamp-2 text-xs">{{
604
+                goodItem.product.store_name }}</div>
629 605
               <div class="flex flex-col justify-start gap-1">
630
-                <div
631
-                    class="text-[10px] text-gray min-w-5  p-1  items-center flex skushadow" v-if="goodItem.productAttr.sku" @click="openTestLog(goodItem)">
632
-                  {{ goodItem.productAttr.sku +' V'}}
606
+                <div class="text-[10px] text-gray min-w-5  p-1  items-center flex skushadow"
607
+                  v-if="goodItem.productAttr.sku" @click="openTestLog(goodItem)">
608
+                  {{ goodItem.productAttr.sku + ' V' }}
633 609
                 </div>
634 610
                 <div class="flex">
635
-                  <CXBYaojinTag :amount="goodItem.yanglao"/>
611
+                  <CXBYaojinTag :amount="goodItem.yanglao" />
636 612
 
637 613
                 </div>
638 614
               </div>
639 615
               <div class="flex  justify-between ">
640
-                <FPrice :price="goodItem.productAttr.price"
641
-                        ex-class="font-bold text-dark"
642
-                />
643
-                <nut-input-number v-model="goodItem.cart_num" @change="(num) => handleNumberChange(num, goodItem)"/>
616
+                <FPrice :price="goodItem.productAttr.price" ex-class="font-bold text-dark" />
617
+                <nut-input-number v-model="goodItem.cart_num" @change="(num) => handleNumberChange(num, goodItem)" />
644 618
               </div>
645 619
             </div>
646 620
           </div>
@@ -649,7 +623,7 @@ const closeTestLog = ()=>{
649 623
       </div>
650 624
     </div>
651 625
 
652
-    <CXBBackTop :Scroll_X="Scroll_X"/>
626
+    <CXBBackTop :Scroll_X="Scroll_X" />
653 627
     <div class="pb-12">
654 628
       <div class="flex flex-row justify-center items-center gap-3 font-bold text-sm p-3 ">
655 629
         <image :src="like_adorn_220628Image" mode="widthFix" class="w-6 h-6"></image>
@@ -661,17 +635,13 @@ const closeTestLog = ()=>{
661 635
 
662 636
       <div class="pb-3 px-3" v-if="state.recommendList">
663 637
         <grid-view type="masonry" cross-axis-count="2" cross-axis-gap="10px" main-axis-gap="10px">
664
-          <div v-for="(item, index) in state.recommendList"
665
-               :key="index"
666
-               @click="handleProductItemClick(item)"
667
-          >
638
+          <div v-for="(item, index) in state.recommendList" :key="index" @click="handleProductItemClick(item)">
668 639
             <MerchantProductCard :item="item" />
669 640
 
670 641
           </div>
671 642
         </grid-view>
672 643
 
673
-        <div class=" flex justify-center items-center text-[12px] text-gray-500"
674
-        >
644
+        <div class=" flex justify-center items-center text-[12px] text-gray-500">
675 645
           <div v-if="state.status === 'loading'">
676 646
             加载中...
677 647
           </div>
@@ -683,21 +653,12 @@ const closeTestLog = ()=>{
683 653
       </div>
684 654
     </div>
685 655
   </div>
686
-  <CXBSkuPopup 
687
-  v-model:show="state.isShowSku"
688
-      :detail="detail"
689
-      @selected:item="onSelectedSku"
690
-      @submit="handleCreateShopping"
691
-      @count-change="handleCountChange"
692
-  />
693
-  <div v-if="hasShopping"
694
-       class="fixed bottom-0 w-full z-3">
656
+  <CXBSkuPopup v-model:show="state.isShowSku" :detail="detail" @selected:item="onSelectedSku"
657
+    @submit="handleCreateShopping" @count-change="handleCountChange" />
658
+  <div v-if="hasShopping" class="fixed bottom-0 w-full z-3">
695 659
     <div class="bg-white h-10 flex justify-between" v-if="shopping && shopping.list">
696 660
       <div class="flex justify-center items-center gap-2 pl-3" @tap.stop="handleSelectAll">
697
-        <nut-checkbox v-model="isAllSelect"
698
-                      label="全选"
699
-                      class="!text-primary"
700
-        >全选
661
+        <nut-checkbox v-model="isAllSelect" label="全选" class="!text-primary">全选
701 662
         </nut-checkbox>
702 663
         <div class="text-xs text-gray">共 {{ state.totalCartCount }} 件</div>
703 664
       </div>
@@ -708,12 +669,9 @@ const closeTestLog = ()=>{
708 669
           <FPrice :price="state.totalPrice"></FPrice>
709 670
           <!--          {{totalCartInfo.totalPrice}}-->
710 671
         </div>
711
-        <FButton
712
-            @click="handleSubmit"
713
-            size="small"
714
-            :exClass="['rounded-full','!text-[14px]', 'text-white', 'bg-primary', 'w-full']"
715
-        >
716
-          {{ state.isManage? '去结算' : '删除'}}
672
+        <FButton @click="handleSubmit" size="small"
673
+          :exClass="['rounded-full', '!text-[14px]', 'text-white', 'bg-primary', 'w-full']">
674
+          {{ state.isManage ? '去结算' : '删除' }}
717 675
         </FButton>
718 676
       </div>
719 677
     </div>
@@ -723,7 +681,8 @@ const closeTestLog = ()=>{
723 681
 page {
724 682
   background-color: #f8f8f8;
725 683
 }
726
-.skushadow{
684
+
685
+.skushadow {
727 686
   background-color: rgb(240, 240, 240);
728 687
   border-radius: 10px;
729 688
 }

+ 121 - 0
src/pages/sold-out/sold-out.vue

@@ -0,0 +1,121 @@
1
+<script setup lang='ts'>
2
+import { ref, reactive, defineProps } from 'vue'
3
+import { getRecommendList } from '~/apis/merchant'
4
+import { DcProductModel } from '~/apis/model/dacang.model'
5
+import { DyProductModel, JdProductModel, SuNingProductModel, TaobaoProductThirdPartyWaresModel, VipProductModel } from '~/apis/model/product.model'
6
+import MerchantProductCard from "~/pages/store/home/components/MerchantProductCard.vue";
7
+let state=reactive({
8
+  recommendList:[]
9
+})
10
+
11
+onLoad((options: any) => {
12
+  YouLike()
13
+  uni.hideLoading()
14
+
15
+})
16
+
17
+
18
+//猜你喜欢
19
+function YouLike() {
20
+  getRecommendList({
21
+    page: 1,
22
+    limit: 10
23
+  }).then(res => {
24
+    state.recommendList = res.list
25
+    console.log(state.recommendList);
26
+    
27
+  })
28
+}
29
+
30
+function handleProductItemClick(
31
+  item:
32
+    JdProductModel
33
+    & DcProductModel
34
+    & DyProductModel
35
+    & SuNingProductModel
36
+    & TaobaoProductThirdPartyWaresModel
37
+    & VipProductModel
38
+) {
39
+  // function navigateToDetail(params) {
40
+  //   let otherDetailUrl = `/pages/store/product/other`
41
+  //   return uni.navigateTo({
42
+  //     url: `${otherDetailUrl}?params=${params}`
43
+  //   })
44
+  // }
45
+  // 大仓
46
+  uni.navigateTo({
47
+    url: `/pages/store/product/detail?id=${item.product_id}`
48
+  })
49
+}
50
+
51
+
52
+
53
+</script>
54
+
55
+<template>
56
+  <div class="box-out">
57
+    <div class="flex-box pb-3 px-3 ">
58
+      <div class="img-div">
59
+        <image lazy-load src="../../../static/icon/商品下架不存在@3x.png" mode="widthFix" class=" top-0 right-0 sold-out ">
60
+        </image>
61
+      </div>
62
+      <div class="out-conter">该商品下架不存在</div>
63
+    </div>
64
+
65
+  </div>
66
+  <div class="flex flex-col pb-safe gap-3">
67
+      <div class="p-3 bg-white">
68
+        <div
69
+            class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
70
+          <div class="pl-2">
71
+            猜你喜欢
72
+          </div>
73
+        </div>
74
+      </div>
75
+      <div class="pb-3 px-3" v-if="state.recommendList.length!=0">
76
+        <grid-view type="masonry" cross-axis-count="2" cross-axis-gap="10px" main-axis-gap="10px">
77
+          <div v-for="(item, index) in state.recommendList"
78
+               :key="index"
79
+               @click="handleProductItemClick(item)"
80
+          >
81
+            <MerchantProductCard :item="item"/>
82
+
83
+          </div>
84
+        </grid-view>
85
+      </div>
86
+
87
+    </div>
88
+</template>
89
+
90
+
91
+<style scoped>
92
+.box-out {
93
+  background: #f8f8f8;
94
+  height: 200px;
95
+}
96
+
97
+.flex-box {
98
+  background: #ffffff;
99
+  box-shadow: 3px;
100
+  height: 80%;
101
+  display: flex;
102
+  flex-direction: column;
103
+  justify-content: space-evenly;
104
+}
105
+
106
+.img-div {
107
+  width: 100%;
108
+
109
+}
110
+
111
+.sold-out {
112
+  display: block;
113
+  width: 120px;
114
+  height: 120px;
115
+  margin: 0 auto;
116
+}
117
+
118
+.out-conter {
119
+  text-align: center;
120
+}
121
+</style>

+ 242 - 215
src/pages/store/product/detail.vue

@@ -1,24 +1,24 @@
1 1
 <script lang="ts" setup>
2 2
 import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html'
3
-import {getProductDetail, getRecommendList} from "~/apis/merchant";
3
+import { getProductDetail, getRecommendList } from "~/apis/merchant";
4 4
 import MerchantProductCard from "~/pages/store/home/components/MerchantProductCard.vue";
5 5
 import FCell from "~/components/FCell/FCell.vue";
6
-import type {SkuModel} from "~/apis/model/product.model";
6
+import type { SkuModel } from "~/apis/model/product.model";
7 7
 import CXBSkuPopup from "~/components/CXBSkuPopup/CXBSkuPopup.vue";
8 8
 import CXBBackTop from '~/components/CXBBackTop/CXBBackTop.vue';
9
-import {createShopping} from "~/apis/order.api";
10
-import {getAgentInfo, getCartCount, relation, removeMyRelation, xcxBanding} from "~/apis/user";
9
+import { createShopping } from "~/apis/order.api";
10
+import { getAgentInfo, getCartCount, relation, removeMyRelation, xcxBanding } from "~/apis/user";
11 11
 import {
12 12
   DyProductModel,
13 13
   JdProductModel,
14 14
   SuNingProductModel,
15 15
   TaobaoProductThirdPartyWaresModel, VipProductModel
16 16
 } from "~/apis/model/product.model";
17
-import {DcProductModel} from "~/apis/model/dacang.model";
18
-import {CDN_URL} from "~/config/app";
17
+import { DcProductModel } from "~/apis/model/dacang.model";
18
+import { CDN_URL } from "~/config/app";
19 19
 import dayjs from "dayjs";
20
-import {getShareId} from "~/apis/product";
21
-import {debounce} from "lodash-es";
20
+import { getShareId } from "~/apis/product";
21
+import { debounce } from "lodash-es";
22 22
 
23 23
 const usePageStore = usePageStoreWidthOut()
24 24
 
@@ -54,9 +54,9 @@ const state = reactive({
54 54
   goods: {
55 55
     price: '4599.00',
56 56
     imagePath:
57
-        '//img14.360buyimg.com/n4/jfs/t1/215845/12/3788/221990/618a5c4dEc71cb4c7/7bd6eb8d17830991.jpg'
57
+      '//img14.360buyimg.com/n4/jfs/t1/215845/12/3788/221990/618a5c4dEc71cb4c7/7bd6eb8d17830991.jpg'
58 58
   },
59
-//1表示立即购买;2表示加入购物车,3表示立即兑换
59
+  //1表示立即购买;2表示加入购物车,3表示立即兑换
60 60
   flag: '1',
61 61
   isNew: '0',
62 62
   cartNum: 1,
@@ -64,7 +64,7 @@ const state = reactive({
64 64
   shareImage: '',
65 65
 })
66 66
 const detail: any = ref(null)
67
-
67
+let isShow = ref(false)
68 68
 onShow(() => {
69 69
   uni.showLoading({
70 70
     title: '数据加载中',
@@ -87,10 +87,16 @@ uni.showShareMenu({
87 87
   menus: ['shareAppMessage', 'shareTimeline']
88 88
 })
89 89
 onLoad((option: any) => {
90
+  uni.showLoading({
91
+    title: '数据加载中',
92
+    icon: 'none'
93
+  })
94
+  console.log(option);
90 95
   // const id = '4858'
91 96
   state.id = option.id
92 97
   // state.id = 4858
93 98
   const fromShareId = option.shareID
99
+  // console.log(fromShareId);
94 100
   // console.log(fromShareId + '---share_id...')
95 101
   // if (state.shareId) {
96 102
   if (fromShareId) {
@@ -108,45 +114,58 @@ onLoad((option: any) => {
108 114
     state.recommendList = res.list
109 115
   })
110 116
 
111
-  getShareId({ pid: state.id, type: 1}).then(res => {
117
+  getShareId({ pid: state.id, type: 1 }).then(res => {
112 118
     state.shareId = res.share_id
113 119
     userStore.setRedirectPage(`/pages/store/product/detail?id=${state.id}&from=share&shareID=${state.shareId}`, 'page')
114 120
 
115 121
   })
116 122
 
123
+
124
+
117 125
 })
118 126
 
119 127
 function loadProductDetail() {
120 128
 
121 129
   getProductDetail(state.id).then(res => {
122
-    // console.log(res)
123
-    detail.value = res
124
-
125
-    state.shareImage = detail.value.image
126
-    if (res && res.mer_id && res.mer_id === '148') {
127
-      if (detail.value && detail.value.price ) {
128
-        detail.value.price = detail.value.price * 30
130
+    // console.log('我是res.message', res.message)
131
+    // console.log(res);
132
+    if (res.status === 200) {
133
+      detail.value = res.data
134
+
135
+      state.shareImage = detail.value.image
136
+      if (res && res.mer_id && res.mer_id === '148') {
137
+        if (detail.value && detail.value.price) {
138
+          detail.value.price = detail.value.price * 30
139
+        }
129 140
       }
130
-    }
131
-    state.isRelation = res.isRelation
132
-    if (res.merchant_type == 2) {
133
-      xcxBanding({
134
-        mer_id: res.mer_id,
135
-        share_id: state.shareId
136
-      }).then(res => {
137
-        console.info(res)
141
+      state.isRelation = res.isRelation
142
+      if (res.merchant_type == 2) {
143
+        xcxBanding({
144
+          mer_id: res.mer_id,
145
+          share_id: state.shareId
146
+        }).then(res => {
147
+          console.info(res)
148
+        })
149
+      }
150
+
151
+      // if (detail.value.mer_id === '148') {
152
+      // }
153
+      uni.hideLoading()
154
+    } else {
155
+      isShow.value = true
156
+      uni.setNavigationBarTitle({
157
+        title: '商品下架不存在'
138 158
       })
159
+      uni.hideLoading()
160
+
139 161
     }
140 162
 
141
-    // if (detail.value.mer_id === '148') {
142
-    // }
143
-    uni.hideLoading()
144 163
   }).catch(error => {
145 164
     // console.log(error)
146 165
     uni.showToast({
147 166
       icon: "none",
148 167
       title: error
149
-    }).then( () => {
168
+    }).then(() => {
150 169
       setTimeout(() => {
151 170
         uni.navigateBack()
152 171
       }, 500)
@@ -201,7 +220,7 @@ onShareTimeline(() => {
201 220
 
202 221
   return {
203 222
     title: `${detail.value.store_name}`,
204
-    imageUrl:  state.shareImage,
223
+    imageUrl: state.shareImage,
205 224
     query: `id=${state.id}&from=share&shareID=${state.shareId}`
206 225
   }
207 226
 
@@ -290,7 +309,7 @@ function handleCreateShopping() {
290 309
     // product_attr_unique: JSON.stringify(state.currentSku),
291 310
     product_attr_unique: state.currentSku.unique,
292 311
     cart_num: state.cartNum,
293
-    is_new: (state.flag === '1' || state.flag === '3') ? '1': '0'
312
+    is_new: (state.flag === '1' || state.flag === '3') ? '1' : '0'
294 313
   }).then(res => {
295 314
     // console.log(res)
296 315
     if (res.cart_id) {
@@ -316,7 +335,7 @@ function handleCreateShopping() {
316 335
         title: error,
317 336
         icon: 'none'
318 337
       })
319
-    } else if (error === '库存不足')  {
338
+    } else if (error === '库存不足') {
320 339
       return uni.showToast({
321 340
         title: error,
322 341
         icon: 'none'
@@ -335,7 +354,7 @@ function handleCreateShopping() {
335 354
  *
336 355
  * @param flag //1表示立即购买;2表示加入购物车,3表示立即兑换
337 356
  */
338
-function handleOrderConfirm(flag: '1' | '2'| '3') {
357
+function handleOrderConfirm(flag: '1' | '2' | '3') {
339 358
   debounce(() => {
340 359
     if (!userStore.uid) {
341 360
       return uni.showToast({
@@ -350,7 +369,7 @@ function handleOrderConfirm(flag: '1' | '2'| '3') {
350 369
 
351 370
       })
352 371
     }
353
-  }, 150,  {
372
+  }, 150, {
354 373
     'leading': true,
355 374
     'trailing': false
356 375
   })
@@ -368,17 +387,17 @@ function handleCountChange(val) {
368 387
   // console.log(val)
369 388
   // detail.value.
370 389
   // if (val > 0) {
371
-    state.cartNum = val
390
+  state.cartNum = val
372 391
   // }
373 392
 }
374 393
 function handleProductItemClick(
375
-    item:
376
-        JdProductModel
377
-        & DcProductModel
378
-        & DyProductModel
379
-        & SuNingProductModel
380
-        & TaobaoProductThirdPartyWaresModel
381
-        & VipProductModel
394
+  item:
395
+    JdProductModel
396
+    & DcProductModel
397
+    & DyProductModel
398
+    & SuNingProductModel
399
+    & TaobaoProductThirdPartyWaresModel
400
+    & VipProductModel
382 401
 ) {
383 402
   // function navigateToDetail(params) {
384 403
   //   let otherDetailUrl = `/pages/store/product/other`
@@ -421,7 +440,7 @@ function handleRelation() {
421 440
 
422 441
 function handleRemoveRelation() {
423 442
   // console.log('on....')
424
-  removeMyRelation({type: 1, type_id: state.id}).then(res => {
443
+  removeMyRelation({ type: 1, type_id: state.id }).then(res => {
425 444
     // isCare.value = false
426 445
     state.isRelation = false
427 446
 
@@ -464,10 +483,10 @@ let Scroll_X = ref(0)
464 483
 const headerClass = ref('')
465 484
 onPageScroll((page) => {
466 485
   // console.log('滚轮事件触发了',page.scrollTop.toFixed());
467
-  
486
+
468 487
   // console.log(page.scrollTop.toFixed(),'距离顶部的距离')
469 488
   Scroll_X.value = Number(page.scrollTop.toFixed())
470
-  if (page.scrollTop >= 76 ) {
489
+  if (page.scrollTop >= 76) {
471 490
     headerClass.value = 'bg-white !text-gray-900'
472 491
   } else {
473 492
     headerClass.value = ''
@@ -476,27 +495,21 @@ onPageScroll((page) => {
476 495
 </script>
477 496
 
478 497
 <template>
498
+  <!-- 商品上架状态 -->
479 499
   <div class="flex flex-col gap-3 pb-20" v-if="detail">
480
-    <CXBBackTop :Scroll_X="Scroll_X"/>
500
+    <CXBBackTop :Scroll_X="Scroll_X" />
481 501
     <div class="bg-white ">
482 502
       <div class="w-screen h-94">
483
-        <swiper
484
-            v-if="detail && detail.slider_image"
485
-            :indicator-dots="state.indicatorDots"
486
-            indicator-active-color="#e93323"
487
-            :autoplay="state.autoplay"
488
-            :circular="state.circular"
489
-            :interval="state.interval"
490
-            :duration="state.duration"
491
-            class="w-full h-94"
492
-        >
503
+        <swiper v-if="detail && detail.slider_image" :indicator-dots="state.indicatorDots"
504
+          indicator-active-color="#e93323" :autoplay="state.autoplay" :circular="state.circular"
505
+          :interval="state.interval" :duration="state.duration" class="w-full h-94">
493 506
           <swiper-item v-for="(item, index) in detail.slider_image" :key="index">
494
-            <image :src="item" @tap="previewImage(index)" class="!w-full !h-full" mode="aspectFill"/>
507
+            <image :src="item" @tap="previewImage(index)" class="!w-full !h-full" mode="aspectFill" />
495 508
           </swiper-item>
496 509
         </swiper>
497 510
       </div>
498 511
       <div class="bg-gradient-to-r from-[#fe7577] to-[#fe0032] h-20 mt-3 flex items-center p-3 justify-between"
499
-           v-if="detail.seckill == 1">
512
+        v-if="detail.seckill == 1">
500 513
         <div class="flex flex-col">
501 514
           <div class="flex gap-2 items-center text-white">
502 515
             <div class="text-[30px] font-bold">
@@ -505,16 +518,15 @@ onPageScroll((page) => {
505 518
             <image :src="miaoshaIcon" mode="widthFix" class="w-10"></image>
506 519
           </div>
507 520
           <div class="text-white text-xs">
508
-            即将恢复原价 ¥{{detail.ot_price}}
521
+            即将恢复原价 ¥{{ detail.ot_price }}
509 522
           </div>
510 523
         </div>
511 524
         <div class="flex flex-col items-center gap-2 justify-center">
512 525
           <image :src="xiaoshimiaoshaIcon" class="w-17 h-4" model="widthFix"></image>
513 526
           <div class="text-white " v-if="detail.seckill_s == 1">
514
-            <div class="text-xs"
515
-                 >
516
-            距秒杀结束</div>
517
-            <nut-countdown :end-time="new Date(detail.seckill_date_end).getTime() + 60 * 1000" ></nut-countdown>
527
+            <div class="text-xs">
528
+              距秒杀结束</div>
529
+            <nut-countdown :end-time="new Date(detail.seckill_date_end).getTime() + 60 * 1000"></nut-countdown>
518 530
           </div>
519 531
           <div class="text-white" v-if="detail.seckill_s == 2">
520 532
             <div class="">
@@ -527,18 +539,14 @@ onPageScroll((page) => {
527 539
         </div>
528 540
 
529 541
       </div>
530
-      <div class="bg-black bg-op-30 fixed top-3  rounded-full right-3 h-6 w-6 flex flex-col justify-center items-center z-10"
531
-           @click="toggleRelation"
532
-      >
533
-        <div class="h4 w-4"
534
-             :class="state.isRelation ? 'bg-primary i-tabler-star-filled' : 'i-tabler-star text-white'"
535
-
536
-        ></div>
542
+      <div
543
+        class="bg-black bg-op-30 fixed top-3  rounded-full right-3 h-6 w-6 flex flex-col justify-center items-center z-10"
544
+        @click="toggleRelation">
545
+        <div class="h4 w-4" :class="state.isRelation ? 'bg-primary i-tabler-star-filled' : 'i-tabler-star text-white'">
546
+        </div>
537 547
       </div>
538 548
 
539
-      <div
540
-          class="flex flex-col p-3 gap-3"
541
-      >
549
+      <div class="flex flex-col p-3 gap-3">
542 550
         <div class="flex flex-row  items-center text-[#FE0032] font-bold text-lg gap-2">
543 551
           <div v-if="is148Merchant && detail.price" class="flex justify-end items-end gap-2">
544 552
             <div class="!text-[24px]">{{ Number.parseFloat(detail.price).toFixed(2) }} </div>
@@ -549,18 +557,14 @@ onPageScroll((page) => {
549 557
               ¥ {{ detail.price }}
550 558
             </div>
551 559
           </div>
552
-          <div
553
-              v-if="!is148Merchant"
554
-              class="line-through text-xs font-bold flex text-gray-600"
555
-          >
560
+          <div v-if="!is148Merchant" class="line-through text-xs font-bold flex text-gray-600">
556 561
             原价 ¥ {{ detail.ot_price }}
557 562
           </div>
558 563
         </div>
559
-        <div
560
-            v-if="!is148Merchant"
561
-            class="border border-solid border-1 border-red rounded flex text-xs items-center text-[#FE0032] w-fit">
562
-          <image src="https://cdn.bjtdba.com/vod/image/2023-09-15/20230915160858609.png"
563
-                 mode="widthFix" class="!w-8 h-4"></image>
564
+        <div v-if="!is148Merchant"
565
+          class="border border-solid border-1 border-red rounded flex text-xs items-center text-[#FE0032] w-fit">
566
+          <image src="https://cdn.bjtdba.com/vod/image/2023-09-15/20230915160858609.png" mode="widthFix" class="!w-8 h-4">
567
+          </image>
564 568
           <div class="px-2 flex items-center jusitify-center" v-if="detail.yanglao">
565 569
             <div>
566 570
               养老金 ¥{{ detail.yanglao }}
@@ -570,16 +574,14 @@ onPageScroll((page) => {
570 574
 
571 575
         <div class="flex flex-col gap-2">
572 576
           <div class="flex font-bold flex items-center gap-1" v-if="detail && detail.store_name">
573
-           <div class="flex bg-primary text-white rounded text-[10px] text-center">
574
-             <div class=" h-4 w-4 ">仓</div></div>
577
+            <div class="flex bg-primary text-white rounded text-[10px] text-center">
578
+              <div class=" h-4 w-4 ">仓</div>
579
+            </div>
575 580
             <div class=" justify-center items-center" v-html="detail.store_name">
576 581
             </div>
577 582
           </div>
578
-          <div
579
-              v-if="detail.store_info"
580
-              class="text-gray-600 text-sm w-fit px-1"
581
-               :class="is148Merchant ? 'border border-solid border-gray' : ''"
582
-          >
583
+          <div v-if="detail.store_info" class="text-gray-600 text-sm w-fit px-1"
584
+            :class="is148Merchant ? 'border border-solid border-gray' : ''">
583 585
             {{ detail.store_info }}
584 586
           </div>
585 587
         </div>
@@ -587,11 +589,11 @@ onPageScroll((page) => {
587 589
         <div class="flex gap-3 text-[12px]">
588 590
           <div>分享:</div>
589 591
           <div class="flex-1  items-center flex  ">
590
-              <button open-type="share" class="flex gap-2 w-1/2 text-[12px]">
592
+            <button open-type="share" class="flex gap-2 w-1/2 text-[12px]">
591 593
 
592 594
               <image :src="wx_shareImg" mode="widthFix" class="w-5 h-5"></image>
593 595
               <div>微信</div>
594
-              </button>
596
+            </button>
595 597
 
596 598
             <div class="flex gap-2 w-1/2" @click="shareShowTips = true">
597 599
               <image :src="pyqImg" mode="widthFix" class="w-5 h-5"></image>
@@ -603,29 +605,24 @@ onPageScroll((page) => {
603 605
       </div>
604 606
     </div>
605 607
 
606
-    <FCell
607
-        arrow
608
-        @tap="state.isShowSku = !state.isShowSku"
609
-    >
608
+    <FCell arrow @tap="state.isShowSku = !state.isShowSku">
610 609
       <template #title>
611 610
         <div class="flex items-center" v-if="state.currentSku">
612 611
           <div class="font-bold">规格:</div>
613
-<!--          <div v-for="(key, index) in Object.keys(detail.sku)"-->
614
-<!--               :key="index"-->
615
-<!--               class="pl-2 text-sm"-->
616
-<!--          >-->
617
-<!--            {{ key }}-->
618
-<!--          </div>-->
619
-          {{state.currentSku.sku}}
612
+          <!--          <div v-for="(key, index) in Object.keys(detail.sku)"-->
613
+          <!--               :key="index"-->
614
+          <!--               class="pl-2 text-sm"-->
615
+          <!--          >-->
616
+          <!--            {{ key }}-->
617
+          <!--          </div>-->
618
+          {{ state.currentSku.sku }}
620 619
         </div>
621 620
 
622 621
       </template>
623 622
     </FCell>
624 623
 
625 624
     <!-- 店铺信息 -->
626
-    <div
627
-        @tap="handleShowMerchant(detail.mer_id)"
628
-        class="flex gap-3 p-3 bg-white">
625
+    <div @tap="handleShowMerchant(detail.mer_id)" class="flex gap-3 p-3 bg-white">
629 626
       <div v-if="detail && detail.merchant">
630 627
         <image :src="detail.merchant.mer_avatar" mode="widthFix" class=" h-12 w-12"></image>
631 628
       </div>
@@ -634,9 +631,7 @@ onPageScroll((page) => {
634 631
           <div>{{ detail.merchant.mer_name }}</div>
635 632
           <div class="i-tabler-chevron-right text-gray"></div>
636 633
         </div>
637
-        <div
638
-            class="border border-solid border-red text-red text-xs px-1 rounded-full w-fit"
639
-        >
634
+        <div class="border border-solid border-red text-red text-xs px-1 rounded-full w-fit">
640 635
           进入店铺
641 636
         </div>
642 637
       </div>
@@ -645,26 +640,19 @@ onPageScroll((page) => {
645 640
     <div class="flex flex-col bg-white">
646 641
       <div class="p-3">
647 642
         <div
648
-            class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
643
+          class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
649 644
           <div class="pl-2">
650 645
             为你推荐
651 646
           </div>
652 647
         </div>
653 648
       </div>
654 649
       <div class="pb-3">
655
-        <scroll-view
656
-            class=" whitespace-nowrap  w-screen  text-white text-sm"
657
-            :scroll-with-animation="true"
658
-            :scroll-x="true"
659
-            :show-scrollbar="false"
660
-        >
650
+        <scroll-view class=" whitespace-nowrap  w-screen  text-white text-sm" :scroll-with-animation="true"
651
+          :scroll-x="true" :show-scrollbar="false">
661 652
           <div class="pl-3" v-if="detail && detail.merchant">
662
-            <div v-for="(item, index) in detail.merchant.recommend"
663
-                 :key="index"
664
-                 @click="handleProductItemClick(item)"
665
-                 class="flex inline-flex items-center justify-center relative "
666
-            >
667
-              <MerchantProductCard :item="item" exClass="w-40 border border-solid border-gray-200 mr-3"/>
653
+            <div v-for="(item, index) in detail.merchant.recommend" :key="index" @click="handleProductItemClick(item)"
654
+              class="flex inline-flex items-center justify-center relative ">
655
+              <MerchantProductCard :item="item" exClass="w-40 border border-solid border-gray-200 mr-3" />
668 656
             </div>
669 657
 
670 658
           </div>
@@ -676,7 +664,7 @@ onPageScroll((page) => {
676 664
     <div class="flex flex-col justify-center bg-white">
677 665
       <div class="p-3">
678 666
         <div
679
-            class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-800 before:rounded relative inline-block">
667
+          class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-800 before:rounded relative inline-block">
680 668
           <div class="pl-2">
681 669
             图文详情
682 670
           </div>
@@ -694,7 +682,7 @@ onPageScroll((page) => {
694 682
     <div class="flex flex-col pb-safe gap-3">
695 683
       <div class="p-3 bg-white">
696 684
         <div
697
-            class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
685
+          class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
698 686
           <div class="pl-2">
699 687
             猜你喜欢
700 688
           </div>
@@ -702,11 +690,8 @@ onPageScroll((page) => {
702 690
       </div>
703 691
       <div class="pb-3 px-3" v-if="state.recommendList">
704 692
         <grid-view type="masonry" cross-axis-count="2" cross-axis-gap="10px" main-axis-gap="10px">
705
-          <div v-for="(item, index) in state.recommendList"
706
-               :key="index"
707
-               @click="handleProductItemClick(item)"
708
-          >
709
-            <MerchantProductCard :item="item"/>
693
+          <div v-for="(item, index) in state.recommendList" :key="index" @click="handleProductItemClick(item)">
694
+            <MerchantProductCard :item="item" />
710 695
 
711 696
           </div>
712 697
         </grid-view>
@@ -715,57 +700,75 @@ onPageScroll((page) => {
715 700
     </div>
716 701
 
717 702
   </div>
718
-  <div class="fixed bottom-0 w-screen pb-safe bg-white">
703
+  <!-- 商品下架 -->
704
+  <div class="relative w-screen " v-if="isShow">
705
+    <CXBBackTop :Scroll_X="Scroll_X" />
706
+    <div class="box-out">
707
+      <div class="flex-box pb-3 px-3 ">
708
+        <div class="img-div">
709
+          <image lazy-load src="../../../static/icon/商品下架不存在@3x.png" mode="widthFix" class=" top-0 right-0 sold-out ">
710
+          </image>
711
+        </div>
712
+        <div class="out-conter">该商品下架不存在</div>
713
+      </div>
714
+
715
+    </div>
716
+    <div class="flex flex-col pb-safe gap-3">
717
+      <div class="p-3 bg-white">
718
+        <div
719
+          class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
720
+          <div class="pl-2">
721
+            猜你喜欢
722
+          </div>
723
+        </div>
724
+      </div>
725
+      <div class="pb-3 px-3" v-if="state.recommendList.length != 0">
726
+        <grid-view type="masonry" cross-axis-count="2" cross-axis-gap="10px" main-axis-gap="10px">
727
+          <div v-for="(item, index) in state.recommendList" :key="index" @click="handleProductItemClick(item)">
728
+            <MerchantProductCard :item="item" />
729
+
730
+          </div>
731
+        </grid-view>
732
+      </div>
733
+
734
+    </div>
735
+  </div>
736
+  <!-- 底部栏 -->
737
+  <div class="fixed bottom-0 w-screen pb-safe bg-white" v-if="detail">
719 738
     <div class="flex flex-row justify-between py-2 ">
720 739
       <div class=" flex justify-around">
721
-        <div
722
-            @tap="handleShowMerchant(detail.mer_id)"
723
-            class="flex flex-col justify-center items-center pl-4"
724
-        >
725
-<!--          <div class="i-tabler-building-store"></div>-->
740
+        <div @tap="handleShowMerchant(detail.mer_id)" class="flex flex-col justify-center items-center pl-4">
741
+          <!--          <div class="i-tabler-building-store"></div>-->
726 742
           <image :src="shangpinxiangqing_dianpu" mode="widthFix" class="w-6 h-6"></image>
727 743
           <div class="text-[11px]">店铺</div>
728 744
         </div>
729 745
 
730
-        <div
731
-            @tap="handleShowCustomer"
732
-            class="flex flex-col justify-center items-center pl-4">
733
-<!--          <div class="i-tabler-headset"></div>-->
746
+        <div @tap="handleShowCustomer" class="flex flex-col justify-center items-center pl-4">
747
+          <!--          <div class="i-tabler-headset"></div>-->
734 748
           <image :src="shangpinxiangqing_kefu" mode="widthFix" class="w-6 h-6"></image>
735 749
 
736 750
           <div class="text-[11px]">客服</div>
737 751
         </div>
738
-        <div
739
-            @tap="handleShowShopCart"
740
-            class="flex flex-col justify-center items-center pl-4 relative">
741
-          <div class="bg-primary rounded-full w-3 h-3 text-[9px] text-white justify-center items-center absolute top--1 right--1 text-center"
742
-               v-if="state.cartCount"
743
-          >
744
-            {{state.cartCount}}
752
+        <div @tap="handleShowShopCart" class="flex flex-col justify-center items-center pl-4 relative">
753
+          <div
754
+            class="bg-primary rounded-full w-3 h-3 text-[9px] text-white justify-center items-center absolute top--1 right--1 text-center"
755
+            v-if="state.cartCount">
756
+            {{ state.cartCount }}
745 757
           </div>
746 758
           <image :src="shangpinxiangqing_gouwuche" mode="widthFix" class="w-6 h-6"></image>
747 759
 
748
-<!--          <div class="i-tabler-shopping-cart"></div>-->
760
+          <!--          <div class="i-tabler-shopping-cart"></div>-->
749 761
           <div class="text-[11px]">购物车</div>
750 762
         </div>
751 763
       </div>
752 764
       <div class="flex flex-row text-sm text-white gap-2 pr-3">
753
-        <div
754
-            @tap="handleAddCart"
755
-            v-if="!is148Merchant"
756
-            class="bg-[#FFA319] rounded-full w-25 flex justify-center items-center h-9">
765
+        <div @tap="handleAddCart" v-if="!is148Merchant"
766
+          class="bg-[#FFA319] rounded-full w-25 flex justify-center items-center h-9">
757 767
           加入购物车
758 768
         </div>
759
-        <div
760
-            class="bg-[#F94032] rounded-full w-25 flex justify-center items-center h-9"
761
-        >
762
-          <div v-if="is148Merchant"
763
-               @click="handleOrderConfirm('3')"
764
-          >立即兑换</div>
765
-          <div
766
-              v-else
767
-              @click="handleOrderConfirm('1')"
768
-          >立即购买</div>
769
+        <div class="bg-[#F94032] rounded-full w-25 flex justify-center items-center h-9">
770
+          <div v-if="is148Merchant" @click="handleOrderConfirm('3')">立即兑换</div>
771
+          <div v-else @click="handleOrderConfirm('1')">立即购买</div>
769 772
         </div>
770 773
       </div>
771 774
     </div>
@@ -773,73 +776,97 @@ onPageScroll((page) => {
773 776
 
774 777
   </div>
775 778
 
776
-  <CXBSkuPopup
777
-      v-model:show="state.isShowSku"
778
-      :detail="detail"
779
-      @selected:item="onSelectedSku"
780
-      @submit="handleCreateShopping"
781
-      @count-change="handleCountChange"
782
-  />
783
-<!--  <nut-sku-->
784
-<!--      v-model:visible="state.isShowSku"-->
785
-<!--      :goods="state.goods"-->
786
-<!--      @selectSku="selectSku"-->
787
-<!--  >-->
788
-<!--    &lt;!&ndash; 商品展示区,价格区域 &ndash;&gt;-->
789
-<!--    <template #sku-header-price>-->
790
-<!--      <div>-->
791
-<!--        <nut-price :price="goods.price" :needSymbol="true" :thousands="false"> </nut-price>-->
792
-<!--        <span class="tag"></span>-->
793
-<!--      </div>-->
794
-<!--    </template>-->
795
-<!--  </nut-sku>-->
779
+  <CXBSkuPopup v-model:show="state.isShowSku" :detail="detail" @selected:item="onSelectedSku"
780
+    @submit="handleCreateShopping" @count-change="handleCountChange" />
781
+  <!--  <nut-sku-->
782
+  <!--      v-model:visible="state.isShowSku"-->
783
+  <!--      :goods="state.goods"-->
784
+  <!--      @selectSku="selectSku"-->
785
+  <!--  >-->
786
+  <!--    &lt;!&ndash; 商品展示区,价格区域 &ndash;&gt;-->
787
+  <!--    <template #sku-header-price>-->
788
+  <!--      <div>-->
789
+  <!--        <nut-price :price="goods.price" :needSymbol="true" :thousands="false"> </nut-price>-->
790
+  <!--        <span class="tag"></span>-->
791
+  <!--      </div>-->
792
+  <!--    </template>-->
793
+  <!--  </nut-sku>-->
796 794
 
797 795
 
798 796
   <nut-overlay v-model:visible="shareShowTips" :lock-scroll="true">
799
-        <image src="https://cdn.bjtdba.com/vod/image/2023-09-16/20230916194347287.png"
800
-               mode="widthFix" class="absolute top-0 right-0"
801
-        ></image>
802
-
803
-<!--    <div class="flex flex-col justify-center items-center w-full h-full"-->
804
-<!--    >-->
805
-<!--      <div class="bg-white">-->
806
-<!--        <image :src="currentItem.image_fake" mode="widthFix" class="w-60"></image>-->
807
-<!--        <div class="bg-white p-3 flex justify-around gap-3">-->
808
-<!--          <div class="flex flex-col text-[12px] justify-center items-center" @tap.stop="shareImage">-->
809
-<!--            <image :src="wechatImg" mode="widthFix" class="w-8 h-8"></image>-->
810
-<!--            <div>微信</div>-->
811
-<!--          </div>-->
812
-<!--          <div class="flex flex-col text-[12px] justify-center items-center" @tap.stop="shareImage">-->
813
-<!--            <image :src="pyqImg" mode="widthFix" class="w-8 h-8"></image>-->
814
-<!--            <div>朋友圈</div>-->
815
-<!--          </div>-->
816
-<!--          <div class="flex flex-col text-[12px] justify-center items-center" @tap.stop="shareImage">-->
817
-<!--            <image :src="bctpImg" mode="widthFix" class="w-8 h-8"></image>-->
818
-<!--            <div>保存图片</div>-->
819
-<!--          </div>-->
820
-<!--        </div>-->
821
-<!--      </div>-->
822
-
823
-<!--    </div>-->
797
+    <image :lazy-load="true" src="https://cdn.bjtdba.com/vod/image/2023-09-16/20230916194347287.png" mode="widthFix"
798
+      class="absolute top-0 right-0"></image>
799
+
800
+    <!--    <div class="flex flex-col justify-center items-center w-full h-full"-->
801
+    <!--    >-->
802
+    <!--      <div class="bg-white">-->
803
+    <!--        <image :src="currentItem.image_fake" mode="widthFix" class="w-60"></image>-->
804
+    <!--        <div class="bg-white p-3 flex justify-around gap-3">-->
805
+    <!--          <div class="flex flex-col text-[12px] justify-center items-center" @tap.stop="shareImage">-->
806
+    <!--            <image :src="wechatImg" mode="widthFix" class="w-8 h-8"></image>-->
807
+    <!--            <div>微信</div>-->
808
+    <!--          </div>-->
809
+    <!--          <div class="flex flex-col text-[12px] justify-center items-center" @tap.stop="shareImage">-->
810
+    <!--            <image :src="pyqImg" mode="widthFix" class="w-8 h-8"></image>-->
811
+    <!--            <div>朋友圈</div>-->
812
+    <!--          </div>-->
813
+    <!--          <div class="flex flex-col text-[12px] justify-center items-center" @tap.stop="shareImage">-->
814
+    <!--            <image :src="bctpImg" mode="widthFix" class="w-8 h-8"></image>-->
815
+    <!--            <div>保存图片</div>-->
816
+    <!--          </div>-->
817
+    <!--        </div>-->
818
+    <!--      </div>-->
819
+
820
+    <!--    </div>-->
824 821
   </nut-overlay>
825 822
 </template>
826 823
 <style>
827 824
 page {
828 825
   background-color: #f8f8f8;
829 826
 }
830
- button {
831
-   margin: 0;
832
-   padding: 0;
833
-   outline: none;
834
-   border-radius: 0;
835
-   background-color: transparent;
836
-   line-height: inherit;
837
- }
827
+
828
+button {
829
+  margin: 0;
830
+  padding: 0;
831
+  outline: none;
832
+  border-radius: 0;
833
+  background-color: transparent;
834
+  line-height: inherit;
835
+}
838 836
 
839 837
 button::after {
840 838
   border: none;
841 839
 }
842 840
 
841
+.box-out {
842
+  background: #f8f8f8;
843
+  height: 200px;
844
+}
845
+
846
+.flex-box {
847
+  background: #ffffff;
848
+  box-shadow: 3px;
849
+  height: 80%;
850
+  display: flex;
851
+  flex-direction: column;
852
+  justify-content: space-evenly;
853
+}
854
+
855
+.img-div {
856
+  width: 100%;
857
+
858
+}
859
+
860
+.sold-out {
861
+  display: block;
862
+  width: 120px;
863
+  height: 120px;
864
+  margin: 0 auto;
865
+}
866
+
867
+.out-conter {
868
+  text-align: center;
869
+}
843 870
 </style>
844 871
 <route lang="yaml">
845 872
 style:

+ 317 - 161
src/pages/store/product/other.vue

@@ -9,27 +9,37 @@ import {
9 9
   getVipProductDetail
10 10
 } from "~/apis/product";
11 11
 import CXBBasePage from "~/components/CXBBasePage/CXBBasePage.vue";
12
+import MerchantProductCard from "~/pages/store/home/components/MerchantProductCard.vue";
12 13
 import type {
14
+  DyProductModel,
13 15
   IProductDetail,
14 16
   JdProductDetailModel,
17
+  JdProductModel,
18
+  SuNingProductModel,
15 19
   TaobaoProductThirdPartyWaresModel,
16
-  TaobaoWaresDetail
20
+  TaobaoWaresDetail,
21
+  VipProductModel
17 22
 } from "~/apis/model/product.model";
18 23
 import FPrice from "~/components/FPrice/FPrice.vue";
19 24
 import FButton from "~/components/FButton/FButton.vue";
20 25
 import CXBButton from "~/components/CXBButton/CXBButton.vue";
21 26
 import CXBBackTop from "~/components/CXBBackTop/CXBBackTop.vue";
22
-import {debounce, merge} from "lodash-es";
27
+import { debounce, merge } from "lodash-es";
23 28
 
24
-import {useDebounceFn} from '@vueuse/core';
29
+import { useDebounceFn } from '@vueuse/core';
25 30
 
26 31
 import dayjs from "dayjs";
27
-import {decodeBase64} from "~/utils/http/helper";
28
-import {CDN_URL} from "~/config/app";
32
+import { decodeBase64 } from "~/utils/http/helper";
33
+import { CDN_URL } from "~/config/app";
34
+import { getRecommendList } from "~/apis/merchant";
35
+import type { DcProductModel } from "~/apis/model/dacang.model";
29 36
 
30 37
 const discount_coupon_bg_220804Image = CDN_URL + '/static/assets/discount_coupon_bg_220804.png'
31 38
 const productId = ref('')
32
-//
39
+//推荐商品列表
40
+let skuInfo = reactive({
41
+  recommendList: []
42
+})
33 43
 
34 44
 const userStore = useUserStore()
35 45
 const isSubmit = ref(false)
@@ -55,149 +65,238 @@ const state = reactive({
55 65
   data: {},
56 66
   shareId: ''
57 67
 })
68
+const isShow = ref(false)
58 69
 const detail = ref<IProductDetail>()
70
+const detailclone = ref<IProductDetail>()
59 71
 onLoad((options: any) => {
60 72
 
61 73
   const data: Partial<IProductDetail> = JSON.parse(decodeBase64(options.params))
62
-  // console.log(data)
63
-  mergeProductDetail(data)
74
+  console.log('我是options数据', data)
75
+
64 76
   // if (options.platform && options.id) {
65 77
   uni.showLoading({
66 78
     title: '数据加载中',
67 79
     icon: 'none'
68 80
   })
81
+  mergeProductDetail(data)
69 82
   loadProductDetail(data)
70 83
   // }
71 84
 })
85
+
72 86
 onShow(() => {
73 87
   isSubmit.value = false
74 88
 })
75 89
 
90
+//猜你喜欢
91
+function YouLike() {
92
+  getRecommendList({
93
+    page: 1,
94
+    limit: 10
95
+  }).then(res => {
96
+    skuInfo.recommendList = res.list
97
+    console.log(skuInfo.recommendList);
76 98
 
99
+  })
100
+}
77 101
 
78 102
 function mergeProductDetail(data: Partial<IProductDetail> = {}) {
79
-  detail.value = merge(detail.value, data)
103
+  detailclone.value = merge(detailclone.value, data)
104
+
105
+}
106
+function mergeProductDetailclone(data: Partial<IProductDetail> = {}) {
107
+  detail.value = merge(detailclone.value, data)
108
+  console.log(detail.value);
109
+
80 110
 }
81 111
 
82 112
 function loadProductDetail(product: Partial<IProductDetail>) {
83
-  // console.log('产品id')
84
-  // console.log(product.id)
113
+  // console.log('产品id')  // console.log(product.id)
114
+
85 115
   // 京东
86 116
   if (product.platform == 6) {
87 117
     getJdProductDetail(product.id).then(res => {
88
-      const jdProduct = res[0]
89
-      // console.log(jdProduct)
90
-      mergeProductDetail({
91
-        images: jdProduct.detail,
92
-        coupon: {
93
-          amount: jdProduct.couMoney
94
-        },
95
-        ...jdProduct
96
-      })
118
+      console.log(res);
119
+      let { data, status } = res
120
+      if (status === 200) {
121
+        const jdProduct = data[0]
122
+        // console.log(jdProduct)
123
+        mergeProductDetailclone({
124
+          images: jdProduct.detail,
125
+          coupon: {
126
+            amount: jdProduct.couMoney
127
+          },
128
+          ...jdProduct
129
+        })
97 130
 
98
-      uni.hideLoading()
131
+        uni.hideLoading()
132
+      } else {
133
+        isShow.value = true
134
+        uni.setNavigationBarTitle({
135
+          title: '商品下架不存在'
136
+        })
137
+        YouLike()
138
+        uni.hideLoading()
139
+      }
99 140
     })
100 141
   }
101
-  // 淘宝
142
+  // 淘宝 *
102 143
   if (product.platform === 5) {
103 144
     getTaobaoProductDetail(product.id).then(res => {
104
-      const product = res.waresDetail
105
-      mergeProductDetail({
106
-        images: product.small_images,
107
-        coupon: {
108
-          startTime: product.couponStartTime,
109
-          endTime: product.couponEndTime
110
-        },
111
-        ...product
112
-      })
113
-      uni.hideLoading()
145
+      // console.log('taobao>>>',res);
146
+      let { status, data } = res
147
+      if (status === 200) {
148
+        const product = data.waresDetail
149
+        mergeProductDetailclone({
150
+          images: product.small_images,
151
+          coupon: {
152
+            startTime: product.couponStartTime,
153
+            endTime: product.couponEndTime
154
+          },
155
+          ...product
156
+        })
157
+        uni.hideLoading()
158
+      } else {
159
+
160
+        isShow.value = true
161
+        uni.setNavigationBarTitle({
162
+          title: '商品下架不存在'
163
+        })
164
+        YouLike()
165
+        uni.hideLoading()
166
+      }
167
+
114 168
 
115 169
     })
116 170
   }
117 171
 
118
-  // 拼多多
172
+  // 拼多多 *
119 173
   if (product.platform == 1) {
120 174
     getPddProductDetail(product.id).then(res => {
175
+      // console.log(res);
176
+      let { status, data } = res
121 177
       // detail.value = res
122
-      mergeProductDetail({
123
-        spreadUrl: res.pddlink.url,
124
-        images: res.goods_gallery_urls,
125
-        featured: res.goods_gallery_urls,
126
-        mallName: res.mall_name,
127
-        ...res
128
-        // allowance:
129
-      })
130
-
131
-      if (res.coupon_start_time > 0) {
132
-        mergeProductDetail({
133
-          coupon: {
134
-            // amount: (res.extra_coupon_amount / 100).toString(),
135
-            startTime: dayjs.unix(res.coupon_start_time).format('YYYY-MM-DD'),
136
-            endTime: dayjs.unix(res.coupon_end_time).format('YYYY-MM-DD')
137
-          },
178
+      if (status !== 200) {
179
+        isShow.value = true
180
+        uni.setNavigationBarTitle({
181
+          title: '商品下架不存在'
138 182
         })
183
+        YouLike()
184
+        uni.hideLoading()
139 185
       } else {
140
-        mergeProductDetail({
141
-          coupon: null
186
+        mergeProductDetailclone({
187
+          spreadUrl: data.pddlink.url,
188
+          images: data.goods_gallery_urls,
189
+          featured: data.goods_gallery_urls,
190
+          mallName: data.mall_name,
191
+          ...data
192
+          // allowance:
142 193
         })
194
+
195
+        if (data.coupon_start_time > 0) {
196
+          mergeProductDetailclone({
197
+            coupon: {
198
+              // amount: (res.extra_coupon_amount / 100).toString(),
199
+              startTime: dayjs.unix(data.coupon_start_time).format('YYYY-MM-DD'),
200
+              endTime: dayjs.unix(data.coupon_end_time).format('YYYY-MM-DD')
201
+            },
202
+          })
203
+        } else {
204
+          mergeProductDetailclone({
205
+            coupon: null
206
+          })
207
+        }
208
+
209
+        uni.hideLoading()
143 210
       }
144 211
 
145
-      uni.hideLoading()
146 212
 
147 213
     })
148 214
   }
149 215
 
150
-  // 唯品会
216
+  // 唯品会 *
151 217
   if (product.platform == 2) {
152 218
     getVipProductDetail(product.id).then(res => {
153 219
       // console.log(res.result[0])
154
-      const product = res.result[0]
155
-      // detail.value = product
156
-      mergeProductDetail({
157
-        featured: product.goodsCarouselPictures,
158
-        images: product.goodsDetailPictures,
159
-        mallName: '唯品自营',
160
-        ...product,
161
-        ...res
162
-      })
163
-      if (product.couponInfo) {
164
-        mergeProductDetail({
165
-          coupon: {
166
-            amount: product.couponInfo.activedAmount,
167
-            startTime: product.couponInfo.useBeginTime,
168
-            endTime: product.couponInfo.useEndTime
169
-          }
220
+      let { data, status } = res
221
+      if (status === 200) {
222
+        const product = data.result[0]
223
+        // detail.value = product
224
+        mergeProductDetailclone({
225
+          featured: product.goodsCarouselPictures,
226
+          images: product.goodsDetailPictures,
227
+          mallName: '唯品自营',
228
+          ...product,
229
+          ...res
230
+        })
231
+        if (product.couponInfo) {
232
+          mergeProductDetailclone({
233
+            coupon: {
234
+              amount: product.couponInfo.activedAmount,
235
+              startTime: product.couponInfo.useBeginTime,
236
+              endTime: product.couponInfo.useEndTime
237
+            }
238
+          })
239
+        }
240
+
241
+        uni.hideLoading()
242
+      } else {
243
+        isShow.value = true
244
+        uni.setNavigationBarTitle({
245
+          title: '商品下架不存在'
170 246
         })
247
+        YouLike()
248
+        uni.hideLoading()
171 249
       }
172 250
 
173
-      uni.hideLoading()
174 251
 
175 252
     })
176 253
   }
177
-  // 苏宁
254
+  // 苏宁 *
178 255
   if (product.platform == 3) {
179 256
     getSuProductDetail(product.id).then(res => {
180 257
       // const product = res
181
-      mergeProductDetail({
182
-        images: res.detail,
183
-        ...res
184
-      })
258
+      let { status, data } = res
259
+      if (status === 200) {
260
+        mergeProductDetailclone({
261
+          images: data.detail,
262
+          ...data
263
+        })
185 264
 
186
-      uni.hideLoading()
265
+        uni.hideLoading()
266
+
267
+      } else {
268
+        isShow.value = true
269
+        uni.setNavigationBarTitle({
270
+          title: '商品下架不存在'
271
+        })
272
+        YouLike()
273
+        uni.hideLoading()
274
+      }
187 275
 
188 276
     })
189 277
   }
190
-  // 抖音
278
+  // 抖音 *
191 279
   if (product.platform == 9) {
192 280
     getDyProductDetail(product.id).then(res => {
193 281
       console.log(res)
194
-      mergeProductDetail({
195
-        mallName: res.shopName,
196
-        images: res.imgs,
197
-        ...res
198
-      })
282
+      let { status, data } = res
283
+      if (status === 200) {
284
+        mergeProductDetailclone({
285
+          mallName: data.shopName,
286
+          images: data.imgs,
287
+          ...data
288
+        })
289
+
290
+        uni.hideLoading()
291
+      } else {
292
+        isShow.value = true
293
+        uni.setNavigationBarTitle({
294
+          title: '商品下架不存在'
295
+        })
296
+        YouLike()
297
+        uni.hideLoading()
298
+      }
199 299
 
200
-      uni.hideLoading()
201 300
 
202 301
     })
203 302
 
@@ -271,39 +370,39 @@ function handleBuyNow() {
271 370
       // console.log(detail.value.pddlink)
272 371
       // console.log(pddWx)
273 372
     } else {
274
-/*      let platformName = ''
275
-      let clipboardData = ''
276
-      if (detail.value?.platform == 5) {
277
-        platformName = '淘宝'
278
-        clipboardData = detail.value?.spreadUrl
279
-      }
280
-      if (detail.value?.platform == 9) {
281
-        platformName = '抖音'
282
-        clipboardData = detail.value?.dyZlink
283
-      }
284
-      if (detail.value?.platform == 2) {
285
-        platformName = '唯品会'
286
-        clipboardData = detail.value?.destUrl
287
-      }
288
-      if (detail.value?.platform == 3) {
289
-        platformName = '苏宁易购'
290
-        clipboardData = detail.value?.productUrlWap
291
-      }
292
-      return uni.setClipboardData({
293
-        data: clipboardData,
294
-        success(res) {
295
-          return uni.showToast({
296
-            title: `链接已复制,去【${platformName}】打开即可。`,
297
-            icon: 'none'
298
-          })
299
-        },
300
-        fail(res) {
301
-          return uni.showToast({
302
-            title: '请更新隐私协议',
303
-            icon: 'none'
304
-          })
305
-        }
306
-      })*/
373
+      /*      let platformName = ''
374
+            let clipboardData = ''
375
+            if (detail.value?.platform == 5) {
376
+              platformName = '淘宝'
377
+              clipboardData = detail.value?.spreadUrl
378
+            }
379
+            if (detail.value?.platform == 9) {
380
+              platformName = '抖音'
381
+              clipboardData = detail.value?.dyZlink
382
+            }
383
+            if (detail.value?.platform == 2) {
384
+              platformName = '唯品会'
385
+              clipboardData = detail.value?.destUrl
386
+            }
387
+            if (detail.value?.platform == 3) {
388
+              platformName = '苏宁易购'
389
+              clipboardData = detail.value?.productUrlWap
390
+            }
391
+            return uni.setClipboardData({
392
+              data: clipboardData,
393
+              success(res) {
394
+                return uni.showToast({
395
+                  title: `链接已复制,去【${platformName}】打开即可。`,
396
+                  icon: 'none'
397
+                })
398
+              },
399
+              fail(res) {
400
+                return uni.showToast({
401
+                  title: '请更新隐私协议',
402
+                  icon: 'none'
403
+                })
404
+              }
405
+            })*/
307 406
 
308 407
       // }
309 408
       return uni.showToast({
@@ -370,7 +469,7 @@ function handleBuyNow() {
370 469
 
371 470
     return {
372 471
       title: `${detail.value.store_name}`,
373
-      imageUrl:  state.shareImage,
472
+      imageUrl: state.shareImage,
374 473
       query: `id=${state.id}&from=share&shareID=${state.shareId}`
375 474
     }
376 475
 
@@ -385,16 +484,38 @@ const hasCoupon = computed(() => {
385 484
   return detail.value?.coupon && detail.value?.coupon.startTime
386 485
 })
387 486
 
487
+//跳转大仓商品详情
488
+function handleProductItemClick(
489
+  item:
490
+    JdProductModel
491
+    & DcProductModel
492
+    & DyProductModel
493
+    & SuNingProductModel
494
+    & TaobaoProductThirdPartyWaresModel
495
+    & VipProductModel
496
+) {
497
+  // function navigateToDetail(params) {
498
+  //   let otherDetailUrl = `/pages/store/product/other`
499
+  //   return uni.navigateTo({
500
+  //     url: `${otherDetailUrl}?params=${params}`
501
+  //   })
502
+  // }
503
+  // 大仓
504
+  uni.navigateTo({
505
+    url: `/pages/store/product/detail?id=${item.product_id}`
506
+  })
507
+}
508
+
388 509
 // 距离顶部距离
389 510
 let Scroll_X = ref(0)
390 511
 
391 512
 const headerClass = ref('')
392 513
 onPageScroll((page) => {
393 514
   // console.log('滚轮事件触发了',page.scrollTop.toFixed());
394
-  
515
+
395 516
   // console.log(page.scrollTop.toFixed(),'距离顶部的距离')
396 517
   Scroll_X.value = Number(page.scrollTop.toFixed())
397
-  if (page.scrollTop >= 76 ) {
518
+  if (page.scrollTop >= 76) {
398 519
     headerClass.value = 'bg-white !text-gray-900'
399 520
   } else {
400 521
     headerClass.value = ''
@@ -404,53 +525,29 @@ onPageScroll((page) => {
404 525
 <template>
405 526
   <CXBBasePage>
406 527
     <div class="relative w-screen " v-if="detail">
407
-      <swiper
408
-          v-if="detail.featured"
409
-          :indicator-dots="false"
410
-          :circular="true"
411
-          :autoplay="true"
412
-          :interval="5000"
413
-          :duration="500"
414
-          class="h-95"
415
-      >
416
-        <swiper-item
417
-            v-for="(item, index) in detail.featured"
418
-            :key="index"
419
-        >
420
-          <image
421
-              :key="index"
422
-              :src="item"
423
-              mode="aspectFill" class="h-full w-full"
424
-          />
528
+      <swiper v-if="detail.featured" :indicator-dots="false" :circular="true" :autoplay="true" :interval="5000"
529
+        :duration="500" class="h-95">
530
+        <swiper-item v-for="(item, index) in detail.featured" :key="index">
531
+          <image :key="index" :src="item" mode="aspectFill" class="h-full w-full" />
425 532
         </swiper-item>
426 533
       </swiper>
427
-      <CXBBackTop :Scroll_X="Scroll_X"/>
534
+      <CXBBackTop :Scroll_X="Scroll_X" />
428 535
       <div>
429 536
         <div class="relative p-3 bg-white">
430 537
           <div class="flex gap-2 items-end">
431 538
             <FPrice v-if="detail && detail.salePrice" :price="detail.salePrice" need-symbol :size="'large'"
432
-                    ex-class="!text-[24px]"/>
539
+              ex-class="!text-[24px]" />
433 540
             <FPrice v-if="detail && detail.price" :price="detail.price" :ex-class="'!text-gray'" need-symbol
434
-                    strike-through/>
541
+              strike-through />
435 542
           </div>
436 543
 
437 544
           <div class="font-bold py-2">{{ detail.title }}</div>
438 545
         </div>
439 546
 
440
-        <div class="relative"
441
-             v-if="hasCoupon"
442
-
443
-        >
444
-          <div
445
-              class="px-3 relative"
446
-              @tap="handleBuyNow"
447
-          >
448
-            <image :src="discount_coupon_bg_220804Image"
449
-                   mode="widthFix"
450
-                   class="w-full"
451
-            ></image>
452
-            <div class="absolute top-2 left-15 h-full w-fit text-white"
453
-            >
547
+        <div class="relative" v-if="hasCoupon">
548
+          <div class="px-3 relative" @tap="handleBuyNow">
549
+            <image lazy-load :src="discount_coupon_bg_220804Image" mode="widthFix" class="w-full"></image>
550
+            <div class="absolute top-2 left-15 h-full w-fit text-white">
454 551
               <div class=" inline-flex justify-center items-end w-full py-2">
455 552
                 <div class="text-[28px]">{{ detail.coupon.amount }}</div>
456 553
                 元代金劵
@@ -466,12 +563,8 @@ onPageScroll((page) => {
466 563
             {{ detail.mallName }}
467 564
           </div>
468 565
           <!--          <mpHtml :content=""></mpHtml>-->
469
-          <image v-for="(imgItem, index) in detail.images"
470
-                 :key="index"
471
-                 mode="widthFix"
472
-                 :src="imgItem"
473
-                 class="w-full h-full"
474
-          ></image>
566
+          <image v-for="(imgItem, index) in detail.images" :key="index" mode="widthFix" :src="imgItem"
567
+            class="w-full h-full"></image>
475 568
         </div>
476 569
       </div>
477 570
       <div class="fixed bottom-0  w-full h-15 shadow">
@@ -479,7 +572,7 @@ onPageScroll((page) => {
479 572
           <div class="flex justify-between items-center p-3">
480 573
             <div class="inline-flex items-center">
481 574
               <div class="text-sm">预估养老金</div>
482
-              <FPrice :price="detail.yanglao || detail.commission" need-symbol ex-class="text-[20px] font-bold"/>
575
+              <FPrice :price="detail.yanglao || detail.commission" need-symbol ex-class="text-[20px] font-bold" />
483 576
             </div>
484 577
             <div>
485 578
               <nut-button type="primary" @tap="handleBuyNow" :disabled="isSubmit">
@@ -490,10 +583,73 @@ onPageScroll((page) => {
490 583
         </div>
491 584
       </div>
492 585
     </div>
586
+    <div class="relative w-screen " v-if="isShow">
587
+      <CXBBackTop :Scroll_X="Scroll_X" />
588
+      <div class="box-out">
589
+        <div class="flex-box pb-3 px-3 ">
590
+          <div class="img-div">
591
+            <image lazy-load src="../../../static/icon/商品下架不存在@3x.png" mode="widthFix" class=" top-0 right-0 sold-out ">
592
+            </image>
593
+          </div>
594
+          <div class="out-conter">该商品下架不存在</div>
595
+        </div>
596
+
597
+      </div>
598
+      <div class="flex flex-col pb-safe gap-3">
599
+        <div class="p-3 bg-white">
600
+          <div
601
+            class="before:content-[''] before:block before:absolute before:w-1 before:h-full before:bg-gradient-to-b from-red-500 to-red-600 before:rounded relative inline-block">
602
+            <div class="pl-2">
603
+              猜你喜欢
604
+            </div>
605
+          </div>
606
+        </div>
607
+        <div class="pb-3 px-3" v-if="skuInfo.recommendList.length != 0">
608
+          <grid-view type="masonry" cross-axis-count="2" cross-axis-gap="10px" main-axis-gap="10px">
609
+            <div v-for="(item, index) in skuInfo.recommendList" :key="index" @click="handleProductItemClick(item)">
610
+              <MerchantProductCard :item="item" />
493 611
 
612
+            </div>
613
+          </grid-view>
614
+        </div>
615
+
616
+      </div>
617
+    </div>
494 618
   </CXBBasePage>
619
+
620
+  <!-- 下架 -->
495 621
 </template>
622
+<style scoped>
623
+.box-out {
624
+  background: #f8f8f8;
625
+  height: 200px;
626
+}
627
+
628
+.flex-box {
629
+  background: #ffffff;
630
+  box-shadow: 3px;
631
+  height: 80%;
632
+  display: flex;
633
+  flex-direction: column;
634
+  justify-content: space-evenly;
635
+}
496 636
 
637
+.img-div {
638
+  width: 100%;
639
+
640
+}
641
+
642
+.sold-out {
643
+  display: block;
644
+  width: 120px;
645
+  height: 120px;
646
+  margin: 0 auto;
647
+}
648
+
649
+.out-conter {
650
+  text-align: center;
651
+}
652
+</style>
497 653
 <route lang="yaml">
498 654
 style:
499 655
   navigationBarTitleText: 商品详情

BIN
src/static/icon/商品下架不存在@3x.png


+ 111 - 0
src/utils/http/detailhttp.ts

@@ -0,0 +1,111 @@
1
+import { cloneDeep } from 'lodash-es'
2
+import { joinTimestamp } from './helper'
3
+import { checkStatus } from './checkStatus'
4
+import type { RequestOptions, Result } from './types'
5
+import { isString } from '~/utils/is'
6
+import { getToken } from '~/utils/auth'
7
+import { RequestEnum, ResultEnum } from '~/enums/httpEnum'
8
+import { setObjToUrlParams } from '~/utils'
9
+
10
+// const { showNotify } = usePageStoreWidthOut()
11
+
12
+type UniRequestOptions = UniApp.RequestOptions & { params?: any }
13
+
14
+export interface CreateRequestOptions extends UniRequestOptions {
15
+    authenticationScheme?: string
16
+    authenticationHeader: string
17
+    urlPrefix?: string
18
+    requestOptions?: RequestOptions
19
+}
20
+
21
+export class vRequest {
22
+    private readonly options: CreateRequestOptions
23
+
24
+    constructor(options: CreateRequestOptions) {
25
+        this.options = options
26
+    }
27
+
28
+    request<T = any>(config: UniRequestOptions, options?: RequestOptions): Promise<T> {
29
+        const configTemp: CreateRequestOptions = cloneDeep(Object.assign({}, this.options, config))
30
+        const optionsTemp: RequestOptions = Object.assign({}, this.options.requestOptions, options)
31
+
32
+        const {
33
+            urlPrefix, apiUrl, joinPrefix, joinTime = true, withToken, joinParamsToUrl,
34
+            isReturnNativeResponse, isTransformResponse,
35
+        } = optionsTemp
36
+
37
+        // token header
38
+        const token = getToken()
39
+        if (token && withToken !== false) {
40
+            // jwt token
41
+            Object.assign(configTemp.header, {
42
+                [configTemp.authenticationHeader]: configTemp.authenticationScheme
43
+                    ? `${configTemp.authenticationScheme} ${token}`
44
+                    : token,
45
+            })
46
+        }
47
+
48
+        // add prefix
49
+        if (joinPrefix)
50
+            configTemp.url = `${urlPrefix}${configTemp.url}`
51
+
52
+        const params = configTemp.params || {}
53
+        if (params) {
54
+            if (configTemp.method?.toUpperCase() === RequestEnum.GET) {
55
+                // add timestamp avoid cache
56
+                if (!isString(params)) {
57
+                    configTemp.params = Object.assign(params || {}, joinTimestamp(joinTime, false))
58
+                    if (joinParamsToUrl && configTemp.params) {
59
+                        configTemp.url = setObjToUrlParams(
60
+                            configTemp.url,
61
+                            Object.assign({}, configTemp.params, configTemp.data))
62
+                        configTemp.params = undefined
63
+                    }
64
+                }
65
+                else {
66
+                    // compatible with restful style
67
+                    configTemp.url = `${config.url + params}${joinTimestamp(joinTime, true)}`
68
+                    configTemp.params = undefined
69
+                }
70
+            }
71
+        }
72
+
73
+        if (apiUrl && isString(apiUrl))
74
+            configTemp.url = `${apiUrl}${configTemp.url}`
75
+
76
+        return new Promise((resolve, reject) => {
77
+            uni.request({
78
+                url: configTemp.url,
79
+                data: configTemp.data || {},
80
+                method: configTemp.method?.toUpperCase() as UniApp.RequestOptions['method'],
81
+                header: configTemp.header || {},
82
+                success: (res) => {
83
+                    // console.log('我是商品res啊', res);
84
+
85
+                    resolve(res.data as any)
86
+
87
+                },
88
+                fail: (e) => {
89
+                    reject(e.errMsg)
90
+                },
91
+                complete() { },
92
+            })
93
+        })
94
+    }
95
+
96
+    post<T = any>(config: UniRequestOptions, options?: RequestOptions): Promise<T> {
97
+        return this.request({ ...config, method: 'POST' }, options)
98
+    }
99
+
100
+    get<T = any>(config: UniRequestOptions, options?: RequestOptions): Promise<T> {
101
+        return this.request({ ...config, method: 'GET' }, options)
102
+    }
103
+
104
+    put<T = any>(config: UniRequestOptions, options?: RequestOptions): Promise<T> {
105
+        return this.request({ ...config, method: 'PUT' }, options)
106
+    }
107
+
108
+    delete<T = any>(config: UniRequestOptions, options?: RequestOptions): Promise<T> {
109
+        return this.request({ ...config, method: 'DELETE' }, options)
110
+    }
111
+}

+ 2 - 0
src/utils/http/http.ts

@@ -80,6 +80,8 @@ export class VRequest {
80 80
                 method: configTemp.method?.toUpperCase() as UniApp.RequestOptions['method'],
81 81
                 header: configTemp.header || {},
82 82
                 success: (res) => {
83
+                    // console.log('我是res数据',res);
84
+                    
83 85
                     const data = res.data as Result
84 86
                     const _message: string = data?.message ?? ''
85 87
                     if (res.statusCode && res.statusCode !== 200) {

+ 40 - 0
src/utils/http/index.ts

@@ -1,4 +1,5 @@
1 1
 import { VRequest } from './http'
2
+import { vRequest } from './detailhttp'
2 3
 import { deepMerge } from '~/utils'
3 4
 import { ContentTypeEnum } from '~/enums/httpEnum'
4 5
 
@@ -41,6 +42,45 @@ function createRequest(options?: any) {
41 42
 
42 43
 export const defHttp = createRequest()
43 44
 
45
+
46
+//商品下架
47
+function onRequest(options?: any) {
48
+    return new vRequest(deepMerge(
49
+        {
50
+            url: '',
51
+            timeout: 5 * 1000,
52
+            authenticationScheme: 'Bearer',
53
+            authenticationHeader: 'X-Token',
54
+            // authenticationHeader: 'Authorization',
55
+            // authenticationScheme: '',
56
+
57
+            header: { 'Content-Type': ContentTypeEnum.JSON },
58
+            // 配置项,下面的选项都可以在独立的接口请求中覆盖
59
+            requestOptions: {
60
+                urlPrefix: '',
61
+                joinPrefix: false,
62
+                // 接口地址
63
+                apiUrl,
64
+                // 消息提示类型
65
+                errorMessageMode: 'message',
66
+                // 请求参数拼接到url
67
+                joinParamsToUrl: true,
68
+                //  是否加入时间戳
69
+                joinTime: true,
70
+                // 请求头是否携带token
71
+                withToken: true,
72
+                // 是否返回原生响应头 比如:需要获取响应头时使用该属性
73
+                isReturnNativeResponse: false,
74
+                // 需要对返回数据进行处理
75
+                isTransformResponse: true,
76
+            },
77
+        },
78
+        options || {},
79
+    ))
80
+}
81
+
82
+export const detailHttp = onRequest()
83
+
44 84
 // other api url
45 85
 // export const otherHttp = createRequest({
46 86
 //   requestOptions: {