Browse Source

!9 商品详情页合并,初始化
Merge pull request !9 from Bluemark/vue3_tmp

芋道源码 1 year ago
parent
commit
06943e821e

+ 0 - 20
env

@@ -1,20 +0,0 @@
-# 版本号
-SHOPRO_VERSION = v1.8.3
-
-# 正式环境接口域名
-SHOPRO_BASE_URL = https://api.shopro.sheepjs.com
-
-# 开发环境接口域名
-SHOPRO_DEV_BASE_URL = https://api.shopro.sheepjs.com
-
-# 开发环境运行端口
-SHOPRO_DEV_PORT = 3000
-
-# 接口地址前缀
-SHOPRO_API_PATH = /shop/api/
-
-# 客户端静态资源地址 空=默认使用服务端指定的CDN资源地址前缀 | local=本地  |  http(s)://xxx.xxx=自定义静态资源地址前缀
-SHOPRO_STATIC_URL = https://file.sheepjs.com
-
-# 是否开启直播  1 开启直播 | 0 关闭直播 (小程序官方后台未审核开通直播权限时请勿开启)
-SHOPRO_MPLIVE_ON = 0

+ 159 - 149
pages/goods/comment/list.vue

@@ -1,160 +1,170 @@
 <!-- 页面  -->
 <template>
-  <s-layout title="全部评价">
-    <su-tabs
-      :list="state.type"
-      :scrollable="false"
-      @change="onTabsChange"
-      :current="state.currentTab"
-    ></su-tabs>
-    <view class="ss-m-t-20">
-      <view class="list-item" v-for="item in state.pagination.data" :key="item">
-        <comment-item :item="item"></comment-item>
-      </view>
-    </view>
-    <s-empty v-if="state.pagination.total === 0" text="暂无数据" icon="/static/data-empty.png" />
-    <uni-load-more
-      v-if="state.pagination.total > 0"
-      :status="state.loadStatus"
-      :content-text="{
+	<s-layout title="全部评价">
+		<su-tabs :list="state.type" :scrollable="false" @change="onTabsChange" :current="state.currentTab"></su-tabs>
+		<view class="ss-m-t-20">
+			<view class="list-item" v-for="item in state.pagination.data" :key="item">
+				<comment-item :item="item"></comment-item>
+			</view>
+		</view>
+		<s-empty v-if="state.pagination.total === 0" text="暂无数据" icon="/static/data-empty.png" />
+		<uni-load-more v-if="state.pagination.total > 0" :status="state.loadStatus" :content-text="{
         contentdown: '上拉加载更多',
-      }"
-      @tap="loadmore"
-    />
-  </s-layout>
+      }" @tap="loadmore" />
+	</s-layout>
 </template>
 
 <script setup>
-  import sheep from '@/sheep';
-  import { onLoad, onReachBottom } from '@dcloudio/uni-app';
-  import { computed, reactive } from 'vue';
-  import _ from 'lodash';
-  import commentItem from '../components/detail/comment-item.vue';
+	import sheep from '@/sheep';
+	import {
+		onLoad,
+		onReachBottom
+	} from '@dcloudio/uni-app';
+	import {
+		computed,
+		reactive
+	} from 'vue';
+	import _ from 'lodash';
+	import commentItem from '../components/detail/comment-item.vue';
 
-  const pagination = {
-    data: [],
-    current_page: 1,
-    total: 1,
-    last_page: 1,
-  };
-  const state = reactive({
-    list: [],
-    type: [],
-    currentTab: 0,
-    pagination: {
-      data: [],
-      current_page: 1,
-      total: 1,
-      last_page: 1,
-    },
-    commentId: 0,
-    code: 'all',
-  });
-  // 切换选项卡
-  function onTabsChange(e) {
-    state.pagination = pagination
-    state.currentTab = e.index;
-    state.code = e.code;
-    getList(state.commentId, e.code);
-  }
-  async function getType(id) {
-    const { error, data } = await sheep.$api.goods.getType(id);
-    if (error === 0) {
-      state.type = data;
-    }
-  }
-  async function getList(id, code, page = 1, list_rows = 6) {
-    state.loadStatus = 'loading';
-    let res = await sheep.$api.goods.comment(id, {
-      type: code,
-      list_rows,
-      page,
-    });
-    if (res.error === 0) {
-        let orderList = _.concat(state.pagination.data, res.data.data);
-        state.pagination = {
-          ...res.data,
-          data: orderList,
-        };
-      if (state.pagination.current_page < state.pagination.last_page) {
-        state.loadStatus = 'more';
-      } else {
-        state.loadStatus = 'noMore';
-      }
-    }
-  }
-  // 加载更多
-  function loadmore() {
-    if (state.loadStatus !== 'noMore') {
-      getList(state.commentId, state.code, state.pagination.current_page + 1);
-    }
-  }
-  onLoad((options) => {
-    state.commentId = options.id;
-    getType(state.commentId);
-    getList(state.commentId);
-  });
-  // 上拉加载更多
-  onReachBottom(() => {
-    loadmore();
-  });
+	const pagination = {
+		data: [],
+		current_page: 1,
+		total: 1,
+		last_page: 1,
+	};
+	const state = reactive({
+		list: [],
+		type: [],
+		currentTab: 0,
+		pagination: {
+			data: [],
+			current_page: 1,
+			total: 1,
+			last_page: 1,
+		},
+		commentId: 0,
+		code: 0,
+	});
+	// 切换选项卡
+	function onTabsChange(e) {
+		state.pagination = pagination
+		state.currentTab = e.index;
+		state.code = e.code;
+		getList(state.commentId, e.code);
+	}
+	async function getType(id) {
+		const {
+			error,
+			data
+		} = await sheep.$api.goods.getType(id);
+		if (error === 0) {
+			console.log(data)
+			// state.type = data;
+			state.type = [{code:0,name:'全部'},{code:1,name:'好评'},{code:2,name:'中评'},{code:3,name:'差评'}];
+		}
+	}
+	async function getList(id, code=0, page = 1, list_rows = 6) {
+		state.loadStatus = 'loading';
+		let res = await sheep.$api.goods.comment2(id, {
+			type: code,
+			pageSize: list_rows,
+			pageNo: page,
+		});
+		console.log(res);
+		if (res.code === 0) {
+			let orderList = _.concat(state.pagination.data, res.data.list);
+			state.pagination = {
+				...res.data,
+				data: orderList,
+			};
+			if (state.pagination.current_page < state.pagination.last_page) {
+				state.loadStatus = 'more';
+			} else {
+				state.loadStatus = 'noMore';
+			}
+		}
+	}
+	// 加载更多
+	function loadmore() {
+		if (state.loadStatus !== 'noMore') {
+			getList(state.commentId, state.code, state.pagination.current_page + 1);
+		}
+	}
+	onLoad((options) => {
+		state.commentId = options.id;
+		getType(state.commentId);
+		getList(state.commentId);
+	});
+	// 上拉加载更多
+	onReachBottom(() => {
+		loadmore();
+	});
 </script>
 
 <style lang="scss" scoped>
