XSLu08042 1 周之前
父節點
當前提交
74d9a14fcf
共有 56 個文件被更改,包括 2890 次插入1042 次删除
  1. 30 9
      api/myStoreOrder.js
  2. 1 1
      api/store.js
  3. 1 1
      common/request.js
  4. 117 0
      components/evaluateItem.vue
  5. 2 2
      components/medicineItem.vue
  6. 1 1
      components/tuiProduct.vue
  7. 29 1
      pages.json
  8. 1 1
      pages/auth/login.vue
  9. 27 6
      pages/index/index.vue
  10. 1 0
      pages/index/webview.vue
  11. 28 84
      pages/shopping/index.vue
  12. 0 2
      pages_company/storeOrderDetail.vue
  13. 39 10
      pages_order/prescribeDetails.vue
  14. 53 4
      pages_order/prescribeList.vue
  15. 1 1
      pages_order/storeOrderDetail.vue
  16. 2 1
      pages_shopping/api/product.js
  17. 92 67
      pages_shopping/cart.vue
  18. 234 109
      pages_shopping/confirmOrder.vue
  19. 146 0
      pages_shopping/evaluate.vue
  20. 361 0
      pages_shopping/evaluateDetail.vue
  21. 2 2
      pages_shopping/payOrder.vue
  22. 146 80
      pages_shopping/paymentOrder.vue
  23. 4 3
      pages_shopping/prescribe.vue
  24. 314 212
      pages_shopping/productDetails.vue
  25. 5 0
      pages_shopping/productList.vue
  26. 3 3
      pages_shopping/registerMerchant.vue
  27. 19 6
      pages_shopping/success.vue
  28. 100 53
      pages_shopping/user/otherPaymentOrder.vue
  29. 27 30
      pages_store/components/tuiStoreProduct.vue
  30. 147 99
      pages_store/storeIndex.vue
  31. 1 3
      pages_user/api/storeAfterSales.js
  32. 0 79
      pages_user/api/storeOrder.js
  33. 1 5
      pages_user/cert.vue
  34. 389 24
      pages_user/complaint.vue
  35. 14 4
      pages_user/complaintList.vue
  36. 41 8
      pages_user/complaintListDetail.vue
  37. 134 54
      pages_user/registerDoctor.vue
  38. 1 1
      pages_user/shopping/paymentOrderRemain.vue
  39. 35 5
      pages_user/shopping/storeOrder.vue
  40. 1 1
      pages_user/shopping/storeOrderDelivery.vue
  41. 35 8
      pages_user/shopping/storeOrderDetail.vue
  42. 8 0
      uni_modules/mescroll-uni/changelog.md
  43. 1 1
      uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue
  44. 5 5
      uni_modules/mescroll-uni/components/mescroll-empty/mescroll-empty.vue
  45. 29 13
      uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-top.vue
  46. 0 11
      uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js
  47. 9 6
      uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.vue
  48. 0 9
      uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js
  49. 5 2
      uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js
  50. 1 1
      uni_modules/mescroll-uni/components/mescroll-uni/wxs/renderjs.js
  51. 1 0
      uni_modules/mescroll-uni/components/mescroll-uni/wxs/wxs.wxs
  52. 66 0
      uni_modules/mescroll-uni/hooks/useMescroll.js
  53. 56 0
      uni_modules/mescroll-uni/hooks/useMescrollComp.js
  54. 69 0
      uni_modules/mescroll-uni/hooks/useMescrollMore.js
  55. 10 14
      uni_modules/mescroll-uni/package.json
  56. 45 0
      uni_modules/mescroll-uni/readme.md

+ 30 - 9
pages_shopping/api/storeOrder.js → api/myStoreOrder.js

@@ -16,25 +16,39 @@ let request = new Request().http
  export function getStoreOrderById(data) {
  	 return request('/store/app/storeOrder/getStoreOrderById',data,'GET');
  } 
- 
- 
+  export function getStoreOrderByCombinationId(data) {
+  	 return request('/store/app/storeOrder/getStoreOrderByCombinationId',data,'GET');
+  }
+  export function otherPaymentByCombinationId(data) {
+  	 return request('/store/app/storeOrder/otherPaymentByCombinationId',data,'POST','application/json;charset=UTF-8');
+  }
  export function confirm(data) {
- 	 return request('/store/app/storeOrder/confirm',data,'POST','application/json;charset=UTF-8');
+	 return request('/store/app/storeOrder/confirmMultiStore',data,'POST','application/json;charset=UTF-8');
+ 	 // return request('/store/app/storeOrder/confirm',data,'POST','application/json;charset=UTF-8');
  }
  export function computed(data) {
- 	 return request('/store/app/storeOrder/computed',data,'POST','application/json;charset=UTF-8');
+	 return request('/store/app/storeOrder/computedMultiStore',data,'POST','application/json;charset=UTF-8');
+ 	 // return request('/store/app/storeOrder/computed',data,'POST','application/json;charset=UTF-8');
  }
  export function create(data) {
- 	 return request('/store/app/storeOrder/create',data,'POST','application/json;charset=UTF-8');
+	 return request('/store/app/storeOrder/createMultiStore',data,'POST','application/json;charset=UTF-8');
+ 	 // return request('/store/app/storeOrder/create',data,'POST','application/json;charset=UTF-8');
  }
  export function pay(data) {
  	 return request('/store/app/storeOrder/pay',data,'POST','application/json;charset=UTF-8');
  }
- 
+ export function payByCombinationId(data) {
+ 	 return request('/store/app/storeOrder/payByCombinationId',data,'POST','application/json;charset=UTF-8');
+ }
  export function editPayType(data) {
  	 return request('/store/app/storeOrder/editPayType',data,'POST','application/json;charset=UTF-8');
  }
  
+  export function editPayTypeByCombinationId(data) {
+  	 return request('/store/app/storeOrder/editPayTypeByCombinationId',data,'POST','application/json;charset=UTF-8');
+  }
+ 
+ 
  export function payRemain(data) {
  	 return request('/store/app/storeOrder/payRemain',data,'POST','application/json;charset=UTF-8');
  }
@@ -73,7 +87,14 @@ let request = new Request().http
  export function getOrderCount() {
  	 return request('/store/app/storeOrder/getOrderCount',null,'GET');
  } 
+
+ export function addOrderComment(data) {
+ 	 return request('/store/app/storeOrder/addOrderComment',data,'POST','application/json;charset=UTF-8');
+ }
  
- 
- 
- 
+ export function selectCommentByUser(data) {
+ 	 return request('/store/app/storeOrder/selectFsStoreOrderScrmCommentByUser',data,'POST','application/json;charset=UTF-8');
+ }
+ export function orderPrescription(id) {
+ 	 return request('/store/app/storeOrder/orderPrescription/'+id,null,'GET');
+ }

+ 1 - 1
api/store.js

@@ -2,7 +2,7 @@ import Request from '../common/request.js';
 let request = new Request().http
  
 export function getStoreList(data) {
-	return request('/app/store/getStoreList', data, 'GET');
+	return request('/store/app/store/getStoreList', data, 'GET');
 }
 // 开票
 export function bill(data) {

+ 1 - 1
common/request.js

@@ -7,7 +7,7 @@ export default class Request {
 		// var path = 'https://userapp.his.cdwjyyh.com';
 		// var path = 'https://app.rtys.cdwjyyh.com';
 		var path = "https://userapp.bjyjbao.com/prod-api"
-		// var path = "http://f5778469.natappfree.cc"
+		// var path = "http://u7f8b756.natappfree.cc"
 		// var path = "http://192.168.10.126:8113"
 		let token="";
 		let type = 0

+ 117 - 0
components/evaluateItem.vue

@@ -0,0 +1,117 @@
+<template>
+	<view class="comment-item">
+		<!-- 头像 + 昵称 -->
+		<view class="header">
+			<image class="avatar"
+				:src="item.userAvatar || 'https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/my_heads_icon.png'"
+				mode="aspectFill" />
+			<text class="nick ellipsis">{{item.nickName}}</text>
+			<text class="date">{{item.createTime}}</text>
+		</view>
+
+		<!-- 星级 -->
+		<view class="stars">
+			<u-rate active-color="#FF6633" :count="item.rating" v-model="item.rating" readonly size="14"></u-rate>
+		</view>
+
+		<!-- 文字评价 -->
+		<text class="content ellipsis2">{{item.content}}</text>
+
+		<!-- 图片缩略图 -->
+		<view class="pics" v-if="item.imageUrl && item.imageUrl.length">
+			<image v-for="(img,idx) in item.imageUrl.split(',')" :key="idx" class="pic" :src="img" mode="aspectFill"
+				@tap="preview(item.imageUrl,idx)" />
+		</view>
+		<view class="merchantReply" v-show="item.merchantReply">
+			商家回复: {{item.merchantReply}}
+		</view>
+		<view v-show="showLine!=0">
+			<u-line margin="20rpx 0rpx"></u-line>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: ['item','showLine'],
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			preview(img, current) {
+				const urls = img.split(',')
+				uni.previewImage({
+					urls,
+					current
+				});
+			},
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	.merchantReply {
+		padding: 20rpx;
+		font-size: 28rpx;
+		color: #999;
+		background: #f5f5f5;
+		margin-top: 6rpx;
+		border-radius: 10rpx;
+	}
+	.comment-item {
+		margin-bottom: 20rpx;
+		background-color: #ffff;
+		border-radius: 10rpx;
+
+		.header {
+			display: flex;
+			align-items: center;
+		}
+
+		.avatar {
+			width: 64rpx;
+			height: 64rpx;
+			border-radius: 50%;
+			margin-right: 16rpx;
+		}
+
+		.nick {
+			flex: 1;
+			font-size: 28rpx;
+			color: #333;
+			display: block;
+		}
+
+		.date {
+			font-size: 24rpx;
+			color: #999;
+		}
+
+		.stars {
+			margin: 12rpx 0;
+		}
+
+		.content {
+			font-size: 30rpx;
+			color: #555;
+			margin-top: 12rpx;
+			line-height: 1.6;
+		}
+
+		.pics {
+			display: flex;
+			flex-wrap: wrap;
+			margin-top: 16rpx;
+		}
+
+		.pic {
+			width: 160rpx;
+			height: 160rpx;
+			margin-right: 12rpx;
+			margin-bottom: 12rpx;
+			border-radius: 8rpx;
+		}
+	}
+</style>

+ 2 - 2
components/medicineItem.vue

@@ -33,7 +33,7 @@
 
 <script>
 	export default {
-		props: ['item','type'],
+		props: ['item','type','storeId'],
 		data() {
 			return {
 				
@@ -60,7 +60,7 @@
 			},
 			showProduct() {
 				uni.navigateTo({
-					url: '/pages_shopping/productDetails?productId=' + this.item.productId
+					url: '/pages_shopping/productDetails?productId=' + this.item.productId+'&storeId='+this.storeId || ''
 				})
 			},
 		}

+ 1 - 1
components/tuiProduct.vue

@@ -26,7 +26,7 @@
 			return {
 				page: {
 					page: 1,
-					pageSize: 10
+					pageSize: 4
 				},
 				total: 0,
 				list: [],

+ 29 - 1
pages.json

@@ -965,7 +965,7 @@
 				    "path" : "registerDoctor",
 				    "style" :                                                                                    
 				    {
-				        "navigationBarTitleText": "注册医生",
+				        "navigationBarTitleText": "注册",
 						"navigationBarTextStyle": "black",
 						"navigationBarBackgroundColor": "#ffffff"
 				    }
@@ -2057,6 +2057,34 @@
 				// 	}
 					
 				// },
+				{
+				    "path" : "evaluate",
+				    "style" :                                                                                    
+				    {
+				        "navigationBarTitleText": "商品评价",
+						"enablePullDownRefresh": false,
+						"navigationBarTextStyle": "black",
+						"navigationBarBackgroundColor": "#ffffff",
+						"app-plus": {
+							"titleNView": false
+						}
+				    }
+				    
+				},
+				{
+				    "path" : "evaluateDetail",
+				    "style" :                                                                                    
+				    {
+				        "navigationBarTitleText": "商品评价",
+						"enablePullDownRefresh": false,
+						"navigationBarTextStyle": "black",
+						"navigationBarBackgroundColor": "#ffffff",
+						"app-plus": {
+							"titleNView": false
+						}
+				    }
+				    
+				},
 				{
 				    "path" : "registerMerchant",
 				    "style" :                                                                                    

+ 1 - 1
pages/auth/login.vue

@@ -188,7 +188,7 @@ export default {
 											uni.setStorageSync('AppToken', res.token);
 											uni.setStorageSync('userId', res.user.userId);
 											uni.setStorageSync('avatar', res.user.avatar);
-											uni.setStorageSync('nickName', res.user.nickName);
+											uni.setStorageSync('nickName', res.user.nickName || res.user.nickname);
 											if (res.user.isWeixinAuth == 0) {
 												that.wxAuthOpen();
 											} else {

+ 27 - 6
pages/index/index.vue

@@ -262,13 +262,15 @@
 									<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/index/white_right_arrow_right_icon.png" mode="aspectFill"></image>
 								</view>
 							</view>
-							<view class="text" style="margin-top: 6rpx;">药品交易平台备案:XXXXX</view>
-							<view class="text" style="margin-top: 6rpx;">医疗器械交易平台备案:XXXXX</view>
+							<view class="text" style="margin-top: 6rpx;">药品交易平台备案:{{qual.icpztbah}}</view>
+							<view class="text" style="margin-top: 6rpx;">医疗器械交易平台备案:{{qual.ylqxwljyfwdsfptbah}}</view>
+							<view class="text" style="margin-top: 6rpx;">互联网药品信息服务备案:{{qual.hlwypxxfwba}}</view>
+							<view class="text" style="margin-top: 6rpx;">第三方平台备案:{{qual.ypwljyfwdsfpt}}</view>
 						</view>
 					</view>
 					<view>
-						<text class="text" style="margin-right: 40rpx;">投诉举报邮箱:Yijabao@163.com</text>
-						<text class="text">联系电话:13466304507</text>
+						<text class="text" style="margin-right: 40rpx;">投诉举报邮箱:{{qual.jbyx}}</text>
+						<text class="text">联系电话:{{qual.baxx}}</text>
 					</view>
 				</view>
 			</view>
@@ -320,7 +322,8 @@
 				doctocArticles:[],
 				hosLevelOptions:[],
 				packages:[],
-				storeIndexList: []
+				storeIndexList: [],
+				qual: {}
 			}
 		},
 		onLoad() {
@@ -360,14 +363,21 @@
 			this.getDoctorList();
 			this.getArticleList();
 			this.getAdvList();
-			this.getCartCount();
 			// this.getDepartmentList();
 			// this.getDoctorArticleList();
 			// this.getPackageList();
 			this.getConfigByKey("his.appShow");
+			this.getQual()
 			this.getStore()
 			var that=this;
 			uni.$emit('refreshMsgCount');
+			this.$isLogin().then(
+				res => {
+					if(res){
+						this.getCartCount();
+					}
+				}
+			);
 		},
 		onPageScroll(e) {
 			this.top=e.scrollTop;
@@ -435,6 +445,17 @@
 				);
 				
 			},
+			getQual(){
+				let param = {key:"his.zzzs"};
+				getConfigByKey(param).then(
+					res => {
+						if(res.code==200){
+							this.qual = res.data ? JSON.parse(res.data) : {}
+						}
+					},
+					rej => {}
+				);
+			},
 			getConfigByKey(key){
 				var that=this;
 				var data={key:key}

+ 1 - 0
pages/index/webview.vue

@@ -25,6 +25,7 @@ export default {
 		if(options.type = 'prescribe') {
 			// 开方
 			this.url = decodeURIComponent(options.url);
+			console.log("开方url",this.url)
 		} else{
 			this.schemeUrl = decodeURIComponent(options.url);
 			console.log('Scheme 数据:', this.schemeUrl); // 输出:rtlive://course?courseId=1

+ 28 - 84
pages/shopping/index.vue

@@ -12,8 +12,8 @@
 				</view>
 			</view>
 		</view>
-		<view  :style="{height: divHeight}"   class="medic-box">
-			<view class="cate-list">
+		<view   class="medic-box">
+			<view class="cate-list" :style="{top: mescrollTop+'px',height:divHeight}" >
 				<view 
 					v-for="(item,index) in cates" 
 					:key="index" 
@@ -40,23 +40,11 @@
 					</swiper>
 				</view> -->
 				<!-- 药品列表 -->
-			<!-- 	<view class="medic-list">
-						<view class="item" v-for="(item,index) in subCates" :key="index">
-							<view class="title">{{item.cateName}}</view>
-							<view class="inner-list">
-								<view class="definite"v-for="(subItem,index) in subCates"   @click="showProductList(subItem)">
-									<view class="img-box">
-										<image :src="subItem.pic" mode="aspectFit"></image>
-									</view>
-									<view class="name ellipsis">{{subItem.cateName}}</view>
-								</view>
-							</view>
-						</view>
-				</view> -->
-				<mescroll-body ref="mescrollRef" :height="mescrollHeight+'px'" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
-				<view style="display: flex;flex-wrap: wrap;">
-					<medicineVerticalItem v-for="(item, index) in dataList" :key="index" :item="item"></medicineVerticalItem>
-				</view>
+				<mescroll-body :top="mescrollTop+'px'" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
+					<view style="padding-right: 16rpx;">
+						<medicineItem v-for="(item, index) in dataList" :key="index" :item="item"></medicineItem>
+						<!-- <medicineVerticalItem v-for="(item, index) in dataList" :key="index" :item="item"></medicineVerticalItem> -->
+					</view>
 				</mescroll-body>
 			</view>
 		</view>
@@ -67,11 +55,13 @@
 	import {getProductCate,getProducts} from '@/api/index.js'
 	import {getAdv} from '@/api/adv'
 	import medicineVerticalItem from "@/components/medicineVerticalItem";
+	import medicineItem from "@/components/medicineItem";
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		mixins: [MescrollMixin], // 使用mixin
 		components: {
-			medicineVerticalItem
+			medicineVerticalItem,
+			medicineItem
 		},
 		data() {
 			return {
@@ -117,7 +107,7 @@
 					cateId:'',
 					pid:''
 				},
-				mescrollHeight: 200
+				mescrollTop: 200
 			};
 		},
 		onLoad() {
@@ -129,20 +119,17 @@
 			this.getProductCate();
 		},
 		onShow() {
-			var that=this;
+			let that=this;
 			setTimeout(function(){
 				let info = uni.createSelectorQuery().select(".top-content");
 		     info.boundingClientRect(function(data) { //data - 各种参数
 					that.divHeight="calc(100vh - "+data.height+"px)"
-					that.mescrollHeight = uni.getSystemInfoSync().screenHeight - data.height
+					that.mescrollTop = data.height
 		      }).exec()
 			},500);
 			this.getAdv();
 		},
 		methods:{
-			// divHeight(){
-			//    return 'height:calc(100% - ${this.top}px);'
-			// },
 			splitPrice(num) {
 			  const [intPart = '0', decPart = '00'] = String(num||0).split('.');
 			  return { intPart, decPart: decPart.padEnd(2, '0').slice(0, 2) };
@@ -253,7 +240,6 @@
 				mescroll.resetUpScroll()
 			},
 			upCallback(page) {
-				console.log("==upCallback==")
 				//联网加载数据
 				var that = this;
 				this.form.page=page.num;
@@ -297,6 +283,10 @@
 		.top-content{
 			width: 100%;
 			z-index: 10;
+			position: fixed;
+			left: 0;
+			top: 0;
+			background-color: #FFFFFF;
 			.top-title{
 				height: 88upx;
 				line-height: 88upx;
@@ -332,11 +322,18 @@
 				}
 			}
 		}
+		::v-deep{
+			.mescroll-body, .mescroll-body{
+				padding-left: 204rpx;
+			}
+		}
 		.medic-box{
-			display: flex;
 			.cate-list{
+				position: fixed;
+				left: 0;
+				z-index: 999;
 				box-sizing: border-box;
-				width: 200upx;
+				width: 180upx;
 				background: #F2F5F9;
 				display: flex;
 				flex-direction: column;
@@ -345,7 +342,7 @@
 				.item{
 					height: 100upx;
 					line-height: 100upx;
-					padding-left: 30upx;
+					padding-left: 20upx;
 					font-size: 28upx;
 					font-family: PingFang SC;
 					font-weight: 500;
@@ -366,10 +363,8 @@
 				}
 			}
 			.medic{
+				overflow: hidden;
 				box-sizing: border-box;
-				width: calc(100% - 200upx);
-				height: 100%;
-				margin: 0 24upx;
 				.banner-box{
 					margin-top: 30rpx;
 					width: 100%;
@@ -383,57 +378,6 @@
 						height: 100%;
 					}
 				}
-				.medic-list{
-					box-sizing: border-box;
-					padding: 30upx 0;
-					overflow-y: auto;
-					height: calc(100% - 220upx);
-					position: relative;
-					// .item{
-					// 	.title{
-					// 		font-size: 28upx;
-					// 		font-family: PingFang SC;
-					// 		font-weight: bold;
-					// 		color: #333333;
-					// 		padding-top: 20upx;
-					// 		margin-bottom: 30upx;
-					// 	}
-						
-					// }
-					.inner-list{
-						display: flex;
-						flex-wrap: wrap;
-						.definite{
-							width: calc(33% - 20upx);
-							margin-right: 30upx;
-							margin-bottom: 30upx;
-							.img-box{
-								width: 100%;
-								height: 144upx;
-								background: #F5F5F5;
-								border-radius: 8upx;
-								overflow: hidden;
-								display: flex;
-								align-items: center;
-								image{	
-									max-width: 100%;
-								}
-							}
-							.name{
-								width: 100%;
-								margin-top: 20upx;
-								font-size: 24upx;
-								font-family: PingFang SC;
-								font-weight: 500;
-								color: #666666;
-								text-align: center;
-							}
-							&:nth-child(3n) {
-								margin-right: 0;
-							}
-						}
-					}
-				}
 			}
 		}
 		

+ 0 - 2
pages_company/storeOrderDetail.vue

@@ -262,7 +262,6 @@
 							};
 							cancelOrder(data).then(res => {
 								if(res.code==200){
-									 that.getMyStoreOrderById()
 									 uni.$emit('refreshStoreOrder');
 								}else{
 									uni.showToast({
@@ -289,7 +288,6 @@
 							};
 							finishOrder(data).then(res => {
 								if(res.code==200){
-									 that.getMyStoreOrderById()
 									 uni.$emit('refreshStoreOrder');
 								}else{
 									uni.showToast({

+ 39 - 10
pages_order/prescribeDetails.vue

@@ -6,19 +6,19 @@
 				<view class="item">
 					<view class="left">
 						<text class="label">医生姓名:</text>
-						<text class="text">{{prescribe.doctorName}} </text>
+						<text class="text">{{prescribe.doctorName || '--'}} </text>
 					</view>
 				</view>
 				<view class="item">
 					<view class="left">
 						<text class="label">患者姓名:</text>
-						<text class="text">{{prescribe.userFamilyName}} </text>
+						<text class="text">{{prescribe.userFamilyName || '--'}} </text>
 					</view>
 				</view>
 				<view class="item">
 					<view class="left">
 						<text class="label">患者年龄:</text>
-						<text class="text">{{prescribe.userFamilyAge}}岁 </text>
+						<text class="text">{{prescribe.userFamilyAge || '--'}}岁 </text>
 					</view>
 				</view>
 				<view class="item">
@@ -33,19 +33,19 @@
 				<view class="item">
 					<view class="left">
 						<text class="label">处方单号:</text>
-						<text class="text">{{prescribe.pid}}</text>
+						<text class="text">{{prescribe.pid || '--'}}</text>
 					</view>
 				</view>
 				<view class="item">
 					<view class="left">
 						<text class="label">开方时间:</text>
-						<text class="text">{{prescribe.createdTime}}</text>
+						<text class="text">{{prescribe.createdTime || '--'}}</text>
 					</view>
 				</view>
 				<view class="item">
 					<view class="left">
 						<text class="label">医生诊断:</text>
-						<view class="text">{{prescribe.tags}}</view>
+						<view class="text">{{prescribe.tags || '--'}}</view>
 					</view>
 				</view>
 				<view class="item" v-if="prescribe.status==2">
@@ -54,6 +54,18 @@
 						<text class="text">{{prescribe.reason}}</text>
 					</view>
 				</view>
+				<view class="item">
+					<view class="left">
+						<text class="label">审方时间:</text>
+						<text class="text">{{prescribe.auditTime || '--'}}</text>
+					</view>
+				</view>
+				<view class="item">
+					<view class="left">
+						<text class="label">审方药师:</text>
+						<text class="text">{{prescribe.auditApothecaryName || '--'}}</text>
+					</view>
+				</view>
 			</view>
 			<view class="drug-cont"  >
 				<view class="title">药品信息</view>
@@ -139,8 +151,11 @@
 				<view class="title">处方单</view>
 				<image style="width: 100%;" :src="prescribe.dstFilePath" mode="widthFix" @click="showImg"></image>
 			</view>
-			<view class="btn-box">
-				<view class="btn pay" v-if="prescribe.storeOrderId!=null&&prescribe.storeOrderId>0&&prescribe.status==1"  @click="navTo('/pages_order/storeOrderDetail?orderId='+prescribe.storeOrderId)">药品订单</view>
+			<view class="btn-box"  v-if="source!='order'&&prescribe.status==0">
+				<view class="btn pay" @click="addPrescribe">进入开方</view>
+			</view>
+			<view class="btn-box"  v-if="source!='order'&&prescribe.storeOrderId!=null&&prescribe.storeOrderId>0&&prescribe.status==1">
+				<view class="btn pay" @click="navTo('/pages_order/storeOrderDetail?orderId='+prescribe.storeOrderId)">药品订单</view>
 			</view>
 		</view>
 	</view>
@@ -155,11 +170,13 @@
 				drugs:[],
 				prescribe:null,
 				prescribeId:null,
-				usage:{}
+				usage:{},
+				source: '', // order从订单详情来的
 			}
 		},
 		 
 		onLoad(options) {
+			this.source = options.source || ''
 			if(options.prescribeId!=null){
 				this.prescribeId=options.prescribeId;
 			}
@@ -220,7 +237,19 @@
 				uni.navigateTo({
 					url: url
 				})
-			} 
+			},
+			addPrescribe() {
+				if(!this.prescribe.jumpUrl) {
+					uni.showToast({
+						icon:'none',
+						title: "暂无开方链接",
+					});
+					return
+				}
+				uni.navigateTo({
+				 	url: '/pages/index/webview?url='+encodeURIComponent(this.prescribe.jumpUrl)
+				})
+			}
 		}
 	}
 </script>

+ 53 - 4
pages_order/prescribeList.vue

@@ -14,9 +14,9 @@
 					<view class="ordersn-box">
 						<view class="num">处方单号:{{item.pid||''}}</view>
 						<view class="status-box">
-							<text   class="text info" v-if="item.status==0">待开方</text>
-							<text   class="text success" v-if="item.status==1">已开方</text>
-							<text   class="text black" v-if="item.status==2">已拒绝</text>
+							<text   class="text black" v-if="item.prescriptionStatusByOrderStatus==1">待生效</text>
+							<text   class="text success" v-if="item.prescriptionStatusByOrderStatus==2">已生效</text>
+							<text   class="text info" v-if="item.prescriptionStatusByOrderStatus==3">已失效</text>
 						</view>
 					</view>
 					<view class="ask-text"  >诊断结果:{{item.tags||''}}</view>
@@ -33,6 +33,11 @@
 					<view class="patient-text">患者:{{item.userFamilyName}} {{item.userFamilyAge}}岁 {{item.userFamilyGender==1?'男':'女'}} </view>
 					<view class="ask-time" v-if="item.createTime!=null">提交时间:{{item.createTime}}</view>
 					<view class="ask-time" v-if="item.createdTime!=null">开方时间:{{item.createdTime}}</view>
+					<view class="bottom-box">
+						<view class="btn-box">
+							<view class="btn pay"  v-if="status==0"  @click.stop="addPrescribe(item)">进入开方</view>
+						</view>
+					</view>
 				</view>
 		</view>
 		</mescroll-body>
@@ -139,12 +144,56 @@
 				 	urls: imgArr,
 				 	current: imgArr[0]
 				 });
+			},
+			addPrescribe(item) {
+				if(!item.jumpUrl) {
+					uni.showToast({
+						icon:'none',
+						title: "暂无开方链接",
+					});
+					return
+				}
+				uni.navigateTo({
+				 	url: '/pages/index/webview?url='+encodeURIComponent(item.jumpUrl)
+				})
 			}
 		}
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
+	.bottom-box{
+		display: flex;
+		align-items: center;
+		justify-content: flex-end;
+		.btn-box{
+			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;
+				margin-left: 15upx;
+				&:first-child{
+					margin-left: 0;
+				}
+				&.cancel{
+					border: 1px solid #DDDDDD;
+					color: #666666;
+				}
+				&.pay{
+					background: #2BC7B9;
+					color: #FFFFFF;
+				}
+			}
+		}
+	}
 	.content{
 		.top-fixed{
 			width: 100%;

+ 1 - 1
pages_order/storeOrderDetail.vue

@@ -211,7 +211,7 @@
 <script>
 	import {getPrescribeById} from '@/api/prescribe.js'
 	
-	import {getMyStoreOrderById,cancelOrder,finishOrder,splitOrder2ERP} from '@/api/storeOrder'
+	import {getMyStoreOrderById,cancelOrder,finishOrder,splitOrder2ERP} from '@/api/myStoreOrder.js'
 	export default {
 		data() {
 			return {

+ 2 - 1
pages_shopping/api/product.js

@@ -17,7 +17,8 @@ let request = new Request().http
  	 return request('/store/app/product/getProductDetails',data,'GET');
  }
  export function getCarts(data) {
- 	 return request('/store/app/product/getCarts',data,'GET');
+ 	 // return request('/store/app/product/getCarts',data,'GET');
+	 return request('/store/app/product/getCartsMultiStore',data,'GET');
  }
  export function addCart(data) {
  	 return request('/store/app/product/addCart',data,'POST','application/json;charset=UTF-8');

+ 92 - 67
pages_shopping/cart.vue

@@ -1,42 +1,49 @@
 <template>
 	<view class="content">
 		<!-- 商品列表 -->
-		<view class="goods-list">
-			<view class="item" v-for="(item,index) in carts" :key="index">
+		<view class="shopbox" v-for="(shop,idx) in carts" :key="idx">
+			<view class="shopbox-name" v-if="shop.storeName && shop.storeName != 'null'">
 				<label style="margin-right: 30upx;">
-					<checkbox :value="item.checked"  :checked="item.checked" @click="checkChange(item)" />
+					<checkbox :value="shop.checked" :checked="shop.checked" @click="checkShopChange(shop)" style="transform: scale(0.9);" />
 				</label>
-				<image class="goods-img" :src="item.productAttrImage==null||item.productAttrImage==''?item.productImage:item.productAttrImage" mode="aspectFit"></image>
-				<view class="info-box">
-					<view>
-						<view class="title-box">
-							<view class="tag" :style="{background:_background(item.productType)}">{{$getDictLabelName("storeProductType",item.productType)}}</view>
-							<view class="title ellipsis">{{ item.productName }}</view>
-						</view>
-						<view class="intro ellipsis">{{item.productAttrName}}</view>
-					</view>
-					<view class="price-num">
-						<view class="price">
-							<text class="unit">¥</text>
-							<text class="text">{{item.price}}</text>
+				<text>{{shop.storeName}}</text>
+			</view>
+			<view class="goods-list">
+				<view class="item" v-for="(item,index) in shop.list" :key="index">
+					<label style="margin-right: 30upx;">
+						<checkbox :value="item.checked"  :checked="item.checked" @click="checkChange(item,shop)" style="transform: scale(0.9);" />
+					</label>
+					<image class="goods-img" :src="item.productAttrImage==null||item.productAttrImage==''?item.productImage:item.productAttrImage" mode="aspectFit"></image>
+					<view class="info-box">
+						<view>
+							<view class="title-box">
+								<view class="tag">{{$getDictLabelName("storeProductType",item.productType)}}</view>
+								<view class="title ellipsis">{{ item.productName }}</view>
+							</view>
+							<view class="intro ellipsis">{{item.productAttrName}}</view>
 						</view>
-						<view class="num-box">
-							<view class="img-box" @click="delNum(item)">
-								<image v-if="item.cartNum <= 1" src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/jian.png" mode=""></image>
-								<image v-else src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/jian2.png" mode=""></image>
+						<view class="price-num">
+							<view class="price">
+								<text class="unit">¥</text>
+								<text class="text">{{item.price}}</text>
 							</view>
-							<input  type="number" @change="changeNum($event,item)" :value="item.cartNum"   />
-							<view class="img-box" @click="addNum(item)">
-								<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/add.png" mode=""></image>
+							<view class="num-box">
+								<view class="img-box" @click="delNum(item)">
+									<image v-if="item.cartNum <= 1" src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/jian.png" mode=""></image>
+									<image v-else src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/jian2.png" mode=""></image>
+								</view>
+								<input  type="number" @change="changeNum($event,item)" :value="item.cartNum"   />
+								<view class="img-box" @click="addNum(item)">
+									<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/add.png" mode=""></image>
+								</view>
 							</view>
 						</view>
 					</view>
 				</view>
 			</view>
 		</view>
-	 
 		<view v-if="carts.length == 0" class="no-data-box">
-			<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/empty_icon.png" mode="aspectFit"></image>
+			<image src="https://cos.his.cdwjyyh.com/fs/20240423/cf4a86b913a04341bb44e34bb4d37aa2.png" mode="aspectFit"></image>
 			<view class="empty-title">暂无数据</view>
 		</view>
 		<!-- 猜你喜欢 -->
@@ -48,7 +55,7 @@
 		<view class="btn-foot">
 			<view class="left">
 				<label>
-					<checkbox  :checked="checkAll" @click="handleCheckAll()" />
+					<checkbox  :checked="checkAll" @click="handleCheckAll()" style="transform: scale(0.9);" />
 				</label>
 				<text class="text">全选</text>
 				<text class="text" @click="delCart()">删除</text>
@@ -69,8 +76,8 @@
 </template>
 
 <script>
-	import {getCarts,cartNum,delCart} from './api/product'
-	// import likeProduct from './components/likeProduct.vue'
+	import {getCarts,cartNum,delCart} from './api/product.js'
+	// import likeProduct from '@/components/likeProduct.vue'
 	export default {
 		// components: {
 		// 	likeProduct
@@ -83,32 +90,13 @@
 				checkAll:false,
 			}	
 		},
-		onLoad() {
+		onShow() {
 			this.getCarts();
- 
-		},
-		onReachBottom() {
-			// this.$refs.product.getGoodsProducts();
-		},
-		computed: {
-			_background() {
-				//productType: 1:OTC,2:Rx,3:非药品,4:器械
-				return (productType)=> {
-					switch (productType) {
-						case 1: return '#37E2EA' // OTC
-						case 2: return 'red'     // Rx
-						case 3: return '#2583EB' // 非药品
-						case 4: return '#999'    // 器械
-						default: return '#ccc'
-					}
-				}
-			}
 		},
 		methods: {
-			delCart(){
-				var selectCarts=this.carts.filter(ele => ele.checked==true).map(ele => {
-				  return ele.id
-				});
+			delCart(){			
+				var selectCarts = this.carts.flatMap(item => item.list.filter(listItem => listItem.checked === true)).map(el => el.id);
+				
 				if(selectCarts.length==0){
 					uni.showToast({
 						icon:'none',
@@ -135,17 +123,17 @@
 					},
 					rej => {}
 				);
-				console.log(selectCarts)
 			},
 			computedMoney(){
 				var money=0;
 				var that=this;
 				this.carts.forEach((item,index,arr)=>{
-					 if(item.checked){
-						 money+=item.price*item.cartNum;
-					 }
+					item.list.forEach(it => {
+						if(it.checked){
+							money+=it.price*it.cartNum;
+						}
+					});
 				})
-				console.log(money);
 				this.totalMoney=money;
 			},
 			handleCheckAll(){
@@ -153,11 +141,24 @@
 				var that=this;
 				this.carts.forEach((item,index,arr)=>{
 				     item.checked=that.checkAll;
+					 item.list.forEach(it => {
+					 	it.checked=that.checkAll;
+					 });
 				})
 				this.computedMoney();
 			},
-			checkChange(item){
+			checkShopChange(item) {
+				item.checked = !item.checked;
+				item.list.forEach(it => {
+					it.checked= item.checked;
+				});
+				this.checkAll = this.carts.every(it => it.checked == true);
+				this.computedMoney();
+			},
+			checkChange(item,shop){
 				item.checked=!item.checked;
+				shop.checked = shop.list.every(it => it.checked == true);
+				this.checkAll = this.carts.every(it => it.checked == true);
 				this.computedMoney();
 			},
 			changeNum(e,item) {
@@ -205,9 +206,12 @@
 					res => {
 						if(res.code==200){
 							 this.carts=res.carts;
-							 this.carts.forEach((item,index,arr)=>{
-							      item.checked=false;
-							 })
+							 this.carts.forEach(item => {
+							   item.checked = false;
+							   item.list.forEach(it => {
+							     it.checked = false;
+							   });
+							 });
 							 this.computedMoney();
 						}else{
 							uni.showToast({
@@ -247,9 +251,15 @@
 			},
 			// 结算
 			submit() {
-				var selectCarts=this.carts.filter(ele => ele.checked==true).map(ele => {
-				  return ele.id
-				});
+				let selectCarts = this.carts
+				  .filter(item => item.list.some(listItem => listItem.checked === true))
+				  .map(item => ({
+				    storeId: item.list[0].storeId || "",
+				    data: {
+				      type: "cart",
+				      cartIds: item.list.filter(it=>it.checked == true).map(it => it.id).join(","),
+				    }
+				  }));
 				if(selectCarts.length==0){
 					uni.showToast({
 						icon:'none',
@@ -258,7 +268,7 @@
 					return;
 				}
 				uni.navigateTo({
-					url: './confirmOrder?type=cart&cartIds='+selectCarts.toString()
+					url: './confirmOrder?type=cart&confirmParam='+ encodeURIComponent(JSON.stringify(selectCarts))
 				})
 			},
 			showProduct(item){
@@ -277,6 +287,21 @@
 	.content{
 		height: 100%;
 		padding: 20upx;
+		.shopbox {
+			background: #FFFFFF;
+			border-radius: 16rpx;
+			margin-bottom: 20rpx;
+		}
+		.shopbox-name {
+			padding: 30rpx 30rpx 0 30rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			font-size: 30rpx;
+			color: #111;
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+		}
 		.goods-list{
 			.item{
 				box-sizing: border-box;
@@ -315,7 +340,7 @@
 							font-family: PingFang SC;
 							font-weight: bold;
 							color: #FFFFFF;
-							background: linear-gradient(90deg, #2583EB 0%, #92C1F5 100%);
+							background: linear-gradient(90deg, #66b2ef 0%, #0bb3f2 100%);
 							border-radius: 4upx;
 							margin-right: 10upx;
 							flex-shrink: 0;
@@ -327,10 +352,10 @@
 							font-weight: 500;
 							color: #111111;
 							line-height: 1;
+							display: block;
 						}
 					}
 					.intro{
-						display: block;
 						font-size: 24upx;
 						font-family: PingFang SC;
 						font-weight: 500;
@@ -467,7 +492,7 @@
 					font-family: PingFang SC;
 					font-weight: bold;
 					color: #FFFFFF;
-					background: #2583EB;
+					background: #0bb3f2;
 					border-radius: 44upx;
 				}
 			}

+ 234 - 109
pages_shopping/confirmOrder.vue

@@ -28,77 +28,108 @@
 				</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!=null?item.productAttrImage:item.productImage" mode="aspectFill"></image>
-					</view>
-					<view class="info-box">
-						<view>
-							<view class="name-box ellipsis2">
-								<view class="tag" :style="{background:_background(item.productType)}">{{$getDictLabelName("storeProductType",item.productType)}}</view>{{item.productName}}
-							</view>
-							<view class="spec ellipsis2">{{item.productAttrName}}</view>
+			<view class="shopbox" v-for="(shop,idx) in carts" :key="idx">
+				<view class="shopbox-name" v-if="shop.storeName && shop.storeName != 'null'">
+					<text>{{shop.storeName}}</text>
+				</view>
+				<view class="goods-list">
+					<view v-for="(item,index) in shop.list" :key="index" class="item">
+						<view class="img-box">
+							<image :src="item.productAttrImage || item.productImage" mode="aspectFill"></image>
 						</view>
-						<view class="price-num">
-							<view class="price">
-								<text class="unit">¥</text>
-								<text class="num">{{item.price&&item.price.toFixed(2)}}</text>
+						<view class="info-box">
+							<view>
+								<view class="name-box ellipsis2">
+									<view class="tag" :style="{background:_background(item.productType)}">{{$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? item.price.toFixed(2): '0.00'}}</text>
+								</view>
+								<view class="num">x{{item.cartNum}}</view>
 							</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&&price.totalPrice.toFixed(2)}}</text>
+					<!-- 运费 -->
+					<view class="points">
+						<view class="left">
+							<text class="text">运费</text>
+						</view>
+						<view class="right" v-if="price&&price.length > 0">
+							<text class="text">{{price[idx].payPostage==null||price[idx].payPostage==0?'免运费':price[idx].payPostage.toFixed(2)}}</text>
+						</view>
+					</view>
+					<!-- 备注 -->
+					<view class="points">
+						<view class="left">
+							<text class="text">备注</text>
+						</view>
+						<view class="remarks">
+							<input type="text" v-model="shop.markinfo" placeholder="备注留言(选填)" placeholder-class="input" />
+						</view>
 					</view>
 				</view>
 			</view>
 			<!-- 积分 -->
-			<view class="points">
-				<view class="left">
-					<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/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="#2583EB" inactiveColor="rgba(0, 0, 0, 0.1)"></evan-switch>
-				</view>
-			</view>
-			<!-- <view class="points" @click="openCoupon()">
-				<view class="left">
-					<text class="text">优惠券</text>
+			<view class="price-info">
+				<view class="price-info-title">价格明细</view>
+				<view class="points">
+					<view class="left">
+						<text class="text">商品总价</text>
+					</view>
+					<view class="right" style="align-items: baseline;">
+						<text class="price-info-unit">¥</text>
+						<text class="price-info-num">{{priceAll.totalPrice.toFixed(2)}}</text>
+					</view>
 				</view>
-				<view class="right">
-					<text class="text">{{couponText}}</text>
-					<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/arrow4.png" mode=""></image>
+				<view class="points">
+					<view class="left">
+						<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/points.png" mode=""></image>
+						<text class="text">可用积分</text>
+					</view>
+					<view class="right">
+						<text class="text">{{priceAll.usedIntegral}}积分</text>
+						<evan-switch @change="integralChange" v-model="checked" activeColor="#0bb3f2" inactiveColor="rgba(0, 0, 0, 0.1)"></evan-switch>
+					</view>
 				</view>
-			</view> -->
-			<view class="points">
-				<view class="left">
-					<text class="text">运费</text>
+				<view class="points" @click="openCoupon()">
+					<view class="left">
+						<text class="text">优惠券</text>
+					</view>
+					<view class="right">
+						<text class="text">{{couponText}}</text>
+						<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/arrow4.png" mode=""></image>
+					</view>
 				</view>
-				<view class="right">
-					<text class="text" v-if="address!=null">{{price.payPostage==null||price.payPostage==0?'免运费':price.payPostage.toFixed(2)}}</text>
-					<text class="text" v-if="address==null">--</text>
-					
+				<view class="points">
+					<view class="left">
+						<text class="text">合计</text>
+					</view>
+					<view class="right" style="align-items: baseline;">
+						<text class="price-info-unit">¥</text>
+						<text class="price-info-num">{{priceAll.payPrice.toFixed(2)}}</text>
+					</view>
 				</view>
 			</view>
-			<view class="points">
+			<!-- <view class="points">
 				<view class="left">
 					<text class="text">服务费</text>
 				</view>
 				<view class="right">
-					<text class="text">{{price.serviceFee.toFixed(2)}}</text>
+					<text class="text">{{price.serviceFee? price.serviceFee.toFixed(2):'0.00'}}</text>
 				</view>
-			</view>
+			</view> -->
 			<!-- 备注 -->
-			<view class="remarks">
+			<!-- <view class="remarks">
 				<input type="text" v-model="form.mark" placeholder="备注留言(选填)" placeholder-class="input" />
+			</view> -->
+			<view class="agreement">
+				<label>
+					<checkbox :checked="isAgreement" color="#2583EB" style="transform:scale(0.7)" @click="handleAgreement()" />药品属于特殊特殊商品除药品质量问题外,一经售出,不得退换
+				</label>
 			</view>
 		</view>
 		<!-- 底部按钮 -->
@@ -108,7 +139,7 @@
 					<text class="label">合计:</text>
 					<view class="price">
 						<text class="unit">¥</text>
-						<text class="num">{{price.payPrice.toFixed(2)}}</text>
+						<text class="num">{{priceAll.payPrice.toFixed(2)}}</text>
 					</view>
 				</view>
 				<view class="btn" @click="submitOrder">提交订单</view>
@@ -150,7 +181,7 @@
 <script>
 	import {getWeixinOrderTemps} from '@/api/common'
 	
-	import {confirm,computed,create} from './api/storeOrder'
+	import {confirm,computed,create} from '@/api/myStoreOrder.js'
 	import { getMyEnableCouponList } from './api/coupon'
 	 
 	import EvanSwitch from './components/evan-switch.vue'
@@ -163,17 +194,13 @@
 		},
 		data() {
 			return {
+				isAgreement: true,
 				temps:[],
 				couponUserId:null,
 				couponText:"请选择",
 				couponsList:[],
 				couponVisible:false,
-				price:{
-					payPrice:0,
-					totalPostage:0,
-					usedIntegral:0,
-					totalPrice:0.00,
-				},
+				price:[],
 				address:null,
 				carts:[],
 				checked: false,
@@ -186,8 +213,15 @@
 					mark:null,
 					companyId:null,
 					companyUserId:null
-				}
-				
+				},
+				storeId: '',
+				priceAll:{
+					payPrice:0,
+					totalPostage:0,
+					usedIntegral:0,
+					totalPrice:0.00,
+				},
+				confirmParam: []
 			}
 		},
 		computed: {
@@ -207,8 +241,10 @@
 		onLoad(option) {
 			this.form.companyId=option.companyId;
 			this.form.companyUserId=option.companyUserId;
-			this.cartIds=option.cartIds;
+			// this.cartIds=option.cartIds;
 			this.type=option.type;
+			this.storeId=option.storeId;
+			this.confirmParam = JSON.parse(decodeURIComponent(option.confirmParam))
 			this.confirm();
 			uni.$on('updateAddress', (e) => {
 				this.address=e;
@@ -218,6 +254,9 @@
 			this.getWeixinOrderTemps();
 		},
 		methods: {
+			handleAgreement() {
+				this.isAgreement = !this.isAgreement;
+			},
 			getWeixinOrderTemps:function(){
 				getWeixinOrderTemps().then(
 					res => {
@@ -250,39 +289,55 @@
 				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 => {}
-				);
+			confirm(){
+				if(this.confirmParam && this.confirmParam.length > 0) {
+					confirm(this.confirmParam).then(
+						res => {
+							if(res.code==200){
+								this.carts=res.carts.map(item=>({
+									 ...item,
+									 markinfo: ""
+								}));
+								 this.form.orderKey=res.orderKeys;
+								 if(res.address!=null){
+									 this.form.addressId=res.address.id;
+									 this.address=res.address;
+								 }
+								 this.computed()
+							}else{
+								uni.showToast({
+									icon:'none',
+									title: res.msg,
+								});
+							}
+						},
+						rej => {}
+					)
+				}else {
+					uni.showToast({
+						icon: 'none',
+						title:'订单参数不存在~',
+					});
+				}
 			},
 			computed(){
-				let data = {companyId:this.form.companyId,couponUserId:this.couponUserId,orderKey:this.form.orderKey,addressId:this.form.addressId,useIntegral:this.form.useIntegral};
+				let data = {
+					companyId:this.form.companyId,
+					couponUserId:this.couponUserId,
+					orderKeys: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
-							 
+							 this.price= res.data && res.data.length > 0 ? res.data : []
+							 this.priceAll = res.data && res.data.length > 0 ? res.data[res.data.length -1] : {
+								 payPrice:0,
+								 totalPostage:0,
+								 usedIntegral:0,
+								 totalPrice:0.00,
+							 }
 						}else{
 							if(res.code==501){
 								uni.showToast({
@@ -311,7 +366,7 @@
 			// 提交订单
 			submitOrder() {
 				var that=this;
-				if(this.form.orderKey==null){
+				if(this.form.orderKey==null || this.form.orderKey.length == 0){
 					uni.showToast({
 						icon:'none',
 						title: '订单KEY不存在',
@@ -325,7 +380,13 @@
 					});
 					return;
 				}
-				
+				if(!this.isAgreement) {
+					uni.showToast({
+						icon:'none',
+						title: '购买前请同意相关须知',
+					});
+					return;
+				}
 				uni.requestSubscribeMessage({
 					tmplIds: this.temps,
 					success(res) {
@@ -338,6 +399,7 @@
 				
 			},
 			createOrder(){
+				const mark = this.carts.map(item => item.markinfo)
 				var that=this;
 				var data=null;
 				var tuiUserId=uni.getStorageSync('tuiUserId');
@@ -345,30 +407,48 @@
 					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};
+					data = {orderCreateType:1,tuiUserId:tuiUserId,companyId:this.form.companyId,companyUserId:this.form.companyUserId,couponUserId:this.couponUserId,mark:mark,orderKeys:this.form.orderKey,addressId:this.form.addressId,useIntegral:this.form.useIntegral,payType:1,appId: getApp().globalData.appId};
 				}
 				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};
+					data = {orderCreateType:1,companyId:this.form.companyId,companyUserId:this.form.companyUserId,couponUserId:this.couponUserId,mark:mark,orderKeys:this.form.orderKey,addressId:this.form.addressId,useIntegral:this.form.useIntegral,payType:1,appId: getApp().globalData.appId};
+				}
+				if(this.storeId!=null&& this.storeId>0){
+					data.storeId=this.storeId;
 				}
 				create(data).then(
 					res => {
 						uni.hideLoading()
-						if(res.code==200){
+						if(res.code == 200){
 							uni.hideLoading()
-							if(res.order.isPrescribe==1){
+							if(res.data.some(item=> item.order.isPrescribe) == 1) {
 								setTimeout(function(){
+									let orderIds = res.data.filter(item=> item.order.isPrescribe == 1).map(it=>it.order.id)
+									orderIds = orderIds.join(',')
 									uni.redirectTo({
-										url:"/pages_shopping/prescribe?orderId="+res.order.id
+										url:"/pages_shopping/prescribe?orderId="+orderIds+"&combinationOrderId="+encodeURIComponent(res.data[0].order.combinationOrderId)
 									})
 								},200);
-							}
-							else{
+							} else {
 								setTimeout(function(){
 									uni.redirectTo({
-										url: '/pages_shopping/paymentOrder?orderId='+res.order.id
+										url: '/pages_shopping/paymentOrder?combinationOrderId='+encodeURIComponent(res.data[0].order.combinationOrderId)
 									})
 								},200);
 							}
+							// if(res.order.isPrescribe==1){
+							// 	setTimeout(function(){
+							// 		uni.redirectTo({
+							// 			url:"/pages_shopping/prescribe?orderId="+res.order.id
+							// 		})
+							// 	},200);
+							// }
+							// else{
+							// 	setTimeout(function(){
+							// 		uni.redirectTo({
+							// 			url: '/pages_shopping/paymentOrder?orderId='+res.order.id
+							// 		})
+							// 	},200);
+							// }
 							return;
 						}
 						else{
@@ -404,7 +484,7 @@
 	}
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
 	.inner-box{
 		padding: 20upx 20upx 140upx;
 		.address-box{
@@ -458,8 +538,29 @@
 				}
 			}
 		}
+		.shopbox {
+			background: #FFFFFF;
+			border-radius: 16rpx;
+			margin: 20rpx 0;
+			.points {
+				padding: 0 !important;
+			}
+			.remarks {
+				padding: 0 !important;
+			}
+		}
+		.shopbox-name {
+			padding: 30rpx 30rpx 0 30rpx;
+			font-family: PingFang SC, PingFang SC;
+			font-weight: bold;
+			font-size: 30rpx;
+			color: #111;
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+		}
 		.goods-list{
-			margin-top: 20upx;
+			// margin-top: 20upx;
 			padding: 0 30upx;
 			background-color: #FFFFFF;
 			border-radius: 16upx;
@@ -493,7 +594,7 @@
 							display: inline-block;
 							padding: 0 6upx;
 							height: 30upx;
-							background: linear-gradient(90deg, #2583EB 0%, #92C1F5 100%);
+							background: linear-gradient(90deg, #66b2ef 0%, #0bb3f2 100%);
 							border-radius: 4upx;
 							margin-right: 10upx;
 							font-size: 22upx;
@@ -578,12 +679,30 @@
 				}
 			}
 		}
+		.price-info {
+			background: #FFFFFF;
+			border-radius: 16upx;
+			&-title {
+					padding: 30rpx 30rpx 20rpx 30rpx;
+					font-family: PingFang SC, PingFang SC;
+					font-weight: 500;
+					font-size: 30rpx;
+					color: #111;
+			}
+			&-unit {
+				font-size: 24rpx;
+			}
+			&-num {
+				font-size: 28rpx;
+			}
+		}
 		.points{
 			height: 88upx;
+			width: 100%;
 			padding: 0 30upx;
+			box-sizing: border-box;
 			background: #FFFFFF;
 			border-radius: 16upx;
-			 
 			display: flex;
 			align-items: center;
 			justify-content: space-between;
@@ -624,7 +743,6 @@
 			padding: 0 30upx;
 			background: #FFFFFF;
 			border-radius: 16upx;
-			margin-top: 20upx;
 			display: flex;
 			align-items: center;
 			input{
@@ -643,13 +761,20 @@
 		}
 	}
 	
+	.agreement {
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: red;
+		padding: 30rpx 0;
+	}
 	
 	.btn-foot{
 		box-sizing: border-box;
 		width: 100%;
 		height: 121upx;
 		background: #FFFFFF;
-		padding: 16upx 30upx 16upx 60upx;
+		padding: 16upx;
 		display: flex;
 		align-items: center;
 		justify-content: flex-end;
@@ -700,13 +825,13 @@
 				font-family: PingFang SC;
 				font-weight: bold;
 				color: #FFFFFF;
-				background: #2583EB;
+				background: #0bb3f2;
 				border-radius: 44upx;
 			}
 		}
 	}
-</style>
-<style lang="less" scoped>
+// </style>
+// <style lang="less" scoped>
 	.coupon {
 	  height: 100%;
 	}

+ 146 - 0
pages_shopping/evaluate.vue

@@ -0,0 +1,146 @@
+<template>
+	<view>
+<!-- 		<view class="top-fixed">
+			<u-tabs
+			 :scrollable="false"
+			 :list="tabs"
+			 :current="current"
+			 lineColor="#2583EB"
+			@change="tabChange">
+			</u-tabs>
+		</view> -->
+		<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">	
+			<view class="evaluate">
+				<evaluateItem :showLine="0" v-for="(item,index) in dataList" :key="index" :item="item"></evaluateItem>
+			</view>
+		</mescroll-body>
+	</view>
+</template>
+
+<script>
+	import evaluateItem from "@/components/evaluateItem";
+	import {selectCommentByUser} from '@/api/myStoreOrder.js'
+	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
+	export default {
+		mixins: [MescrollMixin], 
+		components: {
+			evaluateItem
+		},
+		data() {
+			return {
+				tabs:[
+					{
+						id:0,
+						name:'待评价'
+					},
+					{
+						id:1,
+						name:'已评价'
+					}
+				],
+				current: 0,
+				mescroll: null,
+				downOption: {   //下拉刷新
+				 	use:true,
+					auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
+				},
+				upOption: {
+					onScroll:true,
+					use: true, // 是否启用上拉加载; 默认true
+					page: {
+						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
+						size: 10 // 每页数据的数量,默认10
+					},
+					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					empty: {
+						icon:'https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/empty_icon.png',
+						tip: '暂无数据',
+						
+					},
+					textNoMore:"已经到底了",
+				},
+				// 列表数据
+				dataList: [],
+				orderId: '',
+				productIds: '',
+				storeId: '',
+			}
+		},
+		onLoad(option) {
+			this.orderId = option.orderId || ''
+			this.productIds = option.productIds || ''
+			this.storeId = option.storeId || ''
+		},
+		methods: {
+			tabChange(item){
+				this.current=item.index
+				this.mescroll.resetUpScroll()
+			},
+			preview(img, current) {
+				const urls = img.split(',')
+				uni.previewImage({
+					urls,
+					current
+				});
+			},
+			mescrollInit(mescroll) {
+				this.mescroll = mescroll;
+			},
+			upCallback(page) {
+				//联网加载数据
+				var that = this;
+				var data = {
+					page: page.num,
+					pageSize: page.size,
+					storeId:this.storeId,
+					orderId:this.orderId,
+					productIds:this.productIds,
+					userId: uni.getStorageSync('userId'),
+					showSelf: this.orderId ? 1 : 0
+				};
+				selectCommentByUser(data).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();
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+	.top-fixed{
+		width: 100%;
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 10;
+		height: 88upx;
+		background-color: #fff;
+	}
+	.evaluate {
+		padding: 24rpx;
+		::v-deep {
+			.comment-item {
+				padding: 24rpx;
+				border-radius: 16rpx;
+			}
+		}
+	}
+</style>

+ 361 - 0
pages_shopping/evaluateDetail.vue

@@ -0,0 +1,361 @@
+<template>
+	<view class="page-evaluate">
+		<!-- 头部商品信息 -->
+		<view class="card">
+			<view class="goods-list">
+				<view v-if="order.isPackage!=1" v-for="(item,index) in items" :key="index" class="item">
+					<view class="img-box">
+						<image :src="JSON.parse(item.jsonInfo).image" mode="aspectFill"></image>
+					</view>
+					<view class="info-box">
+						<view>
+							<view class="name-box ellipsis2">
+								<view v-if="item.isPrescribe==1" class="tag">处方药</view>{{JSON.parse(item.jsonInfo).productName}}
+							</view>
+							<view class="spec ellipsis2">{{JSON.parse(item.jsonInfo).sku}}</view>
+						</view>
+						<view class="price-num">
+							<view class="price">
+								<text class="unit">¥</text>
+								<text class="num">{{JSON.parse(item.jsonInfo).price.toFixed(2)}}</text>
+							</view>
+							<view class="num">x{{JSON.parse(item.jsonInfo).num}}</view>
+						</view>
+					</view>
+				</view>
+				<view  v-if="order.isPackage==1&&order.packageJson!=null"   class="item"  >
+					<view class="img-box">
+						<image :src="JSON.parse(order.packageJson).imgUrl" mode="aspectFill"></image>
+					</view>
+					<view class="info-box">
+						<view>
+							<view class="name-box ellipsis2">
+								<view class="tag">套餐</view>{{JSON.parse(order.packageJson).title}}
+							</view>
+							<view class="spec ellipsis2">{{JSON.parse(order.packageJson).descs}}</view>
+						</view>
+						 
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="card">
+			<!-- 表单区 -->
+			<u-form ref="form" :model="form" :rules="rules" label-width="140rpx" errorType="toast">
+				<!-- 1. 商品打分 -->
+				<u-form-item label="商品打分" prop="rating">
+					<u-rate v-model="form.rating" :count="5" active-icon="star-fill" inactive-icon="star" size="24"></u-rate>
+				</u-form-item>
+
+				<!-- 2. 评价内容 -->
+				<u-form-item label="评价内容" prop="content">
+					<u-textarea v-model="form.content" placeholder="请分享您的使用感受~" maxlength="200" height="160"
+						count></u-textarea>
+				</u-form-item>
+
+				<!-- 3. 上传图片 -->
+				<u-form-item label="上传图片">
+					<u-upload :fileList="fileList1" @afterRead="afterRead" @delete="deletePic" name="1" multiple
+						:maxCount="6" :previewFullImage="true"></u-upload>
+				</u-form-item>
+
+				<!-- 4. 是否匿名 -->
+				<u-form-item label="匿名评价">
+					<view><checkbox :checked="form.isAnonymous" @click="handleAnonymous()" style="transform: scale(0.7);" /></view>
+				</u-form-item>
+			</u-form>
+		</view>
+		<!-- 5. 提交按钮 -->
+		<view class="u-p-30">
+			<u-button type="primary" shape="circle" @click="submit">提交评价</u-button>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {getMyStoreOrderById,addOrderComment} from '@/api/myStoreOrder.js'
+	export default {
+		data() {
+			return {
+				form: {
+					rating: 5, // 默认 5 星
+					content: '',
+					isAnonymous: false
+				},
+				fileList1: [], // 上传组件回显列表
+				rules: {
+					rating: [{
+						type: 'number',
+						min: 1,
+						required: true,
+						message: '请打分',
+						trigger: 'change'
+					}],
+					content: [{
+							required: true,
+							message: '请输入评价',
+							trigger:  ['change','blur']
+						},
+						{
+							min: 5,
+							message: '至少 5 个字',
+							trigger:  ['change','blur']
+						}
+					]
+				},
+				orderId: '',
+				order:{},
+				items:[],
+			}
+		},
+		onLoad(option) {
+			this.orderId = option.orderId
+			this.getMyStoreOrderById()
+		},
+		onReady() {
+			this.$refs.form.setRules(this.rules)
+		},
+		methods: {
+			handleAnonymous() {
+				this.form.isAnonymous = !this.form.isAnonymous;
+			},
+			// 选择图片后回调
+			async afterRead(event) {
+				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
+				let lists = [].concat(event.file)
+				let fileListLen = this[`fileList${event.name}`].length
+				lists.map((item) => {
+					this[`fileList${event.name}`].push({
+						...item,
+						status: 'uploading',
+						message: '上传中'
+					})
+				})
+				for (let i = 0; i < lists.length; i++) {
+					const result = await this.uploadFilePromise(lists[i].url)
+					let item = this[`fileList${event.name}`][fileListLen]
+					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
+						status: 'success',
+						message: '',
+						url: result
+					}))
+					fileListLen++
+				}
+			},
+			uploadFilePromise(url) {
+				return new Promise((resolve, reject) => {
+					let a = uni.uploadFile({
+						url: uni.getStorageSync('requestPath')+'/app/common/uploadOSS', // 仅为示例,非真实的接口地址
+						filePath: url,
+						name: 'file',
+						formData: {
+							user: 'test'
+						},
+						success: (res) => {
+							setTimeout(() => {
+								console.log(JSON.parse(res.data).url)
+								resolve(JSON.parse(res.data).url)
+							}, 1000)
+						}
+					});
+				})
+			},
+			// 删除图片
+			deletePic(event) {
+				this[`fileList${event.name}`].splice(event.index, 1)
+			},
+			// 提交
+			submit() {
+				this.$refs.form.validate().then(res => {
+					if(res) {
+						const imgUrls = this.fileList1.map(item => item.url).join(',')
+						const params = {
+							orderId: this.orderId,
+							rating: this.form.rating,
+							content: this.form.content.trim(),
+							imageUrl: imgUrls,
+							isAnonymous: this.form.isAnonymous ? 1 : 0,
+							isShow: 1,
+							isDel: 0,
+							nickName: uni.getStorageSync('nickName'),
+							userId: uni.getStorageSync('userId'),
+						}
+						uni.showLoading({
+							title: '提交中'
+						})
+						addOrderComment(params).then(res=>{
+							uni.hideLoading()
+							if(res.code == 200) {
+								uni.showToast({
+									title: '评价成功',
+									icon: 'success'
+								})
+								uni.$emit('refreshOrder')
+								setTimeout(() => uni.navigateBack(), 800)
+							} else {
+								uni.showToast({
+									title: res.msg,
+									icon: 'success'
+								})
+							}
+						})
+					}
+				})
+			},
+			getMyStoreOrderById(){
+				var data={orderId:this.orderId};
+				getMyStoreOrderById(data).then(res => {
+					if(res.code==200){
+						 this.order=res.order;
+						 this.items=res.items;
+					}else{
+						uni.showToast({
+							icon:'none',
+							title: "请求失败",
+						});
+						 
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.page-evaluate {
+		padding: 24rpx;
+	}
+	.card {
+		background: #fff;
+		padding: 24rpx;
+		border-radius: 16rpx;
+		margin-bottom: 20rpx;
+	}
+	.goods-list{
+		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, #2BC7B9 0%, #2BC7A4 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: 18upx;
+					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;
+			.discount{
+				font-size: 24upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 1;
+				margin-right: 30upx;
+			}
+			.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;
+				}
+			}
+		}
+	}
+</style>

+ 2 - 2
pages_shopping/payOrder.vue

@@ -51,7 +51,7 @@
 </template>
 
 <script>
-	import {pay,getStoreOrderById} from '@/api/storeOrder'
+	import {payByCombinationId,getStoreOrderById} from '@/api/myStoreOrder'
 	export default {
 		data() {
 			return {
@@ -116,7 +116,7 @@
 				var data = {orderId:this.order.id,appId: getApp().globalData.appId};
 				var that=this;
 				uni.showLoading();
-				pay(data).then(
+				payByCombinationId(data).then(
 					res => {
 						if(res.code==200){
 							 console.log(res);

+ 146 - 80
pages_shopping/paymentOrder.vue

@@ -112,8 +112,10 @@
 				<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 class="text" v-for="item in order.orderCodes" :key="item">{{item}}</view>
+						</view>
+						<view class="copy-btn" @click="copyOrderSn(orderCode)">复制</view>
 					</view>
 				</view>
 				<view class="item">
@@ -147,7 +149,7 @@
 	import {getUserInfo} from '@/api/user'
 	
 	import {getStoreConfig} from './api/common.js'
-	import {editPayType,pay,getStoreOrderById} from './api/storeOrder'
+	import {editPayType,pay,getStoreOrderById,payByCombinationId,getStoreOrderByCombinationId,editPayTypeByCombinationId} from '@/api/myStoreOrder.js'
 	export default {
 		data() {
 			return {
@@ -159,10 +161,15 @@
 				payLimitTime:null,
 				order:null,
 				user:null,
+				combinationOrderId: '',
+				orderCode: "",
+				// 需要开处方的订单id
+				prescribeOrder: ""
 			}
 		},
 		onLoad(option) {
-			this.orderId=JSON.parse(option.orderId);
+			this.combinationOrderId = option.combinationOrderId ? decodeURIComponent(option.combinationOrderId) : ''
+			this.orderId=option.orderId ? JSON.parse(option.orderId) : '';
 			uni.showShareMenu({
 				withShareTicket:true,
 				//小程序的原生菜单中显示分享按钮,才能够让发送给朋友与分享到朋友圈两个按钮可以点击
@@ -172,7 +179,11 @@
 		onShow() {
 			this.$isLogin().then(res => {
 				if(res){
-					this.getStoreOrderById();
+					if(this.combinationOrderId) {
+						this.getStoreOrderByCombinationId()
+					} else {
+						this.getStoreOrderById();
+					}
 					this.getStoreConfig();
 					this.getUserInfo();
 				} else {
@@ -184,10 +195,11 @@
 		},
 		//发送给朋友
 		onShareAppMessage(res) {
+			const combinationOrderId = this.combinationOrderId ? `&combinationOrderId=${encodeURIComponent(this.combinationOrderId)}` : ''
 			return {
 				title: "帮TA支付",
-				path: '/pages_shopping/user/otherPaymentOrder?orderId='+this.orderId,
-				imageUrl: 'https://hos-1309931967.cos.ap-chongqing.myqcloud.com/fs/20230106/6b459adfb1004c1a96219bcdf07e337c.png' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
+				path: '/pages_shopping/user/otherPaymentOrder?orderId='+this.orderId + combinationOrderId,
+				imageUrl: 'https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/sharelogo.png' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
 			}
 			
 		},
@@ -295,84 +307,54 @@
 				);
 				
 			},
-			otherPayOrder(){
-				uni.navigateTo({
-					url: '/pages_shopping/user/otherPaymentOrder?orderId='+this.orderId
-				})
+			getStoreOrderByCombinationId() {
+				var data = {combinationId:this.combinationOrderId};
+				var that=this;
+				uni.showLoading();
+				getStoreOrderByCombinationId(data).then(
+					res => {
+						if(res.code==200){
+							console.log(res);
+							uni.hideLoading();
+							that.order=res.order;
+							that.orderCode = res.order.orderCodes ? res.order.orderCodes.join(',') : "";
+							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;
+								}
+							}
+							that.prescribeOrder = res.prescribeOrder;
+							this.editPayTypeByCombinationId(this.order.payType)
+							
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
 			},
-			payOrder(){
-				var data = {orderId:this.order.id,payType:this.order.payType,appId: getApp().globalData.appId};
+			editPayTypeByCombinationId(payType){
+				var data = {combinationOrderId:this.combinationOrderId,payType:payType};
 				var that=this;
 				uni.showLoading();
-				pay(data).then(
+				editPayTypeByCombinationId(data).then(
 					res => {
 						if(res.code==200){
-							 console.log(res);
-							 if(res.payType==1||res.payType==2){
-								 // var result=JSON.parse(res.result);
-								 let result = res.result
-								 uni.requestPayment({
-								 	provider: 'wxpay',
-								 	timeStamp: result.timeStamp,
-								 	nonceStr: result.nonceStr,
-								 	package: result.package,
-								 	signType: result.signType,
-								 	paySign: result.paySign,
-								 	success: function(res) {
-										uni.hideLoading();
-										uni.redirectTo({
-											url:"success?order="+JSON.stringify(that.order)
-										}) 
-								 	},
-								 	fail: function(err) {
-										uni.showToast({
-											icon:'none',
-											title:'fail:' + JSON.stringify(err),
-										});
-								 		console.log('fail:' + JSON.stringify(err));
-								 		uni.hideLoading();
-								 	}
-								 });
-								 
-								 // 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();
-									// 	  uni.redirectTo({
-									// 	  	url:"success?order="+JSON.stringify(that.order)
-									// 	  }) 
-								 // 	},
-								 // 	fail: function(err) {
-									// 	uni.showToast({
-									// 		icon:'none',
-									// 		title:'fail:' + JSON.stringify(err),
-									// 	});
-								 // 		console.log('fail:' + JSON.stringify(err));
-								 // 		uni.hideLoading();
-								 // 	}
-								 // });
-							 }
-							 else if(res.payType==3){
-								 uni.hideLoading();
-								 if(that.order.isPrescribe){
-									 //如果是处方订单开处方
-									uni.redirectTo({
-										url:"prescribe?orderId="+that.order.id
-									})
-								 }
-								 else{
-									//如果是普通订单
-									uni.redirectTo({
-										url:"success?order="+JSON.stringify(that.order)
-									}) 
-								 }
-							 }
-							 
+							console.log(res);
+							uni.hideLoading();
+							that.order=res.order;
+							that.orderCode = res.order.orderCodes ? res.order.orderCodes.join(',') : "";
+							//this.payType=this.order.payType
+							this.payMoney=this.order.payMoney;
+							this.payDelivery=this.order.payDelivery;
+							that.prescribeOrder = res.prescribeOrder;
 						}else{
 							uni.showToast({
 								icon:'none',
@@ -383,6 +365,90 @@
 					rej => {}
 				);
 				
+			},
+			payOrder(){
+				if(this.combinationOrderId) {
+					let data = {combinationOrderId:this.combinationOrderId,payType:this.order.payType,appId: getApp().globalData.appId};
+					let that=this;
+					uni.showLoading();
+					payByCombinationId(data).then(
+						res => {
+							if(res.code==200){
+								this.payfun(res)
+							}else{
+								uni.showToast({
+									icon:'none',
+									title: res.msg,
+								});
+							}
+						},
+						rej => {}
+					);
+				} else {
+					let data = {orderId:this.order.id,payType:this.order.payType,appId: getApp().globalData.appId};
+					let that=this;
+					uni.showLoading();
+					pay(data).then(
+						res => {
+							if(res.code==200){
+								this.payfun(res)
+							}else{
+								uni.showToast({
+									icon:'none',
+									title: res.msg,
+								});
+							}
+						},
+						rej => {}
+					);
+				}
+			},
+			payfun(res) {
+				const that = this
+				console.log(res.result);
+				if(res.payType==1||res.payType==2){
+					 uni.requestPayment({
+						provider: 'wxpay',
+						timeStamp: res.result.timeStamp,
+						nonceStr: res.result.nonceStr,
+						// package: res.result.packageValue,
+						package: res.result.packageStr,
+						signType: res.result.signType,
+						paySign: res.result.paySign,
+						success: function(res) {
+							 uni.hideLoading();
+							  uni.redirectTo({
+								url:"/pages_shopping/success?order="+JSON.stringify(that.order)
+							  }) 
+						},
+						fail: function(err) {
+							uni.showToast({
+								icon:'none',
+								title:'fail:' + JSON.stringify(err),
+							});
+							console.log('fail:' + JSON.stringify(err));
+							uni.hideLoading();
+						}
+					 });
+				}
+				else if(res.payType==3){
+					 uni.hideLoading();
+					 if(that.order.isPrescribe){
+						 //如果是处方订单开处方
+						// uni.redirectTo({
+						// 	url:"prescribe?orderId="+that.order.id
+						// })
+						uni.redirectTo({
+							url:"/pages_shopping/prescribe?orderId="+that.prescribeOrder+"&combinationOrderId="+encodeURIComponent(that.order.combinationOrderId)
+						})
+					 }
+					 else{
+						//如果是普通订单
+						uni.redirectTo({
+							url:"/pages_shopping/success?order="+JSON.stringify(that.order)
+						}) 
+					 }
+				}
 			}
 		}
 	}

+ 4 - 3
pages_shopping/prescribe.vue

@@ -154,8 +154,8 @@
 			</view>
 		</view>
 		<view class="agreement">
-			<label>
-				<checkbox :checked="isAgreement" color="#2583EB" style="transform:scale(0.7)" @click="handleAgreement()" />我确认已确诊此疾病并使用过该药,且无过敏史、无相关禁忌症和不良反应
+			<label @click="handleAgreement()">
+				<checkbox :checked="isAgreement" color="#2583EB" style="transform:scale(0.7)" />我确认已确诊此疾病并使用过该药,且无过敏史、无相关禁忌症和不良反应
 			</label>
 		</view>
 		<view class="btn-box">
@@ -190,7 +190,7 @@
 </template>
 
 <script>
-	import {getStoreOrderById} from './api/storeOrder.js'
+	import {getStoreOrderById} from '@/api/myStoreOrder.js'
 	import {getWeixinPrescribeTemps} from '@/api/common'
 	import {doPrescribe,diseaseQueryList} from './api/prescribe'
 	import {getPatientList,delPatient} from '@/api/patient'
@@ -411,6 +411,7 @@
 				// 	url: '/pages/index/webview?url='+encodeURIComponent(url)
 				// })
 				// return
+				console.log('this.isAgreement==',this.isAgreement)
 				if (!this.isAgreement) {
 					uni.showToast({
 						icon: 'none',

文件差異過大導致無法顯示
+ 314 - 212
pages_shopping/productDetails.vue


+ 5 - 0
pages_shopping/productList.vue

@@ -86,6 +86,11 @@
 				cateId:null,
 				defaultOrder:'desc',
 				pid:null,
+				mescroll: null,
+				downOption: {   //下拉刷新
+				 	use:true,
+					auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
+				},
 				//上拉加载的配置
 				upOption: {
 					onScroll:true,

+ 3 - 3
pages_shopping/registerMerchant.vue

@@ -395,9 +395,9 @@ export default {
 	onLoad(options) {
 		this.form.doctorType=options.type;
 		this.getCitys()
-		this.getHospitalList();
-		this.getDepartmentList();
-		this.getDictByKey("sys_doc_position");
+		// this.getHospitalList();
+		// this.getDepartmentList();
+		// this.getDictByKey("sys_doc_position");
 	},
 	onShow() {
 		

+ 19 - 6
pages_shopping/success.vue

@@ -14,8 +14,10 @@
 				<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 class="text" v-for="item in order.orderCodes" :key="item">{{item}}</view>
+						</view>
+						<view class="copy-btn" @click="copyOrderSn(orderCode)">复制</view>
 					</view>
 				</view>
 				<view class="item">
@@ -35,10 +37,15 @@
 		data() {
 			return {
 				order:null,
+				orderCode: "",
+				ids: []
 			}
 		},
 		onLoad(option) {
-			this.order=JSON.parse(option.order) 
+			this.order=JSON.parse(decodeURIComponent(option.order))
+			// orderCodes和ids字段表示店铺订单
+			this.orderCode = this.order && this.order.orderCodes ? this.order.orderCodes.join(',') : this.order.orderCode || '';
+			this.ids = this.order && this.order.ids ? this.order.ids : this.order.id ?  [this.order.id] : [];
 			uni.$emit('refreshOrder');
 		},
 		methods: {
@@ -55,9 +62,15 @@
 				});
 			},
 			goOrderDetails(id){
-				uni.redirectTo({
-					url: "/pages_user/shopping/storeOrderDetail?id="+id
-				}) 
+				if(this.ids && this.ids.length > 1) {
+					uni.navigateTo({
+						url: '/pages_user/shopping/storeOrder?status='
+					})
+				} else {
+					uni.redirectTo({
+						url: "/pages_user/shopping/storeOrderDetail?id="+this.ids[0]
+					}) 
+				}
 			}
 		}
 	}

+ 100 - 53
pages_shopping/user/otherPaymentOrder.vue

@@ -15,7 +15,7 @@
 				<radio-group   >
 					<view class="item"   >
 						<view class="left"  >
-							<image src="../../static/images/wecha_pay.png" mode=""></image>
+							<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/shop/image/wecha_pay.png" mode=""></image>
 							<text class="text">微信支付</text>
 						</view>
 						<label>
@@ -31,8 +31,10 @@
 				<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 class="text" v-for="item in order.orderCodes" :key="item">{{item}}</view>
+						</view>
+						<view class="copy-btn" @click="copyOrderSn(orderCode)">复制</view>
 					</view>
 				</view>
 				<view class="item">
@@ -52,7 +54,7 @@
 </template>
 
 <script>
-	import {otherPayment,getStoreOrderById} from '@/api/storeOrder'
+	import {otherPayment,getStoreOrderById,getStoreOrderByCombinationId,otherPaymentByCombinationId} from '@/api/myStoreOrder'
 	export default {
 		data() {
 			return {
@@ -63,21 +65,18 @@
 				payLimitTime:null,
 				order:null,
 				user:null,
+				combinationOrderId: "",
+				orderCode: ''
 			}
 		},
 		onLoad(option) {
-			this.orderId=JSON.parse(option.orderId);
-		},
-		onShow() {
-			this.$isLogin().then(res => {
-				if(res){
-					this.getStoreOrderById();
-				} else {
-					uni.navigateTo({
-						url:'/pages/auth/login',
-					})
-				}
-			})
+			this.orderId=option.orderId ? JSON.parse(option.orderId) : '';
+			this.combinationOrderId = option.combinationOrderId ? decodeURIComponent(option.combinationOrderId) : ''
+			if(this.combinationOrderId) {
+				this.getStoreOrderByCombinationId();
+			} else {
+				this.getStoreOrderById();
+			}
 		},
 		methods: {
 			copyOrderSn(text) {
@@ -103,7 +102,8 @@
 							uni.hideLoading();
 							that.order=res.order;
 							this.payMoney=that.order.payMoney;
-							
+							that.order.orderCodes = res.order.orderCode ? [res.order.orderCode] : []
+							that.orderCode = res.order.orderCode
 						}else{
 							uni.showToast({
 								icon:'none',
@@ -115,34 +115,61 @@
 				);
 				
 			},
+			getStoreOrderByCombinationId() {
+				var data = {combinationId:this.combinationOrderId};
+				var that=this;
+				uni.showLoading();
+				getStoreOrderByCombinationId(data).then(
+					res => {
+						if(res.code==200){
+							console.log(res);
+							uni.hideLoading();
+							that.order=res.order;
+							that.orderCode = res.order.orderCodes ? res.order.orderCodes.join(',') : "";
+							this.payMoney=that.order.payMoney;
+							
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+			},
 			pay(){
 				uni.login({
 					success: res => {
 						console.log(res)
-						this.otherPayment(res.code);
+						if(this.combinationOrderId) {
+							this.otherPaymentByCombinationId(res.code)
+						} else {
+							this.otherPayment(res.code);
+						}
 					}
 				});
 			},
 			otherPayment(code){
-				var data = {orderId:this.order.id,code:code,appId: getApp().globalData.appId };
+				var data = {orderId:this.order.id,code:code,appId: getApp().globalData.appId};
 				var that=this;
 				uni.showLoading();
 				otherPayment(data).then(
 					res => {
 						if(res.code==200){
-							var result=JSON.parse(res.result);
 							uni.requestPayment({
 								provider: 'wxpay',
-								timeStamp: result.timeStamp,
-								nonceStr: result.nonceStr,
-								package: result.package,
-								signType: result.signType,
-								paySign: result.paySign,
+								timeStamp: res.result.timeStamp,
+								nonceStr: res.result.nonceStr,
+								// package: res.result.packageValue,
+								package: res.result.packageStr,
+								signType: res.result.signType,
+								paySign: res.result.paySign,
 								success: function(res) {
-										uni.hideLoading();
-										uni.redirectTo({
-											url:"otherPaySuccess"
-										})
+									uni.hideLoading();
+									uni.redirectTo({
+										url:"otherPaySuccess"
+									}) 
 								},
 								fail: function(err) {
 									uni.showToast({
@@ -153,28 +180,6 @@
 									uni.hideLoading();
 								}
 							});
-							// 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();
-							// 		uni.redirectTo({
-							// 			url:"otherPaySuccess"
-							// 		}) 
-							// 	},
-							// 	fail: function(err) {
-							// 		uni.showToast({
-							// 			icon:'none',
-							// 			title:'fail:' + JSON.stringify(err),
-							// 		});
-							// 		console.log('fail:' + JSON.stringify(err));
-							// 		uni.hideLoading();
-							// 	}
-							// });
 							 
 						}else{
 							uni.showToast({
@@ -186,7 +191,49 @@
 					rej => {}
 				);
 				
-			}
+			},
+			otherPaymentByCombinationId(code){
+				var data = {combinationOrderId:this.combinationOrderId,code:code,appId: getApp().globalData.appId};
+				var that=this;
+				uni.showLoading();
+				otherPaymentByCombinationId(data).then(
+					res => {
+						if(res.code==200){
+							uni.requestPayment({
+								provider: 'wxpay',
+								timeStamp: res.result.timeStamp,
+								nonceStr: res.result.nonceStr,
+								// package: res.result.packageValue,
+								package: res.result.packageStr,
+								signType: res.result.signType,
+								paySign: res.result.paySign,
+								success: function(res) {
+									uni.hideLoading();
+									uni.redirectTo({
+										url:"otherPaySuccess"
+									}) 
+								},
+								fail: function(err) {
+									uni.showToast({
+										icon:'none',
+										title:'fail:' + JSON.stringify(err),
+									});
+									console.log('fail:' + JSON.stringify(err));
+									uni.hideLoading();
+								}
+							});
+							 
+						}else{
+							uni.showToast({
+								icon:'none',
+								title: res.msg,
+							});
+						}
+					},
+					rej => {}
+				);
+				
+			},
 		}
 	}
 </script>
@@ -370,7 +417,7 @@
 				font-weight: bold;
 				color: #FFFFFF;
 				text-align: center;
-				background: #2583EB;
+				background: #0bb3f2;
 				border-radius: 44upx;
 				margin-bottom: 10rpx;
 			}

+ 27 - 30
pages_store/components/tuiStoreProduct.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<!-- 数据列表 -->
-		<mescroll-body top="0" :height="scrollHeight+'px'" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
+		<!-- <mescroll-body :top="top+'px'" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption"> -->
 			<view class="medic-itemlist">
 				<medicineItem :type="'store'" v-for="(item, index) in dataList" :key="index" :item="item"></medicineItem>
 				<view class="morebtn" v-if="dataList&&dataList.length>0" @click="navTo('/pages_shopping/home/productList?storeId='+storeId)">查看更多</view>
@@ -24,7 +24,7 @@
 					</view>
 				</view>
 			</view> -->
-		</mescroll-body>
+		<!-- </mescroll-body> -->
 	</view>
 </template>
 
@@ -39,7 +39,7 @@
 		},
 		 props: {
 			 storeId:'',
-			 scrollHeight: 0
+			 top: 0
 		 },
 		data() {
 			return {
@@ -60,7 +60,7 @@
 						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
 						size: 10 // 每页数据的数量,默认10
 					},
-					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					noMoreSize: 20, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
 					empty: {
 						icon:'https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/empty_icon.png',
 						tip: '暂无数据'
@@ -85,18 +85,18 @@
 				}
 			}
 		},
-		watch: {
-		  storeId: {
-		    immediate: true,           // 第一次也触发
-		    handler (newVal, oldVal) {
-		      console.log('msg 变了:', newVal)
-			  if(newVal) {
-				  console.log(this.mescroll)
-				 this.mescroll.resetUpScroll()
-			  }
-		    }
-		  }
-		},
+		// watch: {
+		//   storeId: {
+		//     immediate: true,           // 第一次也触发
+		//     handler (newVal, oldVal) {
+		//       console.log('msg 变了:', newVal)
+		// 	  if(newVal) {
+		// 		  console.log(this.mescroll)
+		// 		 this.mescroll.resetUpScroll()
+		// 	  }
+		//     }
+		//   }
+		// },
 		methods:{
 			navTo(url) {
 				uni.navigateTo({
@@ -110,34 +110,31 @@
 			downCallback(mescroll) {
 				mescroll.resetUpScroll()
 			},
-			upCallback(page) {
+			getProducts(storeId) {
+				this.storeId = storeId
 				//联网加载数据
 				var that = this;
 				const param = {
-					page: page.num,
-					pageSize: page.size,
-					storeId: this.storeId
+					page: 1,
+					pageSize: 10,
+					storeId: this.storeId,
+					isGood: 1
 				}
 				getProducts(param).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);
+						that.dataList = res.data.list;
+						// that.mescroll.endBySize(res.data.list.length, 10);
 						
 					}else{
 						uni.showToast({
 							icon:'none',
 							title: "请求失败",
 						});
-						that.dataList = null;
-						that.mescroll.endErr();
+						// that.dataList = null;
+						// that.mescroll.endErr();
 					}
+					that.$emit('refreshElementTop')
 				});
 			},
 			// 查看详情

+ 147 - 99
pages_store/storeIndex.vue

@@ -8,7 +8,7 @@
 				<view class="search-cont">
 					<view class="inner">
 						<image class="icon-search" src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/shop/image/icon_search.png" mode=""></image>
-						<input type="text" disabled   confirm-type="搜索" @click="toSearch" placeholder="输入药品名称" placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
+						<input type="text" disabled   confirm-type="搜索" @click="toSearch" placeholder="查找店内药品" placeholder-style="font-size:28rpx;color:#BBBBBB;font-family: PingFang SC;" />
 					</view>
 				</view>
 			</view>
@@ -23,7 +23,7 @@
 				<!-- <view class="storebox-btn" @click="goStoreDetail">详情</view> -->
 			</view>
 			<view class="top-fixed x-ac" style="background-color: #fff;">
-				 <view style="width: 50%;">
+				 <view>
 					 <u-tabs
 					  :scrollable="false"
 					  :list="tabs"  
@@ -34,12 +34,20 @@
 				 </view>
 			</view>
 		</view>
-		<view  :style="{height: divHeight,background:' #f5f5f5',overflow:'auto'}">
-			<view v-show="current==0" style="width: 100%;">
-				<tuiStoreProduct ref="tuiStoreProduct" :scrollHeight="mescrollHeight" :storeId="storeId"></tuiStoreProduct>
+			<view v-show="current!=1"  :style="{paddingTop: mescrollTop+'px'}">
+				<tuiStoreProduct ref="tuiStoreProduct" :top="mescrollTop" :storeId="storeId" @refreshElementTop="getElementTop"></tuiStoreProduct>
+				<view class="evaluate">
+					<view class="title">店内商品评价({{evaluateTotal}})</view>
+					<evaluateItem v-for="(item,index) in evaluate" :key="index" :item="item"></evaluateItem>
+					<view class="footer-desc" v-if="evaluate&&evaluate.length>0"> 
+						<text @click="moreEvaluate">查看更多评价</text>
+						<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/shop/image/arrow_gray.png"></image>
+					</view>
+				</view>
+				<detail class="store-detail" ref="getStoreInfo" :storeInfo="storeInfo"></detail>
 			</view>
-			<view v-if="current==1" style="height: 100%" class="medic-box">
-				<view class="cate-list">
+			<view v-if="current==1" class="medic-box">
+				<view class="cate-list" :style="{top: mescrollTop+'px',height:divHeight}">
 					<view 
 						v-for="(item,index) in cates" 
 						:key="index" 
@@ -48,9 +56,10 @@
 					>{{item.cateName }}</view>
 				</view>
 				<view class="medic">
-					<mescroll-body :height="mescrollHeight+'px'" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
-					<view style="display: flex;flex-wrap: wrap;">
-						<medicineVerticalItem v-for="(item, index) in dataList" :key="index" :item="item" :storeId="storeId"></medicineVerticalItem>
+					<mescroll-body :top="mescrollTop+'px'" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
+					<view  style="padding-right: 16rpx;">
+						<medicineItem v-for="(item, index) in dataList" :key="index" :item="item" :storeId="storeId"></medicineItem>
+						<!-- <medicineVerticalItem v-for="(item, index) in dataList" :key="index" :item="item" :storeId="storeId"></medicineVerticalItem> -->
 					</view>
 					</mescroll-body>
 					<!-- 轮播图 -->
@@ -70,26 +79,8 @@
 							</swiper-item>
 						</swiper>
 					</view> -->
-					<!-- 药品列表 -->
-					<!-- <view class="medic-list">
-							<view class="item" v-for="(item,index) in subCates" :key="index">
-								<view class="title">{{item.cateName}}</view>
-								<view class="inner-list">
-									<view class="definite"v-for="(subItem,index) in subCates"   @click="showProductList(subItem)">
-										<view class="img-box">
-											<image :src="subItem.pic" mode="aspectFit"></image>
-										</view>
-										<view class="name ellipsis">{{subItem.cateName}}</view>
-									</view>
-								</view>
-							</view>
-					</view> -->
 				</view>
 			</view>
-			<template v-if="current==2">
-				<detail ref="getStoreInfo" :storeInfo="storeInfo"></detail>
-			</template>
-		</view>
 	</view>
 </template>
 
@@ -99,7 +90,10 @@
 	import qualifications from './components/qualifications.vue'
 	import {getProductCate,storeDetail,getProducts} from '@/api/index.js'
 	import medicineVerticalItem from "@/components/medicineVerticalItem";
+	import medicineItem from "@/components/medicineItem";
+	import evaluateItem from "@/components/evaluateItem";
 	import detail from './components/storeDetail.vue'
+	import {selectCommentByUser} from '@/api/myStoreOrder.js'
 	// import {getAdv} from '@/api/adv'
 	export default {
 		mixins: [MescrollMixin], // 使用mixin
@@ -107,6 +101,8 @@
 			tuiStoreProduct,
 			qualifications,
 			medicineVerticalItem,
+			medicineItem,
+			evaluateItem,
 			detail
 		},
 		data() {
@@ -132,6 +128,10 @@
 					},
 					{
 						id:3,
+						name:'评价'
+					},
+					{
+						id:4,
 						name:'详情'
 					}
 				],
@@ -171,7 +171,12 @@
 					pid:'',
 					storeId: ''
 				},
-				mescrollHeight: 200
+				mescrollTop: 200,
+				evaluate: [],
+				evaluateTotal: 0,
+				isScrollUpdating: false, // 标志位
+				evaluateTop: 0,
+				storeDetailTop: 0
 			};
 		},
 		onLoad(option) {
@@ -183,31 +188,56 @@
 				menus:["shareAppMessage","shareTimeline"] //不设置默认发送给朋友
 			})
 			this.getProductCate();
-			this.getStoreInfo()
+			this.getStoreInfo();
+			this.getCommentByUser();
+		},
+		onReady() {
+			this.$refs.tuiStoreProduct.getProducts(this.storeId)
 		},
 		onShow() {
 			var that=this;
 			setTimeout(function(){
 				let info = uni.createSelectorQuery().select(".top-content");
 		     info.boundingClientRect(function(data) { //data - 各种参数
-		       	console.log(data.height)  // 获取元素宽度
+		//        	console.log(data.height)  // 获取元素宽度
 					// console.log(uni.upx2px(10)) 
 					that.divHeight="calc(100% - "+data.height+"px)"
-					that.mescrollHeight = uni.getSystemInfoSync().screenHeight - data.height
+					that.mescrollTop = data.height
 		      }).exec()
 			},500);
-			// this.getAdv();
+		},
+		onPageScroll(e) {
+			if (this.isScrollUpdating) return;
+		    const scrollTop = e.scrollTop;
+		
+		    if (this.evaluateTop && this.storeDetailTop) {
+		        if (scrollTop >= this.storeDetailTop) {
+		            this.current = 3;
+		        } else if (scrollTop >= this.evaluateTop) {
+		            this.current = 2;
+		        } else {
+		            this.current = 0; // 或其他默认值
+		        }
+		    }
 		},
 		methods:{
-			// divHeight(){
-			//    return 'height:calc(100% - ${this.top}px);'
-			// },
+			getElementTop(type) {
+				this.$nextTick(() => {
+					const query = uni.createSelectorQuery().in(this);
+					query.select('.evaluate').boundingClientRect();
+					query.select('.store-detail').boundingClientRect(); // 注意:ref 不能直接用于 select,需要加 class
+					query.exec(res => {
+						this.evaluateTop = res[0]?.top - this.mescrollTop || 0;
+						this.storeDetailTop = res[1]?.top - this.mescrollTop || 0;
+					});
+				});
+			},
 			getStoreInfo() {
-				console.log(this.storeId)
 				storeDetail(this.storeId).then(res=>{
 					if(res.code==200) {
 						this.storeInfo =res.data || {}
 					}
+					this.getElementTop('storeDetailTop');
 				})
 			},
 			navback() {
@@ -215,6 +245,23 @@
 			},
 			tabChange(item) {
 				this.current=item.index
+				this.isScrollUpdating = true; 
+				if ([0, 2, 3].includes(this.current)) {
+				    const scrollMap = {
+				        0: 0,
+				        2: this.evaluateTop,
+				        3: this.storeDetailTop
+				    };
+				    setTimeout(()=>{
+						uni.pageScrollTo({
+							scrollTop: scrollMap[this.current] || 0 ,
+							duration: 0,
+							complete: () => {
+								this.isScrollUpdating = false;
+							}
+						});
+					},100)
+				}
 			},
 			toSearch() {
 				uni.navigateTo({
@@ -222,7 +269,6 @@
 				})
 			},
 			handleAdvClick(item){
-				console.log(item);
 				if(item.showType==1){
 					uni.setStorageSync('url',item.advUrl);
 					uni.navigateTo({
@@ -299,7 +345,6 @@
 				    return item.pid==that.cateSelect
 				});
 				 
-				console.log(this.subCates);
 			},
 			// 查看药品详情
 			showProductList(item) {
@@ -354,14 +399,59 @@
 					}
 				});
 			},
+			moreEvaluate() {
+				uni.navigateTo({
+					url: '/pages_shopping/evaluate?storeId='+this.storeId,
+				})
+			},
+			getCommentByUser(){
+				const param = {
+					page: 1,
+					pageSize: 2,
+					storeId:this.storeId,
+					orderId: null,
+					productIds:null,
+					userId: uni.getStorageSync('userId') || null,
+					showSelf: 0
+				}
+				selectCommentByUser(param).then(res=>{
+					if(res.code==200) {
+						this.evaluate = res.data.list
+						this.evaluateTotal = res.data.total
+					} else {
+						this.evaluate = []
+						this.evaluateTotal = 0
+					}
+					this.getElementTop('evaluate');
+				})
+			}
 		}
 	}
 </script>
 
-<style lang="scss">
-	page{
-		height: 100%;
-		background-color: #fff;
+<style lang="scss" scoped>
+	.evaluate {
+		padding: 30rpx 30rpx 0 30rpx;
+		background-color: #FFFFFF;
+		margin-bottom: 24rpx;
+		.title {
+			font-family: PingFang SC, PingFang SC;
+			font-weight: 600;
+			font-size: 30rpx;
+			color: #222222;
+			padding-bottom: 24rpx;
+		}
+		.footer-desc {
+			text-align: center;
+			padding: 0 32rpx 24rpx 0;
+			font-size: 28rpx;
+			color: #999;
+			image{
+				margin-left: 10rpx;
+				width:15rpx;
+				height:20rpx;
+			}
+		}
 	}
 	.storebox {
 		padding: 26rpx 32rpx;
@@ -400,6 +490,9 @@
 		display: flex;
 		flex-direction: column;
 		.top-content{
+			position: fixed;
+			left: 0;
+			top: 0;
 			width: 100%;
 			z-index: 10;
 			background-repeat: no-repeat;
@@ -444,9 +537,17 @@
 		.medic-box{
 			display: flex;
 			background: #fff;
+			::v-deep{
+				.mescroll-body, .mescroll-body{
+					padding-left: 204rpx;
+				}
+			}
 			.cate-list{
+				position: fixed;
+				left: 0;
+				z-index: 999;
 				box-sizing: border-box;
-				width: 200upx;
+				width: 180upx;
 				background: #F2F5F9;
 				display: flex;
 				flex-direction: column;
@@ -455,7 +556,7 @@
 				.item{
 					height: 100upx;
 					line-height: 100upx;
-					padding-left: 30upx;
+					padding-left: 20upx;
 					font-size: 28upx;
 					font-family: PingFang SC;
 					font-weight: 500;
@@ -476,10 +577,8 @@
 				}
 			}
 			.medic{
+				overflow: hidden;
 				box-sizing: border-box;
-				width: calc(100% - 200upx);
-				height: 100%;
-				margin: 0 24upx;
 				.banner-box{
 					margin-top: 30rpx;
 					width: 100%;
@@ -493,57 +592,6 @@
 						height: 100%;
 					}
 				}
-				.medic-list{
-					box-sizing: border-box;
-					padding: 30upx 0;
-					overflow-y: auto;
-					height: calc(100% - 220upx);
-					position: relative;
-					// .item{
-					// 	.title{
-					// 		font-size: 28upx;
-					// 		font-family: PingFang SC;
-					// 		font-weight: bold;
-					// 		color: #333333;
-					// 		padding-top: 20upx;
-					// 		margin-bottom: 30upx;
-					// 	}
-						
-					// }
-					.inner-list{
-						display: flex;
-						flex-wrap: wrap;
-						.definite{
-							width: calc(33% - 20upx);
-							margin-right: 30upx;
-							margin-bottom: 30upx;
-							.img-box{
-								width: 100%;
-								height: 144upx;
-								background: #F5F5F5;
-								border-radius: 8upx;
-								overflow: hidden;
-								display: flex;
-								align-items: center;
-								image{	
-									max-width: 100%;
-								}
-							}
-							.name{
-								width: 100%;
-								margin-top: 20upx;
-								font-size: 24upx;
-								font-family: PingFang SC;
-								font-weight: 500;
-								color: #666666;
-								text-align: center;
-							}
-							&:nth-child(3n) {
-								margin-right: 0;
-							}
-						}
-					}
-				}
 			}
 		}
 		

+ 1 - 3
pages_user/api/storeAfterSales.js

@@ -20,9 +20,7 @@ let request = new Request().http
  }
  export function addDelivery(data) {
  	 return request('/store/app/storeAfterSales/addDelivery',data,'POST','application/json;charset=UTF-8');
- }
- 
- 
+ } 
  
  
  

+ 0 - 79
pages_user/api/storeOrder.js

@@ -1,79 +0,0 @@
-import Request from '@/common/request.js';
-let request = new Request().http
-
- 
- export function getMyStoreOrderList(data) {
- 	 return request('/store/app/storeOrder/getMyStoreOrderList',data,'GET');
- } 
- export function getCompanyStoreOrderList(data) {
- 	 return request('/store/app/storeOrder/getCompanyStoreOrderList',data,'GET');
- } 
- export function getMyStoreOrderById(data) {
- 	 return request('/store/app/storeOrder/getMyStoreOrderById',data,'GET');
- } 
- 
- 
- export function getStoreOrderById(data) {
- 	 return request('/store/app/storeOrder/getStoreOrderById',data,'GET');
- } 
- 
- 
- export function confirm(data) {
- 	 return request('/store/app/storeOrder/confirm',data,'POST','application/json;charset=UTF-8');
- }
- export function computed(data) {
- 	 return request('/store/app/storeOrder/computed',data,'POST','application/json;charset=UTF-8');
- }
- export function create(data) {
- 	 return request('/store/app/storeOrder/create',data,'POST','application/json;charset=UTF-8');
- }
- export function pay(data) {
- 	 return request('/store/app/storeOrder/pay',data,'POST','application/json;charset=UTF-8');
- }
- 
- export function editPayType(data) {
- 	 return request('/store/app/storeOrder/editPayType',data,'POST','application/json;charset=UTF-8');
- }
- 
- export function payRemain(data) {
- 	 return request('/store/app/storeOrder/payRemain',data,'POST','application/json;charset=UTF-8');
- }
- 
- export function otherPayment(data) {
- 	 return request('/store/app/storeOrder/otherPayment',data,'POST','application/json;charset=UTF-8');
- }
- 
- export function otherPaymentRemain(data) {
- 	 return request('/store/app/storeOrder/otherPaymentRemain',data,'POST','application/json;charset=UTF-8');
- }
- 
- 
- export function cancelOrder(data) {
- 	 return request('/store/app/storeOrder/cancelOrder',data,'POST','application/json;charset=UTF-8');
- }
- export function finishOrder(data) {
- 	 return request('/store/app/storeOrder/finishOrder',data,'POST','application/json;charset=UTF-8');
- }
- export function getExpress(data) {
- 	 return request('/store/app/storeOrder/getExpress',data,'POST','application/json;charset=UTF-8');
- }
- 
- 
- export function confirmPackageOrder(data) {
- 	 return request('/store/app/storeOrder/confirmPackageOrder',data,'POST','application/json;charset=UTF-8');
- }
- export function computedPackageOrder(data) {
- 	 return request('/store/app/storeOrder/computedPackageOrder',data,'POST','application/json;charset=UTF-8');
- }
- 
- export function createPackageOrder(data) {
- 	 return request('/store/app/storeOrder/createPackageOrder',data,'POST','application/json;charset=UTF-8');
- }
- 
- export function getOrderCount() {
- 	 return request('/store/app/storeOrder/getOrderCount',null,'GET');
- } 
- 
- 
- 
- 

+ 1 - 5
pages_user/cert.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="my-content">
 		<view class="item" v-for="item in certs">
-			<image @click="showImg(item)" :src="item"></image>
+			<image @click="showImg(item)" :src="item" mode="widthFix"></image>
 		</view>
 		
 	</view>
@@ -63,10 +63,6 @@ page{
 		align-items: center;
 		margin: 30rpx;
 		width: 100%;
-		image{
-			
-			
-		}
 	}
 	
 }

+ 389 - 24
pages_user/complaint.vue

@@ -29,10 +29,75 @@
 					</view>
 				</view>
 			</u-form-item>
-			<u-form-item label=" " prop="title" v-if="formdata.type == 1">
+			<u-form-item label=" " v-if="formdata.type == 1">
+				<view class="form-item" @click="openStore">
+					<view class="form-item-title x-bc">
+						<text>选择店铺</text>
+						<u-icon name="arrow-right" color="#333" size="18"></u-icon>
+					</view>
+					<view class="storename x-bc">
+						<text>{{storeId? storeName : "选择店铺"}}</text>
+					</view>
+				</view>
+			</u-form-item>
+			<u-form-item label=" " v-if="formdata.complaintType == 2&&formdata.type == 2">
 				<view class="form-item">
-					<view class="form-item-title">选择店铺</view>
-					<view class="storename" @click="openStore">{{storeId? storeName : "选择店铺"}}</view>
+					<view class="form-item-title x-bc" @click="openOrder">
+						<text> 选择订单商品</text>
+						<u-icon name="arrow-right" color="#333" size="18"></u-icon>
+					</view>
+					<view class="orderbox chooseorder" v-show="item&&JSON.stringify(item)!='{}'">
+						<view class="item" >
+							<!-- 订单号,状态 -->
+							<view class="ordersn-box">
+								<view class="num">订单号:{{item.orderCode}}</view>
+								<!-- <view class="status-box">
+									<text   class="text success">
+										{{$getDictLabelName("storeOrderStatus",item.status)}}
+									</text>
+								</view> -->
+							</view>
+							<!-- 药品列表 -->
+							<view  class="drug-list"  >
+								<view v-if="item.isPackage!=1" v-for="(subItem,subIndex) in item.items" :key="subIndex" class="drug-item" >
+									<view class="x-f">
+										<checkbox :value="subItem.checked" :checked="subItem.checked" @click="checkShopChange(subItem)" />
+										<view class="img-box">
+											<image :src="JSON.parse(subItem.jsonInfo).image" mode="aspectFill"></image>
+										</view>
+									</view>
+									<view class="drug-info"  >
+										<view>
+											<view class="name-box ellipsis2">
+												<view v-if="subItem.isPrescribe==1" class="tag">处方药</view>{{JSON.parse(subItem.jsonInfo).productName}}
+											</view>
+											<view class="spec ellipsis2">{{JSON.parse(subItem.jsonInfo).sku}}</view>
+										</view>
+										<view class="num-box">
+											<view class="price">
+												<text class="unit">¥</text>
+												<text class="num">{{JSON.parse(subItem.jsonInfo).price.toFixed(2)}}</text>
+											</view>
+											<view class="amount">x{{JSON.parse(subItem.jsonInfo).num}}</view>
+										</view>
+									</view>
+								</view>
+								<view v-if="item.isPackage==1&&item.packageJson!=null" class="drug-item" >
+									<view class="img-box">
+										<image :src="JSON.parse(item.packageJson).imgUrl" mode="aspectFill"></image>
+									</view>
+									<view class="drug-info"  >
+										<view>
+											<view class="name-box ellipsis2">
+												<view class="tag">套餐</view>{{JSON.parse(item.packageJson).title}}
+											</view>
+											<view class="spec ellipsis2">{{JSON.parse(item.packageJson).descs}}</view>
+										</view>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
 				</view>
 			</u-form-item>
 			<u-form-item label=" " prop="title">
@@ -63,12 +128,75 @@
 			<view class="storePop">
 				<view class="storePop-title">选择店铺</view>
 				<scroll-view class="scroll-list" scroll-y="true" @scrolltolower="lower" >
+					<view v-if="storeList.length == 0" class="no-data-box" >
+						<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/empty_icon.png" mode="aspectFit"></image>
+						<view class="empty-title">暂无店铺</view>
+					</view>
 					<view class="storebox" v-for="(item,index) in storeList" :key="index">
 						<image class="logo" :src="item.store.logoUrl" mode="aspectFill"></image>
 						<view class="storebox-r">
 							<view class="x-bc" style="flex: 1;min-height: 104rpx;">
 								<view class="storename ellipsis">{{item.store.storeName || ''}}</view>
-								<view class="storebox-btn" @click="handleClick(item)">选择</u-icon></view>
+								<view class="storebox-btn" @click="handleClick(item,'store')">选择</u-icon></view>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+		</u-popup>
+		<u-popup :show="showOrder" :closeable="true" @close="closeOrder">
+			<view class="storePop">
+				<view class="storePop-title">选择订单</view>
+				<scroll-view class="scroll-list" style="height: 80vh" scroll-y="true" @scrolltolower="lowerOrder" >
+					<view v-if="orderList.length == 0" class="no-data-box" >
+						<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/empty_icon.png" mode="aspectFit"></image>
+						<view class="empty-title">暂无订单</view>
+					</view>
+					<view class="item" v-for="(item,index) in orderList" :key="index">
+						<!-- 订单号,状态 -->
+						<view class="ordersn-box">
+							<view class="num">订单号:{{item.orderCode}}</view>
+							<view class="storebox-btn" @click="handleClick(item,'order')">选择</u-icon></view>
+							<!-- <view class="status-box">
+								<text   class="text success">
+									{{$getDictLabelName("storeOrderStatus",item.status)}}
+								</text>
+							</view> -->
+						</view>
+						<!-- 药品列表 -->
+						<view  class="drug-list"  >
+							<view v-if="item.isPackage!=1" v-for="(subItem,subIndex) in item.items" :key="subIndex" class="drug-item" >
+								<view class="img-box">
+									<image :src="JSON.parse(subItem.jsonInfo).image" mode="aspectFill"></image>
+								</view>
+								<view class="drug-info"  >
+									<view>
+										<view class="name-box ellipsis2">
+											<view v-if="subItem.isPrescribe==1" class="tag">处方药</view>{{JSON.parse(subItem.jsonInfo).productName}}
+										</view>
+										<view class="spec ellipsis2">{{JSON.parse(subItem.jsonInfo).sku}}</view>
+									</view>
+									<view class="num-box">
+										<view class="price">
+											<text class="unit">¥</text>
+											<text class="num">{{JSON.parse(subItem.jsonInfo).price.toFixed(2)}}</text>
+										</view>
+										<view class="amount">x{{JSON.parse(subItem.jsonInfo).num}}</view>
+									</view>
+								</view>
+							</view>
+							<view v-if="item.isPackage==1&&item.packageJson!=null" class="drug-item" >
+								<view class="img-box">
+									<image :src="JSON.parse(item.packageJson).imgUrl" mode="aspectFill"></image>
+								</view>
+								<view class="drug-info"  >
+									<view>
+										<view class="name-box ellipsis2">
+											<view class="tag">套餐</view>{{JSON.parse(item.packageJson).title}}
+										</view>
+										<view class="spec ellipsis2">{{JSON.parse(item.packageJson).descs}}</view>
+									</view>
+								</view>
 							</view>
 						</view>
 					</view>
@@ -79,6 +207,7 @@
 </template>
 
 <script>
+	import {getMyStoreOrderList} from '@/api/myStoreOrder.js'
 	import {recommendList} from "@/api/index.js"
 	import {storeComplaint} from "@/api/user.js"
 	export default {
@@ -112,11 +241,20 @@
 						required: true,
 						message: '请输入内容'
 					}],
-					images: [{
-						required: true,
-						message: '请上传凭证'
-					}]
-				}
+					// images: [{
+					// 	required: true,
+					// 	message: '请上传凭证'
+					// }]
+				},
+				item: {},
+				showOrder: false,
+				orderList: [],
+				orderParamQuery: {
+					total: 0,
+					pageNum: 1,
+					isLastPage: false
+				},
+				orderInfo: {}
 			}
 		},
 		methods: {
@@ -136,10 +274,24 @@
 					this.getList();
 				}
 			},
-			handleClick(item) {
-				this.storeId = item.store.storeId
-				this.storeName = item.store.storeName
-				this.show = false
+			handleClick(item,type) { 
+				if(type=='order') {
+					this.showOrder = false
+					item.items = item.items.map(it=>({
+						...it,
+						checked: true
+					}))
+					this.item = item
+					this.orderId = item.id
+					console.log("this.item==",this.item)
+				} else if(type=='store') {
+					this.storeId = item.store.storeId
+					this.storeName = item.store.storeName
+					this.show = false
+				}
+			},
+			checkShopChange(item) {
+				item.checked = !item.checked;
 			},
 			getList(){
 				if(this.isLastPage){
@@ -193,6 +345,24 @@
 					})
 					return
 				}
+				let productIds = ''
+				if(this.formdata.complaintType == 2&&this.formdata.type == 2) {
+					if(this.item==null || JSON.stringify(this.item)=='{}') {
+						uni.showToast({
+							title: '请选择订单',
+							icon: 'none'
+						})
+						return
+					}
+					productIds = this.item.items.filter(it => it.checked == true).map(ele=>ele.productId).join(',')
+					if(!productIds) {
+						uni.showToast({
+							title: '请选择商品',
+							icon: 'none'
+						})
+						return
+					}
+				}
 				this.$refs.uForm.validate().then(res => {
 					if (res) {
 						this.$isLogin().then(res => {
@@ -200,7 +370,9 @@
 								if(this.formdata.type == 1) {
 									this.formdata = {
 										...this.formdata,
-										storeId: this.storeId
+										storeId: this.storeId,
+										orderId: this.orderId,
+										productIds: productIds
 									}
 								}
 								storeComplaint(this.formdata).then(res => {
@@ -277,6 +449,47 @@
 					});
 				})
 			},
+			openOrder() {
+				this.showOrder = true
+				this.orderParamQuery.pageNum = 1
+				this.getOrderList()
+			},
+			closeOrder() {
+				this.showOrder = false
+			},
+			lowerOrder(event) {
+				if(this.orderParamQuery.total>this.orderList.length){
+					this.orderParamQuery.pageNum++;
+					this.getOrderList();
+				}
+			},
+			getOrderList(){
+				if(this.orderParamQuery.isLastPage){
+					return;
+				}
+				const param = {
+					pageSize: 10,
+					statusList:'3,4',
+					page: this.orderParamQuery.pageNum,
+				};
+				getMyStoreOrderList(param).then(res => {
+					if(res.code==200){
+						//设置列表数据
+						if (this.orderParamQuery.pageNum == 1) {
+							this.orderList = res.data.list; 
+						} else {
+							this.orderList = this.orderList.concat(res.data.list);
+						}
+						this.orderParamQuery.total=res.data.total
+						this.orderParamQuery.isLastPage=res.data.isLastPage
+					}else{
+						uni.showToast({
+							icon:'none',
+							title: "请求失败",
+						});
+					}
+				});
+			},
 		}
 	}
 </script>
@@ -293,6 +506,16 @@
 	::v-deep .u-form-item__body {
 		padding: 0 !important;
 	}
+	.chooseorder {
+		padding: 0 !important;
+		.item {
+			padding: 0 !important;
+			margin-bottom: 0 !important;
+		}
+		.ordersn-box {
+			padding: 20rpx 0 !important;
+		}
+	}
 	.storePop{
 		background-color: #f5f5f5;
 		&-title {
@@ -334,18 +557,18 @@
 				flex: 1;
 				overflow: hidden;
 			}
-			.storebox-btn {
-				flex-shrink: 0;
-				padding: 10rpx 24rpx;
-				font-size: 28rpx;
-				border-radius: 28rpx 28rpx 28rpx 28rpx;
-				border: 2rpx solid #FF5C03;
-				font-weight: 500;
-				font-size: 24rpx;
-				color: #FF5C03;
-			}
 		}
 	}
+	.storebox-btn {
+		flex-shrink: 0;
+		padding: 10rpx 24rpx;
+		font-size: 28rpx;
+		border-radius: 28rpx 28rpx 28rpx 28rpx;
+		border: 2rpx solid #FF5C03;
+		font-weight: 500;
+		font-size: 24rpx;
+		color: #FF5C03;
+	}
 	.btn-box {
 		width: 100%;
 		height: 120upx;
@@ -420,4 +643,146 @@
 		justify-content: space-between;
 		padding: 24rpx !important;
 	}
+	.orderbox{
+		padding: 20upx;
+	}
+	.item{
+		background: #FFFFFF;
+		border-radius: 16upx;
+		padding: 0 30upx;
+		margin-bottom: 20upx;
+		.ordersn-box{
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			padding: 34upx 0 20upx;
+			.num{
+				font-size: 26upx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				line-height: 1;
+			}
+			.status-box{
+				display: flex;
+				align-items: center;
+				.recom-box{
+					width: 108upx;
+					height: 30upx;
+					line-height: 30upx;
+					text-align: left;
+					padding-left: 8upx;
+					font-size: 22upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #FFFFFF;
+					background-image: url('https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/recom.png');
+					background-repeat: no-repeat;
+					background-size: 100% 100%;
+					margin-right: 8upx;
+				}
+				.text{
+					font-size: 28upx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					line-height: 1;
+					&.success{
+						color: #2BC7B9;
+					}
+					&.black{
+						color: #111111;
+					}
+					&.info{
+						color: #999999;
+					}
+				}
+			}
+		}
+		.drug-list{
+			.drug-item{
+				padding: 30upx 0;
+				border-bottom: 1px soli #F0F0F0;
+				display: flex;
+				align-items: center;
+				.img-box{
+					width: 160upx;
+					height: 160upx;
+					margin-right: 30upx;
+					flex-shrink: 0;
+					image{
+						width: 100%;
+						height: 100%;
+					}
+				}
+				.drug-info{
+					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, #2BC7B9 0%, #2BC7A4 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{
+						font-size: 24upx;
+						font-family: PingFang SC;
+						font-weight: 500;
+						color: #999999;
+						line-height: 1;
+						margin-top: 10upx;
+					}
+					.num-box{
+						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;
+							}
+						}
+						.amount{
+							font-size: 24upx;
+							font-family: PingFang SC;
+							font-weight: 500;
+							color: #999999;
+							line-height: 1;
+						}
+					}
+				}
+			}
+		}
+	}
 </style>

+ 14 - 4
pages_user/complaintList.vue

@@ -2,15 +2,17 @@
 	<view style="padding: 24rpx;">
 		<mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption">
 		<view class="list x-f" v-for="(item,index) in dataList" :key="index">
-			<view class="image" v-if="item.isHandlePlatform==0&&item.isHandleStore==0">
+			<view class="image">
 				<image :src="item.images?item.images.split(',')[0]:''" mode="aspectFill" style="width: 100%;height: 100%;"></image>
-				<view class="tag" :style="{backgroundColor: item.isHandlePlatform==0&&item.isHandleStore==0 ? 'red':'#2583EB'}">{{item.isHandlePlatform==0&&item.isHandleStore==0 ? '待处理':'已处理'}}</view>
+				<view class="tag" :style="{backgroundColor: item.isProcessCompleted==1? '#eee': item.isHandlePlatform==0&&item.isHandleStore==0 ? 'red':'#2583EB', color: item.isProcessCompleted==1? '#666':'#fff'}">
+					{{item.isProcessCompleted==1? '已结束':item.isHandlePlatform==0&&item.isHandleStore==0 ? '待处理':'已处理'}}
+				</view>
 			</view>
-			<view style="flex: 1;overflow: hidden;">
+			<view style="flex: 1;overflow: hidden;" @click="showDetail(item)">
 				<view class="ellipsis2">{{item.title}}</view>
 				<view class="x-bc">
 					<view class="time">{{item.createTime}}</view>
-					<view class="btn" @click="showDetail(item)">查看</view>
+					<view class="btn">查看</view>
 				</view>
 			</view>
 		</view>
@@ -25,6 +27,10 @@
 			return {
 				mescroll:null,
 				// 上拉加载的配置
+				downOption: {   //下拉刷新
+				 	use:true,
+					auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback)
+				},
 				upOption: {
 					onScroll:true,
 					use: true, // 是否启用上拉加载; 默认true
@@ -33,6 +39,7 @@
 						size: 10 // 每页数据的数量,默认10
 					},
 					noMoreSize: 10, // 配置列表的总数量要大于等于5条才显示'-- END --'的提示
+					textNoMore: '没有更多了', 
 					empty: {
 						icon:'/static/images/no_data.png',
 						tip: '暂无数据'
@@ -42,6 +49,9 @@
 				dataList: []
 			}
 		},
+		onShow() {
+			this.mescroll.resetUpScroll()
+		},
 		methods: {
 			showDetail(item) {
 				uni.navigateTo({

+ 41 - 8
pages_user/complaintListDetail.vue

@@ -4,13 +4,16 @@
 			<image v-for="(img,i) in images" :key="i" :src="img" mode="aspectFill" @click="previewImage(i,images)"></image>
 		</view>
 		<viwe class="con">
-			<view class="title">{{info.title}}</view>
+			<view class="title">
+				<text class="tag" :style="{backgroundColor: info.isProcessCompleted==1? '#eee': info.isHandlePlatform==0&&info.isHandleStore==0 ? 'red':'#2583EB', color: item.isProcessCompleted==1? '#666':'#fff'}">
+					{{info.isProcessCompleted==1? '已结束':info.isHandlePlatform==0&&info.isHandleStore==0 ? '待处理':'已处理'}}
+				</text>{{info.title}}</view>
 			<view>{{info.content}}</view>
 			<view style="margin-top: 24rpx;color:#999999">时间:{{info.createTime || '--'}}</view>
 		</viwe>
-		<viwe class="con">
+		<viwe class="con" v-show="msgList&&msgList.length>0">
 			<view class="msg">
-				<view v-for="(msg,i) in msgList" :key="i" style="margin-bottom: 24rpx;">
+				<view v-for="(msg,i) in msgList" :key="i" :class="msg.sendType !=1?'storemsg':''" style="margin-bottom: 24rpx;">
 					<view class="lable">{{msg.sendType ==2?'商家回复:':msg.sendType ==3?'平台回复:':msg.sendType ==1?'我:':''}}</view>
 					<view class="imgs" v-if="msg.images">
 						<image v-for="(img,i) in msg.images.split(',')" :key="i" :src="img" mode="aspectFill" @click="previewImage(i,msg.images.split(','))"></image>
@@ -18,7 +21,7 @@
 					<view class="val">{{msg.content||''}}</view>
 					<view class="val x-f" style="margin-top: 10rpx;font-size: 28rpx;color:#999999;">
 						<text style="margin-right: 16rpx;">{{msg.createTime || '--'}}</text>
-						<u-icon name="chat" color="#999" size="48rpx" v-if="msg.sendType ==2||msg.sendType ==3" @click="open"></u-icon>
+						<!-- <u-icon name="chat" color="#999" size="48rpx" v-if="info.isProcessCompleted!=1&&(msg.sendType ==2||msg.sendType ==3)" @click="open"></u-icon> -->
 					</view>
 				</view>
 			</view>
@@ -27,6 +30,9 @@
 				<view class="val x-f" style="margin-top: 10rpx;font-size: 28rpx;color:#999999;"><text style="margin-right: 16rpx;">2022-12-22 12:33</text></view>
 			</view> -->
 		</viwe>
+		<view class="chatbox" v-if="info.isProcessCompleted!=1">
+			<u-icon name="chat" color="#999" size="48rpx"@click="open"></u-icon>
+		</view>
 		<u-popup :show="show" :closeable="true" @close="close">
 			<view class="replybox">
 				<view class="replybox-title">回复:</view>
@@ -188,18 +194,41 @@
 </script>
 
 <style scoped lang="scss">
+	.chatbox {
+		height: 80rpx;
+		width: 80rpx;
+		border-radius: 50%;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		position: fixed;
+		bottom: 200rpx;
+		right: 50rpx;
+		z-index: 999;
+		box-shadow: 0 0 20px 5px #eee;
+		background-color: #fff;
+	}
 	.lable {
 		margin-bottom: 16rpx;
+		font-weight: bold;
+	}
+	.tag {
+		padding: 5rpx 6rpx;
+		font-size: 20rpx;
+		color: #FFFFFF;
+		background-color: red;
+		border-radius: 10rpx;
+		margin-right: 10rpx;
 	}
 	.send{
 		flex-shrink: 0;
 		padding: 10rpx 24rpx;
 		font-size: 28rpx;
 		border-radius: 28rpx 28rpx 28rpx 28rpx;
-		border: 2rpx solid #FF5C03;
+		background-color: #2583EB;
 		font-weight: 500;
 		font-size: 24rpx;
-		color: #FF5C03;
+		color: #fff;
 	}
 	.replybox {
 		padding: 0 24rpx 24rpx 24rpx;
@@ -221,9 +250,12 @@
 	}
 	.msg{
 		margin-bottom: 20rpx;
+		border-radius: 16rpx 16rpx 16rpx 16rpx;
+	}
+	.storemsg {
 		background-color: #f5f5f5;
 		padding: 16rpx;
-		border-radius: 16rpx 16rpx 16rpx 16rpx;
+		border-radius: 16rpx;
 	}
 	.val {
 		color:#222;
@@ -251,8 +283,9 @@
 			color: #666666;
 			.title {
 				font-size: 30rpx;
-				font-weight: 500;
+				font-weight: bold;
 				color: #333;
+				margin-bottom: 16rpx;
 			}
 		}
 	}

+ 134 - 54
pages_user/registerDoctor.vue

@@ -11,7 +11,7 @@
 					<view v-if="form.doctorType==2" class="desc">请填写药师资料</view>
 				</view>
 				<view class="my-form"  >
-					<u-form   :rules="rules" :model="form" ref="uForm" labelPosition="left">
+					<u-form   :rules="rules" :model="form" ref="uForm" labelPosition="left" errorType="toast">
 						<u-form-item labelWidth="180rpx"  borderBottom label="真实姓名" prop="doctorName">
 							<u-input border="none" placeholder="请输入真实姓名" v-model="form.doctorName" />
 						</u-form-item>
@@ -42,7 +42,7 @@
 						</u-form-item>
 						
 						
-						<u-form-item labelWidth="180rpx" prop="cityId" @click="cityShow=true"  borderBottom label="所在城市">
+						<u-form-item labelWidth="180rpx" prop="cityIds" @click="cityShow=true"  borderBottom label="所在城市">
 							<u-input
 								v-model="form.cityName"
 								disabled
@@ -57,34 +57,36 @@
 							</template>
 							 
 						</u-form-item>
-						<u-form-item labelWidth="180rpx" prop="hospitalId" @click="hospitalShow=true"  borderBottom label="就职医院">
-							<u-input
-								v-model="form.hospitalName"
-								disabled
-								disabledColor="#ffffff"
-								placeholder="请选择医院"
-								border="none"
-							></u-input>
-							<template #right>
-								<u-icon
-									name="arrow-right"
-								></u-icon>
-							</template>
-						</u-form-item>
-						<u-form-item labelWidth="180rpx" prop="deptId" @click="deptShow=true"  borderBottom label="所属科室">
-							<u-input
-								v-model="form.deptName"
-								disabled
-								disabledColor="#ffffff"
-								placeholder="请选择科室"
-								border="none"
-							></u-input>
-							<template #right>
-								<u-icon
-									name="arrow-right"
-								></u-icon>
-							</template>
-						</u-form-item>
+						<template v-if="form.doctorType==1">
+							<u-form-item labelWidth="180rpx" prop="hospitalId" @click="hospitalShow=true"  borderBottom label="就职医院">
+								<u-input
+									v-model="form.hospitalName"
+									disabled
+									disabledColor="#ffffff"
+									placeholder="请选择医院"
+									border="none"
+								></u-input>
+								<template #right>
+									<u-icon
+										name="arrow-right"
+									></u-icon>
+								</template>
+							</u-form-item>
+							<u-form-item labelWidth="180rpx" prop="deptId" @click="deptShow=true"  borderBottom label="所属科室">
+								<u-input
+									v-model="form.deptName"
+									disabled
+									disabledColor="#ffffff"
+									placeholder="请选择科室"
+									border="none"
+								></u-input>
+								<template #right>
+									<u-icon
+										name="arrow-right"
+									></u-icon>
+								</template>
+							</u-form-item>
+						</template>
 						<u-form-item labelWidth="180rpx" prop="position" @click="positionShow=true"  borderBottom label="职称">
 							<u-input
 								v-model="form.position"
@@ -99,13 +101,29 @@
 								></u-icon>
 							</template>
 						</u-form-item>
+						<template v-if="form.doctorType==2">
+							<u-form-item labelWidth="180rpx" prop="position" @click="storeShow=true"  borderBottom label="药店">
+								<u-input
+									v-model="form.storeName"
+									disabled
+									disabledColor="#ffffff"
+									placeholder="请选择药店"
+									border="none"
+								></u-input>
+								<template #right>
+									<u-icon
+										name="arrow-right"
+									></u-icon>
+								</template>
+							</u-form-item>
+						</template>
 						<u-form-item labelWidth="180rpx" borderBottom label="擅长领域" prop="speciality">
 							<u--textarea v-model="form.speciality" placeholder="请输入擅长领域" count ></u--textarea>
 						</u-form-item>
 						<u-form-item labelWidth="180rpx" borderBottom label="个人简介" prop="introduction">
 							<u--textarea v-model="form.introduction" placeholder="请输入个人简介" count ></u--textarea>
 						</u-form-item>
-						<u-form-item labelWidth="180rpx" borderBottom label="医生照片" prop="avatar">
+						<u-form-item labelWidth="180rpx" borderBottom :label="`${typeName}照片`" prop="avatar">
 							<u-upload
 								:fileList="fileList1"
 								@afterRead="afterRead"
@@ -176,14 +194,14 @@
 						>
 						</u-checkbox>
 					</u-checkbox-group>
-					<text class="text" @click="openContent('doctorRegister')" >《医生注册协议》</text>
-					<text class="text" @click="openContent('doctorFiling')" >《医生多机构备案协议》</text>
+					<text class="text" @click="openContent('doctorRegister')" >{{`《${typeName}注册协议》`}}</text>
+					<text class="text" @click="openContent('doctorFiling')" >{{`《${typeName}多机构备案协议》`}}</text>
 				</view>
 				<u-picker ref="cityPicker" @cancel="cityShow = false"  keyName="n" @confirm="citySelect" @change="cityChangeHandler"  :show="cityShow" :columns="citys"></u-picker>
 				<u-picker ref="deptPicker" @cancel="deptShow = false"  keyName="deptName" @confirm="deptSelect"   :show="deptShow" :columns="depts"></u-picker>
 				<u-picker  @cancel="hospitalShow = false"  keyName="hospitalName" @confirm="hospitalSelect"    :show="hospitalShow" :columns="hospitals"></u-picker>
 				<u-picker ref="positionPicker" @cancel="positionShow = false"  keyName="dictLabel" @confirm="positionSelect"   :show="positionShow" :columns="positions"></u-picker>
-						
+				<u-picker ref="storePicker" @cancel="storeShow = false"  keyName="storeName" @confirm="storeSelect"   :show="storeShow" :columns="stores"></u-picker>		
 			</view>
 			<view class="btn-box">
 				<view class="sub-btn" @click="submit()">提交</view>
@@ -196,6 +214,7 @@
 <script>
 import {getDictByKey,getHospitalList,getDepartmentList,sendSmsCode,uploadOSS,getCitys} from '@/api/common.js'
 import {registerDoctor} from '@/api/user.js'
+import { getStoreList } from '@/api/store.js'
 
 export default {
  	data() {
@@ -218,12 +237,14 @@ export default {
 			checked:0,
 			form:{
 				sex:"1",
+				introduction: '',
+				speciality:''
 			},
 			rules: {
 				doctorName: [
 					{ 
 						required: true, 
-						message: '请输入医生姓名', 
+						message: '请输入真实姓名', 
 					}
 				],
 				idCard: [
@@ -234,18 +255,6 @@ export default {
 						trigger: ['change','blur'],
 					}
 				],
-				deptId: [
-					{ 
-						required: true, 
-						message: '请选择部门'
-					}
-				],
-				hospitalId: [
-					{ 
-						required: true, 
-						message: '请选择医院'
-					}
-				],
 				position: [
 					{ 
 						required: true, 
@@ -277,17 +286,33 @@ export default {
 						// 可以单个或者同时写两个触发验证方式 
 						trigger: ['change','blur'],
 					}
+				],
+				speciality : [
+					{ 
+						required: true, 
+						message: '请输入擅长领域',
+					}
 				]
-				 
-			}
+			},
+			typeName: '',
+			storeShow: false,
+			stores: [[]]
  		}
  	},
 	onLoad(options) {
 		this.form.doctorType=options.type;
+		this.typeName= options.type==1 ? '医生':options.type==2 ? '药师' : ''
+		uni.setNavigationBarTitle({
+			title: options.type==1 ? '医生注册':options.type==2 ? '药师注册' : ''
+		})
 		this.getCitys()
 		this.getHospitalList();
 		this.getDepartmentList();
-		this.getDictByKey("sys_doc_position");
+		this.getStoreList()
+		if(options.type==1) {
+			
+		}
+		this.getDictByKey();
 	},
 	onShow() {
 		
@@ -314,8 +339,13 @@ export default {
 			this.form.position=this.positions[0][e.indexs[0]].dictLabel;
 			this.positionShow=false;
 		},
+		storeSelect(e){
+			this.form.storeName=this.stores[0][e.indexs[0]].storeName;
+			this.form.storeId=this.stores[0][e.indexs[0]].storeId;
+			this.storeShow=false;
+		},
 		getDictByKey(key){
-			var data={key:key}
+			var data={key:this.form.doctorType==2?"sys_pharmacist_position":"sys_doc_position"}
 			getDictByKey(data).then(
 				res => {
 					if(res.code==200){
@@ -416,6 +446,20 @@ export default {
 				}
 			);
 		},
+		getStoreList(){
+			var that=this;
+			var data={}
+			getStoreList(data).then(
+				res => {
+					if(res.code==200){
+						that.stores[0]=res.data;
+					}
+				},
+				err => {
+					 
+				}
+			);
+		},
 		deletePic(event) {
 			this[`fileList${event.name}`].splice(event.index, 1)
 		},
@@ -452,7 +496,7 @@ export default {
 					},
 					success: (res) => {
 						setTimeout(() => {
-							console.log(JSON.parse(res.data).url)
+							// console.log(JSON.parse(res.data).url)
 							resolve(JSON.parse(res.data).url)
 						}, 1000)
 					}
@@ -498,7 +542,7 @@ export default {
 				if(images.length!=2){
 					uni.showToast({
 						icon:'none',
-						title:"请上传身份证",
+						title:"请上传身份证照片(正反面)",
 					});
 					return
 					return;
@@ -528,7 +572,40 @@ export default {
 				return
 			}
 			console.log(this.form)
+			// deptId: [
+			// 	{ 
+			// 		required: true, 
+			// 		message: '请选择部门'
+			// 	}
+			// ],
+			// hospitalId: [
+			// 	{ 
+			// 		required: true, 
+			// 		message: '请选择医院'
+			// 	}
+			// ],
  			this.$refs.uForm.validate().then(res => {
+				if(that.form.doctorType == 1&& !that.form.deptId) {
+					uni.showToast({
+						title: '请选择部门',
+						icon: 'none'
+					})
+					return
+				}
+				if(that.form.doctorType == 1&&!that.form.hospitalId) {
+					uni.showToast({
+						title: '请选择医院',
+						icon: 'none'
+					})
+					return
+				}
+				if(that.form.doctorType == 2&&!that.form.storeId) {
+					uni.showToast({
+						title: '请选择药店',
+						icon: 'none'
+					})
+					return
+				}
  				that.register()
  			}).catch(errors => {
 				console.log(errors)
@@ -567,7 +644,10 @@ export default {
 				.title{
 					z-index: 999;
 					padding: 0rpx 30rpx;
-					font-size: 40upx;					font-family: PingFang SC;					font-weight: bold;					color: #FFFFFF;
+					font-size: 40upx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #FFFFFF;
 				}
 				.desc{
 					z-index: 999;

+ 1 - 1
pages_user/shopping/paymentOrderRemain.vue

@@ -64,7 +64,7 @@
 
 <script>
 	import {getUserInfo} from '@/api/user'
-	import {payRemain,getStoreOrderById} from '../api/storeOrder'
+	import {payRemain,getStoreOrderById} from '@/api/myStoreOrder.js'
 	export default {
 		data() {
 			return {

+ 35 - 5
pages_user/shopping/storeOrder.vue

@@ -93,10 +93,12 @@
 							</view>
 							<view class="btn-box">
 								<view v-if="item.status == 0" class="btn cancel" @click="cancel(item)">取消订单</view>
-								<view v-if="item.status == 0" class="btn pay" @click="pay(item)">支付</view>
+								<view v-if="(item.status == 0&&item.isPrescribe!=1)||(item.status == 0&&item.isPrescribe==1&&item.prescribeId)" class="btn pay" @click="pay(item)">支付</view>
+								<view class="btn pay"  v-if="(item.status==0||item.status==1)&&item.isPrescribe==1&&!item.prescribeId"  @click="addPrescribe(item)">开处方</view>
 								<view v-if="item.isAfterSales==1" class="btn cancel" @click="refund(item)">申请售后</view>
 								<view v-if="item.status >=2 &&item.deliveryId!=null" class="btn pay" @click.stop="showDelivery(item)">查看物流</view>
-								<!-- <view v-if="item.status==4" class="btn pay">再次购买</view> -->
+								<view v-if="item.status == 3" class="btn pay" @click.stop="showEvaluate('/pages_shopping/evaluateDetail?orderId='+item.id)">去评价</view>
+								<view v-if="item.status == 4" class="btn pay" @click.stop="showEvaluate('/pages_shopping/evaluate?orderId='+item.id)">查看评价</view>
 							</view>
 						</view>
 					</view>
@@ -107,7 +109,7 @@
 </template>
 
 <script>
-	import {getMyStoreOrderList,cancelOrder} from '../api/storeOrder'
+	import {getMyStoreOrderList,cancelOrder,orderPrescription} from '@/api/myStoreOrder.js'
 	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
 	export default {
 		mixins: [MescrollMixin], 
@@ -120,7 +122,8 @@
 					{name:"待付款",value:"0"},
 					{name:"待发货",value:"1"},
 					{name:"待收货",value:"2"},
-					{name:"已完成",value:"3"}
+					{name:"已完成",value:"3"},
+					{name:"已评价",value:"4"}
 				],
 				mescroll:null,
 				// 上拉加载的配置
@@ -148,6 +151,9 @@
 				that.mescroll.resetUpScroll()
 			})
 		},
+		onUnload() {
+			uni.$off('refreshOrder')
+		},
 		methods: {
 			goSearch(e) {
 				this.searchKey=e.detail.value;
@@ -248,8 +254,32 @@
 				uni.navigateTo({
 					url: './storeOrderDelivery?orderId='+item.id
 				})
+			},
+			showEvaluate(url) {
+				uni.navigateTo({
+					url: url
+				})
+			},
+			addPrescribe(item){
+				orderPrescription(item.id).then(res=>{
+					if(res.code == 200) {
+						// {status:状态 0未开放,跳转填写信息界面。 1开方中,跳转医生开方界面 2开方完成,跳转到支付,jumpLink:status为1时用这个跳转连接}
+						if(res.data.status == 0) {
+							uni.navigateTo({
+							 	url:"/pages_shopping/prescribe?orderId="+item.id
+							})
+						} else if(res.data.status == 1) {
+							uni.navigateTo({
+							 	url: '/pages/index/webview?url='+encodeURIComponent(res.data.jumpLink)
+							})
+						} else if(res.data.status == 2) {
+							uni.navigateTo({
+								url: '/pages_shopping/paymentOrder?orderId='+item.id
+							})
+						}
+					}
+				})
 			}
-			
 		}
 	}
 </script>

+ 1 - 1
pages_user/shopping/storeOrderDelivery.vue

@@ -56,7 +56,7 @@
 </template>
 
 <script>
-	import {getMyStoreOrderById,cancelOrder,getExpress} from '../api/storeOrder'
+	import {getMyStoreOrderById,cancelOrder,getExpress} from '@/api/myStoreOrder.js'
 	export default {
 		data() {
 			return {

+ 35 - 8
pages_user/shopping/storeOrderDetail.vue

@@ -51,7 +51,7 @@
 						</view>
 					</view>
 					<!-- 已完成 -->
-					<view v-if="order.status == 3" class="inner">
+					<view v-if="order.status == 3||order.status == 4" class="inner">
 						<view class="img-box">
 							<image src="https://bjyjb-1362704775.cos.ap-chongqing.myqcloud.com/app/newImages/shopping/finish96.png" mode=""></image>
 						</view>
@@ -107,7 +107,7 @@
 				<view class="content">
 					<!-- 药品列表 -->
 					<view class="goods-list">
-						<view v-if="order.isPackage!=1" v-for="(item,index) in items" :key="index" class="item" @click="openDetails(item)">
+						<view v-if="order.isPackage!=1" v-for="(item,index) in items" :key="index" class="item">
 							<view class="img-box">
 								<image :src="JSON.parse(item.jsonInfo).image" mode="aspectFill"></image>
 							</view>
@@ -243,18 +243,21 @@
 		<view   class="btn-box">
 			<!-- <view class="btn cancel">联系客服</view> -->
 			<view class="btn cancel" v-if="order.status==0" @click="cancel()">取消订单</view>
-			<view class="btn pay" v-if="order.status==0" @click="pay()">立即付款</view>
-			<view class="btn cancel"  v-if="(order.status==0||order.status==1)&&order.isPrescribe==1&&prescribe==null"  @click="addPrescribe()">开处方</view>
+			<view class="btn pay" v-if="(order.status == 0&&order.isPrescribe!=1)||(order.status == 0&&order.isPrescribe==1&&order.prescribeId)" @click="pay()">立即付款</view>
+			<view class="btn cancel"  v-if="order.isPrescribe==1&&prescribe!=null"  @click="goPrescribe()">查看处方</view>
+			<view class="btn pay"  v-if="(order.status==0||order.status==1)&&order.isPrescribe==1&&prescribe==null"  @click="addPrescribe()">开处方</view>
 			<view class="btn cancel"  v-if="isAfterSales==1"  @click="refund()">申请售后</view>
 			<view class="btn pay" v-if="order.status>=2&&order.deliveryId!=null" @click="express()">查看物流</view>
 			<view class="btn pay" v-if="order.status==2&&order.payType!=1&&order.isPayRemain==0&&order.deliverySn=='SF'" @click="payRemain()">支付尾款</view>
 			<view class="btn pay" v-if="order.status==2" @click="finish()">确认收货</view>
+			<view v-if="order.status == 3" class="btn pay" @click="showEvaluate('/pages_shopping/evaluateDetail?orderId='+order.id)">去评价</view>
+			<view v-if="order.status == 4" class="btn pay" @click="showEvaluate('/pages_shopping/evaluate?orderId='+order.id)">查看评价</view>
 		</view>
 	</view>
 </template>
 
 <script>
-	import {getMyStoreOrderById,cancelOrder,express,finishOrder} from '../api/storeOrder'
+	import {getMyStoreOrderById,cancelOrder,express,finishOrder,orderPrescription} from '@/api/myStoreOrder.js'
 	export default {
 		data() {
 			return {
@@ -276,15 +279,39 @@
 			this.getMyStoreOrderById()
 		},
 		methods: {
+			showEvaluate(url){
+				uni.navigateTo({
+					url: url
+				})
+			},
 			openDetails(item){
-				console.log(item)
 				uni.navigateTo({
-					url: '/pages/shopping/productDetails?productId='+item.productId
+					url: '/pages_shopping/productDetails?productId='+item.productId
 				})
 			},
 			addPrescribe(){
+				orderPrescription(this.order.id).then(res=>{
+					if(res.code == 200) {
+						// {status:状态 0未开放,跳转填写信息界面。 1开方中,跳转医生开方界面 2开方完成,跳转到支付,jumpLink:status为1时用这个跳转连接}
+						if(res.data.status == 0) {
+							uni.navigateTo({
+							 	url:"/pages_shopping/prescribe?orderId="+this.order.id
+							})
+						} else if(res.data.status == 1) {
+							uni.navigateTo({
+							 	url: '/pages/index/webview?url='+encodeURIComponent(res.data.jumpLink)
+							})
+						} else if(res.data.status == 2) {
+							uni.navigateTo({
+								url: '/pages_shopping/paymentOrder?orderId='+this.order.id
+							})
+						}
+					}
+				})
+			},
+			goPrescribe(){
 				uni.navigateTo({
-				 	url:"/pages/shopping/prescribe?orderId="+this.order.id
+				 	url:"/pages_order/prescribeDetails?source=order&prescribeId="+this.prescribe.prescribeId
 				})
 			},
 			showImg(){

+ 8 - 0
uni_modules/mescroll-uni/changelog.md

@@ -0,0 +1,8 @@
+## 1.3.8(2023-03-27)
+1. 新增useMescroll的hook, 支持vue3 script setup的写法  
+2. 新增vue3 script setup的示例 ( 根据vue2的示例,全部重写了一遍 )  
+3. mescroll-body 和 mescroll-uni 无需再写 ref="mescrollRef"  
+4. 解决mescroll-uni在页面渲染之后,无法动态设置height的问题  
+5. 解决renderjs在h5返回有时候无法正常滑动的问题  
+6. 修复小程序编辑器提示 Cannot read property 'nv_optDown' of undefined 的错误  
+-by 小瑾同学

+ 1 - 1
uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue

@@ -106,7 +106,7 @@
 	 * @event {Function} emptyclick 点击empty配置的btnText按钮回调
 	 * @event {Function} topclick 点击回到顶部的按钮回调
 	 * @event {Function} scroll 滚动监听 (需在 up 配置 onScroll:true 才生效)
-	 * @example <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-body>
+	 * @example <mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-body>
 	 */
 	export default {
 		name: 'mescroll-body',

+ 5 - 5
uni_modules/mescroll-uni/components/mescroll-empty/mescroll-empty.vue

@@ -77,7 +77,7 @@ export default {
 .mescroll-empty {
 	box-sizing: border-box;
 	width: 100%;
-	padding: 300rpx 50rpx;
+	padding: 100rpx 50rpx;
 	text-align: center;
 }
 
@@ -89,14 +89,14 @@ export default {
 }
 
 .mescroll-empty .empty-icon {
-	width: 200rpx;
-	height: 150rpx;
+	width: 280rpx;
+	height: 280rpx;
 }
 
 .mescroll-empty .empty-tip {
 	margin-top: 20rpx;
-	font-size: 28rpx;
-	color:  #bbbbbb;
+	font-size: 24rpx;
+	color: gray;
 }
 
 .mescroll-empty .empty-btn {

+ 29 - 13
uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-top.vue

@@ -1,11 +1,11 @@
 <!-- 回到顶部的按钮 -->
 <template>
 	<image
-		v-if="mOption.src"
+		v-if="option.src"
 		class="mescroll-totop"
-		:class="[value ? 'mescroll-totop-in' : 'mescroll-totop-out', {'mescroll-totop-safearea': mOption.safearea}]"
-		:style="{'z-index':mOption.zIndex, 'left': left, 'right': right, 'bottom':addUnit(mOption.bottom), 'width':addUnit(mOption.width), 'border-radius':addUnit(mOption.radius)}"
-		:src="mOption.src"
+		:class="[isShow ? 'mescroll-totop-in' : 'mescroll-totop-out', {'mescroll-totop-safearea': option.safearea}]"
+		:style="{'z-index':option.zIndex, 'left': left, 'right': right, 'bottom':addUnit(option.bottom), 'width':addUnit(option.width), 'border-radius':addUnit(option.radius)}"
+		:src="option.src"
 		mode="widthFix"
 		@click="toTopClick"
 	/>
@@ -15,22 +15,33 @@
 export default {
 	props: {
 		// up.toTop的配置项
-		option: Object,
+		option: {
+			type: Object,
+			default(){
+				return {}
+			}
+		},
 		// 是否显示
-		value: false
+		value: false, // vue2
+		modelValue: false // vue3
 	},
 	computed: {
-		// 支付宝小程序需写成计算属性,prop定义default仍报错
-		mOption(){
-			return this.option || {}
-		},
 		// 优先显示左边
 		left(){
-			return this.mOption.left ? this.addUnit(this.mOption.left) : 'auto';
+			return this.option.left ? this.addUnit(this.option.left) : 'auto';
 		},
 		// 右边距离 (优先显示左边)
 		right() {
-			return this.mOption.left ? 'auto' : this.addUnit(this.mOption.right);
+			return this.option.left ? 'auto' : this.addUnit(this.option.right);
+		},
+		// 是否显示
+		isShow(){
+			// #ifdef VUE3
+			return this.modelValue
+			// #endif
+			// #ifdef VUE2
+			return this.value
+			// #endif
 		}
 	},
 	methods: {
@@ -40,7 +51,12 @@ export default {
 			return num
 		},
 		toTopClick() {
-			this.$emit('input', false); // 使v-model生效
+			// #ifdef VUE3
+			this.$emit("update:modelValue", false); // 使v-model生效 vue3
+			// #endif
+			// #ifdef VUE2
+			this.$emit('input', false); // 使v-model生效 vue2
+			// #endif
 			this.$emit('click'); // 派发点击事件
 		}
 	}

+ 0 - 11
uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js

@@ -21,14 +21,6 @@ const MescrollMixin = {
 		// mescroll组件初始化的回调,可获取到mescroll对象
 		mescrollInit(mescroll) {
 			this.mescroll = mescroll;
-			this.mescrollInitByRef(); // 兼容字节跳动小程序
-		},
-		// 以ref的方式初始化mescroll对象 (兼容字节跳动小程序)
-		mescrollInitByRef() {
-			if(!this.mescroll || !this.mescroll.resetUpScroll){
-				let mescrollRef = this.$refs.mescrollRef;
-				if(mescrollRef) this.mescroll = mescrollRef.mescroll
-			}
 		},
 		// 下拉刷新的回调 (mixin默认resetUpScroll)
 		downCallback() {
@@ -47,9 +39,6 @@ const MescrollMixin = {
 				this.mescroll.endErr();
 			}, 500)
 		}
-	},
-	mounted() {
-		this.mescrollInitByRef(); // 兼容字节跳动小程序, 避免未设置@init或@init此时未能取到ref的情况
 	}
 	
 }

+ 9 - 6
uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.vue

@@ -106,7 +106,7 @@
 	 * @event {Function} emptyclick 点击empty配置的btnText按钮回调
 	 * @event {Function} topclick 点击回到顶部的按钮回调
 	 * @event {Function} scroll 滚动监听 (需在 up 配置 onScroll:true 才生效)
-	 * @example <mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-uni>
+	 * @example <mescroll-uni @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-uni>
 	 */
 	export default {
 		name: 'mescroll-uni',
@@ -151,6 +151,12 @@
 				statusBarHeight: 0 // 状态栏高度
 			}
 		},
+		watch: {
+			height() {
+				// 设置容器的高度
+				this.setClientHeight()
+			}
+		},
 		computed: {
 			// 是否使用fixed定位 (当height有值,则不使用)
 			isFixed(){
@@ -259,7 +265,7 @@
 			},
 			// 更新滚动区域的高度 (使内容不满屏和到底,都可继续翻页)
 			setClientHeight() {
-				if (this.mescroll.getClientHeight(true) === 0 && !this.isExec) {
+				if (!this.isExec) {
 					this.isExec = true; // 避免多次获取
 					this.$nextTick(() => { // 确保dom已渲染
 						this.getClientInfo(data=>{
@@ -278,10 +284,7 @@
 			},
 			// 获取滚动区域的信息
 			getClientInfo(success){
-				let query = uni.createSelectorQuery();
-				// #ifndef MP-ALIPAY || MP-DINGTALK
-				query = query.in(this) // 支付宝小程序不支持in(this),而字节跳动小程序必须写in(this), 否则都取不到值
-				// #endif
+				let query = uni.createSelectorQuery().in(this);
 				let view = query.select('#' + this.viewId);
 				view.boundingClientRect(data => {
 					success(data)

+ 0 - 9
uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js

@@ -32,18 +32,9 @@ const MescrollMoreItemMixin = {
 		}
 	},
 	methods: {
-		// 以ref的方式初始化mescroll对象 (兼容字节跳动小程序)
-		mescrollInitByRef() {
-			if(!this.mescroll || !this.mescroll.resetUpScroll){
-				// 字节跳动小程序编辑器不支持一个页面存在相同的ref, 多mescroll的ref需动态生成, 格式为'mescrollRef下标'
-				let mescrollRef = this.$refs.mescrollRef || this.$refs['mescrollRef'+this.i];
-				if(mescrollRef) this.mescroll = mescrollRef.mescroll
-			}
-		},
 		// mescroll组件初始化的回调,可获取到mescroll对象 (覆盖mescroll-mixins.js的mescrollInit, 为了标记isInit)
 		mescrollInit(mescroll) {
 			this.mescroll = mescroll;
-			this.mescrollInitByRef && this.mescrollInitByRef(); // 兼容字节跳动小程序
 			// 自动加载当前tab的数据
 			if(this.i === this.index){
 				this.mescrollTrigger()

+ 5 - 2
uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js

@@ -62,9 +62,12 @@ const MescrollMoreMixin = {
 		tabChange(i){
 			let mescroll = this.getMescroll(i);
 			if(mescroll){
-				// 延时(比$nextTick靠谱一些),确保元素已渲染
+				// 恢复上次滚动条的位置
+				let y = mescroll.getScrollTop()
+				mescroll.scrollTo(y, 0)
+				// 再次恢复上次滚动条的位置, 确保元素已渲染
 				setTimeout(()=>{
-					mescroll.scrollTo(mescroll.getScrollTop(),0)
+					mescroll.scrollTo(y, 0)
 				},30)
 			}
 		}

+ 1 - 1
uni_modules/mescroll-uni/components/mescroll-uni/wxs/renderjs.js

@@ -47,7 +47,7 @@ if(window && !window.$mescrollRenderInit){
 
 /* 获取滚动条的位置 */
 me.getScrollTop = function() {
-	return me.scrollTop || 0
+	return me.scrollTop || document.documentElement.scrollTop || document.body.scrollTop || 0
 }
 
 /* 是否禁用下拉刷新 */

+ 1 - 0
uni_modules/mescroll-uni/components/mescroll-uni/wxs/wxs.wxs

@@ -63,6 +63,7 @@ me.clearTransform = function (ins){
  * 监听逻辑层数据的变化 (实时更新数据)
  */
 function propObserver(wxsProp) {
+	if(!wxsProp) return
 	me.optDown = wxsProp.optDown
 	me.scrollTop = wxsProp.scrollTop
 	me.bodyHeight = wxsProp.bodyHeight

+ 66 - 0
uni_modules/mescroll-uni/hooks/useMescroll.js

@@ -0,0 +1,66 @@
+// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173
+// import { onPageScroll, onReachBottom, onPullDownRefresh} from '@dcloudio/uni-app';
+
+/** 
+ * 初始化mescroll, 相当于vue2的mescroll-mixins.js文件 (mescroll-body 和 mescroll-uni 通用) 
+ * mescroll-body需传入onPageScroll, onReachBottom
+ * mescroll-uni无需传onPageScroll, onReachBottom
+ * 当down.native为true时,需传入onPullDownRefresh
+ */ 
+function useMescroll(onPageScroll, onReachBottom, onPullDownRefresh){
+	// mescroll实例对象
+	let mescroll = null;
+	
+	// mescroll组件初始化的回调,可获取到mescroll对象
+	const mescrollInit = (e)=> {
+		mescroll = e;
+	}
+	
+	// 获取mescroll对象, mescrollInit执行之后会有值, 生命周期created中会有值
+	const getMescroll = ()=>{
+		return mescroll
+	}
+	
+	// 下拉刷新的回调 (mixin默认resetUpScroll)
+	const downCallback = ()=> {
+		if(mescroll.optUp.use){
+			mescroll.resetUpScroll()
+		}else{
+			setTimeout(()=>{
+				mescroll.endSuccess();
+			}, 500)
+		}
+	}
+	
+	// 上拉加载的回调
+	const upCallback = ()=> {
+		// mixin默认延时500自动结束加载
+		setTimeout(()=>{
+			mescroll.endErr();
+		}, 500)
+	}
+	
+	// 注册系统自带的下拉刷新 (配置down.native为true时生效, 还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
+	onPullDownRefresh && onPullDownRefresh(() => {
+	  mescroll && mescroll.onPullDownRefresh();
+	})
+	
+	// 注册列表滚动事件,用于判定在顶部可下拉刷新,在指定位置可显示隐藏回到顶部按钮 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
+	onPageScroll && onPageScroll(e=>{
+		mescroll && mescroll.onPageScroll(e);
+	})
+	
+	// 注册滚动到底部的事件,用于上拉加载 (此方法为页面生命周期,无法在子组件中触发, 仅在mescroll-body生效)
+	onReachBottom && onReachBottom(()=>{
+		mescroll && mescroll.onReachBottom();
+	}) 
+	
+	return {
+		getMescroll,
+		mescrollInit,
+		downCallback,
+		upCallback
+	}
+}
+
+export default useMescroll

+ 56 - 0
uni_modules/mescroll-uni/hooks/useMescrollComp.js

@@ -0,0 +1,56 @@
+import { ref } from 'vue';
+
+// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173
+// import { onPageScroll, onReachBottom, onPullDownRefresh} from '@dcloudio/uni-app';
+
+/** 
+ * mescroll-body写在子组件时,需通过useMescrollComp补充子组件缺少的生命周期, 相当于vue2的mescroll-comp.js文件
+ * 必须传入onPageScroll, onReachBottom
+ * 当down.native为true时,需传入onPullDownRefresh
+ */ 
+function useMescrollComp(onPageScroll, onReachBottom, onPullDownRefresh){
+	// 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件
+	onPageScroll(e=>{
+		handlePageScroll(e)
+	})
+	
+	onReachBottom(()=>{
+		handleReachBottom()
+	})
+	
+	// 当down的native: true时, 还需传递此方法进到子组件
+	onPullDownRefresh && onPullDownRefresh(()=>{
+		handlePullDownRefresh()
+	})
+	
+	const mescrollItem = ref(null)
+	
+	const handlePageScroll = (e)=>{
+		const mescroll = getMescroll()
+		mescroll && mescroll.onPageScroll(e);
+	}
+	
+	const handleReachBottom = ()=>{
+		const mescroll = getMescroll()
+		mescroll && mescroll.onReachBottom();
+	}
+	
+	const handlePullDownRefresh = ()=>{
+		const mescroll = getMescroll()
+		mescroll && mescroll.onPullDownRefresh();
+	}
+	
+	const getMescroll = ()=>{
+		if(mescrollItem.value && mescrollItem.value.getMescroll){
+			return mescrollItem.value.getMescroll()
+		}
+		return null
+	}
+	
+	return {
+		mescrollItem,
+		getMescroll
+	}
+}
+
+export default useMescrollComp

+ 69 - 0
uni_modules/mescroll-uni/hooks/useMescrollMore.js

@@ -0,0 +1,69 @@
+import { ref  } from 'vue';
+
+// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173
+// import { onPageScroll, onReachBottom, onPullDownRefresh} from '@dcloudio/uni-app';
+
+/** mescroll-more示例写在子组件时,需通过useMescrollMore补充子组件缺少的生命周期, 相当于vue2的mescroll-more.js文件 */ 
+function useMescrollMore(mescrollItems, onPageScroll, onReachBottom, onPullDownRefresh){
+	// 当前tab下标
+	const tabIndex = ref(0) 
+	
+	// 因为子组件无onPageScroll和onReachBottom的页面生命周期,需在页面传递进到子组件
+	onPageScroll && onPageScroll(e=>{
+		handlePageScroll(e)
+	})
+	
+	onReachBottom && onReachBottom(()=>{
+		handleReachBottom()
+	})
+	
+	// 当down的native: true时, 还需传递此方法进到子组件
+	onPullDownRefresh && onPullDownRefresh(()=>{
+		handlePullDownRefresh()
+	})
+	
+	const handlePageScroll = (e)=>{
+		let mescroll = getMescroll(tabIndex.value);
+		mescroll && mescroll.onPageScroll(e);
+	}
+	const handleReachBottom = ()=>{
+		let mescroll = getMescroll(tabIndex.value);
+		mescroll && mescroll.onReachBottom();
+	}
+		
+	const handlePullDownRefresh = ()=>{
+		let mescroll = getMescroll(tabIndex.value);
+		mescroll && mescroll.onPullDownRefresh();
+	}
+	
+	// 根据下标获取对应子组件的mescroll
+	const getMescroll = (i)=>{
+		if (mescrollItems && mescrollItems[i]) {
+			return mescrollItems[i].value.getMescroll()
+		} else{
+			return null
+		}
+	}
+	
+	// 切换tab,恢复滚动条位置
+	const scrollToLastY = ()=>{
+		let mescroll = getMescroll(tabIndex.value);
+		if(mescroll){
+			// 恢复上次滚动条的位置
+			let y = mescroll.getScrollTop()
+			mescroll.scrollTo(y, 0)
+			// 再次恢复上次滚动条的位置, 确保元素已渲染
+			setTimeout(()=>{
+				mescroll.scrollTo(y, 0)
+			},20)
+		}
+	}
+	
+	return {
+		tabIndex,
+		getMescroll,
+		scrollToLastY
+	}
+}
+
+export default useMescrollMore

+ 10 - 14
uni_modules/mescroll-uni/package.json

@@ -1,24 +1,19 @@
 {
   "id": "mescroll-uni",
-  "displayName": "【wxs+renderjs实现】高性能下拉刷新上拉加载组件",
-  "version": "1.3.7",
-  "description": "mescroll - 支持uni-app的下拉刷新和上拉加载的组件,支持原生页面和局部区域滚动",
+  "displayName": "高性能下拉刷新上拉加载组件 支持vue3 setup",
+  "version": "1.3.8",
+  "description": "【mescroll】wxs+renderjs实现, 支持原生页面和局部区域滚动, 支持vue3 script setup的写法",
   "keywords": [
     "下拉刷新",
     "上拉加载",
-    "翻页",
-    "分页",
-    "wxs"
+    "翻页分页",
+    "wxs",
+    "setup"
 ],
   "repository": "https://github.com/mescroll/mescroll",
-  "engines": {
-    "HBuilderX": "^3.1.0"
+"engines": {
   },
-  "dcloudext": {
-    "category": [
-        "前端组件",
-        "通用组件"
-    ],
+"dcloudext": {
     "sale": {
       "regular": {
         "price": "0.00"
@@ -35,7 +30,8 @@
       "data": "无",
       "permissions": "无"
     },
-    "npmurl": "https://www.npmjs.com/package/mescroll-uni"
+    "npmurl": "https://www.npmjs.com/package/mescroll-uni",
+    "type": "component-vue"
   },
   "uni_modules": {
     "dependencies": [],

+ 45 - 0
uni_modules/mescroll-uni/readme.md

@@ -0,0 +1,45 @@
+## mescroll --【wxs+renderjs实现】高性能的下拉刷新上拉加载组件
+1. mescroll的uni版本 是专门用在uni-app的下拉刷新和上拉加载的组件  
+
+2. mescroll的uni版本 继承了mescroll.js的实用功能: 自动处理分页, 自动控制无数据, 空布局提示, 回到顶部按钮 ..
+
+3. mescroll的uni版本 丰富的案例, 自由灵活的api, 超详细的注释, 可让您快速自定义真正属于自己的下拉上拉组件
+
+<br/>
+
+
+## 最新文档(1.3.8版本): <a href="https://www.mescroll.com/uni.html">https://www.mescroll.com/uni.html</a>
+2023-03-26 by 小瑾同学 (文档可能会有缓存,建议打开时刷新一下)
+
+
+## 1.3.5版本已调整为[uni_modules](https://uniapp.dcloud.io/uni_modules)
+uni_modules版本的mescroll-body 和 mescroll-empty 支持 [easycom规范](https://uniapp.dcloud.io/collocation/pages?id=easycom)  
+所以 main.js 无需再为mescroll-body注册全局组件  
+所以个别页面要单独使用 mescroll-empty , 也无需手动注册
+#### 1.3.5以前的用户升级为uni_modules版本:
+```
+1. 删除原来的 @/components/mescroll-uni 组件
+2. 删除 main.js 注册的 mescroll 组件
+3. 从插件市场导入最新mescroll组件 (1.3.5+uni_modules版本)
+4. 全局搜索 '@/components/mescroll-uni/' 替换为 '@/uni_modules/mescroll-uni/components/mescroll-uni/'
+5. mescroll-empty遵循easycom规范, 若某些页面单独使用 'mescroll-empty.vue', 可删除手动导入的代码
+```
+
+## 近期已更新优化的内容:
+1. 新增vue3 script setup的示例  
+2. 新增`入门极简`示例, 国际化`mescroll-i18n.vue`示例, 轮播吸顶菜单`mescroll-swiper-sticky.vue`示例  
+3. 新增 "局部区域滚动" 的案例: mescroll-body-part.vue 和 mescroll-uni-part.vue  
+4. 新增 me-video 视频组件, 解决APP端视频下拉悬浮错位的问题, 参考 mescroll-options.vue 示例  
+5. 新增 me-tabs 组件,tabs支持水平滑动; 优化mescroll-more和mescroll-swiper的案例, 顶部tab支持水平滑动  
+6. 吸顶悬浮提供了原生sticky和监听滚动条实现的示例: sticky.vue 和 sticky-scroll.vue (推荐使用sticky样式实现)  
+7. mescroll.scrollTo(y)的y支持css选择器, 包括跨自定义组件的后代选择器, 支持滚动到子组件的view (参考 mescroll-options.vue)  
+8. topbar 顶部是否预留状态栏的高度, 默认false; 还可支持设置状态栏背景: 如 '#ffff00', 'url(xxx) 0 0/100% 100%', 'linear-gradient(xx)'  
+9. down.bgColor 和 up.bgColor 加载区域的背景,不仅支持色值, 而且还是支持背景图和渐变: 如 'url(xxx) 0 0/100% 100%', 'linear-gradient(xx)'  
+10. topbar,bgColor支持一行代码定义background: [https://www.runoob.com/cssref/css3-pr-background.html](https://www.runoob.com/cssref/css3-pr-background.html)
+<br/>
+<br/>
+<a href="https://ext.dcloud.net.cn/plugin?id=343&update_log">查看更多 ... </a>
+
+<br/>
+
+#### mescroll不支持nvue,也暂无支持的计划哈,so sorry~

部分文件因文件數量過多而無法顯示