Ver Fonte

ui 首页生活号接口

liujiaxin há 2 semanas atrás
pai
commit
490bd199a6

+ 4 - 4
api/activity.js

@@ -3,11 +3,11 @@ let request = new Request().http
  
  
  
- export function getStoreActivity(data) {
- 	 return request('/app/activity/getStoreActivity',data,'GET');
+ export function getStoreActivity() {
+ 	 return request('/app/activity/getStoreActivity',null,'GET');
  }
- export function getStoreActivityDetails(data) {
- 	 return request('/app/activity/getStoreActivityDetails',data,'GET');
+ export function getStoreActivityDetails() {
+ 	 return request('/app/activity/getStoreActivityDetails',null,'GET');
  }
  export function share(activityId) {
  	 return request('/app/activity/share?activityId='+activityId,null,'POST');

+ 44 - 18
api/index.js

@@ -2,38 +2,64 @@ import Request from '../common/request.js';
 let request = new Request().http
 
 export function getDicts(data) {
- 	 return request('/app/common/getDicts',data,'GET');
-} 
+	return request('/app/common/getDicts', data, 'GET');
+}
 
 
 export function getCanvas() {
- 	 return request('/app/index/getCanvas',null,'GET');
-} 
+	return request('/app/index/getCanvas', null, 'GET');
+}
 
 export function getMenu() {
- 	 return request('/app/index/getMenu',null,'GET');
-} 
+	return request('/app/index/getMenu', null, 'GET');
+}
 
 export function getIndexData(data) {
- 	 return request('/app/index/getIndexData',data,'GET');
-} 
+	return request('/app/index/getIndexData', data, 'GET');
+}
 export function getTuiArticle(data) {
- 	 return request('/app/index/getTuiArticle',data,'GET');
-} 
+	return request('/app/index/getTuiArticle', data, 'GET');
+}
 export function getTuiDoctor(data) {
- 	 return request('/app/index/getTuiDoctor',data,'GET');
-} 
+	return request('/app/index/getTuiDoctor', data, 'GET');
+}
 
 
 
 export function getTuiDoctorOrder(data) {
- 	 return request('/app/index/getTuiDoctorOrder',data,'GET');
-} 
+	return request('/app/index/getTuiDoctorOrder', data, 'GET');
+}
 
 export function getCartCount() {
- 	 return request('/app/index/getCartCount',null,'GET');
-} 
+	return request('/app/index/getCartCount', null, 'GET');
+}
 
+// 商品搜索瀑布流
+export function productWaterfall(data) {
+	return request('/app/product/getProductWaterfall', data, 'POST');
+}
 
- 
- 
+// 获取首页推荐商品
+export function recommendProduct() {
+	return request('/app/product/getRecommendProduct', null, 'GET');
+}
+// 添加购物车
+export function addCart(data) {
+	return request('/app/product/addCart', data, 'POST');
+}
+// 删除购物车
+export function delCart(data) {
+	return request('/app/product/delCart', data, 'POST');
+}
+// 改变购物车数量
+export function cartNum(data) {
+	return request('/app/product/cartNum', data, 'POST');
+}
+// 获取商品购物车数量
+export function cartCount() {
+	return request('/app/product/cartCount', null, 'GET');
+}
+// 获取购物车列表
+export function getCarts() {
+	return request('/app/product/getCarts', null, 'GET');
+}

+ 42 - 12
api/life.js

@@ -5,50 +5,80 @@ let request = new Request().http
 
 // 达人主页
 export function expertHomePage(data) {
-	return request(`/store/life/expertHomePage/${expertId}`, data, 'POST');
+	return request(`/app/store/life/expertHomePage/${expertId}`, data, 'POST');
 }
 
-// 关注用户
+//关注用户/取消关注
 export function follow(data) {
-	return request(`/store/life/follow/${expertId}`, data, 'POST');
+	return request(`/app/store/life/follow/${expertId}`, data, 'POST');
 }
 
 // 内容详情
 export function lifeDetail(data) {
-	return request('/store/life/lifeDetail', data, 'POST');
+	return request('/app/store/life/lifeDetail', data, 'POST');
 }
 
 // 内容列表
 export function lifeList(data) {
-	return request('/store/life/lifeList', data, 'POST');
+	return request('/app/store/life/lifeList', data, 'POST');
 }
 
 // 一级评论列表
 export function listRootComments(data) {
-	return request('/store/life/listRootComments', data, 'POST');
+	return request('/app/store/life/listRootComments', data, 'POST');
 }
 
 //二级评论列表
 export function listSubComments(data) {
-	return request('/store/life/listSubComments', data, 'POST');
+	return request('/app/store/life/listSubComments', data, 'POST');
 }
 
 //发表评论
 export function postComment(data) {
-	return request('/store/life/postComment', data, 'POST');
+	return request('/app/store/life/postComment', data, 'POST');
 }
 
 //内容分享
 export function share(data) {
-	return request('/store/life/share', data, 'POST');
+	return request('/app/store/life/share', data, 'POST');
 }
 
 //内容点赞/取消点赞
 export function toggleLike(data) {
-	return request('/store/life/toggleLike', data, 'POST');
+	return request('/app/store/life/toggleLike', data, 'POST');
+}
+//内容收藏/取消收藏接口
+export function toggleCollection(data) {
+	return request('/app/store/life/toggleCollection', data, 'POST');
 }
-
 //评论点赞
 export function toggleLikeComments(data) {
-	return request('/store/life/toggleLikeComments', data, 'POST');
+	return request('/app/store/life/toggleLikeComments', data, 'POST');
+}
+
+
+
+
+
+/** 商品评价 **/
+
+// 新增一级评论
+export function addComment(data) {
+	return request('/app/store/productComment/add', data, 'POST');
+}
+// 点赞/取消点赞
+export function like(data) {
+	return request('/app/store/productComment/like', data, 'POST');
+}
+// 查询评论列表
+export function page(data) {
+	return request('/app/store/productComment/page', data, 'POST');
+}
+//回复评论
+export function reply(data) {
+	return request('/app/store/productComment/reply', data, 'POST');
 }
+// 查询店铺评价汇总
+export function summary(storeId) {
+	return request(`/app/store/productComment/store/summary/${storeId}`, data, 'GET');
+}

+ 77 - 20
api/order.js