-  .list-item {
-    padding: 32rpx 30rpx 20rpx 20rpx;
-    background: #fff;
-    .avatar {
-      width: 52rpx;
-      height: 52rpx;
-      border-radius: 50%;
-    }
-    .nickname {
-      font-size: 26rpx;
-      font-weight: 500;
-      color: #999999;
-    }
-    .create-time {
-      font-size: 24rpx;
-      font-weight: 500;
-      color: #c4c4c4;
-    }
-    .content-title {
-      font-size: 26rpx;
-      font-weight: 400;
-      color: #666666;
-      line-height: 42rpx;
-    }
-    .content-img {
-      width: 174rpx;
-      height: 174rpx;
-    }
-    .cicon-info-o {
-      font-size: 26rpx;
-      color: #c4c4c4;
-    }
-    .foot-title {
-      font-size: 24rpx;
-      font-weight: 500;
-      color: #999999;
-    }
-  }
+	.list-item {
+		padding: 32rpx 30rpx 20rpx 20rpx;
+		background: #fff;
 
-  .btn-box {
-    width: 100%;
-    height: 120rpx;
-    background: #fff;
-    border-top: 2rpx solid #eee;
-  }
-  .tab-btn {
-    width: 130rpx;
-    height: 62rpx;
-    background: #eeeeee;
-    border-radius: 31rpx;
-    font-size: 28rpx;
-    font-weight: 400;
-    color: #999999;
-    border: 1px solid #e5e5e5;
-    margin-right: 10rpx;
-  }
-</style>
+		.avatar {
+			width: 52rpx;
+			height: 52rpx;
+			border-radius: 50%;
+		}
+
+		.nickname {
+			font-size: 26rpx;
+			font-weight: 500;
+			color: #999999;
+		}
+
+		.create-time {
+			font-size: 24rpx;
+			font-weight: 500;
+			color: #c4c4c4;
+		}
+
+		.content-title {
+			font-size: 26rpx;
+			font-weight: 400;
+			color: #666666;
+			line-height: 42rpx;
+		}
+
+		.content-img {
+			width: 174rpx;
+			height: 174rpx;
+		}
+
+		.cicon-info-o {
+			font-size: 26rpx;
+			color: #c4c4c4;
+		}
+
+		.foot-title {
+			font-size: 24rpx;
+			font-weight: 500;
+			color: #999999;
+		}
+	}
+
+	.btn-box {
+		width: 100%;
+		height: 120rpx;
+		background: #fff;
+		border-top: 2rpx solid #eee;
+	}
+
+	.tab-btn {
+		width: 130rpx;
+		height: 62rpx;
+		background: #eeeeee;
+		border-radius: 31rpx;
+		font-size: 28rpx;
+		font-weight: 400;
+		color: #999999;
+		border: 1px solid #e5e5e5;
+		margin-right: 10rpx;
+	}
+</style>

+ 4 - 4
pages/goods/components/detail/comment-item.vue

@@ -5,19 +5,19 @@
         <image class="avatar" :src="sheep.$url.cdn(item.user_avatar)"></image>
       </view>
       <view class="nickname ss-m-r-20">
-        {{ item.user_nickname }}
+        {{ item.userNickname }}
       </view>
       <view class="">
-        <uni-rate :readonly="true" v-model="item.level" size="18" />
+        <uni-rate :readonly="true" v-model="item.scores" size="18" />
       </view>
     </view>
     <view class="content">
       {{ item.content }}
     </view>
-    <view class="ss-m-t-24" v-if="item.images?.length">
+    <view class="ss-m-t-24" v-if="item.picUrls?.length">
       <scroll-view class="scroll-box" scroll-x scroll-anchoring>
         <view class="ss-flex">
-          <view v-for="(item, index) in item.images" :key="item" class="ss-m-r-10">
+          <view v-for="(item, index) in item.picUrls" :key="item" class="ss-m-r-10">
             <su-image class="content-img" isPreview :previewList="state.commentImages" :current="index" :src="item"
               :height="120" :width="120" mode="aspectFill"></su-image>
           </view>

+ 4 - 3
pages/goods/components/detail/detail-comment-card.vue

@@ -46,9 +46,10 @@
   async function getComment(id) {
     const { data } = await sheep.$api.goods.comment(id, {
       list_rows: 3,
-    });
-    state.commentList = data.data;
-    state.total = data.total;
+    });  
+	 const {data:datas} = await sheep.$api.goods.comment2(id);
+    state.commentList = data;
+    state.total = datas.total;
   }
   onBeforeMount(() => {
     getComment(props.goodsId);

+ 11 - 3
pages/goods/index.vue

@@ -95,7 +95,7 @@
         <!-- 评价 -->
         <detail-comment-card class="detail-comment-selector" :goodsId="state.goodsId" />
         <!-- 详情 -->
-        <detail-content-card class="detail-content-selector" :content="state.goodsInfo.content" />
+        <detail-content-card class="detail-content-selector" :content="state.goodsInfo.description" />
 
         <!-- 活动跳转 -->
         <detail-activity-tip
@@ -242,6 +242,7 @@
   });
 
   onLoad(async (options) => {
+	  console.log('页面被访问')
     // 非法参数
     if (!options.id) {
       state.goodsInfo = null;
@@ -250,10 +251,17 @@
     state.goodsId = options.id;
     // 加载商品信息
     sheep.$api.goods.detail(state.goodsId).then((res) => {
+		console.log(res)
       state.skeletonLoading = false;
-      if (res.error === 0) {
+      if (res.code === 0) {
+		  // 在此处对数据做出转换
+		res.data.sales=res.data.salesCount
+		res.data.original_price=res.data.marketPrice/100
+		res.data.subtitle=res.data.introduction
+		res.data.title=res.data.name
+		res.data.price=[res.data.price/100]
         state.goodsInfo = res.data;
-        state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.images);
+        state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.sliderPicUrls);
       } else {
         // 未找到商品
         state.goodsInfo = null;

+ 4 - 4
pages/goods/list.vue

@@ -261,12 +261,12 @@
       sort: Sort,
       order: Order,
       category_id: !keyword ? categoryId : '',
-      list_rows,
+      pageSize:list_rows,
       keyword: keyword,
-      page,
+      pageNo:page,
     });
-    if (res.error === 0) {
-        let couponList = _.concat(state.pagination.data, res.data.data);
+    if (res.code === 0) {
+        let couponList = _.concat(state.pagination.data, res.data.list);
         state.pagination = {
           ...res.data,
           data: couponList,

+ 8 - 8
pages/index/cart.vue

@@ -36,19 +36,19 @@
               />
             </label>
             <s-goods-item
-              :title="item.goods.title"
-              :img="item.sku_price.image || item.goods.image"
-              :price="item.sku_price.price"
-              :skuText="item.sku_price.goods_sku_text"
+              :title="item.spu.name"
+              :img="item.spu.picUrl || item.goods.image"
+              :price="item.sku.price/100"
+              :skuText="item.sku.properties.length>1? item.sku.properties.reduce((items2,items)=>items2.valueName+' '+items.valueName):item.sku.properties[0].valueName"
               priceColor="#FF3000"
               :titleWidth="400"
             >
               <template v-if="!state.editMode" v-slot:tool>
                 <su-number-box
                   :min="0"
-                  :max="item.sku_price.stock"
+                  :max="item.sku.stock"
                   :step="1"
-                  v-model="item.goods_num"
+                  v-model="item.count"
                   @change="onNumberChange($event, item)"
                 ></su-number-box>
               </template>
@@ -112,9 +112,9 @@
     isAllSelected: computed(() => cart.isAllSelected),
     totalPriceSelected: computed(() => cart.totalPriceSelected),
   });
-
   // 单选选中
   function onSelectSingle(id) {
+	  console.log('单选')
     cart.selectSingle(id);
   }
   // 全选
@@ -154,7 +154,7 @@
     if(cartItem.goods_num === e) return;
     cartItem.goods_num = e;
     cart.update({
-      goods_id: cartItem.goods_id,
+      goods_id: cartItem.id,
       goods_num: e,
       goods_sku_price_id: cartItem.goods_sku_price_id,
     });

+ 221 - 239
pages/index/category.vue

@@ -1,250 +1,232 @@
 <template>
-  <s-layout title="分类" tabbar="/pages/index/category" :bgStyle="{ color: '#fff' }">
-    <view class="s-category">
-      <view class="three-level-wrap ss-flex ss-col-top" :style="[{ height: pageHeight + 'px' }]">
-        <scroll-view class="side-menu-wrap" scroll-y :style="[{ height: pageHeight + 'px' }]">
-          <view
-            class="menu-item ss-flex"
-            v-for="(item, index) in state.categoryList?.children"
-            :key="item.id"
-            :class="[{ 'menu-item-active': index == state.activeMenu }]"
-            @tap="onMenu(index)"
-          >
-            <view class="menu-title ss-line-1">
-              {{ item.name }}
-            </view>
-          </view>
-        </scroll-view>
-        <scroll-view
-          class="goods-list-box"
-          scroll-y
-          :style="[{ height: pageHeight + 'px' }]"
-          v-if="state.categoryList?.children?.length"
-        >
-          <image
-            v-if="state.categoryList.children[state.activeMenu].image"
-            class="banner-img"
-            :src="sheep.$url.cdn(state.categoryList.children[state.activeMenu].image)"
-            mode="widthFix"
-          >
-          </image>
-          <first-one
-            v-if="state.categoryList.style === 'first_one'"
-            :data="state.categoryList"
-            :activeMenu="state.activeMenu"
-            :pagination="state.pagination"
-          />
-          <first-two
-            v-if="state.categoryList.style === 'first_two'"
-            :data="state.categoryList"
-            :activeMenu="state.activeMenu"
-            :pagination="state.pagination"
-          />
-          <second-one
-            v-if="state.categoryList.style === 'second_one'"
-            :data="state.categoryList"
-            :activeMenu="state.activeMenu"
-            :pagination="state.pagination"
-          />
-          <third-one
-            v-if="state.categoryList.style === 'third_one'"
-            :data="state.categoryList"
-            :activeMenu="state.activeMenu"
-            :pagination="state.pagination"
-          />
-          <uni-load-more
-            v-if="
+	<s-layout title="分类" tabbar="/pages/index/category" :bgStyle="{ color: '#fff' }">
+		<view class="s-category">
+			<view class="three-level-wrap ss-flex ss-col-top" :style="[{ height: pageHeight + 'px' }]">
+				<scroll-view class="side-menu-wrap" scroll-y :style="[{ height: pageHeight + 'px' }]">
+					<view class="menu-item ss-flex" v-for="(item, index) in state.categoryList?.children" :key="item.id"
+						:class="[{ 'menu-item-active': index == state.activeMenu }]" @tap="onMenu(index)">
+						<view class="menu-title ss-line-1">
+							{{ item.name }}
+						</view>
+					</view>
+				</scroll-view>
+				<scroll-view class="goods-list-box" scroll-y :style="[{ height: pageHeight + 'px' }]"
+					v-if="state.categoryList?.children?.length">
+					<image v-if="state.categoryList.children[state.activeMenu].image" class="banner-img"
+						:src="sheep.$url.cdn(state.categoryList.children[state.activeMenu].image)" mode="widthFix">
+					</image>
+					<first-one v-if="state.categoryList.style === 'first_one'" :data="state.categoryList"
+						:activeMenu="state.activeMenu" :pagination="state.pagination" />
+					<first-two v-if="state.categoryList.style === 'first_two'" :data="state.categoryList"
+						:activeMenu="state.activeMenu" :pagination="state.pagination" />
+					<second-one v-if="state.categoryList.style === 'second_one'" :data="state.categoryList"
+						:activeMenu="state.activeMenu" :pagination="state.pagination" />
+					<third-one v-if="state.categoryList.style === 'third_one'" :data="state.categoryList"
+						:activeMenu="state.activeMenu" :pagination="state.pagination" />
+					<uni-load-more v-if="
               (state.categoryList.style === 'first_one' ||
                 state.categoryList.style === 'first_two') &&
               state.pagination.total > 0
-            "
-            :status="state.loadStatus"
-            :content-text="{
+            " :status="state.loadStatus" :content-text="{
               contentdown: '点击查看更多',
-            }"
-            @tap="loadmore"
-          />
-        </scroll-view>
-      </view>
-    </view>
-  </s-layout>
+            }" @tap="loadmore" />
+				</scroll-view>
+			</view>
+		</view>
+	</s-layout>
 </template>
 
 <script setup>
-  import secondOne from './components/second-one.vue';
-  import thirdOne from './components/third-one.vue';
-  import firstOne from './components/first-one.vue';
-  import firstTwo from './components/first-two.vue';
-  import sheep from '@/sheep';
-
-  import { onLoad, onReachBottom } from '@dcloudio/uni-app';
-  import { computed, reactive } from 'vue';
-  import _ from 'lodash';
-  const state = reactive({
-    categoryList: [],
-    activeMenu: '0',
-
-    pagination: {
-      data: [],
-      current_page: 1,
-      total: 1,
-      last_page: 1,
-    },
-    loadStatus: '',
-  });
-
-  const { screenHeight, safeAreaInsets, screenWidth, safeArea } = sheep.$platform.device;
-  const pageHeight = computed(() => safeArea.height - 44 - 50);
-
-  async function getList(options) {
-    const { error, data } = await sheep.$api.category.list({
-      id: options.id,
-    });
-    if (error === 0) {
-      state.categoryList = data;
-    }
-  }
-
-  const onMenu = (val) => {
-    state.activeMenu = val;
-    if (state.categoryList.style === 'first_one' || state.categoryList.style === 'first_two') {
-      state.pagination = {
-        data: [],
-        current_page: 1,
-        total: 1,
-        last_page: 1,
-      };
-      getGoodsList(state.categoryList.children[val].id);
-    }
-  };
-
-  async function getGoodsList(id, page = 1, list_rows = 6) {
-    state.loadStatus = 'loading';
-    const res = await sheep.$api.goods.list({
-      category_id: id,
-      list_rows,
-      page,
-    });
-    if (res.error === 0) {
-      let couponList = _.concat(state.pagination.data, res.data.data);
-      state.pagination = {
-        ...res.data,
-        data: couponList,
-      };
-      if (state.pagination.current_page < state.pagination.last_page) {
-        state.loadStatus = 'more';
-      } else {
-        state.loadStatus = 'noMore';
-      }
-    }
-  }
-  // 加载更多
-  function loadmore() {
-    if (state.loadStatus !== 'noMore') {
-      getGoodsList(
-        state.categoryList.children[state.activeMenu].id,
-        state.pagination.current_page + 1,
-      );
-    }
-  }
-  onLoad(async (options) => {
-    await getList(options);
-    if (state.categoryList.style === 'first_one' || state.categoryList.style === 'first_two') {
-      getGoodsList(state.categoryList.children[0].id);
-    }
-  });
-  onReachBottom(() => {
-    loadmore();
-  });
+	import secondOne from './components/second-one.vue';
+	import thirdOne from './components/third-one.vue';
+	import firstOne from './components/first-one.vue';
+	import firstTwo from './components/first-two.vue';
+	import sheep from '@/sheep';
+
+	import {
+		onLoad,
+		onReachBottom
+	} from '@dcloudio/uni-app';
+	import {
+		computed,
+		reactive
+	} from 'vue';
+	import _ from 'lodash';
+	const state = reactive({
+		categoryList: [],
+		activeMenu: '0',
+
+		pagination: {
+			data: [],
+			current_page: 1,
+			total: 1,
+			last_page: 1,
+		},
+		loadStatus: '',
+	});
+
+	const {
+		screenHeight,
+		safeAreaInsets,
+		screenWidth,
+		safeArea
+	} = sheep.$platform.device;
+	const pageHeight = computed(() => safeArea.height - 44 - 50);
+
+	async function getList(options) {
+		const {
+			code,
+			data
+		} = await sheep.$api.category.list({
+			id: options.id,
+		});
+		if (code === 0) {
+			state.categoryList = {
+				children: data
+			};
+		}
+	}
+
+	const onMenu = (val) => {
+		state.activeMenu = val;
+		if (state.categoryList.style === 'first_one' || state.categoryList.style === 'first_two') {
+			state.pagination = {
+				data: [],
+				current_page: 1,
+				total: 1,
+				last_page: 1,
+			};
+		}
+		// 这段代码本来是在判断里的
+		getGoodsList(state.categoryList.children[val].id);
+	};
+
+	async function getGoodsList(id, page = 1, list_rows = 6) {
+		state.loadStatus = 'loading';
+		const res = await sheep.$api.goods.list({
+			categoryId: id,
+			pageSize:list_rows,
+			pageNo:page,
+		});
+		if (res.code === 0) {
+			let couponList = _.concat(state.pagination.data, res.data.list);
+			state.pagination = {
+				...res.data,
+				data: couponList,
+			};
+			console.log(state.pagination)
+			if (state.pagination.current_page < state.pagination.last_page) {
+				state.loadStatus = 'more';
+			} else {
+				state.loadStatus = 'noMore';
+			}
+		}
+	}
+	// 加载更多
+	function loadmore() {
+		if (state.loadStatus !== 'noMore') {
+			getGoodsList(
+				state.categoryList.children[state.activeMenu].id,
+				state.pagination.current_page + 1,
+			);
+		}
+	}
+	onLoad(async (options) => {
+		await getList(options);
+		if (state.categoryList.style === 'first_one' || state.categoryList.style === 'first_two') {
+			getGoodsList(state.categoryList.children[0].id);
+		}
+	});
+	onReachBottom(() => {
+		loadmore();
+	});
 </script>
 
 <style lang="scss" scoped>
-  .s-category {
-    :deep() {
-      .side-menu-wrap {
-        width: 200rpx;
-        height: 100%;
-        padding-left: 12rpx;
-        background-color: #f6f6f6;
-
-        .menu-item {
-          width: 100%;
-          height: 88rpx;
-          position: relative;
-          transition: all linear 0.2s;
-
-          .menu-title {
-            line-height: 32rpx;
-            font-size: 30rpx;
-            font-weight: 400;
-            color: #333;
-            margin-left: 28rpx;
-            position: relative;
-            z-index: 0;
-
-            &::before {
-              content: '';
-              width: 64rpx;
-              height: 12rpx;
-              background: linear-gradient(
-                90deg,
-                var(--ui-BG-Main-gradient),
-                var(--ui-BG-Main-light)
-              ) !important;
-              position: absolute;
-              left: -64rpx;
-              bottom: 0;
-              z-index: -1;
-              transition: all linear 0.2s;
-            }
-          }
-
-          &.menu-item-active {
-            background-color: #fff;
-            border-radius: 20rpx 0 0 20rpx;
-
-            &::before {
-              content: '';
-              position: absolute;
-              right: 0;
-              bottom: -20rpx;
-              width: 20rpx;
-              height: 20rpx;
-              background: radial-gradient(circle at 0 100%, transparent 20rpx, #fff 0);
-            }
-
-            &::after {
-              content: '';
-              position: absolute;
-              top: -20rpx;
-              right: 0;
-              width: 20rpx;
-              height: 20rpx;
-              background: radial-gradient(circle at 0% 0%, transparent 20rpx, #fff 0);
-            }
-
-            .menu-title {
-              font-weight: 600;
-
-              &::before {
-                left: 0;
-              }
-            }
-          }
-        }
-      }
-
-      .goods-list-box {
-        background-color: #fff;
-        width: calc(100vw - 100px);
-        padding: 10px;
-      }
-
-      .banner-img {
-        width: calc(100vw - 130px);
-        border-radius: 5px;
-        margin-bottom: 20rpx;
-      }
-    }
-  }
-</style>
+	.s-category {
+		:deep() {
+			.side-menu-wrap {
+				width: 200rpx;
+				height: 100%;
+				padding-left: 12rpx;
+				background-color: #f6f6f6;
+
+				.menu-item {
+					width: 100%;
+					height: 88rpx;
+					position: relative;
+					transition: all linear 0.2s;
+
+					.menu-title {
+						line-height: 32rpx;
+						font-size: 30rpx;
+						font-weight: 400;
+						color: #333;
+						margin-left: 28rpx;
+						position: relative;
+						z-index: 0;
+
+						&::before {
+							content: '';
+							width: 64rpx;
+							height: 12rpx;
+							background: linear-gradient(90deg,
+									var(--ui-BG-Main-gradient),
+									var(--ui-BG-Main-light)) !important;
+							position: absolute;
+							left: -64rpx;
+							bottom: 0;
+							z-index: -1;
+							transition: all linear 0.2s;
+						}
+					}
+
+					&.menu-item-active {
+						background-color: #fff;
+						border-radius: 20rpx 0 0 20rpx;
+
+						&::before {
+							content: '';
+							position: absolute;
+							right: 0;
+							bottom: -20rpx;
+							width: 20rpx;
+							height: 20rpx;
+							background: radial-gradient(circle at 0 100%, transparent 20rpx, #fff 0);
+						}
+
+						&::after {
+							content: '';
+							position: absolute;
+							top: -20rpx;
+							right: 0;
+							width: 20rpx;
+							height: 20rpx;
+							background: radial-gradient(circle at 0% 0%, transparent 20rpx, #fff 0);
+						}
+
+						.menu-title {
+							font-weight: 600;
+
+							&::before {
+								left: 0;
+							}
+						}
+					}
+				}
+			}
+
+			.goods-list-box {
+				background-color: #fff;
+				width: calc(100vw - 100px);
+				padding: 10px;
+			}
+
+			.banner-img {
+				width: calc(100vw - 130px);
+				border-radius: 5px;
+				margin-bottom: 20rpx;
+			}
+		}
+	}
+</style>

+ 70 - 56
pages/index/index.vue

@@ -1,70 +1,84 @@
 <template>
-  <view v-if="template">
-    <s-layout
-      title="首页"
-      navbar="custom"
-      tabbar="/pages/index/index"
-      :bgStyle="template.style?.background"
-      :navbarStyle="template.style?.navbar"
-      onShareAppMessage
-    >
-      <s-block v-for="(item, index) in template.data" :key="index" :styles="item.style">
-        <s-block-item :type="item.type" :data="item.data" :styles="item.style" />
-      </s-block>
-      <!-- 广告模块 -->
-      <s-popup-image />
-    </s-layout>
-  </view>
+	<view v-if="template">
+		<s-layout title="首页" navbar="custom" tabbar="/pages/index/index" :bgStyle="template.style?.background"
+			:navbarStyle="template.style?.navbar" onShareAppMessage>
+			<s-block v-for="(item, index) in template.data" :key="index" :styles="item.style">
+				<s-block-item :type="item.type" :data="item.data" :styles="item.style" />
+			</s-block>
+			<!-- 广告模块 -->
+			<s-popup-image />
+		</s-layout>
+	</view>
 </template>
 
 <script setup>
-  import { computed } from 'vue';
-  import { onLoad, onPageScroll, onPullDownRefresh } from '@dcloudio/uni-app';
-  import sheep from '@/sheep';
-  import $share from '@/sheep/platform/share';
+	import {
+		computed
+	} from 'vue';
+	import {
+		onLoad,
+		onPageScroll,
+		onPullDownRefresh
+	} from '@dcloudio/uni-app';
+	import sheep from '@/sheep';
+	import $share from '@/sheep/platform/share';
+	import index2Api from '@/sheep/api/index2';
+	// 隐藏原生tabBar
+	uni.hideTabBar();
 
-  // 隐藏原生tabBar
-  uni.hideTabBar();
+	const template = computed(() => sheep.$store('app').template?.home);
+	// 在此处拦截改变一下首页轮播图 此处先写死后期复活
+	(async function() {
+		let {
+			data
+		} = await index2Api.decorate();
+		template.value.data[0].data.list = JSON.parse(data[0].value).map(item => {
+			return {
+				src: item.picUrl,
+				url: item.url,
+				title: item.name,
+				type: "image"
+			}
+		})
+	}())
 
-  const template = computed(() => sheep.$store('app').template?.home);
+	onLoad((options) => {
+		// #ifdef MP
+		// 小程序识别二维码
+		if (options.scene) {
+			const sceneParams = decodeURIComponent(options.scene).split('=');
+			options[sceneParams[0]] = sceneParams[1];
+		}
+		// #endif
 
-  onLoad((options) => {
-    // #ifdef MP
-    // 小程序识别二维码
-    if (options.scene) {
-      const sceneParams = decodeURIComponent(options.scene).split('=');
-      options[sceneParams[0]] = sceneParams[1];
-    }
-    // #endif
+		// 预览模板
+		if (options.templateId) {
+			sheep.$store('app').init(options.templateId);
+		}
 
-    // 预览模板
-    if (options.templateId) {
-      sheep.$store('app').init(options.templateId);
-    }
+		// 解析分享信息
+		if (options.spm) {
+			$share.decryptSpm(options.spm);
+		}
 
-    // 解析分享信息
-    if (options.spm) {
-      $share.decryptSpm(options.spm);
-    }
+		// 进入指定页面(完整页面路径)
+		if (options.page) {
+			sheep.$router.go(decodeURIComponent(options.page));
+		}
 
-    // 进入指定页面(完整页面路径)
-    if (options.page) {
-      sheep.$router.go(decodeURIComponent(options.page));
-    }
+		// TODO 芋艿:测试接口的调用
+		sheep.$api.app.test();
+	});
 
-    // TODO 芋艿:测试接口的调用
-    sheep.$api.app.test();
-  });
+	// 下拉刷新
+	onPullDownRefresh(() => {
+		sheep.$store('app').init();
+		setTimeout(function() {
+			uni.stopPullDownRefresh();
+		}, 800);
+	});
 
-  // 下拉刷新
-  onPullDownRefresh(() => {
-    sheep.$store('app').init();
-    setTimeout(function () {
-      uni.stopPullDownRefresh();
-    }, 800);
-  });
-
-  onPageScroll(() => {});
+	onPageScroll(() => {});
 </script>
 
-<style></style>
+<style></style>

+ 8 - 7
sheep/api/cart.js

@@ -1,9 +1,10 @@
 import request from '@/sheep/request';
+import request2 from '@/sheep/request2';
 
 export default {
   list: (data) =>
-    request({
-      url: 'cart',
+    request2({
+      url: 'trade/cart/list',
       method: 'GET',
       custom: {
         showLoading: false,
@@ -25,14 +26,14 @@ export default {
     }),
   // 删除购物车
   delete: (ids) =>
-    request({
-      url: 'cart/' + ids,
+    request2({
+      url: 'trade/cart/delete?ids=' + ids,
       method: 'DELETE',
     }),
   update: (data) =>
-    request({
-      url: 'cart',
-      method: 'POST',
+    request2({
+      url: 'trade/cart/update-count',
+      method: 'PUT',
       data: {
         ...data,
         type: 'cover',

+ 3 - 3
sheep/api/category.js

@@ -1,9 +1,9 @@
-import request from '@/sheep/request';
+import request2 from '@/sheep/request2';
 
 export default {
   list: (params) =>
-    request({
-      url: 'category',
+    request2({
+      url: 'product/category/list',
       method: 'GET',
       params,
     }),

+ 17 - 6
sheep/api/goods.js

@@ -1,10 +1,11 @@
 import request from '@/sheep/request';
+import request2 from '@/sheep/request2';
 
 export default {
   // 商品详情
   detail: (id, params = {}) =>
-    request({
-      url: 'goods/goods/' + id,
+    request2({
+      url: 'product/spu/get-detail?id=' + id,
       method: 'GET',
       params,
       custom: {
@@ -15,8 +16,8 @@ export default {
 
   // 商品列表
   list: (params) =>
-    request({
-      url: 'goods/goods',
+    request2({
+      url: 'product/spu/page',
       method: 'GET',
       params,
       custom: {
@@ -39,8 +40,18 @@ export default {
 
   // 商品评价列表
   comment: (id, params = {}) =>
-    request({
-      url: 'goods/comment/' + id,
+    request2({
+      url: 'product/comment/list?spuId=' + id,
+      method: 'GET',
+      params,
+      custom: {
+        showLoading: false,
+        showError: false,
+      },
+    }),
+  comment2: (id, params = {pageNo:1,pageSize:10,type:0}) =>
+    request2({
+      url: 'product/comment/page?spuId='+id,
       method: 'GET',
       params,
       custom: {

+ 9 - 0
sheep/api/index2.js

@@ -0,0 +1,9 @@
+import request2 from '@/sheep/request2';
+
+export default {
+  decorate: () =>
+    request2({
+      url: 'promotion/decorate/list?page=1',
+      method: 'GET',
+    }),
+};

+ 1 - 1
sheep/config/index.js

@@ -7,7 +7,7 @@ if (process.env.NODE_ENV === 'development') {
   baseUrl = import.meta.env.SHOPRO_BASE_URL;
 }
 version = import.meta.env.SHOPRO_VERSION;
-console.log(`[Shopro ${version}]  https://www.sheepjs.com/`);
+console.log(`[Shopro ${version}]  http://api-dashboard.yudao.iocoder.cn/`);
 export const apiPath = import.meta.env.SHOPRO_API_PATH;
 
 export const staticUrl = import.meta.env.SHOPRO_STATIC_URL;

+ 217 - 0
sheep/request2/index.js

@@ -0,0 +1,217 @@
+/**
+ * Shopro-request
+ * @description api模块管理,loading配置,请求拦截,错误处理
+ */
+
+import Request from 'luch-request';
+import { baseUrl, apiPath } from '@/sheep/config';
+import $store from '@/sheep/store';
+import $platform from '@/sheep/platform';
+import { showAuthModal } from '@/sheep/hooks/useModal';
+
+const options = {
+  // 显示操作成功消息 默认不显示
+  showSuccess: false,
+  // 成功提醒 默认使用后端返回值
+  successMsg: '',
+  // 显示失败消息 默认显示
+  showError: true,
+  // 失败提醒 默认使用后端返回信息
+  errorMsg: '',
+  // 显示请求时loading模态框 默认显示
+  showLoading: true,
+  // loading提醒文字
+  loadingMsg: '加载中',
+  // 需要授权才能请求 默认放开
+  auth: false,
+  // ...
+};
+
+// Loading全局实例
+let LoadingInstance = {
+  target: null,
+  count: 0,
+};
+
+/**
+ * 关闭loading
+ */
+function closeLoading() {
+  if (LoadingInstance.count > 0) LoadingInstance.count--;
+  if (LoadingInstance.count === 0) uni.hideLoading();
+}
+
+/**
+ * @description 请求基础配置 可直接使用访问自定义请求
+ */
+const http = new Request({
+  baseURL: 'https://api.shopro.sheepjs.com/',
+  timeout: 8000,
+  method: 'GET',
+  header: {
+    Accept: 'text/json',
+    'Content-Type': 'application/json;charset=UTF-8',
+    platform: $platform.name,
+  },
+  // #ifdef APP-PLUS
+  sslVerify: false,
+  // #endif
+  // #ifdef H5
+  // 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
+  withCredentials: false,
+  // #endif
+  custom: options,
+});
+
+/**
+ * @description 请求拦截器
+ */
+http.interceptors.request.use(
+  (config) => {
+	  // console.log(config);
+    if (config.custom.auth && !$store('user').isLogin) {
+      showAuthModal();
+      return Promise.reject();
+    }
+    if (config.custom.showLoading) {
+      LoadingInstance.count++;
+      LoadingInstance.count === 1 &&
+        uni.showLoading({
+          title: config.custom.loadingMsg,
+          mask: true,
+          fail: () => {
+            uni.hideLoading();
+          },
+        });
+    }
+    const token = uni.getStorageSync('token');
+    if (token) config.header['Authorization'] = token;
+    // TODO 芋艿:特殊处理
+    if (config.url.indexOf('/app-api/') !== -1) {
+      config.header['Accept'] = '*/*'
+      config.header['tenant-id'] = '1';
+      config.header['Authorization'] = 'Bearer test247';
+    }
+    return config;
+  },
+  (error) => {
+    return Promise.reject(error);
+  },
+);
+
+/**
+ * @description 响应拦截器
+ */
+http.interceptors.response.use(
+  (response) => {
+    // 自动设置登陆令牌
+    if (response.header.authorization || response.header.Authorization) {
+      $store('user').setToken(response.header.authorization || response.header.Authorization);
+    }
+
+    response.config.custom.showLoading && closeLoading();
+    if (response.data.code !== 0) {
+      if (response.config.custom.showError)
+        uni.showToast({
+          title: response.data.msg || '服务器开小差啦,请稍后再试~',
+          icon: 'none',
+          mask: true,
+        });
+      return Promise.resolve(response.data);
+    }
+    if (
+      response.data.error === 0 &&
+      response.data.msg !== '' &&
+      response.config.custom.showSuccess
+    ) {
+      uni.showToast({
+        title: response.config.custom.successMsg || response.data.msg,
+        icon: 'none',
+      });
+    }
+    return Promise.resolve(response.data);
+  },
+  (error) => {
+    const userStore = $store('user');
+    const isLogin = userStore.isLogin;
+    let errorMessage = '网络请求出错';
+    if (error !== undefined) {
+      switch (error.statusCode) {
+        case 400:
+          errorMessage = '请求错误';
+          break;
+        case 401:
+          if (isLogin) {
+            errorMessage = '您的登陆已过期';
+          } else {
+            errorMessage = '请先登录';
+          }
+          userStore.logout(true);
+          showAuthModal();
+          break;
+        case 403:
+          errorMessage = '拒绝访问';
+          break;
+        case 404:
+          errorMessage = '请求出错';
+          break;
+        case 408:
+          errorMessage = '请求超时';
+          break;
+        case 429:
+          errorMessage = '请求频繁, 请稍后再访问';
+          break;
+        case 500:
+          errorMessage = '服务器开小差啦,请稍后再试~';
+          break;
+        case 501:
+          errorMessage = '服务未实现';
+          break;
+        case 502:
+          errorMessage = '网络错误';
+          break;
+        case 503:
+          errorMessage = '服务不可用';
+          break;
+        case 504:
+          errorMessage = '网络超时';
+          break;
+        case 505:
+          errorMessage = 'HTTP版本不受支持';
+          break;
+      }
+      if (error.errMsg.includes('timeout')) errorMessage = '请求超时';
+      // #ifdef H5
+      if (error.errMsg.includes('Network'))
+        errorMessage = window.navigator.onLine ? '服务器异常' : '请检查您的网络连接';
+      // #endif
+    }
+
+    if (error && error.config) {
+      if (error.config.custom.showError === false) {
+        uni.showToast({
+          title: error.data?.msg || errorMessage,
+          icon: 'none',
+          mask: true,
+        });
+      }
+      error.config.custom.showLoading && closeLoading();
+    }
+
+    return false;
+  },
+);
+
+const request = (config) => {
+  if (config.url[0] !== '/') {
+    config.url = '/app-api/' + config.url;
+  }
+  // TODO 芋艿:额外拼接
+  if (config.url.indexOf('/app-api/') >= 0) {
+    config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】
+    // config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】
+  }
+  return http.middleware(config);
+};
+
+export default request;

+ 4 - 4
sheep/router/index.js

@@ -58,10 +58,10 @@ const _go = (
   }
 
   // 页面登录拦截
-  if (nextRoute.meta?.auth && !$store('user').isLogin) {
-    showAuthModal();
-    return;
-  }
+  // if (nextRoute.meta?.auth && !$store('user').isLogin) {
+  //   showAuthModal();
+  //   return;
+  // }
 
   url = page;
   if (!isEmpty(query)) {

+ 8 - 8
sheep/store/cart.js

@@ -15,7 +15,7 @@ const cart = defineStore({
       if (!state.selectedIds.length) return price.toFixed(2);
       state.list.forEach((item) => {
         price += state.selectedIds.includes(item.id)
-          ? Number(item.sku_price.price) * item.goods_num
+          ? Number(item.sku.price/100) * item.count
           : 0;
       });
       return price.toFixed(2);
@@ -24,9 +24,9 @@ const cart = defineStore({
   actions: {
     // 获取购物车列表
     async getList() {
-      const { data, error } = await cartApi.list();
-      if (error === 0) {
-        this.list = data;
+      const { data, code } = await cartApi.list();
+      if (code === 0) {
+        this.list = data.validList;
       }
     },
     // 添加购物车
@@ -44,8 +44,8 @@ const cart = defineStore({
     // 更新购物车
     async update(goodsInfo) {
       const { error } = await cartApi.update({
-        goods_id: goodsInfo.goods_id,
-        goods_num: goodsInfo.goods_num,
+        id: goodsInfo.goods_id,
+        count: goodsInfo.goods_num,
         goods_sku_price_id: goodsInfo.goods_sku_price_id,
       });
       if (error === 0) {
@@ -58,8 +58,8 @@ const cart = defineStore({
       if (typeof ids === 'array') {
         ids = ids.join(',');
       }
-      const { error } = await cartApi.delete(ids);
-      if (error === 0) {
+      const { code } = await cartApi.delete(ids);
+      if (code === 0) {
         this.selectAll(false);
         this.getList();
       }