Parcourir la source

Signed-off-by: 李妹妹 <1639016684@qq.com>

李妹妹 il y a 1 jour
Parent
commit
f3809fe82a
52 fichiers modifiés avec 8671 ajouts et 0 suppressions
  1. 23 0
      .hbuilderx/launch.json
  2. 32 0
      api/home.js
  3. 48 0
      components/custom-toast.vue
  4. 553 0
      pages/index/course.vue
  5. 559 0
      pages/index/video.vue
  6. 885 0
      pages/shopping/confirmOrder.vue
  7. 343 0
      pages/shopping/payOrder.vue
  8. 751 0
      pages/shopping/paymentOrder.vue
  9. 830 0
      pages/shopping/prescribe.vue
  10. 1389 0
      pages/shopping/productDetails.vue
  11. 190 0
      pages/shopping/success.vue
  12. 155 0
      pages_mall/components/CategoryTags.vue
  13. 67 0
      pages_mall/components/ChannelEntry.vue
  14. 157 0
      pages_mall/components/GoodsCard.vue
  15. 67 0
      pages_mall/components/GoodsList.vue
  16. 94 0
      pages_mall/components/GoodsNav.vue
  17. 315 0
      pages_mall/components/HotProduct.vue
  18. 270 0
      pages_mall/components/NewProduct.vue
  19. 395 0
      pages_mall/components/RecommendSection.vue
  20. 128 0
      pages_mall/components/SearchBar.vue
  21. 454 0
      pages_mall/home - 副本.vue
  22. 614 0
      pages_mall/homeIndex.vue
  23. 132 0
      pages_mall/productSearch.vue
  24. 220 0
      pages_mall/recommendList.vue
  25. BIN
      static/image/tabbar/cart.png
  26. BIN
      static/image/tabbar/cart_sel.png
  27. BIN
      static/image/tabbar/home.png
  28. BIN
      static/image/tabbar/home_sel.png
  29. BIN
      static/image/tabbar/mall.png
  30. BIN
      static/image/tabbar/mall_sel.png
  31. BIN
      static/image/tabbar/my.png
  32. BIN
      static/image/tabbar/my_sel.png
  33. BIN
      static/image/tabbar/video.png
  34. BIN
      static/image/tabbar/video_sel.png
  35. BIN
      static/images/bg.png
  36. BIN
      static/images/hot.png
  37. BIN
      static/images/launch/1080x1882.png
  38. BIN
      static/images/launch/1080x2340.png
  39. BIN
      static/images/launch/480.png
  40. BIN
      static/images/launch/720.png
  41. BIN
      static/images/new.png
  42. BIN
      static/images/new/back.png
  43. BIN
      static/images/new/banner.png
  44. BIN
      static/images/new/bofang.png
  45. BIN
      static/images/new/expand.png
  46. BIN
      static/images/new/jpk.png
  47. BIN
      static/images/new/nodata.png
  48. BIN
      static/images/new/renshu.png
  49. BIN
      static/images/new/search.png
  50. BIN
      static/images/new/time.png
  51. BIN
      static/images/new/title.png
  52. BIN
      static/images/new/yyx.png

+ 23 - 0
.hbuilderx/launch.json

@@ -0,0 +1,23 @@
+{
+    "version" : "1.0",
+    "configurations" : [
+        {
+            "app" : {
+                "launchtype" : "local"
+            },
+            "default" : {
+                "launchtype" : "local"
+            },
+            "h5" : {
+                "launchtype" : "local"
+            },
+            "provider" : "aliyun",
+            "type" : "uniCloud"
+        },
+        {
+            "customPlaygroundType" : "local",
+            "playground" : "custom",
+            "type" : "uni-app:app-android"
+        }
+    ]
+}

+ 32 - 0
api/home.js

@@ -0,0 +1,32 @@
+import Request from '../common/request.js';
+const request = new Request().http;
+
+/**
+ * 首页初始化核心数据(频道入口、分类标签、商品分类导航)
+ */
+export function getHomeInit() {
+	return request('/store/app/index/home/init', null, 'GET');
+}
+
+/**
+ * 首页推荐区块(直播中、上新推荐等)
+ */
+export function getHomeRecommend() {
+	return request('/store/app/index/home/recommend', null, 'GET');
+}
+
+/**
+ * 首页商品列表(支持用户端分类 id,id 为空查全部)
+ * @param {Object} data - { id, pageNum, pageSize } 其中 id 可选,不传或空为全部
+ */
+export function getHomeGoods(data) {
+	return request('/store/app/index/home/goods', data || {}, 'GET');
+}
+
+/**
+ * 首页推荐「更多」分页:绿色有机(green) / 上新推荐(hot)
+ * @param {Object} data - { type: 'green'|'hot', pageNum, pageSize } 默认第1页10条
+ */
+export function getHomeGoodsRecommend(data) {
+	return request('/store/app/index/home/goods/recommend', data || {}, 'GET');
+}

+ 48 - 0
components/custom-toast.vue

@@ -0,0 +1,48 @@
+<template>
+  <view class="custom-toast" v-if="visible">
+    {{ message }}
+  </view>
+</template>
+
+<script>
+export default {
+  name:'CustomToast',
+  data() {
+    return {
+      visible: false,
+      message: '',
+      duration: 1500,
+      fontSize: '16px' // 可配置字体大小
+    };
+  },
+  methods: {
+    show(options) {
+      this.message = options.title || '';
+      this.duration = options.duration || 1500;
+      this.fontSize = options.fontSize || '16px';
+      this.visible = true;
+      setTimeout(() => {
+        this.visible = false;
+      }, this.duration);
+    }
+  }
+};
+</script>
+
+<style>
+.custom-toast {
+  position: fixed;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%);
+  padding: 12px 24px;
+  background-color: rgba(0, 0, 0, 0.7);
+  color: white;
+  border-radius: 4px;
+  font-size: 16px; /* 默认字体大小 */
+  z-index: 9999;
+  line-height: 44rpx;
+  white-space: pre-line; /* 解析 \n 为换行 */
+  text-align: center; /* 可选,让文本居中 */
+}
+</style>

+ 553 - 0
pages/index/course.vue

@@ -0,0 +1,553 @@
+<template>
+	<view class="container">
+		<!-- 顶部导航 Tab -->
+		<view class="top-nav" :style="{marginTop: statusBarHeight}">
+			<view class="nav-tabs">
+				<view
+					class="nav-item"
+					:class="{ active: tabIndex === 0 }"
+					@click="tabIndex = 0"
+				>
+					<text>精品课程</text>
+					<view v-if="tabIndex === 0" class="nav-indicator"></view>
+				</view>
+				<view
+					class="nav-item"
+					:class="{ active: tabIndex === 1 }"
+					@click="tabIndex = 1"
+				>
+					<text>最近学习</text>
+					<view v-if="tabIndex === 1" class="nav-indicator"></view>
+				</view>
+			</view>
+			<view v-if="tabIndex === 0" class="category-wrap">
+				<view class="category-tags" :class="{ collapsed: !categoryExpand }">
+					<view
+						v-for="(cat, idx) in categories"
+						:key="idx"
+						class="tag-item"
+						:class="{ active: categoryIndex === idx }"
+						@click="categoryIndex = idx"
+					>
+						<text>{{ cat }}</text>
+					</view>
+				</view>
+				<view class="expand-btn" @click="categoryExpand = !categoryExpand">
+					<text>{{ categoryExpand ? '收起' : '展开' }}</text>
+					<image :class="{ 'rotate-arrow': !categoryExpand }"   src="@/static/images/new/expand.png"></image>
+					<!-- <text class="arrow">{{ categoryExpand ? '▲' : '▼' }}</text> -->
+				</view>
+			</view>
+		</view>
+
+		<!-- 精品课程 内容 -->
+		<scroll-view v-show="tabIndex === 0" scroll-y class="scroll-wrap" :show-scrollbar="false">
+			<!-- 分类标签区 -->
+			
+
+			<!-- 课程网格 -->
+			<view class="course-grid">
+				<view
+					v-for="(course, idx) in courseList"
+					:key="idx"
+					class="course-card"
+					@click="onCourseClick(course)"
+				>
+					<view class="card-cover">
+						<image :src="course.cover || '/static/logo.jpg'" mode="aspectFill" class="cover-img"></image>
+					</view>
+					<view class="course-info">
+						<text class="card-title">{{ course.title }}</text>
+						<view class="x-end" style="justify-content: space-between;">
+							<view class="course-meta">
+								<image src="@/static/images/new/renshu.png"></image>
+								<text class="meta-count">{{ course.views }}</text>
+							</view>
+							<view class="btn-watch" @click.stop="onCourseClick(course)">立即观看</view>
+						</view>
+					</view>
+					
+				</view>
+			</view>
+			<view class="bottom-placeholder"></view>
+		</scroll-view>
+
+		<!-- 最近学习 内容 -->
+		<scroll-view v-show="tabIndex === 1" scroll-y class="scroll-wrap" :show-scrollbar="false">
+			<!-- 有学习记录:按日期分组列表 -->
+			<template v-if="recentList.length > 0">
+				<view v-for="(group, gIdx) in recentList" :key="gIdx" class="recent-group">
+					<view class="group-date">
+						<image class="date-icon" src="@/static/images/new/time.png"></image>
+						<text class="date-text">{{ group.date }}</text>
+					</view>
+					<view
+						v-for="(item, i) in group.list"
+						:key="i"
+						class="recent-card"
+						@click="onCourseClick(item)"
+					>
+						<view class="recent-thumb">
+							<image :src="item.cover || '/static/logo.jpg'" mode="aspectFill" class="thumb-img"></image>
+						</view>
+						<view class="recent-info">
+							<text class="recent-title">{{ item.title }}</text>
+							<text class="recent-progress">已学: {{ item.progress }}%</text>
+							<view class="y-end">
+								<view class="btn-watch" @click.stop="onCourseClick(item)">立即观看</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</template>
+
+			<!-- 无学习记录:空态 + 为您精选 -->
+			<template v-else>
+				<view class="empty-state">
+					<!-- <view class="empty-icon"></view> -->
+					<image class="empty-icon" src="@/static/images/new/nodata.png"></image>
+					<text class="empty-text">暂无学习内容</text>
+				</view>
+				<view class="recommend-section">
+					<text class="recommend-title">为您精选</text>
+					<view class="course-grid" style="padding: 0;">
+						<view
+							v-for="(course, idx) in recommendList"
+							:key="idx"
+							class="course-card"
+							@click="onCourseClick(course)"
+						>
+							<view class="card-cover">
+								<image :src="course.cover || '/static/logo.jpg'" mode="aspectFill" class="cover-img"></image>
+							</view>
+							
+							<view class="card-footer">
+								<text class="card-title">{{ course.title }}</text>
+								<view class="x-end" style="justify-content: space-between;">
+									<view class="course-meta">
+										<image src="@/static/images/new/renshu.png"></image>
+										<text class="meta-count">{{ course.views }}</text>
+									</view>
+									<view class="btn-watch" @click.stop="onCourseClick(course)">立即观看</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</template>
+			<view class="bottom-placeholder"></view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+			tabIndex: 0,
+			categoryExpand: true,
+			categoryIndex: 0,
+			categories: ['全部', '歌唱艺术', '太极养生', '防骗指南', '手机摄影', '棋牌益智', '用药指导', '膳食营养', '慢病管理'],
+			courseList: [
+				{ title: '刘金的《0基础金曲演唱速练课》', views: '9239', cover: '' },
+				{ title: '邹方斌讲《毛笔书法修心课》', views: '10.8w', cover: '' },
+				{ title: '张斌《元气八段锦》系列课', views: '2.5w', cover: '' },
+				{ title: '翔哥精讲摄影课—手机微距拍摄技巧...', views: '100w+', cover: '' },
+				{ title: '道家智慧 入门21讲', views: '1.2w', cover: '' },
+				{ title: '入门进阶必修 瑜伽呼吸全精讲', views: '3.6w', cover: '' }
+			],
+			recentList: [
+				{
+					date: '2026-02-08',
+					list: [
+						{ title: '歌唱家刘金的《0基础金曲演唱速练课》', progress: 87, cover: '' },
+						{ title: '资深编辑邹方斌讲《毛笔书法修心课》', progress: 56, cover: '' }
+					]
+				},
+				{
+					date: '2026-02-01',
+					list: [
+						{ title: '张斌《元气八段锦》系列课', progress: 56, cover: '' }
+					]
+				}
+			],
+			recommendList: [
+				{ title: '刘金的《0基础金曲演唱速练课》', views: '9239', cover: '' },
+				{ title: '邹方斌讲《毛笔书法修心课》', views: '10.8w', cover: '' },
+				{ title: '张斌《元气八段锦》系列课', views: '2.5w', cover: '' },
+				{ title: '翔哥精讲摄影课-手机微距拍摄技巧...', views: '100w+', cover: '' }
+			]
+		}
+	},
+	onLoad() {
+		// 若无最近学习,可置空 recentList 显示空态
+		// this.recentList = [];
+	},
+	methods: {
+		onCourseClick(course) {
+			uni.showToast({ title: course.title || '立即观看', icon: 'none' })
+			// uni.navigateTo({ url: '/pages_course/videovip?id=' + (course.id || '') })
+		}
+	}
+}
+</script>
+
+<style scoped>
+	/* 图片箭头旋转类(展开时向上) */
+	.rotate-arrow {
+	  transform: rotate(180deg);
+	}
+.container {
+	min-height: 100vh;
+	background: #F5F5F5;
+	display: flex;
+	flex-direction: column;
+}
+
+/* 顶部 Tab */
+.top-nav {
+	display: flex;
+	flex-direction: column;
+	background: #fff;
+	/* border-bottom: 1rpx solid #f0f0f0; */
+}
+.nav-tabs {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+.nav-item {
+	flex:1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	position: relative;
+	padding: 24rpx 0;
+}
+.nav-item text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 36rpx;
+	color: #030303;
+}
+.nav-item.active text {
+	font-weight: 600;
+	font-size: 40rpx;
+}
+.nav-indicator {
+	position: absolute;
+	left: 50%;
+	bottom: 0;
+	transform: translateX(-50%);
+	width: 100rpx;
+	height: 10rpx;
+	background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+	border-radius: 6rpx;
+}
+.nav-actions {
+	display: flex;
+	align-items: center;
+	gap: 24rpx;
+}
+.action-icon {
+	font-size: 36rpx;
+	color: #666;
+}
+
+/* 滚动区 */
+.scroll-wrap {
+	flex: 1;
+	height: 0;
+}
+
+/* 分类标签 */
+.category-wrap {
+	padding:24rpx 0;
+	border-radius: 0rpx 0rpx 20rpx 20rpx;
+	background: #fff;
+	display: flex;
+	align-items: center;
+	flex-direction: column;
+}
+.category-tags {
+	display: flex;
+	flex-wrap: wrap;
+	gap:24rpx;
+	flex-direction: row;
+	justify-content: center;
+}
+.category-tags.collapsed {
+	max-height: 88rpx;
+	overflow: hidden;
+}
+.tag-item {
+	width: 30%;
+	padding: 20rpx 0;
+	text-align: center;
+	border-radius: 20rpx;
+	background: #f0f0f0;
+}
+.tag-item text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 40rpx;
+	color: rgba(0,0,0,0.85);
+}
+.tag-item.active {
+	background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+}
+.tag-item.active text {
+	color: #fff;
+}
+.expand-btn {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	margin-top: 20rpx;
+	width: 166rpx;
+	height: 64rpx;
+	border-radius: 32rpx;
+	border: 2rpx solid #FF233C;
+}
+.expand-btn text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #FF233C;
+}
+.expand-btn .arrow {
+	margin-left: 6rpx;
+	font-size: 22rpx;
+}
+.expand-btn image{
+	margin-left:10rpx ;
+	width: 32rpx;
+	height: 32rpx;
+}
+/* 课程网格 */
+.course-grid {
+	display: flex;
+	flex-wrap: wrap;
+	padding:24rpx;
+	gap: 24rpx 20rpx;
+	flex-direction: column;
+}
+.course-card {
+	display: flex;
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+	padding: 20rpx;
+}
+.course-tag {
+	position: absolute;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	padding: 8rpx 12rpx;
+	background: linear-gradient(transparent, rgba(0,0,0,0.6));
+	font-size: 22rpx;
+	color: #fff;
+}
+.course-info {
+	flex: 1;
+	padding-left: 24rpx;
+/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+
+.course-meta {
+	display: flex;
+	align-items: center;
+	image{
+		width: 30rpx;
+		height: 30rpx;
+	}
+	
+}
+.meta-icon {
+	font-size: 24rpx;
+	margin-right: 6rpx;
+	color: #999;
+}
+.meta-count {
+	margin-left: 10rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #666666;
+}
+.card-cover {
+	position: relative;
+	width: 296rpx;
+	height: 222rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	flex-shrink: 0;
+}
+.cover-img {
+	width: 100%;
+	height: 100%;
+	background: #BB6D6D;
+}
+.card-title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #222222;
+	line-height: 50rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+.card-footer {
+	flex: 1;
+		padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		min-width: 0;
+}
+.card-views {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #666666;
+	line-height: 44rpx;
+}
+.btn-watch {
+		width: 168rpx;
+		height: 64rpx;
+		line-height: 64rpx;
+		text-align: center;
+		background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+		border-radius: 32rpx;
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 600;
+		font-size: 32rpx;
+	color: #FFFFFF;
+}
+
+/* 最近学习 - 按日期分组 */
+.recent-group {
+	padding: 24rpx 24rpx 0;
+}
+.group-date {
+	display: flex;
+	align-items: center;
+	margin-bottom: 24rpx;
+}
+.date-icon {
+	width: 32rpx;
+	height: 32rpx;
+	margin-right: 8rpx;
+}
+.date-text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 40rpx;
+	line-height: 56rpx;
+	color: #222222;
+}
+.recent-card {
+	display: flex;
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+	padding: 20rpx;
+	margin-bottom: 24rpx;
+}
+.recent-card:last-child{
+	margin-bottom: 0;
+}
+.recent-thumb {
+	position: relative;
+	width: 296rpx;
+	height: 222rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	flex-shrink: 0;
+}
+.thumb-img {
+	width: 100%;
+	height: 100%;
+	background: #BB6D6D;
+}
+.recent-info {
+	flex: 1;
+	padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+.recent-title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #222222;
+	line-height: 50rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+.recent-progress {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0,0,0,0.65);
+	line-height: 44rpx;
+}
+
+/* 空态 */
+.empty-state {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	padding: 80rpx 0 48rpx;
+	/* background: linear-gradient(180deg, #fff5f5 0%, #fff 100%); */
+}
+.empty-icon {
+	width: 310rpx;
+	height: 260rpx;
+	margin-bottom: 30rpx;
+}
+.empty-text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 36rpx;
+	color: rgba(0,0,0,0.25);
+	line-height: 50rpx;
+}
+
+/* 为您精选 */
+.recommend-section {
+	padding: 0 24rpx 32rpx;
+}
+.recommend-title {
+	display: block;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 40rpx;
+	color: #222222;
+	line-height: 56rpx;
+	padding-bottom: 24rpx;
+}
+
+.bottom-placeholder {
+	height: 120rpx;
+}
+</style>

+ 559 - 0
pages/index/video.vue

@@ -0,0 +1,559 @@
+<template>
+	<view class="container">
+		<!-- 顶部导航 Tab -->
+		<view class="top-nav" :style="{marginTop: statusBarHeight}">
+			<view class="nav-tabs">
+				<view
+					class="nav-item"
+					:class="{ active: tabIndex === 0 }"
+					@click="tabIndex = 0"
+				>
+					<text>央广原乡行</text>
+					<view v-if="tabIndex === 0" class="nav-indicator"></view>
+				</view>
+				<view
+					class="nav-item"
+					:class="{ active: tabIndex === 1 }"
+					@click="tabIndex = 1"
+				>
+					<text>最近观看</text>
+					<view v-if="tabIndex === 1" class="nav-indicator"></view>
+				</view>
+			</view>
+			<view v-if="tabIndex === 0" class="category-wrap">
+				<view class="category-tags" :class="{ collapsed: !categoryExpand }">
+					<view
+						v-for="(cat, idx) in categories"
+						:key="idx"
+						class="tag-item"
+						:class="{ active: categoryIndex === idx }"
+						@click="categoryIndex = idx"
+					>
+						<text>{{ cat }}</text>
+					</view>
+				</view>
+				<view class="expand-btn" @click="categoryExpand = !categoryExpand">
+					<text>{{ categoryExpand ? '收起' : '展开' }}</text>
+					<image :class="{ 'rotate-arrow': !categoryExpand }"   src="@/static/images/new/expand.png"></image>
+					<!-- <text class="arrow">{{ categoryExpand ? '▲' : '▼' }}</text> -->
+				</view>
+			</view>
+		</view>
+
+		<!-- 精品课程 内容 -->
+		<scroll-view v-show="tabIndex === 0" scroll-y class="scroll-wrap" :show-scrollbar="false">
+			<!-- 分类标签区 -->
+			
+
+			<!-- 课程网格 -->
+			<view class="course-grid">
+				<view
+					v-for="(course, idx) in courseList"
+					:key="idx"
+					class="course-card"
+					@click="onCourseClick(course)"
+				>
+					<view class="card-cover">
+						<image :src="course.cover || '/static/logo.jpg'" mode="aspectFill" class="cover-img"></image>
+					</view>
+					<view class="course-info">
+						<text class="card-title">{{ course.title }}</text>
+						<view class="y-bc">
+							<view class="course-meta">
+							邀你一起看恩施美景,寻长寿秘密
+							</view>
+							<view class="y-end">
+								<view class="btn-watch" @click.stop="onCourseClick(item)">立即观看</view>
+							</view>
+						</view>
+					</view>
+					
+				</view>
+			</view>
+			<view class="bottom-placeholder"></view>
+		</scroll-view>
+
+		<!-- 最近学习 内容 -->
+		<scroll-view v-show="tabIndex === 1" scroll-y class="scroll-wrap" :show-scrollbar="false">
+			<!-- 有学习记录:按日期分组列表 -->
+			<template v-if="recentList.length > 0">
+				<view v-for="(group, gIdx) in recentList" :key="gIdx" class="recent-group">
+					<view class="group-date">
+						<image class="date-icon" src="@/static/images/new/time.png"></image>
+						<text class="date-text">{{ group.date }}</text>
+					</view>
+					<view
+						v-for="(item, i) in group.list"
+						:key="i"
+						class="recent-card"
+						@click="onCourseClick(item)"
+					>
+						<view class="recent-thumb">
+							<image :src="item.cover || '/static/logo.jpg'" mode="aspectFill" class="thumb-img"></image>
+						</view>
+						<view class="recent-info">
+							<text class="recent-title">{{ item.title }}</text>
+							<text class="recent-meta">邀你一起看恩施美景,寻长寿秘密</text>
+							<view class="y-end">
+								<view class="btn-watch" @click.stop="onCourseClick(item)">回看</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</template>
+
+			<!-- 无学习记录:空态 + 为您精选 -->
+			<template v-else>
+				<view class="empty-state">
+					<!-- <view class="empty-icon"></view> -->
+					<image class="empty-icon" src="@/static/images/new/nodata.png"></image>
+					<text class="empty-text">暂无学习内容</text>
+				</view>
+				<view class="recommend-section">
+					<text class="recommend-title">为您精选</text>
+					<view class="course-grid" style="padding: 0;">
+						<view
+							v-for="(course, idx) in recommendList"
+							:key="idx"
+							class="course-card"
+							@click="onCourseClick(course)"
+						>
+							<view class="card-cover">
+								<image :src="course.cover || '/static/logo.jpg'" mode="aspectFill" class="cover-img"></image>
+							</view>
+							
+							<view class="card-footer">
+								<text class="card-title">{{ course.title }}</text>
+								<view class="y-b">
+									<view class="course-meta">
+									邀你一起看恩施美景,寻长寿秘密
+									</view>
+									<view class="y-end">
+										<view class="btn-watch" @click.stop="onCourseClick(item)">回看</view>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</template>
+			<view class="bottom-placeholder"></view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+			tabIndex: 0,
+			categoryExpand: true,
+			categoryIndex: 0,
+			categories: ['全部', '歌唱艺术', '太极养生', '防骗指南', '手机摄影', '棋牌益智', '用药指导', '膳食营养', '慢病管理'],
+			courseList: [
+				{ title: '刘金的《0基础金曲演唱速练课》', views: '9239', cover: '' },
+				{ title: '邹方斌讲《毛笔书法修心课》', views: '10.8w', cover: '' },
+				{ title: '张斌《元气八段锦》系列课', views: '2.5w', cover: '' },
+				{ title: '翔哥精讲摄影课—手机微距拍摄技巧...', views: '100w+', cover: '' },
+				{ title: '道家智慧 入门21讲', views: '1.2w', cover: '' },
+				{ title: '入门进阶必修 瑜伽呼吸全精讲', views: '3.6w', cover: '' }
+			],
+			recentList: [
+				// {
+				// 	date: '2026-02-08',
+				// 	list: [
+				// 		{ title: '歌唱家刘金的《0基础金曲演唱速练课》', progress: 87, cover: '' },
+				// 		{ title: '资深编辑邹方斌讲《毛笔书法修心课》', progress: 56, cover: '' }
+				// 	]
+				// },
+				// {
+				// 	date: '2026-02-01',
+				// 	list: [
+				// 		{ title: '张斌《元气八段锦》系列课', progress: 56, cover: '' }
+				// 	]
+				// }
+			],
+			recommendList: [
+				{ title: '刘金的《0基础金曲演唱速练课》', views: '9239', cover: '' },
+				{ title: '邹方斌讲《毛笔书法修心课》', views: '10.8w', cover: '' },
+				{ title: '张斌《元气八段锦》系列课', views: '2.5w', cover: '' },
+				{ title: '翔哥精讲摄影课-手机微距拍摄技巧...', views: '100w+', cover: '' }
+			]
+		}
+	},
+	onLoad() {
+		// 若无最近学习,可置空 recentList 显示空态
+		// this.recentList = [];
+	},
+	methods: {
+		onCourseClick(course) {
+			uni.showToast({ title: course.title || '立即观看', icon: 'none' })
+			// uni.navigateTo({ url: '/pages_course/videovip?id=' + (course.id || '') })
+		}
+	}
+}
+</script>
+
+<style scoped>
+	/* 图片箭头旋转类(展开时向上) */
+	.rotate-arrow {
+	  transform: rotate(180deg);
+	}
+.container {
+	min-height: 100vh;
+	background: #F5F5F5;
+	display: flex;
+	flex-direction: column;
+}
+
+/* 顶部 Tab */
+.top-nav {
+	display: flex;
+	flex-direction: column;
+	background: #fff;
+	/* border-bottom: 1rpx solid #f0f0f0; */
+}
+.nav-tabs {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+.nav-item {
+	flex:1;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	position: relative;
+	padding: 24rpx 0;
+}
+.nav-item text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 36rpx;
+	color: #030303;
+}
+.nav-item.active text {
+	font-weight: 600;
+	font-size: 40rpx;
+}
+.nav-indicator {
+	position: absolute;
+	left: 50%;
+	bottom: 0;
+	transform: translateX(-50%);
+	width: 100rpx;
+	height: 10rpx;
+	background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+	border-radius: 6rpx;
+}
+.nav-actions {
+	display: flex;
+	align-items: center;
+	gap: 24rpx;
+}
+.action-icon {
+	font-size: 36rpx;
+	color: #666;
+}
+
+/* 滚动区 */
+.scroll-wrap {
+	flex: 1;
+	height: 0;
+}
+
+/* 分类标签 */
+.category-wrap {
+	padding:24rpx 0;
+	border-radius: 0rpx 0rpx 20rpx 20rpx;
+	background: #fff;
+	display: flex;
+	align-items: center;
+	flex-direction: column;
+}
+.category-tags {
+	display: flex;
+	flex-wrap: wrap;
+	gap:24rpx;
+	flex-direction: row;
+	justify-content: center;
+}
+.category-tags.collapsed {
+	max-height: 88rpx;
+	overflow: hidden;
+}
+.tag-item {
+	width: 30%;
+	padding: 20rpx 0;
+	text-align: center;
+	border-radius: 20rpx;
+	background: #f0f0f0;
+}
+.tag-item text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 40rpx;
+	color: rgba(0,0,0,0.85);
+}
+.tag-item.active {
+	background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+}
+.tag-item.active text {
+	color: #fff;
+}
+.expand-btn {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	margin-top: 20rpx;
+	width: 166rpx;
+	height: 64rpx;
+	border-radius: 32rpx;
+	border: 2rpx solid #FF233C;
+}
+.expand-btn text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #FF233C;
+}
+.expand-btn .arrow {
+	margin-left: 6rpx;
+	font-size: 22rpx;
+}
+.expand-btn image{
+	margin-left:10rpx ;
+	width: 32rpx;
+	height: 32rpx;
+}
+/* 课程网格 */
+.course-grid {
+	display: flex;
+	flex-wrap: wrap;
+	padding:24rpx;
+	gap: 24rpx 20rpx;
+	flex-direction: column;
+}
+.course-card {
+	display: flex;
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+	padding: 20rpx;
+}
+.course-tag {
+	position: absolute;
+	left: 0;
+	bottom: 0;
+	right: 0;
+	padding: 8rpx 12rpx;
+	background: linear-gradient(transparent, rgba(0,0,0,0.6));
+	font-size: 22rpx;
+	color: #fff;
+}
+.course-info {
+	flex: 1;
+	padding-left: 24rpx;
+/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+
+.course-meta {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0,0,0,0.65);
+	line-height: 44rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+.meta-icon {
+	font-size: 24rpx;
+	margin-right: 6rpx;
+	color: #999;
+}
+.meta-count {
+	margin-left: 10rpx;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #666666;
+}
+.card-cover {
+	position: relative;
+	width: 296rpx;
+	height: 222rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	flex-shrink: 0;
+}
+.cover-img {
+	width: 100%;
+	height: 100%;
+	background: #BB6D6D;
+}
+.card-title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #222222;
+	line-height: 50rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+.card-footer {
+	flex: 1;
+		padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		min-width: 0;
+}
+.card-views {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: #666666;
+	line-height: 44rpx;
+}
+.btn-watch {
+		width: 168rpx;
+		height: 64rpx;
+		line-height: 64rpx;
+		text-align: center;
+		background: linear-gradient( 135deg, #FF5267 0%, #FF233C 100%);
+		border-radius: 32rpx;
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 600;
+		font-size: 32rpx;
+	color: #FFFFFF;
+}
+
+/* 最近学习 - 按日期分组 */
+.recent-group {
+	padding: 24rpx 24rpx 0;
+}
+.group-date {
+	display: flex;
+	align-items: center;
+	margin-bottom: 24rpx;
+}
+.date-icon {
+	width: 32rpx;
+	height: 32rpx;
+	margin-right: 8rpx;
+}
+.date-text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 40rpx;
+	line-height: 56rpx;
+	color: #222222;
+}
+.recent-card {
+	display: flex;
+	background: #fff;
+	border-radius: 20rpx;
+	overflow: hidden;
+	padding: 20rpx;
+	margin-bottom: 24rpx;
+}
+.recent-card:last-child{
+	margin-bottom: 0;
+}
+.recent-thumb {
+	position: relative;
+	width: 296rpx;
+	height: 222rpx;
+	border-radius: 20rpx;
+	overflow: hidden;
+	flex-shrink: 0;
+}
+.thumb-img {
+	width: 100%;
+	height: 100%;
+	background: #BB6D6D;
+}
+.recent-info {
+	flex: 1;
+	padding-left: 24rpx;
+	/* padding: 20rpx 24rpx; */
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+.recent-title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 36rpx;
+	color: #222222;
+	line-height: 50rpx;
+	text-align: justify;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+.recent-progress {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0,0,0,0.65);
+	line-height: 44rpx;
+}
+
+/* 空态 */
+.empty-state {
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	padding: 80rpx 0 48rpx;
+	/* background: linear-gradient(180deg, #fff5f5 0%, #fff 100%); */
+}
+.empty-icon {
+	width: 310rpx;
+	height: 260rpx;
+	margin-bottom: 30rpx;
+}
+.empty-text {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 36rpx;
+	color: rgba(0,0,0,0.25);
+	line-height: 50rpx;
+}
+
+/* 为您精选 */
+.recommend-section {
+	padding: 0 24rpx 32rpx;
+}
+.recommend-title {
+	display: block;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 600;
+	font-size: 40rpx;
+	color: #222222;
+	line-height: 56rpx;
+	padding-bottom: 24rpx;
+}
+
+.bottom-placeholder {
+	height: 120rpx;
+}
+</style>

+ 885 - 0
pages/shopping/confirmOrder.vue

@@ -0,0 +1,885 @@
+<template>
+	<view>
+		<view class="inner-box">
+			<!-- 收货人 -->
+			<view class="address-box" v-if="address==null" @click="openAddress()">
+				<view class="left">
+					<view class="name-box">
+						<text class="text name">添加收货地址</text>
+					</view>
+					</vie>
+				</view>
+				<view class="arrow-box">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow_gray.png"
+						mode=""></image>
+				</view>
+			</view>
+			<view class="address-box" v-if="address!=null" @click="openAddress()">
+				<view class="left">
+					<view class="name-box">
+						<text class="text name">{{address.realName}}</text>
+						<text class="text" v-if="address.phone!=null">{{$parsePhone(address.phone)}}</text>
+					</view>
+					<view class="address">
+						{{address.province}}{{address.city}}{{address.district}}{{address.detail}}
+					</view>
+				</view>
+				<view class="arrow-box">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow_gray.png"
+						mode=""></image>
+				</view>
+			</view>
+			<!-- 产品列表 -->
+			<view class="goods-list">
+				<view v-for="(item,index) in carts" :key="index" class="item">
+					<view class="img-box">
+						<image :src="item.productAttrImage||item.productImage" mode="aspectFill"></image>
+					</view>
+					<view class="info-box">
+						<view>
+							<view class="name-box ellipsis2">
+								<!-- <view class="tag">{{utils.getDictLabelName("storeProductType",item.productType)}}</view> -->
+								{{item.productName}}
+							</view>
+							<view class="spec ellipsis2">{{item.productAttrName}}</view>
+						</view>
+						<view class="price-num">
+							<view class="price">
+								<text class="unit">¥</text>
+								<text class="num">{{item.price.toFixed(2)}}</text>
+							</view>
+							<view class="num">x{{item.cartNum}}</view>
+						</view>
+					</view>
+				</view>
+				<!-- 小计 -->
+				<view class="sub-total">
+					<text class="label">小计:</text>
+					<view class="price">
+						<text class="unit">¥</text>
+						<text class="num">{{price.totalPrice.toFixed(2)}}</text>
+					</view>
+				</view>
+			</view>
+			<!-- 积分 -->
+			<view class="points">
+				<view class="left">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/points.png" mode="">
+					</image>
+					<text class="text">可用积分</text>
+				</view>
+				<view class="right">
+					<text class="text">{{price.usedIntegral}}积分</text>
+					<evan-switch @change="integralChange" v-model="checked" activeColor="#FF233C"
+						inactiveColor="rgba(0, 0, 0, 0.1)"></evan-switch>
+				</view>
+			</view>
+			<view class="points" @click="openCoupon()">
+				<view class="left">
+					<text class="text">优惠券</text>
+				</view>
+				<view class="right">
+					<text class="text">{{couponText}}</text>
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow4.png" mode="">
+					</image>
+				</view>
+			</view>
+			<view class="points">
+				<view class="left">
+					<text class="text">运费</text>
+				</view>
+				<view class="right">
+					<text
+						class="text">{{price.payPostage==null||price.payPostage==0?'免运费':price.payPostage.toFixed(2)}}</text>
+				</view>
+			</view>
+			<!-- 备注 -->
+			<view class="remarks">
+				<input type="text" v-model="form.mark" placeholder="备注留言(选填)" placeholder-class="input" />
+			</view>
+		</view>
+		<!-- 底部按钮 -->
+		<view class="btn-foot">
+			<view class="right">
+				<view class="total">
+					<text class="label">合计:</text>
+					<view class="price">
+						<text class="unit">¥</text>
+						<text class="num">{{price.payPrice.toFixed(2)}}</text>
+					</view>
+				</view>
+				<view class="btn" @click="submitOrder">提交订单</view>
+			</view>
+		</view>
+		<popupBottom ref="popup" :visible.sync="couponVisible" title=" " bgColor="#f5f5f5" radius="30" maxHeight="60%">
+			<view class="coupon" style="height:650rpx;">
+				<div class="coupon-list" v-if="couponsList.length > 0">
+					<div class="item acea-row row-center-wrapper" v-for="(item, index) in couponsList" :key="index">
+						<div class="money">
+							<image v-if="item.status==0" class="img"
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/coupon1.png"
+								mode="widthFix"></image>
+							<image v-if="item.status!=0" class="img"
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/coupon2.png"
+								mode="widthFix"></image>
+							<div style="z-index: 999;">
+								¥<span class="num">{{ item.couponPrice }}</span>
+							</div>
+							<div class="pic-num">满{{ item.useMinPrice }}元可用</div>
+						</div>
+						<div class="text">
+							<div class="condition line1">
+								{{ item.couponTitle }}
+							</div>
+							<div class="data acea-row row-between-wrapper">
+								<div>{{ item.limitTime }}到期</div>
+								<div class="bnt bg-color-red" @click="couponSelect(item)">选择</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<view v-if="couponsList.length == 0" class="no-data-box">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/no_data.png"
+						mode="aspectFit"></image>
+					<view class="empty-title">暂无数据</view>
+				</view>
+			</view>
+
+		</popupBottom>
+	</view>
+</template>
+
+<script>
+	import {
+		getWeixinOrderTemps
+	} from '@/api/common'
+
+	import {
+		confirm,
+		computed,
+		create
+	} from '@/api/storeOrder'
+	import {
+		getMyEnableCouponList
+	} from '@/api/coupon'
+
+	import EvanSwitch from '@/components/evan-switch/evan-switch.vue'
+	import popupBottom from '@/components/px-popup-bottom/px-popup-bottom.vue'
+
+	export default {
+		components: {
+			EvanSwitch,
+			popupBottom
+		},
+		data() {
+			return {
+				temps: [],
+				couponUserId: null,
+				couponText: "请选择",
+				couponsList: [],
+				couponVisible: false,
+				price: {
+					payPrice: 0,
+					totalPostage: 0,
+					usedIntegral: 0,
+					totalPrice: 0.00,
+				},
+				address: null,
+				carts: [],
+				checked: false,
+				type: null,
+				cartIds: null,
+				storeId: null,
+				form: {
+					useIntegral: 0,
+					orderKey: null,
+					addressId: null,
+					mark: null,
+					companyId: null,
+					companyUserId: null
+				},
+				courseId:null
+
+			}
+		},
+		onLoad(option) {
+			console.log("确认订单option是", option)
+			this.form.companyId = option.companyId;
+			this.form.companyUserId = option.companyUserId;
+			this.cartIds = option.cartIds;
+			this.type = option.type;
+			this.storeId = option.storeId;
+			this.courseId = option.courseId
+			this.confirm();
+			uni.$on('updateAddress', (e) => {
+				this.address = e;
+				this.form.addressId = e.id;
+				this.computed();
+			})
+			this.getWeixinOrderTemps();
+		},
+		onUnload() {
+			uni.$off('updateAddress')
+		},
+		methods: {
+			getWeixinOrderTemps: function() {
+				getWeixinOrderTemps().then(
+					res => {
+						if (res.code == 200) {
+							this.temps = res.temp
+							console.log(this.temps)
+						} else {
+
+						}
+					},
+					rej => {}
+				);
+			},
+			couponSelect(item) {
+				this.couponText = "-¥" + item.couponPrice.toFixed(2);
+				this.couponUserId = item.id;
+				this.couponVisible = false;
+				this.computed();
+			},
+			openCoupon() {
+				let that = this;
+				var data = {
+					couponType: 0,
+					useMinPrice: this.price.payPrice
+				};
+				getMyEnableCouponList(data).then(res => {
+					this.couponVisible = true;
+					that.couponsList = res.data
+				})
+			},
+			integralChange(e) {
+				console.log(e)
+				this.form.useIntegral = e ? 1 : 0
+				this.computed()
+			},
+			confirm(item) {
+				let data = {
+					type: this.type,
+					cartIds: this.cartIds
+				};
+				confirm(data).then(
+					res => {
+						if (res.code == 200) {
+
+							this.carts = res.carts;
+							this.form.orderKey = res.orderKey;
+							if (res.address != null) {
+								this.form.addressId = res.address.id;
+								this.address = res.address;
+								console.log(this.form.addreddId)
+							}
+							this.computed()
+						} else {
+
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			computed(item) {
+				let data = {
+					couponUserId: this.couponUserId,
+					orderKey: this.form.orderKey,
+					addressId: this.form.addressId,
+					useIntegral: this.form.useIntegral
+				};
+				computed(data).then(
+					res => {
+						if (res.code == 200) {
+							console.log(res)
+							this.price = res.data
+
+						} else {
+							if (res.code == 501) {
+								uni.showToast({
+									icon: 'none',
+									title: res.msg,
+								});
+								setTimeout(function() {
+									uni.navigateBack({
+										delta: 1
+									})
+								}, 500);
+								return;
+							} else {
+								uni.showToast({
+									icon: 'none',
+									title: res.msg,
+								});
+							}
+
+						}
+					},
+					rej => {}
+				);
+			},
+			// 提交订单
+			submitOrder() {
+				var that = this;
+				if (this.form.orderKey == null) {
+					uni.showToast({
+						icon: 'none',
+						title: '订单KEY不存在',
+					});
+					return;
+				}
+				if (this.form.addressId == null) {
+					uni.showToast({
+						icon: 'none',
+						title: '收货地址不能为空',
+					});
+					return;
+				}
+                this.createOrder();
+				// uni.requestSubscribeMessage({
+				// 	tmplIds: this.temps,
+				// 	success(res) {
+				// 		that.createOrder();
+				// 	},
+				// 	fail(res) {
+				// 		that.createOrder();
+				// 	}
+				// })
+
+			},
+			createOrder() {
+				var that = this;
+				var data = null;
+				var tuiUserId = uni.getStorageSync('tuiUserId');
+				uni.showLoading({
+					title: '正在处理中...'
+				});
+				if (tuiUserId != null && tuiUserId != undefined && tuiUserId > 0) {
+					data = {
+						orderCreateType: 1,
+						tuiUserId: tuiUserId,
+						companyId: this.form.companyId,
+						companyUserId: this.form.companyUserId,
+						couponUserId: this.couponUserId,
+						mark: this.form.mark,
+						orderKey: this.form.orderKey,
+						addressId: this.form.addressId,
+						useIntegral: this.form.useIntegral,
+						payType: 1
+					};
+				} else {
+					data = {
+						orderCreateType: 1,
+						companyId: this.form.companyId,
+						companyUserId: this.form.companyUserId,
+						couponUserId: this.couponUserId,
+						mark: this.form.mark,
+						orderKey: this.form.orderKey,
+						addressId: this.form.addressId,
+						useIntegral: this.form.useIntegral,
+						payType: 1
+					};
+				}
+				if (this.storeId != null && this.storeId > 0) {
+					data.storeId = this.storeId;
+				}
+				var urlInfo = uni.getStorageSync('urlInfo')
+				console.log('this.isCourse',this.courseId)
+				if(this.courseId!=null && this.courseId > 0){
+					data.courseId=urlInfo.courseId
+					data.videoId=urlInfo.videoId
+					data.periodId = urlInfo.periodId
+					data.projectId = urlInfo.projectId
+					data.companyUserId=urlInfo.companyUserId
+					data.companyId=urlInfo.companyId
+					data.orderType=3
+				}
+				uni.hideLoading()
+				create(data).then(
+					res => {
+						uni.hideLoading()
+						if (res.code == 200) {
+							uni.hideLoading()
+							if (res.order.isPrescribe == 1) {
+								setTimeout(function() {
+									uni.redirectTo({
+										url: "prescribe?orderId=" + res.order.id
+									})
+								}, 200);
+							} else {
+								setTimeout(function() {
+									uni.redirectTo({
+										url: './paymentOrder?orderId=' + res.order.id
+									})
+								}, 200);
+							}
+							return;
+						} else {
+							if (res.code == 501) {
+								uni.showToast({
+									icon: 'none',
+									title: res.msg,
+								});
+								setTimeout(function() {
+									uni.navigateBack({
+										delta: 1
+									})
+								}, 200);
+								return;
+							} else {
+								uni.showToast({
+									icon: 'none',
+									title: res.msg,
+								});
+							}
+						}
+					},
+					rej => {}
+				);
+			},
+			openAddress() {
+				uni.navigateTo({
+					url: '/pages_user/user/address'
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.inner-box {
+		padding: 20upx 20upx 140upx;
+
+		.address-box {
+			box-sizing: border-box;
+			min-height: 171upx;
+			background: #FFFFFF;
+			border-radius: 16upx;
+			background-image: url("https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/address_bg.png");
+			background-repeat: no-repeat;
+			background-size: 100% 30upx;
+			background-position: left bottom;
+			padding: 38upx 30upx 36upx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+
+			.left {
+				width: 92%;
+
+				.name-box {
+					display: flex;
+					align-items: center;
+
+					.text {
+						font-size: 32upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #111111;
+						line-height: 1;
+
+						&.name {
+							margin-right: 30upx;
+						}
+					}
+				}
+
+				.address {
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+					line-height: 42upx;
+					text-align: left;
+					margin-top: 23upx;
+				}
+			}
+
+			.arrow-box {
+				width: 12upx;
+				height: 23upx;
+				display: flex;
+				align-items: cenetr;
+				justify-content: cenetr;
+
+				image {
+					width: 100%;
+					height: 100%;
+				}
+			}
+		}
+
+		.goods-list {
+			margin-top: 20upx;
+			padding: 0 30upx;
+			background-color: #FFFFFF;
+			border-radius: 16upx;
+
+			.item {
+				padding: 30upx 0;
+				border-bottom: 1px solid #EDEEEF;
+				display: flex;
+				align-items: center;
+
+				.img-box {
+					width: 160upx;
+					height: 160upx;
+					margin-right: 30upx;
+
+					image {
+						width: 100%;
+						height: 100%;
+					}
+				}
+
+				.info-box {
+					width: calc(100% - 190upx);
+					height: 160upx;
+					display: flex;
+					flex-direction: column;
+					justify-content: space-between;
+
+					.name-box {
+						font-size: 28upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #111111;
+						line-height: 40upx;
+
+						.tag {
+							display: inline-block;
+							padding: 0 6upx;
+							height: 30upx;
+							background: linear-gradient(90deg, #66b2ef 0%, #FF233C 100%);
+							border-radius: 4upx;
+							margin-right: 10upx;
+							font-size: 22upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #FFFFFF;
+							line-height: 30upx;
+							float: left;
+							margin-top: 7upx;
+						}
+					}
+
+					.spec {
+						margin-top: 10upx;
+						font-size: 24upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						line-height: 1;
+					}
+
+					.price-num {
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+
+						.price {
+							display: flex;
+							align-items: flex-end;
+
+							.unit {
+								font-size: 24upx;
+								font-family: PingFang SC;
+								font-weight: 500;
+								color: #111111;
+								line-height: 1.2;
+								margin-right: 4upx;
+							}
+
+							.num {
+								font-size: 32upx;
+								font-family: PingFang SC;
+								font-weight: 500;
+								color: #111111;
+								line-height: 1;
+							}
+						}
+
+						.num {
+							font-size: 24upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #999999;
+							line-height: 1;
+						}
+					}
+				}
+			}
+
+			.sub-total {
+				height: 88upx;
+				display: flex;
+				align-items: center;
+				justify-content: flex-end;
+
+				.label {
+					font-size: 24upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+				}
+
+				.price {
+					display: flex;
+					align-items: flex-end;
+
+					.unit {
+						font-size: 24upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #FF6633;
+						line-height: 1.2;
+						margin-right: 4upx;
+					}
+
+					.num {
+						font-size: 32upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1;
+					}
+				}
+			}
+		}
+
+		.points {
+			height: 88upx;
+			padding: 0 30upx;
+			background: #FFFFFF;
+			border-radius: 16upx;
+
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+
+			.left {
+				display: flex;
+				align-items: center;
+
+				image {
+					width: 28upx;
+					height: 28upx;
+					margin-right: 20upx;
+				}
+
+				.text {
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+				}
+			}
+
+			.right {
+				display: flex;
+				align-items: center;
+
+				.text {
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #111111;
+
+				}
+
+				image {
+					margin-left: 15upx;
+					width: 14upx;
+					height: 24upx;
+				}
+			}
+		}
+
+		.remarks {
+			height: 88upx;
+			padding: 0 30upx;
+			background: #FFFFFF;
+			border-radius: 16upx;
+			margin-top: 20upx;
+			display: flex;
+			align-items: center;
+
+			input {
+				width: 100%;
+				font-size: 28upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #000000;
+			}
+
+			.input {
+				font-size: 28upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+			}
+		}
+	}
+
+
+	.btn-foot {
+		box-sizing: border-box;
+		width: 100%;
+		height: 121upx;
+		background: #FFFFFF;
+		padding: 16upx 30upx 16upx 60upx;
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+		position: fixed;
+		left: 0;
+		bottom: 0;
+		z-index: 99;
+
+		.right {
+			display: flex;
+			align-items: center;
+
+			.total {
+				display: flex;
+				align-items: flex-end;
+				margin-right: 36upx;
+
+				.label {
+					font-size: 26upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 1.5;
+				}
+
+				.price {
+					display: flex;
+					align-items: flex-end;
+
+					.unit {
+						font-size: 32upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1.2;
+						margin-right: 10upx;
+					}
+
+					.num {
+						font-size: 50upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1;
+					}
+				}
+			}
+
+			.btn {
+				width: 200upx;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				background: #FF233C;
+				border-radius: 44upx;
+			}
+		}
+	}
+</style>
+<style lang="less" scoped>
+	.coupon {
+		height: 100%;
+	}
+
+	/*优惠券列表公共*/
+	.coupon-list {}
+
+	.coupon-list .item {
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 100%;
+		height: 1.7 * 100rpx;
+		margin-bottom: 0.16 * 100rpx;
+	}
+
+	.coupon-list .item .money {
+		background-size: 100% 100%;
+		width: 2.4 * 100rpx;
+		height: 100%;
+		color: #fff;
+		font-size: 0.36 * 100rpx;
+		font-weight: bold;
+		text-align: center;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		position: relative;
+
+	}
+
+	.coupon-list .item .money .img {
+		position: absolute;
+		width: 2.4 * 100rpx;
+		height: 100%;
+		color: #fff;
+
+	}
+
+	.coupon-list .item .money .num {
+		font-size: 0.6 * 100rpx;
+	}
+
+	.coupon-list .item .money .pic-num {
+		font-size: 20rpx;
+		z-index: 99;
+	}
+
+
+	.coupon-list .item .text {
+		width: 4.5 * 100rpx;
+		padding: 0 0.17 * 100rpx 0 0.24 * 100rpx;
+		background-color: #fff;
+		box-sizing: border-box;
+	}
+
+	.coupon-list .item .text .condition {
+		font-size: 0.3 * 100rpx;
+		color: #282828;
+		height: 0.93 * 100rpx;
+		line-height: 0.93 * 100rpx;
+		border-bottom: 1px solid #f0f0f0;
+	}
+
+	.coupon-list .item .text .data {
+		font-size: 0.2 * 100rpx;
+		color: #999;
+		height: 0.76 * 100rpx;
+	}
+
+	.coupon-list .item .text .data .bnt {
+		width: 1.36 * 100rpx;
+		height: 0.44 * 100rpx;
+		border-radius: 0.22 * 100rpx;
+		font-size: 0.22 * 100rpx;
+		color: #fff;
+		text-align: center;
+		line-height: 0.44 * 100rpx;
+		background-color: red;
+	}
+
+	.coupon-list .item .text .data .bnt.gray {
+		background-color: #ccc;
+	}
+</style>

+ 343 - 0
pages/shopping/payOrder.vue

@@ -0,0 +1,343 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<!-- 时间、价格 -->
+			<view class="time-price">
+				<text class="time">请在{{payLimitTime}}前完成支付</text>
+				<view class="price-box">
+					<text class="unit">¥</text>
+					<text class="num">{{order.payPrice}}</text>
+				</view>
+			</view>
+			<!-- 支付方式 -->
+			<view class="pay-type">
+				<view class="title">支付方式</view>
+				<view class="item">
+					<view class="left">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/wecha_pay.png" mode=""></image>
+						<text class="text">微信支付</text>
+					</view>
+					<label>
+						<checkbox disabled value="" :checked="wxPay" />
+					</label>
+				</view>
+			</view>
+			<!-- 订单详情查看 -->
+			<view class="order-info">
+				<view class="title">订单信息</view>
+				<view class="item">
+					<text class="label">订单编号</text>
+					<view class="sn-box">
+						<text class="text">{{order.orderCode}}</text>
+						<view class="copy-btn" @click="copyOrderSn(order.orderCode)">复制</view>
+					</view>
+				</view>
+				<view class="item">
+					<text class="label">下单时间</text>
+					<text class="text">{{order.createTime}}</text>
+				</view>
+				<view class="item">
+					<text class="label">支付方式</text>
+					<text class="text">微信支付</text>
+				</view>
+				 
+			</view>
+			
+		</view>
+		<view class="btn-box">
+			<view class="btn" @click="payOrder()">去支付</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {pay,getStoreOrderById} from '@/api/storeOrder'
+	export default {
+		data() {
+			return {
+				payLimitTime:null,
+				order:null,
+				// 默认选中微信支付
+				wxPay: true,
+			}
+		},
+		onLoad: function(options) {
+		    if (options.hasOwnProperty('q') && options.q) {
+				// 通过下面这步解码,可以拿到url的值
+				const url = decodeURIComponent(options.q)
+				this.url=url;
+				// // 对url中携带的参数提取处理
+				const obj = this.utils.urlToObj(url)
+				this.orderId=obj.orderId;
+		    }
+			else if(options!=null&&options.orderId!=null){
+				this.orderId=options.orderId;
+			}
+		},
+		onShow() {
+			this.getStoreOrderById();
+		},
+		methods: {
+			copyOrderSn(text) {
+				// 复制方法
+				uni.setClipboardData({
+					data:text,
+					success:()=>{
+						uni.showToast({
+							title:'内容已成功复制到剪切板',
+							icon:'none'
+						})
+					}
+				});
+			},
+			getStoreOrderById(){
+				var data = {orderId:this.orderId};
+				var that=this;
+				uni.showLoading();
+				getStoreOrderById(data).then(
+					res => {
+						if(res.code==200){
+							 console.log(res);
+							  uni.hideLoading();
+							  that.order=res.order;
+							  that.payLimitTime=res.payLimitTime;
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+				
+			},
+			payOrder(){
+				var data = {orderId:this.order.id,appId: wx.getAccountInfoSync().miniProgram.appId};
+				console.log('当前小程序信息id',data)
+				var that=this;
+				uni.showLoading();
+				pay(data).then(
+					res => {
+						if(res.code==200){
+							 console.log(res);
+							 uni.requestPayment({
+							 	provider: 'wxpay',
+							 	timeStamp: res.result.timeStamp,
+							 	nonceStr: res.result.nonceStr,
+							 	package: res.result.packageValue,
+							 	signType: res.result.signType,
+							 	paySign: res.result.paySign,
+							 	success: function(res) {
+							 		 uni.hideLoading();
+									 if(that.order.isPrescribe){
+										 //如果是处方订单开处方
+										uni.redirectTo({
+										 	url:"prescribe?orderId="+that.order.id
+										})
+									 }
+									 else{
+										//如果是普通订单
+										uni.redirectTo({
+											url:"success?order="+JSON.stringify(that.order)
+										}) 
+									 }
+							 	},
+							 	fail: function(err) {
+							 		console.log('fail:' + JSON.stringify(err));
+							 		uni.hideLoading();
+							 	}
+							 });
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+				
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		height: 100%;
+		background-color: #F2F5F9;
+	}
+	.content{
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		.inner{
+			padding: 20upx;
+			.time-price{
+				box-sizing: border-box;
+				height: 200upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				padding-top: 50upx;
+				.time{
+					font-size: 26upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 1;
+					text-align: center;
+				}
+				.price-box{
+					display: flex;
+					align-items: flex-end;
+					margin-top: 28upx;
+					.unit{
+						font-size: 32upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1.3;
+						margin-right: 10upx;
+					}
+					.num{
+						font-size: 56upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1;
+					}
+				}
+			}
+			.pay-type{
+				box-sizing: border-box;
+				height: 192upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				margin-top: 20upx;
+				padding: 40upx 30upx;
+				display: flex;
+				flex-direction: column;
+				justify-content: space-between;
+				.title{
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 1;
+				}
+				.item{
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					.left{
+						display: flex;
+						align-items: center;
+						image{
+							width: 44upx;
+							height: 44upx;
+							margin-right: 20upx;
+						}
+						.text{
+							font-size: 30upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #222222;
+							line-height: 1;
+						}
+					}
+				}
+			}
+			.order-info{
+				margin-top: 20upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 40upx 30upx;
+				.title{
+					font-size: 30upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #222222;
+					line-height: 1;
+				}
+				.item{
+					margin-top: 40upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					.label{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 1;
+					}
+					.text{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						line-height: 32upx;
+					}
+					.cont-text{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						.bold{
+							color: #111111;
+						}
+					}
+					.sn-box{
+						display: flex;
+						align-items: center;
+						.copy-btn{
+							width: 58upx;
+							height: 32upx;
+							line-height: 32upx;
+							text-align: center;
+							font-size: 22upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #222222;
+							background: #F5F5F5;
+							border-radius: 4upx;
+							margin-left: 24upx;
+						}
+					}
+					 
+				}
+				.line{
+					width: 100%;
+					height: 1px;
+					background: #F0F0F0;
+					margin-top: 30upx;
+				}
+			}
+		}
+		.btn-box{
+			height: 121upx;
+			background: #FFFFFF;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			.btn{
+				width: 91.73%;
+				height: 88upx;
+				line-height: 88upx;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				text-align: center;
+				background: #FF233C;
+				border-radius: 44upx;
+			}
+		}
+	}
+	
+</style>

+ 751 - 0
pages/shopping/paymentOrder.vue

@@ -0,0 +1,751 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<!-- 时间、价格 -->
+			<view class="time-price">
+				<text class="time">请在{{payLimitTime}}前完成支付</text>
+				<view class="price-box">
+					<text class="unit">¥</text>
+					<text class="num">{{payMoney.toFixed(2)}}</text>
+				</view>
+				<!-- <text class="desc" v-if="payType==2">代收金额{{payDelivery.toFixed(2)}},请您在收到快递后支付尾款给快递人员。</text> -->
+				<!-- <text class="desc" v-if="payType==3">货到付款金额{{payDelivery.toFixed(2)}},请您在收到快递后支付给快递人员。</text> -->
+			</view>
+			<!-- 支付方式 -->
+			<view class="pay-type">
+				<view class="title">支付方式</view>
+				<!-- 改价订单只能选择微信支付和物流代收 -->
+				<radio-group @change="payTypeChange" v-if="order.isEditMoney!=null&&order.isEditMoney==1">
+					<view class="item">
+						<view class="left">
+							<image
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/wecha_pay.png"
+								mode=""></image>
+							<text class="text">微信支付</text>
+						</view>
+						<label>
+							<radio :value="1" :checked="order.payType=='1'" />
+						</label>
+					</view>
+					<!-- <view class="item"  >
+						<view class="left">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/pay_de.png" mode=""></image>
+							<text class="text">物流代收</text>
+						</view>
+						<label>
+							<radio  :value="2" :checked="order.payType=='2'" />
+						</label>
+					</view> -->
+				</radio-group>
+
+				<radio-group @change="payTypeChange" v-else-if="order.orderCreateType!=null&& order.orderCreateType==3">
+					<view class="item">
+						<view class="left">
+							<image
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/wecha_pay.png"
+								mode=""></image>
+							<text class="text">微信支付</text>
+						</view>
+						<label>
+							<radio :value="1" :checked="order.payType=='1'" />
+						</label>
+					</view>
+					<!-- <view class="item" >
+						<view class="left">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/pay_de.png" mode=""></image>
+							<text class="text">物流代收</text>
+						</view>
+						<label>
+							<radio  :value="2" :checked="order.payType=='2'" />
+						</label>
+					</view> -->
+					<!-- <view class="item" v-if="user!=null&&user.level==1 "> -->
+					<!-- <view class="item" >
+						<view class="left">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/pay_1.png" mode=""></image>
+							<text class="text">货到付款</text>
+						</view>
+						<label>
+							<radio  :value="3" :checked="order.payType=='3'" />
+						</label>
+					</view> -->
+				</radio-group>
+				<radio-group @change="payTypeChange" v-else-if="order.orderCreateType!=null&& order.orderCreateType==2">
+					<view class="item" v-if="payType==1||payType==4">
+						<view class="left">
+							<image
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/wecha_pay.png"
+								mode=""></image>
+							<text class="text">微信支付</text>
+						</view>
+						<label>
+							<radio :value="1" :checked="order.payType=='1'" />
+						</label>
+					</view>
+					<!-- <view class="item" v-if="payType==2||payType==4">
+						<view class="left" >
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/pay_de.png" mode=""></image>
+							<text class="text">物流代收</text>
+						</view>
+						<label>
+							<radio  :value="2" :checked="order.payType=='2'" />
+						</label>
+					</view> -->
+					<!-- <view class="item" v-if="user!=null&&user.level==1 "> -->
+					<!-- <view class="item" v-if="payType==1||payType==4" >
+						<view class="left">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/pay_1.png" mode=""></image>
+							<text class="text">货到付款</text>
+						</view>
+						<label>
+							<radio  :value="3" :checked="order.payType=='3'" />
+						</label>
+					</view> -->
+				</radio-group>
+				<radio-group @change="payTypeChange"
+					v-else-if="order.orderCreateType!=null&&(order.orderCreateType==1)">
+					<view class="item">
+						<view class="left">
+							<image
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/wecha_pay.png"
+								mode=""></image>
+							<text class="text">微信支付</text>
+						</view>
+						<label>
+							<radio :value="1" checked />
+						</label>
+					</view>
+				</radio-group>
+			</view>
+			<!-- 订单详情查看 -->
+			<view class="order-info">
+				<view class="title">订单信息</view>
+				<view class="item">
+					<text class="label">订单编号</text>
+					<view class="sn-box">
+						<text class="text">{{order.orderCode}}</text>
+						<view class="copy-btn" @click="copyOrderSn(order.orderCode)">复制</view>
+					</view>
+				</view>
+				<view class="item">
+					<text class="label">下单时间</text>
+					<text class="text">{{order.createTime}}</text>
+				</view>
+				<view class="item">
+					<text class="label">订单金额</text>
+					<text class="text" v-if="order!=null">{{order.payPrice.toFixed(2)}}</text>
+				</view>
+
+				<!-- <view class="item">
+					<text class="label">支付方式</text>
+					<text class="text">微信支付</text>
+				</view> -->
+
+			</view>
+
+		</view>
+		<view class="btn-box">
+			<view class="btn" @click="payOrder()">去支付</view>
+			<!-- <view class="other-btn" >
+				亲友代付
+				<button  class="share" data-name="shareBtn" open-type="share">分享</button>
+			</view> -->
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getUserInfo
+	} from '@/api/user'
+	import {
+		getStoreConfig
+	} from '@/api/common'
+	import {
+		editPayType,
+		pay,
+		getStoreOrderById,
+		orderBindUser,
+		clearPayType
+	} from '@/api/storeOrder'
+	export default {
+		data() {
+			return {
+				orderId: null,
+				payDelivery: 0,
+				payMoney: 0,
+				config: null,
+				payType: 1,
+				payLimitTime: null,
+				order: null,
+				user: null,
+				payParams: null,
+				userinfo: {},
+				isPaying: false, // 防止重复支付
+				payDebounceTimer: null // 防抖定时器
+			}
+		},
+		onLoad(option) {
+			this.getSafeUserInfo();
+			this.orderId = JSON.parse(option.orderId);
+			// this.orderBindUser(this.orderId)
+			this.getStoreOrderById();
+			this.getStoreConfig();
+			// this.getUserInfo();
+		},
+		onShow() {
+			this.getUserInfo();
+		},
+		onUnload() {
+			this.clearPayTypeFun()
+		},
+		methods: {
+			getSafeUserInfo() {
+				try {
+					const userInfoStr = uni.getStorageSync('userInfo');
+					if (!userInfoStr) {
+						this.userinfo = {};
+						return;
+					}
+
+					// 如果是字符串,解析为对象
+					if (typeof userInfoStr === 'string') {
+						this.userinfo = JSON.parse(userInfoStr);
+					} else {
+						// 如果是对象,直接使用
+						this.userinfo = userInfoStr;
+					}
+
+					console.log('获取到的用户信息:', this.userinfo);
+				} catch (error) {
+					console.error('获取用户信息失败:', error);
+					this.userinfo = {};
+				}
+			},
+			redirectToLogin() {
+				// 直接跳转到登录页,不删除token和userInfo
+				uni.navigateTo({
+					url: '/pages/auth/login'
+				});
+			},
+			async clearPayTypeFun() {
+				this.payParams && this.payParams.orderId && await clearPayType(this.payParams)
+			},
+			// 防抖函数
+			debounce(func, wait = 1000) {
+				return (...args) => {
+					// 清除之前的定时器
+					if (this.payDebounceTimer) {
+						clearTimeout(this.payDebounceTimer);
+					}
+
+					// 设置新的定时器
+					this.payDebounceTimer = setTimeout(() => {
+						func.apply(this, args);
+						this.payDebounceTimer = null;
+					}, wait);
+				};
+			},
+
+			orderBindUser(orderId) {
+				uni.showLoading({
+					title: '加载中...'
+				})
+				orderBindUser({
+					orderId: orderId
+				}).then(res => {
+					uni.hideLoading()
+					if (res.code == 200) {
+						this.getStoreOrderById();
+						this.getStoreConfig();
+						this.getUserInfo();
+					} else {
+						uni.showToast({
+							icon: 'none',
+							title: res.msg,
+						});
+
+					}
+				}).catch(() => {
+					uni.hideLoading()
+				});
+			},
+			getUserInfo() {
+				getUserInfo().then(
+					res => {
+						if (res.code == 200) {
+							if (res.user != null) {
+								this.user = res.user;
+							}
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: "请求失败",
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			getStoreConfig() {
+				getStoreConfig().then(
+					res => {
+						if (res.code == 200) {
+							this.config = res.data
+							console.log(this.config);
+						}
+					},
+					rej => {}
+				);
+			},
+			payTypeChange(e) {
+				this.editPayType(e.detail.value)
+			},
+			copyOrderSn(text) {
+				// 复制方法
+				uni.setClipboardData({
+					data: text,
+					success: () => {
+						uni.showToast({
+							title: '内容已成功复制到剪切板',
+							icon: 'none'
+						})
+					}
+				});
+			},
+			getStoreOrderById() {
+				var data = {
+					orderId: this.orderId
+				};
+				var that = this;
+				uni.showLoading();
+				getStoreOrderById(data).then(
+					res => {
+						if (res.code == 200) {
+							console.log(res);
+							uni.hideLoading();
+							that.order = res.order;
+							that.payLimitTime = res.payLimitTime;
+							//套餐订单处理
+							if (res.productPackage != null) {
+								this.payType = res.productPackage.payType;
+								console.log(this.payType)
+								if (this.order.payType == 4) {
+									this.order.payType = 1;
+								}
+							}
+							this.editPayType(this.order.payType)
+
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+
+			},
+			editPayType(payType) {
+				var data = {
+					orderId: this.orderId,
+					payType: payType
+				};
+				this.payParams = data
+				var that = this;
+				uni.showLoading();
+
+				editPayType(data).then(
+					res => {
+						if (res.code == 200) {
+							console.log(res);
+							uni.hideLoading();
+							that.order = res.order;
+							//this.payType=this.order.payType
+							this.payMoney = this.order.payMoney;
+							this.payDelivery = this.order.payDelivery;
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+
+			},
+			otherPayOrder() {
+				uni.navigateTo({
+					url: '/pages_user/user/otherPaymentOrder?orderId=' + this.orderId
+				})
+			},
+			// 防抖后的支付方法
+			// 修复后的支付方法
+			payOrder() {
+				// 1. 安全地获取用户信息
+				this.getSafeUserInfo();
+				// 2. 检查 maOpenId,但不要直接修改字符串
+				// 3. 检查用户信息是否有效
+				if (!this.userinfo || Object.keys(this.userinfo).length === 0) {
+					// uni.showToast({
+					// 	title: '用户信息异常,请重新登录',
+					// 	icon: 'none'
+					// });
+
+					// 直接跳转到登录页
+					this.redirectToLogin();
+					return;
+				}
+
+				// 4. 检查 maOpenId,如果不存在则提示重新登录
+				if (!this.userinfo.maOpenId) {
+					// uni.showModal({
+					// 	title: '提示',
+					// 	content: '用户信息不完整,需要重新登录',
+					// 	success: (res) => {
+					// 		if (res.confirm) {
+					// 			this.redirectToLogin();
+					// 		}
+					// 	}
+					// });
+					this.redirectToLogin();
+					return;
+				}
+
+				// 5. 检查登录状态
+				// this.utils.isLogin().then(res => {
+					if (this.$isLogin()) {
+						// 创建防抖函数实例
+						const debouncedPay = this.debounce(function() {
+							this.executePay();
+						}, 1000); // 1秒防抖时间
+
+						// 执行防抖函数
+						debouncedPay();
+					} else {
+						// 未登录,直接跳转到登录页
+						this.redirectToLogin();
+					}
+				// }).catch(err => {
+				// 	console.error('检查登录状态失败:', err);
+				// 	uni.showToast({
+				// 		title: '登录状态异常',
+				// 		icon: 'none'
+				// 	});
+				// 	// 登录状态异常,也跳转到登录页
+				// 	this.redirectToLogin();
+				// });
+			},
+
+			// 实际的支付执行逻辑
+			executePay() {
+				var data = {
+					orderId: this.order.id,
+					payType: this.order.payType,
+					appId: wx.getAccountInfoSync().miniProgram.appId
+				};
+				console.log('当前小程序信息id',data)
+				var that = this;
+
+				// 防止重复点击,可以添加加载状态
+				if (this.isPaying) return;
+				this.isPaying = true;
+
+				uni.showLoading();
+				pay(data).then(
+					res => {
+						this.isPaying = false;
+						if (res.code == 501) {
+							return uni.navigateBack()
+						}
+						if (res.code == 200) {
+							console.log(res);
+							if (res.payType == 1 || res.payType == 2 || res.payType == 3) {
+								uni.requestPayment({
+									provider: 'wxpay',
+									timeStamp: res.result.timeStamp,
+									nonceStr: res.result.nonceStr,
+									package: res.result.packageValue,
+									signType: res.result.signType,
+									paySign: res.result.paySign,
+									success: function(res) {
+										console.log('yess:' + JSON.stringify(res));
+										uni.hideLoading();
+										uni.redirectTo({
+											url: "success?order=" + JSON.stringify(that.order)
+										})
+									},
+									fail: function(err) {
+										uni.showToast({
+											icon: 'none',
+											title: '支付失败',
+										});
+										console.log('fail:' + JSON.stringify(err));
+										uni.hideLoading();
+									},
+									complete: (err) => {
+										console.log('fail:' + JSON.stringify(err));
+									}
+								});
+							}
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {
+						this.isPaying = false;
+						uni.hideLoading();
+						uni.showToast({
+							icon: 'none',
+							title: '网络请求失败',
+						});
+					}
+				);
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		height: 100%;
+	}
+
+	.content {
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+
+		.inner {
+			padding: 20upx;
+
+			.time-price {
+				box-sizing: border-box;
+				padding: 50upx 0upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+
+				.time {
+					font-size: 32upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #222222;
+					line-height: 1;
+					text-align: center;
+				}
+
+				.desc {
+					margin: 30upx 0upx 15upx;
+					font-size: 26upx;
+					font-family: PingFang SC;
+					color: #999999;
+					line-height: 1;
+					text-align: center;
+				}
+
+				.price-box {
+					display: flex;
+					align-items: flex-end;
+					margin-top: 28upx;
+
+					.unit {
+						font-size: 32upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1.3;
+						margin-right: 10upx;
+					}
+
+					.num {
+						font-size: 56upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1;
+					}
+				}
+			}
+
+			.pay-type {
+				box-sizing: border-box;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				margin-top: 20upx;
+				padding: 40upx 30upx;
+				display: flex;
+				flex-direction: column;
+				justify-content: space-between;
+
+				.title {
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 1;
+					margin-bottom: 10upx;
+				}
+
+				.item {
+					padding: 15upx 0upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+
+					.left {
+						display: flex;
+						align-items: center;
+
+						image {
+							width: 44upx;
+							height: 44upx;
+							margin-right: 20upx;
+						}
+
+						.text {
+							font-size: 30upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #222222;
+							line-height: 1;
+						}
+					}
+				}
+			}
+
+			.order-info {
+				margin-top: 20upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 40upx 30upx;
+
+				.title {
+					font-size: 30upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #222222;
+					line-height: 1;
+				}
+
+				.item {
+					margin-top: 40upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+
+					.label {
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 1;
+					}
+
+					.text {
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						line-height: 32upx;
+					}
+
+					.cont-text {
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+
+						.bold {
+							color: #111111;
+						}
+					}
+
+					.sn-box {
+						display: flex;
+						align-items: center;
+
+						.copy-btn {
+							width: 58upx;
+							height: 32upx;
+							line-height: 32upx;
+							text-align: center;
+							font-size: 22upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #222222;
+							background: #F5F5F5;
+							border-radius: 4upx;
+							margin-left: 24upx;
+						}
+					}
+
+				}
+
+				.line {
+					width: 100%;
+					height: 1px;
+					background: #F0F0F0;
+					margin-top: 30upx;
+				}
+			}
+		}
+
+		.btn-box {
+			height: 242upx;
+			background: #FFFFFF;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			flex-direction: column;
+
+			.btn {
+				width: 91.73%;
+				height: 88upx;
+				line-height: 88upx;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				text-align: center;
+				background: #FF233C;
+				border-radius: 44upx;
+				margin-bottom: 10rpx;
+			}
+
+			.other-btn {
+				width: 91.73%;
+				height: 88upx;
+				line-height: 88upx;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FF233C;
+				border: 1rpx solid #FF233C;
+				text-align: center;
+				background: #FFFFFF;
+				border-radius: 44upx;
+				margin-bottom: 10rpx;
+				position: relative;
+
+				.share {
+					display: inline-block;
+					position: absolute;
+					top: 0;
+					left: 0;
+					width: 100%;
+					height: 100%;
+					opacity: 0;
+				}
+			}
+		}
+	}
+</style>

+ 830 - 0
pages/shopping/prescribe.vue

@@ -0,0 +1,830 @@
+<template>
+	<view class="content">
+		<view class="fixed-top-box">
+			<view class="status_bar" :style="{height: statusBarHeight}"></view>
+			<view class="back-box" @click="back">
+				<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/back_white.png" mode=""></image>
+				<text class="title">填写处方信息</text>
+				<text></text>
+			</view>
+		</view>
+		<view class="inner">
+			<view :style="{height: statusBarHeight}"></view>
+			<!-- 步骤 -->
+			<view class="steps-box">
+				<view class="item active">填写信息</view>
+				<image class="arrow" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow4.png" mode=""></image>
+				<view class="item">医生开方</view>
+				<image class="arrow" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow4.png" mode=""></image>
+				<view class="item">支付订单</view>
+				<image class="arrow" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow4.png" mode=""></image>
+				<view class="item">厂家发货</view>
+			</view>
+			<!-- 提示 -->
+			<!-- <view class="tip-box">
+				<view class="top">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/safe2.png" mode=""></image>
+					<text class="text">依据国家规定、处方药需凭处方购买</text>
+				</view>
+				<view class="time-tip">填写问诊人信息、处方信息</view>
+			</view> -->
+			<view class="info-box">
+				<!-- 选择问诊人 -->
+				<view class="chose-people">
+					<view class="title-box">
+						<text class="title">选择问诊人</text>
+						<view class="add-box" @click="addPeople()">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/add26.png" mode=""></image>
+							<text >添加</text>
+						</view>
+					</view>
+					<view class="peop-list" v-if="patient.length>0">
+						<view v-for="(item,index) in patient" :key="index" :class="patientId == item.patientId?'item active':'item'" @click="chosePatient(item)">
+							<view class="name">{{ item.patientName }}</view>
+							<view class="info">
+								<text class="sex" v-if="item.gender==1">男</text>
+								<text class="sex" v-if="item.gender==2">女</text>
+								<text class="ege">{{utils.getAge(item.birthday)}}岁</text>
+							</view>
+							<!-- 选中的对号角标 -->
+							<image v-if="patientId == item.patientId" class="active-img" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/sel_right50.png" mode=""></image>
+						</view>
+					</view>
+				</view>
+				<view class="text-content">
+					<view class="title">
+						<text class="black">主诉</text>
+						<text class="gray">(选填)</text>
+					</view>
+					<textarea class="textArea" maxlength="200" @input="chiefComplaintInput" placeholder="请填写主诉内容"></textarea>
+				</view>
+				<view class="text-content">
+					<view class="title">
+						<text class="black">既往病史</text>
+						<text class="gray">(选填)</text>
+					</view>
+					<textarea class="textArea" maxlength="200" @input="historyIllnessInput" placeholder="请填写既往病史内容"></textarea>
+				</view>
+				<view class="img-content">
+					<view class="title">
+						<text class="black">复诊凭证</text>
+						<text class="gray">(选填) {{imgList.length}}/4</text>
+					</view>
+					<view class="upload-img">
+						<view class="img" v-for="(item,index) in imgList" :key="index"  >
+							<image :src="item" mode="aspectFill"  @click="previewImage(index)"></image>
+							<view class="del" @click="delImg(index)" >
+								<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/del2.png"></image>
+							</view>
+						</view>
+						<view class="chose-img" @tap="chooseImage(1)" v-if="imgList.length<4">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/adds.png"></image>
+						</view>
+					</view>
+					
+					 
+				</view>
+				<!-- 疾病选择 -->
+				<!-- <view class="disease-select">
+					<view class="title">
+						<text class="black">本次用药的确诊疾病</text>
+						<text class="gray">(可多选)</text>
+					</view>
+					<view class="dise-list">
+						<view 
+							v-for="(item,index) in diseaseList" 
+							:key="index" 
+							:class="activeDise == index?'item active':'item'"
+							@click="choseDise(index)"
+						>
+							{{ item }}
+						</view>
+					</view>
+				</view> -->
+				<!-- 是否使用过此药 -->
+				<view class="check-box">
+					<view class="left">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/yao.png" mode=""></image>
+						<text class="text">是否有过敏史</text>
+					</view>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio value="1" :checked="isAllergic==true" style="margin-right: 16upx;" />
+							<text class="my-radio-text">是</text>
+						</label>
+						<label>
+							<radio value="0" :checked="isAllergic==false" style="margin-right: 16upx;" />
+							<text class="my-radio-text">否</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="check-box">
+					<view class="left">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/yao.png" mode=""></image>
+						<text class="text">肝功能是否异常</text>
+					</view>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio value="1" :checked="isLiver==true" style="margin-right: 16upx;" />
+							<text class="my-radio-text">是</text>
+						</label>
+						<label>
+							<radio value="0" :checked="isLiver==false" style="margin-right: 16upx;" />
+							<text class="my-radio-text">否</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="check-box">
+					<view class="left">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/yao.png" mode=""></image>
+						<text class="text">肾功能是否异常</text>
+					</view>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio value="1" :checked="isRenal==true" style="margin-right: 16upx;" />
+							<text class="my-radio-text">是</text>
+						</label>
+						<label>
+							<radio value="0" :checked="isRenal==false" style="margin-right: 16upx;" />
+							<text class="my-radio-text">否</text>
+						</label>
+					</radio-group>
+				</view>
+				<view class="check-box">
+					<view class="left">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/yao.png" mode=""></image>
+						<text class="text">是否是备孕/怀孕/哺乳期</text>
+					</view>
+					<radio-group style="display: flex;align-items: center;">
+						<label style="margin-right: 50upx;">
+							<radio value="1" :checked="isLactation==true" style="margin-right: 16upx;" />
+							<text class="my-radio-text">是</text>
+						</label>
+						<label>
+							<radio value="0" :checked="isLactation==false" style="margin-right: 16upx;" />
+							<text class="my-radio-text">否</text>
+						</label>
+					</radio-group>
+				</view>
+			</view>
+		</view>
+		<view class="btn-box">
+			<view class="btn" @click="submit()">去开处方</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getStoreOrderById} from '@/api/storeOrder'
+	import {getWeixinPrescribeTemps} from '@/api/common'
+	import {doPrescribe} from '@/api/prescribe'
+	import {getPatientList,delPatient} from '@/api/patient'
+	export default {
+		data() {
+			return {
+				statusBarHeight: uni.getStorageSync('menuInfo').statusBarHeight,
+				order:null,
+				temps:[],
+				imgList: [],  
+				orderId:null,
+				patient:[],
+				patientId:null,
+				pickPatient:null,
+				// 疾病列表
+				// diseaseList: ['消化不良','心血管','呼吸系统','感染病','皮肤病','口腔','妇科','耳鼻喉'],
+				// 选中的疾病
+				// activeDise: 0,
+				isAllergic: false,
+				isLiver: false,
+				isRenal: false,
+				isLactation: false,
+				chiefComplaint:null,
+				historyIllness:null
+			}
+		},
+		onLoad(option) {
+			this.orderId=option.orderId
+			this.getPatientList();
+			uni.$on('refreshPatient', () => {
+				this.getPatientList()
+			})
+			this.getWeixinPrescribeTemps();
+			this.getStoreOrderById();
+		},
+		onShow() {
+			this.getPatientList();
+		},
+		//发送给朋友
+		onShareAppMessage(res) {
+			if(this.utils.isLogin()){
+				var user=JSON.parse(uni.getStorageSync('userInfo'))
+				return {
+					title: "填写处方信息",
+					path: "/pages/shopping/prescribe?orderId="+this.orderId,
+					imageUrl: this.$store.state.imgpath+'/app/image/logo.jpg' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
+				}
+			}
+		},
+		methods: {
+			back(){
+			  // uni.showToast({
+			  // 	icon:'none',
+			  // 	title: "请填写资料提交处方,否则将无法发货"
+			  // });
+			  uni.navigateBack();
+			},
+			getStoreOrderById:function(){
+				var data={orderId:this.orderId}
+				getStoreOrderById(data).then(
+					res => {
+						if(res.code==200){
+							this.order=res.order
+						}else{
+							 
+						}
+					},
+					rej => {}
+				);
+			},
+			getWeixinPrescribeTemps:function(){
+				getWeixinPrescribeTemps().then(
+					res => {
+						if(res.code==200){
+							this.temps=res.temp
+							console.log(this.temps)
+						}else{
+							 
+						}
+					},
+					rej => {}
+				);
+			},
+			chiefComplaintInput(e) {
+				this.chiefComplaint = e.detail.value
+			},
+			historyIllnessInput(e) {
+				this.historyIllness = e.detail.value
+			},
+			// 选择图片
+			chooseImage(type) {
+				var that=this;
+				uni.chooseImage({
+					count: 4, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album', 'camera'], //从相册选择
+					success: (res) => {
+						uni.uploadFile({
+							url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', //仅为示例,非真实的接口地址
+							filePath: res.tempFilePaths[0],
+							name: 'file',
+							success: (res) => {
+								that.imgList.push(JSON.parse( res.data).url)
+							}
+						});
+					}
+				});
+			},
+			//图片预览
+			previewImage(index){
+				//预览图片
+				uni.previewImage({
+					urls: this.imgList,
+					current: this.imgList[index]
+				});
+			},
+			delImg(index) {
+				uni.showModal({
+					title: '提示',
+					content: '确定要删除这张图片吗?',
+					cancelText: '取消',
+					confirmText: '确定',
+					success: res => {
+						if (res.confirm) {
+							this.imgList.splice(index, 1);
+						}
+					}
+				})
+			},
+			submit(){
+				var that=this;
+				if(this.patientId==null){
+					uni.showToast({
+						icon:'none',
+						title: "请选择患者"
+					});
+					return;
+				}
+				if(this.pickPatient.isAuth==0){
+					uni.showToast({
+						icon:'none',
+						title: "该问诊人未实名认证"
+					});
+					return;
+				}
+				 
+				uni.showLoading({
+					title:"正在处理中"
+				})
+				var data={
+					patientId:this.patientId,
+					orderId:this.orderId,
+					isAllergic:this.isAllergic,
+					isLiver:this.isLiver,
+					isRenal:this.isRenal,
+					isLactation:this.isLactation,
+					chiefComplaint:this.chiefComplaint,
+					historyIllness:this.historyIllness,
+					recordPic:this.imgList.toString()
+				}
+				 doPrescribe(data).then(
+				 	res => {
+				 		if(res.code==200){
+							 uni.hideLoading()
+				 			 uni.showToast({
+				 			 	icon:'success',
+				 			 	title:res.msg,
+				 			 });
+							 var order =res.order;
+							 uni.requestSubscribeMessage({
+							 	tmplIds: this.temps,
+							 	success(res) {
+									setTimeout(function(){
+										if(order.paid!=1){
+											uni.redirectTo({
+												url: './paymentOrder?orderId='+that.order.id
+											})
+										}
+										else{
+											uni.navigateBack({  
+												delta: 1
+											});
+											
+										}
+										
+									},500);
+							 	},
+							 	fail(res) {
+							 		setTimeout(function(){
+										if(order.paid!=1){
+											uni.redirectTo({
+												url: './paymentOrder?orderId='+that.order.id
+											})
+										}
+										else{
+											uni.navigateBack({  
+												delta: 1
+											});
+											
+										}
+							 			 
+							 		},500);
+							 	}
+							 })
+							 
+				 			
+				 		}else{
+				 			uni.showToast({
+								icon:'none',
+				 				title: res.msg,
+				 			});
+				 		}
+				 	},
+				 	rej => {}
+				 );
+				
+			},
+			getPatientList(){
+			 	uni.showLoading({
+			 		title:"正在加载中"
+			 	})
+			 	getPatientList().then(
+			 		res => {
+			 			uni.hideLoading()
+			 			if(res.code==200){
+			 				this.patient=res.data;
+			 			}else{
+			 				uni.showToast({
+			 					icon:'none',
+			 					title: "请求失败",
+			 				});
+			 			}
+			 		},
+			 		rej => {}
+			 	);
+			},
+			// 选中问诊人
+			chosePatient(item) {
+				this.patientId = item.patientId;
+				this.pickPatient=item;
+			},
+			// 添加问诊人
+			addPeople() {
+				uni.navigateTo({
+					url:"/pages_user/user/patient"
+				})
+			},
+			// 疾病选择
+			choseDise(index) {
+				this.activeDise = index
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		.fixed-top-box{
+			width: 100%;
+			background: linear-gradient(135deg, #66b2ef 0%, #FF233C 100%);
+			position: fixed;
+			top: 0;
+			left: 0;
+			z-index: 1000;
+			.back-box{
+				height: 88upx;
+				padding-left: 22upx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 0 20upx;
+				image{
+					width: 40upx;
+					height: 40upx;
+				}
+				.title{
+					font-size: 36upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FFFFFF;
+				}
+			}
+		}
+		.inner{
+			margin-top: 88rpx;
+			.steps-box{
+				height: 88upx;
+				background: #FFFFFF;
+				padding: 0 48upx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				.item{
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+					&.active{
+						font-weight: bold;
+						color: #FF233C;
+					}
+				}
+				.arrow{
+					width: 12upx;
+					height: 22upx;
+				}
+			}
+			.tip-box{
+				box-sizing: border-box;
+				height: 130upx;
+				background: #FFF4E6;
+				padding: 26upx 0 30upx 50upx;
+				display: flex;
+				flex-direction: column;
+				justify-content: space-between;
+				.top{
+					display: flex;
+					align-items: center;
+					image{
+						width: 26upx;
+						height: 31upx;
+						margin-right: 10upx;
+					}
+					.text{
+						font-size: 28upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #EF8A07;
+						line-height: 1;
+					}
+				}
+				.time-tip{
+					padding-left: 40upx;
+					font-size: 24upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+					line-height: 1;
+				}
+			}
+			.info-box{
+				padding: 20upx;
+				.chose-people{
+					box-sizing: border-box;
+					background: #FFFFFF;
+					border-radius: 16upx;
+					padding: 40upx 30upx 30upx;
+					.title-box{
+						display: flex;
+						align-items: center;
+						justify-content: space-between;
+						.title{
+							font-size: 32upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #111111;
+						}
+						.add-box{
+							display: flex;
+							align-items: center;
+							image{
+								width: 26upx;
+								height: 26upx;
+								margin-right: 11upx;
+							}
+							text{
+								font-size: 28upx;
+								font-family: PingFang SC;
+								font-weight: 500;
+								color: #111111;
+							}
+						}
+					}
+					.peop-list{
+						display: flex;
+						flex-wrap: wrap;
+						margin-top: 30upx;
+						.item{
+							box-sizing: border-box;
+							padding: 18upx 30upx;
+							width: 31.28%;
+							height: 110upx;
+							background: #F7F7F7;
+							border-radius: 16upx;
+							margin: 0 20upx 10upx 0;
+							border: 2upx solid #F7F7F7;
+							display: flex;
+							flex-direction: column;
+							justify-content: space-between;
+							&:nth-child(3n){
+								margin-right: 0;
+							}
+							&.active{
+								background: rgba(230, 250, 247, 0);
+								border: 2upx solid #FF233C;
+								position: relative;
+							}
+							.active-img{
+								width: 50upx;
+								height: 50upx;
+								position: absolute;
+								right: -2upx;
+								bottom: -2upx;
+							}
+							.name{
+								font-size: 30upx;
+								line-height: 1;
+								font-family: PingFang SC;
+								font-weight: bold;
+								color: #111111;
+							}
+							.info{
+								display: flex;
+								align-items: center;
+								.sex,
+								.ege{
+									font-size: 26upx;
+									font-family: PingFang SC;
+									line-height: 1;
+									font-weight: 500;
+									color: #666666;
+								}
+								.ege{
+									margin-left: 19upx;
+								}
+							}
+						}
+					}
+				}
+				.disease-select{
+					box-sizing: border-box;
+					min-height: 286upx;
+					background: #FFFFFF;
+					border-radius: 16upx;
+					padding: 40upx 30upx 22upx;
+					margin-top: 20upx;
+					.title{
+						display: flex;
+						align-items: center;
+						align-items: flex-end;
+						.black{
+							font-size: 32upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #111111;
+							line-height: 1;
+							margin-left: 10upx;
+						}
+						.gray{
+							font-size: 28upx;
+							font-family: PingFang SC;
+							color: #999999;
+							line-height: 1;
+							margin-left: 10upx;
+						}
+					}
+					.dise-list{
+						display: flex;
+						flex-wrap: wrap;
+						margin-top: 26upx;
+						.item{
+							box-sizing: border-box;
+							height: 64upx;
+							line-height: 64upx;
+							font-size: 28upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #FF233C;
+							background: #F5FFFE;
+							border: 1px solid #8AD5CE;
+							padding: 0 20upx;
+							border-radius: 32upx;
+							margin: 0 20upx 20upx 0;
+							&.active{
+								background: #FF233C;
+								border: 1px solid #FF233C;
+								color: #FFFFFF;
+							}
+						}
+					}
+				}
+				.text-content{
+					box-sizing: border-box;
+					min-height: 286upx;
+					background: #FFFFFF;
+					border-radius: 16upx;
+					padding: 40upx 30upx 22upx;
+					margin-top: 20upx;
+					.title{
+						display: flex;
+						align-items: center;
+						align-items: flex-end;
+						.black{
+							font-size: 32upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #111111;
+							line-height: 1;
+							margin-left: 10upx;
+						}
+						.gray{
+							font-size: 28upx;
+							font-family: PingFang SC;
+							color: #999999;
+							line-height: 1;
+							margin-left: 10upx;
+						}
+					}
+					.textArea{
+						margin: 30rpx 0rpx 0rpx 0rpx;
+						width: 100%;
+					}
+					 
+					
+					 
+				}
+				.img-content{
+					box-sizing: border-box;
+					min-height: 286upx;
+					background: #FFFFFF;
+					border-radius: 16upx;
+					padding: 40upx 30upx 22upx;
+					margin-top: 20upx;
+					margin-bottom: 20upx;
+					.title{
+						display: flex;
+						align-items: center;
+						align-items: flex-end;
+						.black{
+							font-size: 32upx;
+							font-family: PingFang SC;
+							font-weight: bold;
+							color: #111111;
+							line-height: 1;
+							margin-left: 10upx;
+						}
+						.gray{
+							font-size: 28upx;
+							font-family: PingFang SC;
+							color: #999999;
+							line-height: 1;
+							margin-left: 10upx;
+						}
+					}
+					.textArea{
+						margin: 30rpx 0rpx 0rpx 0rpx;
+						width: 100%;
+					}
+					.upload-img{
+						margin: 30rpx 0rpx 0rpx 0rpx;
+						width: 100%;
+						display: flex;
+						align-items: flex-start;
+						.img{
+							margin-right: 10rpx;
+							width: 100rpx;
+							height: 100rpx;
+							position: relative;
+							image{
+								width: 100%;
+								height: 100%;
+							}
+							.del{
+								right:0rpx;
+								top:0rpx;
+								position: absolute;
+								image{
+									width: 30rpx;
+									height:30rpx;
+								}
+							}
+						}
+						.chose-img{
+							border-radius: 5rpx;
+							border: 1px solid #eee;
+							padding: 5rpx;
+							display: flex;
+							align-items: center;
+							justify-content: center;
+							width: 100rpx;
+							height: 100rpx;
+							image{
+								width: 50rpx;
+								height: 50rpx;
+							}
+							
+						}
+					}
+					
+					 
+				}
+
+				.check-box{
+					height: 88upx;
+					background: #FFFFFF;
+					border-radius: 16upx;
+					padding: 0 30upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					.left{
+						display: flex;
+						align-items: center;
+						image{
+							width: 21upx;
+							height: 27upx;
+							margin-right: 20upx;
+						}
+						.text{
+							font-size: 32upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #666666;
+						}
+					}
+					.my-radio-text{
+						font-size: 30upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #111111;
+						line-height: 30upx;
+					}
+				}
+			}
+		}
+		.btn-box{
+			height: 120upx;
+			padding: 30upx;
+			// background: #FFFFFF;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			.btn{
+				width: 100%;
+				height: 88upx;
+				line-height: 88upx;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				text-align: center;
+				background: #FF233C;
+				border-radius: 44upx;
+			}
+		}
+	}
+	
+</style>

+ 1389 - 0
pages/shopping/productDetails.vue

@@ -0,0 +1,1389 @@
+<template>
+	<view class="content">
+		<!-- 商品轮播图片 -->
+		<view class="shop-banner" @click="showImg()">
+			<swiper class="swiper" :indicator-dots="false" :circular="true" :autoplay="true" :interval="3000"
+				:duration="1000" indicator-color="rgba(255, 255, 255, 0.6)" indicator-active-color="#ffffff"
+				@change="swiperChange">
+				<swiper-item class="swiper-item" v-for="(item,index) in  banner" :key="index">
+					<image :src="item" mode="aspectFill"></image>
+					<!-- <view class="cf-box" v-if="product.productType==2">
+						<view class="title">处方药</view>
+						<view class="subTitle">请在医师指导下使用</view>
+					</view> -->
+				</swiper-item>
+			</swiper>
+			<!-- 底部遮罩 -->
+			<view class="banner-mask"></view>
+			<!-- 数量 -->
+			<view class="num-box">{{ activeBanner }}/{{ banner.length }}</view>
+		</view>
+		<!-- 详细信息 -->
+		<view class="det-info">
+			<view class="price-box">
+				<view class="price">
+					<text class="label" v-if="userinfo.isShow==1&&isuser==false">会员价</text>
+					<text class="label" v-else>零售价</text>
+					<text class="unit">¥</text>
+					<text class="num" v-if="userinfo.isShow==1&&isuser==false">{{product.price}}</text>
+					<text class="num" v-else>{{product.otPrice}}</text>
+					<text class="label" v-if="userinfo.isShow==1&&isuser==false">零售价</text>
+					<text class="old" v-if="userinfo.isShow==1&&isuser==false">¥{{product.otPrice}}</text>
+				</view>
+				<!-- <view class="share-box" v-if="userinfo.isShow==1&&isuser==false">
+					<text class="text">分享</text>
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/share1.png" mode="">
+					</image>
+					<button class="share" data-name="shareBtn" open-type="share">分享</button>
+				</view> -->
+			</view>
+			<view class="name-box">
+				<!-- <view class="tag">{{utils.getDictLabelName("storeProductType",product.productType)}}</view> -->
+				{{product.productName}}
+			</view>
+			<view class="intro" v-if="product.productInfo!=null" v-html="product.productInfo.replace(/\n/g,'<br>')">
+			</view>
+			<!-- <view class="safe-box">
+				<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/safe.png" mode=""></image>
+				<text class="text" v-if="userinfo.isShow==1&&isuser==false">免邮发货</text>
+				<view class="line" v-if="userinfo.isShow==1&&isuser==false"></view>
+				<view class="line"></view>
+				<text class="text">药师服务</text>
+				<view class="line"></view>
+				<text class="text">隐私保护</text>
+			</view> -->
+		</view>
+		<!-- 购买人数、库存 -->
+		<view class="inventor" v-if="userinfo.isShow==1&&isuser==false">
+			<view class="left">
+				<!-- <view class="head-box">
+					<view class="head" v-for="(item,j) in 5" :key="j">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/head.jpg" mode=""></image>
+					</view>
+				</view> -->
+				<view class="num-box">
+					已有 <text class="text">{{product.sales}}</text> 人购买
+					<view v-if=" purchaseLimit > 0" class="limit-text">
+						 限购{{purchaseLimit}}件<text v-if="remainingPurchaseLimit !== null && remainingPurchaseLimit >= 0">,已购{{purchaseLimit - remainingPurchaseLimit}}件</text>
+					</view> 
+				</view>
+			</view>
+			<!-- <view class="right">
+				库存 <text class="text">{{product.stock}}{{product.unitName}}</text>
+			</view> -->
+			<!-- <view class="right">
+				 <text class="text">库存{{product.stock>0?'充足':'售罄'}} </text>
+			</view> -->
+		</view>
+		<!-- 功效 -->
+		<!-- <view class="effect">
+			<view class="label">产品说明书</view>
+			<view class="label">查看</view>
+			
+		</view> -->
+		<!-- 图文详情 -->
+		<view class="det-box">
+			<view class="title">图文详情</view>
+			<view class="inner">
+				<view v-html="product.description" style="font-size:0"></view>
+			</view>
+		</view>
+		<!-- 底部按钮 -->
+		<!-- userinfo.isShow==1&& -->
+		<view class="btn-foot" v-if="isuser==false">
+			<view class="menu-box">
+			<!-- 	<view class="item" @click="goHome">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/back_home.png"
+						mode=""></image>
+					<text class="label">首页</text>
+				</view>
+				<view class="item" style="position: relative;">
+					<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/consult_small.png"
+						mode=""></image>
+					<text class="label">咨询</text>
+					<button class="contact-btn" open-type="contact"></button>
+				</view>
+				<view class="item" @click="toCart('./cart')">
+					<uni-badge size="small" :text="cartCount" absolute="rightTop" type="error">
+						<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/cart36.png"
+							mode=""></image>
+					</uni-badge>
+					<text class="label">购物车</text>
+				</view> -->
+			</view>
+			<view class="btn-box">
+				<view class="btn cart" @click="addCart('cart')">加入购物车</view>
+				<view class="btn buy" @click="addCart('buy')">{{buyText}}</view>
+			</view>
+		</view>
+		<!-- 选择产品规格弹窗 -->
+		<popupBottom ref="popup" :visible.sync="specVisible" title=" " radius="32" maxHeight="1024">
+			<view class="product-spec">
+				<!-- 商品信息 -->
+				<view class="pro-info">
+					<view class="img-box" @click="showImg(productValueSelect.image)">
+						<image
+							:src="productValueSelect.image==null||productValueSelect.image==''?product.image:productValueSelect.image"
+							mode="aspectFill"></image>
+					</view>
+					<view class="info-text">
+						<view class="price">
+							<text class="unit">¥</text>
+							<text class="num">{{ productValueSelect.price.toFixed(2) }}</text>
+						</view>
+						<view class="desc-box">
+							<text class="text">已选:{{ productValueSelect.sku }}</text>
+							<text class="text">库存:{{ productValueSelect.stock }}</text>
+						</view>
+					</view>
+				</view>
+
+				<!-- 门店 -->
+				<!-- 		<view class="spec-box form-item" v-if="stores.length>0">
+					<text class="label">所属门店</text> 
+					<picker  class="birth-picker"  mode="selector" :value="storeIdx" :range="storeNames" @change="pickerChange"  @columnchange="pickerColumnchange">
+						<view class="right-box">
+							<view class="input-box">
+								<input type="text" v-model="storeName" placeholder="请选择门店" class="form-input" disabled="disabled" />
+							</view>
+							<image class="arrow" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/arrow_gray.png" mode=""></image>
+						</view>
+					</picker>
+				</view> -->
+
+				<!-- 规格 -->
+				<view class="spec-box">
+					<view v-for="(item,index) in attrs" :key="index">
+						<view class="title">{{item.attrName}}</view>
+						<view class="spec-list">
+							<view v-for="(subItem,subindex) in item.values" :key="subindex"
+								:class="subindex==item.index?'item active':'item'" @click="choseSpec(index,subindex)">
+								{{ subItem }}
+							</view>
+						</view>
+					</view>
+				</view>
+				<!-- 数量 -->
+				<view class="price-num">
+					<view class="label">数量</view>
+					<view class="num-box">
+						<view class="img-box" @click="lessNum()">
+							<image v-if="specNum <= 1"
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/jian.png"
+								mode=""></image>
+							<image v-else
+								src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/jian2.png"
+								mode=""></image>
+						</view>
+						<input type="number" @change="changeNum" v-model="specNum" />
+						<view class="img-box" @click="addNum()">
+							<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/add.png"
+								mode=""></image>
+						</view>
+					</view>
+				</view>
+				<view class="sub-btn" @click="submit">确定</view>
+			</view>
+		</popupBottom>
+
+		<view class="loadding" v-if="loadding==true">
+			<image src="../../static/logo.png"></image>
+			<text class="text">加载中...</text>
+		</view>
+    <CustomToast ref="customToast">
+    </CustomToast>
+		<!-- <u-modal :show="showModal" title="温馨提示" content="处方药须凭处方在药师指导下购买和使用" @confirm="hideModal()"></u-modal> -->
+	</view>
+</template>
+
+<script>
+import {CustomToast} from '@/components/custom-toast.vue';
+
+	import {
+		getDicts
+	} from '@/api/index'
+	import {
+		getUserInfo
+	} from '@/api/user'
+	import {
+		getProductDetails,
+		getCartCount,
+		addCart
+	} from '@/api/product'
+	import popupBottom from '@/components/px-popup-bottom/px-popup-bottom.vue'
+	export default {
+		components: {
+			item: {},
+			popupBottom,
+      CustomToast
+		},
+		data() {
+			return {
+				loadding: true,
+				buyText: "立即购买",
+				// mTitle:"温馨提示",
+				// mContent:"处方药须凭处方在药师指导下购买和使用",
+				type: null,
+				productValueSelect: {
+					price: 0,
+					serviceFee: 0
+				},
+				banner: [],
+				productId: null,
+				attrs: [],
+				values: [],
+				stores: [],
+				storeId: null,
+				storeNames: [],
+				storeIdx: 0,
+				storeName: "",
+				product: {
+					price: 0,
+					otPrice: 0,
+				},
+				showModal: false,
+				// 当前轮播的图片
+				activeBanner: 1,
+				// 购物车数量
+				cartCount: 0,
+				// 规格弹窗
+				specVisible: false,
+				// 规格数量
+				specNum: 1,
+				config: null,
+				showServiceFee: false,
+				selectVal: "",
+				userinfo: [],
+				isuser: false,
+				remainingPurchaseLimit:null,
+				purchaseLimit:0, // 总限购数量
+				courseId:null
+			};
+		},
+		onLoad(options) {
+			console.log("qxj options:" + JSON.stringify(options));
+			uni.setStorageSync('urlInfo', options);
+			if (options.userId != null) {
+				uni.setStorageSync('tuiUserId', options.userId);
+			} else if (options.hasOwnProperty('q') && options.q) {
+				// 通过下面这步解码,可以拿到url的值
+				const url = decodeURIComponent(options.q)
+				this.url = url;
+				// // 对url中携带的参数提取处理
+				const obj = this.utils.urlToObj(url)
+				uni.setStorageSync('tuiUserId', obj.userId);
+			}
+			if(options.courseId){
+				this.courseId=options.courseId
+			}
+			uni.showShareMenu({
+				withShareTicket: true,
+				//小程序的原生菜单中显示分享按钮,才能够让发送给朋友与分享到朋友圈两个按钮可以点击
+				menus: ["shareAppMessage", "shareTimeline"] //不设置默认发送给朋友
+			})
+			this.getDicts();
+			this.productId = options.productId;
+			if (this.utils.checkToken()) {
+				this.getCartCount();
+			}
+		},
+		onShow() {
+			this.getProductDetails();
+			if (uni.getStorageSync('AppToken')) {
+				this.getuser()
+			} else {
+				this.isuser = true
+			}
+		},
+		//发送给朋友
+		onShareAppMessage(res) {
+			if (this.utils.isLogin()) {
+				var user = JSON.parse(uni.getStorageSync('userInfo'))
+				return {
+					title: this.product.productName,
+					path: '/pages/shopping/productDetails?productId=' + this.product.productId + "&userId=" + user.userId,
+					imageUrl: '/static/logo.jpg' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
+				}
+			}
+		},
+		//分享到朋友圈
+		onShareTimeline(res) {
+			if (this.utils.isLogin()) {
+				var user = JSON.parse(uni.getStorageSync('userInfo'))
+				return {
+					title: this.product.productName,
+					query: 'productId=' + this.product.productId + "&userId=" + user.userId, //页面参数
+					imageUrl: '/static/logo.jpg' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
+				}
+			}
+
+		},
+		methods: {
+			getuser() {
+				getUserInfo().then(
+					res => {
+						if (res.code == 200) {
+							if (res.user != null) {
+								this.userinfo = res.user;
+								console.log(this.userinfo)
+								uni.setStorageSync('userInfo', JSON.stringify(res.user));
+							}
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: "请求失败",
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+			getDicts: function() {
+				getDicts().then(
+					res => {
+						if (res.code == 200) {
+							uni.setStorageSync('dicts', JSON.stringify(res));
+						}
+					},
+					rej => {}
+				);
+			},
+			showImg(img) {
+				if (img != null) {
+					var imgs = [];
+					imgs.push(img)
+					//预览图片
+					uni.previewImage({
+						urls: imgs,
+						current: imgs[0]
+					});
+				} else {
+					//预览图片
+					uni.previewImage({
+						urls: this.banner,
+						current: this.banner[0]
+					});
+				}
+			},
+			doAddCart(type) {
+				// 检查限购数量
+				if (this.remainingPurchaseLimit !== null && typeof this.remainingPurchaseLimit === 'number') {
+					// 如果限购数量为0,提示库存不足
+					if (this.remainingPurchaseLimit === 0) {
+            this.$refs.customToast.show({
+              title: `该商品限购:${this.purchaseLimit}件\n已达购买上限`,
+              duration: 2000
+            });
+						// uni.showToast({
+						// 	icon: 'none',
+						// 	title: "该商品限购:" + this.purchaseLimit +",已达到购买上限",
+						// });
+						return;
+					}
+					// 如果购买数量超过限购数量,提示
+					if (this.specNum > this.remainingPurchaseLimit) {
+            this.$refs.customToast.show({
+              title: "购买数量不能超过限购数量:" + this.remainingPurchaseLimit,
+              duration: 2000
+            });
+						// uni.showToast({
+						// 	icon: 'none',
+						// 	title: "购买数量不能超过限购数量:" + this.remainingPurchaseLimit,
+						// });
+						return;
+					}
+				}
+				if (this.specNum == 0) {
+					uni.showToast({
+						icon: 'none',
+						title: "购买商品数量必须大于0",
+					});
+					return;
+				}
+				var isBuy = type == "buy" ? 1 : 0;
+				let data = {
+					isBuy: isBuy,
+					cartNum: this.specNum,
+					productId: this.productValueSelect.productId,
+					attrValueId: this.productValueSelect.id
+				};
+				addCart(data).then(
+					res => {
+						if (res.code == 200) {
+							if (type == "buy") {
+								uni.navigateTo({
+									url: '/pages/shopping/confirmOrder?type=' + this.type + "&cartIds=" + res
+										.id + "&orderType=" + this.orderType + "&storeId=" + this.storeId +"&courseId="+this.courseId
+								})
+							} else {
+								this.getCartCount()
+								uni.showToast({
+									icon: 'success',
+									title: "添加成功",
+								});
+							}
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+							this.getProductDetails()
+						}
+					},
+					rej => {}
+				);
+			},
+			getProductDetails() {
+				let data = {
+					productId: this.productId
+				};
+				getProductDetails(data).then(
+					res => {
+						this.loadding = false
+						if (res.code == 200) {
+							this.product = res.product;
+							this.remainingPurchaseLimit = res.remainingPurchaseLimit;
+							// 如果接口返回了总限购数量和已购买数量,也保存
+							if (res.product.purchaseLimit !== null) {
+								this.purchaseLimit = res.product.purchaseLimit;
+							}
+							if (this.product.productType == 1) {
+								this.buyText = "立即购买"
+							} else if (this.product.productType == 2) {
+								this.showModal = true;
+								this.buyText = "开方购买"
+							}
+							this.product.otPrice = this.product.otPrice.toFixed(2);
+							this.product.price = this.product.price.toFixed(2);
+							if (this.product.sliderImage != null) {
+								this.banner = this.product.sliderImage.split(',');
+							} else {
+								this.banner = []
+							}
+							this.attrs = res.productAttr;
+							this.attrs.forEach((item, index, arr) => {
+								item.values = item.attrValues.split(',');
+								item.index = 0
+							});
+							this.values = res.productValues;
+							this.choseSpec(0, 0)
+							// this.stores=res.stores;
+							// this.storeNames=this.stores.map(store => store.storeName);
+							// if(this.stores.length>0){
+							// 	this.storeName=this.storeNames[this.storeIdx];
+							// 	this.storeId=this.stores[this.storeIdx].storeId;
+							// }
+
+
+						} else {
+							uni.showToast({
+								icon: 'none',
+								title: res.msg,
+							});
+							setTimeout(function() {
+								uni.reLaunch({
+									url: '/pages/home/index',
+								})
+							}, 2000)
+
+						}
+					},
+					rej => {}
+				);
+			},
+			getCartCount() {
+				let data = {
+					productId: this.productId
+				};
+				getCartCount(data).then(
+					cartRes => {
+						if (cartRes.code == 200) {
+							this.cartCount = cartRes.data;
+						}
+					},
+					rej => {}
+				);
+
+			},
+			// swiper变化事件
+			swiperChange(event) {
+				this.activeBanner = event.detail.current + 1
+			},
+			// 回到首页
+			goHome() {
+				uni.switchTab({
+					url: '/pages/home/index'
+				})
+			},
+			// 跳转页面
+			navgetTo(url) {
+				this.utils.isLogin().then(res => {
+					if (res) {
+						uni.navigateTo({
+							url: url
+						})
+					}
+				})
+			},
+			toCart(url) {
+				this.utils.isLogin().then(res => {
+					if (res) {
+						uni.switchTab({
+							url: url
+						})
+					}
+				})
+			},
+
+			// 加入购物车
+			addCart(type) {
+				if (type == 'buy') {
+					let userInfoStr = uni.getStorageSync('userInfo');
+					if(Object.prototype.toString.call(userInfoStr) == '[object String]'){
+						userInfoStr = JSON.parse(userInfoStr)
+					}
+					if (!userInfoStr || userInfoStr && !userInfoStr.maOpenId) {
+						uni.navigateTo({
+							url: '/pages/auth/login'
+						});
+						return;
+					}
+				}
+				// this.utils.isLogin().then(res => {
+					if (this.$isLogin()) {
+						this.type = type;
+						this.specVisible = true
+					}
+				// })
+			},
+			// 规格选择
+			choseSpec(index, subIndex) {
+				this.attrs[index].index = subIndex;
+				this.$forceUpdate();
+				let productAttr = this.attrs;
+				let values = [];
+				for (let i = 0; i < productAttr.length; i++) {
+					for (let j = 0; j < productAttr[i].values.length; j++) {
+						if (productAttr[i].index === j) { //筛选出默认规格
+							values.push(productAttr[i].values[j]);
+						}
+					}
+				}
+				let selectVal = values.sort().join(","); //返回值:默认
+				this.selectVal = selectVal;
+				// var valueSelect=this.values.filter((item)=>{
+				//      return item.sku==selectVal;
+				// });
+				var valueSelect = this.getValueSelect();
+				console.log("qxj valueSelect:" + valueSelect);
+				if (valueSelect != null && valueSelect.length > 0) {
+					this.productValueSelect = valueSelect[0];
+				}
+				console.log("qxj productValueSelect:" + JSON.stringify(this.productValueSelect));
+				this.updateSpecNum();
+
+			},
+			//更新数量
+			updateSpecNum() {
+				if (this.productValueSelect.stock == 0) {
+					this.specNum = 0;
+				} else {
+					this.specNum = 1;
+				}
+			},
+			changeNum(e) {
+				this.specNum = e.detail.value.replace(/\D/g, '')
+				if (this.specNum < 1) {
+					this.specNum = 1
+				}
+				if (this.specNum >= this.productValueSelect.stock) {
+					this.specNum = this.productValueSelect.stock
+				}
+				// 检查限购数量
+				if (this.remainingPurchaseLimit !== null && typeof this.remainingPurchaseLimit === 'number' && this.specNum > this.remainingPurchaseLimit) {
+					this.specNum = this.remainingPurchaseLimit;
+          this.$refs.customToast.show({
+            title: `该商品限购:${this.remainingPurchaseLimit}件\n已达购买上限`,
+            duration: 2000
+          });
+					// uni.showToast({
+					// 	icon: 'none',
+					// 	title: "该商品限购:" + this.remainingPurchaseLimit + "次,已达购买上限",
+					// });
+				}
+			},
+			// 数量减法
+			lessNum() {
+				this.specNum--
+				if (this.specNum < 1) {
+					this.specNum = 1
+				}
+				if (this.specNum >= this.productValueSelect.stock) {
+					this.specNum = this.productValueSelect.stock
+				}
+				// 检查限购数量
+				if (this.remainingPurchaseLimit !== null && typeof this.remainingPurchaseLimit === 'number' && this.specNum > this.remainingPurchaseLimit) {
+					this.specNum = this.remainingPurchaseLimit;
+          this.$refs.customToast.show({
+            title: `该商品限购:${this.remainingPurchaseLimit}件\n已达购买上限`,
+            duration: 2000
+          });
+					// uni.showToast({
+					// 	icon: 'none',
+					// 	title: "该商品限购:" + this.remainingPurchaseLimit + "次,已达购买上限",
+					// });
+				}
+			},
+			// 数量加法
+			addNum() {
+				this.specNum++
+				if (this.specNum >= this.productValueSelect.stock) {
+					this.specNum = this.productValueSelect.stock
+				}
+				// 检查限购数量
+				if (this.remainingPurchaseLimit !== null && typeof this.remainingPurchaseLimit === 'number' && this.specNum > this.remainingPurchaseLimit) {
+					this.specNum = this.remainingPurchaseLimit;
+                 this.$refs.customToast.show({
+                 title: `该商品限购:${this.remainingPurchaseLimit}件\n已达购买上限`,
+                  duration: 2000
+                  });
+					// uni.showToast({
+					// 	icon: 'none',
+					// 	title: "该商品限购:" + this.remainingPurchaseLimit + "次,已达购买上限",
+					// });
+				}
+			},
+			// 确定选择该规格
+			submit() {
+				this.specVisible = false
+				this.doAddCart(this.type);
+			},
+			hideModal() {
+				this.showModal = false;
+			},
+			getValueSelect() {
+				var valueSelect = this.values.filter((item) => {
+					return item.sku == this.selectVal;
+				});
+				return valueSelect;
+			},
+			pickerChange(e) {
+				console.log("pickerChange index:" + e.detail.value);
+				var valueSelect = this.getValueSelect();
+				this.productValueSelect = valueSelect[0];
+
+			},
+			pickerColumnchange(e) {
+
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.shop-banner {
+		height: 756upx;
+		background-color: #FFFFFF;
+		position: relative;
+
+		.swiper-item {
+			box-sizing: border-box;
+			position: relative;
+		}
+
+		.swiper,
+		.swiper-item,
+		.swiper-item image {
+			width: 100%;
+			height: 100%;
+		}
+
+		.banner-mask {
+			width: 100%;
+			height: 44upx;
+			// background: linear-gradient(0deg, rgba(0, 0, 0, 0.04), rgba(0, 0, 0, 0));
+			// opacity: 0.8;
+			position: absolute;
+			left: 0;
+			bottom: 0;
+			z-index: 9;
+			background-image: url(https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/black_mask.png);
+			background-size: 20upx 44upx;
+			background-repeat: repeat-x;
+		}
+
+		.num-box {
+			width: 80upx;
+			height: 44upx;
+			line-height: 44upx;
+			text-align: center;
+			font-size: 24upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #FFFFFF;
+			background: rgba(0, 0, 0, .3);
+			border-radius: 22upx;
+			position: absolute;
+			right: 30upx;
+			bottom: 30upx;
+			z-index: 10;
+		}
+
+		.cf-box {
+			position: absolute;
+			z-index: 10;
+			left: 0;
+			right: 0;
+			top: calc(50% - 200rpx);
+			bottom: calc(50% - 200rpx);
+			background-color: rgba(0, 0, 0, 0.3);
+			backdrop-filter: blur(2rpx);
+			/* 背景模糊度 */
+			display: flex;
+			flex-direction: column;
+			flex: 1;
+			justify-content: center;
+			align-items: center;
+			color: #EDEEEF;
+
+			.title {
+				font-size: 40rpx;
+				font-weight: bold;
+			}
+
+			.subTitle {
+				font-size: 28rpx;
+				font-weight: bold;
+				margin-top: 10rpx;
+			}
+		}
+
+
+	}
+
+	.det-info {
+		background: #FFFFFF;
+		padding: 36upx 30upx 25upx;
+
+		.price-box {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+
+			.price {
+				display: flex;
+				align-items: flex-end;
+
+				.label {
+					color: #333;
+					font-size: 28upx;
+					font-family: PingFang SC;
+					line-height: 1.3;
+					margin-right: 5upx;
+				}
+
+				.unit {
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FF6633;
+					line-height: 1.3;
+				}
+
+				.num {
+					font-size: 40upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FF6633;
+					margin: 0 20upx 0 10upx;
+					line-height: 1;
+				}
+
+				.old {
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					text-decoration: line-through;
+					color: #BBBBBB;
+					line-height: 1.3;
+				}
+			}
+
+			.share-box {
+				width: 120upx;
+				height: 46upx;
+				border: 1px solid #FF233C;
+				border-radius: 23upx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				position: relative;
+
+				.text {
+					font-size: 26upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FF233C;
+				}
+
+				image {
+					margin-left: 2rpx;
+					width: 25upx;
+					height: 24upx;
+				}
+
+				.share {
+					display: inline-block;
+					position: absolute;
+					top: 0;
+					left: 0;
+					width: 100%;
+					height: 100%;
+					opacity: 0;
+				}
+			}
+
+			.spec {
+				font-size: 24upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 36upx;
+			}
+		}
+
+		.name-box {
+			font-size: 32upx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #111111;
+			line-height: 44upx;
+			margin-top: 32upx;
+
+			.tag {
+				display: inline-block;
+				padding: 0 6upx;
+				height: 30upx;
+				background: linear-gradient(90deg, #66b2ef 0%, #FF233C 100%);
+				border-radius: 4upx;
+				margin-right: 10upx;
+				font-size: 22upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+				line-height: 30upx;
+				float: left;
+				margin-top: 7upx;
+			}
+		}
+
+		.intro {
+			font-size: 26upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #999999;
+			line-height: 36upx;
+			padding: 18upx 0 23upx;
+			border-bottom: 1px solid #f7f7f7;
+		}
+
+		.safe-box {
+			display: flex;
+			align-items: center;
+			padding-top: 24upx;
+
+			image {
+				width: 20upx;
+				height: 24upx;
+				margin-right: 20upx;
+			}
+
+			.text {
+				font-size: 22upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 1;
+			}
+
+			.line {
+				width: 1px;
+				height: 23upx;
+				background: #EDEEEF;
+				margin: 0 20upx;
+			}
+		}
+	}
+
+	.inventor {
+		height: 88upx;
+		padding: 0 39upx 0 30upx;
+		margin-top: 10upx;
+		background: #FFFFFF;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+
+		.left {
+			display: flex;
+			align-items: center;
+
+			.head-box {
+				margin-right: 27upx;
+				display: flex;
+				align-items: center;
+
+				.head {
+					width: 48upx;
+					height: 48upx;
+					border-radius: 50%;
+					overflow: hidden;
+					box-shadow: 0 0 0 1px #fff;
+					margin-right: -10upx;
+
+					image {
+						width: 100%;
+						height: 100%;
+					}
+				}
+			}
+
+			.num-box {
+				font-size: 24upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+
+				.text {
+					font-size: 24upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #999999;
+				}
+				
+				.limit-text {
+					font-size: 32rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FF6633;
+					margin-left: 20upx;
+				}
+			}
+		}
+
+		.right {
+			font-size: 24upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #999999;
+
+			.text {
+				font-size: 24upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #666666;
+			}
+		}
+	}
+
+	.effect {
+		box-sizing: border-box;
+		padding: 20upx 30upx;
+		background: #FFFFFF;
+		font-size: 28upx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		line-height: 1.8;
+		margin-top: 10upx;
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+
+		.label {
+			font-size: 28upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #111111;
+			line-height: 1.8;
+		}
+	}
+
+	.det-box {
+		margin-top: 10upx;
+		padding: 40upx 30upx 130upx 30upx;
+		background-color: #FFFFFF;
+
+		.title {
+			font-size: 30upx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #333333;
+			line-height: 1;
+			margin-bottom: 25upx;
+		}
+
+	}
+
+	.btn-foot {
+		box-sizing: border-box;
+		width: 100%;
+		height: 121upx;
+		background: #FFFFFF;
+		padding: 0 32upx 0 28upx;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+		position: fixed;
+		left: 0;
+		bottom: 0;
+		z-index: 99;
+
+		.menu-box {
+			display: flex;
+			align-items: center;
+
+			.item {
+				display: flex;
+				align-items: center;
+				flex-direction: column;
+				margin-right: 48upx;
+
+				&:last-child {
+					margin-right: 0;
+				}
+
+				image {
+					width: 36upx;
+					height: 36upx;
+					margin-bottom: 10upx;
+				}
+
+				.label {
+					font-size: 20upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #666666;
+					text-align: center;
+				}
+			}
+
+			:deep(.uni-badge--x) {
+				display: flex;
+				align-items: center;
+				justify-content: center;
+			}
+
+			:deep(.uni-badge) {
+				border: none;
+				background-color: #FF3636;
+				font-family: Roboto;
+			}
+		}
+
+		.btn-box {
+			display: flex;
+			align-items: center;
+
+			.btn {
+				width: 200upx;
+				height: 88upx;
+				line-height: 88upx;
+				text-align: center;
+				border-radius: 44upx;
+				margin-left: 20upx;
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #FFFFFF;
+
+				&:first-child {
+					margin-left: 0;
+				}
+
+				&.cart {
+					background: #FF6633;
+				}
+
+				&.buy {
+					background: #FF233C;
+				}
+			}
+		}
+	}
+
+	.product-spec {
+		.pro-info {
+			display: flex;
+			align-items: center;
+
+			.img-box {
+				width: 200upx;
+				height: 200upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				overflow: hidden;
+				margin-right: 30upx;
+
+				image {
+					width: 100%;
+					height: 100%;
+				}
+			}
+
+			.info-text {
+				height: 200upx;
+				display: flex;
+				flex-direction: column;
+				justify-content: space-between;
+
+				.price {
+					display: flex;
+					align-items: flex-end;
+
+					.unit {
+						font-size: 32upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1.2;
+						margin-right: 10upx;
+					}
+
+					.num {
+						font-size: 50upx;
+						font-family: PingFang SC;
+						font-weight: bold;
+						color: #FF6633;
+						line-height: 1;
+					}
+				}
+
+				.desc-box {
+					display: flex;
+					flex-direction: column;
+					padding-bottom: 9upx;
+
+					.text {
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						margin-top: 27upx;
+						line-height: 1;
+
+						&:first-child {
+							margin-top: 0;
+						}
+					}
+				}
+			}
+		}
+
+		.spec-box {
+			padding-top: 50upx;
+
+			.title {
+				font-size: 34upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #111111;
+				line-height: 1;
+			}
+
+			.spec-list {
+				display: flex;
+				flex-wrap: wrap;
+				margin-top: 30upx;
+
+				.item {
+					box-sizing: border-box;
+					height: 64upx;
+					padding: 0 30upx;
+					line-height: 64upx;
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #111111;
+					background: #F7F7F7;
+					border: 1px solid #F7F7F7;
+					border-radius: 32upx;
+					margin-right: 20upx;
+					margin-bottom: 30upx;
+
+					&.active {
+						background: #F1FFFE;
+						border: 1px solid #8AD5CE;
+						color: #FF233C;
+					}
+				}
+			}
+		}
+
+		.price-num {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			margin-top: 14upx;
+
+			.label {
+				font-size: 34upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #111111;
+			}
+
+			.num-box {
+				display: flex;
+				align-items: center;
+
+				.img-box {
+					width: 60upx;
+					height: 60upx;
+					// border-radius: 4upx;
+					border: 1px solid #dddddd;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+
+					image {
+						width: 25rpx;
+						height: 25rpx;
+					}
+				}
+
+				input {
+					width: 60upx;
+					height: 60upx;
+					line-height: 60upx;
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #111111;
+					// border-radius: 4upx;
+					border-top: 1px solid #dddddd;
+					border-bottom: 1px solid #dddddd;
+					text-align: center;
+					// margin: 0 16upx;
+				}
+			}
+		}
+
+		.sub-btn {
+			width: 100%;
+			height: 88upx;
+			line-height: 88upx;
+			text-align: center;
+			font-size: 30upx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #FFFFFF;
+			background: #FF233C;
+			border-radius: 44upx;
+			margin-top: 30upx;
+			// margin-bottom: 30upx;
+
+		}
+	}
+
+	.contact-btn {
+		display: inline-block;
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		opacity: 0;
+		z-index: 9999;
+	}
+
+	.loadding {
+		background-color: #fff;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		z-index: 9999;
+
+		image {
+			border-radius: 50%;
+			animation: load linear 1s infinite;
+			width: 120rpx;
+			height: 120rpx;
+		}
+
+		.text {
+			font-size: 28rpx;
+			margin-top: 20rpx;
+		}
+	}
+
+	.form-item {
+		padding: 30upx 0;
+		display: flex;
+		align-items: flex-start;
+		border-bottom: 1px solid #F1F1F1;
+
+		&:last-child {
+			border-bottom: none;
+		}
+
+		.label {
+			width: 180upx;
+			text-align: left;
+			font-size: 30upx;
+			line-height: 44upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #222222;
+			flex-shrink: 0;
+		}
+
+		input {
+			text-align: left;
+		}
+
+		.form-input {
+			font-size: 30upx;
+			font-family: PingFang SC;
+			font-weight: 500;
+			color: #999999;
+			text-align: left;
+		}
+
+		.form-textarea {
+			font-size: 30upx;
+			color: #999999;
+			height: 100upx;
+			padding: 4upx 0;
+		}
+
+		.birth-picker {
+			flex: 1;
+			display: flex;
+			align-items: center;
+
+			.right-box {
+				width: 100%;
+				display: flex;
+				align-items: center;
+
+				.input-box {
+					width: 470upx;
+				}
+
+				.arrow {
+					width: 13upx;
+					height: 23upx;
+					margin-left: 20upx;
+				}
+			}
+		}
+	}
+</style>

+ 190 - 0
pages/shopping/success.vue

@@ -0,0 +1,190 @@
+<template>
+	<view class="content">
+		<view class="inner">
+			<view class="top">
+				<text class="title">支付成功</text>
+				 <image class="icon" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/success.png" ></image>
+				 <view   class="btn-box">
+				 	<view class="btn cancel" @click="goOrderDetails(order.id)"> 查看订单</view>
+				 </view>
+			</view>
+			<!-- 订单详情查看 -->
+			<view class="order-info">
+				<view class="title">订单信息</view>
+				<view class="item">
+					<text class="label">订单编号</text>
+					<view class="sn-box">
+						<text class="text">{{order.orderCode}}</text>
+						<view class="copy-btn" @click="copyOrderSn(order.orderCode)">复制</view>
+					</view>
+				</view>
+				<view class="item">
+					<text class="label">下单时间</text>
+					<text class="text">{{order.createTime}}</text>
+				</view>
+				 
+			</view>
+			
+		</view>
+		 
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				order:null,
+			}
+		},
+		onLoad(option) {
+			this.order=JSON.parse(option.order) 
+		},
+		methods: {
+			copyOrderSn(text) {
+				// 复制方法
+				uni.setClipboardData({
+					data:text,
+					success:()=>{
+						uni.showToast({
+							title:'内容已成功复制到剪切板',
+							icon:'none'
+						})
+					}
+				});
+			},
+			goOrderDetails(id){
+				uni.redirectTo({
+					url: "/pages_user/user/storeOrderDetail?id="+id
+				}) 
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		height: 100%;
+	}
+	.content{
+		height: 100%;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		.inner{
+			padding: 20upx;
+			.top{
+				box-sizing: border-box;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				padding: 50upx 0upx;
+				.title{
+					font-size: 40upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #222222;
+					line-height: 1;
+					text-align: center;
+				}
+				.icon{
+					margin: 60upx 0upx;
+					width: 100upx;
+					height: 100upx;
+				}
+				 
+			}
+			 
+			.order-info{
+				margin-top: 20upx;
+				background: #FFFFFF;
+				border-radius: 16upx;
+				padding: 40upx 30upx;
+				.title{
+					font-size: 30upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #222222;
+					line-height: 1;
+				}
+				.item{
+					margin-top: 40upx;
+					display: flex;
+					align-items: center;
+					justify-content: space-between;
+					.label{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						line-height: 1;
+					}
+					.text{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #222222;
+						line-height: 32upx;
+					}
+					.cont-text{
+						font-size: 26upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #666666;
+						.bold{
+							color: #111111;
+						}
+					}
+					.sn-box{
+						display: flex;
+						align-items: center;
+						.copy-btn{
+							width: 58upx;
+							height: 32upx;
+							line-height: 32upx;
+							text-align: center;
+							font-size: 22upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #222222;
+							background: #F5F5F5;
+							border-radius: 4upx;
+							margin-left: 24upx;
+						}
+					}
+					 
+				}
+				.line{
+					width: 100%;
+					height: 1px;
+					background: #F0F0F0;
+					margin-top: 30upx;
+				}
+			}
+		}
+		.btn-box{
+			margin-top: 20upx;
+			box-sizing: border-box;
+			display: flex;
+			align-items: center;
+			.btn{
+				width: 155upx;
+				height: 64upx;
+				line-height: 64upx;
+				font-size: 26upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				text-align: center;
+				border-radius: 32upx;
+				&.cancel{
+					border: 1px solid #DDDDDD;
+					color: #666666;
+				}
+				 
+			}
+		}
+	}
+	
+</style>

+ 155 - 0
pages_mall/components/CategoryTags.vue

@@ -0,0 +1,155 @@
+<template>
+	<view class="category-tags" v-if="tags && tags.length > 0">
+		<!-- 1个:整行单模块 -->
+		<view v-if="tags.length === 1" class="layout-single">
+			<view class="tag-item" @tap="onSelect(tags[0])">
+				<image v-if="tags[0].icon" class="tag-icon" :src="tags[0].icon" mode="aspectFill" />
+				<text class="tag-name">{{ tags[0].categoryName|| '-' }}</text>
+			</view>
+		</view>
+		<!-- 2~4个:一行平分 -->
+		<view v-else-if="tags.length >= 2 && tags.length <= 4" class="layout-row" :style="{ '--cols': tags.length }">
+			<view
+				v-for="(item, index) in tags"
+				:key="item.id"
+				class="tag-item"
+				@tap="onSelect(item)"
+			>
+				<image v-if="item.icon" class="tag-icon" :src="item.icon" mode="aspectFill" />
+				<text class="tag-name">{{ item.categoryName|| '-' }}</text>
+			</view>
+		</view>
+		<!-- 5~8个:两行,每行最多4个,按四等分 -->
+		<view v-else class="layout-grid">
+			<view
+				v-for="(item, index) in tags"
+				:key="item.id"
+				class="tag-item"
+				@tap="onSelect(item)"
+			>
+				<image v-if="item.icon" class="tag-icon" :src="item.icon" mode="aspectFill" />
+				<text class="tag-name">{{ item.categoryName|| '-' }}</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'CategoryTags',
+	props: {
+		tags: { type: Array, default: () => [] }
+	},
+  onload(val){
+    //console.log('-----',this.tags)
+  },
+	methods: {
+		onSelect(item) {
+			//console.log(item,'item')
+			if (item != null && typeof item === 'object') {
+				this.$emit('selectClick', item);
+			}
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.category-tags {
+	background: #fff;
+	margin:0 24rpx;
+	padding-top:30rpx;
+	border-radius: 30rpx;
+}
+
+/* 1个:整行占据 */
+.layout-single {
+	width: 100%;
+	.tag-item {
+		width: 100%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-bottom: 30rpx;
+		// padding: 24rpx;
+		//background: #f5f5f5;
+		border-radius: 16rpx;
+	}
+	.tag-icon {
+		width: 100rpx;
+		height: 100rpx;
+		border-radius:50%;
+		// margin-right: 12rpx;
+		flex-shrink: 0;
+	}
+	.tag-name {
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: rgba(0,0,0,0.65);
+		text-align: center;
+	}
+}
+
+/* 2~4个:一行平分 */
+.layout-row {
+	display: flex;
+	flex-wrap: wrap;
+	// gap: 24rpx;
+	.tag-item {
+		flex: 1;
+		min-width: 0;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		margin-bottom: 30rpx;
+		// padding: 20rpx 12rpx;
+		border-radius: 16rpx;
+	}
+	.tag-icon {
+		width: 100rpx;
+		height: 100rpx;
+		border-radius:50%;
+		margin-bottom: 12rpx;
+		flex-shrink: 0;
+	}
+	.tag-name {
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: rgba(0,0,0,0.65);
+		text-align: center;
+	}
+}
+
+/* 5~8个:两行,每行四等分 */
+.layout-grid {
+	display: grid;
+	grid-template-columns: repeat(4, 1fr);
+	// gap: 24rpx;
+	.tag-item {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+		margin-bottom: 30rpx;
+		// padding: 20rpx 8rpx;
+		border-radius: 16rpx;
+	}
+	.tag-icon {
+		width: 100rpx;
+		height: 100rpx;
+		border-radius:50%;
+		margin-bottom: 12rpx;
+		flex-shrink: 0;
+	}
+	.tag-name {
+		font-family: PingFangSC, PingFang SC;
+		font-weight: 400;
+		font-size: 28rpx;
+		color: rgba(0,0,0,0.65);
+		text-align: center;
+	}
+}
+</style>

+ 67 - 0
pages_mall/components/ChannelEntry.vue

@@ -0,0 +1,67 @@
+<template>
+	<view class="channel-entry" v-if="list && list.length > 0">
+		<view class="channel-grid-wrap">
+			<view class="channel-grid">
+				<view class="channel-item" v-for="(item, ci) in list" :key="item.id || ci" @tap="onClick(item)">
+					<image class="channel-icon" :src="item.icon || item.imageUrl" mode="aspectFill"></image>
+					<text class="channel-name">{{ item.categoryName || item.name || item.menuName }}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'ChannelEntry',
+	props: {
+		list: { type: Array, default: () => [] },
+		perRow: { type: Number, default: 4 },
+		rows: { type: Number, default: 2 },
+		imgSize: { type: Number, default: 88 }
+	},
+	methods: {
+		onClick(item) {
+			this.$emit('click', item);
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.channel-entry {
+	background: #fff;
+	padding: 24rpx 0 32rpx;
+}
+.channel-grid-wrap {
+	padding: 0 24rpx;
+}
+.channel-grid {
+	display: flex;
+	flex-wrap: wrap;
+}
+.channel-item {
+	width: 25%;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	padding-bottom: 28rpx;
+	box-sizing: border-box;
+}
+.channel-icon {
+	width: 96rpx;
+	height: 96rpx;
+	border-radius: 50%;
+	margin-bottom: 12rpx;
+	background: #f5f5f5;
+}
+.channel-name {
+	font-size: 24rpx;
+	color: #333;
+	text-align: center;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+	max-width: 100%;
+}
+</style>

+ 157 - 0
pages_mall/components/GoodsCard.vue

@@ -0,0 +1,157 @@
+<template>
+	<view class="goods-card" @click="showProduct(item)">
+		<view class="img-wrap">
+			<image class="img" :src="item.image" mode="aspectFill"></image>
+			<view class="tag-row" v-if="tagList && tagList.length > 0">
+				<text class="tag-chip" v-for="(t, i) in tagList" :key="i">{{ t }}</text>
+			</view>
+		</view>
+		<view class="info">
+			<view class="title line2">{{ item.productName }}</view>
+			<view class="x-bc">
+				<view class="price-row">
+					<text class="unit"v-if="showPrice">¥</text>
+					<text class="price" v-if="showPrice">{{item.price != null ? item.price : item.payPrice || 0 }}</text>
+					<text class="ot-price" v-if="item.otPrice != null">原价¥{{item.otPrice }}</text>
+				</view>
+				<view class="meta-row" v-if="item.sales != null || item.positiveRating != null">
+					<text class="sales" v-if="item.sales != null">已售{{ item.sales }}</text>
+					<text v-if="item.positiveRating">I</text>
+					<text class="good-rate" v-if="item.positiveRating != null">好评{{ item.positiveRating }}%</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'GoodsCard',
+	props: {
+		item: { type: Object, required: true },
+		showPrice: { type: Boolean, default: true },
+		defaultImg: {
+			type: String,
+			default: 'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/no-img.png'
+		}
+	},
+	computed: {
+		tagList() {
+			const item = this.item
+			if (!item) return []
+			if (Array.isArray(item.tagList)) return item.tagList
+			if (Array.isArray(item.tagNames)) return item.tagNames
+			if (Array.isArray(item.tags)) return item.tags.map(t => typeof t === 'string' ? t : (t.tagName || t.name))
+			if (item.tag) return [item.tag]
+			return []
+		}
+	},
+	methods:{
+		showProduct(item) {
+			uni.navigateTo({ url: '/pages/shopping/productDetails?productId=' + item.productId })
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.goods-card {
+	width: 100%;
+	background: #fff;
+	border-radius: 16rpx;
+	overflow: hidden;
+	box-sizing: border-box;
+	display: flex;
+	flex-direction:column;
+	align-items: stretch;
+}
+.img-wrap {
+	width: 100%;
+	height: 394rpx;
+	flex-shrink: 0;
+	background: #f5f5f5;
+	position: relative;
+}
+.img {
+	width: 100%;
+	height: 100%;
+}
+.info {
+	flex: 1;
+	padding: 20rpx;
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	min-width: 0;
+}
+.tag-row {
+	position: absolute;
+	bottom:0;
+	display: flex;
+	flex-wrap: wrap;
+	gap: 12rpx;
+	padding: 0 12rpx;
+	margin-bottom: 12rpx;
+}
+.tag-chip {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 30rpx;
+	color: #AA4726;
+	line-height: 42rpx;
+	background: #FFF4F1;
+	padding: 4rpx 12rpx;
+	border-radius: 6rpx;
+}
+.title {
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 500;
+	font-size: 36rpx;
+	color: rgba(0,0,0,0.85);
+	line-height: 50rpx;
+}
+.line2 {
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+	overflow: hidden;
+}
+.price-row {
+	display: flex;
+	align-items: baseline;
+	gap: 12rpx;
+	margin-top: 8rpx;
+}
+.unit{
+	font-weight: 600;
+	font-size: 28rpx;
+	color: #FF233C;
+}
+.price {
+	font-size: 44rpx;
+	font-weight: 600;
+	color: #FF233C;
+}
+.ot-price {
+	font-size: 28rpx;
+	color: #999;
+	text-decoration: line-through;
+}
+.meta-row {
+	display: flex;
+	align-items: center;
+	gap: 8rpx;
+	margin-top: 8rpx;
+	font-size: 28rpx;
+	color: #999;
+}
+// .sales,
+// .good-rate {
+// 	font-size: 28rpx;
+// 	color: #999;
+// }
+.sales{
+	// border-right: 1rpx solid #e5e5e5; /* 右侧竖线 */
+	// padding-right: 14rpx; /* 竖线与文字的间距 */
+}
+</style>

+ 67 - 0
pages_mall/components/GoodsList.vue

@@ -0,0 +1,67 @@
+<template>
+	<view class="goods-list">
+		<view class="list-column" v-if="list && list.length > 0">
+			<view class="list-item" v-for="(item, index) in list" :key="item.productId">
+				<GoodsCard :item="item" :show-price="showPrice" @click="$emit('itemClick', item)" />
+			</view>
+		</view>
+		<view class="empty" v-else-if="!loading">
+			<text class="empty-text">暂无商品</text>
+		</view>
+		<view class="loading" v-if="loading">
+			<text class="loading-text">加载中...</text>
+		</view>
+		<view class="load-more" v-if="hasMore && !loading && list.length > 0" @click="$emit('loadMore')">
+			<text>加载更多</text>
+		</view>
+	</view>
+</template>
+
+<script>
+import GoodsCard from './GoodsCard.vue';
+export default {
+	name: 'GoodsList',
+	components: { GoodsCard },
+	props: {
+		list: { type: Array, default: () => [] },
+		loading: { type: Boolean, default: false },
+		hasMore: { type: Boolean, default: true },
+		showPrice: { type: Boolean, default: true }
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.goods-list {
+	padding: 24rpx;
+	background: #f5f5f5;
+	min-height: 400rpx;
+	padding-bottom: 120rpx;
+}
+.list-column {
+	display: flex;
+	flex-direction: column;
+	gap: 24rpx;
+}
+.list-item {
+	width: 100%;
+}
+.empty,
+.loading {
+	padding: 80rpx 0;
+	text-align: center;
+}
+.empty-text,
+.loading-text {
+	font-size: 28rpx;
+	color: #999;
+}
+.load-more {
+	padding: 32rpx 0;
+	text-align: center;
+}
+.load-more text {
+	font-size: 28rpx;
+	color: #FF233C;
+}
+</style>

+ 94 - 0
pages_mall/components/GoodsNav.vue

@@ -0,0 +1,94 @@
+<template>
+	<view class="goods-nav" v-if="navList && navList.length > 0">
+		<view class="nav-row">
+			<view class="nav-all" :class="{ active: activeId === 'all' || activeId === 0 || activeId === '0' }" @tap.stop="onSelectAll" @click.stop="onSelectAll">
+				<text>全部</text>
+			</view>
+			<scroll-view scroll-x class="nav-scroll" :show-scrollbar="false">
+			<view class="nav-inner">
+				<view
+					v-for="(item, index) in navList"
+					:key="item.id || item.value || index"
+					:class="['nav-item', { active: (item.id || item.value) === activeId }]"
+					@tap.stop="onSelectByIndex(index)"
+					@click.stop="onSelectByIndex(index)"
+				>
+					<text>{{ item.name || item.categoryName || item.label }}</text>
+				</view>
+			</view>
+			</scroll-view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'GoodsNav',
+	props: {
+		navList: { type: Array, default: () => [] },
+		activeId: { type: [String, Number], default: null }
+	},
+	methods: {
+		onSelectAll() {
+			this.$emit('select', { id: 'all', name: '全部', categoryName: '全部' });
+		},
+		onSelectByIndex(index) {
+			const list = this.navList;
+			if (!list || index < 0 || index >= list.length) {
+				console.warn('[GoodsNav] onSelectByIndex 无效 index:', index, 'list.length:', list ? list.length : 0);
+				return;
+			}
+			const item = list[index];
+			this.$emit('select', item);
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.goods-nav {
+	width: 100%;
+}
+.nav-row {
+	display: flex;
+	align-items: center;
+	padding: 0 24rpx;
+	gap: 30rpx;
+}
+.nav-all {
+	flex-shrink: 0;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 40rpx;
+	color: rgba(0,0,0,0.85);
+	line-height: 56rpx;
+}
+.nav-all.active {
+	color: #FF233C;
+	font-weight: 600;
+}
+.nav-scroll {
+	flex: 1;
+}
+.nav-inner {
+	display: inline-flex;
+	padding:0;
+	gap: 30rpx;
+}
+.nav-item {
+	flex-shrink: 0;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 40rpx;
+	color: rgba(0,0,0,0.85);
+	line-height: 56rpx;
+}
+.nav-item.active {
+	color: #FF233C;
+	font-weight: 600;
+}
+.nav-item.active text {
+	// border-bottom: 2rpx solid #E5212B;
+	// padding-bottom: 4rpx;
+}
+</style>

+ 315 - 0
pages_mall/components/HotProduct.vue

@@ -0,0 +1,315 @@
+<template>
+    <view class="group-goods" v-if="detail.length>0">
+        <view class="title-box x-bc"  >
+            <text class="title">热门榜单</text>
+            <view class="group-people x-f" @tap="navTo('/pages/home/productList')">
+                <text class="tip">更多</text>
+                <text class="cuIcon-right"></text>
+            </view>
+        </view>
+        <view class="goods-box swiper-box x-f">
+            <swiper class="carousel" circular @change="swiperChange" :autoplay="true" interval="10000" duration="2000">
+                <swiper-item v-for="(goods, index) in goodsList" :key="index" class="carousel-item">
+                    <view class="goods-list-box x-f">
+                        <block v-for="mgoods in goods" :key="mgoods.productId" >
+                            <view class="min-goods"  @tap="showProduct(mgoods)"  >
+                                <view class="img-box">
+                                    <view class="tag">hot</view>
+                                    <image class="img" :src="mgoods.image" mode="widthFix"></image>
+                                </view>
+                                <view class="price-box">
+                                    <view class="y-f">
+                                        <text class="seckill-current" v-if="user.isShow==1">¥{{  mgoods.price.toFixed(2)  }}</text>
+                                        <text class="seckill-current" v-else>¥{{  mgoods.otPrice.toFixed(2)  }}</text>
+										<!-- {{mgoods.unitName}} -->
+                                        <text class="original" v-if="user.isShow==1">销量{{ mgoods.sales }}</text>
+                                    </view>
+                                </view>
+                                <view class="title">
+                                    <slot name="titleText"></slot>
+                                </view>
+                            </view>
+                        </block>
+                    </view>
+                </swiper-item>
+            </swiper>
+            <view class="swiper-dots" v-if="goodsList.length > 1">
+                <text :class="swiperCurrent === index ? 'dot-active' : 'dot'" v-for="(dot, index) in goodsList.length"
+                    :key="index"></text>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+	import {getUserInfo} from '@/api/user'
+    export default {
+        name: "HotProduct",
+         
+        data() {
+            return {
+                goodsList: [],
+                swiperCurrent: 0,
+				UserInfo:uni.getStorageSync('AppToken'),
+				user:{}
+            };
+        },
+        props: {
+            detail: Array
+        },
+        computed: {},
+        created() {},
+        watch: {
+            detail(next) {
+                this.goodsList = this.sortData(next, 4)
+            },
+			UserInfo() {
+			    return uni.getStorageSync('AppToken')
+			}
+        },
+		mounted() {
+			this.UserInfo = uni.getStorageSync('AppToken') // 强制更新登录状态
+			if(this.UserInfo) {
+				this.getUserInfo()
+			}
+			console.log(this.detail)
+		},
+        methods: {
+			getUserInfo(){
+				getUserInfo().then(
+					res => {
+						if(res.code==200){
+							if(res.user!=null){
+								this.user=res.user;
+							}
+							else{
+								// this.utils.loginOut();
+							}
+							
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: "请求失败",
+							});
+						}
+					},
+					rej => {}
+				);
+			},
+            swiperChange(e) {
+                this.swiperCurrent = e.detail.current;
+            },
+            // 数据分层
+            sortData(oArr, length) {
+                let arr = [];
+                let minArr = [];
+                oArr.forEach(c => {
+                    if (minArr.length === length) {
+                        minArr = [];
+                    }
+                    if (minArr.length === 0) {
+                        arr.push(minArr);
+                    }
+                    minArr.push(c);
+                });
+
+                return arr;
+            },
+			navTo(url){
+				uni.navigateTo({
+					url: url
+				})
+			},
+			showProduct(item){
+				uni.navigateTo({
+					url: '/pages/shopping/productDetails?productId='+item.productId
+				})
+			},
+            
+        }
+    }
+</script>
+
+
+<style lang="scss" scoped>
+    .group-goods {
+        position: relative;
+        z-index: 1;
+		background: #FFFFFF;
+		border-radius: 16upx;
+		margin-bottom: 20upx;
+		margin-top: 20upx;
+		padding: 20upx;
+    }
+
+    .swiper-box,
+    .carousel {
+        width: 700rpx;
+        height: 240upx;
+        position: relative;
+        border-radius: 20rpx;
+
+        .carousel-item {
+            width: 100%;
+            height: 100%;
+            // padding: 0 28upx;
+            overflow: hidden;
+        }
+
+        .swiper-image {
+            width: 100%;
+            height: 100%;
+            // border-radius: 10upx;
+            background: #ccc;
+        }
+    }
+
+    .swiper-dots {
+        display: flex;
+        position: absolute;
+        left: 50%;
+        transform: translateX(-50%);
+        bottom: 0rpx;
+        z-index: 66;
+
+        .dot {
+            width: 45rpx;
+            height: 3rpx;
+            background: #eee;
+            border-radius: 50%;
+            margin-right: 10rpx;
+        }
+
+        .dot-active {
+            width: 45rpx;
+            height: 3rpx;
+            background: #a8700d;
+            border-radius: 50%;
+            margin-right: 10rpx;
+        }
+    }
+
+    // 今日必拼+限时抢购
+    .group-goods {
+        background: #fff;
+        border-radius: 20rpx;
+        overflow: hidden;
+
+        .title-box {
+            padding-bottom: 20rpx;
+
+            .title {
+                font-size: 32rpx;
+                font-weight: bold;
+            }
+
+            .group-people {
+                .time-box {
+                    font-size: 26rpx;
+                    color: #edbf62;
+
+                    .count-text-box {
+                        width: 30rpx;
+                        height: 34rpx;
+                        background: #edbf62;
+                        text-align: center;
+                        line-height: 34rpx;
+                        font-size: 24rpx;
+                        border-radius: 6rpx;
+                        color: rgba(#fff, 0.9);
+                        margin: 0 8rpx;
+                    }
+                }
+
+                .head-box {
+                    .head-img {
+                        width: 40rpx;
+                        height: 40rpx;
+                        border-radius: 50%;
+                        background: #ccc;
+                    }
+                }
+
+                .tip {
+                    font-size: 24rpx;
+                    padding-left: 30rpx;
+                    color: #999999;
+                }
+
+                .cuIcon-right {
+                    font-size: 30rpx;
+                    line-height: 28rpx;
+                    color: #666;
+                }
+            }
+        }
+
+        .goods-box {
+            .goods-item {
+                margin-right: 22rpx;
+
+                &:nth-child(4n) {
+                    margin-right: 0;
+                }
+            }
+        }
+        .min-goods{
+            margin-right: 22rpx;
+
+        }
+    }
+	.min-goods {
+	  width: 152rpx;
+	  background: #fff;
+	  .img-box {
+	    width: 152rpx;
+	    height: 152rpx;
+	    overflow: hidden;
+	    position: relative;
+	
+	    .tag {
+	      position: absolute;
+	      left: 0;
+	      bottom: 0rpx;
+	      z-index: 2;
+	      line-height: 35rpx;
+	      background: linear-gradient(132deg, rgba(243, 223, 177, 1), rgba(243, 223, 177, 1), rgba(236, 190, 96, 1));
+	      border-radius: 0px 18rpx 18rpx 0px;
+	      padding: 0 10rpx;
+	      font-size: 24rpx;
+	      font-family: PingFang SC;
+	      font-weight: bold;
+	      color: rgba(120, 79, 6, 1);
+	    }
+	
+	    .img {
+	      width: 100%;
+	      background-color: #ccc;
+	    }
+	  }
+	
+	  .price-box {
+	    width: 100%;
+	    margin-top: 10rpx;
+	
+	    .seckill-current {
+	      font-size: 30rpx;
+	      font-weight: 500;
+	      color: rgba(225, 33, 43, 1);
+	    }
+	
+	    .original {
+	      font-size: 20rpx;
+	      font-weight: 400;
+	      // text-decoration: line-through;
+	      color: rgba(153, 153, 153, 1);
+	      margin-left: 14rpx;
+	    }
+	  }
+	
+	  .title {
+	    font-size: 26rpx;
+	  }
+	}
+	
+</style>

+ 270 - 0
pages_mall/components/NewProduct.vue

@@ -0,0 +1,270 @@
+<template>
+    <view class="group-goods" v-if="detail.length>0">
+        <view class="title-box x-bc"  >
+            <text class="title">新品首发</text>
+            <view class="group-people x-f" @tap="navTo('/pages/home/productList')">
+                <text class="tip">更多</text>
+                <text class="cuIcon-right"></text>
+            </view>
+        </view>
+        <view class="goods-box swiper-box x-f">
+            <swiper class="carousel" circular @change="swiperChange" :autoplay="true" interval="10000" duration="2000">
+                <swiper-item v-for="(goods, index) in goodsList" :key="index" class="carousel-item">
+                    <view class="goods-list-box x-f">
+                        <block v-for="mgoods in goods" :key="mgoods.productId"  >
+                            <view class="min-goods" @tap="showProduct(mgoods)"  >
+                                <view class="img-box">
+                                    <view class="tag">new</view>
+                                    <image class="img" :src="mgoods.image" mode="widthFix"></image>
+                                </view>
+                                <view class="price-box">
+                                    <view class="y-f">
+                                        <text class="seckill-current">¥{{  mgoods.price  }}</text>
+                                        <text class="original">销量{{ mgoods.sales }}{{mgoods.unitName}}</text>
+                                    </view>
+                                </view>
+                                <view class="title">
+                                    <slot name="titleText"></slot>
+                                </view>
+                            </view>
+                        </block>
+                    </view>
+                </swiper-item>
+            </swiper>
+            <view class="swiper-dots" v-if="goodsList.length > 1">
+                <text :class="swiperCurrent === index ? 'dot-active' : 'dot'" v-for="(dot, index) in goodsList.length"
+                    :key="index"></text>
+            </view>
+        </view>
+    </view>
+</template>
+
+<script>
+    export default {
+        name: "NewProduct",
+         
+        data() {
+            return {
+                goodsList: [],
+                swiperCurrent: 0
+            };
+        },
+        props: {
+            detail: Array
+        },
+        computed: {},
+        created() {},
+        watch: {
+            detail(next) {
+                this.goodsList = this.sortData(next, 4);
+            }
+        },
+        methods: {
+            swiperChange(e) {
+                this.swiperCurrent = e.detail.current;
+            },
+            // 数据分层
+            sortData(oArr, length) {
+                let arr = [];
+                let minArr = [];
+                oArr.forEach(c => {
+                    if (minArr.length === length) {
+                        minArr = [];
+                    }
+                    if (minArr.length === 0) {
+                        arr.push(minArr);
+                    }
+                    minArr.push(c);
+                });
+
+                return arr;
+            },
+			navTo(url){
+				uni.navigateTo({
+					url: url
+				})
+			},
+			showProduct(item){
+				uni.navigateTo({
+					url: '/pages/shopping/productDetails?productId='+item.productId
+				})
+			}
+        }
+    }
+</script>
+
+
+<style lang="scss" scoped>
+    .group-goods {
+        position: relative;
+        z-index: 1;
+		background: #FFFFFF;
+		border-radius: 16upx;
+		margin-bottom: 20upx;
+		margin-top: 20upx;
+		padding: 20upx;
+    }
+    .swiper-box,.carousel {
+        width: 700rpx;
+        height: 240rpx;
+        position: relative;
+        border-radius: 20rpx;
+        .carousel-item {
+            width: 100%;
+            height: 100%;
+            // padding: 0 28upx;
+            overflow: hidden;
+        }
+        .swiper-image {
+            width: 100%;
+            height: 100%;
+            // border-radius: 10upx;
+            background: #ccc;
+        }
+    }
+    .swiper-dots {
+        display: flex;
+        position: absolute;
+        left: 50%;
+        transform: translateX(-50%);
+        bottom: 0rpx;
+        z-index: 66;
+        .dot {
+            width: 45rpx;
+            height: 3rpx;
+            background: #eee;
+            border-radius: 50%;
+            margin-right: 10rpx;
+        }
+        .dot-active {
+            width: 45rpx;
+            height: 3rpx;
+            background: #a8700d;
+            border-radius: 50%;
+            margin-right: 10rpx;
+        }
+    }
+
+    // 今日必拼+限时抢购
+    .group-goods {
+        background: #fff;
+        border-radius: 20rpx;
+        overflow: hidden;
+
+        .title-box {
+            padding-bottom: 20rpx;
+
+            .title {
+                font-size: 32rpx;
+                font-weight: bold;
+            }
+
+            .group-people {
+                .time-box {
+                    font-size: 26rpx;
+                    color: #edbf62;
+
+                    .count-text-box {
+                        width: 30rpx;
+                        height: 34rpx;
+                        background: #edbf62;
+                        text-align: center;
+                        line-height: 34rpx;
+                        font-size: 24rpx;
+                        border-radius: 6rpx;
+                        color: rgba(#fff, 0.9);
+                        margin: 0 8rpx;
+                    }
+                }
+
+                .head-box {
+                    .head-img {
+                        width: 40rpx;
+                        height: 40rpx;
+                        border-radius: 50%;
+                        background: #ccc;
+                    }
+                }
+
+                .tip {
+                    font-size: 24rpx;
+                    padding-left: 30rpx;
+                    color: #999999;
+                }
+
+                .cuIcon-right {
+                    font-size: 30rpx;
+                    line-height: 28rpx;
+                    color: #666;
+                }
+            }
+        }
+
+        .goods-box {
+            .goods-item {
+                margin-right: 22rpx;
+                &:nth-child(4n) {
+                    margin-right: 0;
+                }
+            }
+        }
+        .min-goods{
+            margin-right: 22rpx;
+
+        }
+    }
+	.min-goods {
+	  width: 152rpx;
+	  background: #fff;
+	  .img-box {
+	    width: 152rpx;
+	    height: 152rpx;
+	    overflow: hidden;
+	    position: relative;
+	
+	    .tag {
+	      position: absolute;
+	      left: 0;
+	      bottom: 0rpx;
+	      z-index: 2;
+	      line-height: 35rpx;
+	      background: linear-gradient(132deg, rgba(243, 223, 177, 1), rgba(243, 223, 177, 1), rgba(236, 190, 96, 1));
+	      border-radius: 0px 18rpx 18rpx 0px;
+	      padding: 0 10rpx;
+	      font-size: 24rpx;
+	      font-family: PingFang SC;
+	      font-weight: bold;
+	      color: rgba(120, 79, 6, 1);
+	    }
+	
+	    .img {
+	      width: 100%;
+	      background-color: #ccc;
+	    }
+	  }
+	
+	  .price-box {
+	    width: 100%;
+	    margin-top: 10rpx;
+	
+	    .seckill-current {
+	      font-size: 30rpx;
+	      font-weight: 500;
+	      color: rgba(225, 33, 43, 1);
+	    }
+	
+	    .original {
+	      font-size: 20rpx;
+	      font-weight: 400;
+	      // text-decoration: line-through;
+	      color: rgba(153, 153, 153, 1);
+	      margin-left: 14rpx;
+	    }
+	  }
+	
+	  .title {
+	    font-size: 26rpx;
+	  }
+	}
+	
+</style>

+ 395 - 0
pages_mall/components/RecommendSection.vue

@@ -0,0 +1,395 @@
+<template>
+	<view class="recommend-section" v-if="hasContent">
+		<!-- 平均分(占位,无数据时显示 —) -->
+		<view class="score-row" v-if="showScore">
+			<text class="score-label">平均分</text>
+			<text class="score-value">{{ averageScore != null ? averageScore : '—' }}</text>
+		</view>
+
+		<view class="recommend-layout">
+			<!-- 左侧:直播卡片轮播,自动滚动 + 可手动左右滑动,右上角 当前index/总数量 -->
+			<view class="block-left-wrap" v-if="liveList.length > 0" @click="onLive">
+				<swiper class="live-swiper" :current="liveCurrent" circular :indicator-dots="false" :autoplay="true"
+					:interval="3000" :duration="1000" indicator-color="rgba(255, 255, 255, 0.6)"
+					indicator-active-color="#ffffff" @change="onLiveSwiperChange">
+					<!-- <swiper-item v-for="(item, idx) in liveList" :key="idx" @click="onLiveClick(item)">
+						<view class="block-left">
+							<view class="x-c" :class="['block-label', isLiving(item) ? 'live' : 'replay']">
+								<image class="w24 h24"
+									:src="isLiving(item) ? '/static/images/live.gif' : '/static/images/replay.png'"
+									mode="aspectFill"></image>
+								{{ isLiving(item) ? '直播中' : '回放' }}
+							</view>
+							<image class="block-img" :src="item.liveImgUrl" mode="aspectFill"></image>
+							<view class="block-tit">
+								<image class="item-avatar" src="/static/logo.jpg" mode="aspectFill"></image>
+								<view class="item-title one-t">{{ item.liveName }}</view>
+							</view>
+						</view>
+					</swiper-item> -->
+					<swiper-item>
+						<view class="block-left">
+							<image class="block-img" src="https://bjzmky-1323137866.cos.ap-chongqing.myqcloud.com/app/image/yuanxiangxing.png" mode="aspectFill"></image>
+							<view class="block-title one-t">央广会客厅</view>
+						</view>
+					</swiper-item>
+				</swiper>
+				<!-- <view class="swiper-dots" v-if="liveList.length > 1">
+					<text v-for="(dot, index) in liveList.length" :key="'live-dot-' + index"
+						:class="liveCurrent === index ? 'dot-active' : 'dot'"></text>
+				</view> -->
+			</view>
+
+			<!-- 右侧:上 绿色有机,下 上新推荐 -->
+			<view class="block-right">
+				<view class="block-small">
+					<view class="block-small-head">
+						<image class="w140" src="@/static/images/new.png" mode="widthFix"></image>
+						<view class="more" @click.stop="goMore('hot')">
+							<text class="green">更多</text>
+							<u-icon name="play-right-fill" color="#FF5B25" size="24rpx"></u-icon>
+						</view>
+					</view>
+					<view class="block-small-body">
+						<view class="small-item" v-for="(item, i) in hot.slice(0, 2)" :key="i"
+							@click.stop="onItemClick(item, 'hot')">
+							<image class="small-thumb" :src="getFirstImage(item)" mode="aspectFill"></image>
+							<view>
+								<text class="unit">¥</text>
+								<text class="small-price" v-if="item.price != null">{{ Number(item.price).toFixed(2)
+									}}</text>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="block-small">
+					<view class="block-small-head">
+						<image class="w140" src="@/static/images/hot.png" mode="widthFix"></image>
+						<view class="more" @click.stop="goMore('green')">
+							<text class="hot">更多</text>
+							<u-icon name="play-right-fill" color="#FF485D" size="24rpx"></u-icon>
+						</view>
+					</view>
+					<view class="block-small-body">
+						<view class="small-item" v-for="(item, e) in green.slice(0, 2)" :key="e"
+							@click.stop="onItemClick(item, 'green')">
+							<image class="small-thumb" :src="getFirstImage(item)" mode="aspectFill"></image>
+							<view>
+								<text class="unit">¥</text>
+								<text class="small-price" v-if="item.price != null">{{ Number(item.price).toFixed(2)
+									}}</text>
+							</view>
+
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'RecommendSection',
+	props: {
+		live: { type: Array, default: () => [] },
+		green: { type: Array, default: () => [] },
+		hot: { type: Array, default: () => [] },
+		averageScore: { type: [String, Number], default: null },
+		showScore: { type: Boolean, default: false }
+	},
+	computed: {
+		hasContent() {
+			return (this.live && this.live.length > 0) || (this.green && this.green.length > 0) || (this.hot && this.hot.length > 0)
+		},
+		liveList() {
+			return this.live && this.live.length > 0 ? this.live : []
+		},
+		liveCurrentDisplay() {
+			return this.liveList.length > 0 ? this.liveCurrent + 1 : 0
+		}
+	},
+	data() {
+		return {
+			liveCurrent: 0
+		}
+	},
+	methods: {
+	onLive(){
+		uni.showToast({
+			title: '暂无课程',
+			icon: 'none'
+		})
+	},
+		onLiveSwiperChange(e) {
+			this.liveCurrent = e.detail.current
+		},
+		isLiving(item) {
+			if (!item) return false
+			if (item.liveType === 1) return true
+			if (item.liveType === 2 && item.liveFlag === 1) return true
+			return false
+		},
+		onLiveClick(item) {
+			//console.log(item)
+			this.$emit('liveClick', item)
+		},
+		goMore(type) {
+			this.$emit('more', { type })
+		},
+		onItemClick(item, type) {
+			//this.$emit('itemClick', { item, section: { type } })
+			this.$emit('itemClick', item,type)
+		},
+		// 取 sliderImage 逗号拼接的第一张图,没有则用 image
+		getFirstImage(item) {
+			if (!item) return ''
+			const str = item.sliderImage || item.image || ''
+			if (typeof str !== 'string') return item.image || ''
+			const first = str.split(',')[0]
+			return (first && first.trim()) || item.image || ''
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+.recommend-section {
+	margin: 30rpx 24rpx 40rpx;
+}
+
+.score-row {
+	display: flex;
+	align-items: center;
+	margin-bottom: 16rpx;
+	font-size: 26rpx;
+}
+
+.score-label {
+	color: #666;
+	margin-right: 12rpx;
+}
+
+.score-value {
+	color: #333;
+	font-weight: 600;
+}
+
+.recommend-layout {
+	display: flex;
+	gap: 20rpx;
+}
+
+.block-left-wrap {
+	flex: 1;
+	// width: 340rpx;
+	flex-shrink: 0;
+	// height: 420rpx;
+	border-radius: 24rpx;
+	overflow: hidden;
+	position: relative;
+}
+
+.live-swiper {
+	width: 100%;
+	height: 100%;
+}
+
+.block-left {
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+	background: #f5f5f5;
+	position: relative;
+}
+
+.live-index-badge {
+	position: absolute;
+	top: 0;
+	right: 0;
+	z-index: 2;
+	background: rgba(0, 0, 0, 0.5);
+	color: #fff;
+	font-size: 22rpx;
+	padding: 8rpx 16rpx;
+	border-radius: 0 0 0 12rpx;
+}
+
+.block-label {
+	position: absolute;
+	top: 20rpx;
+	left: 0;
+	z-index: 2;
+	color: #fff;
+	font-size: 24rpx;
+	padding: 8rpx 20rpx;
+	background: linear-gradient(135deg, #FF5267 0%, #FF233C 100%);
+	border-radius: 0rpx 8rpx 8rpx 0rpx;
+
+	image {
+		margin-right: 4rpx;
+	}
+}
+
+// .block-label.live {
+// 	background: #E5212B;
+// }
+// .block-label.replay {
+// 	background: #666;
+// }
+.block-img {
+	width: 100%;
+	height: 100%;
+	display: block;
+}
+
+.block-title {
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background: rgba(0, 0, 0, 0.45);
+	color: #fff;
+	font-size: 26rpx;
+	padding: 16rpx;
+}
+.block-tit {
+	display: flex;
+	align-items: center;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	background: rgba(0, 0, 0, 0.45);
+	color: #fff;
+	font-size: 26rpx;
+	padding: 16rpx 16rpx 50rpx;
+
+	.item-avatar {
+		width: 40rpx;
+		height: 40rpx;
+		border-radius: 50%;
+		margin-right: 10rpx;
+	}
+
+	.item-title {
+		font-size: 32rpx;
+		color: #FFFFFF;
+		line-height: 44rpx;
+	}
+}
+.swiper-dots {
+	display: flex;
+	position: absolute;
+	left: 50%;
+	transform: translateX(-50%);
+	bottom: 12rpx;
+	z-index: 3;
+	gap: 6rpx;
+}
+
+.dot {
+	width: 8rpx;
+	height: 8rpx;
+	background: #FFFFFF;
+	opacity: 0.7;
+	border-radius: 4rpx;
+}
+
+.dot-active {
+	width: 16rpx;
+	height: 8rpx;
+	background: #FFFFFF;
+	border-radius: 4rpx;
+}
+
+.block-right {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
+	min-width: 0;
+}
+
+.block-small {
+	flex: 1;
+	background: linear-gradient(180deg, #FFC7A7 0%, #FFF8F3 36.36%, #FFFFFF 100%);
+	border-radius: 24rpx;
+	overflow: hidden;
+	padding: 16rpx;
+
+	&:last-child {
+		background: linear-gradient(180deg, #FFC5C5 0%, #FFF5F5 36.36%, #FFFFFF 100%);
+	}
+}
+
+.block-small-head {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-bottom: 18rpx;
+}
+
+.block-small-title {
+	font-size: 28rpx;
+	font-weight: 600;
+}
+
+.green {
+	color: #FF5B25;
+}
+
+.hot {
+	color: #FF485D;
+}
+
+.more {
+	display: flex;
+	align-items: center;
+	font-size: 28rpx;
+
+	text {
+		margin-right: 5rpx;
+	}
+
+	// color: #999;
+}
+
+.arrow {
+	margin-left: 4rpx;
+	font-size: 28rpx;
+}
+
+.block-small-body {
+	display: flex;
+	// gap: 16rpx;
+}
+
+.small-item {
+	flex: 1;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+}
+
+.small-thumb {
+	width: 110rpx;
+	height: 110rpx;
+	border-radius: 10rpx;
+}
+
+.unit {
+	font-weight: 600;
+	font-size: 20rpx;
+	color: #FF233C;
+	margin-top: 8rpx;
+	margin-right: 4rpx;
+}
+
+.small-price {
+	font-size: 32rpx;
+	font-weight: 600;
+	color: #FF233C;
+	margin-top: 8rpx;
+}
+</style>

+ 128 - 0
pages_mall/components/SearchBar.vue

@@ -0,0 +1,128 @@
+<template>
+	<view class="search-bar" :style="{ background:`url(${bgColor})`}">
+		<view class="status_bar" :style="{ height: statusBarHeight}"></view>
+		<!-- <view class="top-title">
+			<view class="name">{{ title }}</view>
+		</view> -->
+		<view class="func-cont" :style="{marginTop: marginTop}">
+			<view class="search-cont" :style="{ width: searchWidth }" @tap.stop="goPage">
+				<image class="icon-search" :src="searchIcon" mode=""></image>
+				<input type="text" :value="keyword" :placeholder="placeholder" placeholder-class="placeholder"
+					disabled />
+			</view>
+			<!-- <uni-badge size="small" :text="cartCount" absolute="rightTop" type="error" v-show="cartCount > 0">
+				<view class="img-item" @click="$emit('cartClick')">
+					<image :src="cartIcon" mode=""></image>
+				</view>
+			</uni-badge>
+			<view class="img-item" v-show="cartCount <= 0" @click="$emit('cartClick')">
+				<image :src="cartIcon" mode=""></image>
+			</view>
+			<view class="img-item" style="position: relative;">
+				<image :src="serviceIcon" mode=""></image>
+				<button class="contact-btn" open-type="contact"></button>
+			</view> -->
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	name: 'SearchBar',
+	props: {
+		title: { type: String, default: '岚财优选' },
+		keyword: { type: String, default: '' },
+		placeholder: { type: String, default: '请输入产品名称' },
+		bgColor: { type: String, default: 'rgba(43,199,185, 0)' },
+		statusBarHeight: { type: String, default: ''},
+		cartCount: { type: Number, default: 0 },
+		searchWidth: { type: String, default: '' },
+		marginTop:{ type: String, default: '' },
+		searchIcon: {
+			type: String,
+			// default: 'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search.png',
+			default: '/static/images/search.png'
+		},
+		cartIcon: {
+			type: String,
+			default: 'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/cart_wihte.png'
+		},
+		serviceIcon: {
+			type: String,
+			default: 'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/customer.png'
+		}
+	},
+	methods:{
+		goPage(){
+			uni.navigateTo({ url: '/pages_mall/productList' })
+		}
+	}
+};
+</script>
+<style lang="stylus">
+	.placeholder{
+		color: rgba(0,0,0,0.25) !important;
+	}
+</style>
+<style lang="scss" scoped>
+.search-bar {
+	position: fixed;
+	top: 0;
+	left: 0;
+	right: 0;
+	z-index: 10000;
+	background-size: 100% !important;
+}
+.top-title .name {
+	font-size: 36rpx;
+	font-weight: bold;
+	color: #fff;
+	padding: 20rpx 0;
+}
+.func-cont {
+	display: flex;
+	align-items: center;
+	padding: 0 24rpx 24rpx;
+}
+.search-cont {
+	display: flex;
+	align-items: center;
+	height: 64rpx;
+	background: rgba(255,255,255,0.5);
+	border-radius: 38rpx;
+	// padding: 0 24rpx;
+	// flex: 1;
+	// margin-right: 20rpx;
+}
+.icon-search {
+	width: 44rpx;
+	height: 44rpx;
+	margin-right: 16rpx;
+}
+.search-cont input {
+	flex: 1;
+	pointer-events: none;
+	font-family: PingFangSC, PingFang SC;
+	font-weight: 400;
+	font-size: 32rpx;
+	color: rgba(0,0,0,0.25);
+	line-height: 44rpx;
+}
+.img-item {
+	width: 48rpx;
+	height: 48rpx;
+	margin-left: 24rpx;
+}
+.img-item image {
+	width: 100%;
+	height: 100%;
+}
+.contact-btn {
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	opacity: 0;
+}
+</style>

+ 454 - 0
pages_mall/home - 副本.vue

@@ -0,0 +1,454 @@
+<template>
+	<view class="home-container">
+		<!-- 头部搜索与标题 -->
+		<view class="custom-header" :style="{paddingTop: statusBarHeight + 'px'}">
+			<view class="title-bar">
+				<view class="back-btn" @click="goBack">
+					<u-icon name="arrow-left" color="#fff" size="20"></u-icon>
+				</view>
+				<text class="title">商城</text>
+				<view class="right-info">
+					<text class="coin-badge">福币:{{integral}}</text>
+				</view>
+			</view>
+			<view class="search-section">
+				<u-search placeholder="搜索您想要的内容" :show-action="false" v-model="keyword" bg-color="#fff" color="#333"
+					placeholder-color="#999" @search="refreshList" @clear="refreshList"></u-search>
+			</view>
+		</view>
+
+		<!-- 滚动内容区 -->
+		<scroll-view scroll-y class="scroll-content" @scrolltolower="scrolltolower">
+			<!-- Banner -->
+			<view class="banner-section" v-if="false">
+				<view class="banner-wrapper">
+					<view class="banner-icon">
+						<u-icon name="volume-fill" color="#fff" size="24"></u-icon>
+					</view>
+					<view class="banner-content">
+						<text class="banner-title">快递停运通知</text>
+						<text class="banner-sub">春节期间快递服务调整,请提前安排下单</text>
+					</view>
+					<view class="banner-action">
+						<text>查看</text>
+						<u-icon name="arrow-right" color="#fff" size="12"></u-icon>
+					</view>
+				</view>
+			</view>
+
+			<!-- 金刚区导航 -->
+			<view class="nav-grid">
+				<view class="nav-item" @click="navTo('/pages_mall/newArrival')">
+					<view class="icon-box icon-new">
+						<u-icon name="star-fill" color="#fff" size="24"></u-icon>
+					</view>
+					<text>新品推荐</text>
+				</view>
+				<view class="nav-item" @click="switchTab(1)">
+					<view class="icon-box icon-cate">
+						<u-icon name="grid-fill" color="#fff" size="24"></u-icon>
+					</view>
+					<text>商品分类</text>
+				</view>
+				<view class="nav-item" @click="navTo('/pages_mall/exchange')">
+					<view class="icon-box icon-mall">
+						<u-icon name="bag-fill" color="#fff" size="24"></u-icon>
+					</view>
+					<text>福币商城</text>
+				</view>
+				<view class="nav-item" @click="switchTab(3)">
+					<view class="icon-box icon-user">
+						<u-icon name="account-fill" color="#fff" size="24"></u-icon>
+					</view>
+					<text>个人中心</text>
+				</view>
+			</view>
+
+			<!-- 商品列表 -->
+			<view class="goods-section">
+				<!-- <view class="goods-item"
+					@click="navTo('/pages/user/integral/integralGoodsDetails?goodsId=' + item.goodsId)" -->
+				<view class="goods-item" @click="navTo('/pages_mall/productDetails?productId='+item.productId)"
+					v-for="(item,index) in dataList" :key="index">
+					<image :src="item.image || item.imgUrl" mode="aspectFill" class="goods-img"></image>
+					<view class="goods-info">
+						<text class="goods-title ellipsis2">{{item.productName || item.goodsName}}</text>
+						<view class="goods-price">
+							<text class="price es-mr-10">¥{{item.otPrice ? item.otPrice.toFixed(2) : item.price}}</text>
+							<text class="es-fs-24">已售{{item.sales || 0}}件</text>
+							<!-- <text class="org-price" v-if="item.price">¥{{item.price}}</text> -->
+						</view>
+					</view>
+				</view>
+			</view>
+
+			<view class="loading-more" v-if="dataList.length > 0">
+				<u-loadmore :status="isMore ? 'loading' : 'nomore'" />
+			</view>
+
+			<view class="empty-box" v-if="dataList.length == 0">
+				<u-empty mode="data" text="暂无商品数据"></u-empty>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+	import {
+		getDictByKey
+	} from '@/api/common.js'
+	import {
+		getProducts
+	} from '@/api/product.js'
+	import {
+		getUserInfo
+	} from '@/api/user'
+	import {
+		getAdvList
+	} from '@/api/adv.js'
+	import {
+		getIntegralGoodsList
+	} from '@/api/integral.js'
+
+	export default {
+		data() {
+			return {
+				statusBarHeight: 20,
+				integral: 0,
+				keyword: "",
+				dataList: [],
+				pageNum: 1,
+				pageSize: 10,
+				isMore: true,
+				total: 0,
+				bannerList: [], // 轮播图图片列表
+				bannerAdvs: [] // 轮播图完整数据
+			}
+		},
+		created() {
+			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
+			this.initData();
+		},
+		methods: {
+			initData() {
+				this.getUserInfo();
+				this.getBannerData();
+				this.refreshList();
+			},
+			getBannerData() {
+				// 尝试获取轮播图,假设商城首页advType为1或使用通用配置
+				// 如果没有特定ID,先尝试用1,或者使用模拟数据
+				let data = {
+					advType: 1
+				};
+				getAdvList(data).then(res => {
+					if (res.code == 200 && res.data && res.data.length > 0) {
+						this.bannerAdvs = res.data;
+						this.bannerList = res.data.map(item => item.imageUrl);
+					} else {
+						// 如果接口没有数据,使用默认好看的占位图
+						this.bannerList = [
+							'https://zkzh-2025.oss-cn-beijing.aliyuncs.com/shop/images/banner1.jpg',
+							'https://zkzh-2025.oss-cn-beijing.aliyuncs.com/shop/images/banner2.jpg'
+						];
+						// 这里的图片地址如果是404,我会换成更稳定的图,或者使用项目中已有的图
+						// 为了稳妥,使用picsum或者mock
+						// 但考虑到是医疗商城,最好用相关图。先用假数据占位,或者复用项目中看到的图
+					}
+
+					// 如果列表为空(包括接口没数据且上面没设置默认),则设置默认
+					if (this.bannerList.length === 0) {
+						this.bannerList = [
+							'https://cdn.uviewui.com/uview/swiper/swiper1.png',
+							'https://cdn.uviewui.com/uview/swiper/swiper2.png',
+							'https://cdn.uviewui.com/uview/swiper/swiper3.png'
+						];
+					}
+				});
+			},
+			getUserInfo() {
+				getUserInfo().then(res => {
+					if (res.code == 200 && res.user != null) {
+						this.integral = res.user.integral;
+					}
+				});
+			},
+			refreshList() {
+				this.pageNum = 1;
+				this.isMore = true;
+				this.dataList = [];
+				this.getList();
+			},
+			scrolltolower() {
+				if (this.isMore) {
+					this.getList();
+				}
+			},
+			getList() {
+				var data = {
+					page: this.pageNum,
+					pageNum: this.pageNum,
+					limit: this.pageSize,
+					pageSize: this.pageSize,
+					keyword: this.keyword,
+				};
+				// 保持原逻辑
+				getProducts(data).then(res => {
+				// getIntegralGoodsList(data).then(res => {
+					if (res.code == 200) {
+						let list = res.data.list && res.data.list.length > 0 ? res.data.list : []
+						this.dataList = this.dataList.concat(list)
+						this.total = res.data.total
+						this.pageNum++
+						if (this.dataList.length >= this.total) {
+							this.isMore = false
+						}
+					} else {
+						// this.dataList = [] // Keep existing if error? Or clear. Original cleared.
+					}
+				});
+			},
+			navTo(url) {
+				uni.navigateTo({
+					url: url
+				})
+			},
+			goBack() {
+				uni.showTabBar()
+				uni.switchTab({
+					url: '/pages_im/pages/conversation/conversationList/index'
+				})
+			},
+			switchTab(index) {
+				this.$emit('switchTab', index);
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	.home-container {
+		display: flex;
+		flex-direction: column;
+		height: 100%;
+		background-color: #F5F7FA;
+	}
+
+	.custom-header {
+		background: linear-gradient(to bottom, #FF233C, #4FACFE);
+		padding: 20rpx 30rpx;
+		color: #fff;
+
+		.title-bar {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			height: 88rpx;
+
+			.title {
+				font-size: 36rpx;
+				font-weight: bold;
+			}
+
+			.coin-badge {
+				background: rgba(255, 255, 255, 0.25);
+				padding: 6rpx 20rpx;
+				border-radius: 30rpx;
+				font-size: 24rpx;
+				backdrop-filter: blur(10px);
+			}
+		}
+
+		.search-section {
+			margin-top: 10rpx;
+			padding-bottom: 20rpx;
+		}
+	}
+
+	.scroll-content {
+		flex: 1;
+		height: 0;
+	}
+
+	.banner-section {
+		padding: 20rpx 30rpx;
+		background-color: #fff;
+		margin-bottom: 20rpx;
+
+		.banner-wrapper {
+			background: linear-gradient(90deg, #FF6B6B, #FF8E53);
+			border-radius: 16rpx;
+			padding: 20rpx;
+			display: flex;
+			align-items: center;
+			box-shadow: 0 4rpx 12rpx rgba(255, 107, 107, 0.3);
+
+			.banner-icon {
+				width: 60rpx;
+				height: 60rpx;
+				background: rgba(255, 255, 255, 0.2);
+				border-radius: 50%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				margin-right: 20rpx;
+			}
+
+			.banner-content {
+				flex: 1;
+				display: flex;
+				flex-direction: column;
+
+				.banner-title {
+					font-size: 30rpx;
+					font-weight: bold;
+					color: #fff;
+					margin-bottom: 6rpx;
+				}
+
+				.banner-sub {
+					font-size: 24rpx;
+					color: rgba(255, 255, 255, 0.9);
+				}
+			}
+
+			.banner-action {
+				display: flex;
+				align-items: center;
+				background: rgba(255, 255, 255, 0.2);
+				padding: 6rpx 16rpx;
+				border-radius: 24rpx;
+
+				text {
+					font-size: 22rpx;
+					color: #fff;
+					margin-right: 4rpx;
+				}
+			}
+		}
+	}
+
+	.scroll-content {
+		flex: 1;
+		height: 0; // Important for flex scroll
+	}
+
+
+
+	.nav-grid {
+		display: flex;
+		justify-content: space-between;
+		padding: 30rpx;
+		background: #fff;
+		margin: 0 30rpx 20rpx;
+		border-radius: 24rpx;
+		box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
+
+		.nav-item {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+
+			.icon-box {
+				width: 100rpx;
+				height: 100rpx;
+				border-radius: 36rpx;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				margin-bottom: 16rpx;
+				transition: transform 0.2s;
+
+				&:active {
+					transform: scale(0.95);
+				}
+
+				&.icon-new {
+					background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+				}
+
+				&.icon-cate {
+					background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+				}
+
+				&.icon-mall {
+					background: linear-gradient(135deg, #fa709a 0%, #fee140 100%);
+				}
+
+				&.icon-user {
+					background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+				}
+			}
+
+			text {
+				font-size: 26rpx;
+				color: #333;
+				font-weight: 500;
+			}
+		}
+	}
+
+	.goods-section {
+		padding: 0 30rpx 20rpx;
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+
+		.goods-item {
+			width: 48%;
+			background: #fff;
+			border-radius: 20rpx;
+			margin-bottom: 24rpx;
+			overflow: hidden;
+			box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
+			transition: transform 0.2s;
+
+			&:active {
+				transform: scale(0.98);
+			}
+
+			.goods-img {
+				width: 100%;
+				height: 320rpx;
+				background: #eee;
+			}
+
+			.goods-info {
+				padding: 20rpx;
+
+				.goods-title {
+					font-size: 28rpx;
+					color: #333;
+					margin-bottom: 16rpx;
+					height: 80rpx;
+					line-height: 40rpx;
+					font-weight: 500;
+				}
+
+				.goods-price {
+					display: flex;
+					align-items: baseline;
+
+					.price {
+						color: #FF5000;
+						font-size: 34rpx;
+						font-weight: bold;
+
+						&::before {
+							content: '¥';
+							font-size: 24rpx;
+							margin-right: 4rpx;
+						}
+					}
+
+					.org-price {
+						color: #999;
+						font-size: 22rpx;
+						text-decoration: line-through;
+						margin-left: 12rpx;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 614 - 0
pages_mall/homeIndex.vue

@@ -0,0 +1,614 @@
+<template>
+	<view class="content">
+		<image class="bg" src="@/static/images/bg.png" mode="aspectFill"></image>
+
+		<view class="header-wrap">
+			<SearchBar
+				:margin-top="'24rpx'"
+				:bg-color="bgColor"
+				:status-bar-height="statusBarHeight"
+				:cart-count="cartCount"
+				:search-width="'100%'"
+				placeholder="搜索商品"
+				@searchClick="toSearch"
+				@cartClick="goAuthUrl()"
+			/>
+		</view>
+
+		<!-- 作为组件嵌入 indexOld 时,外层使用 overflow:hidden;这里改成 scroll-view 保障可滚动与触底加载 -->
+		<scroll-view scroll-y class="scroll-content" @scroll="onScroll" @scrolltolower="loadMoreGoods">
+			<!-- 顶部占位:避免固定搜索栏遮挡 -->
+			<view style="padding-bottom:110rpx">
+				<view class="status_bar" :style="{height: statusBarHeight}"></view>
+			</view>
+
+			<!-- 推荐频道 -->
+			<ChannelEntry :list="channelList" :per-row="4" :rows="2" @click="onChannelClick" />
+
+			<!-- 金刚区:分类图标 2 行 4 列,仅展示 -->
+			<CategoryTags :tags="categoryTagsData" @selectClick="onCategoryTagsSelect" />
+
+			<!-- 推荐区块:左侧直播卡(直播中/回放)+ 右上绿色有机 + 右下上新推荐 -->
+			<RecommendSection
+				:live="recommendData.live"
+				:green="recommendData.green"
+				:hot="recommendData.hot"
+				@liveClick="onLiveClick"
+				@more="onRecommendMore"
+				@itemClick="onRecommendItemClick"
+			/>
+
+			<!-- 瀑布流:全部 + 分类标签横向滚动 -->
+			<GoodsNav :nav-list="goodsNavList" :active-id="activeGoodsNavId" @select="onGoodsNavSelect" />
+
+			<GoodsList
+				:list="goodsList"
+				:loading="goodsLoading"
+				:has-more="goodsHasMore"
+				@itemClick="showProduct"
+				@loadMore="loadMoreGoods"
+			/>
+
+			<!--#ifdef MP-WEIXIN-->
+			<view class="official-account">
+				<official-account @load="bindload" @error="binderror"></official-account>
+			</view>
+			<!--#endif-->
+
+			<view class="popup-box" v-if="activityShow">
+				<view class="info-mask" @tap="closeActivity()"></view>
+				<view class="info-form">
+					<image :src="activity.logoUrl" @tap="showActivity()" />
+				</view>
+			</view>
+
+			<Server />
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+// import zModal from '@/components/z-modal/z-modal.vue'
+import { getMenu, getIndexData, getCartCount } from '@/api/index'
+import { getStoreConfig } from '@/api/common'
+import { getHomeInit, getHomeRecommend, getHomeGoods } from '@/api/home.js'
+import HotProduct from './components/HotProduct.vue'
+//import TuiProduct from '@/components/tuiProduct.vue'
+import SearchBar from './components/SearchBar.vue'
+import CategoryTags from './components/CategoryTags.vue'
+import ChannelEntry from './components/ChannelEntry.vue'
+import RecommendSection from './components/RecommendSection.vue'
+import GoodsNav from './components/GoodsNav.vue'
+import GoodsList from './components/GoodsList.vue'
+import { getUserInfo, bindPromoter } from '@/api/user'
+
+export default {
+	components: {
+		// zModal,
+		HotProduct,
+		//TuiProduct,
+		SearchBar,
+		CategoryTags,
+		ChannelEntry,
+		RecommendSection,
+		GoodsNav,
+		GoodsList
+	},
+	data() {
+		return {
+			btnGroup: [
+				{ text: '取消', color: '#FFFFFF', bgColor: '#999999', width: '150rpx', height: '80rpx', shape: 'fillet', eventName: 'cancle' },
+				{ text: '确定', color: '#FFFFFF', bgColor: '#FF233C', width: '150rpx', height: '80rpx', shape: 'fillet', eventName: 'sure' }
+			],
+			menuButtonInfo: {
+				top: '0px',
+				height: '0px',
+				centerY: '0px',
+				right: '0px'
+			}, // 胶囊按钮布局信息
+			initDone: false,
+			showInitRan: false,
+			tuiModalControl: false,
+			activity: null,
+			activityShow: false,
+			hotProductList: [],
+			menus: [],
+			channelList: [],
+			categoryTagsData: [],
+			goodsNav: [],
+			recommendData: { live: [], green: [], hot: [] },
+			activeGoodsNavId: 'all',
+			goodsList: [],
+			goodsLoading: false,
+			goodsHasMore: true,
+			goodsPageNum: 1,
+			cartCount: 0,
+			advList: [],
+			top: 0,
+			statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px',
+			userinfoa: [],
+			isuser: false,
+			currentTab: 0
+		}
+	},
+	computed: {
+		bgColor() {
+			const t = this.top / 30
+			if(t>0){
+				return '/static/images/bg.png'
+			}else{
+				return ''
+			}
+		},
+		// 瀑布流标签:后端 categoryTags(不包含“全部”)
+		goodsNavList() {
+			const tags = (this.goodsNav || []).map(t => ({
+				id: t.id || t.cateId,
+				name: t.categoryName || t.cateName || t.name,
+				categoryName: t.categoryName || t.cateName || t.name
+			}))
+			return tags
+		}
+	},
+	mounted() {
+		// 作为组件嵌入 indexOld 时,onShow/onLoad 通常不会触发;这里兜底初始化数据
+		setTimeout(() => {
+			if (!this.showInitRan && !this.initDone) this.initIndexData(false)
+		}, 30)
+	},
+	onLoad(option) {
+		this.getMenuButtonInfo(); // 初始化获取胶囊信息
+		if (option.userCode != null) {
+			uni.setStorageSync('userCode', option.userCode)
+			if (this.utils.checkLoginState()) this.getUserInfo()
+		}
+		if (option.hasOwnProperty('q') && option.q) {
+			const url = decodeURIComponent(option.q)
+			const obj = this.utils.urlToObj(url)
+			uni.setStorageSync('userCode', obj.userCode)
+			if (this.utils.checkLoginState()) this.getUserInfo()
+		}
+	},
+	onUnload() {
+		uni.showTabBar();
+		uni.$emit('stop')
+	},
+	onHide() {
+		uni.$emit('stop')
+	},
+	onBackPress() {
+		uni.showTabBar();
+		uni.switchTab({
+			//url: '/pages_im/pages/conversation/conversationList/index'
+			url: '../index/index'
+		})
+	},
+	onPageScroll(e) {
+		// 页面滚动时兼容 uni-app 事件结构
+		this.top = e?.detail?.scrollTop ?? e?.scrollTop ?? 0
+	},
+	onShow() {
+		this.showInitRan = true
+		this.initIndexData(true)
+		uni.hideTabBar();
+	},
+	onShareAppMessage() {
+		return { title: '岚财优选-您的专属解决方案', path: '/pages/common/launch', imageUrl: '/static/logo.jpg' }
+	},
+	onShareTimeline() {
+		return { title: '岚财优选-您的专属解决方案', query: '', imageUrl: '/static/logo.jpg' }
+	},
+	onReachBottom() {
+		this.loadMoreGoods()
+		//this.$refs.tuiProduct && this.$refs.tuiProduct.getTuiProducts()
+	},
+	methods: {
+		onScroll(e) {
+			// scroll-view 的滚动事件
+			this.top = e?.detail?.scrollTop ?? e?.scrollTop ?? 0
+		},
+		switchTab(index) {
+			this.currentTab = index;
+		},
+		initIndexData(force = false) {
+			if (this.initDone && !force) return
+			this.initDone = true
+
+			//this.getMenuButtonInfo()
+			this.getHomeInit()
+			this.getHomeRecommend()
+			this.getMenu()
+			//this.getIndexData()
+
+			if (uni.getStorageSync('AppToken')) {
+				this.getUserInfo()
+			} else {
+				this.isuser = true
+			}
+			if (this.utils.checkLoginState()) this.getCartCount()
+			this.getStoreConfig()
+		},
+		// 获取胶囊按钮布局参数
+		getMenuButtonInfo() {
+			// 微信小程序API(Uniapp可直接用uni.getMenuButtonBoundingClientRect)
+			const menuBtn = uni.getMenuButtonBoundingClientRect();
+			if (menuBtn) {
+		
+				this.menuButtonInfo = {
+					top: menuBtn.top + 'px', // 胶囊顶部距离
+					height: menuBtn.height + 'px', // 胶囊高度
+					centerY: (menuBtn.top + menuBtn.height / 2) + 'px', // 胶囊垂直居中Y坐标
+					right: menuBtn.right + 'px' // 胶囊右侧距离
+				};
+			}
+		},
+		getHomeInit() {
+			getHomeInit().then(res => {
+				if (res.code == 200 && res.data) {
+					this.channelList = res.data.channelList || []
+					this.categoryTagsData = res.data.categoryTags || []
+					this.goodsNav = res.data.goodsNav || []
+					if (this.activeGoodsNavId === null || this.activeGoodsNavId === undefined) {
+						this.activeGoodsNavId = 'all'
+					}
+					this.fetchGoodsList(true)
+				}
+			}).catch(() => {})
+		},
+		getHomeRecommend() {
+			getHomeRecommend().then(res => {
+				if (res.code != 200) return
+				this.recommendData = {
+					live: res.live && Array.isArray(res.live) ? res.live.slice(0, 3) : [],
+					green: res.green && Array.isArray(res.green) ? res.green : [],
+					hot: res.hot && Array.isArray(res.hot) ? res.hot : []
+				}
+			}).catch(() => {})
+		},
+		fetchGoodsList(reset) {
+			if (reset) {
+				this.goodsPageNum = 1
+				this.goodsList = []
+				this.goodsHasMore = true
+			}
+			if (this.goodsLoading || !this.goodsHasMore) return
+			this.goodsLoading = true
+			const id = this.activeGoodsNavId === 'all' || this.activeGoodsNavId === '' ? 0 : this.activeGoodsNavId
+			getHomeGoods({ id, position:2, pageNum: this.goodsPageNum, pageSize: 10 }).then(res => {
+				this.goodsLoading = false
+				if (res.code == 200 && res.data) {
+					const list = Array.isArray(res.data.list) ? res.data.list : []
+					const total = res.data.total != null ? Number(res.data.total) : 0
+					if (reset) this.goodsList = list
+					else this.goodsList = this.goodsList.concat(list)
+					this.goodsHasMore = list.length >= 20 && (this.goodsList.length < total || total === 0)
+					this.goodsPageNum++
+				}
+			}).catch(() => { this.goodsLoading = false })
+		},
+		loadMoreGoods() {
+			this.fetchGoodsList(false)
+		},
+		onGoodsNavSelect(item) {
+      //console.log("2222")
+      //console.log(item.id)
+			this.activeGoodsNavId = item.id
+			this.fetchGoodsList(true)
+		},
+		onCategoryTagsSelect(item) {
+			//console.log(this.categoryTagsData,'item')
+			// 金刚区点击:带分类 id 跳转商品列表页筛选(防护 item 为空)
+			if (!item || typeof item !== 'object') {
+				uni.navigateTo({ url: '/pages_mall/productList' })
+				return
+			}
+			const id = item.id ?? item.cateId ?? item.categoryId
+			if (id != null && id !== '') {
+				uni.navigateTo({ url: '/pages_mall/productList?id=' + id })
+			} else {
+				uni.navigateTo({ url: '/pages_mall/productList' })
+			}
+		},
+		onChannelClick(item) {
+			// 推荐频道点击,可跳转或筛选,按需扩展
+		},
+		onRecommendMore(section) {
+			if (section && section.moreUrl) {
+				uni.navigateTo({ url: '/pages_mall/recommendList' })
+				return
+			}
+			if (section && (section.type === 'green' || section.type === 'hot')) {
+				uni.navigateTo({ url: '/pages_mall/recommendList?type='+section.type})
+			}
+		},
+		onLiveClick(item) {
+			//console.log(item)
+			if (item && item.liveId) uni.navigateTo({ url: '/pages_course/living?liveId=' + item.liveId })
+		},
+		onRecommendItemClick(item,type) {
+			if (item.productId) this.showProduct(item,type)
+		},
+		getMenu() {
+			// getMenu().then(res => {
+			// 	if (res.code == 200) this.menus = res.data || []
+			// })
+		},
+		getIndexData() {
+			getIndexData({}).then(res => {
+				if (res.code == 200) {
+					this.advList = res.data.advList || []
+					this.hotProductList = res.data.hotProductList || []
+				} else {
+					uni.showToast({ icon: 'none', title: '请求失败' })
+				}
+			})
+		},
+		getUserInfo() {
+			getUserInfo().then(res => {
+				if (res.code == 200 && res.user != null) this.userinfoa = res.user
+				else uni.showToast({ icon: 'none', title: '请求失败' })
+			})
+		},
+		getCartCount() {
+			this.utils.isLogin().then(res => {
+				if (res) getCartCount().then(cartRes => {
+					if (cartRes.code == 200) this.cartCount = cartRes.data
+				})
+			})
+		},
+		getStoreConfig() {
+			getStoreConfig().then(res => {
+				if (res.code == 200) uni.setStorageSync('config', JSON.stringify(res.data))
+			})
+		},
+		cancleTui() {
+			this.tuiModalControl = false
+		},
+		submitTui(e) {
+			if (!e.inputText) {
+				uni.showToast({ icon: 'none', title: '请输入邀请码' })
+				return
+			}
+			bindPromoter({ userCode: e.inputText }).then(res => {
+				uni.showToast({ icon: 'none', title: res.msg })
+				if (res.code == 200) this.tuiModalControl = false
+			})
+		},
+		bindload() {},
+		binderror() {},
+		closeActivity() {
+			this.activityShow = false
+		},
+		showActivity() {
+			this.activityShow = false
+			if (this.activity && this.activity.activityId) {
+				uni.navigateTo({ url: '/pages_shopping/shopping/activityDetails?activityId=' + this.activity.activityId })
+			}
+		},
+		menuClick(item) {
+			const linkUrl = item.linkUrl || item.url
+			const linkType = item.linkType != null ? item.linkType : (linkUrl ? 1 : 0)
+			if (linkType == 1 && linkUrl) {
+				if (linkUrl == '/pages/shopping/index' || linkUrl == '/pages/healthy/index') {
+					uni.switchTab({ url: linkUrl })
+				} else {
+					uni.navigateTo({ url: linkUrl })
+				}
+			} else if (linkType == 0) {
+				uni.showToast({ icon: 'none', title: '开发中...' })
+			}
+		},
+		handleAdvClick(item) {
+			if (item.showType == 1) {
+				uni.setStorageSync('url', item.advUrl)
+				uni.navigateTo({ url: 'h5' })
+			} else if (item.showType == 2) {
+				uni.navigateTo({ url: item.advUrl })
+			} else if (item.showType == 3) {
+				uni.setStorageSync('content', item.content)
+				uni.navigateTo({ url: 'content' })
+			}
+		},
+		goAuthUrl(url) {
+			this.utils.isLogin().then(res => {
+				if (res) uni.switchTab({ url })
+			})
+		},
+		navTo(url) {
+			uni.navigateTo({ url })
+		},
+		toSearch() {
+			
+			//uni.navigateTo({ url: './productSearch' })
+			uni.navigateTo({ url: '/pages_mall/productList' })
+		},
+		showProduct(item,type) {
+			//console.log('item',type)
+			//uni.navigateTo({ url: '../shopping/productDetails?productId=' + item.productId })
+			uni.navigateTo({ url: '/pages_mall/recommendList?type='+type})
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+	.tab-bar {
+		height: 100rpx;
+		background-color: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+		border-top: 1rpx solid #eee;
+		padding-bottom: constant(safe-area-inset-bottom);
+		padding-bottom: env(safe-area-inset-bottom);
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		right: 0;
+		z-index: 9999;
+	
+		.tab-item {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			justify-content: center;
+	
+			text {
+				font-size: 24rpx;
+				margin-top: 6rpx;
+				color: #999999;
+			}
+	
+			&.active text {
+				color: #FF233C;
+			}
+	
+			.icon-wrap {
+				position: relative;
+	
+				.badge {
+					position: absolute;
+					top: -10rpx;
+					right: -10rpx;
+					background: #fa436a;
+					color: #fff;
+					font-size: 18rpx;
+					width: 30rpx;
+					height: 30rpx;
+					border-radius: 50%;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+			}
+		}
+	}
+.content {
+	width: 100%;
+	position: relative;
+	min-height: 0;
+	padding-top: 1rpx;
+	display: flex;
+	flex-direction: column;
+	height: 100%;
+}
+.scroll-content {
+	flex: 1;
+	height: 0;
+}
+.header-wrap {
+	position: relative;
+	z-index: 10;
+}
+.banner-row {
+	position: relative;
+	display: flex;
+	gap: 20rpx;
+	padding: 20rpx 24rpx;
+	// background: #fff;
+}
+.banner-item {
+	flex: 1;
+	height: 220rpx;
+	border-radius: 16rpx;
+	overflow: hidden;
+	background: #f5f5f5;
+}
+.banner-img {
+	width: 100%;
+	height: 100%;
+}
+.bg {
+	width: 100%;
+	height: 380rpx;
+	position: absolute;
+	top: 0;
+	left: 0;
+	z-index: 0;
+}
+.status_bar {
+	width: 100%;
+}
+.banner-box {
+	padding: 0 20upx;
+}
+.banner-box .inner {
+	width: 100%;
+	height: 236upx;
+	border-radius: 10upx;
+	overflow: hidden;
+}
+.banner-box .swiper,
+.banner-box .swiper-item,
+.banner-box .swiper-item image {
+	width: 100%;
+	height: 100%;
+}
+.menu-content {
+	background-color: #fff;
+	overflow: hidden;
+	padding: 20upx 20upx 0;
+}
+.menu-box {
+	display: flex;
+	align-items: center;
+	background-color: #fff;
+}
+.online-inquiry {
+	box-sizing: border-box;
+	width: 100%;
+	height: 300upx;
+	padding: 20upx;
+	background: linear-gradient(180deg, rgba(255, 255, 255, 0.38) 62%, rgba(255, 255, 255, 0) 100%);
+}
+.online-inquiry .item {
+	width: 100%;
+	height: 100%;
+	position: relative;
+}
+.online-inquiry .bg-img {
+	width: 100%;
+	height: 100%;
+	position: absolute;
+	top: 0;
+	left: 0;
+	border-radius: 15rpx;
+}
+.index-cont {
+	box-sizing: border-box;
+	padding: 0 20upx 120rpx;
+}
+.official-account {
+	width: 100%;
+}
+.popup-box {
+	position: fixed;
+	top: 0;
+	right: 0;
+	left: 0;
+	bottom: 0;
+	z-index: 999;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+}
+.popup-box .info-mask {
+	position: fixed;
+	top: 0;
+	right: 0;
+	bottom: 0;
+	left: 0;
+	background-color: rgba(0, 0, 0, 0.5);
+	z-index: 999;
+}
+.popup-box .info-form {
+	z-index: 1000;
+	width: 450rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+}
+.popup-box .info-form image {
+	width: 100%;
+}
+</style>

+ 132 - 0
pages_mall/productSearch.vue

@@ -0,0 +1,132 @@
+<template>
+	<view class="content">
+		<!-- 搜索框 -->
+		<view class="search-cont">
+			<view class="inner">
+				<image class="icon-search" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search.png" mode=""></image>
+				<input type="text" value="" placeholder="输入产品名称" confirm-type="搜索" @confirm="goSearch" :focus='setFocus' placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
+			</view>
+		</view>
+		<!-- 搜索历史 -->
+		<view class="title-box">
+			<text class="title">历史搜索</text>
+			<image src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/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">
+			<text class="title">推荐搜索</text>
+		</view>
+		<view class="data-list">
+			<view class="item" v-for="(item,index) in topSearch" :key="index" @click="doSearch(item)">
+				{{ item }}
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				setFocus: false,
+				// 历史搜索
+				searchHistory: [],
+				// 推荐搜索
+				topSearch: []
+			};
+		},
+		onShow() {
+			this.setFocus = true
+			this.searchHistory=this.utils.getHisSearch();
+			var config=uni.getStorageSync('config');
+			if(config!=null&&config!=undefined&&config!=""){
+				this.topSearch=JSON.parse(config).hotSearch.split(',');
+			}
+		},
+		methods:{
+			// 清空历史搜索数据
+			clearHistory() {
+				this.utils.clearHisSearch();
+				this.searchHistory=this.utils.getHisSearch();
+			},
+			doSearch(item){
+				uni.navigateTo({					url: './productList?key=' + item				})
+			},
+			goSearch(e) {
+				if(e.detail.value!=null&&e.detail.value!=""){
+					this.utils.addHisSearch(e.detail.value);
+				}
+				uni.navigateTo({
+					url: './productList?key=' + e.detail.value
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		.search-cont{
+			padding: 16upx 30upx;
+			background-color: #FFFFFF;
+			.inner{
+				box-sizing: border-box;
+				width: 100%;
+				height: 72upx;
+				background: #F7F7F7;
+				border-radius: 36upx;
+				display: flex;
+				align-items: center;
+				padding: 0 30upx;
+				.icon-search{
+					width: 28upx;
+					height: 28upx;
+					margin-right: 20upx;
+				}
+				input{
+					height: 60upx;
+					line-height: 60upx;
+					flex: 1;
+				}
+			}
+		}
+		.title-box{
+			padding: 30upx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			.title{
+				font-size: 30upx;
+				font-family: PingFang SC;
+				font-weight: bold;
+				color: #111111;
+			}
+			image{
+				width: 30upx;
+				height: 30upx;
+			}
+		}
+		.data-list{
+			padding: 0upx 10upx 30upx;
+			display: flex;
+			flex-wrap: wrap;
+			.item{
+				padding: 0 30upx;
+				height: 56upx;
+				line-height: 56upx;
+				font-size: 26upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #333333;
+				background: #F5F5F5;
+				border-radius: 28upx;
+				margin: 0 20upx 20upx 0;
+			}
+		}
+	}
+</style>

+ 220 - 0
pages_mall/recommendList.vue

@@ -0,0 +1,220 @@
+<template>
+	<view class="page">
+		<view class="top-fixed">
+			<!-- 搜索框 -->
+			<view class="search-cont">
+				<view class="inner">
+					<image class="icon-search" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search.png" mode=""></image>
+					<input type="text" @confirm="goSearch"   :value="keyword" placeholder="输入商品名称" placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
+				</view>
+				<!-- <view class="icon-search">
+					<image @click="showChange(2)" v-if="showType==1"  src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search1.png" mode=""></image>
+					<image @click="showChange(1)" v-if="showType==2"  src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/search2.png" mode=""></image>
+				</view> -->
+			</view>
+			<!-- 排序框 -->
+		<!-- 	<view class="sort-box">
+				<view class="item" :class="form.defaultOrder=='desc'?'active':''" @click="searchChange('1')">
+					<text class="label">默认</text>
+				</view>
+				<view class="item" :class="form.defaultOrder=='desc'?'active':''" @click="searchChange('1')">
+					<text class="label">新品</text>
+				</view>
+				<view class="item" :class="form.defaultOrder=='desc'?'active':''" @click="searchChange('1')">
+					<text class="label">默认</text>
+				</view>
+				<view class="item" @click="searchChange('2')">
+					<text class="label">价格</text>
+					<view class="sort-img">
+						<image v-if="form.priceOrder==null||form.priceOrder=='desc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_up.png" mode="" @click="priceUp(true)"></image>
+						<image v-if="form.priceOrder=='asc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_up2.png" mode="" @click="priceUp(false)"></image>
+						<image v-if="form.priceOrder==null||form.priceOrder=='asc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_down.png" mode="" @click="priceDown(true)"></image>
+						<image v-if="form.priceOrder=='desc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_down2.png" mode="" @click="priceDown(false)"></image>
+					</view>
+				</view>
+				<view class="item" @click="searchChange('3')">
+					<text class="label">销量</text>
+					<view class="sort-img">
+						<image v-if="form.salesOrder==null||form.salesOrder=='desc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_up.png" mode="" @click="saleUp(true)"></image>
+						<image v-if="form.salesOrder=='asc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_up2.png" mode="" @click="saleUp(false)"></image>
+						<image v-if="form.salesOrder==null||form.salesOrder=='asc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_down.png" mode="" @click="saleDown(true)"></image>
+						<image v-if="form.salesOrder=='desc'" src="https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/price_arrow_down2.png" mode="" @click="saleDown(false)"></image>
+					</view>
+				</view>
+				<view class="item" :class="form.newOrder=='desc'?'active':''" @click="searchChange('4')">
+					<text class="label">新品</text>
+				</view>
+			</view> -->
+		</view>
+		<mescroll-body
+			top="100rpx" bottom="40rpx"
+			ref="mescrollRef"
+			@init="mescrollInit"
+			@down="downCallback"
+			@up="upCallback"
+			:down="downOption"
+			:up="upOption"
+		>
+			<view class="list-wrap">
+				<view class="goods-grid">
+					<view class="grid-item" v-for="(item, index) in dataList" :key="item.productId">
+						<GoodsCard :item="item" :show-price="true" @click="showProduct(item)" />
+					</view>
+				</view>
+			</view>
+		</mescroll-body>
+	</view>
+</template>
+
+<script>
+import { getHomeGoodsRecommend } from '@/api/home.js'
+import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'
+import GoodsCard from './components/GoodsCard.vue'
+
+export default {
+	name: 'RecommendList',
+	components: { GoodsCard },
+	mixins: [MescrollMixin],
+	data() {
+		return {
+			type: 'hot',
+			titleMap: { hot: '热卖有机', green: '上新推荐' },
+			mescroll: null,
+			keyword:'',
+			downOption: {},
+			upOption: {
+				onScroll: true,
+				use: true,
+				page: {
+					num: 0,
+					size: 10
+				},
+				noMoreSize: 10,
+				empty: {
+					icon: 'https://jnlzjk-1323137866.cos.ap-chongqing.myqcloud.com/shop/images/no_data.png',
+					tip: '暂无商品'
+				},
+				textNoMore: '已经到底了'
+			},
+			dataList: []
+		}
+	},
+	onLoad(options) {
+		this.type = (options.type || 'green').toLowerCase()
+		if (this.type !== 'green' && this.type !== 'hot') this.type = 'green'
+		uni.setNavigationBarTitle({ title: this.titleMap[this.type]})
+	},
+	methods: {
+		goSearch(e) {
+			this.keyword=e.detail.value;
+			this.mescroll.resetUpScroll();
+		},
+		mescrollInit(mescroll) {
+			this.mescroll = mescroll
+		},
+		downCallback(mescroll) {
+			mescroll.resetUpScroll()
+		},
+		upCallback(page) {
+			const that = this
+			getHomeGoodsRecommend({
+				keyword:this.keyword,
+				type: that.type,
+				pageNum: page.num,
+				pageSize: page.size
+			}).then(res => {
+				if(res.code==200){
+					//设置列表数据
+					if (page.num == 1) {
+						that.dataList = res.data.list; 
+						
+					} else {
+						that.dataList = that.dataList.concat(res.data.list);
+						 
+					}
+					that.mescroll.endBySize(res.data.list.length, res.data.total);
+					
+				}else{
+					uni.showToast({
+						icon:'none',
+						title: "请求失败",
+					});
+					that.dataList = null;
+					that.mescroll.endErr();
+				}
+			}).catch(() => {
+				that.dataList = page.num == 1 ? [] : that.dataList
+				that.mescroll.endErr()
+			})
+		},
+		showProduct(item) {
+			if (item && item.productId) {
+				uni.navigateTo({ url: '/pages/shopping/productDetails?productId=' + item.productId })
+			}
+		}
+	}
+}
+</script>
+
+<style lang="scss" scoped>
+	.top-fixed{
+		width: 100%;
+		position: fixed;
+		// top: 0;
+		left: 0;
+		z-index: 10;
+	}
+	.search-cont{
+		padding: 16upx 30upx;
+		background-color: #FFFFFF;
+		display:flex;
+		align-items: center;
+		justify-content: space-between;
+		.inner{
+			box-sizing: border-box;
+			width: 100%;
+			height: 72upx;
+			background: #F7F7F7;
+			border-radius: 36upx;
+			display: flex;
+			align-items: center;
+			padding: 0 30upx;
+			.icon-search{
+				width: 28upx;
+				height: 28upx;
+				margin-right: 20upx;
+			}
+			input{
+				height: 60upx;
+				line-height: 60upx;
+				flex: 1;
+			}
+			
+		}
+		.icon-search{
+			margin-left: 10upx;
+			width: 40upx;
+			height: 40upx;
+			image{
+				width: 40upx;
+				height: 40upx;
+			}
+			
+		}
+	}
+.page {
+	min-height: 100vh;
+	background: #f5f5f5;
+}
+.list-wrap {
+	padding: 24rpx;
+}
+.goods-grid {
+	display: flex;
+	flex-direction: column;
+	gap: 20rpx;
+}
+.goods-grid .grid-item {
+	width: 100%;
+}
+</style>

BIN
static/image/tabbar/cart.png


BIN
static/image/tabbar/cart_sel.png


BIN
static/image/tabbar/home.png


BIN
static/image/tabbar/home_sel.png


BIN
static/image/tabbar/mall.png


BIN
static/image/tabbar/mall_sel.png


BIN
static/image/tabbar/my.png


BIN
static/image/tabbar/my_sel.png


BIN
static/image/tabbar/video.png


BIN
static/image/tabbar/video_sel.png


BIN
static/images/bg.png


BIN
static/images/hot.png


BIN
static/images/launch/1080x1882.png


BIN
static/images/launch/1080x2340.png


BIN
static/images/launch/480.png


BIN
static/images/launch/720.png


BIN
static/images/new.png


BIN
static/images/new/back.png


BIN
static/images/new/banner.png


BIN
static/images/new/bofang.png


BIN
static/images/new/expand.png


BIN
static/images/new/jpk.png


BIN
static/images/new/nodata.png


BIN
static/images/new/renshu.png


BIN
static/images/new/search.png


BIN
static/images/new/time.png


BIN
static/images/new/title.png


BIN
static/images/new/yyx.png