@@ -5,7 +5,7 @@ const api = {
 	liveOrderList: '/app/live/liveOrder/list', // 订单列表
 	createliveOrder: '/app/live/liveOrder/create', // 创建订单
 	createReward: '/app/live/liveOrder/createReward', // 创建中奖订单
-	
+
 	updateConfirm: (orderId, type) => `/app/live/liveOrder/updateConfirm/${orderId}/${type} `, // 取消/支付订单确认
 	updateLiveOrder: '/app/live/liveOrder/update', // 取消/支付订单
 	liveOrderKey: '/app/live/liveOrder/confirm', // 生成订单key
@@ -39,10 +39,10 @@ const api = {
 	getMyStoreOrderById: (orderId) => `/app/live/liveOrder/info/${orderId}`,
 	computed: '/app/live/liveOrder/computed', // 查询创建订单信息
 	computedReward: '/app/live/liveOrder/computedReward', // 中奖填地址=>查询创建中奖订单信息
-	
+
 	// finishOrder: '/app/live/liveOrder/finishOrder', 
 	// cancelOrder: '/app/live/liveOrder/cancelOrder',
-	
+
 
 }
 
@@ -209,27 +209,84 @@ export function getMyStoreOrderById(orderId, data = {}) {
 }
 
 // 查询创建订单信息
-export function computed(data ) {
+export function computed(data) {
 	return request(api.computed, data, 'POST', 'application/json;charset=UTF-8');
 }
 // 中奖填地址=>查询中奖创建订单信息
-export function computedReward(data ) {
+export function computedReward(data) {
 	return request(api.computedReward, data, 'POST', 'application/json;charset=UTF-8');
 }
 
 //填写物流
- export function addDelivery(data) {
- 	 return request('/app/live/storeAfterSales/addDelivery',data,'POST','application/json;charset=UTF-8');
- }
-
- export function getExpressMulti(data) {
- 	 return request('/app/live/liveOrder/getExpressMulti',data,'POST','application/json;charset=UTF-8');
- }
- export function getExpress(data) {
- 	 return request('/app/live/liveOrder/getExpress',data,'POST','application/json;charset=UTF-8');
- }
- 
- // 抽奖中奖接口
- export function payConfirmReward(data) {
- 	 return request('/app/live/liveOrder/payConfirmReward',data,'POST','application/json;charset=UTF-8');
- }
+export function addDelivery(data) {
+	return request('/app/live/storeAfterSales/addDelivery', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+export function getExpressMulti(data) {
+	return request('/app/live/liveOrder/getExpressMulti', data, 'POST', 'application/json;charset=UTF-8');
+}
+export function getExpress(data) {
+	return request('/app/live/liveOrder/getExpress', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 抽奖中奖接口
+export function payConfirmReward(data) {
+	return request('/app/live/liveOrder/payConfirmReward', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+
+
+
+
+
+
+
+
+
+
+
+/*订单接口*/
+// 取消订单
+export function orderCancelOrder(data) {
+	return request('/app/storeOrder/cancelOrder', data, 'POST', 'application/json;charset=UTF-8');
+}
+// 取消支付
+export function orderCancelPay(data) {
+	return request('/app/storeOrder/cancelPay', data, 'POST', 'application/json;charset=UTF-8');
+}
+// 计算订单金额
+export function orderComputed(data) {
+	return request('/app/storeOrder/computed', data, 'POST', 'application/json;charset=UTF-8');
+}
+// 确认订单
+export function orderConfirm(data) {
+	return request('/app/storeOrder/confirm', data, 'POST', 'application/json;charset=UTF-8');
+}
+// 创建订单
+export function orderCreate(data) {
+	return request('/app/storeOrder/create', data, 'POST', 'application/json;charset=UTF-8');
+}
+
+// 获取我的订单详情
+export function myStoreOrderById() {
+	return request('/app/storeOrder/getMyStoreOrderById', null, 'GET', 'application/json;charset=UTF-8');
+}
+// 获取我的订单列表
+export function myStoreOrderList() {
+	return request('/app/storeOrder/getMyStoreOrderList', null, 'GET', 'application/json;charset=UTF-8');
+}
+// 获取订单总数
+export function orderCount() {
+	return request('/app/storeOrder/getOrderCount', null, 'GET', 'application/json;charset=UTF-8');
+}
+// 获取订单
+export function storeOrderById() {
+	return request('/app/storeOrder/getStoreOrderById', null, 'GET', 'application/json;charset=UTF-8');
+}
+
+
+
+// 支付
+export function orderPay(data) {
+	return request('/app/storeOrder/pay', data, 'POST', 'application/json;charset=UTF-8');
+}

+ 6 - 0
api/product.js

@@ -45,6 +45,12 @@ let request = new Request().http
  }
  
  
+ // 获取今日热卖榜和30天畅销榜
+ export function todayAndHot(data) {
+ 	 return request('/app/product/getTodayHotAndThirtyDaysNewProductHot',data,'GET');
+ }
+ 
+ 
  
  
 

+ 30 - 0
api/search.js

@@ -0,0 +1,30 @@
+import Request from '../common/request.js';
+let request = new Request().http
+ 
+ 
+ //添加搜索记录
+ export function addHistory(data) {
+ 	 return request('/app/search/history/add',data,'POST');
+ }
+ // 清空用户所有搜索记录
+ export function clear(data) {
+ 	 return request('/app/search/history/clear',data,'DELETE');
+ }
+ 
+ // 删除单条搜索记录
+ export function delete(data) {
+ 	 return request('/app/search/history/delete',data,'DELETE');
+ }
+ export function list() {
+ 	 return request('/app/search/history/list',null,'GET');
+ }
+  
+ 
+ 
+
+ 
+ 
+ 
+ 
+ 
+ 

+ 6 - 3
common/request.js

@@ -3,7 +3,11 @@ import store from '@/store/index.js'
 export default class Request {
 	http(router, data = {}, method, contentType, url) {
 		let that = this;
-		let path = 'https://api.fhhx.runtzh.com';
+		// let path = 'https://api.fhhx.runtzh.com';
+		// let path ='http://t8467d6f.natappfree.cc'//刘欣
+		// let path ='http://hee96674.natappfree.cc'//张秦
+		let path ='http://129.28.77.198:7014'//张秦
+		
 		// let path = 'http://x5d7cc68.natappfree.cc';//刘明欣
 		// let path =  'http://192.168.10.122:7014';
 		// let path = 'http://192.168.10.126:7014';
@@ -56,8 +60,7 @@ export default class Request {
 			// 请求
 			uni.request({
 				header: {
-					// 'Content-Type': 'application/x-www-form-urlencoded',
-					'Content-Type': httpContentType,
+					'Content-Type': method === 'POST' ? 'application/json' : 'application/x-www-form-urlencoded',
 					'AppToken': token
 				},
 				url: `${path}${router}`,

+ 104 - 0
components/emoji-picker.vue

@@ -0,0 +1,104 @@
+<template>
+	<view class="emoji-picker">
+		<view class="emoji-header">
+			<text class="title">表情</text>
+			<text class="close" @click="handleClose">关闭</text>
+		</view>
+		<view class="emoji-list">
+			<view 
+				v-for="(emoji, index) in emojiList" 
+				:key="index"
+				class="emoji-item"
+				@click="handleEmojiClick(emoji)"
+			>
+				<text class="emoji">{{ emoji }}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'EmojiPicker',
+	props: {
+		visible: {
+			type: Boolean,
+			default: false
+		}
+	},
+	data() {
+		return {
+			// 表情列表
+			emojiList: [
+				'😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣',
+				'😊', '😇', '🙂', '🙃', '😉', '😌', '😍', '🥰',
+				'😘', '😗', '😙', '😚', '😋', '😛', '😝', '😜',
+				'🤪', '🤨', '🧐', '🤓', '😎', '🤩', '🥳', '😏',
+				'😒', '😞', '😔', '😟', '😕', '🙁', '☹️', '😣',
+				'😖', '😫', '😩', '🥺', '😢', '😭', '😤', '😠',
+				'😡', '🤬', '🤯', '😳', '🥵', '🥶', '😱', '😨',
+				'😰', '😥', '😓', '🤗', '🤔', '🤭', '🤫', '🤥'
+			]
+		}
+	},
+	methods: {
+		// 点击表情
+		handleEmojiClick(emoji) {
+			this.$emit('select', emoji);
+		},
+		// 点击关闭
+		handleClose() {
+			this.$emit('close');
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.emoji-picker {
+	background-color: #ffffff;
+	border-top: 1rpx solid #EEEEEE;
+	position: fixed;
+	bottom: 100rpx;
+	left: 0;
+	right: 0;
+	z-index: 999;
+
+	.emoji-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding: 20rpx 24rpx;
+		border-bottom: 1rpx solid #F0F0F0;
+
+		.title {
+			font-size: 28rpx;
+			font-weight: 500;
+			color: #333333;
+		}
+
+		.close {
+			font-size: 26rpx;
+			color: #999999;
+		}
+	}
+
+	.emoji-list {
+		display: flex;
+		flex-wrap: wrap;
+		padding: 24rpx;
+
+		.emoji-item {
+			width: 20%;
+			height: 80rpx;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+
+			.emoji {
+				font-size: 40rpx;
+			}
+		}
+	}
+}
+</style>

+ 3 - 3
components/public/scs-scroll-navbar.vue

@@ -193,7 +193,7 @@ export default {
     text-align: center;
     display: inline-block;
     position: relative;
-    font-size: 40rpx;
+    font-size: 30rpx;
     margin-right: 32rpx;
 
     &:last-child {
@@ -210,13 +210,13 @@ export default {
   }
 
   .act-current {
-    font-size: 40rpx;
+    // font-size: 40rpx;
     font-weight: bold;
   }
 
   .nav-underline {
     position: relative;
-    height: 16rpx;
+    height: 12rpx;
     // background: linear-gradient( 90deg, rgba(56,217,125,0.5) 0%, rgba(56,217,125,0) 100%);
     border-radius: 8rpx;
     bottom: 15rpx;

+ 1 - 1
manifest.json

@@ -69,7 +69,7 @@
     "quickapp" : {},
     /* 小程序特有相关 */
     "mp-weixin" : {
-        "appid" : "wx4d225cc86cc7885d",
+        "appid" : "wx776d6bd6848eec49",
         "setting" : {
             "urlCheck" : false,
             "minified" : true,

+ 107 - 113
pages/home/components/home-discount.vue

@@ -6,120 +6,114 @@
  * @Description: 自定义轮播图组件
 -->
 <template>
-    <view class="w-all relative zi-2  mt-4">
-        <swiper class="w-all" :style="{ height: height * 2 + 'rpx', }" :circular="circular"
-            :indicator-dots="indicatorDots" indicator-active-color="#02B176 " indicator-color="#EEEEEE"
-            :autoplay="autoplay" :interval="interval" :duration="duration" :current="current"
-            :display-multiple-items='displayMultipleItems' :next-margin="nextMargin" @change="change"
-            @transition="transition" @animationfinish="animationfinish">
-            <swiper-item class="flex flex-wrap h-all " v-for="(item, index) in swiperList" :key="index">
-                <view class="w-74 h-82 bg-white flex items-center justify-center">
-                    <view class="w-64 h-82 flex flex-column items-center  justify-center">
-                        <image
-                            src="https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422"
-                            class="w-35 h-44" />
-                        <view class="h-15 text-ellipsis fw-400 fs-11 my-3">葵小儿健脾问问</view>
-                        <view class="w-54 h-16 rounded-16 bg-FA341E text-white text-center fs-9 relative">
-                            ¥<text class="fs-13">19</text>
-                            <text class="fs-9">.20</text>
-                            <image src="/static/images/home/sdyhzq_arrow_icon16@2x.png"
-                                class="w-16 h-16 absolute top-0 left--6 zi-10" />
-                        </view>
-                    </view>
-
-                </view>
-            </swiper-item>
-        </swiper>
-        <view class="flex items-center justify-center w-all gap-6 mt-11" v-if="isCustomDot">
-            <view v-for="(item, index) in swiperList" :key="index" class="w-10 h-2  rounded-1"
-                :class="index == current ? 'bg-02B176' : 'bg-EEEEEE'"></view>
-        </view>
-    </view>
+	<view class="w-all relative zi-2 mt-4">
+		<swiper class="w-all" :style="{ height: height * 2 + 'rpx' }" :circular="circular"
+			:indicator-dots="indicatorDots" indicator-active-color="#02B176" indicator-color="#EEEEEE"
+			:autoplay="autoplay" :interval="interval" :duration="duration" :current="current"
+			:display-multiple-items="displayMultipleItems" :next-margin="nextMargin" @change="change"
+			@transition="transition" @animationfinish="animationfinish">
+			<swiper-item class="flex flex-wrap h-all" v-for="(item, index) in list" :key="index">
+				<view class="w-74 h-82 bg-white flex items-center justify-center">
+					<view class="w-64 h-82 flex flex-column items-center justify-center">
+						<image :src="item.image || '/static/images/img.png'" class="w-35 h-44" />
+						<view class="h-15 text-ellipsis fw-400 fs-11 my-3">{{ item.productName || '商品名称' }}</view>
+						<view class="w-54 h-16 rounded-16 bg-FA341E text-white text-center fs-9 relative">
+							¥<text class="fs-13">{{ splitPrice(item.price).integer || '00' }}</text>
+							<text class="fs-9">{{ splitPrice(item.price).decimal || '00' }}</text>
+							<image src="/static/images/home/sdyhzq_arrow_icon16@2x.png"
+								class="w-16 h-16 absolute top-0 left--6 zi-10" />
+						</view>
+					</view>
+				</view>
+			</swiper-item>
+		</swiper>
+		<view class="flex items-center justify-center w-all gap-6 mt-11" v-if="isCustomDot">
+			<view v-for="(item, index) in list" :key="index" class="w-10 h-2 rounded-1"
+				:class="index == current ? 'bg-02B176' : 'bg-EEEEEE'"></view>
+		</view>
+	</view>
 </template>
 <script>
 export default {
-    props: {
-        swiperList: {
-            type: Array,
-            default: () => []
-        },
-        // 轮播图高度rpx
-        height: {
-            type: Number,
-            default: 85
-        },
-        // 是否显示指示器
-        indicatorDots: {
-            type: Boolean,
-            default: false
-        },
-        // 是否循环播放
-        circular: {
-            type: Boolean,
-            default: true
-        },
-        // 是否自动切换
-        autoplay: {
-            type: Boolean,
-            default: false
-        },
-        // 自动切换时间间隔
-        interval: {
-            type: Number,
-            default: 3000
-        },
-        // 切换动画时长
-        duration: {
-            type: Number,
-            default: 1000
-        },
-        // 显示多个项
-        displayMultipleItems: {
-            type: Number,
-            default: 2
-        },
-        // 下一个项的外边距
-        nextMargin: {
-            type: String,
-            default: '0'
-        },
-
-        // 当前滑块显示项的索引
-        current: {
-            type: Number,
-            default: 0
-        },
-        // 是否显示自定义指示点
-        isCustomDot: {
-            type: Boolean,
-            default: false
-        },
-    },
-    data() {
-        return {
-            currentDot: 0,
-        }
-    },
-    methods: {
-        // current 改变时会触发 change 事件
-        change(e) {
-            this.$emit('change', e.detail.current)
-        },
-        // 	swiper-item 的位置发生改变时会触发
-        transition(e) {
-            // console.log('transition:', e.detail)
-            this.$emit('transition', e.detail.current)
-        },
-        // 	swiper-item 的位置发生改变并且动画结束时会触发
-        animationfinish(e) {
-            this.$emit('animationfinish', e.detail.current)
-        },
-        // 导航到对应页面
-        handleNavTo(value) {
-            // 根据实际需求实现导航逻辑
-            console.log('导航到:', value)
-        }
-    }
-}
+	props: {
+		swiperList: {
+			type: Array,
+			default: () => []
+		},
+		height: {
+			type: Number,
+			default: 85
+		},
+		indicatorDots: {
+			type: Boolean,
+			default: false
+		},
+		circular: {
+			type: Boolean,
+			default: true
+		},
+		autoplay: {
+			type: Boolean,
+			default: false
+		},
+		interval: {
+			type: Number,
+			default: 3000
+		},
+		duration: {
+			type: Number,
+			default: 1000
+		},
+		displayMultipleItems: {
+			type: Number,
+			default: 2
+		},
+		nextMargin: {
+			type: String,
+			default: '0'
+		},
+		current: {
+			type: Number,
+			default: 0
+		},
+		isCustomDot: {
+			type: Boolean,
+			default: false
+		}
+	},
+	data() {
+		return {
+			list: [],
+			currentDot: 0
+		}
+	},
+	mounted() {
+		console.log("首单优惠专区", this.swiperList);
+		this.list = this.swiperList[0].productList || [];
+		console.log("数据", this.swiperList);
+	},
+	methods: {
+		splitPrice(price) {
+			const priceStr = parseFloat(price).toFixed(2).toString();
+			return {
+				integer: priceStr.split('.')[0],
+				decimal: priceStr.split('.')[1]
+			};
+		},
+		change(e) {
+			this.$emit('change', e.detail.current);
+		},
+		transition(e) {
+			this.$emit('transition', e.detail.current);
+		},
+		animationfinish(e) {
+			this.$emit('animationfinish', e.detail.current);
+		},
+		handleNavTo(value) {
+			console.log('导航到:', value);
+		}
+	}
+};
 </script>
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+</style>

+ 51 - 17
pages/home/components/home-goods.vue

@@ -1,26 +1,27 @@
 <template>
     <view class="px-12 mt-14">
-        <view class="bg-white  pb-10 rounded-8 overflow-hidden">
+        <view v-for="(product, index) in productList" :key="index" class="bg-white  pb-10 rounded-8 overflow-hidden mb-14">
             <image class="w-all h-195"
-                src="https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422">
+                :src="product.image|| '/static/images/img.png'">
             </image>
             <view
                 class="goods-count px-12 flex items-center justify-between text-white w-all h-32 rounded-6 mt--15 zi-2 relative">
-                <view class="fw-500 fs-18">热卖爆品</view>
-                <view class="fw-400 fs-13">已售1000件</view>
+                <view class="fw-500 fs-18">{{ product.tag || '热卖爆品' }}</view>
+                <view class="fw-400 fs-13">已售{{ product.sales || '0' }}件</view>
             </view>
             <view class="fw-500 fs-13 text-333333 mt-11 px-12">
-                [广州康和药业 GKH PHARMACEUTICAL LTD]盐酸多西环素片 0.1g*12片 1盒装
+                {{ product.name || product.productName || '产品名称' }}
             </view>
-            <view class="fw-400 fs-12 text-D46C0D mt-7 px-12">
-                处方药须凭处方在药师指导下购买和使用
+            <view class="fw-400 fs-12 text-D46C0D mt-7 px-12" v-if="product.warning">
+                {{ product.warning }}
             </view>
             <view class="flex items-center justify-between mt-7 px-12">
-                <view class="flex items-center gap-4 text-FF4B33 fs-11">
-                    <view class="px-4 ph-2 border border-FFA599 rounded-2 ">9.5折</view>
-                    <view class="px-4 ph-2 border border-FFA599 rounded-2 ">限购1份</view>
+                <view class="flex items-center gap-4 text-FF4B33 fs-11" v-if="product.discounts && product.discounts.length">
+                    <view v-for="(discount, i) in product.discounts" :key="i" class="px-4 ph-2 border border-FFA599 rounded-2 ">
+                        {{ discount }}
+                    </view>
                 </view>
-                <view class="flex items-center gap-2">
+                <view class="flex items-center gap-2" v-if="product.coupon">
                     <view class="fs-12 text-FA341E fw-400">领卷</view>
                     <image class="w-12 h-12" src="/static/images/home/sdyhzq_bg@2x.png"></image>
                 </view>
@@ -29,25 +30,58 @@
                 <view class="flex items-end gap-8">
                     <view class="text-FA341E ">
                         <text class="fs-12 fw-600">¥</text>
-                        <text class="fs-24 fw-600">105</text>
-                        <text class="fs-15 fw-600">.36</text>
+                        <text class="fs-24 fw-600">{{splitPrice(product.price).integer||'0'}}</text>
+                        <text class="fs-15 fw-600">{{ splitPrice(product.price).decimal|| '0' }}</text>
                     </view>
-                    <view class="text-999999 fs-13 fw-400 text-line-through pb-3">
-                        ¥128.00
+                    <view class="text-999999 fs-13 fw-400 text-line-through pb-3" v-if="product.originalPrice">
+                        ¥{{ product.originalPrice }}
                     </view>
                 </view>
                 <view class="flex items-center w-110 h-34 rounded-34 overflow-hidden">
-                    <view class="w-44 h-all flex items-center justify-center bg-38D97D">
+                    <view class="w-44 h-all flex items-center justify-center bg-38D97D" @click="addToCart(product)">
                         <image class="w-20 h-20" src="/static/images/home/shopping_car_icon24@2x.png">
                         </image>
                     </view>
-                    <view class="flex-1 h-all flex items-center justify-center bg-02B176 fw-500 text-white fs-14">
+                    <view class="flex-1 h-all flex items-center justify-center bg-02B176 fw-500 text-white fs-14" @click="goToBuy(product)">
                         去购买</view>
                 </view>
             </view>
         </view>
     </view>
 </template>
+<script>
+export default {
+    props: {
+        productList: {
+            type: Array,
+            default: () => []
+        },
+    },
+    mounted() {
+        console.log("商品列表", this.productList);
+    },
+    methods: {splitPrice(price) {
+				const priceStr = parseFloat(price).toFixed(2).toString();
+				return {
+					integer: priceStr.split('.')[0],
+					decimal: priceStr.split('.')[1]
+				};
+			},
+        // 添加到购物车
+        addToCart(product) {
+            console.log('添加到购物车:', product);
+            // 触发父组件的添加购物车事件
+            this.$emit('addToCart', product);
+        },
+        // 去购买
+        goToBuy(product) {
+            console.log('去购买:', product);
+            // 触发父组件的去购买事件
+            this.$emit('goToBuy', product);
+        },
+    }
+}
+</script>
 <style scoped lang="scss">
 .goods-count {
     background: linear-gradient(to right, #FA341E, #F4A007)

+ 12 - 5
pages/home/components/home-hot.vue

@@ -16,11 +16,11 @@
                 <view class="w-74 h-82 bg-white flex items-center justify-center">
                     <view class="w-64 h-82 flex flex-column items-center  justify-center">
                         <image style="border: 1px solid #ffffff;"
-                            src="https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422"
-                            class="w-46 h-46 rounded-6" />
-                        <view class="h-15 text-ellipsis fw-400 fs-10 my-3 fw-500 text-D46C0D">营养保健Top1</view>
+                            :src="item.imageUrl || item.img || 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422'"
+                            class="image" />
+                        <view class="fs20 fw-500 text-D46C0D mt14">{{ item.rankText || '营养保健Top1' }}</view>
                         <view class="w-54 h-16 rounded-16  text-D46C0D text-center fs-10 fw-400 relative">
-                            热销234件
+                            热销{{ item.sales || '234' }}
                             <image src="/static/images/home/hot_selling_list_img@2x.png"
                                 class="w-8 h-12 absolute top-0 left--4 zi-10 rotateY-180" />
                             <image src="/static/images/home/hot_selling_list_img@2x.png"
@@ -122,4 +122,11 @@ export default {
     }
 }
 </script>
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+	.image{
+		width: 92rpx;
+		height: 92rpx;
+		flex-shrink: 0;
+	}
+	
+</style>

+ 3 - 3
pages/home/components/home-play.vue

@@ -14,12 +14,12 @@
             :next-margin="nextMargin" @change="change" @transition="transition" @animationfinish="animationfinish">
             <swiper-item class="flex flex-wrap h-all w-all bg-light relative" v-for="(item, index) in swiperList"
                 :key="index">
-                <image src="https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422"
+                <image :src="item.imageUrl || item.img || 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422'"
                     class="w-all h-all" />
 
                 <view class="flex items-center h-30 fw-400 fs-10 rounded-6 overflow-hidden absolute top-8 left-8">
-                    <view class="h-all left-box text-white px-4 lh-30">预约中</view>
-                    <view class="h-all px-4 text-white bg-000000 opacity-6 lh-30">1800人已预约</view>
+                    <view class="h-all left-box text-white px-4 lh-30">{{ item.status || '预约中' }}</view>
+                    <view class="h-all px-4 text-white bg-000000 opacity-6 lh-30">{{ item.reserveCount || '1800' }}人已预约</view>
                 </view>
             </swiper-item>
         </swiper>

+ 18 - 15
pages/home/components/home-product.vue

@@ -10,7 +10,7 @@
                 </view>
 
             </view>
-            <HomePlay :swiperList="swiperPlayList" :current="swiperCurrent"
+            <HomePlay :swiperList="recommendList" :current="swiperCurrent"
                 @change="swiperCurrent = $event" />
         </view>
         <view class="w-171 h-265 flex flex-column justify-between">
@@ -19,14 +19,14 @@
                 </image>
                 <view class="relative zi-2">
                     <image class="w-95 h-18 " src="/static/images/home/sdyhzq_title@2x.png"></image>
-                    <HomeDiscount  :swiperList="swiperPlayList"  />
+                    <HomeDiscount  :swiperList="recommendList"  />
                 </view>
             </view>
             <view class="w-all h-128 bg-white relative p-11 rounded-8 overflow-hidden">
                 <image class="w-all h-all absolute top-0 left-0 " src="/static/images/home/jrrm_bg@2x.png"></image>
                 <view class="relative zi-2">
                     <image class="w-64 h-18 " src="/static/images/home/jrrm_title@2x.png"></image>
-                    <HomeHot :swiperList="swiperPlayList"/>
+                    <HomeHot :swiperList="recommendList"/>
                 </view>
             </view>
         </view>
@@ -44,23 +44,26 @@ export default {
         HomeHot,
     },
     props: {
-
+        recommendList: {
+            type: Array,
+            default: () => []
+        },
     },
     data() {
         return {
             swiperCurrent: 0,
-            swiperPlayList: [
-                {
-                    name: '1',
-                },
-                {
-                    name: '2',
-                },
-                {
-                    name: '3',
-                },
-            ],
         }
     },
+    mounted() {
+        console.log("首单-组件挂载时",this.recommendList);
+    },
+    watch: {
+        recommendList: {
+            immediate: true,
+            handler(newVal) {
+                console.log("首单-recommendList变化", newVal);
+            }
+        }
+    }
 }
 </script>

+ 72 - 0
pages/home/components/home-sales-rank.vue

@@ -0,0 +1,72 @@
+<!--
+ * @Author: jmy
+ * @Date: 2026-01-20 12:00:00
+ * @Description: 实时销量榜组件
+-->
+<template>
+    <view class="sales-rank-container mt-14">
+        <view class="rank-bg" style="background-image: url('/static/sales_ranking_bg.png');">
+            <view class="rank-title flex items-center justify-between mb-10 px-12 pt-12">
+                <view class="fs-18 fw-500 text-333333">实时销量榜</view>
+                <view class="fs-12 fw-400 text-999999 flex items-center">
+                    更多 <image class="w-12 h-12 ml-4" src="/static/right1.png"></image>
+                </view>
+            </view>
+            <view class="rank-list px-12 pb-12">
+                <view v-for="(item, index) in rankList" :key="index" class="rank-item flex items-center justify-between p-12 bg-white rounded-8 mb-10">
+                    <view class="flex items-center">
+                        <view class="rank-number w-24 h-24 rounded-full flex items-center justify-center text-white fs-12 fw-600 mr-10" :class="{
+                            'bg-FA341E': index === 0,
+                            'bg-F4A007': index === 1,
+                            'bg-FFA599': index === 2,
+                            'bg-999999': index >= 3
+                        }">
+                            {{ index + 1 }}
+                        </view>
+                        <image :src="item.imageUrl || item.img || 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422'" class="w-72 h-72 rounded-4 mr-12"></image>
+                        <view class="flex-1">
+                            <view class="fs-13 fw-500 text-333333 text-ellipsis">{{ item.name || item.productName || '商品名称' }}</view>
+                            <view class="fs-11 fw-400 text-999999 mt-4">已售{{ item.sales || 0 }}件</view>
+                            <view class="fs-14 fw-600 text-FA341E mt-4">¥{{ item.price || '0.00' }}</view>
+                        </view>
+                    </view>
+                    <view class="add-to-cart w-36 h-36 bg-02B176 rounded-full flex items-center justify-center" @click="$emit('addToCart', item)">
+                        <image class="w-20 h-20" src="/static/images/home/shopping_car_icon24@2x.png"></image>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+<script>
+export default {
+    props: {
+        rankList: {
+            type: Array,
+            default: () => []
+        }
+    },
+    mounted() {},
+
+
+    methods: {
+        // 方法可以在这里添加
+    }
+}
+</script>
+<style lang="scss" scoped>
+.sales-rank-container {
+    .rank-bg {
+        background-size: cover;
+        background-repeat: no-repeat;
+        background-position: center;
+        border-radius: 8px;
+        overflow: hidden;
+    }
+    .rank-item {
+        &:last-child {
+            margin-bottom: 0;
+        }
+    }
+}
+</style>

+ 1 - 1
pages/home/components/home-search.vue

@@ -5,7 +5,7 @@
                 <image class="icon-search" src="/static/images/search.png" mode="aspectFit"></image>
                 <input class="input-value" type="text" v-model="keyword" placeholder="搜索商品" confirm-type="search"
                     @confirm="onSearch" />
-                <button class="w-60 h-30 rounded-15 fs-14 color-white lh-30" @click="onSearch">搜索</button>
+                <button class="w-60 h-30 rounded-15 fs-14 colorf lh-30" @click="onSearch">搜索</button>
             </view>
         </view>
         <view class="w-24 h-24 relative">

+ 65 - 0
pages/home/components/home-waterfall.vue

@@ -0,0 +1,65 @@
+<!--
+ * @Author: jmy
+ * @Date: 2026-01-20 12:00:00
+ * @Description: 瀑布流商品组件
+-->
+<template>
+    <view class="waterfall-container mt-14">
+        <view class="waterfall-title flex items-center justify-between mb-10 px-12">
+            <view class="fs-18 fw-500 text-333333">瀑布流商品</view>
+        </view>
+        <view class="waterfall-list flex justify-between px-12">
+            <view class="waterfall-column" v-for="(column, index) in waterfallColumns" :key="index">
+                <view v-for="(item, idx) in column" :key="idx" class="waterfall-item bg-white rounded-8 mb-10 overflow-hidden">
+                    <image :src="item.firstImage || 'https://img1.baidu.com/it/u=2172818577,3783888802&fm=253&app=138&f=JPEG?w=800&h=1422'" class="w-all"></image>
+                    <view class="p-12">
+                        <view class="fs-13 fw-500 text-333333 text-ellipsis">{{item.title || '商品名称' }}</view>
+                        <view class="fs-11 fw-400 text-999999 mt-4 line-2">{{ item.intro || '商品描述' }}</view>
+                        <view class="flex items-end justify-between mt-10">
+                            <view class="fs-16 fw-600 text-FA341E">¥{{ item.price || '0.00' }}</view>
+                            <view class="add-to-cart w-36 h-36 bg-02B176 rounded-full flex items-center justify-center" @click="$emit('addToCart', item)">
+                                <image class="w-20 h-20" src="/static/images/home/shopping_car_icon24@2x.png"></image>
+                            </view>
+                        </view>
+                    </view>
+                </view>
+            </view>
+        </view>
+    </view>
+</template>
+<script>
+export default {
+    props: {
+        productList: {
+            type: Array,
+            default: () => []
+        },
+        columns: {
+            type: Number,
+            default: 2
+        }
+    },
+    computed: {
+        waterfallColumns() {
+            // 将商品列表分割成指定列数的瀑布流
+            const columns = [];
+            for (let i = 0; i < this.columns; i++) {
+                columns[i] = [];
+            }
+            this.productList.forEach((item, index) => {
+                columns[index % this.columns].push(item);
+            });
+            return columns;
+        }
+    }
+}
+</script>
+<style lang="scss" scoped>
+.waterfall-container {
+    .waterfall-list {
+        .waterfall-column {
+            width: calc((100% - 10px) / 2);
+        }
+    }
+}
+</style>

+ 245 - 12
pages/home/index.vue

@@ -45,7 +45,7 @@
 						<HomeMenu :autoplay="false" :swiperList="menusData" />
 					</view>
 					<!-- 商品栏 -->
-					<HomeProduct />
+					<HomeProduct :recommendList="recommendList" />
 					<!-- tab栏 -->
 					<view class="tab-goods w-all mt-10 rounded-t-8 px-28">
 						<ScsScrollNavbar :tabsData="tabsProduct" activeColor="#02B176" textColor="#333333"
@@ -54,7 +54,16 @@
 							@tabChange="tabProductChange" />
 					</view>
 					<!-- 商品列表 -->
-					<HomeGoods />
+					<HomeGoods :productList="recommendList" @addToCart="addToCart" @goToBuy="goToBuy" />
+
+					<!-- 销量榜和瀑布流商品容器 -->
+					<view class="sales-waterfall-container px-12">
+						<!-- 实时销量榜 -->
+						<HomeSalesRank :rankList="salesRankList" @addToCart="addToCart" />
+
+						<!-- 瀑布流商品 -->
+						<HomeWaterfall :productList="productList" @addToCart="addToCart" />
+					</view>
 
 					<u-gap height="15"></u-gap>
 				</template>
@@ -74,9 +83,18 @@
 	import HomeProduct from './components/home-product.vue'
 	import HomeSearch from './components/home-search.vue'
 	import HomeGoods from './components/home-goods.vue'
+	import HomeSalesRank from './components/home-sales-rank.vue'
+	import HomeWaterfall from './components/home-waterfall.vue'
 	import channel from '@/components/channel.vue'
 	import {
-		getMenu
+		getMenu,
+		productWaterfall, // 商品搜索瀑布流
+		recommendProduct, // 获取首页推荐商品
+		addCart, // 添加购物车
+		cartNum, // 改变购物车数量
+		delCart, // 删除购物车
+		cartCount, // 获取商品购物车数量
+		getCarts, // 获取购物车列表
 	} from '@/api/index'
 
 	export default {
@@ -85,10 +103,14 @@
 			HomeProduct,
 			HomeSearch,
 			HomeGoods,
+			HomeSalesRank,
+			HomeWaterfall,
 			channel
 		},
 		data() {
 			return {
+				recommendList: [], //推荐商品
+				productList: [], //瀑布流商品
 				showChannel: false, // 默认不显示
 				channelManager: true,
 				// 频道相关数据
@@ -173,16 +195,173 @@
 
 				// 商品列表数据
 				goodList: [1, 2],
+				// 购物车数据
+				cartCount: 0,
+				cartList: [],
+				// 加载状态
+				loading: false,
+				refreshing: false,
+				// 分页
+				page: 1,
+				pageSize: 10,
+				// 是否有更多数据
+				hasMore: true,
+				// 实时销量榜数据
+				salesRankList: [],
 			}
 		},
 		onLoad() {
+			// 临时设置AppToken用于测试
+			// uni.setStorageSync('AppToken', 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiI1NDU2NDYiLCJpYXQiOjE3Njc3NzUzNjAsImV4cCI6MTc3NjQxNTM2MH0.FByLtpMTm2p3V385nfRqkoYFZO41FaoW3NQ-mqxHEoUV2mwdx8Y6w_MHadA7lFWGzK5CLZ8fmyqupEXBKYvflg');
+
+			this.getProductWaterfall(); // 商品搜索瀑布流
+			this.getRecommendProduct(); // 获取首页推荐商品
+			// this.getCartCount(); // 获取商品购物车数量
+			// this.getCarts(); //获取购物车列表
 			this.onSomeButtonClick();
+
 			// 页面加载时初始化
 		},
 		onShow() {
 			this.getMenuData();
 		},
 		methods: {
+			// 商品搜索瀑布流
+			getProductWaterfall(isLoadMore = false) {
+
+				if (this.loading && !isLoadMore) return;
+
+				this.loading = true;
+				let data = {
+					page: isLoadMore ? this.page + 1 : 1,
+					pageSize: this.pageSize
+				}
+
+				productWaterfall(data).then(
+					res => {
+						if (res.code == 200) {
+
+							if (isLoadMore) {
+								console.log("加载更多商品");
+
+								// 加载更多
+								if (res.data && res.data.length > 0) {
+									this.productList = [...this.productList, ...res.data];
+									this.page += 1;
+									this.hasMore = res.data.length === this.pageSize;
+								} else {
+									this.hasMore = false;
+								}
+							} else {
+								// 首次加载或刷新
+								this.productList = res.data || [];
+								console.log("加载更多商品", res.data);
+
+								this.page = 1;
+								this.hasMore = res.data && res.data.length === this.pageSize;
+							}
+						} else {
+							uni.showToast({
+								title: res.msg || '获取商品列表失败',
+								icon: 'none'
+							})
+						}
+						this.loading = false;
+						this.refreshing = false;
+					},
+					rej => {
+						uni.showToast({
+							title: '网络错误,请重试',
+							icon: 'none'
+						})
+						this.loading = false;
+						this.refreshing = false;
+					}
+				);
+			},
+			// 获取首页推荐商品
+			getRecommendProduct() {
+				recommendProduct().then(
+					res => {
+						if (res.code == 200) {
+							this.recommendList = res.data;
+							console.log("获取首页推荐商品", res.data);
+							// 使用推荐商品数据作为销量榜数据(实际项目中应该使用专门的销量榜接口)
+							// 按照销量排序
+							this.salesRankList = [...res.data].sort((a, b) => (b.sales || 0) - (a.sales || 0)).slice(0,
+								5);
+						} else {
+							uni.showToast({
+								title: res.msg || '获取推荐商品失败',
+								icon: 'none'
+							})
+						}
+					},
+					rej => {
+						uni.showToast({
+							title: '网络错误,请重试',
+							icon: 'none'
+						})
+					}
+				);
+			},
+			// 获取商品购物车数量
+			getCartCount() {
+				getCartCount().then(
+					res => {
+						if (res.code == 200) {
+							console.log("获取商品购物车数量", res.data);
+							// 保存购物车数量到全局或本地状态
+							this.cartCount = res.data;
+						}
+					},
+					rej => {
+						console.error("获取商品购物车数量失败", rej);
+					}
+				);
+			},
+			// 获取购物车列表
+			getCarts() {
+				getCarts().then(
+					res => {
+						if (res.code == 200) {
+							console.log("获取购物车列表", res.data);
+							// 保存购物车列表到全局或本地状态
+							this.cartList = res.data;
+						}
+					},
+					rej => {
+						console.error("获取购物车列表失败", rej);
+					}
+				);
+			},
+
+			async getMenuData() {
+				try {
+					const {
+						code,
+						data,
+						msg
+					} = await getMenu();
+					if (code == 200) {
+						// 将数据每5个一组分割
+						this.menusData = this.$scsUtils.splitArrayIntoSubarrays(data, 5) || []
+					} else {
+						uni.showToast({
+							title: msg,
+							icon: 'none'
+						})
+					}
+				} catch (error) {
+					console.error('获取菜单数据失败:', error);
+					uni.showToast({
+						title: '网络错误,请重试',
+						icon: 'none'
+					})
+				}
+			},
+
+
 			showChannelPopup() {
 				this.showChannel = true;
 			},
@@ -218,8 +397,20 @@
 						msg
 					} = await getMenu();
 					if (code == 200) {
+						// 确保数据格式正确,适配HomeMenu组件需要的icon和menuName字段
+						const formattedData = data.map(item => ({
+							// 适配接口返回的字段名,如果接口返回的字段名不同,可以在这里进行映射
+							icon: item.icon || '',
+							menuName: item.name || item.menuName || ''
+						}));
+
 						// 将数据每5个一组分割
-						this.menusData = this.$scsUtils.splitArrayIntoSubarrays(data, 5) || []
+						if (this.$scsUtils && this.$scsUtils.splitArrayIntoSubarrays) {
+							this.menusData = this.$scsUtils.splitArrayIntoSubarrays(formattedData, 5) || [];
+						} else {
+							// 如果$scsUtils不存在,使用自定义的分割方法
+							this.menusData = this.splitArrayIntoSubarrays(formattedData, 5);
+						}
 					} else {
 						uni.showToast({
 							title: msg,
@@ -234,24 +425,34 @@
 					})
 				}
 			},
+			// 自定义数组分割方法
+			splitArrayIntoSubarrays(arr, size) {
+				if (!Array.isArray(arr)) return [];
+				const result = [];
+				for (let i = 0; i < arr.length; i += size) {
+					result.push(arr.slice(i, i + size));
+				}
+				return result;
+			},
 
 			// 下拉刷新
 			onfresher() {
+				if (this.refreshing || this.loading) return;
+
+				this.refreshing = true;
 				const self = this;
 				self.$refs.fresher.isTrigger = true;
 
-				// 模拟异步请求
-				setTimeout(() => {
-					self.$refs.fresher.refresherText = "刷新成功";
-					self.$refs.fresher.isTrigger = false;
-					// 这里可以添加实际的数据刷新逻辑
-				}, 500);
+				// 刷新数据
+				this.getProductWaterfall(false);
 			},
 
 			// 上拉加载更多
 			loadMore() {
-				// 实现加载更多逻辑
-				console.log('加载更多数据');
+				if (this.loading || this.refreshing || !this.hasMore) return;
+
+				// 加载更多数据
+				this.getProductWaterfall(true);
 			},
 
 			// 频道相关方法
@@ -270,6 +471,38 @@
 				this.activeChannelId = channel.id;
 				// 根据频道切换内容
 			},
+
+			// 添加到购物车
+			addToCart(product) {
+				console.log('添加到购物车:', product);
+				// 调用添加购物车接口
+				addCart({
+					productId: product.id,
+					quantity: 1
+				}).then(res => {
+					if (res.code == 200) {
+						uni.showToast({
+							title: '添加购物车成功',
+							icon: 'success'
+						})
+						// 重新获取购物车数量
+						this.getCartCount();
+					} else {
+						uni.showToast({
+							title: res.msg || '添加购物车失败',
+							icon: 'none'
+						})
+					}
+				})
+			},
+			// 去购买
+			goToBuy(product) {
+				console.log('去购买:', product);
+				// 跳转到商品详情页
+				uni.navigateTo({
+					url: `/pages/product/detail?id=${product.id}`
+				})
+			},
 		}
 	}
 </script>

+ 78 - 44
pages/home/productSearch.vue

@@ -15,16 +15,6 @@
 				<view class="search" @click="handleSearch">搜索</view>
 			</view>
 		</view>
-		<!-- 搜索历史 -->
-		<!-- <view class="title-box">
-			<text class="title">历史搜索</text>
-			<image src="../../static/images/del.png" mode="" @click="clearHistory"></image>
-		</view>
-		<view class="data-list">
-			<view class="item" v-for="(item,index) in searchHistory" :key="index" @click="doSearch(item)">
-				{{ item }}
-			</view>
-		</view> -->
 
 		<!-- 热门搜索 -->
 		<view class="title-box">
@@ -57,17 +47,18 @@
 					<text class="title1">今日热卖榜</text>
 				</view>
 				<view class="product-list">
-					<view class="product-item">
+					<view class="product-item" v-for="(item,index) in todayList" :key="index">
 						<view class="left">
-							<image class="photo" src="/static/images/img.png"></image>
-							<view class="lable">1</view>
+							<image class="photo" :src="item.image"></image>
+							<view class="lable" :class="index === 0 ? 'bg1' : index === 1 ? 'bg2' : index === 2 ? 'bg3' : 'bg'">{{index+1}}</view>
 						</view>
 						<view class="right">
-							<view class="title">乌灵胶囊81粒养心安神失乌灵胶囊81粒养心安神失眠乌灵胶囊81粒养心安神失眠眠健...</view>
-							<view class="txt">肌肉酸疼、扭伤拉伤</view>
+							<view class="title">{{item.productName}}</view>
+							<view class="txt">{{item.productInfo}}</view>
 							<view class="num-box">
-								<view class="price"><text class="symbol">¥</text><text class="bold">89</text>.48</view>
-								<view class="sale">已售 5485</view>
+								<view class="price"><text class="symbol">¥</text><text
+										class="bold">{{item.price}}</text>.48</view>
+								<view class="sale">已售 {{item.sales}}</view>
 							</view>
 						</view>
 					</view>
@@ -82,17 +73,18 @@
 					<text class="title1">30天新品热销榜单</text>
 				</view>
 				<view class="product-list">
-					<view class="product-item">
+					<view class="product-item" v-for="(item,index) in newProductList" :key="index">
 						<view class="left">
-							<image class="photo" src="/static/images/img.png"></image>
-							<view class="lable">1</view>
+							<image class="photo" :src="item.image"></image>
+						<view class="lable" :class="index === 0 ? 'bg1' : index === 1 ? 'bg2' : index === 2 ? 'bg3' : 'bg'">{{index+1}}</view>
 						</view>
 						<view class="right">
-							<view class="title">乌灵胶囊81粒养心安神失乌灵胶囊81粒养心安神失眠乌灵胶囊81粒养心安神失眠眠健...</view>
-							<view class="txt">肌肉酸疼、扭伤拉伤</view>
+							<view class="title">{{item.productName}}</view>
+							<view class="txt">{{item.productInfo}}</view>
 							<view class="num-box">
-								<view class="price"><text class="symbol">¥</text><text class="bold">89</text>.48</view>
-								<view class="sale">已售 5485</view>
+								<view class="price"><text class="symbol">¥</text><text
+										class="bold">{{item.price}}</text>.48</view>
+								<view class="sale">已售 {{item.sales}}</view>
 							</view>
 						</view>
 					</view>
@@ -103,9 +95,14 @@
 </template>
 
 <script>
+	import {
+		todayAndHot
+	} from '@/api/product.js'
 	export default {
 		data() {
 			return {
+				newProductList: [],
+				todayList: [],
 				searchValue: '',
 				// 状态栏的高度
 				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
@@ -117,6 +114,8 @@
 			};
 		},
 		onShow() {
+			this.getTodayAndHot();
+			
 			this.setFocus = true
 			this.searchHistory = this.utils.getHisSearch();
 			var config = uni.getStorageSync('config');
@@ -129,6 +128,24 @@
 			this.setFocus = false;
 		},
 		methods: {
+			getTodayAndHot() {
+				todayAndHot().then(
+					(res) => {
+						if (res.code == 200) {
+							this.newProductList = res.data.thirtyDaysNewProductRank
+							this.todayList = res.data.todayHotRank
+						} else {
+							uni.showToast({
+								title: res.msg,
+								icon: 'none'
+							});
+						}
+					},
+					(rej) => {}
+				);
+			},
+
+
 			goBack() {
 				uni.navigateBack({
 					delta: 1 // 返回的页面数,1表示返回上一页
@@ -286,34 +303,38 @@
 
 		.card-group {
 			display: flex;
-			padding: 0 24rpx;
-			box-sizing: border-box;
+				padding: 0 24rpx 30rpx; /* 添加底部内边距 */
+				box-sizing: border-box;
+				align-items: flex-start;
 
 			.card {
 				width: 600rpx;
-				padding: 26rpx 32rpx 0;
-				background: #FFFFFF;
-				border-radius: 24rpx 24rpx 24rpx 24rpx;
-				position: relative;
-				z-index: 0;
-
+						padding: 26rpx 32rpx 32rpx;
+						background: #FFFFFF;
+						border-radius: 24rpx 24rpx 24rpx 24rpx;
+						position: relative;
+						z-index: 0;
+						flex-shrink: 0;
+						box-sizing: border-box;
+						display: flex;
+						flex-direction: column;
 				.card-bg {
 					width: 100%;
-					height: 96rpx;
-					position: absolute;
-					top: 0;
-					left: 0;
-					border-radius: 24rpx 24rpx 0 0;
-					z-index: -1;
+								height: 96rpx;
+								position: absolute;
+								top: 0;
+								left: 0;
+								border-radius: 24rpx 24rpx 0 0;
+								z-index: -1;
 				}
 
 				.card-title {
 					display: flex;
-					align-items: center;
-					font-weight: 600;
-					font-size: 32rpx;
-					margin-bottom: 34rpx;
-
+								align-items: center;
+								font-weight: 600;
+								font-size: 32rpx;
+								margin-bottom: 34rpx;
+								min-height: 50rpx;
 					.title1 {
 						color: #FF4400;
 					}
@@ -324,6 +345,7 @@
 				}
 
 				.product-list {
+					flex: 1;
 					.product-item {
 						display: flex;
 						align-items: center;
@@ -350,7 +372,7 @@
 								height: 32rpx;
 								text-align: center;
 								line-height: 32rpx;
-								background: linear-gradient(135deg, #C1C5CD 0%, #A5AAB5 100%);
+								// background: linear-gradient(135deg, #C1C5CD 0%, #A5AAB5 100%);
 								border-radius: 8rpx 0rpx 8rpx 0rpx;
 								font-family: Roboto, Roboto;
 								font-weight: 500;
@@ -358,6 +380,18 @@
 								color: #FFFFFF;
 
 							}
+							.bg1{
+								background: linear-gradient( 135deg, #FB7E4C 0%, #ED4B17 100%);
+							}
+							.bg2{
+								background: linear-gradient( 135deg, #FBCF3F 0%, #F9B71B 100%);
+							}
+							.bg3{
+								background: linear-gradient( 135deg, #D5AB78 0%, #C39760 100%);
+							}
+							.bg{
+								background: linear-gradient( 135deg, #C1C5CD 0%, #A5AAB5 100%);
+							}
 						}
 
 						.right {

+ 49 - 29
pages/life/life.vue

@@ -12,10 +12,10 @@
 					<image class="w40 h40" src="/static/images/shopping_car.png"></image>
 				</view>
 			</view>
-			<view class="search-cont" @click="toSearch">
+			<view class="search-cont">
 				<image class="icon-search" src="/static/images/search.png" mode=""></image>
-				<input type="text" disabled value="" placeholder="搜索商品"
-					placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
+				<input type="text" v-model="searchKeyword" placeholder="输入关键词搜索"
+					placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" @confirm="handleSearch" />
 			</view>
 			<view class="vedio-block">
 				<!-- tab栏 -->
@@ -25,7 +25,6 @@
 							:class="status ==item.value?'item active':'item'" @click="orderStatusChange(item)">
 							<view class="text">
 								{{ item.name }}
-								</image>
 							</view>
 						</view>
 					</view>
@@ -63,20 +62,20 @@
 				<mescroll-body bottom="0" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"
 					:down="downOption" :up="upOption">
 					<view class="list">
-						<view class="list-item" @click="goLive(item)" v-for="(item,index) in list" :key="index">
-							<image class="img" v-if="item.liveImgUrl" :src="item.liveImgUrl" mode="widthFix"></image>
+						<view class="list-item" @click="goLifeDetail(item.resourceId)" v-for="(item,index) in list" :key="index">
+							<image class="img" :src="item.imgsUrl||'/static/images/img.png'" mode="widthFix"></image>
 							<image class="video-icon" src="/static/images/video_icon.png"></image>
 							<image class="suspension-icon" @click="onTask" src="/static/images/suspension.png"></image>
 							<view class="info-block">
-								<view class="title">冰乳绿豆糕 冰冰凉凉谁吃谁迷糊! 谁懂,...</view>
+								<view class="title">{{ item.content }}</view>
 								<view class="item">
 									<view class="flex">
-										<image class="head" src="/static/images/img.png"></image>
-										<text class="name">崔医生</text>
+										<image class="head" :src="item.avatar"></image>
+										<text class="name">{{ item.nickname }}</text>
 									</view>
 									<view class="flex">
 										<image class="icon" src="/static/images/zan_icon.png"></image>
-										<text>141</text>
+										<text>{{ item.clickCount }}</text>
 									</view>
 								</view>
 								<view class="card">
@@ -100,11 +99,11 @@
 <script>
 	import Task from '@/components/task.vue'
 	import {
-		// liveList
+		lifeList
 	} from '@/api/life.js'
-	import {
-		liveList
-	} from '@/api/living.js'
+	// import {
+	// 	liveList
+	// } from '@/api/living.js'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		mixins: [MescrollMixin],
@@ -114,31 +113,32 @@
 		data() {
 			return {
 				showTask: false,
-				status: '',
+				status: '1',
 				orderStatus: [{
 						name: "推荐",
-						value: ""
+						value: "1"
 					},
 					{
 						name: "今日主推",
-						value: "0"
+						value: "2"
 					},
 					{
 						name: "溯源相册",
-						value: "1"
+						value: "3"
 					},
 					{
 						name: "悦选菜谱",
-						value: "2"
+						value: "4"
 					}, {
 						name: "好物分享",
-						value: "3"
+						value: "5"
 					}
 				],
 				activeTab: 0,
 				// 状态栏的高度
 				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
 				list: [],
+				searchKeyword: '',
 				downOption: {
 					offset: 80,
 					use: true,
@@ -174,17 +174,33 @@
 			},
 			// 顶部搜索
 			toSearch() {
-				console.log("跳转")
-				uni.navigateTo({
-					url: '/pages/home/productSearch'
-				})
+				// console.log("跳转")
+				// uni.navigateTo({
+				// 	url: '/pages/home/productSearch'
+				// })
+			},
+			// 搜索按钮点击事件
+			handleSearch() {
+				console.log("点击搜索按钮,搜索关键词:", this.searchKeyword);
+				if (this.mescroll) {
+					this.list = [];
+					this.mescroll.resetUpScroll();
+				} else {
+					console.log("mescroll未初始化");
+				}
 			},
 			orderStatusChange(item) {
 				this.status = item.value
+				console.log(this.status)
+				if (this.mescroll) {
+					this.list = [];
+					this.mescroll.resetUpScroll();
+				}
 			},
 
 			mescrollInit(mescroll) {
 				this.mescroll = mescroll;
+				console.log("mescroll初始化完成");
 			},
 
 			// 下拉刷新回调
@@ -199,10 +215,14 @@
 				const pageSize = mescroll.size;
 
 				let data = {
+					lifeResourceType: this.status,
+					search: this.searchKeyword,
+					page: pageNum,
 					pageSize: pageSize,
-					pageNum: pageNum,
+					expertId: '', // 达人id,可根据需要添加
 				}
-				liveList(data).then(res => {
+				console.log("请求lifeList接口,参数:", data);
+				lifeList(data).then(res => {
 					if (!res) {
 						mescroll.endErr();
 						return;
@@ -228,10 +248,10 @@
 				});
 			},
 
-			goLive(item) {
+			goLifeDetail(item) {
+				console.log("去生活号文章",item)
 				uni.navigateTo({
-					// &immediate=true
-					url: `./living?liveId=${item.liveId}`
+					url: `/pages_shopping/live/article?resourceId=${item}`
 				});
 			}
 		}

+ 785 - 459
pages_shopping/live/article.vue

@@ -1,29 +1,29 @@
 <template>
 	<view class="content">
-		<view class="status_bar" :style="{height: statusBarHeight}"></view>
+		<view class="status_bar" :style="{ height: statusBarHeight }"></view>
 		<view class="top-block">
 			<view class="left">
 				<image class="w64 h64 " src="/static/images/back_black.png"></image>
-				<image class="head" src="/static/images/img.png"></image>
-				<text class="name">芳华悦选</text>
+				<image class="head" :src="lifeDetail.userInfo.avatar" @click="gotoExpertPage"></image>
+				<text class="name">{{lifeDetail.userInfo.nickname}}</text>
 			</view>
 			<view class="right">
-				<view class="icon-bg">
-					<image class="w40 h40" src="/static/images/share-icon.png"></image>
-				</view>
+				<view class="icon-bg" @click="handleShareClick">
+						<image class="w40 h40" src="/static/images/share-icon.png"></image>
+					</view>
 				<view class="icon-bg">
 					<image class="w40 h40" src="/static/images/shopping_car.png"></image>
 				</view>
 			</view>
 		</view>
 
-		<!-- 文章 -->
+		<!-- 文章 --> 
 		<view class="article">
-			<image class="photo" src="/static/images/img.png"></image>
+			<image class="photo" :src="lifeDetail.imgsUrl"></image>
 			<view class="article-main">
-				<view class="title">秋季常见问题儿科专家直播</view>
+				<view class="title">{{lifeDetail.title}}</view>
 				<view class="txt">
-					<text>秋意渐浓,凉爽的秋风不仅带来了宜人的景色,也悄然引发了儿童鼻炎的高发期。鼻塞、流涕、打喷嚏……这些看似不起眼的症状,却可能严重影响孩子们的日常生活和学习。#儿童鼻炎的高发期</text>
+					<text>{{lifeDetail.content}}</text>
 					<text class="lable">#儿童鼻炎的高发期</text>
 				</view>
 				<view class="card">
@@ -34,112 +34,93 @@
 					</view>
 					<image class="go" src="/static/images/jb_arrow_right_icon.png"></image>
 				</view>
-				<view class="place">5天前 重庆</view>
+				<view class="place">{{date}} {{lifeDetail.userInfo.addrIp}}</view>
 			</view>
 		</view>
 		<view class="line"></view>
 		<!-- 评论 -->
 		<view class="comment">
 			<view class="comment-num">
-				<text>共 124 条评论</text>
+				<text>共 {{lifeDetail.commentsCount}}条评论</text>
 				<image class="w24 h24 ml10" src="/static/images/comment-icon.png"></image>
 			</view>
 			<!--可评论输入框 -->
 			<view class="my-input">
 				<image class="head" src="/static/images/img.png"></image>
 				<view class="input-item">
-					<input class="input" placeholder="说点什么..." />
-					<image class="w40 h40" src="/static/images/emoticon_icon.png"></image>
+					<input class="input" placeholder="说点什么..." v-model="commentInput" 
+						@focus="showKeyboardInput = true" />
+					<image class="w40 h40" src="/static/images/emoticon_icon.png" @click="showEmojiPicker = true"></image>
 				</view>
 			</view>
 
 
 			<!-- 消息 -->
 			<view class="message">
-				<view class="message-item">
+				<view v-for="comment in rootComments" :key="comment.commentId" class="message-item">
 					<view class="left">
-						<image class="head" src="/static/images/img.png"></image>
+						<image class="head" :src="comment.userInfo.avatar"></image>
 						<view class="column">
 							<view class="chat">
 								<view class="name">
-									<text>爱吃土豆</text>
+									<text>{{comment.userInfo.nickname}}</text>
+									<view v-if="comment.userInfo.userId === lifeDetail.userInfo.userId" class="author-lable">作者</view>
 								</view>
 								<view class="flex-wrap">
-									<view class="txt">孩子鼻炎很严重,能不能治好呀?</view>
+									<view class="txt">{{comment.content}}</view>
 									<view class="info">
-										<text class="time">1小时前 重庆</text>
-										<view class="reply">回复</view>
-									</view>
+												<text class="time">{{comment.createAt}}</text>
+												<view class="reply" @click="handleReply(comment)">回复</view>
+											</view>
 								</view>
 							</view>
-							<view class="left mt26">
-								<image class="head-little" src="/static/images/img.png"></image>
+							<!-- 二级评论 -->
+							<view v-if="comment.children && comment.children.length > 0" class="left mt26">
+								<image class="head-little" :src="comment.children[0].userInfo.avatar"></image>
 								<view class="chat">
 									<view class="name">
-										<text>爱吃土豆</text>
-										<view class="author-lable">作者</view>
+										<text>{{comment.children[0].userInfo.nickname}}</text>
+										<view v-if="comment.children[0].userInfo.userId === lifeDetail.userInfo.userId" class="author-lable">作者</view>
 									</view>
 									<view class="flex-wrap">
-										<view class="txt">请告诉一下具体症状</view>
+										<view class="txt">{{comment.children[0].content}}</view>
 										<view class="info">
-											<text class="time">1小时前 重庆</text>
-											<view class="reply">回复</view>
-										</view>
-									</view>
-								</view>
-							</view>
-							<view class="expand">展开 2 条回复</view>
-						</view>
-					</view>
-					<view class="right">
-						<image v-if="isLike" class="w40 h40" src="/static/images/like_red_icon.png" @click="onLike">
-						</image>
-						<image v-else class="w40 h40" src="/static/images/like_icon.png" @click="onLike"></image>
-						<view class="">20</view>
-					</view>
-				</view>
-
-				<view class="message-item">
-					<view class="left">
-						<image class="head" src="/static/images/img.png"></image>
-						<view class="column">
-							<view class="chat">
-								<view class="name">
-									<text>爱吃土豆</text>
-								</view>
-								<view class="flex-wrap">
-									<view class="txt">孩子鼻炎很严重,能不能治好呀?</view>
-									<view class="info">
-										<text class="time">1小时前 重庆</text>
-										<view class="reply">回复</view>
+												<text class="time">{{comment.children[0].createAt}}</text>
+												<view class="reply" @click="handleReply(comment.children[0])">回复</view>
+											</view>
 									</view>
 								</view>
 							</view>
-							<view class="left mt26">
-								<image class="head-little" src="/static/images/img.png"></image>
-								<view class="chat">
-									<view class="name">
-										<text>爱吃土豆</text>
-										<view class="author-lable">作者</view>
-									</view>
-									<view class="flex-wrap">
-										<view class="txt">请告诉一下具体症状</view>
-										<view class="info">
-											<text class="time">1小时前 重庆</text>
-											<view class="reply">回复</view>
+							<!-- 展开的二级评论 -->
+							<view v-if="expandedComments[comment.commentId] && comment.children && comment.children.length > 1" class="mt26">
+								<view v-for="(child, index) in comment.children.slice(1)" :key="child.commentId" class="left mt26">
+									<image class="head-little" :src="child.userInfo.avatar"></image>
+									<view class="chat">
+										<view class="name">
+											<text>{{child.userInfo.nickname}}</text>
+											<view v-if="child.userInfo.userId === lifeDetail.userInfo.userId" class="author-lable">作者</view>
+										</view>
+										<view class="flex-wrap">
+											<view class="txt">{{child.content}}</view>
+											<view class="info">
+												<text class="time">{{child.createAt}}</text>
+												<view class="reply" @click="handleReply(child)">回复</view>
+											</view>
 										</view>
 									</view>
 								</view>
 							</view>
-							<view class="expand">展开 2 条回复</view>
+							<view v-if="comment.children && comment.children.length > 1" class="expand" @click="toggleExpand(comment)">
+								{{expandedComments[comment.commentId] ? '收起' : '展开 ' + (comment.children.length - 1) + ' 条回复'}}
+							</view>
 						</view>
 					</view>
 					<view class="right">
-						<image v-if="isLike" class="w40 h40" src="/static/images/like_red_icon.png" @click="onLike">
-						</image>
-						<image v-else class="w40 h40" src="/static/images/like_icon.png" @click="onLike"></image>
-						<view class="">20</view>
-					</view>
+								<image v-if="comment.isLiked" class="w40 h40" src="/static/images/like_red_icon.png" @click="toggleLikeComments(comment.commentId)">
+								</image>
+								<image v-else class="w40 h40" src="/static/images/like_icon.png" @click="toggleLikeComments(comment.commentId,!comment.isLiked)"></image>
+								<view class="">{{comment.likeCount}}</view>
+							</view>
 				</view>
 			</view>
 		</view>
@@ -147,504 +128,849 @@
 		<!-- 输入框 -->
 		<view class="chat-input-container">
 			<view class=" input-container">
-				<input id="txgMsg" placeholder="说点什么..." v-model="inputValue" placeholder-style="color:#999999;"
-					class="ml20 input-native input-field" cursor-spacing="100" :adjust-position="false" />
+				<input id="txgMsg" placeholder="说点什么..." v-model="inputValue" placeholder-style="color:#999999;" 
+					class="ml20 input-native input-field" cursor-spacing="100" :adjust-position="false" 
+					@focus="showKeyboardInput = true" />
 			</view>
 			<view class="icon-container">
-				<view class="icon-item">
-					<image v-if="isLike" class="icon" src="/static/images/like_red_icon.png" />
+				<view class="icon-item" @click="handleContentLike">
+					<image v-if="isLiked" class="icon" src="/static/images/like_red_icon.png" />
 					<image v-else class="icon" src="/static/images/like_icon.png" />
-					<text>8</text>
+					<text>{{lifeDetail.likeCount}}</text>
 				</view>
-				<view class="icon-item">
-					<image v-if="isLike" class="icon" src="/static/images/collection_yellow.png" />
+				<view class="icon-item" @click="handleContentCollection">
+					<image v-if="isCollected" class="icon" src="/static/images/collection_yellow.png" />
 					<image v-else class="icon" src="/static/images/collection.png" />
-					<text>10</text>
+					<text>{{lifeDetail.collectionCount}}</text>
 				</view>
-				<view class="icon-item">
+				<view class="icon-item" @click="handleCommentClick">
 					<image class="icon" src="/static/images/comment.png" />
-					<text>200</text>
+					<text>{{lifeDetail.commentsCount}}</text>
 				</view>
 			</view>
 		</view>
+		
+		<!-- 键盘上方的输入框 -->
+		<view v-if="showKeyboardInput" class="keyboard-input-container">
+			<view class="keyboard-input-item">
+				<input placeholder="说点什么..." v-model="keyboardInput" placeholder-style="color:#999999;" 
+					class="keyboard-input" />
+				<image class="w40 h40" src="/static/images/emoticon_icon.png" @click="showEmojiPicker = true"></image>
+				<view class="send-btn" @click="sendKeyboardComment">发送</view>
+			</view>
+		</view>
+
+		<!-- 表情选择器 -->
+		<EmojiPicker 
+			v-if="showEmojiPicker" 
+			@select="handleEmojiSelect" 
+			@close="showEmojiPicker = false" 
+		/>
 
 	</view>
 </template>
 
 <script>
-	import Task from '@/components/task.vue'
-	import {
-		listRootComments, // 一级评论列表
-		listSubComments, //二级评论列表
-		toggleLike, //内容点赞/取消点赞
-		toggleLikeComments, //评论点赞
-		share //内容分享
-	} from '@/api/life.js'
-	export default {
-		data() {
-			return {
-				resourceId: null,
-				// 状态栏的高度
-				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
-				isLike: false
+import Task from '@/components/task.vue'
+import EmojiPicker from './components/emoji-picker.vue'
+import {
+	lifeDetail,
+	listRootComments, // 一级评论列表
+	listSubComments, //二级评论列表
+	toggleLikeComments as apiToggleLikeComments, //评论点赞
+	toggleLike, //内容点赞/取消点赞
+	share, //内容分享
+	toggleCollection,//内容收藏/取消收藏点赞
+	postComment //发表评论
+} from '@/api/life.js'
+
+// 点赞/取消点赞常量
+const LIKE = 'LIKE';
+const UNLIKE = 'UNLIKE';
+export default {
+	components: {
+		Task,
+		EmojiPicker
+	},
+	data() {
+		return {
+			isCollected:false,
+			isLiked:false,
+			date:null,
+			lifeDetail: {},
+			resourceId:9,
+			// 状态栏的高度
+			statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
+			isLike: false,
+			isCollection: false,
+			// 评论输入框
+			commentInput: '',
+			// 底部输入框
+			inputValue: '',
+			// 表情选择器显示状态
+			showEmojiPicker: false,
+			// 一级评论列表
+			rootComments: [],
+			// 二级评论列表
+			subComments: [],
+			// 键盘上方输入框显示状态
+			showKeyboardInput: false,
+			// 键盘上方输入框内容
+			keyboardInput: '',
+			// 父评论ID(用于回复)
+			parentId: '',
+			// 评论展开状态
+			expandedComments: {}
 
+		}
+	},
+	onLoad(option) {
+		this.resourceId = option.resourceId;
+		this.getLifeDetail();
+		this.getListRootComments();
+		this.getListSubComments();
+	},
+	onUnload() {
+
+	},
+	methods: {
+		// 内容详情
+		getLifeDetail() {
+			if (!this.resourceId) return;
+			let data = {
+				resourceId: this.resourceId
 			}
+			lifeDetail(data).then(res => {
+				if (res.code == 200) {
+					this.lifeDetail=res.data;
+					// 计算时间差并赋值给date
+					this.date = this.calculateTimeDiff(res.data.createAt);
+					// 更新点赞和收藏状态
+					this.isLiked = res.data.isLiked || false;
+					this.isCollected = res.data.isCollected || false;
+					console.log("内容详情", res)
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			}).catch(err => { });
 		},
-		onLoad() {
-			this.getListRootComments();
+		onLike() {
+			this.isLike = !this.isLike;
 		},
-		onUnload() {
 
+		// 一级评论列表
+		getListRootComments() {
+			if (!this.resourceId) return;
+			let data = {
+				page: 1,
+				pageSize: 10,
+				resourceId: this.resourceId
+			}
+			listRootComments(data).then(res => {
+				if (res.code == 200) {
+					this.rootComments = res.data.list;
+					console.log("一级评论列表", res)
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			}).catch(err => { });
 		},
-		methods: {
-			onLike() {
-				this.isLike = !this.isLike;
-			},
-
-			// 一级评论列表
-			getListRootComments() {
-				if (!this.resourceId) return;
-				let data = {
-					page: 1,
-					pageSize: 10,
-					resourceId: this.resourceId
+		// 二级评论列表
+		getListSubComments() {
+			if (!this.resourceId) return;
+			let data = {
+				page: 1,
+				pageSize: 10,
+				resourceId: this.resourceId
+			}
+			listSubComments(data).then(res => {
+				if (res.code == 200) {
+					this.subComments = res.data.list;
+					console.log("二级评论列表", res)
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
 				}
-				listRootComments(data).then(res => {
-					if (res.code == 200) {
-						console.log("一级评论列表", res)
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
-					}
-				}).catch(err => {});
-			},
-			// 二级评论列表
-			getListSubComments() {
-				if (!this.resourceId) return;
-				let data = {
-					page: 1,
-					pageSize: 10,
-					resourceId: this.resourceId
+			}).catch(err => { });
+		},
+		// 内容点赞/取消点赞
+		toggleLike() {
+			this.isLiked=!this.isLiked;
+			if (!this.resourceId) return;
+			let data = {
+				action: this.isLike ? UNLIKE : LIKE, //LIKE / UNLIKE
+				resourceId: this.resourceId
+			}
+			toggleLike(data).then(res => {
+				if (res.code == 200) {
+					console.log("内容点赞/取消点赞", res)
+					// 切换点赞状态
+					this.isLike = !this.isLike;
+					// 重新获取内容详情,更新点赞数
+					this.getLifeDetail();
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
 				}
-				listSubComments(data).then(res => {
-					if (res.code == 200) {
-						console.log("二级评论列表", res)
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
-					}
-				}).catch(err => {});
-			},
-			// 内容点赞/取消点赞
-			toggleLike() {
-				if (!this.resourceId) return;
-				let data = {
-					action: LIKE, //LIKE / UNLIKE
-					resourceId: this.resourceId
+			}).catch(err => { });
+		},//内容收藏/取消收藏
+		toggleCollection() {
+			this.isCollected=!this.isCollected;
+
+			if (!this.resourceId) return;
+			let data = {
+				action: this.isCollection ? UNLIKE : LIKE, //LIKE / UNLIKE
+				resourceId: this.resourceId
+			}
+			toggleCollection(data).then(res => {
+				if (res.code == 200) {
+					console.log("内容收藏/取消收藏", res)
+					// 切换收藏状态
+					this.isCollection = !this.isCollection;
+					// 重新获取内容详情,更新收藏数
+					this.getLifeDetail();
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
 				}
-				toggleLike(data).then(res => {
-					if (res.code == 200) {
-						console.log("内容点赞/取消点赞", res)
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
-					}
-				}).catch(err => {});
-			},
-			// 内容分享
-			share() {
-				if (!this.resourceId) return;
-				let data = {
-					resourceId: this.resourceId
+			}).catch(err => { });
+		},
+		// 处理内容点赞按钮点击事件
+		handleContentLike() {
+			this.toggleLike();
+		},
+		// 处理内容收藏按钮点击事件
+		handleContentCollection() {
+			this.toggleCollection();
+		},
+		// 处理评论图标点击事件
+		handleCommentClick() {
+			// 显示键盘输入框
+			this.showKeyboardInput = true;
+			// 自动聚焦到键盘输入框
+			setTimeout(() => {
+				const input = uni.createSelectorQuery().select('.keyboard-input');
+				input.focus();
+			}, 100);
+		},
+		// 处理分享图标点击事件
+		handleShareClick() {
+			this.share();
+		},
+		// 跳转到专家页面
+		gotoExpertPage() {
+			if (this.lifeDetail && this.lifeDetail.userInfo && this.lifeDetail.userInfo.userId) {
+				uni.navigateTo({
+					url: '/pages_shopping/live/expert?expertId=' + this.lifeDetail.userInfo.userId
+				});
+			}
+		},
+		// 内容分享
+		share() {
+			if (!this.resourceId) return;
+			let data = {
+				resourceId: this.resourceId
+			}
+			share(data).then(res => {
+				if (res.code == 200) {
+					console.log("内容分享", res)
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
 				}
-				share(data).then(res => {
-					if (res.code == 200) {
-						console.log("内容分享", res)
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
-					}
-				}).catch(err => {});
-			},
-			 // 评论点赞
-			toggleLikeComments() {
-				if (!this.resourceId) return;
-				let data = {
-					resourceId: this.resourceId
+			}).catch(err => { });
+		},
+		// 评论点赞
+		toggleLikeComments(commentId) {
+			if (!commentId) return;
+			// 查找评论对象,获取isLiked状态
+			let isLiked = false;
+			let found = false;
+			// 先在一级评论中查找
+			for (let comment of this.rootComments) {
+				if (comment.commentId === commentId) {
+					isLiked = comment.isLiked;
+					found = true;
+					break;
 				}
-				toggleLikeComments(data).then(res => {
-					if (res.code == 200) {
-						console.log("内容分享", res)
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
+				// 再在二级评论中查找
+				if (comment.children && comment.children.length > 0) {
+					for (let child of comment.children) {
+						if (child.commentId === commentId) {
+							isLiked = child.isLiked;
+							found = true;
+							break;
+						}
 					}
-				}).catch(err => {});
-			},
-			// 发表评论
-			getPostComment() {
-				let data = {
-					content: this.content,
-					parentId: this.parentId || '', //父评论ID(回复必填,一级不填)
-					resourceId: this.resourceId //业务ID (文章ID / 视频ID )
+					if (found) break;
 				}
-				postComment(data).then(res => {
-					if (res.code == 200) {
-						console.log("发表评论", res)
-					} else {
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
-					}
-				}).catch(err => {});
-			},
-		}
-	}
+			}
+			let data = {
+				action: isLiked ? UNLIKE : LIKE,// UNLIKE
+				commentId: commentId
+			}
+			console.log("评论点赞参数:", data);
+			apiToggleLikeComments(data).then(res => {
+				if (res.code == 200) {
+					console.log("评论点赞", res)
+					// 重新获取评论列表
+					this.getListRootComments();
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			}).catch(err => { 
+				console.log("评论点赞错误:", err);
+			});
+		},
+		// 发表评论
+		getPostComment() {
+			// 检查哪个输入框有内容
+			let content = this.commentInput || this.inputValue;
+			if (!content.trim()) {
+				uni.showToast({
+					title: '请输入评论内容',
+					icon: 'none'
+				});
+				return;
+			}
+			let data = {
+				content: content,
+				parentId: '', //父评论ID(回复必填,一级不填)
+				resourceId: this.resourceId //业务ID (文章ID / 视频ID )
+			}
+			postComment(data).then(res => {
+				if (res.code == 200) {
+					console.log("发表评论", res)
+					// 发表成功后清空输入框
+					this.commentInput = '';
+					this.inputValue = '';
+					// 重新获取评论列表
+					this.getListRootComments();
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			}).catch(err => { });
+		},
+		// 表情选择事件
+		handleEmojiSelect(emoji) {
+			// 优先添加到键盘上方输入框
+			if (this.showKeyboardInput) {
+				this.keyboardInput += emoji;
+			} else if (this.commentInput) {
+				this.commentInput += emoji;
+			} else {
+				this.inputValue += emoji;
+			}
+			this.showEmojiPicker = false;
+		},
+		// 处理回复按钮点击事件
+		handleReply(comment) {
+			this.parentId = comment.commentId;
+			this.showKeyboardInput = true;
+			// 自动聚焦到键盘输入框
+			setTimeout(() => {
+				const input = uni.createSelectorQuery().select('.keyboard-input');
+				input.focus();
+			}, 100);
+		},
+		// 切换评论展开/收起状态
+		toggleExpand(comment) {
+			// 切换展开状态
+			const isExpanded = this.expandedComments[comment.commentId];
+			this.$set(this.expandedComments, comment.commentId, !isExpanded);
+			// 如果展开,获取二级评论
+			if (!isExpanded) {
+				this.getListSubComments(comment.commentId);
+			}
+		},
+		// 获取二级评论列表
+		getListSubComments(commentId) {
+			if (!commentId || !this.resourceId) return;
+			let data = {
+				page: 1,
+				pageSize: 10,
+				resourceId: this.resourceId,
+				commentId: commentId
+			}
+			listSubComments(data).then(res => {
+				if (res.code == 200) {
+					console.log("二级评论列表", res)
+					// 这里可以将二级评论存储到对应的一级评论中
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			}).catch(err => { });
+		},
+		// 发送键盘输入框的评论
+		sendKeyboardComment() {
+			if (!this.keyboardInput.trim()) {
+				uni.showToast({
+					title: '请输入评论内容',
+					icon: 'none'
+				});
+				return;
+			}
+			let data = {
+				content: this.keyboardInput,
+				parentId: this.parentId, //父评论ID(回复必填,一级不填)
+				resourceId: this.resourceId //业务ID (文章ID / 视频ID )
+			}
+			postComment(data).then(res => {
+				if (res.code == 200) {
+					console.log("发表评论", res)
+					// 发表成功后清空输入框
+					this.keyboardInput = '';
+					this.showKeyboardInput = false;
+					this.parentId = '';
+					// 重新获取评论列表
+					this.getListRootComments();
+				} else {
+					uni.showToast({
+						title: res.msg,
+						icon: 'none'
+					});
+				}
+			}).catch(err => { });
+		},
+		// 计算时间差
+		calculateTimeDiff(createAt) {
+			if (!createAt) return '';
+			
+			const createTime = new Date(createAt).getTime();
+			const now = new Date().getTime();
+			const diff = now - createTime;
+			
+			// 时间单位(毫秒)
+			const minute = 60 * 1000;
+			const hour = 60 * minute;
+			const day = 24 * hour;
+			const month = 30 * day;
+			const year = 365 * day;
+			
+			// 计算时间差
+			if (diff < minute) {
+				return '刚刚';
+			} else if (diff < hour) {
+				const minutes = Math.floor(diff / minute);
+				return `${minutes}分钟前`;
+			} else if (diff < day) {
+				const hours = Math.floor(diff / hour);
+				return `${hours}小时前`;
+			} else if (diff < month) {
+				const days = Math.floor(diff / day);
+				return `${days}天前`;
+			} else if (diff < year) {
+				const months = Math.floor(diff / month);
+				return `${months}个月前`;
+			} else {
+				const years = Math.floor(diff / year);
+				return `${years}年前`;
+			}
+		},
+	},
+}
 </script>
 
 <style lang="scss" scoped>
-	.content {
-		min-height: 100vh;
-		background: #ffffff;
-		position: relative;
-
-		.top-block {
-			padding-left: 24rpx;
+.content {
+	min-height: 100vh;
+	background: #ffffff;
+	position: relative;
+
+	.top-block {
+		padding-left: 24rpx;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+
+		.left {
 			display: flex;
-			justify-content: space-between;
 			align-items: center;
 
-			.left {
-				display: flex;
-				align-items: center;
-
-				.head {
-					width: 68rpx;
-					height: 68rpx;
-					border-radius: 34rpx 34rpx 34rpx 34rpx;
-					margin: 0 16rpx;
-				}
+			.head {
+				width: 68rpx;
+				height: 68rpx;
+				border-radius: 34rpx 34rpx 34rpx 34rpx;
+				margin: 0 16rpx;
+			}
 
-				.name {
-					font-weight: 500;
-					font-size: 32rpx;
-					color: #333333;
-				}
+			.name {
+				font-weight: 500;
+				font-size: 32rpx;
+				color: #333333;
 			}
+		}
 
-			.right {
-				display: flex;
-				align-items: center;
-				margin-right: 210rpx;
-
-				.icon-bg {
-					width: 64rpx;
-					height: 64rpx;
-					padding: 12rpx;
-					border-radius: 32rpx 32rpx 32rpx 32rpx;
-					border: 1rpx solid #E9E9E9;
-					box-sizing: border-box;
-					background: #FFFFFF;
-					margin-left: 24rpx;
-				}
+		.right {
+			display: flex;
+			align-items: center;
+			margin-right: 210rpx;
+
+			.icon-bg {
+				width: 64rpx;
+				height: 64rpx;
+				padding: 12rpx;
+				border-radius: 32rpx 32rpx 32rpx 32rpx;
+				border: 1rpx solid #E9E9E9;
+				box-sizing: border-box;
+				background: #FFFFFF;
+				margin-left: 24rpx;
 			}
+		}
 
-			.title-box {
-				position: relative;
+		.title-box {
+			position: relative;
 
-				.title {
-					font-weight: 600;
-					font-size: 40rpx;
-					color: #333333;
-				}
+			.title {
+				font-weight: 600;
+				font-size: 40rpx;
+				color: #333333;
 			}
 		}
+	}
 
-		// 文章
-		.article {
-			display: flex;
-			flex-direction: column;
-			margin-top: 30rpx;
+	// 文章
+	.article {
+		display: flex;
+		flex-direction: column;
+		margin-top: 30rpx;
 
-			.photo {
-				width: 100%;
-				height: 416rpx;
-			}
+		.photo {
+			width: 100%;
+			height: 416rpx;
+		}
 
-			.article-main {
-				padding: 0 24rpx;
+		.article-main {
+			padding: 0 24rpx;
 
-				.title {
-					margin: 18rpx 0 32rpx;
-					font-weight: 500;
-					font-size: 36rpx;
-					color: #333333;
-				}
+			.title {
+				margin: 18rpx 0 32rpx;
+				font-weight: 500;
+				font-size: 36rpx;
+				color: #333333;
+			}
 
-				.txt {
-					font-size: 30rpx;
-					color: #333333;
+			.txt {
+				font-size: 30rpx;
+				color: #333333;
 
-					.lable {
-						color: #153868;
-						margin-left: 8rpx;
-					}
+				.lable {
+					color: #153868;
+					margin-left: 8rpx;
 				}
+			}
 
-				.card {
+			.card {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				background: #FFF5EB;
+				width: 100%;
+				height: 64rpx;
+				border-radius: 8rpx;
+				border: 1rpx solid #F3E2D0;
+				padding: 16rpx;
+				box-sizing: border-box;
+				margin: 22rpx 0 32rpx; // 添加边距
+
+				.card-item {
 					display: flex;
-					justify-content: space-between;
 					align-items: center;
-					background: #FFF5EB;
-					width: 100%;
-					height: 64rpx;
-					border-radius: 8rpx;
-					border: 1rpx solid #F3E2D0;
-					padding: 16rpx;
-					box-sizing: border-box;
-					margin: 22rpx 0 32rpx; // 添加边距
-
-					.card-item {
-						display: flex;
-						align-items: center;
-						color: #D46C0D;
-
-						.card-icon {
-							width: 60rpx;
-							height: 32rpx;
-							margin-right: 24rpx;
-						}
+					color: #D46C0D;
 
-						.ranking {
-							font-size: 24rpx;
-						}
+					.card-icon {
+						width: 60rpx;
+						height: 32rpx;
+						margin-right: 24rpx;
+					}
 
-						.top {
-							font-family: Roboto Flex, Roboto Flex;
-							font-weight: normal;
-							font-size: 24rpx;
-							transform: skewX(-8deg);
-							display: inline-block;
-							margin-left: 8rpx;
-						}
+					.ranking {
+						font-size: 24rpx;
 					}
 
-					.go {
-						width: 16rpx;
-						height: 16rpx;
+					.top {
+						font-family: Roboto Flex, Roboto Flex;
+						font-weight: normal;
+						font-size: 24rpx;
+						transform: skewX(-8deg);
+						display: inline-block;
+						margin-left: 8rpx;
 					}
 				}
 
-				.place {
-					font-size: 24rpx;
-					color: #999999;
+				.go {
+					width: 16rpx;
+					height: 16rpx;
 				}
+			}
 
+			.place {
+				font-size: 24rpx;
+				color: #999999;
 			}
+
 		}
+	}
 
-		.line {
-			margin: 32rpx 0;
-			width: 100%;
-			height: 0rpx;
-			border: 1rpx solid #EEEEEE;
+	.line {
+		margin: 32rpx 0;
+		width: 100%;
+		height: 0rpx;
+		border: 1rpx solid #EEEEEE;
+	}
+
+	// 评论
+	.comment {
+		display: flex;
+		flex-direction: column;
+		padding: 0 24rpx 120rpx;
+
+		.comment-num {
+			display: flex;
+			align-items: center;
+			font-weight: 500;
+			font-size: 28rpx;
+			color: #333333;
+			margin-bottom: 30rpx;
 		}
 
-		// 评论
-		.comment {
+		.my-input {
 			display: flex;
-			flex-direction: column;
-			padding: 0 24rpx 120rpx;
+			margin-bottom: 40rpx;
 
-			.comment-num {
+			.head {
+				width: 68rpx;
+				height: 68rpx;
+				margin-right: 24rpx;
+				border-radius: 50%;
+				flex-shrink: 0;
+			}
+
+			.input-item {
+				flex: 1;
 				display: flex;
 				align-items: center;
-				font-weight: 500;
-				font-size: 28rpx;
-				color: #333333;
-				margin-bottom: 30rpx;
+				background: #F5F7FA;
+				padding: 0 24rpx;
+				border-radius: 34rpx;
+
+				.input {
+					flex: 1;
+				}
 			}
+		}
 
-			.my-input {
+		.message {
+			display: flex;
+			flex-direction: column;
+
+			.message-item {
 				display: flex;
+				justify-content: space-between;
 				margin-bottom: 40rpx;
 
-				.head {
-					width: 68rpx;
-					height: 68rpx;
-					margin-right: 24rpx;
-					border-radius: 50%;
-					flex-shrink: 0;
-				}
-
-				.input-item {
-					flex: 1;
+				.left {
 					display: flex;
-					align-items: center;
-					background: #F5F7FA;
-					padding: 0 24rpx;
-					border-radius: 34rpx;
 
-					.input {
-						flex: 1;
+					.head {
+						width: 68rpx;
+						height: 68rpx;
+						margin-right: 24rpx;
+						border-radius: 50%;
+						flex-shrink: 0;
 					}
-				}
-			}
 
-			.message {
-				display: flex;
-				flex-direction: column;
+					.head-little {
+						width: 48rpx;
+						height: 48rpx;
+						margin-right: 16rpx;
+						border-radius: 50%;
+						flex-shrink: 0;
+					}
 
-				.message-item {
-					display: flex;
-					justify-content: space-between;
-					margin-bottom: 40rpx;
-
-					.left {
-						display: flex;
-
-						.head {
-							width: 68rpx;
-							height: 68rpx;
-							margin-right: 24rpx;
-							border-radius: 50%;
-							flex-shrink: 0;
+					.chat {
+						.name {
+							font-size: 26rpx;
+							color: #999999;
+							display: flex;
+
+							.author-lable {
+								width: 62rpx;
+								height: 32rpx;
+								background: #E0FFF4;
+								border-radius: 16rpx;
+								text-align: center;
+								line-height: 32rpx;
+								font-weight: 500;
+								font-size: 18rpx;
+								color: #02B176;
+								margin-left: 14rpx;
+							}
 						}
 
-						.head-little {
-							width: 48rpx;
-							height: 48rpx;
-							margin-right: 16rpx;
-							border-radius: 50%;
-							flex-shrink: 0;
-						}
+						.flex-wrap {
+							display: flex;
+							flex-wrap: wrap;
+							align-items: center;
 
-						.chat {
-							.name {
-								font-size: 26rpx;
-								color: #999999;
-								display: flex;
 
-								.author-lable {
-									width: 62rpx;
-									height: 32rpx;
-									background: #E0FFF4;
-									border-radius: 16rpx;
-									text-align: center;
-									line-height: 32rpx;
-									font-weight: 500;
-									font-size: 18rpx;
-									color: #02B176;
-									margin-left: 14rpx;
-								}
+							.txt {
+								font-size: 28rpx;
+								color: #333333;
+								margin: 12rpx 24rpx 12rpx 0;
 							}
 
-							.flex-wrap {
+							.info {
+								font-size: 24rpx;
 								display: flex;
-								flex-wrap: wrap;
-								align-items: center;
 
-
-								.txt {
-									font-size: 28rpx;
-									color: #333333;
-									margin: 12rpx 24rpx 12rpx 0;
+								.time {
+									color: #999999;
 								}
 
-								.info {
-									font-size: 24rpx;
-									display: flex;
-
-									.time {
-										color: #999999;
-									}
-
-									.reply {
-										color: #666666;
-										margin-left: 22rpx;
-									}
+								.reply {
+									color: #666666;
+									margin-left: 22rpx;
 								}
 							}
 						}
 					}
+				}
 
-					.expand {
-						font-size: 26rpx;
-						color: #153868;
-						padding: 0 64rpx;
-					}
+				.expand {
+					font-size: 26rpx;
+					color: #153868;
+					padding: 0 64rpx;
+				}
 
-					.right {
-						display: flex;
-						flex-direction: column;
-						align-items: center;
-						font-size: 24rpx;
-						color: #666666;
-					}
+				.right {
+					display: flex;
+					flex-direction: column;
+					align-items: center;
+					font-size: 24rpx;
+					color: #666666;
 				}
 			}
 		}
+	}
 
-		// 输入框
-		.chat-input-container {
+	// 输入框
+	.chat-input-container {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		height: 100rpx;
+		box-sizing: border-box;
+		padding: 20rpx 24rpx;
+		width: 100%;
+		box-sizing: border-box;
+		position: fixed;
+		bottom: 0;
+		background-color: #ffffff;
+		border-top: 1rpx solid #EEEEEE;
+
+		.input-container {
+			background: #F5F7FA;
+			height: 68rpx;
+			box-sizing: border-box;
+			border-radius: 36rpx;
 			display: flex;
-			justify-content: space-between;
 			align-items: center;
-			height: 100rpx;
-			box-sizing: border-box;
-			padding: 20rpx 24rpx;
-			width: 100%;
-			box-sizing: border-box;
-			position: fixed;
-			bottom: 0;
-			background-color: #ffffff;
-			border-top: 1rpx solid #EEEEEE;
-
-			.input-container {
-				background: #F5F7FA;
-				height: 68rpx;
-				box-sizing: border-box;
-				border-radius: 36rpx;
-				display: flex;
-				align-items: center;
-				overflow: hidden;
+			overflow: hidden;
+			margin-right: 20rpx;
+
+			.send-btn {
+				margin-left: 20rpx;
+				padding: 8rpx 20rpx;
+				background-color: #FF6B6B;
+				color: white;
+				font-size: 24rpx;
+				border-radius: 15rpx;
 				margin-right: 20rpx;
+			}
 
+		}
 
-			}
+		.icon-container {
+			display: flex;
+			align-items: center;
 
-			.icon-container {
+			.icon-item {
 				display: flex;
 				align-items: center;
+				margin-right: 42rpx;
 
-				.icon-item {
-					display: flex;
-					align-items: center;
-					margin-right: 42rpx;
-
-					&:last-child {
-						margin-right: 0rpx;
-					}
+				&:last-child {
+					margin-right: 0rpx;
+				}
 
-					.icon {
-						width: 48rpx;
-						height: 48rpx;
-						margin-right: 8rpx;
-					}
+				.icon {
+					width: 48rpx;
+					height: 48rpx;
+					margin-right: 8rpx;
 				}
 			}
 		}
+	}
 
+	// 键盘上方的输入框
+	.keyboard-input-container {
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		background-color: #ffffff;
+		border-top: 1rpx solid #EEEEEE;
+		padding: 20rpx 24rpx;
+		z-index: 999;
+
+		.keyboard-input-item {
+			display: flex;
+			align-items: center;
+			background: #F5F7FA;
+			padding: 0 24rpx;
+			border-radius: 34rpx;
+			height: 68rpx;
+
+			.keyboard-input {
+				flex: 1;
+				height: 100%;
+				font-size: 26rpx;
+			}
+
+			.send-btn {
+				margin-left: 20rpx;
+				padding: 8rpx 20rpx;
+				background-color: #FF6B6B;
+				color: white;
+				font-size: 24rpx;
+				border-radius: 15rpx;
+			}
+		}
 	}
+
+}
 </style>

+ 113 - 0
pages_shopping/live/components/emoji-picker.vue

@@ -0,0 +1,113 @@
+<template>
+	<view class="emoji-picker">
+		<view class="emoji-header">
+			<text class="title">表情</text>
+			<text class="close" @click="handleClose">关闭</text>
+		</view>
+		<view class="emoji-list">
+			<view 
+				v-for="(emoji, index) in emojiList" 
+				:key="index"
+				class="emoji-item"
+				@click="handleEmojiClick(emoji)"
+			>
+				<text class="emoji">{{ emoji }}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'EmojiPicker',
+	props: {
+		visible: {
+			type: Boolean,
+			default: false
+		}
+	},
+	data() {
+		return {
+			// 表情列表
+			emojiList: [
+				'😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣',
+				'😊', '😇', '🙂', '🙃', '😉', '😌', '😍', '🥰',
+				'😘', '😗', '😙', '😚', '😋', '😛', '😝', '😜',
+				'🤪', '🤨', '🧐', '🤓', '😎', '🤩', '🥳', '😏',
+				'😒', '😞', '😔', '😟', '😕', '🙁', '☹️', '😣',
+				'😖', '😫', '😩', '🥺', '😢', '😭', '😤', '😠',
+				'😡', '🤬', '🤯', '😳', '🥵', '🥶', '😱', '😨',
+				'😰', '😥', '😓', '🤗', '🤔', '🤭', '🤫', '🤥',
+				'😶', '😐', '😑', '😬', '🙄', '😯', '😦', '😧',
+				'😮', '😲', '🥱', '😴', '🤤', '😪', '😵', '🤐',
+				'🥴', '🤢', '🤮', '🤧', '😷', '🤒', '🤕', '🤖'
+			]
+		}
+	},
+	methods: {
+		// 点击表情
+		handleEmojiClick(emoji) {
+			this.$emit('select', emoji);
+		},
+		// 点击关闭
+		handleClose() {
+			this.$emit('close');
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.emoji-picker {
+	background-color: #ffffff;
+	border-top: 1rpx solid #EEEEEE;
+	position: fixed;
+	bottom: 100rpx;
+	left: 0;
+	right: 0;
+	height: 40vh;
+	z-index: 999;
+	display: flex;
+	flex-direction: column;
+
+	.emoji-header {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		padding: 20rpx 24rpx;
+		border-bottom: 1rpx solid #F0F0F0;
+		flex-shrink: 0;
+
+		.title {
+			font-size: 28rpx;
+			font-weight: 500;
+			color: #333333;
+		}
+
+		.close {
+			font-size: 26rpx;
+			color: #999999;
+		}
+	}
+
+	.emoji-list {
+		display: flex;
+		flex-wrap: wrap;
+		padding: 24rpx;
+		flex: 1;
+		overflow-y: auto;
+
+		.emoji-item {
+			width: 20%;
+			height: 80rpx;
+			display: flex;
+			justify-content: center;
+			align-items: center;
+
+			.emoji {
+				font-size: 40rpx;
+			}
+		}
+	}
+}
+</style>

+ 39 - 37
pages_shopping/live/expert.vue

@@ -108,9 +108,9 @@
 		expertHomePage, // 达人主页
 		follow, // 关注用户
 	} from '@/api/life.js'
-	import {
-		liveList
-	} from '@/api/living.js'
+	// import {
+	// 	liveList
+	// } from '@/api/living.js'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		components: {
@@ -143,7 +143,9 @@
 				mescroll: null,
 			}
 		},
-		onLoad() {
+		onLoad(option) {
+			this.expertId=option.expertId;
+			this.getExpertHomePage();
 			// if (!uni.getStorageSync("AppToken")) {
 			// 	uni.navigateTo({
 			// 		url: '/pages/auth/login'
@@ -206,39 +208,39 @@
 			},
 
 			// 上拉加载回调
-			upCallback(mescroll) {
-				const pageNum = mescroll.num;
-				const pageSize = mescroll.size;
-
-				let data = {
-					pageSize: pageSize,
-					pageNum: pageNum,
-				}
-				liveList(data).then(res => {
-					if (!res) {
-						mescroll.endErr();
-						return;
-					}
-					if (res.code == 200) {
-						let curPageData = Array.isArray(res.data.list) ? res.data.list : [];
-						let totalSize = Number(res.data.total) || 0;
-						if (pageNum === 1) {
-							this.list = [];
-						}
-						this.list = this.list.concat(curPageData);
-
-						mescroll.endBySize(curPageData.length, totalSize);
-					} else {
-						mescroll.endErr();
-						uni.showToast({
-							title: res.msg,
-							icon: 'none'
-						});
-					}
-				}).catch(err => {
-					mescroll.endErr();
-				});
-			},
+			// upCallback(mescroll) {
+			// 	const pageNum = mescroll.num;
+			// 	const pageSize = mescroll.size;
+
+			// 	let data = {
+			// 		pageSize: pageSize,
+			// 		pageNum: pageNum,
+			// 	}
+			// 	liveList(data).then(res => {
+			// 		if (!res) {
+			// 			mescroll.endErr();
+			// 			return;
+			// 		}
+			// 		if (res.code == 200) {
+			// 			let curPageData = Array.isArray(res.data.list) ? res.data.list : [];
+			// 			let totalSize = Number(res.data.total) || 0;
+			// 			if (pageNum === 1) {
+			// 				this.list = [];
+			// 			}
+			// 			this.list = this.list.concat(curPageData);
+
+			// 			mescroll.endBySize(curPageData.length, totalSize);
+			// 		} else {
+			// 			mescroll.endErr();
+			// 			uni.showToast({
+			// 				title: res.msg,
+			// 				icon: 'none'
+			// 			});
+			// 		}
+			// 	}).catch(err => {
+			// 		mescroll.endErr();
+			// 	});
+			// },
 
 			goLive(item) {
 				uni.navigateTo({

BIN
static/images/sales_ranking_bg.png