Ver código fonte

更新研究生公寓,新增钟点房预订

嘀嘀嘀 1 ano atrás
pai
commit
f846167a6d
100 arquivos alterados com 6725 adições e 962 exclusões
  1. 5 5
      App.vue
  2. 15 1
      main.js
  3. 6 3
      manifest.json
  4. 9 1
      pages.json
  5. 69 0
      pages/huoquCode/huoquCode.vue
  6. 10 0
      pages/huoquanshibai/huoquanshibai.vue
  7. 30 9
      pages/index/css/index.css
  8. 216 47
      pages/index/index.vue
  9. 9 9
      pages/liuchengManger/css/liu_manage.css
  10. 42 0
      pages/liuchengManger/detail/teach_detail.css
  11. 174 55
      pages/liuchengManger/detail/teach_detail.vue
  12. 284 68
      pages/liuchengManger/liu_manage.vue
  13. 2 2
      pages/liuchengO/css/liu_other.css
  14. 69 55
      pages/liuchengO/detail/teach_detail.vue
  15. 209 58
      pages/liuchengO/liu_other.vue
  16. 1 1
      pages/liuchengTeacher/css/liu_teach.css
  17. 74 50
      pages/liuchengTeacher/detail/teach_detail.vue
  18. 225 52
      pages/liuchengTeacher/liu_teach.vue
  19. 3 3
      pages/my_orderlist/css/my_orderlist.css
  20. 190 174
      pages/my_orderlist/my_orderlist.vue
  21. 10 9
      pages/myself/css/myself.css
  22. 75 52
      pages/myself/myself.vue
  23. 172 110
      pages/order_mark/order_mark.vue
  24. 1 1
      pages/order_room/css/order_room.css
  25. 184 155
      pages/order_room/order_room.vue
  26. 2 1
      pages/submit_order/css/submit_order.css
  27. 236 13
      pages/submit_order/submit_order.vue
  28. BIN
      static/my/touxiang.png
  29. 9 0
      uni_modules/uv-count-down/changelog.md
  30. 25 0
      uni_modules/uv-count-down/components/uv-count-down/props.js
  31. 62 0
      uni_modules/uv-count-down/components/uv-count-down/utils.js
  32. 169 0
      uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue
  33. 87 0
      uni_modules/uv-count-down/package.json
  34. 11 0
      uni_modules/uv-count-down/readme.md
  35. 76 0
      uni_modules/uv-ui-tools/changelog.md
  36. 6 0
      uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue
  37. 79 0
      uni_modules/uv-ui-tools/index.js
  38. 7 0
      uni_modules/uv-ui-tools/index.scss
  39. 34 0
      uni_modules/uv-ui-tools/libs/config/config.js
  40. 32 0
      uni_modules/uv-ui-tools/libs/css/color.scss
  41. 100 0
      uni_modules/uv-ui-tools/libs/css/common.scss
  42. 23 0
      uni_modules/uv-ui-tools/libs/css/components.scss
  43. 111 0
      uni_modules/uv-ui-tools/libs/css/variable.scss
  44. 40 0
      uni_modules/uv-ui-tools/libs/css/vue.scss
  45. 134 0
      uni_modules/uv-ui-tools/libs/function/colorGradient.js
  46. 29 0
      uni_modules/uv-ui-tools/libs/function/debounce.js
  47. 167 0
      uni_modules/uv-ui-tools/libs/function/digit.js
  48. 734 0
      uni_modules/uv-ui-tools/libs/function/index.js
  49. 75 0
      uni_modules/uv-ui-tools/libs/function/platform.js
  50. 287 0
      uni_modules/uv-ui-tools/libs/function/test.js
  51. 30 0
      uni_modules/uv-ui-tools/libs/function/throttle.js
  52. 132 0
      uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js
  53. 51 0
      uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js
  54. 201 0
      uni_modules/uv-ui-tools/libs/luch-request/core/Request.js
  55. 20 0
      uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js
  56. 33 0
      uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js
  57. 6 0
      uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js
  58. 126 0
      uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js
  59. 16 0
      uni_modules/uv-ui-tools/libs/luch-request/core/settle.js
  60. 64 0
      uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js
  61. 14 0
      uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js
  62. 14 0
      uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js
  63. 197 0
      uni_modules/uv-ui-tools/libs/luch-request/index.d.ts
  64. 2 0
      uni_modules/uv-ui-tools/libs/luch-request/index.js
  65. 135 0
      uni_modules/uv-ui-tools/libs/luch-request/utils.js
  66. 264 0
      uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js
  67. 13 0
      uni_modules/uv-ui-tools/libs/mixin/button.js
  68. 172 0
      uni_modules/uv-ui-tools/libs/mixin/mixin.js
  69. 8 0
      uni_modules/uv-ui-tools/libs/mixin/mpMixin.js
  70. 13 0
      uni_modules/uv-ui-tools/libs/mixin/mpShare.js
  71. 47 0
      uni_modules/uv-ui-tools/libs/mixin/openType.js
  72. 59 0
      uni_modules/uv-ui-tools/libs/mixin/touch.js
  73. 216 0
      uni_modules/uv-ui-tools/libs/util/dayjs.js
  74. 126 0
      uni_modules/uv-ui-tools/libs/util/route.js
  75. 81 0
      uni_modules/uv-ui-tools/package.json
  76. 23 0
      uni_modules/uv-ui-tools/readme.md
  77. 43 0
      uni_modules/uv-ui-tools/theme.scss
  78. BIN
      unpackage/dist/build/h5.zip
  79. BIN
      unpackage/dist/build/h5/static/img/index_bg.d2c7fb24.jpg
  80. BIN
      unpackage/dist/build/h5/static/img/order_bg.2d37a2fb.jpg
  81. BIN
      unpackage/dist/build/h5/static/img/success.34f76374.png
  82. 0 1
      unpackage/dist/build/h5/static/img/touxiang.48c02f8b.svg
  83. 0 1
      unpackage/dist/build/h5/static/index.b0707a6a.css
  84. BIN
      unpackage/dist/build/h5/static/index/welcome.png
  85. 0 14
      unpackage/dist/build/h5/static/js/chunk-vendors.41816274.js
  86. 0 1
      unpackage/dist/build/h5/static/js/index.de311645.js
  87. 0 1
      unpackage/dist/build/h5/static/js/pages-gongyuxiangqing-gongyuxiangqing.7f7331c0.js
  88. 0 1
      unpackage/dist/build/h5/static/js/pages-huoquanshibai-huoquanshibai.0f67de97.js
  89. 0 1
      unpackage/dist/build/h5/static/js/pages-index-index.10e1336a.js
  90. 0 1
      unpackage/dist/build/h5/static/js/pages-index-index~pages-my_orderlist-my_orderlist~pages-order_mark-order_mark~pages-order_room-order_room.b6504273.js
  91. 0 1
      unpackage/dist/build/h5/static/js/pages-index-index~pages-my_orderlist-my_orderlist~pages-order_room-order_room.642f5866.js
  92. 0 1
      unpackage/dist/build/h5/static/js/pages-my_orderlist-my_orderlist.d79d487f.js
  93. 0 1
      unpackage/dist/build/h5/static/js/pages-myself-myself.cc6a31c5.js
  94. 0 1
      unpackage/dist/build/h5/static/js/pages-order_mark-order_mark.27384da7.js
  95. 0 1
      unpackage/dist/build/h5/static/js/pages-order_room-order_room.256e5c81.js
  96. 0 1
      unpackage/dist/build/h5/static/js/pages-ruzhuxuzhi-ruzhuxuzhi.d6fd2301.js
  97. 0 1
      unpackage/dist/build/h5/static/js/pages-zhifuchenggong-zhifuchenggong.ee656fba.js
  98. BIN
      unpackage/dist/build/h5/static/my/touxiang.png
  99. BIN
      unpackage/dist/build/web/assets/uniicons.b6d3756e.ttf
  100. 0 0
      unpackage/dist/build/h5/index.html

+ 5 - 5
App.vue

@@ -2,14 +2,14 @@
 	export default {
 		onLaunch: function() {
 			console.log('App Launch')
-			// if(localStorage.getItem('token')=='null' && localStorage.getItem('errorMsg')=='null') {
-			// 	window.location.href ='https://open.wecard.qq.com/connect/oauth/authorize?app_key=4FD5599032819781&response_type=code&scope=snsapi_userinfo&ocode=1015730314&redirect_uri=https://chtech.ncjti.edu.cn/hotel/ihotel-api/ihotel/hotelUser/weixiaoAuth&state=https://chtech.ncjti.edu.cn/hotel/ihotel-api/ihotel/hotelUser/weixiaoAuth';
-			// } else if (localStorage.getItem('token')=='null' && localStorage.getItem('errorMsg')=='获取用户信息失败') {
+			if(localStorage.getItem('token')=='null' && localStorage.getItem('errorMsg')=='null') {
+				// alert(window.location.href,'p')
+				window.location.href ='https://open.wecard.qq.com/connect/oauth/authorize?app_key=4FD5599032819781&response_type=code&scope=snsapi_userinfo&ocode=1015730314&redirect_uri=https://chtech.ncjti.edu.cn/hotel/ihotel/auto/appletLogin/login&state=https://chtech.ncjti.edu.cn/hotel/ihotel/auto/appletLogin/login';
+			} else if (localStorage.getItem('token')=='null' && localStorage.getItem('errorMsg')=='获取用户信息失败') {
 				uni.navigateTo({
 					url:'pages/huoquanshibai/huoquanshibai'
 				})
-			// }
-			
+			}
 		},
 		onShow: function() {
 			console.log('App Show')

+ 15 - 1
main.js

@@ -5,12 +5,26 @@ import App from './App'
 import axios from "axios"
 import qs from 'qs'
 import getUrlKey from './utils/getToken.js'
+// alert(localStorage.getItem('errorMsg')+'09'+getUrlKey('token'))
 localStorage.setItem('token',getUrlKey('token'))
+localStorage.setItem('user_head',getUrlKey('user_head'))
+// localStorage.setItem('token',"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXNzd29yZCI6IlBCL2tVMDRZSkswVG54c0l5RHRlNlZxa20rUURhdkZ3UWxxcEtnR0pEMEpRWXlSSS9QdWFCd1h4dW5CR0poTjVKOE92ZndVMUFVaHBSMEx1SVA3UmhHbFpMdGZaaTJyNnZmbkFOcWR0QlhPQlAyL3gxays0OTFHTGJET0ZqeXhYUmtrRDZ1MWsyeTNsWnY0djlWdEFPV1k0T1VYUHJnNE1CUE14WlBVK1pTdz0iLCJleHAiOjE3MTUxNjA1NDIsImlhdCI6MTcxNTA3NDE0MiwiYWNjb3VudCI6ImFkbWluIn0.uGnaiXAg3UD9tYWiaPw9_uqhJzrMf5a9Naw50pxdvFc")
+// localStorage.setItem('user_head',"756D1D9856695F71029C45B16D407517")
 localStorage.setItem('errorMsg',getUrlKey('errorMsg'))
 localStorage.setItem('openId',getUrlKey('openId'))
-console.log(localStorage.getItem('token'))
+localStorage.setItem('usersId',getUrlKey('usersId'))
+localStorage.setItem('adminMenuId',getUrlKey('adminMenuId'))
+localStorage.setItem('adminMenuName',getUrlKey('adminMenuName'))
+localStorage.setItem('telephone',getUrlKey('telephone'))
+localStorage.setItem('name',getUrlKey('name'))
+localStorage.setItem('user_head',getUrlKey('user_head'))
+localStorage.setItem('department',getUrlKey('department'))//部门,0是其他,4是教师
+localStorage.setItem('manager',getUrlKey('manager'))//管理员1,0不是
+// alert(localStorage.getItem('token'))
+console.log(localStorage.getItem('token'),getUrlKey('usersId'))
 console.log(localStorage.getItem('errorMsg'))
 console.log(localStorage.getItem('openId'))
+// alert('管理员'+localStorage.getItem('manager')+'身份'+localStorage.getItem('department'))
 
 //引入公共接口
 import http from './utils/request.js'

+ 6 - 3
manifest.json

@@ -70,14 +70,15 @@
             "proxy" : {
                 //使用代理
                 // https://chtech.ncjti.edu.cn/hotel/ihotel-api/ihotel/roomType/list
-                "/hotel/ihotel-api" : {
-                    "target" : "https://chtech.ncjti.edu.cn/hotel/ihotel-api", //目标地址
+                "/ihotel/auto" : {
+                    "target" : "https://chtech.ncjti.edu.cn/hotel/ihotel/auto/", //目标地址
+                    // "target" : "http://192.168.161.190:8090/ihotel/auto", //目标地址
                     "changeOrigin" : true,
                     "secure" : true, // 设置支持https协议的代理
 
                     // 设置地址重定向,把程序中/api开头的路径替换成:http://t.yushu.im"
                     "pathRewrite" : {
-                        "/hotel/ihotel-api" : "" // 设置/api路径重定向
+                        "/ihotel/auto" : "" // 设置/api路径重定向
                     }
                 }
             }
@@ -94,3 +95,5 @@
         }
     }
 }
+// "base" : "/ihotel"
+

+ 9 - 1
pages.json

@@ -2,7 +2,9 @@
 	"pages": [{
 		"path": "pages/index/index",
 		"style": {
-			"navigationBarTitleText": "智慧校园公寓"
+			"navigationBarTitleText": "智慧校园公寓",
+			"navigationStyle": "custom",
+			"enablePullDownRefresh": true
 		}
 	},
 	{
@@ -98,6 +100,12 @@
 		}
 	},
 	{
+		"path": "pages/huoquCode/huoquCode",
+		"style":{
+			"navigationBarTitleText": "获取code"
+		}
+	},
+	{
 		"path": "pages/gongyuxiangqing/gongyuxiangqing",
 		"style":{
 			"navigationBarTitleText": "公寓详情"

+ 69 - 0
pages/huoquCode/huoquCode.vue

@@ -0,0 +1,69 @@
+<template>
+	<view class="content">
+		<view class="text-area">
+			<text class="top-line"></text>
+				<view class="item">
+					<!-- <image src="../../static/success.png" class="success-img"></image> -->
+					<text class="success-text">授权获取code</text>
+				</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		
+		onLoad() {
+			
+		},
+		onShow() {
+			window.location.href ='https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd87cbe1db0437303&redirect_uri=https%3A%2F%2Fchtech.ncjti.edu.cn%2Fhotel%2Fh5%2F%23%2Fpages%2Findex%2Findex&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect';
+		},
+		methods:{
+			
+		}
+	}
+	
+</script>
+
+<style>
+	.content {
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			justify-content: center;
+		}
+		
+		.text-area {
+			display: flex;
+			justify-content: center;
+		}
+		.top-line{
+			margin-top: 0rpx;
+			margin-left: 0;
+			position: absolute;
+			width: 750rpx;
+			height: 1rpx;
+			background: #CCCCCC;
+		}
+		.item{
+			margin-top: 400rpx;
+			text-align: center;
+			width: 750rpx;
+			height: 1206rpx;
+		}
+		.success-img{
+			margin-left: 242rpx;
+			margin-top: 73rpx;
+			width: 261rpx;
+			height: 266rpx;
+		}
+		.success-text{
+			margin-left: 276rpx;
+			margin-top: 433rpx;
+			font-size: 49rpx;
+			font-family: Microsoft YaHei-3970(82674968);
+			font-weight: 400;
+			color: #333333;
+		}
+</style>

+ 10 - 0
pages/huoquanshibai/huoquanshibai.vue

@@ -13,7 +13,17 @@
 <script>
 	export default {
 		
+		onLoad() {
+			
+		},
+		onShow() {
+			// window.location.href ='https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd87cbe1db0437303&redirect_uri=https%3A%2F%2Fchtech.ncjti.edu.cn%2Fhotel%2Fh5%2F%23%2Fpages%2Findex%2Findex&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect';
+		},
+		methods:{
+			
+		}
 	}
+	
 </script>
 
 <style>

+ 30 - 9
pages/index/css/index.css

@@ -10,7 +10,7 @@
 	width: 750rpx;
 	height: 320rpx;
 	margin: 0 auto;
-	background-image: url(../../static/index/index_bg.jpg);
+	/* background-image: url(../../static/index/index_bg.jpg); */
 	background-size: 100% 100%;
 	background-attachment: inherit;
 	background-repeat: no-repeat;
@@ -18,8 +18,10 @@
 }
 /* 欢迎光临 */
 .welcome{
-	width: 112rpx;
-	height: 41rpx;
+	/* width: 112rpx;
+	height: 41rpx; */
+	width: 750rpx;
+	height: 320rpx;
 	background: rgba(255, 255, 255, 0.4);
 	backdrop-filter: blur(5px);
 }
@@ -27,11 +29,14 @@
 	position: absolute;
 	margin-left: 14rpx;
 	margin-top: 5rpx;
-	width: 86rpx;
-	height: 31rpx;
+	/* width: 86rpx;
+	height: 31rpx; */
+	width: 750rpx;
+	height: 320rpx;
 }
 /* <!-- 第一层公寓名称卡片 --> */
 .uni-ka{
+	z-index: 1;
 	width: 710rpx;
 	height: 254rpx;
 	background: rgba(255, 255, 255, 1);
@@ -302,10 +307,26 @@
 	font-size: 24rpx;
 	font-weight: 400;
 }
+.room-time2{
+	position: absolute;
+	margin-left: 260rpx;
+	margin-top: 45px;
+	color: rgba(153, 153, 153, 1);
+	font-size: 24rpx;
+	font-weight: 400;
+}
+.room-time3{
+	position: absolute;
+	margin-left: 142px;
+	margin-top: 80px;
+	color: rgba(153, 153, 153, 1);
+	font-size: 24rpx;
+	font-weight: 400;
+}
 .room-icon{
 	position: absolute;
 	margin-left: 261rpx;
-	margin-top: 116rpx;
+	margin-top: 66px;
 }
 .before-price{
 	position: absolute;
@@ -318,7 +339,7 @@
 	position: absolute;
 	/* margin-left: 605rpx; */
 	margin-top: 46rpx;
-	margin-left: 285px;
+	margin-left: 265px;
 	width: 84px;
 	text-align: center;
 	color: rgba(255, 87, 51, 1);
@@ -328,7 +349,7 @@
 .room-button{
 	position: absolute;
 	margin-left: 579rpx;
-	margin-top: 96rpx;
+	margin-top: 64px;
 	width: 100rpx;
 	height: 66rpx;
 	background: rgba(41, 109, 227, 1);
@@ -342,7 +363,7 @@
 .room-button2{
 	position: absolute;
 	margin-left: 569rpx;
-	margin-top: 96rpx;
+	margin-top: 64px;
 	width: 120rpx;
 	height: 66rpx;
 	background: rgba(128, 127, 131, 0.5);

+ 216 - 47
pages/index/index.vue

@@ -2,11 +2,19 @@
 	<view class="content">
 		<!-- 背景图 -->
 		<view class="index_bg">
-			<view class="welcome"><image class="welcome_img" src="../../static/index/welcome.png"></image></view>
+			<swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" :duration="duration">
+			  <swiper-item v-for="(item,index) in apartList.coverPicture" :key="index">
+				<image class="welcome_img" :src="item.url"></image>
+				<!-- <view class="swiper-item">1</view> -->
+			  </swiper-item>
+			</swiper>
+			<!-- <view class="welcome" v-for="(item,index) in apartList.coverPicture" :key="index">
+				<image class="welcome_img" :src="item.url"></image>
+			</view> -->
 		</view>
 		<!-- 第一层公寓名称卡片 -->
 		<view class="uni-ka" style="margin-top: -40px;margin-bottom:0px;">
-			<text class="uni-title">墨轩湖姬子公寓(南昌交通学院)</text>
+			<text class="uni-title">{{apartList.name}}(南昌交通学院)</text>
 			<text class="uni-sub-title">2021年装修 | 智能门锁 | 房间wifi | 免费停车</text>
 			<text class="uni-extra" @click="navigateToXiangqing">设施/详情></text>
 			<text class="uni-body">江西省宜春市靖安县墨轩湖大道1号</text>
@@ -46,11 +54,11 @@
 				@close="dialogClose"></uni-popup-dialog>
 		</uni-popup>
 		<!-- 切换全日房和钟点房 -->
-		<view class="select-type" v-if="roomtype" @click="changeType">
+		<view class="select-type" v-if="roomtype==1" @click="changeType">
 			<view class="allday">全日房</view>
-			<view class="hourday_no">钟点房</view>
+			<view class="hourday_no">钟点房</view> 
 		</view>
-		<view class="select-type" v-else @click="changeType">
+		<view class="select-type" v-else-if="roomtype==2" @click="changeType">
 			<view class="allday2">全日房</view>
 			<view class="hourday_no2">钟点房</view>
 		</view>
@@ -58,7 +66,7 @@
 		<view class="room-list">
 			<!-- 选择住房日期 -->
 			<!-- 全日房 -->
-			<view class="select-time" @click="openCalendar" v-if="roomtype">
+			<view class="select-time" @click="openCalendar" v-if="roomtype==1">
 				<view class="select-time-one">
 				  <text class="select-list">{{startWeek}}入住</text>
 				  <text class="select-list-time">{{startTime}}</text>
@@ -76,7 +84,7 @@
 			<!-- 钟点房 -->
 			<view class="select-time" v-else>
 				<view class="hourtime">
-					<uni-datetime-picker type="date" v-model="hourruzhu" @maskClick="maskClick">
+					<uni-datetime-picker type="date" v-model="hourruzhu" @change="changezhong" :start="mindate">
 						入住时段
 						<text class="select-list-time" style="margin-left: 26rpx;">{{hourruzhu}}</text>
 						<image class="hour_right" src="../../static/index/hour_right.png"></image>
@@ -94,23 +102,26 @@
 				:endDate="info.endDate" :range="info.range" @change="change"/>
 				</view>
 			</uni-popup>
-			<!-- 房型列表 -->
+			<!-- 房型列表-->
 			<view class="room-kuang">
 				<view class="room-xinxi" v-for="(item,index) in roomType" :key="index">
-					<image class="room-image" :src="item.masterImage" @click="inputDialogToggle(item.id)"></image>
-					<view class="room-name">{{item.typeName}}</view>
-					<view class="room-mark">{{item.typeShortDesc}}</view>
+					<image class="room-image" :src="item.roomPicture" @click="inputDialogToggle(item.id)"></image>
+					<view class="room-name">{{item.roomName}}</view>
+					<view class="room-mark" v-if="item.roomConfiguration.length>11">{{item.roomConfiguration.substring(0,11)}}...</view>
+					<view class="room-mark" v-else>{{item.roomConfiguration}}</view>
+					<view class="room-time2" v-if="item.roomType==2">{{apartList.hourTime}}</view>
+					<view class="room-time3" v-if="item.roomType==2">{{item.roomLiveTime}}小时</view>
 					<view class="room-icon">
 						<image src="../../static/index/index_wifi.svg" style="width: 30rpx;height: 30rpx;"></image>
 						<image src="../../static/index/index_kongtiao.svg" style="width: 26rpx;height: 26rpx;margin-left: 10rpx;"></image>
 						<image src="../../static/index/index_nosmoking.svg" style="width: 30rpx;height: 30rpx;margin-left: 10rpx;"></image>
 						<image src="../../static/index/index_lock.svg" style="width: 30rpx;height: 30rpx;margin-left: 10rpx;"></image>
 					</view>
-					<view class="before-price"><strike>¥{{item.usualPrice}}</strike></view>
-					<view class="room-price">¥{{item.depositPrice}}</view>
-					<view class="room-button" :class="{'room-button2': item.enableNum == 0}">
-						<text v-if="item.enableNum==0">已满</text>
-						<text v-else @click="navigateToOrderRoom(item.enableNum,item.id,item.typeName)">订</text>
+					<!-- <view class="before-price"><strike>¥{{item.usualPrice}}</strike></view> -->
+					<view class="room-price">¥{{item.roomPrice}}</view>
+					<view class="room-button" :class="{'room-button2': item.houseStatus == 2}">
+						<text v-if="item.houseStatus==2">已满</text>
+						<text v-else-if="item.houseStatus==1" @click="navigateToOrderRoom(item.houseStatus,item.id,item.roomName,item)">订</text>
 					</view>
 					<view class="room-line"  v-if="index<(roomType.length-1)"></view>
 				</view>
@@ -202,7 +213,7 @@
 
 		dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
 
-		var a = new Array("日", "一", "二", "三", "四", "五", "六");  
+		var a = new Array("日", "一", "二", "三", "四", "五", "六","日");  
 		var week = new Date().getDay();    
 		var week2 = new Date().getDay()+1;    
 		const y = dd.getFullYear()
@@ -226,13 +237,18 @@
 	import {
 		getroomtype,
 		getroomtypeinfo,
-		getorderpage
+		getorderpage,
+		apartSet
 	} from '../../utils/api_hotel.js'
 	// 导入图片
 	import AMap from "../../lib/qqmap-wx-jssdk.js"
 	export default {
 		data() {
 			return {
+				indicatorDots: true,
+				autoplay: true,
+				interval: 2000,
+				duration: 500,
 				showCalendar: false,
 				info: {
 					lunar: true,
@@ -264,11 +280,57 @@
 					date:'',
 					endDate:''
 				},
-				roomType:[],
+				roomType:[
+					{
+					                "id": 1,
+					                "roomName": "标准房",
+					                "roomType": 1,
+					                "roomPrice": 250,
+					                "number": 3,
+					                "roomArea": "25",
+					                "roomLiveTime": "1",
+					                "receivingTime": "15:08-16:08",
+					                "visible": "1,2",
+					                "roomConfiguration": "1,浴室,投影机",
+					                "roomPicture": "http://192.168.161.224:12345/6/f/5/6f51cacb44f94ef09acd08ad65135371.jpg",
+					                "houseStatus": "1",
+					                "surplusCount": 1
+					            },
+					            {
+					                "id": 4,
+					                "roomName": "豪华别墅",
+					                "roomType": 1,
+					                "roomPrice": 2500,
+					                "number": 6,
+					                "roomArea": "100",
+					                "roomLiveTime": "1",
+					                "receivingTime": "16:31-17:31",
+					                "visible": "1,2,3",
+					                "roomConfiguration": "2",
+					                "roomPicture": "http://192.168.161.224:12345/1/b/3/1b38ab1658724de0875fd575f6533c42.jpg",
+					                "houseStatus": "1",
+					                "surplusCount": 6
+					            },
+					            {
+					                "id": 5,
+					                "roomName": "豪华单间",
+					                "roomType": 1,
+					                "roomPrice": 800,
+					                "number": 2,
+					                "roomArea": "50",
+					                "roomLiveTime": "1",
+					                "receivingTime": "16:52-17:52",
+					                "visible": "1,2",
+					                "roomConfiguration": "2",
+					                "roomPicture": "http://192.168.161.224:12345/f/6/4/f64bd3ee73ef4c03a1d266bba3ac4a0f.jpg",
+					                "houseStatus": "1",
+					                "surplusCount": 2
+					            }
+				],
 				typeText:'',//房型详细描述
 				indicatorDots: true,//滚动图片提示条默认出现
 				img:[],//轮播图里图片
-				phone:'0791-82293574',//电话
+				phone:'',//电话
 				latitude: '', // 默认当前纬度
 				longitude:'',
 				scale: 12, // 默认16
@@ -281,16 +343,19 @@
 				dai_type:[],// 办理入住判断条件
 				dai_panduan:[],// 办理入住判断条件赋值
 				order_txt:'',//订房事故时信息
-				roomtype:true,//区分房型,ture全日房 ;false钟点房
+				roomtype:1,//区分房型,1全日房 ;2钟点房
 				hourruzhu:'',//钟点房入住时间
+				mindate:new Date().toISOString().slice(0, 10),
+				page:1,
+				size:10,
+				totalCount: 0,
+				apartList:{},
+				hourTime:'',//钟点房营业时间
 			}
 		},
 		onLoad() {
-			this.startDate = getDate(new Date()).fullDate2
-			this.endDate =  getDate(new Date(),1).fullDate2
-			this.getRoomType()
-			
-			
+			this.getAllset()
+			this.handleUrlCode()
 			// uni.showToast({
 			// 	title: 'openId'+localStorage.getItem('openId')
 			// })
@@ -316,7 +381,7 @@
 				this.infoXu.endDate =  getDate(new Date(),6).fullDate
 				this.startTime = getDate(new Date()).fullTime
 				this.endTime = getDate(new Date(),1).fullTime
-				this.hourruzhu= getDate(new Date(),1).fullDate
+				this.hourruzhu= getDate(new Date()).fullDate
 				this.startWeek = getDate(new Date()).sWeek
 				this.endWeek = getDate(new Date(),1).eWeek
 			}, 1)
@@ -373,28 +438,131 @@
 		},
 			
 		methods: {
+			// 截取 url中的code方法
+			handleUrlCode() {
+				var url = location.href; //获取打开的公众号的路径
+				// alert(url)
+				var theRequest = new Object();
+				if (url.indexOf('?') != -1) {
+					var str = url.substr(url.indexOf('?') + 1);
+					var strs = str.split('&');
+					for (var i = 0; i < strs.length; i++) {
+						var items = strs[i].split('=');
+						if(strs[i].split('=')[0]=='code'){
+							var code=strs[i].split('=')[1]
+							localStorage.setItem('code',code)
+						}
+						theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1];
+						theRequest[i] = strs[i].split('=')[1];
+					}
+				// alert(code+'p'+localStorage.getItem('code'))
+				
+				}
+			},
+			//公寓整体配置
+			getAllset(){
+				let _self = this
+				_self.roomType = []
+				apartSet().then((res) => {
+					if (res.success) {
+						this.apartList=res.data
+						this.phone=this.apartList.phoneNumbr
+						localStorage.setItem('liveTime',this.apartList.liveTime)
+						localStorage.setItem('leaveTime',this.apartList.leaveTime)
+						this.startDate = getDate(new Date()).fullDate+" "+this.apartList.liveTime
+						this.endDate =  getDate(new Date(),1).fullDate+" "+this.apartList.leaveTime
+						this.hourTime=this.apartList.hourTime
+						this.getRoomType()
+						return;
+					} else {
+						uni.showModal({
+							content:"没有符合条件的数据!"
+						})
+					}
+				}).catch((err) => {
+					  uni.showModal({
+						content:err.message
+					  })
+				});
+			},
+			onReachBottom: function() {
+				console.log('当前长度',this.roomType.length)
+				
+				if (this.roomType.length < this.totalCount) {
+					wx.showLoading({
+					   title: '加载中...',
+					 })
+					this.page = this.page + 1;
+					this.getRoomType()
+				} else {
+				}
+			},
+			onPullDownRefresh: function() {
+				this.page = 1;
+				this.getRoomType();
+			},
 			//切换房型
 			changeType(){
-				this.roomtype=!this.roomtype
+				if(this.roomtype==1){
+					this.roomtype=2
+					this.page = 1;
+					this.startDate = getDate(new Date()).fullDate+" "+getDate(new Date()).fullDate2.substring(11,19)
+					this.endDate =  getDate(new Date()).fullDate+" "+"23:59:00"
+					this.startTime = getDate(new Date()).fullDate.substring(5,7)+'月'+getDate(new Date()).fullDate.substring(8,10)+'日'
+					this.getRoomType();
+				}else if(this.roomtype==2){
+					this.roomtype=1
+					this.page = 1;
+					this.startDate = getDate(new Date()).fullDate+" "+this.apartList.liveTime
+					this.endDate =  getDate(new Date(),1).fullDate+" "+this.apartList.leaveTime
+					this.getRoomType();
+				}
+			},
+			//钟点房选择日期
+			changezhong(e){
+				console.log(e,getDate(new Date()).fullDate,getDate(new Date()).fullDate<e,'l')
+				this.hourruzhu=e
+				if(getDate(new Date()).fullDate<e){
+					this.startDate = e+" "+"00:00:00"
+					this.endDate = e+" "+"23:59:00"
+				}else{
+					this.startDate = e+" "+getDate(new Date()).fullDate2.substring(11,19)
+					this.endDate = e+" "+"23:59:00"
+				}
+				this.startTime = e.substring(5,7)+'月'+e.substring(8,10)+'日'
+				this.getRoomType();
 			},
 			// 房型接口
 			getRoomType() {
 			  let _self = this
 			  _self.roomType = []
-			  var data="?startDate="+this.startDate.substring(0,10)+"&endDate="+this.endDate.substring(0,10)
+			  var data="?page="+_self.page+"&size="+_self.size+"&type="+_self.roomtype+"&startTime="+_self.startDate+"&endTime="+_self.endDate
 			  getroomtype(data).then((res) => {
 			  	if (res.success) {
-					res.data.forEach(data => {
-						if (data.flag !== '-1') {
-						  _self.roomType.push(data)
-						}
-					  })
-			  		return;
+					this.totalCount = res.data.total
+					// res.data.records.forEach(data => {
+					// 	// if (data.houseStatus == '1') {//房间可订
+					// 	  _self.roomType.push(data)
+					// 	// }
+					//   })
+			  		if (this.page == 1) {
+			  			_self.roomType = res.data.records
+			  		} else {
+			  			_self.roomType = [..._self.roomType, ...res.data.records]
+			  		}
+			  		uni.stopPullDownRefresh();
+			  		uni.hideLoading()
 			  	} else {
-			  		this.$message.warning('没有符合条件的数据!')
+					uni.showModal({
+						content:"没有符合条件的数据!"
+					})
+			  		// this.$message.warning('没有符合条件的数据!')
 			  	}
 			  }).catch((err) => {
-			  	this.$message.error(err.message)
+				  uni.showModal({
+				  	content:err.message
+				  })
+			  	// this.$message.error(err.message)
 			  });
 			},
 			// 房型详情接口
@@ -402,11 +570,11 @@
 			  let _self = this
 			  _self.typeText=''
 			  _self.img=[]
-			  var data=id
+			  var data="?houseId="+id
 			  getroomtypeinfo(data).then((res) => {
 			  	if (res.success) {
-					_self.typeText=res.data.typeDesc
-					_self.img=res.data.typeImage.split(',')
+					_self.typeText=res.data.introductory
+					_self.img=res.data.housePicture.split(',')
 			  		return;
 			  	} else {
 			  		this.$message.warning('没有符合条件的数据!')
@@ -475,15 +643,16 @@
 				});
 			},
 			// 订房间 
-			navigateToOrderRoom(enableNum,id,typeName) {
+			navigateToOrderRoom(houseStatus,id,roomName,item) {
 				let _self = this
 				_self.roomType = []
-				if (enableNum>=1){
+				if (houseStatus==1){
 					uni.navigateTo({
-					  url: "../order_room/order_room?roomTypeId="+id +"&enableStartTime="+this.startDate+"&enableEndTime="+this.endDate+"&startTime="+this.startTime+"&endTime="+this.endTime+"&typeName="+typeName,
+					  url: "../order_room/order_room?roomTypeId="+id +"&enableStartTime="+this.startDate+"&enableEndTime="+this.endDate+"&startTime="+this.startTime+"&endTime="+this.endTime+"&typeName="+roomName+"&ruzhu_num="+this.ruzhu_num+"&roomArea="
+					  +item.roomArea+"&roomType="+item.roomType+"&roomConfiguration="+item.roomConfiguration+"&roomPrice="+item.roomPrice+'&surplusCount='+item.surplusCount+'&zhongTime='+this.apartList.hourTime+'&zhongshi='+item.roomLiveTime,
 					});
 				}
-				this.getRoomType()
+				// this.getRoomType()
 				
 				
 			},
@@ -602,10 +771,10 @@
 						this.endWeek='周'+e.lunar.ncWeek.substring(2,3)
 						this.startTime=e.range.before.substring(5,7)+'月'+e.range.before.substring(8,10)+'日'
 						this.endTime=e.range.after.substring(5,7)+'月'+e.range.after.substring(8,10)+'日'
-						this.startDate = e.range.before +' 14:00:00'
-						this.endDate =  e.range.after +' 12:00:00'
+						this.startDate = e.range.before +' '+this.apartList.liveTime
+						this.endDate =  e.range.after +' '+this.apartList.leaveTime
 						this.ruzhu_num=parseInt(((new Date(e.range.after).getTime())-(new Date(e.range.before).getTime()))/1000/60/60/24)
-						if(this.endDate !=' 12:00:00') {
+						if(this.endDate !=this.apartList.leaveTime) {
 							this.getRoomType()
 						}
 					}

+ 9 - 9
pages/liuchengManger/css/liu_manage.css

@@ -62,7 +62,7 @@
 	color: rgba(0, 0, 0, 1);
 }
 .submit-time{
-	margin: 0 0 0 353rpx;
+	margin: 0 0 0 253rpx;
 }
 .submit-line{
 	margin: 0 0 0 21rpx;
@@ -104,25 +104,25 @@
 	text-align: center;
 }
 .submit-disagree{
-	margin: 46rpx 0 0 24rpx;
-	width: 310rpx;
-	height: 74rpx;
+	margin: 16rpx 0 0 374rpx;
+	width: 118rpx;
+	height: 55rpx;
 	border-radius: 12rpx;
 	border: 1rpx solid rgba(0, 97, 255, 1);
 	font-size: 28rpx;
-	line-height: 74rpx;
+	line-height: 55rpx;
 	color: rgba(0, 97, 255, 1);
 	text-align: center;
 	float: left;
 }
 .submit-agree{
-	margin: 46rpx 0 0 382rpx;
-	width: 310rpx;
-	height: 74rpx;
+	margin: 16rpx 0 0 573rpx;
+	width: 118rpx;
+	height: 55rpx;
 	border-radius: 12rpx;
 	background: rgba(0, 97, 255, 1);
 	font-size: 28rpx;
-	line-height: 74rpx;
+	line-height: 55rpx;
 	color: rgba(255, 255, 255, 1);
 	text-align: center;
 }

+ 42 - 0
pages/liuchengManger/detail/teach_detail.css

@@ -202,4 +202,46 @@
 	line-height: 74rpx;
 	color: rgba(255, 255, 255, 1);
 	text-align: center;
+}
+.list_title{
+	position: absolute;
+	margin: 20rpx 0 0 16rpx;
+	font-size: 32rpx;
+	font-weight: 500;
+	color: rgba(0, 0, 0, 1);
+}
+/* 几级审批 */
+.item_image{
+	position: absolute;
+	margin: 0 0 0 22rpx;
+	width: 60rpx;
+	height: 60rpx;
+	background-color:  rgba(255, 170, 0, 1.0);
+	border-radius: 50%;
+}
+.item_title{
+	position: absolute;
+	margin: 0 0 0 105rpx;
+	font-size: 24rpx;
+	font-weight: 400;
+	color: rgba(0, 0, 0, 1);
+}
+.item_name{
+	position: absolute;
+	margin: 31rpx 0 0 105rpx;
+	font-size: 24rpx;
+	font-weight: 400;
+	color: rgba(128, 128, 128, 1);
+}
+.item_time{
+	margin: 13rpx 0 0 539rpx;
+	font-size: 24rpx;
+	font-weight: 400;
+	color: rgba(166, 166, 166, 1);
+}
+.item_line{
+	margin: 13rpx 0 0 52rpx;
+	height: 50rpx;
+	width: 0px;
+	border: 2rpx solid rgba(204, 204, 204, 1);
 }

+ 174 - 55
pages/liuchengManger/detail/teach_detail.vue

@@ -2,42 +2,54 @@
 	<view class="content">
 		<!-- 申请类型 -->
 		<view class="request_type">
-			<view class="type_title">换课申请</view>
-			<view class="type_time">2023.11.04  12:00</view>
-			<view class="type_zhuang">审批通过</view>
-			<!-- <view class="type_zhuang2">审批通过</view>
-			<view class="type_zhuang3">审批通过</view> -->
+			<text class="type_title" v-if="department=='7'">临时人员</text>
+			<text class="type_title" v-if="department=='4'">教师换课</text>
+			<view class="type_time">{{list.submissionTime}}</view>
+			<view class="type_zhuang2" v-if="list.status==0">已拒绝</view>
+			<view class="type_zhuang3" v-if="list.status==1">待审批</view>
+			<view class="type_zhuang3" v-if="list.status==2">处理中</view>
+			<view class="type_zhuang" v-if="list.status==3">审批通过</view>
 		</view>
 		<!-- 申请内容 -->
 		<view class="request_detail">
-			<uni-forms ref="valiForm" :rules="rules" :modelValue="baseFormData">
+			<uni-forms ref="valiForm">
 				<uni-forms-item label="类型" name="companyName" required>
 						<view class="uni-input">
-							111
+							<template v-if="list.department=='0'">其他</template>
+							<template v-if="list.department=='1'">学生</template>
+							<template v-if="list.department=='4'">教职工</template>
+							<template v-if="list.department=='5'">校友</template>
+							<template v-if="list.department=='6'">访客</template>
+							<template v-if="list.department=='7'">临时人员</template>
 						</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="开始时间" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.startTime}}
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="结束时间" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.endTime}}
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="申请部门" name="companyName" required>
 					<view class="uni-input">
-						111
+						<template v-if="list.department=='0'">其他</template>
+						<template v-if="list.department=='1'">学生</template>
+						<template v-if="list.department=='4'">教职工</template>
+						<template v-if="list.department=='5'">校友</template>
+						<template v-if="list.department=='6'">访客</template>
+						<template v-if="list.department=='7'">临时人员</template>
 					</view>
 				</uni-forms-item>
-				<view class="form-line"></view>
-				<uni-forms-item label="换课老师" name="companyName" required>
+				<view class="form-line" v-if="department=='4'"></view>
+				<uni-forms-item label="换课老师" name="companyName" required v-if="department=='4'">
 					<view class="uni-input">
-						111
+						{{list.changeUsersName}}
 					</view>
 				</uni-forms-item>
 			</uni-forms>
@@ -46,61 +58,69 @@
 		<view class="request_remark">
 			<uni-forms-item label="备注" name="companyName" required>
 			</uni-forms-item>
-			<view class="liyou">{{shanchang}}</view>
-			<text class="textsrea-txt">1/200</text>
+			<view class="liyou">{{list.reasonApplication}}</view>
+			<text class="textsrea-txt">{{zishunum}}</text>
+		</view>
+		<!-- 审批记录 -->
+		<view class="request_list" v-if="list.status==0 || list.status==3">
+			<view class="list_title">审批记录</view>
+			<!-- 几级审批 -->
+			<view style="position: absolute;margin-top: 110rpx;background: rgba(255, 255, 255, 1);height: 30%;">
+			<view>
+				<image class="item_image"></image>
+				<view class="item_title">提交申请</view>
+				<view class="item_name">{{list.usersName}}</view>
+				<view class="item_time">{{list.submissionTime}}</view>
+				<view class="item_line" v-if="list.approverName || list.secondaryApproverName"></view>
+			</view>
+			<view v-if="list.secondaryApproverName">
+				<image class="item_image"></image>
+				<view class="item_title">{{list.secondaryExamineAndApproveRemark}}</view>
+				<view class="item_name">{{list.secondaryApproverName}}</view>
+				<view class="item_time">{{list.secondaryExamineAndApproveTime}}</view>
+				<view class="item_line" v-if="list.approverName"></view>
+			</view>
+			<view v-if="list.approverName">
+				<image class="item_image"></image>
+				<view class="item_title">{{list.examineAndApproveRemark}}</view>
+				<view class="item_name">{{list.approverName}}</view>
+				<view class="item_time">{{list.examineAndApproveTime}}</view>
+			</view>
+			</view>
 		</view>
 		<!-- 审批意见 -->
-		<view class="option_title">审批意见</view>
-		<view class="request_list">
+		<view class="option_title" v-if="list.status==1 || list.status==2">审批意见</view>
+		<view class="request_list" v-if="list.status==1 || list.status==2">
 			<uni-easyinput type="textarea" v-model="option" placeholder="请输入审批意见" @input="input"></uni-easyinput>
-			<text class="textsrea-txt" style="margin-left: 337px;">3/800</text>
+			<text class="textsrea-txt" style="margin-left: 337px;">{{textNum}}/800</text>
 		</view>
-		<view class="submit-disagree" v-if="type==2">驳回</view>
-		<view class="submit-agree" v-if="type==2">同意</view>
+		<view class="submit-disagree" v-if="list.status==1 || list.status==2" @click="disagree()">驳回</view>
+		<view class="submit-agree" v-if="list.status==1 || list.status==2" @click="agree()">同意</view>
 	</view>
 </template>
 
 <script>
+	import {
+			shenpiLinshi,
+			shenpiTeacher,
+			getlistXiang
+		} from '../../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
-				list:[
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-				],
-				//表单数据
-				baseFormData:{
-					submittype:['住院医师','主任医师','副主任医师','主治医师'],//职称
-					indextype:0,
-					startTime:'',
-					endTime:'',
-					remark:'',//备注
-				},
-				// 校验规则
-				rules: {
-					indextype: {
-						rules: [{
-							required: true,
-							errorMessage: '类型不能为空'
-						}]
-					},
-					age: {
-						rules: [{
-							required: true,
-							errorMessage: '年龄不能为空'
-						}, {
-							format: 'number',
-							errorMessage: '年龄只能输入数字'
-						}]
-					}
-				},
-				option:'',//审批意见
-				type:'2',
+				list:[],
+				id:'',
+				department:'',//身份
+				zishunum:0,
+				textNum:0,
+				option:'',
+				agreestatu:'',
 			}
 		},
-		onLoad() {
+		onLoad(option) {
+			this.id=option.id
+			this.department=option.department
+			this.getXiang()
 		},
 		mounted() {
 		},
@@ -108,6 +128,105 @@
 			//输入审批意见
 			input(e){
 				this.option=e
+				this.textNum=e.length
+			},
+			//详情
+			getXiang(){
+				let _self = this
+				// adminMenuId身份类型,4为教职工,7为临时人员localStorage.getItem('department')
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?department="+_self.department+"&id="+_self.id
+				getlistXiang(data).then((res) => {
+					if (res.success) {
+						this.list=res.data
+						this.zishunum=res.data.reasonApplication.length
+						return;
+					} else {
+						uni.showToast({
+							title: '获取记录详情失败'
+						})
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			//驳回
+			disagree(){
+				this.agreestatu='0'
+				if(this.department=='7'){
+					this.shenpiLinshi()
+				}else if(this.department=='4'){
+					this.shenpiTeacher()
+				}
+			},
+			//同意
+			agree(){
+				this.agreestatu='1'
+				if(this.department=='7'){
+					this.shenpiLinshi()
+				}else if(this.department=='4'){
+					this.shenpiTeacher()
+				}
+			},
+			// 审批临时人员
+			shenpiLinshi(){
+				let _self = this
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"id": _self.id, //审批表id
+					"adminMenuId": localStorage.getItem('manager'),//1管理员,0不是管理员
+					"status": _self.agreestatu, //审批状态   1:同意 0:拒绝
+					"adminId": localStorage.getItem('usersId'),//管理端id
+					"remark": _self.option ,//审批备注
+				}
+				shenpiLinshi(data).then((res) => {
+					if (res.success) {
+						uni.showToast({
+							title: '审批成功',
+							icon: 'success',
+							duration: 1000
+						})
+						_self.getXiang()
+					} else {
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			// 审批教师换课
+			shenpiTeacher(){
+				let _self = this
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"id": _self.id, //审批表id
+					"adminMenuId": localStorage.getItem('manager'),//1管理员,0不是管理员
+					"status": _self.agreestatu, //审批状态   1:同意 0:拒绝
+					"adminId": localStorage.getItem('usersId'),//管理端id
+					"remark": _self.option ,//审批备注
+				}
+				shenpiTeacher(data).then((res) => {
+					if (res.success) {
+						uni.showToast({
+							title: '审批成功',
+							icon: 'success',
+							duration: 1000
+						})
+						_self.getXiang()
+					} else {
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
 			},
 		}
 	}

+ 284 - 68
pages/liuchengManger/liu_manage.vue

@@ -5,12 +5,19 @@
 			<view class="select_submit">
 				<view style="width: 80px;margin-left: 9rpx;position: absolute;">
 					<uni-data-select
+						v-model="value3"
+						:localdata="shenfen"
+						@change="changeShen"
+					  ></uni-data-select>
+				</view>
+				<view style="width: 80px;margin-left: 196rpx;position: absolute;">
+					<uni-data-select
 						v-model="value"
 						:localdata="zhuangtai"
 						@change="changezhuang"
 					  ></uni-data-select>
 				</view>
-				<view style="width: 80px;margin-left: 196rpx;">
+				<view style="width: 80px;margin-left: 396rpx;">
 					<uni-data-select
 						v-model="value2"
 						:localdata="TimeRanges"
@@ -18,18 +25,23 @@
 					  ></uni-data-select>
 				</view>
 				<!-- 不同状态的记录 -->
-				<view :class="item.type==2?'submit-list2':'submit-list'" v-for="(item,index) in submit" :key="index" @click="clickDetail">
-					<text class="submit-title">{{item.title}}</text>
-					<text class="submit-time">{{item.time}}</text>
-					<view class="submit-line"></view>
-					<view class="submit-start">开始时间:{{item.startT}}</view>
-					<view class="submit-end">结束时间:{{item.endT}}</view>
-					<view class="submit-teacher">换课老师:{{item.teacher}}</view>
-					<view class="submit-remark">备注:{{item.remark}}</view>
-					<view class="submit-type" v-if="item.type==0">审批通过</view>
-					<view class="submit-type1" v-if="item.type==1">已拒绝</view>
-					<view class="submit-disagree" v-if="item.type==2">驳回</view>
-					<view class="submit-agree" v-if="item.type==2">同意</view>
+				<view :class="item.department=='4'?'submit-list2':'submit-list'" v-for="(item,index) in submit" :key="index">
+					<text @click="clickDetail(item.id,item.department)">
+						<text class="submit-title" v-if="item.department=='7'">临时人员</text>
+						<text class="submit-title" v-if="item.department=='4'">教师换课</text>
+						<text class="submit-time">{{item.submissionTime}}</text>
+						<view class="submit-line"></view>
+						<view class="submit-start">开始时间:{{item.startTime}}</view>
+						<view class="submit-end">结束时间:{{item.endTime}}</view>
+						<view class="submit-teacher" v-if="item.department=='4'">换课老师:{{item.changeUsersName}}</view>
+						<view class="submit-remark">备注:{{item.reasonApplication}}</view>
+						<view class="submit-type1" v-if="item.status==0">已拒绝</view>
+						<view class="submit-type1" v-if="item.status==1">待审批</view>
+						<view class="submit-type2" v-if="item.status==2">处理中</view>
+						<view class="submit-type" v-if="item.status==3">已同意</view>
+					</text>
+					<view class="submit-disagree" v-if="item.status==1 || item.status==2" @click="disagree(item.id)">驳回</view>
+					<view class="submit-agree" v-if="item.status==1 || item.status==2" @click="agree(item.id)">同意</view>
 				</view>
 
 			</view>
@@ -38,90 +50,294 @@
 </template>
 
 <script>
+	import {
+			getManaLinlist,
+			getManaTealist,
+			shenpiLinshi,
+			shenpiTeacher
+		} from '../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
-				//表单数据
-				baseFormData:{
-					submittype:['住院医师','主任医师','副主任医师','主治医师'],//职称
-					indextype:0,
-					startTime:'',
-					endTime:'',
-					remark:'',//备注
-				},
-				textNum:0,
-				// 校验规则
-				rules: {
-					indextype: {
-						rules: [{
-							required: true,
-							errorMessage: '类型不能为空'
-						}]
-					},
-					age: {
-						rules: [{
-							required: true,
-							errorMessage: '年龄不能为空'
-						}, {
-							format: 'number',
-							errorMessage: '年龄只能输入数字'
-						}]
-					}
-				},
-				// 提交记录 
-				value: 0,
+				// 提交记录
+				value3: 0,
+				shenfen: [
+				  { value: 0, text: "临时人员" },
+				  { value: 1, text: "教师换课" },
+				],
+				value: '',
 				zhuangtai: [
-				  { value: 0, text: "篮球篮球" },
-				  { value: 1, text: "足球" },
-				  { value: 2, text: "游泳" },
+				  { value: 0, text: "已拒绝" },
+				  { value: 1, text: "待审批" },
+				  { value: 2, text: "处理中" },
+				  { value: 3, text: "已同意" },
+				  { value: '', text: "全部" },
 				],
-				value2: 0,
+				value2: 2,
 				TimeRanges: [
 				  { value: 0, text: "近一周" },
-				  { value: 1, text: "近一年" },
-				  { value: 2, text: "近两年" },
+				  { value: 1, text: "本月" },
+				  { value: 2, text: "全部" },
 				],
-				submit:[
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'0'},
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'1'},
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'2'},
-				]
+				submit:[],
+				page:1,
+				size:10,
+				startTime:'',
+				endTime:'',
+				nowTime: new Date().toISOString().slice(0, 10),//当前日期2024-07-23
+				totalCount:0,
+				agreestatu:'',//1:同意 0:拒绝
 			}
 		},
 		onLoad() {
-			
+			this.getManageLin()
 		},
 		mounted() {
 			
 		},
 		methods: {
-			//切换房型
-			changeType(){
-				this.liutype=!this.liutype
+			//管理员查看临时人员记录
+			getManageLin(){
+				let _self = this
+				// adminMenuId身份类型,localStorage.getItem('manager'),//1管理员,0不是管理员
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?adminMenuId="+localStorage.getItem('manager')+"&startTime="+this.startTime+"&endTime="+this.endTime+"&status="+this.value+"&page="+this.page+"&size="+this.size
+				getManaLinlist(data).then((res) => {
+					if (res.success) {
+						this.totalCount=res.data.total
+						if (this.page == 1) {
+							this.submit = res.data.records
+						} else {
+							this.submit = [...this.submit, ...res.data.records]
+						}
+						uni.stopPullDownRefresh();
+						uni.hideLoading()
+					} else {
+						console.log('获取记录失败')
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			//管理员查看换课教师记录
+			getManageTeacher(){
+				let _self = this
+				// adminMenuId身份类型,localStorage.getItem('manager'),//1管理员,0不是管理员
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?adminMenuId="+localStorage.getItem('manager')+"&startTime="+this.startTime+"&endTime="+this.endTime+"&status="+this.value+"&page="+this.page+"&size="+this.size
+				getManaTealist(data).then((res) => {
+					if (res.success) {
+						this.totalCount=res.data.totalCount
+						if (this.page == 1) {
+							this.submit = res.data.list
+						} else {
+							this.submit = [...this.submit, ...res.data.list]
+						}
+						uni.stopPullDownRefresh();
+						uni.hideLoading()
+					} else {
+						console.log('获取记录失败')
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			
+			//驳回
+			disagree(id){
+				this.agreestatu='0'
+				var id=id
+				if(this.value3==0){
+					this.shenpiLinshi(id)
+				}else if(this.value3==1){
+					this.shenpiTeacher(id)
+				}
+			},
+			//同意
+			agree(id){
+				this.agreestatu='1'
+				var id=id
+				if(this.value3==0){
+					this.shenpiLinshi(id)
+				}else if(this.value3==1){
+					this.shenpiTeacher(id)
+				}
 			},
-			//修改类型
-			bindPickerChangetype: function(e) {
-				this.baseFormData.indextype=e.detail.value
+			// 审批临时人员
+			shenpiLinshi(id){
+				let _self = this
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"id": id, //审批表id
+					"adminMenuId": localStorage.getItem('manager'),//1管理员,0不是管理员
+					"status": _self.agreestatu, //审批状态   1:同意 0:拒绝
+					"adminId": localStorage.getItem('usersId'),//管理端id
+					"remark": "" ,//审批备注
+				}
+				shenpiLinshi(data).then((res) => {
+					if (res.success) {
+						uni.showToast({
+							title: '审批成功',
+							icon: 'success',
+							duration: 1000
+						})
+						if(_self.value3==1){
+							_self.getManageTeacher()
+						}else if(_self.value3==0){
+							_self.getManageLin()
+						}
+					} else {
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
 			},
-			//输入备注
-			input(e){
-				this.baseFormData.remark=e
+			// 审批教师换课
+			shenpiTeacher(id){
+				let _self = this
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"id": id, //审批表id
+					"adminMenuId": localStorage.getItem('manager'),//1管理员,0不是管理员
+					"status": _self.agreestatu, //审批状态   1:同意 0:拒绝
+					"adminId": localStorage.getItem('usersId'),//管理端id
+					"remark": "" ,//审批备注
+				}
+				shenpiTeacher(data).then((res) => {
+					if (res.success) {
+						uni.showToast({
+							title: '审批成功',
+							icon: 'success',
+							duration: 1000
+						})
+						if(_self.value3==1){
+							_self.getManageTeacher()
+						}else if(_self.value3==0){
+							_self.getManageLin()
+						}
+					} else {
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
 			},
 			// 提交记录
+			//选择审批类型身份
+			changeShen(e){
+				this.value3=e
+				if(this.value3==1){
+					this.getManageTeacher()
+				}else if(this.value3==0){
+					this.getManageLin()
+				}
+			},
 			// 选择审批状态
 			changezhuang(e) {
-			  console.log("e:", e);
+			  this.value=e
+			  if(this.value3==1){
+			  	this.getManageTeacher()
+			  }else if(this.value3==0){
+			  	this.getManageLin()
+			  }
+			},
+			//获得本周的开始时间:
+			getStartDayOfWeek(time) {
+				let now = new Date(time); // 当前日期
+				let nowDayOfWeek = now.getDay(); // 今天本周的第几天
+				let day = nowDayOfWeek || 7;
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, nowDay + 1 - day));
+			},
+			//获得本周的结束时间:
+			getEndDayOfWeek(time) {
+				let now = new Date(time); // 当前日期
+				let nowDayOfWeek = now.getDay(); // 今天本周的第几天
+				let day = nowDayOfWeek || 7;
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, nowDay + 7 - day));
+			},
+			//获得本月的开始时间:
+			getStartDayOfMonth(time) {
+				let now = new Date(time); // 当前日期
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, 1));
+			},
+			// 日期格式化
+			formatDate(date) {
+				let myyear = date.getFullYear();
+				let mymonth = date.getMonth() + 1;
+				let myweekday = date.getDate();
+				if (mymonth < 10) {
+					mymonth = '0' + mymonth;
+				}
+				if (myweekday < 10) {
+					myweekday = '0' + myweekday;
+				}
+				return (myyear + '-' + mymonth + '-' + myweekday);
 			},
 			// 选择时间
 			changetime(e) {
-			  console.log("e:", e);
+			    this.value2=e
+				if(this.value2==0){
+					this.startTime=this.getStartDayOfWeek(this.nowTime).slice(0, 10)+' 00:00:00'
+					this.endTime=this.getEndDayOfWeek(this.nowTime).slice(0, 10)+' 23:59:59'
+				}else if(this.value2==1){
+					this.startTime=this.getStartDayOfMonth(this.nowTime).slice(0, 10)+' 00:00:00'
+					this.endTime=this.nowTime+' 23:59:59'
+				}else if(this.value2==2){
+					this.startTime=''
+					this.endTime=''
+				}
+				if(this.value3==1){
+					this.getManageTeacher()
+				}else if(this.value3==0){
+					this.getManageLin()
+				}
 			},
 			// 跳转到详情页面
-			clickDetail(){
+			clickDetail(id,department){
 				uni.navigateTo({
-					url: "../liuchengManger/detail/teach_detail"
+					url: "../liuchengManger/detail/teach_detail?id="+id+"&department="+department
 				})
-			}
+			},
+			onReachBottom: function() {
+				
+				if (this.submit.length < this.totalCount) {
+					wx.showLoading({
+					   title: '加载中...',
+					 })
+					this.page = this.page + 1;
+					if(this.value3==1){
+						this.getManageTeacher()
+					}else if(this.value3==0){
+						this.getManageLin()
+					}
+				} else {
+				}
+			},
+			onPullDownRefresh: function() {
+				this.page = 1;
+				if(this.value3==1){
+					this.getManageTeacher()
+				}else if(this.value3==0){
+					this.getManageLin()
+				}
+			},
 		}
 	}
 </script>

+ 2 - 2
pages/liuchengO/css/liu_other.css

@@ -259,7 +259,7 @@ uni-picker {
 .submit-list{
 	margin: 11rpx 0 0 20rpx;
 	width: 710rpx;
-	height: 370rpx;
+	height: 320rpx;
 	opacity: 0.9;
 	border-radius: 10rpx;
 	background: rgba(255, 255, 255, 1);
@@ -275,7 +275,7 @@ uni-picker {
 	color: rgba(0, 0, 0, 1);
 }
 .submit-time{
-	margin: 0 0 0 353rpx;
+	margin: 0 0 0 253rpx;
 }
 .submit-line{
 	margin: 0 0 0 21rpx;

+ 69 - 55
pages/liuchengO/detail/teach_detail.vue

@@ -2,64 +2,78 @@
 	<view class="content">
 		<!-- 申请类型 -->
 		<view class="request_type">
-			<view class="type_title">换课申请</view>
-			<view class="type_time">2023.11.04  12:00</view>
-			<view class="type_zhuang">审批通过</view>
-			<!-- <view class="type_zhuang2">审批通过</view>
-			<view class="type_zhuang3">审批通过</view> -->
+			<view class="type_title">临时人员</view>
+			<view class="type_time">{{list.submissionTime}}</view>
+			<view class="type_zhuang2" v-if="list.status==0">已拒绝</view>
+			<view class="type_zhuang3" v-if="list.status==1">待审批</view>
+			<view class="type_zhuang3" v-if="list.status==2">处理中</view>
+			<view class="type_zhuang" v-if="list.status==3">审批通过</view>
 		</view>
 		<!-- 申请内容 -->
 		<view class="request_detail">
-			<uni-forms ref="valiForm" :rules="rules" :modelValue="baseFormData">
+			<uni-forms ref="valiForm">
 				<uni-forms-item label="类型" name="companyName" required>
 						<view class="uni-input">
-							111
+							临时人员
 						</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="开始时间" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.startTime}}
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="结束时间" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.endTime}}
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="申请部门" name="companyName" required>
 					<view class="uni-input">
-						111
+						<template v-if="list.department=='0'">其他</template>
+						<template v-if="list.department=='1'">学生</template>
+						<template v-if="list.department=='4'">教职工</template>
+						<template v-if="list.department=='5'">校友</template>
+						<template v-if="list.department=='6'">访客</template>
+						<template v-if="list.department=='7'">临时人员</template>
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
-				<uni-forms-item label="换课老师" name="companyName" required>
-					<view class="uni-input">
-						111
-					</view>
-				</uni-forms-item>
 			</uni-forms>
 		</view>
 		<!-- 申请备注 -->
 		<view class="request_remark">
 			<uni-forms-item label="备注" name="companyName" required>
 			</uni-forms-item>
-			<view class="liyou">{{shanchang}}</view>
-			<text class="textsrea-txt">1/200</text>
+			<view class="liyou">{{list.reasonApplication}}</view>
+			<text class="textsrea-txt">{{zishunum}}</text>
 		</view>
 		<!-- 审批记录 -->
 		<view class="request_list">
 			<view class="list_title">审批记录</view>
 			<!-- 几级审批 -->
 			<view style="position: absolute;margin-top: 110rpx;">
-			<view v-for="(item,index) in list" :key="index">
+			<view>
 				<image class="item_image"></image>
-				<view class="item_title">{{item.title}}</view>
-				<view class="item_name">{{item.name}}</view>
-				<view class="item_time">{{item.time}}</view>
-				<view class="item_line" v-if="index<(list.length-1)"></view>
+				<view class="item_title">提交申请</view>
+				<view class="item_name">{{list.usersName}}</view>
+				<view class="item_time">{{list.submissionTime}}</view>
+				<view class="item_line" v-if="list.approverUserName || list.secondaryApproverName"></view>
+			</view>
+			<view v-if="list.secondaryApproverName">
+				<image class="item_image"></image>
+				<view class="item_title">{{list.secondaryExamineAndApproveRemark}}</view>
+				<view class="item_name">{{list.secondaryApproverName}}</view>
+				<view class="item_time">{{list.secondaryExamineAndApproveTime}}</view>
+				<view class="item_line" v-if="list.approverName"></view>
+			</view>
+			<view v-if="list.approverName">
+				<image class="item_image"></image>
+				<view class="item_title">{{list.examineAndApproveRemark}}</view>
+				<view class="item_name">{{list.approverName}}</view>
+				<view class="item_time">{{list.examineAndApproveTime}}</view>
 			</view>
 			</view>
 		</view>
@@ -67,48 +81,48 @@
 </template>
 
 <script>
+	import {
+		getlistXiang
+	} from '../../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
-				list:[
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-				],
-				//表单数据
-				baseFormData:{
-					submittype:['住院医师','主任医师','副主任医师','主治医师'],//职称
-					indextype:0,
-					startTime:'',
-					endTime:'',
-					remark:'',//备注
-				},
-				// 校验规则
-				rules: {
-					indextype: {
-						rules: [{
-							required: true,
-							errorMessage: '类型不能为空'
-						}]
-					},
-					age: {
-						rules: [{
-							required: true,
-							errorMessage: '年龄不能为空'
-						}, {
-							format: 'number',
-							errorMessage: '年龄只能输入数字'
-						}]
-					}
-				},
+				list:{},
+				id:'',
+				department:'',//身份
+				zishunum:0,
 			}
 		},
-		onLoad() {
+		onLoad(option) {
+			this.id=option.id
+			this.department=option.department
+			this.getXiang()
 		},
 		mounted() {
 		},
 		methods: {
+			// 临时人员提交记录
+			getXiang(){
+				let _self = this
+				// adminMenuId身份类型,4为教职工,7为临时人员localStorage.getItem('department')
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?department="+_self.department+"&id="+_self.id
+				getlistXiang(data).then((res) => {
+					if (res.success) {
+						this.list=res.data
+						this.zishunum=res.data.reasonApplication.length
+						return;
+					} else {
+						uni.showToast({
+							title: '获取记录详情失败'
+						})
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
 		}
 	}
 </script>

+ 209 - 58
pages/liuchengO/liu_other.vue

@@ -15,41 +15,46 @@
 				<!-- 基础表单校验 -->
 				<uni-forms ref="valiForm" :rules="rules" :modelValue="baseFormData">
 					<uni-forms-item label="类型" name="companyName" required>
-						<picker @change="bindPickerChangetype" :value="baseFormData.indextype" :range="baseFormData.submittype">
-							<view class="uni-input">
-								<template v-if="baseFormData.indextype==''">请选择</template>
-								<template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
-								<text class="jiantou">〉</text>
+						<!-- <picker :range="baseFormData.submittype"> -->
+							<view class="uni-input" style="margin-right: 40px;color: black;">
+								<template>临时人员</template>
+								<!-- <template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
+								<text class="jiantou">〉</text> -->
 							</view>
-						</picker>
+						<!-- </picker> -->
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="开始时间" name="companyName" required>
-						<uni-datetime-picker type="datetime" return-type="timestamp" v-model="baseFormData.startTime"/>
+						<uni-datetime-picker type="dateTime" return-type="datetime" @change="changeStartTime" v-model="baseFormData.startTime" :start="baseFormData.mindate"/>
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="结束时间" name="companyName" required>
-						<uni-datetime-picker type="datetime" return-type="timestamp" v-model="baseFormData.endTime"/>
+						<uni-datetime-picker type="date" return-type="datetime" @change="changeEndTime" v-model="baseFormData.endTime" :start="baseFormData.mindate"/>
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="申请部门" name="companyName" required>
-						<picker @change="bindPickerChangetype" :value="baseFormData.indextype" :range="baseFormData.submittype">
-							<view class="uni-input">
-								<template v-if="baseFormData.indextype==''">请选择</template>
-								<template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
-								<text class="jiantou">〉</text>
-							</view>
-						</picker>
+						<view class="uni-input" style="margin-right: 40px;color: black;">
+							<!-- <template v-if="baseFormData.indextype==null">请选择</template> -->
+							<template>
+								<template v-if="baseFormData.bumen=='0'">其他</template>
+								<template v-if="baseFormData.bumen=='1'">学生</template>
+								<template v-if="baseFormData.bumen=='4'">教职工</template>
+								<template v-if="baseFormData.bumen=='5'">校友</template>
+								<template v-if="baseFormData.bumen=='6'">访客</template>
+								<template v-if="baseFormData.bumen=='7'">临时人员</template>
+							</template>
+							<!-- <text class="jiantou">〉</text> -->
+						</view>
 					</uni-forms-item>
 					<view style="width: 750rpx;height: 20rpx;background-color: rgba(242, 243, 245, 1);margin-left: -20px;"></view>
 					<uni-forms-item label="备注" name="companyName" required>
 					</uni-forms-item>
-					<uni-easyinput type="textarea" v-model="baseFormData.remark" placeholder="请输入备注" @input="input"></uni-easyinput>
+					<uni-easyinput type="textarea" v-model="baseFormData.remark" placeholder="请输入备注" maxlength="800" @input="input"></uni-easyinput>
 					<text class="textsrea-txt">{{textNum}}/800</text>
 					<view style="width:100%;height: 30px;"></view>
 				</uni-forms>
 			</view>
-			<view class="submit_button">提交</view>
+			<view class="submit_button" @click="submitshen">提交</view>
 		</view>
 		<!-- 提交记录 -->
 		<view v-else>
@@ -69,17 +74,17 @@
 					  ></uni-data-select>
 				</view>
 				<!-- 不同状态的记录 -->
-				<view class="submit-list" v-for="(item,index) in submit" :key="index" @click="clickDetail">
-					<text class="submit-title">{{item.title}}</text>
-					<text class="submit-time">{{item.time}}</text>
+				<view class="submit-list" v-for="(item,index) in submit" :key="index" @click="clickDetail(item.id,item.department)">
+					<text class="submit-title">临时人员</text>
+					<text class="submit-time">{{item.submissionTime}}</text>
 					<view class="submit-line"></view>
-					<view class="submit-start">开始时间:{{item.startT}}</view>
-					<view class="submit-end">结束时间:{{item.endT}}</view>
-					<view class="submit-teacher">换课老师:{{item.teacher}}</view>
-					<view class="submit-remark">备注:{{item.remark}}</view>
-					<view class="submit-type" v-if="item.type==0">审批通过</view>
-					<view class="submit-type1" v-if="item.type==1">已拒绝</view>
-					<view class="submit-type2" v-if="item.type==2">待审批</view>
+					<view class="submit-start">开始时间:{{item.startTime}}</view>
+					<view class="submit-end">结束时间:{{item.endTime}}</view>
+					<view class="submit-remark">备注:{{item.reasonApplication}}</view>
+					<view class="submit-type1" v-if="item.status==0">已拒绝</view>
+					<view class="submit-type1" v-if="item.status==1">待审批</view>
+					<view class="submit-type2" v-if="item.status==2">处理中</view>
+					<view class="submit-type" v-if="item.status==3">已同意</view>
 				</view>
 
 			</view>
@@ -88,27 +93,25 @@
 </template>
 
 <script>
+	import {
+		postLingshi,
+		getOtherlist
+	} from '../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
 				liutype:true,//切换流程状态
 				//表单数据
 				baseFormData:{
-					submittype:['住院医师','主任医师','副主任医师','主治医师'],//职称
-					indextype:0,
 					startTime:'',
 					endTime:'',
+					mindate:new Date().toISOString().slice(0, 10),
 					remark:'',//备注
+					bumen:localStorage.getItem('department'),
 				},
 				textNum:0,
 				// 校验规则
 				rules: {
-					indextype: {
-						rules: [{
-							required: true,
-							errorMessage: '类型不能为空'
-						}]
-					},
 					age: {
 						rules: [{
 							required: true,
@@ -120,57 +123,205 @@
 					}
 				},
 				// 提交记录 
-				value: 0,
+				value: '',
 				zhuangtai: [
-				  { value: 0, text: "篮球篮球" },
-				  { value: 1, text: "足球" },
-				  { value: 2, text: "游泳" },
+				  { value: 0, text: "已拒绝" },
+				  { value: 1, text: "待审批" },
+				  { value: 2, text: "处理中" },
+				  { value: 3, text: "已同意" },
+				  { value: '', text: "全部" },
 				],
-				value2: 0,
+				value2: 2,
 				TimeRanges: [
 				  { value: 0, text: "近一周" },
-				  { value: 1, text: "近一年" },
-				  { value: 2, text: "近两年" },
+				  { value: 1, text: "本月" },
+				  { value: 2, text: "全部" },
 				],
-				submit:[
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'0'},
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'1'},
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'2'},
-				]
+				submit:[],
+				page:1,
+				size:10,
+				startTime:'',
+				endTime:'',
+				nowTime: new Date().toISOString().slice(0, 10),//当前日期2024-07-23
+				totalCount:0,
 			}
 		},
 		onLoad() {
-			
 		},
 		mounted() {
 			
 		},
 		methods: {
-			//切换房型
+			//切换
 			changeType(){
 				this.liutype=!this.liutype
-			},
-			//修改类型
-			bindPickerChangetype: function(e) {
-				this.baseFormData.indextype=e.detail.value
+				if(this.liutype==false){
+					this.getOtherlist()
+				}
+				
 			},
 			//输入备注
 			input(e){
 				this.baseFormData.remark=e
+				this.textNum=e.length
+			},
+			changeStartTime(e){
+				this.baseFormData.startTime=e
+			},
+			changeEndTime(e){
+				this.baseFormData.endTime=e
+			},
+			//提交审核
+			submitshen(){
+				if(this.baseFormData.endTime<=this.baseFormData.startTime){
+					uni.showToast({
+						title: '开始时间不能大于结束时间',
+						icon: 'error',
+						duration: 1000
+					})
+					return
+				}
+				let _self = this
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"usersId": localStorage.getItem('usersId'), //申请人id
+					"startTime": this.baseFormData.startTime, //开始时间
+					"endTime": this.baseFormData.endTime, //结束时间
+					"department": localStorage.getItem('department'), //部门
+					"reasonApplication": this.baseFormData.remark ,//申请原因
+				}
+				postLingshi(data).then((res) => {
+					if (res.success) {
+						uni.showToast({
+							title: '提交成功',
+							icon: 'success',
+							duration: 1000
+						})
+						this.liutype=false
+						this.getOtherlist()
+						// setTimeout(function() {
+						// 	this.liutype=false
+						// 	// uni.switchTab({
+						// 	// 	url:'/pages/myself/myself'
+						// 	// })
+						// }, 2000);
+					} else {
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			// 临时人员提交记录
+			getOtherlist(){
+				let _self = this
+				// adminMenuId身份类型,4为教职工,7为临时人员localStorage.getItem('department')
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?department="+localStorage.getItem('department')+"&userId=13"+"&startTime="+this.startTime+"&endTime="+this.endTime+"&status="+this.value+"&page="+this.page+"&size="+this.size
+				getOtherlist(data).then((res) => {
+					if (res.success) {
+						this.totalCount=res.data.totalCount
+						if (this.page == 1) {
+							this.submit = res.data.list
+						} else {
+							this.submit = [...this.submit, ...res.data.list]
+						}
+						uni.stopPullDownRefresh();
+						uni.hideLoading()
+					} else {
+						console.log('获取记录失败')
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			onReachBottom: function() {
+				console.log('当前长度',this.submit.length,this.totalCount)
+				
+				if (this.submit.length < this.totalCount) {
+					wx.showLoading({
+					   title: '加载中...',
+					 })
+					this.page = this.page + 1;
+					this.getOtherlist()
+				} else {
+					// uni.showToast({
+					// 	title: '已经到底了',
+					// 	icon: 'none'
+					// })
+				}
+			},
+			onPullDownRefresh: function() {
+				this.page = 1;
+				this.getOtherlist();
 			},
-			// 提交记录
 			// 选择审批状态
 			changezhuang(e) {
-			  console.log("e:", e);
+				this.value=e
+				this.getOtherlist()
+			},
+			//获得本周的开始时间:
+			getStartDayOfWeek(time) {
+				let now = new Date(time); // 当前日期
+				let nowDayOfWeek = now.getDay(); // 今天本周的第几天
+				let day = nowDayOfWeek || 7;
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, nowDay + 1 - day));
+			},
+			//获得本周的结束时间:
+			getEndDayOfWeek(time) {
+				let now = new Date(time); // 当前日期
+				let nowDayOfWeek = now.getDay(); // 今天本周的第几天
+				let day = nowDayOfWeek || 7;
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, nowDay + 7 - day));
+			},
+			//获得本月的开始时间:
+			getStartDayOfMonth(time) {
+				let now = new Date(time); // 当前日期
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, 1));
+			},
+			// 日期格式化
+			formatDate(date) {
+				let myyear = date.getFullYear();
+				let mymonth = date.getMonth() + 1;
+				let myweekday = date.getDate();
+				if (mymonth < 10) {
+					mymonth = '0' + mymonth;
+				}
+				if (myweekday < 10) {
+					myweekday = '0' + myweekday;
+				}
+				return (myyear + '-' + mymonth + '-' + myweekday);
 			},
 			// 选择时间
 			changetime(e) {
-			  console.log("e:", e);
+			    this.value2=e
+				if(this.value2==0){
+					this.startTime=this.getStartDayOfWeek(this.nowTime).slice(0, 10)+' 00:00:00'
+					this.endTime=this.getEndDayOfWeek(this.nowTime).slice(0, 10)+' 23:59:59'
+				}else if(this.value2==1){
+					this.startTime=this.getStartDayOfMonth(this.nowTime).slice(0, 10)+' 00:00:00'
+					this.endTime=this.nowTime+' 23:59:59'
+				}else if(this.value2==2){
+					this.startTime=''
+					this.endTime=''
+				}
+				this.getOtherlist()
 			},
 			// 跳转到详情页面
-			clickDetail(){
+			clickDetail(id,department){
 				uni.navigateTo({
-					url: "../liuchengO/detail/teach_detail"
+					url: "../liuchengO/detail/teach_detail?id="+id+"&department="+department
 				})
 			}
 		}

+ 1 - 1
pages/liuchengTeacher/css/liu_teach.css

@@ -275,7 +275,7 @@ uni-picker {
 	color: rgba(0, 0, 0, 1);
 }
 .submit-time{
-	margin: 0 0 0 353rpx;
+	margin: 0 0 0 253rpx;
 }
 .submit-line{
 	margin: 0 0 0 21rpx;

+ 74 - 50
pages/liuchengTeacher/detail/teach_detail.vue

@@ -3,41 +3,52 @@
 		<!-- 申请类型 -->
 		<view class="request_type">
 			<view class="type_title">换课申请</view>
-			<view class="type_time">2023.11.04  12:00</view>
-			<view class="type_zhuang">审批通过</view>
-			<!-- <view class="type_zhuang2">审批通过</view>
-			<view class="type_zhuang3">审批通过</view> -->
+			<view class="type_time">{{list.submissionTime}}</view>
+			<view class="type_zhuang2" v-if="list.status==0">已拒绝</view>
+			<view class="type_zhuang3" v-if="list.status==1">待审批</view>
+			<view class="type_zhuang3" v-if="list.status==2">处理中</view>
+			<view class="type_zhuang" v-if="list.status==3">审批通过</view>
 		</view>
 		<!-- 申请内容 -->
 		<view class="request_detail">
-			<uni-forms ref="valiForm" :rules="rules" :modelValue="baseFormData">
+			<uni-forms ref="valiForm">
 				<uni-forms-item label="类型" name="companyName" required>
 						<view class="uni-input">
-							111
+							<template v-if="list.department=='0'">其他</template>
+							<template v-if="list.department=='1'">学生</template>
+							<template v-if="list.department=='4'">教职工</template>
+							<template v-if="list.department=='5'">校友</template>
+							<template v-if="list.department=='6'">访客</template>
+							<template v-if="list.department=='7'">临时人员</template>
 						</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="开始时间" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.startTime}}
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="结束时间" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.endTime}}
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="申请部门" name="companyName" required>
 					<view class="uni-input">
-						111
+						<template v-if="list.department=='0'">其他</template>
+						<template v-if="list.department=='1'">学生</template>
+						<template v-if="list.department=='4'">教职工</template>
+						<template v-if="list.department=='5'">校友</template>
+						<template v-if="list.department=='6'">访客</template>
+						<template v-if="list.department=='7'">临时人员</template>
 					</view>
 				</uni-forms-item>
 				<view class="form-line"></view>
 				<uni-forms-item label="换课老师" name="companyName" required>
 					<view class="uni-input">
-						111
+						{{list.changeUsersName}}
 					</view>
 				</uni-forms-item>
 			</uni-forms>
@@ -46,20 +57,33 @@
 		<view class="request_remark">
 			<uni-forms-item label="备注" name="companyName" required>
 			</uni-forms-item>
-			<view class="liyou">{{shanchang}}</view>
-			<text class="textsrea-txt">1/200</text>
+			<view class="liyou">{{list.reasonApplication}}</view>
+			<text class="textsrea-txt">{{zishunum}}</text>
 		</view>
 		<!-- 审批记录 -->
 		<view class="request_list">
 			<view class="list_title">审批记录</view>
 			<!-- 几级审批 -->
 			<view style="position: absolute;margin-top: 110rpx;">
-			<view v-for="(item,index) in list" :key="index">
+			<view>
 				<image class="item_image"></image>
-				<view class="item_title">{{item.title}}</view>
-				<view class="item_name">{{item.name}}</view>
-				<view class="item_time">{{item.time}}</view>
-				<view class="item_line" v-if="index<(list.length-1)"></view>
+				<view class="item_title">提交申请</view>
+				<view class="item_name">{{list.usersName}}</view>
+				<view class="item_time">{{list.submissionTime}}</view>
+				<view class="item_line" v-if="list.approverUserName || list.secondaryApproverName"></view>
+			</view>
+			<view v-if="list.secondaryApproverName">
+				<image class="item_image"></image>
+				<view class="item_title">{{list.secondaryExamineAndApproveRemark}}</view>
+				<view class="item_name">{{list.secondaryApproverName}}</view>
+				<view class="item_time">{{list.secondaryExamineAndApproveTime}}</view>
+				<view class="item_line" v-if="list.approverName"></view>
+			</view>
+			<view v-if="list.approverName">
+				<image class="item_image"></image>
+				<view class="item_title">{{list.examineAndApproveRemark}}</view>
+				<view class="item_name">{{list.approverName}}</view>
+				<view class="item_time">{{list.examineAndApproveTime}}</view>
 			</view>
 			</view>
 		</view>
@@ -67,48 +91,48 @@
 </template>
 
 <script>
+	import {
+		getlistXiang
+	} from '../../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
-				list:[
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-					{title:'提交申请',name:'我',time:'2023.11.07  09:00'},
-				],
-				//表单数据
-				baseFormData:{
-					submittype:['住院医师','主任医师','副主任医师','主治医师'],//职称
-					indextype:0,
-					startTime:'',
-					endTime:'',
-					remark:'',//备注
-				},
-				// 校验规则
-				rules: {
-					indextype: {
-						rules: [{
-							required: true,
-							errorMessage: '类型不能为空'
-						}]
-					},
-					age: {
-						rules: [{
-							required: true,
-							errorMessage: '年龄不能为空'
-						}, {
-							format: 'number',
-							errorMessage: '年龄只能输入数字'
-						}]
-					}
-				},
+				list:[],
+				id:'',
+				department:'',//身份
+				zishunum:0,
 			}
 		},
-		onLoad() {
+		onLoad(option) {
+			this.id=option.id
+			this.department=option.department
+			this.getXiang()
 		},
 		mounted() {
 		},
 		methods: {
+			// 临时人员提交记录
+			getXiang(){
+				let _self = this
+				// adminMenuId身份类型,4为教职工,7为临时人员localStorage.getItem('department')
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?department="+_self.department+"&id="+_self.id
+				getlistXiang(data).then((res) => {
+					if (res.success) {
+						this.list=res.data
+						this.zishunum=res.data.reasonApplication.length
+						return;
+					} else {
+						uni.showToast({
+							title: '获取记录详情失败'
+						})
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
 		}
 	}
 </script>

+ 225 - 52
pages/liuchengTeacher/liu_teach.vue

@@ -15,40 +15,39 @@
 				<!-- 基础表单校验 -->
 				<uni-forms ref="valiForm" :rules="rules" :modelValue="baseFormData">
 					<uni-forms-item label="类型" name="companyName" required>
-						<picker @change="bindPickerChangetype" :value="baseFormData.indextype" :range="baseFormData.submittype">
-							<view class="uni-input">
-								<template v-if="baseFormData.indextype==''">请选择</template>
-								<template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
-								<text class="jiantou">〉</text>
+						<!-- <picker :value="baseFormData.indextype" :range="baseFormData.submittype"> -->
+							<view class="uni-input" style="margin-right: 40rpx;color: black;">
+								<template>教师换课</template>
+								<!-- <template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
+								<text class="jiantou">〉</text> -->
 							</view>
-						</picker>
+						<!-- </picker> -->
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="开始时间" name="companyName" required>
-						<uni-datetime-picker type="datetime" return-type="timestamp" v-model="baseFormData.startTime"/>
+						<uni-datetime-picker type="dateTime" return-type="datetime" @change="changeStartTime" v-model="baseFormData.startTime" :start="baseFormData.mindate"/>
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="结束时间" name="companyName" required>
-						<uni-datetime-picker type="datetime" return-type="timestamp" v-model="baseFormData.endTime"/>
+						<uni-datetime-picker type="date" return-type="datetime" @change="changeEndTime" v-model="baseFormData.endTime" :start="baseFormData.mindate"/>
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="申请部门" name="companyName" required>
-						<picker @change="bindPickerChangetype" :value="baseFormData.indextype" :range="baseFormData.submittype">
-							<view class="uni-input">
-								<template v-if="baseFormData.indextype==''">请选择</template>
-								<template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
-								<text class="jiantou">〉</text>
+						<!-- <picker @change="bindPickerChangetype" :value="baseFormData.indextype" :range="baseFormData.submittype"> -->
+							<view class="uni-input" style="margin-right: 40px;color: black;">
+								<template v-if="baseFormData.bumen=='0'">其他</template>
+								<template v-if="baseFormData.bumen=='1'">学生</template>
+								<template v-if="baseFormData.bumen=='4'">教职工</template>
+								<template v-if="baseFormData.bumen=='5'">校友</template>
+								<template v-if="baseFormData.bumen=='6'">访客</template>
+								<template v-if="baseFormData.bumen=='7'">临时人员</template>
 							</view>
-						</picker>
+						<!-- </picker> -->
 					</uni-forms-item>
 					<view class="form-line"></view>
 					<uni-forms-item label="换课老师" name="companyName" required>
-						<picker @change="bindPickerChangetype" :value="baseFormData.indextype" :range="baseFormData.submittype">
-							<view class="uni-input">
-								<template v-if="baseFormData.indextype==''">请选择</template>
-								<template v-else>{{baseFormData.submittype[baseFormData.indextype]}}</template>
-								<text class="jiantou">〉</text>
-							</view>
+						<picker @change="bindPickerChangetype" :value="indextype" :range="submittype" range-key="userName">
+							<view>{{indextype.userName?indextype.userName:'请选择'}}</view>
 						</picker>
 					</uni-forms-item>
 					<view style="width: 750rpx;height: 20rpx;background-color: rgba(242, 243, 245, 1);margin-left: -20px;"></view>
@@ -59,7 +58,7 @@
 					<view style="width:100%;height: 30px;"></view>
 				</uni-forms>
 			</view>
-			<view class="submit_button">提交</view>
+			<view class="submit_button" @click="submitshen">提交</view>
 		</view>
 		<!-- 提交记录 -->
 		<view v-else>
@@ -79,17 +78,18 @@
 					  ></uni-data-select>
 				</view>
 				<!-- 不同状态的记录 -->
-				<view class="submit-list" v-for="(item,index) in submit" :key="index" @click="clickDetail">
-					<text class="submit-title">{{item.title}}</text>
-					<text class="submit-time">{{item.time}}</text>
+				<view class="submit-list" v-for="(item,index) in submit" :key="index" @click="clickDetail(item.id,item.department)">
+					<text class="submit-title">换课申请</text>
+					<text class="submit-time">{{item.submissionTime}}</text>
 					<view class="submit-line"></view>
-					<view class="submit-start">开始时间:{{item.startT}}</view>
-					<view class="submit-end">结束时间:{{item.endT}}</view>
-					<view class="submit-teacher">换课老师:{{item.teacher}}</view>
-					<view class="submit-remark">备注:{{item.remark}}</view>
-					<view class="submit-type" v-if="item.type==0">审批通过</view>
-					<view class="submit-type1" v-if="item.type==1">已拒绝</view>
-					<view class="submit-type2" v-if="item.type==2">待审批</view>
+					<view class="submit-start">开始时间:{{item.startTime}}</view>
+					<view class="submit-end">结束时间:{{item.endTime}}</view>
+					<view class="submit-teacher">换课老师:{{item.changeUsersName}}</view>
+					<view class="submit-remark">备注:{{item.reasonApplication}}</view>
+					<view class="submit-type1" v-if="item.status==0">已拒绝</view>
+					<view class="submit-type1" v-if="item.status==1">待审批</view>
+					<view class="submit-type2" v-if="item.status==2">处理中</view>
+					<view class="submit-type" v-if="item.status==3">已同意</view>
 				</view>
 
 			</view>
@@ -98,17 +98,24 @@
 </template>
 
 <script>
+import {
+		postTeacher,
+		getChange,
+		getOtherlist
+	} from '../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
 				liutype:true,//切换流程状态
 				//表单数据
+				submittype:[],//换课老师
+				indextype:1,
 				baseFormData:{
-					submittype:['住院医师','主任医师','副主任医师','主治医师'],//职称
-					indextype:0,
 					startTime:'',
 					endTime:'',
+					mindate:new Date().toISOString().slice(0, 10),
 					remark:'',//备注
+					bumen:localStorage.getItem('department'),
 				},
 				textNum:0,
 				// 校验规则
@@ -130,57 +137,223 @@
 					}
 				},
 				// 提交记录 
-				value: 0,
+				value: '',
 				zhuangtai: [
-				  { value: 0, text: "篮球篮球" },
-				  { value: 1, text: "足球" },
-				  { value: 2, text: "游泳" },
+				  { value: 0, text: "已拒绝" },
+				  { value: 1, text: "待审批" },
+				  { value: 2, text: "处理中" },
+				  { value: 3, text: "已同意" },
+				  { value: '', text: "全部" },
 				],
-				value2: 0,
+				value2: 2,
 				TimeRanges: [
 				  { value: 0, text: "近一周" },
-				  { value: 1, text: "近一年" },
-				  { value: 2, text: "近两年" },
+				  { value: 1, text: "本月" },
+				  { value: 2, text: "全部" },
 				],
-				submit:[
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'0'},
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'1'},
-					{title:'换课申请',time:'2023.11.04  12:00',startT:'2023.11.04  12:00',endT:'2023.11.04  12:00',teacher:'李华',remark:'家中有事',type:'2'},
-				]
+				submit:[],
+				page:1,
+				size:10,
+				startTime:'',
+				endTime:'',
+				nowTime: new Date().toISOString().slice(0, 10),//当前日期2024-07-23
+				totalCount:0,
 			}
 		},
 		onLoad() {
-			
+			this.getChange()
 		},
 		mounted() {
-			
 		},
 		methods: {
+			// 获取老师
+			getChange(){
+				this.baseFormData.submittype=[]
+				let _self = this
+				getChange().then((res) => {
+					if (res.success) {
+						this.submittype=res.data
+						return;
+					} else {
+						uni.showToast({
+							title: '获取换课老师失败'
+						})
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
 			//切换房型
 			changeType(){
 				this.liutype=!this.liutype
+				if(this.liutype==false){
+					this.getOtherlist()
+				}
+			},
+			changeStartTime(e){
+				this.baseFormData.startTime=e
+			},
+			changeEndTime(e){
+				this.baseFormData.endTime=e
+			},
+			//提交审核
+			submitshen(){
+				if(this.baseFormData.endTime<=this.baseFormData.startTime){
+					uni.showToast({
+						title: '开始时间不能大于结束时间',
+						icon: 'error',
+						duration: 1000
+					})
+					return
+				}
+				let _self = this
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"usersId": localStorage.getItem('usersId'), //申请人id
+					"startTime": this.baseFormData.startTime, //开始时间
+					"endTime": this.baseFormData.endTime, //结束时间
+					"department": localStorage.getItem('department'), //部门
+					"changeUsersId": this.indextype.id,//换课人id
+					"reasonApplication": this.baseFormData.remark ,//申请原因
+				}
+				postTeacher(data).then((res) => {
+					if (res.success) {
+						uni.showToast({
+							title: '提交成功',
+							icon: 'success',
+							duration: 1000
+						})
+						this.liutype=false
+						this.getOtherlist()
+					} else {
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
+			},
+			// 临时人员提交记录
+			getOtherlist(){
+				let _self = this
+				// adminMenuId身份类型,4为教职工,7为临时人员localStorage.getItem('department')
+				// 状态,0:已拒绝,1:待审批,2:处理中,3:已同意
+				var data="?department="+localStorage.getItem('department')+"&userId=13"+"&startTime="+this.startTime+"&endTime="+this.endTime+"&status="+this.value+"&page="+this.page+"&size="+this.size
+				getOtherlist(data).then((res) => {
+					if (res.success) {
+						this.totalCount=res.data.totalCount
+						if (this.page == 1) {
+							this.submit = res.data.list
+						} else {
+							this.submit = [...this.submit, ...res.data.list]
+						}
+						uni.stopPullDownRefresh();
+						uni.hideLoading()
+					} else {
+						console.log('获取记录失败')
+					}
+				}).catch((err) => {
+					uni.showToast({
+						title: err.message
+					})
+				});
 			},
 			//修改类型
 			bindPickerChangetype: function(e) {
-				this.baseFormData.indextype=e.detail.value
+				this.indextype = this.submittype[e.detail.value];
 			},
 			//输入备注
 			input(e){
 				this.baseFormData.remark=e
+				this.textNum=e.length
 			},
 			// 提交记录
+			onReachBottom: function() {
+				console.log('当前长度',this.submit.length,this.totalCount)
+				
+				if (this.submit.length < this.totalCount) {
+					wx.showLoading({
+					   title: '加载中...',
+					 })
+					this.page = this.page + 1;
+					this.getOtherlist()
+				} else {
+					// uni.showToast({
+					// 	title: '已经到底了',
+					// 	icon: 'none'
+					// })
+				}
+			},
+			onPullDownRefresh: function() {
+				this.page = 1;
+				this.getOtherlist();
+			},
 			// 选择审批状态
 			changezhuang(e) {
-			  console.log("e:", e);
+			  this.value=e
+			  this.getOtherlist()
+			},
+			//获得本周的开始时间:
+			getStartDayOfWeek(time) {
+				let now = new Date(time); // 当前日期
+				let nowDayOfWeek = now.getDay(); // 今天本周的第几天
+				let day = nowDayOfWeek || 7;
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, nowDay + 1 - day));
+			},
+			//获得本周的结束时间:
+			getEndDayOfWeek(time) {
+				let now = new Date(time); // 当前日期
+				let nowDayOfWeek = now.getDay(); // 今天本周的第几天
+				let day = nowDayOfWeek || 7;
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, nowDay + 7 - day));
+			},
+			//获得本月的开始时间:
+			getStartDayOfMonth(time) {
+				let now = new Date(time); // 当前日期
+				let nowDay = now.getDate(); // 当前日
+				let nowMonth = now.getMonth(); // 当前月
+				return this.formatDate(new Date(now.getFullYear(), nowMonth, 1));
+			},
+			// 日期格式化
+			formatDate(date) {
+				let myyear = date.getFullYear();
+				let mymonth = date.getMonth() + 1;
+				let myweekday = date.getDate();
+				if (mymonth < 10) {
+					mymonth = '0' + mymonth;
+				}
+				if (myweekday < 10) {
+					myweekday = '0' + myweekday;
+				}
+				return (myyear + '-' + mymonth + '-' + myweekday);
 			},
 			// 选择时间
 			changetime(e) {
-			  console.log("e:", e);
+			    this.value2=e
+				if(this.value2==0){
+					this.startTime=this.getStartDayOfWeek(this.nowTime).slice(0, 10)+' 00:00:00'
+					this.endTime=this.getEndDayOfWeek(this.nowTime).slice(0, 10)+' 23:59:59'
+				}else if(this.value2==1){
+					this.startTime=this.getStartDayOfMonth(this.nowTime).slice(0, 10)+' 00:00:00'
+					this.endTime=this.nowTime+' 23:59:59'
+				}else if(this.value2==2){
+					this.startTime=''
+					this.endTime=''
+				}
+				this.getOtherlist()
 			},
 			// 跳转到详情页面
-			clickDetail(){
+			clickDetail(id,department){
 				uni.navigateTo({
-					url: "../liuchengTeacher/detail/teach_detail"
+					url: "../liuchengTeacher/detail/teach_detail?id="+id+"&department="+department
 				})
 			}
 		}

+ 3 - 3
pages/my_orderlist/css/my_orderlist.css

@@ -65,7 +65,7 @@
 	flex-direction: column;
 	align-items: center;
 	width: 710rpx;
-	height: 243rpx;
+	height: 283rpx;
 	margin-top: 20rpx;
 }
 .room-image{
@@ -146,7 +146,7 @@
 .room-button2{
 	position: absolute;
 	margin-left: 551rpx;
-	margin-top: 146rpx;
+	margin-top: 186rpx;
 	width: 146rpx;
 	height: 56rpx;
 	border: 1px solid rgba(41, 109, 227, 1);
@@ -171,7 +171,7 @@
 .room-line{
 	position: absolute;
 	margin-left: 20rpx;
-	margin-top: 225rpx;
+	margin-top: 265rpx;
 	width: 710rpx;
 	height: 1px;
 	background: rgba(220, 225, 230, 1);

+ 190 - 174
pages/my_orderlist/my_orderlist.vue

@@ -4,48 +4,50 @@
 		<scroll-view :scroll-x="true" class="inv-h-w">
 			<view :class="['inv-h',Inv==6?'inv-h-se':'']" @click="changeTab(6)">全部</view>
 			<view :class="['inv-h',Inv==1?'inv-h-se':'']" @click="changeTab(1)">待支付</view>
-			<view :class="['inv-h',Inv==2?'inv-h-se':'']" @click="changeTab(2)">待入住</view>
-			<view :class="['inv-h',Inv==3?'inv-h-se':'']" @click="changeTab(3)">已入住</view>
-			<view :class="['inv-h',Inv==0?'inv-h-se':'']" @click="changeTab(0)">已取消</view>
-			<view :class="['inv-h',Inv==4?'inv-h-se':'']" @click="changeTab(4)">待结账</view>
-			<view :class="['inv-h',Inv==5?'inv-h-se':'']" @click="changeTab(5)">已完成</view>
+			<view :class="['inv-h',Inv==3?'inv-h-se':'']" @click="changeTab(3)">待入住</view>
+			<view :class="['inv-h',Inv==4?'inv-h-se':'']" @click="changeTab(4)">已入住</view>
+			<view :class="['inv-h',Inv==9?'inv-h-se':'']" @click="changeTab(9)">已取消</view>
+			<view :class="['inv-h',Inv==5?'inv-h-se':'']" @click="changeTab(5)">待结账</view>
+			<view :class="['inv-h',Inv==8?'inv-h-se':'']" @click="changeTab(8)">已完成</view>
 		</scroll-view>
 		<!-- 订单样式 -->
 		<uni-list class="room-kuang">
 			<view class="room-xinxi" v-for="(item,index) in troom" :key="index">
 				<view @click="navigateToOrderMark(item.id)">
-					<image class="room-image" :src="item.roomTypeMasterImg"></image>
-					<view class="room-name">{{item.roomTypeName}}</view>
-					<view class="room-time">{{item.enableStartTime|snippet}}-{{item.enableEndTime|snippet}}</view>
-					<view class="room-order">订单号:{{item.id}}</view>
+					<image class="room-image" :src="item.url"></image>
+					<view class="room-name">{{item.roomNumber}}</view>
+					<view class="room-time">{{item.reserveLiveTime|snippet}}-{{item.reserveLeaveTime|snippet}}</view>
+					<view class="room-order">订单号:{{item.orderNumber}}</view>
 					<view class="room-type">
-						<text v-if="item.orderStatu==0">已取消</text>
-						<text v-if="item.orderStatu==1">待支付</text>
-						<text v-if="item.orderStatu==2">待入住</text>
-						<text v-if="item.orderStatu==3">已入住</text>
-						<text v-if="item.orderStatu==4">
+						<text v-if="item.orderStatus==9">已取消</text>
+						<text v-if="item.orderStatus==1">待支付</text>
+						<text v-if="item.orderStatus==3">待入住</text>
+						<text v-if="item.orderStatus==4">已入住</text>
+						<text v-if="item.orderStatus==5">
 							待结账
 						</text>
-						<text v-if="item.orderStatu==5">已完成</text>
+						<text v-if="item.orderStatus==8">已完成</text>
 					</view>
-					<view class="room-price">¥{{item.payAmount}}</view>
+					<view class="room-price">¥{{item.payPrice}}</view>
 				</view>
-				<uni-countdown v-if="item.orderStatu == 1" class="room-count" color="#FF5733" :show-day="false" :second="timeupSecond" @timeup="timeup(item.createTime)" />
-				<text v-if="item.orderStatu == 1" class="room-count-txt">之后取消</text>
-				<view class="room-button" v-if="item.orderStatu != 4 && item.orderStatu != 2 && item.orderStatu != 3">
-					<text v-if="item.orderStatu == 0" @click="openDel(item.id,'warn')">删除</text>
-					<text v-if="item.orderStatu == 1" @click="openQu(item.id,'warn')">取消订单</text>
-					<text v-if="item.orderStatu == 5" @click="openDel(item.id,'warn')">删除</text>
-					<!-- <text v-if="item.orderStatu == 2">取消订单</text> -->
-					<!-- <text v-if="item.orderStatu == 3" @click="navigateToXuzhu">续住</text> -->
+				<uv-count-down v-if="item.orderStatus == 1" class="room-count" color="#FF5733" :time="new Date(item.createTime).getTime() + 15 * 60 * 1000 - new Date().getTime()" format="mm:ss" @finish="finish(timeupSecond,item)"></uv-count-down>
+				<!-- <uni-countdown v-if="item.orderStatus == 1" class="room-count" color="#FF5733" :show-day="false" :second="timeupSecond" @timeup="timeup(item.createTime)" /> -->
+				<text v-if="item.orderStatus == 1" class="room-count-txt">之后取消</text>
+				<!--  v-if="item.orderStatus != 5 && item.orderStatus != 3 && item.orderStatus != 4" 无删除时-->
+				<view class="room-button" v-if="item.orderStatus == 1 || item.orderStatus == 3">
+					<!-- <text v-if="item.orderStatus == 9" @click="openDel(item.id,'warn')">删除</text> -->
+					<text v-if="item.orderStatus == 1" @click="openQu(item.orderNumber,item.houseNumberId,'warn')">取消订单</text>
+					<!-- <text v-if="item.orderStatus == 8" @click="openDel(item.id,'warn')">删除</text> -->
+					<text v-if="item.orderStatus == 3" @click="openQu(item.orderNumber,item.houseNumberId,'warn')">办理退款</text>
+					<!-- <text v-if="item.orderStatu == 4" @click="navigateToXuzhu">续住</text> -->
 				</view>
-				<view class="room-button2" :class="{'room-button3': item.orderStatu == 1 || item.orderStatu == 4}">
-					<text v-if="item.orderStatu == 0" @click="navigateToZaici(item.enableStartTime,item.enableEndTime,item.roomTypeId)">再次预定</text>
-					<text v-if="item.orderStatu == 1" @click="getOrderPay(item.id)">支付</text>
-					<text v-if="item.orderStatu == 4" @click="navigateToJiezhang(item.id)">去处理</text>
-					<text v-if="item.orderStatu == 5" @click="navigateToWanchengZaici(item.roomTypeId)">再次预定</text>
-					<text v-if="item.orderStatu == 2" @click="openRu(item.id,'warn')">办理入住</text>
-					<text v-if="item.orderStatu == 3" @click="openTui(item.id,'warn')">退房</text>
+				<view class="room-button2" :class="{'room-button3': item.orderStatus == 1 || item.orderStatus == 3}">
+					<text v-if="item.orderStatus == 9" @click="navigateToZaici(item.reserveLiveTime,item.reserveLeaveTime,item.id,item)">再次预定</text>
+					<text v-if="item.orderStatus == 1" @click="getOrderPay(item.id,item.price)">支付</text>
+					<text v-if="item.orderStatus == 5" @click="navigateToJiezhang(item.id)">去处理</text>
+					<text v-if="item.orderStatus == 8" @click="navigateToWanchengZaici(item.id,item)">再次预定</text>
+					<text v-if="item.orderStatus == 3" @click="openRu(item.id,'warn')">办理入住</text>
+					<text v-if="item.orderStatus == 4" @click="openTui(item.orderNumber,item.houseNumberId,'warn')">退房</text>
 					
 				</view>
 				<view class="room-line"  v-if="index<(troom.length-1)"></view>
@@ -141,7 +143,8 @@
 		getorderreturn,
 		getorderhold,
 		getorderdelete,
-		getordercancel
+		quxiaoorder,
+		getchapay
 	} from '../../utils/api_hotel.js'
 	export default {
 		data(){
@@ -167,10 +170,18 @@
 				order_txt2:'',//
 				tankuang:false,//弹框是否确定
 				order_txt_id:'',
+				houseNumberId:'',//房间id
 				curPage:1,
 				pageSize:10,
 				total: 0,
 				loadStatus: '',
+				
+				appId: "",     //公众号ID,由商户传入
+				timeStamp: "",     //时间戳,自1970年以来的秒数     
+				nonceStr: "",      //随机串     
+				package: "",
+				signType: "",     //微信签名方式:     
+				paySign:'',
 			}
 		},
 		filters:{
@@ -192,8 +203,10 @@
 			this.troom = room;//真实数据赋值给页面数据
 			this.changeTab(this.Inv)
 		},
+		
 		//下拉刷新
 		onPullDownRefresh() {
+			this.curPage = 1;
 			this.getOrderPage(this.Inv)
 			setTimeout(function () {
 				uni.stopPullDownRefresh();
@@ -245,48 +258,30 @@
 				  if (this.Inv==6) {
 					  Inv2=''
 				  }
-				  var data='?curPage='+this.curPage+"&pageSize="+this.pageSize+"&statu="+Inv2
+				  var data='?page='+this.curPage+"&size="+this.pageSize+"&status="+Inv2+"&userId="+localStorage.getItem('usersId')
 				  getorderpage(data).then((res) => {
 				  	if (res.success) {
-				  		res.data.list.forEach(data => {
-							_self.troom.push(data)
-							_self.room.push(data)
-				  		})
-				  		_self.total=res.data.totalCount
+						if (this.curPage == 1) {
+							_self.troom = res.data.records
+							_self.room = res.data.records
+						} else {
+							_self.troom = [..._self.troom, ...res.data.records]
+							_self.room = [..._self.room, ...res.data.records]
+						}
+						uni.stopPullDownRefresh();
+						uni.hideLoading()
+				  		_self.total=res.data.total
 				  		return;
 				  	} else {
-				  		this.$message.warning('没有符合条件的数据!')
+						uni.showModal({
+							content:"没有符合条件的数据!"
+						})
 				  	}
 				  }).catch((err) => {
-				  	this.$message.error(err.message)
+					  uni.showModal({
+					  	content:err.message
+					  })
 				  });
-				 //  this.$axios.get("/hotel/ihotel-api/ihotel/hotelOrder/user/order/page?curPage="+this.curPage+"&pageSize="+this.pageSize+"&statu="+Inv2,
-				 //  {
-					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
-					//   },
-				 //  }).then(res => {
-					// res = res.data
-					// if (res.success) {
-					// 	// console.log(res)
-					//   res.data.list.forEach(data => {
-					// 	_self.troom.push(data)
-					// 	_self.room.push(data)
-					//   })
-					//   _self.total=res.data.totalCount
-					// } else {
-					//   console.log('获取订单列表失败')
-					//  //  _self.troom = [
-					//  //  	{roomTypeName:'11',roomTypeMasterImg:'',id:'1',enableStartTime:'111111',enableEndTime:''},
-					// 	// {roomTypeName:'11',roomTypeMasterImg:'',id:'1',enableStartTime:'111111',enableEndTime:''},
-					// 	// {roomTypeName:'11',roomTypeMasterImg:'',id:'1',enableStartTime:'111111',enableEndTime:''},
-					// 	// {roomTypeName:'11',roomTypeMasterImg:'',id:'1',enableStartTime:'111111',enableEndTime:''},
-					// 	// {roomTypeName:'11',roomTypeMasterImg:'',id:'1',enableStartTime:'111111',enableEndTime:''},
-					// 	// {roomTypeName:'11',roomTypeMasterImg:'',id:'1',enableStartTime:'111111',enableEndTime:''},
-					// 	// {roomTypeName:'11',roomTypeMasterImg:'',id:'2',enableStartTime:'111111',enableEndTime:''},
-					//  //  ]
-					// }
-				 //  });
 			},
 			//待确认的弹框操作
 			dialogConfirm() {
@@ -296,11 +291,11 @@
 					if(this.order_txt2=='确定删除?') {
 						this.getOrderDelete(this.order_txt_id)
 					} else if(this.order_txt2=='确定退房?') {
-						this.getOrderReturn(this.order_txt_id)
+						this.getOrderReturn(this.order_txt_id,this.houseNumberId)
 					} else if(this.order_txt2=='确定入住?') {
 						this.getOrderHold(this.order_txt_id)
 					} else if(this.order_txt2=='确定取消订单?') {
-						this.getOrderCancel(this.order_txt_id)
+						this.getOrderCancel(this.order_txt_id,this.houseNumberId)
 					}
 				} 
 			},
@@ -315,8 +310,9 @@
 				this.$refs.popup_order2.open()
 			},
 			//退房弹框
-			openTui(id,type) {
-				this.order_txt_id=id
+			openTui(orderNumber,houseNumberId,type) {
+				this.order_txt_id=orderNumber
+				this.houseNumberId=houseNumberId
 				this.msgType2 = type
 				this.order_txt2='确定退房?'
 				this.$refs.popup_order2.open()
@@ -329,60 +325,106 @@
 				this.$refs.popup_order2.open()
 			},
 			//取消订单弹框
-			openQu(id,type) {
-				this.order_txt_id=id
+			openQu(orderNumber,houseNumberId,type) {
+				this.order_txt_id=orderNumber
+				this.houseNumberId=houseNumberId
 				this.msgType2 = type
 				this.order_txt2='确定取消订单?'
 				this.$refs.popup_order2.open()
 			},
 			// 支付订单
-			getOrderPay(id) {
+			getOrderPay(id,price) {
+				if(localStorage.getItem('code')=='undefined'){
+					uni.navigateTo({
+						url:'/pages/huoquCode/huoquCode'
+					})
+					return
+				}
 				  let _self = this
-				  var data=id
+				  var data={
+						"houseOrderId": id, //订单号id
+						"usersId": localStorage.getItem('usersId'), //用户id 
+						"totalPrice": price //支付金额
+					}
 				  getorderpay(data).then((res) => {
 				  	if (res.success) {
-				  		if(res.data.payAmount==0) {
-				  			uni.navigateTo({
-				  				url: '../zhifuchenggong/zhifuchenggong?orderId='+res.data.orderId
-				  			})
-				  		} else {
-				  			window.location.href = res.data.payUrl;
-				  		}
-				  		return;
-				  	} else {
-						this.order_txt=res.message
-						this.$refs.popup_order.open()
-					}
+				  		_self.appId=res.data.appId
+				  		_self.timeStamp=res.data.timeStamp
+				  		_self.nonceStr=res.data.nonceStr
+				  		_self.package=res.data.packageVal
+				  		_self.signType=res.data.signType
+				  		_self.paySign=res.data.paySign
+				  		_self.onBridgeReady();
+				  	} else if(res.code=='500'){
+						uni.navigateTo({
+							url:'/pages/huoquCode/huoquCode'
+						})
+				  	}
 				  }).catch((err) => {
-				  	this.$message.error(err.message)
+				  	uni.navigateTo({
+				  		url:'/pages/huoquCode/huoquCode'
+				  	})
 				  });
-				 //  this.$axios.get(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/pay/${id}`,
-				 //  {
-					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
-					//   }
-				 //  }).then(res => {
-					// res = res.data
-					// if (res.success) {
-					// 	if(res.data.payAmount==0) {
-					// 		uni.navigateTo({
-					// 			url: '../zhifuchenggong/zhifuchenggong?orderId='+res.data.orderId
-					// 		})
-					// 	} else {
-					// 		window.location.href = res.data.payUrl;
-					// 	}
+			},
+			onBridgeReady() {
+			    WeixinJSBridge.invoke('getBrandWCPayRequest', {
+			        "appId": this.appId,     //公众号ID,由商户传入     
+			        "timeStamp": this.timeStamp,     //时间戳,自1970年以来的秒数     
+			        "nonceStr": this.nonceStr,      //随机串     
+			        "package": this.package,
+			        "signType": this.signType,     //微信签名方式:     
+			        "paySign": this.paySign //微信签名 
+			    },
+			    function(res) {
+			        if (res.err_msg == "get_brand_wcpay_request:ok") {
+			        	uni.navigateTo({
+			        		url:'/pages/my_orderlist/my_orderlist?Inv=3'
+			        	})
+			            // 使用以上方式判断前端返回,微信团队郑重提示:
+			            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+			        }else{
+			        	this.chapayIf()
+			        }
+			    });
+			},
+			//查询是否支付成功
+			chapayIf(){
+				var data={
+					"outTradeNo": this.orderNumber,//订单号id
+				}
+				getchapay(data).then((res) => {
+					if (res.success) {
+						if(res.data.tradeState=="SUCCESS"){
+							uni.showModal({
+								content:'支付成功',
+								success: (res) => {
+									uni.switchTab({
+										url:'pages/my_orderlist/my_orderlist?Inv=3'
+									})
+								},
+							})
+						}else{
+							uni.showModal({
+								content:res.data.tradeStateDesc
+							})
+						}
 						
-					// } else {
-					// 	this.order_txt=res.message
-					// 	this.$refs.popup_order.open()
-					// 	console.log('支付失败')
-					// }
-				 //  });
+						// return;
+					} else {
+					}
+				}).catch((err) => {
+					uni.showModal({
+						content:err.message
+					})
+				});
 			},
 			// 办理退房
-			getOrderReturn(order_txt_id) {
+			getOrderReturn(order_txt_id,houseNumberId) {
 				let _self = this
-				var data=order_txt_id
+				var data={
+					"orderNumber": order_txt_id,//订单号
+					"houseNumberId": houseNumberId//房间号id
+				}
 				getorderreturn(data).then((res) => {
 					if (res.success) {
 						this.order_txt='退房成功'
@@ -394,9 +436,11 @@
 						this.$refs.popup_order.open()
 					}
 				}).catch((err) => {
-					this.$message.error(err.message)
+					uni.showModal({
+						content:err.message
+					})
 				});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
 				// this.$axios.put(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/return/${this.order_txt_id}`,).then(res => {
 				// 	res = res.data
 				// 	if (res.success) {
@@ -414,7 +458,7 @@
 			// 办理入住
 			getOrderHold(order_txt_id) {
 				let _self = this
-				var data=order_txt_id
+				var data="?houseOrderId="+order_txt_id+"&userId="+localStorage.getItem('usersId')
 				getorderhold(data).then((res) => {
 					if (res.success) {
 						this.order_txt='办理入住成功'
@@ -426,9 +470,11 @@
 						this.$refs.popup_order.open()
 					}
 				}).catch((err) => {
-					this.$message.error(err.message)
+					uni.showModal({
+						content:err.message
+					})
 				});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
 				// this.$axios.put(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/hold/${this.order_txt_id}`,).then(res => {
 				// 	res = res.data
 				// 	if (res.success) {
@@ -458,7 +504,7 @@
 				}).catch((err) => {
 					this.$message.error(err.message)
 				});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
 				// this.$axios.delete(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/${this.order_txt_id}`,).then(res => {
 				// 	res = res.data
 				// 	if (res.success) {
@@ -473,12 +519,19 @@
 				this.tankuang==false
 			},
 			// 待支付取消订单
-			getOrderCancel(order_txt_id) {
+			getOrderCancel(order_txt_id,houseNumberId) {
 				let _self = this
-				var data=order_txt_id
-				getordercancel(data).then((res) => {
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['user_head'] = localStorage.getItem('user_head');
+				// this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"usersId": localStorage.getItem('usersId'),
+					"orderNumber": order_txt_id, //订单号
+					"houseNumberId": houseNumberId, //房间号id
+				}
+				quxiaoorder(data).then((res) => {
 					if (res.success) {
-						this.order_txt='取消成功'
+						this.order_txt='订单已取消'
 						this.$refs.popup_order.open()
 						this.getOrderPage()
 						return;
@@ -487,31 +540,24 @@
 						this.$refs.popup_order.open()
 					}
 				}).catch((err) => {
-					this.$message.error(err.message)
+					uni.showModal({
+						content:err.message
+					})
 				});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
-				// this.$axios.put(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/cancel/${this.order_txt_id}`,).then(res => {
-				// 	res = res.data
-				// 	if (res.success) {
-				// 		this.order_txt='取消成功'
-				// 		this.$refs.popup_order.open()
-				// 		this.getOrderPage()
-				// 	} else {
-				// 		this.order_txt=res.message
-				// 		this.$refs.popup_order.open()
-				// 	}
-				// });
 			},
 			// 订单取消再次预订
-			navigateToZaici(enableStartTime,enableEndTime,roomTypeId){
-				uni.navigateTo({
-					url:"../order_room/order_room?enableStartTime="+enableStartTime+"&enableEndTime="+enableEndTime+"&startTime="+enableStartTime.substring(5,7)+'月'+enableStartTime.substring(8,10)+'日'+"&endTime="+enableEndTime.substring(5,7)+'月'+enableEndTime.substring(8,10)+'日'+"&roomTypeId="+roomTypeId
+			navigateToZaici(enableStartTime,enableEndTime,roomTypeId,item){
+				uni.reLaunch({
+					url:"../index/index"
+					// url: "../order_room/order_room?roomTypeId="+roomTypeId +"&enableStartTime="+enableStartTime+"&enableEndTime="+enableEndTime+"&startTime="+enableStartTime.substring(5,7)+'月'+enableStartTime.substring(8,10)+'日'+"&endTime="+enableEndTime.substring(5,7)+'月'+enableEndTime.substring(8,10)+'日'+"&typeName="+item.roomName+"&roomArea="+item.roomArea+"&roomType="+item.roomType+"&roomConfiguration="+item.roomConfiguration+"&roomPrice="+item.roomPrice+'&surplusCount='+item.surplusCount,
+					// url:"../order_room/order_room?enableStartTime="+enableStartTime+"&enableEndTime="+enableEndTime+"&startTime="+enableStartTime.substring(5,7)+'月'+enableStartTime.substring(8,10)+'日'+"&endTime="+enableEndTime.substring(5,7)+'月'+enableEndTime.substring(8,10)+'日'+"&roomTypeId="+roomTypeId
 				})
 			},
 			// 订单已完成再次预订
 			navigateToWanchengZaici(roomTypeId){
-				uni.navigateTo({
-					url:'../order_room/order_room?roomTypeId='+roomTypeId
+				uni.reLaunch({
+					url:"../index/index"
+					// url:'../order_room/order_room?roomTypeId='+roomTypeId
 				})
 			},
 			//处理结账
@@ -530,7 +576,7 @@
 				var arr = [];
 				this.getOrderPage(this.Inv)
 				that.room.map(item => {//遍历真实数据,拿到所需要的数据放在页面数据tlist中,展示在页面上
-					if(item.orderStatu == this.Inv){
+					if(item.orderStatus == this.Inv){
 						arr.push(item);
 					}
 				})
@@ -544,40 +590,10 @@
 					scrollTop: 0 //滚动到实际距离是元素距离顶部的距离减去最外层盒子的滚动距离(如res.top - data.top)
 				})
 			},
-			// 倒计时
-			timeup(createTime) {
-				    var that = this;
-				    /**setInterval间歇调用 */
-				    that.timer = setInterval(function () {
-					//订单下单时间
-					var buy_time = createTime;
-					//计算剩余下单时间
-					var time = (new Date(buy_time).getTime() + 10* 60 * 1000) - (new Date().getTime());
-					if(time>0){
-					  //计算剩余的分钟
-					  var minutes = parseInt(time / 1000 / 60 % 60, 10);
-					  //计算剩余的秒数
-					  var seconds = parseInt(time / 1000 % 60, 10);
-					  that.timeupSecond=parseInt(time / 1000);
-					  // console.log(that.timeupSecond)
-					  //判断分钟和秒数小于10要在前面加个0.
-					  if(minutes<10){
-						minutes = '0' + minutes;
-					  }
-					  if (seconds < 10) {
-						seconds = '0' + seconds;
-					  }
-					  var timer = minutes + ":" + seconds;
-					}
-				}, 1000);
-				if(that.timeupSecond==0) {
-					uni.showToast({
-						title: '时间到'
-					})
-					this.getOrderPage()
-				}
-				
-				// this.timeupSecond = 0
+			// 倒计时结束回调
+			finish(timeupSecond,item) {
+				// this.countDownTime = new Date(item.createTime).getTime() + 15 * 60 * 1000 - new Date().getTime()
+				this.getOrderCancel(item.orderNumber,item.houseNumberId)
 			},
 			// 跳转到订单详情
 			navigateToOrderMark(id) {

+ 10 - 9
pages/myself/css/myself.css

@@ -13,7 +13,7 @@
 	background-size: 100%;
 }
 .person_touxiang{
-	position: absolute;
+	/* position: absolute; */
 	margin-left: 30rpx;
 	margin-top: 40rpx;
 	width: 142rpx;
@@ -24,28 +24,29 @@
 	position: absolute;
 	margin-left: 22rpx;
 	margin-top: 50rpx;
-	color: rgba(0, 0, 0, 1);
-	font-size: 36rpx;
+	color: rgba(255, 255, 255, 1);
+	font-size: 40rpx;
 	font-weight: 600;
 }
 .person_identity{
 	position: absolute;
 	margin-left: 14rpx;
-	width: 91rpx;
-	height: 38rpx;
-	background: rgba(41, 109, 227, 1);
+	margin-top: 160rpx;
+	width: 179rpx;
+	height: 42rpx;
+	background: rgba(255, 255, 255, 0.2);
 	border-radius: 145rpx;
 	color: rgba(255, 255, 255, 1);
-	font-size: 20rpx;
+	font-size: 24rpx;
 	font-weight: 400;
-	line-height: 38rpx;
+	line-height: 42rpx;
 	text-align: center;
 }
 .person_phone{
 	position: absolute;
 	margin-left: 22rpx;
 	margin-top: 98rpx;
-	color: rgba(128, 128, 128, 1);
+	color: rgba(255, 255, 255, 0.5);
 	font-size: 24rpx;
 	font-weight: 400;
 }

+ 75 - 52
pages/myself/myself.vue

@@ -1,17 +1,17 @@
 <template>
 	<view class="content">
 		<view class="person">
-			<image class="person_touxiang" v-if="touxiang==''" src="../../static/my/touxiang.png"></image>
+			<image class="person_touxiang" v-if="touxiang=='' || touxiang==null" src="../../static/my/touxiang.png"></image>
 			<image class="person_touxiang" v-else :src="touxiang"></image>
-			<text class="person_name">{{cardName}}
-				<text class="person_identity">
-					<text v-if="cardIdentity==0">其他</text>
-					<text v-if="cardIdentity==1">学生</text>
-					<text v-if="cardIdentity==4">教职工</text>
-					<text v-if="cardIdentity==5">校友</text>
-				</text>
-			</text>
+			<text class="person_name">{{cardName}}</text>
 			<text class="person_phone">{{cardNum}}</text>
+			<text class="person_identity">
+				<text v-if="cardIdentity=='0'">其他</text>
+				<text v-if="cardIdentity=='1'">学生</text>
+				<text v-if="cardIdentity=='4'">教职工</text>
+				<text v-if="cardIdentity=='5'">校友</text>
+				<text v-if="cardIdentity=='7'">临时人员</text>
+			</text>
 		</view>
 		<!-- 第二部分,我的订单 -->
 		<view class="my_order">
@@ -54,10 +54,20 @@
 			    <image src="../../static/my/person_phone.svg" class="img-btn"></image>
 			    <text class="list-txt">人工热线</text>
 			  </view>
-			  <view class="item-list-one" @click="navigateToLiucheng">
+			   <!-- -->
+			  <view class="item-list-one" @click="navigateToLiucheng" v-if="cardIdentity=='7'">
 			    <image src="../../static/my/liucheng.png" class="img-btn"></image>
 			    <text class="list-txt">流程管理</text>
 			  </view>
+			   <!-- v-if="cardIdentity=='4'" -->
+			  <view class="item-list-one" @click="navigateToLiucheng2">
+			    <image src="../../static/my/liucheng.png" class="img-btn"></image>
+			    <text class="list-txt">教师流程</text>
+			  </view>
+			  <view class="item-list-one" @click="navigateToLiucheng3" v-if="manager=='1'">
+			    <image src="../../static/my/liucheng.png" class="img-btn"></image>
+			    <text class="list-txt">管理员流程</text>
+			  </view>
 			</view>
 		</view>
 	</view>
@@ -71,32 +81,51 @@
 		data() {
 			return {
 				phone:'0791-82293574',//客服热线电话
-				cardName:'',//用户名
-				cardIdentity:'',//身份
-				cardNum:'',//卡号
-				touxiang:'',
+				cardName:localStorage.getItem('name'),//用户名
+				cardIdentity:localStorage.getItem('department'),//身份
+				cardNum:localStorage.getItem('telephone'),//卡号
+				touxiang:localStorage.getItem('user_head'),
+				manager:localStorage.getItem('manager'),//1管理员,0不是管理员
 			}
 		},
 		onLoad() {
-			this.getUserInfo()
+		},
+		onShow() {
+			// this.getUserInfo()
 		},
 		mounted() {
-			// window.location.href ='https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxa46ef222053a1047&redirect_uri=https://chtech.ncjti.edu.cn/hotel/ihotel-api/ihotel/hotelUser/weixinAuth&response_type=code&scope=snsapi_base&state=pages/index/index#wechat_redirect';
 		},
 		methods: {
+			// 授权获取code
+						handleAuthCode() {
+							alert('aaa')
+							let authCode = this.handleUrlCode().code(); // 截取页面code
+							let appId = 'wxd87cbe1db0437303'; // 微信公众号的AppId
+							let scope = 'snsapi_userinfo' // 授权
+							let redirectUri = 'https%3A%2F%2Fchtech.ncjti.edu.cn%2Fhotel%2Fh5%2F%23%2Fpages%2Fmyself%2Fmyself';//回调地址
+							let path = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + appId +
+								'&redirect_uri=' + redirectUri  + '&response_type=code&scope=' + scope +
+								'&state=STATE#wechat_redirect';
+							if (authCode == null || authCode == '' || authCode == undefined) {
+								alert('a')
+								window.location.href = path;
+							} else {
+								alert('b')
+								// this.handleOpenId(authCode);
+							}
+						},
+						
+						
 			// 获取用户信息
 			getUserInfo() {
-				  let _self = this
-				  getuserinfo().then((res) => {
+				let _self = this
+				var data="?userId="+localStorage.getItem('usersId')
+				getuserinfo(data).then((res) => {
 					if (res.success) {
-						if (res.data.statu == '1') {
-						  _self.cardName=res.data.name
-						  _self.cardIdentity=res.data.identityType
-						  _self.cardNum=res.data.telPhone
-						  _self.touxiang=res.data.headImage
-						}else {
-							alert('您没有权限,请联系客服')
-						}
+						_self.cardName=res.data.userName
+						_self.cardNum=res.data.phone
+						_self.cardIdentity=res.data.idCardInformation
+						_self.touxiang=res.data.headImage
 						return;
 					} else {
 						console.log('获取用户信息失败')
@@ -104,26 +133,6 @@
 				}).catch((err) => {
 					this.$message.error(err.message)
 				});
-				 //  this.$axios.get("/hotel/ihotel-api/ihotel/hotelUser/userInfo",
-				 //  {
-					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
-					//   }
-				 //  }).then(res => {
-					// res = res.data
-					// if (res.success) {
-					// 	if (res.data.statu == '1') {
-					// 	  _self.cardName=res.data.name
-					// 	  _self.cardIdentity=res.data.identityType
-					// 	  _self.cardNum=res.data.telPhone
-					// 	  _self.touxiang=res.data.headImage
-					// 	}else {
-					// 		alert('您没有权限,请联系客服')
-					// 	}
-					// } else {
-					//   console.log('获取用户信息失败')
-					// }
-				 //  });
 			},
 			//跳转到全部订单
 			navigateToAll(){
@@ -140,40 +149,54 @@
 			//跳转到待入住订单
 			navigateToDairuzhu(){
 				uni.navigateTo({ 
-					url: "../my_orderlist/my_orderlist?Inv=2"
+					url: "../my_orderlist/my_orderlist?Inv=3"
 				})
 			},
 			//跳转到已入住订单
 			navigateToYiruzhu(){
 				uni.navigateTo({ 
-					url: "../my_orderlist/my_orderlist?Inv=3"
+					url: "../my_orderlist/my_orderlist?Inv=4"
 				})
 			},
 			//跳转到已取消订单
 			navigateToYiquxiao(){
 				uni.navigateTo({ 
-					url: "../my_orderlist/my_orderlist?Inv=0"
+					url: "../my_orderlist/my_orderlist?Inv=9"
 				})
 			},
 			//跳转到待结账订单
 			navigateToDaijiezhang(){
 				uni.navigateTo({ 
-					url: "../my_orderlist/my_orderlist?Inv=4"
+					url: "../my_orderlist/my_orderlist?Inv=5"
 				})
 			},
 			//跳转到已完成订单
 			navigateToYiwancheng(){
 				uni.navigateTo({ 
-					url: "../my_orderlist/my_orderlist?Inv=5"
+					url: "../my_orderlist/my_orderlist?Inv=8"
 				})
 			},
 			//拨打人工热线
 			telphone(phone){
 				uni.makePhoneCall({ phoneNumber: phone }) // 传参带入号码即可
 			},
-			//跳转到流程管理
+			//跳转到临时人员流程管理
 			navigateToLiucheng(){
 				uni.navigateTo({
+					url: "../liuchengO/liu_other"
+				})
+			},
+			//跳转到流程管理
+			navigateToLiucheng2(){
+				uni.navigateTo({
+					url: "../liuchengTeacher/liu_teach"
+					// url: "../liuchengO/liu_other"
+					// url:"../liuchengManger/liu_manage"
+				})
+			},
+			//跳转到流程管理
+			navigateToLiucheng3(){
+				uni.navigateTo({
 					// url: "../liuchengTeacher/liu_teach"
 					// url: "../liuchengO/liu_other"
 					url:"../liuchengManger/liu_manage"

+ 172 - 110
pages/order_mark/order_mark.vue

@@ -1,17 +1,17 @@
 <template>
 	<view class="content">
 		<!-- 第一层模块 -->
-		<view class="one-order3" v-if="orderList.orderStatu == 5">
-			<view class="one-order-title">订单已完成 / 期待您再次光临<text class="all-price">¥{{orderList.shouldFree}}</text></view>
+		<view class="one-order3" v-if="orderList.houseOrder.orderStatus == 8">
+			<view class="one-order-title">订单已完成 / 期待您再次光临<text class="all-price">¥{{orderList.houseOrder.payPrice}}</text></view>
 			<view class="one-order-menshi">水电扣除<text class="menshi-price">¥{{orderList.totalFree}}</text></view>
-			<view class="room-button-6"@click="getOrderDelete(orderList.orderId)">
+			<!-- <view class="room-button-6"@click="getOrderDelete(orderList.houseOrder.orderNumber)">
 				<text>删除订单</text>
-			</view>
-			<view class="room-button2-6" @click="navigateToWanchengZaici(orderList.roomTypeId)">
+			</view> -->
+			<view class="room-button2-6" @click="navigateToWanchengZaici(orderList.houseOrder.houseId)">
 				<text>再次预定</text>
 			</view>
 		</view>
-		<view class="one-order3" v-else-if="orderList.orderStatu == 4">
+		<view class="one-order3" v-else-if="orderList.houseOrder.orderStatus == 5">
 			<view class="one-order-title">待结账</view>
 			<view class="one-order-menshi" v-if="billXin.flag==1">
 				预退款<text class="menshi-price">¥{{billXin.refundFee}}</text>
@@ -19,9 +19,9 @@
 			<view class="one-order-menshi" v-if="billXin.flag==2">
 				预补缴<text class="menshi-price">¥{{billXin.supperFee}}</text>
 			</view>
-			<view class="room-button-6">
+			<!-- <view class="room-button-6">
 				<text>删除订单</text>
-			</view>
+			</view> -->
 			<view class="room-button2-6" v-if="billXin.flag==1">
 				<text>退款</text>
 			</view>
@@ -31,49 +31,54 @@
 		</view>
 		<view class="one-order" v-else>
 			<view class="one-order-title">
-				<text v-if="orderList.orderStatu == 0">订单已取消 / 期待您再次光临</text>
-				<text v-if="orderList.orderStatu == 1">请在10分钟之内支付</text>
-				<text v-if="orderList.orderStatu == 2">预定成功 / 等待您的入住</text>
-				<text v-if="orderList.orderStatu == 3">办理成功 / 期待您的到来</text>
-				<text class="all-price">¥{{orderList.payAmount}}</text>
+				<text v-if="orderList.houseOrder.orderStatus == 9">订单已取消 / 期待您再次光临</text>
+				<text v-if="orderList.houseOrder.orderStatus == 1">请在15分钟之内支付</text>
+				<text v-if="orderList.houseOrder.orderStatus == 3">预定成功 / 等待您的入住</text>
+				<text v-if="orderList.houseOrder.orderStatus == 4">办理成功 / 期待您的到来</text>
+				<text class="all-price">¥{{orderList.houseOrder.payPrice}}</text>
 			</view>
-			<view class="one-order-menshi">门市价<text class="menshi-price">¥{{orderList.roomTypeUsualPrice}}</text></view>
+			<!-- <view class="one-order-menshi">门市价<text class="menshi-price">¥{{orderList.roomTypeUsualPrice}}</text></view>
 			<view class="one-order-fuli">教师福利<text class="fuli-price">¥{{orderList.roomTypeDiscountPrice}}</text></view>
 			<view class="one-order-yufukuan">
 				预付款<text class="yufukuan-price">¥{{orderList.payAmount}}</text>
-			</view>
+			</view> -->
 			<!-- <view class="one-order-zhu">
 				注:水费为0.62元/吨,电费为1.1元/度;补助吨数为3吨,补助度
 				数为10度,超出标准需在预付款中扣除,未超出原路返回预
 				付款
 			</view> -->
-			<view class="room-button" v-if="orderList.orderStatu != 2&& orderList.orderStatu != 3">
-				<text v-if="orderList.orderStatu == 0" @click="navigateToZaici(orderList.enableStartTime,orderList.enableEndTime,orderList.roomTypeId)">再次预定</text>
-				<text v-if="orderList.orderStatu == 1" @click="openQu()(orderList.orderId,'warn')">取消订单</text>
-				<!-- <text v-if="orderList.orderStatu == 3">办理续住</text> -->
+			<view class="room-button" v-if="orderList.houseOrder.orderStatus != 4&&orderList.houseOrder.orderStatus != 9">
+				
+				<text v-if="orderList.houseOrder.orderStatus == 1" @click="openQu(orderList.houseOrder.orderNumber,'warn',orderList.houseOrder.houseNumberId)">取消订单</text>
+				<text v-if="orderList.houseOrder.orderStatus == 3" @click="openQu(orderList.houseOrder.orderNumber,'warn',orderList.houseOrder.houseNumberId)">办理退款</text>
 			</view>
-			<view class="room-button2" :class="{'buttonNo': orderList.orderStatu == 3 || orderList.orderStatu == 2}">
-				<text v-if="orderList.orderStatu == 0" @click="openDel(orderList.orderId,'warn')">删除</text>
-				<text v-if="orderList.orderStatu == 1" @click="getOrderPay(orderList.orderId)">支付</text>
-				<text v-if="orderList.orderStatu == 3" @click="openTui(orderList.orderId,'warn')">办理退房</text>
-				<text v-if="orderList.orderStatu == 2" @click="openRu(orderList.orderId,'warn')">办理入住</text>
+			<view class="room-button2" :class="{'buttonNo': orderList.houseOrder.orderStatus == 4}">
+				<text v-if="orderList.houseOrder.orderStatus == 9" @click="navigateToZaici(orderList.houseOrder.reserveLiveTime,orderList.houseOrder.reserveLeaveTime,orderList.houseOrder.houseId)">再次预定</text>
+				<!-- <text v-if="orderList.houseOrder.orderStatus == 9" @click="openDel(orderList.houseOrder.orderNumber,'warn',orderList.houseOrder.houseNumberId)">删除</text> -->
+				<text v-if="orderList.houseOrder.orderStatus == 1" @click="getOrderPay(orderList.houseOrder.id,orderList.houseOrder.price)">支付</text>
+				<text v-if="orderList.houseOrder.orderStatus == 4" @click="openTui(orderList.houseOrderid.orderNumber,'warn')">办理退房</text>
+				<text v-if="orderList.houseOrder.orderStatus == 3" @click="openRu(orderList.houseOrder.id,'warn')">办理入住</text>
 			</view>
 		</view>
 		<!-- 第二层模块 -->
-		<view class="two-order" :class="{'two-order3': orderList.orderStatu == 3,'two-order4': orderList.orderStatu == 5||orderList.orderStatu == 4}">
+		<view class="two-order" :class="{'two-order3': orderList.houseOrder.orderStatus == 4,'two-order4': orderList.houseOrder.orderStatus == 8||orderList.houseOrder.orderStatus == 5}">
 			<view class="two-order-title">订单信息</view>
-			<view class="two-order-name">预定信息:<text class="two-order-txt">{{orderList.userName}}</text></view>
-			<view class="two-order-phone">手机号码:<text class="two-order-txt">{{orderList.userPhone}}</text></view>
-			<view class="two-order-count">订  单  号:<text class="two-order-txt">{{orderList.orderId}}</text></view>
-			<view class="two-order-time">下单时间:<text class="two-order-txt">{{orderList.createTime}}</text></view>
-			<view class="two-order-xing">户         型:<text class="two-order-txt">{{orderList.roomNo}}</text></view>
-			<view class="two-order-zhuTime">入离时间:<text class="two-order-txt" v-if="orderList.enableStartTime,orderList.enableEndTime">入住日{{orderList.enableStartTime}}后   离店日{{orderList.enableEndTime}}前</text></view>
-			<view class="two-order-secret" v-if="orderList.orderStatu ==3">房间门锁密码:{{orderList.lockRealtimePassword}}</view>
-			<view class="two-order-shui" v-if="orderList.orderStatu == 5||orderList.orderStatu ==4||orderList.orderStatu ==3">水起码:{{orderList.startOfWater}}吨</view>
-			<view class="two-order-dian" v-if="orderList.orderStatu == 5||orderList.orderStatu ==4||orderList.orderStatu ==3">电起码:{{orderList.startOfElectric}}度</view>
-			<view class="two-order-shui2" v-if="orderList.orderStatu == 5||orderList.orderStatu == 4">水止码:{{orderList.endOfWater}}吨</view>
-			<view class="two-order-dian2" v-if="orderList.orderStatu == 5||orderList.orderStatu == 4">电止码:{{orderList.endOfElectric}}度</view>
-			<view class="two-order-lidian2" v-if="orderList.orderStatu == 5">退房时间:{{}}</view>
+			<view class="two-order-name">预定人信息:<text class="two-order-txt">{{orderList.houseOrder.reserveName}}</text></view>
+			<view class="two-order-phone">手机号码:<text class="two-order-txt">{{orderList.houseOrder.reservePhone}}</text></view>
+			<view class="two-order-count">订  单  号:<text class="two-order-txt">{{orderList.houseOrder.orderNumber}}</text></view>
+			<view class="two-order-time">下单时间:<text class="two-order-txt">{{orderList.houseOrder.createTime}}</text></view>
+			<view class="two-order-xing">户         型:<text class="two-order-txt">{{orderList.house.roomName}}</text></view>
+			<view class="two-order-zhuTime">入离时间:
+				<text class="two-order-txt" v-if="orderList.houseOrder.reserveLiveTime,orderList.houseOrder.reserveLeaveTime">
+				<view>入住日{{orderList.houseOrder.reserveLiveTime}}后   </view>
+				<view>离店日{{orderList.houseOrder.reserveLeaveTime}}前</view></text>
+			</view>
+			<view class="two-order-secret" v-if="orderList.houseOrder.orderStatus ==4">房间门锁密码:{{orderList.passWord}}</view>
+			<view class="two-order-shui" v-if="orderList.houseOrder.orderStatus == 8||orderList.houseOrder.orderStatus ==5||orderList.houseOrder.orderStatus ==4">水起码:{{orderList.startOfWater}}吨</view>
+			<view class="two-order-dian" v-if="orderList.houseOrder.orderStatus == 8||orderList.houseOrder.orderStatus ==5||orderList.houseOrder.orderStatus ==4">电起码:{{orderList.startOfElectric}}度</view>
+			<view class="two-order-shui2" v-if="orderList.houseOrder.orderStatus == 8||orderList.houseOrder.orderStatus == 5">水止码:{{orderList.endOfWater}}吨</view>
+			<view class="two-order-dian2" v-if="orderList.houseOrder.orderStatus == 8||orderList.houseOrder.orderStatus == 5">电止码:{{orderList.endOfElectric}}度</view>
+			<view class="two-order-lidian2" v-if="orderList.houseOrder.orderStatus == 8">退房时间:{{}}</view>
 		</view>
 		
 		<view class="order-mark">您的满意是我们最大的追求</view>
@@ -90,10 +95,11 @@
 
 <script>
 	import {
-		getorderxiang,
+		getorderdetail,
 		getorderbill,
-		getordercancel,
+		quxiaoorder,
 		getorderpay,
+		getchapay,
 		getorderdelete,
 		getorderhold,
 		getorderreturn
@@ -101,7 +107,7 @@
 	export default {
 		data(){
 			return {
-				orderList:'',//订单整体
+				orderList:{},//订单整体
 				orderId:'',//订单号
 				billXin:'',//结账信息
 				order_txt:'',//弹框提示信息
@@ -111,6 +117,14 @@
 				order_txt2:'',//
 				tankuang:false,//弹框是否确定
 				order_txt_id:'',
+				houseNumberId:'',
+				
+				appId: "",     //公众号ID,由商户传入
+				timeStamp: "",     //时间戳,自1970年以来的秒数     
+				nonceStr: "",      //随机串     
+				package: "",
+				signType: "",     //微信签名方式:     
+				paySign:'',
 			}
 		},
 		onShow() {
@@ -131,8 +145,8 @@
 			getOrderInfo() {
 				  let _self = this
 				  _self.orderList = []
-				  var data=_self.orderId
-				  getorderxiang(data).then((res) => {
+				  var data="?houseOrderId="+_self.orderId
+				  getorderdetail(data).then((res) => {
 					if (res.success) {
 						_self.orderList=res.data
 						return;
@@ -140,23 +154,10 @@
 							console.log('获取订单列表失败')
 						}
 					}).catch((err) => {
-						this.$message.error(err.message)
+						uni.showModal({
+							content:err.message
+						})
 					});
-				 //  this.$axios.get(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/${this.orderId}`,
-				 //  {
-					//   headers:{
-					//   		'user_token':localStorage.getItem('token')
-					//   }
-				 //  }
-				 //  ).then(res => {
-					// res = res.data
-					// if (res.success) {
-					// 	console.log(res)
-					// 	this.orderList=res.data
-					// } else {
-					//   console.log('获取订单列表失败')
-					// }
-				 //  });
 			},
 			//待确认的弹框操作
 			dialogConfirm() {
@@ -170,7 +171,7 @@
 					} else if(this.order_txt2=='确定入住?') {
 						this.getOrderHold(this.order_txt_id)
 					} else if(this.order_txt2=='确定取消订单?') {
-						this.getOrderCancel(this.order_txt_id)
+						this.getOrderCancel(this.order_txt_id,this.houseNumberId)
 					}
 				} 
 			},
@@ -199,8 +200,9 @@
 				this.$refs.popup_order2.open()
 			},
 			//取消订单弹框
-			openQu(orderId,type) {
+			openQu(orderId,type,houseNumberId) {
 				this.order_txt_id=orderId
+				this.houseNumberId=houseNumberId
 				this.msgType2 = type
 				this.order_txt2='确定取消订单?'
 				this.$refs.popup_order2.open()
@@ -224,7 +226,7 @@
 				 //  this.$axios.get(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/bill/${this.orderId}`,
 				 //  {
 					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
+					// 	  'token':localStorage.getItem('token')
 					//   }
 				 //  }).then(res => {
 					// res = res.data
@@ -241,65 +243,72 @@
 			},
 			// 订单取消再次预订
 			navigateToZaici(enableStartTime,enableEndTime,roomTypeId){
-				uni.navigateTo({
-					url:"../order_room/order_room?enableStartTime="+enableStartTime+"&enableEndTime="+enableEndTime+"&startTime="+enableStartTime.substring(5,7)+'月'+enableStartTime.substring(8,10)+'日'+"&endTime="+enableEndTime.substring(5,7)+'月'+enableEndTime.substring(8,10)+'日'+"&roomTypeId="+roomTypeId
+				uni.reLaunch({
+					url:"../index/index"
+					// url:'../order_room/order_room?roomTypeId='+roomTypeId
 				})
 			},
 			// 待支付取消订单
-			getOrderCancel(order_txt_id) {
+			getOrderCancel(order_txt_id,houseNumberId) {
 				let _self = this
-				var data=_self.order_txt_id
-				getordercancel(data).then((res) => {
+				var data={
+					"usersId": localStorage.getItem('usersId'),
+					"orderNumber": order_txt_id, //订单号
+					"houseNumberId": houseNumberId, //房间号id
+				}
+				quxiaoorder(data).then((res) => {
 					if (res.success) {
 						this.order_txt='取消成功'
 						this.$refs.popup_order.open()
 						this.getOrderInfo()
 						return;
-						} else {
-							this.order_txt=res.message
-							this.$refs.popup_order.open()
-						}
-					}).catch((err) => {
-						this.$message.error(err.message)
-					});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
-				// this.$axios.put(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/cancel/${this.order_txt_id}`,).then(res => {
-				// 	res = res.data
-				// 	if (res.success) {
-				// 		this.order_txt='取消成功'
-				// 		this.$refs.popup_order.open()
-				// 		this.getOrderInfo()
-				// 	} else {
-				// 		this.order_txt=res.message
-				// 		this.$refs.popup_order.open()
-				// 	}
-				// });
+					} else {
+						this.order_txt=res.message
+						this.$refs.popup_order.open()
+					}
+				}).catch((err) => {
+					uni.showModal({
+						content:err.message
+					})
+				});
 			},
 			// 支付订单
-			getOrderPay(orderId) {
+			getOrderPay(id,price) {
+				if(localStorage.getItem('code')=='undefined'){
+					uni.navigateTo({
+						url:'/pages/huoquCode/huoquCode'
+					})
+					return
+				}
 				  let _self = this
-				  getorderpay(orderId).then((res) => {
-					if (res.success) {
-						if(res.data.payAmount==0) {
-							uni.navigateTo({
-								url: '../zhifuchenggong/zhifuchenggong?orderId='+res.data.orderId
-							})
-						} else {
-							window.location.href = res.data.payUrl;
-						}
-						return;
-						} else {
-							this.order_txt=res.message
-							this.$refs.popup_order.open()
-							console.log('支付失败')
-						}
-					}).catch((err) => {
-						this.$message.error(err.message)
-					});
+				  var data={
+						"houseOrderId": id, //订单号id
+						"usersId": localStorage.getItem('usersId'), //用户id localStorage.getItem('usersId')
+						"totalPrice": price //支付金额
+					}
+				  getorderpay(data).then((res) => {
+				  	if (res.success) {
+				  		_self.appId=res.data.appId
+				  		_self.timeStamp=res.data.timeStamp
+				  		_self.nonceStr=res.data.nonceStr
+				  		_self.package=res.data.packageVal
+				  		_self.signType=res.data.signType
+				  		_self.paySign=res.data.paySign
+				  		_self.onBridgeReady();
+				  	} else if(res.code=='500'){
+				  		uni.navigateTo({
+				  			url:'/pages/huoquCode/huoquCode'
+				  		})
+				  	}
+				  }).catch((err) => {
+				  	uni.navigateTo({
+				  		url:'/pages/huoquCode/huoquCode'
+				  	})
+				  });
 				 //  this.$axios.get(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/pay/${orderId}`,
 				 //  {
 					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
+					// 	  'token':localStorage.getItem('token')
 					//   }
 				 //  }).then(res => {
 					// res = res.data
@@ -318,6 +327,58 @@
 					// }
 				 //  });
 			},
+			onBridgeReady() {
+			    WeixinJSBridge.invoke('getBrandWCPayRequest', {
+			        "appId": this.appId,     //公众号ID,由商户传入     
+			        "timeStamp": this.timeStamp,     //时间戳,自1970年以来的秒数     
+			        "nonceStr": this.nonceStr,      //随机串     
+			        "package": this.package,
+			        "signType": this.signType,     //微信签名方式:     
+			        "paySign": this.paySign //微信签名 
+			    },
+			    function(res) {
+			        if (res.err_msg == "get_brand_wcpay_request:ok") {
+			        	uni.navigateTo({
+			        		url:'/pages/my_orderlist/my_orderlist?Inv=3'
+			        	})
+			            // 使用以上方式判断前端返回,微信团队郑重提示:
+			            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+			        }else{
+			        	this.chapayIf()
+			        }
+			    });
+			},
+			//查询是否支付成功
+			chapayIf(){
+				var data={
+					"outTradeNo": this.orderNumber,//订单号id
+				}
+				getchapay(data).then((res) => {
+					if (res.success) {
+						if(res.data.tradeState=="SUCCESS"){
+							uni.showModal({
+								content:'支付成功',
+								success: (res) => {
+									uni.switchTab({
+										url:'pages/my_orderlist/my_orderlist?Inv=3'
+									})
+								},
+							})
+						}else{
+							uni.showModal({
+								content:res.data.tradeStateDesc
+							})
+						}
+						
+						// return;
+					} else {
+					}
+				}).catch((err) => {
+					uni.showModal({
+						content:err.message
+					})
+				});
+			},
 			// 删除订单
 			getOrderDelete(order_txt_id) {
 				let _self = this
@@ -334,7 +395,7 @@
 					}).catch((err) => {
 						this.$message.error(err.message)
 					});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
 				// this.$axios.delete(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/${this.order_txt_id}`,).then(res => {
 				// 	res = res.data
 				// 	if (res.success) {
@@ -349,8 +410,9 @@
 			},
 			// 订单已完成再次预订
 			navigateToWanchengZaici(roomTypeId){
-				uni.navigateTo({
-					url:'../order_room/order_room?roomTypeId='+roomTypeId
+				uni.reLaunch({
+					url:"../index/index"
+					// url:'../order_room/order_room?roomTypeId='+roomTypeId
 				})
 			},
 			// 办理入住
@@ -369,7 +431,7 @@
 					}).catch((err) => {
 						this.$message.error(err.message)
 					});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
 				// this.$axios.put(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/hold/${this.order_txt_id}`,).then(res => {
 				// 	res = res.data
 				// 	if (res.success) {
@@ -399,7 +461,7 @@
 					}).catch((err) => {
 						this.$message.error(err.message)
 					});
-				// this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
 				// this.$axios.put(`/hotel/ihotel-api/ihotel/hotelOrder/user/order/return/${this.order_txt_id}`,).then(res => {
 				// 	res = res.data
 				// 	if (res.success) {

+ 1 - 1
pages/order_room/css/order_room.css

@@ -268,7 +268,7 @@
 	width: 240px;
 	padding-left: 20rpx;
 	color: rgba(255, 87, 51, 1);
-	font-size: 24rpx;
+	font-size: 44rpx;
 	font-weight: 500;
 	text-align: center;
 	line-height: 126rpx;

+ 184 - 155
pages/order_room/order_room.vue

@@ -2,7 +2,7 @@
 	<view class="content">
 		<!-- 第一层表单 -->
 		<view class="two_all">
-			<view class="select-time" @click="openCalendar">
+			<view class="select-time" @click="openCalendar" v-if="roomType==1">
 				<view class="select-time-one">
 				  <text class="select-list-time">{{startTime}}
 					<text class="select-list">{{startWeek}}</text>
@@ -19,13 +19,26 @@
 				  </text>
 				</view>
 			</view>
+			<view class="select-time" v-if="roomType==2">
+				<view class="select-time-one">
+				  <text class="select-list-time">{{startTime}}
+					<text class="select-list">{{startWeek}}</text>
+				  </text>
+				</view>
+				<view class="select-time-one">
+				  <text class="select-list-time" style="font-size: 12px;">{{zhongTime}}
+				  <text class="select-list">{{zhongshi}}小时</text>
+				  </text>
+				</view>
+			</view>
 			<!-- 房型信息 -->
-			<view class="select_name">大床房</view>
-			<view class="select_type">包吃住型</view>
+			<view class="select_name">{{typeName}}</view>
+			<view class="select_type" v-if="roomType==1">全日房</view>
+			<view class="select_type" v-else-if="roomType==2">钟点房</view>
 			<view class="select_detail">
-				16-20㎡
-				<text style="margin-left: 20px;">双人床</text>
-				<text style="margin-left: 20px;">窗户位于走廊/窗户较小</text>
+				{{roomArea}}
+				<text style="margin-left: 20px;">{{roomConfiguration}}</text>
+				<!-- <text style="margin-left: 20px;">窗户位于走廊/窗户较小</text> -->
 			</view>
 			<uni-popup ref="popup_picker" :mask-click="true">
 				<view class=popup_bg_picker>
@@ -47,41 +60,52 @@
 			<view class="form-phone">联系电话:
 			<text class="list-text">{{cardPhone}}</text></view>
 			<view class="form-line" style="margin-top: 381rpx;"></view>
-			<view class="uni-list-cell-db">预计到店:
+			<view class="uni-list-cell-db" v-if="roomType==1">预计到店:
 				<picker style="margin-left: 70px;margin-top: -22px;"
 				 @change="bindPickerChange" :value="index" :range="array">
 					<view class="uni-input" style="color: rgba(0, 0, 0, 1);">{{array[index]}}</view>
 					<text class="jiantou">〉</text>
 				</picker>
 			</view>
+			<view class="uni-list-cell-db" v-if="roomType==2">入住时段:
+				<picker style="margin-left: 70px;margin-top: -22px;"
+				 @change="bindPickerChange2" :value="index2" :range="array2">
+					<view class="uni-input" style="color: rgba(0, 0, 0, 1);">{{array2[index2]}}</view>
+					<text class="jiantou">〉</text>
+				</picker>
+			</view>
 		</view>
 		<!-- 第三层表单 -->
 		<view class="third_basic">
 			<view class="third_title">费用明细</view>
 			<view class="third-line1"></view>
 			<view class="third-num">在线支付:
-				<text class="third-text">1间1晚</text>
+				<text class="third-text">
+					1间
+					<template v-if="roomType==1">{{ruzhu_num}}晚</template>
+				</text>
 				<text style="margin-left: 10rpx;">共
-					<text class="third-text2">¥280.00</text>
+					<text class="third-text2">¥{{payMount}}</text>
 				</text>
 			</view>
 		</view>
 		<!-- 第四层房费 -->
 		<view class="four_basic">
 			<view class="four_title">房费
-				<text style="margin-left: 533rpx;">¥280</text>
+				<text style="margin-left: 533rpx;">¥{{payMount}}</text>
 			</view>
 			<view class="four-line1"></view>
-			<view class="four-num">2023-08-01</view>
-			<view class="four-num2">2023-08-02</view>
-			<view class="four-all">1 x ¥280</view>
+			<view class="four-num">{{startDate}}</view>
+			<view class="four-num2">{{endDate}}</view>
+			<view class="four-all">{{ruzhu_num}} x ¥{{roomPrice}}</view>
 		</view>
 		<!-- 支付框 -->
 		<view class="fukuan">
 			<view class="fu-price">¥{{payMount}}</view>
 			<view class="fu-zhifu" :class="{'room-button2': freeRoom == 0}">
-				<text v-if="freeRoom==0">房间已满</text>
-				<text v-else @click="getOrderSubmit('warn')">立即支付</text>
+				<!-- <text v-if="freeRoom==0">房间已满</text> -->
+				<!--  v-else<text v-else @click="getOrderSubmit('warn')">立即支付</text> -->
+				<text @click="postOrder('warn')">立即支付</text>
 			</view>
 		</view>
 		<!-- 提交订单时弹框 -->
@@ -95,10 +119,10 @@
 
 <script>
 	import {
-		getsubmittoken,
-		getorderconfirm,
 		getuserinfo,
-		getsubmit
+		getprice,
+		postOrder,
+		getZhongTime
 	} from '../../utils/api_hotel.js'
 	/**
 	 * 获取任意时间
@@ -156,33 +180,50 @@
 				endWeek:'',// 默认离店
 				array: ['18:00前到店', '19:00前到店', '20:00前到店', '21:00前到店'],
 				index: 0,
+				
+				array2: [''],//钟点房
+				index2: 0,
 				mayTime:'',// 预计到店时间
 				typeName:'',//户型名
 				textNum:0,//输入框当前字数
 				cardName:'',//用户名
 				cardPhone:'',//用户电话
 				cardIdentity:'',//身份
-				submitToken:'',//请求令牌
 				roomTypeId:'',//房间类型id
 				remark:'',//备注要求
 				payMount:0,//应付金额
-				freeRoom:0,//剩余房间
+				freeRoom:0,//剩余房间可预订的房间数
 				ruzhu_num:1,//入住夜晚
+				roomArea:'0',//房间面积
+				roomType:1,//房间类型
+				roomPrice:"",//房间单价
+				roomConfiguration:'',//房间配置
 				order_txt:'',//提交订单时信息
 				msgType:'warn',
+				zhongTime:'',//钟点房订的时间段
+				zhongshi:'',//钟点房时间
+				startDateZ:'',//钟点房默认到店日期接口数据
+				endDateZ:'',//钟点房默认离店日期接口数据
 			}
 		},
 		onLoad(option) {
 			console.log(option)
 			// this.payMount=Number(option.payMount)
-			// this.ruzhu_num=option.ruzhu_num
-			// this.freeRoom=option.freeRoom
+			this.ruzhu_num=option.ruzhu_num
+			this.roomArea=option.roomArea
+			this.roomType=option.roomType
+			this.roomConfiguration=option.roomConfiguration
+			this.roomPrice=option.roomPrice
+			this.freeRoom=option.surplusCount
+			this.zhongTime=option.zhongTime
+			this.zhongshi=option.zhongshi
 			localStorage.setItem('roomTypeId',option.roomTypeId)
 			localStorage.setItem('typeName',option.typeName)
 			localStorage.setItem('startTime',option.startTime)
 			localStorage.setItem('endTime',option.endTime)
 			localStorage.setItem('enableStartTime',option.enableStartTime)
 			localStorage.setItem('enableEndTime',option.enableEndTime)
+			localStorage.setItem('zhongTime',option.zhongTime)
 			
 		},
 		mounted() {
@@ -190,16 +231,17 @@
 			this.typeName=localStorage.getItem('typeName')
 			this.startTime=localStorage.getItem('startTime')
 			this.endTime=localStorage.getItem('endTime')
-			this.startDate=localStorage.getItem('enableStartTime').substring(0,11)+"12:00:00"
-			this.endDate=localStorage.getItem('enableEndTime').substring(0,11)+"14:00:00"
+			this.zhongTime=localStorage.getItem('zhongTime')
+			this.startDate=localStorage.getItem('enableStartTime')
+			this.endDate=localStorage.getItem('enableEndTime')
+			
 			this.startWeek=this.getweekday(this.startDate)
 			this.endWeek=this.getweekday(this.endDate)
 			this.mayTime=this.startDate.substring(0,11)+"18:00:00"
 			// console.log(this.getweekday(this.startDate))
-			this.getTokenSubmit()
+			this.getZhongTime()
 			// window.location.href ='https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxa46ef222053a1047&redirect_uri=https://chtech.ncjti.edu.cn/hotel/ihotel-api/ihotel/hotelUser/weixinAuth&response_type=code&scope=snsapi_base&state=pages/order_room/order_room#wechat_redirect';
 			this.getUserInfo()
-			this.getOrderConfirm('warn')
 		},
 		onReady() {
 			this.$nextTick(() => {
@@ -210,137 +252,138 @@
 				this.info.date = getDate(new Date()).fullDate
 				this.info.startDate = getDate(new Date()).fullDate
 				this.info.endDate =  getDate(new Date(),6).fullDate
-				this.startTime = getDate(new Date()).fullTime
-				this.endTime = getDate(new Date(),1).fullTime
-				this.startWeek = getDate(new Date()).sWeek
-				this.endWeek = getDate(new Date(),1).eWeek
-				this.ruzhu_num=1
+				// this.startTime = getDate(new Date()).fullTime
+				// this.endTime = getDate(new Date(),1).fullTime
+				// this.startWeek = getDate(new Date()).sWeek
+				// this.endWeek = getDate(new Date(),1).eWeek
+				// this.ruzhu_num=1
 			}, 20)
 		},
 		methods: {
-			// 获取请求令牌
-			getTokenSubmit() {
+			// 获取用户信息
+			getUserInfo() {
 				  let _self = this
-				  getsubmittoken().then((res) => {
+				  var data="?userId="+localStorage.getItem('usersId')
+				  getuserinfo(data).then((res) => {
 					if (res.success) {
-						this.submitToken=res.data.submitToken
+						_self.cardName=res.data.userName
+						_self.cardPhone=res.data.phone
+						_self.cardIdentity=res.data.idCardInformation
+						this.getjisuanprice()
 						return;
 					} else {
-						console.log('获取请求令牌失败')
+						console.log('获取用户信息失败')
 					}
 					}).catch((err) => {
 						this.$message.error(err.message)
 					});
-				 //  this.$axios.get("/hotel/ihotel-api/ihotel/hotelOrder/user/submit/token",
-				 //  {
-					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
-					//   }
-				 //  }).then(res => {
-					// res = res.data
-					// if (res.success) {
-					// 	this.submitToken=res.data.submitToken
-					// } else {
-					//   console.log('获取请求令牌失败')
-					// }
-				 //  });
 			},
-			// 获取用户信息
-			getUserInfo() {
+			//获取钟点房可住时间段
+			getZhongTime(){
+				this.array2=[]
 				  let _self = this
-				  getuserinfo().then((res) => {
+				  var data="?houseNumberId="+_self.roomTypeId+"&startTime="+_self.startDate
+				  +"&liveTime="+this.zhongshi
+				  getZhongTime(data).then((res) => {
 					if (res.success) {
-						if (res.data.statu == '1') {
-						  _self.cardName=res.data.name
-						  _self.cardPhone=res.data.telPhone
-						  _self.cardIdentity=res.data.identityType
-						}else {
-							alert('您没有权限,请联系客服')
-						}
+						res.data.forEach(data => {
+							if(data.status=="可用"){
+								_self.array2.push(data.hourDate)
+								this.startDateZ=localStorage.getItem('enableStartTime').substring(0,11)+this.array2[0].substring(0,8)
+								this.endDateZ=localStorage.getItem('enableEndTime').substring(0,11)+this.array2[0].substring(9,17)
+							}
+						})
 						return;
 					} else {
-						console.log('获取用户信息失败')
+						console.log('失败')
 					}
 					}).catch((err) => {
-						this.$message.error(err.message)
+						uni.showModal({
+							content:err.message
+						})
 					});
-				 //  this.$axios.get("/hotel/ihotel-api/ihotel/hotelUser/userInfo",
-				 //  {
-					//   headers:{
-					// 	  'user_token':localStorage.getItem('token')
-					//   }
-				 //  }).then(res => {
-					// res = res.data
-					// if (res.success) {
-					// 	if (res.data.statu == '1') {
-					// 	  _self.cardName=res.data.name
-					// 	  _self.cardPhone=res.data.telPhone
-					// 	  _self.cardIdentity=res.data.identityType
-					// 	}else {
-					// 		alert('您没有权限,请联系客服')
-					// 	}
-					// } else {
-					//   console.log('获取用户信息失败')
-					// }
-				 //  });
 			},
-			// 确认订单
-			getOrderConfirm(type) {
-				let _self = this
-				var data="?startTime="+this.startDate.substring(0,10)+
-				"&endTime="+this.endDate.substring(0,10)+
-				'&roomTypeId='+this.roomTypeId
-				getorderconfirm(data).then((res) => {
+			// 计算订单金额
+			getjisuanprice() {
+				this.payMount=0
+				  let _self = this
+				  var data="?userId="+localStorage.getItem('usersId') 
+				  +
+				  "&houseId="+_self.roomTypeId+"&liveTime="+_self.startDate
+				  +"&leaveTime="+_self.endDate+"&houseOrderNumber=1"
+				  getprice(data).then((res) => {
 					if (res.success) {
-						this.payMount=res.data.totalAmount
-						this.freeRoom=res.data.freeNum
-						this.ruzhu_num=res.data.nums
+						_self.payMount=res.data
 						return;
 					} else {
-						this.msgType = type
-						this.order_txt=res.message
-						this.$refs.popup_order.open()
+						uni.showModal({
+							content:res.message
+						})
 					}
 					}).catch((err) => {
-						this.$message.error(err.message)
+						uni.showModal({
+							content:err.message
+						})
 					});
-				// this.$axios.get("/hotel/ihotel-api/ihotel/hotelOrder/user/order/confirm?startTime="+this.startDate.substring(0,10)+"&endTime="+this.endDate.substring(0,10)+'&roomTypeId='+this.roomTypeId).then(res => {
-				// 	res = res.data
-				// 	if (res.success) {
-				// 	  this.payMount=res.data.totalAmount
-				// 	  this.freeRoom=res.data.freeNum
-				// 	  this.ruzhu_num=res.data.nums
-				// 	} else {
-				// 		this.msgType = type
-				// 		this.order_txt=res.message
-				// 		this.$refs.popup_order.open()
-				// 	}
-				// });
 			},
-			// 提交订单
-			getOrderSubmit(type) {
-				uni.navigateTo({
-					url:'/pages/submit_order/submit_order'
-				})
+			// onBridgeReady () {
+			//       console.log('调用微信支付WeixinJSBridge')
+			//       var vm = this
+			//       WeixinJSBridge.invoke(
+			//         'getBrandWCPayRequest', { // 下面参数内容都是后台返回的
+			//           "appId": "wxd87cbe1db0437303",     //公众号ID,由商户传入
+			//           "timeStamp": "1720083271",//时间戳,自1970年以来的秒数     
+			//           "nonceStr": "ORsH3qtW9wauQQ7iV5ovSm6n58s6Z2Nu",      //随机串     
+			//           "package": "prepay_id=wx041654316576072897ded7969912130000",
+			//           "signType": "RSA",     //微信签名方式:     
+			//           "paySign": "ZbyL2qiE9QScgwEHhObRn5/9VQgJQxLo0zKc7VxUK+Emeb3Eas/rzePUp89rHnUVYDCRJcbNsmuR2b1LHY4mydBZVnPy1vwHE/EOrCmdgALZ4J8GcQK0wTLNu9kMx97WR0f9TItPN/sR604df9ca5CKA4P40vNaUIEdK45mkqo3MR2IAdvyn+L8DhW49cL7jlsqIRiohVwwRsS4n06mX/yx1kuA339l7hbwnHaq7D4elvEqFYoMSHD8CR3XnoZ0HFE7Klu1RChMzgO4WUgVIMUxhsF6bhy5TkSea25OG/QWGZW/EHOl58bTCg3PorhZeJ/7fDkIC6pNRtKndrdsd+Q==" //微信签名 
+			//         },
+			//         function(res){
+			//         	if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
+			//         }
+			//       )
+			//     },
+			//创建订单
+			postOrder(type){
+				// var vm = this
+				// if (typeof WeixinJSBridge === 'undefined') { // 微信浏览器内置对象。参考微信官方文档
+				//           if (document.addEventListener) {
+				//             document.addEventListener('WeixinJSBridgeReady', vm.onBridgeReady(), false)
+				//           } else if (document.attachEvent) {
+				//             document.attachEvent('WeixinJSBridgeReady', vm.onBridgeReady())
+				//             document.attachEvent('onWeixinJSBridgeReady', vm.onBridgeReady())
+				//           }
+				//         } else {
+				//           console.log('准备调用微信支付')
+				//           vm.onBridgeReady()
+				//         }
+				if(this.roomType=='1'){
+					var startDate=this.startDate
+					var endDate=this.endDate
+				}else {
+					var startDate=this.startDateZ
+					var endDate=this.endDateZ
+				}
 				this.payUrl=''
 				let _self = this
-				this.$axios.defaults.headers.common['user_token'] = localStorage.getItem('token');
-				this.$axios.defaults.headers.common['request_token'] = this.submitToken;
+				this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				this.$axios.defaults.headers.common['user_head'] = localStorage.getItem('user_head');
 				this.$axios.defaults.headers.common['Content-Type'] ='application/json'
 				var data={
-					"enableStartTime":this.startDate,//入住时间
-					"enableEndTime":this.endDate,//离店时间
-					"roomTypeId":this.roomTypeId,//房间类型id
-					"payAmount":this.payMount,//需支付金额
-					"userName":this.cardName,
-					"userPhone":this.cardPhone,
-					"mayIntoTime":this.mayTime,
-					"remark":this.remark,
+					"userId": localStorage.getItem('usersId'),
+					"houseId": this.roomTypeId,
+					"payPrice": this.payMount,
+					"houseOrderNumber": 1,
+					"liveDay": this.ruzhu_num,
+					"reserveLiveTime": startDate,
+					"reserveLeaveTime": endDate,
+					"reservePhone": this.cardPhone,
+					"reserveName": this.cardName
 				}
-				getsubmit(data).then((res) => {
+				postOrder(data).then((res) => {
 					if (res.success) {
 						uni.navigateTo({
-							url:'/pages/submit_order/submit_order'
+							url:'/pages/submit_order/submit_order?houseOrderId='+res.data.id
 						})
 						// if(res.data.payAmount==0) {
 						// 	uni.navigateTo({
@@ -358,35 +401,8 @@
 				}).catch((err) => {
 					this.$message.error(err.message)
 				});
-				// this.$axios.post("/hotel/ihotel-api/ihotel/hotelOrder/user/order/submit",
-				// {
-				// 	"enableStartTime":this.startDate,//入住时间
-				// 	"enableEndTime":this.endDate,//离店时间
-				// 	"roomTypeId":this.roomTypeId,//房间类型id
-				// 	"payAmount":this.payMount,//需支付金额
-				// 	"userName":this.cardName,
-				// 	"userPhone":this.cardPhone,
-				// 	"mayIntoTime":this.mayTime,
-				// 	"remark":this.remark,
-				// }
-				// ).then(res => {
-				// 	res = res.data
-				// 	if (res.success) {
-				// 		if(res.data.payAmount==0) {
-				// 			uni.navigateTo({
-				// 				url:'../zhifuchenggong/zhifuchenggong?orderId='+res.data.orderId
-				// 			})
-				// 		} else {
-				// 			window.location.href = res.data.payUrl;
-				// 		}
-						
-				// 	} else {
-				// 		this.msgType = type
-				// 		this.order_txt=res.message
-				// 		this.$refs.popup_order.open()
-				// 	}
-				// });
 			},
+
 			// 计算指定时间是周几
 			getweekday(date){
 			   // date例如:'2022-03-05'
@@ -422,11 +438,12 @@
 						this.endWeek='周'+e.lunar.ncWeek.substring(2,3)
 						this.startTime=e.range.before.substring(5,7)+'月'+e.range.before.substring(8,10)+'日'
 						this.endTime=e.range.after.substring(5,7)+'月'+e.range.after.substring(8,10)+'日'
-						this.startDate = e.range.before +' 14:00:00'
-						this.endDate =  e.range.after +' 12:00:00'
+						this.startDate = e.range.before +' '+localStorage.getItem('liveTime')
+						this.endDate =  e.range.after +' '+localStorage.getItem('leaveTime')
 						this.ruzhu_num=parseInt(((new Date(e.range.after).getTime())-(new Date(e.range.before).getTime()))/1000/60/60/24)
 					}
 				}
+				this.getjisuanprice()
 			},
 			//选择器
 			bindPickerChange: function(e) {
@@ -435,10 +452,22 @@
 				this.mayTime = this.startDate.substring(0,11)+this.array[this.index].substring(0,5)+":00"
 				// console.log(this.mayTime)
 			},
+			//钟点房选择器
+			bindPickerChange2: function(e) {
+				console.log('picker发送选择改变,携带值为', e.detail.value)
+				this.index2 = e.detail.value
+				console.log(this.array2[this.index2].substring(0,8),this.array2[this.index2])
+				if(this.array2.length<=0){
+					
+				}else{
+					this.startDateZ=localStorage.getItem('enableStartTime').substring(0,11)+this.array2[this.index2].substring(0,8)
+					this.endDateZ=localStorage.getItem('enableEndTime').substring(0,11)+this.array2[this.index2].substring(9,17)
+				}
+				this.mayTime = this.startDate.substring(0,11)+this.array[this.index].substring(0,5)+":00"
+				// console.log(this.mayTime)
+			},
 			// 输入框
 			bindTextAreaBlur: function (e) {
-				// console.log(e.detail.cursor)
-				// console.log(e.detail.value)
 				this.textNum=e.detail.cursor
 				this.remark=e.detail.value
 			}

+ 2 - 1
pages/submit_order/css/submit_order.css

@@ -58,6 +58,7 @@
 		color: rgba(153, 153, 153, 1);
 		font-size: 24rpx;
 		font-weight: 400;
+		margin-left: 10rpx;
 	}
 	.select-list-time{
 		color: rgba(0, 0, 0, 1);
@@ -99,7 +100,7 @@
 		background: rgba(41, 109, 227, 1);
 	}
 	.select_name{
-		margin: 81rpx 0 0 31rpx;
+		margin: 88rpx 0 0 31rpx;
 		font-size: 28rpx;
 		font-weight: 500;
 		color: rgba(0, 0, 0, 1);

+ 236 - 13
pages/submit_order/submit_order.vue

@@ -1,8 +1,12 @@
 <template>
 	<view class="content">
 		<!-- 支付剩余时间 -->
-		<view class="break_time">交易剩余时间15:00</view>
-		<view class="break_money">¥280.00</view>
+		<view class="break_time">
+			交易剩余时间<uv-count-down :time="new Date(allTime).getTime() + 15 * 60 * 1000 - new Date().getTime()" format="mm:ss" @change="change" @finish="finish(countDownTime,allTime)"></uv-count-down>
+		</view>
+		<!-- <uv-count-down :time="56687" format="mm:ss" @finish="finish(countDownTime)"></uv-count-down> -->
+		<!-- <view class="break_time">交易剩余时间15:00</view> -->
+		<view class="break_money">¥{{countMoney}}</view>
 		<!-- 住房信息 -->
 		<view class="zhufang">住房信息</view>
 		<view class="two_all">
@@ -24,12 +28,13 @@
 				</view>
 			</view>
 			<!-- 房型信息 -->
-			<view class="select_name">大床房</view>
-			<view class="select_type">包吃住型</view>
+			<view class="select_name">{{roomName}}</view>
+			<view class="select_type" v-if="roomType==1">全日房</view>
+			<view class="select_type" v-else-if="roomType==2">钟点房</view>
 			<view class="select_detail">
-				16-20
-				<text style="margin-left: 20px;">双人床</text>
-				<text style="margin-left: 20px;">窗户位于走廊/窗户较小</text>
+				{{roomArea}}
+				<text style="margin-left: 20px;">{{roomConfiguration}}</text>
+				<!-- <text style="margin-left: 20px;">窗户位于走廊/窗户较小</text> -->
 			</view>
 		</view>
 		<!-- 支付方式 -->
@@ -43,27 +48,245 @@
 			</label>
 		</view>
 		<!-- 确认支付 -->
-		<view class="quwer">确认支付</view>
+		<view class="quwer" @click="queZhifu1">确认支付</view>
 	</view>
 </template>
 
 <script>
+	import {
+		getorderdetail,
+		quxiaoorder,
+		getorderpay,
+		getchapay
+	} from '../../utils/api_hotel.js'
 	export default {
 		data() {
 			return {
 				orderId:'',//订单id
-				startTime:'7月6日',//到店日期
-				endTime:'7月7日',//离店日期
-				startWeek:'今天',// 默认入店日
-				endWeek:'明天',// 默认离店
+				startTime:'',//到店日期
+				endTime:'',//离店日期
+				startWeek:'',// 默认入店日
+				endWeek:'',// 默认离店
 				ruzhu_num:1,//入住夜晚
 				pay_way: '微信支付',
+				roomName:'',
+				roomType:1,
+				roomArea:'',
+				roomConfiguration:'',//房间配置
+				countMoney:'',
+				countDownTime:null,
+				allTime:'',
+				orderNumber:'', //订单号
+				houseNumberId:'', //房间号id
+				money:'',
+				
+				appId: "",     //公众号ID,由商户传入
+				timeStamp: "",     //时间戳,自1970年以来的秒数     
+				nonceStr: "",      //随机串     
+				package: "",
+				signType: "",     //微信签名方式:     
+				paySign:'',
 			}
 		},
 		onLoad(option) {
-			this.orderId=option.orderId
+			this.orderId=option.houseOrderId
+		},
+		onShow() {
+			this.getorderXiang()
 		},
 		methods: {
+			// 截取 url中的code方法
+			handleUrlCode() {
+				var url = location.href; //获取打开的公众号的路径
+				var theRequest = new Object();
+				if (url.indexOf('?') != -1) {
+					var str = url.substr(url.indexOf('?') + 1);
+					var strs = str.split('&');
+					for (var i = 0; i < strs.length; i++) {
+						var items = strs[i].split('=');
+						if(strs[i].split('=')[0]=='code'){
+							var code=strs[i].split('=')[1]
+						
+						}
+						theRequest[strs[i].split('=')[0]] = strs[i].split('=')[1];
+						theRequest[i] = strs[i].split('=')[1];
+						localStorage.setItem('code',code)
+					}
+				// alert(code+'p')
+				
+				}
+			},
+			// 订单详情
+			getorderXiang() {
+				this.payMount=0
+				  let _self = this
+				  var data="?houseOrderId="+this.orderId
+				  getorderdetail(data).then((res) => {
+					if (res.success) {
+						this.roomName=res.data.roomNumber
+						this.roomType=res.data.house.roomType
+						this.roomArea=res.data.house.roomArea
+						this.roomConfiguration=res.data.house.roomConfiguration
+						this.countMoney=res.data.houseOrder.payPrice
+						this.ruzhu_num=res.data.houseOrder.liveDay
+						this.startTime=(res.data.houseOrder.reserveLiveTime).substring(5,10)
+						this.endTime=(res.data.houseOrder.reserveLeaveTime).substring(5,10)
+						this.startWeek=this.getweekday(res.data.houseOrder.reserveLiveTime)
+						this.endWeek=this.getweekday(res.data.houseOrder.reserveLeaveTime)
+						
+						this.orderNumber=res.data.houseOrder.orderNumber //订单号
+						this.houseNumberId=res.data.houseOrder.houseNumberId //房间号id
+						// 兼容ios部分系统转换时间格式
+						this.allTime = res.data.houseOrder.createTime.replace(/-/g, '/')
+						this.countDownTime = new Date(this.allTime).getTime() + 15 * 60 * 1000 - new Date().getTime()
+						return;
+					} else {
+						console.log('订单详情获取失败')
+					}
+					}).catch((err) => {
+						this.$message.error(err.message)
+					});
+			},
+			// 计算指定时间是周几
+			getweekday(date){
+			   // date例如:'2022-03-05'
+				var weekArray = new Array("周日","周一", "周二", "周三", "周四", "周五", "周六")
+				var weeka  = weekArray[new Date(date).getDay()]
+				return weeka
+			},
+			//确认支付
+			queZhifu1(){
+				if(localStorage.getItem('code')=='undefined'){
+					uni.navigateTo({
+						url:'/pages/huoquCode/huoquCode'
+					})
+					return
+				}
+				let _self = this 
+				var data={
+					"usersId": localStorage.getItem('usersId'),
+					"houseOrderId": this.orderId,//订单号idlocalStorage.getItem('orderId')
+					"totalPrice":this.countMoney  //支付金额
+				}
+				getorderpay(data).then((res) => {
+					// alert(res.message+res.code)
+					if (res.success) {
+						_self.appId=res.data.appId
+						_self.timeStamp=res.data.timeStamp
+						_self.nonceStr=res.data.nonceStr
+						_self.package=res.data.packageVal
+						_self.signType=res.data.signType
+						_self.paySign=res.data.paySign
+						_self.onBridgeReady();
+					} else if(res.code=='500'){
+						uni.navigateTo({
+							url:'/pages/huoquCode/huoquCode'
+						})
+						// uni.showModal({
+						// 	content:res.message
+						// })
+					}
+				}).catch((err) => {
+					uni.navigateTo({
+						url:'/pages/huoquCode/huoquCode'
+					})
+				});
+			},
+			onBridgeReady() {
+			    WeixinJSBridge.invoke('getBrandWCPayRequest', {
+			        "appId": this.appId,     //公众号ID,由商户传入     
+			        "timeStamp": this.timeStamp,     //时间戳,自1970年以来的秒数     
+			        "nonceStr": this.nonceStr,      //随机串     
+			        "package": this.package,
+			        "signType": this.signType,     //微信签名方式:     
+			        "paySign": this.paySign //微信签名 
+			    },
+			    function(res) {
+					// alert('p1'+res.err_msg)
+			        if (res.err_msg == "get_brand_wcpay_request:ok") {
+						// alert('pp')
+						uni.navigateTo({
+							url:'/pages/my_orderlist/my_orderlist?Inv=3'
+						})
+			            // 使用以上方式判断前端返回,微信团队郑重提示:
+			            //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
+			        }else{
+						this.chapayIf()
+					}
+			    });
+			},
+			//查询是否支付成功
+			chapayIf(){
+				var data={
+					"outTradeNo": this.orderNumber,//订单号id
+				}
+				getchapay(data).then((res) => {
+					if (res.success) {
+						if(res.data.tradeState=="SUCCESS"){
+							uni.showModal({
+								content:'支付成功',
+								success: (res) => {
+									uni.navigateTo({
+										url:'/pages/my_orderlist/my_orderlist?Inv=3'
+									})
+								},
+							})
+						}else{
+							uni.showModal({
+								content:res.data.tradeStateDesc
+							})
+						}
+						
+						// return;
+					} else {
+					}
+				}).catch((err) => {
+					uni.showModal({
+						content:err.message
+					})
+				});
+			},
+			// 倒计时结束回调
+			finish(countDownTime,item) {
+				// alert('倒计时结束'+item)
+				// if(item==)
+				this.quxiaoorder()
+			},
+			// 取消订单
+			quxiaoorder(){
+				let _self = this
+				// this.$axios.defaults.headers.common['token'] = localStorage.getItem('token');
+				// this.$axios.defaults.headers.common['user_head'] = localStorage.getItem('user_head');
+				// this.$axios.defaults.headers.common['Content-Type'] ='application/json'
+				var data={
+					"usersId": localStorage.getItem('usersId'),
+					"orderNumber": this.orderNumber, //订单号
+					"houseNumberId": this.houseNumberId, //房间号id
+				}
+				quxiaoorder(data).then((res) => {
+					if (res.success) {
+						uni.showModal({
+							content:'支付超时,请重新订房',
+							success: (res) => {
+								uni.switchTab({
+									url:'/pages/index/index'
+								})
+							},
+							fail: (e) => {
+								// uni.switchTab({
+								// 	url:'/pages/index/index'
+								// })
+							},
+						})
+						// return;
+					} else {
+					}
+				}).catch((err) => {
+					uni.showModal({
+						content:err.message
+					})
+				});
+			}
 		}
 	}
 </script>

BIN
static/my/touxiang.png


+ 9 - 0
uni_modules/uv-count-down/changelog.md

@@ -0,0 +1,9 @@
+## 1.0.3(2023-10-13)
+1. unmounted兼容vue3
+## 1.0.2(2023-06-20)
+1. 增加外部样式customStyle参数
+## 1.0.1(2023-05-16)
+1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
+2. 优化部分功能
+## 1.0.0(2023-05-10)
+uv-count-down 倒计时

+ 25 - 0
uni_modules/uv-count-down/components/uv-count-down/props.js

@@ -0,0 +1,25 @@
+export default {
+	props: {
+		// 倒计时时长,单位ms
+		time: {
+			type: [String, Number],
+			default: 0
+		},
+		// 时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒
+		format: {
+			type: String,
+			default: 'HH:mm:ss'
+		},
+		// 是否自动开始倒计时
+		autoStart: {
+			type: Boolean,
+			default: true
+		},
+		// 是否展示毫秒倒计时
+		millisecond: {
+			type: Boolean,
+			default: false
+		},
+		...uni.$uv?.props?.countDown
+	}
+}

+ 62 - 0
uni_modules/uv-count-down/components/uv-count-down/utils.js

@@ -0,0 +1,62 @@
+// 补0,如1 -> 01
+function padZero(num, targetLength = 2) {
+    let str = `${num}`
+    while (str.length < targetLength) {
+        str = `0${str}`
+    }
+    return str
+}
+const SECOND = 1000
+const MINUTE = 60 * SECOND
+const HOUR = 60 * MINUTE
+const DAY = 24 * HOUR
+export function parseTimeData(time) {
+    const days = Math.floor(time / DAY)
+    const hours = Math.floor((time % DAY) / HOUR)
+    const minutes = Math.floor((time % HOUR) / MINUTE)
+    const seconds = Math.floor((time % MINUTE) / SECOND)
+    const milliseconds = Math.floor(time % SECOND)
+    return {
+        days,
+        hours,
+        minutes,
+        seconds,
+        milliseconds
+    }
+}
+export function parseFormat(format, timeData) {
+    let {
+        days,
+        hours,
+        minutes,
+        seconds,
+        milliseconds
+    } = timeData
+    // 如果格式化字符串中不存在DD(天),则将天的时间转为小时中去
+    if (format.indexOf('DD') === -1) {
+        hours += days * 24
+    } else {
+        // 对天补0
+        format = format.replace('DD', padZero(days))
+    }
+    // 其他同理于DD的格式化处理方式
+    if (format.indexOf('HH') === -1) {
+        minutes += hours * 60
+    } else {
+        format = format.replace('HH', padZero(hours))
+    }
+    if (format.indexOf('mm') === -1) {
+        seconds += minutes * 60
+    } else {
+        format = format.replace('mm', padZero(minutes))
+    }
+    if (format.indexOf('ss') === -1) {
+        milliseconds += seconds * 1000
+    } else {
+        format = format.replace('ss', padZero(seconds))
+    }
+    return format.replace('SSS', padZero(milliseconds, 3))
+}
+export function isSameSecond(time1, time2) {
+    return Math.floor(time1 / 1000) === Math.floor(time2 / 1000)
+}

+ 169 - 0
uni_modules/uv-count-down/components/uv-count-down/uv-count-down.vue

@@ -0,0 +1,169 @@
+<template>
+	<view 
+		class="uv-count-down"
+		:style="[$uv.addStyle(customStyle)]">
+		<slot>
+			<text class="uv-count-down__text">{{ formattedTime }}</text>
+		</slot>
+	</view>
+</template>
+<script>
+	import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
+	import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
+	import props from './props.js';
+	import {
+		isSameSecond,
+		parseFormat,
+		parseTimeData
+	} from './utils';
+	/**
+	 * uv-count-down 倒计时
+	 * @description 该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
+	 * @tutorial https://www.uvui.cn/components/countDown.html
+	 * @property {String | Number}	time		倒计时时长,单位ms (默认 0 )
+	 * @property {String}			format		时间格式,DD-日,HH-时,mm-分,ss-秒,SSS-毫秒  (默认 'HH:mm:ss' )
+	 * @property {Boolean}			autoStart	是否自动开始倒计时 (默认 true )
+	 * @property {Boolean}			millisecond	是否展示毫秒倒计时 (默认 false )
+	 * @event {Function} finish 倒计时结束时触发 
+	 * @event {Function} change 倒计时变化时触发 
+	 * @event {Function} start	开始倒计时
+	 * @event {Function} pause	暂停倒计时 
+	 * @event {Function} reset	重设倒计时,若 auto-start 为 true,重设后会自动开始倒计时 
+	 * @example <uv-count-down :time="time"></uv-count-down>
+	 */
+	export default {
+		name: 'uv-count-down',
+		mixins: [mpMixin, mixin, props],
+		data() {
+			return {
+				timer: null,
+				// 各单位(天,时,分等)剩余时间
+				timeData: parseTimeData(0),
+				// 格式化后的时间,如"03:23:21"
+				formattedTime: '0',
+				// 倒计时是否正在进行中
+				runing: false,
+				endTime: 0, // 结束的毫秒时间戳
+				remainTime: 0, // 剩余的毫秒时间
+			}
+		},
+		watch: {
+			time(n) {
+				this.reset()
+			}
+		},
+		mounted() {
+			this.init()
+		},
+		methods: {
+			init() {
+				this.reset()
+			},
+			// 开始倒计时
+			start() {
+				if (this.runing) return
+				// 标识为进行中
+				this.runing = true
+				// 结束时间戳 = 此刻时间戳 + 剩余的时间
+				this.endTime = Date.now() + this.remainTime
+				this.toTick()
+			},
+			// 根据是否展示毫秒,执行不同操作函数
+			toTick() {
+				if (this.millisecond) {
+					this.microTick()
+				} else {
+					this.macroTick()
+				}
+			},
+			macroTick() {
+				this.clearTimeout()
+				// 每隔一定时间,更新一遍定时器的值
+				// 同时此定时器的作用也能带来毫秒级的更新
+				this.timer = setTimeout(() => {
+					// 获取剩余时间
+					const remain = this.getRemainTime()
+					// 重设剩余时间
+					if (!isSameSecond(remain, this.remainTime) || remain === 0) {
+						this.setRemainTime(remain)
+					}
+					// 如果剩余时间不为0,则继续检查更新倒计时
+					if (this.remainTime !== 0) {
+						this.macroTick()
+					}
+				}, 30)
+			},
+			microTick() {
+				this.clearTimeout()
+				this.timer = setTimeout(() => {
+					this.setRemainTime(this.getRemainTime())
+					if (this.remainTime !== 0) {
+						this.microTick()
+					}
+				}, 50)
+			},
+			// 获取剩余的时间
+			getRemainTime() {
+				// 取最大值,防止出现小于0的剩余时间值
+				return Math.max(this.endTime - Date.now(), 0)
+			},
+			// 设置剩余的时间
+			setRemainTime(remain) {
+				this.remainTime = remain
+				// 根据剩余的毫秒时间,得出该有天,小时,分钟等的值,返回一个对象
+				const timeData = parseTimeData(remain)
+				this.$emit('change', timeData)
+				// 得出格式化后的时间
+				this.formattedTime = parseFormat(this.format, timeData)
+				// 如果时间已到,停止倒计时
+				if (remain <= 0) {
+					this.pause()
+					this.$emit('finish')
+				}
+			},
+			// 重置倒计时
+			reset() {
+				this.pause()
+				this.remainTime = this.time
+				this.setRemainTime(this.remainTime)
+				if (this.autoStart) {
+					this.start()
+				}
+			},
+			// 暂停倒计时
+			pause() {
+				this.runing = false;
+				this.clearTimeout()
+			},
+			// 清空定时器
+			clearTimeout() {
+				clearTimeout(this.timer)
+				this.timer = null
+			}
+		},
+		// #ifdef VUE2
+		beforeDestroy() {
+			this.clearTimeout()
+		},
+		// #endif
+		// #ifdef VUE3
+		unmounted() {
+			this.clearTimeout()
+		}
+		// #endif
+	}
+</script>
+<style lang="scss" scoped>
+	@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
+	@import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
+	$uv-count-down-text-color: $uv-content-color !default;
+	$uv-count-down-text-font-size: 15px !default;
+	$uv-count-down-text-line-height: 22px !default;
+	.uv-count-down {
+		&__text {
+			color: $uv-count-down-text-color;
+			font-size: $uv-count-down-text-font-size;
+			line-height: $uv-count-down-text-line-height;
+		}
+	}
+</style>

+ 87 - 0
uni_modules/uv-count-down/package.json

@@ -0,0 +1,87 @@
+{
+  "id": "uv-count-down",
+  "displayName": "uv-count-down 倒计时 全面兼容小程序、nvue、vue2、vue3等多端",
+  "version": "1.0.3",
+  "description": "该倒计时组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。",
+  "keywords": [
+    "uv-count-down",
+    "uvui",
+    "uv-ui",
+    "countDown",
+    "倒计时"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+    	"ads": "无",
+    	"data": "插件不采集任何数据",
+    	"permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uv-ui-tools"
+		],
+    "encrypt": [],
+    "platforms": {
+			"cloud": {
+				"tcb": "y",
+				"aliyun": "y"
+			},
+			"client": {
+				"Vue": {
+					"vue2": "y",
+					"vue3": "y"
+				},
+				"App": {
+					"app-vue": "y",
+					"app-nvue": "y"
+				},
+				"H5-mobile": {
+					"Safari": "y",
+					"Android Browser": "y",
+					"微信浏览器(Android)": "y",
+					"QQ浏览器(Android)": "y"
+				},
+				"H5-pc": {
+					"Chrome": "y",
+					"IE": "y",
+					"Edge": "y",
+					"Firefox": "y",
+					"Safari": "y"
+				},
+				"小程序": {
+					"微信": "y",
+					"阿里": "y",
+					"百度": "y",
+					"字节跳动": "y",
+					"QQ": "y",
+					"钉钉": "u",
+					"快手": "u",
+					"飞书": "u",
+					"京东": "u"
+				},
+				"快应用": {
+					"华为": "u",
+					"联盟": "u"
+				}
+			}
+		}
+  }
+}

+ 11 - 0
uni_modules/uv-count-down/readme.md

@@ -0,0 +1,11 @@
+## CountDown 倒计时
+
+> **组件名:uv-count-down**
+
+该组件一般使用于某个活动的截止时间上,通过数字的变化,给用户明确的时间感受,提示用户进行某一个行为操作。
+
+### <a href="https://www.uvui.cn/components/countDown.html" target="_blank">查看文档</a>
+
+### [完整示例项目下载 | 关注更多组件](https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+#### 如使用过程中有任何问题,或者您对uv-ui有一些好的建议,欢迎加入 uv-ui 交流群:<a href="https://ext.dcloud.net.cn/plugin?id=12287" target="_blank">uv-ui</a>、<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>

+ 76 - 0
uni_modules/uv-ui-tools/changelog.md

@@ -0,0 +1,76 @@
+## 1.1.25(2024-01-20)
+1.1.20版本更新
+## 1.1.24(2023-12-21)
+1. luch-request更新
+## 1.1.23(2023-12-12)
+1. 1.1.19版本
+## 1.1.22(2023-11-28)
+1. 优化
+## 1.1.21(2023-11-10)
+1. 1.1.17版本
+## 1.1.20(2023-10-30)
+1. 1.1.16版本
+## 1.1.19(2023-10-13)
+1. 兼容vue3
+## 1.1.18(2023-10-12)
+1. 1.1.15版本
+## 1.1.17(2023-09-27)
+1. 1.1.14版本发布
+## 1.1.16(2023-09-15)
+1. 1.1.13版本发布
+## 1.1.15(2023-09-15)
+1. 更新button.js相关按钮支持open-type="agreePrivacyAuthorization"
+## 1.1.14(2023-09-14)
+1. 优化dayjs
+## 1.1.13(2023-09-13)
+1. 优化,$uv中增加unit参数,方便组件中使用
+## 1.1.12(2023-09-10)
+1. 升级版本
+## 1.1.11(2023-09-04)
+1. 1.1.11版本
+## 1.1.10(2023-08-31)
+1. 修复customStyle和customClass存在冲突的问题
+## 1.1.9(2023-08-27)
+1. 版本升级
+2. 优化
+## 1.1.8(2023-08-24)
+1. 版本升级
+## 1.1.7(2023-08-22)
+1. 版本升级
+## 1.1.6(2023-08-18)
+uvui版本:1.1.6
+## 1.0.15(2023-08-14)
+1. 更新uvui版本号
+## 1.0.13(2023-08-06)
+1. 优化
+## 1.0.12(2023-08-06)
+1. 修改版本号
+## 1.0.11(2023-08-06)
+1. 路由增加events参数
+2. 路由拦截修复
+## 1.0.10(2023-08-01)
+1. 优化
+## 1.0.9(2023-06-28)
+优化openType.js
+## 1.0.8(2023-06-15)
+1. 修改支付宝报错的BUG
+## 1.0.7(2023-06-07)
+1. 解决微信小程序使用uvui提示 Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors
+2. 解决上述提示,需要在uni.scss配置$uvui-nvue-style: false; 然后在APP.vue下面引入uvui内置的基础样式:@import '@/uni_modules/uv-ui-tools/index.scss';
+## 1.0.6(2023-06-04)
+1.  uv-ui-tools 优化工具组件,兼容更多功能
+2.  小程序分享功能优化等
+## 1.0.5(2023-06-02)
+1. 修改扩展使用mixin中方法的问题
+## 1.0.4(2023-05-23)
+1. 兼容百度小程序修改bem函数
+## 1.0.3(2023-05-16)
+1. 优化组件依赖,修改后无需全局引入,组件导入即可使用
+2. 优化部分功能
+## 1.0.2(2023-05-10)
+1. 增加Http请求封装
+2. 优化
+## 1.0.1(2023-05-04)
+1. 修改名称及备注
+## 1.0.0(2023-05-04)
+1. uv-ui工具集首次发布

+ 6 - 0
uni_modules/uv-ui-tools/components/uv-ui-tools/uv-ui-tools.vue

@@ -0,0 +1,6 @@
+<template>
+</template>
+<script>
+</script>
+<style>
+</style>

+ 79 - 0
uni_modules/uv-ui-tools/index.js

@@ -0,0 +1,79 @@
+// 全局挂载引入http相关请求拦截插件
+import Request from './libs/luch-request'
+
+// 引入全局mixin
+import mixin from './libs/mixin/mixin.js'
+// 小程序特有的mixin
+import mpMixin from './libs/mixin/mpMixin.js'
+// #ifdef MP
+import mpShare from './libs/mixin/mpShare.js'
+// #endif
+
+// 路由封装
+import route from './libs/util/route.js'
+// 公共工具函数
+import * as index from './libs/function/index.js'
+// 防抖方法
+import debounce from './libs/function/debounce.js'
+// 节流方法
+import throttle from './libs/function/throttle.js'
+// 规则检验
+import * as test from './libs/function/test.js'
+
+// 颜色渐变相关,colorGradient-颜色渐变,hexToRgb-十六进制颜色转rgb颜色,rgbToHex-rgb转十六进制
+import * as colorGradient from './libs/function/colorGradient.js'
+
+// 配置信息
+import config from './libs/config/config.js'
+// 平台
+import platform from './libs/function/platform'
+
+const $uv = {
+	route,
+	config,
+	test,
+	date: index.timeFormat, // 另名date
+	...index,
+	colorGradient: colorGradient.colorGradient,
+	hexToRgb: colorGradient.hexToRgb,
+	rgbToHex: colorGradient.rgbToHex,
+	colorToRgba: colorGradient.colorToRgba,
+	http: new Request(),
+	debounce,
+	throttle,
+	platform,
+	mixin,
+	mpMixin
+}
+uni.$uv = $uv;
+const install = (Vue,options={}) => {
+		// #ifndef APP-NVUE
+		const cloneMixin = index.deepClone(mixin);
+		delete cloneMixin?.props?.customClass;
+		delete cloneMixin?.props?.customStyle;
+		Vue.mixin(cloneMixin);
+		// #ifdef MP
+		if(options.mpShare){
+			Vue.mixin(mpShare);
+		}
+		// #endif
+		// #endif
+		// #ifdef VUE2
+		// 时间格式化,同时两个名称,date和timeFormat
+		Vue.filter('timeFormat', (timestamp, format) => uni.$uv.timeFormat(timestamp, format));
+		Vue.filter('date', (timestamp, format) => uni.$uv.timeFormat(timestamp, format));
+		// 将多久以前的方法,注入到全局过滤器
+		Vue.filter('timeFrom', (timestamp, format) => uni.$uv.timeFrom(timestamp, format));
+		// 同时挂载到uni和Vue.prototype中
+		// #ifndef APP-NVUE
+		// 只有vue,挂载到Vue.prototype才有意义,因为nvue中全局Vue.prototype和Vue.mixin是无效的
+		Vue.prototype.$uv = $uv;
+		// #endif
+		// #endif
+		// #ifdef VUE3
+		Vue.config.globalProperties.$uv = $uv;
+		// #endif
+}
+export default {
+	install
+}

+ 7 - 0
uni_modules/uv-ui-tools/index.scss

@@ -0,0 +1,7 @@
+// 引入公共基础类
+@import "./libs/css/common.scss";
+
+// 非nvue的样式
+/* #ifndef APP-NVUE */
+@import "./libs/css/vue.scss";
+/* #endif */

+ 34 - 0
uni_modules/uv-ui-tools/libs/config/config.js

@@ -0,0 +1,34 @@
+// 此版本发布于2024-01-20
+const version = '1.1.20'
+
+// 开发环境才提示,生产环境不会提示
+if (process.env.NODE_ENV === 'development') {
+	console.log(`\n %c uvui V${version} https://www.uvui.cn/ \n\n`, 'color: #ffffff; background: #3c9cff; padding:5px 0; border-radius: 5px;');
+}
+
+export default {
+    v: version,
+    version,
+    // 主题名称
+    type: [
+        'primary',
+        'success',
+        'info',
+        'error',
+        'warning'
+    ],
+    // 颜色部分,本来可以通过scss的:export导出供js使用,但是奈何nvue不支持
+    color: {
+        'uv-primary': '#2979ff',
+        'uv-warning': '#ff9900',
+        'uv-success': '#19be6b',
+        'uv-error': '#fa3534',
+        'uv-info': '#909399',
+        'uv-main-color': '#303133',
+        'uv-content-color': '#606266',
+        'uv-tips-color': '#909399',
+        'uv-light-color': '#c0c4cc'
+    },
+	// 默认单位,可以通过配置为rpx,那么在用于传入组件大小参数为数值时,就默认为rpx
+	unit: 'px'
+}

+ 32 - 0
uni_modules/uv-ui-tools/libs/css/color.scss

@@ -0,0 +1,32 @@
+$uv-main-color: #303133 !default;
+$uv-content-color: #606266 !default;
+$uv-tips-color: #909193 !default;
+$uv-light-color: #c0c4cc !default;
+$uv-border-color: #dadbde !default;
+$uv-bg-color: #f3f4f6 !default;
+$uv-disabled-color: #c8c9cc !default;
+
+$uv-primary: #3c9cff !default;
+$uv-primary-dark: #398ade !default;
+$uv-primary-disabled: #9acafc !default;
+$uv-primary-light: #ecf5ff !default;
+
+$uv-warning: #f9ae3d !default;
+$uv-warning-dark: #f1a532 !default;
+$uv-warning-disabled: #f9d39b !default;
+$uv-warning-light: #fdf6ec !default;
+
+$uv-success: #5ac725 !default;
+$uv-success-dark: #53c21d !default;
+$uv-success-disabled: #a9e08f !default;
+$uv-success-light: #f5fff0;
+
+$uv-error: #f56c6c !default;
+$uv-error-dark: #e45656 !default;
+$uv-error-disabled: #f7b2b2 !default;
+$uv-error-light: #fef0f0 !default;
+
+$uv-info: #909399 !default;
+$uv-info-dark: #767a82 !default;
+$uv-info-disabled: #c4c6c9 !default;
+$uv-info-light: #f4f4f5 !default;

+ 100 - 0
uni_modules/uv-ui-tools/libs/css/common.scss

@@ -0,0 +1,100 @@
+// 超出行数,自动显示行尾省略号,最多5行
+// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】
+@for $i from 1 through 5 {
+	.uv-line-#{$i} {
+		/* #ifdef APP-NVUE */
+		// nvue下,可以直接使用lines属性,这是weex特有样式
+		lines: $i;
+		text-overflow: ellipsis;
+		overflow: hidden;
+		flex: 1;
+		/* #endif */
+
+		/* #ifndef APP-NVUE */
+		// vue下,单行和多行显示省略号需要单独处理
+		@if $i == '1' {
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+		} @else {
+			display: -webkit-box!important;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			word-break: break-all;
+			-webkit-line-clamp: $i;
+			-webkit-box-orient: vertical!important;
+		}
+		/* #endif */
+	}
+}
+$uv-bordercolor: #dadbde;
+@if variable-exists(uv-border-color) {
+	$uv-bordercolor: $uv-border-color;
+}
+
+// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时,
+// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效
+// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important
+// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现
+.uv-border {
+	border-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-style: solid;
+}
+
+.uv-border-top {
+	border-top-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-top-style: solid;
+}
+
+.uv-border-left {
+	border-left-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-left-style: solid;
+}
+
+.uv-border-right {
+	border-right-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-right-style: solid;
+}
+
+.uv-border-bottom {
+	border-bottom-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-bottom-style: solid;
+}
+
+.uv-border-top-bottom {
+	border-top-width: 0.5px!important;
+	border-bottom-width: 0.5px!important;
+	border-color: $uv-bordercolor!important;
+    border-top-style: solid;
+    border-bottom-style: solid;
+}
+
+// 去除button的所有默认样式,让其表现跟普通的view、text元素一样
+.uv-reset-button {
+	padding: 0;
+	background-color: transparent;
+	/* #ifndef APP-PLUS */
+	font-size: inherit;
+	line-height: inherit;
+	color: inherit;
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	border-width: 0;
+	/* #endif */
+}
+
+/* #ifndef APP-NVUE */
+.uv-reset-button::after {
+   border: none;
+}
+/* #endif */
+
+.uv-hover-class {
+	opacity: 0.7;
+}
+

+ 23 - 0
uni_modules/uv-ui-tools/libs/css/components.scss

@@ -0,0 +1,23 @@
+@mixin flex($direction: row) {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: $direction;
+}
+
+/* #ifndef APP-NVUE */
+// 由于uvui是基于nvue环境进行开发的,此环境中普通元素默认为flex-direction: column;
+// 所以在非nvue中,需要对元素进行重置为flex-direction: column; 否则可能会表现异常
+$uvui-nvue-style: true !default;
+@if $uvui-nvue-style == true {
+	view, scroll-view, swiper-item {
+		display: flex;
+		flex-direction: column;
+		flex-shrink: 0;
+		flex-grow: 0;
+		flex-basis: auto;
+		align-items: stretch;
+		align-content: flex-start;
+	}
+}
+/* #endif */

+ 111 - 0
uni_modules/uv-ui-tools/libs/css/variable.scss

@@ -0,0 +1,111 @@
+// 超出行数,自动显示行尾省略号,最多5行
+// 来自uvui的温馨提示:当您在控制台看到此报错,说明需要在App.vue的style标签加上【lang="scss"】
+@if variable-exists(show-lines) {
+	@for $i from 1 through 5 {
+		.uv-line-#{$i} {
+			/* #ifdef APP-NVUE */
+			// nvue下,可以直接使用lines属性,这是weex特有样式
+			lines: $i;
+			text-overflow: ellipsis;
+			overflow: hidden;
+			flex: 1;
+			/* #endif */
+
+			/* #ifndef APP-NVUE */
+			// vue下,单行和多行显示省略号需要单独处理
+			@if $i == '1' {
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
+			} @else {
+				display: -webkit-box!important;
+				overflow: hidden;
+				text-overflow: ellipsis;
+				word-break: break-all;
+				-webkit-line-clamp: $i;
+				-webkit-box-orient: vertical!important;
+			}
+			/* #endif */
+		}
+	}
+}
+@if variable-exists(show-border) {
+	$uv-bordercolor: #dadbde;
+	@if variable-exists(uv-border-color) {
+		$uv-bordercolor: $uv-border-color;
+	}
+	// 此处加上!important并非随意乱用,而是因为目前*.nvue页面编译到H5时,
+	// App.vue的样式会被uni-app的view元素的自带border属性覆盖,导致无效
+	// 综上,这是uni-app的缺陷导致我们为了多端兼容,而必须要加上!important
+	// 移动端兼容性较好,直接使用0.5px去实现细边框,不使用伪元素形式实现
+	@if variable-exists(show-border-surround) {
+		.uv-border {
+			border-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-style: solid;
+		}
+	}
+	@if variable-exists(show-border-top) {
+		.uv-border-top {
+			border-top-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-top-style: solid;
+		}
+	}
+	@if variable-exists(show-border-left) {
+		.uv-border-left {
+			border-left-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-left-style: solid;
+		}
+	}
+	@if variable-exists(show-border-right) {
+		.uv-border-right {
+			border-right-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-right-style: solid;
+		}
+	}
+	@if variable-exists(show-border-bottom) {
+		.uv-border-bottom {
+			border-bottom-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+				border-bottom-style: solid;
+		}
+	}
+	@if variable-exists(show-border-top-bottom) {
+		.uv-border-top-bottom {
+			border-top-width: 0.5px!important;
+			border-bottom-width: 0.5px!important;
+			border-color: $uv-bordercolor!important;
+			border-top-style: solid;
+			border-bottom-style: solid;
+		}
+	}
+}
+@if variable-exists(show-reset-button) {
+	// 去除button的所有默认样式,让其表现跟普通的view、text元素一样
+	.uv-reset-button {
+		padding: 0;
+		background-color: transparent;
+		/* #ifndef APP-PLUS */
+		font-size: inherit;
+		line-height: inherit;
+		color: inherit;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		border-width: 0;
+		/* #endif */
+	}
+
+	/* #ifndef APP-NVUE */
+	.uv-reset-button::after {
+		 border: none;
+	}
+	/* #endif */
+}
+@if variable-exists(show-hover) {
+	.uv-hover-class {
+		opacity: 0.7;
+	}
+}

+ 40 - 0
uni_modules/uv-ui-tools/libs/css/vue.scss

@@ -0,0 +1,40 @@
+// 历遍生成4个方向的底部安全区
+@each $d in top, right, bottom, left {
+	.uv-safe-area-inset-#{$d} {
+		padding-#{$d}: 0;
+		padding-#{$d}: constant(safe-area-inset-#{$d});  
+		padding-#{$d}: env(safe-area-inset-#{$d});  
+	}
+}
+
+//提升H5端uni.toast()的层级,避免被uvui的modal等遮盖
+/* #ifdef H5 */
+uni-toast {
+    z-index: 10090;
+}
+uni-toast .uni-toast {
+   z-index: 10090;
+}
+/* #endif */
+
+// 隐藏scroll-view的滚动条
+::-webkit-scrollbar {
+    display: none;  
+    width: 0 !important;  
+    height: 0 !important;  
+    -webkit-appearance: none;  
+    background: transparent;  
+}
+
+$uvui-nvue-style: true !default;
+@if $uvui-nvue-style == false {
+	view, scroll-view, swiper-item {
+		display: flex;
+		flex-direction: column;
+		flex-shrink: 0;
+		flex-grow: 0;
+		flex-basis: auto;
+		align-items: stretch;
+		align-content: flex-start;
+	}
+}

+ 134 - 0
uni_modules/uv-ui-tools/libs/function/colorGradient.js

@@ -0,0 +1,134 @@
+/**
+ * 求两个颜色之间的渐变值
+ * @param {string} startColor 开始的颜色
+ * @param {string} endColor 结束的颜色
+ * @param {number} step 颜色等分的份额
+ * */
+function colorGradient(startColor = 'rgb(0, 0, 0)', endColor = 'rgb(255, 255, 255)', step = 10) {
+    const startRGB = hexToRgb(startColor, false) // 转换为rgb数组模式
+    const startR = startRGB[0]
+    const startG = startRGB[1]
+    const startB = startRGB[2]
+
+    const endRGB = hexToRgb(endColor, false)
+    const endR = endRGB[0]
+    const endG = endRGB[1]
+    const endB = endRGB[2]
+
+    const sR = (endR - startR) / step // 总差值
+    const sG = (endG - startG) / step
+    const sB = (endB - startB) / step
+    const colorArr = []
+    for (let i = 0; i < step; i++) {
+        // 计算每一步的hex值
+        let hex = rgbToHex(`rgb(${Math.round((sR * i + startR))},${Math.round((sG * i + startG))},${Math.round((sB
+			* i + startB))})`)
+        // 确保第一个颜色值为startColor的值
+        if (i === 0) hex = rgbToHex(startColor)
+        // 确保最后一个颜色值为endColor的值
+        if (i === step - 1) hex = rgbToHex(endColor)
+        colorArr.push(hex)
+    }
+    return colorArr
+}
+
+// 将hex表示方式转换为rgb表示方式(这里返回rgb数组模式)
+function hexToRgb(sColor, str = true) {
+    const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+    sColor = String(sColor).toLowerCase()
+    if (sColor && reg.test(sColor)) {
+        if (sColor.length === 4) {
+            let sColorNew = '#'
+            for (let i = 1; i < 4; i += 1) {
+                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
+            }
+            sColor = sColorNew
+        }
+        // 处理六位的颜色值
+        const sColorChange = []
+        for (let i = 1; i < 7; i += 2) {
+            sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
+        }
+        if (!str) {
+            return sColorChange
+        }
+        return `rgb(${sColorChange[0]},${sColorChange[1]},${sColorChange[2]})`
+    } if (/^(rgb|RGB)/.test(sColor)) {
+        const arr = sColor.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
+        return arr.map((val) => Number(val))
+    }
+    return sColor
+}
+
+// 将rgb表示方式转换为hex表示方式
+function rgbToHex(rgb) {
+    const _this = rgb
+    const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+    if (/^(rgb|RGB)/.test(_this)) {
+        const aColor = _this.replace(/(?:\(|\)|rgb|RGB)*/g, '').split(',')
+        let strHex = '#'
+        for (let i = 0; i < aColor.length; i++) {
+            let hex = Number(aColor[i]).toString(16)
+            hex = String(hex).length == 1 ? `${0}${hex}` : hex // 保证每个rgb的值为2位
+            if (hex === '0') {
+                hex += hex
+            }
+            strHex += hex
+        }
+        if (strHex.length !== 7) {
+            strHex = _this
+        }
+        return strHex
+    } if (reg.test(_this)) {
+        const aNum = _this.replace(/#/, '').split('')
+        if (aNum.length === 6) {
+            return _this
+        } if (aNum.length === 3) {
+            let numHex = '#'
+            for (let i = 0; i < aNum.length; i += 1) {
+                numHex += (aNum[i] + aNum[i])
+            }
+            return numHex
+        }
+    } else {
+        return _this
+    }
+}
+
+/**
+* JS颜色十六进制转换为rgb或rgba,返回的格式为 rgba(255,255,255,0.5)字符串
+* sHex为传入的十六进制的色值
+* alpha为rgba的透明度
+*/
+function colorToRgba(color, alpha) {
+    color = rgbToHex(color)
+    // 十六进制颜色值的正则表达式
+    const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
+    /* 16进制颜色转为RGB格式 */
+    let sColor = String(color).toLowerCase()
+    if (sColor && reg.test(sColor)) {
+        if (sColor.length === 4) {
+            let sColorNew = '#'
+            for (let i = 1; i < 4; i += 1) {
+                sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
+            }
+            sColor = sColorNew
+        }
+        // 处理六位的颜色值
+        const sColorChange = []
+        for (let i = 1; i < 7; i += 2) {
+            sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`))
+        }
+        // return sColorChange.join(',')
+        return `rgba(${sColorChange.join(',')},${alpha})`
+    }
+
+    return sColor
+}
+
+export {
+    colorGradient,
+    hexToRgb,
+    rgbToHex,
+    colorToRgba
+}

+ 29 - 0
uni_modules/uv-ui-tools/libs/function/debounce.js

@@ -0,0 +1,29 @@
+let timeout = null
+
+/**
+ * 防抖原理:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
+ *
+ * @param {Function} func 要执行的回调函数
+ * @param {Number} wait 延时的时间
+ * @param {Boolean} immediate 是否立即执行
+ * @return null
+ */
+function debounce(func, wait = 500, immediate = false) {
+    // 清除定时器
+    if (timeout !== null) clearTimeout(timeout)
+    // 立即执行,此类情况一般用不到
+    if (immediate) {
+        const callNow = !timeout
+        timeout = setTimeout(() => {
+            timeout = null
+        }, wait)
+        if (callNow) typeof func === 'function' && func()
+    } else {
+        // 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
+        timeout = setTimeout(() => {
+            typeof func === 'function' && func()
+        }, wait)
+    }
+}
+
+export default debounce

+ 167 - 0
uni_modules/uv-ui-tools/libs/function/digit.js

@@ -0,0 +1,167 @@
+let _boundaryCheckingState = true; // 是否进行越界检查的全局开关
+
+/**
+ * 把错误的数据转正
+ * @private
+ * @example strip(0.09999999999999998)=0.1
+ */
+function strip(num, precision = 15) {
+  return +parseFloat(Number(num).toPrecision(precision));
+}
+
+/**
+ * Return digits length of a number
+ * @private
+ * @param {*number} num Input number
+ */
+function digitLength(num) {
+  // Get digit length of e
+  const eSplit = num.toString().split(/[eE]/);
+  const len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
+  return len > 0 ? len : 0;
+}
+
+/**
+ * 把小数转成整数,如果是小数则放大成整数
+ * @private
+ * @param {*number} num 输入数
+ */
+function float2Fixed(num) {
+  if (num.toString().indexOf('e') === -1) {
+    return Number(num.toString().replace('.', ''));
+  }
+  const dLen = digitLength(num);
+  return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
+}
+
+/**
+ * 检测数字是否越界,如果越界给出提示
+ * @private
+ * @param {*number} num 输入数
+ */
+function checkBoundary(num) {
+  if (_boundaryCheckingState) {
+    if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
+      console.warn(`${num} 超出了精度限制,结果可能不正确`);
+    }
+  }
+}
+
+/**
+ * 把递归操作扁平迭代化
+ * @param {number[]} arr 要操作的数字数组
+ * @param {function} operation 迭代操作
+ * @private
+ */
+function iteratorOperation(arr, operation) {
+  const [num1, num2, ...others] = arr;
+  let res = operation(num1, num2);
+
+  others.forEach((num) => {
+    res = operation(res, num);
+  });
+
+  return res;
+}
+
+/**
+ * 高精度乘法
+ * @export
+ */
+export function times(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, times);
+  }
+
+  const [num1, num2] = nums;
+  const num1Changed = float2Fixed(num1);
+  const num2Changed = float2Fixed(num2);
+  const baseNum = digitLength(num1) + digitLength(num2);
+  const leftValue = num1Changed * num2Changed;
+
+  checkBoundary(leftValue);
+
+  return leftValue / Math.pow(10, baseNum);
+}
+
+/**
+ * 高精度加法
+ * @export
+ */
+export function plus(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, plus);
+  }
+
+  const [num1, num2] = nums;
+  // 取最大的小数位
+  const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
+  // 把小数都转为整数然后再计算
+  return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
+}
+
+/**
+ * 高精度减法
+ * @export
+ */
+export function minus(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, minus);
+  }
+
+  const [num1, num2] = nums;
+  const baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
+  return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
+}
+
+/**
+ * 高精度除法
+ * @export
+ */
+export function divide(...nums) {
+  if (nums.length > 2) {
+    return iteratorOperation(nums, divide);
+  }
+
+  const [num1, num2] = nums;
+  const num1Changed = float2Fixed(num1);
+  const num2Changed = float2Fixed(num2);
+  checkBoundary(num1Changed);
+  checkBoundary(num2Changed);
+  // 重要,这里必须用strip进行修正
+  return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
+}
+
+/**
+ * 四舍五入
+ * @export
+ */
+export function round(num, ratio) {
+  const base = Math.pow(10, ratio);
+  let result = divide(Math.round(Math.abs(times(num, base))), base);
+  if (num < 0 && result !== 0) {
+    result = times(result, -1);
+  }
+  // 位数不足则补0
+  return result;
+}
+
+/**
+ * 是否进行边界检查,默认开启
+ * @param flag 标记开关,true 为开启,false 为关闭,默认为 true
+ * @export
+ */
+export function enableBoundaryChecking(flag = true) {
+  _boundaryCheckingState = flag;
+}
+
+
+export default {
+  times,
+  plus,
+  minus,
+  divide,
+  round,
+  enableBoundaryChecking,
+};
+

+ 734 - 0
uni_modules/uv-ui-tools/libs/function/index.js

@@ -0,0 +1,734 @@
+import { number, empty } from './test.js'
+import { round } from './digit.js'
+/**
+ * @description 如果value小于min,取min;如果value大于max,取max
+ * @param {number} min
+ * @param {number} max
+ * @param {number} value
+ */
+function range(min = 0, max = 0, value = 0) {
+	return Math.max(min, Math.min(max, Number(value)))
+}
+
+/**
+ * @description 用于获取用户传递值的px值  如果用户传递了"xxpx"或者"xxrpx",取出其数值部分,如果是"xxxrpx"还需要用过uni.upx2px进行转换
+ * @param {number|string} value 用户传递值的px值
+ * @param {boolean} unit
+ * @returns {number|string}
+ */
+function getPx(value, unit = false) {
+	if (number(value)) {
+		return unit ? `${value}px` : Number(value)
+	}
+	// 如果带有rpx,先取出其数值部分,再转为px值
+	if (/(rpx|upx)$/.test(value)) {
+		return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value)))
+	}
+	return unit ? `${parseInt(value)}px` : parseInt(value)
+}
+
+/**
+ * @description 进行延时,以达到可以简写代码的目的 比如: await uni.$uv.sleep(20)将会阻塞20ms
+ * @param {number} value 堵塞时间 单位ms 毫秒
+ * @returns {Promise} 返回promise
+ */
+function sleep(value = 30) {
+	return new Promise((resolve) => {
+		setTimeout(() => {
+			resolve()
+		}, value)
+	})
+}
+/**
+ * @description 运行期判断平台
+ * @returns {string} 返回所在平台(小写)
+ * @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台
+ */
+function os() {
+	return uni.getSystemInfoSync().platform.toLowerCase()
+}
+/**
+ * @description 获取系统信息同步接口
+ * @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync
+ */
+function sys() {
+	return uni.getSystemInfoSync()
+}
+
+/**
+ * @description 取一个区间数
+ * @param {Number} min 最小值
+ * @param {Number} max 最大值
+ */
+function random(min, max) {
+	if (min >= 0 && max > 0 && max >= min) {
+		const gab = max - min + 1
+		return Math.floor(Math.random() * gab + min)
+	}
+	return 0
+}
+
+/**
+ * @param {Number} len uuid的长度
+ * @param {Boolean} firstU 将返回的首字母置为"u"
+ * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
+ */
+function guid(len = 32, firstU = true, radix = null) {
+	const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
+	const uuid = []
+	radix = radix || chars.length
+
+	if (len) {
+		// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
+		for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
+	} else {
+		let r
+		// rfc4122标准要求返回的uuid中,某些位为固定的字符
+		uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
+		uuid[14] = '4'
+
+		for (let i = 0; i < 36; i++) {
+			if (!uuid[i]) {
+				r = 0 | Math.random() * 16
+				uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r]
+			}
+		}
+	}
+	// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
+	if (firstU) {
+		uuid.shift()
+		return `u${uuid.join('')}`
+	}
+	return uuid.join('')
+}
+
+/**
+* @description 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法
+   this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx
+   这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name
+   值(默认为undefined),就是查找最顶层的$parent
+*  @param {string|undefined} name 父组件的参数名
+*/
+function $parent(name = undefined) {
+	let parent = this.$parent
+	// 通过while历遍,这里主要是为了H5需要多层解析的问题
+	while (parent) {
+		// 父组件
+		if (parent.$options && parent.$options.name !== name) {
+			// 如果组件的name不相等,继续上一级寻找
+			parent = parent.$parent
+		} else {
+			return parent
+		}
+	}
+	return false
+}
+
+/**
+ * @description 样式转换
+ * 对象转字符串,或者字符串转对象
+ * @param {object | string} customStyle 需要转换的目标
+ * @param {String} target 转换的目的,object-转为对象,string-转为字符串
+ * @returns {object|string}
+ */
+function addStyle(customStyle, target = 'object') {
+	// 字符串转字符串,对象转对象情形,直接返回
+	if (empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' &&
+		typeof(customStyle) === 'string') {
+		return customStyle
+	}
+	// 字符串转对象
+	if (target === 'object') {
+		// 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的
+		customStyle = trim(customStyle)
+		// 根据";"将字符串转为数组形式
+		const styleArray = customStyle.split(';')
+		const style = {}
+		// 历遍数组,拼接成对象
+		for (let i = 0; i < styleArray.length; i++) {
+			// 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤
+			if (styleArray[i]) {
+				const item = styleArray[i].split(':')
+				style[trim(item[0])] = trim(item[1])
+			}
+		}
+		return style
+	}
+	// 这里为对象转字符串形式
+	let string = ''
+	for (const i in customStyle) {
+		// 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名
+		const key = i.replace(/([A-Z])/g, '-$1').toLowerCase()
+		string += `${key}:${customStyle[i]};`
+	}
+	// 去除两端空格
+	return trim(string)
+}
+
+/**
+ * @description 添加单位,如果有rpx,upx,%,px等单位结尾或者值为auto,直接返回,否则加上px单位结尾
+ * @param {string|number} value 需要添加单位的值
+ * @param {string} unit 添加的单位名 比如px
+ */
+function addUnit(value = 'auto', unit = uni?.$uv?.config?.unit ? uni?.$uv?.config?.unit : 'px') {
+	value = String(value)
+	// 用uvui内置验证规则中的number判断是否为数值
+	return number(value) ? `${value}${unit}` : value
+}
+
+/**
+ * @description 深度克隆
+ * @param {object} obj 需要深度克隆的对象
+ * @param cache 缓存
+ * @returns {*} 克隆后的对象或者原值(不是对象)
+ */
+function deepClone(obj, cache = new WeakMap()) {
+	if (obj === null || typeof obj !== 'object') return obj;
+	if (cache.has(obj)) return cache.get(obj);
+	let clone;
+	if (obj instanceof Date) {
+		clone = new Date(obj.getTime());
+	} else if (obj instanceof RegExp) {
+		clone = new RegExp(obj);
+	} else if (obj instanceof Map) {
+		clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));
+	} else if (obj instanceof Set) {
+		clone = new Set(Array.from(obj, value => deepClone(value, cache)));
+	} else if (Array.isArray(obj)) {
+		clone = obj.map(value => deepClone(value, cache));
+	} else if (Object.prototype.toString.call(obj) === '[object Object]') {
+		clone = Object.create(Object.getPrototypeOf(obj));
+		cache.set(obj, clone);
+		for (const [key, value] of Object.entries(obj)) {
+			clone[key] = deepClone(value, cache);
+		}
+	} else {
+		clone = Object.assign({}, obj);
+	}
+	cache.set(obj, clone);
+	return clone;
+}
+
+/**
+ * @description JS对象深度合并
+ * @param {object} target 需要拷贝的对象
+ * @param {object} source 拷贝的来源对象
+ * @returns {object|boolean} 深度合并后的对象或者false(入参有不是对象)
+ */
+function deepMerge(target = {}, source = {}) {
+	target = deepClone(target)
+	if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target;
+	const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target);
+	for (const prop in source) {
+		if (!source.hasOwnProperty(prop)) continue;
+		const sourceValue = source[prop];
+		const targetValue = merged[prop];
+		if (sourceValue instanceof Date) {
+			merged[prop] = new Date(sourceValue);
+		} else if (sourceValue instanceof RegExp) {
+			merged[prop] = new RegExp(sourceValue);
+		} else if (sourceValue instanceof Map) {
+			merged[prop] = new Map(sourceValue);
+		} else if (sourceValue instanceof Set) {
+			merged[prop] = new Set(sourceValue);
+		} else if (typeof sourceValue === 'object' && sourceValue !== null) {
+			merged[prop] = deepMerge(targetValue, sourceValue);
+		} else {
+			merged[prop] = sourceValue;
+		}
+	}
+	return merged;
+}
+
+/**
+ * @description error提示
+ * @param {*} err 错误内容
+ */
+function error(err) {
+	// 开发环境才提示,生产环境不会提示
+	if (process.env.NODE_ENV === 'development') {
+		console.error(`uvui提示:${err}`)
+	}
+}
+
+/**
+ * @description 打乱数组
+ * @param {array} array 需要打乱的数组
+ * @returns {array} 打乱后的数组
+ */
+function randomArray(array = []) {
+	// 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0
+	return array.sort(() => Math.random() - 0.5)
+}
+
+// padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序
+// 所以这里做一个兼容polyfill的兼容处理
+if (!String.prototype.padStart) {
+	// 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解
+	String.prototype.padStart = function(maxLength, fillString = ' ') {
+		if (Object.prototype.toString.call(fillString) !== '[object String]') {
+			throw new TypeError(
+				'fillString must be String'
+			)
+		}
+		const str = this
+		// 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉
+		if (str.length >= maxLength) return String(str)
+
+		const fillLength = maxLength - str.length
+		let times = Math.ceil(fillLength / fillString.length)
+		while (times >>= 1) {
+			fillString += fillString
+			if (times === 1) {
+				fillString += fillString
+			}
+		}
+		return fillString.slice(0, fillLength) + str
+	}
+}
+
+/**
+ * @description 格式化时间
+ * @param {String|Number} dateTime 需要格式化的时间戳
+ * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合 默认yyyy-mm-dd
+ * @returns {string} 返回格式化后的字符串
+ */
+function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
+	let date
+	// 若传入时间为假值,则取当前时间
+	if (!dateTime) {
+		date = new Date()
+	}
+	// 若为unix秒时间戳,则转为毫秒时间戳(逻辑有点奇怪,但不敢改,以保证历史兼容)
+	else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
+		date = new Date(dateTime * 1000)
+	}
+	// 若用户传入字符串格式时间戳,new Date无法解析,需做兼容
+	else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
+		date = new Date(Number(dateTime))
+	}
+	// 处理平台性差异,在Safari/Webkit中,new Date仅支持/作为分割符的字符串时间
+	// 处理 '2022-07-10 01:02:03',跳过 '2022-07-10T01:02:03'
+	else if (typeof dateTime === 'string' && dateTime.includes('-') && !dateTime.includes('T')) {
+		date = new Date(dateTime.replace(/-/g, '/'))
+	}
+	// 其他都认为符合 RFC 2822 规范
+	else {
+		date = new Date(dateTime)
+	}
+
+	const timeSource = {
+		'y': date.getFullYear().toString(), // 年
+		'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月
+		'd': date.getDate().toString().padStart(2, '0'), // 日
+		'h': date.getHours().toString().padStart(2, '0'), // 时
+		'M': date.getMinutes().toString().padStart(2, '0'), // 分
+		's': date.getSeconds().toString().padStart(2, '0') // 秒
+		// 有其他格式化字符需求可以继续添加,必须转化成字符串
+	}
+
+	for (const key in timeSource) {
+		const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
+		if (ret) {
+			// 年可能只需展示两位
+			const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
+			formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
+		}
+	}
+
+	return formatStr
+}
+
+/**
+ * @description 时间戳转为多久之前
+ * @param {String|Number} timestamp 时间戳
+ * @param {String|Boolean} format
+ * 格式化规则如果为时间格式字符串,超出一定时间范围,返回固定的时间格式;
+ * 如果为布尔值false,无论什么时间,都返回多久以前的格式
+ * @returns {string} 转化后的内容
+ */
+function timeFrom(timestamp = null, format = 'yyyy-mm-dd') {
+	if (timestamp == null) timestamp = Number(new Date())
+	timestamp = parseInt(timestamp)
+	// 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位)
+	if (timestamp.toString().length == 10) timestamp *= 1000
+	let timer = (new Date()).getTime() - timestamp
+	timer = parseInt(timer / 1000)
+	// 如果小于5分钟,则返回"刚刚",其他以此类推
+	let tips = ''
+	switch (true) {
+		case timer < 300:
+			tips = '刚刚'
+			break
+		case timer >= 300 && timer < 3600:
+			tips = `${parseInt(timer / 60)}分钟前`
+			break
+		case timer >= 3600 && timer < 86400:
+			tips = `${parseInt(timer / 3600)}小时前`
+			break
+		case timer >= 86400 && timer < 2592000:
+			tips = `${parseInt(timer / 86400)}天前`
+			break
+		default:
+			// 如果format为false,则无论什么时间戳,都显示xx之前
+			if (format === false) {
+				if (timer >= 2592000 && timer < 365 * 86400) {
+					tips = `${parseInt(timer / (86400 * 30))}个月前`
+				} else {
+					tips = `${parseInt(timer / (86400 * 365))}年前`
+				}
+			} else {
+				tips = timeFormat(timestamp, format)
+			}
+	}
+	return tips
+}
+
+/**
+ * @description 去除空格
+ * @param String str 需要去除空格的字符串
+ * @param String pos both(左右)|left|right|all 默认both
+ */
+function trim(str, pos = 'both') {
+	str = String(str)
+	if (pos == 'both') {
+		return str.replace(/^\s+|\s+$/g, '')
+	}
+	if (pos == 'left') {
+		return str.replace(/^\s*/, '')
+	}
+	if (pos == 'right') {
+		return str.replace(/(\s*$)/g, '')
+	}
+	if (pos == 'all') {
+		return str.replace(/\s+/g, '')
+	}
+	return str
+}
+
+/**
+ * @description 对象转url参数
+ * @param {object} data,对象
+ * @param {Boolean} isPrefix,是否自动加上"?"
+ * @param {string} arrayFormat 规则 indices|brackets|repeat|comma
+ */
+function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') {
+	const prefix = isPrefix ? '?' : ''
+	const _result = []
+	if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets'
+	for (const key in data) {
+		const value = data[key]
+		// 去掉为空的参数
+		if (['', undefined, null].indexOf(value) >= 0) {
+			continue
+		}
+		// 如果值为数组,另行处理
+		if (value.constructor === Array) {
+			// e.g. {ids: [1, 2, 3]}
+			switch (arrayFormat) {
+				case 'indices':
+					// 结果: ids[0]=1&ids[1]=2&ids[2]=3
+					for (let i = 0; i < value.length; i++) {
+						_result.push(`${key}[${i}]=${value[i]}`)
+					}
+					break
+				case 'brackets':
+					// 结果: ids[]=1&ids[]=2&ids[]=3
+					value.forEach((_value) => {
+						_result.push(`${key}[]=${_value}`)
+					})
+					break
+				case 'repeat':
+					// 结果: ids=1&ids=2&ids=3
+					value.forEach((_value) => {
+						_result.push(`${key}=${_value}`)
+					})
+					break
+				case 'comma':
+					// 结果: ids=1,2,3
+					let commaStr = ''
+					value.forEach((_value) => {
+						commaStr += (commaStr ? ',' : '') + _value
+					})
+					_result.push(`${key}=${commaStr}`)
+					break
+				default:
+					value.forEach((_value) => {
+						_result.push(`${key}[]=${_value}`)
+					})
+			}
+		} else {
+			_result.push(`${key}=${value}`)
+		}
+	}
+	return _result.length ? prefix + _result.join('&') : ''
+}
+
+/**
+ * 显示消息提示框
+ * @param {String} title 提示的内容,长度与 icon 取值有关。
+ * @param {Number} duration 提示的延迟时间,单位毫秒,默认:2000
+ */
+function toast(title, duration = 2000) {
+	uni.showToast({
+		title: String(title),
+		icon: 'none',
+		duration
+	})
+}
+
+/**
+ * @description 根据主题type值,获取对应的图标
+ * @param {String} type 主题名称,primary|info|error|warning|success
+ * @param {boolean} fill 是否使用fill填充实体的图标
+ */
+function type2icon(type = 'success', fill = false) {
+	// 如果非预置值,默认为success
+	if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success'
+	let iconName = ''
+	// 目前(2019-12-12),info和primary使用同一个图标
+	switch (type) {
+		case 'primary':
+			iconName = 'info-circle'
+			break
+		case 'info':
+			iconName = 'info-circle'
+			break
+		case 'error':
+			iconName = 'close-circle'
+			break
+		case 'warning':
+			iconName = 'error-circle'
+			break
+		case 'success':
+			iconName = 'checkmark-circle'
+			break
+		default:
+			iconName = 'checkmark-circle'
+	}
+	// 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的
+	if (fill) iconName += '-fill'
+	return iconName
+}
+
+/**
+ * @description 数字格式化
+ * @param {number|string} number 要格式化的数字
+ * @param {number} decimals 保留几位小数
+ * @param {string} decimalPoint 小数点符号
+ * @param {string} thousandsSeparator 千分位符号
+ * @returns {string} 格式化后的数字
+ */
+function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') {
+	number = (`${number}`).replace(/[^0-9+-Ee.]/g, '')
+	const n = !isFinite(+number) ? 0 : +number
+	const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals)
+	const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator
+	const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint
+	let s = ''
+
+	s = (prec ? round(n, prec) + '' : `${Math.round(n)}`).split('.')
+	const re = /(-?\d+)(\d{3})/
+	while (re.test(s[0])) {
+		s[0] = s[0].replace(re, `$1${sep}$2`)
+	}
+
+	if ((s[1] || '').length < prec) {
+		s[1] = s[1] || ''
+		s[1] += new Array(prec - s[1].length + 1).join('0')
+	}
+	return s.join(dec)
+}
+
+/**
+ * @description 获取duration值
+ * 如果带有ms或者s直接返回,如果大于一定值,认为是ms单位,小于一定值,认为是s单位
+ * 比如以30位阈值,那么300大于30,可以理解为用户想要的是300ms,而不是想花300s去执行一个动画
+ * @param {String|number} value 比如: "1s"|"100ms"|1|100
+ * @param {boolean} unit  提示: 如果是false 默认返回number
+ * @return {string|number}
+ */
+function getDuration(value, unit = true) {
+	const valueNum = parseInt(value)
+	if (unit) {
+		if (/s$/.test(value)) return value
+		return value > 30 ? `${value}ms` : `${value}s`
+	}
+	if (/ms$/.test(value)) return valueNum
+	if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000
+	return valueNum
+}
+
+/**
+ * @description 日期的月或日补零操作
+ * @param {String} value 需要补零的值
+ */
+function padZero(value) {
+	return `00${value}`.slice(-2)
+}
+
+/**
+ * @description 在uv-form的子组件内容发生变化,或者失去焦点时,尝试通知uv-form执行校验方法
+ * @param {*} instance
+ * @param {*} event
+ */
+function formValidate(instance, event) {
+	const formItem = $parent.call(instance, 'uv-form-item')
+	const form = $parent.call(instance, 'uv-form')
+	// 如果发生变化的input或者textarea等,其父组件中有uv-form-item或者uv-form等,就执行form的validate方法
+	// 同时将form-item的pros传递给form,让其进行精确对象验证
+	if (formItem && form) {
+		form.validateField(formItem.prop, () => {}, event)
+	}
+}
+
+/**
+ * @description 获取某个对象下的属性,用于通过类似'a.b.c'的形式去获取一个对象的的属性的形式
+ * @param {object} obj 对象
+ * @param {string} key 需要获取的属性字段
+ * @returns {*}
+ */
+function getProperty(obj, key) {
+	if (!obj) {
+		return
+	}
+	if (typeof key !== 'string' || key === '') {
+		return ''
+	}
+	if (key.indexOf('.') !== -1) {
+		const keys = key.split('.')
+		let firstObj = obj[keys[0]] || {}
+
+		for (let i = 1; i < keys.length; i++) {
+			if (firstObj) {
+				firstObj = firstObj[keys[i]]
+			}
+		}
+		return firstObj
+	}
+	return obj[key]
+}
+
+/**
+ * @description 设置对象的属性值,如果'a.b.c'的形式进行设置
+ * @param {object} obj 对象
+ * @param {string} key 需要设置的属性
+ * @param {string} value 设置的值
+ */
+function setProperty(obj, key, value) {
+	if (!obj) {
+		return
+	}
+	// 递归赋值
+	const inFn = function(_obj, keys, v) {
+		// 最后一个属性key
+		if (keys.length === 1) {
+			_obj[keys[0]] = v
+			return
+		}
+		// 0~length-1个key
+		while (keys.length > 1) {
+			const k = keys[0]
+			if (!_obj[k] || (typeof _obj[k] !== 'object')) {
+				_obj[k] = {}
+			}
+			const key = keys.shift()
+			// 自调用判断是否存在属性,不存在则自动创建对象
+			inFn(_obj[k], keys, v)
+		}
+	}
+
+	if (typeof key !== 'string' || key === '') {
+
+	} else if (key.indexOf('.') !== -1) { // 支持多层级赋值操作
+		const keys = key.split('.')
+		inFn(obj, keys, value)
+	} else {
+		obj[key] = value
+	}
+}
+
+/**
+ * @description 获取当前页面路径
+ */
+function page() {
+	const pages = getCurrentPages();
+	const route = pages[pages.length - 1]?.route;
+	// 某些特殊情况下(比如页面进行redirectTo时的一些时机),pages可能为空数组
+	return `/${route ? route : ''}`
+}
+
+/**
+ * @description 获取当前路由栈实例数组
+ */
+function pages() {
+	const pages = getCurrentPages()
+	return pages
+}
+
+/**
+ * 获取页面历史栈指定层实例
+ * @param back {number} [0] - 0或者负数,表示获取历史栈的哪一层,0表示获取当前页面实例,-1 表示获取上一个页面实例。默认0。
+ */
+function getHistoryPage(back = 0) {
+	const pages = getCurrentPages()
+	const len = pages.length
+	return pages[len - 1 + back]
+}
+
+
+
+/**
+ * @description 修改uvui内置属性值
+ * @param {object} props 修改内置props属性
+ * @param {object} config 修改内置config属性
+ * @param {object} color 修改内置color属性
+ * @param {object} zIndex 修改内置zIndex属性
+ */
+function setConfig({
+	props = {},
+	config = {},
+	color = {},
+	zIndex = {}
+}) {
+	const {
+		deepMerge,
+	} = uni.$uv
+	uni.$uv.config = deepMerge(uni.$uv.config, config)
+	uni.$uv.props = deepMerge(uni.$uv.props, props)
+	uni.$uv.color = deepMerge(uni.$uv.color, color)
+	uni.$uv.zIndex = deepMerge(uni.$uv.zIndex, zIndex)
+}
+
+export {
+	range,
+	getPx,
+	sleep,
+	os,
+	sys,
+	random,
+	guid,
+	$parent,
+	addStyle,
+	addUnit,
+	deepClone,
+	deepMerge,
+	error,
+	randomArray,
+	timeFormat,
+	timeFrom,
+	trim,
+	queryParams,
+	toast,
+	type2icon,
+	priceFormat,
+	getDuration,
+	padZero,
+	formValidate,
+	getProperty,
+	setProperty,
+	page,
+	pages,
+	getHistoryPage,
+	setConfig
+}

+ 75 - 0
uni_modules/uv-ui-tools/libs/function/platform.js

@@ -0,0 +1,75 @@
+/**
+ * 注意:
+ * 此部分内容,在vue-cli模式下,需要在vue.config.js加入如下内容才有效:
+ * module.exports = {
+ *     transpileDependencies: ['uview-v2']
+ * }
+ */
+
+let platform = 'none'
+
+// #ifdef VUE3
+platform = 'vue3'
+// #endif
+
+// #ifdef VUE2
+platform = 'vue2'
+// #endif
+
+// #ifdef APP-PLUS
+platform = 'plus'
+// #endif
+
+// #ifdef APP-NVUE
+platform = 'nvue'
+// #endif
+
+// #ifdef H5
+platform = 'h5'
+// #endif
+
+// #ifdef MP-WEIXIN
+platform = 'weixin'
+// #endif
+
+// #ifdef MP-ALIPAY
+platform = 'alipay'
+// #endif
+
+// #ifdef MP-BAIDU
+platform = 'baidu'
+// #endif
+
+// #ifdef MP-TOUTIAO
+platform = 'toutiao'
+// #endif
+
+// #ifdef MP-QQ
+platform = 'qq'
+// #endif
+
+// #ifdef MP-KUAISHOU
+platform = 'kuaishou'
+// #endif
+
+// #ifdef MP-360
+platform = '360'
+// #endif
+
+// #ifdef MP
+platform = 'mp'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW
+platform = 'quickapp-webview'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW-HUAWEI
+platform = 'quickapp-webview-huawei'
+// #endif
+
+// #ifdef QUICKAPP-WEBVIEW-UNION
+platform = 'quckapp-webview-union'
+// #endif
+
+export default platform

+ 287 - 0
uni_modules/uv-ui-tools/libs/function/test.js

@@ -0,0 +1,287 @@
+/**
+ * 验证电子邮箱格式
+ */
+function email(value) {
+    return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value)
+}
+
+/**
+ * 验证手机格式
+ */
+function mobile(value) {
+    return /^1([3589]\d|4[5-9]|6[1-2,4-7]|7[0-8])\d{8}$/.test(value)
+}
+
+/**
+ * 验证URL格式
+ */
+function url(value) {
+    return /^((https|http|ftp|rtsp|mms):\/\/)(([0-9a-zA-Z_!~*'().&=+$%-]+: )?[0-9a-zA-Z_!~*'().&=+$%-]+@)?(([0-9]{1,3}.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z].[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/?)|(\/[0-9a-zA-Z_!~*'().;?:@&=+$,%#-]+)+\/?)$/
+        .test(value)
+}
+
+/**
+ * 验证日期格式
+ */
+function date(value) {
+    if (!value) return false
+    // 判断是否数值或者字符串数值(意味着为时间戳),转为数值,否则new Date无法识别字符串时间戳
+    if (number(value)) value = +value
+    return !/Invalid|NaN/.test(new Date(value).toString())
+}
+
+/**
+ * 验证ISO类型的日期格式
+ */
+function dateISO(value) {
+    return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
+}
+
+/**
+ * 验证十进制数字
+ */
+function number(value) {
+    return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
+}
+
+/**
+ * 验证字符串
+ */
+function string(value) {
+    return typeof value === 'string'
+}
+
+/**
+ * 验证整数
+ */
+function digits(value) {
+    return /^\d+$/.test(value)
+}
+
+/**
+ * 验证身份证号码
+ */
+function idCard(value) {
+    return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(
+        value
+    )
+}
+
+/**
+ * 是否车牌号
+ */
+function carNo(value) {
+    // 新能源车牌
+    const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/
+    // 旧车牌
+    const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/
+    if (value.length === 7) {
+        return creg.test(value)
+    } if (value.length === 8) {
+        return xreg.test(value)
+    }
+    return false
+}
+
+/**
+ * 金额,只允许2位小数
+ */
+function amount(value) {
+    // 金额,只允许保留两位小数
+    return /^[1-9]\d*(,\d{3})*(\.\d{1,2})?$|^0\.\d{1,2}$/.test(value)
+}
+
+/**
+ * 中文
+ */
+function chinese(value) {
+    const reg = /^[\u4e00-\u9fa5]+$/gi
+    return reg.test(value)
+}
+
+/**
+ * 只能输入字母
+ */
+function letter(value) {
+    return /^[a-zA-Z]*$/.test(value)
+}
+
+/**
+ * 只能是字母或者数字
+ */
+function enOrNum(value) {
+    // 英文或者数字
+    const reg = /^[0-9a-zA-Z]*$/g
+    return reg.test(value)
+}
+
+/**
+ * 验证是否包含某个值
+ */
+function contains(value, param) {
+    return value.indexOf(param) >= 0
+}
+
+/**
+ * 验证一个值范围[min, max]
+ */
+function range(value, param) {
+    return value >= param[0] && value <= param[1]
+}
+
+/**
+ * 验证一个长度范围[min, max]
+ */
+function rangeLength(value, param) {
+    return value.length >= param[0] && value.length <= param[1]
+}
+
+/**
+ * 是否固定电话
+ */
+function landline(value) {
+    const reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/
+    return reg.test(value)
+}
+
+/**
+ * 判断是否为空
+ */
+function empty(value) {
+    switch (typeof value) {
+    case 'undefined':
+        return true
+    case 'string':
+        if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true
+        break
+    case 'boolean':
+        if (!value) return true
+        break
+    case 'number':
+        if (value === 0 || isNaN(value)) return true
+        break
+    case 'object':
+        if (value === null || value.length === 0) return true
+        for (const i in value) {
+            return false
+        }
+        return true
+    }
+    return false
+}
+
+/**
+ * 是否json字符串
+ */
+function jsonString(value) {
+    if (typeof value === 'string') {
+        try {
+            const obj = JSON.parse(value)
+            if (typeof obj === 'object' && obj) {
+                return true
+            }
+            return false
+        } catch (e) {
+            return false
+        }
+    }
+    return false
+}
+
+/**
+ * 是否数组
+ */
+function array(value) {
+    if (typeof Array.isArray === 'function') {
+        return Array.isArray(value)
+    }
+    return Object.prototype.toString.call(value) === '[object Array]'
+}
+
+/**
+ * 是否对象
+ */
+function object(value) {
+    return Object.prototype.toString.call(value) === '[object Object]'
+}
+
+/**
+ * 是否短信验证码
+ */
+function code(value, len = 6) {
+    return new RegExp(`^\\d{${len}}$`).test(value)
+}
+
+/**
+ * 是否函数方法
+ * @param {Object} value
+ */
+function func(value) {
+    return typeof value === 'function'
+}
+
+/**
+ * 是否promise对象
+ * @param {Object} value
+ */
+function promise(value) {
+    return object(value) && func(value.then) && func(value.catch)
+}
+
+/** 是否图片格式
+ * @param {Object} value
+ */
+function image(value) {
+    const newValue = value.split('?')[0]
+    const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i
+    return IMAGE_REGEXP.test(newValue)
+}
+
+/**
+ * 是否视频格式
+ * @param {Object} value
+ */
+function video(value) {
+    const VIDEO_REGEXP = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i
+    return VIDEO_REGEXP.test(value)
+}
+
+/**
+ * 是否为正则对象
+ * @param {Object}
+ * @return {Boolean}
+ */
+function regExp(o) {
+    return o && Object.prototype.toString.call(o) === '[object RegExp]'
+}
+
+export {
+    email,
+    mobile,
+    url,
+    date,
+    dateISO,
+    number,
+    digits,
+    idCard,
+    carNo,
+    amount,
+    chinese,
+    letter,
+    enOrNum,
+    contains,
+    range,
+    rangeLength,
+    empty,
+    jsonString,
+    landline,
+    object,
+    array,
+    code,
+    func,
+    promise,
+    video,
+    image,
+    regExp,
+    string
+}

+ 30 - 0
uni_modules/uv-ui-tools/libs/function/throttle.js

@@ -0,0 +1,30 @@
+let timer; let
+    flag
+/**
+ * 节流原理:在一定时间内,只能触发一次
+ *
+ * @param {Function} func 要执行的回调函数
+ * @param {Number} wait 延时的时间
+ * @param {Boolean} immediate 是否立即执行
+ * @return null
+ */
+function throttle(func, wait = 500, immediate = true) {
+    if (immediate) {
+        if (!flag) {
+            flag = true
+            // 如果是立即执行,则在wait毫秒内开始时执行
+            typeof func === 'function' && func()
+            timer = setTimeout(() => {
+                flag = false
+            }, wait)
+        }
+    } else if (!flag) {
+        flag = true
+        // 如果是非立即执行,则在wait毫秒内的结束处执行
+        timer = setTimeout(() => {
+            flag = false
+            typeof func === 'function' && func()
+        }, wait)
+    }
+}
+export default throttle

+ 132 - 0
uni_modules/uv-ui-tools/libs/luch-request/adapters/index.js

@@ -0,0 +1,132 @@
+import buildURL from '../helpers/buildURL'
+import buildFullPath from '../core/buildFullPath'
+import settle from '../core/settle'
+import {isUndefined} from "../utils"
+
+/**
+ * 返回可选值存在的配置
+ * @param {Array} keys - 可选值数组
+ * @param {Object} config2 - 配置
+ * @return {{}} - 存在的配置项
+ */
+const mergeKeys = (keys, config2) => {
+  let config = {}
+  keys.forEach(prop => {
+    if (!isUndefined(config2[prop])) {
+      config[prop] = config2[prop]
+    }
+  })
+  return config
+}
+export default (config) => {
+  return new Promise((resolve, reject) => {
+    let fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params, config.paramsSerializer)
+    const _config = {
+      url: fullPath,
+      header: config.header,
+      complete: (response) => {
+        config.fullPath = fullPath
+        response.config = config
+        response.rawData = response.data
+        try {
+          let jsonParseHandle = false
+          const forcedJSONParsingType = typeof config.forcedJSONParsing
+          if (forcedJSONParsingType === 'boolean') {
+            jsonParseHandle = config.forcedJSONParsing
+          } else if (forcedJSONParsingType === 'object') {
+            const includesMethod = config.forcedJSONParsing.include || []
+            jsonParseHandle = includesMethod.includes(config.method)
+          }
+
+          // 对可能字符串不是json 的情况容错
+          if (jsonParseHandle && typeof response.data === 'string') {
+            response.data = JSON.parse(response.data)
+          }
+          // eslint-disable-next-line no-empty
+        } catch (e) {
+        }
+        settle(resolve, reject, response)
+      }
+    }
+    let requestTask
+    if (config.method === 'UPLOAD') {
+      delete _config.header['content-type']
+      delete _config.header['Content-Type']
+      let otherConfig = {
+        // #ifdef MP-ALIPAY
+        fileType: config.fileType,
+        // #endif
+        filePath: config.filePath,
+        name: config.name
+      }
+      const optionalKeys = [
+        // #ifdef APP-PLUS || H5
+        'files',
+        // #endif
+        // #ifdef H5
+        'file',
+        // #endif
+        // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+        'timeout',
+        // #endif
+        'formData'
+      ]
+      requestTask = uni.uploadFile({..._config, ...otherConfig, ...mergeKeys(optionalKeys, config)})
+    } else if (config.method === 'DOWNLOAD') {
+      const optionalKeys = [
+        // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+        'timeout',
+        // #endif
+        // #ifdef MP
+        'filePath',
+        // #endif
+      ]
+      requestTask = uni.downloadFile({..._config, ...mergeKeys(optionalKeys, config)})
+    } else {
+      const optionalKeys = [
+        'data',
+        'method',
+        // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+        'timeout',
+        // #endif
+        'dataType',
+        // #ifndef MP-ALIPAY
+        'responseType',
+        // #endif
+        // #ifdef APP-PLUS
+        'sslVerify',
+        // #endif
+        // #ifdef H5
+        'withCredentials',
+        // #endif
+        // #ifdef APP-PLUS
+        'firstIpv4',
+        // #endif
+        // #ifdef MP-WEIXIN
+        'enableHttp2',
+        'enableQuic',
+        // #endif
+        // #ifdef MP-TOUTIAO || MP-WEIXIN
+        'enableCache',
+        // #endif
+        // #ifdef MP-WEIXIN
+        'enableHttpDNS',
+        'httpDNSServiceId',
+        'enableChunked',
+        'forceCellularNetwork',
+        // #endif
+        // #ifdef MP-ALIPAY
+        'enableCookie',
+        // #endif
+        // #ifdef MP-BAIDU
+        'cloudCache',
+        'defer'
+        // #endif
+      ]
+      requestTask = uni.request({..._config, ...mergeKeys(optionalKeys, config)})
+    }
+    if (config.getTask) {
+      config.getTask(requestTask, config)
+    }
+  })
+}

+ 51 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/InterceptorManager.js

@@ -0,0 +1,51 @@
+'use strict'
+
+
+function InterceptorManager() {
+  this.handlers = []
+}
+
+/**
+ * Add a new interceptor to the stack
+ *
+ * @param {Function} fulfilled The function to handle `then` for a `Promise`
+ * @param {Function} rejected The function to handle `reject` for a `Promise`
+ *
+ * @return {Number} An ID used to remove interceptor later
+ */
+InterceptorManager.prototype.use = function use(fulfilled, rejected) {
+  this.handlers.push({
+    fulfilled: fulfilled,
+    rejected: rejected
+  })
+  return this.handlers.length - 1
+}
+
+/**
+ * Remove an interceptor from the stack
+ *
+ * @param {Number} id The ID that was returned by `use`
+ */
+InterceptorManager.prototype.eject = function eject(id) {
+  if (this.handlers[id]) {
+    this.handlers[id] = null
+  }
+}
+
+/**
+ * Iterate over all the registered interceptors
+ *
+ * This method is particularly useful for skipping over any
+ * interceptors that may have become `null` calling `eject`.
+ *
+ * @param {Function} fn The function to call for each interceptor
+ */
+InterceptorManager.prototype.forEach = function forEach(fn) {
+  this.handlers.forEach(h => {
+    if (h !== null) {
+      fn(h)
+    }
+  })
+}
+
+export default InterceptorManager

+ 201 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/Request.js

@@ -0,0 +1,201 @@
+/**
+ * @Class Request
+ * @description luch-request http请求插件
+ * @Author lu-ch
+ * @Email webwork.s@qq.com
+ * 文档: https://www.quanzhan.co/luch-request/
+ * github: https://github.com/lei-mu/luch-request
+ * DCloud: http://ext.dcloud.net.cn/plugin?id=392
+ */
+
+
+import dispatchRequest from './dispatchRequest'
+import InterceptorManager from './InterceptorManager'
+import mergeConfig from './mergeConfig'
+import defaults from './defaults'
+import { isPlainObject } from '../utils'
+import clone from '../utils/clone'
+
+export default class Request {
+  /**
+   * @param {Object} arg - 全局配置
+   * @param {String} arg.baseURL - 全局根路径
+   * @param {Object} arg.header - 全局header
+   * @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
+   * @param {String} arg.dataType = [json] - 全局默认的dataType
+   * @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
+   * @param {Object} arg.custom - 全局默认的自定义参数
+   * @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
+   * @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
+   * @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
+   * @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
+   * @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
+   */
+  constructor(arg = {}) {
+    if (!isPlainObject(arg)) {
+      arg = {}
+      console.warn('设置全局参数必须接收一个Object')
+    }
+    this.config = clone({...defaults, ...arg})
+    this.interceptors = {
+      request: new InterceptorManager(),
+      response: new InterceptorManager()
+    }
+  }
+
+  /**
+   * @Function
+   * @param {Request~setConfigCallback} f - 设置全局默认配置
+   */
+  setConfig(f) {
+    this.config = f(this.config)
+  }
+
+  middleware(config) {
+    config = mergeConfig(this.config, config)
+    let chain = [dispatchRequest, undefined]
+    let promise = Promise.resolve(config)
+
+    this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
+      chain.unshift(interceptor.fulfilled, interceptor.rejected)
+    })
+
+    this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
+      chain.push(interceptor.fulfilled, interceptor.rejected)
+    })
+
+    while (chain.length) {
+      promise = promise.then(chain.shift(), chain.shift())
+    }
+
+    return promise
+  }
+
+  /**
+   * @Function
+   * @param {Object} config - 请求配置项
+   * @prop {String} options.url - 请求路径
+   * @prop {Object} options.data - 请求参数
+   * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
+   * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
+   * @prop {Object} [options.header = config.header] - 请求header
+   * @prop {Object} [options.method = config.method] - 请求方法
+   * @returns {Promise<unknown>}
+   */
+  request(config = {}) {
+    return this.middleware(config)
+  }
+
+  get(url, options = {}) {
+    return this.middleware({
+      url,
+      method: 'GET',
+      ...options
+    })
+  }
+
+  post(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'POST',
+      ...options
+    })
+  }
+
+  // #ifndef MP-ALIPAY || MP-KUAISHOU || MP-JD
+  put(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'PUT',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+  delete(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'DELETE',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef H5 || MP-WEIXIN
+  connect(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'CONNECT',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef  H5 || MP-WEIXIN || MP-BAIDU
+  head(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'HEAD',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
+  options(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'OPTIONS',
+      ...options
+    })
+  }
+
+  // #endif
+
+  // #ifdef H5 || MP-WEIXIN
+  trace(url, data, options = {}) {
+    return this.middleware({
+      url,
+      data,
+      method: 'TRACE',
+      ...options
+    })
+  }
+
+  // #endif
+
+  upload(url, config = {}) {
+    config.url = url
+    config.method = 'UPLOAD'
+    return this.middleware(config)
+  }
+
+  download(url, config = {}) {
+    config.url = url
+    config.method = 'DOWNLOAD'
+    return this.middleware(config)
+  }
+
+  get version () {
+    return '3.1.0'
+  }
+}
+
+
+/**
+ * setConfig回调
+ * @return {Object} - 返回操作后的config
+ * @callback Request~setConfigCallback
+ * @param {Object} config - 全局默认config
+ */

+ 20 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/buildFullPath.js

@@ -0,0 +1,20 @@
+'use strict'
+
+import isAbsoluteURL from '../helpers/isAbsoluteURL'
+import combineURLs from '../helpers/combineURLs'
+
+/**
+ * Creates a new URL by combining the baseURL with the requestedURL,
+ * only when the requestedURL is not already an absolute URL.
+ * If the requestURL is absolute, this function returns the requestedURL untouched.
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} requestedURL Absolute or relative URL to combine
+ * @returns {string} The combined full path
+ */
+export default function buildFullPath(baseURL, requestedURL) {
+  if (baseURL && !isAbsoluteURL(requestedURL)) {
+    return combineURLs(baseURL, requestedURL)
+  }
+  return requestedURL
+}

+ 33 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/defaults.js

@@ -0,0 +1,33 @@
+/**
+ * 默认的全局配置
+ */
+
+
+export default {
+  baseURL: '',
+  header: {},
+  method: 'GET',
+  dataType: 'json',
+  paramsSerializer: null,
+  // #ifndef MP-ALIPAY
+  responseType: 'text',
+  // #endif
+  custom: {},
+  // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+  timeout: 60000,
+  // #endif
+  // #ifdef APP-PLUS
+  sslVerify: true,
+  // #endif
+  // #ifdef H5
+  withCredentials: false,
+  // #endif
+  // #ifdef APP-PLUS
+  firstIpv4: false,
+  // #endif
+  validateStatus: function validateStatus(status) {
+    return status >= 200 && status < 300
+  },
+  // 是否尝试将响应数据json化
+  forcedJSONParsing: true
+}

+ 6 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/dispatchRequest.js

@@ -0,0 +1,6 @@
+import adapter from '../adapters/index'
+
+
+export default (config) => {
+  return adapter(config)
+}

+ 126 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/mergeConfig.js

@@ -0,0 +1,126 @@
+import {deepMerge, isUndefined} from '../utils'
+
+/**
+ * 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
+ * @param {Array} keys - 配置项
+ * @param {Object} globalsConfig - 当前的全局配置
+ * @param {Object} config2 - 局部配置
+ * @return {{}}
+ */
+const mergeKeys = (keys, globalsConfig, config2) => {
+  let config = {}
+  keys.forEach(prop => {
+    if (!isUndefined(config2[prop])) {
+      config[prop] = config2[prop]
+    } else if (!isUndefined(globalsConfig[prop])) {
+      config[prop] = globalsConfig[prop]
+    }
+  })
+  return config
+}
+/**
+ *
+ * @param globalsConfig - 当前实例的全局配置
+ * @param config2 - 当前的局部配置
+ * @return - 合并后的配置
+ */
+export default (globalsConfig, config2 = {}) => {
+  const method = config2.method || globalsConfig.method || 'GET'
+  let config = {
+    baseURL: config2.baseURL || globalsConfig.baseURL || '',
+    method: method,
+    url: config2.url || '',
+    params: config2.params || {},
+    custom: {...(globalsConfig.custom || {}), ...(config2.custom || {})},
+    header: deepMerge(globalsConfig.header || {}, config2.header || {})
+  }
+  const defaultToConfig2Keys = ['getTask', 'validateStatus', 'paramsSerializer', 'forcedJSONParsing']
+  config = {...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2)}
+
+  // eslint-disable-next-line no-empty
+  if (method === 'DOWNLOAD') {
+    const downloadKeys = [
+      // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+      'timeout',
+      // #endif
+      // #ifdef MP
+      'filePath',
+      // #endif
+    ]
+    config = {...config, ...mergeKeys(downloadKeys, globalsConfig, config2)}
+  } else if (method === 'UPLOAD') {
+    delete config.header['content-type']
+    delete config.header['Content-Type']
+    const uploadKeys = [
+      // #ifdef APP-PLUS || H5
+      'files',
+      // #endif
+      // #ifdef MP-ALIPAY
+      'fileType',
+      // #endif
+      // #ifdef H5
+      'file',
+      // #endif
+      'filePath',
+      'name',
+      // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+      'timeout',
+      // #endif
+      'formData',
+    ]
+    uploadKeys.forEach(prop => {
+      if (!isUndefined(config2[prop])) {
+        config[prop] = config2[prop]
+      }
+    })
+    // #ifdef H5 || APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-TOUTIAO || MP-KUAISHOU
+    if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
+      config['timeout'] = globalsConfig['timeout']
+    }
+    // #endif
+  } else {
+    const defaultsKeys = [
+      'data',
+      // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
+      'timeout',
+      // #endif
+      'dataType',
+      // #ifndef MP-ALIPAY
+      'responseType',
+      // #endif
+      // #ifdef APP-PLUS
+      'sslVerify',
+      // #endif
+      // #ifdef H5
+      'withCredentials',
+      // #endif
+      // #ifdef APP-PLUS
+      'firstIpv4',
+      // #endif
+      // #ifdef MP-WEIXIN
+      'enableHttp2',
+      'enableQuic',
+      // #endif
+      // #ifdef MP-TOUTIAO || MP-WEIXIN
+      'enableCache',
+      // #endif
+      // #ifdef MP-WEIXIN
+      'enableHttpDNS',
+      'httpDNSServiceId',
+      'enableChunked',
+      'forceCellularNetwork',
+      // #endif
+      // #ifdef MP-ALIPAY
+      'enableCookie',
+      // #endif
+      // #ifdef MP-BAIDU
+      'cloudCache',
+      'defer'
+      // #endif
+
+    ]
+    config = {...config, ...mergeKeys(defaultsKeys, globalsConfig, config2)}
+  }
+
+  return config
+}

+ 16 - 0
uni_modules/uv-ui-tools/libs/luch-request/core/settle.js

@@ -0,0 +1,16 @@
+/**
+ * Resolve or reject a Promise based on response status.
+ *
+ * @param {Function} resolve A function that resolves the promise.
+ * @param {Function} reject A function that rejects the promise.
+ * @param {object} response The response.
+ */
+export default function settle(resolve, reject, response) {
+  const validateStatus = response.config.validateStatus
+  const status = response.statusCode
+  if (status && (!validateStatus || validateStatus(status))) {
+    resolve(response)
+  } else {
+    reject(response)
+  }
+}

+ 64 - 0
uni_modules/uv-ui-tools/libs/luch-request/helpers/buildURL.js

@@ -0,0 +1,64 @@
+'use strict'
+
+import * as utils from './../utils'
+
+function encode(val) {
+  return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
+}
+
+/**
+ * Build a URL by appending params to the end
+ *
+ * @param {string} url The base of the url (e.g., http://www.google.com)
+ * @param {object} [params] The params to be appended
+ * @returns {string} The formatted url
+ */
+export default function buildURL(url, params, paramsSerializer) {
+  /*eslint no-param-reassign:0*/
+  if (!params) {
+    return url
+  }
+
+  var serializedParams
+  if (paramsSerializer) {
+    serializedParams = paramsSerializer(params)
+  } else if (utils.isURLSearchParams(params)) {
+    serializedParams = params.toString()
+  } else {
+    var parts = []
+
+    utils.forEach(params, function serialize(val, key) {
+      if (val === null || typeof val === 'undefined') {
+        return
+      }
+
+      if (utils.isArray(val)) {
+        key = key + '[]'
+      } else {
+        val = [val]
+      }
+
+      utils.forEach(val, function parseValue(v) {
+        if (utils.isDate(v)) {
+          v = v.toISOString()
+        } else if (utils.isObject(v)) {
+          v = JSON.stringify(v)
+        }
+        parts.push(encode(key) + '=' + encode(v))
+      })
+    })
+
+    serializedParams = parts.join('&')
+  }
+
+  if (serializedParams) {
+    var hashmarkIndex = url.indexOf('#')
+    if (hashmarkIndex !== -1) {
+      url = url.slice(0, hashmarkIndex)
+    }
+
+    url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
+  }
+
+  return url
+}

+ 14 - 0
uni_modules/uv-ui-tools/libs/luch-request/helpers/combineURLs.js

@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Creates a new URL by combining the specified URLs
+ *
+ * @param {string} baseURL The base URL
+ * @param {string} relativeURL The relative URL
+ * @returns {string} The combined URL
+ */
+export default function combineURLs(baseURL, relativeURL) {
+  return relativeURL
+    ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
+    : baseURL
+}

+ 14 - 0
uni_modules/uv-ui-tools/libs/luch-request/helpers/isAbsoluteURL.js

@@ -0,0 +1,14 @@
+'use strict'
+
+/**
+ * Determines whether the specified URL is absolute
+ *
+ * @param {string} url The URL to test
+ * @returns {boolean} True if the specified URL is absolute, otherwise false
+ */
+export default function isAbsoluteURL(url) {
+  // A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
+  // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
+  // by any combination of letters, digits, plus, period, or hyphen.
+  return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url)
+}

+ 197 - 0
uni_modules/uv-ui-tools/libs/luch-request/index.d.ts

@@ -0,0 +1,197 @@
+export type HttpTask = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask;
+
+export type HttpRequestTask = UniApp.RequestTask;
+
+export type HttpUploadTask = UniApp.UploadTask;
+
+export type HttpDownloadTask = UniApp.DownloadTask;
+
+export type HttpMethod =
+    "GET"
+    | "POST"
+    | "PUT"
+    | "DELETE"
+    | "CONNECT"
+    | "HEAD"
+    | "OPTIONS"
+    | "TRACE"
+    | "UPLOAD"
+    | "DOWNLOAD";
+
+export type HttpRequestHeader = Record<string, string>;
+
+export type HttpParams = Record<string, any>;
+
+export type HttpData = Record<string, any>;
+
+export type HttpResponseType = 'arraybuffer' | 'text';
+
+export type HttpCustom = Record<string, any>;
+
+export type HttpFileType = 'image' | 'video' | 'audio';
+
+export type HttpFormData = Record<string, any>;
+
+export type HttpResponseHeader = Record<string, string> & {
+    "set-cookie"?: string[]
+};
+
+export interface HttpRequestConfig<T = HttpTask> {
+    /** @desc 请求服务器接口地址 */
+    url?: string;
+    /** @desc 请求方式,默认为 GET */
+    method?: HttpMethod;
+    /** @desc 请求基地址 */
+    baseURL?: string;
+    /** @desc 请求头信息,不能设置 Referer,App、H5 端会自动带上 cookie,且 H5 端不可手动修改 */
+    header?: HttpRequestHeader;
+    /** @desc 请求查询参数,自动拼接为查询字符串 */
+    params?: HttpParams;
+    /** @desc 请求体参数 */
+    data?: HttpData;
+    /** @desc 超时时间,单位 ms,默认为 60000,仅 H5 (HBuilderX 2.9.9+)、APP (HBuilderX 2.9.9+)、微信小程序 (2.10.0)、支付宝小程序支持 */
+    timeout?: number;
+    /** @desc 跨域请求时是否携带凭证 (cookies),默认为 false,仅 H5 (HBuilderX 2.6.15+) 支持 */
+    withCredentials?: boolean;
+    /** @desc 设置响应的数据类型,支付宝小程序不支持 */
+    responseType?: HttpResponseType;
+    /** @desc 全局自定义验证器 */
+    validateStatus?: ((statusCode: number) => boolean) | null;
+
+
+    /** params 参数自定义处理 */
+    paramsSerializer?: (params: AnyObject) => string | void;
+
+    /** @desc 默认为 json,如果设为 json,会尝试对返回的数据做一次 JSON.parse */
+    dataType?: string;
+    /** @desc DNS 解析时是否优先使用 ipv4,默认为 false,仅 App-Android (HBuilderX 2.8.0+) 支持 */
+    firstIpv4?: boolean;
+    /** @desc 是否验证 SSL 证书,默认为 true,仅 App-Android (HBuilderX 2.3.3+) 支持 */
+    sslVerify?: boolean;
+
+    /** @desc 开启 http2;微信小程序 */
+    enableHttp2?: boolean;
+
+    /** @desc 开启 quic;微信小程序 */
+    enableQuic?: boolean;
+    /** @desc 开启 cache;微信小程序、字节跳动小程序 2.31.0+ */
+    enableCache?: boolean;
+    /** @desc 开启 httpDNS;微信小程序 */
+    enableHttpDNS?: boolean;
+    /** @desc httpDNS 服务商;微信小程序 */
+    httpDNSServiceId?: string;
+    /** @desc 开启 transfer-encoding chunked;微信小程序 */
+    enableChunked?: boolean;
+    /** @desc wifi下使用移动网络发送请求;微信小程序 */
+    forceCellularNetwork?: boolean;
+    /** @desc 开启后可在headers中编辑cookie;支付宝小程序 10.2.33+ */
+    enableCookie?: boolean;
+    /** @desc 是否开启云加速;百度小程序 3.310.11+ */
+    cloudCache?: boolean | object;
+    /** @desc 控制当前请求是否延时至首屏内容渲染后发送;百度小程序 3.310.11+ */
+    defer?: boolean;
+
+    /** @desc 自定义参数 */
+    custom?: HttpCustom;
+
+    /** @desc 返回当前请求的 task 和 options,不要在这里修改 options */
+    getTask?: (task: T, options: HttpRequestConfig<T>) => void;
+
+    /** @desc 需要上传的文件列表,使用 files 时,filePath 和 name 不生效,仅支持 App、H5 (2.6.15+) */
+    files?: { name?: string; file?: File; uri: string; }[];
+    /** @desc 文件类型,仅支付宝小程序支持且为必填项 */
+    fileType?: HttpFileType;
+    /** @desc 要上传的文件对象,仅 H5 (2.6.15+) 支持 */
+    file?: File;
+    /** @desc 要上传文件资源的路径,使用 files 时,filePath 和 name 不生效 */
+    filePath?: string;
+    /** @desc 文件对应的 key,开发者在服务器端通过这个 key 可以获取到文件二进制内容,使用 files 时,filePath 和 name 不生效 */
+    name?: string;
+    /** @desc 请求中其他额外的 form data */
+    formData?: HttpFormData;
+}
+
+export interface HttpResponse<T = any, D = HttpTask> {
+    data: T;
+    statusCode: number;
+    header: HttpResponseHeader;
+    config: HttpRequestConfig<D>;
+    cookies: string[];
+    errMsg: string;
+    rawData: any;
+}
+
+export interface HttpUploadResponse<T = any, D = HttpTask> {
+    data: T;
+    statusCode: number;
+    config: HttpRequestConfig<D>;
+    errMsg: string;
+    rawData: any;
+}
+
+export interface HttpDownloadResponse extends HttpResponse {
+    tempFilePath: string;
+    apFilePath?: string;
+    filePath?: string;
+    fileContent?: string;
+}
+
+export interface HttpError<T = any, D = HttpTask> {
+    data?: T;
+    statusCode?: number;
+    header?: HttpResponseHeader;
+    config: HttpRequestConfig<D>;
+    cookies?: string[];
+    errMsg: string;
+}
+
+export interface HttpPromise<T = any> extends Promise<HttpResponse<T>> {
+}
+
+export interface HttpInterceptorManager<V, E = V> {
+    use(onFulfilled?: (value: V) => V | Promise<V>, onRejected?: (error: E) => T | Promise<E>): void;
+
+    eject(id: number): void;
+}
+
+export abstract class HttpRequestAbstract {
+    constructor(config?: HttpRequestConfig);
+
+    interceptors: {
+        request: HttpInterceptorManager<HttpRequestConfig>;
+        response: HttpInterceptorManager<HttpResponse, HttpError>;
+    }
+
+    request<T = any, R = HttpResponse<T>, D = HttpRequestTask>(config: HttpRequestConfig<D>): Promise<R>;
+
+    get<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
+
+    delete<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    head<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    options<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    post<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    put<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    config: HttpRequestConfig;
+
+    setConfig<D = HttpTask>(onSend: (config: HttpRequestConfig<D>) => HttpRequestConfig<D>): void;
+
+    connect<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    trace<T = any, R = HttpResponse<T>, D = HttpRequestTask>(url: string, data?: HttpData, config?: HttpRequestConfig<D>): Promise<R>;
+
+    upload<T = any, R = HttpUploadResponse<T>, D = HttpUploadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
+
+    download<T = any, R = HttpDownloadResponse<T>, D = HttpDownloadTask>(url: string, config?: HttpRequestConfig<D>): Promise<R>;
+
+    middleware<T = any, R = HttpResponse<T>, D = HttpTask>(config: HttpRequestConfig<D>): Promise<R>;
+}
+
+declare class HttpRequest extends HttpRequestAbstract {
+}
+
+export default HttpRequest;

+ 2 - 0
uni_modules/uv-ui-tools/libs/luch-request/index.js

@@ -0,0 +1,2 @@
+import Request from './core/Request'
+export default Request

+ 135 - 0
uni_modules/uv-ui-tools/libs/luch-request/utils.js

@@ -0,0 +1,135 @@
+'use strict'
+
+// utils is a library of generic helper functions non-specific to axios
+
+var toString = Object.prototype.toString
+
+/**
+ * Determine if a value is an Array
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Array, otherwise false
+ */
+export function isArray (val) {
+  return toString.call(val) === '[object Array]'
+}
+
+
+/**
+ * Determine if a value is an Object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is an Object, otherwise false
+ */
+export function isObject (val) {
+  return val !== null && typeof val === 'object'
+}
+
+/**
+ * Determine if a value is a Date
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a Date, otherwise false
+ */
+export function isDate (val) {
+  return toString.call(val) === '[object Date]'
+}
+
+/**
+ * Determine if a value is a URLSearchParams object
+ *
+ * @param {Object} val The value to test
+ * @returns {boolean} True if value is a URLSearchParams object, otherwise false
+ */
+export function isURLSearchParams (val) {
+  return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams
+}
+
+
+/**
+ * Iterate over an Array or an Object invoking a function for each item.
+ *
+ * If `obj` is an Array callback will be called passing
+ * the value, index, and complete array for each item.
+ *
+ * If 'obj' is an Object callback will be called passing
+ * the value, key, and complete object for each property.
+ *
+ * @param {Object|Array} obj The object to iterate
+ * @param {Function} fn The callback to invoke for each item
+ */
+export function forEach (obj, fn) {
+  // Don't bother if no value provided
+  if (obj === null || typeof obj === 'undefined') {
+    return
+  }
+
+  // Force an array if not already something iterable
+  if (typeof obj !== 'object') {
+    /*eslint no-param-reassign:0*/
+    obj = [obj]
+  }
+
+  if (isArray(obj)) {
+    // Iterate over array values
+    for (var i = 0, l = obj.length; i < l; i++) {
+      fn.call(null, obj[i], i, obj)
+    }
+  } else {
+    // Iterate over object keys
+    for (var key in obj) {
+      if (Object.prototype.hasOwnProperty.call(obj, key)) {
+        fn.call(null, obj[key], key, obj)
+      }
+    }
+  }
+}
+
+/**
+ * 是否为boolean 值
+ * @param val
+ * @returns {boolean}
+ */
+export function isBoolean(val) {
+  return typeof val === 'boolean'
+}
+
+/**
+ * 是否为真正的对象{} new Object
+ * @param {any} obj - 检测的对象
+ * @returns {boolean}
+ */
+export function isPlainObject(obj) {
+  return Object.prototype.toString.call(obj) === '[object Object]'
+}
+
+
+
+/**
+ * Function equal to merge with the difference being that no reference
+ * to original objects is kept.
+ *
+ * @see merge
+ * @param {Object} obj1 Object to merge
+ * @returns {Object} Result of all merge properties
+ */
+export function deepMerge(/* obj1, obj2, obj3, ... */) {
+  let result = {}
+  function assignValue(val, key) {
+    if (typeof result[key] === 'object' && typeof val === 'object') {
+      result[key] = deepMerge(result[key], val)
+    } else if (typeof val === 'object') {
+      result[key] = deepMerge({}, val)
+    } else {
+      result[key] = val
+    }
+  }
+  for (let i = 0, l = arguments.length; i < l; i++) {
+    forEach(arguments[i], assignValue)
+  }
+  return result
+}
+
+export function isUndefined (val) {
+  return typeof val === 'undefined'
+}

+ 264 - 0
uni_modules/uv-ui-tools/libs/luch-request/utils/clone.js

@@ -0,0 +1,264 @@
+/* eslint-disable */
+var clone = (function() {
+  'use strict';
+
+  function _instanceof(obj, type) {
+    return type != null && obj instanceof type;
+  }
+
+  var nativeMap;
+  try {
+    nativeMap = Map;
+  } catch(_) {
+    // maybe a reference error because no `Map`. Give it a dummy value that no
+    // value will ever be an instanceof.
+    nativeMap = function() {};
+  }
+
+  var nativeSet;
+  try {
+    nativeSet = Set;
+  } catch(_) {
+    nativeSet = function() {};
+  }
+
+  var nativePromise;
+  try {
+    nativePromise = Promise;
+  } catch(_) {
+    nativePromise = function() {};
+  }
+
+  /**
+   * Clones (copies) an Object using deep copying.
+   *
+   * This function supports circular references by default, but if you are certain
+   * there are no circular references in your object, you can save some CPU time
+   * by calling clone(obj, false).
+   *
+   * Caution: if `circular` is false and `parent` contains circular references,
+   * your program may enter an infinite loop and crash.
+   *
+   * @param `parent` - the object to be cloned
+   * @param `circular` - set to true if the object to be cloned may contain
+   *    circular references. (optional - true by default)
+   * @param `depth` - set to a number if the object is only to be cloned to
+   *    a particular depth. (optional - defaults to Infinity)
+   * @param `prototype` - sets the prototype to be used when cloning an object.
+   *    (optional - defaults to parent prototype).
+   * @param `includeNonEnumerable` - set to true if the non-enumerable properties
+   *    should be cloned as well. Non-enumerable properties on the prototype
+   *    chain will be ignored. (optional - false by default)
+   */
+  function clone(parent, circular, depth, prototype, includeNonEnumerable) {
+    if (typeof circular === 'object') {
+      depth = circular.depth;
+      prototype = circular.prototype;
+      includeNonEnumerable = circular.includeNonEnumerable;
+      circular = circular.circular;
+    }
+    // maintain two arrays for circular references, where corresponding parents
+    // and children have the same index
+    var allParents = [];
+    var allChildren = [];
+
+    var useBuffer = typeof Buffer != 'undefined';
+
+    if (typeof circular == 'undefined')
+      circular = true;
+
+    if (typeof depth == 'undefined')
+      depth = Infinity;
+
+    // recurse this function so we don't reset allParents and allChildren
+    function _clone(parent, depth) {
+      // cloning null always returns null
+      if (parent === null)
+        return null;
+
+      if (depth === 0)
+        return parent;
+
+      var child;
+      var proto;
+      if (typeof parent != 'object') {
+        return parent;
+      }
+
+      if (_instanceof(parent, nativeMap)) {
+        child = new nativeMap();
+      } else if (_instanceof(parent, nativeSet)) {
+        child = new nativeSet();
+      } else if (_instanceof(parent, nativePromise)) {
+        child = new nativePromise(function (resolve, reject) {
+          parent.then(function(value) {
+            resolve(_clone(value, depth - 1));
+          }, function(err) {
+            reject(_clone(err, depth - 1));
+          });
+        });
+      } else if (clone.__isArray(parent)) {
+        child = [];
+      } else if (clone.__isRegExp(parent)) {
+        child = new RegExp(parent.source, __getRegExpFlags(parent));
+        if (parent.lastIndex) child.lastIndex = parent.lastIndex;
+      } else if (clone.__isDate(parent)) {
+        child = new Date(parent.getTime());
+      } else if (useBuffer && Buffer.isBuffer(parent)) {
+        if (Buffer.from) {
+          // Node.js >= 5.10.0
+          child = Buffer.from(parent);
+        } else {
+          // Older Node.js versions
+          child = new Buffer(parent.length);
+          parent.copy(child);
+        }
+        return child;
+      } else if (_instanceof(parent, Error)) {
+        child = Object.create(parent);
+      } else {
+        if (typeof prototype == 'undefined') {
+          proto = Object.getPrototypeOf(parent);
+          child = Object.create(proto);
+        }
+        else {
+          child = Object.create(prototype);
+          proto = prototype;
+        }
+      }
+
+      if (circular) {
+        var index = allParents.indexOf(parent);
+
+        if (index != -1) {
+          return allChildren[index];
+        }
+        allParents.push(parent);
+        allChildren.push(child);
+      }
+
+      if (_instanceof(parent, nativeMap)) {
+        parent.forEach(function(value, key) {
+          var keyChild = _clone(key, depth - 1);
+          var valueChild = _clone(value, depth - 1);
+          child.set(keyChild, valueChild);
+        });
+      }
+      if (_instanceof(parent, nativeSet)) {
+        parent.forEach(function(value) {
+          var entryChild = _clone(value, depth - 1);
+          child.add(entryChild);
+        });
+      }
+
+      for (var i in parent) {
+        var attrs = Object.getOwnPropertyDescriptor(parent, i);
+        if (attrs) {
+          child[i] = _clone(parent[i], depth - 1);
+        }
+
+        try {
+          var objProperty = Object.getOwnPropertyDescriptor(parent, i);
+          if (objProperty.set === 'undefined') {
+            // no setter defined. Skip cloning this property
+            continue;
+          }
+          child[i] = _clone(parent[i], depth - 1);
+        } catch(e){
+          if (e instanceof TypeError) {
+            // when in strict mode, TypeError will be thrown if child[i] property only has a getter
+            // we can't do anything about this, other than inform the user that this property cannot be set.
+            continue
+          } else if (e instanceof ReferenceError) {
+            //this may happen in non strict mode
+            continue
+          }
+        }
+
+      }
+
+      if (Object.getOwnPropertySymbols) {
+        var symbols = Object.getOwnPropertySymbols(parent);
+        for (var i = 0; i < symbols.length; i++) {
+          // Don't need to worry about cloning a symbol because it is a primitive,
+          // like a number or string.
+          var symbol = symbols[i];
+          var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
+          if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
+            continue;
+          }
+          child[symbol] = _clone(parent[symbol], depth - 1);
+          Object.defineProperty(child, symbol, descriptor);
+        }
+      }
+
+      if (includeNonEnumerable) {
+        var allPropertyNames = Object.getOwnPropertyNames(parent);
+        for (var i = 0; i < allPropertyNames.length; i++) {
+          var propertyName = allPropertyNames[i];
+          var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
+          if (descriptor && descriptor.enumerable) {
+            continue;
+          }
+          child[propertyName] = _clone(parent[propertyName], depth - 1);
+          Object.defineProperty(child, propertyName, descriptor);
+        }
+      }
+
+      return child;
+    }
+
+    return _clone(parent, depth);
+  }
+
+  /**
+   * Simple flat clone using prototype, accepts only objects, usefull for property
+   * override on FLAT configuration object (no nested props).
+   *
+   * USE WITH CAUTION! This may not behave as you wish if you do not know how this
+   * works.
+   */
+  clone.clonePrototype = function clonePrototype(parent) {
+    if (parent === null)
+      return null;
+
+    var c = function () {};
+    c.prototype = parent;
+    return new c();
+  };
+
+// private utility functions
+
+  function __objToStr(o) {
+    return Object.prototype.toString.call(o);
+  }
+  clone.__objToStr = __objToStr;
+
+  function __isDate(o) {
+    return typeof o === 'object' && __objToStr(o) === '[object Date]';
+  }
+  clone.__isDate = __isDate;
+
+  function __isArray(o) {
+    return typeof o === 'object' && __objToStr(o) === '[object Array]';
+  }
+  clone.__isArray = __isArray;
+
+  function __isRegExp(o) {
+    return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
+  }
+  clone.__isRegExp = __isRegExp;
+
+  function __getRegExpFlags(re) {
+    var flags = '';
+    if (re.global) flags += 'g';
+    if (re.ignoreCase) flags += 'i';
+    if (re.multiline) flags += 'm';
+    return flags;
+  }
+  clone.__getRegExpFlags = __getRegExpFlags;
+
+  return clone;
+})();
+
+export default clone

+ 13 - 0
uni_modules/uv-ui-tools/libs/mixin/button.js

@@ -0,0 +1,13 @@
+export default {
+    props: {
+        lang: String,
+        sessionFrom: String,
+        sendMessageTitle: String,
+        sendMessagePath: String,
+        sendMessageImg: String,
+        showMessageCard: Boolean,
+        appParameter: String,
+        formType: String,
+        openType: String
+    }
+}

+ 172 - 0
uni_modules/uv-ui-tools/libs/mixin/mixin.js

@@ -0,0 +1,172 @@
+import * as index from '../function/index.js';
+import * as test from '../function/test.js';
+import route from '../util/route.js';
+import debounce from '../function/debounce.js';
+import throttle from '../function/throttle.js';
+export default {
+	// 定义每个组件都可能需要用到的外部样式以及类名
+	props: {
+		// 每个组件都有的父组件传递的样式,可以为字符串或者对象形式
+		customStyle: {
+			type: [Object, String],
+			default: () => ({})
+		},
+		customClass: {
+			type: String,
+			default: ''
+		},
+		// 跳转的页面路径
+		url: {
+			type: String,
+			default: ''
+		},
+		// 页面跳转的类型
+		linkType: {
+			type: String,
+			default: 'navigateTo'
+		}
+	},
+	data() {
+		return {}
+	},
+	onLoad() {
+		// getRect挂载到$uv上,因为这方法需要使用in(this),所以无法把它独立成一个单独的文件导出
+		this.$uv.getRect = this.$uvGetRect
+	},
+	created() {
+		// 组件当中,只有created声明周期,为了能在组件使用,故也在created中将方法挂载到$uv
+		this.$uv.getRect = this.$uvGetRect
+	},
+	computed: {
+		$uv() {
+			return {
+				...index,
+				test,
+				route,
+				debounce,
+				throttle,
+				unit: uni?.$uv?.config?.unit
+			}
+		},
+		/**
+		 * 生成bem规则类名
+		 * 由于微信小程序,H5,nvue之间绑定class的差异,无法通过:class="[bem()]"的形式进行同用
+		 * 故采用如下折中做法,最后返回的是数组(一般平台)或字符串(支付宝和字节跳动平台),类似['a', 'b', 'c']或'a b c'的形式
+		 * @param {String} name 组件名称
+		 * @param {Array} fixed 一直会存在的类名
+		 * @param {Array} change 会根据变量值为true或者false而出现或者隐藏的类名
+		 * @returns {Array|string}
+		 */
+		bem() {
+			return function(name, fixed, change) {
+				// 类名前缀
+				const prefix = `uv-${name}--`
+				const classes = {}
+				if (fixed) {
+					fixed.map((item) => {
+						// 这里的类名,会一直存在
+						classes[prefix + this[item]] = true
+					})
+				}
+				if (change) {
+					change.map((item) => {
+						// 这里的类名,会根据this[item]的值为true或者false,而进行添加或者移除某一个类
+						this[item] ? (classes[prefix + item] = this[item]) : (delete classes[prefix + item])
+					})
+				}
+				return Object.keys(classes)
+					// 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
+					// #ifdef MP-ALIPAY || MP-TOUTIAO || MP-LARK || MP-BAIDU
+					.join(' ')
+				// #endif
+			}
+		}
+	},
+	methods: {
+		// 跳转某一个页面
+		openPage(urlKey = 'url') {
+			const url = this[urlKey]
+			if (url) {
+				// 执行类似uni.navigateTo的方法
+				uni[this.linkType]({
+					url
+				})
+			}
+		},
+		// 查询节点信息
+		// 目前此方法在支付宝小程序中无法获取组件跟接点的尺寸,为支付宝的bug(2020-07-21)
+		// 解决办法为在组件根部再套一个没有任何作用的view元素
+		$uvGetRect(selector, all) {
+			return new Promise((resolve) => {
+				uni.createSelectorQuery()
+					.in(this)[all ? 'selectAll' : 'select'](selector)
+					.boundingClientRect((rect) => {
+						if (all && Array.isArray(rect) && rect.length) {
+							resolve(rect)
+						}
+						if (!all && rect) {
+							resolve(rect)
+						}
+					})
+					.exec()
+			})
+		},
+		getParentData(parentName = '') {
+			// 避免在created中去定义parent变量
+			if (!this.parent) this.parent = {}
+			// 这里的本质原理是,通过获取父组件实例(也即类似uv-radio的父组件uv-radio-group的this)
+			// 将父组件this中对应的参数,赋值给本组件(uv-radio的this)的parentData对象中对应的属性
+			// 之所以需要这么做,是因为所有端中,头条小程序不支持通过this.parent.xxx去监听父组件参数的变化
+			// 此处并不会自动更新子组件的数据,而是依赖父组件uv-radio-group去监听data的变化,手动调用更新子组件的方法去重新获取
+			this.parent = this.$uv.$parent.call(this, parentName)
+			if (this.parent.children) {
+				// 如果父组件的children不存在本组件的实例,才将本实例添加到父组件的children中
+				this.parent.children.indexOf(this) === -1 && this.parent.children.push(this)
+			}
+			if (this.parent && this.parentData) {
+				// 历遍parentData中的属性,将parent中的同名属性赋值给parentData
+				Object.keys(this.parentData).map((key) => {
+					this.parentData[key] = this.parent[key]
+				})
+			}
+		},
+		// 阻止事件冒泡
+		preventEvent(e) {
+			e && typeof(e.stopPropagation) === 'function' && e.stopPropagation()
+		},
+		// 空操作
+		noop(e) {
+			this.preventEvent(e)
+		}
+	},
+	onReachBottom() {
+		uni.$emit('uvOnReachBottom')
+	},
+	beforeDestroy() {
+		// 判断当前页面是否存在parent和chldren,一般在checkbox和checkbox-group父子联动的场景会有此情况
+		// 组件销毁时,移除子组件在父组件children数组中的实例,释放资源,避免数据混乱
+		if (this.parent && test.array(this.parent.children)) {
+			// 组件销毁时,移除父组件中的children数组中对应的实例
+			const childrenList = this.parent.children
+			childrenList.map((child, index) => {
+				// 如果相等,则移除
+				if (child === this) {
+					childrenList.splice(index, 1)
+				}
+			})
+		}
+	},
+	// 兼容vue3
+	unmounted() {
+		if (this.parent && test.array(this.parent.children)) {
+			// 组件销毁时,移除父组件中的children数组中对应的实例
+			const childrenList = this.parent.children
+			childrenList.map((child, index) => {
+				// 如果相等,则移除
+				if (child === this) {
+					childrenList.splice(index, 1)
+				}
+			})
+		}
+	}
+}

+ 8 - 0
uni_modules/uv-ui-tools/libs/mixin/mpMixin.js

@@ -0,0 +1,8 @@
+export default {
+    // #ifdef MP-WEIXIN
+    // 将自定义节点设置成虚拟的(去掉自定义组件包裹层),更加接近Vue组件的表现,能更好的使用flex属性
+    options: {
+        virtualHost: true
+    }
+    // #endif
+}

+ 13 - 0
uni_modules/uv-ui-tools/libs/mixin/mpShare.js

@@ -0,0 +1,13 @@
+export default {
+	onLoad() {
+	    // 设置默认的转发参数
+	    uni.$uv.mpShare = {
+	        title: '', // 默认为小程序名称
+	        path: '', // 默认为当前页面路径
+	        imageUrl: '' // 默认为当前页面的截图
+	    }
+	},
+	onShareAppMessage() {
+	    return uni.$uv.mpShare
+	}
+}

+ 47 - 0
uni_modules/uv-ui-tools/libs/mixin/openType.js

@@ -0,0 +1,47 @@
+export default {
+    props: {
+        openType: String
+    },
+		emits: ['getphonenumber','getuserinfo','error','opensetting','launchapp','contact','chooseavatar','addgroupapp','chooseaddress','subscribe','login','im'],
+    methods: {
+        onGetPhoneNumber(event) {
+            this.$emit('getphonenumber', event.detail)
+        },
+        onGetUserInfo(event) {
+            this.$emit('getuserinfo', event.detail)
+        },
+        onError(event) {
+            this.$emit('error', event.detail)
+        },
+        onOpenSetting(event) {
+            this.$emit('opensetting', event.detail)
+        },
+        onLaunchApp(event) {
+            this.$emit('launchapp', event.detail)
+        },
+        onContact(event) {
+            this.$emit('contact', event.detail)
+        },
+        onChooseavatar(event) {
+            this.$emit('chooseavatar', event.detail)
+        },
+        onAgreeprivacyauthorization(event) {
+            this.$emit('agreeprivacyauthorization', event.detail)
+        },
+        onAddgroupapp(event) {
+            this.$emit('addgroupapp', event.detail)
+        },
+        onChooseaddress(event) {
+            this.$emit('chooseaddress', event.detail)
+        },
+        onSubscribe(event) {
+            this.$emit('subscribe', event.detail)
+        },
+        onLogin(event) {
+            this.$emit('login', event.detail)
+        },
+        onIm(event) {
+            this.$emit('im', event.detail)
+        }
+    }
+}

+ 59 - 0
uni_modules/uv-ui-tools/libs/mixin/touch.js

@@ -0,0 +1,59 @@
+const MIN_DISTANCE = 10
+
+function getDirection(x, y) {
+    if (x > y && x > MIN_DISTANCE) {
+        return 'horizontal'
+    }
+    if (y > x && y > MIN_DISTANCE) {
+        return 'vertical'
+    }
+    return ''
+}
+
+export default {
+    methods: {
+        getTouchPoint(e) {
+            if (!e) {
+                return {
+                    x: 0,
+                    y: 0
+                }
+            } if (e.touches && e.touches[0]) {
+                return {
+                    x: e.touches[0].pageX,
+                    y: e.touches[0].pageY
+                }
+            } if (e.changedTouches && e.changedTouches[0]) {
+                return {
+                    x: e.changedTouches[0].pageX,
+                    y: e.changedTouches[0].pageY
+                }
+            }
+            return {
+                x: e.clientX || 0,
+                y: e.clientY || 0
+            }
+        },
+        resetTouchStatus() {
+            this.direction = ''
+            this.deltaX = 0
+            this.deltaY = 0
+            this.offsetX = 0
+            this.offsetY = 0
+        },
+        touchStart(event) {
+            this.resetTouchStatus()
+            const touch = this.getTouchPoint(event)
+            this.startX = touch.x
+            this.startY = touch.y
+        },
+        touchMove(event) {
+            const touch = this.getTouchPoint(event)
+            this.deltaX = touch.x - this.startX
+            this.deltaY = touch.y - this.startY
+            this.offsetX = Math.abs(this.deltaX)
+            this.offsetY = Math.abs(this.deltaY)
+            this.direction =				this.direction || getDirection(this.offsetX, this.offsetY)
+        }
+    }
+}

Diferenças do arquivo suprimidas por serem muito extensas
+ 216 - 0
uni_modules/uv-ui-tools/libs/util/dayjs.js


+ 126 - 0
uni_modules/uv-ui-tools/libs/util/route.js

@@ -0,0 +1,126 @@
+/**
+ * 路由跳转方法,该方法相对于直接使用uni.xxx的好处是使用更加简单快捷
+ * 并且带有路由拦截功能
+ */
+import { queryParams, deepMerge, page } from '@/uni_modules/uv-ui-tools/libs/function/index.js'
+class Router {
+	constructor() {
+		// 原始属性定义
+		this.config = {
+			type: 'navigateTo',
+			url: '',
+			delta: 1, // navigateBack页面后退时,回退的层数
+			params: {}, // 传递的参数
+			animationType: 'pop-in', // 窗口动画,只在APP有效
+			animationDuration: 300, // 窗口动画持续时间,单位毫秒,只在APP有效
+			intercept: false ,// 是否需要拦截
+			events: {} // 页面间通信接口,用于监听被打开页面发送到当前页面的数据。hbuilderx 2.8.9+ 开始支持。
+		}
+		// 因为route方法是需要对外赋值给另外的对象使用,同时route内部有使用this,会导致route失去上下文
+		// 这里在构造函数中进行this绑定
+		this.route = this.route.bind(this)
+	}
+
+	// 判断url前面是否有"/",如果没有则加上,否则无法跳转
+	addRootPath(url) {
+		return url[0] === '/' ? url : `/${url}`
+	}
+
+	// 整合路由参数
+	mixinParam(url, params) {
+		url = url && this.addRootPath(url)
+
+		// 使用正则匹配,主要依据是判断是否有"/","?","="等,如“/page/index/index?name=mary"
+		// 如果有url中有get参数,转换后无需带上"?"
+		let query = ''
+		if (/.*\/.*\?.*=.*/.test(url)) {
+			// object对象转为get类型的参数
+			query = queryParams(params, false)
+			// 因为已有get参数,所以后面拼接的参数需要带上"&"隔开
+			return url += `&${query}`
+		}
+		// 直接拼接参数,因为此处url中没有后面的query参数,也就没有"?/&"之类的符号
+		query = queryParams(params)
+		return url += query
+	}
+
+	// 对外的方法名称
+	async route(options = {}, params = {}) {
+		// 合并用户的配置和内部的默认配置
+		let mergeConfig = {}
+
+		if (typeof options === 'string') {
+			// 如果options为字符串,则为route(url, params)的形式
+			mergeConfig.url = this.mixinParam(options, params)
+			mergeConfig.type = 'navigateTo'
+		} else {
+			mergeConfig = deepMerge(this.config, options)
+			// 否则正常使用mergeConfig中的url和params进行拼接
+			mergeConfig.url = this.mixinParam(options.url, options.params)
+		}
+		// 如果本次跳转的路径和本页面路径一致,不执行跳转,防止用户快速点击跳转按钮,造成多次跳转同一个页面的问题
+		if (mergeConfig.url === page()) return
+
+		if (params.intercept) {
+			mergeConfig.intercept = params.intercept
+		}
+		// params参数也带给拦截器
+		mergeConfig.params = params
+		// 合并内外部参数
+		mergeConfig = deepMerge(this.config, mergeConfig)
+		// 判断用户是否定义了拦截器
+		if (typeof mergeConfig.intercept === 'function') {
+			// 定一个promise,根据用户执行resolve(true)或者resolve(false)来决定是否进行路由跳转
+			const isNext = await new Promise((resolve, reject) => {
+				mergeConfig.intercept(mergeConfig, resolve)
+			})
+			// 如果isNext为true,则执行路由跳转
+			isNext && this.openPage(mergeConfig)
+		} else {
+			this.openPage(mergeConfig)
+		}
+	}
+
+	// 执行路由跳转
+	openPage(config) {
+		// 解构参数
+		const {
+			url,
+			type,
+			delta,
+			animationType,
+			animationDuration,
+			events
+		} = config
+		if (config.type == 'navigateTo' || config.type == 'to') {
+			uni.navigateTo({
+				url,
+				animationType,
+				animationDuration,
+				events
+			})
+		}
+		if (config.type == 'redirectTo' || config.type == 'redirect') {
+			uni.redirectTo({
+				url
+			})
+		}
+		if (config.type == 'switchTab' || config.type == 'tab') {
+			uni.switchTab({
+				url
+			})
+		}
+		if (config.type == 'reLaunch' || config.type == 'launch') {
+			uni.reLaunch({
+				url
+			})
+		}
+		if (config.type == 'navigateBack' || config.type == 'back') {
+			uni.navigateBack({
+				delta
+			})
+		}
+	}
+}
+
+export default (new Router()).route

+ 81 - 0
uni_modules/uv-ui-tools/package.json

@@ -0,0 +1,81 @@
+{
+  "id": "uv-ui-tools",
+  "displayName": "uv-ui-tools 工具集 全面兼容vue3+2、app、h5、小程序等多端",
+  "version": "1.1.25",
+  "description": "uv-ui-tools,集成工具库,强大的Http请求封装,清晰的文档说明,开箱即用。方便使用,可以全局使用",
+  "keywords": [
+    "uv-ui-tools,uv-ui组件库,工具集,uvui,uView2.x"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y",
+          "钉钉": "y",
+          "快手": "y",
+          "飞书": "y",
+          "京东": "y"
+        },
+        "快应用": {
+          "华为": "y",
+          "联盟": "y"
+        }
+      }
+    }
+  }
+}

+ 23 - 0
uni_modules/uv-ui-tools/readme.md

@@ -0,0 +1,23 @@
+## uv-ui-tools 工具集
+
+> **组件名:uv-ui-tools**
+
+uv-ui工具集成,包括网络Http请求、便捷工具、节流防抖、对象操作、时间格式化、路由跳转、全局唯一标识符、规则校验等等。
+
+该组件推荐配合[uv-ui组件库](https://www.uvui.cn/components/intro.html)使用,单独下载也可以在自己项目中使用,需要做相应的配置,可查看文档。强烈推荐使用[uv-ui组件库](https://www.uvui.cn/components/intro.html),导入组件都会自动导入`uv-ui-tools`。需要在自己的项目中使用请参考[扩展配置](https://www.uvui.cn/components/setting.html)。
+
+uv-ui破釜沉舟之兼容vue3+2、app、h5、多端小程序的uni-app生态框架,大部分组件基于uView2.x,在经过改进后全面支持vue3,部分组件做了进一步的优化,修复大量BUG,支持单独导入,方便开发者选择导入需要的组件。开箱即用,灵活配置。
+
+# <a href="https://www.uvui.cn/js/intro.html" target="_blank">查看文档</a>
+
+## [下载完整示例项目](https://ext.dcloud.net.cn/plugin?name=uv-ui) <small>(请不要 下载插件ZIP)</small>
+
+### [更多插件,请关注uv-ui组件库](https://ext.dcloud.net.cn/plugin?name=uv-ui)
+
+<a href="https://ext.dcloud.net.cn/plugin?name=uv-ui" target="_blank">
+
+![image](https://mp-a667b617-c5f1-4a2d-9a54-683a67cff588.cdn.bspapp.com/uv-ui/banner.png)
+
+</a>
+
+#### 如使用过程中有任何问题反馈,或者您对uv-ui有一些好的建议,欢迎加入uv-ui官方交流群:<a href="https://www.uvui.cn/components/addQQGroup.html" target="_blank">官方QQ群</a>

+ 43 - 0
uni_modules/uv-ui-tools/theme.scss

@@ -0,0 +1,43 @@
+// 此文件为uvUI的主题变量,这些变量目前只能通过uni.scss引入才有效,另外由于
+// uni.scss中引入的样式会同时混入到全局样式文件和单独每一个页面的样式中,造成微信程序包太大,
+// 故uni.scss只建议放scss变量名相关样式,其他的样式可以通过main.js或者App.vue引入
+
+$uv-main-color: #303133;
+$uv-content-color: #606266;
+$uv-tips-color: #909193;
+$uv-light-color: #c0c4cc;
+$uv-border-color: #dadbde;
+$uv-bg-color: #f3f4f6;
+$uv-disabled-color: #c8c9cc;
+
+$uv-primary: #3c9cff;
+$uv-primary-dark: #398ade;
+$uv-primary-disabled: #9acafc;
+$uv-primary-light: #ecf5ff;
+
+$uv-warning: #f9ae3d;
+$uv-warning-dark: #f1a532;
+$uv-warning-disabled: #f9d39b;
+$uv-warning-light: #fdf6ec;
+
+$uv-success: #5ac725;
+$uv-success-dark: #53c21d;
+$uv-success-disabled: #a9e08f;
+$uv-success-light: #f5fff0;
+
+$uv-error: #f56c6c;
+$uv-error-dark: #e45656;
+$uv-error-disabled: #f7b2b2;
+$uv-error-light: #fef0f0;
+
+$uv-info: #909399;
+$uv-info-dark: #767a82;
+$uv-info-disabled: #c4c6c9;
+$uv-info-light: #f4f4f5;
+
+@mixin flex($direction: row) {
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	flex-direction: $direction;
+}

BIN
unpackage/dist/build/h5.zip


BIN
unpackage/dist/build/h5/static/img/index_bg.d2c7fb24.jpg


BIN
unpackage/dist/build/h5/static/img/order_bg.2d37a2fb.jpg


BIN
unpackage/dist/build/h5/static/img/success.34f76374.png


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/img/touxiang.48c02f8b.svg


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/index.b0707a6a.css


BIN
unpackage/dist/build/h5/static/index/welcome.png


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 14
unpackage/dist/build/h5/static/js/chunk-vendors.41816274.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/index.de311645.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-gongyuxiangqing-gongyuxiangqing.7f7331c0.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-huoquanshibai-huoquanshibai.0f67de97.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-index-index.10e1336a.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-index-index~pages-my_orderlist-my_orderlist~pages-order_mark-order_mark~pages-order_room-order_room.b6504273.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-index-index~pages-my_orderlist-my_orderlist~pages-order_room-order_room.642f5866.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-my_orderlist-my_orderlist.d79d487f.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-myself-myself.cc6a31c5.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-order_mark-order_mark.27384da7.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-order_room-order_room.256e5c81.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-ruzhuxuzhi-ruzhuxuzhi.d6fd2301.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 1
unpackage/dist/build/h5/static/js/pages-zhifuchenggong-zhifuchenggong.ee656fba.js


BIN
unpackage/dist/build/h5/static/my/touxiang.png


BIN
unpackage/dist/build/web/assets/uniicons.b6d3756e.ttf


+ 0 - 0
unpackage/dist/build/h5/index.html


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff