Browse Source

枣泉:1.0.2

tiandewen 3 năm trước cách đây
mục cha
commit
14919396b5
100 tập tin đã thay đổi với 7445 bổ sung488 xóa
  1. 8 0
      common/production-http/production-api.js
  2. 43 0
      common/vmeitime-http/api.js
  3. 1 1
      components/t-i-banner/t-i-banner.vue
  4. 163 69
      components/t-i-navbar/t-i-navbar.vue
  5. 5 0
      components/t-i-notice/t-i-notice.vue
  6. BIN
      components/t-m-icon/icon/wodegongdan.png
  7. 68 5
      components/t-m-icon/t-m-icon.vue
  8. 9 3
      components/t-m-info/t-m-info.vue
  9. 0 0
      components/t-o-communication/icon/bangong.png
  10. 0 0
      components/t-o-communication/icon/bumen.png
  11. 0 0
      components/t-o-communication/icon/jiagou.png
  12. 0 0
      components/t-o-communication/icon/qingjia.png
  13. 0 0
      components/t-o-communication/icon/qita.png
  14. 0 0
      components/t-o-communication/icon/title_icon.png
  15. 0 0
      components/t-o-communication/icon/yongyin.png
  16. 36 15
      components/t-o-zaoquan/t-o-zaoquan.vue
  17. 11 56
      components/t-p-zaoquan/t-p-zaoquan.vue
  18. 18 5
      components/t-w-zaoquan/t-w-zaoquan.vue
  19. 4 4
      manifest.json
  20. 116 3
      pages.json
  21. 65 0
      pages/index/integral/detail/detail.vue
  22. 178 0
      pages/index/integral/integral.vue
  23. 244 0
      pages/my/business-audit/business-audit.vue
  24. 377 0
      pages/my/business-audit/chakan/chakan.vue
  25. 461 0
      pages/my/business-audit/shenhe/shenhe.vue
  26. 300 0
      pages/my/business-my/business-my.vue
  27. 377 0
      pages/my/business-my/chakan/chakan.vue
  28. 1 1
      pages/my/message-reminder/message-detail/message-detail.vue
  29. 1 0
      pages/my/message-reminder/message-reminder.vue
  30. BIN
      pages/my/personal_information/icon/top.png
  31. 23 0
      pages/my/personal_information/personal_information - 副本 (2).vue
  32. 407 0
      pages/my/personal_information/personal_information.vue
  33. 38 0
      pages/my/signature/signature.vue
  34. 0 0
      pages/origanization/communication/origanization/icon/close.png
  35. 0 0
      pages/origanization/communication/origanization/icon/open.png
  36. 0 0
      pages/origanization/communication/origanization/icon/title_icon.png
  37. 0 0
      pages/origanization/communication/origanization/my_department/icon/close.png
  38. 0 0
      pages/origanization/communication/origanization/my_department/icon/open.png
  39. 0 0
      pages/origanization/communication/origanization/my_department/icon/title_icon.png
  40. 172 0
      pages/origanization/communication/origanization/my_department/my_department.vue
  41. 0 0
      pages/origanization/communication/origanization/origanization - 二级列表.vue
  42. 0 0
      pages/origanization/communication/origanization/origanization - 单独部门列表.vue
  43. 0 0
      pages/origanization/communication/origanization/origanization - 递归.vue
  44. 0 0
      pages/origanization/communication/origanization/origanization.vue
  45. 0 0
      pages/origanization/communication/origanization/search/icon/close.png
  46. 0 0
      pages/origanization/communication/origanization/search/icon/open.png
  47. 0 0
      pages/origanization/communication/origanization/search/icon/title_icon.png
  48. 33 20
      pages/origanization/zaoquan/origanization/search/search.vue
  49. 0 249
      pages/origanization/zaoquan/origanization/my_department/my_department.vue
  50. 92 35
      pages/production/zaoquan/mine_water_treatment/mine_water_treatment.vue
  51. 26 0
      pages/production/zaoquan/zidonghua_list/detail/detail.vue
  52. BIN
      pages/production/zaoquan/zidonghua_list/img/icon.png
  53. BIN
      pages/production/zaoquan/zidonghua_list/img/psxt.jpg
  54. BIN
      pages/production/zaoquan/zidonghua_list/img/tfgl.jpg
  55. BIN
      pages/production/zaoquan/zidonghua_list/img/yfzd.jpg
  56. BIN
      pages/production/zaoquan/zidonghua_list/img/zys.jpg
  57. 288 0
      pages/production/zaoquan/zidonghua_list/zidonghua_list.vue
  58. 5 2
      pages/tabbar/my/my.vue
  59. 2 1
      pages/tabbar/origanization/origanization.vue
  60. 43 0
      pages/workbench/business_classfication/apply/apply.vue
  61. 81 0
      pages/workbench/business_classfication/business_classfication.vue
  62. 13 13
      pages/workbench/duty_information/duty_information.vue
  63. 23 0
      pages/workbench/gridding/gridding.vue
  64. BIN
      static/logo_xin.png
  65. BIN
      static/qidongtu.png
  66. BIN
      static/star.png
  67. 85 0
      uni_modules/uni-datetime-picker/changelog.md
  68. 185 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue
  69. 898 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue
  70. 19 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json
  71. 8 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js
  72. 19 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json
  73. 19 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json
  74. 45 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js
  75. 927 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue
  76. 981 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue
  77. 410 0
      uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js
  78. 90 0
      uni_modules/uni-datetime-picker/package.json
  79. 21 0
      uni_modules/uni-datetime-picker/readme.md
  80. 2 2
      unpackage/dist/build/app-plus/app-config-service.js
  81. 2 2
      unpackage/dist/build/app-plus/app-service.js
  82. 1 1
      unpackage/dist/build/app-plus/app-view.js
  83. BIN
      unpackage/dist/build/app-plus/components/t-m-icon/icon/wodegongdan.png
  84. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/bangong.png
  85. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/bumen.png
  86. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/jiagou.png
  87. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/qingjia.png
  88. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/qita.png
  89. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/title_icon.png
  90. 0 0
      unpackage/dist/build/app-plus/components/t-o-communication/icon/yongyin.png
  91. 1 1
      unpackage/dist/build/app-plus/manifest.json
  92. BIN
      unpackage/dist/build/app-plus/pages/my/personal_information/icon/top.png
  93. 0 0
      unpackage/dist/build/app-plus/pages/origanization/communication/origanization/icon/close.png
  94. 0 0
      unpackage/dist/build/app-plus/pages/origanization/communication/origanization/icon/open.png
  95. 0 0
      unpackage/dist/build/app-plus/pages/origanization/communication/origanization/icon/title_icon.png
  96. 0 0
      unpackage/dist/build/app-plus/pages/origanization/communication/origanization/my_department/icon/title_icon.png
  97. 0 0
      unpackage/dist/build/app-plus/pages/origanization/communication/origanization/search/icon/title_icon.png
  98. BIN
      unpackage/dist/build/app-plus/pages/production/zaoquan/zidonghua_list/img/icon.png
  99. BIN
      unpackage/dist/build/app-plus/pages/production/zaoquan/zidonghua_list/img/psxt.jpg
  100. 0 0
      unpackage/dist/build/app-plus/pages/production/zaoquan/zidonghua_list/img/tfgl.jpg

+ 8 - 0
common/production-http/production-api.js

@@ -330,3 +330,11 @@ export const jt_safety_alarm_list = (data) => {
 	})
 }
 
+// 矿井水
+export const automate_mine_water_get_list = (data) => {
+	return http.request({
+		method: 'POST',
+		url: '/automate/mine_water/get_list',
+		data,
+	})
+}

+ 43 - 0
common/vmeitime-http/api.js

@@ -372,3 +372,46 @@ export const user_list = (data) => {
         data,
     })
 }
+
+
+// 积分
+// 添加员工积分
+export const staff_integral_increase = (data) => {
+    return http.request({
+		method:'POST',
+        url: '/staff/integral/increase',
+        data,
+    })
+}
+//查询员工积分
+export const staff_integral_query = (data) => {
+    return http.request({
+		method:'POST',
+        url: '/staff/integral/query',
+        data,
+    })
+}
+// 查询当日员工积分获取情况
+export const staff_integral_list = (data) => {
+    return http.request({
+		method:'POST',
+        url: '/staff/integral/list',
+        data,
+    })
+}
+
+// 搜索全矿人员
+export const user_search = (data) => {
+    return http.request({
+		method:'POST',
+        url: '/user/search',
+        data,
+    })
+}
+// 获取个人信息
+export const user_getUinfo = (data) => {
+    return http.request({
+        url: '/user/getUinfo',
+        data,
+    })
+}	

+ 1 - 1
components/t-i-banner/t-i-banner.vue

@@ -36,7 +36,7 @@
 
 <style lang="scss">
 	.banner{
-		margin-top: -40rpx;
+		margin-top: -50rpx;
 		.box{
 			width: 750rpx;
 			height: 600rpx;

+ 163 - 69
components/t-i-navbar/t-i-navbar.vue

@@ -4,11 +4,11 @@
 			<view class="status_bar">
 				<!-- 这里是状态栏 -->
 			</view>
-			
+
 			<view class="navbar">
 				<view class="left" @click="switch_kuang()">
 					<image v-if="mine_code == 'ningdongyunying'" src="./icon/ningdongyunying.png" mode=""></image>
-					
+
 					<image v-if="mine_code == 'zaoquan'" src="./icon/zaoquan.png" mode=""></image>
 					<uni-icons type="arrowdown" color="#fff" v-if="mine_code == 'ningdongyunying'"></uni-icons>
 				</view>
@@ -20,26 +20,31 @@
 							</view>
 							<view class="text">搜索</view>
 						</view>
-						<view class="scan">
+						<view class="scan" @click="scan()">
 							<image src="./icon/saoma.png" mode=""></image>
 						</view>
 					</view>
 				</view>
 				<view class="right">
-					<view class="icon">
-						<image src="./icon/day.png" mode=""></image>
-					</view>
-					<view class="num">{{temperature_curr}}</view>
+					<swiper class="box" autoplay circular vertical :interval="4000" :duration="1000">
+						<swiper-item class="item">
+							<view class="icon">
+								<image src="./icon/day.png" mode=""></image>
+							</view>
+							<view class="num">{{temperature_curr}}</view>
+						</swiper-item>
+						<swiper-item class="item" @click="go_integral()">
+							<view class="icon" style="margin-right: 4rpx;">
+								积分
+							</view>
+							<view class="num">{{total}} 分</view>
+						</swiper-item>
+					</swiper>
+
 				</view>
-				<!-- <view class="right" v-show="show">
-					<view class="icon" style="margin-right: 4rpx;">
-						积分
-					</view>
-					<view class="num">999分</view>
-				</view> -->
 			</view>
 		</view>
-		
+
 		<view class="status_bar"></view>
 		<view style="height: 88rpx;"></view>
 	</view>
@@ -54,32 +59,106 @@
 		data() {
 			return {
 				// 当前温度
-				temperature_curr:"",
+				temperature_curr: "",
+				
+				// 总积分
+				total:0
 			};
 		},
 		created() {
 			// 当前温度
 			uni.request({
-				url:"http://api.k780.com/?app=weather.today&weaId=286&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json",
-				method:"GET",
-				success:(res)=> {
+				url: "http://api.k780.com/?app=weather.today&weaId=286&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json",
+				method: "GET",
+				success: (res) => {
 					// console.log(res.data.result.temperature_curr)
 					this.temperature_curr = res.data.result.temperature_curr
 				}
 			})
-			
+
+			// 登录签到
+			this.add_staff_integral_increase()
+			//查询员工积分
+			this.get_staff_integral_query()
+
 		},
-		methods:{
-			switch_kuang(){
-				if(this.mine_code == 'ningdongyunying'){
+		methods: {
+			switch_kuang() {
+				if (this.mine_code == 'ningdongyunying') {
 					uni.navigateTo({
-						url:"../../index/switch-kuang/switch-kuang"
+						url: "../../index/switch-kuang/switch-kuang"
 					})
 				}
 			},
-			go_search(){
+			go_search() {
 				uni.navigateTo({
-					url:"../../index/search/search?mine_code=" + this.mine_code
+					url: "../../index/search/search?mine_code=" + this.mine_code,
+					animationType: "fade-in",
+					animationDuration: 500
+				})
+			},
+			scan() {
+				// 只允许通过相机扫码
+				uni.scanCode({
+					onlyFromCamera: true,
+					success: function(res) {
+						// console.log('条码类型:' + res.scanType);
+						// console.log('条码内容:' + res.result);
+
+						let pageId = ""
+
+						function GetQueryString(name) {
+							var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+							var r = res.match(reg);
+							if (r != null) return unescape(r[2]);
+							return null;
+						}
+						console.log(GetQueryString("pageId"))
+						if (GetQueryString("pageId")) {
+							pageId = GetQueryString("pageId")
+						} else {
+							pageId = res.split('=')[1]
+						}
+
+						uni.navigateTo({
+							url: "../../index/record/record?pageId=" + pageId + "&mine_code=" + this
+								.mine_code,
+						})
+					}
+				})
+			},
+
+			// 添加员工积分 登录签到
+			add_staff_integral_increase() {
+				this.$api.staff_integral_increase({
+					staff_num: uni.getStorageSync('user').staff_num,
+					integral_type: 1,
+					integral_num: 1
+				}).then((res) => {
+					// console.log(res)
+
+					if (res.data.content.is_exists == 0) {
+						uni.showToast({
+							icon: "none",
+							title: "签到成功!"
+						})
+					}
+				})
+			},
+			//查询员工积分
+			get_staff_integral_query() {
+				this.$api.staff_integral_query({
+					staff_num: uni.getStorageSync('user').staff_num
+				}).then((res) => {
+					console.log(res)
+					
+					this.total = res.data.content.data.integral_sum
+				})
+			},
+			// 积分详情
+			go_integral(){
+				uni.navigateTo({
+					url:"../../index/integral/integral?total=" + this.total
 				})
 			}
 		}
@@ -87,87 +166,94 @@
 </script>
 
 <style lang="scss">
-	.content{
+	.content {
 		position: fixed;
 		top: 0;
 		left: 0;
-		
+
 		z-index: 999;
-		
-		
+
+
 		width: 750rpx;
-		
+
 		background-image: url(./icon/bg_img.jpg);
 		background-size: 750rpx 334rpx;
 		background-repeat: no-repeat;
 	}
-	
-	.navbar{
+
+	.navbar {
 		box-sizing: border-box;
 		padding: 10rpx 25rpx;
-		
+
 		display: flex;
 		align-items: center;
 		justify-content: space-between;
-		
+
 		height: 88rpx;
-		.left{
+
+		.left {
 			display: flex;
 			align-items: center;
-			
+
 			width: 170rpx;
-			image{
+
+			image {
 				width: 165rpx;
 				height: 48rpx;
-				
+
 				margin-right: 10rpx;
 			}
 		}
-		.search{
+
+		.search {
 			width: 370rpx;
-			
-			.box{
+
+			.box {
 				display: flex;
 				justify-content: space-between;
 				align-items: center;
-				
+
 				height: 68rpx;
-				
-				background-color: rgba(255,255,255,.4);
+
+				background-color: rgba(255, 255, 255, .4);
 				border-radius: 50rpx;
-				
+
 				box-sizing: border-box;
 				padding: 0 20rpx;
-				
-				.left{
+
+				.left {
 					display: flex;
 					height: 68rpx;
 					width: 300rpx;
-					
-					.icon{
-						image{
+
+					.icon {
+						image {
 							width: 21rpx;
 							height: 21rpx;
 						}
 					}
-					.text{
+
+					.text {
 						color: #FFFFFF;
 						font-size: 24rpx;
 					}
-					
+
 				}
-				.scan{
+
+				.scan {
 					width: 68rpx;
 					text-align: right;
 					line-height: 68rpx;
-					image{
+
+					image {
 						width: 27rpx;
 						height: 25rpx;
 					}
 				}
 			}
 		}
-		.right{
+
+		.right {
 			white-space: nowrap;
 			color: #FFFFFF;
 			font-size: 24rpx;
@@ -176,23 +262,31 @@
 			border-left: 2rpx solid #FFFFFF;
 			box-sizing: border-box;
 			padding-left: 20rpx;
-			
-			display: flex;
-			align-items: center;
-			justify-content: space-around;
 			height: 40rpx;
-			
-			.icon{
-				margin-right: 10rpx;
-				image{
-					width: 40rpx;
-					height: 40rpx;
+
+			.box {
+				width: 124rpx;
+				height: 40rpx;
+
+				.item {
+					display: flex;
+					align-items: center;
+
+					.icon {
+						margin-right: 10rpx;
+
+						image {
+							width: 40rpx;
+							height: 40rpx;
+						}
+					}
+
+					.num {
+						color: #FFFFFF;
+						font-size: 24rpx;
+					}
 				}
 			}
-			.num{
-				color: #FFFFFF;
-				font-size: 24rpx;
-			}
 		}
 	}
 </style>

+ 5 - 0
components/t-i-notice/t-i-notice.vue

@@ -86,9 +86,14 @@
 
 		box-sizing: border-box;
 		padding: 0 20rpx;
+		
 
 		/deep/.uni-noticebar {
 			margin-bottom: 0;
 		}
+		
+		/deep/.uni-noticebar:nth-child(2){
+			padding-top: 0;
+		}
 	}
 </style>

BIN
components/t-m-icon/icon/wodegongdan.png


+ 68 - 5
components/t-m-icon/t-m-icon.vue

@@ -13,19 +13,31 @@
 				</view>
 				<view class="name">消息提醒</view>
 			</view>
-			<view class="item">
+			<view class="item" @click="go_business_audit()">
 				<view class="icon">
 					<image src="./icon/gongdanshenhe.png" mode=""></image>
 				</view>
 				<view class="name">工单审核</view>
 			</view>
-			<view class="item">
+			<view class="item" @click="go_business_my()">
+				<view class="icon">
+					<image src="./icon/wodegongdan.png" mode=""></image>
+				</view>
+				<view class="name">我的工单</view>
+			</view>
+			<view class="item" @click="go_user_manual()">
 				<view class="icon">
 					<image src="./icon/shiyongshouce.png" mode=""></image>
 				</view>
 				<view class="name">使用手册</view>
 			</view>
-			<view class="item">
+			<!-- <view class="item" @click="go_signature()">
+				<view class="icon">
+					<image src="./icon/jianyifankui.png" mode=""></image>
+				</view>
+				<view class="name">手写签名</view>
+			</view> -->
+			<view class="item" @click="go_feedback()">
 				<view class="icon">
 					<image src="./icon/jianyifankui.png" mode=""></image>
 				</view>
@@ -37,7 +49,7 @@
 				</view>
 				<view class="name">修改密码</view>
 			</view>
-			<view class="item">
+			<view class="item" @click="go_update_log()">
 				<view class="icon">
 					<image src="./icon/gengxin.png" mode=""></image>
 				</view>
@@ -57,13 +69,16 @@
 <script>
 	export default {
 		name:"t-m-icon",
+		props: [
+			"mine_code"
+		],
 		data() {
 			return {
 				
 			};
 		},
 		created() {
-			
+			console.log(this.mine_code)
 		},
 		methods:{
 			// 拨打服务电话
@@ -94,6 +109,54 @@
 						title:"清除完成"
 					})
 				},1500)
+			},
+			// 使用手册
+			go_user_manual(){
+				if(this.mine_code == 'zaoquan'){
+					uni.navigateTo({
+						url:"../../index/record/record?pageId=f73209f7e0a4425a94a32210cdfc311d&mine_code=" + this.mine_code,
+					})
+				}else{
+					
+				}
+			},
+			// 建议反馈
+			go_feedback(){
+				if(this.mine_code == 'zaoquan'){
+					uni.navigateTo({
+						url:"../../index/record/record?pageId=45c1a10e9da04670962ff67da80be5b1&mine_code=" + this.mine_code,
+					})
+				}else{
+					
+				}
+			},
+			// 更新日志
+			go_update_log(){
+				if(this.mine_code == 'zaoquan'){
+					uni.navigateTo({
+						url:"../../index/record/record?pageId=982d321d1fd64894a4a22c8f940ed7cc&mine_code=" + this.mine_code,
+					})
+				}else{
+					
+				}
+			},
+			// 工单审核
+			go_business_audit(){
+				uni.navigateTo({
+					url:"../../my/business-audit/business-audit"
+				})
+			},
+			// 我的工单
+			go_business_my(){
+				uni.navigateTo({
+					url:"../../my/business-my/business-my"
+				})
+			},
+			// 手写签名
+			go_signature(){
+				uni.navigateTo({
+					url:"../../my/signature/signature"
+				})
 			}
 			
 		}

+ 9 - 3
components/t-m-info/t-m-info.vue

@@ -1,6 +1,6 @@
 <template>
 	<view class="content">
-		<view class="user">
+		<view class="user" @click="go_information()">
 			<view class="left">
 				<view class="img">
 					<image v-if="user.avatar" :src="user.avatar" mode=""></image>
@@ -12,7 +12,7 @@
 				</view>
 			</view>
 			<view class="right">
-				<!-- <uni-icons type="arrowright"></uni-icons> -->
+				<uni-icons type="arrowright" size="24"></uni-icons>
 			</view>
 		</view>
 		<view class="tip" v-if="tip_password" @click="go_m_repassword()">
@@ -44,7 +44,7 @@
 			};
 		},
 		created() {
-			// console.log(uni.getStorageSync('user'))
+			console.log(uni.getStorageSync('user'))
 			// 获取用户基本信息
 			this.user = uni.getStorageSync('user');
 			this.mobile = uni.getStorageSync('mobile');
@@ -105,6 +105,12 @@
 					url:"../../my/repassword/repassword"
 				})
 			},
+			// 个人信息
+			go_information(){
+				uni.navigateTo({
+					url:"../../my/personal_information/personal_information"
+				})
+			}
 		}
 		
 	}

components/t-o-zaoquan/icon/bangong.png → components/t-o-communication/icon/bangong.png


components/t-o-zaoquan/icon/bumen.png → components/t-o-communication/icon/bumen.png


components/t-o-zaoquan/icon/jiagou.png → components/t-o-communication/icon/jiagou.png


components/t-o-zaoquan/icon/qingjia.png → components/t-o-communication/icon/qingjia.png


components/t-o-zaoquan/icon/qita.png → components/t-o-communication/icon/qita.png


components/t-o-zaoquan/icon/title_icon.png → components/t-o-communication/icon/title_icon.png


components/t-o-zaoquan/icon/yongyin.png → components/t-o-communication/icon/yongyin.png


+ 36 - 15
components/t-o-zaoquan/t-o-zaoquan.vue

@@ -1,30 +1,33 @@
 <template>
 	<view>
 		<view class="list">
-			<view class="item">
+			<view class="item" v-for="(item,index) in list" :key="index" @click="go_business(item.id,item.title)">
 				<view class="icon">
-					<image src="./icon/bangong.png" mode=""></image>
+					<image v-if="item.title == '办公品领用'" src="./icon/bangong.png" mode=""></image>
+					<image v-if="item.title == '用印申请'" src="./icon/yongyin.png" mode=""></image>
+					<image v-if="item.title == '请假'" src="./icon/qingjia.png" mode=""></image>
+					<image v-if="item.title == '其他申请'" src="./icon/qita.png" mode=""></image>
 				</view>
-				<view class="text">办公品领用</view>
+				<view class="text">{{item.title}}</view>
 			</view>
-			<view class="item">
+			<!-- <view class="item" @click="go_business()">
 				<view class="icon">
 					<image src="./icon/yongyin.png" mode=""></image>
 				</view>
 				<view class="text">用印申请</view>
 			</view>
-			<view class="item">
+			<view class="item" @click="go_business()">
 				<view class="icon">
 					<image src="./icon/qingjia.png" mode=""></image>
 				</view>
 				<view class="text">请假</view>
 			</view>
-			<view class="item">
+			<view class="item" @click="go_business()">
 				<view class="icon">
 					<image src="./icon/qita.png" mode=""></image>
 				</view>
 				<view class="text">其他申请</view>
-			</view>
+			</view> -->
 		</view>
 		
 		<view class="content">
@@ -35,7 +38,7 @@
 				<view class="text">国家能源集团枣泉煤矿</view>
 			</view>
 			<view class="box">
-				<view class="item" @click="go_zaoquan_origanization()">
+				<view class="item" @click="go_communication_origanization()">
 					<view class="icon">
 						<image src="./icon/jiagou.png" mode=""></image>
 					</view>
@@ -54,22 +57,40 @@
 
 <script>
 	export default {
-		name:"t-o-zaoquan",
+		name:"t-o-communication",
 		data() {
 			return {
-				
+				list:[]
 			};
 		},
+		created() {
+			this.get_worksheet_classify_list()
+		},
 		methods:{
-			go_zaoquan_origanization(){
+			// 获取分类
+			get_worksheet_classify_list(){
+				this.$api.worksheet_classify_list({
+					
+				}).then((res)=>{
+					console.log(res.data.data)
+					this.list = res.data.data
+				})
+			},
+			// 工单列表
+			go_business(id,title){
 				uni.navigateTo({
-					url:"../../origanization/zaoquan/origanization/origanization"
+					url:"../../workbench/business_classfication/business_classfication?id="+id+"&title="+title
+				})
+			},
+			go_communication_origanization(){
+				uni.navigateTo({
+					url:"../../origanization/communication/origanization/origanization"
 				})
 			},
 			go_my_department(){
-				// uni.navigateTo({
-				// 	url:"../../origanization/zaoquan/origanization/my_department/my_department"
-				// })
+				uni.navigateTo({
+					url:"../../origanization/communication/origanization/my_department/my_department"
+				})
 			}
 		}
 	}

+ 11 - 56
components/t-p-zaoquan/t-p-zaoquan.vue

@@ -57,75 +57,26 @@
 			</view>
 		</view>
 		<view class="item_box" style="background-color: #9CE2A6;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/djtf/#/')">
+			@click="go_zdhxt('tfgl')">
 			<view class="img">
 				<image src="../t-p-icon/icon_5.png" mode=""></image>
 			</view>
 			<view class="text">
 				<view class="name">通风管理</view>
-				<view class="tip">东井通风</view>
-			</view>
-		</view>
-		<view class="item_box" style="background-color: #9CE2A6;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/xjtf/#/')">
-			<view class="img">
-				<image src="../t-p-icon/icon_5.png" mode=""></image>
-			</view>
-			<view class="text">
-				<view class="name">通风管理</view>
-				<view class="tip">西井通风</view>
-			</view>
-		</view>
-		<view class="item_box" style="background-color: #2873FF;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/720bf/#/')">
-			<view class="img">
-				<image src="../t-p-icon/icon_9.png" mode=""></image>
-			</view>
-			<view class="text">
-				<view class="name">排水系统</view>
-				<view class="tip">720泵房</view>
-			</view>
-		</view>
-		<view class="item_box" style="background-color: #9FD4FF;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/980bf/#/')">
-			<view class="img">
-				<image src="../t-p-icon/icon_9.png" mode=""></image>
-			</view>
-			<view class="text">
-				<view class="name">排水系统</view>
-				<view class="tip">980泵房</view>
-			</view>
-		</view>
-		<view class="item_box" style="background-color: #2873FF;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/950bf/#/')">
-			<view class="img">
-				<image src="../t-p-icon/icon_9.png" mode=""></image>
-			</view>
-			<view class="text">
-				<view class="name">排水系统</view>
-				<view class="tip">950泵房</view>
-			</view>
-		</view>
-		<view class="item_box" style="background-color: #9FD4FF;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/880bf/#/')">
-			<view class="img">
-				<image src="../t-p-icon/icon_9.png" mode=""></image>
-			</view>
-			<view class="text">
-				<view class="name">排水系统</view>
-				<view class="tip">880泵房</view>
+				<view class="tip"></view>
 			</view>
 		</view>
 		<view class="item_box" style="background-color: #2873FF;"
-			@click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/929bf/#/')">
+			@click="go_zdhxt('psxt')">
 			<view class="img">
 				<image src="../t-p-icon/icon_9.png" mode=""></image>
 			</view>
 			<view class="text">
 				<view class="name">排水系统</view>
-				<view class="tip">929泵房</view>
+				<view class="tip"></view>
 			</view>
 		</view>
+		
 	</view>
 </template>
 
@@ -161,8 +112,12 @@
 		methods: {
 			// 自动化统计列表
 			go_zdhxt(zdhxt) {
+				// uni.navigateTo({
+				// 	url: "../../production/zidonghua/zidonghua?url=" + zdhxt
+				// })
+				
 				uni.navigateTo({
-					url: "../../production/zidonghua/zidonghua?url=" + zdhxt
+					url:"../../production/zaoquan/zidonghua_list/zidonghua_list?zdhxt=" + zdhxt
 				})
 			},
 			// 生产报表
@@ -199,7 +154,7 @@
 			// 矿井水处理
 			go_mine_water_treatment(){
 				uni.navigateTo({
-					url: "../../production/zaoquan/mine_water_treatment/mine_water_treatment"
+					url: "../../production/zaoquan/mine_water_treatment/mine_water_treatment?mine_code=" + this.mine_code
 				})
 			}
 		}

+ 18 - 5
components/t-w-zaoquan/t-w-zaoquan.vue

@@ -105,14 +105,24 @@
 						uni.navigateTo({
 							url:"../../my/message-reminder/message-reminder"
 						})
-					}
-					if(link.indexOf("/workBench/getDuty") != -1){
+					}else if(link.indexOf("/workBench/getDuty") != -1){
 						console.log("值班信息")
 						
 						uni.navigateTo({
 							url:"../../workbench/duty_information/duty_information"
 						})
+					}else if(link.indexOf("/workBench/huiyiList") != -1){
+						uni.showToast({
+							icon:"none",
+							title:"暂时没有会议"
+						})
+					}else{
+						uni.showToast({
+							icon:"none",
+							title:"暂未开通"
+						})
 					}
+					
 				}
 			},
 			getmodule(link){
@@ -156,9 +166,7 @@
 						uni.navigateTo({
 							url:"../../workbench/invoice_assistant/invoice_assistant"
 						})
-					}
-					// 下井记录
-					if(link.indexOf("/productionData/logging") != -1){
+					}else if(link.indexOf("/productionData/logging") != -1){
 						console.log("下井记录")
 						// uni.navigateTo({
 						// 	url:"../../production/personnel_orientation/downhole_statistics/downhole_statistics?people_num="+people_num+"&depart_name="+depart_name+"&name="+name+"&mine="+this.mine
@@ -168,6 +176,11 @@
 						uni.navigateTo({
 							url:"../../production/personnel_orientation/downhole_statistics/downhole_statistics"
 						})
+					}else if(link.indexOf("/browseQrcode/gridSubmitItem_win") != -1){
+						console.log("网格排查")
+						uni.navigateTo({
+							url:"../../workbench/gridding/gridding"
+						})
 					}
 				}
 				

+ 4 - 4
manifest.json

@@ -2,7 +2,7 @@
     "name" : "智慧枣泉",
     "appid" : "__UNI__4B520D3",
     "description" : "",
-    "versionName" : "1.0.1",
+    "versionName" : "1.0.2",
     "versionCode" : "100",
     "transformPx" : false,
     /* 5+App特有相关 */
@@ -92,9 +92,9 @@
             "splashscreen" : {
                 "androidStyle" : "default",
                 "android" : {
-                    "hdpi" : "static/qidongtu.png",
-                    "xhdpi" : "static/qidongtu.png",
-                    "xxhdpi" : "static/qidongtu.png"
+                    "hdpi" : "static/star.png",
+                    "xhdpi" : "static/star.png",
+                    "xxhdpi" : "static/star.png"
                 }
             }
         }

+ 116 - 3
pages.json

@@ -270,7 +270,7 @@
 			}
 
 		}, {
-			"path": "pages/origanization/zaoquan/origanization/origanization",
+			"path": "pages/origanization/communication/origanization/origanization",
 			"style": {
 				"navigationBarTitleText": "组织架构"
 			}
@@ -299,7 +299,7 @@
             
         }
         ,{
-            "path" : "pages/origanization/zaoquan/origanization/search/search",
+            "path" : "pages/origanization/communication/origanization/search/search",
             "style" :                                                                                    
             {
                 "navigationBarTitleText": "组织架构"
@@ -307,13 +307,126 @@
             
         }
         ,{
-            "path" : "pages/origanization/zaoquan/origanization/my_department/my_department",
+            "path" : "pages/origanization/communication/origanization/my_department/my_department",
             "style" :                                                                                    
             {
                 "navigationBarTitleText": "我的部门"
             }
             
         }
+        ,{
+            "path" : "pages/index/integral/integral",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "积分"
+            }
+            
+        }
+        ,{
+            "path" : "pages/index/integral/detail/detail",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "积分明细"
+            }
+            
+        }
+        ,{
+            "path" : "pages/workbench/gridding/gridding",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": " "
+            }
+            
+        }
+        
+        ,{
+            "path" : "pages/my/business-audit/business-audit",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "工单审核"
+            }
+            
+        }
+        ,{
+            "path" : "pages/my/business-audit/chakan/chakan",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": ""
+            }
+            
+        }
+        ,{
+            "path" : "pages/my/business-audit/shenhe/shenhe",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": ""
+            }
+            
+        }
+        ,{
+            "path" : "pages/my/business-my/business-my",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "我的工单"
+            }
+            
+        }
+        ,{
+            "path" : "pages/my/business-my/chakan/chakan",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": ""
+            }
+            
+        }
+        ,{
+            "path" : "pages/workbench/business_classfication/business_classfication",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": ""
+            }
+            
+        }
+        ,{
+            "path" : "pages/workbench/business_classfication/apply/apply",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": " "
+            }
+            
+        }
+        ,{
+            "path" : "pages/my/signature/signature",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "手写签名"
+            }
+            
+        }
+        ,{
+            "path" : "pages/my/personal_information/personal_information",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "个人信息"
+            }
+            
+        }
+        ,{
+            "path" : "pages/production/zaoquan/zidonghua_list/zidonghua_list",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": ""
+            }
+            
+        }
+        ,{
+            "path" : "pages/production/zaoquan/zidonghua_list/detail/detail",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": ""
+            }
+            
+        }
     ],
 	"globalStyle": {
 		"navigationBarTextStyle": "white",

+ 65 - 0
pages/index/integral/detail/detail.vue

@@ -0,0 +1,65 @@
+<template>
+	<view>
+		<view class="list">
+			<view class="item" v-for="(item,index) in list" :key="index">
+				<view class="left">
+					<view class="text">签到</view>
+					<view class="time">{{item.integral_time}}</view>
+				</view>
+				<view class="right">+1</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				list:[]
+			};
+		},
+		onLoad() {
+			this.get_staff_integral_query()
+		},
+		methods:{
+			//查询员工积分
+			get_staff_integral_query() {
+				this.$api.staff_integral_query({
+					staff_num: uni.getStorageSync('user').staff_num
+				}).then((res) => {
+					console.log(res.data.content.data)
+					
+					this.list = res.data.content.data.list
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.list{
+		box-sizing: border-box;
+		padding: 25rpx;
+		.item{
+			height: 110rpx;
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			.left{
+				line-height: 40rpx;
+				.text{
+					font-size: 30rpx;
+				}
+				.time{
+					font-size: 26rpx;
+					color: #B9B9B9;
+				}
+			}
+			.right{
+				font-size: 36rpx;
+				color: #009FE8;
+			}
+		}
+	}
+</style>

+ 178 - 0
pages/index/integral/integral.vue

@@ -0,0 +1,178 @@
+<template>
+	<view>
+		<view class="top">
+			<image src="https://cdn.colorhub.me/FtCRBWhR-HX35qVlQciv-quxr01HzFMcEnt3l-er1tY/auto/280/0/ce/0/bG9jYWw6Ly8vMzgv/MmUvNjIyZjRjN2Vj/MDgxMTllMWVlMDAx/ZTZmOWQ5YThiOTkw/NGFmMzgyZS5qcGVn.jpg" mode="aspectFill"></image>
+			
+			<view class="inner">
+				<view class="name">总积分</view>
+				<view class="total">{{total}}</view>
+			</view>
+		</view>
+		
+		<view class="content">
+			<view class="title">
+				<view class="text">积分规则</view>
+				<view class="more" @click="go_more()">积分明细 <uni-icons type="arrowright" color="#999" size="11"></uni-icons>
+				</view>
+			</view>
+			<view class="list">
+				<view class="item">
+					<view class="left">
+						<view class="type">签到</view>
+						<view class="text">1分/每日首次登录</view>
+						<view class="box">
+							<slider block-size="0" disabled :min="1" :max="1"/>
+							<view class="text">	已获1分/每日上限1分</view>
+						</view>
+					</view>
+					<view class="right">
+						<view class="tip" v-if="is_finish == 0" style="background-color: #94BA2B;color: #FFFFFF;">未完成</view>
+						<view class="tip" v-if="is_finish == 1">已完成</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 完成状态
+				is_finish:0,
+				// 总积分
+				total:0
+			};
+		},
+		onLoad() {
+			this.get_staff_integral_list()
+			//查询员工积分
+			this.get_staff_integral_query()
+		},
+		methods:{
+			//查询员工积分
+			get_staff_integral_query() {
+				this.$api.staff_integral_query({
+					staff_num: uni.getStorageSync('user').staff_num
+				}).then((res) => {
+					console.log(res)
+					
+					this.total = res.data.content.data.integral_sum
+				})
+			},
+			
+			get_staff_integral_list(){
+				this.$api.staff_integral_list({
+					staff_num: uni.getStorageSync('user').staff_num,
+					integral_type: 1
+				}).then((res)=>{
+					console.log(res.data.content.data)
+					
+					
+					
+					this.is_finish = res.data.content.data.is_finish
+				})
+			},
+			// 积分明细
+			go_more(){
+				uni.navigateTo({
+					url:"./detail/detail"
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.top{
+		image{
+			width: 750rpx;
+			height: 340rpx;
+		}
+		
+		position: relative;
+		
+		.inner{
+			position: absolute;
+			top: 0;
+			left: 0;
+			
+			width: 750rpx;
+			text-align: center;
+			color: #FFFFFF;
+			.name{
+				margin-top: 140rpx;
+				font-size: 32rpx;
+			}
+			.total{
+				font-size: 68rpx;
+				line-height: 150rpx;
+			}
+		}
+	}
+	
+	.content {
+		background-color: #FFFFFF;
+	
+		box-sizing: border-box;
+		padding: 50rpx 25rpx;
+	}
+	
+	.title {
+		display: flex;
+		align-items: baseline;
+		justify-content: space-between;
+	
+		.text {
+			font-size: 36rpx;
+		}
+	
+		.more {
+			font-size: 26rpx;
+			color: #999;
+	
+		}
+	}
+	
+	.list{
+		margin-top: 40rpx;
+		.item{
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			// height: 150rpx;
+			.left{
+				font-size: 28rpx;
+				line-height: 50rpx;
+				.type{
+					font-size: 32rpx;
+				}
+				.text{
+					color: #999;
+				}
+				.box{
+					display: flex;
+					align-items: center;
+					
+					slider{
+						margin: 0;
+						width: 100rpx;
+					}
+					.text{
+						margin-left: 20rpx;
+						color: #999;
+					}
+				}
+			}
+			.right{
+				.tip{
+					padding: 10rpx 20rpx;
+					background-color: #e9e9e9;
+					color: #666;
+					font-size: 24rpx;
+				}
+			}
+		}
+	}
+</style>

+ 244 - 0
pages/my/business-audit/business-audit.vue

@@ -0,0 +1,244 @@
+<template>
+	<view class="content">
+		<view class="title">
+			<view class="item" :class="active_item == 0?'active':''" @click="click_btn(0)">待审核</view>
+			<view class="item" :class="active_item == 1?'active':''" @click="click_btn(1)">已审核</view>
+		</view>
+		<view class="list" v-if="active_item == 0">
+			<view class="item" v-for="(item,index) in list" :key="index" v-if="item.staff_state == 0">
+				<view class="top">
+					<view class="user">
+						<!-- <view class="img">
+							<image :src="item.staff_avatar" mode="aspectFill"></image>
+						</view> -->
+						<view class="info">
+							<view class="text">{{item.name}}</view>
+							<view class="text">编号:#{{item.id}} {{item.created_at}}</view>
+						</view>
+					</view>
+					<view class="state" v-if="item.staff_state == 0">待审核</view>
+				</view>
+				<view class="inner">
+					<view class="class_name">{{item.classify}}</view>
+					<view class="name">{{item.title}}</view>
+					<view class="tip">{{item.introduce}}</view>
+				</view>
+				<view class="bottom">
+					<view class="btn" @click="go_shenhe(item.id,item.title)">审核</view>
+				</view>
+			</view>
+		</view>
+		<view class="list" v-if="active_item == 1">
+			<view class="item" v-for="(item,index) in list" :key="index"  v-if="item.staff_state == 1" :style="item.state == 3?'border-top: 2px solid red;':''">
+				<view class="top">
+					<view class="user">
+						<!-- <view class="img">
+							<image :src="item.staff_avatar" mode="aspectFill"></image>
+						</view> -->
+						<view class="info">
+							<view class="text">{{item.name}}</view>
+							<view class="text">编号:#{{item.id}} {{item.created_at}}</view>
+						</view>
+					</view>
+					<view class="state" v-if="item.state == 1 && item.staff_state == 1" style="color: #00D983;">已审核</view>
+					<view class="state" v-if="item.state == 2" style="color: #00D983;">{{item.status}}</view>
+					<view class="state" v-if="item.state == 3" style="color: red;">{{item.status}}</view>
+				</view>
+				<view class="inner">
+					<view class="class_name">{{item.classify}}</view>
+					<view class="name">{{item.title}}</view>
+					<view class="tip">{{item.introduce}}</view>
+				</view>
+				<view class="bottom" v-if="active_item == 1">
+					<view class="btn" @click="go_shenhe(item.id,item.title)">审核</view>
+				</view>
+				<view class="bottom" v-if="active_item == 2">
+					<view class="btn" style="background-color: #009FE8;" @click="go_chakan(item.id,item.title)">查看</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				active_item:0,
+				list:[],
+				
+				
+				page:1,
+				page_size:10,
+				state:0
+			};
+		},
+		onLoad() {
+			// this.get_worksheet_check_listmei()
+		},
+		onShow() {
+			this.get_worksheet_check_listmei()
+		},
+		onReachBottom(){
+			console.log("++")
+			this.page++
+			this.get_worksheet_check_listmei()
+		},
+		methods:{
+			// 切换列表
+			click_btn(item){
+				this.active_item = item
+				this.state = item
+				this.page = 1
+				this.list = []
+				
+				// 刷新数据
+				if(item == 0){
+					this.get_worksheet_check_listmei()
+				}else if(item == 1){
+					this.get_worksheet_check_listmei()
+				}
+			},
+			go_shenhe(id,title){
+				uni.navigateTo({
+					url:"shenhe/shenhe?id=" + id + "&title=" + title
+				})
+			},
+			go_chakan(id,title){
+				uni.navigateTo({
+					url:"chakan/chakan?id=" + id + "&title=" + title
+				})
+			},
+			get_worksheet_check_listmei(){
+				uni.showLoading()
+				
+				this.$api.worksheet_check_listmei({
+					page:this.page,
+					size:this.page_size,
+					state:this.state,
+					
+				}).then((res)=>{
+					console.log(res)
+					console.log(res.data.data)
+					this.list = this.list.concat(res.data.data)
+					
+					uni.hideLoading()
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		width: 749rpx;
+	}
+	
+	.title{
+		position: fixed;
+		top: 1;
+		left: 0rpx;
+		z-index: 999;
+		background-color: #FFFFFF;
+		
+		height: 43px;
+		display: flex;
+	
+		border-bottom: 1px solid #E4E4E4;
+		.item{
+			width: 374rpx;
+			line-height: 43px;
+			text-align: center;
+			font-size: 16px;
+			color: #BDC3C7;
+		}
+		.active{
+			border-bottom: 2px solid #16A085;
+			color: #16A085;
+		}
+		
+	}
+	
+	.list{
+		box-sizing: border-box;
+		padding: 24rpx;
+		
+		padding-top: 53px;
+		.item{
+			width: 700rpx;
+			border-radius: 6px;
+			border: 1px solid #EDEFF9;
+			border-top: 2px solid #00D983;
+			
+			box-sizing: border-box;
+			padding: 10px 25rpx;
+			
+			margin-bottom: 15px;
+			.top{
+				display: flex;
+				justify-content: space-between;
+				.user{
+					display: flex;
+					.img{
+						width: 60px;
+						height: 60px;
+						border-radius: 50%;
+						overflow: hidden;
+						image{
+							width: 60px;
+							height: 60px;
+						}
+					}
+					.info{
+						margin-left: 10rpx;
+						height: 60px;
+						.text{
+							line-height: 25px;
+							font-size: 12px;
+						}
+					}
+				}
+				.state{
+					width: 150rpx;
+					text-align: right;
+					line-height: 25px;
+					font-size: 12px;
+					color: #2ECC71;
+				}
+				
+			}
+			.inner{
+				margin: 10px auto;
+				width: 650rpx;
+				border: 1px solid #EDEFF9;
+				border-radius: 6px;
+				box-sizing: border-box;
+				padding: 10px;
+				font-size: 12px;
+				.class_name{
+					line-height: 20px;
+					color: #3498DB;
+				}
+				.name{
+					line-height: 20px;
+				}
+				.tip{
+					line-height: 20px;
+					text-indent: 2em;
+				}
+			}
+			.bottom{
+				text-align: right;
+				.btn{
+					display: inline-block;
+					width: 80px;
+					text-align: center;
+					line-height: 30px;
+					font-size: 12px;
+					color: #FFFFFF;
+					background-color: #16A085;
+				}
+			}
+		}
+	}
+</style>

+ 377 - 0
pages/my/business-audit/chakan/chakan.vue

@@ -0,0 +1,377 @@
+<template>
+	<view>
+		<view class="content">
+			<view class="section">
+				<view class="title">申请人</view>
+				<view class="inner">
+					<view class="user">
+						<!-- <view class="img">
+							<view class="avatar" :style="{backgroundColor:bgColor[1]}">{{detail.staff.split('').pop()}}</view>
+						</view> -->
+						<view class="info">
+							<view class="name">{{detail.staff}}</view>
+							<view class="section">{{detail.staff_section}}</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">申请时间</view>
+				<view class="inner">{{detail.created_at}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务分类</view>
+				<view class="inner">{{detail.classify}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务名称</view>
+				<view class="inner">{{detail.title}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务介绍</view>
+				<view class="inner">{{detail.introduce}}</view>
+			</view>
+			<view class="section" v-if="detail.filelist">
+				<view class="title">需审核文件</view>
+				<view class="inner">
+					<view class="file_list">
+						<view class="item" v-for="(item,index) in detail.filelist" :key="index"
+							@click="open_file(item.path)">
+							<view class="left">
+								<view class="icon"></view>
+								<view class="info">
+									<view class="name">{{item.fileName}}</view>
+									<!-- <view class="size">{{item.fileSize}}KB</view> -->
+								</view>
+							</view>
+							<view class="right">
+								<uni-icons type="arrowright"></uni-icons>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section" v-if="detail.$photos">
+				<view class="title">需审核图片</view>
+				<view class="inner">
+					<view class="img_list">
+						<view class="item" v-for="item in detail.$photos">
+							<image :src="item.path" @click="open_img(item.path)"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">审批流程</view>
+				<view class="inner">
+					<view class="shenpi_list">
+						<view class="item" v-for="(item,index) in detail.approval_list" :key="index">
+							<view class="name">{{item.title}}</view>
+							<view class="list">
+								<view class="box" v-for="(item_2,index_2) in item.member" :key="index_2">
+									<view class="label">{{item_2.title}}:{{item_2.name}}</view>
+									<view v-if="!item_2.state" style="color: #F0AD4E;">待审核。</view>
+									<view class="label" v-if="item_2.state == 2 && item_2.remark == ''" style="color: #E94C3D;">驳回。</view>
+									<view class="label" v-if="item_2.state == 0 && item_2.remark == ''" style="color: #E94C3D;">驳回。</view>
+									<view class="label" v-if="item_2.state == 1 && item_2.remark == ''" style="color: #17A086;">通过。</view>
+									<view class="remark" v-if="item_2.state == 1" style="color: #17A086;">{{item_2.remark}}</view>
+									<view class="remark" v-if="item_2.state == 2 || item_2.state == 0 || item_2.state == 3" style="color: #E94C3D;">{{item_2.remark}}</view>
+									<view v-if="item_2.state == 1">
+										<image :src="item_2.base_img" style="width: 300rpx; height: 90rpx;"></image>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+
+		</view>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 业务id
+				id: 0,
+				// 业务详情
+				detail: {},
+				// 审核留言
+				remark_text: "",
+				// 头像随即色
+				bgColor: []
+			};
+		},
+		onLoad(option) {
+			// console.log(option.id)
+			// 设置业务id
+			this.id = option.id
+			// 设置标题
+			uni.setNavigationBarTitle({
+				title: option.title
+			})
+			// 获取业务详情
+			this.get_worksheet_checkmei(option.id)
+		},
+		methods: {
+			// 获取业务详情
+			get_worksheet_checkmei(id) {
+				// 业务详情接口
+				this.$api.worksheet_checkmei({
+					id: id
+				}).then((res) => {
+					console.log(res.data.data)
+
+					for (let i = 0; i < 2; i++) {
+						// 获取随机色
+						let r = parseInt(Math.random() * 256)
+						let g = parseInt(Math.random() * 256)
+						let b = parseInt(Math.random() * 256)
+
+						// ES6 字符串拼接
+						// this.bgColor = `rgba(${r},${g},${b},0.3)`
+						let color = "rgba(" + r + "," + g + "," + b + "," + 0.3 + ")"
+						// console.log(color)
+						this.bgColor.push(color)
+					}
+
+					this.detail = res.data.data
+				})
+			},
+			// 审核事件
+			btn_shenhe(type) {
+				// 提交审核接口
+				this.$api.worksheet_checkmei_tijiao({
+					id: this.id,
+					allow: type,
+					remark: this.remark_text
+				}).then((res) => {
+					console.log(res.data)
+					// 审核过
+					if (res.data.code == 1) {
+						uni.showToast({
+							icon: "none",
+							title: res.data.message
+						})
+					} else {
+						uni.switchTab({
+							url: "../../../tabbar/my/my"
+						})
+					}
+
+				})
+			},
+
+			// 预览文件
+			open_file(path) {
+				uni.downloadFile({
+				  url: path,
+				  success: function (res) {
+				    var filePath = res.tempFilePath;
+				    uni.openDocument({
+				      filePath: filePath,
+				      success: function (res) {
+				        console.log('打开文档成功');
+				      }
+				    });
+				  }
+				});
+			},
+			// 预览图片
+			open_img(path){
+				const urls = [];
+				urls.push(path)
+				// console.log(urls[0])
+				uni.previewImage({
+					urls: urls,
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		margin-bottom: 40px;
+		background-color: #F3F3F3;
+
+		width: 749rpx;
+		box-sizing: border-box;
+		padding: 24rpx;
+	}
+
+	.content {
+		width: 700rpx;
+		min-height: 90vh;
+		background-color: #FFFFFF;
+		border-radius: 4px;
+
+		box-sizing: border-box;
+		padding: 25rpx;
+	}
+
+	.section {
+		.title {
+			padding-left: 8px;
+			border-left: 2px solid #009FE8;
+			font-weight: 700;
+		}
+
+		.inner {
+			padding: 10px;
+
+			.user {
+				display: flex;
+				align-items: center;
+
+				.img {
+					width: 66px;
+					height: 66px;
+					border-radius: 50%;
+					overflow: hidden;
+
+					image {
+						width: 66px;
+						height: 66px;
+					}
+
+					.avatar {
+						width: 66px;
+						height: 66px;
+						text-align: center;
+						line-height: 66px;
+						color: #FFFFFF;
+						font-size: 28px;
+					}
+				}
+
+				.info {
+
+					// margin-left: 12px;
+					.name {
+						font-size: 19px;
+						font-family: PingFangSC-Medium, PingFang SC;
+						font-weight: 500;
+						color: #232627;
+						line-height: 26px;
+					}
+
+					.section {
+						margin-top: 4px;
+						font-size: 14px;
+						font-family: PingFangSC-Medium, PingFang SC;
+						font-weight: 500;
+						color: #232627;
+						line-height: 19px;
+					}
+				}
+			}
+
+			.file_list {
+				.item {
+					height: 49px;
+
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+
+					border-bottom: 1px solid #ECF0F1;
+					padding: 8px 0;
+
+					.left {
+						display: flex;
+						align-items: center;
+
+						.icon {}
+
+						.info {
+							height: 49px;
+							display: flex;
+							flex-flow: column;
+							justify-content: space-around;
+
+							.name {
+								font-size: 16px;
+								font-family: MicrosoftYaHei;
+								color: #2C3E50;
+							}
+
+							.size {
+								font-size: 13px;
+								font-family: MicrosoftYaHei;
+								color: #BDC3C7;
+							}
+						}
+					}
+
+					.right {}
+				}
+			}
+
+			.img_list {
+				overflow: hidden;
+
+				.item {
+					float: left;
+					width: 284rpx;
+					height: 260rpx;
+					margin-right: 40rpx;
+					margin-bottom: 40rpx;
+
+					image {
+						width: 284rpx;
+						height: 260rpx;
+					}
+				}
+
+				.item:nth-child(2n) {
+					margin-right: 0;
+				}
+			}
+
+			.shenpi_list {
+				width: 612rpx;
+
+				.item {
+					display: flex;
+
+					.name {
+						width: 200rpx;
+						color: #009FE8;
+					}
+
+					.list {
+						width: 412rpx;
+
+						.box {
+							margin-bottom: 8px;
+
+							.label {}
+
+							.remark {}
+						}
+					}
+				}
+			}
+
+			.remark_text {
+				border: 1px solid #BDC3C7;
+			}
+		}
+	}
+
+	.bottom {
+		margin-top: 20px;
+		display: flex;
+		justify-content: space-around;
+
+		.btn {
+			padding: 8px 40px;
+			color: #FFFFFF;
+			border-radius: 60px;
+		}
+	}
+</style>

+ 461 - 0
pages/my/business-audit/shenhe/shenhe.vue

@@ -0,0 +1,461 @@
+<template>
+	<view>
+		<view class="content">
+			<view class="section">
+				<view class="title">申请人</view>
+				<view class="inner">
+					<view class="user">
+						<!-- <view class="img">
+							<view class="avatar" :style="{backgroundColor:bgColor[1]}">{{detail.staff.split('').pop()}}</view>
+						</view> -->
+						<view class="info">
+							<view class="name">{{detail.staff}}</view>
+							<view class="section">{{detail.staff_section}}</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">申请时间</view>
+				<view class="inner">{{detail.created_at}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务分类</view>
+				<view class="inner">{{detail.classify}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务名称</view>
+				<view class="inner">{{detail.title}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务介绍</view>
+				<view class="inner">{{detail.introduce}}</view>
+			</view>
+			<view class="section" v-if="detail.filelist">
+				<view class="title">需审核文件</view>
+				<view class="inner">
+					<view class="file_list">
+						<view class="item" v-for="(item,index) in detail.filelist" :key="index"
+							@click="open_file(item.path)">
+							<view class="left">
+								<view class="icon"></view>
+								<view class="info">
+									<view class="name">{{item.fileName}}</view>
+									<!-- <view class="size">{{item.fileSize}}KB</view> -->
+								</view>
+							</view>
+							<view class="right">
+								<uni-icons type="arrowright"></uni-icons>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section" v-if="detail.$photos">
+				<view class="title">需审核图片</view>
+				<view class="inner">
+					<view class="img_list">
+						<view class="item" v-for="item in detail.$photos">
+							<image :src="item.path" @click="open_img(item.path)"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">审批流程</view>
+				<view class="inner">
+					<view class="shenpi_list">
+						<view class="item" v-for="(item,index) in detail.approval_list" :key="index">
+							<view class="name">{{item.title}}</view>
+							<view class="list">
+								<view class="box" v-for="(item_2,index_2) in item.member" :key="index_2">
+									<view class="label">{{item_2.title}}:{{item_2.name}}</view>
+									<view v-if="!item_2.state" style="color: #F0AD4E;">待审核。</view>
+									<view class="label" v-if="item_2.state == 2 && item_2.remark == ''"
+										style="color: #E94C3D;">驳回。</view>
+									<view class="label" v-if="item_2.state == 0 && item_2.remark == ''"
+										style="color: #E94C3D;">驳回。</view>
+									<view class="label" v-if="item_2.state == 1 && item_2.remark == ''"
+										style="color: #17A086;">通过。</view>
+									<view class="remark" v-if="item_2.state == 1" style="color: #17A086;">
+										{{item_2.remark}}
+									</view>
+									<view class="remark"
+										v-if="item_2.state == 2 || item_2.state == 0 || item_2.state == 3"
+										style="color: #E94C3D;">{{item_2.remark}}</view>
+									<view v-if="item_2.state == 1">
+										<image :src="item_2.base_img" style="width: 300rpx; height: 90rpx;"></image>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">审批意见</view>
+				<view class="inner">
+					<view class="remark_text">
+						<textarea value="" v-model="remark_text" placeholder="请输入审批意见。"
+							style="height: 80px; padding: 10px;" />
+					</view>
+				</view>
+			</view>
+
+		</view>
+
+
+		<view class="bottom">
+			<view class="btn" style="background-color: #16A086;" @click="btn_shenhe(1)">通过</view>
+			<view class="btn" style="background-color: #E94C3D;" @click="btn_shenhe(0)">驳回</view>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 业务id
+				id: 0,
+				// 业务详情
+				detail: {},
+				// 审核留言
+				remark_text: "",
+				// 头像随即色
+				bgColor: [],
+
+
+				// 单据是否需要强制浏览类型 0 不强制 1 强制浏览
+				is_browse: 0,
+				
+				// 职位是否需要强制浏览 1是 2否
+				is_force: 2,
+				// 职位浏览时长
+				browse_duration: 0,
+
+				// 是否浏览完成
+				is_read: true,
+				
+				// 工号
+				staff_num:""
+
+			};
+		},
+		onLoad(option) {
+			// console.log(option.id)
+			// 设置业务id
+			this.id = option.id
+			// 设置标题
+			uni.setNavigationBarTitle({
+				title: option.title
+			})
+			// 获取业务详情
+			this.get_worksheet_checkmei(option.id)
+
+
+			this.staff_num = uni.getStorageSync('user').staff_num
+
+		},
+		methods: {
+			// 获取业务详情
+			get_worksheet_checkmei(id) {
+				// 业务详情接口
+				this.$api.worksheet_checkmei({
+					id: id
+				}).then((res) => {
+					console.log(res.data.data)
+
+					for (let i = 0; i < 2; i++) {
+						// 获取随机色
+						let r = parseInt(Math.random() * 256)
+						let g = parseInt(Math.random() * 256)
+						let b = parseInt(Math.random() * 256)
+
+						// ES6 字符串拼接
+						// this.bgColor = `rgba(${r},${g},${b},0.3)`
+						let color = "rgba(" + r + "," + g + "," + b + "," + 0.3 + ")"
+						// console.log(color)
+						this.bgColor.push(color)
+					}
+
+					this.detail = res.data.data
+
+					this.is_browse = res.data.data.is_browse
+
+					if (this.is_browse == 1) {
+						// 1 需要强制浏览
+						this.is_read = false
+
+						// 强制浏览限制时间
+						this.$api.worksheet_force_query({
+							staff_num: this.staff_num
+						}).then((res) => {
+							console.log(res.data.data)
+
+							this.is_force = res.data.data.is_force
+							// 1强制 2不强制
+							if (this.is_force == 1) {
+								this.browse_duration = res.data.data.browse_duration
+								
+								// 计时
+								setTimeout(() => {
+									this.is_read = true
+								}, this.browse_duration*60000)
+							} else if (this.is_force == 2) {
+								
+							}
+						})
+					}
+
+				})
+			},
+			// 审核事件
+			btn_shenhe(type) {
+
+				// 判断是否浏览相应时长
+				if (!this.is_read) {
+					uni.showToast({
+						icon: "none",
+						title: "至少浏览" + this.browse_duration + "分钟、才可审批"
+					})
+
+					return
+				}
+
+				// 提交审核接口
+				this.$api.worksheet_checkmei_tijiao({
+					id: this.id,
+					allow: type,
+					remark: this.remark_text
+				}).then((res) => {
+					console.log(res.data)
+					// 审核过
+					if (res.data.code == 1) {
+						uni.showToast({
+							icon: "none",
+							title: res.data.message
+						})
+					} else {
+						// uni.switchTab({
+						// 	url: "../../../tabbar/my/my"
+						// })
+						uni.navigateBack()
+					}
+
+				})
+			},
+
+			// 预览文件
+			open_file(path) {
+				uni.downloadFile({
+					url: path,
+					success: (res) => {
+						var filePath = res.tempFilePath;
+						uni.openDocument({
+							filePath: filePath,
+							success: (res) => {
+								console.log('打开文档成功');
+
+								
+							}
+						});
+					}
+				});
+			},
+			// 预览图片
+			open_img(path) {
+				const urls = [];
+				urls.push(path)
+				// console.log(urls[0])
+				uni.previewImage({
+					urls: urls,
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		margin-bottom: 40px;
+		background-color: #F3F3F3;
+
+		width: 749rpx;
+		box-sizing: border-box;
+		padding: 24rpx;
+	}
+
+	.content {
+		width: 700rpx;
+		min-height: 90vh;
+		background-color: #FFFFFF;
+		border-radius: 4px;
+
+		box-sizing: border-box;
+		padding: 25rpx;
+	}
+
+	.section {
+		.title {
+			padding-left: 8px;
+			border-left: 2px solid #009FE8;
+			font-weight: 700;
+		}
+
+		.inner {
+			padding: 10px;
+
+			.user {
+				display: flex;
+				align-items: center;
+
+				.img {
+					width: 66px;
+					height: 66px;
+					border-radius: 50%;
+					overflow: hidden;
+
+					image {
+						width: 66px;
+						height: 66px;
+					}
+
+					.avatar {
+						width: 66px;
+						height: 66px;
+						text-align: center;
+						line-height: 66px;
+						color: #FFFFFF;
+						font-size: 28px;
+					}
+				}
+
+				.info {
+
+					// margin-left: 12px;
+					.name {
+						font-size: 19px;
+						font-family: PingFangSC-Medium, PingFang SC;
+						font-weight: 500;
+						color: #232627;
+						line-height: 26px;
+					}
+
+					.section {
+						margin-top: 4px;
+						font-size: 14px;
+						font-family: PingFangSC-Medium, PingFang SC;
+						font-weight: 500;
+						color: #232627;
+						line-height: 19px;
+					}
+				}
+			}
+
+			.file_list {
+				.item {
+					height: 49px;
+
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+
+					border-bottom: 1px solid #ECF0F1;
+					padding: 8px 0;
+
+					.left {
+						display: flex;
+						align-items: center;
+
+						.icon {}
+
+						.info {
+							height: 49px;
+							display: flex;
+							flex-flow: column;
+							justify-content: space-around;
+
+							.name {
+								font-size: 16px;
+								font-family: MicrosoftYaHei;
+								color: #2C3E50;
+							}
+
+							.size {
+								font-size: 13px;
+								font-family: MicrosoftYaHei;
+								color: #BDC3C7;
+							}
+						}
+					}
+
+					.right {}
+				}
+			}
+
+			.img_list {
+				overflow: hidden;
+
+				.item {
+					float: left;
+					width: 284rpx;
+					height: 260rpx;
+					margin-right: 40rpx;
+					margin-bottom: 40rpx;
+
+					image {
+						width: 284rpx;
+						height: 260rpx;
+					}
+				}
+
+				.item:nth-child(2n) {
+					margin-right: 0;
+				}
+			}
+
+			.shenpi_list {
+				width: 612rpx;
+
+				.item {
+					display: flex;
+
+					.name {
+						width: 200rpx;
+						color: #009FE8;
+					}
+
+					.list {
+						width: 412rpx;
+
+						.box {
+							margin-bottom: 8px;
+
+							.label {}
+
+							.remark {}
+						}
+					}
+				}
+			}
+
+			.remark_text {
+				border: 1px solid #BDC3C7;
+			}
+		}
+	}
+
+	.bottom {
+		margin-top: 20px;
+		display: flex;
+		justify-content: space-around;
+
+		.btn {
+			padding: 8px 40px;
+			color: #FFFFFF;
+			border-radius: 60px;
+		}
+	}
+</style>

+ 300 - 0
pages/my/business-my/business-my.vue

@@ -0,0 +1,300 @@
+<template>
+	<view class="content">
+		<view class="title">
+			<view class="item" :class="active_item == 0?'active':''" @click="click_btn(0)">全部</view>
+			<view class="item" :class="active_item == 1?'active':''" @click="click_btn(1)">待审核</view>
+			<view class="item" :class="active_item == 2?'active':''" @click="click_btn(2)">已通过</view>
+			<view class="item" :class="active_item == 3?'active':''" @click="click_btn(3)">被驳回</view>
+		</view>
+		<view class="list">
+			<view class="item" v-for="(item,index) in list" :key="index" v-if="active_item == 0" :style="item.state == 3?'border-top-color: red;':''">
+				<view class="top">
+					<view class="user">
+						<view class="img" v-if="item.staff_avatar">
+							<image :src="item.staff_avatar" mode="aspectFill"></image>
+						</view>
+						<view class="info">
+							<view class="text">{{item.section}}{{item.staff}}</view>
+							<view class="text">编号:#{{item.id}} {{item.created_at}}</view>
+						</view>
+					</view>
+					<view class="state" v-if="item.state == 1">{{item.status}}</view>
+					<view class="state" v-if="item.state == 2">{{item.status}}</view>
+					<view class="state" v-if="item.state == 3" style="color: red;">{{item.status}}</view>
+				</view>
+				<view class="inner">
+					<view class="class_name">{{item.classify}} : </view>
+					<view class="name">{{item.title}}</view>
+					<view class="tip">{{item.introduce}}</view>
+				</view>
+				<view class="bottom">
+					<view class="btn" style="background-color: #FDDD9B; margin-right: 10px;" v-if="item.state == 1" @click="del_btn(item.id,item.title)">撤回</view>
+					<view class="btn" @click="go_chakan(item.id,item.title)">查看</view>
+				</view>
+			</view>
+			<view class="item" v-for="(item,index) in list" :key="index" v-if="active_item == 1 && item.state == 1">
+				<view class="top">
+					<view class="user">
+						<!-- <view class="img">
+							<image :src="item.staff_avatar" mode="aspectFill"></image>
+						</view> -->
+						<view class="info">
+							<view class="text">{{item.section}}{{item.staff}}</view>
+							<view class="text">编号:#{{item.id}} {{item.created_at}}</view>
+						</view>
+					</view>
+					<view class="state" v-if="item.state == 1">{{item.status}}</view>
+				</view>
+				<view class="inner">
+					<view class="class_name">{{item.classify}} : </view>
+					<view class="name">{{item.title}}</view>
+					<view class="tip">{{item.introduce}}</view>
+				</view>
+				<view class="bottom">
+					<view class="btn" style="background-color: #FDDD9B; margin-right: 10px;" v-if="item.state == 1" @click="del_btn(item.id,item.title)">撤回</view>
+					<view class="btn" @click="go_chakan(item.id,item.title)">查看</view>
+				</view>
+			</view>
+			<view class="item" v-for="(item,index) in list" :key="index" v-if="active_item == 2 && item.state == 2">
+				<view class="top">
+					<view class="user">
+						<!-- <view class="img">
+							<image :src="item.staff_avatar" mode="aspectFill"></image>
+						</view> -->
+						<view class="info">
+							<view class="text">{{item.section}}{{item.staff}}</view>
+							<view class="text">编号:#{{item.id}} {{item.created_at}}</view>
+						</view>
+					</view>
+					
+					<view class="state" v-if="item.state == 2">{{item.status}}</view>
+				</view>
+				<view class="inner">
+					<view class="class_name">{{item.classify}} : </view>
+					<view class="name">{{item.title}}</view>
+					<view class="tip">{{item.introduce}}</view>
+				</view>
+				<view class="bottom">
+					<view class="btn" @click="go_chakan(item.id,item.title)">查看</view>
+				</view>
+			</view>
+			<view class="item" v-for="(item,index) in list" :key="index" v-if="active_item == 3 && item.state == 3" style="border-top-color: red;">
+				<view class="top">
+					<view class="user">
+						<!-- <view class="img">
+							<image :src="item.staff_avatar" mode="aspectFill"></image>
+						</view> -->
+						<view class="info">
+							<view class="text">{{item.section}}{{item.staff}}</view>
+							<view class="text">编号:#{{item.id}} {{item.created_at}}</view>
+						</view>
+					</view>
+					
+					<view class="state" v-if="item.state == 3" style="color: red;">{{item.status}}</view>
+				</view>
+				<view class="inner">
+					<view class="class_name">{{item.classify}} : </view>
+					<view class="name">{{item.title}}</view>
+					<view class="tip">{{item.introduce}}</view>
+				</view>
+				<view class="bottom">
+					<view class="btn" @click="go_chakan(item.id,item.title)">查看</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				active_item:0,
+				list:[],
+				
+				
+				page:1,
+				page_size:10,
+				state:0
+			};
+		},
+		onLoad() {
+			this.get_worksheet_apply_listmei()
+		},
+		onReachBottom(){
+			console.log("++")
+			this.page++
+			this.get_worksheet_apply_listmei()
+		},
+		methods:{
+			// 切换列表
+			click_btn(item){
+				this.active_item = item
+				this.state = item
+				this.page = 1
+				this.list = []
+				// 刷新数据
+				if(item == 0){
+					this.get_worksheet_apply_listmei()
+				}else if(item == 1){
+					this.get_worksheet_apply_listmei()
+				}else if(item == 2){
+					this.get_worksheet_apply_listmei()
+				}else if(item == 3){
+					this.get_worksheet_apply_listmei()
+				}
+			},
+			go_chakan(id,title){
+				console.log(id,title)
+				
+				uni.navigateTo({
+					url:"chakan/chakan?id=" + id + "&title=" + title
+				})
+			},
+			get_worksheet_apply_listmei(){
+				uni.showLoading()
+				
+				this.$api.worksheet_apply_listmei({
+					page:this.page,
+					size:this.page_size,
+					state:this.state,
+				}).then((res)=>{
+					// console.log(res.data.data)
+					this.list = this.list.concat(res.data.data)
+					
+					uni.hideLoading()
+				})
+			},
+			
+			// 撤回
+			del_btn(id,title){
+				console.log(id,title)
+				
+				uni.showModal({
+				    title: '撤回提醒',
+				    content: '是否撤回' + title + '?',
+				    success: (res) => {
+				        if (res.confirm) {
+				            // console.log('用户点击确定');
+							this.$api.worksheet_orderdel({
+								id:id
+							}).then((res)=>{
+								// console.log(res)
+								
+								this.get_worksheet_apply_listmei()
+							})
+				        } else if (res.cancel) {
+				            console.log('用户点击取消');
+				        }
+				    }
+				});
+				
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content{
+		width: 749rpx;
+	}
+	
+	.title{
+		height: 43px;
+		display: flex;
+	
+		border-bottom: 1px solid #E4E4E4;
+		.item{
+			width: 249rpx;
+			line-height: 43px;
+			text-align: center;
+			font-size: 16px;
+			color: #BDC3C7;
+		}
+		.active{
+			border-bottom: 2px solid #16A085;
+			color: #16A085;
+		}
+	}
+	
+	.list{
+		box-sizing: border-box;
+		padding: 24rpx;
+		.item{
+			width: 700rpx;
+			border-radius: 6px;
+			border: 1px solid #EDEFF9;
+			border-top: 2px solid #00D983;
+			
+			box-sizing: border-box;
+			padding: 10px 25rpx;
+			
+			margin-bottom: 15px;
+			.top{
+				display: flex;
+				justify-content: space-between;
+				.user{
+					display: flex;
+					.img{
+						width: 60px;
+						height: 60px;
+						border-radius: 50%;
+						overflow: hidden;
+						image{
+							width: 60px;
+							height: 60px;
+						}
+					}
+					.info{
+						margin-left: 10rpx;
+						height: 60px;
+						.text{
+							line-height: 25px;
+							font-size: 12px;
+						}
+					}
+				}
+				.state{
+					width: 150rpx;
+					text-align: right;
+					line-height: 25px;
+					font-size: 12px;
+					color: #2ECC71;
+				}
+				
+			}
+			.inner{
+				margin: 10px auto;
+				width: 650rpx;
+				border: 1px solid #EDEFF9;
+				border-radius: 6px;
+				box-sizing: border-box;
+				padding: 10px;
+				font-size: 12px;
+				.class_name{
+					line-height: 20px;
+					color: #3498DB;
+				}
+				.name{
+					line-height: 20px;
+				}
+				.tip{
+					line-height: 20px;
+					text-indent: 2em;
+				}
+			}
+			.bottom{
+				text-align: right;
+				.btn{
+					display: inline-block;
+					width: 80px;
+					text-align: center;
+					line-height: 30px;
+					font-size: 12px;
+					color: #FFFFFF;
+					background-color: #3498DB;
+				}
+			}
+		}
+	}
+</style>

+ 377 - 0
pages/my/business-my/chakan/chakan.vue

@@ -0,0 +1,377 @@
+<template>
+	<view>
+		<view class="content">
+			<view class="section">
+				<view class="title">申请人</view>
+				<view class="inner">
+					<view class="user">
+						<!-- <view class="img">
+							<view class="avatar" :style="{backgroundColor:bgColor[1]}">{{detail.staff.split('').pop()}}</view>
+						</view> -->
+						<view class="info">
+							<view class="name">{{detail.staff}}</view>
+							<view class="section">{{detail.staff_section}}</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">申请时间</view>
+				<view class="inner">{{detail.created_at}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务分类</view>
+				<view class="inner">{{detail.classify}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务名称</view>
+				<view class="inner">{{detail.title}}</view>
+			</view>
+			<view class="section">
+				<view class="title">业务介绍</view>
+				<view class="inner">{{detail.introduce}}</view>
+			</view>
+			<view class="section" v-if="detail.filelist">
+				<view class="title">需审核文件</view>
+				<view class="inner">
+					<view class="file_list">
+						<view class="item" v-for="(item,index) in detail.filelist" :key="index"
+							@click="open_file(item.path)">
+							<view class="left">
+								<view class="icon"></view>
+								<view class="info">
+									<view class="name">{{item.fileName}}</view>
+									<!-- <view class="size">{{item.fileSize}}KB</view> -->
+								</view>
+							</view>
+							<view class="right">
+								<uni-icons type="arrowright"></uni-icons>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section" v-if="detail.$photos">
+				<view class="title">需审核图片</view>
+				<view class="inner">
+					<view class="img_list">
+						<view class="item" v-for="item in detail.$photos">
+							<image :src="item.path" @click="open_img(item.path)"></image>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="section">
+				<view class="title">审批流程</view>
+				<view class="inner">
+					<view class="shenpi_list">
+						<view class="item" v-for="(item,index) in detail.approval_list" :key="index">
+							<view class="name">{{item.title}}</view>
+							<view class="list">
+								<view class="box" v-for="(item_2,index_2) in item.member" :key="index_2">
+									<view class="label">{{item_2.title}}:{{item_2.name}}</view>
+									<view v-if="!item_2.state" style="color: #F0AD4E;">待审核。</view>
+									<view class="label" v-if="item_2.state == 2 && item_2.remark == ''" style="color: #E94C3D;">驳回。</view>
+									<view class="label" v-if="item_2.state == 0 && item_2.remark == ''" style="color: #E94C3D;">驳回。</view>
+									<view class="label" v-if="item_2.state == 1 && item_2.remark == ''" style="color: #17A086;">通过。</view>
+									<view class="remark" v-if="item_2.state == 1" style="color: #17A086;">{{item_2.remark}}</view>
+									<view class="remark" v-if="item_2.state == 2 || item_2.state == 0 || item_2.state == 3" style="color: #E94C3D;">{{item_2.remark}}</view>
+									<view v-if="item_2.state == 1">
+										<image :src="item_2.base_img" style="width: 300rpx; height: 90rpx;"></image>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+
+		</view>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 业务id
+				id: 0,
+				// 业务详情
+				detail: {},
+				// 审核留言
+				remark_text: "",
+				// 头像随即色
+				bgColor: []
+			};
+		},
+		onLoad(option) {
+			// console.log(option.id)
+			// 设置业务id
+			this.id = option.id
+			// 设置标题
+			uni.setNavigationBarTitle({
+				title: option.title
+			})
+			// 获取业务详情
+			this.get_worksheet_applymei(option.id)
+		},
+		methods: {
+			// 获取业务详情
+			get_worksheet_applymei(id) {
+				// 业务详情接口
+				this.$api.worksheet_applymei({
+					id: id
+				}).then((res) => {
+					console.log(res.data.data)
+
+					for (let i = 0; i < 2; i++) {
+						// 获取随机色
+						let r = parseInt(Math.random() * 256)
+						let g = parseInt(Math.random() * 256)
+						let b = parseInt(Math.random() * 256)
+
+						// ES6 字符串拼接
+						// this.bgColor = `rgba(${r},${g},${b},0.3)`
+						let color = "rgba(" + r + "," + g + "," + b + "," + 0.3 + ")"
+						// console.log(color)
+						this.bgColor.push(color)
+					}
+
+					this.detail = res.data.data
+				})
+			},
+			// 审核事件
+			btn_shenhe(type) {
+				// 提交审核接口
+				this.$api.worksheet_checkmei_tijiao({
+					id: this.id,
+					allow: type,
+					remark: this.remark_text
+				}).then((res) => {
+					console.log(res.data)
+					// 审核过
+					if (res.data.code == 1) {
+						uni.showToast({
+							icon: "none",
+							title: res.data.message
+						})
+					} else {
+						uni.switchTab({
+							url: "../../../tabbar/my/my"
+						})
+					}
+
+				})
+			},
+
+			// 预览文件
+			open_file(path) {
+				uni.downloadFile({
+				  url: path,
+				  success: function (res) {
+				    var filePath = res.tempFilePath;
+				    uni.openDocument({
+				      filePath: filePath,
+				      success: function (res) {
+				        console.log('打开文档成功');
+				      }
+				    });
+				  }
+				});
+			},
+			// 预览图片
+			open_img(path){
+				const urls = [];
+				urls.push(path)
+				// console.log(urls[0])
+				uni.previewImage({
+					urls: urls,
+				});
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		margin-bottom: 40px;
+		background-color: #F3F3F3;
+
+		width: 749rpx;
+		box-sizing: border-box;
+		padding: 24rpx;
+	}
+
+	.content {
+		width: 700rpx;
+		min-height: 90vh;
+		background-color: #FFFFFF;
+		border-radius: 4px;
+
+		box-sizing: border-box;
+		padding: 25rpx;
+	}
+
+	.section {
+		.title {
+			padding-left: 8px;
+			border-left: 2px solid #009FE8;
+			font-weight: 700;
+		}
+
+		.inner {
+			padding: 10px;
+
+			.user {
+				display: flex;
+				align-items: center;
+
+				.img {
+					width: 66px;
+					height: 66px;
+					border-radius: 50%;
+					overflow: hidden;
+
+					image {
+						width: 66px;
+						height: 66px;
+					}
+
+					.avatar {
+						width: 66px;
+						height: 66px;
+						text-align: center;
+						line-height: 66px;
+						color: #FFFFFF;
+						font-size: 28px;
+					}
+				}
+
+				.info {
+
+					// margin-left: 12px;
+					.name {
+						font-size: 19px;
+						font-family: PingFangSC-Medium, PingFang SC;
+						font-weight: 500;
+						color: #232627;
+						line-height: 26px;
+					}
+
+					.section {
+						margin-top: 4px;
+						font-size: 14px;
+						font-family: PingFangSC-Medium, PingFang SC;
+						font-weight: 500;
+						color: #232627;
+						line-height: 19px;
+					}
+				}
+			}
+
+			.file_list {
+				.item {
+					height: 49px;
+
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+
+					border-bottom: 1px solid #ECF0F1;
+					padding: 8px 0;
+
+					.left {
+						display: flex;
+						align-items: center;
+
+						.icon {}
+
+						.info {
+							height: 49px;
+							display: flex;
+							flex-flow: column;
+							justify-content: space-around;
+
+							.name {
+								font-size: 16px;
+								font-family: MicrosoftYaHei;
+								color: #2C3E50;
+							}
+
+							.size {
+								font-size: 13px;
+								font-family: MicrosoftYaHei;
+								color: #BDC3C7;
+							}
+						}
+					}
+
+					.right {}
+				}
+			}
+
+			.img_list {
+				overflow: hidden;
+
+				.item {
+					float: left;
+					width: 284rpx;
+					height: 260rpx;
+					margin-right: 40rpx;
+					margin-bottom: 40rpx;
+
+					image {
+						width: 284rpx;
+						height: 260rpx;
+					}
+				}
+
+				.item:nth-child(2n) {
+					margin-right: 0;
+				}
+			}
+
+			.shenpi_list {
+				width: 612rpx;
+
+				.item {
+					display: flex;
+
+					.name {
+						width: 200rpx;
+						color: #009FE8;
+					}
+
+					.list {
+						width: 412rpx;
+
+						.box {
+							margin-bottom: 8px;
+
+							.label {}
+
+							.remark {}
+						}
+					}
+				}
+			}
+
+			.remark_text {
+				border: 1px solid #BDC3C7;
+			}
+		}
+	}
+
+	.bottom {
+		margin-top: 20px;
+		display: flex;
+		justify-content: space-around;
+
+		.btn {
+			padding: 8px 40px;
+			color: #FFFFFF;
+			border-radius: 60px;
+		}
+	}
+</style>

+ 1 - 1
pages/my/message-reminder/message-detail/message-detail.vue

@@ -63,7 +63,6 @@
 					id: id
 				}).then((res) => {
 					console.log(res)
-					this.get_message_list()
 				})
 			},
 			// 预览文件
@@ -113,6 +112,7 @@
 		text-indent: 2rem;
 		word-break: break-all;
 		overflow: hidden;
+		line-height: 1.5;
 	}
 
 	.file_list {

+ 1 - 0
pages/my/message-reminder/message-reminder.vue

@@ -180,6 +180,7 @@
 				width: 660rpx;
 				text-indent: 2em;
 				font-size: 14px;
+				line-height: 1.5;
 
 				overflow: hidden;
 				word-break: break-all;

BIN
pages/my/personal_information/icon/top.png


+ 23 - 0
pages/my/personal_information/personal_information - 副本 (2).vue

@@ -0,0 +1,23 @@
+<template>
+	<view>
+		<web-view :src="href"></web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				href: ""
+
+			};
+		},
+		onLoad(option) {
+			this.href = "http://webdevelop.nxjiewei.com/assets/html/zhks-quankuang/user_info?token=" + uni.getStorageSync('Authorization') + "&mine_code=" + uni.getStorageSync('mine_code') + "&staff_num=" + uni.getStorageSync('user').staff_num
+		}
+	}
+</script>
+
+<style lang="scss">
+
+</style>

+ 407 - 0
pages/my/personal_information/personal_information.vue

@@ -0,0 +1,407 @@
+<template>
+	<view>
+		<view class="top">
+			<view class="avatar">
+				<image v-if="info.avatar" :src="info.avatar" mode="aspectFill"></image>
+				<view class="avatar" v-if="!info.avatar && !info" :style="{backgroundColor:bgColor[1]}">
+					{{info.name.split('').pop()}}
+				</view>
+			</view>
+			<view class="info">
+				<view class="name">{{info.name}}</view>
+				<view class="box">
+					<view class="item">
+						<view class="label">部门</view>
+						<view class="text">{{info.section_fullname}}</view>
+					</view>
+					<view class="item">
+						<view class="label">职务</view>
+						<view class="text">{{info.duty_num}}</view>
+					</view>
+					<view class="item">
+						<view class="label">员工编号</view>
+						<view class="text">{{info.staff_num}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="content">
+			<view class="box">
+				<view class="item" @click="change_active(1)">
+					<view class="text" :style="{color:active == 1?'#333':'#8e8e8e'}">个人信息</view>
+					<view class="line" v-if="active == 1"></view>
+				</view>
+				<view class="item" @click="change_active(2)">
+					<view class="text" :style="{color:active == 2?'#333':'#8e8e8e'}">工作经历</view>
+					<view class="line" v-if="active == 2"></view>
+				</view>
+				<view class="item" @click="change_active(3)">
+					<view class="text" :style="{color:active == 3?'#333':'#8e8e8e'}">荣誉及证书</view>
+					<view class="line" v-if="active == 3"></view>
+				</view>
+			</view>
+
+
+			<!-- 个人信息 -->
+			<view class="list_1" v-if="active == 1">
+				<view class="item" @click="binding_phone()">
+					<view class="label">手机号</view>
+					<view class="text">12345678</view>
+					<view class="right">
+						<uni-icons type="arrowright" size="20" color="#999"></uni-icons>
+					</view>
+				</view>
+				<view class="item" @click="go_signature()">
+					<view class="label">手写签名</view>
+					<view class="text"> </view>
+					<view class="right">
+						<uni-icons type="arrowright" size="20" color="#999"></uni-icons>
+					</view>
+				</view>
+				<view class="item">
+					<view class="label">岗位分类</view>
+					<view class="text">{{info.job_classify}}</view>
+					<view class="right"></view>
+				</view>
+				<!-- <view class="item">
+					<view class="label">岗位</view>
+					<view class="text">{{info.position.title}}</view>
+					<view class="right"></view>
+				</view> -->
+				<view class="item">
+					<view class="label">民族</view>
+					<view class="text">{{info.nation}}</view>
+					<view class="right"></view>
+				</view>
+				<view class="item">
+					<view class="label">出生日期</view>
+					<view class="text">{{info.birthday}}</view>
+					<view class="right"></view>
+				</view>
+			</view>
+
+			<!-- 工作经历 -->
+			<view class="list_2" v-if="active == 2">
+				<view class="item">
+					<view class="text_1">任职时间</view>
+					<view class="text_2">工作单位</view>
+					<view class="text_3">职务</view>
+				</view>
+				<view class="item" v-for="item in 3">
+					<view class="text_1">2008-06-23至1010-05-14</view>
+					<view class="text_2">公司名称公司名称公司名称</view>
+					<view class="text_3">工程师</view>
+				</view>
+			</view>
+			<!-- 荣誉及证书 -->
+			<view class="list_3" v-if="active == 3">
+				<view class="item" v-for="item in 4">
+					<view class="img">
+						<image
+							src="https://cdn.colorhub.me/7X-46x4lrKMmT8Tyo5qNMRFN0p1R-nMEzlYx-XvdZiw/rs:auto:280:0:0/g:ce/bG9jYWw6Ly8vMTgv/NzUvOGFkNWU4NmZj/Mzc2NWJjYTBiYzAw/YTY1N2JiNWE5ZmMz/MjAyMTg3NS5qcGc.jpg"
+							mode="aspectFill"></image>
+					</view>
+					<view class="text">奖项名称奖项名称奖项名称</view>
+				</view>
+				<view class="item">
+					<view class="img">
+						<view class="add" @click="add()">+</view>
+					</view>
+					<view class="text"></view>
+				</view>
+			</view>
+		</view>
+
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 当前煤矿编码
+				mine_code: "",
+				// 基础请求路径
+				base_url: " ",
+				
+				active: 1,
+				info: {},
+				// 头像随机色
+				bgColor: [],
+			};
+		},
+		onLoad() {
+			// 设置头像
+			for (let i = 0; i < 2; i++) {
+				// 获取随机色
+				let r = parseInt(Math.random() * 256)
+				let g = parseInt(Math.random() * 256)
+				let b = parseInt(Math.random() * 256)
+
+				// ES6 字符串拼接
+				// this.bgColor = `rgba(${r},${g},${b},0.3)`
+				let color = "rgba(" + r + "," + g + "," + b + "," + 0.3 + ")"
+				// console.log(color)
+				this.bgColor.push(color)
+			}
+			
+			// 初始化当前煤矿编码
+			this.mine_code = uni.getStorageSync('mine_code')
+			
+			// 根据矿编码切换首页接口不同的请求基础路径
+			switch (this.mine_code) {
+				case 'ningdongyunying':
+					this.base_url = "http://ningdongyunying.nxjiewei.com:8011/api"
+					break;
+				case 'meihuajing':
+					this.base_url = "http://meihuajing.nxjiewei.com:8011/api"
+					break;
+				case 'zaoquan':
+					this.base_url = "http://zaoquan.nxjiewei.com:8011/api"
+					break;
+				default:
+					this.base_url = ""
+			}
+
+			this.get_info()
+		},
+		methods: {
+			change_active(index) {
+				this.active = index
+			},
+			// 绑定手机
+			binding_phone() {
+				uni.navigateTo({
+					url: "../../my/setPhone/setPhone"
+				})
+			},
+			// 手写签名
+			go_signature() {
+				uni.navigateTo({
+					url: "../../my/signature/signature"
+				})
+			},
+			get_info() {
+				this.$api.user_getUinfo({
+					staff_num: uni.getStorageSync('user').staff_num
+				}).then((res) => {
+					console.log(res.data.data)
+					this.info = res.data.data
+				})
+			},
+			
+			add(){
+				uni.chooseImage({
+					count: 1,
+					success: (chooseImageRes) => {
+						const tempFilePaths = chooseImageRes.tempFilePaths;
+						console.log(chooseImageRes.tempFiles[0]);
+				
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #F5F8F8;
+	}
+
+	.top {
+		background-color: #FFFFFF;
+		width: 750rpx;
+		height: 440rpx;
+
+		background-image: url(./icon/top.png);
+		background-size: 100% 100%;
+		background-position: 0 -110rpx;
+		background-repeat: no-repeat;
+
+		.avatar {
+			padding-top: 34rpx;
+			text-align: center;
+
+			image {
+				width: 200rpx;
+				height: 200rpx;
+
+				border-radius: 50%;
+			}
+		}
+
+		.info {
+			margin-top: 20rpx;
+
+			.name {
+				text-align: center;
+				font-size: 40rpx;
+				font-weight: 700;
+			}
+
+			.box {
+				margin-top: 30rpx;
+				display: flex;
+				justify-content: space-around;
+
+				.item {
+					width: 250rpx;
+					text-align: center;
+
+					.label {
+						font-size: 30rpx;
+						color: #009FE8;
+						margin-bottom: 10rpx;
+					}
+
+					.text {
+						font-size: 32rpx;
+					}
+				}
+			}
+		}
+
+		margin-bottom: 20rpx;
+	}
+
+	.content {
+		background-color: #FFFFFF;
+
+		.box {
+			display: flex;
+			justify-content: space-around;
+			align-items: center;
+
+			border-bottom: 2rpx solid #F5F8F8;
+
+			.item {
+				height: 95rpx;
+				width: 230rpx;
+				text-align: center;
+
+				position: relative;
+
+				.text {
+					font-size: 34rpx;
+					line-height: 95rpx;
+				}
+
+				.line {
+					margin: -6rpx auto 0;
+					width: 80rpx;
+					height: 6rpx;
+					background-color: #009FE8;
+				}
+			}
+		}
+
+		.list_1 {
+			box-sizing: border-box;
+			padding: 0 50rpx;
+
+			.item {
+				border-bottom: 2rpx solid #F5F8F8;
+				height: 95rpx;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				font-size: 32rpx;
+
+				.label {
+					width: 200rpx;
+					text-align: left;
+				}
+
+				.text {
+					width: 350rpx;
+					text-align: left;
+					color: #8e8e8e;
+
+				}
+
+				.right {
+					width: 100rpx;
+					text-align: right;
+				}
+			}
+
+		}
+
+		.list_2 {
+			box-sizing: border-box;
+			padding: 0 50rpx;
+
+			.item {
+				border-bottom: 2rpx solid #F5F8F8;
+				height: 95rpx;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				font-size: 30rpx;
+				text-align: center;
+				color: #8e8e8e;
+
+				.text_1 {
+					width: 190rpx;
+				}
+
+				.text_2 {
+					width: 240rpx;
+
+				}
+
+				.text_3 {
+					width: 160rpx;
+				}
+			}
+
+			.item:first-child {
+				font-size: 32rpx;
+				color: #333;
+			}
+
+		}
+
+		.list_3 {
+			box-sizing: border-box;
+			padding: 50rpx;
+			
+			overflow: hidden;
+			
+			.item {
+				float: left;
+				margin-right: 25rpx;
+				margin-bottom: 30rpx;
+				
+				width: 200rpx;
+				text-align: center;
+				.img{
+					image{
+						width: 200rpx;
+						height: 140rpx;
+					}
+					
+					.add{
+						font-size: 110rpx;
+						color: #DCDCDC;
+						text-align: center;
+						height: 140rpx;
+						line-height: 140rpx;
+						background-color: #EEEEEE;
+					}
+				}
+				.text{
+					width: 180rpx;
+					font-size: 24rpx;
+					color: #8e8e8e;
+				}
+			}
+			.item:nth-child(3n){
+				margin-right: 0;
+			}
+		}
+	}
+</style>

+ 38 - 0
pages/my/signature/signature.vue

@@ -0,0 +1,38 @@
+<template>
+	<view>
+		<web-view :src="href"></web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 手写签名H5地址
+				href:'',
+				mine_code:"",
+				
+				staff_num:'',
+				Authorization:""
+			}
+		},
+		onLoad() {
+			// 初始化当前煤矿编码
+			this.mine_code = uni.getStorageSync('mine_code')
+			// 用户工号
+			this.staff_num = uni.getStorageSync('user').staff_num
+			this.Authorization = uni.getStorageSync('token_type') + ' ' + uni.getStorageSync('Authorization')
+			// console.log(this.Authorization)
+			// console.log(this.staff_num)
+			
+			this.href = "http://webdevelop.nxjiewei.com/assets/html/zhks-quankuang/signature?staff=" + this.staff_num + "&token=" + this.Authorization + "&mine_code=" + this.mine_code
+		
+		}
+	}
+
+
+</script>
+
+<style scoped="true" lang="scss">
+	
+</style>

pages/origanization/zaoquan/origanization/icon/close.png → pages/origanization/communication/origanization/icon/close.png


pages/origanization/zaoquan/origanization/icon/open.png → pages/origanization/communication/origanization/icon/open.png


pages/origanization/zaoquan/origanization/icon/title_icon.png → pages/origanization/communication/origanization/icon/title_icon.png


pages/origanization/zaoquan/origanization/my_department/icon/close.png → pages/origanization/communication/origanization/my_department/icon/close.png


pages/origanization/zaoquan/origanization/my_department/icon/open.png → pages/origanization/communication/origanization/my_department/icon/open.png


pages/origanization/zaoquan/origanization/my_department/icon/title_icon.png → pages/origanization/communication/origanization/my_department/icon/title_icon.png


+ 172 - 0
pages/origanization/communication/origanization/my_department/my_department.vue

@@ -0,0 +1,172 @@
+<template>
+	<view>
+		<!-- <view class="search">
+			<view class="box">
+				<view class="icon">
+					<uni-icons type="search" size="16" color="#BBBBBB"></uni-icons>
+				</view>
+				<view class="text">
+					<input type="text" v-model="search_text" value="" placeholder="搜索" confirm-type="search"
+						placeholder-style="font-size: 30rpx;color: #BBBBBB;" @input="get_list()"/>
+				</view>
+			</view>
+		</view> -->
+
+		<view class="content">
+			<view class="title">
+				<view class="icon">
+					<image src="./icon/title_icon.png" mode=""></image>
+				</view>
+				<view class="text">{{section_fullname}}</view>
+			</view>
+
+			<view class="list">
+				<view class="item" v-for="(item,index) in list" :key="index">
+					<view class="icon">{{item.name.charAt(0)}}</view>
+					<view class="text">{{item.name}} {{item.section_fullname}} {{item.position_name}}</view>
+				</view>
+			</view>
+
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				search_text: "",
+				
+				// 部门名称
+				section_fullname:"",
+				// 人员列表
+				list: [
+
+				],
+
+			};
+		},
+		onLoad() {
+			this.get_info()
+		},
+		methods: {
+			get_info() {
+				this.$api.user_getUinfo({
+					staff_num : uni.getStorageSync('user').staff_num
+				}).then((res)=>{
+					console.log(res.data.data)
+					this.section_fullname = res.data.data.section_fullname
+					// 获取当前部门人员
+					uni.showLoading({
+						mask:true
+					})
+					this.$api.user_list({
+						id:res.data.data.section_id
+					}).then((res)=>{
+						uni.hideLoading()
+						console.log(res)
+						this.list = res.data.data
+					})
+				})
+			},
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #F3F8F7;
+	}
+
+	.search {
+		margin-bottom: 20rpx;
+		background-color: #FFFFFF;
+		box-sizing: border-box;
+		padding: 25rpx 30rpx;
+
+		.box {
+			height: 80rpx;
+			background-color: #F4F4F4;
+			border-radius: 50rpx;
+
+			display: flex;
+			align-items: center;
+
+			box-sizing: border-box;
+			padding: 0 25rpx;
+
+			.icon {
+				margin-right: 10rpx;
+			}
+
+			.text {
+				font-size: 30rpx;
+				color: #BBBBBB;
+
+			}
+		}
+	}
+
+	.content {
+		background-color: #FFFFFF;
+
+		.title {
+			height: 110rpx;
+			display: flex;
+			align-items: center;
+
+			box-sizing: border-box;
+			padding: 0 36rpx;
+			border-bottom: 1rpx solid #F3F8F7;
+
+			.icon {
+				image {
+					width: 48rpx;
+					height: 36rpx;
+				}
+			}
+
+			.text {
+				margin-left: 20rpx;
+				font-size: 36rpx;
+				font-weight: 700;
+			}
+		}
+
+		.list {
+			box-sizing: border-box;
+			padding: 0 20rpx;
+
+			.item {
+				height: 110rpx;
+
+				display: flex;
+				justify-content: left;
+				align-items: center;
+
+				margin-left: 40rpx;
+				border-bottom: 1rpx solid #F3F8F7;
+
+				.icon {
+					width: 35rpx;
+					text-align: center;
+					line-height: 35rpx;
+					border-radius: 50%;
+					border: 1rpx solid #00A1E9;
+
+					font-size: 24rpx;
+					color: #00A1E9;
+				}
+
+				.text {
+					margin-left: 18rpx;
+					font-size: 30rpx;
+
+				}
+			}
+
+		}
+
+	}
+</style>

pages/origanization/zaoquan/origanization/origanization - 二级列表.vue → pages/origanization/communication/origanization/origanization - 二级列表.vue


pages/origanization/zaoquan/origanization/origanization - 单独部门列表.vue → pages/origanization/communication/origanization/origanization - 单独部门列表.vue


pages/origanization/zaoquan/origanization/origanization - 递归.vue → pages/origanization/communication/origanization/origanization - 递归.vue


pages/origanization/zaoquan/origanization/origanization.vue → pages/origanization/communication/origanization/origanization.vue


pages/origanization/zaoquan/origanization/search/icon/close.png → pages/origanization/communication/origanization/search/icon/close.png


pages/origanization/zaoquan/origanization/search/icon/open.png → pages/origanization/communication/origanization/search/icon/open.png


pages/origanization/zaoquan/origanization/search/icon/title_icon.png → pages/origanization/communication/origanization/search/icon/title_icon.png


+ 33 - 20
pages/origanization/zaoquan/origanization/search/search.vue

@@ -6,7 +6,8 @@
 					<uni-icons type="search" size="16" color="#BBBBBB"></uni-icons>
 				</view>
 				<view class="text">
-					<input type="text" value="" placeholder="搜索" confirm-type="search" placeholder-style="font-size: 30rpx;color: #BBBBBB;" />
+					<input type="text" v-model="search_text" value="" placeholder="搜索" confirm-type="search"
+						placeholder-style="font-size: 30rpx;color: #BBBBBB;" @input="get_list()"/>
 				</view>
 			</view>
 		</view>
@@ -18,14 +19,15 @@
 				</view>
 				<view class="text">国家能源集团枣泉煤矿</view>
 			</view>
-			
+
 			<view class="list">
 				<view class="item" v-for="(item,index) in list" :key="index">
 					<view class="icon">{{item.name.charAt(0)}}</view>
-					<view class="text">{{item.name}} {{item.position_name}}</view>
+					<view class="text">{{item.name}} {{item.dept_name}} {{item.duty_num}}</view>
+				</view>
+
+				<view v-if="list.length == 0" style="font-size: 32rpx;text-align: center;line-height: 400rpx;">暂无搜索结果
 				</view>
-				
-				<view v-if="list.length == 0" style="font-size: 32rpx;text-align: center;line-height: 400rpx;">暂无搜索结果</view>
 			</view>
 
 		</view>
@@ -36,14 +38,23 @@
 	export default {
 		data() {
 			return {
+				search_text: "",
 				// 人员列表
 				list: [
 
-				]
+				],
+
 			};
 		},
 		methods: {
-			
+			get_list() {
+				this.$api.user_search({
+					content: this.search_text
+				}).then((res) => {
+					console.log(res)
+					this.list = res.data.data
+				})
+			}
 		}
 	}
 </script>
@@ -77,7 +88,7 @@
 			.text {
 				font-size: 30rpx;
 				color: #BBBBBB;
-				
+
 			}
 		}
 	}
@@ -107,37 +118,39 @@
 				font-weight: 700;
 			}
 		}
-		
-		.list{
+
+		.list {
 			box-sizing: border-box;
 			padding: 0 20rpx;
-			
-			.item{
+
+			.item {
 				height: 110rpx;
-				
+
 				display: flex;
 				justify-content: left;
 				align-items: center;
-				
-				margin-left: 108rpx;
+
+				margin-left: 58rpx;
 				border-bottom: 1rpx solid #F3F8F7;
-				.icon{
+
+				.icon {
 					width: 35rpx;
 					text-align: center;
 					line-height: 35rpx;
 					border-radius: 50%;
 					border: 1rpx solid #00A1E9;
-					
+
 					font-size: 24rpx;
 					color: #00A1E9;
 				}
-				.text{
+
+				.text {
 					margin-left: 18rpx;
 					font-size: 30rpx;
-					
+
 				}
 			}
-			
+
 		}
 
 	}

+ 0 - 249
pages/origanization/zaoquan/origanization/my_department/my_department.vue

@@ -1,249 +0,0 @@
-<template>
-	<view>
-		<view class="search">
-			<view class="box" @click="go_search()">
-				<view class="icon">
-					<uni-icons type="search" size="16" color="#BBBBBB"></uni-icons>
-				</view>
-				<view class="text">搜索</view>
-			</view>
-		</view>
-
-		<view class="content">
-			<view class="title">
-				<view class="icon">
-					<image src="./icon/title_icon.png" mode=""></image>
-				</view>
-				<view class="text">国家能源集团枣泉煤矿</view>
-			</view>
-			
-			<view class="section" v-for="(item,index) in list" :key="index">
-				<view class="box">
-					<view class="item">
-						<view class="left">
-							<view class="icon" v-if="active == index" @click.stop="change_active(index,item.id)">
-								<image src="./icon/close.png" mode=""></image>
-							</view>
-							<view class="icon" v-if="active != index" @click.stop="change_active(index,item.id)">
-								<image src="./icon/open.png" mode=""></image>
-							</view>
-							<view class="text">{{item.title}} ({{item.user_num}})</view>
-						</view>
-						<view class="right">
-							<uni-icons type="eye"></uni-icons>
-						</view>
-					</view>
-					<view class="list" v-if="active == index">
-						<view class="item" v-for="(item_2,index_2) in user_list" :key="index_2">
-							<view class="icon">{{item_2.name.charAt(0)}}</view>
-							<view class="text">{{item_2.name}} {{item_2.position_name}}</view>
-						</view>
-					</view>
-				</view>
-			</view>
-
-		</view>
-	</view>
-</template>
-
-<script>
-	export default {
-		data() {
-			return {
-				// 部门列表
-				list: [
-
-				],
-				// 当前展开部门
-				active: 99999999,
-				
-				// 人员列表
-				user_list:[]
-			};
-		},
-		methods: {
-			// 搜索
-			go_search(){
-				uni.navigateTo({
-					url:"./search/search",
-					animationType:"fade-in",
-					animationDuration:200
-				})
-			},
-			// 获取部门列表
-			get_section_getGroupList() {
-				uni.showLoading({
-					mask:true
-				})
-				this.$api.section_getGroupList({
-
-				}).then((res) => {
-					uni.hideLoading()
-					console.log(res)
-
-					this.list = res.data.data.group.leader.data.concat(res.data.data.group.office.data.concat(res
-						.data.data.group.basic.data.concat()))
-					// console.log(this.list)
-				})
-			},
-			
-			change_active(index,id) {
-				this.user_list = []
-				if (this.active == index) {
-					this.active = 99999999
-				} else {
-					this.active = index
-					this.get_user_list(id)
-				}
-			},
-			// 获取当前部门人员
-			get_user_list(id){
-				uni.showLoading({
-					mask:true
-				})
-				this.$api.user_list({
-					id:id
-				}).then((res)=>{
-					uni.hideLoading()
-					console.log(res)
-					this.user_list = res.data.data
-				})
-			}
-		},
-		onLoad() {
-			this.get_section_getGroupList()
-		}
-	}
-</script>
-
-<style lang="scss">
-	page {
-		background-color: #F3F8F7;
-	}
-
-	.search {
-		margin-bottom: 20rpx;
-		background-color: #FFFFFF;
-		box-sizing: border-box;
-		padding: 25rpx 30rpx;
-
-		.box {
-			height: 80rpx;
-			background-color: #F4F4F4;
-			border-radius: 50rpx;
-
-			display: flex;
-			align-items: center;
-
-			box-sizing: border-box;
-			padding: 0 25rpx;
-
-			.icon {
-				margin-right: 10rpx;
-			}
-
-			.text {
-				font-size: 30rpx;
-				color: #BBBBBB;
-			}
-		}
-	}
-
-	.content {
-		background-color: #FFFFFF;
-
-		.title {
-			height: 110rpx;
-			display: flex;
-			align-items: center;
-
-			box-sizing: border-box;
-			padding: 0 36rpx;
-			border-bottom: 1rpx solid #F3F8F7;
-
-			.icon {
-				image {
-					width: 48rpx;
-					height: 36rpx;
-				}
-			}
-
-			.text {
-				margin-left: 20rpx;
-				font-size: 36rpx;
-				font-weight: 700;
-			}
-		}
-		
-		.section{
-			box-sizing: border-box;
-			padding: 0 20rpx;
-			
-			.box{
-				
-				.item{
-					height: 110rpx;
-					display: flex;
-					align-items: center;
-					justify-content: space-between;
-					
-					margin-left: 20rpx;
-					border-bottom: 1rpx solid #F3F8F7;
-					
-					.left{
-						display: flex;
-						align-items: center;
-						.icon{
-							line-height: 110rpx;
-							width: 90rpx;
-							text-align: center;
-							image{
-								width: 24rpx;
-								height: 24rpx;
-							}
-						}
-						.text{
-							font-size: 32rpx;
-						}
-					}
-					.right{
-						line-height: 110rpx;
-						width: 90rpx;
-						text-align: center;
-					}
-				}
-				
-				.list{
-					.item{
-						height: 110rpx;
-						
-						display: flex;
-						justify-content: left;
-						align-items: center;
-						
-						margin-left: 108rpx;
-						border-bottom: 1rpx solid #F3F8F7;
-						.icon{
-							width: 35rpx;
-							text-align: center;
-							line-height: 35rpx;
-							border-radius: 50%;
-							border: 1rpx solid #00A1E9;
-							
-							font-size: 24rpx;
-							color: #00A1E9;
-						}
-						.text{
-							margin-left: 18rpx;
-							font-size: 30rpx;
-							
-						}
-					}
-				}
-			
-			}
-			
-		}
-
-	}
-</style>

+ 92 - 35
pages/production/zaoquan/mine_water_treatment/mine_water_treatment.vue

@@ -19,14 +19,14 @@
 						<view class="item">
 							<view class="text name">矸石山调节池A</view>
 							<view class="text num">
-								<view class="num_box">0.74</view>
+								<view class="num_box">{{list[6].point_value}}</view>
 							</view>
 							<view class="text company">m</view>
 						</view>
 						<view class="item">
 							<view class="text name">矸石山调节池B</view>
 							<view class="text num">
-								<view class="num_box">0.74</view>
+								<view class="num_box">{{list[7].point_value}}</view>
 							</view>
 							<view class="text company">m</view>
 						</view>
@@ -38,14 +38,14 @@
 						<view class="item">
 							<view class="text name">外排水池A液位</view>
 							<view class="text num">
-								<view class="num_box">1.98</view>
+								<view class="num_box">{{list[0].point_value}}</view>
 							</view>
 							<view class="text company">m</view>
 						</view>
 						<view class="item">
 							<view class="text name">外排水池B液位</view>
 							<view class="text num">
-								<view class="num_box">1.98</view>
+								<view class="num_box">{{list[1].point_value}}</view>
 							</view>
 							<view class="text company">m</view>
 						</view>
@@ -53,7 +53,7 @@
 				</view>
 			</view>
 		</view>
-		
+
 		<!-- 快滤池 -->
 		<view class="section section_2">
 			<view class="title">
@@ -66,14 +66,28 @@
 						<view class="item">
 							<view class="text name">滤池出水流量</view>
 							<view class="text num">
-								<view class="num_box">0.833</view>
+								<view class="num_box">{{list[2].point_value}}</view>
 							</view>
 							<view class="text company">m3/h</view>
 						</view>
 						<view class="item">
 							<view class="text name">滤池出水流量累积</view>
 							<view class="text num">
-								<view class="num_box">933759</view>
+								<view class="num_box">{{list[3].point_value}}</view>
+							</view>
+							<view class="text company">m3</view>
+						</view>
+						<view class="item">
+							<view class="text name">矿井水进水瞬时流量</view>
+							<view class="text num">
+								<view class="num_box">{{list[4].point_value}}</view>
+							</view>
+							<view class="text company">m3/h</view>
+						</view>
+						<view class="item">
+							<view class="text name">矿井水进水流量累积</view>
+							<view class="text num">
+								<view class="num_box">{{list[5].point_value}}</view>
 							</view>
 							<view class="text company">m3</view>
 						</view>
@@ -89,54 +103,86 @@
 	export default {
 		data() {
 			return {
-				
+				mine_code: "",
+
+				list: []
 			};
+		},
+		onLoad(option) {
+			this.mine_code = option.mine_code
+			this.automate_mine_water_get_list()
+
+			for (var i = 0; i < 10; i++) {
+				this.list.push({
+					point_value: 0
+				})
+			}
+			
+			console.log(this.list)
+		},
+		methods: {
+			automate_mine_water_get_list() {
+				this.$p_api.automate_mine_water_get_list({
+					mine_id: this.mine_code
+				}).then((res) => {
+					console.log(res.data.content.data)
+
+					this.list = res.data.content.data
+
+				})
+			}
 		}
+
 	}
 </script>
 
 <style lang="scss">
-	page{
+	page {
 		background: #009FE8;
 	}
-	.top{
+
+	.top {
 		position: relative;
-		image{
+
+		image {
 			width: 750rpx;
 			height: 302rpx;
 		}
-		.time{
+
+		.time {
 			position: absolute;
 			right: 20rpx;
 			bottom: 20rpx;
-			
+
 			font-size: 34rpx;
 			font-weight: 500;
 			color: #FFFFFF;
 		}
 	}
-	
-	.section{
+
+	.section {
 		margin: 10rpx 15rpx 0;
 		background: #FFFFFF;
 		box-shadow: 0px 3rpx 30rpx 0px rgba(59, 74, 116, 0.14);
 		border-radius: 21rpx;
 
-		.title{
+		.title {
 			height: 103rpx;
 			display: flex;
 			justify-content: center;
 			align-items: center;
-			
+
 			border-bottom: 2rpx solid #f3f3f3;
-			.icon{
+
+			.icon {
 				width: 68rpx;
 				height: 71rpx;
 				background-image: url(icon/icon_1.png);
 				background-size: cover;
 				background-repeat: no-repeat;
 			}
-			.name{
+
+			.name {
 				margin-left: 30rpx;
 				font-size: 31rpx;
 				font-weight: 500;
@@ -144,50 +190,60 @@
 
 			}
 		}
-		.content{
+
+		.content {
 			padding-bottom: 20rpx;
-			.box{
+
+			.box {
 				box-sizing: border-box;
 				padding: 0 15rpx;
-				.box_title{
+
+				.box_title {
 					margin: 20rpx 0;
 					line-height: 60rpx;
-					
+
 					font-size: 34rpx;
 					font-weight: 500;
 					color: #232627;
-					
+
 					border-left: 8rpx solid #009fe8;
 					padding-left: 15rpx;
 
 				}
-				.box_list{
+
+				.box_list {
 					padding-bottom: 10rpx;
-					.item{
+
+					.item {
 						display: flex;
 						height: 110rpx;
 						align-items: center;
 						font-size: 30rpx;
-						
+
 						border-bottom: 1rpx solid #f3f3f3;
-						.text{
+
+						.text {
 							font-weight: 400;
 							color: #232627;
 							line-height: 83rpx;
 							text-align: center;
 						}
-						.name{
+
+						.name {
 							width: 324rpx;
 						}
-						.num{
+
+						.num {
 							margin-left: 26rpx;
 							width: 162rpx;
-							.num_box{
+
+							.num_box {
 								background: #8ADAFF;
 								line-height: 40rpx;
 							}
 						}
-						.company{
+
+						.company {
 							margin-left: 16rpx;
 							width: 162rpx;
 						}
@@ -196,9 +252,10 @@
 			}
 		}
 	}
-	.section_2{
-		.title{
-			.icon{
+
+	.section_2 {
+		.title {
+			.icon {
 				background-image: url(icon/icon_2.png);
 			}
 		}

+ 26 - 0
pages/production/zaoquan/zidonghua_list/detail/detail.vue

@@ -0,0 +1,26 @@
+<template>
+	<view>
+		<web-view :src="url"></web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				url:""
+			};
+		},
+		onLoad(option) {
+			this.url = option.url
+			
+			uni.setNavigationBarTitle({
+				title:option.name
+			})
+		}
+	}
+</script>
+
+<style lang="scss">
+
+</style>

BIN
pages/production/zaoquan/zidonghua_list/img/icon.png


BIN
pages/production/zaoquan/zidonghua_list/img/psxt.jpg


BIN
pages/production/zaoquan/zidonghua_list/img/tfgl.jpg


BIN
pages/production/zaoquan/zidonghua_list/img/yfzd.jpg


BIN
pages/production/zaoquan/zidonghua_list/img/zys.jpg


+ 288 - 0
pages/production/zaoquan/zidonghua_list/zidonghua_list.vue

@@ -0,0 +1,288 @@
+<template>
+	<view>
+		<!-- 头图 -->
+		<view class="top_img">
+			<!-- 通风管理 -->
+			<view v-if="zdhxt == 'tfgl'">
+				<image src="./img/tfgl.jpg" mode=""></image>
+			</view>
+			<!-- 排水系统 -->
+			<view v-if="zdhxt == 'psxt'">
+				<image src="./img/psxt.jpg" mode=""></image>
+			</view>
+		</view>
+		
+		<!-- 列表 -->
+		<view class="list">
+			<!-- 通风管理 -->
+			<view v-if="zdhxt == 'tfgl'">
+				<view class="item" v-for="(item,index) in data_tfgl" :key="index">
+					<view class="title" @click="item_active(index)">
+						<view class="left">
+							<view class="icon"></view>
+							<view class="name">
+								{{item.name}}
+							</view>
+						</view>
+						<view class="right" v-if="index != active">
+							<uni-icons type="arrowright"></uni-icons>
+						</view>
+						<view class="right" v-if="index == active">
+							<uni-icons type="arrowdown"></uni-icons>
+						</view>
+					</view>
+					<view class="inner_list" v-if="active == index">
+						<view class="inner_item" v-for="(item_2,index_2) in item.list" :key="index_2" @click="inner_item_active(item_2)">
+							<view class="inner_icon"></view>
+							<view class="inner_name">{{item_2.name}}</view>
+						</view>
+					</view>
+				</view>
+				
+			</view>
+			<!-- 压风制氮 -->
+			<view v-if="zdhxt == 'yfzd'">
+				<view class="item" v-for="(item,index) in data_yfzd" :key="index">
+					<view class="title" @click="item_active(index)">
+						<view class="left">
+							<view class="icon"></view>
+							<view class="name">
+								{{item.name}}
+							</view>
+						</view>
+						<view class="right" v-if="index != active">
+							<uni-icons type="arrowright"></uni-icons>
+						</view>
+						<view class="right" v-if="index == active">
+							<uni-icons type="arrowdown"></uni-icons>
+						</view>
+					</view>
+					<view class="inner_list" v-if="active == index">
+						<view class="inner_item" v-for="(item_2,index_2) in item.list" :key="index_2" @click="inner_item_active(item_2)">
+							<view class="inner_icon"></view>
+							<view class="inner_name">{{item_2.name}}</view>
+						</view>
+					</view>
+				</view>
+				
+			</view>
+			<!-- 排水系统 -->
+			<view v-if="zdhxt == 'psxt'">
+				<view class="item" v-for="(item,index) in data_psxt" :key="index">
+					<view class="title" @click="item_active(index)">
+						<view class="left">
+							<view class="icon"></view>
+							<view class="name">
+								{{item.name}}
+							</view>
+						</view>
+						<view class="right" v-if="index != active">
+							<uni-icons type="arrowright"></uni-icons>
+						</view>
+						<view class="right" v-if="index == active">
+							<uni-icons type="arrowdown"></uni-icons>
+						</view>
+					</view>
+					<view class="inner_list" v-if="active == index">
+						<view class="inner_item" v-for="(item_2,index_2) in item.list" :key="index_2" @click="inner_item_active(item_2)">
+							<view class="inner_icon"></view>
+							<view class="inner_name">{{item_2.name}}</view>
+						</view>
+					</view>
+				</view>
+				
+			</view>
+			<!-- 主运输 -->
+			<view v-if="zdhxt == 'zys'">
+				<view class="item" v-for="(item,index) in data_zys" :key="index">
+					<view class="title" @click="item_active(index)">
+						<view class="left">
+							<view class="icon"></view>
+							<view class="name">
+								{{item.name}}
+							</view>
+						</view>
+						<view class="right" v-if="index != active">
+							<uni-icons type="arrowright"></uni-icons>
+						</view>
+						<view class="right" v-if="index == active">
+							<uni-icons type="arrowdown"></uni-icons>
+						</view>
+					</view>
+					<view class="inner_list" v-if="active == index">
+						<view class="inner_item" v-for="(item_2,index_2) in item.list" :key="index_2" @click="inner_item_active(item_2)">
+							<view class="inner_icon"></view>
+							<view class="inner_name">{{item_2.name}}</view>
+						</view>
+					</view>
+				</view>
+				
+			</view>
+		</view>
+	
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				zdhxt:"",
+				active:0,
+				
+				
+				// 通风管理
+				data_tfgl:[
+					{
+						name:"枣泉煤矿",
+						list:[
+							{
+								name:"东井通风",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/djtf/#/"
+							},
+							{
+								name:"西井通风",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/xjtf/#/"
+							}
+						]
+					}
+				],
+				// 排水系统
+				data_psxt:[
+					{
+						name:"枣泉煤矿",
+						list:[
+							{
+								name:"720泵房",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/720bf/#/"
+							},
+							{
+								name:"880泵房",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/880bf/#/"
+							},
+							{
+								name:"929泵房",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/929bf/#/"
+							},
+							{
+								name:"950泵房",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/950bf/#/"
+							},
+							{
+								name:"980泵房",
+								url:"http://webdevelop.nxjiewei.com/assets/html/zaoquan/980bf/#/"
+							},
+						]
+					},
+					
+				],
+				
+			}
+		},
+		onLoad(option) {
+			this.zdhxt = option.zdhxt
+			
+			if(this.zdhxt == 'tfgl'){
+				uni.setNavigationBarTitle({
+					title:"通风管理"
+				})
+			}else if(this.zdhxt == 'psxt'){
+				uni.setNavigationBarTitle({
+					title:"排水系统"
+				})
+			}
+		},
+		methods: {
+			// item_active(index){
+			// 	console.log(index)
+				
+			// 	if(index != this.active){
+			// 		this.active = index
+			// 	}else{
+			// 		this.active = 9999
+			// 	}
+			// },
+			inner_item_active(item_2){
+				// console.log(item_2)
+				uni.navigateTo({
+					url:"./detail/detail?url=" + item_2.url + "&name=" + item_2.name
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color: #F7F7F7;
+	}
+	
+	.top_img{
+		image{
+			width: 750rpx;
+			height: 360rpx;
+		}
+	}
+	
+	.list{
+		padding-top: 20rpx;
+		.item{
+			background-color: #FFFFFF;
+			margin-bottom: 20rpx;
+			
+			box-sizing: border-box;
+			padding: 0 35rpx;
+			
+			.title{
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				
+				height: 110rpx;
+				border-bottom: 1rpx solid #f7f7f7;
+				.left{
+					display: flex;
+					align-items: center;
+					.icon{
+						width: 31rpx;
+						height: 27rpx;
+						
+						background-image: url(img/icon.png);
+						background-size: cover;
+						background-repeat: no-repeat;
+					}
+					.name{
+						margin-left: 26rpx;
+						font-size: 38rpx;
+					}
+				}
+				.right{
+					
+				}
+			}
+			.inner_list{
+				.inner_item{
+					display: flex;
+					align-items: center;
+					
+					height: 110rpx;
+					border-bottom: 1rpx solid #f7f7f7;
+					
+					padding-left: 96rpx;
+					.inner_icon{
+						width: 20rpx;
+						height: 20rpx;
+						background-color: #0992E5;
+						border-radius: 50%;
+					}
+					.inner_name{
+						margin-left: 29rpx;
+						font-size: 32rpx;
+						color: #8a8a8a;
+					}
+				}
+			}
+		}
+		
+	}
+</style>

+ 5 - 2
pages/tabbar/my/my.vue

@@ -5,7 +5,7 @@
 		<t-m-info></t-m-info>
 		
 		<!-- t-m-icon -->
-		<t-m-icon></t-m-icon>
+		<t-m-icon :mine_code="mine_code"></t-m-icon>
 		
 		<t-m-list></t-m-list>
 	</view>
@@ -15,10 +15,13 @@
 	export default {
 		data() {
 			return {
-				
+				// 当前煤矿编码
+				mine_code: "",
 			};
 		},
 		onLoad() {
+			// 初始化当前煤矿编码
+			this.mine_code = uni.getStorageSync('mine_code')
 			// 判断会否登录、没有则跳转至登录页
 			const Authorization = uni.getStorageSync('Authorization')
 			if (Authorization == '') {

+ 2 - 1
pages/tabbar/origanization/origanization.vue

@@ -1,8 +1,9 @@
 <template>
 	<view class="">
+		<!-- 组织架构 -->
 		<!-- 枣泉 -->
 		<view v-if="mine_code == 'zaoquan'">
-			<t-o-zaoquan></t-o-zaoquan>
+			<t-o-communication></t-o-communication>
 		</view>
 		
 	</view>

+ 43 - 0
pages/workbench/business_classfication/apply/apply.vue

@@ -0,0 +1,43 @@
+<template>
+	<view>
+		<web-view :src="href"></web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				href:"",
+				mine_code:""
+			};
+		},
+		onLoad(option) {
+			// 初始化当前煤矿编码
+			this.mine_code = uni.getStorageSync('mine_code')
+			this.Authorization = uni.getStorageSync('token_type') + ' ' + uni.getStorageSync('Authorization')
+
+			// 设置标题
+			uni.setNavigationBarTitle({
+				title: option.title
+			})
+			
+			console.log(option.id)
+			
+			// this.href = "http://tysc.tianyuyezi.com/apply?id=" + option.id + "&token=" + this.Authorization
+			this.href = "http://webdevelop.nxjiewei.com/assets/html/zhks-quankuang/apply?id=" + option.id + "&token=" + this.Authorization + "&mine_code=" + this.mine_code
+
+		},

+		
+	}
+</script>
+
+<style lang="scss">
+	.content {
+		width: 749rpx;
+		box-sizing: border-box;
+		padding: 30px 24rpx;
+	}
+
+	
+</style>

+ 81 - 0
pages/workbench/business_classfication/business_classfication.vue

@@ -0,0 +1,81 @@
+<template>
+	<view class="list">
+		<view class="item" v-for="(item,index) in list" :key="index" @click="go_detail(item.id,item.title)">
+			<view class="left">
+				<view class="text">{{item.title}}</view>
+			</view>
+			<view class="right">
+				<uni-icons type="eye" size="18"></uni-icons>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				list:[]
+			};
+		},
+		onLoad(option) {
+			this.get_worksheet_design_list(option.id)
+			
+			uni.setNavigationBarTitle({
+				title:option.title
+			})
+		},
+		methods:{
+			// 获取业务菜单
+			get_worksheet_design_list(id){
+				// console.log(id)
+				uni.showLoading({
+					mask:true
+				})
+				this.$api.worksheet_design_list({
+					id:id
+				}).then((res)=>{
+					uni.hideLoading()
+					console.log(res.data.data)
+					this.list = res.data.data
+					
+				})
+			},
+			// 打开申请详情
+			go_detail(id,title){
+				uni.navigateTo({
+					url:"./apply/apply?id=" + id + "&title=" + title
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.list{
+		box-sizing: border-box;
+		padding: 10rpx 25rpx;
+		.item{
+			height: 110rpx;
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			
+			margin-left: 20rpx;
+			border-bottom: 1rpx solid #F3F8F7;
+			
+			.left{
+				display: flex;
+				align-items: center;
+				.text{
+					font-size: 34rpx;
+				}
+			}
+			.right{
+				line-height: 110rpx;
+				width: 90rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 13 - 13
pages/workbench/duty_information/duty_information.vue

@@ -48,7 +48,7 @@
 					</view>
 				</view>
 			</view>
-			<view v-if="month_list.length == 0" style="text-align: center;line-height: 90rpx;font-size: 28rpx;">当前没有你值班的排期!</view>
+			<view v-if="month_list.length == 0" style="text-align: center;line-height: 90rpx;font-size: 34rpx;">当前没有你值班的排期!</view>
 		</view>
 		
 		<!-- content -->
@@ -243,7 +243,7 @@
 			.title{
 				text-align: center;
 				height: 47rpx;
-				font-size: 33rpx;
+				font-size: 36rpx;
 				font-weight: 500;
 				color: #BDC3C7;
 				line-height: 47rpx;
@@ -266,28 +266,28 @@
 
 	.content{
 		.month{
-			height: 87rpx;
+			height: 100rpx;
 			box-sizing: border-box;
 			padding-left: 13rpx;
-			padding-top: 14rpx;
+			padding-top: 24rpx;
 			.month_list{
 				display: flex;
 				.month_item{
 					box-sizing: border-box;
 					border: 1rpx solid #009FE8;
 					background-color:  transparent;
-					height: 55rpx;
+					height: 60rpx;
 					border-radius: 10rpx;
 					text-align: center;
 					margin-right: 21rpx;
 					
 					.text{
-						width: 200rpx;
+						width: 210rpx;
 
-						font-size: 27rpx;
+						font-size: 32rpx;
 						font-weight: 400;
 						color: #009FE8;
-						line-height: 50rpx;
+						line-height: 60rpx;
 
 					}
 				}
@@ -315,7 +315,7 @@
 				
 				.time{
 					width: 194rpx;
-					font-size: 29rpx;
+					font-size: 32rpx;
 					font-weight: 500;
 					color: #009FE8;
 					line-height: 94rpx;
@@ -324,7 +324,7 @@
 				.name{
 					margin-left: 45rpx;
 					width: 469rpx;
-					font-size: 29rpx;
+					font-size: 32rpx;
 					font-weight: 500;
 					color: #009FE8;
 					line-height: 94rpx;
@@ -348,7 +348,7 @@
 						.month_day{
 							text-align: center;
 							height: 39rpx;
-							font-size: 27rpx;
+							font-size: 30rpx;
 							font-weight: 400;
 							color: #232627;
 							line-height: 39rpx;
@@ -356,7 +356,7 @@
 						}
 						.week{
 							text-align: center;
-							height: 39rpx;
+							height: 30rpx;
 							font-size: 27rpx;
 							font-weight: 400;
 							color: #6C6F74;
@@ -369,7 +369,7 @@
 						.inner_info{
 							margin-left: 45rpx;
 							text{
-								font-size: 27rpx;
+								font-size: 30rpx;
 								font-weight: 500;
 								color: #232627;
 								line-height: 39rpx;

+ 23 - 0
pages/workbench/gridding/gridding.vue

@@ -0,0 +1,23 @@
+<template>
+	<view>
+		<web-view :src="href"></web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				href: ""
+
+			};
+		},
+		onLoad(option) {
+			this.href = "http://webdevelop.nxjiewei.com/assets/html/zhks-quankuang/grid_troubleshoot?token=" + uni.getStorageSync('Authorization') + "&mine_code=" + uni.getStorageSync('mine_code')
+		}
+	}
+</script>
+
+<style lang="scss">
+
+</style>

BIN
static/logo_xin.png


BIN
static/qidongtu.png


BIN
static/star.png


+ 85 - 0
uni_modules/uni-datetime-picker/changelog.md

@@ -0,0 +1,85 @@
+## 2.2.2(2021-12-10)
+- 修复 clear-icon 属性在小程序平台不生效的 bug
+## 2.2.1(2021-12-10)
+- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的 bug
+## 2.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
+## 2.1.5(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 2.1.4(2021-09-10)
+- 修复 hide-second 在移动端的 bug
+- 修复 单选赋默认值时,赋值日期未高亮的 bug
+- 修复 赋默认值时,移动端未正确显示时间的 bug
+## 2.1.3(2021-09-09)
+- 新增 hide-second 属性,支持只使用时分,隐藏秒
+## 2.1.2(2021-09-03)
+- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
+- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
+- 优化 调整字号大小,美化日历界面
+- 修复 因国际化导致的 placeholder 失效的 bug
+## 2.1.1(2021-08-24)
+- 新增 支持国际化
+- 优化 范围选择器在 pc 端过宽的问题
+## 2.1.0(2021-08-09)
+- 新增 适配 vue3
+## 2.0.19(2021-08-09)
+- 新增 支持作为 uni-forms 子组件相关功能
+- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
+## 2.0.18(2021-08-05)
+- 修复 type 属性动态赋值无效的 bug
+- 修复 ‘确认’按钮被 tabbar 遮盖 bug
+- 修复 组件未赋值时范围选左、右日历相同的 bug
+## 2.0.17(2021-08-04)
+- 修复 范围选未正确显示当前值的 bug
+- 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
+## 2.0.16(2021-07-21)
+- 新增 return-type 属性支持返回 date 日期对象
+## 2.0.15(2021-07-14)
+- 修复 单选日期类型,初始赋值后不在当前日历的 bug
+- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
+- 优化 移动端移除显示框的清空按钮,无实际用途
+## 2.0.14(2021-07-14)
+- 修复 组件赋值为空,界面未更新的 bug
+- 修复 start 和 end 不能动态赋值的 bug
+- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的 bug
+## 2.0.13(2021-07-08)
+- 修复 范围选择不能动态赋值的 bug
+## 2.0.12(2021-07-08)
+- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
+## 2.0.11(2021-07-08)
+- 优化 弹出层在超出视窗边缘定位不准确的问题
+## 2.0.10(2021-07-08)
+- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的 bug
+- 优化 弹出层在超出视窗边缘被遮盖的问题
+## 2.0.9(2021-07-07)
+- 新增 maskClick 事件
+- 修复 特殊情况日历 rpx 布局错误的 bug,rpx -> px
+- 修复 范围选择时清空返回值不合理的bug,['', ''] -> []
+## 2.0.8(2021-07-07)
+- 新增 日期时间显示框支持插槽
+## 2.0.7(2021-07-01)
+- 优化 添加 uni-icons 依赖
+## 2.0.6(2021-05-22)
+- 修复 图标在小程序上不显示的 bug
+- 优化 重命名引用组件,避免潜在组件命名冲突
+## 2.0.5(2021-05-20)
+- 优化 代码目录扁平化
+## 2.0.4(2021-05-12)
+- 新增 组件示例地址
+## 2.0.3(2021-05-10)
+- 修复 ios 下不识别 '-' 日期格式的 bug
+- 优化 pc 下弹出层添加边框和阴影
+## 2.0.2(2021-05-08)
+- 修复 在 admin 中获取弹出层定位错误的bug
+## 2.0.1(2021-05-08)
+- 修复 type 属性向下兼容,默认值从 date 变更为 datetime
+## 2.0.0(2021-04-30)
+- 支持日历形式的日期+时间的范围选择
+ > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)
+## 1.0.6(2021-03-18)
+- 新增 hide-second 属性,时间支持仅选择时、分
+- 修复 选择跟显示的日期不一样的 bug
+- 修复 chang事件触发2次的 bug
+- 修复 分、秒 end 范围错误的 bug
+- 优化 更好的 nvue 适配

+ 185 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue

@@ -0,0 +1,185 @@
+<template>
+	<view class="uni-calendar-item__weeks-box" :class="{
+		'uni-calendar-item--disable':weeks.disable,
+		'uni-calendar-item--before-checked-x':weeks.beforeMultiple,
+		'uni-calendar-item--multiple': weeks.multiple,
+		'uni-calendar-item--after-checked-x':weeks.afterMultiple,
+		}" @click="choiceDate(weeks)" @mouseenter="handleMousemove(weeks)">
+		<view class="uni-calendar-item__weeks-box-item" :class="{
+				'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && (calendar.userChecked || !checkHover),
+				'uni-calendar-item--checked-range-text': checkHover,
+				'uni-calendar-item--before-checked':weeks.beforeMultiple,
+				'uni-calendar-item--multiple': weeks.multiple,
+				'uni-calendar-item--after-checked':weeks.afterMultiple,
+				'uni-calendar-item--disable':weeks.disable,
+				}">
+			<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
+			<text class="uni-calendar-item__weeks-box-text uni-calendar-item__weeks-box-text-disable uni-calendar-item--checked-text">{{weeks.date}}</text>
+		</view>
+		<view :class="{'uni-calendar-item--isDay': weeks.isDay}"></view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			weeks: {
+				type: Object,
+				default () {
+					return {}
+				}
+			},
+			calendar: {
+				type: Object,
+				default: () => {
+					return {}
+				}
+			},
+			selected: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+			lunar: {
+				type: Boolean,
+				default: false
+			},
+			checkHover: {
+				type: Boolean,
+				default: false
+			}
+		},
+		methods: {
+			choiceDate(weeks) {
+				this.$emit('change', weeks)
+			},
+			handleMousemove(weeks) {
+				this.$emit('handleMouse', weeks)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-calendar-item__weeks-box {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		margin: 1px 0;
+		position: relative;
+	}
+
+	.uni-calendar-item__weeks-box-text {
+		font-size: 14px;
+		// font-family: Lato-Bold, Lato;
+		font-weight: bold;
+		color: #455997;
+	}
+
+	.uni-calendar-item__weeks-lunar-text {
+		font-size: 12px;
+		color: #333;
+	}
+
+	.uni-calendar-item__weeks-box-item {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		width: 40px;
+		height: 40px;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+
+	.uni-calendar-item__weeks-box-circle {
+		position: absolute;
+		top: 5px;
+		right: 5px;
+		width: 8px;
+		height: 8px;
+		border-radius: 8px;
+		background-color: #dd524d;
+
+	}
+
+	.uni-calendar-item__weeks-box .uni-calendar-item--disable {
+		// background-color: rgba(249, 249, 249, $uni-opacity-disabled);
+		cursor: default;
+	}
+
+	.uni-calendar-item--disable .uni-calendar-item__weeks-box-text-disable {
+		color: #D1D1D1;
+	}
+
+	.uni-calendar-item--isDay {
+		position: absolute;
+		top: 10px;
+		right: 17%;
+		background-color: #dd524d;
+		width:6px;
+		height: 6px;
+		border-radius: 50%;
+	}
+
+	.uni-calendar-item--extra {
+		color: #dd524d;
+		opacity: 0.8;
+	}
+
+	.uni-calendar-item__weeks-box .uni-calendar-item--checked {
+		background-color: #007aff;
+		border-radius: 50%;
+		box-sizing: border-box;
+		border: 3px solid #fff;
+	}
+
+	.uni-calendar-item--checked .uni-calendar-item--checked-text {
+		color: #fff;
+	}
+
+	.uni-calendar-item--multiple .uni-calendar-item--checked-range-text {
+		color: #333;
+	}
+
+	.uni-calendar-item--multiple {
+		background-color:  #F6F7FC;
+		// color: #fff;
+	}
+
+	.uni-calendar-item--multiple .uni-calendar-item--before-checked,
+	.uni-calendar-item--multiple .uni-calendar-item--after-checked {
+		background-color: #409eff;
+		border-radius: 50%;
+		box-sizing: border-box;
+		border: 3px solid #F6F7FC;
+	}
+
+	.uni-calendar-item--before-checked .uni-calendar-item--checked-text,
+	.uni-calendar-item--after-checked .uni-calendar-item--checked-text {
+		color: #fff;
+	}
+
+	.uni-calendar-item--before-checked-x {
+		border-top-left-radius: 50px;
+		border-bottom-left-radius: 50px;
+		box-sizing: border-box;
+		background-color: #F6F7FC;
+	}
+
+	.uni-calendar-item--after-checked-x {
+		border-top-right-radius: 50px;
+		border-bottom-right-radius: 50px;
+		background-color: #F6F7FC;
+	}
+</style>

+ 898 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue

@@ -0,0 +1,898 @@
+<template>
+	<view class="uni-calendar" @mouseleave="leaveCale">
+		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}"
+			@click="clean"></view>
+		<view v-if="insert || show" class="uni-calendar__content"
+			:class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow, 'uni-calendar__content-mobile': aniMaskShow}">
+			<view class="uni-calendar__header" :class="{'uni-calendar__header-mobile' :!insert}">
+				<view v-if="left" class="uni-calendar__header-btn-box" @click.stop="pre">
+					<view class="uni-calendar__header-btn uni-calendar--left"></view>
+				</view>
+				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
+					<text
+						class="uni-calendar__header-text">{{ (nowDate.year||'') + ' 年 ' + ( nowDate.month||'') +' 月'}}</text>
+				</picker>
+				<view v-if="right" class="uni-calendar__header-btn-box" @click.stop="next">
+					<view class="uni-calendar__header-btn uni-calendar--right"></view>
+				</view>
+				<view v-if="!insert" class="dialog-close" @click="clean">
+					<view class="dialog-close-plus" data-id="close"></view>
+					<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
+				</view>
+
+				<!-- <text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> -->
+			</view>
+			<view class="uni-calendar__box">
+				<view v-if="showMonth" class="uni-calendar__box-bg">
+					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
+				</view>
+				<view class="uni-calendar__weeks" style="padding-bottom: 7px;">
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{monText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
+					</view>
+					<view class="uni-calendar__weeks-day">
+						<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
+					</view>
+				</view>
+				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
+					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
+						<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar"
+							:selected="selected" :lunar="lunar" :checkHover="range" @change="choiceDate"
+							@handleMouse="handleMouse">
+						</calendar-item>
+					</view>
+				</view>
+			</view>
+			<view v-if="!insert && !range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top"
+				style="padding: 0 80px;">
+				<view class="uni-date-changed--time-date">{{tempSingleDate ? tempSingleDate : selectDateText}}</view>
+				<time-picker type="time" :start="reactStartTime" :end="reactEndTime" v-model="time"
+					:disabled="!tempSingleDate" :border="false" :hide-second="hideSecond" class="time-picker-style">
+				</time-picker>
+			</view>
+
+			<view v-if="!insert && range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top">
+				<view class="uni-date-changed--time-start">
+					<view class="uni-date-changed--time-date">{{tempRange.before ? tempRange.before : startDateText}}
+					</view>
+					<time-picker type="time" :start="reactStartTime" v-model="timeRange.startTime" :border="false"
+						:hide-second="hideSecond" :disabled="!tempRange.before" class="time-picker-style">
+					</time-picker>
+				</view>
+				<uni-icons type="arrowthinright" color="#999" style="line-height: 50px;"></uni-icons>
+				<view class="uni-date-changed--time-end">
+					<view class="uni-date-changed--time-date">{{tempRange.after ? tempRange.after : endDateText}}</view>
+					<time-picker type="time" :end="reactEndTime" v-model="timeRange.endTime" :border="false"
+						:hide-second="hideSecond" :disabled="!tempRange.after" class="time-picker-style">
+					</time-picker>
+				</view>
+			</view>
+			<view v-if="!insert" class="uni-date-changed uni-date-btn--ok">
+				<!-- <view class="uni-calendar__header-btn-box">
+					<text class="uni-calendar__button-text uni-calendar--fixed-width">{{okText}}</text>
+				</view> -->
+				<view class="uni-datetime-picker--btn" @click="confirm">确认</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import Calendar from './util.js';
+	import calendarItem from './calendar-item.vue'
+	import timePicker from './time-picker.vue'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+	/**
+	 * Calendar 日历
+	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
+	 * @property {String} date 自定义当前时间,默认为今天
+	 * @property {Boolean} lunar 显示农历
+	 * @property {String} startDate 日期选择范围-开始日期
+	 * @property {String} endDate 日期选择范围-结束日期
+	 * @property {Boolean} range 范围选择
+	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
+	 * 	@value true 弹窗模式
+	 * 	@value false 插入模式
+	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
+	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
+	 * @property {Boolean} showMonth 是否选择月份为背景
+	 * @event {Function} change 日期改变,`insert :ture` 时生效
+	 * @event {Function} confirm 确认选择`insert :false` 时生效
+	 * @event {Function} monthSwitch 切换月份时触发
+	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
+	 */
+	export default {
+		components: {
+			calendarItem,
+			timePicker
+		},
+		props: {
+			date: {
+				type: String,
+				default: ''
+			},
+			defTime: {
+				type: [String, Object],
+				default: ''
+			},
+			selectableTimes: {
+				type: [Object],
+				default () {
+					return {}
+				}
+			},
+			selected: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			lunar: {
+				type: Boolean,
+				default: false
+			},
+			startDate: {
+				type: String,
+				default: ''
+			},
+			endDate: {
+				type: String,
+				default: ''
+			},
+			range: {
+				type: Boolean,
+				default: false
+			},
+			typeHasTime: {
+				type: Boolean,
+				default: false
+			},
+			insert: {
+				type: Boolean,
+				default: true
+			},
+			showMonth: {
+				type: Boolean,
+				default: true
+			},
+			clearDate: {
+				type: Boolean,
+				default: true
+			},
+			left: {
+				type: Boolean,
+				default: true
+			},
+			right: {
+				type: Boolean,
+				default: true
+			},
+			checkHover: {
+				type: Boolean,
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean],
+				default: false
+			},
+			pleStatus: {
+				type: Object,
+				default () {
+					return {
+						before: '',
+						after: '',
+						data: [],
+						fulldate: ''
+					}
+				}
+			}
+		},
+		data() {
+			return {
+				show: false,
+				weeks: [],
+				calendar: {},
+				nowDate: '',
+				aniMaskShow: false,
+				firstEnter: true,
+				time: '',
+				timeRange: {
+					startTime: '',
+					endTime: ''
+				},
+				tempSingleDate: '',
+				tempRange: {
+					before: '',
+					after: ''
+				}
+			}
+		},
+		watch: {
+			date: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (!this.range) {
+						this.tempSingleDate = newVal
+						setTimeout(() => {
+							this.init(newVal)
+						}, 100)
+					}
+				}
+			},
+			defTime: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (!this.range) {
+						this.time = newVal
+					} else {
+						// console.log('-----', newVal);
+						this.timeRange.startTime = newVal.start
+						this.timeRange.endTime = newVal.end
+					}
+				}
+			},
+			startDate(val) {
+				this.cale.resetSatrtDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			endDate(val) {
+				this.cale.resetEndDate(val)
+				this.cale.setDate(this.nowDate.fullDate)
+				this.weeks = this.cale.weeks
+			},
+			selected(newVal) {
+				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
+				this.weeks = this.cale.weeks
+			},
+			pleStatus: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					const {
+						before,
+						after,
+						fulldate,
+						which
+					} = newVal
+					this.tempRange.before = before
+					this.tempRange.after = after
+					setTimeout(() => {
+						if (fulldate) {
+							this.cale.setHoverMultiple(fulldate)
+							if (before && after) {
+								this.cale.lastHover = true
+								if (this.rangeWithinMonth(after, before)) return
+								this.setDate(before)
+							} else {
+								this.cale.setMultiple(fulldate)
+								this.setDate(this.nowDate.fullDate)
+								this.calendar.fullDate = ''
+								this.cale.lastHover = false
+							}
+						} else {
+							this.cale.setDefaultMultiple(before, after)
+							if (which === 'left') {
+								this.setDate(before)
+								this.weeks = this.cale.weeks
+							} else {
+								this.setDate(after)
+								this.weeks = this.cale.weeks
+							}
+							this.cale.lastHover = true
+						}
+					}, 16)
+				}
+			}
+		},
+		computed: {
+			reactStartTime() {
+				const activeDate = this.range ? this.tempRange.before : this.calendar.fullDate
+				const res = activeDate === this.startDate ? this.selectableTimes.start : ''
+				return res
+			},
+			reactEndTime() {
+				const activeDate = this.range ? this.tempRange.after : this.calendar.fullDate
+				const res = activeDate === this.endDate ? this.selectableTimes.end : ''
+				return res
+			},
+			/**
+			 * for i18n
+			 */
+			selectDateText() {
+				return t("uni-datetime-picker.selectDate")
+			},
+			startDateText() {
+				return this.startPlaceholder || t("uni-datetime-picker.startDate")
+			},
+			endDateText() {
+				return this.endPlaceholder || t("uni-datetime-picker.endDate")
+			},
+			okText() {
+				return t("uni-datetime-picker.ok")
+			},
+			monText() {
+				return t("uni-calender.MON")
+			},
+			TUEText() {
+				return t("uni-calender.TUE")
+			},
+			WEDText() {
+				return t("uni-calender.WED")
+			},
+			THUText() {
+				return t("uni-calender.THU")
+			},
+			FRIText() {
+				return t("uni-calender.FRI")
+			},
+			SATText() {
+				return t("uni-calender.SAT")
+			},
+			SUNText() {
+				return t("uni-calender.SUN")
+			},
+		},
+		created() {
+			// 获取日历方法实例
+			this.cale = new Calendar({
+				// date: new Date(),
+				selected: this.selected,
+				startDate: this.startDate,
+				endDate: this.endDate,
+				range: this.range,
+				// multipleStatus: this.pleStatus
+			})
+			// 选中某一天
+			// this.cale.setDate(this.date)
+			this.init(this.date)
+			// this.setDay
+		},
+		methods: {
+			leaveCale() {
+				this.firstEnter = true
+			},
+			handleMouse(weeks) {
+				if (weeks.disable) return
+				if (this.cale.lastHover) return
+				let {
+					before,
+					after
+				} = this.cale.multipleStatus
+				if (!before) return
+				this.calendar = weeks
+				// 设置范围选
+				this.cale.setHoverMultiple(this.calendar.fullDate)
+				this.weeks = this.cale.weeks
+				// hover时,进入一个日历,更新另一个
+				if (this.firstEnter) {
+					this.$emit('firstEnterCale', this.cale.multipleStatus)
+					this.firstEnter = false
+				}
+			},
+			rangeWithinMonth(A, B) {
+				const [yearA, monthA] = A.split('-')
+				const [yearB, monthB] = B.split('-')
+				return yearA === yearB && monthA === monthB
+			},
+
+			// 取消穿透
+			clean() {
+				this.close()
+			},
+
+			clearCalender() {
+				if (this.range) {
+					this.timeRange.startTime = ''
+					this.timeRange.endTime = ''
+					this.tempRange.before = ''
+					this.tempRange.after = ''
+					this.cale.multipleStatus.before = ''
+					this.cale.multipleStatus.after = ''
+					this.cale.multipleStatus.data = []
+					this.cale.lastHover = false
+				} else {
+					this.time = ''
+					this.tempSingleDate = ''
+				}
+				this.calendar.fullDate = ''
+				this.setDate()
+			},
+
+			bindDateChange(e) {
+				const value = e.detail.value + '-1'
+				this.init(value)
+			},
+			/**
+			 * 初始化日期显示
+			 * @param {Object} date
+			 */
+			init(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.calendar = this.cale.getInfo(date)
+			},
+			// choiceDate(weeks) {
+			// 	if (weeks.disable) return
+			// 	this.calendar = weeks
+			// 	// 设置多选
+			// 	this.cale.setMultiple(this.calendar.fullDate, true)
+			// 	this.weeks = this.cale.weeks
+			// 	this.tempSingleDate = this.calendar.fullDate
+			// 	this.tempRange.before = this.cale.multipleStatus.before
+			// 	this.tempRange.after = this.cale.multipleStatus.after
+			// 	this.change()
+			// },
+			/**
+			 * 打开日历弹窗
+			 */
+			open() {
+				// 弹窗模式并且清理数据
+				if (this.clearDate && !this.insert) {
+					this.cale.cleanMultipleStatus()
+					// this.cale.setDate(this.date)
+					this.init(this.date)
+				}
+				this.show = true
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.aniMaskShow = true
+					}, 50)
+				})
+			},
+			/**
+			 * 关闭日历弹窗
+			 */
+			close() {
+				this.aniMaskShow = false
+				this.$nextTick(() => {
+					setTimeout(() => {
+						this.show = false
+						this.$emit('close')
+					}, 300)
+				})
+			},
+			/**
+			 * 确认按钮
+			 */
+			confirm() {
+				this.setEmit('confirm')
+				this.close()
+			},
+			/**
+			 * 变化触发
+			 */
+			change() {
+				if (!this.insert) return
+				this.setEmit('change')
+			},
+			/**
+			 * 选择月份触发
+			 */
+			monthSwitch() {
+				let {
+					year,
+					month
+				} = this.nowDate
+				this.$emit('monthSwitch', {
+					year,
+					month: Number(month)
+				})
+			},
+			/**
+			 * 派发事件
+			 * @param {Object} name
+			 */
+			setEmit(name) {
+				let {
+					year,
+					month,
+					date,
+					fullDate,
+					lunar,
+					extraInfo
+				} = this.calendar
+				this.$emit(name, {
+					range: this.cale.multipleStatus,
+					year,
+					month,
+					date,
+					time: this.time,
+					timeRange: this.timeRange,
+					fulldate: fullDate,
+					lunar,
+					extraInfo: extraInfo || {}
+				})
+			},
+			/**
+			 * 选择天触发
+			 * @param {Object} weeks
+			 */
+			choiceDate(weeks) {
+				if (weeks.disable) return
+				this.calendar = weeks
+				this.calendar.userChecked = true
+				// 设置多选
+				this.cale.setMultiple(this.calendar.fullDate, true)
+				this.weeks = this.cale.weeks
+				this.tempSingleDate = this.calendar.fullDate
+				this.tempRange.before = this.cale.multipleStatus.before
+				this.tempRange.after = this.cale.multipleStatus.after
+				this.change()
+			},
+			/**
+			 * 回到今天
+			 */
+			backtoday() {
+				let date = this.cale.getDate(new Date()).fullDate
+				// this.cale.setDate(date)
+				this.init(date)
+				this.change()
+			},
+			/**
+			 * 比较时间大小
+			 */
+			dateCompare(startDate, endDate) {
+				// 计算截止时间
+				startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+				// 计算详细项的截止时间
+				endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+				if (startDate <= endDate) {
+					return true
+				} else {
+					return false
+				}
+			},
+			/**
+			 * 上个月
+			 */
+			pre() {
+				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
+				this.setDate(preDate)
+				this.monthSwitch()
+
+			},
+			/**
+			 * 下个月
+			 */
+			next() {
+				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
+				this.setDate(nextDate)
+				this.monthSwitch()
+			},
+			/**
+			 * 设置日期
+			 * @param {Object} date
+			 */
+			setDate(date) {
+				this.cale.setDate(date)
+				this.weeks = this.cale.weeks
+				this.nowDate = this.cale.getInfo(date)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-calendar {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+	}
+
+	.uni-calendar__mask {
+		position: fixed;
+		bottom: 0;
+		top: 0;
+		left: 0;
+		right: 0;
+		background-color: rgba(0, 0, 0, 0.4);
+		transition-property: opacity;
+		transition-duration: 0.3s;
+		opacity: 0;
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--mask-show {
+		opacity: 1
+	}
+
+	.uni-calendar--fixed {
+		position: fixed;
+		bottom: calc(var(--window-bottom));
+		left: 0;
+		right: 0;
+		transition-property: transform;
+		transition-duration: 0.3s;
+		transform: translateY(460px);
+		/* #ifndef APP-NVUE */
+		z-index: 99;
+		/* #endif */
+	}
+
+	.uni-calendar--ani-show {
+		transform: translateY(0);
+	}
+
+	.uni-calendar__content {
+		background-color: #fff;
+	}
+
+	.uni-calendar__content-mobile {
+		border-top-left-radius: 10px;
+		border-top-right-radius: 10px;
+		box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.1);
+	}
+
+	.uni-calendar__header {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: center;
+		align-items: center;
+		height: 50px;
+	}
+
+	.uni-calendar__header-mobile {
+		padding: 10px;
+		padding-bottom: 0;
+	}
+
+	.uni-calendar--fixed-top {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+		border-top-color: rgba(0, 0, 0, 0.4);
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-calendar--fixed-width {
+		width: 50px;
+	}
+
+	.uni-calendar__backtoday {
+		position: absolute;
+		right: 0;
+		top: 25rpx;
+		padding: 0 5px;
+		padding-left: 10px;
+		height: 25px;
+		line-height: 25px;
+		font-size: 12px;
+		border-top-left-radius: 25px;
+		border-bottom-left-radius: 25px;
+		color: #fff;
+		background-color: #f1f1f1;
+	}
+
+	.uni-calendar__header-text {
+		text-align: center;
+		width: 100px;
+		font-size: 15px;
+		color: #666;
+	}
+
+	.uni-calendar__button-text {
+		text-align: center;
+		width: 100px;
+		font-size: 14px;
+		color: #007aff;
+		/* #ifndef APP-NVUE */
+		letter-spacing: 3px;
+		/* #endif */
+	}
+
+	.uni-calendar__header-btn-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		width: 50px;
+		height: 50px;
+	}
+
+	.uni-calendar__header-btn {
+		width: 9px;
+		height: 9px;
+		border-left-color: #808080;
+		border-left-style: solid;
+		border-left-width: 1px;
+		border-top-color: #555555;
+		border-top-style: solid;
+		border-top-width: 1px;
+	}
+
+	.uni-calendar--left {
+		transform: rotate(-45deg);
+	}
+
+	.uni-calendar--right {
+		transform: rotate(135deg);
+	}
+
+
+	.uni-calendar__weeks {
+		position: relative;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-calendar__weeks-item {
+		flex: 1;
+	}
+
+	.uni-calendar__weeks-day {
+		flex: 1;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+		height: 40px;
+		border-bottom-color: #F5F5F5;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+	}
+
+	.uni-calendar__weeks-day-text {
+		font-size: 12px;
+		color: #B2B2B2;
+	}
+
+	.uni-calendar__box {
+		position: relative;
+		// padding: 0 10px;
+		padding-bottom: 7px;
+	}
+
+	.uni-calendar__box-bg {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+	}
+
+	.uni-calendar__box-bg-text {
+		font-size: 200px;
+		font-weight: bold;
+		color: #999;
+		opacity: 0.1;
+		text-align: center;
+		/* #ifndef APP-NVUE */
+		line-height: 1;
+		/* #endif */
+	}
+
+	.uni-date-changed {
+		padding: 0 10px;
+		// line-height: 50px;
+		text-align: center;
+		color: #333;
+		border-top-color: #DCDCDC;
+		;
+		border-top-style: solid;
+		border-top-width: 1px;
+		flex: 1;
+	}
+
+	.uni-date-btn--ok {
+		padding: 20px 15px;
+	}
+
+	.uni-date-changed--time-start {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+	}
+
+	.uni-date-changed--time-end {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+	}
+
+	.uni-date-changed--time-date {
+		color: #999;
+		line-height: 50px;
+		margin-right: 5px;
+		// opacity: 0.6;
+	}
+
+	.time-picker-style {
+		// width: 62px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center
+	}
+
+	.mr-10 {
+		margin-right: 10px;
+	}
+
+	.dialog-close {
+		position: absolute;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		padding: 0 25px;
+		margin-top: 10px;
+	}
+
+	.dialog-close-plus {
+		width: 16px;
+		height: 2px;
+		background-color: #737987;
+		border-radius: 2px;
+		transform: rotate(45deg);
+	}
+
+	.dialog-close-rotate {
+		position: absolute;
+		transform: rotate(-45deg);
+	}
+
+	.uni-datetime-picker--btn {
+		border-radius: 100px;
+		height: 40px;
+		line-height: 40px;
+		background-color: #007aff;
+		color: #fff;
+		font-size: 16px;
+		letter-spacing: 5px;
+	}
+
+	/* #ifndef APP-NVUE */
+	.uni-datetime-picker--btn:active {
+		opacity: 0.7;
+	}
+	/* #endif */
+</style>

+ 19 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json

@@ -0,0 +1,19 @@
+{
+	"uni-datetime-picker.selectDate": "select date",
+	"uni-datetime-picker.selectTime": "select time",
+	"uni-datetime-picker.selectDateTime": "select datetime",
+	"uni-datetime-picker.startDate": "start date",
+	"uni-datetime-picker.endDate": "end date",
+	"uni-datetime-picker.startTime": "start time",
+	"uni-datetime-picker.endTime": "end time",
+	"uni-datetime-picker.ok": "ok",
+	"uni-datetime-picker.clear": "clear",
+	"uni-datetime-picker.cancel": "cancel",
+	"uni-calender.MON": "MON",
+	"uni-calender.TUE": "TUE",
+	"uni-calender.WED": "WED",
+	"uni-calender.THU": "THU",
+	"uni-calender.FRI": "FRI",
+	"uni-calender.SAT": "SAT",
+	"uni-calender.SUN": "SUN"
+}

+ 8 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js

@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant
+}

+ 19 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json

@@ -0,0 +1,19 @@
+{
+	"uni-datetime-picker.selectDate": "选择日期",
+	"uni-datetime-picker.selectTime": "选择时间",
+	"uni-datetime-picker.selectDateTime": "选择日期时间",
+	"uni-datetime-picker.startDate": "开始日期",
+	"uni-datetime-picker.endDate": "结束日期",
+	"uni-datetime-picker.startTime": "开始时间",
+	"uni-datetime-picker.endTime": "结束时间",
+	"uni-datetime-picker.ok": "确定",
+	"uni-datetime-picker.clear": "清除",
+	"uni-datetime-picker.cancel": "取消",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六"
+}

+ 19 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json

@@ -0,0 +1,19 @@
+{
+	"uni-datetime-picker.selectDate": "選擇日期",
+	"uni-datetime-picker.selectTime": "選擇時間",
+	"uni-datetime-picker.selectDateTime": "選擇日期時間",
+	"uni-datetime-picker.startDate": "開始日期",
+	"uni-datetime-picker.endDate": "結束日期",
+	"uni-datetime-picker.startTime": "開始时间",
+	"uni-datetime-picker.endTime": "結束时间",
+	"uni-datetime-picker.ok": "確定",
+	"uni-datetime-picker.clear": "清除",
+	"uni-datetime-picker.cancel": "取消",
+	"uni-calender.SUN": "日",
+	"uni-calender.MON": "一",
+	"uni-calender.TUE": "二",
+	"uni-calender.WED": "三",
+	"uni-calender.THU": "四",
+	"uni-calender.FRI": "五",
+	"uni-calender.SAT": "六"
+}

+ 45 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js

@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+  name: 'Keypress',
+  props: {
+    disable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  mounted () {
+    const keyNames = {
+      esc: ['Esc', 'Escape'],
+      tab: 'Tab',
+      enter: 'Enter',
+      space: [' ', 'Spacebar'],
+      up: ['Up', 'ArrowUp'],
+      left: ['Left', 'ArrowLeft'],
+      right: ['Right', 'ArrowRight'],
+      down: ['Down', 'ArrowDown'],
+      delete: ['Backspace', 'Delete', 'Del']
+    }
+    const listener = ($event) => {
+      if (this.disable) {
+        return
+      }
+      const keyName = Object.keys(keyNames).find(key => {
+        const keyName = $event.key
+        const value = keyNames[key]
+        return value === keyName || (Array.isArray(value) && value.includes(keyName))
+      })
+      if (keyName) {
+        // 避免和其他按键事件冲突
+        setTimeout(() => {
+          this.$emit(keyName, {})
+        }, 0)
+      }
+    }
+    document.addEventListener('keyup', listener)
+    this.$once('hook:beforeDestroy', () => {
+      document.removeEventListener('keyup', listener)
+    })
+  },
+	render: () => {}
+}
+// #endif

+ 927 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue

@@ -0,0 +1,927 @@
+<template>
+	<view class="uni-datetime-picker">
+		<view @click="initTimePicker">
+			<slot>
+				<view class="uni-datetime-picker-timebox-pointer"
+					:class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}">
+					<text class="uni-datetime-picker-text">{{time}}</text>
+					<view v-if="!time" class="uni-datetime-picker-time">
+						<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
+					</view>
+				</view>
+			</slot>
+		</view>
+		<view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view>
+		<view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']"
+			:style="fixNvueBug">
+			<view class="uni-title">
+				<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
+			</view>
+			<view v-if="dateShow" class="uni-datetime-picker__container-box">
+				<picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd"
+					@change="bindDateChange">
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+				</picker-view>
+				<!-- 兼容 nvue 不支持伪类 -->
+				<text class="uni-datetime-picker-sign sign-left">-</text>
+				<text class="uni-datetime-picker-sign sign-right">-</text>
+			</view>
+			<view v-if="timeShow" class="uni-datetime-picker__container-box">
+				<picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']"
+					:indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange">
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column>
+						<view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+					<picker-view-column v-if="!hideSecond">
+						<view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index">
+							<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
+						</view>
+					</picker-view-column>
+				</picker-view>
+				<!-- 兼容 nvue 不支持伪类 -->
+				<text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text>
+				<text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text>
+			</view>
+			<view class="uni-datetime-picker-btn">
+				<view @click="clearTime">
+					<text class="uni-datetime-picker-btn-text">{{clearText}}</text>
+				</view>
+				<view class="uni-datetime-picker-btn-group">
+					<view class="uni-datetime-picker-cancel" @click="tiggerTimePicker">
+						<text class="uni-datetime-picker-btn-text">{{cancelText}}</text>
+					</view>
+					<view @click="setTime">
+						<text class="uni-datetime-picker-btn-text">{{okText}}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		<!-- #ifdef H5 -->
+		<!-- <keypress v-if="visible" @esc="tiggerTimePicker" @enter="setTime" /> -->
+		<!-- #endif -->
+	</view>
+</template>
+
+<script>
+	// #ifdef H5
+	import keypress from './keypress'
+	// #endif
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {	t	} = initVueI18n(messages)
+
+	/**
+	 * DatetimePicker 时间选择器
+	 * @description 可以同时选择日期和时间的选择器
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
+	 * @property {String} type = [datetime | date | time] 显示模式
+	 * @property {Boolean} multiple = [true|false] 是否多选
+	 * @property {String|Number} value 默认值
+	 * @property {String|Number} start 起始日期或时间
+	 * @property {String|Number} end 起始日期或时间
+	 * @property {String} return-type = [timestamp | string]
+	 * @event {Function} change  选中发生变化触发
+	 */
+
+	export default {
+		name: 'UniDatetimePicker',
+		components: {
+			// #ifdef H5
+			keypress
+			// #endif
+		},
+		data() {
+			return {
+				indicatorStyle: `height: 50px;`,
+				visible: false,
+				fixNvueBug: {},
+				dateShow: true,
+				timeShow: true,
+				title: '日期和时间',
+				// 输入框当前时间
+				time: '',
+				// 当前的年月日时分秒
+				year: 1920,
+				month: 0,
+				day: 0,
+				hour: 0,
+				minute: 0,
+				second: 0,
+				// 起始时间
+				startYear: 1920,
+				startMonth: 1,
+				startDay: 1,
+				startHour: 0,
+				startMinute: 0,
+				startSecond: 0,
+				// 结束时间
+				endYear: 2120,
+				endMonth: 12,
+				endDay: 31,
+				endHour: 23,
+				endMinute: 59,
+				endSecond: 59,
+			}
+		},
+		props: {
+			type: {
+				type: String,
+				default: 'datetime'
+			},
+			value: {
+				type: [String, Number],
+				default: ''
+			},
+			modelValue: {
+				type: [String, Number],
+				default: ''
+			},
+			start: {
+				type: [Number, String],
+				default: ''
+			},
+			end: {
+				type: [Number, String],
+				default: ''
+			},
+			returnType: {
+				type: String,
+				default: 'string'
+			},
+			disabled: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: [Boolean, String],
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean, String],
+				default: false
+			}
+		},
+		watch: {
+			value: {
+				handler(newVal, oldVal) {
+					if (newVal) {
+						this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式
+						this.initTime(false)
+					} else {
+						this.time = ''
+						this.parseValue(Date.now())
+					}
+				},
+				immediate: true
+			},
+			type: {
+				handler(newValue) {
+					if (newValue === 'date') {
+						this.dateShow = true
+						this.timeShow = false
+						this.title = '日期'
+					} else if (newValue === 'time') {
+						this.dateShow = false
+						this.timeShow = true
+						this.title = '时间'
+					} else {
+						this.dateShow = true
+						this.timeShow = true
+						this.title = '日期和时间'
+					}
+				},
+				immediate: true
+			},
+			start: {
+				handler(newVal) {
+					this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'start') //兼容 iOS、safari 日期格式
+				},
+				immediate: true
+			},
+			end: {
+				handler(newVal) {
+					this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'end') //兼容 iOS、safari 日期格式
+				},
+				immediate: true
+			},
+
+			// 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项
+			months(newVal) {
+				this.checkValue('month', this.month, newVal)
+			},
+			days(newVal) {
+				this.checkValue('day', this.day, newVal)
+			},
+			hours(newVal) {
+				this.checkValue('hour', this.hour, newVal)
+			},
+			minutes(newVal) {
+				this.checkValue('minute', this.minute, newVal)
+			},
+			seconds(newVal) {
+				this.checkValue('second', this.second, newVal)
+			}
+		},
+		computed: {
+			// 当前年、月、日、时、分、秒选择范围
+			years() {
+				return this.getCurrentRange('year')
+			},
+
+			months() {
+				return this.getCurrentRange('month')
+			},
+
+			days() {
+				return this.getCurrentRange('day')
+			},
+
+			hours() {
+				return this.getCurrentRange('hour')
+			},
+
+			minutes() {
+				return this.getCurrentRange('minute')
+			},
+
+			seconds() {
+				return this.getCurrentRange('second')
+			},
+
+			// picker 当前值数组
+			ymd() {
+				return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay]
+			},
+			hms() {
+				return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond]
+			},
+
+			// 当前 date 是 start
+			currentDateIsStart() {
+				return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay
+			},
+
+			// 当前 date 是 end
+			currentDateIsEnd() {
+				return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay
+			},
+
+			// 当前年、月、日、时、分、秒的最小值和最大值
+			minYear() {
+				return this.startYear
+			},
+			maxYear() {
+				return this.endYear
+			},
+			minMonth() {
+				if (this.year === this.startYear) {
+					return this.startMonth
+				} else {
+					return 1
+				}
+			},
+			maxMonth() {
+				if (this.year === this.endYear) {
+					return this.endMonth
+				} else {
+					return 12
+				}
+			},
+			minDay() {
+				if (this.year === this.startYear && this.month === this.startMonth) {
+					return this.startDay
+				} else {
+					return 1
+				}
+			},
+			maxDay() {
+				if (this.year === this.endYear && this.month === this.endMonth) {
+					return this.endDay
+				} else {
+					return this.daysInMonth(this.year, this.month)
+				}
+			},
+			minHour() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart) {
+						return this.startHour
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					return this.startHour
+				}
+			},
+			maxHour() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd) {
+						return this.endHour
+					} else {
+						return 23
+					}
+				}
+				if (this.type === 'time') {
+					return this.endHour
+				}
+			},
+			minMinute() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart && this.hour === this.startHour) {
+						return this.startMinute
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.startHour) {
+						return this.startMinute
+					} else {
+						return 0
+					}
+				}
+			},
+			maxMinute() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd && this.hour === this.endHour) {
+						return this.endMinute
+					} else {
+						return 59
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.endHour) {
+						return this.endMinute
+					} else {
+						return 59
+					}
+				}
+			},
+			minSecond() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) {
+						return this.startSecond
+					} else {
+						return 0
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.startHour && this.minute === this.startMinute) {
+						return this.startSecond
+					} else {
+						return 0
+					}
+				}
+			},
+			maxSecond() {
+				if (this.type === 'datetime') {
+					if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) {
+						return this.endSecond
+					} else {
+						return 59
+					}
+				}
+				if (this.type === 'time') {
+					if (this.hour === this.endHour && this.minute === this.endMinute) {
+						return this.endSecond
+					} else {
+						return 59
+					}
+				}
+			},
+
+			/**
+			 * for i18n
+			 */
+			selectTimeText() {
+				return t("uni-datetime-picker.selectTime")
+			},
+			okText() {
+				return t("uni-datetime-picker.ok")
+			},
+			clearText() {
+				return t("uni-datetime-picker.clear")
+			},
+			cancelText() {
+				return t("uni-datetime-picker.cancel")
+			}
+		},
+
+		mounted() {
+			// #ifdef APP-NVUE
+			const res = uni.getSystemInfoSync();
+			this.fixNvueBug = {
+				top: res.windowHeight / 2,
+				left: res.windowWidth / 2
+			}
+			// #endif
+		},
+
+		methods: {
+			/**
+			 * @param {Object} item
+			 * 小于 10 在前面加个 0
+			 */
+
+			lessThanTen(item) {
+				return item < 10 ? '0' + item : item
+			},
+
+			/**
+			 * 解析时分秒字符串,例如:00:00:00
+			 * @param {String} timeString
+			 */
+			parseTimeType(timeString) {
+				if (timeString) {
+					let timeArr = timeString.split(':')
+					this.hour = Number(timeArr[0])
+					this.minute = Number(timeArr[1])
+					this.second = Number(timeArr[2])
+				}
+			},
+
+			/**
+			 * 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000
+			 * @param {String | Number} datetime
+			 */
+			initPickerValue(datetime) {
+				let defaultValue = null
+				if (datetime) {
+					defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end)
+				} else {
+					defaultValue = Date.now()
+					defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end)
+				}
+				this.parseValue(defaultValue)
+			},
+
+			/**
+			 * 初始值规则:
+			 * - 用户设置初始值 value
+			 * 	- 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start
+			 * 	- 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start
+			 * 	- 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end
+			 * 	- 无起始终止时间,则初始值为 value
+			 * - 无初始值 value,则初始值为当前本地时间 Date.now()
+			 * @param {Object} value
+			 * @param {Object} dateBase
+			 */
+			compareValueWithStartAndEnd(value, start, end) {
+				let winner = null
+				value = this.superTimeStamp(value)
+				start = this.superTimeStamp(start)
+				end = this.superTimeStamp(end)
+
+				if (start && end) {
+					if (value < start) {
+						winner = new Date(start)
+					} else if (value > end) {
+						winner = new Date(end)
+					} else {
+						winner = new Date(value)
+					}
+				} else if (start && !end) {
+					winner = start <= value ? new Date(value) : new Date(start)
+				} else if (!start && end) {
+					winner = value <= end ? new Date(value) : new Date(end)
+				} else {
+					winner = new Date(value)
+				}
+
+				return winner
+			},
+
+			/**
+			 * 转换为可比较的时间戳,接受日期、时分秒、时间戳
+			 * @param {Object} value
+			 */
+			superTimeStamp(value) {
+				let dateBase = ''
+				if (this.type === 'time' && value && typeof value === 'string') {
+					const now = new Date()
+					const year = now.getFullYear()
+					const month = now.getMonth() + 1
+					const day = now.getDate()
+					dateBase = year + '/' + month + '/' + day + ' '
+				}
+				if (Number(value) && typeof value !== NaN) {
+					value = parseInt(value)
+					dateBase = 0
+				}
+				return this.createTimeStamp(dateBase + value)
+			},
+
+			/**
+			 * 解析默认值 value,字符串、时间戳
+			 * @param {Object} defaultTime
+			 */
+			parseValue(value) {
+				if (!value) {
+					return
+				}
+				if (this.type === 'time' && typeof value === "string") {
+					this.parseTimeType(value)
+				} else {
+					let defaultDate = null
+					defaultDate = new Date(value)
+					if (this.type !== 'time') {
+						this.year = defaultDate.getFullYear()
+						this.month = defaultDate.getMonth() + 1
+						this.day = defaultDate.getDate()
+					}
+					if (this.type !== 'date') {
+						this.hour = defaultDate.getHours()
+						this.minute = defaultDate.getMinutes()
+						this.second = defaultDate.getSeconds()
+					}
+				}
+				if (this.hideSecond) {
+					this.second = 0
+				}
+			},
+
+			/**
+			 * 解析可选择时间范围 start、end,年月日字符串、时间戳
+			 * @param {Object} defaultTime
+			 */
+			parseDatetimeRange(point, pointType) {
+				// 时间为空,则重置为初始值
+				if (!point) {
+					if (pointType === 'start') {
+						this.startYear = 1920
+						this.startMonth = 1
+						this.startDay = 1
+						this.startHour = 0
+						this.startMinute = 0
+						this.startSecond = 0
+					}
+					if (pointType === 'end') {
+						this.endYear = 2120
+						this.endMonth = 12
+						this.endDay = 31
+						this.endHour = 23
+						this.endMinute = 59
+						this.endSecond = 59
+					}
+					return
+				}
+				if (this.type === 'time') {
+					const pointArr = point.split(':')
+					this[pointType + 'Hour'] = Number(pointArr[0])
+					this[pointType + 'Minute'] = Number(pointArr[1])
+					this[pointType + 'Second'] = Number(pointArr[2])
+				} else {
+					if (!point) {
+						pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60
+						return
+					}
+					if (Number(point) && Number(point) !== NaN) {
+						point = parseInt(point)
+					}
+					// datetime 的 end 没有时分秒, 则不限制
+					const hasTime = /[0-9]:[0-9]/
+					if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test(
+							point)) {
+						point = point + ' 23:59:59'
+					}
+					const pointDate = new Date(point)
+					this[pointType + 'Year'] = pointDate.getFullYear()
+					this[pointType + 'Month'] = pointDate.getMonth() + 1
+					this[pointType + 'Day'] = pointDate.getDate()
+					if (this.type === 'datetime') {
+						this[pointType + 'Hour'] = pointDate.getHours()
+						this[pointType + 'Minute'] = pointDate.getMinutes()
+						this[pointType + 'Second'] = pointDate.getSeconds()
+					}
+				}
+			},
+
+			// 获取 年、月、日、时、分、秒 当前可选范围
+			getCurrentRange(value) {
+				const range = []
+				for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) {
+					range.push(i)
+				}
+				return range
+			},
+
+			// 字符串首字母大写
+			capitalize(str) {
+				return str.charAt(0).toUpperCase() + str.slice(1)
+			},
+
+			// 检查当前值是否在范围内,不在则当前值重置为可选范围第一项
+			checkValue(name, value, values) {
+				if (values.indexOf(value) === -1) {
+					this[name] = values[0]
+				}
+			},
+
+			// 每个月的实际天数
+			daysInMonth(year, month) { // Use 1 for January, 2 for February, etc.
+				return new Date(year, month, 0).getDate();
+			},
+
+			//兼容 iOS、safari 日期格式
+			fixIosDateFormat(value) {
+				if (typeof value === 'string') {
+					value = value.replace(/-/g, '/')
+				}
+				return value
+			},
+
+			/**
+			 * 生成时间戳
+			 * @param {Object} time
+			 */
+			createTimeStamp(time) {
+				if (!time) return
+				if (typeof time === "number") {
+					return time
+				} else {
+					time = time.replace(/-/g, '/')
+					if (this.type === 'date') {
+						time = time + ' ' + '00:00:00'
+					}
+					return Date.parse(time)
+				}
+			},
+
+			/**
+			 * 生成日期或时间的字符串
+			 */
+			createDomSting() {
+				const yymmdd = this.year +
+					'-' +
+					this.lessThanTen(this.month) +
+					'-' +
+					this.lessThanTen(this.day)
+
+				let hhmmss = this.lessThanTen(this.hour) +
+					':' +
+					this.lessThanTen(this.minute)
+
+				if (!this.hideSecond) {
+					hhmmss = hhmmss + ':' + this.lessThanTen(this.second)
+				}
+
+				if (this.type === 'date') {
+					return yymmdd
+				} else if (this.type === 'time') {
+					return hhmmss
+				} else {
+					return yymmdd + ' ' + hhmmss
+				}
+			},
+
+			/**
+			 * 初始化返回值,并抛出 change 事件
+			 */
+			initTime(emit = true) {
+				this.time = this.createDomSting()
+				if (!emit) return
+				if (this.returnType === 'timestamp' && this.type !== 'time') {
+					this.$emit('change', this.createTimeStamp(this.time))
+					this.$emit('input', this.createTimeStamp(this.time))
+					this.$emit('update:modelValue', this.createTimeStamp(this.time))
+				} else {
+					this.$emit('change', this.time)
+					this.$emit('input', this.time)
+					this.$emit('update:modelValue', this.time)
+				}
+			},
+
+			/**
+			 * 用户选择日期或时间更新 data
+			 * @param {Object} e
+			 */
+			bindDateChange(e) {
+				const val = e.detail.value
+				this.year = this.years[val[0]]
+				this.month = this.months[val[1]]
+				this.day = this.days[val[2]]
+			},
+			bindTimeChange(e) {
+				const val = e.detail.value
+				this.hour = this.hours[val[0]]
+				this.minute = this.minutes[val[1]]
+				this.second = this.seconds[val[2]]
+			},
+
+			/**
+			 * 初始化弹出层
+			 */
+			initTimePicker() {
+				if (this.disabled) return
+				const value = this.fixIosDateFormat(this.value)
+				this.initPickerValue(value)
+				this.visible = !this.visible
+			},
+
+			/**
+			 * 触发或关闭弹框
+			 */
+			tiggerTimePicker(e) {
+				this.visible = !this.visible
+			},
+
+			/**
+			 * 用户点击“清空”按钮,清空当前值
+			 */
+			clearTime() {
+				this.time = ''
+				this.$emit('change', this.time)
+				this.$emit('input', this.time)
+				this.$emit('update:modelValue', this.time)
+				this.tiggerTimePicker()
+			},
+
+			/**
+			 * 用户点击“确定”按钮
+			 */
+			setTime() {
+				this.initTime()
+				this.tiggerTimePicker()
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-datetime-picker {
+		/* #ifndef APP-NVUE */
+		/* width: 100%; */
+		/* #endif */
+	}
+
+	.uni-datetime-picker-view {
+		height: 130px;
+		width: 270px;
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-item {
+		height: 50px;
+		line-height: 50px;
+		text-align: center;
+		font-size: 14px;
+	}
+
+	.uni-datetime-picker-btn {
+		margin-top: 60px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		cursor: pointer;
+		/* #endif */
+		flex-direction: row;
+		justify-content: space-between;
+	}
+
+	.uni-datetime-picker-btn-text {
+		font-size: 14px;
+		color: #007AFF;
+	}
+
+	.uni-datetime-picker-btn-group {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-datetime-picker-cancel {
+		margin-right: 30px;
+	}
+
+	.uni-datetime-picker-mask {
+		position: fixed;
+		bottom: 0px;
+		top: 0px;
+		left: 0px;
+		right: 0px;
+		background-color: rgba(0, 0, 0, 0.4);
+		transition-duration: 0.3s;
+		z-index: 998;
+	}
+
+	.uni-datetime-picker-popup {
+		border-radius: 8px;
+		padding: 30px;
+		width: 270px;
+		/* #ifdef APP-NVUE */
+		height: 500px;
+		/* #endif */
+		/* #ifdef APP-NVUE */
+		width: 330px;
+		/* #endif */
+		background-color: #fff;
+		position: fixed;
+		top: 50%;
+		left: 50%;
+		transform: translate(-50%, -50%);
+		transition-duration: 0.3s;
+		z-index: 999;
+	}
+
+	.fix-nvue-height {
+		/* #ifdef APP-NVUE */
+		height: 330px;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-time {
+		color: grey;
+	}
+
+	.uni-datetime-picker-column {
+		height: 50px;
+	}
+
+	.uni-datetime-picker-timebox {
+
+		border: 1px solid #E5E5E5;
+		border-radius: 5px;
+		padding: 7px 10px;
+		/* #ifndef APP-NVUE */
+		box-sizing: border-box;
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-timebox-pointer {
+		/* #ifndef APP-NVUE */
+		cursor: pointer;
+		/* #endif */
+	}
+
+
+	.uni-datetime-picker-disabled {
+		opacity: 0.4;
+		/* #ifdef H5 */
+		cursor: not-allowed !important;
+		/* #endif */
+	}
+
+	.uni-datetime-picker-text {
+		font-size: 14px;
+	}
+
+	.uni-datetime-picker-sign {
+		position: absolute;
+		top: 53px;
+		/* 减掉 10px 的元素高度,兼容nvue */
+		color: #999;
+		/* #ifdef APP-NVUE */
+		font-size: 16px;
+		/* #endif */
+	}
+
+	.sign-left {
+		left: 86px;
+	}
+
+	.sign-right {
+		right: 86px;
+	}
+
+	.sign-center {
+		left: 135px;
+	}
+
+	.uni-datetime-picker__container-box {
+		position: relative;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		margin-top: 40px;
+	}
+
+	.time-hide-second {
+		width: 180px;
+	}
+</style>

+ 981 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue

@@ -0,0 +1,981 @@
+<template>
+	<view class="uni-date">
+		<view class="uni-date-editor" @click="show">
+			<slot>
+				<view class="uni-date-editor--x" :class="{'uni-date-editor--x__disabled': disabled,
+		'uni-date-x--border': border}">
+					<view v-if="!isRange" class="uni-date-x uni-date-single">
+						<uni-icons type="calendar" color="#e1e1e1" size="22"></uni-icons>
+						<input class="uni-date__x-input" type="text" v-model="singleVal"
+							:placeholder="singlePlaceholderText" :disabled="true" />
+					</view>
+					<view v-else class="uni-date-x uni-date-range">
+						<uni-icons type="calendar" color="#e1e1e1" size="22"></uni-icons>
+						<input class="uni-date__x-input t-c" type="text" v-model="range.startDate"
+							:placeholder="startPlaceholderText" :disabled="true" />
+						<slot>
+							<view class="">{{rangeSeparator}}</view>
+						</slot>
+						<input class="uni-date__x-input t-c" type="text" v-model="range.endDate"
+							:placeholder="endPlaceholderText" :disabled="true" />
+					</view>
+					<view v-if="showClearIcon" class="uni-date__icon-clear" @click.stop="clear">
+						<uni-icons type="clear" color="#e1e1e1" size="18"></uni-icons>
+					</view>
+				</view>
+			</slot>
+		</view>
+
+		<view v-show="popup" class="uni-date-mask" @click="close"></view>
+		<view v-if="!isPhone" ref="datePicker" v-show="popup" class="uni-date-picker__container">
+			<view v-if="!isRange" class="uni-date-single--x" :style="popover">
+				<view class="uni-popper__arrow"></view>
+				<view v-if="hasTime" class="uni-date-changed popup-x-header">
+					<input class="uni-date__input t-c" type="text" v-model="tempSingleDate"
+						:placeholder="selectDateText" />
+					<time-picker type="time" v-model="time" :border="false" :disabled="!tempSingleDate"
+						:start="reactStartTime" :end="reactEndTime" :hideSecond="hideSecond" style="width: 100%;">
+						<input class="uni-date__input t-c" type="text" v-model="time" :placeholder="selectTimeText"
+							:disabled="!tempSingleDate" />
+					</time-picker>
+				</view>
+				<calendar ref="pcSingle" :showMonth="false"
+					:start-date="caleRange.startDate" :end-date="caleRange.endDate" :date="defSingleDate"
+					@change="singleChange" style="padding: 0 8px;" />
+				<view v-if="hasTime" class="popup-x-footer">
+					<!-- <text class="">此刻</text> -->
+					<text class="confirm" @click="confirmSingleChange">{{okText}}</text>
+				</view>
+				<view class="uni-date-popper__arrow"></view>
+			</view>
+
+			<view v-else class="uni-date-range--x" :style="popover">
+				<view class="uni-popper__arrow"></view>
+				<view v-if="hasTime" class="popup-x-header uni-date-changed">
+					<view class="popup-x-header--datetime">
+						<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.startDate"
+							:placeholder="startDateText" />
+						<time-picker type="time" v-model="tempRange.startTime" :start="reactStartTime" :border="false"
+							:disabled="!tempRange.startDate" :hideSecond="hideSecond">
+							<input class="uni-date__input uni-date-range__input" type="text"
+								v-model="tempRange.startTime" :placeholder="startTimeText"
+								:disabled="!tempRange.startDate" />
+						</time-picker>
+					</view>
+					<uni-icons type="arrowthinright" color="#999" style="line-height: 40px;"></uni-icons>
+					<view class="popup-x-header--datetime">
+						<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endDate"
+							:placeholder="endDateText" />
+						<time-picker type="time" v-model="tempRange.endTime" :end="reactEndTime" :border="false"
+							:disabled="!tempRange.endDate" :hideSecond="hideSecond">
+							<input class="uni-date__input uni-date-range__input" type="text" v-model="tempRange.endTime"
+								:placeholder="endTimeText" :disabled="!tempRange.endDate" />
+						</time-picker>
+					</view>
+				</view>
+				<view class="popup-x-body">
+					<calendar ref="left" :showMonth="false"
+						:start-date="caleRange.startDate" :end-date="caleRange.endDate" :range="true"
+						@change="leftChange" :pleStatus="endMultipleStatus" @firstEnterCale="updateRightCale"
+						@monthSwitch="leftMonthSwitch" style="padding: 0 8px;" />
+					<calendar ref="right" :showMonth="false"
+						:start-date="caleRange.startDate" :end-date="caleRange.endDate" :range="true"
+						@change="rightChange" :pleStatus="startMultipleStatus" @firstEnterCale="updateLeftCale"
+						@monthSwitch="rightMonthSwitch" style="padding: 0 8px;border-left: 1px solid #F1F1F1;" />
+				</view>
+				<view v-if="hasTime" class="popup-x-footer">
+					<text class="" @click="clear">{{clearText}}</text>
+					<text class="confirm" @click="confirmRangeChange">{{okText}}</text>
+				</view>
+			</view>
+		</view>
+		<calendar v-show="isPhone" ref="mobile" :clearDate="false" :date="defSingleDate" :defTime="reactMobDefTime"
+			:start-date="caleRange.startDate" :end-date="caleRange.endDate" :selectableTimes="mobSelectableTime"
+			:pleStatus="endMultipleStatus" :showMonth="false" :range="isRange" :typeHasTime="hasTime" :insert="false"
+			:hideSecond="hideSecond" @confirm="mobileChange" />
+	</view>
+</template>
+<script>
+	/**
+	 * DatetimePicker 时间选择器
+	 * @description 同时支持 PC 和移动端使用日历选择日期和日期范围
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=3962
+	 * @property {String} type 选择器类型
+	 * @property {String|Number|Array|Date} value 绑定值
+	 * @property {String} placeholder 单选择时的占位内容
+	 * @property {String} start 起始时间
+	 * @property {String} end 终止时间
+	 * @property {String} start-placeholder 范围选择时开始日期的占位内容
+	 * @property {String} end-placeholder 范围选择时结束日期的占位内容
+	 * @property {String} range-separator 选择范围时的分隔符
+	 * @property {Boolean} border = [true|false] 是否有边框
+	 * @property {Boolean} disabled = [true|false] 是否禁用
+	 * @property {Boolean} clearIcon = [true|false] 是否显示清除按钮(仅PC端适用)
+	 * @event {Function} change 确定日期时触发的事件
+	 * @event {Function} show 打开弹出层
+	 * @event {Function} close 关闭弹出层
+	 * @event {Function} clear 清除上次选中的状态和值
+	 **/
+	import calendar from './calendar.vue'
+	import timePicker from './time-picker.vue'
+	import {
+		initVueI18n
+	} from '@dcloudio/uni-i18n'
+	import messages from './i18n/index.js'
+	const {
+		t
+	} = initVueI18n(messages)
+
+	export default {
+		name: 'UniDatetimePicker',
+		components: {
+			calendar,
+			timePicker
+		},
+		data() {
+			return {
+				isRange: false,
+				hasTime: false,
+				mobileRange: false,
+				// 单选
+				singleVal: '',
+				tempSingleDate: '',
+				defSingleDate: '',
+				time: '',
+				// 范围选
+				caleRange: {
+					startDate: '',
+					startTime: '',
+					endDate: '',
+					endTime: ''
+				},
+				range: {
+					startDate: '',
+					// startTime: '',
+					endDate: '',
+					// endTime: ''
+				},
+				tempRange: {
+					startDate: '',
+					startTime: '',
+					endDate: '',
+					endTime: ''
+				},
+				// 左右日历同步数据
+				startMultipleStatus: {
+					before: '',
+					after: '',
+					data: [],
+					fulldate: ''
+				},
+				endMultipleStatus: {
+					before: '',
+					after: '',
+					data: [],
+					fulldate: ''
+				},
+				visible: false,
+				popup: false,
+				popover: null,
+				isEmitValue: false,
+				isPhone: false,
+				isFirstShow: true,
+			}
+		},
+		props: {
+			type: {
+				type: String,
+				default: 'datetime'
+			},
+			value: {
+				type: [String, Number, Array, Date],
+				default: ''
+			},
+			modelValue: {
+				type: [String, Number, Array, Date],
+				default: ''
+			},
+			start: {
+				type: [Number, String],
+				default: ''
+			},
+			end: {
+				type: [Number, String],
+				default: ''
+			},
+			returnType: {
+				type: String,
+				default: 'string'
+			},
+			placeholder: {
+				type: String,
+				default: ''
+			},
+			startPlaceholder: {
+				type: String,
+				default: ''
+			},
+			endPlaceholder: {
+				type: String,
+				default: ''
+			},
+			rangeSeparator: {
+				type: String,
+				default: '-'
+			},
+			border: {
+				type: [Boolean],
+				default: true
+			},
+			disabled: {
+				type: [Boolean],
+				default: false
+			},
+			clearIcon: {
+				type: [Boolean],
+				default: true
+			},
+			hideSecond: {
+				type: [Boolean],
+				default: false
+			}
+		},
+		watch: {
+			type: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (newVal.indexOf('time') !== -1) {
+						this.hasTime = true
+					} else {
+						this.hasTime = false
+					}
+					if (newVal.indexOf('range') !== -1) {
+						this.isRange = true
+					} else {
+						this.isRange = false
+					}
+				}
+			},
+			value: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (this.isEmitValue) {
+						this.isEmitValue = false
+						return
+					}
+					this.initPicker(newVal)
+				}
+			},
+
+			start: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (!newVal) return
+					const {
+						defDate,
+						defTime
+					} = this.parseDate(newVal)
+					this.caleRange.startDate = defDate
+					if (this.hasTime) {
+						this.caleRange.startTime = defTime
+					}
+				}
+			},
+
+			end: {
+				immediate: true,
+				handler(newVal, oldVal) {
+					if (!newVal) return
+					const {
+						defDate,
+						defTime
+					} = this.parseDate(newVal)
+					this.caleRange.endDate = defDate
+					if (this.hasTime) {
+						this.caleRange.endTime = defTime
+					}
+				}
+			},
+		},
+		computed: {
+			reactStartTime() {
+				const activeDate = this.isRange ? this.tempRange.startDate : this.tempSingleDate
+				const res = activeDate === this.caleRange.startDate ? this.caleRange.startTime : ''
+				return res
+			},
+			reactEndTime() {
+				const activeDate = this.isRange ? this.tempRange.endDate : this.tempSingleDate
+				const res = activeDate === this.caleRange.endDate ? this.caleRange.endTime : ''
+				return res
+			},
+			reactMobDefTime() {
+				const times = {
+					start: this.tempRange.startTime,
+					end: this.tempRange.endTime
+				}
+				return this.isRange ? times : this.time
+			},
+			mobSelectableTime() {
+				return {
+					start: this.caleRange.startTime,
+					end: this.caleRange.endTime
+				}
+			},
+			datePopupWidth() {
+				// todo
+				return this.isRange ? 653 : 301
+			},
+
+			/**
+			 * for i18n
+			 */
+			singlePlaceholderText() {
+				return this.placeholder || (this.type === 'date' ? this.selectDateText : t(
+					"uni-datetime-picker.selectDateTime"))
+			},
+			startPlaceholderText() {
+				return this.startPlaceholder || this.startDateText
+			},
+			endPlaceholderText() {
+				return this.endPlaceholder || this.endDateText
+			},
+			selectDateText() {
+				return t("uni-datetime-picker.selectDate")
+			},
+			selectTimeText() {
+				return t("uni-datetime-picker.selectTime")
+			},
+			startDateText() {
+				return this.startPlaceholder || t("uni-datetime-picker.startDate")
+			},
+			startTimeText() {
+				return t("uni-datetime-picker.startTime")
+			},
+			endDateText() {
+				return this.endPlaceholder || t("uni-datetime-picker.endDate")
+			},
+			endTimeText() {
+				return t("uni-datetime-picker.endTime")
+			},
+			okText() {
+				return t("uni-datetime-picker.ok")
+			},
+			clearText() {
+				return t("uni-datetime-picker.clear")
+			},
+			showClearIcon() {
+				const { clearIcon, disabled, singleVal, range } = this
+				const bool = clearIcon && !disabled && (singleVal || (range.startDate && range.endDate))
+				return bool
+			}
+		},
+		created() {
+			this.form = this.getForm('uniForms')
+			this.formItem = this.getForm('uniFormsItem')
+
+			// if (this.formItem) {
+			// 	if (this.formItem.name) {
+			// 		this.rename = this.formItem.name
+			// 		this.form.inputChildrens.push(this)
+			// 	}
+			// }
+		},
+		mounted() {
+			this.platform()
+		},
+		methods: {
+			/**
+			 * 获取父元素实例
+			 */
+			getForm(name = 'uniForms') {
+				let parent = this.$parent;
+				let parentName = parent.$options.name;
+				while (parentName !== name) {
+					parent = parent.$parent;
+					if (!parent) return false
+					parentName = parent.$options.name;
+				}
+				return parent;
+			},
+			initPicker(newVal) {
+				if (!newVal || Array.isArray(newVal) && !newVal.length) {
+					this.$nextTick(() => {
+						this.clear(false)
+					})
+					return
+				}
+				if (!Array.isArray(newVal) && !this.isRange) {
+					const {
+						defDate,
+						defTime
+					} = this.parseDate(newVal)
+					this.singleVal = defDate
+					this.tempSingleDate = defDate
+					this.defSingleDate = defDate
+					if (this.hasTime) {
+						this.singleVal = defDate + ' ' + defTime
+						this.time = defTime
+					}
+				} else {
+					const [before, after] = newVal
+					if (!before && !after) return
+					const defBefore = this.parseDate(before)
+					const defAfter = this.parseDate(after)
+					const startDate = defBefore.defDate
+					const endDate = defAfter.defDate
+					this.range.startDate = this.tempRange.startDate = startDate
+					this.range.endDate = this.tempRange.endDate = endDate
+
+					if (this.hasTime) {
+						this.range.startDate = defBefore.defDate + ' ' + defBefore.defTime
+						this.range.endDate = defAfter.defDate + ' ' + defAfter.defTime
+						this.tempRange.startTime = defBefore.defTime
+						this.tempRange.endTime = defAfter.defTime
+					}
+					const defaultRange = {
+						before: defBefore.defDate,
+						after: defAfter.defDate
+					}
+					this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, defaultRange, {
+						which: 'right'
+					})
+					this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, defaultRange, {
+						which: 'left'
+					})
+				}
+			},
+			updateLeftCale(e) {
+				const left = this.$refs.left
+				// 设置范围选
+				left.cale.setHoverMultiple(e.after)
+				left.setDate(this.$refs.left.nowDate.fullDate)
+			},
+			updateRightCale(e) {
+				const right = this.$refs.right
+				// 设置范围选
+				right.cale.setHoverMultiple(e.after)
+				right.setDate(this.$refs.right.nowDate.fullDate)
+			},
+			platform() {
+				const systemInfo = uni.getSystemInfoSync()
+				this.isPhone = systemInfo.windowWidth <= 500
+				this.windowWidth = systemInfo.windowWidth
+			},
+			show(event) {
+				if (this.disabled) {
+					return
+				}
+				this.platform()
+				if (this.isPhone) {
+					this.$refs.mobile.open()
+					return
+				}
+				this.popover = {
+					top: '10px'
+				}
+				const dateEditor = uni.createSelectorQuery().in(this).select(".uni-date-editor")
+				dateEditor.boundingClientRect(rect => {
+					if (this.windowWidth - rect.left < this.datePopupWidth) {
+						this.popover.right = 0
+					}
+				}).exec()
+				setTimeout(() => {
+					this.popup = !this.popup
+					if (!this.isPhone && this.isRange && this.isFirstShow) {
+						this.isFirstShow = false
+						const {
+							startDate,
+							endDate
+						} = this.range
+						if (startDate && endDate) {
+							if (this.diffDate(startDate, endDate) < 30) {
+								this.$refs.right.next()
+							}
+						} else {
+							this.$refs.right.next()
+							this.$refs.right.cale.lastHover = false
+						}
+					}
+
+				}, 50)
+			},
+
+			close() {
+				setTimeout(() => {
+					this.popup = false
+					this.$emit('maskClick', this.value)
+				}, 20)
+			},
+			setEmit(value) {
+				if (this.returnType === "timestamp" || this.returnType === "date") {
+					if (!Array.isArray(value)) {
+						if (!this.hasTime) {
+							value = value + ' ' + '00:00:00'
+						}
+						value = this.createTimestamp(value)
+						if (this.returnType === "date") {
+							value = new Date(value)
+						}
+					} else {
+						if (!this.hasTime) {
+							value[0] = value[0] + ' ' + '00:00:00'
+							value[1] = value[1] + ' ' + '00:00:00'
+						}
+						value[0] = this.createTimestamp(value[0])
+						value[1] = this.createTimestamp(value[1])
+						if (this.returnType === "date") {
+							value[0] = new Date(value[0])
+							value[1] = new Date(value[1])
+						}
+					}
+				}
+				this.formItem && this.formItem.setValue(value)
+				this.$emit('change', value)
+				this.$emit('input', value)
+				this.$emit('update:modelValue', value)
+				this.isEmitValue = true
+			},
+			createTimestamp(date) {
+				date = this.fixIosDateFormat(date)
+				return Date.parse(new Date(date))
+			},
+			singleChange(e) {
+				this.tempSingleDate = e.fulldate
+				if (this.hasTime) return
+				this.confirmSingleChange()
+			},
+
+			confirmSingleChange() {
+				if (!this.tempSingleDate) {
+					this.popup = false
+					return
+				}
+				if (this.hasTime) {
+					this.singleVal = this.tempSingleDate + ' ' + (this.time ? this.time : '00:00:00')
+				} else {
+					this.singleVal = this.tempSingleDate
+				}
+				this.setEmit(this.singleVal)
+				this.popup = false
+			},
+
+			leftChange(e) {
+				const {
+					before,
+					after
+				} = e.range
+				this.rangeChange(before, after)
+				const obj = {
+					before: e.range.before,
+					after: e.range.after,
+					data: e.range.data,
+					fulldate: e.fulldate
+				}
+				this.startMultipleStatus = Object.assign({}, this.startMultipleStatus, obj)
+			},
+
+			rightChange(e) {
+				const {
+					before,
+					after
+				} = e.range
+				this.rangeChange(before, after)
+				const obj = {
+					before: e.range.before,
+					after: e.range.after,
+					data: e.range.data,
+					fulldate: e.fulldate
+				}
+				this.endMultipleStatus = Object.assign({}, this.endMultipleStatus, obj)
+			},
+
+			mobileChange(e) {
+				if (this.isRange) {
+					const {
+						before,
+						after
+					} = e.range
+					this.handleStartAndEnd(before, after, true)
+					if (this.hasTime) {
+						const {
+							startTime,
+							endTime
+						} = e.timeRange
+						this.tempRange.startTime = startTime
+						this.tempRange.endTime = endTime
+					}
+					this.confirmRangeChange()
+
+				} else {
+					if (this.hasTime) {
+						this.singleVal = e.fulldate + ' ' + e.time
+					} else {
+						this.singleVal = e.fulldate
+					}
+					this.setEmit(this.singleVal)
+				}
+				this.$refs.mobile.close()
+			},
+
+			rangeChange(before, after) {
+				if (!(before && after)) return
+				this.handleStartAndEnd(before, after, true)
+				if (this.hasTime) return
+				this.confirmRangeChange()
+			},
+
+			confirmRangeChange() {
+				if (!this.tempRange.startDate && !this.tempRange.endDate) {
+					this.popup = false
+					return
+				}
+				let start, end
+				if (!this.hasTime) {
+					start = this.range.startDate = this.tempRange.startDate
+					end = this.range.endDate = this.tempRange.endDate
+				} else {
+					start = this.range.startDate = this.tempRange.startDate + ' ' +
+						(this.tempRange.startTime ? this.tempRange.startTime : '00:00:00')
+					end = this.range.endDate = this.tempRange.endDate + ' ' +
+						(this.tempRange.endTime ? this.tempRange.endTime : '00:00:00')
+				}
+				const displayRange = [start, end]
+				this.setEmit(displayRange)
+				this.popup = false
+			},
+
+			handleStartAndEnd(before, after, temp = false) {
+				if (!(before && after)) return
+				const type = temp ? 'tempRange' : 'range'
+				if (this.dateCompare(before, after)) {
+					this[type].startDate = before
+					this[type].endDate = after
+				} else {
+					this[type].startDate = after
+					this[type].endDate = before
+				}
+			},
+
+			/**
+			 * 比较时间大小
+			 */
+			dateCompare(startDate, endDate) {
+				// 计算截止时间
+				startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+				// 计算详细项的截止时间
+				endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+				if (startDate <= endDate) {
+					return true
+				} else {
+					return false
+				}
+			},
+
+			/**
+			 * 比较时间差
+			 */
+			diffDate(startDate, endDate) {
+				// 计算截止时间
+				startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+				// 计算详细项的截止时间
+				endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+				const diff = (endDate - startDate) / (24 * 60 * 60 * 1000)
+				return Math.abs(diff)
+			},
+
+			clear(needEmit = true) {
+				if (!this.isRange) {
+					this.singleVal = ''
+					this.tempSingleDate = ''
+					this.time = ''
+					if (this.isPhone) {
+						this.$refs.mobile && this.$refs.mobile.clearCalender()
+					} else {
+						this.$refs.pcSingle && this.$refs.pcSingle.clearCalender()
+					}
+					if (needEmit) {
+						this.formItem && this.formItem.setValue('')
+						this.$emit('change', '')
+						this.$emit('input', '')
+						this.$emit('update:modelValue', '')
+					}
+				} else {
+					this.range.startDate = ''
+					this.range.endDate = ''
+					this.tempRange.startDate = ''
+					this.tempRange.startTime = ''
+					this.tempRange.endDate = ''
+					this.tempRange.endTime = ''
+					if (this.isPhone) {
+						this.$refs.mobile && this.$refs.mobile.clearCalender()
+					} else {
+						this.$refs.left && this.$refs.left.clearCalender()
+						this.$refs.right && this.$refs.right.clearCalender()
+						this.$refs.right && this.$refs.right.next()
+					}
+					if (needEmit) {
+						this.formItem && this.formItem.setValue([])
+						this.$emit('change', [])
+						this.$emit('input', [])
+						this.$emit('update:modelValue', [])
+					}
+				}
+			},
+
+			parseDate(date) {
+				date = this.fixIosDateFormat(date)
+				const defVal = new Date(date)
+				const year = defVal.getFullYear()
+				const month = defVal.getMonth() + 1
+				const day = defVal.getDate()
+				const hour = defVal.getHours()
+				const minute = defVal.getMinutes()
+				const second = defVal.getSeconds()
+				const defDate = year + '-' + this.lessTen(month) + '-' + this.lessTen(day)
+				const defTime = this.lessTen(hour) + ':' + this.lessTen(minute) + (this.hideSecond ? '' : (':' + this
+					.lessTen(second)))
+				return {
+					defDate,
+					defTime
+				}
+			},
+
+			lessTen(item) {
+				return item < 10 ? '0' + item : item
+			},
+
+			//兼容 iOS、safari 日期格式
+			fixIosDateFormat(value) {
+				if (typeof value === 'string') {
+					value = value.replace(/-/g, '/')
+				}
+				return value
+			},
+
+			leftMonthSwitch(e) {
+				// console.log('leftMonthSwitch 返回:', e)
+			},
+			rightMonthSwitch(e) {
+				// console.log('rightMonthSwitch 返回:', e)
+			}
+		}
+	}
+</script>
+
+<style>
+	.uni-date-x {
+		display: flex;
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		padding: 0 10px;
+		border-radius: 4px;
+		background-color: #fff;
+		color: #666;
+		font-size: 14px;
+	}
+
+	.uni-date-x--border {
+		box-sizing: border-box;
+		border-radius: 4px;
+		border: 1px solid #dcdfe6;
+	}
+
+	.uni-date-editor--x {
+		position: relative;
+	}
+
+	.uni-date-editor--x .uni-date__icon-clear {
+		position: absolute;
+		top: 0;
+		right: 0;
+		display: inline-block;
+		box-sizing: border-box;
+		border: 9px solid transparent;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-date__x-input {
+		padding: 0 8px;
+		height: 40px;
+		width: 100%;
+		line-height: 40px;
+		font-size: 14px;
+	}
+
+	.t-c {
+		text-align: center;
+	}
+
+	.uni-date__input {
+		height: 40px;
+		width: 100%;
+		line-height: 40px;
+		font-size: 14px;
+	}
+
+	.uni-date-range__input {
+		text-align: center;
+		max-width: 142px;
+	}
+
+	.uni-date-picker__container {
+		position: relative;
+		/* 		position: fixed;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		box-sizing: border-box;
+		z-index: 996;
+		font-size: 14px; */
+	}
+
+	.uni-date-mask {
+		position: fixed;
+		bottom: 0px;
+		top: 0px;
+		left: 0px;
+		right: 0px;
+		background-color: rgba(0, 0, 0, 0);
+		transition-duration: 0.3s;
+		z-index: 996;
+	}
+
+	.uni-date-single--x {
+		/* padding: 0 8px; */
+		background-color: #fff;
+		position: absolute;
+		top: 0;
+		z-index: 999;
+		border: 1px solid #EBEEF5;
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+		border-radius: 4px;
+	}
+
+	.uni-date-range--x {
+		/* padding: 0 8px; */
+		background-color: #fff;
+		position: absolute;
+		top: 0;
+		z-index: 999;
+		border: 1px solid #EBEEF5;
+		box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+		border-radius: 4px;
+	}
+
+	.uni-date-editor--x__disabled {
+		opacity: 0.4;
+		cursor: default;
+	}
+
+	.uni-date-editor--logo {
+		width: 16px;
+		height: 16px;
+		vertical-align: middle;
+	}
+
+	/* 添加时间 */
+	.popup-x-header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		/* justify-content: space-between; */
+	}
+
+	.popup-x-header--datetime {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		flex: 1;
+	}
+
+	.popup-x-body {
+		display: flex;
+	}
+
+	.popup-x-footer {
+		padding: 0 15px;
+		border-top-color: #F1F1F1;
+		border-top-style: solid;
+		border-top-width: 1px;
+		/* background-color: #fff; */
+		line-height: 40px;
+		text-align: right;
+		color: #666;
+	}
+
+	.popup-x-footer text:hover {
+		color: #007aff;
+		cursor: pointer;
+		opacity: 0.8;
+	}
+
+	.popup-x-footer .confirm {
+		margin-left: 20px;
+		color: #007aff;
+	}
+
+	.uni-date-changed {
+		/* background-color: #fff; */
+		text-align: center;
+		color: #333;
+		border-bottom-color: #F1F1F1;
+		border-bottom-style: solid;
+		border-bottom-width: 1px;
+		/* padding: 0 50px; */
+	}
+
+	.uni-date-changed--time text {
+		/* padding: 0 20px; */
+		height: 50px;
+		line-height: 50px;
+	}
+
+	.uni-date-changed .uni-date-changed--time {
+		/* display: flex; */
+		flex: 1;
+	}
+
+	.uni-date-changed--time-date {
+		color: #333;
+		opacity: 0.6;
+	}
+
+	.mr-50 {
+		margin-right: 50px;
+	}
+
+	/* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
+	.uni-popper__arrow,
+	.uni-popper__arrow::after {
+		position: absolute;
+		display: block;
+		width: 0;
+		height: 0;
+		border-color: transparent;
+		border-style: solid;
+		border-width: 6px;
+	}
+
+	.uni-popper__arrow {
+		filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
+		top: -6px;
+		left: 10%;
+		margin-right: 3px;
+		border-top-width: 0;
+		border-bottom-color: #EBEEF5;
+	}
+
+	.uni-popper__arrow::after {
+		content: " ";
+		top: 1px;
+		margin-left: -6px;
+		border-top-width: 0;
+		border-bottom-color: #fff;
+	}
+</style>

+ 410 - 0
uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js

@@ -0,0 +1,410 @@
+class Calendar {
+	constructor({
+		date,
+		selected,
+		startDate,
+		endDate,
+		range,
+		// multipleStatus
+	} = {}) {
+		// 当前日期
+		this.date = this.getDate(new Date()) // 当前初入日期
+		// 打点信息
+		this.selected = selected || [];
+		// 范围开始
+		this.startDate = startDate
+		// 范围结束
+		this.endDate = endDate
+		this.range = range
+		// 多选状态
+		this.cleanMultipleStatus()
+		// 每周日期
+		this.weeks = {}
+		// this._getWeek(this.date.fullDate)
+		// this.multipleStatus = multipleStatus
+		this.lastHover = false
+	}
+	/**
+	 * 设置日期
+	 * @param {Object} date
+	 */
+	setDate(date) {
+		this.selectDate = this.getDate(date)
+		this._getWeek(this.selectDate.fullDate)
+	}
+
+	/**
+	 * 清理多选状态
+	 */
+	cleanMultipleStatus() {
+		this.multipleStatus = {
+			before: '',
+			after: '',
+			data: []
+		}
+	}
+
+	/**
+	 * 重置开始日期
+	 */
+	resetSatrtDate(startDate) {
+		// 范围开始
+		this.startDate = startDate
+
+	}
+
+	/**
+	 * 重置结束日期
+	 */
+	resetEndDate(endDate) {
+		// 范围结束
+		this.endDate = endDate
+	}
+
+	/**
+	 * 获取任意时间
+	 */
+	getDate(date, AddDayCount = 0, str = 'day') {
+		if (!date) {
+			date = new Date()
+		}
+		if (typeof date !== 'object') {
+			date = date.replace(/-/g, '/')
+		}
+		const dd = new Date(date)
+		switch (str) {
+			case 'day':
+				dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
+				break
+			case 'month':
+				if (dd.getDate() === 31) {
+					dd.setDate(dd.getDate() + AddDayCount)
+				} else {
+					dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
+				}
+				break
+			case 'year':
+				dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
+				break
+		}
+		const y = dd.getFullYear()
+		const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
+		const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
+		return {
+			fullDate: y + '-' + m + '-' + d,
+			year: y,
+			month: m,
+			date: d,
+			day: dd.getDay()
+		}
+	}
+
+
+	/**
+	 * 获取上月剩余天数
+	 */
+	_getLastMonthDays(firstDay, full) {
+		let dateArr = []
+		for (let i = firstDay; i > 0; i--) {
+			const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
+			dateArr.push({
+				date: beforeDate,
+				month: full.month - 1,
+				disable: true
+			})
+		}
+		return dateArr
+	}
+	/**
+	 * 获取本月天数
+	 */
+	_currentMonthDys(dateData, full) {
+		let dateArr = []
+		let fullDate = this.date.fullDate
+		for (let i = 1; i <= dateData; i++) {
+			let isinfo = false
+			let nowDate = full.year + '-' + (full.month < 10 ?
+				full.month : full.month) + '-' + (i < 10 ?
+				'0' + i : i)
+			// 是否今天
+			let isDay = fullDate === nowDate
+			// 获取打点信息
+			let info = this.selected && this.selected.find((item) => {
+				if (this.dateEqual(nowDate, item.date)) {
+					return item
+				}
+			})
+
+			// 日期禁用
+			let disableBefore = true
+			let disableAfter = true
+			if (this.startDate) {
+				// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
+				// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
+				disableBefore = this.dateCompare(this.startDate, nowDate)
+			}
+
+			if (this.endDate) {
+				// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
+				// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
+				disableAfter = this.dateCompare(nowDate, this.endDate)
+			}
+			let multiples = this.multipleStatus.data
+			let checked = false
+			let multiplesStatus = -1
+			if (this.range) {
+				if (multiples) {
+					multiplesStatus = multiples.findIndex((item) => {
+						return this.dateEqual(item, nowDate)
+					})
+				}
+				if (multiplesStatus !== -1) {
+					checked = true
+				}
+			}
+			let data = {
+				fullDate: nowDate,
+				year: full.year,
+				date: i,
+				multiple: this.range ? checked : false,
+				beforeMultiple: this.isLogicBefore(nowDate, this.multipleStatus.before, this.multipleStatus.after),
+				afterMultiple: this.isLogicAfter(nowDate, this.multipleStatus.before, this.multipleStatus.after),
+				month: full.month,
+				disable: !(disableBefore && disableAfter),
+				isDay,
+				userChecked: false
+			}
+			if (info) {
+				data.extraInfo = info
+			}
+
+			dateArr.push(data)
+		}
+		return dateArr
+	}
+	/**
+	 * 获取下月天数
+	 */
+	_getNextMonthDays(surplus, full) {
+		let dateArr = []
+		for (let i = 1; i < surplus + 1; i++) {
+			dateArr.push({
+				date: i,
+				month: Number(full.month) + 1,
+				disable: true
+			})
+		}
+		return dateArr
+	}
+
+	/**
+	 * 获取当前日期详情
+	 * @param {Object} date
+	 */
+	getInfo(date) {
+		if (!date) {
+			date = new Date()
+		}
+		const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
+		return dateInfo
+	}
+
+	/**
+	 * 比较时间大小
+	 */
+	dateCompare(startDate, endDate) {
+		// 计算截止时间
+		startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
+		// 计算详细项的截止时间
+		endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
+		if (startDate <= endDate) {
+			return true
+		} else {
+			return false
+		}
+	}
+
+	/**
+	 * 比较时间是否相等
+	 */
+	dateEqual(before, after) {
+		// 计算截止时间
+		before = new Date(before.replace('-', '/').replace('-', '/'))
+		// 计算详细项的截止时间
+		after = new Date(after.replace('-', '/').replace('-', '/'))
+		if (before.getTime() - after.getTime() === 0) {
+			return true
+		} else {
+			return false
+		}
+	}
+
+	/**
+	 *  比较真实起始日期
+	 */
+
+	isLogicBefore(currentDay, before, after) {
+		let logicBefore = before
+		if (before && after) {
+			logicBefore = this.dateCompare(before, after) ? before : after
+		}
+		return this.dateEqual(logicBefore, currentDay)
+	}
+
+	isLogicAfter(currentDay, before, after) {
+		let logicAfter = after
+		if (before && after) {
+			logicAfter = this.dateCompare(before, after) ? after : before
+		}
+		return this.dateEqual(logicAfter, currentDay)
+	}
+
+	/**
+	 * 获取日期范围内所有日期
+	 * @param {Object} begin
+	 * @param {Object} end
+	 */
+	geDateAll(begin, end) {
+		var arr = []
+		var ab = begin.split('-')
+		var ae = end.split('-')
+		var db = new Date()
+		db.setFullYear(ab[0], ab[1] - 1, ab[2])
+		var de = new Date()
+		de.setFullYear(ae[0], ae[1] - 1, ae[2])
+		var unixDb = db.getTime() - 24 * 60 * 60 * 1000
+		var unixDe = de.getTime() - 24 * 60 * 60 * 1000
+		for (var k = unixDb; k <= unixDe;) {
+			k = k + 24 * 60 * 60 * 1000
+			arr.push(this.getDate(new Date(parseInt(k))).fullDate)
+		}
+		return arr
+	}
+
+	/**
+	 *  获取多选状态
+	 */
+	setMultiple(fullDate) {
+		let {
+			before,
+			after
+		} = this.multipleStatus
+		if (!this.range) return
+		if (before && after) {
+			if (!this.lastHover) {
+				this.lastHover = true
+				return
+			}
+			this.multipleStatus.before = fullDate
+			this.multipleStatus.after = ''
+			this.multipleStatus.data = []
+			this.multipleStatus.fulldate = ''
+			this.lastHover = false
+		} else {
+			if (!before) {
+				this.multipleStatus.before = fullDate
+				this.lastHover = false
+			} else {
+				this.multipleStatus.after = fullDate
+				if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
+						.after);
+				} else {
+					this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
+						.before);
+				}
+				this.lastHover = true
+			}
+		}
+		this._getWeek(fullDate)
+	}
+
+	/**
+	 *  鼠标 hover 更新多选状态
+	 */
+	setHoverMultiple(fullDate) {
+		let {
+			before,
+			after
+		} = this.multipleStatus
+
+		if (!this.range) return
+		if (this.lastHover) return
+
+		if (!before) {
+			this.multipleStatus.before = fullDate
+		} else {
+			this.multipleStatus.after = fullDate
+			if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
+				this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
+			} else {
+				this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
+			}
+		}
+		this._getWeek(fullDate)
+	}
+
+	/**
+	 * 更新默认值多选状态
+	 */
+	setDefaultMultiple(before, after) {
+		this.multipleStatus.before = before
+		this.multipleStatus.after = after
+		if (before && after) {
+			if (this.dateCompare(before, after)) {
+				this.multipleStatus.data = this.geDateAll(before, after);
+				this._getWeek(after)
+			} else {
+				this.multipleStatus.data = this.geDateAll(after, before);
+				this._getWeek(before)
+			}
+		}
+	}
+
+	/**
+	 * 获取每周数据
+	 * @param {Object} dateData
+	 */
+	_getWeek(dateData) {
+		const {
+			fullDate,
+			year,
+			month,
+			date,
+			day
+		} = this.getDate(dateData)
+		let firstDay = new Date(year, month - 1, 1).getDay()
+		let currentDay = new Date(year, month, 0).getDate()
+		let dates = {
+			lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
+			currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
+			nextMonthDays: [], // 下个月开始几天
+			weeks: []
+		}
+		let canlender = []
+		const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
+		dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
+		canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
+		let weeks = {}
+		// 拼接数组  上个月开始几天 + 本月天数+ 下个月开始几天
+		for (let i = 0; i < canlender.length; i++) {
+			if (i % 7 === 0) {
+				weeks[parseInt(i / 7)] = new Array(7)
+			}
+			weeks[parseInt(i / 7)][i % 7] = canlender[i]
+		}
+		this.canlender = canlender
+		this.weeks = weeks
+	}
+
+	//静态方法
+	// static init(date) {
+	// 	if (!this.instance) {
+	// 		this.instance = new Calendar(date);
+	// 	}
+	// 	return this.instance;
+	// }
+}
+
+
+export default Calendar

+ 90 - 0
uni_modules/uni-datetime-picker/package.json

@@ -0,0 +1,90 @@
+{
+  "id": "uni-datetime-picker",
+  "displayName": "uni-datetime-picker 日期选择器",
+  "version": "2.2.2",
+  "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
+  "keywords": [
+    "uni-datetime-picker",
+    "uni-ui",
+    "uniui",
+    "日期时间选择器",
+    "日期时间"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "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"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 21 - 0
uni_modules/uni-datetime-picker/readme.md

@@ -0,0 +1,21 @@
+
+
+> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护`
+
+## DatetimePicker 时间选择器
+
+> **组件名:uni-datetime-picker**
+> 代码块: `uDatetimePicker`
+
+
+该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。
+
+若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。
+
+**_点击 picker 默认值规则:_**
+
+- 若设置初始值 value, 会显示在 picker 显示框中
+- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
unpackage/dist/build/app-plus/app-config-service.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
unpackage/dist/build/app-plus/app-service.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
unpackage/dist/build/app-plus/app-view.js


BIN
unpackage/dist/build/app-plus/components/t-m-icon/icon/wodegongdan.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/bangong.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/bangong.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/bumen.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/bumen.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/jiagou.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/jiagou.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/qingjia.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/qingjia.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/qita.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/qita.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/title_icon.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/title_icon.png


unpackage/dist/build/app-plus/components/t-o-zaoquan/icon/yongyin.png → unpackage/dist/build/app-plus/components/t-o-communication/icon/yongyin.png


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
unpackage/dist/build/app-plus/manifest.json


BIN
unpackage/dist/build/app-plus/pages/my/personal_information/icon/top.png


unpackage/dist/build/app-plus/pages/origanization/zaoquan/origanization/icon/close.png → unpackage/dist/build/app-plus/pages/origanization/communication/origanization/icon/close.png


unpackage/dist/build/app-plus/pages/origanization/zaoquan/origanization/icon/open.png → unpackage/dist/build/app-plus/pages/origanization/communication/origanization/icon/open.png


unpackage/dist/build/app-plus/pages/origanization/zaoquan/origanization/icon/title_icon.png → unpackage/dist/build/app-plus/pages/origanization/communication/origanization/icon/title_icon.png


unpackage/dist/build/app-plus/pages/origanization/zaoquan/origanization/my_department/icon/title_icon.png → unpackage/dist/build/app-plus/pages/origanization/communication/origanization/my_department/icon/title_icon.png


unpackage/dist/build/app-plus/pages/origanization/zaoquan/origanization/search/icon/title_icon.png → unpackage/dist/build/app-plus/pages/origanization/communication/origanization/search/icon/title_icon.png


BIN
unpackage/dist/build/app-plus/pages/production/zaoquan/zidonghua_list/img/icon.png


BIN
unpackage/dist/build/app-plus/pages/production/zaoquan/zidonghua_list/img/psxt.jpg


+ 0 - 0
unpackage/dist/build/app-plus/pages/production/zaoquan/zidonghua_list/img/tfgl.jpg


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác