Przeglądaj źródła

更新枣泉版本

tiandewen 3 lat temu
rodzic
commit
3ae201d36c
100 zmienionych plików z 44217 dodań i 23640 usunięć
  1. 2 1
      App.vue
  2. 0 3
      README.md
  3. 8 0
      common/js-base64.js
  4. 2 1
      common/vmeitime-http/interface.js
  5. 88 0
      components/e-browse/e-browse.vue
  6. 60 0
      components/e-equipment/e-equipment.vue
  7. 91 0
      components/e-file/e-file.vue
  8. 47 0
      components/e-image-text/e-image-text.vue
  9. 282 0
      components/e-link/e-link.vue
  10. 121 0
      components/e-picture/e-picture.vue
  11. 113 0
      components/e-record/e-record.vue
  12. 38 0
      components/e-text/e-text.vue
  13. 64 0
      components/e-video/e-video.vue
  14. 3 17
      components/t-i-banner/t-i-banner.vue
  15. 31 17
      components/t-i-icon/t-i-icon.vue
  16. BIN
      components/t-i-navbar/icon/zaoquan.png
  17. 19 4
      components/t-i-navbar/t-i-navbar.vue
  18. 11 24
      components/t-i-news/t-i-news.vue
  19. 3 21
      components/t-i-notice/t-i-notice.vue
  20. BIN
      components/t-m-icon/icon/fuwudianhua.png
  21. BIN
      components/t-m-icon/icon/gengxin.png
  22. BIN
      components/t-m-icon/icon/gongdanshenhe.png
  23. BIN
      components/t-m-icon/icon/jianyifankui.png
  24. BIN
      components/t-m-icon/icon/qingchu.png
  25. BIN
      components/t-m-icon/icon/shiyongshouce.png
  26. BIN
      components/t-m-icon/icon/xiaoxi.png
  27. BIN
      components/t-m-icon/icon/xiugaimima.png
  28. 62 14
      components/t-m-icon/t-m-icon.vue
  29. 31 20
      components/t-m-info/t-m-info.vue
  30. 5 22
      components/t-m-list/t-m-list.vue
  31. 202 0
      components/t-p-zaoquan/t-p-zaoquan.vue
  32. 126 73
      manifest.json
  33. 97 51
      pages.json
  34. 177 5
      pages/index/news/news.vue
  35. 6 2
      pages/index/news/news_list/news_list.vue
  36. 26 0
      pages/index/record/record-video/record-video.vue
  37. 402 0
      pages/index/record/record.vue
  38. 27 0
      pages/index/switch-kuang/switch-kuang.vue
  39. 346 0
      pages/my/forget-password/forget-password.vue
  40. BIN
      pages/my/forget-password/icon/Avatar.png
  41. BIN
      pages/my/forget-password/icon/Password.png
  42. 13 9
      pages/my/login/login.vue
  43. 147 0
      pages/my/message-reminder/message-detail/message-detail.vue
  44. 217 0
      pages/my/message-reminder/message-reminder.vue
  45. 125 8
      pages/tabbar/index/index.vue
  46. 3 0
      pages/tabbar/my/my.vue
  47. 4 0
      pages/tabbar/production/production.vue
  48. BIN
      static/qidongtu.png
  49. 160 0
      uni_modules/mp-html/README.md
  50. 62 0
      uni_modules/mp-html/changelog.md
  51. 432 0
      uni_modules/mp-html/components/mp-html/mp-html.vue
  52. 524 0
      uni_modules/mp-html/components/mp-html/node/node.vue
  53. 1223 0
      uni_modules/mp-html/components/mp-html/parser.js
  54. 79 0
      uni_modules/mp-html/package.json
  55. 1 0
      uni_modules/mp-html/static/app-plus/mp-html/js/handler.js
  56. 1 0
      uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js
  57. 1 0
      uni_modules/mp-html/static/app-plus/mp-html/local.html
  58. 4 0
      uni_modules/uni-config-center/changelog.md
  59. 80 0
      uni_modules/uni-config-center/package.json
  60. 93 0
      uni_modules/uni-config-center/readme.md
  61. 1 0
      uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js
  62. 9 0
      uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json
  63. 62 0
      uni_modules/uni-id/changelog.md
  64. 84 0
      uni_modules/uni-id/package.json
  65. 33 0
      uni_modules/uni-id/readme.md
  66. 201 0
      uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md
  67. 1 0
      uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
  68. 16 0
      uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
  69. 51 0
      uni_modules/uni-upgrade-center-app/changelog.md
  70. 84 0
      uni_modules/uni-upgrade-center-app/package.json
  71. 500 0
      uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue
  72. 18 0
      uni_modules/uni-upgrade-center-app/pages_init.json
  73. 119 0
      uni_modules/uni-upgrade-center-app/readme.md
  74. BIN
      uni_modules/uni-upgrade-center-app/static/app_update_close.png
  75. BIN
      uni_modules/uni-upgrade-center-app/static/bg_top.png
  76. 9 0
      uni_modules/uni-upgrade-center-app/uniCloud/cloudfunctions/check-version/check-version.param.json
  77. 167 0
      uni_modules/uni-upgrade-center-app/uniCloud/cloudfunctions/check-version/index.js
  78. 29 0
      uni_modules/uni-upgrade-center-app/utils/call-check-version.js
  79. 155 0
      uni_modules/uni-upgrade-center-app/utils/check-update.js
  80. 2 2
      unpackage/dist/dev/app-plus/app-config-service.js
  81. 13658 6342
      unpackage/dist/dev/app-plus/app-service.js
  82. 23356 17003
      unpackage/dist/dev/app-plus/app-view.js
  83. BIN
      unpackage/dist/dev/app-plus/components/t-i-icon/icon/gaikuang.png
  84. BIN
      unpackage/dist/dev/app-plus/components/t-i-navbar/icon/zaoquan.png
  85. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/fuwudianhua.png
  86. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/gengxin.png
  87. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/gongdanshenhe.png
  88. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/icon_11.png
  89. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/icon_4.png
  90. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/icon_9.png
  91. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/jianyifankui.png
  92. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/qingchu.png
  93. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/shiyongshouce.png
  94. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/xiaoxi.png
  95. BIN
      unpackage/dist/dev/app-plus/components/t-m-icon/icon/xiugaimima.png
  96. BIN
      unpackage/dist/dev/app-plus/components/t-m-list/icon/list_1.png
  97. 1 1
      unpackage/dist/dev/app-plus/manifest.json
  98. 1 0
      unpackage/dist/dev/app-plus/uni_modules/mp-html/static/app-plus/mp-html/js/handler.js
  99. 1 0
      unpackage/dist/dev/app-plus/uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js
  100. 0 0
      unpackage/dist/dev/app-plus/uni_modules/mp-html/static/app-plus/mp-html/local.html

+ 2 - 1
App.vue

@@ -5,9 +5,10 @@
 			// 启动初始化
 
 			// 煤矿鉴别-名称
-			uni.setStorageSync('mine_code', 'ningdongyunying');
+			// uni.setStorageSync('mine_code', 'ningdongyunying');
 			// uni.setStorageSync('mine_code', 'shicaocun');
 			// uni.setStorageSync('mine_code', 'meihuajing');
+			uni.setStorageSync('mine_code', 'zaoquan');
 
 		},
 		onShow: function() {

+ 0 - 3
README.md

@@ -1,3 +0,0 @@
-# uni-zhihuikuangshan
-
-全矿代码。

Plik diff jest za duży
+ 8 - 0
common/js-base64.js


+ 2 - 1
common/vmeitime-http/interface.js

@@ -34,7 +34,8 @@ http.delete('user/1').then((res)=>{
 export default {
 	config: {
 		// baseUrl: "http://colliery.nxjiewei.com/api",
-		baseUrl: "http://ningdongyunying.nxjiewei.com:8011/api",
+		// baseUrl: "http://ningdongyunying.nxjiewei.com:8011/api",
+		baseUrl: "http://zaoquan.nxjiewei.com:8011/api",
 		header: {
 			"Content-Type":"multipart/form-data",
 			'Content-Type':'application/json;charset=UTF-8',

+ 88 - 0
components/e-browse/e-browse.vue

@@ -0,0 +1,88 @@
+<template>
+	<view class="browse">
+		<view class="title">浏览记录</view>
+		<view class="list">
+			<view class="item" v-for="(item,index) in browse" :key="index">
+				<view class="img">
+					<view v-if="item.img == '' || item.img == 'none'">
+						<image :src="item.img" mode=""></image>
+					</view>
+					<view v-else>
+						<view class="img_tip" :style="{backgroundColor:bgColor[index]}">
+							{{item.name.split('').pop()}}
+						</view>
+					</view>
+				</view>
+				<view class="name">{{item.name}}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[
+			"browse",
+			"bgColor"
+		],
+		
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss">
+	.browse{
+		margin-top: 20px;
+		margin-bottom: 40px;
+		.title {
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+		.list{
+			overflow: hidden;
+			.item{
+				float: left;
+				width: 140rpx;
+				text-align: center;
+				margin-bottom: 10px;
+				.img{
+					margin: 0 auto;
+					margin-bottom: 5px;
+					width: 120rpx;
+					height: 120rpx;
+					border-radius: 50%;
+					overflow: hidden;
+					
+					image{
+						width: 120rpx;
+						height: 120rpx;
+					}
+					
+					.img_tip{
+						width: 120rpx;
+						height: 120rpx;
+						// background-color: skyblue;
+						
+						text-align: center;
+						line-height: 120rpx;
+						color: #FFFFFF;
+					}
+				}
+				.name{
+					width: 140rpx;
+					
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
+			}
+		}
+	}
+</style>

+ 60 - 0
components/e-equipment/e-equipment.vue

@@ -0,0 +1,60 @@
+<template>
+	<view>
+		<view class="equipmentList">
+			<view class="title">{{equipmentList[0].title}}</view>
+			<view class="list">
+				<view class="item" v-for="item in equipmentList" :key="item.id">
+					<view class="name">{{item.paramName}}</view>
+					<view class="inner">{{item.paramContent}}</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[
+			"equipmentList"
+		],
+		data() {
+			return {
+				
+			};
+		},
+		methods:{
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.equipmentList{
+		.title{
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+		.list{
+			.item{
+				padding: 20rpx 25rpx;
+				border-bottom: 1rpx solid #f4f4f4;
+				
+				display: flex;
+				justify-content: space-between;
+				
+				.name{
+					white-space: nowrap;
+					overflow: hidden; 
+					text-overflow:ellipsis;
+
+				}
+				.inner{
+					color: #999;
+				}
+			}
+		}
+	}
+</style>

+ 91 - 0
components/e-file/e-file.vue

@@ -0,0 +1,91 @@
+<template>
+	<view>
+		<view class="fileList">
+			<view class="title" v-if="fileList[0].title">{{fileList[0].title}}</view>
+			<view class="list">
+				<view class="item" v-for="item in fileList" :key="item.id" @click="detail(item.filePath,item.fileName)">
+					<view class="icon">
+						<uni-icons type="paperplane" size="30" color="#009FE8"></uni-icons>
+					</view>
+					<view>
+						<view class="name">{{item.fileName}}</view>
+						<view class="size">{{item.fileSize}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: [
+			"fileList"
+		],
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			detail(filePath,name) {
+				uni.downloadFile({
+					url: filePath,
+					success: function(res) {
+						var filePath = res.tempFilePath;
+						uni.openDocument({
+							filePath: filePath,
+							success: function(res) {
+								console.log('打开文档成功');
+							}
+						});
+					}
+				});
+				// #ifndef APP-PLUS
+				uni.navigateTo({
+					// url:"../../pages/file/file?path=" + filePath + "&name=" + name,
+					url:"../../pages/record/record_link/record_link?name=" + name + "&url=" + filePath
+				})
+				// #endif
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.fileList {
+		.title {
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+
+		.list {
+			.item {
+				padding: 20rpx 25rpx;
+				border-bottom: 1px solid #f4f4f4;
+
+				display: flex;
+				align-items: center;
+
+				.icon {
+					padding-right: 20px;
+				}
+
+				.name {
+					width: 540rpx;
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
+
+				.size {
+					font-size: 14px;
+					color: #999;
+				}
+			}
+		}
+	}
+</style>

+ 47 - 0
components/e-image-text/e-image-text.vue

@@ -0,0 +1,47 @@
+<template>
+	<view>
+		<view class="imageText">
+			<view class="title">{{imageText.title}}</view>
+			<view class="img" v-if="imageText.imageUrl">
+				<image :src="imageText.imageUrl" mode="widthFix"></image>
+			</view>
+			<view class="content">
+				<view v-html="imageText.dataContent"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[
+			"imageText"
+		],
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss">
+	.imageText{
+		.title{
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+		.img{
+			width: 700rpx;
+			image{
+				width: 100%;
+			}
+		}
+		.content{
+			
+		}
+	}
+</style>

+ 282 - 0
components/e-link/e-link.vue

@@ -0,0 +1,282 @@
+<template>
+	<view>
+		<view class="linksList">
+			<view class="title" v-if="linksList[0].title">{{linksList[0].title}}</view>
+
+			<view v-if="linksList[0].types == 11">
+				<view class="list_11">
+					<view class="item" v-for="item in linksList" :key="item.id" @click="go_page(item.linkUrl)">
+						<view class="left">
+							<view class="icon">
+								<view class="img"
+									v-if="item.imageUrl == '../../static/images/link.png' || item.imageUrl == ''">
+									<uni-icons type="paperclip" size="30"></uni-icons>
+								</view>
+								<view class="img" v-else>
+									<image :src="item.imageUrl" mode=""></image>
+								</view>
+							</view>
+							<view class="name">{{item.linkName}}</view>
+						</view>
+						<view class="right">
+							<uni-icons type="arrowright" size="20"></uni-icons>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="linksList[0].types == 12">
+				<view class="list_12">
+					<view class="item" v-for="item in linksList" :key="item.id" @click="go_page(item.linkUrl)">
+						<view class="icon">
+							<view class="img"
+								v-if="item.imageUrl == '../../static/images/link.png'  || item.imageUrl == ''">
+								<uni-icons type="paperclip" size="30"></uni-icons>
+							</view>
+							<view class="img" v-else>
+								<image :src="item.imageUrl" mode=""></image>
+							</view>
+						</view>
+						<view class="name">{{item.linkName}}</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="linksList[0].types == 13">
+				<view class="list_13">
+					<view class="item" v-for="item in linksList" :key="item.id" @click="go_page(item.linkUrl)">
+						<view class="icon">
+							<view class="img"
+								v-if="item.imageUrl == '../../static/images/link.png'  || item.imageUrl == ''">
+								<uni-icons type="paperclip" size="30"></uni-icons>
+							</view>
+							<view class="img" v-else>
+								<image :src="item.imageUrl" mode=""></image>
+							</view>
+						</view>
+						<view class="name">{{item.linkName}}</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="linksList[0].types == 14">
+				<view class="list_14">
+					<view class="item" v-for="item in linksList" :key="item.id" @click="go_page(item.linkUrl)">
+						<view class="icon">
+							<view class="img"
+								v-if="item.imageUrl == '../../static/images/link.png'  || item.imageUrl == ''">
+								<uni-icons type="paperclip" size="30"></uni-icons>
+							</view>
+							<view class="img" v-else>
+								<image :src="item.imageUrl" mode=""></image>
+							</view>
+						</view>
+						<view class="name">{{item.linkName}}</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: [
+			"linksList",
+			"mine_code"
+		],
+		data() {
+			return {
+
+			};
+		},
+		methods: {
+			go_page(link) {
+				console.log(link)
+				let pageId = ""
+				function GetQueryString(name) {
+					var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+					var r = link.match(reg);
+					if (r != null) return unescape(r[2]);
+					return null;
+				}
+				console.log(GetQueryString("pageId"))
+				if (GetQueryString("pageId")) {
+					pageId = GetQueryString("pageId")
+				} else {
+					pageId = link.split('=')[1]
+				}
+
+				uni.navigateTo({
+					url: "../../index/record/record?pageId=" + pageId + "&mine_code=" + this.mine_code,
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.linksList {
+		.title {
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+
+		// 一行一项
+		.list_11 {
+			.item {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+
+				padding: 10px 0;
+				border-bottom: 1px solid #f4f4f4;
+
+				.left {
+					display: flex;
+					align-items: center;
+
+					.icon {
+						width: 60px;
+						line-height: 80rpx;
+						margin-right: 10px;
+
+						.img {
+							width: 60px;
+							height: 80rpx;
+							line-height: 80rpx;
+							text-align: center;
+
+							image {
+								width: 80rpx;
+								height: 80rpx;
+							}
+						}
+					}
+
+					.name {
+						width: 400rpx;
+						white-space: nowrap;
+						overflow: hidden;
+						text-overflow: ellipsis;
+					}
+				}
+
+				.right {}
+			}
+		}
+
+		// 一行两项
+		.list_12 {
+			display: flex;
+			flex-wrap: wrap;
+
+			.item {
+				width: 320rpx;
+				display: flex;
+				align-items: center;
+				margin-left: 10rpx;
+				// border-right: 1px solid #f4f4f4;
+				padding-right: 10rpx;
+				margin-bottom: 10px;
+
+				.icon {
+					margin-right: 30rpx;
+
+					.img {
+						image {
+							width: 90rpx;
+							height: 90rpx;
+						}
+					}
+				}
+
+				.name {
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
+			}
+
+			.item:nth-child(2n) {
+				border-right: none;
+			}
+		}
+
+		// 一行三项
+		.list_13 {
+			overflow: hidden;
+
+			.item {
+				float: left;
+				width: 210rpx;
+				text-align: center;
+				margin-bottom: 10px;
+				margin-right: 35rpx;
+
+				.icon {
+					width: 210rpx;
+
+					.img {
+						width: 210rpx;
+						line-height: 30px;
+						text-align: center;
+
+						image {
+							width: 90rpx;
+							height: 90rpx;
+						}
+					}
+				}
+
+				.name {
+					margin-top: 10rpx;
+
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
+			}
+
+			.item:nth-child(3n) {
+				margin-right: 0;
+			}
+		}
+
+		// 一行四项
+		.list_14 {
+			overflow: hidden;
+
+			.item {
+				float: left;
+				width: 175rpx;
+				text-align: center;
+				margin-bottom: 10px;
+
+				.icon {
+					width: 175rpx;
+
+					.img {
+						width: 175rpx;
+						line-height: 30px;
+						text-align: center;
+
+						image {
+							width: 50px;
+							height: 50px;
+						}
+					}
+				}
+
+				.name {
+					margin-top: 10rpx;
+
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
+			}
+		}
+
+	}
+</style>

+ 121 - 0
components/e-picture/e-picture.vue

@@ -0,0 +1,121 @@
+<template>
+	<view>
+		<view class="pictureList">
+			<view class="title">{{pictureList[0].title}}</view>
+			
+			<view v-if="pictureList[0].imageType == 10">
+				<view class="list_10">
+					<swiper class="box" autoplay="true" interval="3000" circular="true">
+						<swiper-item class="item" v-for="item in pictureList" :key="item.id">
+							<view class="swiper-item">
+								<image :src="item.imageUrl" mode=""></image>
+							</view>
+						</swiper-item>
+					</swiper>
+				</view>
+			</view>
+			<view v-if="pictureList[0].imageType == 11">
+				<view class="list_11">
+					<view class="item" v-for="item in pictureList" :key="item.id">
+						<view class="img">
+							<image :src="item.imageUrl" mode=""></image>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="pictureList[0].imageType == 12">
+				<view class="list_12">
+					<view class="item" v-for="item in pictureList" :key="item.id">
+						<view class="img">
+							<image :src="item.imageUrl" mode=""></image>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[
+			"pictureList"
+		],
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss">
+	.pictureList{
+		.title{
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+		
+		// 轮播图
+		.list_10{
+			height: 240px;
+			.box{
+				width: 700rpx;
+				height: 220px;
+				.item{
+					.swiper-item{
+						height: 220px;
+						image{
+							width: 100%;
+							height: 220px;
+						}
+					}
+				}
+			}
+		}
+		
+		// 一行两张
+		.list_11{
+			overflow: hidden;
+			.item{
+				float: left;
+				margin-right: 20rpx;
+				margin-bottom: 10px;
+				.img{
+					width: 340rpx;
+					height: 140px;
+					image{
+						width: 100%;
+						height: 100%;
+					}
+				}
+			}
+			.item:nth-child(2n){
+				margin-right: 0;
+			}
+		}
+		// 一行三张
+		.list_12{
+			overflow: hidden;
+			.item{
+				float: left;
+				margin-right: 35rpx;
+				margin-bottom: 10px;
+				.img{
+					width: 210rpx;
+					height: 100px;
+					image{
+						width: 100%;
+						height: 100%;
+					}
+				}
+			}
+			.item:nth-child(3n){
+				margin-right: 0;
+			}
+		}
+	}
+</style>

+ 113 - 0
components/e-record/e-record.vue

@@ -0,0 +1,113 @@
+<template>
+	<view>
+		<view class="recordList">
+			<view class="title">记录列表</view>
+			
+			
+			<scroll-view scroll-x="true" >
+				<view class="list">
+					<view class="item" :class="{active:active==index}" v-for="(item,index) in recordList" :key="index" @click="click_active(index,item)">{{item.templateName}}</view>
+				</view>
+			</scroll-view>
+			
+			<view class="content">
+				<view class="inner" v-for="(item,index) in instanceList" :key="index">
+					<view style="color: #009FE8;">记录时间 : {{item[0].createDate}}</view>
+					<view style="color: #009FE8;">{{item[0].templateName}}</view>
+					<view>{{item[0].createName}}</view>
+					<view v-for="(item_2,index_2) in item[0].recordStatusInstanceList" :key="index_2">
+						<view> <span style="color: #999999;">{{item_2.statusName}} :</span> {{item_2.recordStatusInstanceValue}}</view>
+					</view>
+					<view style="color: #009FE8;" v-if="item[0].statusFlag">结束 : {{item[0].createDate}}</view>
+					<view style="color: #F0AD4E;" v-else>等待处理...</view>
+				</view>
+			</view>
+			
+			
+			<view class="more">查看更多</view>
+			
+				
+			
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: [
+			"recordList",
+			"instanceList"
+		],
+		data() {
+			return {
+				active:0
+			};
+		},
+		methods: {
+			click_active(index,item){
+				this.active = index
+				this.$emit("set_parentId",item.parentId)
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.recordList {
+		width: 700rpx;
+		.title {
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+		
+		.list{
+			width: 400%;
+			padding: 8px 0;
+			border-top: 1px solid #ccc;
+			border-bottom: 1px solid #ccc;
+			cursor: pointer;
+			
+			display: flex;
+			
+			.item{
+				margin-right: 15px;
+				border: 1px solid #ccc;
+				color: #ccc;
+				font-size: 17px;
+				padding: 4px 8px;
+				border-radius: 4px;
+			}
+			.active{
+				background-color: #009FE8;
+				color: #fff;
+			}
+		}
+		
+		.content{
+			padding:10rpx;
+			.inner{
+				box-sizing: border-box;
+				padding: 10px 30rpx;
+				width: 680rpx;
+				border: 1px dashed #ccc;
+				border-radius: 10px;
+				margin-bottom: 10px;
+			}
+			
+		}
+
+		
+	}
+
+
+	.more{
+		text-align: center;
+		line-height: 60px;
+		font-size: 18px;
+		border-bottom: 2px solid #C0C0C0;
+		margin: 0 -25rpx;
+	}
+</style>

+ 38 - 0
components/e-text/e-text.vue

@@ -0,0 +1,38 @@
+<template>
+	<view>
+		<view class="textVo">
+			<view class="title">{{textVo.title}}</view>
+			<view class="text">
+				<view v-html="textVo.dataContent"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[
+			"textVo"
+		],
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss">
+	.textVo{
+		.title{
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}
+		.text{
+			text-indent: 2rem;
+		}
+	}
+</style>

+ 64 - 0
components/e-video/e-video.vue

@@ -0,0 +1,64 @@
+<template>
+	<view>
+		<view class="videoList">
+			<view class="title">{{videoList[0].title}}</view>
+			<view class="list">
+				<view class="item" v-for="item in videoList" :key="item.id">
+					<view class="name">{{item.videoName}}</view>
+					<view class="icon" @click="detail(item.videoUrl,item.videoName)">
+						<uni-icons type="videocam" size="24" color="#009FE8"></uni-icons>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:[
+			"videoList"
+		],
+		data() {
+			return {
+				
+			};
+		},
+		methods:{
+			detail(path,name){
+				console.log(path)
+				uni.navigateTo({
+					url:"../../index/record/record-video/record-video?name=" + name + "&url=" + path
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.videoList{
+		.title{
+			line-height: 30px;
+			border-left: 4px solid #009FE8;
+			border-radius: 4px;
+			padding-left: 10px;
+			margin-bottom: 10px;
+		}.list{
+			.item{
+				padding: 20rpx 25rpx;
+				border-bottom: 1rpx solid #f4f4f4;
+				
+				display: flex;
+				justify-content: space-between;
+				.name{
+					white-space: nowrap;
+					overflow: hidden; 
+					text-overflow:ellipsis;
+				}
+				.icon{
+					padding-left: 50rpx;
+				}
+			}
+		}
+	}
+</style>

+ 3 - 17
components/t-i-banner/t-i-banner.vue

@@ -2,7 +2,7 @@
 	<view>
 		<view class="banner">
 			<swiper class="box" autoplay circular>
-				<swiper-item v-for="(item,index) in banners" :key="item.id">
+				<swiper-item v-for="(item,index) in banner" :key="item.id">
 					<view class="item">
 						<view class="img">
 							<image :src="item.imgURL"></image>
@@ -24,33 +24,19 @@
 	export default {
 		name:"t-i-banner",
 		props: [
-			"base_url"
+			"banner"
 		],
 		data() {
 			return {
-				banners:[]
 				
 			}
 		},
-		created() {
-			this.get_banner()
-		},
-		methods: {
-			get_banner(){
-				uni.request({
-					url: this.base_url + "/scrollImg/list",
-					method: "GET",
-					success: (res) => {
-						this.banners = res.data.data.data
-					}
-				})
-			}
-		}
 	}
 </script>
 
 <style lang="scss">
 	.banner{
+		margin-top: -40rpx;
 		.box{
 			width: 750rpx;
 			height: 600rpx;

+ 31 - 17
components/t-i-icon/t-i-icon.vue

@@ -1,12 +1,18 @@
 <template>
 	<view class="content">
 		<view class="list">
-			<view class="item" v-for="item in 5">
+			<view class="item" v-for="(item,index) in iconList" :key="index" @click="go_link(item.link)">
+				<view class="icon">
+					<image :src="item.icon" mode=""></image>
+				</view>
+				<view class="name">{{item.title}}</view>
+			</view>
+			<!-- <view class="item">
 				<view class="icon">
 					<image src="./icon/gaikuang.png" mode=""></image>
 				</view>
 				<view class="name">概况</view>
-			</view>
+			</view> -->
 		</view>
 	</view>
 </template>
@@ -15,27 +21,35 @@
 	export default {
 		name:"t-i-icon",
 		props: [
-			"base_url"
+			"iconList",
+			"mine_code"
 		],
 		data() {
 			return {
-				list:[]
+				
 			};
 		},
-		created() {
-			this.get_list()
-		},
 		methods:{
-			get_list(){
-				uni.request({
-					url: this.base_url + "/homeNav/list",
-					method: "GET",
-					success: (res) => {
-						// console.log(res.data.data.data)
-						
-						this.list = res.data.data.data.slice(0,5)
-						console.log(this.list)
-					}
+			go_link(link){
+				// console.log(link.split('=')[3].split('&')[0])
+				// let pageId = link.split('=')[3].split('&')[0]
+				
+				let pageId = ""
+				function GetQueryString(name) {
+					var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+					var r = link.match(reg);
+					if (r != null) return unescape(r[2]);
+					return null;
+				}
+				console.log(GetQueryString("pageId"))
+				if (GetQueryString("pageId")) {
+					pageId = GetQueryString("pageId")
+				} else {
+					pageId = link.split('=')[1]
+				}
+				
+				uni.navigateTo({
+					url:"../../index/record/record?pageId=" + pageId + "&mine_code=" + this.mine_code,
 				})
 			}
 		}

BIN
components/t-i-navbar/icon/zaoquan.png


+ 19 - 4
components/t-i-navbar/t-i-navbar.vue

@@ -6,9 +6,11 @@
 			</view>
 			
 			<view class="navbar">
-				<view class="left">
-					<image src="./icon/ningdongyunying.png" mode=""></image>
-					<uni-icons type="arrowdown" color="#fff"></uni-icons>
+				<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>
 				<view class="search">
 					<view class="box">
@@ -42,8 +44,21 @@
 		name: "t-i-navbar",
 		data() {
 			return {
-
+				mine_code:""
 			};
+		},
+		created() {
+			// 初始化当前煤矿编码
+			this.mine_code = uni.getStorageSync('mine_code')
+		},
+		methods:{
+			switch_kuang(){
+				if(this.mine_code == 'ningdongyunying'){
+					uni.navigateTo({
+						url:"../../index/switch-kuang/switch-kuang"
+					})
+				}
+			}
 		}
 	}
 </script>

+ 11 - 24
components/t-i-news/t-i-news.vue

@@ -2,11 +2,11 @@
 	<view class="content">
 		<view class="title">
 			<view class="text">宁煤新闻</view>
-			<view class="more">查看全部 <uni-icons type="arrowright" color="#999" size="11"></uni-icons>
+			<view class="more" @click="go_more()">查看全部 <uni-icons type="arrowright" color="#999" size="11"></uni-icons>
 			</view>
 		</view>
 		<view class="list">
-			<view class="item" v-for="(item,index) in list" :key="index" @click="go_detail(item.id)">
+			<view class="item" v-for="(item,index) in newsList" :key="index" @click="go_detail(item.id)">
 				<view class="left">
 					<image :src="item.main_img"></image>
 				</view>
@@ -23,40 +23,27 @@
 	export default {
 		name: "t-i-news",
 		props: [
-			"base_url"
+			"newsList",
+			"mine_code"
 		],
 		data() {
 			return {
 				list: []
 			};
 		},
-		created() {
-			console.log(this.base_url)
-			// 获取首页新闻列表
-			this.getNews()
-		},
 		methods: {
-			// 请求新闻动态
-			getNews() {
-				uni.request({
-					url: this.base_url + "/article/list",
-					method: "GET",
-					data: {
-						pageSize: 4
-					},
-					success: (res) => {
-						// console.log(res.data.data.data)
-						this.list = res.data.data.data
-					}
-				})
-			},
-
 			// 打开详情页
 			go_detail(id) {
 				uni.navigateTo({
-					url: "../../index/news/news?id=" + id
+					url: "../../index/news/news?id=" + id + "&mine_code=" + this.mine_code
 				})
 			},
+			// 打开列表
+			go_more(){
+				uni.navigateTo({
+					url: "../../index/news/news_list/news_list?mine_code=" + this.mine_code
+				})
+			}
 
 		}
 	}

+ 3 - 21
components/t-i-notice/t-i-notice.vue

@@ -16,35 +16,17 @@
 	export default {
 		name: "t-i-notice",
 		props: [
-			"base_url"
+			"text"
 		],
 		data() {
 			return {
 				text_time:"",
-				text: "暂无公告。"
 			};
 		},
 		created() {
-			this.get_notice()
-			
 			this.getCurrentDate()
 		},
 		methods: {
-			get_notice() {
-				uni.request({
-					url: this.base_url + "/notice/list",
-					method: "GET",
-					success: (res) => {
-						console.log(res)
-						if(!res.data.data.content){
-							this.text = res.data.data.message
-						}else{
-							this.text = res.data.data.title + res.data.data.content
-						}
-					}
-				})
-			},
-
 			getCurrentDate() {
 				var myDate = new Date();
 				var year = myDate.getFullYear(); //年
@@ -98,12 +80,12 @@
 	.box {
 		margin: 0 auto;
 		width: 700rpx;
-		height: 200rpx;
+		// height: 200rpx;
 		background-color: rgba(255, 255, 255, .4);
 		border-radius: 20rpx;
 
 		box-sizing: border-box;
-		padding: 20rpx;
+		padding: 0 20rpx;
 
 		/deep/.uni-noticebar {
 			margin-bottom: 0;

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


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


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


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


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


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


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


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


+ 62 - 14
components/t-m-icon/t-m-icon.vue

@@ -3,21 +3,51 @@
 		<view class="list">
 			<view class="item" @click="tell()">
 				<view class="icon">
-					<image src="./icon/icon_9.png" mode=""></image>
+					<image src="./icon/fuwudianhua.png" mode=""></image>
 				</view>
-				<view class="name">绑定手机</view>
+				<view class="name">服务电话</view>
 			</view>
-			<!-- <view class="item" @click="go_m_signature()">
+			<view class="item" @click="go_m_message_reminder()">
 				<view class="icon">
-					<image src="./icon/icon_4.png" mode=""></image>
+					<image src="./icon/xiaoxi.png" mode=""></image>
 				</view>
-				<view class="name">手写签名</view>
-			</view> -->
-			<view class="item" @click="go_m_download()">
+				<view class="name">消息提醒</view>
+			</view>
+			<view class="item">
+				<view class="icon">
+					<image src="./icon/gongdanshenhe.png" mode=""></image>
+				</view>
+				<view class="name">工单审核</view>
+			</view>
+			<view class="item">
+				<view class="icon">
+					<image src="./icon/shiyongshouce.png" mode=""></image>
+				</view>
+				<view class="name">使用手册</view>
+			</view>
+			<view class="item">
+				<view class="icon">
+					<image src="./icon/jianyifankui.png" mode=""></image>
+				</view>
+				<view class="name">建议反馈</view>
+			</view>
+			<view class="item" @click="go_m_repassword()">
 				<view class="icon">
-					<image src="./icon/icon_11.png" mode=""></image>
+					<image src="./icon/xiugaimima.png" mode=""></image>
 				</view>
-				<view class="name">下载二维码</view>
+				<view class="name">修改密码</view>
+			</view>
+			<view class="item">
+				<view class="icon">
+					<image src="./icon/gengxin.png" mode=""></image>
+				</view>
+				<view class="name">更新日志</view>
+			</view>
+			<view class="item" @click="clear_cache()">
+				<view class="icon">
+					<image src="./icon/qingchu.png" mode=""></image>
+				</view>
+				<view class="name">清除缓存</view>
 			</view>
 			
 		</view>
@@ -36,18 +66,36 @@
 			
 		},
 		methods:{
-			// 绑定
+			// 拨打服务电话
 			tell(){
+				uni.makePhoneCall({
+				    phoneNumber: '18152480670'
+				});
+			},
+			// 修改密码
+			go_m_repassword(){
 				uni.navigateTo({
-					url:"../../my/setPhone/setPhone"
+					url:"../../my/repassword/repassword"
 				})
 			},
-			// 下载二维码
-			go_m_download(){
+			// 消息提醒
+			go_m_message_reminder(){
 				uni.navigateTo({
-					url:"../../my/download/download"
+					url:"../../my/message-reminder/message-reminder"
 				})
 			},
+			// 清除缓存
+			clear_cache(){
+				uni.showLoading()
+				setTimeout(()=>{
+					uni.hideLoading()
+					uni.showToast({
+						icon:"none",
+						title:"清除完成"
+					})
+				},1500)
+			}
+			
 		}
 	}
 </script>

+ 31 - 20
components/t-m-info/t-m-info.vue

@@ -15,11 +15,11 @@
 				<!-- <uni-icons type="arrowright"></uni-icons> -->
 			</view>
 		</view>
-		<view class="tip" v-if="tip_password">
+		<view class="tip" v-if="tip_password" @click="go_m_repassword()">
 			<view class="icon"></view>
 			<view class="text">当前密码为初始密码,请及时修改。</view>
 		</view>
-		<view class="tip" v-if="tip_mobile">
+		<view class="tip" v-if="tip_mobile" @click="binding_phone()">
 			<view class="icon"></view>
 			<view class="text">未绑定手机号,请立即绑定手机号。</view>
 		</view>
@@ -74,26 +74,37 @@
 				this.tip_mobile = true
 			}
 			
-			setTimeout(()=>{
-				if(!this.mobile){
-					uni.showModal({
-					    title: '温馨提示',
-					    content: '当前还未绑定手机号,请及时绑定。',
-						showCancel:false,
-					    success: function (res) {
-					        if (res.confirm) {
-					            console.log('用户点击确定');
-								uni.navigateTo({
-									url:"../../my/setPhone/setPhone"
-								})
-					        }
-					    }
-					});
-				}
-			},500)
+			// setTimeout(()=>{
+			// 	if(!this.mobile){
+			// 		uni.showModal({
+			// 		    title: '温馨提示',
+			// 		    content: '当前还未绑定手机号,请及时绑定。',
+			// 			showCancel:false,
+			// 		    success: function (res) {
+			// 		        if (res.confirm) {
+			// 		            console.log('用户点击确定');
+			// 					uni.navigateTo({
+			// 						url:"../../my/setPhone/setPhone"
+			// 					})
+			// 		        }
+			// 		    }
+			// 		});
+			// 	}
+			// },500)
 		},
 		methods:{
-			
+			// 绑定手机
+			binding_phone(){
+				uni.navigateTo({
+					url:"../../my/setPhone/setPhone"
+				})
+			},
+			// 修改密码
+			go_m_repassword(){
+				uni.navigateTo({
+					url:"../../my/repassword/repassword"
+				})
+			},
 		}
 		
 	}

+ 5 - 22
components/t-m-list/t-m-list.vue

@@ -2,17 +2,6 @@
 	<view class="content">
 		<view class="line"></view>
 		<view class="list">
-			<view class="item" @click="go_m_repassword()">
-				<view class="left">
-					<view class="icon">
-						<image src="./icon/list_1.png" mode=""></image>
-					</view>
-					<view class="name">修改密码</view>
-				</view>
-				<view class="right">
-					<uni-icons type="arrowright"></uni-icons>
-				</view>
-			</view>
 			<view class="item" @click="logout()">
 				<view class="left">
 					<view class="icon">
@@ -24,12 +13,12 @@
 					<uni-icons type="arrowright"></uni-icons>
 				</view>
 			</view>
-			<view class="item" @click="go_m_update_log()">
+			<view class="item" @click="go_m_download()">
 				<view class="left">
 					<view class="icon">
 						<image src="./icon/list_3.png" mode=""></image>
 					</view>
-					<view class="name">更新日志</view>
+					<view class="name">下载二维码</view>
 				</view>
 				<view class="right">
 					<uni-icons type="arrowright"></uni-icons>
@@ -48,12 +37,6 @@
 			};
 		},
 		methods:{
-			// 修改密码
-			go_m_repassword(){
-				uni.navigateTo({
-					url:"../../my/repassword/repassword"
-				})
-			},
 			// 退出登录
 			logout(){
 				uni.clearStorageSync('Authorization');
@@ -67,10 +50,10 @@
 					url:"../../my/login/login"
 				})
 			},
-			// 更新日志
-			go_m_update_log(){
+			// 下载二维码
+			go_m_download(){
 				uni.navigateTo({
-					url:"../../my/update-log/update-log"
+					url:"../../my/download/download"
 				})
 			}
 		}

+ 202 - 0
components/t-p-zaoquan/t-p-zaoquan.vue

@@ -0,0 +1,202 @@
+<template>
+	<view class="content">
+		<view class="item_box" style="background-color: #638BD5;" @click="go_production_report()">
+			<view class="img">
+				<image src="../t-p-icon/icon_2.png" mode=""></image>
+			</view>
+			<view class="text">
+				<view class="name">生产报表</view>
+				<view class="tip">当日产量140517.8吨</view>
+			</view>
+		</view>
+		<view class="item_box" style="background-color: #A3A2E4;" @click="go_personnel_orientation()">
+			<view class="img">
+				<image src="../t-p-icon/icon_3.png" mode=""></image>
+			</view>
+			<view class="text">
+				<view class="name">人员定位</view>
+				<view class="tip">井下人数3892人</view>
+			</view>
+		</view>
+		<view class="item_box" style="background-color: #8BC8DA;" @click="go_safety_monitoring()">
+			<view class="img">
+				<image src="../t-p-icon/icon_4.png" mode=""></image>
+			</view>
+			<view class="text">
+				<view class="name">安全监测</view>
+				<view class="tip">6268监测点</view>
+			</view>
+		</view>
+		<view class="item_box" style="background-color: #FBB47B;" @click="go_video_monitor()">
+			<view class="img">
+				<image src="../t-p-icon/icon_6.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/djtf/#/')">
+			<view class="img">
+				<image src="../t-p-icon/icon_10.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_10.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>
+		</view>
+		<view class="item_box" style="background-color: #2873FF;" @click="go_zdhxt('http://webdevelop.nxjiewei.com/assets/html/zaoquan/929bf/#/')">
+			<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>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: "t-p-zaoquan",
+		data() {
+			return {
+				mine:"640181B0011010037723",
+				org_num:"1014",
+				mine_code:"zaoquan"
+			};
+		},
+		methods: {
+			// 自动化统计列表
+			go_zdhxt(zdhxt){
+				uni.navigateTo({
+					url:"../../production/zidonghua/zidonghua?url=" + zdhxt
+				})
+			},
+			// 生产报表
+			go_production_report() {
+				uni.navigateTo({
+					url: "../../production/production_report/production_report?mine=" + this.mine + "&org_num=" + this.org_num,
+				})
+			},
+			// 安全监测
+			go_safety_monitoring() {
+				uni.navigateTo({
+					url: "../../production/safety_monitoring/safety_monitoring?mine=" + this.mine
+				})
+			},
+			//人员定位
+			go_personnel_orientation() {
+				uni.navigateTo({
+					url:"../../production/personnel_orientation/personnel_orientation?mine=" + this.mine
+				})
+			},
+			// 视频监控
+			go_video_monitor(){
+				uni.navigateTo({
+					url:"../../production/video_monitor/video_monitor?mine_code=" + this.mine_code
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.content {
+		box-sizing: border-box;
+		padding: 20rpx 25rpx 0;
+		margin-bottom: 100rpx;
+
+		overflow: hidden;
+
+		.item_box {
+			float: left;
+
+			width: 220rpx;
+			height: 280rpx;
+
+			margin-right: 20rpx;
+			margin-bottom: 20rpx;
+			border-radius: 16rpx;
+
+			.img {
+				box-sizing: border-box;
+				padding-top: 40rpx;
+				text-align: center;
+
+				image {
+					width: 140rpx;
+					height: 140rpx;
+				}
+			}
+
+			.text {
+				text-align: center;
+				color: #FFFFFF;
+				line-height: 40rpx;
+
+				.name {
+					font-size: 28rpx;
+				}
+
+				.tip {
+					font-size: 24rpx;
+					white-space: nowrap;
+					overflow: hidden;
+					text-overflow: ellipsis;
+				}
+			}
+		}
+
+		.item_box:nth-child(3n) {
+			margin-right: 0;
+		}
+
+	}
+</style>

+ 126 - 73
manifest.json

@@ -1,75 +1,128 @@
 {
-	"name": "智慧矿山-全矿",
-	"appid": "__UNI__854DCD5",
-	"description": "",
-	"versionName": "1.0.0",
-	"versionCode": "100",
-	"transformPx": false,
-	/* 5+App特有相关 */
-	"app-plus": {
-		"compatible": {
-			"ignoreVersion": true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持  
-		},
-		"usingComponents": true,
-		"nvueStyleCompiler": "uni-app",
-		"compilerVersion": 3,
-		"splashscreen": {
-			"alwaysShowBeforeRender": true,
-			"waiting": true,
-			"autoclose": true,
-			"delay": 0
-		},
-		/* 模块配置 */
-		"modules": {},
-		/* 应用发布信息 */
-		"distribute": {
-			/* android打包配置 */
-			"android": {
-				"permissions": [
-					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
-					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
-					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
-					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
-					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
-					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-					"<uses-feature android:name=\"android.hardware.camera\"/>",
-					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
-				]
-			},
-			/* ios打包配置 */
-			"ios": {},
-			/* SDK配置 */
-			"sdkConfigs": {}
-		}
-	},
-	/* 快应用特有相关 */
-	"quickapp": {},
-	/* 小程序特有相关 */
-	"mp-weixin": {
-		"appid": "",
-		"setting": {
-			"urlCheck": false
-		},
-		"usingComponents": true
-	},
-	"mp-alipay": {
-		"usingComponents": true
-	},
-	"mp-baidu": {
-		"usingComponents": true
-	},
-	"mp-toutiao": {
-		"usingComponents": true
-	},
-	"uniStatistics": {
-		"enable": false
-	},
-	"vueVersion": "2"
+    "name" : "智慧枣泉",
+    "appid" : "__UNI__4B520D3",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "compatible" : {
+            "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持  
+        },
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : false,
+            "waiting" : false,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {
+            "VideoPlayer" : {},
+            "Contacts" : {}
+        },
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_CHECKIN_PROPERTIES\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ]
+            },
+            /* ios打包配置 */
+            "ios" : {},
+            /* SDK配置 */
+            "sdkConfigs" : {},
+            "icons" : {
+                "android" : {
+                    "hdpi" : "unpackage/res/icons/72x72.png",
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
+                },
+                "ios" : {
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
+                    "ipad" : {
+                        "app" : "unpackage/res/icons/76x76.png",
+                        "app@2x" : "unpackage/res/icons/152x152.png",
+                        "notification" : "unpackage/res/icons/20x20.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
+                        "settings" : "unpackage/res/icons/29x29.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "spotlight" : "unpackage/res/icons/40x40.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
+                    },
+                    "iphone" : {
+                        "app@2x" : "unpackage/res/icons/120x120.png",
+                        "app@3x" : "unpackage/res/icons/180x180.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
+                    }
+                }
+            },
+            "splashscreen" : {
+                "androidStyle" : "default",
+                "android" : {
+                    "hdpi" : "static/qidongtu.png",
+                    "xhdpi" : "static/qidongtu.png",
+                    "xxhdpi" : "static/qidongtu.png"
+                }
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "vueVersion" : "2",
+    "h5" : {
+        "router" : {
+            "mode" : "hash",
+            "base" : "./"
+        }
+    }
 }

+ 97 - 51
pages.json

@@ -5,7 +5,8 @@
 		{
 			"path": "pages/tabbar/index/index",
 			"style": {
-				"navigationStyle": "custom"
+				"navigationStyle": "custom",
+				"enablePullDownRefresh": true
 				// "navigationBarTitleText": "智慧矿山"
 			}
 		},
@@ -33,7 +34,26 @@
 				"navigationBarTitleText": "个人中心"
 			}
 
-		}, {
+		},
+		// ……其他页面配置
+		{
+			"path": "uni_modules/uni-upgrade-center-app/pages/upgrade-popup",
+			"style": {
+				"disableScroll": true,
+				"app-plus": {
+					"backgroundColorTop": "transparent",
+					"background": "transparent",
+					"titleNView": false,
+					"scrollIndicator": false,
+					"popGesture": "none",
+					"animationType": "fade-in",
+					"animationDuration": 200
+
+				}
+			}
+		},
+
+		{
 			"path": "pages/production/production_report/production_report",
 			"style": {
 				"navigationBarTitleText": "生产报表"
@@ -149,55 +169,81 @@
 
 		}
 
-	    ,{
-            "path" : "pages/index/news/news",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": ""
-            }
-            
-        }
-        ,{
-            "path" : "pages/index/news/news_list/news_list",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": ""
-            }
-            
-        }
-        ,{
-            "path" : "pages/my/login/login",
-            "style" :                                                                                    
-            {
-                "navigationStyle": "custom"
-            }
-            
-        }
-        ,{
-            "path" : "pages/my/repassword/repassword",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "修改密码"
-            }
-            
-        }
-        ,{
-            "path" : "pages/my/setPhone/setPhone",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "绑定手机"
-            }
-            
-        }
-        ,{
-            "path" : "pages/my/download/download",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "下载二维码"
-            }
-            
-        }
-    ],
+		, {
+			"path": "pages/index/news/news",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+
+		}, {
+			"path": "pages/index/news/news_list/news_list",
+			"style": {
+				"navigationBarTitleText": " "
+			}
+
+		}, {
+			"path": "pages/my/login/login",
+			"style": {
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/my/repassword/repassword",
+			"style": {
+				"navigationBarTitleText": "修改密码"
+			}
+
+		}, {
+			"path": "pages/my/setPhone/setPhone",
+			"style": {
+				"navigationBarTitleText": "绑定手机"
+			}
+
+		}, {
+			"path": "pages/my/download/download",
+			"style": {
+				"navigationBarTitleText": "下载二维码"
+			}
+
+		}, {
+			"path": "pages/index/switch-kuang/switch-kuang",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/index/record/record",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+
+		}, {
+			"path": "pages/index/record/record-video/record-video",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+
+		}, {
+			"path": "pages/my/message-reminder/message-reminder",
+			"style": {
+				"navigationBarTitleText": "消息提醒"
+			}
+
+		}, {
+			"path": "pages/my/message-reminder/message-detail/message-detail",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+
+		}, {
+			"path": "pages/my/forget-password/forget-password",
+			"style": {
+				"navigationStyle": "custom"
+			}
+
+		}
+	],
 	"globalStyle": {
 		"navigationBarTextStyle": "white",
 		"navigationBarTitleText": " ",

Plik diff jest za duży
+ 177 - 5
pages/index/news/news.vue


+ 6 - 2
pages/index/news/news_list/news_list.vue

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

+ 26 - 0
pages/index/record/record-video/record-video.vue

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

+ 402 - 0
pages/index/record/record.vue

@@ -0,0 +1,402 @@
+<template>
+	<view>
+		<view class="pageItemList" v-for="(item,index) in pageItemList" :key="index">
+			<!-- 纯文本模块 -->
+			<view class="TEXT">
+				<view v-if="item.pageRelation.businessType === 'TEXT'">
+					<!-- 将内容所在父模块的索引保存到新数组 判断新数组中的索引值==循环的索引值时,让内容模块渲染(textVo_index[index_2] == index)保证了内容模块的排序问题 -->
+					<view v-if="textVo_index[index_2] == index" v-for="(item_2,index_2) in textVo" :key="index_2">
+						<e-text :textVo="textVo[index_2]"></e-text>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 图文模块 -->
+			<view class="IMAGE_TEXT">
+				<view v-if="item.pageRelation.businessType === 'IMAGE_TEXT'">
+					<view v-if="imageText_index[index_2] == index" v-for="(item_2,index_2) in imageText" :key="index_2">
+						<e-image-text :imageText="imageText[index_2]"></e-image-text>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 图集模块 -->
+			<view class="PICTURE">
+				<view v-if="item.pageRelation.businessType === 'PICTURE'">
+					<view v-if="pictureList_index[index_2] == index" v-for="(item_2,index_2) in pictureList" :key="index_2">
+						<e-picture :pictureList="pictureList[index_2]"></e-picture>
+					</view>
+				</view>
+			</view>
+			
+			
+			<!-- 文件模块 -->
+			<view class="FILE">
+				<view v-if="item.pageRelation.businessType === 'FILE'">
+					<view v-if="fileList_index[index_2] == index" v-for="(item_2,index_2) in fileList" :key="index_2">
+						<e-file :fileList="fileList[index_2]"></e-file>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 链接模块 -->
+			<view class="LINKS">
+				<view v-if="item.pageRelation.businessType === 'LINKS'">
+					<view v-if="linksList_index[index_2] == index" v-for="(item_2,index_2) in linksList" :key="index_2">
+						<e-link :linksList="linksList[index_2]" :mine_code="mine_code"></e-link>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 视频模块 -->
+			<view class="VIDEO">
+				<view v-if="item.pageRelation.businessType === 'VIDEO'">
+					<view v-if="videoList_index[index_2] == index" v-for="(item_2,index_2) in videoList" :key="index_2">
+						<e-video :videoList="videoList[index_2]"></e-video>
+					</view>
+				</view>
+			</view>
+			
+			<!-- 设备铭牌模块 -->
+			<view class="EQUIPMENT">
+				<view v-if="item.pageRelation.businessType === 'EQUIPMENT'">
+					<view v-if="equipmentList_index[index_2] == index" v-for="(item_2,index_2) in equipmentList" :key="index_2">
+						<e-equipment :equipmentList="equipmentList[index_2]"></e-equipment>
+					</view>
+				</view>
+			</view>
+			
+		</view>
+		
+
+		<!-- 记录列表 -->
+		<!-- <view v-if="recordList.length != 0">
+			<view class="RECORD">
+				<e-record :recordList="recordList" :instanceList="instanceList" @set_parentId="set_parentId"></e-record>
+			</view>
+		</view> -->
+		<!-- 浏览记录 -->
+		<view v-if="browse.length != 0">
+			<e-browse :browse="browse" :bgColor="bgColor"></e-browse>
+		</view>
+		
+		<!-- 添加记录 -->
+		<!-- <view v-if="selectRecord_list.length > 0" class="bottom_btn" @click="bottom_btn_click()">添加记录</view> -->
+		
+	</view>
+</template>
+
+<script>
+	import Base64 from "@/common/js-base64.js"
+	
+	export default {
+		data() {
+			return {
+				mine_code:"",
+				base_url:"",
+				// 二维码ID
+				pageId:'',
+				
+				// 模块数组
+				pageItemList:[],
+				
+				
+				// 纯文本模块
+				textVo:[],
+				// 所在模块索引
+				textVo_index:[],
+				// base wenben
+				textVo_dataContent:[],
+				
+				
+				// 图文模块
+				imageText:[],
+				// 所在模块索引
+				imageText_index:[],
+				// base wenben
+				imageText_dataContent:[],
+				
+				// 图集模块
+				pictureList:[],
+				// 所在模块索引
+				pictureList_index:[],
+				
+				// 文件模块
+				fileList:[],
+				// 所在模块索引
+				fileList_index:[],
+				
+				// 链接模块
+				linksList:[],
+				// 所在模块索引
+				linksList_index:[],
+				
+				// 视频模块
+				videoList:[],
+				videoList_index:[],
+				
+				// 设备铭牌模块
+				equipmentList:[],
+				// 所在模块索引
+				equipmentList_index:[],
+				
+				// 记录管理模块
+				recordList:[],
+				instanceList:[],
+				
+				// 浏览记录
+				browse:[],
+				// 随即色
+				bgColor:[],
+				
+				
+				// 添加记录入口列表
+				selectRecord_list:[]
+			}
+		},
+		onLoad(option) {
+			this.mine_code = option.mine_code
+			// 根据矿编码切换首页接口不同的请求基础路径
+			switch (option.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 = ""
+			}
+			// 获取二维码ID
+			this.pageId = option.pageId
+			
+			
+			// 获取二维码详情
+			this.get_inner()
+			
+			// 获取浏览记录
+			this.get_browse()
+			
+			// 获取二维码记录筛选接口
+			this.get_selectRecord()
+			
+			
+			// 获取添加记录入口列表
+			this.get_selectRecord_list()
+			
+		},
+		methods: {
+			// 弹出添加记录菜单
+			bottom_btn_click(){
+				uni.showActionSheet({
+				    itemList: this.selectRecord_list_name,
+				    success: (res) => {
+				        // console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
+						// console.log(res.tapIndex)
+						// console.log(this.selectRecord_list[res.tapIndex].parentId)
+						
+						uni.navigateTo({
+							// url:"./selectRecord_list_detail/selectRecord_list_detail?pageRecordId=" + this.selectRecord_list[res.tapIndex].parentId + "&pageId=" + this.pageId,
+							url:"./selectRecord_list_detail/selectRecord_list_detail?pageRecordId=d540a652a218469d92c627f1c4b1d95e&pageId=" + this.pageId,
+						})
+				    },
+				    fail: function (res) {
+				        console.log(res.errMsg);
+				    }
+				})
+			},
+			
+			
+			// 获取二维码详情
+			get_inner(){
+				uni.request({
+					url: this.base_url + "/swagger/api/page/v1/detailPage?pageId="+this.pageId+"&sourceType=&organizationIds=&userId=&userName=",
+					success: (res) => {
+						console.log(res.data.data)
+						const data = res.data.data
+						
+						// 设置页面标题
+						uni.setNavigationBarTitle({
+							title: data.page.title
+						})
+						
+						// 获取模块数组
+						this.pageItemList = data.pageItemList
+						
+						// 判断模块属性
+						for(let i = 0; i < data.pageItemList.length; i++){
+							if(data.pageItemList[i].pageRelation.businessType === 'TEXT'){
+								// console.log("纯文本模块",i)
+								// 内容模块数组
+								this.textVo.push(data.pageItemList[i].textVo)
+								// 保存内容所在父模块的索引
+								this.textVo_index.push(i)
+								// base64解码 替换原数组属性
+								this.textVo_dataContent.push(data.pageItemList[i].textVo.dataContent)
+								for(let i = 0; i < this.textVo_dataContent.length; i++){
+									this.textVo[i].dataContent = Base64.decode(this.textVo_dataContent[i])
+								}
+								// console.log(this.textVo_dataContent)
+								// console.log(this.textVo)
+								// console.log(this.textVo_index)
+							}else if(data.pageItemList[i].pageRelation.businessType === 'IMAGE_TEXT'){
+								// console.log("图文模块",i)
+								// 图文模块
+								this.imageText.push(data.pageItemList[i].imageText)
+								// 保存内容所在父模块的索引
+								this.imageText_index.push(i)
+								// base64解码 替换原数组属性
+								this.imageText_dataContent.push(data.pageItemList[i].imageText.dataContent)
+								for(let i = 0; i < this.imageText_dataContent.length; i++){
+									this.imageText[i].dataContent = Base64.decode(this.imageText_dataContent[i])
+								}
+							}else if(data.pageItemList[i].pageRelation.businessType === 'PICTURE'){
+								// console.log("图集模块",i)
+								this.pictureList.push(data.pageItemList[i].pictureList)
+								this.pictureList_index.push(i)
+							}else if(data.pageItemList[i].pageRelation.businessType === 'FILE'){
+								// console.log("文件模块",i)
+								// 文件模块
+								this.fileList.push(data.pageItemList[i].fileList)
+								this.fileList_index.push(i)
+							}else if(data.pageItemList[i].pageRelation.businessType === 'LINKS'){
+								// console.log("链接模块",i)
+								this.linksList.push(data.pageItemList[i].linksList)
+								this.linksList_index.push(i)
+							}else if(data.pageItemList[i].pageRelation.businessType === 'VIDEO'){
+								// console.log("视频模块",i)
+								// 视频模块
+								this.videoList.push(data.pageItemList[i].videoList)
+								this.videoList_index.push(i)
+							}else if(data.pageItemList[i].pageRelation.businessType === 'EQUIPMENT'){
+								// console.log("设备铭牌模块",i)
+								// 设备铭牌模块
+								this.equipmentList.push(data.pageItemList[i].equipmentList)
+								this.equipmentList_index.push(i)
+							}else if(data.pageItemList[i].pageRelation.businessType === 'RECORD'){
+								// console.log("记录管理模块",i)
+							}
+							
+						}
+						
+						
+					}
+				})
+			},
+			
+			
+			// 获取浏览记录
+			get_browse(){
+				uni.request({
+					url: this.base_url + "/swagger/api/pageuser/v1/getPageUserByPageId/"+this.pageId,
+					success: (res) => {
+						console.log(res.data.data)
+						this.browse = res.data.data
+						
+						for(let i=0;i<100;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)
+						}
+					}
+				})
+			},
+			
+			
+			// 获取二维码记录筛选接口
+			get_selectRecord(){
+				uni.request({
+					url: this.base_url + "/swagger/api/page/v1/selectRecordByGetPageId/"+this.pageId,
+					success: (res) => {
+						console.log(res.data.data)
+						this.recordList = res.data.data
+						// 根据筛选标签获取列表接口
+						this.get_PageRecordInstanceList(res.data.data[0].parentId)
+					}
+				})
+			},
+			
+			
+			set_parentId(parentId){
+				this.get_PageRecordInstanceList(parentId)
+			},
+			// 根据筛选标签获取列表接口
+			get_PageRecordInstanceList(parentId){
+				uni.showLoading({
+					icon:"none",
+					title:"加载中...",
+					mask:true
+				})
+				uni.request({
+					url: this.base_url + "/swagger/api/record/v1/getPageRecordInstanceList?pageId="+this.pageId+"&pageRecordParentId=" + parentId + " &pageNumber=1&pageSize=5",
+					success: (res) => {
+						console.log(res.data.data)
+						this.instanceList = res.data.data
+						uni.hideLoading()
+					}
+				})
+			},
+			
+			
+			// 获取添加记录入口列表
+			get_selectRecord_list(){
+				uni.request({
+					url: this.base_url + "/swagger/api/page/v1/selectRecordByGetPageId/"+this.pageId,
+					success: (res) => {
+						console.log(res.data.data)
+						this.selectRecord_list = res.data.data
+						
+						let selectRecord_list_name = []
+						
+						res.data.data.map(function(item,index){
+							selectRecord_list_name.push(item.templateName)
+						})
+						
+						console.log(selectRecord_list_name)
+						this.selectRecord_list_name = selectRecord_list_name
+					}
+				})
+			},
+		
+		
+		},
+	}
+</script>
+
+<style lang="scss">
+	page{
+		box-sizing: border-box;
+		padding: 25rpx;
+		
+		margin-bottom: 90px;
+	}
+	.pageItemList{
+		width: 700rpx;
+		margin-bottom: 40rpx;
+	}
+	
+	.bottom_btn{
+		position: fixed;
+		left: 0;
+		bottom: 0;
+		
+		width: 750rpx;
+		line-height: 60px;
+		background-color: #009FE8;
+		color: #FFFFFF;
+		text-align: center;
+		font-weight: 700;
+		
+	}
+	
+</style>

+ 27 - 0
pages/index/switch-kuang/switch-kuang.vue

@@ -0,0 +1,27 @@
+<template>
+	<view>
+		<view @click="click('meihuajing')">选择完毕</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			};
+		},
+		methods:{
+			click(data){
+				uni.$emit('update_kuang',{msg:data})
+				uni.switchTab({
+					url:"../../tabbar/index/index",
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+
+</style>

+ 346 - 0
pages/my/forget-password/forget-password.vue

@@ -0,0 +1,346 @@
+<template>
+	<view class="content">
+		<view class="status_bar"></view>
+		<view class="logo">
+			<image src="~@/static/logo.png" mode="aspectFit"></image>
+		</view>
+		<view class="title">
+			<text v-if="mine_code == 'ningdongyunying'">E信管理</text>
+			<text v-if="mine_code == 'zaoquan'">枣泉煤矿</text>
+		</view>
+		<view class="change_box">
+			<view class="item">
+				<view class="name">手机号</view>
+				<view class="input">
+					<input type="text" value=""  v-model="mobile"/>
+				</view>
+			</view>
+			<view class="send_box">
+				<view class="send_code">
+					<view class="name">验证码</view>
+					<view class="input">
+						<input type="text" value="" v-model="vcode"/>
+					</view>
+				</view>
+				
+				<view class="send_btn" @click="send_vcode()">
+					<text>{{send_text}}</text>
+				</view>
+			</view>
+			<view class="item">
+				<view class="name">修改密码</view>
+				<view class="input">
+					<input type="password" value="" v-model="password"/>
+				</view>
+			</view>
+			<view class="item">
+				<view class="name">确认密码</view>
+				<view class="input">
+					<input type="password" value="" v-model="copypassword"/>
+				</view>
+			</view>
+		</view>
+
+		<view class="tips">
+			<text @click="back()">记起来了?请点击这登陆</text>
+		</view>
+
+		<view class="change_btn" @click="changeBtn()">
+			<text>确认修改</text>
+		</view>
+
+	</view>
+</template>
+
+<script>
+	var testPassword =/^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\W_!@#$%^&*`~()-+=]+$)(?![0-9\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\W_!@#$%^&*`~()-+=]{8,15}$/
+	
+	export default {
+		data() {
+			return {
+				mine_code:"",
+				mobile:'',
+				vcode:'',
+				password:'',
+				copypassword:'',
+				send_text:'发送验证码'
+			};
+		},
+		onLoad() {
+			this.mine_code = uni.getStorageSync('mine_code')
+		},
+		methods: {
+			changeBtn() {
+				
+
+			},
+			back(){
+				uni.navigateTo({
+					url:"../login/login"
+				})
+			},
+			
+			
+			send_vcode(){
+				if(this.mobile.length < 11){
+					uni.showToast({
+						icon:'none',
+						title:'请填写正确的手机号'
+					})
+					return
+				}
+				
+				if(this.send_text == "发送验证码"){
+					this.$api.sms_send_v_code({
+						mobile:this.mobile
+					}).then((res)=>{
+						
+						console.log(res.data)
+						
+						if(res.data.code == 3001){
+							uni.showToast({
+								icon:"none",
+								title:"电话号码错误"
+							})
+							this.send_text = "发送验证码"
+						}else if(res.data.code == 3002){
+							uni.showToast({
+								icon:"none",
+								title:"发送失败"
+							})
+							this.send_text = "发送验证码"
+						}else if(res.data.code == 3003){
+							uni.showToast({
+								icon:"none",
+								title:"请填写绑定的手机号"
+							})
+							this.send_text = "发送验证码"
+						}else if(res.data.code == 0){
+							uni.showToast({
+								icon:"none",
+								title:"验证码发送成功"
+							})
+						}
+					})
+				}
+				
+				this.send_text = "已发送"
+				if(this.send_text = "已发送"){
+					uni.showToast({
+						icon:"none",
+						title:"请勿重复发送"
+					})
+				}
+				
+			},
+			
+			changeBtn(){
+				if(this.vcode == ''){
+					uni.showToast({
+						icon:'none',
+						title:'请填写验证码'
+					})
+					return
+				}
+				
+				if(this.password == '' || this.copypassword == ''){
+					uni.showToast({
+						icon:'none',
+						title:'请填写完整信息'
+					})
+					return
+				}
+				
+				if(this.password !== this.copypassword){
+					uni.showToast({
+						icon:'none',
+						title:'两次密码输入不一致'
+					})
+					return
+				}
+				
+				if( !testPassword.test(this.password) ){
+					uni.showToast({
+						icon:'none',
+						title:'密码必须包含大写字母、小写字母、数字和特殊符号且长度在8位至16位之间'
+					})
+					return
+				}
+				
+				this.$api.user_forget_password({
+					mobile:this.mobile,
+					vcode:this.vcode,
+					password:this.password
+				}).then((res)=>{
+					console.log(res)
+					
+					if(res.data.code == 4002){
+						uni.showToast({
+							icon:'none',
+							title:"验证码超时或者错误"
+						})
+						return
+					}else{
+						uni.setStorageSync('login_password',this.password)
+						
+						uni.showToast({
+							icon:'none',
+							title:'密码修改成功、返回登陆'
+						})
+						this.send_text = "发送验证码"
+					}
+					
+					
+					
+					setTimeout(function(){
+						uni.navigateTo({
+							url:"../login/login"
+						})
+					},1000)
+				})
+				
+			}
+
+		}
+
+	}
+</script>
+
+<style lang="scss">
+	page {}
+
+	.content {
+		width: 750rpx;
+		min-height: 100vh;
+		height: 100%;
+		background-image: url(~@/static/login.png);
+		background-size: cover;
+		background-position: center  center;
+		background-repeat: no-repeat;
+		
+		.logo {
+			width: 344rpx;
+			height: 350rpx;
+			margin: 0 auto;
+			padding-top: 100rpx;
+		
+			image {
+				width: 100%;
+				height: 100%;
+			}
+		}
+		
+		.title {
+			margin: 0 auto;
+			margin-top: 32rpx;
+			width: 288rpx;
+			height: 47rpx;
+			font-size: 36rpx;
+			color: #FFFFFF;
+			line-height: 47rpx;
+			text-align: center;
+		}
+		
+		.change_box {
+			padding-top: 40px;
+
+			.item {
+				margin: 0 auto;
+				margin-bottom: 20px;
+				width: 600rpx;
+				height: 45px;
+				background: #FFFFFF;
+				border-radius: 25px;
+				box-sizing: border-box;
+				padding: 0 20px;
+				display: flex;
+				align-items: center;
+
+				.name {
+					width: 150rpx;
+					font-size: 16px;
+					color: #009FE8;
+					line-height: 45px;
+				}
+
+				.input {
+					input {
+						height: 45px;
+						color: #666;
+					}
+				}
+
+			}
+			
+			.send_box{
+				margin: 0 auto;
+				margin-bottom: 20px;
+				width: 600rpx;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				.send_code{
+					background: #FFFFFF;
+					border-radius: 25px;
+					box-sizing: border-box;
+					padding: 0 20px;
+					height: 45px;
+					
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					.name{
+						width: 120rpx;
+						font-size: 16px;
+						font-family: MicrosoftYaHei;
+						color: #009FE8;
+						line-height: 45px;
+					}
+					.input{
+						width: 140rpx;
+					}
+				}
+				.send_btn{
+					width: 220rpx;
+					height: 50px;
+					background: rgba(100, 220, 255, 0.8);
+					border-radius: 25px;
+					text-align: center;
+					line-height: 50px;
+					
+					text {
+						font-size: 34rpx;
+						color: #FFFFFF;
+					}
+				}
+			}
+		}
+
+		.tips {
+			margin: 0 auto;
+			margin-top: 25px;
+			text-align: center;
+			font-size: 14px;
+			color: #ECF0F1;
+			line-height: 40px;
+			text-align: center;
+
+		}
+
+		.change_btn {
+			margin: 40px auto;
+			width: 200px;
+			height: 50px;
+			background: rgba(100, 220, 255, 0.8);
+			border-radius: 25px;
+			text-align: center;
+			line-height: 50px;
+
+			text {
+				font-size: 18px;
+				color: #FFFFFF;
+				letter-spacing: 4px;
+			}
+		}
+	}
+</style>

BIN
pages/my/forget-password/icon/Avatar.png


BIN
pages/my/forget-password/icon/Password.png


+ 13 - 9
pages/my/login/login.vue

@@ -5,7 +5,8 @@
 			<image src="~@/static/logo.png" mode="aspectFit"></image>
 		</view>
 		<view class="title">
-			<text>E信管理</text>
+			<text v-if="mine_code == 'ningdongyunying'">E信管理</text>
+			<text v-if="mine_code == 'zaoquan'">枣泉煤矿</text>
 		</view>
 		<view class="login_box">
 			<view class="item">
@@ -24,13 +25,10 @@
 			</view>
 		</view>
 
-		<view class="tips">
-			<text>忘记密码?请联系信息科管理员重置</text>
+		<view class="tips" @click="go_forget_password()">
+			<text>忘记密码?点击这里重置!</text>
 		</view>
 
-		<!-- <view class="tips">
-			<text>忘记密码?请联系信息科重置密码</text>
-		</view> -->
 
 		<view class="login_btn" @click="loginBtn()">
 			<text>登录</text>
@@ -43,6 +41,7 @@
 	export default {
 		data() {
 			return {
+				mine_code:"",
 				user: {
 					username: '',
 					password: ''
@@ -50,7 +49,7 @@
 			};
 		},
 		onLoad() {
-
+			this.mine_code = uni.getStorageSync('mine_code')
 		},
 		methods: {
 			loginBtn() {
@@ -121,7 +120,13 @@
 				})
 
 			},
-
+			
+			// 重置密码
+			go_forget_password(){
+				uni.navigateTo({
+					url:"../forget-password/forget-password"
+				})
+			}
 		}
 
 	}
@@ -156,7 +161,6 @@
 			width: 288rpx;
 			height: 47rpx;
 			font-size: 36rpx;
-			font-family: MicrosoftYaHei;
 			color: #FFFFFF;
 			line-height: 47rpx;
 			text-align: center;

+ 147 - 0
pages/my/message-reminder/message-detail/message-detail.vue

@@ -0,0 +1,147 @@
+<template>
+	<view>
+		<view class="content">
+			<view class="title">{{detail.title}}</view>
+			<view class="time">{{detail.created_at}}</view>
+			<view class="line">发送人:{{detail.send_user}}</view>
+			<view class="line" v-if="detail.scope != 'all'">接收人:{{detail.scope}}</view>
+			<view class="line" v-if="detail.scope == 'all'">接收人:所有人</view>
+			<view class="inner" v-html="detail.content"></view>
+
+			<view class="section" v-if="detail.files.length > 0">
+				<view class="title">附件:</view>
+				<view>
+					<view class="file_list">
+						<view class="item" v-for="(item,index) in detail.files" :key="index"
+							@click="open_file(item.path)">
+							<view class="left">
+								<view class="icon"></view>
+								<view class="info">
+									<view class="name">{{item.fileName}}</view>
+								</view>
+							</view>
+							<view class="right">
+								<uni-icons type="arrowright"></uni-icons>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				detail: {}
+			};
+		},
+		onLoad() {
+			const self = this
+			const eventChannel = this.getOpenerEventChannel()
+			// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
+			eventChannel.on('acceptDataFromOpenerPage', (data) => {
+				// console.log(data.data)
+				this.detail = data.data
+				console.log(this.detail)
+			})
+
+			// 设置标题
+			uni.setNavigationBarTitle({
+				title: this.detail.title
+			})
+			
+			this.read(this.detail.id)
+		},
+		methods: {
+			// 标为已读
+			read(id) {
+				// console.log(this.detail.id)
+				this.$api.message_read({
+					id: id
+				}).then((res) => {
+					console.log(res)
+					this.get_message_list()
+				})
+			},
+			// 预览文件
+			open_file(path) {
+				uni.downloadFile({
+					url: path,
+					success: function(res) {
+						var filePath = res.tempFilePath;
+						uni.openDocument({
+							filePath: filePath,
+							success: function(res) {
+								console.log('打开文档成功');
+							}
+						});
+					}
+				});
+			},
+		}
+
+	}
+</script>
+
+<style lang="scss">
+	.content {
+		width: 749rpx;
+		box-sizing: border-box;
+		padding: 24rpx;
+	}
+
+	.title {
+		line-height: 30px;
+	}
+
+	.time {
+		line-height: 30px;
+		font-size: 14px;
+		color: #999;
+	}
+
+	.line {
+		line-height: 30px;
+		font-size: 16px;
+	}
+
+	.inner {
+		margin: 20px 0;
+		text-indent: 2rem;
+		word-break: break-all;
+		overflow: hidden;
+	}
+
+	.file_list {
+		.item {
+			height: 30px;
+
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+
+			border-bottom: 1px solid #ECF0F1;
+			padding: 8px 0;
+
+			.left {
+				display: flex;
+
+				.icon {}
+
+				.info {
+					.name {
+						font-size: 16px;
+						font-family: MicrosoftYaHei;
+						color: #2C3E50;
+					}
+
+				}
+			}
+
+			.right {}
+		}
+	}
+</style>

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

@@ -0,0 +1,217 @@
+<template>
+	<view class="content">
+		<view class="search"></view>
+		<view class="list">
+			<view class="item" v-for="(item,index) in list" :key="index" @click="read(item)">
+				<view class="top">
+					<view class="left">
+						<view class="name">{{item.title}}</view>
+						<view class="time">{{item.created_at}} {{item.send_user}}</view>
+					</view>
+					<view class="right">
+						<view class="tip" v-if="item.read == 0">未读</view>
+						<view class="tip" v-if="item.read == 1" style="background-color: #4CD964;">已读</view>
+					</view>
+				</view>
+				<view class="inner">
+					<!-- {{item.content}} -->
+					<view v-html="item.content"></view>
+				</view>
+			</view>
+		</view>
+		<view class="bottom">
+			<view class="title" @click="get_all_list()">所有消息</view>
+			<view class="title" @click="get_unread_list('unread')">未读消息</view>
+			<view class="title" @click="read_all()">全部标已读</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				type:"",
+				page:1,
+				list: []
+			};
+		},
+		onLoad() {
+			this.get_message_list(this.page)
+		},
+		onShow() {
+			this.page = 1,
+			this.type = ""
+			this.list = []
+			this.get_message_list(this.page)
+			this.$forceUpdate()
+		},
+		onReachBottom(){
+			this.page++
+			// console.log(this.page)
+			this.get_message_list()
+		},
+		methods: {
+			get_message_list() {
+				uni.showLoading()
+				this.$api.message_list({
+					type: this.type,
+					page:this.page,
+					page_size:10
+				}).then((res) => {
+					console.log(res.data.data.data)
+					// this.list = res.data.data.data
+					this.list = this.list.concat(res.data.data.data)
+					uni.hideLoading()
+				})
+			},
+			read(item) {
+				this.$api.message_read({
+					id:item.id
+				}).then((res)=>{
+					console.log(res)
+					this.get_message_list()
+				})
+
+				uni.navigateTo({
+					url: "message-detail/message-detail",
+					success: function(res) {
+						// 通过eventChannel向被打开页面传送数据
+						res.eventChannel.emit('acceptDataFromOpenerPage', {
+							data: item
+						})
+					}
+				})
+			},
+			read_all() {
+				uni.showToast({
+					icon: "none",
+					title: "全部已读"
+				})
+				this.$api.message_read({
+
+				}).then((res) => {
+					console.log(res)
+					this.page = 1,
+					this.type = ""
+					this.list = []
+					this.get_message_list()
+				})
+			},
+			get_all_list() {
+				this.page = 1,
+				this.type = ""
+				this.list = []
+				this.get_message_list()
+			},
+			get_unread_list() {
+				this.page = 1,
+				this.type = "unread"
+				this.list = []
+				this.get_message_list()
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #f1f1f1;
+	}
+
+	.content {
+		width: 749rpx;
+	}
+
+	.list {
+		width: 749rpx;
+		box-sizing: border-box;
+		padding: 24rpx;
+
+		margin-bottom: 80px;
+
+		.item {
+			width: 700rpx;
+			background-color: #FFFFFF;
+			box-sizing: border-box;
+			padding: 10px 20rpx;
+
+			margin-bottom: 10px;
+
+			.top {
+				width: 660rpx;
+				display: flex;
+				justify-content: space-between;
+
+				.left {
+					width: 540rpx;
+
+					.name {
+						line-height: 25px;
+						overflow: hidden;
+						/*超出部分隐藏*/
+						white-space: nowrap;
+						/*不换行*/
+						text-overflow: ellipsis;
+						/*超出部分文字以...显示*/
+					}
+
+					.time {
+						line-height: 30px;
+						font-size: 14px;
+						color: #999;
+					}
+				}
+
+				.right {
+					width: 88rpx;
+
+					.tip {
+						text-align: center;
+						line-height: 25px;
+						background-color: #DD524D;
+						font-size: 12px;
+						color: #FFFFFF;
+					}
+				}
+			}
+
+			.inner {
+				width: 660rpx;
+				text-indent: 2em;
+				font-size: 14px;
+
+				overflow: hidden;
+				word-break: break-all;
+				text-overflow: ellipsis;
+				display: -webkit-box;
+				-webkit-box-orient: vertical;
+				-webkit-line-clamp: 4;
+			}
+		}
+	}
+
+	.bottom {
+		background-color: #FFFFFF;
+		position: fixed;
+		left: 0;
+		bottom: 0;
+
+		border-top: 1px solid #eee;
+		height: 50px;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+
+		.title {
+			width: 249rpx;
+			padding: 5px 0;
+			text-align: center;
+			border-right: 1px solid #eee;
+		}
+
+		.title:last-child {
+			border-right: none;
+		}
+	}
+</style>

+ 125 - 8
pages/tabbar/index/index.vue

@@ -2,36 +2,90 @@
 	<view>
 		<t-i-navbar></t-i-navbar>
 		<!-- notice -->
-		<t-i-notice :base_url="base_url"></t-i-notice>
+		<t-i-notice :text="text"></t-i-notice>
 		<!-- banner -->
-		<t-i-banner :base_url="base_url"></t-i-banner>
+		<t-i-banner :banner="banners"></t-i-banner>
 		<!-- 固定入口 -->
-		<t-i-icon :base_url="base_url"></t-i-icon>
+		<t-i-icon :iconList="iconList" :mine_code="mine_code"></t-i-icon>
 		<!-- 常用功能 -->
-		<t-i-common></t-i-common>
+		<t-i-common v-if="mine_code != 'zaoquan'"></t-i-common>
 		<!-- 新闻列表 -->
-		<t-i-news :base_url="base_url"></t-i-news>
+		<t-i-news :newsList="newsList" :mine_code="mine_code"></t-i-news>
 
 	</view>
 </template>
 
 <script>
+	// 版本控制
+	import upApp from "@/uni_modules/uni-upgrade-center-app/utils/check-update"
+	
 	export default {
 		data() {
 			return {
 				// 当前煤矿编码
 				mine_code: "",
-				
+
 				// 首页接口的基础请求路径  默认为当前矿编码的基础路径
-				base_url: " "
+				base_url: " ",
+				
+				
+				// 轮播图
+				banners:[],
+				// 新闻列表
+				newsList:"",
+				// 值班公告
+				text: "暂无公告。",
+				// 固定入口
+				iconList:[]
 
 			}
 		},
+		onPullDownRefresh() {
+			uni.reLaunch({
+				url: "./index"
+			})
+			setTimeout(function() {
+				uni.stopPullDownRefresh();
+			}, 1000);
+		
+		},
 		onLoad() {
 			// 初始化当前煤矿编码
 			this.mine_code = uni.getStorageSync('mine_code')
 			
-
+			// 检查更新
+			upApp()
+			
+			// token过期验证
+			this.$api.worksheet_classify_list({
+			
+			}).then((res) => {
+				// console.log(res)
+				if (res.data.code == 401) {
+					uni.showToast({
+						icon: "none",
+						title: "登录失效、请重新登录"
+					})
+					setTimeout(function() {
+						uni.redirectTo({
+							url: "../../my/login/login"
+						})
+					}, 2000)
+				} else {
+					// console.log(res)
+				}
+			})
+			
+		},
+		onShow() {
+			// E信-切换矿
+			uni.$on('update_kuang', (data) => {
+				console.log('监听到事件来自 update_kuang ,携带参数 msg 为:' + data.msg);
+				this.mine_code = data.msg
+				console.log(this.mine_code)
+			})
+			this.$forceUpdate()
+			
 			// 根据矿编码切换首页接口不同的请求基础路径
 			switch (this.mine_code) {
 				case 'ningdongyunying':
@@ -40,9 +94,72 @@
 				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_banner()
+			// 获取首页新闻列表
+			this.getNews()
+			// 值班公告
+			this.get_notice()
+			// 固定入口
+			this.get_list()
+		},
+		methods:{
+			// 获取轮播图
+			get_banner(){
+				uni.request({
+					url: this.base_url + "/scrollImg/list",
+					method: "GET",
+					success: (res) => {
+						this.banners = res.data.data.data
+					}
+				})
+			},
+			// 请求新闻动态
+			getNews() {
+				uni.request({
+					url: this.base_url + "/article/list",
+					method: "GET",
+					data: {
+						pageSize: 4
+					},
+					success: (res) => {
+						this.newsList = res.data.data.data
+					}
+				})
+			},
+			// 值班公告
+			get_notice() {
+				uni.request({
+					url: this.base_url + "/notice/list",
+					method: "GET",
+					success: (res) => {
+						if(!res.data.data.content){
+							this.text = res.data.data.message
+						}else{
+							this.text = res.data.data.content
+						}
+					}
+				})
+			},
+			// 固定入口
+			get_list(){
+				uni.request({
+					url: this.base_url + "/homeNav/list",
+					method: "GET",
+					success: (res) => {
+						this.iconList = res.data.data.data.slice(0,5)
+					}
+				})
+			}
+			
 		}
 
 	}

+ 3 - 0
pages/tabbar/my/my.vue

@@ -39,6 +39,9 @@
 </script>
 
 <style lang="scss">
+	page{
+		margin-bottom: 80rpx;
+	}
 	.top_bg {
 		height: 60px;
 		background: #009FE8;

+ 4 - 0
pages/tabbar/production/production.vue

@@ -8,6 +8,10 @@
 		<view v-if="mine_code == 'shicaocun'">
 			<t-p-shicaocun></t-p-shicaocun>
 		</view>
+		<!-- 枣泉 -->
+		<view v-if="mine_code == 'zaoquan'">
+			<t-p-zaoquan></t-p-zaoquan>
+		</view>
 		
 		
 	</view>

BIN
static/qidongtu.png


+ 160 - 0
uni_modules/mp-html/README.md

@@ -0,0 +1,160 @@
+## 功能介绍
+- 全端支持(含 `v3、NVUE`)
+- 支持丰富的标签(包括 `table`、`video`、`svg` 等)
+- 支持丰富的事件效果(自动预览图片、链接处理等)
+- 支持设置占位图(加载中、出错时、预览时)
+- 支持锚点跳转、长按复制等丰富功能
+- 支持大部分 *html* 实体
+- 丰富的插件(关键词搜索、内容 **编辑** 等)
+- 效率高、容错性强且轻量化
+
+查看 [功能介绍](https://jin-yufeng.gitee.io/mp-html/#/overview/feature) 了解更多
+
+## 使用方法
+- 源码方式  
+  1. 点击上方的使用 `HBuilder X` 导入插件或将下载的插件包拷贝到项目根目录下  
+     由于插件市场的 **非 uni_modules 版本** 无法更新,若需使用请从 [github](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 或 [gitee](https://gitee.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 获取最新版本
+  2. 在需要使用页面的 `(n)vue` 文件中添加  
+     ```html
+     <mp-html :content="html" />
+     ```
+     ```javascript
+     import mpHtml from '@/components/mp-html/mp-html'
+     export default {
+       // HBuilderX 2.5.5+ 可以通过 easycom 自动引入
+       components: {
+         mpHtml
+       },
+       data() {
+         return {
+           html: '<div>Hello World!</div>'
+         }
+       }
+     }
+     ```
+
+- npm 方式  
+  1. 在项目根目录下执行  
+     ```bash
+     npm install mp-html
+     ```
+  2. 在需要使用页面的 `(n)vue` 文件中添加  
+     ```html
+     <mp-html :content="html" />
+     ```
+     ```javascript
+     import mpHtml from 'mp-html/dist/uni-app/components/mp-html/mp-html'
+     export default {
+       // 不可省略
+       components: {
+         mpHtml
+       },
+       data() {
+         return {
+           html: '<div>Hello World!</div>'
+         }
+       }
+     }
+     ```
+  
+  使用 *cli* 方式运行的项目,通过 *npm* 方式引入时,需要在 *vue.config.js* 中配置 *transpileDependencies*,详情可见 [#330](https://github.com/jin-yufeng/mp-html/issues/330#issuecomment-913617687)  
+  如果在 **nvue** 中使用还要将 `dist/uni-app/static` 目录下的内容拷贝到项目的 `static` 目录下,否则无法运行  
+
+查看 [快速开始](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart) 了解更多
+
+## 组件属性
+
+| 属性 | 类型 | 默认值 | 说明 |
+|:---:|:---:|:---:|---|
+| container-style | String |  | 容器的样式([2.1.0+](https://jin-yufeng.gitee.io/mp-html/#/changelog/changelog#v210)) |
+| content | String |  | 用于渲染的 html 字符串 |
+| copy-link | Boolean | true | 是否允许外部链接被点击时自动复制 |
+| domain | String |  | 主域名(用于链接拼接) |
+| error-img | String |  | 图片出错时的占位图链接 |
+| lazy-load | Boolean | false | 是否开启图片懒加载 |
+| loading-img | String |  | 图片加载过程中的占位图链接 |
+| pause-video | Boolean | true | 是否在播放一个视频时自动暂停其他视频 |
+| preview-img | Boolean | true | 是否允许图片被点击时自动预览 |
+| scroll-table | Boolean | false | 是否给每个表格添加一个滚动层使其能单独横向滚动 |
+| selectable | Boolean | false | 是否开启文本长按复制 |
+| set-title | Boolean | true | 是否将 title 标签的内容设置到页面标题 |
+| show-img-menu | Boolean | true | 是否允许图片被长按时显示菜单 |
+| tag-style | Object |  | 设置标签的默认样式 |
+| use-anchor | Boolean | false | 是否使用锚点链接 |
+
+查看 [属性](https://jin-yufeng.gitee.io/mp-html/#/basic/prop) 了解更多
+
+## 组件事件
+
+| 名称 | 触发时机 |
+|:---:|---|
+| load | dom 树加载完毕时 |
+| ready | 图片加载完毕时 |
+| error | 发生渲染错误时 |
+| imgtap | 图片被点击时 |
+| linktap | 链接被点击时 |
+
+查看 [事件](https://jin-yufeng.gitee.io/mp-html/#/basic/event) 了解更多
+
+## api
+组件实例上提供了一些 `api` 方法可供调用
+
+| 名称 | 作用 |
+|:---:|---|
+| in | 将锚点跳转的范围限定在一个 scroll-view 内 |
+| navigateTo | 锚点跳转 |
+| getText | 获取文本内容 |
+| getRect | 获取富文本内容的位置和大小 |
+| setContent | 设置富文本内容 |
+| imgList | 获取所有图片的数组 |
+
+查看 [api](https://jin-yufeng.gitee.io/mp-html/#/advanced/api) 了解更多
+
+## 插件扩展  
+除基本功能外,本组件还提供了丰富的扩展,可按照需要选用
+
+| 名称 | 作用 |
+|:---:|---|
+| audio | 音乐播放器 |
+| editable | 富文本编辑([示例项目](https://6874-html-foe72-1259071903.tcb.qcloud.la/editable.zip?sign=cc0017be203fb3dbca62d33a0c15792e&t=1608447445)) |
+| emoji | 解析 emoji |
+| highlight | 代码块高亮显示 |
+| markdown | 渲染 markdown |
+| search | 关键词搜索 |
+| style | 匹配 style 标签中的样式 |
+| txv-video | 使用腾讯视频 |
+| img-cache | 图片缓存 by [@PentaTea](https://github.com/PentaTea) |
+
+从插件市场导入的包中 **不含有** 扩展插件,需要使用插件参考以下方法:  
+1. 获取完整组件包  
+   ```bash
+   npm install mp-html
+   ```
+2. 编辑 `tools/config.js` 中的 `plugins` 项,选择需要的插件  
+3. 生成新的组件包  
+   在 `node_modules/mp-html` 目录下执行  
+   ```bash
+   npm install
+   npm run build:uni-app
+   ```
+4. 拷贝 `dist/uni-app` 中的内容到项目根目录  
+
+查看 [插件](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin) 了解更多
+
+## 示例体验
+![富文本插件](https://gitee.com/jin-yufeng/mp-html/raw/master/docs/assets/case/富文本插件.jpg)
+
+## 关于 nvue
+`nvue` 使用原生渲染,不支持部分 `css` 样式,为实现和 `html` 相同的效果,组件内部通过 `web-view` 进行渲染,性能上差于原生,根据 `weex` 官方建议,`web` 标签仅应用在非常规的降级场景。因此,如果通过原生的方式(如 `richtext`)能够满足需要,则不建议使用本组件,如果有较多的富文本内容,则可以直接使用 `vue` 页面  
+由于渲染方式与其他端不同,有以下限制:  
+1. 不支持 `lazy-load` 属性
+2. 视频不支持全屏播放
+
+纯 `nvue` 模式下,[此问题](https://ask.dcloud.net.cn/question/119678) 修复前,不支持通过 `uni_modules` 引入,需要本地引入(将 [dist/uni-app](https://github.com/jin-yufeng/mp-html/tree/master/dist/uni-app) 中的内容拷贝到项目根目录下)  
+
+## 问题反馈
+遇到问题时,请先查阅 [常见问题](https://jin-yufeng.gitee.io/mp-html/#/question/faq) 和 [issue](https://github.com/jin-yufeng/mp-html/issues) 中是否已有相同的问题  
+可通过 [issue](https://github.com/jin-yufeng/mp-html/issues/new/choose) 、插件问答或发送邮件到 [mp_html@126.com](mailto:mp_html@126.com) 提问,不建议在评论区提问(不方便回复)  
+提问请严格按照 [issue 模板](https://github.com/jin-yufeng/mp-html/issues/new/choose) ,描述清楚使用环境、`html` 内容或可复现的 `demo` 项目以及复现方式,对于 **描述不清**、**无法复现** 或重复的问题将不予回复  
+
+查看 [问题反馈](https://jin-yufeng.gitee.io/mp-html/#/question/feedback) 了解更多

+ 62 - 0
uni_modules/mp-html/changelog.md

@@ -0,0 +1,62 @@
+## v2.2.0(2021-10-12)
+1. `A` 增加 `customElements` 配置项,便于添加自定义功能性标签 [详细](https://github.com/jin-yufeng/mp-html/issues/350)
+2. `A` `editable` 插件增加切换音视频自动播放状态的功能 [详细](https://github.com/jin-yufeng/mp-html/pull/341) by [@leeseett](https://github.com/leeseett)
+3. `A` `editable` 插件删除媒体标签时触发 `remove` 事件,便于删除已上传的文件
+4. `U` `editable` 插件 `insertImg` 方法支持同时插入多张图片 [详细](https://github.com/jin-yufeng/mp-html/issues/342)
+5. `U` `editable` 插入图片和音视频时支持拼接 `domian` 主域名
+6. `F` 修复了内部链接参数中包含 `://` 时被认为是外部链接的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/356)
+7. `F` 修复了部分 `svg` 标签名或属性名大小写不正确时不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/351)
+8. `F` 修复了 `nvue` 页面运行到非 `app` 平台时可能样式错误的问题
+## v2.1.5(2021-08-13)
+1. `A` 增加支持标签的 `dir` 属性
+2. `F` 修复了 `ruby` 标签文字与拼音没有居中对齐的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/325)
+3. `F` 修复了音视频标签内有 `a` 标签时可能无法播放的问题
+4. `F` 修复了 `externStyle` 中的 `class` 名包含下划线或数字时可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326)
+5. `F` 修复了 `h5` 端引入 `externStyle` 可能不生效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/326)
+## v2.1.4(2021-07-14)
+1. `F` 修复了 `rt` 标签无法设置样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/318)
+2. `F` 修复了表格中有单元格同时合并行和列时可能显示不正确的问题
+3. `F` 修复了 `app` 端无法关闭图片长按菜单的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/322)
+4. `F` 修复了 `editable` 插件只能添加图片链接不能修改的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/312) by [@leeseett](https://github.com/leeseett)
+## v2.1.3(2021-06-12)
+1. `A` `editable` 插件增加 `insertTable` 方法
+2. `U` `editable` 插件支持编辑表格中的空白单元格 [详细](https://github.com/jin-yufeng/mp-html/issues/310)
+3. `F` 修复了 `externStyle` 中使用伪类可能失效的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/298)
+4. `F` 修复了多个组件同时使用时 `tag-style` 属性时可能互相影响的问题 [详细](https://github.com/jin-yufeng/mp-html/pull/305) by [@woodguoyu](https://github.com/woodguoyu)
+5. `F` 修复了包含 `linearGradient` 的 `svg` 可能无法显示的问题
+6. `F` 修复了编译到头条小程序时可能报错的问题
+7. `F` 修复了 `nvue` 端不触发 `click` 事件的问题
+8. `F` 修复了 `editable` 插件尾部插入时无法撤销的问题
+9. `F` 修复了 `editable` 插件的 `insertHtml` 方法只能在末尾插入的问题
+10. `F` 修复了 `editable` 插件插入音频不显示的问题
+## v2.1.2(2021-04-24)
+1. `A` 增加了 [img-cache](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#img-cache) 插件,可以在 `app` 端缓存图片 [详细](https://github.com/jin-yufeng/mp-html/issues/292) by [@PentaTea](https://github.com/PentaTea)
+2. `U` 支持通过 `container-style` 属性设置 `white-space` 来保留连续空格和换行符 [详细](https://jin-yufeng.gitee.io/mp-html/#/question/faq#space)
+3. `U` 代码风格符合 [standard](https://standardjs.com) 标准
+4. `U` `editable` 插件编辑状态下支持预览视频 [详细](https://github.com/jin-yufeng/mp-html/issues/286)
+5. `F` 修复了 `svg` 标签内嵌 `svg` 时无法显示的问题
+6. `F` 修复了编译到支付宝和头条小程序时部分区域不可复制的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/291)
+## v2.1.1(2021-04-09)
+1. 修复了对 `p` 标签设置 `tag-style` 可能不生效的问题
+2. 修复了 `svg` 标签中的文本无法显示的问题
+3. 修复了使用 `editable` 插件编辑表格时可能报错的问题
+4. 修复了使用 `highlight` 插件运行到头条小程序时可能没有样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/280)
+5. 修复了使用 `editable` 插件 `editable` 属性为 `false` 时会报错的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/284)
+6. 修复了 `style` 插件连续子选择器失效的问题
+7. 修复了 `editable` 插件无法修改图片和字体大小的问题
+## v2.1.0.2(2021-03-21)
+修复了 `nvue` 端使用可能报错的问题
+## v2.1.0(2021-03-20)
+1. `A` 增加了 [container-style](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#container-style) 属性 [详细](https://gitee.com/jin-yufeng/mp-html/pulls/1)
+2. `A` 增加支持 `strike` 标签
+3. `A` `editable` 插件增加 `placeholder` 属性 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable)
+4. `A` `editable` 插件增加 `insertHtml` 方法 [详细](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#editable)
+5. `U` 外部样式支持标签名选择器 [详细](https://jin-yufeng.gitee.io/mp-html/#/overview/quickstart#setting)
+6. `F` 修复了 `nvue` 端部分情况下可能不显示的问题
+## v2.0.5(2021-03-12)
+1. `U` [linktap](https://jin-yufeng.gitee.io/mp-html/#/basic/event#linktap) 事件增加返回内部文本内容 `innerText` [详细](https://github.com/jin-yufeng/mp-html/issues/271)
+2. `U` [selectable](https://jin-yufeng.gitee.io/mp-html/#/basic/prop#selectable) 属性设置为 `force` 时能够在微信 `iOS` 端生效(文本块会变成 `inline-block`) [详细](https://github.com/jin-yufeng/mp-html/issues/267)
+3. `F` 修复了部分情况下竖向无法滚动的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/182)
+4. `F` 修复了多次修改富文本数据时部分内容可能不显示的问题
+5. `F` 修复了 [腾讯视频](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#txv-video) 插件可能无法播放的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/265)
+6. `F` 修复了 [highlight](https://jin-yufeng.gitee.io/mp-html/#/advanced/plugin#highlight) 插件没有设置高亮语言时没有应用默认样式的问题 [详细](https://github.com/jin-yufeng/mp-html/issues/276) by [@fuzui](https://github.com/fuzui)

+ 432 - 0
uni_modules/mp-html/components/mp-html/mp-html.vue

@@ -0,0 +1,432 @@
+<template>
+  <view id="_root" :class="(selectable?'_select ':'')+'_root'" :style="containerStyle">
+    <slot v-if="!nodes[0]" />
+    <!-- #ifndef APP-PLUS-NVUE -->
+    <node v-else :childs="nodes" :opts="[lazyLoad,loadingImg,errorImg,showImgMenu]" name="span" />
+    <!-- #endif -->
+    <!-- #ifdef APP-PLUS-NVUE -->
+    <web-view ref="web" src="/uni_modules/mp-html/static/app-plus/mp-html/local.html" :style="'margin-top:-2px;height:' + height + 'px'" @onPostMessage="_onMessage" />
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+/**
+ * mp-html v2.2.0
+ * @description 富文本组件
+ * @tutorial https://github.com/jin-yufeng/mp-html
+ * @property {String} container-style 容器的样式
+ * @property {String} content 用于渲染的 html 字符串
+ * @property {Boolean} copy-link 是否允许外部链接被点击时自动复制
+ * @property {String} domain 主域名,用于拼接链接
+ * @property {String} error-img 图片出错时的占位图链接
+ * @property {Boolean} lazy-load 是否开启图片懒加载
+ * @property {string} loading-img 图片加载过程中的占位图链接
+ * @property {Boolean} pause-video 是否在播放一个视频时自动暂停其他视频
+ * @property {Boolean} preview-img 是否允许图片被点击时自动预览
+ * @property {Boolean} scroll-table 是否给每个表格添加一个滚动层使其能单独横向滚动
+ * @property {Boolean | String} selectable 是否开启长按复制
+ * @property {Boolean} set-title 是否将 title 标签的内容设置到页面标题
+ * @property {Boolean} show-img-menu 是否允许图片被长按时显示菜单
+ * @property {Object} tag-style 标签的默认样式
+ * @property {Boolean | Number} use-anchor 是否使用锚点链接
+ * @event {Function} load dom 结构加载完毕时触发
+ * @event {Function} ready 所有图片加载完毕时触发
+ * @event {Function} imgTap 图片被点击时触发
+ * @event {Function} linkTap 链接被点击时触发
+ * @event {Function} error 媒体加载出错时触发
+ */
+// #ifndef APP-PLUS-NVUE
+import node from './node/node'
+// #endif
+const plugins=[]
+const Parser = require('./parser')
+// #ifdef APP-PLUS-NVUE
+const dom = weex.requireModule('dom')
+// #endif
+export default {
+  name: 'mp-html',
+  data () {
+    return {
+      nodes: [],
+      // #ifdef APP-PLUS-NVUE
+      height: 3
+      // #endif
+    }
+  },
+  props: {
+    containerStyle: {
+      type: String,
+      default: ''
+    },
+    content: String,
+    copyLink: {
+      type: [Boolean, String],
+      default: true
+    },
+    domain: String,
+    errorImg: {
+      type: String,
+      default: ''
+    },
+    lazyLoad: {
+      type: [Boolean, String],
+      default: false
+    },
+    loadingImg: {
+      type: String,
+      default: ''
+    },
+    pauseVideo: {
+      type: [Boolean, String],
+      default: true
+    },
+    previewImg: {
+      type: [Boolean, String],
+      default: true
+    },
+    scrollTable: [Boolean, String],
+    selectable: [Boolean, String],
+    setTitle: {
+      type: [Boolean, String],
+      default: true
+    },
+    showImgMenu: {
+      type: [Boolean, String],
+      default: true
+    },
+    tagStyle: Object,
+    useAnchor: [Boolean, Number]
+  },
+  // #ifndef APP-PLUS-NVUE
+  components: {
+    node
+  },
+  // #endif
+  watch: {
+    content (content) {
+      this.setContent(content)
+    }
+  },
+  created () {
+    this.plugins = []
+    for (let i = plugins.length; i--;) {
+      this.plugins.push(new plugins[i](this))
+    }
+  },
+  mounted () {
+    if (this.content && !this.nodes.length) {
+      this.setContent(this.content)
+    }
+  },
+  beforeDestroy () {
+    this._hook('onDetached')
+    clearInterval(this._timer)
+  },
+  methods: {
+    /**
+     * @description 将锚点跳转的范围限定在一个 scroll-view 内
+     * @param {Object} page scroll-view 所在页面的示例
+     * @param {String} selector scroll-view 的选择器
+     * @param {String} scrollTop scroll-view scroll-top 属性绑定的变量名
+     */
+    in (page, selector, scrollTop) {
+      // #ifndef APP-PLUS-NVUE
+      if (page && selector && scrollTop) {
+        this._in = {
+          page,
+          selector,
+          scrollTop
+        }
+      }
+      // #endif
+    },
+
+    /**
+     * @description 锚点跳转
+     * @param {String} id 要跳转的锚点 id
+     * @param {Number} offset 跳转位置的偏移量
+     * @returns {Promise}
+     */
+    navigateTo (id, offset) {
+      return new Promise((resolve, reject) => {
+        if (!this.useAnchor) {
+          reject(Error('Anchor is disabled'))
+          return
+        }
+        offset = offset || parseInt(this.useAnchor) || 0
+        // #ifdef APP-PLUS-NVUE
+        if (!id) {
+          dom.scrollToElement(this.$refs.web, {
+            offset
+          })
+          resolve()
+        } else {
+          this._navigateTo = {
+            resolve,
+            reject,
+            offset
+          }
+          this.$refs.web.evalJs('uni.postMessage({data:{action:"getOffset",offset:(document.getElementById(' + id + ')||{}).offsetTop}})')
+        }
+        // #endif
+        // #ifndef APP-PLUS-NVUE
+        let deep = ' '
+        // #ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO
+        deep = '>>>'
+        // #endif
+        const selector = uni.createSelectorQuery()
+          // #ifndef MP-ALIPAY
+          .in(this._in ? this._in.page : this)
+          // #endif
+          .select((this._in ? this._in.selector : '._root') + (id ? `${deep}#${id}` : '')).boundingClientRect()
+        if (this._in) {
+          selector.select(this._in.selector).scrollOffset()
+            .select(this._in.selector).boundingClientRect()
+        } else {
+          // 获取 scroll-view 的位置和滚动距离
+          selector.selectViewport().scrollOffset() // 获取窗口的滚动距离
+        }
+        selector.exec(res => {
+          if (!res[0]) {
+            reject(Error('Label not found'))
+            return
+          }
+          const scrollTop = res[1].scrollTop + res[0].top - (res[2] ? res[2].top : 0) + offset
+          if (this._in) {
+            // scroll-view 跳转
+            this._in.page[this._in.scrollTop] = scrollTop
+          } else {
+            // 页面跳转
+            uni.pageScrollTo({
+              scrollTop,
+              duration: 300
+            })
+          }
+          resolve()
+        })
+        // #endif
+      })
+    },
+
+    /**
+     * @description 获取文本内容
+     * @return {String}
+     */
+    getText (nodes) {
+      let text = '';
+      (function traversal (nodes) {
+        for (let i = 0; i < nodes.length; i++) {
+          const node = nodes[i]
+          if (node.type === 'text') {
+            text += node.text.replace(/&amp;/g, '&')
+          } else if (node.name === 'br') {
+            text += '\n'
+          } else {
+            // 块级标签前后加换行
+            const isBlock = node.name === 'p' || node.name === 'div' || node.name === 'tr' || node.name === 'li' || (node.name[0] === 'h' && node.name[1] > '0' && node.name[1] < '7')
+            if (isBlock && text && text[text.length - 1] !== '\n') {
+              text += '\n'
+            }
+            // 递归获取子节点的文本
+            if (node.children) {
+              traversal(node.children)
+            }
+            if (isBlock && text[text.length - 1] !== '\n') {
+              text += '\n'
+            } else if (node.name === 'td' || node.name === 'th') {
+              text += '\t'
+            }
+          }
+        }
+      })(nodes || this.nodes)
+      return text
+    },
+
+    /**
+     * @description 获取内容大小和位置
+     * @return {Promise}
+     */
+    getRect () {
+      return new Promise((resolve, reject) => {
+        uni.createSelectorQuery()
+          // #ifndef MP-ALIPAY
+          .in(this)
+          // #endif
+          .select('#_root').boundingClientRect().exec(res => res[0] ? resolve(res[0]) : reject(Error('Root label not found')))
+      })
+    },
+
+    /**
+     * @description 设置内容
+     * @param {String} content html 内容
+     * @param {Boolean} append 是否在尾部追加
+     */
+    setContent (content, append) {
+      if (!append || !this.imgList) {
+        this.imgList = []
+      }
+      const nodes = new Parser(this).parse(content)
+      // #ifdef APP-PLUS-NVUE
+      if (this._ready) {
+        this._set(nodes, append)
+      }
+      // #endif
+      this.$set(this, 'nodes', append ? (this.nodes || []).concat(nodes) : nodes)
+
+      // #ifndef APP-PLUS-NVUE
+      this._videos = []
+      this.$nextTick(() => {
+        this._hook('onLoad')
+        this.$emit('load')
+      })
+
+      // 等待图片加载完毕
+      let height
+      clearInterval(this._timer)
+      this._timer = setInterval(() => {
+        this.getRect().then(rect => {
+          // 350ms 总高度无变化就触发 ready 事件
+          if (rect.height === height) {
+            this.$emit('ready', rect)
+            clearInterval(this._timer)
+          }
+          height = rect.height
+        }).catch(() => { })
+      }, 350)
+      // #endif
+    },
+
+    /**
+     * @description 调用插件钩子函数
+     */
+    _hook (name) {
+      for (let i = plugins.length; i--;) {
+        if (this.plugins[i][name]) {
+          this.plugins[i][name]()
+        }
+      }
+    },
+
+    // #ifdef APP-PLUS-NVUE
+    /**
+     * @description 设置内容
+     */
+    _set (nodes, append) {
+      this.$refs.web.evalJs('setContent(' + JSON.stringify(nodes) + ',' + JSON.stringify([this.containerStyle.replace(/(?:margin|padding)[^;]+/g, ''), this.errorImg, this.loadingImg, this.pauseVideo, this.scrollTable, this.selectable]) + ',' + append + ')')
+    },
+
+    /**
+     * @description 接收到 web-view 消息
+     */
+    _onMessage (e) {
+      const message = e.detail.data[0]
+      switch (message.action) {
+        // web-view 初始化完毕
+        case 'onJSBridgeReady':
+          this._ready = true
+          if (this.nodes) {
+            this._set(this.nodes)
+          }
+          break
+        // 内容 dom 加载完毕
+        case 'onLoad':
+          this.height = message.height
+          this._hook('onLoad')
+          this.$emit('load')
+          break
+        // 所有图片加载完毕
+        case 'onReady':
+          this.getRect().then(res => {
+            this.$emit('ready', res)
+          }).catch(() => { })
+          break
+        // 总高度发生变化
+        case 'onHeightChange':
+          this.height = message.height
+          break
+        // 图片点击
+        case 'onImgTap':
+          this.$emit('imgtap', message.attrs)
+          if (this.previewImg) {
+            uni.previewImage({
+              current: parseInt(message.attrs.i),
+              urls: this.imgList
+            })
+          }
+          break
+        // 链接点击
+        case 'onLinkTap': {
+          const href = message.attrs.href
+          this.$emit('linktap', message.attrs)
+          if (href) {
+            // 锚点跳转
+            if (href[0] === '#') {
+              if (this.useAnchor) {
+                dom.scrollToElement(this.$refs.web, {
+                  offset: message.offset
+                })
+              }
+            } else if (href.includes('://')) {
+              // 打开外链
+              if (this.copyLink) {
+                plus.runtime.openWeb(href)
+              }
+            } else {
+              uni.navigateTo({
+                url: href,
+                fail () {
+                  uni.switchTab({
+                    url: href
+                  })
+                }
+              })
+            }
+          }
+          break
+        }
+        // 获取到锚点的偏移量
+        case 'getOffset':
+          if (typeof message.offset === 'number') {
+            dom.scrollToElement(this.$refs.web, {
+              offset: message.offset + this._navigateTo.offset
+            })
+            this._navigateTo.resolve()
+          } else {
+            this._navigateTo.reject(Error('Label not found'))
+          }
+          break
+        // 点击
+        case 'onClick':
+          this.$emit('tap')
+          this.$emit('click')
+          break
+        // 出错
+        case 'onError':
+          this.$emit('error', {
+            source: message.source,
+            attrs: message.attrs
+          })
+      }
+    }
+    // #endif
+  }
+}
+</script>
+
+<style>
+/* #ifndef APP-PLUS-NVUE */
+/* 根节点样式 */
+._root {
+  padding: 1px 0;
+  overflow-x: auto;
+  overflow-y: hidden;
+  -webkit-overflow-scrolling: touch;
+}
+
+/* 长按复制 */
+._select {
+  user-select: text;
+}
+/* #endif */
+</style>

+ 524 - 0
uni_modules/mp-html/components/mp-html/node/node.vue

@@ -0,0 +1,524 @@
+<template>
+  <view :id="attrs.id" :class="'_block _'+name+' '+attrs.class" :style="attrs.style">
+    <block v-for="(n, i) in childs" v-bind:key="i">
+      <!-- 图片 -->
+      <!-- 占位图 -->
+      <image v-if="n.name==='img'&&((opts[1]&&!ctrl[i])||ctrl[i]<0)" class="_img" :style="n.attrs.style" :src="ctrl[i]<0?opts[2]:opts[1]" mode="widthFix" />
+      <!-- 显示图片 -->
+      <!-- #ifdef H5 || APP-PLUS -->
+      <img v-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]===-1?'display:none;':'')+n.attrs.style" :src="n.attrs.src||(ctrl.load?n.attrs['data-src']:'')" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap"/>
+      <!-- #endif -->
+      <!-- #ifndef H5 || APP-PLUS -->
+      <image v-if="n.name==='img'" :id="n.attrs.id" :class="'_img '+n.attrs.class" :style="(ctrl[i]===-1?'display:none;':'')+'width:'+(ctrl[i]||1)+'px;height:1px;'+n.attrs.style" :src="n.attrs.src" :mode="n.h?'':'widthFix'" :lazy-load="opts[0]" :webp="n.webp" :show-menu-by-longpress="opts[3]&&!n.attrs.ignore" :image-menu-prevent="!opts[3]||n.attrs.ignore" :data-i="i" @load="imgLoad" @error="mediaError" @tap.stop="imgTap" @longpress="imgLongTap" />
+      <!-- #endif -->
+      <!-- 文本 -->
+      <!-- #ifndef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO -->
+      <text v-else-if="n.text" :user-select="n.us" decode>{{n.text}}</text>
+      <!-- #endif -->
+      <text v-else-if="n.name==='br'">\n</text>
+      <!-- 链接 -->
+      <view v-else-if="n.name==='a'" :id="n.attrs.id" :class="(n.attrs.href?'_a ':'')+n.attrs.class" hover-class="_hover" :style="'display:inline;'+n.attrs.style" :data-i="i" @tap.stop="linkTap">
+        <node name="span" :childs="n.children" :opts="opts" style="display:inherit" />
+      </view>
+      <!-- 视频 -->
+      <!-- #ifdef APP-PLUS -->
+      <view v-else-if="n.html" :id="n.attrs.id" :class="'_video '+n.attrs.class" :style="n.attrs.style" v-html="n.html" />
+      <!-- #endif -->
+      <!-- #ifndef APP-PLUS -->
+      <video v-else-if="n.name==='video'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay" :controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
+      <!-- #endif -->
+      <!-- #ifdef H5 || APP-PLUS -->
+      <iframe v-else-if="n.name==='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder" :src="n.attrs.src" />
+      <embed v-else-if="n.name==='embed'" :style="n.attrs.style" :src="n.attrs.src" />
+      <!-- #endif -->
+      <!-- #ifndef MP-TOUTIAO -->
+      <!-- 音频 -->
+      <audio v-else-if="n.name==='audio'" :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author" :controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster" :src="n.src[ctrl[i]||0]" :data-i="i" @play="play" @error="mediaError" />
+      <!-- #endif -->
+      <view v-else-if="(n.name==='table'&&n.c)||n.name==='li'" :id="n.attrs.id" :class="'_'+n.name+' '+n.attrs.class" :style="n.attrs.style">
+        <node v-if="n.name==='li'" :childs="n.children" :opts="opts" />
+        <view v-else v-for="(tbody, x) in n.children" v-bind:key="x" :class="'_'+tbody.name+' '+tbody.attrs.class" :style="tbody.attrs.style">
+          <node v-if="tbody.name==='td'||tbody.name==='th'" :childs="tbody.children" :opts="opts" />
+          <block v-else v-for="(tr, y) in tbody.children" v-bind:key="y">
+            <view v-if="tr.name==='td'||tr.name==='th'" :class="'_'+tr.name+' '+tr.attrs.class" :style="tr.attrs.style">
+              <node :childs="tr.children" :opts="opts" />
+            </view>
+            <view v-else :class="'_'+tr.name+' '+tr.attrs.class" :style="tr.attrs.style">
+              <view v-for="(td, z) in tr.children" v-bind:key="z" :class="'_'+td.name+' '+td.attrs.class" :style="td.attrs.style">
+                <node :childs="td.children" :opts="opts" />
+              </view>
+            </view>
+          </block>
+        </view>
+      </view>
+      
+      <!-- 富文本 -->
+      <!-- #ifdef H5 || MP-WEIXIN || MP-QQ || APP-PLUS || MP-360 -->
+      <rich-text v-else-if="handler.use(n)" :id="n.attrs.id" :style="n.f" :nodes="[n]" />
+      <!-- #endif -->
+      <!-- #ifndef H5 || MP-WEIXIN || MP-QQ || APP-PLUS || MP-360 -->
+      <rich-text v-else-if="!n.c" :id="n.attrs.id" :style="n.f+';display:inline'" :preview="false" :nodes="[n]" />
+      <!-- #endif -->
+      <!-- 继续递归 -->
+      <view v-else-if="n.c===2" :id="n.attrs.id" :class="'_block _'+n.name+' '+n.attrs.class" :style="n.f+';'+n.attrs.style">
+        <node v-for="(n2, j) in n.children" v-bind:key="j" :style="n2.f" :name="n2.name" :attrs="n2.attrs" :childs="n2.children" :opts="opts" />
+      </view>
+      <node v-else :style="n.f" :name="n.name" :attrs="n.attrs" :childs="n.children" :opts="opts" />
+    </block>
+  </view>
+</template>
+<script module="handler" lang="wxs">
+// 行内标签列表
+var inlineTags = {
+  abbr: true,
+  b: true,
+  big: true,
+  code: true,
+  del: true,
+  em: true,
+  i: true,
+  ins: true,
+  label: true,
+  q: true,
+  small: true,
+  span: true,
+  strong: true,
+  sub: true,
+  sup: true
+}
+/**
+ * @description 是否使用 rich-text 显示剩余内容
+ */
+module.exports = {
+  use: function (item) {
+    if (item.c) return false
+    // 微信和 QQ 的 rich-text inline 布局无效
+    return !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1
+  }
+}
+</script>
+<script>
+
+import node from './node'
+export default {
+  name: 'node',
+  options: {
+    // #ifdef MP-WEIXIN
+    virtualHost: true,
+    // #endif
+    // #ifdef MP-TOUTIAO
+    addGlobalClass: false
+    // #endif
+  },
+  data () {
+    return {
+      ctrl: {}
+    }
+  },
+  props: {
+    name: String,
+    attrs: {
+      type: Object,
+      default () {
+        return {}
+      }
+    },
+    childs: Array,
+    opts: Array
+  },
+  components: {
+
+    node
+  },
+  mounted () {
+    this.$nextTick(() => {
+      for (this.root = this.$parent; this.root.$options.name !== 'mp-html'; this.root = this.root.$parent);
+    })
+    // #ifdef H5 || APP-PLUS
+    if (this.opts[0]) {
+      let i
+      for (i = this.childs.length; i--;) {
+        if (this.childs[i].name === 'img') break
+      }
+      if (i !== -1) {
+        this.observer = uni.createIntersectionObserver(this).relativeToViewport({
+          top: 500,
+          bottom: 500
+        })
+        this.observer.observe('._img', res => {
+          if (res.intersectionRatio) {
+            this.$set(this.ctrl, 'load', 1)
+            this.observer.disconnect()
+          }
+        })
+      }
+    }
+    // #endif
+  },
+  beforeDestroy () {
+    // #ifdef H5 || APP-PLUS
+    if (this.observer) {
+      this.observer.disconnect()
+    }
+    // #endif
+  },
+  methods:{
+    // #ifdef MP-WEIXIN
+    toJSON () { },
+    // #endif
+    /**
+     * @description 播放视频事件
+     * @param {Event} e
+     */
+    play (e) {
+      // #ifndef APP-PLUS
+      if (this.root.pauseVideo) {
+        let flag = false; const id = e.target.id
+        for (let i = this.root._videos.length; i--;) {
+          if (this.root._videos[i].id === id) {
+            flag = true
+          } else {
+            this.root._videos[i].pause() // 自动暂停其他视频
+          }
+        }
+        // 将自己加入列表
+        if (!flag) {
+          const ctx = uni.createVideoContext(id
+            // #ifndef MP-BAIDU
+            , this
+            // #endif
+          )
+          ctx.id = id
+          this.root._videos.push(ctx)
+        }
+      }
+      // #endif
+    },
+
+    /**
+     * @description 图片点击事件
+     * @param {Event} e
+     */
+    imgTap (e) {
+      const node = this.childs[e.currentTarget.dataset.i]
+      if (node.a) {
+        this.linkTap(node.a)
+        return
+      }
+      if (node.attrs.ignore) return
+      // #ifdef H5 || APP-PLUS
+      node.attrs.src = node.attrs.src || node.attrs['data-src']
+      // #endif
+      this.root.$emit('imgtap', node.attrs)
+      // 自动预览图片
+      if (this.root.previewImg) {
+        uni.previewImage({
+          current: parseInt(node.attrs.i),
+          urls: this.root.imgList
+        })
+      }
+    },
+
+    /**
+     * @description 图片长按
+     */
+    imgLongTap (e) {
+      // #ifdef APP-PLUS
+      const attrs = this.childs[e.currentTarget.dataset.i].attrs
+      if (this.opts[3] && !attrs.ignore) {
+        uni.showActionSheet({
+          itemList: ['保存图片'],
+          success: () => {
+            const save = path => {
+              uni.saveImageToPhotosAlbum({
+                filePath: path,
+                success () {
+                  uni.showToast({
+                    title: '保存成功'
+                  })
+                }
+              })
+            }
+            if (this.root.imgList[attrs.i].startsWith('http')) {
+              uni.downloadFile({
+                url: this.root.imgList[attrs.i],
+                success: res => save(res.tempFilePath)
+              })
+            } else {
+              save(this.root.imgList[attrs.i])
+            }
+          }
+        })
+      }
+      // #endif
+    },
+
+    /**
+     * @description 图片加载完成事件
+     * @param {Event} e
+     */
+    imgLoad (e) {
+      const i = e.currentTarget.dataset.i
+      /* #ifndef H5 || APP-PLUS */
+      if (!this.childs[i].w) {
+        // 设置原宽度
+        this.$set(this.ctrl, i, e.detail.width)
+      } else /* #endif */ if ((this.opts[1] && !this.ctrl[i]) || this.ctrl[i] === -1) {
+        // 加载完毕,取消加载中占位图
+        this.$set(this.ctrl, i, 1)
+      }
+    },
+
+    /**
+     * @description 链接点击事件
+     * @param {Event} e
+     */
+    linkTap (e) {
+      const node = e.currentTarget ? this.childs[e.currentTarget.dataset.i] : {}
+      const attrs = node.attrs || e
+      const href = attrs.href
+      this.root.$emit('linktap', Object.assign({
+        innerText: this.root.getText(node.children || []) // 链接内的文本内容
+      }, attrs))
+      if (href) {
+        if (href[0] === '#') {
+          // 跳转锚点
+          this.root.navigateTo(href.substring(1)).catch(() => { })
+        } else if (href.split('?')[0].includes('://')) {
+          // 复制外部链接
+          if (this.root.copyLink) {
+            // #ifdef H5
+            window.open(href)
+            // #endif
+            // #ifdef MP
+            uni.setClipboardData({
+              data: href,
+              success: () =>
+                uni.showToast({
+                  title: '链接已复制'
+                })
+            })
+            // #endif
+            // #ifdef APP-PLUS
+            plus.runtime.openWeb(href)
+            // #endif
+          }
+        } else {
+          // 跳转页面
+          uni.navigateTo({
+            url: href,
+            fail () {
+              uni.switchTab({
+                url: href,
+                fail () { }
+              })
+            }
+          })
+        }
+      }
+    },
+
+    /**
+     * @description 错误事件
+     * @param {Event} e
+     */
+    mediaError (e) {
+      const i = e.currentTarget.dataset.i
+      const node = this.childs[i]
+      // 加载其他源
+      if (node.name === 'video' || node.name === 'audio') {
+        let index = (this.ctrl[i] || 0) + 1
+        if (index > node.src.length) {
+          index = 0
+        }
+        if (index < node.src.length) {
+          this.$set(this.ctrl, i, index)
+          return
+        }
+      } else if (node.name === 'img' && this.opts[2]) {
+        // 显示错误占位图
+        this.$set(this.ctrl, i, -1)
+      }
+      if (this.root) {
+        this.root.$emit('error', {
+          source: node.name,
+          attrs: node.attrs,
+          errMsg: e.detail.errMsg
+        })
+      }
+    }
+  }
+}
+</script>
+<style>
+/* a 标签默认效果 */
+._a {
+  padding: 1.5px 0 1.5px 0;
+  color: #366092;
+  word-break: break-all;
+}
+
+/* a 标签点击态效果 */
+._hover {
+  text-decoration: underline;
+  opacity: 0.7;
+}
+
+/* 图片默认效果 */
+._img {
+  max-width: 100%;
+  -webkit-touch-callout: none;
+}
+
+/* 内部样式 */
+
+._block {
+  display: block;
+}
+
+._b,
+._strong {
+  font-weight: bold;
+}
+
+._code {
+  font-family: monospace;
+}
+
+._del {
+  text-decoration: line-through;
+}
+
+._em,
+._i {
+  font-style: italic;
+}
+
+._h1 {
+  font-size: 2em;
+}
+
+._h2 {
+  font-size: 1.5em;
+}
+
+._h3 {
+  font-size: 1.17em;
+}
+
+._h5 {
+  font-size: 0.83em;
+}
+
+._h6 {
+  font-size: 0.67em;
+}
+
+._h1,
+._h2,
+._h3,
+._h4,
+._h5,
+._h6 {
+  display: block;
+  font-weight: bold;
+}
+
+._image {
+  height: 1px;
+}
+
+._ins {
+  text-decoration: underline;
+}
+
+._li {
+  display: list-item;
+}
+
+._ol {
+  list-style-type: decimal;
+}
+
+._ol,
+._ul {
+  display: block;
+  padding-left: 40px;
+  margin: 1em 0;
+}
+
+._q::before {
+  content: '"';
+}
+
+._q::after {
+  content: '"';
+}
+
+._sub {
+  font-size: smaller;
+  vertical-align: sub;
+}
+
+._sup {
+  font-size: smaller;
+  vertical-align: super;
+}
+
+._thead,
+._tbody,
+._tfoot {
+  display: table-row-group;
+}
+
+._tr {
+  display: table-row;
+}
+
+._td,
+._th {
+  display: table-cell;
+  vertical-align: middle;
+}
+
+._th {
+  font-weight: bold;
+  text-align: center;
+}
+
+._ul {
+  list-style-type: disc;
+}
+
+._ul ._ul {
+  margin: 0;
+  list-style-type: circle;
+}
+
+._ul ._ul ._ul {
+  list-style-type: square;
+}
+
+._abbr,
+._b,
+._code,
+._del,
+._em,
+._i,
+._ins,
+._label,
+._q,
+._span,
+._strong,
+._sub,
+._sup {
+  display: inline;
+}
+
+/* #ifdef APP-PLUS */
+._video {
+  width: 300px;
+  height: 225px;
+}
+/* #endif */
+</style>

Plik diff jest za duży
+ 1223 - 0
uni_modules/mp-html/components/mp-html/parser.js


+ 79 - 0
uni_modules/mp-html/package.json

@@ -0,0 +1,79 @@
+{
+    "id": "mp-html",
+    "displayName": "mp-html 富文本组件【全端支持,可编辑】",
+    "version": "v2.2.0",
+    "description": "一个强大的富文本组件,高效轻量,功能丰富",
+    "keywords": [
+        "富文本",
+        "编辑器",
+        "html",
+        "rich-text",
+        "editor"
+    ],
+    "repository": "https://github.com/jin-yufeng/mp-html",
+    "dcloudext": {
+        "category": [
+            "前端组件",
+            "通用组件"
+        ],
+        "sale": {
+            "regular": {
+                "price": "0.00"
+            },
+            "sourcecode": {
+                "price": "0.00"
+            }
+        },
+        "contact": {
+            "qq": ""
+        },
+        "declaration": {
+            "ads": "无",
+            "data": "无",
+            "permissions": "无"
+        },
+        "npmurl": "https://www.npmjs.com/package/mp-html"
+    },
+    "uni_modules": {
+        "platforms": {
+            "cloud": {
+                "tcb": "y",
+                "aliyun": "y"
+            },
+            "client": {
+                "App": {
+                    "app-vue": "y",
+                    "app-nvue": "y"
+                },
+                "H5-mobile": {
+                    "Safari": "y",
+                    "Android Browser": "y",
+                    "微信浏览器(Android)": "y",
+                    "QQ浏览器(Android)": "y"
+                },
+                "H5-pc": {
+                    "Chrome": "y",
+                    "IE": "u",
+                    "Edge": "y",
+                    "Firefox": "y",
+                    "Safari": "y"
+                },
+                "小程序": {
+                    "微信": "y",
+                    "阿里": "y",
+                    "百度": "y",
+                    "字节跳动": "y",
+                    "QQ": "y"
+                },
+                "快应用": {
+                    "华为": "y",
+                    "联盟": "y"
+                },
+                "Vue": {
+                    "vue2": "y",
+                    "vue3": "u"
+                }
+            }
+        }
+    }
+}

Plik diff jest za duży
+ 1 - 0
uni_modules/mp-html/static/app-plus/mp-html/js/handler.js


Plik diff jest za duży
+ 1 - 0
uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js


Plik diff jest za duży
+ 1 - 0
uni_modules/mp-html/static/app-plus/mp-html/local.html


+ 4 - 0
uni_modules/uni-config-center/changelog.md

@@ -0,0 +1,4 @@
+## 0.0.2(2021-04-16)
+- 修改插件package信息
+## 0.0.1(2021-03-15)
+- 初始化项目

+ 80 - 0
uni_modules/uni-config-center/package.json

@@ -0,0 +1,80 @@
+{
+  "id": "uni-config-center",
+  "displayName": "uni-config-center",
+  "version": "0.0.2",
+  "description": "uniCloud 配置中心",
+  "keywords": [
+    "配置",
+    "配置中心"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+      "uniCloud",
+      "云函数模板"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "directories": {
+    "example": "../../../scripts/dist"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "u",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "u",
+          "Android Browser": "u",
+          "微信浏览器(Android)": "u",
+          "QQ浏览器(Android)": "u"
+        },
+        "H5-pc": {
+          "Chrome": "u",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": "u",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}

+ 93 - 0
uni_modules/uni-config-center/readme.md

@@ -0,0 +1,93 @@
+# 为什么使用uni-config-center
+
+实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
+
+```bash
+cloudfunctions
+└─────common 公共模块
+        ├─plugin-a // 插件A对应的目录
+        │  ├─index.js
+        │  ├─config.json // plugin-a对应的配置文件
+        │  └─other-file.cert  // plugin-a依赖的其他文件
+        └─plugin-b // plugin-b对应的目录
+           ├─index.js
+           └─config.json // plugin-b对应的配置文件
+```
+
+假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
+
+uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
+
+```bash
+cloudfunctions
+└─────common 公共模块
+        ├─plugin-a // 插件A对应的目录
+        │  └─index.js
+        ├─plugin-b // plugin-b对应的目录
+        │  └─index.js
+        └─uni-config-center
+           ├─index.js // config-center入口文件
+           ├─plugin-a
+           │  ├─config.json  // plugin-a对应的配置文件
+           │  └─other-file.cert  // plugin-a依赖的其他文件
+           └─plugin-b
+              └─config.json  // plugin-b对应的配置文件
+```
+
+使用uni-config-center后的优势
+
+- 配置文件统一管理,分离插件主体和配置信息,更新插件更方便
+- 支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
+
+# 用法
+
+在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:[使用公共模块](https://uniapp.dcloud.net.cn/uniCloud/cf-common)
+
+```js
+const createConfig = require('uni-config-center')
+
+const uniIdConfig = createConfig({
+    pluginId: 'uni-id', // 插件id
+    defaultConfig: { // 默认配置
+        tokenExpiresIn: 7200,
+        tokenExpiresThreshold: 600,
+    },
+    customMerge: function(defaultConfig, userConfig) { // 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
+        // defaudltConfig 默认配置
+        // userConfig 用户配置
+        return Object.assign(defaultConfig, userConfig)
+    }
+})
+
+
+// 以如下配置为例
+// {
+//   "tokenExpiresIn": 7200,
+//   "passwordErrorLimit": 6,
+//   "bindTokenToDevice": false,
+//   "passwordErrorRetryTime": 3600,
+//   "app-plus": {
+//     "tokenExpiresIn": 2592000
+//   },
+//   "service": {
+//     "sms": {
+//       "codeExpiresIn": 300
+//     }
+//   }
+// }
+
+// 获取配置
+uniIdConfig.config() // 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
+uniIdConfig.config('tokenExpiresIn') // 指定键值获取配置,返回:7200
+uniIdConfig.config('service.sms.codeExpiresIn') // 指定键值获取配置,返回:300
+uniIdConfig.config('tokenExpiresThreshold', 600) // 指定键值获取配置,如果不存在则取传入的默认值,返回:600
+
+// 获取文件绝对路径
+uniIdConfig.resolve('custom-token.js') // 获取uni-config-center/uni-id/custom-token.js文件的路径
+
+// 引用文件(require)
+uniIDConfig.requireFile('custom-token.js') // 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
+
+// 判断是否包含某文件
+uniIDConfig.hasFile('custom-token.js') // 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
+```

Plik diff jest za duży
+ 1 - 0
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/index.js


+ 9 - 0
uni_modules/uni-config-center/uniCloud/cloudfunctions/common/uni-config-center/package.json

@@ -0,0 +1,9 @@
+{
+  "name": "uni-config-center",
+  "version": "0.0.2",
+  "description": "配置中心",
+  "main": "index.js",
+  "keywords": [],
+  "author": "DCloud",
+  "license": "Apache-2.0"
+}

+ 62 - 0
uni_modules/uni-id/changelog.md

@@ -0,0 +1,62 @@
+## 3.3.9(2021-11-09)
+- 去除重复的context.xxx未找到的提示语
+## 3.3.8(2021-10-28)
+- 新增 用户账户封禁接口 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=ban-account)
+- 新增 用户账户注销接口 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=close-account)
+- 修复 未传appid时用户重复注册的Bug
+## 3.3.7(2021-10-08)
+- 移除部分接口的废弃提示
+## 3.3.6(2021-09-08)
+- 修复 邀请码可能重复的Bug
+## 3.3.5(2021-08-10)
+- 修复版本号错误
+## 3.3.4(2021-08-10)
+- 微信、QQ、支付宝登录新增type参数用于指定当前是登录还是注册
+## 3.3.3(2021-08-04)
+- 修复使用数组形式的配置文件报错的Bug
+## 3.3.2(2021-08-03)
+- 修复上3.3.0版本引出的createInstance接口传入配置不生效的Bug 感谢[hmh](https://gitee.com/hmh)
+## 3.3.1(2021-07-30)
+- 修复 将设置用户允许登录的应用列表时传入空数组报错的Bug
+## 3.3.0(2021-07-30)
+- 新增 不同端应用配置隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-config)
+- 新增 不同端用户隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-user)
+  + 此版本升级需要开发者处理一下用户数据,请参考 [补齐用户dcloud_appid字段](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=makeup-dcloud-appid)
+- 新增 QQ登录、注册相关功能 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=qq)
+- 调整 不再支持绑定手机、邮箱时不填验证码直接绑定
+## 3.2.1(2021-07-09)
+- 撤销3.2.0版本所做的调整
+## 3.2.0(2021-07-09)
+- 【重要】支持不同端(管理端、用户端等)用户隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-user)
+- 支持不同端(管理端、用户端等)配置文件隔离 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=isolate-config)
+## 3.1.3(2021-07-08)
+- 移除插件内误传的node_modules
+## 3.1.2(2021-07-08)
+- 修复 微信小程序绑定微信账号时报错的Bug
+## 3.1.1(2021-07-01)
+- 使用新的错误码规范,兼容旧版 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=errcode)
+- 修复微信登录、绑定时未返回用户accessToken的Bug
+## 3.1.0(2021-04-19)
+- 增加对用户名、邮箱、密码字段的两端去空格
+- 默认忽略用户名、邮箱的大小写 [详情](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=case-sensitive)
+- 修复 customToken导出async方法报错的Bug
+## 3.0.12(2021-04-13)
+- 调整bindTokenToDevice默认值为false
+## 3.0.11(2021-04-12)
+- 修复3.0.7版本引出的多个用户访问时可能出现30201报错的Bug
+## 3.0.10(2021-04-08)
+- 优化错误提示
+## 3.0.9(2021-04-08)
+- bindMobile接口支持通过一键登录的方式绑定
+- 优化错误提示
+## 3.0.8(2021-03-19)
+- 修复 3.0.7版本某些情况下生成token报错的Bug
+## 3.0.7(2021-03-19)
+- 新增 支持uni-config-center,更新uni-id无须再担心配置被覆盖 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=uni-config-center)
+- 新增 自定义token内容,可以缓存角色权限之外的更多信息到客户端 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=custom-token)
+- 新增 支持传入context获取uni-id实例,防止单实例多并发时全局context混乱 [详情](https://uniapp.dcloud.io/uniCloud/uni-id?id=create-instance)
+## 3.0.6(2021-03-05)
+- 新增[uniID.wxBizDataCrypt](https://uniapp.dcloud.io/uniCloud/uni-id?id=%e5%be%ae%e4%bf%a1%e6%95%b0%e6%8d%ae%e8%a7%a3%e5%af%86)方法
+- 优化loginByApple方法,提高接口响应速度
+## 3.0.5(2021-02-03)
+- 调整为uni_modules目录规范

+ 84 - 0
uni_modules/uni-id/package.json

@@ -0,0 +1,84 @@
+{
+  "id": "uni-id",
+  "displayName": "uni-id",
+  "version": "3.3.9",
+  "description": "简单、统一、可扩展的用户中心",
+  "keywords": [
+    "uniid",
+    "uni-id",
+    "用户管理",
+    "用户中心",
+    "短信验证码"
+],
+  "repository": "https://gitee.com/dcloud/uni-id.git",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+      "uniCloud",
+      "云函数模板"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": ["uni-config-center"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "u",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "u",
+          "Android Browser": "u",
+          "微信浏览器(Android)": "u",
+          "QQ浏览器(Android)": "u"
+        },
+        "H5-pc": {
+          "Chrome": "u",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": "u",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "u"
+        }
+      }
+    }
+  }
+}

+ 33 - 0
uni_modules/uni-id/readme.md

@@ -0,0 +1,33 @@
+**文档已移至[uni-id文档](https://uniapp.dcloud.net.cn/uniCloud/uni-id)**
+
+> 一般uni-id升级大版本时为不兼容更新,从低版本迁移到高版本请参考:[uni-id迁移指南](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=migration)
+
+## 重要升级说明
+
+**uni-id 3.x版本,搭配的uniCloud admin版本需大于1.2.10。**
+
+### 缓存角色权限
+
+自`uni-id 3.0.0`起,支持在token内缓存用户的角色权限,默认开启此功能,各登录接口的needPermission参数不再生效。如需关闭请在config内配置`"removePermissionAndRoleFromToken": true`。
+
+为什么要缓存角色权限?要知道云数据库是按照读写次数来收取费用的,并且读写数据库会拖慢接口响应速度。未配置`"removePermissionAndRoleFromToken": true`的情况下,可以在调用checkToken接口时不查询数据库获取用户角色权限。
+
+详细checkToken流程如下:
+
+![](https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/ed45d350-5a4d-11eb-b997-9918a5dda011.jpg)
+
+可以看出,旧版token(removePermissionAndRoleFromToken为true时生成的)在checkToken时如需返回权限需要进行两次数据库查询。新版token不需要查库即可返回权限信息。
+
+**注意**
+
+- 由于角色权限缓存在token内,可能会存在权限已经更新但是用户token未过期之前依然是旧版角色权限的情况。可以调短一些token过期时间来减少这种情况的影响。
+- admin角色token内不包含permission,如需自行判断用户是否有某个权限,要注意admin角色需要额外判断一下,写法如下
+  ```js
+  const {
+    role,
+    permission
+  } = await uniID.checkToken(event.uniIdToken)
+  if(role.includes('admin') || permission.includes('your permission id')) {
+    // 当前角色拥有'your permission id'对应的权限
+  }
+  ```

+ 201 - 0
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/LICENSE.md

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Plik diff jest za duży
+ 1 - 0
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js


+ 16 - 0
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json

@@ -0,0 +1,16 @@
+{
+  "name": "uni-id",
+  "version": "3.3.9",
+  "description": "uni-id for uniCloud",
+  "main": "index.js",
+  "homepage": "https://uniapp.dcloud.io/uniCloud/uni-id",
+  "repository": {
+    "type": "git",
+    "url": "git+https://gitee.com/dcloud/uni-id.git"
+  },
+  "author": "",
+  "license": "Apache-2.0",
+  "dependencies": {
+    "uni-config-center": "file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
+  }
+}

+ 51 - 0
uni_modules/uni-upgrade-center-app/changelog.md

@@ -0,0 +1,51 @@
+## 0.3.1(2021-11-24)
+- 修复 vue3 上图片不显示的Bug
+## 0.3.0(2021-11-18)
+- 移除 wgt 安装成功后提示,防止重启过快弹框不消失
+## 0.2.2(2021-08-25)
+- 兼容vue3.0
+## 0.2.1(2021-07-26)
+- 修复  使用腾讯云并手动填写地址时,导致下载链接失效的bug
+## 0.2.0(2021-07-13)
+- 更新文档  关于报错local_storage_key 为空,请不要将页面路径设置为pages.json中第一项
+## 0.1.9(2021-06-28)
+- 更新文档
+- 修复  wgt安装失败时,按钮状态不对
+## 0.1.8(2021-06-16)
+- 修复  跳转安装时,导致上次下载的apk还没安装就被删掉的bug
+## 0.1.7(2021-06-03)
+- 修改  移除static中的图片
+## 0.1.6(2021-06-03)
+- 修改  下载更新按钮使用CSS渐变色
+## 0.1.5(2021-04-22)
+- 更新check-update函数。现在返回一个Promise,有更新时成功回调,其他情况错误回调
+## 0.1.4(2021-04-13)
+- 更新文档。明确云函数调用结果
+## 0.1.3(2021-04-13)
+- 解耦云函数与弹框处理。utils中新增 call-check-version.js,可用于单独检测是否有更新
+## 0.1.2(2021-04-07)
+- 更新版本对比函数 compare
+## 0.1.1(2021-04-07)
+- 修复 腾讯云空间下载链接不能下载问题
+## 0.1.0(2021-04-07)
+- 新增使用uni.showModal提示升级示例
+- 修改iOS升级提示方式
+## 0.0.7(2021-04-02)
+- 修复在iOS上打开弹框报错
+## 0.0.6(2021-04-01)
+- 兼容旧版本安卓
+## 0.0.5(2021-04-01)
+- 修复低版本安卓上进度条错位
+## 0.0.4(2021-04-01)
+- 更新readme
+- 修复check-update语法错误
+## 0.0.3(2021-04-01)
+- 新增前台更新弹框,详见readme
+- 更新前台检查更新方法
+
+## 0.0.2(2021-03-29)
+- 更新文档
+- 移除 dependencies
+
+## 0.0.1(2021-03-25)
+- 升级中心前台检查更新

+ 84 - 0
uni_modules/uni-upgrade-center-app/package.json

@@ -0,0 +1,84 @@
+{
+  "id": "uni-upgrade-center-app",
+  "displayName": "升级中心 uni-upgrade-center - App",
+  "version": "0.3.1",
+  "description": "升级中心前台检查更新",
+  "keywords": [
+    "uniCloud",
+    "admin",
+    "update",
+    "升级",
+    "wgt"
+],
+  "repository": "https://gitee.com/dcloud/uni-upgrade-center/tree/master/uni_modules/uni-upgrade-center-app",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "uniCloud",
+        "云端一体页面模板"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "u",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "u",
+          "Android Browser": "u",
+          "微信浏览器(Android)": "u",
+          "QQ浏览器(Android)": "u"
+        },
+        "H5-pc": {
+          "Chrome": "u",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": "u",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "u"
+        }
+      }
+    }
+  }
+}

+ 500 - 0
uni_modules/uni-upgrade-center-app/pages/upgrade-popup.vue

@@ -0,0 +1,500 @@
+<template>
+	<view class="mask flex-center">
+		<view class="content botton-radius">
+			<view class="content-top">
+				<text class="content-top-text">{{title}}</text>
+				<image class="content-top" style="top: 0;" width="100%" height="100%" src="../static/bg_top.png">
+				</image>
+			</view>
+			<view class="content-header"></view>
+			<view class="content-body">
+				<view class="title">
+					<text>{{subTitle}}</text>
+					<!-- <text style="padding-left:20rpx;font-size: 0.5em;color: #666;">v.{{version}}</text> -->
+				</view>
+				<view class="body">
+					<scroll-view class="box-des-scroll" scroll-y="true">
+						<text class="box-des">
+							{{contents}}
+						</text>
+					</scroll-view>
+				</view>
+				<view class="footer flex-center">
+					<template v-if="isiOS">
+						<button class="content-button" style="border: none;color: #fff;" plain @click="jumpToAppStore">
+							{{downLoadBtnTextiOS}}
+						</button>
+					</template>
+					<template v-else>
+						<template v-if="!downloadSuccess">
+							<view class="progress-box flex-column" v-if="downloading">
+								<progress class="progress" border-radius="35" :percent="downLoadPercent"
+									activeColor="#3DA7FF" show-info stroke-width="10" />
+								<view style="width:100%;font-size: 28rpx;display: flex;justify-content: space-around;">
+									<text>{{downLoadingText}}</text>
+									<text>({{downloadedSize}}/{{packageFileSize}}M)</text>
+								</view>
+							</view>
+
+							<button v-else class="content-button" style="border: none;color: #fff;" plain
+								@click="downloadPackage">
+								{{downLoadBtnText}}
+							</button>
+						</template>
+						<button v-else-if="downloadSuccess && !installed" class="content-button"
+							style="border: none;color: #fff;" plain :loading="installing" :disabled="installing"
+							@click="installPackage">
+							{{installing ? '正在安装……' : '下载完成,立即安装'}}
+						</button>
+
+						<button v-if="installed && isWGT" class="content-button" style="border: none;color: #fff;" plain
+							@click="restart">
+							安装完毕,点击重启
+						</button>
+					</template>
+				</view>
+			</view>
+
+			<image v-if="!is_mandatory" class="close-img" src="../static/app_update_close.png"
+				@click.stop="closeUpdate"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	const localFilePathKey = '__localFilePath__'
+	const platform_iOS = 'iOS';
+	let downloadTask = null;
+
+	/**
+	 * 对比版本号,如需要,请自行修改判断规则
+	 * 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
+	 * @param {Object} v1
+	 * @param {Object} v2
+	 * v1 > v2 return 1
+	 * v1 < v2 return -1
+	 * v1 == v2 return 0
+	 */
+	function compare(v1 = '0', v2 = '0') {
+		v1 = String(v1).split('.')
+		v2 = String(v2).split('.')
+		const minVersionLens = Math.min(v1.length, v2.length);
+
+		let result = 0;
+		for (let i = 0; i < minVersionLens; i++) {
+			const curV1 = Number(v1[i])
+			const curV2 = Number(v2[i])
+
+			if (curV1 > curV2) {
+				result = 1
+				break;
+			} else if(curV1 < curV2) {
+				result = -1
+				break;
+			}
+		}
+
+		if (result === 0 && (v1.length !== v2.length)) {
+			const v1BiggerThenv2 = v1.length > v2.length;
+			const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
+			for (let i = minVersionLens; i < maxLensVersion.length; i++) {
+				const curVersion = Number(maxLensVersion[i])
+				if (curVersion > 0) {
+					v1BiggerThenv2 ? result = 1 : result = -1
+					break;
+				}
+			}
+		}
+
+		return result;
+	}
+
+	export default {
+		data() {
+			return {
+				// 从之前下载安装
+				installForBeforeFilePath: '',
+
+				// 安装
+				installed: false,
+				installing: false,
+
+				// 下载
+				downloadSuccess: false,
+				downloading: false,
+
+				downLoadPercent: 0,
+				downloadedSize: 0,
+				packageFileSize: 0,
+
+				tempFilePath: '', // 要安装的本地包地址
+
+				// 默认安装包信息
+				title: '更新日志',
+				contents: '',
+				is_mandatory: false,
+
+				// 可自定义属性
+				subTitle: '发现新版本',
+				downLoadBtnTextiOS: '立即跳转更新',
+				downLoadBtnText: '立即下载更新',
+				downLoadingText: '安装包下载中,请稍后'
+			}
+		},
+		onLoad({
+			local_storage_key
+		}) {
+			if (!local_storage_key) {
+				console.error('local_storage_key为空,请检查后重试')
+				uni.navigateBack()
+				return;
+			};
+
+			const localPackageInfo = uni.getStorageSync(local_storage_key);
+			if (!localPackageInfo) {
+				console.error('安装包信息为空,请检查后重试')
+				uni.navigateBack()
+				return;
+			};
+
+			const requiredKey = ['version', 'url', 'type']
+			for (let key in localPackageInfo) {
+				if (requiredKey.indexOf(key) !== -1 && !localPackageInfo[key]) {
+					console.error(`参数 ${key} 必填,请检查后重试`)
+					uni.navigateBack()
+					return;
+				}
+			}
+
+			Object.assign(this, localPackageInfo)
+			this.checkLocalStoragePackage()
+		},
+		onBackPress() {
+			// 强制更新不允许返回
+			if (this.is_mandatory) {
+				return true
+			}
+
+			downloadTask && downloadTask.abort()
+		},
+		computed: {
+			isWGT() {
+				return this.type === 'wgt'
+			},
+			isiOS() {
+				return !this.isWGT ? this.platform.includes(platform_iOS) : false;
+			}
+		},
+		methods: {
+			checkLocalStoragePackage() {
+				// 如果已经有下载好的包,则直接提示安装
+				const localFilePathRecord = uni.getStorageSync(localFilePathKey)
+				if (localFilePathRecord) {
+					const {
+						version,
+						savedFilePath,
+						installed
+					} = localFilePathRecord
+					
+					// 比对版本
+					if (!installed && compare(version, this.version) === 0) {
+						this.downloadSuccess = true;
+						this.installForBeforeFilePath = savedFilePath;
+						this.tempFilePath = savedFilePath
+					} else {
+						// 如果保存的包版本小 或 已安装过,则直接删除
+						this.deleteSavedFile(savedFilePath)
+					}
+				}
+			},
+			async closeUpdate() {
+				if (this.downloading) {
+					if (this.is_mandatory) {
+						return uni.showToast({
+							title: '下载中,请稍后……',
+							icon: 'none',
+							duration: 500
+						})
+					}
+					uni.showModal({
+						title: '是否取消下载?',
+						cancelText: '否',
+						confirmText: '是',
+						success: res => {
+							if (res.confirm) {
+								downloadTask && downloadTask.abort()
+								uni.navigateBack()
+							}
+						}
+					});
+					return;
+				}
+
+				if (this.downloadSuccess && this.tempFilePath) {
+					// 包已经下载完毕,稍后安装,将包保存在本地
+					await this.saveFile(this.tempFilePath, this.version)
+					uni.navigateBack()
+					return;
+				}
+
+				uni.navigateBack()
+			},
+			downloadPackage() {
+				this.downloading = true;
+
+				//下载包
+				downloadTask = uni.downloadFile({
+					url: this.url,
+					success: res => {
+						if (res.statusCode == 200) {
+							this.downloadSuccess = true;
+							this.tempFilePath = res.tempFilePath
+
+							// 强制更新,直接安装
+							if (this.is_mandatory) {
+								this.installPackage();
+							}
+						}
+					},
+					complete: () => {
+						this.downloading = false;
+
+						this.downLoadPercent = 0
+						this.downloadedSize = 0
+						this.packageFileSize = 0
+
+						downloadTask = null;
+					}
+				});
+
+				downloadTask.onProgressUpdate(res => {
+					this.downLoadPercent = res.progress;
+					this.downloadedSize = (res.totalBytesWritten / Math.pow(1024, 2)).toFixed(2);
+					this.packageFileSize = (res.totalBytesExpectedToWrite / Math.pow(1024, 2)).toFixed(2);
+				});
+			},
+			installPackage() {
+				// #ifdef APP-PLUS
+				// wgt资源包安装
+				if (this.isWGT) {
+					this.installing = true;
+				}
+
+				plus.runtime.install(this.tempFilePath, {
+					force: false
+				}, async res => {
+					this.installing = false;
+					this.installed = true;
+
+					// wgt包,安装后会提示 安装成功,是否重启
+					if (this.isWGT) {
+						// 强制更新安装完成重启
+						if (this.is_mandatory) {
+							uni.showLoading({
+								icon: 'none',
+								title: '安装成功,正在重启……'
+							})
+
+							setTimeout(() => {
+								uni.hideLoading()
+								this.restart();
+							}, 1000)
+						}
+					} else {
+						const localFilePathRecord = uni.getStorageSync(localFilePathKey)
+						uni.setStorageSync(localFilePathKey, {
+							...localFilePathRecord,
+							installed: true
+						})
+					}
+				}, async err => {
+					// 如果是安装之前的包,安装失败后删除之前的包
+					if (this.installForBeforeFilePath) {
+						await this.deleteSavedFile(this.installForBeforeFilePath)
+						this.installForBeforeFilePath = '';
+					}
+
+					// 安装失败需要重新下载安装包
+					this.installing = false;
+					this.installed = false;
+
+					uni.showModal({
+						title: `更新失败${this.isWGT ? '' : ',APK文件不存在'},请重新下载`,
+						content: err.message,
+						showCancel: false
+					});
+				});
+
+				// 非wgt包,安装跳出覆盖安装,此处直接返回上一页
+				if (!this.isWGT) {
+					uni.navigateBack()
+				}
+				// #endif
+			},
+			restart() {
+				this.installed = false;
+				// #ifdef APP-PLUS
+				//更新完重启app
+				plus.runtime.restart();
+				// #endif
+			},
+			async saveFile(tempFilePath, version) {
+				const [err, res] = await uni.saveFile({
+					tempFilePath
+				})
+				if (err) {
+					return;
+				}
+				uni.setStorageSync(localFilePathKey, {
+					version,
+					savedFilePath: res.savedFilePath
+				})
+			},
+			deleteSavedFile(filePath) {
+				uni.removeStorageSync(localFilePathKey)
+				return uni.removeSavedFile({
+					filePath
+				})
+			},
+			jumpToAppStore() {
+				plus.runtime.openURL(this.url);
+			}
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: transparent;
+	}
+
+	.flex-center {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		justify-content: center;
+		align-items: center;
+	}
+
+	.mask {
+		position: fixed;
+		left: 0;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		background-color: rgba(0, 0, 0, .65);
+	}
+
+	.botton-radius {
+		border-bottom-left-radius: 30rpx;
+		border-bottom-right-radius: 30rpx;
+	}
+
+	.content {
+		position: relative;
+		top: 0;
+		width: 600rpx;
+		background-color: #fff;
+		box-sizing: border-box;
+		padding: 0 50rpx;
+		font-family: Source Han Sans CN;
+	}
+
+	.text {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		line-height: 200px;
+		text-align: center;
+		color: #FFFFFF;
+	}
+
+	.content-top {
+		position: absolute;
+		top: -195rpx;
+		left: 0;
+		width: 600rpx;
+		height: 270rpx;
+	}
+
+	.content-top-text {
+		font-size: 45rpx;
+		font-weight: bold;
+		color: #F8F8FA;
+		position: absolute;
+		top: 120rpx;
+		left: 50rpx;
+		z-index: 1;
+	}
+
+	.content-header {
+		height: 70rpx;
+	}
+
+	.title {
+		font-size: 33rpx;
+		font-weight: bold;
+		color: #3DA7FF;
+		line-height: 38px;
+	}
+
+	.footer {
+		height: 150rpx;
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+	}
+
+	.box-des-scroll {
+		box-sizing: border-box;
+		padding: 0 40rpx;
+		height: 200rpx;
+		text-align: left;
+	}
+
+	.box-des {
+		font-size: 26rpx;
+		color: #000000;
+		line-height: 50rpx;
+	}
+
+	.progress-box {
+		width: 100%;
+	}
+
+	.progress {
+		width: 90%;
+		height: 40rpx;
+		border-radius: 35px;
+	}
+
+	.close-img {
+		width: 70rpx;
+		height: 70rpx;
+		z-index: 1000;
+		position: absolute;
+		bottom: -120rpx;
+		left: calc(50% - 70rpx / 2);
+	}
+
+	.content-button {
+		text-align: center;
+		flex: 1;
+		font-size: 30rpx;
+		font-weight: 400;
+		color: #FFFFFF;
+		border-radius: 40rpx;
+		margin: 0 18rpx;
+
+		height: 80rpx;
+		line-height: 80rpx;
+
+		background: linear-gradient(to right, #1785ff, #3DA7FF);
+	}
+
+	.flex-column {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+	}
+</style>

+ 18 - 0
uni_modules/uni-upgrade-center-app/pages_init.json

@@ -0,0 +1,18 @@
+{
+	"pages": [{
+		"path": "uni_modules/uni-upgrade-center-app/pages/upgrade-popup",
+		"style": {
+			"disableScroll": true,
+			"app-plus": {
+				"backgroundColorTop": "transparent",
+				"background": "transparent",
+				"titleNView": false,
+				"scrollIndicator": false,
+				"popGesture": "none",
+				"animationType": "fade-in",
+				"animationDuration": 200
+
+			}
+		}
+	}]
+}

+ 119 - 0
uni_modules/uni-upgrade-center-app/readme.md

@@ -0,0 +1,119 @@
+# uni-upgrade-center - App
+
+### 概述
+
+> 统一管理App及App在`Android`、`iOS`平台上`App安装包`和`wgt资源包`的发布升级
+
+> 本插件为升级中心前台检查更新,后台Admin管理系统请点击查看 [uni-upgrade-center](https://ext.dcloud.net.cn/plugin?id=4470)
+
+### 基于uni-upgrade-center的App前台检查升级插件
+  - 一键式检查更新,统一整包与wgt资源包更新
+  - 好看、实用、可自定义、可拓展的前台更新弹框
+
+## 安装指引
+
+0. 依赖数据库`opendb-app-versions`,如果没有此库,请在云服务空间中创建。
+
+1. 使用`HBuilderX 3.1.0+`,因为要使用到`uni_modules`
+
+3. 在插件市场打开本插件页面,在右侧点击`使用 HBuilderX 导入插件`,选择要导入的项目点击确定
+
+5. 找到`/uni_modules/uni-upgrade-center-app/uniCloud/cloudfunctions/check-version`,右键上传部署
+
+6. 在`pages.json`中添加页面路径。**注:请不要设置为pages.json中第一项**
+```json
+"pages": [
+		// ……其他页面配置
+		{
+			"path": "uni_modules/uni-upgrade-center-app/pages/upgrade-popup",
+			"style": {
+				"disableScroll": true,
+				"app-plus": {
+					"backgroundColorTop": "transparent",
+					"background": "transparent",
+					"titleNView": false,
+					"scrollIndicator": false,
+					"popGesture": "none",
+					"animationType": "fade-in",
+					"animationDuration": 200
+
+				}
+			}
+		}
+]
+```
+
+7. 将`@/uni_modules/uni-upgrade-center-app/utils/check-update`import到需要用到的地方,调用一下即可
+
+8. 升级弹框可自行编写,也可以使用`uni.showModal`,或使用现有的升级弹框样式,如果不满足UI需求请自行替换资源文件。在`utils/check-update.js`中都有实例。
+
+9. wgt更新时,打包前请务必将manifest.json中的版本修改为更高版本。
+
+### 更新下载安装`check-update.js`
+
+*该函数在utils目录下*
+
+1. 如果是静默更新,则不会打开更新弹框,会在后台下载后安装,下次启动应用生效
+
+2. 如果是 iOS,则会直接打开AppStore的链接
+
+3. 其他情况,会将`check-version`返回的结果保存在localStorage中,并跳转进入`upgrade-popup.vue`打开更新弹框
+
+### 检查更新函数`check-version`
+
+*该函数在uniCloud/cloudfunctions目录下*
+
+1. 使用检查更新需要传递三个参数 `appid`、`appVersion`、`wgtVersion`
+
+2. `appid` 使用 plus.runtime.appid 获取,*注:真机运行时为固定值HBuilder,在调试的时候请使用本地调试云函数*
+
+3. `appVersion` 使用 plus.runtime.version 获取
+
+4. `wgtVersion` 使用 plus.runtime.getProperty(plus.runtime.appid,(wgtInfo) => { wgtInfo.version }) 获取
+
+5. `check-version`云函数内部会自动获取 App 平台
+
+
+**Tips**
+
+1. `check-version`云函数内部有版本对比函数(compare)。
+	- 使用多段式版本格式(如:"3.0.0.0.0.1.0.1", "3.0.0.0.0.1")。如果不满足对比规则,请自行修改。
+	- 如果修改,请将*pages/upgrade-popup.vue*中*compare*函数一并修改
+
+## 项目代码说明
+
+### 更新弹框
+- `upgrade-popup.vue` - 更新应用:
+	- 如果云函数`check-version`返回的参数表明需要更新,则将参数保存在localStorage中,带着键值跳转该页面
+	- 进入时会先从localStorage中尝试取出之前存的安装包路径(此包不会是强制安装类型的包)
+	- 如果有已经保存的包,则和传进来的 `version` 进行比较,如果相等则安装。大于和小于都不进行安装,因为admin端可能会调整包的版本。不符合更新会将此包删除
+	- 如果本地没有包或者包不符合安装条件,则进行下载安装包
+	- 点击下载会有进度条、已下载大小和下载包的大小
+	- 下载完成会提示安装:
+		- 如果是 wgt 包,安装时则会提示 正在安装…… 和 安装完成。安装完成会提示是否重启
+		- 如果是 原生安装包,则直接跳出去覆盖安装
+	- 下载过程中,如果退出会提示是否取消下载。如果是强制更新,则只会提示正在下载请稍后,此时不可退出
+	- 如果是下载完成了没有安装就退出,则会将下载完成的包保存在本地。将包的本地路径和包version保存在localStorage中
+
+### 工具类 utils
+- `call-check-version`
+	- 请求云函数`check-version`拿取版本检测结果
+- `check-update`
+	- 调用`call-check-version`并根据结果判断是否显示更新弹框
+
+### 云函数
+- `check-version` - 检查应用更新:
+	- 根据传参,先检测传参是否完整,appid appVersion wgtVersion 必传
+	- 先从数据库取出所有该平台(会从上下文读取平台信息)的所有线上发行更新
+	- 再从所有线上发行更新中取出版本最大的一版。如果可以,尽量先检测wgt的线上发行版更新
+	- 使用上一步取出的版本包的版本号 和传参 appVersion、wgtVersion 来检测是否有更新。必须同时大于这两项,因为上一次可能是wgt热更新,否则返回暂无更新
+	- 如果库中 wgt包 版本大于传参 appVersion,但是不满足 min_uni_version < appVersion,则不会使用wgt更新,会接着判断库中 app包version 是否大于 appVersion
+	- 返回结果:
+
+		|code|message|
+		|:-:|:-:|
+		|0|当前版本已经是最新的,不需要更新|
+		|101|wgt更新|
+		|102|整包更新|
+		|-101|暂无更新或检查appid是否填写正确|
+		|-102|请检查传参是否填写正确|

BIN
uni_modules/uni-upgrade-center-app/static/app_update_close.png


BIN
uni_modules/uni-upgrade-center-app/static/bg_top.png


+ 9 - 0
uni_modules/uni-upgrade-center-app/uniCloud/cloudfunctions/check-version/check-version.param.json

@@ -0,0 +1,9 @@
+// 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
+
+// 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam
+
+{
+	"appid": "__YOUR_APPID__",
+	"appVersion": "2.2.0",
+	"wgtVersion": "2.2.2"
+}

+ 167 - 0
uni_modules/uni-upgrade-center-app/uniCloud/cloudfunctions/check-version/index.js

@@ -0,0 +1,167 @@
+'use strict';
+exports.main = async (event, context) => {
+	/**
+	 * 检测升级 使用说明
+	 * 上传包:
+	 * 1. 根据传参,先检测传参是否完整,appid appVersion wgtVersion 必传
+	 * 2. 先从数据库取出所有该平台(从上下文读取平台信息,默认 Andriod)的所有线上发行更新
+	 * 3. 再从所有线上发行更新中取出版本最大的一版。如果可以,尽量先检测wgt的线上发行版更新
+	 * 4. 使用上步取出的版本包的版本号 和传参 appVersion、wgtVersion 来检测是否有更新,必须同时大于这两项,否则返回暂无更新
+	 * 5. 如果库中 wgt包 版本大于传参 appVersion,但是不满足 min_uni_version < appVersion,则不会使用wgt更新,会接着判断库中 app包version 是否大于 appVersion
+	 */
+
+	let {
+		appid,
+		appVersion,
+		wgtVersion,
+	} = event;
+
+	const platform_Android = 'Android';
+	const platform_iOS = 'iOS';
+	const package_app = 'native_app';
+	const package_wgt = 'wgt';
+	const app_version_db_name = 'opendb-app-versions'
+
+	let platform = platform_Android;
+
+	// 云函数URL化请求
+	if (event.headers) {
+		let body;
+		try {
+			if (event.httpMethod.toLocaleLowerCase() === 'get') {
+				body = event.queryStringParameters;
+			} else {
+				body = JSON.parse(event.body);
+			}
+		} catch (e) {
+			return {
+				code: 500,
+				msg: '请求错误'
+			};
+		}
+
+		appid = body.appid;
+		appVersion = body.appVersion;
+		wgtVersion = body.wgtVersion;
+
+		platform = /iPhone|iPad/.test(event.headers) ? platform_iOS : platform_Android;
+	} else if (context.OS) {
+		platform = context.OS === 'android'
+			? platform_Android
+			: context.OS === 'ios'
+				? platform_iOS
+				: platform_Android;
+	}
+
+	if (appid && appVersion && wgtVersion && platform) {
+		const collection = uniCloud.database().collection(app_version_db_name);
+
+		const record = await collection.where({
+				appid,
+				platform,
+				stable_publish: true
+			})
+			.orderBy('create_date', 'desc')
+			.get();
+
+		if (record && record.data && record.data.length > 0) {
+			const appVersionInDb = record.data.find(item => item.type === package_app) || {};
+			const wgtVersionInDb = record.data.find(item => item.type === package_wgt) || {};
+			const hasAppPackage = !!Object.keys(appVersionInDb).length;
+			const hasWgtPackage = !!Object.keys(wgtVersionInDb).length;
+
+			// 取两个版本中版本号最大的包,版本一样,使用wgt包
+			let stablePublishDb = hasAppPackage
+				? hasWgtPackage
+					? compare(wgtVersionInDb.version, appVersionInDb.version) >= 0
+						? wgtVersionInDb
+						: appVersionInDb
+					: appVersionInDb
+				: wgtVersionInDb;
+
+			const {
+				version,
+				min_uni_version
+			} = stablePublishDb;
+
+			// 库中的version必须满足同时大于appVersion和wgtVersion才行,因为上次更新可能是wgt更新
+			const appUpdate = compare(version, appVersion) === 1; // app包可用更新
+			const wgtUpdate = compare(version, wgtVersion) === 1; // wgt包可用更新
+
+			if (Object.keys(stablePublishDb).length && appUpdate && wgtUpdate) {
+				// 判断是否可用wgt更新
+				if (min_uni_version && compare(min_uni_version, appVersion) < 1) {
+					return {
+						code: 101,
+						message: 'wgt更新',
+						...stablePublishDb
+					};
+				} else if (hasAppPackage && compare(appVersionInDb.version, appVersion) === 1) {
+					return {
+						code: 102,
+						message: '整包更新',
+						...appVersionInDb
+					};
+				}
+			}
+
+			return {
+				code: 0,
+				message: '当前版本已经是最新的,不需要更新'
+			};
+		}
+
+		return {
+			code: -101,
+			message: '暂无更新或检查appid是否填写正确'
+		};
+	}
+
+	return {
+		code: -102,
+		message: '请检查传参是否填写正确'
+	};
+};
+
+/**
+ * 对比版本号,如需要,请自行修改判断规则
+ * 支持比对	("3.0.0.0.0.1.0.1", "3.0.0.0.0.1")	("3.0.0.1", "3.0")	("3.1.1", "3.1.1.1") 之类的
+ * @param {Object} v1
+ * @param {Object} v2
+ * v1 > v2 return 1
+ * v1 < v2 return -1
+ * v1 == v2 return 0
+ */
+function compare(v1 = '0', v2 = '0') {
+	v1 = String(v1).split('.')
+	v2 = String(v2).split('.')
+	const minVersionLens = Math.min(v1.length, v2.length);
+
+	let result = 0;
+	for (let i = 0; i < minVersionLens; i++) {
+		const curV1 = Number(v1[i])
+		const curV2 = Number(v2[i])
+
+		if (curV1 > curV2) {
+			result = 1
+			break;
+		} else if(curV1 < curV2) {
+			result = -1
+			break;
+		}
+	}
+
+	if (result === 0 && (v1.length !== v2.length)) {
+		const v1BiggerThenv2 = v1.length > v2.length;
+		const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
+		for (let i = minVersionLens; i < maxLensVersion.length; i++) {
+			const curVersion = Number(maxLensVersion[i])
+			if (curVersion > 0) {
+				v1BiggerThenv2 ? result = 1 : result = -1
+				break;
+			}
+		}
+	}
+
+	return result;
+}

+ 29 - 0
uni_modules/uni-upgrade-center-app/utils/call-check-version.js

@@ -0,0 +1,29 @@
+export default function() {
+	// #ifdef APP-PLUS
+	return new Promise((resolve, reject) => {
+		plus.runtime.getProperty(plus.runtime.appid, function(widgetInfo) {
+			uniCloud.callFunction({
+				name: 'check-version',
+				data: {
+					appid: plus.runtime.appid,
+					appVersion: plus.runtime.version,
+					wgtVersion: widgetInfo.version
+				},
+				success: (e) => {
+					resolve(e)
+				},
+				fail: (error) => {
+					reject(error)
+				}
+			})
+		})
+	})
+	// #endif
+	// #ifndef APP-PLUS
+	return new Promise((resolve, reject) => {
+		reject({
+			message: '请在App中使用'
+		})
+	})
+	// #endif
+}

+ 155 - 0
uni_modules/uni-upgrade-center-app/utils/check-update.js

@@ -0,0 +1,155 @@
+import callCheckVersion from './call-check-version'
+
+// 推荐再App.vue中使用
+const PACKAGE_INFO_KEY = '__package_info__'
+
+export default function() {
+	// #ifdef APP-PLUS
+	return new Promise((resolve, reject) => {
+		callCheckVersion().then(async (e) => {
+			if (!e.result) return;
+			const {
+				code,
+				message,
+				is_silently, // 是否静默更新
+				url, // 安装包下载地址
+				platform, // 安装包平台
+				type // 安装包类型
+			} = e.result;
+
+			// 此处逻辑仅为实例,可自行编写
+			if (code > 0) {
+				// 腾讯云和阿里云下载链接不同,需要处理一下,阿里云会原样返回
+				const {
+					fileList
+				} = await uniCloud.getTempFileURL({
+					fileList: [url]
+				});
+				if (fileList[0].tempFileURL)
+					e.result.url = fileList[0].tempFileURL;
+
+				resolve(e)
+
+				// 静默更新,只有wgt有
+				if (is_silently) {
+					uni.downloadFile({
+						url: e.result.url,
+						success: res => {
+							if (res.statusCode == 200) {
+								// 下载好直接安装,下次启动生效
+								plus.runtime.install(res.tempFilePath, {
+									force: false
+								});
+							}
+						}
+					});
+					return;
+				}
+
+				/**
+				 * 提示升级一
+				 * 使用 uni.showModal
+				 */
+				// return updateUseModal(e.result)
+
+				/**
+				 * 提示升级二
+				 * 官方适配的升级弹窗,可自行替换资源适配UI风格
+				 */
+				uni.setStorageSync(PACKAGE_INFO_KEY, e.result)
+				uni.navigateTo({
+					url: `/uni_modules/uni-upgrade-center-app/pages/upgrade-popup?local_storage_key=${PACKAGE_INFO_KEY}`,
+					fail: (err) => {
+						console.error('更新弹框跳转失败', err)
+						uni.removeStorageSync(PACKAGE_INFO_KEY)
+					}
+				})
+			} else if (code < 0) {
+				// TODO 云函数报错处理
+				console.error(message)
+				reject(e)
+			}
+		}).catch(err => {
+			// TODO 云函数报错处理
+			console.error(err.message)
+			reject(err)
+		})
+	});
+	// #endif
+}
+
+/**
+ * 使用 uni.showModal 升级
+ */
+function updateUseModal(packageInfo) {
+	const {
+		title, // 标题
+		contents, // 升级内容
+		is_mandatory, // 是否强制更新
+		url, // 安装包下载地址
+		platform, // 安装包平台
+		type // 安装包类型
+	} = packageInfo;
+
+	let isWGT = type === 'wgt'
+	let isiOS = !isWGT ? platform.includes('iOS') : false;
+	let confirmText = isiOS ? '立即跳转更新' : '立即下载更新'
+
+	return uni.showModal({
+		title,
+		content: contents,
+		showCancel: !is_mandatory,
+		confirmText,
+		success: res => {
+			if (res.cancel) return;
+
+			// 安装包下载
+			if (isiOS) {
+				plus.runtime.openURL(url);
+				return;
+			}
+
+			uni.showToast({
+				title: '后台下载中……',
+				duration: 1000
+			});
+
+			// wgt 和 安卓下载更新
+			downloadTask = uni.downloadFile({
+				url,
+				success: res => {
+					if (res.statusCode !== 200) {
+						console.error('下载安装包失败', err);
+						return;
+					}
+					// 下载好直接安装,下次启动生效
+					plus.runtime.install(res.tempFilePath, {
+						force: false
+					}, () => {
+						if (is_mandatory) {
+							//更新完重启app
+							plus.runtime.restart();
+							return;
+						}
+						uni.showModal({
+							title: '安装成功是否重启?',
+							success: res => {
+								if (res.confirm) {
+									//更新完重启app
+									plus.runtime.restart();
+								}
+							}
+						});
+					}, err => {
+						uni.showModal({
+							title: '更新失败',
+							content: err
+								.message,
+							showCancel: false
+						});
+					});
+				}
+			});
+		}
+	});
+}

Plik diff jest za duży
+ 2 - 2
unpackage/dist/dev/app-plus/app-config-service.js


Plik diff jest za duży
+ 13658 - 6342
unpackage/dist/dev/app-plus/app-service.js


Plik diff jest za duży
+ 23356 - 17003
unpackage/dist/dev/app-plus/app-view.js


BIN
unpackage/dist/dev/app-plus/components/t-i-icon/icon/gaikuang.png


BIN
unpackage/dist/dev/app-plus/components/t-i-navbar/icon/zaoquan.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/fuwudianhua.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/gengxin.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/gongdanshenhe.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/icon_11.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/icon_4.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/icon_9.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/jianyifankui.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/qingchu.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/shiyongshouce.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/xiaoxi.png


BIN
unpackage/dist/dev/app-plus/components/t-m-icon/icon/xiugaimima.png


BIN
unpackage/dist/dev/app-plus/components/t-m-list/icon/list_1.png


Plik diff jest za duży
+ 1 - 1
unpackage/dist/dev/app-plus/manifest.json


Plik diff jest za duży
+ 1 - 0
unpackage/dist/dev/app-plus/uni_modules/mp-html/static/app-plus/mp-html/js/handler.js


Plik diff jest za duży
+ 1 - 0
unpackage/dist/dev/app-plus/uni_modules/mp-html/static/app-plus/mp-html/js/uni.webview.min.js


+ 0 - 0
unpackage/dist/dev/app-plus/uni_modules/mp-html/static/app-plus/mp-html/local.html


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików