zhangyun 4 лет назад
Сommit
b10aac463d
100 измененных файлов с 31053 добавлено и 0 удалено
  1. 339 0
      App.vue
  2. 125 0
      components/bazaar-city_list/citylist.json
  3. 299 0
      components/bazaar-city_list/index.vue
  4. 1063 0
      components/city.js
  5. 84 0
      components/equip-item/equip-item.vue
  6. 13 0
      components/js_sdk/u-charts/package.json
  7. 471 0
      components/js_sdk/u-charts/u-charts/config.js
  8. 267 0
      components/js_sdk/u-charts/u-charts/demodata.json
  9. 41 0
      components/js_sdk/u-charts/u-charts/mapdata.json
  10. 6 0
      components/js_sdk/u-charts/u-charts/readme.md
  11. 5687 0
      components/js_sdk/u-charts/u-charts/u-charts.js
  12. 443 0
      components/js_sdk/u-charts/u-charts/u-charts.vue
  13. 639 0
      components/ksp-image-cutter/ksp-image-cutter.vue
  14. 454 0
      components/linzq-citySelect/linzq-citySelect.vue
  15. 140 0
      components/popup-layer/popup-layer.vue
  16. 96 0
      components/uni-icons/icons.js
  17. 57 0
      components/uni-icons/uni-icons.vue
  18. 224 0
      components/uni-nav-bar/uni-nav-bar.vue
  19. 25 0
      components/uni-status-bar/uni-status-bar.vue
  20. 56 0
      main.js
  21. 165 0
      manifest.json
  22. 33 0
      package-lock.json
  23. 18 0
      package.json
  24. 538 0
      pages.json
  25. 434 0
      pages/afterSale/addafter.vue
  26. 331 0
      pages/afterSale/index.vue
  27. 291 0
      pages/afterSale/search.vue
  28. 433 0
      pages/cb/bzy/equip-set/bzyhistoryile.vue
  29. 441 0
      pages/cb/bzy/equip-set/equip-set.vue
  30. 142 0
      pages/cb/cbd/equip-set/addimg.vue
  31. 588 0
      pages/cb/cbd/equip-set/equip-set.vue
  32. 435 0
      pages/cb/cbd/equip-set/historyfile.vue
  33. 337 0
      pages/cb/cbd/equip-set/imgpage.vue
  34. 396 0
      pages/cb/cbd/equip-set/note.vue
  35. 614 0
      pages/cb/cbd/equip-set/statistics.vue
  36. 51 0
      pages/cb/cbd/equip-set/test/test.vue
  37. 792 0
      pages/cb/equip-detail/equip-detail.vue
  38. 276 0
      pages/cb/index/index.vue
  39. 253 0
      pages/cb/index/search.vue
  40. 225 0
      pages/cb/sim/sim.vue
  41. 277 0
      pages/cb/xy/equip-set/equip-set.vue
  42. 492 0
      pages/cb/xy/equip-set/xyhistoryile.vue
  43. 429 0
      pages/cb/xy2.0/historydatas.vue
  44. 430 0
      pages/cb/xy2.0/particulars.vue
  45. 318 0
      pages/disandpests/index.vue
  46. 820 0
      pages/distribution/index.vue
  47. 216 0
      pages/environment/contros.vue
  48. 276 0
      pages/environment/equipment.vue
  49. 452 0
      pages/environment/history.vue
  50. 160 0
      pages/environment/index.vue
  51. 129 0
      pages/environment/onedaythedata.vue
  52. 176 0
      pages/environment/search.vue
  53. 440 0
      pages/equipList/index.vue
  54. 241 0
      pages/equipList/modification.vue
  55. 324 0
      pages/equipList/search.vue
  56. 294 0
      pages/equipMange/index/addusers.vue
  57. 338 0
      pages/equipMange/index/assignment.vue
  58. 162 0
      pages/equipMange/index/changepasswold.vue
  59. 215 0
      pages/equipMange/index/index.vue
  60. 466 0
      pages/equipMange/index/useroperation.vue
  61. 289 0
      pages/expertDiagnosis/exchangeShare.vue
  62. 201 0
      pages/expertDiagnosis/index.vue
  63. 133 0
      pages/expertDiagnosis/introduce.vue
  64. 286 0
      pages/expertDiagnosis/particulars.vue
  65. 200 0
      pages/expertDiagnosis/postmessage.vue
  66. 141 0
      pages/expertDiagnosis/wormcase.vue
  67. 357 0
      pages/fourBase/addbase.vue
  68. 328 0
      pages/fourBase/allocation.vue
  69. 229 0
      pages/fourBase/basefacility.vue
  70. 43 0
      pages/fourBase/city.vue
  71. 347 0
      pages/fourBase/index.vue
  72. 361 0
      pages/fourBase/modification.vue
  73. 419 0
      pages/index/index.vue
  74. 455 0
      pages/login/login.vue
  75. 174 0
      pages/monitor/index.vue
  76. 228 0
      pages/my/about/about.vue
  77. 59 0
      pages/my/feedback/feedback.vue
  78. 207 0
      pages/my/index/index.vue
  79. 105 0
      pages/my/record/record.vue
  80. 203 0
      pages/my/user-info/user-info.vue
  81. 371 0
      pages/prevention/control.vue
  82. 356 0
      pages/prevention/equipmentdetails.vue
  83. 161 0
      pages/prevention/index.vue
  84. 175 0
      pages/prevention/search.vue
  85. 122 0
      pages/prevention/sim.vue
  86. 651 0
      pages/prevention/ucharts.vue
  87. 64 0
      pages/webview.vue
  88. 75 0
      project.config.json
  89. 336 0
      static/data/cbd_pest_library.js
  90. BIN
      static/images/12.png
  91. BIN
      static/images/13.png
  92. BIN
      static/images/14.png
  93. BIN
      static/images/15.png
  94. BIN
      static/images/16.png
  95. BIN
      static/images/17.png
  96. BIN
      static/images/18.png
  97. BIN
      static/images/19.png
  98. BIN
      static/images/distribution/0b551e50be351dbc14f0dd6470e3443.png
  99. BIN
      static/images/distribution/1bd535eb7dbb0809940030d40c64b4c.png
  100. 0 0
      static/images/distribution/2eb9e550709430a1bd8178568c14785.png

Разница между файлами не показана из-за своего большого размера
+ 339 - 0
App.vue


Разница между файлами не показана из-за своего большого размера
+ 125 - 0
components/bazaar-city_list/citylist.json


+ 299 - 0
components/bazaar-city_list/index.vue

@@ -0,0 +1,299 @@
+<template>
+	<view class="citylist">
+		<scroll-view :style="{'height':windowH}" scroll-y="true" :scroll-top="scrollTop"  show-scrollbar="false" @scroll="scroll" >
+			<view>
+				<view class="city-list-container">
+					<!-- 定位城市 -->
+					<view class="city-list-content" id="location_city">
+						<view class="city-title">定位城市</view>
+						<view class="city-list city-list-inline" @tap="location">
+							<view class="location-city">{{locationCity}}</view>
+						</view>
+					</view>
+					<!-- 热门城市 -->
+					<view id="hotcity" class="city-list-content">
+						<view class="city-title">
+							{{hotcity.title}}
+						</view> 
+						<view class="city-list city-list-inline">
+							<view class="city-item" v-for="(item,index) in hotcity.lists" :key="`city${index}`" @tap="selectedCity(item)">
+								{{item}}
+							</view>
+						</view>
+					</view>
+					<!-- 城市列表 -->
+					<view id="citytitle" class="city-list-content">
+						<view class="city_title_wrap" v-for="(city,index) in citylist" :key="`citylist${index}`">
+							<view class="city-title city-title-letter">
+								{{city.title}}
+							</view>
+							<view class="city-list city-list-block">
+								<view class="city-item" v-for="(item,index) in city.lists" :key="`item${index}`" @tap="selectedCity(item)">
+									{{item}}
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</scroll-view>
+		<!-- 固定顶部 -->
+		<view class="fixtitle" :style="{transform:fixedStyle}">
+			<view class="city-title">{{fixedTitle}}</view>
+		</view>
+		<!-- 侧边栏导航 -->
+		<view class="navrightcity">
+			<view class="nav-item nav-letter" @tap="scroll_to_city(0)">定</view>
+			<view class="nav-item nav-letter" @tap="scroll_to_city(1)">热</view>
+			<view v-for="(item,index) in citylist" :key="`nav${index}`" class="nav-item nav-letter" @click="scroll_to_city(index+2)">
+				{{item.title}}
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import CL from './citylist.json'
+	export default{
+		props:{
+			getCity:{
+				type:Function,
+				default:function(){}
+			}
+		},
+		computed:{
+			fixedTitle(){
+				if (this.scrollY < 0) {
+					return ''
+				}
+				return this.title && this.title[this.currentIndex]
+			}
+		},
+		watch:{
+			scrollY(newY){
+				const {tops} = this
+				const index = tops.findIndex((top, index) => {
+					this.diff = tops[index + 1] - newY
+					return newY >= top && newY < tops[index + 1]
+				})
+				this.currentIndex = index;
+			},
+			diff(newVal) {
+				let fixedTop = (newVal > 0 && newVal < 30) ? newVal - 30 : 0
+				if (this.fixedTop === fixedTop) {
+					this.fixedStyle = `translate3d(0,0,0)`
+				}
+				this.fixedTop = fixedTop
+				this.fixedStyle = `translate3d(0,${this.fixedTop}px,0)`
+			}
+		},
+		data(){
+			return{
+				scrollY:-1,//滚动记录
+				tops:[],//每一个.city-title 距离顶部的距离
+				diff:-1, // 
+				citylist:{},
+				hotcity:{},
+				currentIndex:0,
+				title:[],
+				windowH:"",
+				scrollTop:0,
+				fixedStyle:"translate3d(0,0,0)",
+				fixedTop:0,
+				locationCity:"定位中...."
+			}
+		},
+		methods:{
+			// 初始化数据列表
+			initCityList(){
+				let title = [];
+				this.hotcity = CL.hotcity;
+				this.citylist = CL.city
+				title.push("定位城市");
+				title.push(this.hotcity.title);
+				for(let i in this.citylist){
+					title.push(this.citylist[i].title)
+				}
+				this.title = title;
+				let sysInfo = uni.getSystemInfoSync();
+				this.windowH = sysInfo.windowHeight + "px"
+			} ,
+			initTop(){
+				// 1. 初始化tops
+				const query = uni.createSelectorQuery();
+				query.select('#location_city').boundingClientRect()
+				.select('#hotcity').boundingClientRect()
+				.selectAll('.city_title_wrap').boundingClientRect()
+				.exec((list)=>{
+					let tops = []
+					let top = 0
+					tops.push(top);
+					if(list[0]){
+						top += list[0].height;
+						tops.push(top)
+					}
+					if(list[1]){
+						top += list[1].height;
+						tops.push(top)
+					}
+					if(list[2].length !== 0){
+						for(let i in list[2]){
+							top+= list[2][i].height
+							tops.push(top);
+						}
+					}
+					this.tops = tops;
+				})
+			},
+			// 获取城市
+			// selectedCity({city}){
+			selectedCity(city){
+				// console.log(city);
+				this.getCity&&this.getCity({city});
+			},
+			// 定位操作
+			location(){
+				let That = this;
+				uni.chooseLocation({
+				    success(res){
+						console.log(res);
+						uni.setStorage({
+							key:"location",
+							data:[res.longitude,res.latitude]
+						})
+						console.log(res.address);
+						That.locationCity = res && res.address;
+						That.locationName = res && res.name;
+						That.selectedCity({city:That.locationCity,name:That.locationName});
+				    },
+					fail(){
+						That.locationCity = "定位失败,请点击重试";
+						That.locationName = "";
+					}
+				});
+			},
+			// 滚动条Y距离
+			scroll(e){
+				this.scrollY = e.detail && e.detail.scrollTop;
+			},
+			// 滚动到指定位置
+			scroll_to_city(index){
+				this.scrollTop = this.tops[index]
+				this.scrollY = scrollY
+				this.cityScroll.scrollTo(0, -scrollY, 300)
+			}
+		},
+		// 页面挂载后进行异步操作
+		created(){
+			this.initCityList();
+		},
+		mounted(){
+			this.location();
+			this.initTop();
+		}
+	}
+</script>
+
+<style lang="less">
+	.citylist{
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.city-list-container{
+		width: 100%;
+		height: 100%;
+		background-color: #ebebeb;
+		font-size: 14px;
+		color: #333;
+		.city-list-content{
+			margin-right: 25px;
+		}
+		.city-title{
+			padding-left: 15px;
+			line-height: 30px;
+		}
+		.city-list{
+			padding-right: 30px;
+		}
+		.city-title-letter {
+			padding-left: 25px;
+		}
+		.city-list-block {
+			background-color: #f5f5f5;
+			.city-item {
+				height: 44px;
+				line-height: 44px;
+				margin-left: 15px;
+				border-bottom: 1px solid #c8c7cc;
+				&:last-child{
+					border: 0;
+				}
+			}
+		}
+		.city-list-inline {
+			background-color: #f5f5f5;
+			padding-bottom: 8px;
+			overflow: hidden;
+			&::after{
+				content: "";
+				clear: both;
+			}
+			.location-city,.city-item {
+				float: left;
+				background: #fff;
+				width: 29%;
+				height: 33px;
+				margin-top: 15px;
+				margin-left: 4%;
+				padding: 0 4px;
+				border: 1px solid #e6e6e6;
+				border-radius: 3px;
+				line-height: 33px;
+				text-align: center;
+				box-sizing: border-box;
+				white-space: nowrap;
+				overflow: hidden;
+				text-overflow: ellipsis;
+			}
+			.location-city{
+				width: auto;
+				min-width: 30%;
+				padding: 0 20px;
+			}
+		}
+	}
+	.navrightcity {
+		position: fixed;
+		top: 50%;
+		transform: translateY(-50%);
+		right: 0;
+		width: 35px;
+		z-index: 10;
+		text-align: center;
+		font-size: 12px;
+		.nav-item {
+			height: 16px;
+			height: 2.8vh;
+		}
+		.nav-letter {
+			width: 15px;
+			margin-left: 15px;
+		}
+	}
+	.fixtitle{
+		width: 100%;
+		position: fixed;
+		top: 0;
+		left: 0;
+		overflow: hidden;
+		.city-title{
+			padding-left: 15px;
+			line-height: 30px;
+			font-size: 14px;
+			color: #333;
+			background-color: #ebebeb;
+		}
+	}
+</style>

Разница между файлами не показана из-за своего большого размера
+ 1063 - 0
components/city.js


+ 84 - 0
components/equip-item/equip-item.vue

@@ -0,0 +1,84 @@
+<template>
+	<view class="item">
+		<template v-if="item.is_online==1">
+			<view class="tag tag-on" ></view>
+		</template>
+		<template v-else>
+			<view class="tag tag-off" ></view>
+		</template>
+		<view class="info">
+			<text class="">设备ID:{{item.imei||item.device_id}}</text>
+			<text v-if="item.is_online==1" class="state on">在线</text>
+			<text v-else  class="state off">离线</text>
+		</view>
+		<slot></slot>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				tagOn:'/image/tab-on.png',
+				tagOff:'/image/tab-off.png',
+			}
+		},
+		props:[
+			'item'
+		],
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	.item {
+		background: #fff;
+		margin-top: 20rpx;
+		padding: 10rpx 30rpx;
+		padding-left:80rpx;
+		border-radius: 4rpx;
+		box-shadow: 0 0 4px 2px rgba(0, 0, 10, 0.05);
+		line-height: 60rpx;
+		position: relative;
+		.tag {
+			position: absolute;
+			width: 30rpx;
+			height: 60rpx;
+			top: 0;
+			left: 20rpx;
+			background-repeat: no-repeat;
+			background-size:100% auto;
+			background-position: top left;
+		}
+
+		.tag-on {
+			 background-image:url('http://static.yfpyx.com/bigdata_app/image/on.png');
+		}
+
+		.tag-off {
+			  background-image:url('http://static.yfpyx.com/bigdata_app/image/off.png');
+		}
+
+		.info {
+			border-bottom: 1px solid #F5F5F5;
+			color: #333;
+			font-size: 28rpx;
+			display: flex;
+			justify-content: space-between;
+			.on {
+				color: $uni-color-success;
+			}
+			.off{
+				color:$uni-color-error;
+			}
+
+		}
+
+		.date {
+			color: #999;
+			font-size: 24rpx;
+		}
+	}
+</style>

+ 13 - 0
components/js_sdk/u-charts/package.json

@@ -0,0 +1,13 @@
+{
+    "id": "u-charts",
+    "name": "uCharts高性能跨全端图表",
+    "version": "1.9.6.20210214",
+    "description": "支持H5、PC、APP、小程序(微信/支付宝/百度/头条/QQ/360)Vue、Taro",
+    "keywords": [
+        "echarts",
+        "canvas2d",
+        "F2",
+        "图表",
+        "跨全端"
+    ]
+}

+ 471 - 0
components/js_sdk/u-charts/u-charts/config.js

@@ -0,0 +1,471 @@
+/*
+ * uCharts组件 默认配置文件,如有修改,更新前请备份此文件!!
+ * Copyright (c) 2021 QIUN秋云 https://www.ucharts.cn All rights reserved.
+ * Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
+ * 
+ * uCharts官方网站
+ * https://www.uCharts.cn
+ * 
+ * 开源地址:
+ * https://gitee.com/uCharts/uCharts
+ * 
+ * uni-app插件市场地址:
+ * http://ext.dcloud.net.cn/plugin?id=271
+ * 
+ */
+module.exports = {
+	"type":["pie","ring","rose","word","funnel","map","arcbar","line","column","area","radar","gauge","candle","mix","point","bubble"],
+	"categories":["line","column","area","radar","gauge","candle","mix","point","bubble"],
+	//以上数据请勿改动,下面是自定义默认配置,请添加项目所需的个性配置
+	"pie":{
+		type: 'pie',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+			padding:5,
+			lineHeight:11,
+			margin:0,
+		},
+		dataLabel: true,
+		extra: {
+			pie: {
+		    border:true,
+		    borderColor:'#FFFFFF',
+		    borderWidth:3
+			}
+		}
+	},
+	"ring":{
+		type: 'ring',
+		padding:[5,5,5,5],
+		legend:{
+			show:true,
+			position:'right',
+			float:'center',
+			itemGap:10,
+			padding:5,
+			lineHeight:26,
+			margin:5,
+			borderWidth :1
+		},
+		disablePieStroke: true,
+		dataLabel: true,
+		subtitle: {
+			name: '70%',
+			color: '#7cb5ec',
+			fontSize: 25,
+		},
+		title: {
+			name: '收益率',
+			color: '#666666',
+			fontSize: 15,
+		},
+		extra: {
+			pie: {
+			  offsetAngle: 0,
+			  ringWidth: 40,
+			  labelWidth:15
+			}
+		}
+	},
+	"rose":{
+		type: 'rose',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+			position:'left',
+			float:'center',
+			itemGap:10,
+			padding:5,
+			lineHeight:26,
+			margin:5,
+			borderWidth :1
+		},
+		dataLabel: true,
+		extra: {
+			rose: {
+				type:'area',
+				minRadius:50,
+				activeOpacity:0.5,
+				offsetAngle:0,
+				labelWidth:15
+			}
+		}
+	},
+	"word":{
+		type: 'word',
+		extra: {
+			word: {
+				type: 'normal'
+			}
+		}
+	},
+	"funnel":{
+		type: 'funnel',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+			padding:5,
+			lineHeight:11,
+			margin:0,
+		},
+		dataLabel: true,
+		extra: {
+			funnel: {
+		    border:true,
+		    borderWidth:2,
+		    borderColor:'#FFFFFF'
+			}
+		}
+	},
+	"map":{
+		type: 'map',
+		padding:[0,0,0,0],
+		legend:{
+			show:false
+		},
+		dataLabel:true,
+		extra: {
+			map: {
+		    border:true,
+		    borderWidth:1,
+		    borderColor:'#666666',
+		    fillOpacity:0.6
+			}
+		}
+	},
+	"arcbar":{
+		type: 'arcbar',
+		legend:{show:false},
+		dataLabel: true,
+		title: {
+			name: "百分比",
+			color: '#00FF00',
+			fontSize: 25
+		},
+		subtitle: {
+			name: "默认标题",
+			color: '#666666',
+			fontSize: 15
+		},
+		extra: {
+			arcbar:{
+				type:'default',
+				width: 12,
+			}
+		}
+	},
+	"line":{
+		type: 'line',
+		padding:[15,30,0,15],
+		legend:{
+			show:true,
+			padding:5,
+			lineHeight:11,
+			margin:0,
+		},
+		dataLabel: true,
+		dataPointShape:true,
+		xAxis: {
+			disableGrid: true,
+		},
+		yAxis: {
+			gridType: 'dash',
+			gridColor: '#CCCCCC',
+			dashLength: 8,
+			splitNumber: 4,
+			format: val => {
+				return val.toFixed(0);
+			}
+		},
+		extra: {
+			line:{
+				type: 'straight'
+			}
+		}
+	},
+	"column":{
+		type: 'column',
+		padding:[15,5,0,15],
+		legend:{
+			show:true,
+			padding:5,
+			lineHeight:11,
+			margin:0,
+		},
+		animation: true,
+		dataLabel: true,
+		xAxis: {
+			disableGrid:true,
+		},
+		yAxis: {
+		  data:[{
+		    position:'right',
+				axisLine:false,
+		    format:(val)=>{return val.toFixed(0)},
+		  }]
+		},
+		extra: {
+			column: {
+				type:'group',
+				width:30
+			}
+		}
+	},
+	"area":{
+		type: 'area',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+		},
+		dataLabel:true,
+		dataPointShape:true,
+		xAxis: {
+			disableGrid:true,
+		},
+		yAxis: {
+			gridType:'dash',
+			gridColor:'#CCCCCC',
+			dashLength:8,
+			splitNumber:5,
+		},
+		extra: {
+			area:{
+				type: 'straight',
+				opacity:0.2,
+				addLine:true,
+				width:2,
+				gradient:false
+			}
+		}
+	},
+	"radar":{
+		type: 'radar',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+			padding:5,
+			lineHeight:11,
+			margin:0,
+		},
+		animation: true,
+		dataLabel: true,
+		extra: {
+			radar: {
+				max: 200,
+				gridType:'radar'//radar或者circle可选,网格样式,默认radar
+			}
+		}
+	},
+	"gauge":{
+		type: 'gauge',
+		legend:{show:false},
+		animation: true,
+		dataLabel: true,
+		title: {
+			name: "字符串类型",
+			color: '#00FF00',
+			fontSize: 25,
+			offsetY:50,
+		},
+		subtitle: {
+			name: "字符串类型",
+			color: '#666666',
+			fontSize: 15,
+			offsetY:-50,
+		},
+		extra: {
+			gauge:{
+				type:'default',
+				width: 30,
+				startAngle:0.75,
+				endAngle:0.25,
+				startNumber:0,
+				endNumber:100,
+				splitLine:{
+					fixRadius:0,
+					splitNumber:10,
+					width: 30,
+					color:'#FFFFFF',
+					childNumber:5,
+					childWidth:30*0.4,
+				},
+				pointer:{
+					width: 30*0.8,
+					color:'auto'
+				}
+			}
+		}
+	},
+	"candle":{
+		type: 'candle',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+			padding:5,
+			lineHeight:11,
+			margin:8,
+		},
+		enableMarkLine: true,
+		enableScroll: true,
+		dataLabel: false,
+		dataPointShape: true,
+		xAxis: {
+			disableGrid:true,
+			labelCount:4,
+			itemCount:5,
+			scrollShow:true,
+			scrollAlign:'right',
+		},
+		yAxis: {
+			gridType:'dash',
+			splitNumber:5,
+			format:(val)=>{return val.toFixed(0)}
+		},
+		extra: {
+			candle:{
+				color:{
+					upLine:'#f04864',
+					upFill:'#f04864',
+					downLine:'#2fc25b',
+					downFill:'#2fc25b'
+				},
+				average:{
+					show:true,
+					name:['MA5','MA10','MA30'],
+					day:[5,10,20],
+					color:['#1890ff', '#2fc25b', '#facc14']
+				}
+			},
+			tooltip:{
+				bgColor:'#000000',
+				bgOpacity:0.7,
+				gridType:'dash',
+				dashLength:5,
+				gridColor:'#1890ff',
+				fontColor:'#FFFFFF',
+				horizentalLine:true,
+				xAxisLabel:true,
+				yAxisLabel:true,
+				labelBgColor:'#DFE8FF',
+				labelBgOpacity:0.95,
+				labelAlign:'left',
+				labelFontColor:'#666666'
+			},
+		  markLine: {
+		    type: 'dash',
+		    dashLength: 5,
+		    data: [{
+		      value:2150,
+		      lineColor: '#f04864',
+		      showLabel:true
+		    },{
+		      value:2350,
+		      lineColor: '#f04864',
+		      showLabel:true
+		    }]
+		  }
+		}
+	},
+	"mix":{
+		type: 'mix',
+		padding:[15,15,0,15],
+		legend:{
+			show:true,
+		  position:'bottom',
+		  float:'center',
+			padding:5,
+			lineHeight:11,
+			margin:6,
+		},
+		dataLabel: true,
+		dataPointShape: true,
+		xAxis: {
+			disableGrid:true,
+		},
+		yAxis: {
+		  data:[{
+		    calibration:true,
+		    position:'left',
+		    title:'折线',
+		    titleFontSize:12,
+		    format:(val)=>{return val.toFixed(0)+'度'}
+		  },{
+		    calibration:true,
+		    position:'right',
+		    min:0,
+		    max:200,
+		    title:'柱状图',
+		    titleFontSize:12,
+		    format:(val)=>{return val.toFixed(0)+'元'}
+		  },{
+		    calibration:true,
+		    position:'right',
+		    min:0,
+		    max:200,
+		    title:'点',
+		    titleFontSize:12
+		  }],
+		  showTitle:true,
+			gridType:'dash',
+			dashLength:4,
+			splitNumber:5
+		},
+		extra: {
+		  column:{
+		    width:20
+		  }
+		}
+	},
+	"point":{
+		type: 'point',
+		padding:[15,30,0,15],
+		legend:{
+			show:true
+		},
+		dataLabel: false,
+		dataPointShape:true,
+		xAxis: {
+			disableGrid: true,
+			labelCount: 4
+		},
+		yAxis: {
+			gridType: 'dash',
+			gridColor: '#CCCCCC',
+			dashLength: 8,
+			splitNumber: 4,
+			format: val => {
+				return val.toFixed(1);
+			}
+		},
+		extra: {
+			point:{
+			}
+		}
+	},
+	"bubble":{
+		type: 'bubble',
+		padding:[15,30,0,15],
+		legend:{
+			show:true
+		},
+		dataLabel: true,
+		xAxis: {
+			disableGrid: true,
+			labelCount: 4
+		},
+		yAxis: {
+			gridType: 'dash',
+			gridColor: '#CCCCCC',
+			dashLength: 8,
+			splitNumber: 4,
+			format: val => {
+				return val.toFixed(1);
+			}
+		},
+		extra: {
+			bubble:{
+			}
+		}
+	}
+}

+ 267 - 0
components/js_sdk/u-charts/u-charts/demodata.json

@@ -0,0 +1,267 @@
+{
+	"Column": {
+		"categories": ["2016", "2017", "2018", "2019", "2020", "2021"],
+		"series": [{
+			"name": "目标值",
+			"data": [35, 36, 31, 33, 13, 34]
+		}, {
+			"name": "完成量",
+			"data": [18, 27, 21, 24, 6, 28]
+		}]
+	},
+	"ColumnA": {
+		"categories": ["2016", "2017", "2018", "2019", "2020", "2021"],
+		"series": [{
+			"name": "成交量1",
+			"data": [15, {
+				"value": 20,
+				"color": "#f04864"
+			}, 45, 37, 43, 34]
+		}, {
+			"name": "成交量2",
+			"data": [30, {
+				"value": 40,
+				"color": "#facc14"
+			}, 25, 14, 34, 18]
+		}]
+	},
+	"Mix": {
+		"categories": ["2016", "2017", "2018", "2019", "2020", "2021"],
+		"series": [{
+			"name": "曲面",
+			"data": [70, 50, 85, 130, 64, 88],
+			"type": "area",
+			"style": "curve"
+		}, {
+			"name": "柱1",
+			"data": [40, 30, 55, 110, 24, 58],
+			"type": "column"
+		}, {
+			"name": "柱2",
+			"data": [50, 20, 75, 60, 34, 38],
+			"type": "column"
+		}, {
+			"name": "曲线",
+			"data": [70, 50, 85, 130, 64, 88],
+			"type": "line",
+			"style": "curve",
+			"color": "#1890ff",
+			"disableLegend": true
+		}, {
+			"name": "折线",
+			"data": [120, 140, 105, 170, 95, 160],
+			"type": "line",
+			"color": "#2fc25b"
+		}, {
+			"name": "点",
+			"data": [100, 80, 125, 150, 112, 132],
+			"type": "point",
+			"color": "#f04864"
+		}]
+	},
+	"Line": {
+		"categories": ["2016", "2017", "2018", "2019", "2020", "2021"],
+		"series": [{
+			"name": "成交量A",
+			"data": [35, 8, 25, 37, 4, 20]
+		}, {
+			"name": "成交量B",
+			"data": [70, 40, 65, 100, 44, 68]
+		}, {
+			"name": "成交量C",
+			"data": [100, 80, 95, 150, 112, 132]
+		}]
+	},
+	"Pie": {
+		"series": [{
+			"name": "一班",
+			"data": 50
+		}, {
+			"name": "二班",
+			"data": 30
+		}, {
+			"name": "三班",
+			"data": 20
+		}, {
+			"name": "四班",
+			"data": 18
+		}, {
+			"name": "五班",
+			"data": 8
+		}]
+	},
+	"Radar": {
+		"categories": ["维度1", "维度2", "维度3", "维度4", "维度5", "维度6"],
+		"series": [{
+			"name": "成交量1",
+			"data": [90, 110, 165, 195, 187, 172]
+		}, {
+			"name": "成交量2",
+			"data": [190, 210, 105, 35, 27, 102]
+		}]
+	},
+	"Arcbar": {
+		"series": [{
+			"name": "正确率",
+			"data": 0.29,
+			"color": "#2fc25b"
+		}]
+	},
+	"Gauge": {
+		"categories": [{
+			"value": 0.2,
+			"color": "#1890ff"
+		}, {
+			"value": 0.8,
+			"color": "#2fc25b"
+		}, {
+			"value": 1,
+			"color": "#f04864"
+		}],
+		"series": [{
+			"name": "完成率",
+			"data": 0.66
+		}]
+	},
+	"Candle": {
+		"categories": [
+			"2020/1/24", "2020/1/25", "2020/1/28", "2020/1/29", "2020/1/30",
+			"2020/1/31", "2020/2/1", "2020/2/4", "2020/2/5", "2020/2/6",
+			"2020/2/7", "2020/2/8", "2020/2/18", "2020/2/19", "2020/2/20",
+			"2020/2/21", "2020/2/22", "2020/2/25", "2020/2/26", "2020/2/27",
+			"2020/2/28", "2020/3/1", "2020/3/4", "2020/3/5", "2020/3/6",
+			"2020/3/7", "2020/3/8", "2020/3/11", "2020/3/12", "2020/3/13",
+			"2020/3/14", "2020/3/15", "2020/3/18", "2020/3/19", "2020/3/20",
+			"2020/3/21", "2020/3/22", "2020/3/25", "2020/3/26", "2020/3/27",
+			"2020/3/28", "2020/3/29", "2020/4/1", "2020/4/2", "2020/4/3",
+			"2020/4/8", "2020/4/9", "2020/4/10", "2020/4/11", "2020/4/12",
+			"2020/4/15", "2020/4/16", "2020/4/17", "2020/4/18", "2020/4/19",
+			"2020/4/22", "2020/4/23", "2020/4/24", "2020/4/25", "2020/4/26",
+			"2020/5/2", "2020/5/3", "2020/5/6", "2020/5/7", "2020/5/8",
+			"2020/5/9", "2020/5/10", "2020/5/13", "2020/5/14", "2020/5/15",
+			"2020/5/16", "2020/5/17", "2020/5/20", "2020/5/21", "2020/5/22",
+			"2020/5/23", "2020/5/24", "2020/5/27", "2020/5/28", "2020/5/29",
+			"2020/5/30", "2020/5/31", "2020/6/3", "2020/6/4", "2020/6/5",
+			"2020/6/6", "2020/6/7", "2020/6/13"
+		],
+		"series": [{
+			"name": "上证指数",
+			"data": [
+				[2320.26, 2302.6, 2287.3, 2362.94],
+				[2300, 2291.3, 2288.26, 2308.38],
+				[2295.35, 2346.5, 2295.35, 2346.92],
+				[2347.22, 2358.98, 2337.35, 2363.8],
+				[2360.75, 2382.48, 2347.89, 2383.76],
+				[2383.43, 2385.42, 2371.23, 2391.82],
+				[2377.41, 2419.02, 2369.57, 2421.15],
+				[2425.92, 2428.15, 2417.58, 2440.38],
+				[2411, 2433.13, 2403.3, 2437.42],
+				[2432.68, 2434.48, 2427.7, 2441.73],
+				[2430.69, 2418.53, 2394.22, 2433.89],
+				[2416.62, 2432.4, 2414.4, 2443.03],
+				[2441.91, 2421.56, 2415.43, 2444.8],
+				[2420.26, 2382.91, 2373.53, 2427.07],
+				[2383.49, 2397.18, 2370.61, 2397.94],
+				[2378.82, 2325.95, 2309.17, 2378.82],
+				[2322.94, 2314.16, 2308.76, 2330.88],
+				[2320.62, 2325.82, 2315.01, 2338.78],
+				[2313.74, 2293.34, 2289.89, 2340.71],
+				[2297.77, 2313.22, 2292.03, 2324.63],
+				[2322.32, 2365.59, 2308.92, 2366.16],
+				[2364.54, 2359.51, 2330.86, 2369.65],
+				[2332.08, 2273.4, 2259.25, 2333.54],
+				[2274.81, 2326.31, 2270.1, 2328.14],
+				[2333.61, 2347.18, 2321.6, 2351.44],
+				[2340.44, 2324.29, 2304.27, 2352.02],
+				[2326.42, 2318.61, 2314.59, 2333.67],
+				[2314.68, 2310.59, 2296.58, 2320.96],
+				[2309.16, 2286.6, 2264.83, 2333.29],
+				[2282.17, 2263.97, 2253.25, 2286.33],
+				[2255.77, 2270.28, 2253.31, 2276.22],
+				[2269.31, 2278.4, 2250, 2312.08],
+				[2267.29, 2240.02, 2239.21, 2276.05],
+				[2244.26, 2257.43, 2232.02, 2261.31],
+				[2257.74, 2317.37, 2257.42, 2317.86],
+				[2318.21, 2324.24, 2311.6, 2330.81],
+				[2321.4, 2328.28, 2314.97, 2332],
+				[2334.74, 2326.72, 2319.91, 2344.89],
+				[2318.58, 2297.67, 2281.12, 2319.99],
+				[2299.38, 2301.26, 2289, 2323.48],
+				[2273.55, 2236.3, 2232.91, 2273.55],
+				[2238.49, 2236.62, 2228.81, 2246.87],
+				[2229.46, 2234.4, 2227.31, 2243.95],
+				[2234.9, 2227.74, 2220.44, 2253.42],
+				[2232.69, 2225.29, 2217.25, 2241.34],
+				[2196.24, 2211.59, 2180.67, 2212.59],
+				[2215.47, 2225.77, 2215.47, 2234.73],
+				[2224.93, 2226.13, 2212.56, 2233.04],
+				[2236.98, 2219.55, 2217.26, 2242.48],
+				[2218.09, 2206.78, 2204.44, 2226.26],
+				[2199.91, 2181.94, 2177.39, 2204.99],
+				[2169.63, 2194.85, 2165.78, 2196.43],
+				[2195.03, 2193.8, 2178.47, 2197.51],
+				[2181.82, 2197.6, 2175.44, 2206.03],
+				[2201.12, 2244.64, 2200.58, 2250.11],
+				[2236.4, 2242.17, 2232.26, 2245.12],
+				[2242.62, 2184.54, 2182.81, 2242.62],
+				[2187.35, 2218.32, 2184.11, 2226.12],
+				[2213.19, 2199.31, 2191.85, 2224.63],
+				[2203.89, 2177.91, 2173.86, 2210.58],
+				[2170.78, 2174.12, 2161.14, 2179.65],
+				[2179.05, 2205.5, 2179.05, 2222.81],
+				[2212.5, 2231.17, 2212.5, 2236.07],
+				[2227.86, 2235.57, 2219.44, 2240.26],
+				[2242.39, 2246.3, 2235.42, 2255.21],
+				[2246.96, 2232.97, 2221.38, 2247.86],
+				[2228.82, 2246.83, 2225.81, 2247.67],
+				[2247.68, 2241.92, 2231.36, 2250.85],
+				[2238.9, 2217.01, 2205.87, 2239.93],
+				[2217.09, 2224.8, 2213.58, 2225.19],
+				[2221.34, 2251.81, 2210.77, 2252.87],
+				[2249.81, 2282.87, 2248.41, 2288.09],
+				[2286.33, 2299.99, 2281.9, 2309.39],
+				[2297.11, 2305.11, 2290.12, 2305.3],
+				[2303.75, 2302.4, 2292.43, 2314.18],
+				[2293.81, 2275.67, 2274.1, 2304.95],
+				[2281.45, 2288.53, 2270.25, 2292.59],
+				[2286.66, 2293.08, 2283.94, 2301.7],
+				[2293.4, 2321.32, 2281.47, 2322.1],
+				[2323.54, 2324.02, 2321.17, 2334.33],
+				[2316.25, 2317.75, 2310.49, 2325.72],
+				[2320.74, 2300.59, 2299.37, 2325.53],
+				[2300.21, 2299.25, 2294.11, 2313.43],
+				[2297.1, 2272.42, 2264.76, 2297.1],
+				[2270.71, 2270.93, 2260.87, 2276.86],
+				[2264.43, 2242.11, 2240.07, 2266.69],
+				[2242.26, 2210.9, 2205.07, 2250.63],
+				[2190.1, 2148.35, 2126.22, 2190.1]
+			]
+		}]
+	},
+	"CandleColumn": {
+		"categories": [
+			"2020/1/24", "2020/1/25", "2020/1/28", "2020/1/29", "2020/1/30",
+			"2020/1/31", "2020/2/1", "2020/2/4", "2020/2/5", "2020/2/6",
+			"2020/2/7", "2020/2/8", "2020/2/18", "2020/2/19", "2020/2/20",
+			"2020/2/21", "2020/2/22", "2020/2/25", "2020/2/26", "2020/2/27",
+			"2020/2/28", "2020/3/1", "2020/3/4", "2020/3/5", "2020/3/6",
+			"2020/3/7", "2020/3/8", "2020/3/11", "2020/3/12", "2020/3/13",
+			"2020/3/14", "2020/3/15", "2020/3/18", "2020/3/19", "2020/3/20",
+			"2020/3/21", "2020/3/22", "2020/3/25", "2020/3/26", "2020/3/27",
+			"2020/3/28", "2020/3/29", "2020/4/1", "2020/4/2", "2020/4/3",
+			"2020/4/8", "2020/4/9", "2020/4/10", "2020/4/11", "2020/4/12",
+			"2020/4/15", "2020/4/16", "2020/4/17", "2020/4/18", "2020/4/19",
+			"2020/4/22", "2020/4/23", "2020/4/24", "2020/4/25", "2020/4/26",
+			"2020/5/2", "2020/5/3", "2020/5/6", "2020/5/7", "2020/5/8",
+			"2020/5/9", "2020/5/10", "2020/5/13", "2020/5/14", "2020/5/15",
+			"2020/5/16", "2020/5/17", "2020/5/20", "2020/5/21", "2020/5/22",
+			"2020/5/23", "2020/5/24", "2020/5/27", "2020/5/28", "2020/5/29",
+			"2020/5/30", "2020/5/31", "2020/6/3", "2020/6/4", "2020/6/5",
+			"2020/6/6", "2020/6/7", "2020/6/13"
+		],
+		"series": [{
+			"name": "成交量1",
+			"data": [15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45, 37, 43, 15, 20, 45]
+		}]
+	}
+}

Разница между файлами не показана из-за своего большого размера
+ 41 - 0
components/js_sdk/u-charts/u-charts/mapdata.json


+ 6 - 0
components/js_sdk/u-charts/u-charts/readme.md

@@ -0,0 +1,6 @@
+# uCharts JSSDK说明
+1、如不使用uCharts组件,可直接引用u-charts.js,打包编译后会`自动压缩`,压缩后体积约为`90kb`。
+2、如果90kb的体积仍需压缩,请手动删除u-charts.js内您不需要的图表类型,如k线图candle。
+3、config.js为uCharts组件的用户配置文件,升级前请`自行备份config.js`文件,以免被强制覆盖。
+4、demodata.json为标准数据格式,仅供演示使用。
+5、mapdata.json为地图数据格式,遵循geoJson地图数据交换格式参考:http://datav.aliyun.com/tools/atlas/

Разница между файлами не показана из-за своего большого размера
+ 5687 - 0
components/js_sdk/u-charts/u-charts/u-charts.js


+ 443 - 0
components/js_sdk/u-charts/u-charts/u-charts.vue

@@ -0,0 +1,443 @@
+<template>
+	<view class="chartsview" :style="{ background: background }">
+		<view v-show="mixinDatacomLoading"><view class="uni-icons-spinner-cycle">Loading...</view></view>
+		<view v-show="mixinDatacomErrorMessage">
+			<view class="uni-icons-info-filled">{{ mixinDatacomErrorMessage }}</view>
+		</view>
+		<canvas
+			:id="canvasId"
+			:canvas-id="canvasId"
+			:style="{ width: cWidth + 'px', height: cHeight + 'px' }"
+			:type="canvas2d?'2d':''"
+			@tap="tap"
+			@cilck="tap"
+			@touch="tap"
+			@touchstart="touchStart"
+			@touchmove="touchMove"
+			@touchend="touchEnd"
+			@mousemove="mouseMove"
+			@mousedown="mousedown"
+			@mouseup="mouseup"
+			@error="error"
+			v-show="showchart"
+		/>
+	</view>
+</template>
+
+<script>
+import qiunCharts from '../../js_sdk/u-charts/u-charts.js';
+import config from '../../js_sdk/u-charts/config.js';
+var canvases = {};
+var options = {};
+var chartdom = null;
+export default {
+	mixins: [uniCloud.mixinDatacom],
+	props: {
+		type: {
+			type: String,
+			default: null
+		},
+		canvasId: {
+			type: String,
+			default: "uchartsid"
+		},
+		canvas2d: {
+			type: Boolean,
+			default: false
+		},
+		pixelRatio: {
+			type: Number,
+			default: 1
+		},
+		background: {
+			type: String,
+			default: 'none'
+		},
+		animation:{
+			type: Boolean,
+			default: true
+		},
+		chartData: {
+			type: Object,
+			default() {
+				return {
+					categories: [],
+					series: []
+				};
+			}
+		},
+		opts: {
+			type: Object,
+			default: () => ({})
+		},
+		inScrollView:{
+			type: Boolean,
+			default: false
+		},
+		show:{
+			type: Boolean,
+			default: false
+		}
+	},
+	data() {
+		return {
+			cWidth: 375,
+			cHeight: 250,
+			showchart: false,
+			defaultOpts: {}
+		};
+	},
+	mounted() {
+		if(this.canvasId=='uchartsid'){
+			console.warn("注意:请在uCharts组件传入canvasId,以免单页多图产生图表错乱!")
+		}
+		if (this.type && config.type.includes(this.type)) {
+			this.defaultOpts = Object.assign({},config[this.type])
+			this.load()
+		} else {
+			this.mixinDatacomLoading = false
+			this.showchart = false
+			this.mixinDatacomErrorMessage = '参数错误:props参数中type类型不正确'
+		}
+		uni.onWindowResize(res => {
+			this.init()
+		})
+	},
+	watch: {
+		chartData(val, oldval) {
+			if (!this.type || !config.type.includes(this.type)) {
+				this.mixinDatacomLoading = false
+				this.showchart = false
+				this.mixinDatacomErrorMessage = '参数错误:props参数中type不正确'
+				return
+			}
+			if (typeof val === 'object') {
+				if (this.collection != '') {
+					if (config.categories.includes(this.type) && val.categories.length == 0 ) {
+						this.mixinDatacomLoading = false
+						this.showchart = false
+						this.mixinDatacomErrorMessage = '数据错误:chartData中缺少categories'
+					} else {
+						this.mixinDatacomLoading = false
+						this.mixinDatacomErrorMessage = null
+						this.$nextTick(function() {
+							this.init()
+						})
+					}
+				} else {
+					this.mixinDatacomLoading = false
+					this.mixinDatacomErrorMessage = null
+					this.$nextTick(function() {
+						this.init()
+					});
+				}
+			} else {
+				this.mixinDatacomLoading = false
+				this.showchart = false
+				this.mixinDatacomErrorMessage = '参数错误:chartData数据类型错误'
+			}
+		},
+		show(val, oldval) {
+			if (val) {
+				if (this.collection != '') {
+					if (config.categories.includes(this.type) && this.chartData.categories.length == 0 ) {
+						this.mixinDatacomLoading = false
+						this.showchart = false
+						this.mixinDatacomErrorMessage = '数据错误:chartData中缺少categories'
+					} else {
+						this.mixinDatacomLoading = false
+						this.mixinDatacomErrorMessage = null
+						this.$nextTick(function() {
+							this.init()
+						})
+					}
+				} else {
+					this.mixinDatacomLoading = false
+					this.mixinDatacomErrorMessage = null
+					this.$nextTick(function() {
+						this.init()
+					});
+				}
+			}
+		}
+	},
+	methods: {
+		load() {
+			if (this.mixinDatacomLoading == true) {
+				return
+			}
+			this.mixinDatacomLoading = true
+			if (this.collection != '') {
+				this.mixinDatacomGet()
+					.then(res => {
+						this.mixinDatacomLoading = false
+						const { data, count } = res.result
+						this.mixinDatacomResData = data
+						if (config.categories.includes(this.type) && this.chartData.categories.length == 0) {
+							this.mixinDatacomLoading = false
+							this.showchart = false
+							this.mixinDatacomErrorMessage = '数据错误:chartData中缺少categories'
+						} else {
+							this.init()
+						}
+					})
+					.catch(err => {
+						if (this.collection == '') {
+							if (this.chartData.series.length > 0) {
+								this.mixinDatacomLoading = false
+								this.init()
+							}
+						} else {
+							this.mixinDatacomLoading = false
+							this.showchart = false
+							this.mixinDatacomErrorMessage = '请求错误:' + err
+						}
+					});
+			}else{
+				if (this.chartData.series.length > 0) {
+					this.mixinDatacomLoading = false
+					this.init()
+				}
+			}
+		},
+		onMixinDatacomPropsChange(needReset, changed) {
+			if (needReset) {
+				if(options[this.canvasId] !== undefined){
+					options[this.canvasId].context.clearRect(0, 0, options[this.canvasId].width, options[this.canvasId].height)
+					options[this.canvasId].context.draw()
+				}
+				this.showchart = false;
+				this.load()
+			}
+		},
+		cloudDataInit() {
+			let temp = {}
+			let series=[]
+			let resdata = this.mixinDatacomResData
+			let categories = options[this.canvasId].categories
+			resdata.map(function (item, index) {
+				if(item.type!=undefined && !temp[item.type]){
+					series.push({name:item.type,data:[]})
+					temp[item.type] = true;
+				}
+			})
+			if(series.length==0){
+				let seriesname="默认分组"
+				if(this.chartData.series.length>0){
+					seriesname=this.chartData.series[0].name
+				}
+				series=[{name:seriesname,data:[]}]
+				for (let j = 0; j < categories.length; j++) {
+					let seriesdata = 0;
+					for (let i = 0; i < resdata.length; i++) {
+						if(resdata[i].label == categories[j]){
+							seriesdata = resdata[i].value
+						}
+					}
+					series[0].data.push(seriesdata)
+				}
+			}else{
+				for (let k = 0; k < series.length; k++) {
+					if(categories.length>0){
+						for (let j = 0; j < categories.length; j++) {
+							let seriesdata = 0;
+							for (let i = 0; i < resdata.length; i++) {
+								if(series[k].name == resdata[i].type && resdata[i].label == categories[j]){
+									seriesdata = resdata[i].value
+								}
+							}
+							series[k].data.push(seriesdata)
+						}
+					}else{
+						for (let i = 0; i < resdata.length; i++) {
+							if(series[k].name == resdata[i].type){
+								series[k].data.push(resdata[i].type)
+							}
+						}
+					}
+				}
+			}
+			return series;
+		},
+		init() {
+			chartdom = uni.createSelectorQuery().in(this).select('.chartsview');
+			chartdom.boundingClientRect(data => {
+				if(data.width>0 && data.height>0){
+					this.cWidth = data.width
+					this.cHeight = data.height
+					options[this.canvasId] = Object.assign(this.defaultOpts, this.opts)
+					options[this.canvasId].canvasId = this.canvasId
+					options[this.canvasId].categories = this.chartData.categories
+					if (this.collection == '') {
+						options[this.canvasId].series = this.chartData.series
+					}else{
+						options[this.canvasId].series = this.cloudDataInit()
+					}
+					options[this.canvasId].background = this.background == 'none' ? '#FFFFFF' : this.background
+					options[this.canvasId].pixelRatio = this.pixelRatio
+					options[this.canvasId].animation = this.animation
+					options[this.canvasId].width = data.width * this.pixelRatio
+					options[this.canvasId].height = data.height * this.pixelRatio
+					if(this.canvas2d){
+						options[this.canvasId].canvas2d = this.canvas2d
+						const query = uni.createSelectorQuery().in(this)
+						query.select('#'+this.canvasId)
+							.fields({ node: true, size: true })
+							.exec((res) => {
+								const canvas = res[0].node
+								const ctx = canvas.getContext('2d')
+								options[this.canvasId].context = ctx
+								canvas.width = data.width * this.pixelRatio
+								canvas.height = data.height * this.pixelRatio
+								canvas._width = data.width * this.pixelRatio
+								canvas._height = data.height * this.pixelRatio
+								if(!this.mixinDatacomLoading){
+									this.showchart = true
+								}
+								this.newChart()
+							})
+					}else{
+						options[this.canvasId].context = uni.createCanvasContext(this.canvasId,this)
+						if(!this.mixinDatacomLoading){
+							this.showchart = true
+						}
+						this.newChart()
+					}
+				}else{
+					this.mixinDatacomLoading = false
+					this.showchart = false
+					this.mixinDatacomErrorMessage = '布局错误:请尝试props绑定show状态'
+				}
+			}).exec();
+		},
+		newChart() {
+			canvases[this.canvasId] = new qiunCharts(options[this.canvasId])
+			canvases[this.canvasId].addEventListener('renderComplete', () => {
+				this.$emit("complete",{complete:true,charts:canvases[this.canvasId]})
+			});
+			canvases[this.canvasId].addEventListener('scrollLeft', () => {
+				this.$emit("scrollLeft",{scrollLeft:true,charts:canvases[this.canvasId]})
+			});
+			canvases[this.canvasId].addEventListener('scrollRight', () => {
+				this.$emit("scrollRight",{scrollRight:true,charts:canvases[this.canvasId]})
+			});
+		},
+		tap(e) {
+			let currentIndex=null
+			let legendIndex=null
+			if(this.inScrollView){
+				e.type = 'click'
+			}
+			if (e.type == 'click') {
+				chartdom = uni.createSelectorQuery().in(this).select('.chartsview')
+				chartdom.boundingClientRect(data => {
+					e.changedTouches.unshift({ x: e.detail.x - data.left, y: e.detail.y - data.top })
+					e.mp.changedTouches.unshift({ x: e.detail.x - data.left, y: e.detail.y - data.top })
+					canvases[this.canvasId].touchLegend(e)
+					canvases[this.canvasId].showToolTip(e, {
+						format: function(item, category) {
+							if(category){
+								return category + ' ' + item.name + ':' + item.data
+							}else{
+								return item.name + ':' + item.data
+							}
+						}
+					})
+					currentIndex=canvases[this.canvasId].getCurrentDataIndex(e)
+					legendIndex=canvases[this.canvasId].getLegendDataIndex(e) 
+					this.$emit("getIndex",{event:e,currentIndex:currentIndex,legendIndex:legendIndex,charts:canvases[this.canvasId]})
+				}).exec();
+			} else {
+				e.changedTouches.unshift({ x: e.detail.x - e.currentTarget.offsetLeft, y: e.detail.y - e.currentTarget.offsetTop })
+				e.mp.changedTouches.unshift({ x: e.detail.x - e.currentTarget.offsetLeft, y: e.detail.y - e.currentTarget.offsetTop })
+				canvases[this.canvasId].touchLegend(e)
+				canvases[this.canvasId].showToolTip(e, {
+					format: function(item, category) {
+						if(category){
+							return category + ' ' + item.name + ':' + item.data
+						}else{
+							return item.name + ':' + item.data
+						}
+					}
+				});
+				currentIndex=canvases[this.canvasId].getCurrentDataIndex(e)
+				legendIndex=canvases[this.canvasId].getLegendDataIndex(e) 
+				this.$emit("getIndex",{event:e,currentIndex:currentIndex,legendIndex:legendIndex,charts:canvases[this.canvasId]})
+			}
+		},
+		touchStart(e) {
+			canvases[this.canvasId].scrollStart(e)
+			this.$emit("touchStart",{event:e,charts:canvases[this.canvasId]})
+		},
+		touchMove(e) {
+			canvases[this.canvasId].scroll(e)
+			this.$emit("touchMove",{event:e,charts:canvases[this.canvasId]})
+		},
+		touchEnd(e) {
+			canvases[this.canvasId].scrollEnd(e)
+			this.$emit("touchEnd",{event:e,charts:canvases[this.canvasId]})
+		},
+		mousedown(e){
+			if(options[this.canvasId].enableScroll){
+				chartdom = uni.createSelectorQuery().in(this).select('.chartsview')
+				chartdom.boundingClientRect(data => {
+					e.changedTouches.unshift({ x: e.pageX - data.left, y: e.clientY-data.top })
+					e.mp.changedTouches.unshift({ x: e.pageX - data.left, y: e.clientY-data.top })
+					canvases[this.canvasId].scrollStart(e)
+					options[this.canvasId].mousedown=true;
+					this.$emit("touchStart",{event:e,charts:canvases[this.canvasId]})
+				}).exec();
+			}
+		},
+		mouseMove(e) {
+			if (options[this.canvasId].series.length > 0) {
+				chartdom = uni.createSelectorQuery().in(this).select('.chartsview')
+				chartdom.boundingClientRect(data => {
+					e.changedTouches.unshift({ x: e.pageX - data.left, y: e.clientY-data.top })
+					e.mp.changedTouches.unshift({ x: e.pageX - data.left, y: e.clientY-data.top })
+					if(options[this.canvasId].enableScroll && options[this.canvasId].mousedown){
+						canvases[this.canvasId].scroll(e)
+						this.$emit("touchMove",{event:e,charts:canvases[this.canvasId]})
+					}else{
+						canvases[this.canvasId].showToolTip(e, {
+							format: function(item, category) {
+								if(category){
+									return category + ' ' + item.name + ':' + item.data
+								}else{
+									return item.name + ':' + item.data
+								}
+							}
+						});
+					}
+				}).exec()
+			}
+		},
+		mouseup(e){
+			if(options[this.canvasId].enableScroll){
+				chartdom = uni.createSelectorQuery().in(this).select('.chartsview')
+				chartdom.boundingClientRect(data => {
+					e.changedTouches.unshift({ x: e.pageX - data.left, y: e.clientY-data.top })
+					e.mp.changedTouches.unshift({ x: e.pageX - data.left, y: e.clientY-data.top })
+					canvases[this.canvasId].scrollEnd(e)
+					options[this.canvasId].mousedown=false;
+					this.$emit("touchEnd",{event:e,charts:canvases[this.canvasId]})
+				}).exec();
+			}
+		},
+		error(e) {
+			console.log(e)
+		}
+	}
+};
+</script>
+
+<style scoped>
+.chartsview {
+	width: 100%;
+	height: 100%;
+	display: flex;
+	flex: 1;
+	justify-content: center;
+	align-items: center;
+}
+</style>

+ 639 - 0
components/ksp-image-cutter/ksp-image-cutter.vue

@@ -0,0 +1,639 @@
+<template>
+<view v-show="url" class="ksp-image-cutter">
+	<canvas :style="{width: target.width + 'px', height: target.height + 'px'}" canvas-id="target"></canvas>
+	<view class="body">
+		<image v-if="url" class="image" @load="imageLoad" :style="{left: image.left + 'px', top: image.top + 'px', width: image.width + 'px', height: image.height + 'px'}" :src="url"></image>
+		<view v-if="mask.show" class="mask"></view>
+		<view @touchstart="touchStart($event, 'plank')" @touchmove="touchMove" @touchend="touchEnd" @touchcancel="touchCancel"  class="plank">
+			<view class="frame" @touchstart="touchStart($event, 'frame')" @touchstart.stop.prevent="touchHandle" :style="{left: frame.left + 'px', top: frame.top + 'px', width: frame.width + 'px', height: frame.height + 'px'}">
+				<canvas v-if="mask.show" class="canvas" :style="{width: frame.width + 'px', height: frame.height + 'px'}" canvas-id="canvas"></canvas>
+				<view class="rect"></view>
+				<view class="line-one"></view>
+				<view class="line-two"></view>
+				<view class="line-three"></view>
+				<view class="line-four"></view>
+				<view @touchstart="touchStart($event, 'left')" @touchstart.stop.prevent="touchHandle" class="frame-left"></view>
+				<view @touchstart="touchStart($event, 'right')" @touchstart.stop.prevent="touchHandle" class="frame-right"></view>
+				<view @touchstart="touchStart($event, 'top')" @touchstart.stop.prevent="touchHandle" class="frame-top"></view>
+				<view @touchstart="touchStart($event, 'bottom')" @touchstart.stop.prevent="touchHandle" class="frame-bottom"></view>
+				<view @touchstart="touchStart($event, 'left-top')" @touchstart.stop.prevent="touchHandle" class="frame-left-top"></view>
+				<view @touchstart="touchStart($event, 'left-bottom')" @touchstart.stop.prevent="touchHandle" class="frame-left-bottom"></view>
+				<view @touchstart="touchStart($event, 'right-top')" @touchstart.stop.prevent="touchHandle" class="frame-right-top"></view>
+				<view @touchstart="touchStart($event, 'right-bottom')" @touchstart.stop.prevent="touchHandle" class="frame-right-bottom"></view>
+			</view>
+		</view>
+	</view>
+	<view class="toolbar">
+		<button @tap="oncancle" class="btn-cancel">返回</button>
+		<button @tap="onok" class="btn-ok">确定</button>
+	</view>
+</view>
+</template>
+
+<script>
+export default {
+	props: {
+		url: {
+			type: String,
+			default: ""
+		},
+		fixed: {
+			type: Boolean,
+			default: false
+		},
+		width: {
+			type: Number,
+			default: 200
+		},
+		height: {
+			type: Number,
+			default: 200
+		},
+		maxWidth: {
+			type: Number,
+			default: 1024
+		},
+		maxHeight: {
+			type: Number,
+			default: 1024
+		},
+		blob: {
+			type: Boolean,
+			default: true
+		}
+	},
+	data() {
+		return {
+			mask: {
+				show: false
+			},
+			frame: {
+				left: 50,
+				top: 50,
+				width: this.width,
+				height: this.height
+			},
+			image: {
+				left: 20,
+				top: 20,
+				width: 300,
+				height: 400
+			},
+			real: {
+				width: 100,
+				height: 100
+			},
+			target: {
+				width: this.width,
+				height: this.height
+			},
+			touches: [],
+			type: "",
+			start: {
+				frame: {
+					left: 0,
+					top: 0,
+					width: 0,
+					height: 0
+				},
+				image: {
+					left: 0,
+					top: 0,
+					width: 0,
+					height: 0
+				},
+			},
+			timeoutId: -1,
+			context: null
+		};
+	},
+	mounted() {
+		//#ifdef H5
+		this.$el.addEventListener("touchmove", (ev) => {
+			ev.preventDefault();
+		});
+		// #endif
+		this.context = uni.createCanvasContext("canvas", this);
+		this.targetContext = uni.createCanvasContext("target", this);
+	},
+	methods: {
+		imageLoad(ev) {
+			this.mask.show = true;
+			this.real.width = ev.detail.width;
+			this.real.height = ev.detail.height;
+			this.image.width = ev.detail.width;
+			this.image.height = ev.detail.height;
+			this.frame.width = this.width;
+			this.frame.height = this.height;
+			if (!this.fixed) {
+				this.frame.width = this.image.width;
+				this.frame.height = this.image.height;
+			}
+			var query = uni.createSelectorQuery().in(this);
+			query.select(".body").boundingClientRect((data) => {
+				var bw = data.width;
+				var bh = data.height;
+				var fw = this.frame.width;
+				var fh = this.frame.height;
+				var tw = bw * 0.8;
+				var th = bh * 0.8;
+				var sx = tw / fw;
+				var sy = th / fh;
+				var scale = sx;
+				if (sx < sy) {
+					scale = sy;
+				}
+				tw = fw * scale;
+				th = fh * scale;
+				var tx = (bw - tw) / 2;
+				var ty = (bh - th) / 2;
+				this.frame.width = tw;
+				this.frame.height = th;
+				this.frame.left = tx;
+				this.frame.top = ty;
+				
+				var iw = this.image.width;
+				var ih = this.image.height;
+				sx = tw / iw;
+				sy = th / ih;
+				scale = sx;
+				if (sx < sy) {
+					scale = sy;
+				}
+				this.image.width = iw * scale;
+				this.image.height = ih * scale;
+				this.image.left = (bw - this.image.width) / 2;
+				this.image.top = (bh - this.image.height) / 2;
+				setTimeout(() => {
+					this.trimImage();
+				}, 100);
+			}).exec();
+		},
+		touchHandle() {},
+		touchStart(ev, type) {
+			this.stopTime();
+			this.mask.show = false;
+			if (this.touches.length == 0) {
+				this.type = type;
+				this.start.frame.left = this.frame.left;
+				this.start.frame.top = this.frame.top;
+				this.start.frame.width = this.frame.width;
+				this.start.frame.height = this.frame.height;
+				this.start.image.left = this.image.left;
+				this.start.image.top = this.image.top;
+				this.start.image.width = this.image.width;
+				this.start.image.height = this.image.height;
+			}
+			var touches = ev.changedTouches;
+			for(var i = 0; i < touches.length; i++) {
+				var touch = touches[i];
+				// this.touches[touch.identifier] = touch;
+				this.touches.push(touch);
+			}
+		},
+		touchMove(ev) {
+			this.stopTime();
+			ev.preventDefault();
+			var touches = ev.touches;
+			if (this.touches.length == 1) {
+				if (this.type == "plank" || this.type == "frame" || this.fixed) {
+					this.moveImage(this.touches[0], touches[0]);
+				} else {
+					this.scaleFrame(this.touches[0], touches[0], this.type);
+				}
+			} else if (this.touches.length == 2 && touches.length == 2) {
+				var ta = this.touches[0];
+				var tb = this.touches[1];
+				var tc = touches[0];
+				var td = touches[1];
+				if (ta.identifier != tc.identifier) {
+					var temp = tc;
+					tc = td;
+					td = temp;
+				}
+				this.scaleImage(ta, tb, tc, td);
+			}
+		},
+		touchEnd(ev) {
+			this.type = "";
+			this.touches = [];
+			this.startTime();
+		},
+		touchCancel(ev) {
+			this.type = "";
+			this.touches = [];
+			this.startTime();
+		},
+		startTime() {
+			this.stopTime();
+			this.timeoutId = setTimeout(() => {
+				this.trimImage();
+			}, 800);
+		},
+		stopTime() {
+			if (this.timeoutId >= 0) {
+				clearTimeout(this.timeoutId);
+				this.timeoutId = -1;
+			}
+		},
+		trimImage() {
+			this.mask.show = true;
+			var query = uni.createSelectorQuery().in(this);
+			query.select(".body").boundingClientRect((data) => {
+				var bw = data.width;
+				var bh = data.height;
+				var fw = this.frame.width;
+				var fh = this.frame.height;
+				var tw = bw * 0.8;
+				var th = bh * 0.8;
+				var sx = tw / fw;
+				var sy = th / fh;
+				var scale = sx;
+				if (sx > sy) {
+					scale = sy;
+				}
+				tw = fw * scale;
+				th = fh * scale;
+				var tx = (bw - tw) / 2;
+				var ty = (bh - th) / 2;
+				var ax = tx - this.frame.left + (this.frame.left - this.image.left) * (1 - scale);
+				var ay = ty - this.frame.top + (this.frame.top - this.image.top) * (1 - scale);
+				this.frame.width = tw;
+				this.frame.height = th;
+				this.frame.left = tx;
+				this.frame.top = ty;
+				this.image.width *= scale;
+				this.image.height *= scale;
+				this.image.left += ax;
+				this.image.top += ay;
+			}).exec();
+			setTimeout(() => {
+				var scale = this.image.width / this.real.width;
+				var x = (this.frame.left - this.image.left) / scale;
+				var y = (this.frame.top - this.image.top) / scale;
+				var width = this.frame.width / scale;
+				var height = this.frame.height / scale;
+				this.context.drawImage(this.url, x, y, width, height, 0, 0, this.frame.width, this.frame.height);
+				this.context.draw(false);
+			}, 100);
+		},
+		moveImage(ta, tb) {
+			var ax = tb.clientX - ta.clientX;
+			var ay = tb.clientY - ta.clientY;
+			this.image.left = this.start.image.left + ax;
+			this.image.top = this.start.image.top + ay;
+			if (this.image.left > this.frame.left) {
+				this.image.left = this.frame.left;
+			}
+			if (this.image.top > this.frame.top) {
+				this.image.top = this.frame.top;
+			}
+			if (this.image.left + this.image.width < this.frame.left + this.frame.width) {
+				this.image.left = this.frame.left + this.frame.width - this.image.width; 
+			}
+			if (this.image.top + this.image.height < this.frame.top + this.frame.height) {
+				this.image.top = this.frame.top + this.frame.height - this.image.height; 
+			}
+		},
+		scaleImage(ta, tb, tc, td) {
+			var x1 = ta.clientX;
+			var y1 = ta.clientY;
+			var x2 = tb.clientX;
+			var y2 = tb.clientY;
+			var x3 = tc.clientX;
+			var y3 = tc.clientY;
+			var x4 = td.clientX;
+			var y4 = td.clientY;
+			var ol = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+			var el = Math.sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4));
+			var ocx = (x1 + x2) / 2;
+			var ocy = (y1 + y2) / 2;
+			var ecx = (x3 + x4) / 2;
+			var ecy = (y3 + y4) / 2;
+			var ax = ecx - ocx;
+			var ay = ecy - ocy;
+			var scale = el / ol;
+			if (this.start.image.width * scale < this.frame.width) {
+				scale = this.frame.width / this.start.image.width;
+			}
+			if (this.start.image.height * scale < this.frame.height) {
+				scale = this.frame.height / this.start.image.height;
+			}
+			if (this.start.image.width * scale < this.frame.width) {
+				scale = this.frame.width / this.start.image.width;
+			}
+			this.image.left = this.start.image.left + ax - (ocx - this.start.image.left) * (scale - 1);
+			this.image.top = this.start.image.top + ay - (ocy - this.start.image.top) * (scale - 1);
+			this.image.width = this.start.image.width * scale;
+			this.image.height = this.start.image.height * scale;
+			if (this.image.left > this.frame.left) {
+				this.image.left = this.frame.left;
+			}
+			if (this.image.top > this.frame.top) {
+				this.image.top = this.frame.top;
+			}
+			if (this.image.left + this.image.width < this.frame.left + this.frame.width) {
+				this.image.left = this.frame.left + this.frame.width - this.image.width; 
+			}
+			if (this.image.top + this.image.height < this.frame.top + this.frame.height) {
+				this.image.top = this.frame.top + this.frame.height - this.image.height; 
+			}
+			
+		},
+		scaleFrame(ta, tb, type) {
+			var ax = tb.clientX - ta.clientX;
+			var ay = tb.clientY - ta.clientY;
+			var x1 = this.start.frame.left;
+			var y1 = this.start.frame.top;
+			var x2 = this.start.frame.left + this.start.frame.width;
+			var y2 = this.start.frame.top + this.start.frame.height;
+			if (type == "left") {
+				x1 += ax;
+			} else if (type == "right") {
+				x2 += ax;
+			} else if (type == "top") {
+				y1 += ay;
+			} else if (type == "bottom") {
+				y2 += ay;
+			} else if (type == "left-top") {
+				x1 += ax;
+				y1 += ay;
+			} else if (type == "left-bottom") {
+				x1 += ax;
+				y2 += ay;
+			} else if (type == "right-top") {
+				x2 += ax;
+				y1 += ay;
+			} else if (type == "right-bottom") {
+				x2 += ax;
+				y2 += ay;
+			}
+			if (x1 < this.image.left) {
+				x1 = this.image.left;
+			}
+			if (y1 < this.image.top) {
+				y1 = this.image.top;
+			}
+			if (x2 > this.image.left + this.image.width) {
+				x2 = this.image.left + this.image.width;
+			}
+			if (y2 > this.image.top + this.image.height) {
+				y2 = this.image.top + this.image.height;
+			}
+			this.frame.left = x1;
+			this.frame.top = y1;
+			this.frame.width = x2 - x1;
+			this.frame.height = y2 - y1;
+		},
+		parseBlob(base64) {
+			var arr = base64.split(',');
+			var mime = arr[0].match(/:(.*?);/)[1];
+			var bstr = atob(arr[1]);
+			var n = bstr.length;
+			var u8arr = new Uint8Array(n);
+			for(var i = 0; i < n; i++) {
+				u8arr[i] = bstr.charCodeAt(i);
+			}
+			var url = URL || webkitURL;
+			return url.createObjectURL(new Blob([u8arr], {type: mime}));
+		},
+		onok() {
+			var scale = this.image.width / this.real.width;
+			var x = (this.frame.left - this.image.left) / scale;
+			var y = (this.frame.top - this.image.top) / scale;
+			var width = this.frame.width / scale;
+			var height = this.frame.height / scale;
+			var tw = width;
+			var th = height;
+			if (this.fixed) {
+				tw = this.width / 2;
+				th = this.height / 2;
+			} else {
+				if (tw > this.maxWidth / 2) {
+					var sc = this.maxWidth / 2 / tw;
+					tw = tw * sc;
+					th = th * sc;
+				}
+				if (th > this.maxHeight / 2) {
+					var sc = this.maxHeight / 2 / th;
+					th = th * sc;
+					tw = tw * sc;
+				}
+			}
+			this.target.width = tw;
+			this.target.height = th;
+			uni.showLoading({
+				title: "正在裁剪"
+			});
+			setTimeout(() => {
+				this.targetContext.drawImage(this.url, x, y, width, height, 0, 0, tw, th);
+				this.targetContext.draw(false, () => {
+					uni.canvasToTempFilePath({
+						canvasId: "target",
+						success: (res) => {
+							var path = res.tempFilePath;
+							// #ifdef H5
+							if (this.blob) {
+								path = this.parseBlob(path);
+							}
+							// #endif
+							this.$emit("ok", {
+								path: path
+							});
+						},
+						fail: (ev) => {
+							console.log(ev);
+						},
+						complete: () => {
+							uni.hideLoading();
+						}
+					}, this);
+				});
+			}, 100);
+		},
+		oncancle() {
+			this.$emit("cancel");
+		}
+	}
+}
+</script>
+
+<style scoped>
+.ksp-image-cutter {
+	position: absolute;
+	width: 100%;
+	height: 100%;
+	top: 0;
+	bottom: 0;
+	z-index: 1000;
+}
+.toolbar {
+	position: absolute;
+	width: 100%;
+	height: 100upx;
+	left: 0upx;
+	bottom: 0upx;
+	box-sizing: border-box;
+	border-bottom: 1px solid #C0C0C0;
+	background: #F8F8F8;
+}
+.btn-cancel {
+	position: absolute;
+	left: 100upx;
+	top: 12upx;
+	font-size: 30upx;
+	line-height: 30upx;
+	padding: 20upx;
+	color: #333333;
+}
+.btn-ok {
+	position: absolute;
+	right: 100upx;
+	top: 12upx;
+	font-size: 30upx;
+	line-height: 30upx;
+	padding: 20upx;
+	color: #333333;
+}
+.body {
+	position: absolute;
+	left: 0upx;
+	right: 0upx;
+	top: 0upx;
+	bottom: 100upx;
+	background: black;
+	overflow: hidden;
+}
+.mask {
+	position: absolute;
+	left: 0upx;
+	right: 0upx;
+	top: 0upx;
+	bottom: 0upx;
+	background: black;
+	opacity: 0.4;
+}
+.plank {
+	position: absolute;
+	left: 0upx;
+	right: 0upx;
+	top: 0upx;
+	bottom: 0upx;
+}
+.image {
+	position: absolute;
+}
+.frame {
+	position: absolute;
+}
+.canvas {
+	position: absolute;
+	display: block;
+	left: 0px;
+	top: 0px;
+}
+.rect {
+	position: absolute;
+	left: -2px;
+	top: -2px;
+	width: 100%;
+	height: 100%;
+	border: 2px solid white;
+}
+.line-one {
+	position: absolute;
+	width: 100%;
+	height: 1px;
+	background: white;
+	left: 0;
+	top: 33.3%;
+}
+.line-two {
+	position: absolute;
+	width: 100%;
+	height: 1px;
+	background: white;
+	left: 0;
+	top: 66.7%;
+}
+.line-three {
+	position: absolute;
+	width: 1px;
+	height: 100%;
+	background: white;
+	top: 0;
+	left: 33.3%;
+}
+.line-four {
+	position: absolute;
+	width: 1px;
+	height: 100%;
+	background: white;
+	top: 0;
+	left: 66.7%;
+}
+.frame-left {
+	position: absolute;
+	height: 100%;
+	width: 8px;
+	left: -4px;
+	top: 0;
+}
+.frame-right {
+	position: absolute;
+	height: 100%;
+	width: 8px;
+	right: -4px;
+	top: 0;
+}
+.frame-top {
+	position: absolute;
+	width: 100%;
+	height: 8px;
+	top: -4px;
+	left: 0;
+}
+.frame-bottom {
+	position: absolute;
+	width: 100%;
+	height: 8px;
+	bottom: -4px;
+	left: 0;
+}
+.frame-left-top {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	left: -6px;
+	top: -6px;
+	border-left: 4px solid red;
+	border-top: 4px solid red;
+}
+.frame-left-bottom {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	left: -6px;
+	bottom: -6px;
+	border-left: 4px solid red;
+	border-bottom: 4px solid red;
+}
+.frame-right-top {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	right: -6px;
+	top: -6px;
+	border-right: 4px solid red;
+	border-top: 4px solid red;
+}
+.frame-right-bottom {
+	position: absolute;
+	width: 20px;
+	height: 20px;
+	right: -6px;
+	bottom: -6px;
+	border-right: 4px solid red;
+	border-bottom: 4px solid red;
+}
+</style>

+ 454 - 0
components/linzq-citySelect/linzq-citySelect.vue

@@ -0,0 +1,454 @@
+<template>
+	<div class="wrapper" :style="'top:'+statusBarHeight+'px'">
+		<div class="header">
+			<view class="back_div">
+				<image class="back_img" @click="back_city()" :src="'http://static.yfpyx.com/bigdata_app'+'/back_img.png'" mode=""></image>
+			</view>
+			<input class="input" @input="onInput" placeholder="中文/拼音/首字母" v-model="searchValue" />
+		</div>
+		<scroll-view class="calendar-list" scroll-y="true" :scroll-into-view="scrollIntoId">
+			<view v-if="disdingwei" id="hot">
+				<!-- 定位模块 -->
+				<view class="dingwei">
+					<view class="dingwei_Tips">
+						当前定位
+					</view>
+					<view class="dingwei_city">
+						<view class="dingwei_city_one">
+							{{position}}
+						</view>
+						<view class="dingweis_div" @click="getWarpweft">
+							<image class="dingweis" :src="'http://static.yfpyx.com/bigdata_app'+'/dingweis.png'" mode=""></image>
+							<text>{{po_tips}}</text>
+						</view>
+					</view>
+				</view>
+
+				<!-- 最近模块 -->
+				<view class="dingwei" v-if="Visit.length>=0">
+					<view class="dingwei_Tips">
+						最近访问
+					</view>
+					<view class="dingwei_city dingwei_city_zuijin">
+						<view class="dingwei_city_one toright" v-for="(item,index) in Visit" v-if="index<2" @click="back_city(item)">
+							{{item.cityName}}
+						</view> 
+					</view>
+				</view>
+
+			</view>
+
+
+			<!-- 城市列表 -->
+			<view v-if="searchValue == ''" v-for="(item, index) in list" :id="getId(index)" :key="index">
+				<view class="letter-header">{{ getId(index) }}</view>
+				<view class="city-div" v-for="(city, i) in item" :key="i" @click="back_city(city)">
+					<text class="city">{{ city.cityName }}</text>
+				</view>
+			</view>
+			<!-- 搜索结果 -->
+			<view class="city-div" v-for="(item, index) in searchList" @click="back_city(item)">
+				<text class="city">{{ item.cityName }}</text>
+			</view>
+		</scroll-view>
+
+		<!-- 右侧字母 -->
+		<view class="letters" v-if="searchValue == ''">
+			<view class="letters-item" @click="scrollTo('hot')">最近</view>
+			<view class="letters-item" v-for="item in letter" :key="item" @click="scrollTo(item)">{{ item }}</view>
+		</view>
+
+		<!-- 选中之后字母 -->
+		<view class="mask" v-if="showMask">
+			<view class="mask-r">{{selectLetter}}</view>
+		</view>
+	</div>
+</template>
+
+<script>
+	import Citys from '../city.js';
+	export default {
+		components: {},
+		props: {},
+
+		computed: {
+			hotCity() {
+				return Citys.hotCity;
+			},
+
+			citys() {
+				return Citys.cities;
+			}
+		},
+
+		data() {
+			return {
+				statusBarHeight: this.statusBarHeight,
+				ImgUrl: this.ImgUrl,
+				letter: [],
+				selectLetter: '',
+				searchValue: '',
+				scrollIntoId: '',
+				list: [],
+				tId: null,
+				searchList: [],
+				showMask: false,
+				disdingwei: true,
+				Visit: [], //最近访问
+				position: '青岛',
+				longitude: '', //经度
+				latitude: '', //纬度
+				seconds: 3,
+				po_tips: '重新定位',
+			}
+		},
+
+		created() {
+			//获取存储的最近访问
+			var that = this
+			uni.getStorage({
+				key: 'Visit_key',
+				success: function(res) {
+					that.Visit = res.data
+				}
+			});
+			//获取定位 经度纬度
+			that.getWarpweft()
+			//获取city.js 的程序字母
+			var mu = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y',
+				'z'
+			];
+			var tmp = [];
+			for (var i = 0; i < mu.length; i++) {
+				var item = mu[i];
+				for (var j = 0; j < this.citys.length; j++) {
+					var py = this.citys[j].py;
+					if (py.substring(0, 1) == item) {
+						if (tmp.indexOf(item) == -1) {
+							this.list[i] = [this.citys[j]];
+							tmp.push(item);
+							this.letter.push(item.toUpperCase());
+						} else {
+							this.list[i].push(this.citys[j]);
+						}
+					}
+				}
+			}
+		},
+		methods: {
+			getId(index) {
+				return this.letter[index];
+			},
+
+			scrollTo(letter) {
+				this.showMask = true
+				this.selectLetter = letter == 'hot' ? '最' : letter
+				setTimeout(() => {
+					this.showMask = false
+				}, 300);
+				this.scrollIntoId = letter;
+			},
+
+
+			query(source, text) {
+				let res = [];
+				var self = this;
+				res = source.filter(item => {
+					const arr = [];
+					let isHave = false;
+					Object.keys(item).forEach(prop => {
+						const itemStr = item[prop];
+						self.isString(itemStr) &&
+							itemStr.split(',').forEach(val => {
+								arr.push(val);
+							});
+					});
+					arr.some(val => {
+						isHave = new RegExp('^' + text).test(val);
+						return isHave;
+					});
+					return isHave;
+				});
+				console.log(JSON.stringify(res));
+				return res;
+			},
+
+			isString(obj) {
+				return typeof obj === 'string';
+			},
+
+			onInput(e) {
+				const value = e.target.value;
+				console.log(value);
+				if (value !== '' && this.citys && this.citys.length > 0) {
+					const queryData = this.query(this.citys, String(value).trim());
+					this.searchList = queryData;
+					this.disdingwei = false
+				} else {
+					this.searchList = [];
+					this.disdingwei = true
+				}
+			},
+
+			back_city(item) {
+				if (item) {
+					this.$emit('back_city', item);
+					//unshift 把数据插入到首位,与push相反
+					this.Visit.unshift(item)
+					this.searchValue = "";
+					this.disdingwei = true
+					var arr = this.Visit
+					//数组去重
+					function distinct(arr) {
+						let newArr = []
+						for (let i = 0; i < arr.length; i++) {
+							if (newArr.indexOf(arr[i]) < 0) {
+								newArr.push(arr[i])
+							}
+						}
+						return newArr
+					}
+					this.Visit = distinct(arr)
+					console.log(this.Visit, "---最近访问")
+					uni.setStorage({
+						key: 'Visit_key',
+						data: this.Visit
+					});
+				} else {
+					this.$emit('back_city', 'no');
+				}
+
+			},
+			getWarpweft() {
+				var that = this
+				that.po_tips = '定位中...'
+				let countdown = setInterval(() => {
+					that.seconds--;
+					uni.getLocation({
+						type: 'wgs84',
+						success: function(res) {
+							console.log('当前位置的经度:' + res.longitude);
+							console.log('当前位置的纬度:' + res.latitude);
+							that.longitude = res.longitude
+							that.latitude = res.latitude
+						}
+					});
+					if (that.seconds <= 0) {
+						that.seconds = 3
+						that.po_tips = '重新定位'
+						clearInterval(countdown);
+					}
+				}, 1000);
+			}
+		}
+	};
+</script>
+
+<style scoped>
+	.wrapper {
+		position: fixed;
+		z-index: 999999;
+		background: #ffffff;
+		height: 100%;
+		width: 100%;
+		top: 0px;
+		left: 0px;
+	}
+
+	.mask {
+		position: absolute;
+		bottom: 0upx;
+		top: 83upx;
+		left: 0upx;
+		right: 0upx;
+		width: 750upx;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		background: rgba(0, 0, 0, 0);
+	}
+
+	.mask-r {
+		height: 120upx;
+		width: 120upx;
+		border-radius: 60upx;
+		display: flex;
+		background: rgba(0, 0, 0, 0.5);
+		justify-content: center;
+		align-items: center;
+		font-size: 40upx;
+		color: #FFFFFF
+	}
+
+	.content {
+		height: 100%;
+		width: 100%;
+		background-color: #ffffff;
+	}
+
+	.header {
+		height: 85upx;
+		display: flex;
+		justify-content: flex-start;
+		align-items: center;
+	}
+
+
+	.back_div {
+		width: 65upx;
+		height: 100%;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.back_img {
+		width: 35upx;
+		height: 35upx;
+	}
+
+	.input {
+		font-size: 28upx;
+		width: 620upx;
+		height: 55upx;
+		border-radius: 40upx;
+		background-color: #F5F5F5;
+		padding-left: 20upx;
+		padding-right: 20upx;
+		box-sizing: border-box;
+	}
+
+	.title {
+		font-size: 30upx;
+		color: white;
+	}
+
+	.show {
+		left: 0;
+		width: 100%;
+		transition: left 0.3s ease;
+	}
+
+	.hide {
+		left: 100%;
+		width: 100%;
+		transition: left 0.3s ease;
+	}
+
+
+	.title {
+		font-size: 30upx;
+		color: white;
+	}
+
+	.calendar-list {
+		position: absolute;
+		top: 83upx;
+		bottom: 0upx;
+		width: 100%;
+		background-color: #FFFFFF;
+	}
+
+	.letters {
+		position: absolute;
+		right: 30upx;
+		bottom: 0px;
+		width: 50upx;
+		top: 260upx;
+		color: #2f9bfe;
+		text-align: center;
+		font-size: 24upx;
+	}
+
+	.letters-item {
+		margin-bottom: 5upx;
+	}
+
+	.letter-header {
+		height: 45upx;
+		font-size: 22upx;
+		color: #333333;
+		padding-left: 24upx;
+		box-sizing: border-box;
+		display: flex;
+		align-items: center;
+		background-color: #ebedef;
+
+	}
+
+	.city-div {
+		width: 660upx;
+		height: 85upx;
+		margin-left: 24upx;
+		border-bottom-width: 0.5upx;
+		border-bottom-color: #ebedef;
+		border-bottom-style: solid;
+		display: flex;
+		align-items: center;
+		margin-right: 35upx;
+	}
+
+	.city {
+		font-size: 28upx;
+		color: #000000;
+		padding-left: 30upx;
+	}
+
+	.dingwei {
+		width: 100%;
+		padding-top: 25upx;
+		box-sizing: border-box;
+		margin-bottom: 26upx;
+	}
+
+	.dingwei_Tips {
+		margin-left: 24upx;
+		margin-bottom: 24upx;
+		font-size: 24upx;
+		color: #A5A5A5;
+	}
+
+	.dingwei_city {
+		width: 100%;
+		height: 60upx;
+		padding-left: 55upx;
+		padding-right: 70upx;
+		box-sizing: border-box;
+		display: flex;
+		justify-content: space-between;
+	}
+
+	.dingwei_city_one {
+		width: 185upx;
+		height: 60upx;
+		background-color: #F5F5F5;
+		border-radius: 10upx;
+		font-size: 32upx;
+		color: #333333;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.dingweis_div {
+		display: flex;
+		align-content: flex-end;
+		align-items: center;
+		font-size: 24upx;
+		color: #FD5745;
+	}
+
+	.dingweis {
+		width: 32upx;
+		height: 32upx;
+	}
+
+	.dingwei_city_zuijin {
+		display: flex;
+		justify-content: flex-start;
+	}
+
+	.toright {
+		margin-right: 25upx;
+	}
+</style>

+ 140 - 0
components/popup-layer/popup-layer.vue

@@ -0,0 +1,140 @@
+<template>
+	<view>
+		<view v-show="ifshow" @tap="ableClose" @touchmove.stop.prevent class="popup-layer" >
+			
+		</view>
+		<view ref="popRef"  class="popup-content"   @tap.stop="stopEvent" :style="_location">
+			<slot></slot>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'popup-layer',
+		model: {
+			prop: "showPop",
+			event: "change"
+		},
+		props: {
+			showPop:{
+				type:Boolean,
+				default:false,
+			},
+			direction: {
+				type: String,
+				default: 'top', // 方向  top,bottom,left,right 
+			},
+			autoClose: {
+				type: Boolean,
+				default: true,
+			}
+		},
+		data() {
+			return {
+				ifshow: false, // 是否展示,
+				translateValue: -100, // 位移距离
+				site:-100,
+				timer: null,
+				iftoggle: false,
+
+			};
+		},
+		computed: {
+			_translate() {
+				const transformObj = {
+					'top': `transform:translateY(${-this.translateValue}%)`,
+					'bottom': `transform:translateY(${this.translateValue}%)`,
+					'left': `transform:translateX(${-this.translateValue}%)`,
+					'right': `transform:translateX(${this.translateValue}%)`
+				};
+				return transformObj[this.direction]
+			},
+			_location() {
+				const positionValue = {
+					'top': `bottom:${this.site}%;width:100%;`,
+					'bottom': `top:${this.site}%;width:100%;`,
+					'left': `right:0px;top:0;height:100%;`,
+					'right': `left:0px;top:0;height:100%;`,
+				};
+				return positionValue[this.direction]+ this._translate;
+			}
+		},
+		mounted(){
+			if(this.showPop){
+				// console.log(222);
+				this.show();
+			}
+		},
+		watch:{
+			showPop(value){
+				console.log(value)
+				if(value){
+					this.show();
+				}else{
+					this.close();
+				}
+			}	
+		},
+		methods: {
+			stopMove(event){
+				return;
+			},
+			show(events) {
+				this.ifshow = true;
+				this.site=0;
+				let _open = setTimeout(() => {
+					this.translateValue = 0;
+					_open = null;
+				}, 100)
+				let _toggle = setTimeout(() => {
+					this.iftoggle = true;
+					_toggle = null;
+				}, 300);
+			},
+			close() {
+				if (this.timer !== null || !this.iftoggle) {
+					return;
+				}
+				this.translateValue = -100;
+				this.timer = setTimeout(() => {
+					this.ifshow = false;
+					this.timer = null;
+					this.iftoggle = false;
+					this.$emit('closeCallBack', null);
+					this.$emit('change',false)
+				}, 300);
+			},
+			ableClose() {
+				if (this.autoClose) {
+					this.close();
+				}
+			},
+			stopEvent(event) {},
+			doSome(){
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	.popup-layer {
+		position: fixed;
+		z-index: 999999;
+		// background: rgba(0, 0, 0, .3);
+		height: 100%;
+		width: 100%;
+		top: 0px;
+		left: 0px;
+		overflow: hidden;
+	}
+
+	.popup-content {
+		position: fixed;
+		z-index: 1000000;
+		background: #FFFFFF;
+		transition: transform .2s ease;
+		overflow: hidden; 
+	}
+</style>

+ 96 - 0
components/uni-icons/icons.js

@@ -0,0 +1,96 @@
+export default {
+	'contact': '\ue100',
+	'person': '\ue101',
+	'personadd': '\ue102',
+	'contact-filled': '\ue130',
+	'person-filled': '\ue131',
+	'personadd-filled': '\ue132',
+	'phone': '\ue200',
+	'email': '\ue201',
+	'chatbubble': '\ue202',
+	'chatboxes': '\ue203',
+	'phone-filled': '\ue230',
+	'email-filled': '\ue231',
+	'chatbubble-filled': '\ue232',
+	'chatboxes-filled': '\ue233',
+	'weibo': '\ue260',
+	'weixin': '\ue261',
+	'pengyouquan': '\ue262',
+	'chat': '\ue263',
+	'qq': '\ue264',
+	'videocam': '\ue300',
+	'camera': '\ue301',
+	'mic': '\ue302',
+	'location': '\ue303',
+	'mic-filled': '\ue332',
+	'speech': '\ue332',
+	'location-filled': '\ue333',
+	'micoff': '\ue360',
+	'image': '\ue363',
+	'map': '\ue364',
+	'compose': '\ue400',
+	'trash': '\ue401',
+	'upload': '\ue402',
+	'download': '\ue403',
+	'close': '\ue404',
+	'redo': '\ue405',
+	'undo': '\ue406',
+	'refresh': '\ue407',
+	'star': '\ue408',
+	'plus': '\ue409',
+	'minus': '\ue410',
+	'circle': '\ue411',
+	'checkbox': '\ue411',
+	'close-filled': '\ue434',
+	'clear': '\ue434',
+	'refresh-filled': '\ue437',
+	'star-filled': '\ue438',
+	'plus-filled': '\ue439',
+	'minus-filled': '\ue440',
+	'circle-filled': '\ue441',
+	'checkbox-filled': '\ue442',
+	'closeempty': '\ue460',
+	'refreshempty': '\ue461',
+	'reload': '\ue462',
+	'starhalf': '\ue463',
+	'spinner': '\ue464',
+	'spinner-cycle': '\ue465',
+	'search': '\ue466',
+	'plusempty': '\ue468',
+	'forward': '\ue470',
+	'back': '\ue471',
+	'left-nav': '\ue471',
+	'checkmarkempty': '\ue472',
+	'home': '\ue500',
+	'navigate': '\ue501',
+	'gear': '\ue502',
+	'paperplane': '\ue503',
+	'info': '\ue504',
+	'help': '\ue505',
+	'locked': '\ue506',
+	'more': '\ue507',
+	'flag': '\ue508',
+	'home-filled': '\ue530',
+	'gear-filled': '\ue532',
+	'info-filled': '\ue534',
+	'help-filled': '\ue535',
+	'more-filled': '\ue537',
+	'settings': '\ue560',
+	'list': '\ue562',
+	'bars': '\ue563',
+	'loop': '\ue565',
+	'paperclip': '\ue567',
+	'eye': '\ue568',
+	'arrowup': '\ue580',
+	'arrowdown': '\ue581',
+	'arrowleft': '\ue582',
+	'arrowright': '\ue583',
+	'arrowthinup': '\ue584',
+	'arrowthindown': '\ue585',
+	'arrowthinleft': '\ue586',
+	'arrowthinright': '\ue587',
+	'pulldown': '\ue588',
+	'closefill': '\ue589',
+	'sound': '\ue590',
+	'scan': '\ue612'
+}

Разница между файлами не показана из-за своего большого размера
+ 57 - 0
components/uni-icons/uni-icons.vue


+ 224 - 0
components/uni-nav-bar/uni-nav-bar.vue

@@ -0,0 +1,224 @@
+<template>
+	<view class="uni-navbar">
+		<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
+		 class="uni-navbar__content">
+			<uni-status-bar v-if="statusBar" />
+			<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
+				<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
+					<view class="uni-navbar__content_view" v-if="leftIcon.length">
+						<uni-icons :color="color" :type="leftIcon" size="24" />
+					</view>
+					<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view"
+					 v-if="leftText.length">
+						<text :style="{ color: color, fontSize: '14px' }">{{ leftText }}</text>
+					</view>
+					<slot name="left" />
+				</view>
+				<view class="uni-navbar__header-container uni-navbar__content_view">
+					<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
+						<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
+					</view>
+					<!-- 标题插槽 -->
+					<slot />
+				</view>
+				<view :class="title.length ? 'uni-navbar__header-btns-right' : ''" @tap="onClickRight" class="uni-navbar__header-btns uni-navbar__content_view">
+					<view class="uni-navbar__content_view" v-if="rightIcon.length">
+						<uni-icons :color="color" :type="rightIcon" size="24" />
+					</view>
+					<!-- 优先显示图标 -->
+					<view class="uni-navbar-btn-text uni-navbar__content_view" v-if="rightText.length && !rightIcon.length">
+						<text class="uni-nav-bar-right-text">{{ rightText }}</text>
+					</view>
+					<slot name="right" />
+				</view>
+			</view>
+		</view>
+		<view class="uni-navbar__placeholder" v-if="fixed">
+			<uni-status-bar v-if="statusBar" />
+			<view class="uni-navbar__placeholder-view" />
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniStatusBar from "../uni-status-bar/uni-status-bar.vue";
+	import uniIcons from "../uni-icons/uni-icons.vue";
+
+	export default {
+		name: "UniNavBar",
+		components: {
+			uniStatusBar,
+			uniIcons
+		},
+		props: {
+			title: {
+				type: String,
+				default: ""
+			},
+			leftText: {
+				type: String,
+				default: ""
+			},
+			rightText: {
+				type: String,
+				default: ""
+			},
+			leftIcon: {
+				type: String,
+				default: ""
+			},
+			rightIcon: {
+				type: String,
+				default: ""
+			},
+			fixed: {
+				type: [Boolean, String],
+				default: false
+			},
+			color: {
+				type: String,
+				default: "#000000"
+			},
+			backgroundColor: {
+				type: String,
+				default: "#FFFFFF"
+			},
+			statusBar: {
+				type: [Boolean, String],
+				default: false
+			},
+			shadow: {
+				type: [String, Boolean],
+				default: false
+			},
+			border: {
+				type: [String, Boolean],
+				default: true
+			}
+		},
+        mounted() {
+          if(uni.report && this.title !== '') {
+              uni.report('title', this.title)
+          }
+        },
+		methods: {
+			onClickLeft() {
+				this.$emit("clickLeft");
+			},
+			onClickRight() {
+				this.$emit("clickRight");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$nav-height: 44px;
+	.uni-nav-bar-text {
+		/* #ifdef APP-PLUS */
+		font-size: 16px;
+		/* #endif */
+		/* #ifndef APP-PLUS */
+		font-size: $uni-font-size-lg;
+		/* #endif */
+	}
+	.uni-nav-bar-right-text {
+		font-size: $uni-font-size-base;
+	}
+
+	.uni-navbar {
+		width: 100%;
+	}
+
+	.uni-navbar__content {
+		position: relative;
+		width: 750rpx;
+		background-color: $uni-bg-color;
+		overflow: hidden;
+	}
+
+	.uni-navbar__content_view {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		flex-direction: row;
+		// background-color: #FFFFFF;
+	}
+
+	.uni-navbar__header {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		width: 750rpx;
+		height: $nav-height;
+		line-height: $nav-height;
+		font-size: 16px;
+		// background-color: #ffffff;
+	}
+
+	.uni-navbar__header-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-wrap: nowrap;
+		width: 120rpx;
+		padding: 0 6px;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.uni-navbar__header-btns-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 150rpx;
+		justify-content: flex-start;
+	}
+
+	.uni-navbar__header-btns-right {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 150rpx;
+		padding-right: 30rpx;
+		justify-content: flex-end;
+	}
+
+	.uni-navbar__header-container {
+		flex: 1;
+	}
+
+	.uni-navbar__header-container-inner {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		font-size: $uni-font-size-base;
+	}
+
+
+	.uni-navbar__placeholder-view {
+		height: $nav-height;
+	}
+
+	.uni-navbar--fixed {
+		position: fixed;
+		z-index: 998;
+	}
+
+	.uni-navbar--shadow {
+		/* #ifndef APP-NVUE */
+		box-shadow: 0 1px 6px #ccc;
+		/* #endif */
+	}
+
+	// .uni-navbar--border {
+	// 	border-bottom-width: 1rpx;
+	// 	border-bottom-style: solid;
+	// 	border-bottom-color: $uni-border-color;
+	// }
+</style>

+ 25 - 0
components/uni-status-bar/uni-status-bar.vue

@@ -0,0 +1,25 @@
+<template>
+	<view :style="{ height: statusBarHeight }" class="uni-status-bar">
+		<slot />
+	</view>
+</template>
+
+<script>
+	var statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
+	export default {
+		name: 'UniStatusBar',
+		data() {
+			return {
+				statusBarHeight: statusBarHeight
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-status-bar {
+		width: 750rpx;
+		height: 20px;
+		// height: var(--status-bar-height);
+	}
+</style>

+ 56 - 0
main.js

@@ -0,0 +1,56 @@
+import Vue from 'vue'
+import App from './App'
+import uView from "uview-ui"
+Vue.use(uView)
+import {myRequest} from './util/api.js'
+Vue.prototype.$myRequest=myRequest
+
+
+Vue.config.productionTip = false
+
+App.mpType = 'app'
+
+Vue.prototype.$imghost = 'http://static.yfpyx.com/projectimg' // 线上图片服务器路径常量
+// http://static.yfpyx.com/bigdata_app/image/10ca93e17420371a82826073c8425c0.png
+Vue.prototype.$appimghost = 'http://static.yfpyx.com/bigdata_app'
+
+Vue.filter('timeFormat',function(time){
+	function fun(a){
+		return	String(a).length==1?'0'+a: a
+	}
+	let date= new Date(time*1000)
+	let y=date.getFullYear()
+	let m=date.getMonth()+1
+	let d=date.getDate()
+	let h=date.getHours()
+	let min=date.getMinutes()
+	let sec=date.getSeconds()
+	return `${y}-${fun(m)}-${fun(d)} ${fun(h)}:${fun(min)}:${fun(sec)}`
+})
+
+ Vue.prototype.formatTime = function (thistime,fmt = 'yyyy-MM-dd hh:mm:ss') {
+        let $this = new Date(thistime)
+        let o = {
+          'M+': $this.getMonth() + 1,
+          'd+': $this.getDate(),
+          'h+': $this.getHours(),
+          'm+': $this.getMinutes(),
+          's+': $this.getSeconds(),
+          'q+': Math.floor(($this.getMonth() + 3) / 3),
+          'S': $this.getMilliseconds()
+        }
+        if (/(y+)/.test(fmt)) {
+          fmt = fmt.replace(RegExp.$1, ($this.getFullYear() + '').substr(4 - RegExp.$1.length))
+        }
+        for (var k in o) {
+          if (new RegExp('(' + k + ')').test(fmt)) {
+            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
+          }
+        }
+        return fmt
+      }
+
+const app = new Vue({
+    ...App
+})
+app.$mount()

+ 165 - 0
manifest.json

@@ -0,0 +1,165 @@
+{
+    "name" : "大数据平台APP",
+    "appid" : "__UNI__DBA6730",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "softinput" : {
+            "mode" : "adjustPan",
+            "softinputMode" : "adjustResize"
+        },
+        "usingComponents" : true,
+        "nvueCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        "compatible" : {
+            "ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持  
+        },
+        /* 模块配置 */
+        "modules" : {
+            "Geolocation" : {},
+            "Webview-x5" : {},
+            "Maps" : {},
+            "VideoPlayer" : {}
+        },
+        /* 应用发布信息 */
+        "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_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+                    "<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.DISABLE_KEYGUARD\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+                    "<uses-permission android:name=\"android.permission.UPDATE_DEVICE_STATS\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+                ],
+                "abiFilters" : [ "armeabi-v7a", "x86" ]
+            },
+            /* ios打包配置 */
+            "ios" : {},
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "geolocation" : {
+                    "amap" : {
+                        "__platform__" : [ "android" ],
+                        "appkey_ios" : "0ff73cb4d88262325eea8c8dad1a6609",
+                        "appkey_android" : "0ff73cb4d88262325eea8c8dad1a6609"
+                    }
+                },
+                "maps" : {
+                    "amap" : {
+                        "appkey_ios" : "0ff73cb4d88262325eea8c8dad1a6609",
+                        "appkey_android" : "0ff73cb4d88262325eea8c8dad1a6609"
+                    }
+                },
+                "ad" : {}
+            },
+            "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"
+                    }
+                }
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "wx1cabf67f460e3a14",
+        "setting" : {
+            "urlCheck" : false,
+            "minified" : true,
+            "postcss" : false,
+            "es6" : true
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "h5" : {
+        "devServer" : {
+            "port" : 8000,
+            "disableHostCheck" : true,
+            "proxy" : {
+                "/ksy" : {
+                    "target" : "http://182.92.193.64:8002",
+                    "changeOrigin" : true,
+                    "ws" : true,
+                    "pathRewrite" : {
+                        "^/ksy" : "ksy"
+                    }
+                }
+            }
+        }
+    }
+}
+// "sdkConfigs" : {
+//     "maps" : {
+//         "qqmap" : {
+//             "key" : "B2EBZ-2UW6P-RDJDG-LCMLE-AIQUS-CGFMJ"
+//         }
+//     }
+// }
+

+ 33 - 0
package-lock.json

@@ -0,0 +1,33 @@
+{
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "echarts": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.2.tgz",
+      "integrity": "sha512-En0VYpc96nw2/2AZoBWPHsGi471zMublttj50kfFpYAeR4geup0Tj9iVgEXh7QYZFPnRiruDJEjcB5PXZ+BYzQ==",
+      "requires": {
+        "tslib": "2.0.3",
+        "zrender": "5.0.4"
+      }
+    },
+    "highcharts": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/highcharts/-/highcharts-9.0.1.tgz",
+      "integrity": "sha512-0UmcCz2RmFuqfT/Igu3h5sGnkeSqqZwfuYrTzJ/htptmJAo5SSxH62NFcTjVRk+3WstoBJmoXR0v5FVGQUzK5A=="
+    },
+    "tslib": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
+      "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
+    },
+    "zrender": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.4.tgz",
+      "integrity": "sha512-DJpy0yrHYY5CuH6vhb9IINWbjvBUe/56J8aH86Jb7O8rRPAYZ3M2E469Qf5B3EOIfM3o3aUrO5edRQfLJ+l1Qw==",
+      "requires": {
+        "tslib": "2.0.3"
+      }
+    }
+  }
+}

+ 18 - 0
package.json

@@ -0,0 +1,18 @@
+{
+  "dependencies": {
+	    "name": "gulp",
+	    "version": "1.0.0",
+	    "description": "",
+	    "main": "index.js",
+	    "dependencies": {
+	      "gulp": "^4.0.2",
+	      "gulp-uglify": "^3.0.2"
+	    },
+	    "devDependencies": {},
+	    "scripts": {
+	      "test": "echo \"Error: no test specified\" && exit 1"
+	    },
+	    "author": "",
+	    "license": "ISC"
+  }
+}

+ 538 - 0
pages.json

@@ -0,0 +1,538 @@
+{
+	"easycom": {
+		"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
+	},
+	"pages": [ 
+		{
+			"path": "pages/login/login",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/index/index",
+			"style": {
+				"navigationBarTitleText": "首页"
+			}
+		}, {
+			"path": "pages/cb/index/index",
+			"style": {
+				"navigationBarTitleText": "测报系统",
+				"enablePullDownRefresh": true,
+				"navigationStyle": "custom"
+			}
+		}, {
+			"path": "pages/my/user-info/user-info",
+			"style": {
+				"navigationBarTitleText": "个人信息",
+				"enablePullDownRefresh": false
+			}
+		},  {
+			"path": "pages/my/about/about",
+			"style": {
+				"navigationBarTitleText": "关于",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/cb/equip-detail/equip-detail",
+			"style": {
+				"navigationBarTitleText": "设备详情",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/cb/cbd/equip-set/equip-set",
+			"style": {
+				"navigationBarTitleText": "设备控制",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/equipMange/index/index",
+			"style": {
+				"navigationBarTitleText": "设备分配主页",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		},
+		{
+			"path": "pages/equipMange/index/addusers",
+			"style": {
+				"navigationBarTitleText": "增加用户",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		},  {
+			"path": "pages/equipMange/index/changepasswold",
+			"style": {
+				"navigationBarTitleText": "更改密码",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/equipMange/index/assignment",
+			"style": {
+				"navigationBarTitleText": "分配设备",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, 
+		{
+			"path": "pages/equipMange/index/useroperation",
+			"style": {
+				"navigationBarTitleText": "用户详情",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/cb/bzy/equip-set/equip-set",
+			"style": {
+				"navigationBarTitleText": "设备控制",
+				"enablePullDownRefresh": false
+			}
+
+		},  {
+			"path": "pages/cb/sim/sim",
+			"style": {
+				"navigationBarTitleText": "sim卡详情",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/expertDiagnosis/index",
+			"style": {
+				"navigationBarTitleText": "专家诊断",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/expertDiagnosis/wormcase",
+			"style": {
+				"navigationBarTitleText": "虫情百科",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/expertDiagnosis/exchangeShare",
+			"style": {
+				"navigationBarTitleText": "交流圈",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/expertDiagnosis/particulars",
+			"style": {
+				"navigationBarTitleText": "交流圈详情",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/expertDiagnosis/postmessage",
+			"style": {
+				"navigationBarTitleText": "发帖",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/afterSale/index",
+			"style": {
+				"navigationBarTitleText": "售后服务",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/afterSale/search",
+			"style": {
+				"navigationBarTitleText": "售后服务搜索",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/expertDiagnosis/introduce",
+			"style": {
+				"navigationBarTitleText": "病虫害介绍",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/afterSale/addafter",
+			"style": {
+				"navigationBarTitleText": "设备报修",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/my/index/index",
+			"style": {
+				"navigationBarTitleText": "个人中心",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/equipList/index",
+			"style": {
+				"navigationBarTitleText": "设备列表",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/equipList/search",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/equipList/modification",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/distribution/index",
+			"style": {
+				"navigationBarTitleText": "设备分布",
+				"enablePullDownRefresh": false
+			}
+
+		}, {
+			"path": "pages/fourBase/index",
+			"style": {
+				"navigationBarTitleText": "四情基地首页",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/fourBase/addbase",
+			"style": {
+				"navigationBarTitleText": "新增基地",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/fourBase/allocation",
+			"style": {
+				"navigationBarTitleText": "设备分配",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/prevention/index",
+			"style": {
+				"navigationBarTitleText": "防治系统",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/prevention/search",
+			"style": {
+				"navigationBarTitleText": "防治系统搜索",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/prevention/equipmentdetails",
+			"style": {
+				"navigationBarTitleText": "防治系统设备详细",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/prevention/sim",
+			"style": {
+				"navigationBarTitleText": "sim卡详情",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/prevention/control",
+			"style": {
+				"navigationBarTitleText": "设备控制",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/prevention/ucharts",
+			"style": {
+				"navigationBarTitleText": "历史数据",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/environment/index",
+			"style": {
+				"navigationBarTitleText": "环境监测",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/environment/search",
+			"style": {
+				"navigationBarTitleText": "环境监测搜索",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/environment/equipment",
+			"style": {
+				"navigationBarTitleText": "环境监测设备详情",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/environment/contros",
+			"style": {
+				"navigationBarTitleText": "环境监测控制页面",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/environment/onedaythedata",
+			"style": {
+				"navigationBarTitleText": "环境检测24小时数据",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/environment/history",
+			"style": {
+				"navigationBarTitleText": "环境检测历史数据",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/cb/cbd/equip-set/imgpage",
+			"style": {
+				"navigationBarTitleText": "图片列表",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/cb/cbd/equip-set/addimg",
+			"style": {
+				"navigationBarTitleText": "手动添加",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/cb/cbd/equip-set/historyfile",
+			"style": {
+				"navigationBarTitleText": "测报灯历史记录",
+				"enablePullDownRefresh": true,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/cb/cbd/equip-set/note",
+			"style": {
+				"navigationBarTitleText": "短信预警",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/cb/cbd/equip-set/statistics",
+			"style": {
+				"navigationBarTitleText": "害虫统计",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/cb/bzy/equip-set/bzyhistoryile",
+			"style": {
+				"navigationBarTitleText": "孢子仪历史记录",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+		},
+		{
+			"path": "pages/cb/xy/equip-set/equip-set",
+			"style": {
+				"navigationBarTitleText": "设备控制",
+				"enablePullDownRefresh": false
+			}
+		
+		},{
+			"path": "pages/cb/xy/equip-set/xyhistoryile",
+			"style": {
+				"navigationBarTitleText": "性诱设备历史记录",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/disandpests/index",
+			"style": {
+				"navigationBarTitleText": "病虫害识别",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}, {
+			"path": "pages/monitor/index",
+			"style": {
+				"navigationBarTitleText": "监控列表",
+				"enablePullDownRefresh": true,
+				"navigationStyle": "custom"
+			}
+		}, {
+			"path": "pages/webview",
+			"style": {
+				"navigationBarTitleText": "监控列表"
+			}
+		}, 
+		{
+			"path": "pages/fourBase/basefacility",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+		}, 
+		{
+			"path": "pages/fourBase/modification",
+			"style": {
+				"navigationBarTitleText": "四情基地编辑基地",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		},  
+		{
+			"path": "pages/fourBase/city",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"app-plus": {
+					"softinputMode": "adjustResize"
+				}
+			}
+
+		}, {
+			"path": "pages/cb/index/search",
+			"style": {
+				"navigationBarTitleText": "",
+				"enablePullDownRefresh": false,
+				"navigationStyle": "custom"
+			}
+
+		}
+	    ,{
+            "path" : "pages/my/record/record",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "版本更新记录详情",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/cb/xy2.0/particulars",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "设备详情",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+        ,{
+            "path" : "pages/cb/xy2.0/historydatas",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "历史数据",
+                "enablePullDownRefresh": false
+            }
+            
+        }
+    ],
+	"condition": { //模式配置,仅开发期间生效
+		"current": 3, //当前激活的模式(list 的索引项)
+		"list": [{
+			"name": "about",
+			"path": "pages/my/about/about"
+		}, {
+			"name": "feedback",
+			"path": "pages/my/feedback/feedback"
+		}, {
+			"name": "cdIndex",
+			"path": "pages/cb/index/index"
+		}, {
+			"name": "login",
+			"path": "pages/login/login"
+		}]
+	},
+	"globalStyle": {
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "大数据平台",
+		"navigationBarBackgroundColor": "#fff",
+		"backgroundColor": "#FFFFFF"
+	},
+	"tabBar": {
+		"color": "#cdcdcd",
+		"selectedColor": "#56C979",
+		"borderStyle": "white",
+		"list": [{
+				"pagePath": "pages/index/index",
+				"iconPath": "static/images/13.png",
+				"selectedIconPath": "static/images/12.png",
+				"text": "首页"
+			},
+			{
+				"pagePath": "pages/equipList/index",
+				"iconPath": "static/images/14.png",
+				"selectedIconPath": "static/images/15.png",
+				"text": "设备列表"
+			},
+			{
+				"pagePath": "pages/distribution/index",
+				"iconPath": "static/images/16.png",
+				"selectedIconPath": "static/images/17.png",
+				"text": "设备分布"
+			},
+			{
+				"pagePath": "pages/my/index/index",
+				"iconPath": "static/images/18.png",
+				"selectedIconPath": "static/images/19.png",
+				"text": "个人中心"
+			}
+		]
+	}
+}

+ 434 - 0
pages/afterSale/addafter.vue

@@ -0,0 +1,434 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备报修"></uni-nav-bar>
+			</view>
+			<view class="addafter_con">
+				<view class="addafter_con_top">
+					<p>基本信息</p>
+					<input type="number" v-model="adddata.id" placeholder="请填写设备ID" placeholder-style="color: #62BF89;font-size:24rpx"
+					 @blur="addID" />
+					<input type="select" v-model="adddata.type" placeholder="请选择设备类型" placeholder-style="color: #62BF89;font-size:24rpx"
+					 @click="show = true" disabled />
+					<input type="text" v-model="adddata.name" placeholder="请填写联系人名称" placeholder-style="color: #62BF89;font-size:24rpx" />
+					<input type="number" v-model="adddata.phone" placeholder="请填写联系人电话" placeholder-style="color: #62BF89;font-size:24rpx"
+					 @blur="iphone" />
+					<input type="text" v-model="adddata.site" placeholder="请填写联系人地址" placeholder-style="color: #62BF89;font-size:24rpx" />
+					<u-action-sheet :list="actionSheetList" v-model="show" @click="actionSheetCallback"></u-action-sheet>
+				</view>
+				<view class="addafter_con_connect">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/afterSale/5d9b8db91f11175aa5277fef40581ab.png'" mode=""></image>
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/afterSale/5d9b8db91f11175aa5277fef40581ab.png'" mode=""></image>
+				</view>
+				<view class="addafter_con_bot">
+					<p class="addafter_con_bot_title">保修详情</p>
+					<textarea v-model="adddata.text" placeholder="请描述设备问题" class="textarea" placeholder-style="color: #62BF89;font-size:26rpx" />
+					<p style="color: #808080;font-size: 24rpx;">{{adddata.text.length}}/140</p>
+					<view class="imgvideo">
+						<view class="imgvideo_img" v-for="(item,index) in 3">
+							<view @click="gainimg(index)">
+								<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/afterSale/eee1e84bb85f6f6ff5c5866a3a42779.png'" mode="" v-if="!uploadingTF[index]"></image>
+							</view>
+							<view class="uploading" v-if="uploadingTF[index]">
+								<u-icon name="close" class="delete" @click="deletes(index)"></u-icon>
+								<image :src="imageList[index]" mode="" class="uploading" @click="examine(imageList[index])"></image>
+							</view>
+						</view>
+						<view class="imgvideo_video" v-for="(item,index) in 1">
+							<view @click="gainvideo(index)">
+								<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/afterSale/80314eaa07c32e9c76537a8a8224130.png'" mode="" v-if="!uploadingTF[index+3]"></image>
+							</view>
+							<view class="uploading" v-if="uploadingTF[index+3]">
+								<video :src="BASE_URL+selfList" :controls="false" class="uploading" ></video>
+								<view class="yulan" @click="yulan(index)">
+									预览
+								</view>
+								<view class="deletes" @click="deletes(index+3)">
+									删除
+								</view>
+							</view>
+						</view>
+					</view>
+					<button @click="btn" :disabled="btnisTorF">提 交</button>
+				</view>
+		</view>
+		</view>
+		<kps-image-cutter @ok="onok" @cancel="oncancle" :url="imgs" :fixed="false" :blob="false" :maxWidth="500" :maxHeight="500"></kps-image-cutter>
+		<u-modal v-model="videoshow" :mask-close-able="true" :show-confirm-button="false" title="视频预览" class="model">
+			<view class="model_box">
+				<video :src="BASE_URL+selfList" controls style="width:90%;"></video>
+			</view>
+		</u-modal>
+	</view>
+</template>
+<script>
+	import kpsImageCutter from "@/components/ksp-image-cutter/ksp-image-cutter.vue";
+	export default {
+		components:{
+			kpsImageCutter
+		},
+		data() {
+			return {
+				BASE_URL: 'http://182.92.193.64:8002',
+				adddata:{//设备参数
+					id:'',
+					name:'',
+					phone:'',
+					text:'',
+					site:'',
+					type:'',
+					type_id:''
+				},
+				imageList:[],//图片链接
+				uploadingTF:[false,false,false,false,false,false],//图片的删除
+				selfList:'',//视频链接
+				actionSheetList: [//设备选项
+					{
+						text: '杀虫灯',
+						id:2
+					},
+					{
+						text: '测报灯',
+						id:3
+					},
+					{
+						text: '智能性诱',
+						id:4
+					},
+					{
+						text: '环境监测',
+						id:5
+					},
+					{
+						text: '监控设备',
+						id:6
+					},
+					{
+						text: '孢子仪',
+						id:7
+					},
+					{
+						text: '性诱2.0',
+						id:10
+					},
+				],
+				show:false,//选择器的显示
+				btnisTorF:false,
+				deviceid:false,//设备号判断
+				imageFile:[],
+				phoneTF:true,//手机号判断
+				imgs:'',
+				imgindex:null,
+				videoindex:0,
+				videoshow:false
+			}
+		},
+		onLoad(option) {
+			if(option.device_id){
+				console.log(option)
+				this.adddata.id = option.device_id
+				var typedata = this.actionSheetList.filter((item)=>{
+					return item.id == Number(option.device_type)
+				})
+				console.log(typedata)
+				this.adddata.type = typedata[0].text
+				this.adddata.type_id = typedata[0].id
+			}
+		},
+		methods: {
+			clickLeft(){//返回
+				uni.navigateTo({
+					url:"./index"
+				})
+			},
+			gainimg(index){//添加图片
+				this.imgindex = index
+				uni.chooseImage({
+				    count: 1, //默认9
+				    sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+				    sourceType: ['album','camera'], //从相册选择
+				    success: (res)=> {
+						this.imgs = res.tempFilePaths[0]
+					}
+				});
+			},
+			gainvideo(index){//添加视频
+				uni.chooseVideo({
+				    count: 1,
+					sourceType:['album', 'camera'],
+				    success:(res)=> {
+						console.log(res)
+						uni.uploadFile({
+						    url: 'http://182.92.193.64:8002/api/api_gateway?method=after_sale.after_sale_manage.video_upload', //仅为示例,非真实的接口地址
+						    filePath: res.tempFilePath,
+						    name: 'upload',
+							fileType:"video",
+						    formData: {
+						        'user': 'test'
+						    },
+						    success: (uploadFileRes) => {
+								console.log(uploadFileRes)
+								if(uploadFileRes.statusCode == 200){
+									this.selfList=JSON.parse(uploadFileRes.data).data.data.src
+									this.$forceUpdate() //强制刷新视图
+									this.uploadingTF[index+3] = true
+								}else{
+									uni.showToast({
+									    title: '请将视频压缩后上传!',
+									    duration: 2000,
+										icon:"none"
+									});
+								}
+						    }
+						});
+				    }
+				});
+			},
+			deletes(index){//删除
+				this.uploadingTF[index]=false
+				this.$forceUpdate() //强制刷新视图
+			},
+			async getaddafter(data) {//提交数据
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=after_sale.after_sale_manage.aftersale_apply',
+					data:{
+						    device_id:data.id,
+						    d_type:data.type,
+						    errordesc:data.text,
+						    errorimg:data.imageList,
+							errorvideo:data.selfList,
+						    addr:data.site,
+						    user:data.name,
+						    userphone:data.phone,
+						    is_pc:0
+					}
+				})
+			},
+			async getID(data) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=after_sale.after_sale_manage.device_check',
+					data:{
+						device_id:data
+					}
+				})
+				if(res!=''){
+					this.deviceid=true
+				}else{
+					this.deviceid=false
+				}
+			},
+			btn(){//提交按钮
+				let obj ={}
+				obj.id=this.adddata.id
+				obj.type=this.adddata.type_id
+				obj.text=this.adddata.text
+				obj.imageList=JSON.stringify(this.imageList)
+				obj.site=this.adddata.site
+				obj.name=this.adddata.name
+				obj.phone=this.adddata.phone
+				obj.selfList=JSON.stringify(this.selfList)
+				console.log(obj.imageList)
+				if(this.deviceid && this.adddata.type_id!=''&&this.phoneTF){
+					this.getaddafter(obj)
+				}else{
+					console.log(1)
+					uni.showToast({
+					    title: '设备ID和设备类型不能为空',
+					    duration: 2000,
+						icon:"none"
+					});
+				}
+			},
+			actionSheetCallback(index) {//选择器选择
+				this.adddata.type = this.actionSheetList[index].text;
+				this.adddata.type_id = this.actionSheetList[index].id
+			},
+			iphone(){//检测手机
+				if(!/^1[23456789]\d{9}$/.test(this.adddata.phone)){
+					uni.showToast({
+					    title: '手机号格式不正确',
+					    duration: 2000,
+						icon:'none'
+					});
+					this.phoneTF=false
+				}
+			},
+			addID(){
+				this.getID(this.adddata.id)
+			},
+			examine(url) {
+				var imgarr =[]
+				imgarr.push(url)
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			},
+			onok(ev){
+				uni.uploadFile({
+				    url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+					filePath: ev.path,
+				    name: 'img_file',
+				    formData: {
+				        'user': 'test'
+				    },
+				    success: (uploadFileRes) => {
+						this.imageList[this.imgindex]=JSON.parse(uploadFileRes.data).data.src
+						this.$forceUpdate() //强制刷新视图
+						this.uploadingTF[this.imgindex]=true
+				    }
+				});
+				this.imgs = ""
+			},
+			oncancle(){
+				this.imgs = ""
+			},
+			yulan(index){
+				this.videoindex = index
+				this.videoshow = !this.videoshow
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color: #71CD9A;
+	}
+	.addafter_con{
+		width: 100%;
+		position: absolute;
+		top: 54px;
+		.addafter_con_top{
+			width: 90%;
+			margin: 0 auto;
+			background-color: #FFFFFF;
+			padding: 16rpx 30rpx 36rpx;
+			border-radius: 20rpx;
+			box-sizing: border-box;
+			p{
+				text-align: center;
+				font-size: 30rpx;
+				color: #62BF89;
+			}
+			input{
+				margin-top: 20rpx;
+				background-color: #F1FAF5;
+				color: #62BF89;
+				font-size:26rpx;
+				padding: 8rpx 26rpx;
+				border-radius: 20rpx;
+			}
+		}
+		.addafter_con_connect{
+			width: 90%;
+			margin: -20rpx auto;
+			display: flex;
+			justify-content: space-between;
+			padding: 0 16rpx;
+			box-sizing: border-box;
+			image{
+				width: 20rpx;
+				height: 60rpx;
+			}
+		}
+		.addafter_con_bot{
+			width: 90%;
+			margin: 0 auto;
+			background-color: #FFFFFF;
+			padding: 30rpx;
+			border-radius: 20rpx;
+			box-sizing: border-box;
+			.addafter_con_bot_title{
+				text-align: center;
+				font-size: 30rpx;
+				color: #62BF89;
+			}
+			.textarea{
+				width: 94%;
+				height: 240rpx;
+				padding: 20rpx;
+				background-color: #F1FAF5;
+				margin-top: 20rpx;
+				font-size: 26rpx;
+				border-radius: 20rpx;
+				color: #62BF89;  
+			}
+		}
+		.imgvideo{
+			width: 100%;
+			margin-top: 20rpx;
+			background-color: #FFFFFF;
+			display: flex;
+			flex-wrap: wrap;
+			.imgvideo_img,.imgvideo_video{
+				width: 30%;
+				height: 160rpx;
+				border: 2rpx dashed #A3DABD;
+				text-align: center;
+				line-height: 160rpx;
+				margin:0 10rpx 20rpx 8rpx;
+				position: relative;
+				image{
+					width: 40rpx;
+					height: 32rpx;
+				}
+				.uploading{
+					width: 100%;
+					height: 160rpx;
+					position: absolute;
+					top: 0;
+					left: 0;
+				}
+				.delete{
+					position: absolute;
+					top: -12rpx;
+					right: -12rpx;
+					font-size: 36rpx;
+					background-color: #FE0000;
+					border-radius: 50%;
+					color: #ffffff;
+					z-index: 50;
+				}
+				.deletes{
+					width: 80%;
+					height: 50rpx;
+					margin-left: 110%;
+					font-size: 24rpx;
+					background-color: #FE0000;
+					color: #FFFDEF;
+					line-height: 50rpx;
+				}
+				.yulan{
+					width: 80%;
+					height: 50rpx;
+					margin: 0 0 20rpx 110%;
+					font-size: 24rpx;
+					background-color: #62BF89;
+					color: #FFFDEF;
+					line-height: 50rpx;
+				}
+			}
+		}
+		button{
+			width: 100%;
+			height: 60rpx;
+			font-size: 30rpx;
+			line-height: 60rpx;
+			color: #FFFFFF;
+			background-color: #50CE87;
+			margin-top: 60rpx;
+		}
+	}
+	.model {
+		width: 90%;
+		.model_box {
+			width: 90%;
+			margin: 40rpx auto 48rpx;
+			display: flex;
+			justify-content: center;
+		}
+	}
+</style>

+ 331 - 0
pages/afterSale/index.vue

@@ -0,0 +1,331 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view style="position: fixed;z-index: 100;top: 64px;">
+			<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="售后系统" rightIcon="search" @clickRight="search"></uni-nav-bar>
+		</view>
+		<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/afterSale/dcd7147f4b15d00c5c90006738b8453.png'" class="expertimages"></image>
+		<view class="aftersaleTF" v-if="aftersaleTF">
+			暂无数据
+		</view>
+		<view class="aftersale" v-else>
+			<view class="aftersale_item" v-for="(item,index) in faultdata" :key="index">
+				<view class="aftersale_item_title">
+					<u-icon name="calendar" color="#71D8AF" size="34"></u-icon>
+					<span>设备 ID:{{item.device_id}}</span>
+				</view>
+				<view class="aftersale_item_con">
+					<p>联系人:{{item.user}}</p>
+					<p>联系电话:{{item.userphone}}</p>
+					<p>位置:{{item.addr}}</p>
+					<p>故障上报时间:{{item.uptime|timeFormat()}}</p>
+				</view>
+				<view class="aftersale_item_operate">
+					<button :class="item.errordesc?'fault':'none'" :disabled="!item.errordesc" @click="fault(item.errordesc)">故障原因</button>
+					<button :class="item.errorimg.length!=0?'imgs':'none'" :disabled="item.errorimg.length==0" @click="faultImg(item.errorimg)">图片</button>
+					<button :class="item.errorvideo?'video':'none'" :disabled="!item.errorvideo" @click="faultVideo(item.errorvideo)">视频</button>
+				</view>
+				<view class="aftersale_item_icon">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+aftersale_icon[Number(item.device_type)-2].src" mode=""></image>
+				</view>
+			</view>
+		</view>
+		<view class="addindent" @click="addf">
+			新 增 售 后 单
+		</view>
+		<u-modal v-model="show" :mask-close-able="maskcloseable" :show-confirm-button="showconfirmbutton" :title="title" class="model">
+			<view class="model_box">
+				<p v-if="faultinfo_tf">{{faultinfo}}</p>
+				<u-swiper :list="faultimg" v-if="faultimg_tf" class="uswiper" height="400" style="width: 100%;" @click="examine(faultimg)"></u-swiper>
+				<video :src="BASE_URL+faultvideo" controls v-if="faultvideo_tf" style="width:90%;"></video>
+			</view>
+		</u-modal>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {  
+			return {
+				BASE_URL: 'http://182.92.193.64:8002',
+				faultdata: [],
+				aftersale_icon: [{
+						src: '/image/afterSale/6.png'
+					},
+					{
+						src: '/image/afterSale/1.png'
+					},
+					{
+						src: '/image/afterSale/4.png'
+					},
+					{
+						src: '/image/afterSale/3.png'
+					},
+					{
+						src: '/image/afterSale/5.png'
+					},
+					{
+						src: '/image/afterSale/2.png'
+					}
+				],
+				title:"",//弹框标题
+				show: false,//弹框先显示
+				maskcloseable: true,
+				showconfirmbutton: false,
+				faultinfo: '',//故障信息
+				faultinfo_tf:false,//故障信息显示
+				faultvideo: '',//故障视频
+				faultvideo_tf:false,//故障视频显示
+				faultimg: [],//故障图片
+				faultimg_tf: false,//故障图片显示
+				page:1,
+				aftersaleTF:true,
+				isTop:false
+			}
+		},
+		methods: {
+			async getAftersale() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=after_sale.after_sale_manage.aftersale_info',
+					data:{
+						page:this.page
+					}
+				})
+				if(res.counts == 0){
+					this.aftersaleTF = true
+				}else{
+					this.aftersaleTF = false
+				}
+				this.faultdata =this.faultdata.concat(res.data)
+				for (var i = 0; i < this.faultdata.length; i++) {
+					this.faultdata[i].errorimg = JSON.parse(this.faultdata[i].errorimg)
+					if (this.faultdata[i].errorimg == null) {
+						this.faultdata[i].errorimg = []
+					}
+				}
+				console.log(res)
+			}, 
+			fault(info) { //查看故障信息
+				this.title="故障信息"
+				this.show = true
+				this.faultinfo = info
+				this.faultimg_tf = false
+				this.faultinfo_tf=true
+				this.faultvideo_tf=false
+			},
+			faultImg(info) { //查看故障图片
+				this.faultimg=[]
+				for (var i = 0; i < info.length; i++) {
+					let obj = {}
+					obj.image = info[i]
+					this.faultimg.push(obj)
+				}
+				console.log(this.faultimg)
+				this.title="故障图片"
+				this.show = true
+				this.faultimg_tf = true
+				this.faultinfo_tf=false
+				this.faultvideo_tf=false
+			},
+			faultVideo(info) { //查看故障视频
+				this.title="故障视频" 
+				if(info.indexOf("[")!=-1){
+					this.faultvideo=JSON.parse(info)[0]
+				}else{
+					this.faultvideo=info
+				}
+				console.log(this.faultvideo)
+				this.show = true
+				this.faultimg_tf = false
+				this.faultinfo_tf=false
+				this.faultvideo_tf=true
+			},
+			search() { //搜索
+				uni.navigateTo({
+					url:"./search"
+				})
+			},
+			addf() { //添加
+				uni.navigateTo({
+					url:"./addafter"
+				})
+			},
+			clickLeft(){
+				uni.switchTab({
+					url:"../index/index"
+				})
+			},
+			examine(url) {
+				var imgarr =[]
+				for(var i=0;i<url.length;i++){
+					imgarr.push(url[i].image)
+				}
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad() { 
+			this.getAftersale()
+		},
+		onReachBottom() {
+			this.page++
+			this.getAftersale()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.expertimages {
+		width: 100%;
+		height: 154rpx;
+		position: fixed;
+		top: 108px;
+		z-index: 100;
+	}
+
+	.aftersale_search {
+		position: fixed;
+		z-index: 100;
+		top: 124rpx;
+		right: 20rpx;
+
+		.sp_icon {
+			font-size: 36rpx;
+			margin-left: 16rpx;
+		}
+	}
+	
+	.aftersaleTF{
+		width: 100%;
+		position: relative;
+		top: 340rpx;
+		text-align: center;
+		padding-top: 40rpx;
+		font-size: 20px;
+	}
+	.aftersale {
+		width: 100%;
+		// margin-top: 20rpx;
+		position: relative;
+		top: 380rpx;
+		margin-bottom: 100rpx;
+		.aftersale_item {
+			width: 90%;
+			margin: 0 auto 30rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 30rpx 20rpx 20rpx;
+			position: relative;
+			box-sizing: border-box;
+			.aftersale_item_title {
+				width: 100%;
+
+				span {
+					margin-left: 16rpx;
+					font-weight: 700;
+				}
+			}
+
+			.aftersale_item_con {
+				width: 92%;
+				margin-left: 8%;
+				margin-top: 20rpx;
+
+				p {
+					height: 48rpx;
+					font-size: 24rpx;
+					color: #BEBEBE;
+				}
+			}
+
+			.aftersale_item_operate {
+				width: 70%;
+				display: flex;
+				margin: 18rpx 0 0 30%;
+
+				button {
+					width: 130rpx;
+					padding: 0;
+					font-size: 24rpx;
+					color: #FFFFFF;
+				}
+
+				.fault {
+					background-color: #F78E01;
+				}
+
+				.imgs {
+					background-color: #71CD9A;
+				}
+
+				.video {
+					background-color: #53C6E6;
+				}
+
+				.none {
+					background-color: #F3F3F3;
+					color: #B4B4B4;
+				}
+			}
+
+			.aftersale_item_icon {
+				position: absolute;
+				top: 0;
+				right: 36rpx;
+
+				image {
+					width: 68rpx;
+					height: 64rpx;
+				}
+			}
+		}
+	}
+
+	.model {
+		width: 90%;
+		.model_box {
+			width: 90%;
+			margin: 40rpx auto 48rpx;
+			display: flex;
+			justify-content: center;
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+	.addindent{
+		width: 100%;
+		position: fixed;
+		bottom: 0;
+		left: 0;
+		height: 80rpx;
+		text-align: center;
+		line-height: 80rpx;
+		background-color: #71cd9a;
+		color: #ffffff;
+		font-size: 16px;
+	}
+</style>

+ 291 - 0
pages/afterSale/search.vue

@@ -0,0 +1,291 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view style="position: fixed;z-index: 100;top: 64px;">
+			<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回"></uni-nav-bar>
+			<view class="search_top_input">
+				<input type="text" value="" placeholder="请输入设备ID"  v-model="imports" @input="searchinp"/>
+				<u-icon name="search" size="40" class="icon" @click="search"></u-icon>
+			</view>
+		</view>
+		<view class="aftersaleinfo" v-if="aftersaleinfotf">
+			暂无此设备信息
+		</view>
+		<view class="aftersale" v-else>
+			<view class="aftersale_item" v-for="(item,index) in faultdata" :key="index">
+				<view class="aftersale_item_title">
+					<u-icon name="calendar" color="#71D8AF" size="34"></u-icon>
+					<span>设备 ID:{{item.device_id}}</span>
+				</view>
+				<view class="aftersale_item_con">
+					<p>联系人:{{item.user}}</p>
+					<p>联系电话:{{item.userphone}}</p>
+					<p>位置:{{item.addr}}</p>
+					<p>故障上报时间:{{item.uptime|timeFormat()}}</p>
+				</view>
+				<view class="aftersale_item_operate">
+					<button class="fault" @click="fault(item.errordesc)">故障原因</button>
+					<button :class="item.errorimg.length!=0?'imgs':'none'" :disabled="item.errorimg.length==0" @click="faultImg(item.errorimg)">图片</button>
+					<button :class="item.errorvideo?'video':'none'" :disabled="!item.errorvideo" @click="faultVideo(item.errorvideo)">视频</button>
+				</view>
+				<view class="aftersale_item_icon">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+aftersale_icon[Number(item.device_type)-2].src" mode=""></image>
+				</view>
+			</view>
+		</view>
+		<u-modal v-model="show" :mask-close-able="maskcloseable" :show-confirm-button="showconfirmbutton" :title="title" class="model">
+			<view class="model_box">
+				<p v-if="faultinfo_tf">{{faultinfo}}</p>
+				<u-swiper :list="faultimg" v-if="faultimg_tf" class="uswiper" height="400" style="width: 100%;" @click="examine(faultimg)"></u-swiper>
+				<video :src="BASE_URL+faultvideo" controls v-if="faultvideo_tf" style="width: 90%;"></video>
+			</view>
+		</u-modal>
+	</view>
+</template>
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				imports:'',
+				BASE_URL: 'http://182.92.193.64:8002',
+				faultdata:[],
+				aftersale_icon: [{
+						src: '/image/afterSale/6.png'
+					},
+					{
+						src: '/image/afterSale/1.png'
+					},
+					{
+						src: '/image/afterSale/4.png'
+					},
+					{
+						src: '/image/afterSale/3.png'
+					},
+					{
+						src: '/image/afterSale/5.png'
+					},
+					{
+						src: '/image/afterSale/2.png'
+					}
+				],
+				title:"",//弹框标题
+				show: false,//弹框先显示
+				maskcloseable: true,
+				showconfirmbutton: false,
+				faultinfo: '',//故障信息
+				faultinfo_tf:false,//故障信息显示
+				faultvideo: '',//故障视频
+				faultvideo_tf:false,//故障视频显示
+				faultimg: [],//故障图片
+				faultimg_tf: false,//故障图片显示
+				aftersaleinfotf:'',
+				page:1
+			}
+		},
+		methods: {
+			async getAftersale(num) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=after_sale.after_sale_manage.aftersale_info',
+					data:{
+						f_id:num,
+						page:this.page
+					}
+				})
+				this.faultdata =this.faultdata.concat(res.data)
+				console.log(this.faultdata)
+				if(this.faultdata.length==0){
+					this.aftersaleinfotf = true
+				}else{
+					this.aftersaleinfotf = false
+				}
+				for (var i = 0; i < this.faultdata.length; i++) {
+					this.faultdata[i].errorimg = JSON.parse(this.faultdata[i].errorimg)
+					if (this.faultdata[i].errorimg == null) {
+						this.faultdata[i].errorimg = []
+					}
+				}
+			},
+			search(){
+				this.getAftersale(Number(this.imports))
+			},
+			fault(info) { //查看故障信息
+				this.title="故障信息"
+				this.show = true
+				this.faultinfo = info
+				this.faultimg_tf = false
+				this.faultinfo_tf=true
+				this.faultvideo_tf=false
+			},
+			faultImg(info) { //查看故障图片
+				this.faultimg=[]
+				for (var i = 0; i < info.length; i++) {
+					let obj = {}
+					obj.image = info[i]
+					this.faultimg.push(obj)
+				}
+				console.log(this.faultimg)
+				this.title="故障图片"
+				this.show = true
+				this.faultimg_tf = true
+				this.faultinfo_tf=false
+				this.faultvideo_tf=false
+			},
+			faultVideo(info) { //查看故障视频
+			this.title="故障视频"
+				this.faultvideo=info
+				this.show = true
+				this.faultimg_tf = false
+				this.faultinfo_tf=false
+				this.faultvideo_tf=true
+			},
+			clickLeft(){
+				uni.navigateTo({
+					url:"./index"
+				})
+			},
+			searchinp() {
+				Debounce(() => {
+					this.eqlistdata = []
+					this.search()
+				}, 1000)()
+			},
+			examine(url) {
+				var imgarr =[]
+				for(var i=0;i<url.length;i++){
+					imgarr.push(url[i].image)
+				}
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			},
+		},
+		onReachBottom() {
+			this.page++
+			this.getAftersale(Number(this.imports))
+		}
+	}
+</script>
+<style lang="scss">
+	.search_top_input{
+		width: 80%;
+		height: 54rpx;
+		background-color: #E4E4E4;
+		border-radius: 27rpx;
+		position: absolute;
+		top: 18rpx;
+		right: 18rpx;
+		padding-top: 8rpx;
+		box-sizing: border-box;
+		input {
+			width: 85%;
+			// text-indent: 1rem;
+			font-size: 26rpx;
+			padding-left: 20px;
+		}
+		.icon{
+			position: absolute;
+			top: 8rpx;
+			right: 26rpx;
+		}
+	}
+	.aftersaleinfo{
+		width: 100%;
+		position: relative;
+		top: 98px;
+		height: 100rpx;
+		text-align: center;
+		line-height: 100rpx;
+		font-size: 32rpx;
+	}
+	.aftersale {
+		width: 100%;
+		// margin-top: 20rpx;
+		position: relative;
+		top: 118px;
+	
+		.aftersale_item {
+			width: 90%;
+			margin: 0 auto 30rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 30rpx 20rpx 20rpx;
+			position: relative;
+			box-sizing: border-box;
+			.aftersale_item_title {
+				width: 100%;
+	
+				span {
+					margin-left: 16rpx;
+					font-weight: 700;
+				}
+			}
+	
+			.aftersale_item_con {
+				width: 92%;
+				margin-left: 8%;
+				margin-top: 20rpx;
+	
+				p {
+					height: 48rpx;
+					font-size: 24rpx;
+					color: #BEBEBE;
+				}
+			}
+	
+			.aftersale_item_operate {
+				width: 70%;
+				display: flex;
+				margin: 18rpx 0 0 30%;
+	
+				button {
+					width: 130rpx;
+					padding: 0;
+					font-size: 24rpx;
+					color: #FFFFFF;
+				}
+	
+				.fault {
+					background-color: #F78E01;
+				}
+	
+				.imgs {
+					background-color: #71CD9A;
+				}
+	
+				.video {
+					background-color: #53C6E6;
+				}
+	
+				.none {
+					background-color: #F3F3F3;
+					color: #B4B4B4;
+				}
+			}
+	
+			.aftersale_item_icon {
+				position: absolute;
+				top: 0;
+				right: 36rpx;
+	
+				image {
+					width: 68rpx;
+					height: 64rpx;
+				}
+			}
+		}
+	}
+	.model {
+		width: 90%;
+		.model_box {
+			width: 90%;
+			margin: 20rpx auto 48rpx;
+			display: flex;
+			justify-content: center;
+		}
+	}
+</style>
+

+ 433 - 0
pages/cb/bzy/equip-set/bzyhistoryile.vue

@@ -0,0 +1,433 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="历史数据"></uni-nav-bar>
+			</view>
+			<view class="shuju_one">
+				<view class="shuju_one_title">
+					<view :class="titleidnex==index?'title_text_color':'tltle_text'" v-for="(item,index) in titletext" :key="index"
+					 @click="changeindex(index)">
+						{{item}}
+					</view>
+				</view>
+				<view class="canvastishi" v-if="!canvastishiTF">
+					暂无数据
+				</view>
+				<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
+				 @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+			</view>
+			<view class="refresh" @click="refresh">
+				刷 新
+			</view>
+			<view class="condition">
+				<scroll-view  scroll-x="true" class="scroll-X" scroll-top="0">
+					<table class="table">
+						<tr class="tr">
+							<th class="th" v-for="(item,index) in thdata" :key="index">{{item}}</th>
+						</tr>
+						<tr class="tr" v-for="(items,indexs) in historylistdata" :key="indexs" v-if="!forbidden">
+							<td class="td">{{items.d_h_t.addtime|timeFormat()}}</td>
+							<td class="td">{{items.d_h_t.ds==0?"关":"开"}}</td>
+							<td class="td">{{items.d_h_t.at}}</td>
+							<td class="td">{{items.d_h_t.ah}}</td>
+							<td class="td">{{items.d_h_t.set_temp}}</td>
+							<td class="td">{{items.d_h_t.pre_temp}}</td>
+							<td class="td">{{items.d_h_t.bat_sta==0?"正常":"欠压"}}</td>
+							<td class="td">{{items.d_h_t.rps==0?"正常":"雨控"}}</td>
+							<td class="td">{{items.d_h_t.usb_sta==0?"正常":"异常"}}</td>
+							<td class="td">{{items.d_h_t.csq}}</td>
+							<td class="td">{{items.d_h_t.current}}</td>
+							<td class="td">{{items.d_h_t.vbat}}</td>
+							<td class="td">{{items.d_h_t.dver}}</td>
+						</tr>
+						<tr class="tr" v-if="forbidden">
+							<td class="td" v-for="item in 13" :key="item">暂无数据</td>
+						</tr>
+					</table>
+				</scroll-view>
+				<view class="pagenumber">
+					<button @click="prev">上一页</button>
+					<view class="pagenumber_page">
+						第 {{page}} 页
+					</view>
+					<view class="pagenumber_page">
+						共 {{pagesum}} 页
+					</view>
+					<button @click="next" :disabled="forbidden">下一页</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uCharts from '../../../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvaColumnA = null;
+	export default {
+		data() {
+			return {
+				styles: {
+					// width: "650rpx",
+					height: "400rpx"
+				},
+				d_id: '',
+				start_time: "",
+				end_time: "",
+				historydatas: [],
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				titleidnex: 0,
+				device_id: '',
+				page: 1,
+				pagesum: null,
+				historylistdata: [],
+				thdata: ["上报时间", "设备开关", "环境温度(°C)", "环境湿度(%)", "保温仓温度设定温度(°C)", "保温仓温度当前温度(°C)", "电池状态", "雨控状态", "摄像头状态", "信号强度",
+					"电流(mA)",
+					"电压(V)", "设备版本"
+				],
+				forbidden: false,
+				canvastishiTF: false,
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+			}
+		},
+		methods: {
+			//forecast.worm_lamp.device_polyline_data 历史数据折线图
+			// device_type_id          必传(string)                  设备类型  3虫情测报灯 7孢子仪 4智能性诱 2杀虫灯  9糖醋测报灯  10测报灯rtu
+			//    d_id                    必传                            设备id
+			//    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
+			//    end_time
+			async history() { //获取图片列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_polyline_data',
+					data: {
+						device_type_id: 7,
+						d_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000)
+					}
+				})
+				console.log(res)
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (this.historydatas.length == 0) {
+					this.canvastishiTF = false
+				} else {
+					this.canvastishiTF = true
+
+					var arr1 = []
+					var arr2 = []
+					var arr3 = []
+					var xtitle = []
+					for (var i = 0; i < res.length; i++) {
+						var times = new Date(res[i].addtime * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getMinutes())
+						arr1.unshift(res[i].temperature == "" ? "0" : res[i].temperature)
+						arr2.unshift(res[i].humidity == "" ? "0" : res[i].humidity)
+						arr3.unshift(res[i].others == "" ? "0" : res[i].others)
+					}
+					var obj = [{
+						name: '温度',
+						data: arr1,
+						color: '#00E29D'
+					}, {
+						name: '湿度',
+						data: arr2,
+						color: '#6CBBFF'
+					}, {
+						name: '保温仓温度',
+						data: arr3,
+						color: '#FF3F3F'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+				}
+			},
+			//forecast.worm_lamp.device_history_data历史数据列表
+			async historylist() { //获取图片列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+					data: {
+						device_type_id: 7,
+						device_id: this.device_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+						page: this.page
+					}
+				})
+				this.historylistdata = res.data
+				this.pagesum = Math.ceil(res.counts / 10 + 1)
+				if (res.data.length == 0) {
+					this.forbidden = true
+					console.log(res.data.length)
+				} else {
+					this.forbidden = false
+					console.log(res.data.length)
+				}
+				// console.log(this.historylistdata)
+			},
+			changeindex(index) {
+				this.titleidnex = index
+				var now = new Date()
+				this.$forceUpdate()
+				if (index == 0) {
+					this.start_time = this.end_time - 24 * 60 * 60 * 1000
+					this.history()
+					this.historylist()
+				} else if (index == 1) {
+					var oldtime = now.setMonth(now.getMonth() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 2) {
+					var oldtime = now.setMonth(now.getMonth() - 6)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 3) {
+					var oldtime = now.setFullYear(now.getFullYear() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				}
+			},
+			prev() { //上一页
+				if (this.page > 1) {
+					this.page--
+					this.historylist()
+				}
+			},
+			next() { //下一页
+				this.page++
+				this.historylist()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showColumn(id, xtitle, xinfo) {
+				var _self = this
+				canvaColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position: "top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle,
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				console.log(e)
+				canvaColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvaColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvaColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+			async newdata() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.get_device_config',
+					data: {
+						device_type_id: 7,
+						d_id: this.d_id,
+						control_type: "data"
+					}
+				})
+				if(res){
+					uni.showToast({
+						title: '刷新成功',
+						duration: 2000,
+						icon: "none"
+					});
+					uni.navigateBack({
+						delta: 1
+					})
+				}else{
+					uni.showToast({
+						title: '刷新失败',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			refresh() { //获取当前时间的数据
+				this.newdata()
+			},
+		},
+		onLoad(option) {
+			this.d_id = option.d_id
+			this.device_id = option.device_id
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+		},
+		onShow() {
+			this.end_time = +new Date() 
+			this.start_time = this.end_time - 24 * 60 * 60 * 1000
+			setTimeout(()=>{
+				this.history()
+				this.historylist()
+			},1000)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.shuju_one,
+	.shuju_two {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		height: 550rpx;
+
+		.canvastishi {
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+
+		.shuju_one_title {
+			width: 70%;
+			margin: 0 auto;
+			display: flex;
+
+			.tltle_text {
+				width: 25%;
+				border: 2rpx solid #B2B2B2;
+				color: #B2B2B2;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+
+			.title_text_color {
+				width: 25%;
+				border: 2rpx solid #28AE4F;
+				color: #28AE4F;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+		}
+	}
+
+	.refresh {
+		position: absolute;
+		top: 700rpx;
+		left: 5%;
+		width: 160rpx;
+		height: 50rpx;
+		background-color: #28AE4F;
+		color: #FFFFFF;
+		line-height: 50rpx;
+		text-align: center;
+	}
+
+	.condition {
+		position: absolute;
+		top: 770rpx;
+		display: flex;
+		flex-wrap: wrap;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-bottom: 30rpx;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+			.table{
+				width: 1672px;
+			}
+			.tr {
+				display: flex;
+				overflow: hidden;
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 240rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+
+				.th {
+					height: 100rpx;
+				}
+
+				.th:first-child,
+				.td:first-child {
+					width: 300rpx;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+				margin: 0 10rpx;
+			}
+
+			.pagenumber_page {
+				width: 100rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 441 - 0
pages/cb/bzy/equip-set/equip-set.vue

@@ -0,0 +1,441 @@
+<template>
+	<view>
+		<view class="" v-if="myuser_type">
+			<view class="tit adminTit">
+				操作
+			</view>
+			<view class="btns">
+				 <button type="warn" @click="equipBtnControl('dtu_update')" size="mini">升级</button>
+				 <button type="warn" @click="equipBtnControl('dtu_reboot')" size="mini">重启</button>
+				 <button type="warn" @click="equipBtnControl('dtu_reboot')" size="mini">立即拍照</button>
+				 <button type="warn" @click="equipBtnControl('dtu_reboot')" size="mini">对焦拍照</button>
+				 <button type="warn" @click="equipBtnControl('dtu_reboot')" size="mini">转仓</button>
+			</view>
+			<view class="tit adminTit">
+				设备开关
+			</view>
+			<view class="uni-list-cell"  @click="onoff">
+				<text class="uni-input">{{on_off=="0"?'关闭':'开机'}}</text>
+				<view class="arrow"></view>
+				<u-select v-model="on_off_show" mode="single-column" :list="on_off_list" @confirm="confirm($event,'on_off')"></u-select>
+			</view>
+		</view>
+		<view class="tit">
+			载玻片滴液时间
+		</view>
+		<view class="uni-list-cell" @click="selectFun('drop_time')">
+			<text class="uni-input">{{setFrom.drop_time}}</text>
+			<view class="arrow"></view>
+			<u-select v-model="drop_time_show" mode="single-column" :list="drop_time_List" @confirm="confirm($event,'drop')"></u-select>
+		</view>
+		<view class="tit">
+			孢子培养时间(h)
+		</view>
+		<view class="">
+			<slider :value="setFrom.cul_time" show-value="true" :min="1" :max="24" @change="sliderChange($event,'cul_time')"  block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			保温仓设定温度(℃)
+		</view>
+		<view class="">
+			<slider :value="setFrom.set_temp" show-value="true" :min="10" :max="40" @change="sliderChange($event,'set_temp')"  block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			数据上传时间间隔(min)
+		</view>
+		<view class="">
+			<slider :value="setFrom.datt" show-value="true" :min="10" :max="60" @change="sliderChange($event,'datt')"  block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			采集开启和关闭时间
+		</view>
+		<view class="selectTime">
+			<view class="uni-list-cell time" @click="selectTime('st1')">
+				<text>{{coll_time.time01||'开始时间'}}</text>
+				<u-icon name="clock"></u-icon>
+			</view>
+			<text class="line">-</text>
+			<view class="uni-list-cell time" @click="selectTime('et1')">
+				<text>{{coll_time.time02||'结束时间'}}</text>
+				<u-icon name="clock"></u-icon>
+			</view>
+		</view>
+		<view class="selectTime">
+			<view class="uni-list-cell time" @click="selectTime('st2')">
+				<text>{{coll_time.time03||'开始时间'}}</text>
+				<u-icon name="clock"></u-icon>
+			</view>
+			<text class="line">-</text>
+			<view class="uni-list-cell time" @click="selectTime('et2')">
+				<text>{{coll_time.time04||'开始时间'}}</text>
+				<u-icon name="clock"></u-icon>
+			</view>
+		</view>
+		<view class="selectTime">
+			<view class="uni-list-cell time" @click="selectTime('st3')">
+				<text>{{coll_time.time05||'开始时间'}}</text>
+				<u-icon name="clock"></u-icon>
+			</view>
+			<text class="line">-</text>
+			<view class="uni-list-cell time" @click="selectTime('et3')">
+				<text>{{coll_time.time06||'开始时间'}}</text>
+				<u-icon name="clock"></u-icon>
+			</view>
+		</view>
+		<view class="submit-box">
+			<u-button  @click="submit" type="success">确定</u-button>
+		</view>
+		<u-select v-model="collShow" mode="single-column" :list="timeList" @confirm="collConfirm($event,timeType)"></u-select>
+		<u-toast ref="toast" />
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				d_id:'',
+				on_off_show:false,
+				on_off:null,//设备开关
+				on_off_list:[{
+					value:0,
+					label:'关闭'
+				},{
+					value:1,
+					label:'开机'
+				}],
+				drop_time_show:false,
+				drop_time_List:[],
+			    setFrom: {
+					drop_time: "1", //载玻片滴液时间
+					cul_time: 1, //孢子培养时间
+					set_temp: 10, //保温仓设定温度
+					datt: 10, //数据上传时间间隔(h)-m
+					coll_time: [], //采集开启和关闭时间
+				 },
+				coll_time: {
+			        time01: "",
+			        time02: "",
+			        time03: "",
+			        time04: "",
+			        time05: "",
+			        time06: "",
+					value01: "",
+					value02: "",
+					value03: "",
+					value04: "",
+					value05: "",
+					value06: "",
+			      },
+				timeList:[] ,
+				collShow:false,
+				timeType:'',
+				myuser_type:false
+			}
+		},
+		onLoad(option){
+			this.d_id=option.d_id
+			this.equipOperation()
+			this.equipSet()
+			uni.getStorage({
+				key:"myuser_type",
+				success:(res)=>{
+					if(Number(res.data) == 1){
+						this.myuser_type = true
+					}
+				}
+			})
+		},
+		methods: {
+			//回显设备控制参数
+			async equipSet(){
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.device_control_info',
+					data:{
+						d_id:this.d_id,
+						cmd: "paramconf" 
+					}
+				})
+				this.setFrom.drop_time=res.drop_time 
+				this.setFrom.cul_time=res.cul_time
+				this.setFrom.set_temp=res.set_temp
+				this.setFrom.datt=res.datt
+				let coll_time=res.coll_time 
+				for (let i in coll_time) {
+					if (i == 0) {
+					  let arr = coll_time[i].split("-");
+					  this.coll_time.time01 =
+						Number(arr[0]) < 10 ? "0" + arr[0] + ":00" : arr[0] + ":00";
+					  this.coll_time.time02 =
+						Number(arr[1]) < 10 ? "0" + arr[1] + ":00" : arr[1] + ":00";
+					  this.coll_time.value01=Number(arr[0])
+					  this.coll_time.value02=Number(arr[1])
+					} else if (i == 1) {
+					  let arr = coll_time[i].split("-");
+					  this.coll_time.time03 =
+						Number(arr[0]) < 10 ? "0" + arr[0] + ":00" : arr[0] + ":00";
+					  this.coll_time.time04 =
+						Number(arr[1]) < 10 ? "0" + arr[1] + ":00" : arr[1] + ":00";
+						this.coll_time.value03=Number(arr[0])
+						this.coll_time.value04=Number(arr[1])
+					} else if (i == 2) {
+					  let arr = coll_time[i].split("-");
+					  this.coll_time.time05 =
+						Number(arr[0]) < 10 ? "0" + arr[0] + ":00" : arr[0] + ":00";
+					  this.coll_time.time06 =
+						Number(arr[1]) < 10 ? "0" + arr[1] + ":00" : arr[1] + ":00";
+						this.coll_time.value05=Number(arr[0])
+						this.coll_time.value06=Number(arr[1])
+					}
+				 }
+			console.log(this.setFrom)	
+			},
+			
+			
+			//回显设备开关状态
+			async equipOperation(){
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.worm_lamp.bzy_device',
+					data:{
+						d_id: this.d_id
+					}
+				})
+				this.on_off=res.on_off
+			},
+			//管理员操作
+			async equipBtnControl(cmd){
+					let res=await this.$myRequest({
+						url:'/api/api_gateway?method=forecast.send_control.admin_device_control',
+						data:{
+							cmd,
+							device_type_id: 7,
+							d_id: this.d_id
+						}
+					})
+					if(res){
+						this.$refs.toast.show({
+							title: '指令下发成功!',
+							type: 'success',
+						})
+					}
+			},
+			onoff(){
+					this.on_off_show=true
+			},
+			confirm(e,a){
+				switch(a){
+					case "on_off":
+						if(e[0].value){
+							 this.equipControl("poweron",e[0].value);
+						}else{
+							this.equipControl("poweroff",e[0].value);
+						}
+						break;
+					case "drop":
+						this.setFrom.drop_time=e[0].value;
+						break;
+				}
+			},
+			async equipControl(cmd,val){
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.admin_device_control',
+					data:{
+						cmd,
+						device_type_id: 7,
+						d_id: this.d_id
+					}
+				})
+				this.on_off=val;
+			},
+			selectFun(a){
+				switch(a){
+					case 'drop_time':
+						for(let i=1;i<31;i++){
+							this.drop_time_List.push({
+								value:i,
+								label:i
+							})
+						}
+						this.drop_time_show=true;
+				}
+			},
+			sliderChange(e,a){
+				switch(a){
+					case 'cul_time':
+					  this.setFrom.cul_time=e.detail.value;
+					  break;
+					case 'set_temp':
+					   this.setFrom.set_temp=e.detail.value;
+					   break;
+					case 'datt':
+					  this.setFrom.datt=e.detail.value;
+					  break;
+				}
+			},
+			selectTime(a){
+				this.timeType=a
+				let arr=[]
+				if(a=='st1'){
+					for(let i=1;i<25;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					this.timeList=arr
+				}else if(a=='et1'){
+					for(let i=this.coll_time.value01+1;i<25;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					this.timeList=arr
+				}else if(a=='st2'){
+					for(let i=this.coll_time.value02+1;i<25;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					this.timeList=arr
+				}else if(a=='et2'){
+					for(let i=this.coll_time.value03+1;i<25;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					this.timeList=arr
+				}else if(a=='st3'){
+					for(let i=this.coll_time.value04+1;i<25;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					this.timeList=arr
+				}else if(a=='et3'){
+					for(let i=this.coll_time.value05+1;i<25;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					this.timeList=arr
+				}
+				this.collShow=true
+			},
+			collConfirm(e,a){
+				if(a=='st1'){
+					this.coll_time.time01=e[0].label
+					this.coll_time.value01=e[0].value
+				}else if(a=='et1'){
+					this.coll_time.time02=e[0].label
+					this.coll_time.value02=e[0].value
+				}else if(a=='st2'){
+					this.coll_time.time03=e[0].label
+					this.coll_time.value03=e[0].value
+				}else if(a=='et2'){
+					this.coll_time.time04=e[0].label
+					this.coll_time.value04=e[0].value
+				}else if(a=='st3'){
+					this.coll_time.time05=e[0].label
+					this.coll_time.value05=e[0].value
+				}else if(a=='et3'){
+					this.coll_time.time06=e[0].label
+					this.coll_time.value06=e[0].value
+				}
+			},
+			async submit(){
+				let arr=[]
+				if(this.coll_time.value01&&this.coll_time.value02){
+					arr.push(`${this.coll_time.value01}-${this.coll_time.value02}`)
+				}
+				if(this.coll_time.value03&&this.coll_time.value04){
+					arr.push(`${this.coll_time.value03}-${this.coll_time.value04}`)
+				}
+				if(this.coll_time.value05&&this.coll_time.value06){
+					arr.push(`${this.coll_time.value05}-${this.coll_time.value06}`)
+				}
+				this.setFrom.coll_time=arr
+				console.log(this.setFrom)
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.device_control',
+					data:{
+						device_type_id: 7,
+						d_id: this.d_id,
+						config: JSON.stringify(this.setFrom),
+					}
+				})
+				if(res){
+					this.$refs.toast.show({
+						title: '修改成功!',
+						type: 'success',
+						callback:function(){
+							uni.navigateBack({
+								delta: 1
+							});	
+						}
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		padding:20rpx;
+		box-sizing: border-box;
+	.tit{
+		line-height:30rpx;
+		font-size:30rpx;
+		padding-left:20rpx;
+		border-left-width:2px;
+		border-left-style: solid;
+		border-left-color:$uni-color-success;
+		margin:30rpx 0;
+		}
+	.adminTit{border-left-color:#e64340;}
+	.btns{
+		display:flex;
+		justify-content: flex-start;
+		flex-wrap:no-wrap;
+		button{margin:0;margin-right:10rpx;padding:0 25rpx;}
+	}
+	.uni-list-cell{
+		background:#F7F8FA;
+		padding:10rpx 40rpx;
+		font-size:28rpx;
+		box-sizing: border-box;
+		.arrow{
+			display:inline-block;
+			border-width:12rpx 8rpx ;
+			border-style: solid;
+			float:right;
+			margin-top:10rpx;
+			border-color:#888 transparent transparent transparent;
+		}
+	}
+	.selectTime{
+		display:flex;
+		margin-bottom:20rpx;
+		.time{
+			width:350rpx;
+			display:flex;
+			justify-content: space-between;
+		}
+		.line{width:50rpx;text-align: center;}
+	}
+	.submit-box{
+		margin-top:60rpx
+	}
+	}
+</style>

+ 142 - 0
pages/cb/cbd/equip-set/addimg.vue

@@ -0,0 +1,142 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="手动添加"></uni-nav-bar>
+			</view>
+			<view class="imgform">
+				<u-form :model="form" ref="uForm">
+					<u-form-item label="害虫名称" :required="requireds" label-width="150rpx" prop="pest_name" class="form_item">
+						<u-input v-model="form.pest_name" />
+					</u-form-item>
+					<u-form-item label="害虫数量" :required="requireds" label-width="150rpx" prop="pest_num" class="form_item">
+						<u-input v-model="form.pest_num" type="number" />
+					</u-form-item>
+					<u-form-item label="作物种类" label-width="150rpx" class="form_item">
+						<u-input v-model="form.crop_name" />
+					</u-form-item>
+					<u-form-item label="虫害阶段" label-width="150rpx" class="form_item">
+						<u-input v-model="form.pest_case" />
+					</u-form-item>
+				</u-form>
+				<view class="imgform_btn">
+					<button @click="ensure">确定</button>
+					<button @click="cancel">取消</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				requireds: true,
+				form: {
+					pest_name: '',
+					pest_num: "",
+					crop_name: '',
+					pest_case: ""
+				},
+				rules: {
+					pest_name: [{
+						required: true,
+						message: '请输入害虫名称',
+						trigger: ['blur', 'change'],
+					}],
+					pest_num: [{
+						required: true,
+						message: '请输入害虫数量',
+						trigger: ['blur', 'change'],
+					}],
+				},
+				id: '',
+				device_id: ""
+
+			}
+		},
+		methods: {
+			//describe: "{"pest_num":"1","crop_name":"水稻","pest_case":"1","pest_name":"七星瓢虫"}"
+			// device_id: "819"
+			// img_id: "2396"
+			async species(id) { //统计
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.forecast_system.equip_photo_species',
+					data: {
+						ret: "add_pest",
+						pest: this.form.name,
+						img_id: this.id,
+						device_id: this.device_id,
+						describe: JSON.stringify(this.form)
+					}
+				})
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			cancel() { //取消
+				this.clickLeft()
+			},
+			ensure() {
+				if (this.form.pest_name.length == 0) {
+					uni.showToast({
+						title: '请输入害虫名称',
+						duration: 1000,
+						image: ""
+					});
+				} else if (this.form.pest_num.length == 0) {
+					uni.showToast({
+						title: '请输入害虫数量',
+						duration: 1000,
+						image: ""
+					});
+				} else {
+					this.species()
+					this.clickLeft()
+				}
+			}
+		},
+		onReady() {
+			this.$refs.uForm.setRules(this.rules);
+		},
+		onLoad(option) {
+			// this.species(this.id)
+			this.id = option.id
+			this.device_id = option.device_id
+		}
+	}
+</script>
+
+<style lang="scss">
+	.imgform {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+		.form_item{
+			width: 90%;
+			margin: 0 auto;
+			border-bottom: 2rpx solid #dedede;
+		}
+		.imgform_btn {
+			margin-top: 40rpx;
+			display: flex;
+
+			button {
+				width: 300rpx;
+				font-size: 28rpx;
+				height: 60rpx;
+				line-height: 60rpx;
+			}
+
+			button:first-child {
+				color: #FFFFFF;
+				background-color: #14A478;
+			}
+		}
+	}
+</style>

+ 588 - 0
pages/cb/cbd/equip-set/equip-set.vue

@@ -0,0 +1,588 @@
+<template>
+	<view>
+		<view class="" v-if="myuser_type">
+			<view class="tit adminTit">
+				联网模块
+			</view>
+			<view class="btns">
+				<button type="warn" @click="equipBtnControl('dtu_update')" size="mini">升级</button>
+				<button type="warn" @click="equipBtnControl('dtu_reboot')" size="mini">重启</button>
+				<button type="warn" @click="mqttInfo" size="mini">MQTT配置</button>
+			</view>
+			<view class="tit adminTit">
+				板子设置
+			</view>
+			<view class="btns">
+				<button type="warn" size="mini">查看原始IMEI</button>
+				<button type="warn" size="mini">更改IMEI</button>
+			</view>
+			<view class="tit adminTit">
+				强制操作
+			</view>
+			<view class="btns">
+				<button type="warn" @click="equipBtnControl('takephoto')" size="mini">拍照</button>
+				<button type="warn" @click="equipBtnControl('update')" size="mini">升级</button>
+				<button type="warn" @click="equipBtnControl('reboot')" size="mini">重启</button>
+				<button type="warn" @click="equipBtnControl('close_shake')" size="mini">震动关闭</button>
+				<button type="warn" @click="equipBtnControl('open_shake')" size="mini">震动开启</button>
+			</view>
+		</view>
+		<view class="tit">
+			设备开关
+		</view>
+		<view class="uni-list-cell">
+			<picker @change="turnChange($event,'ds')" value="equipContrlForm.ds" :range="dsArr">
+				<text class="uni-input">{{dsArr[equipContrlForm.ds]}}</text>
+				<view class="arrow"></view>
+			</picker>
+		</view>
+		<!-- 	<view class="tit">
+			工作状态
+		</view>
+		<view class="uni-list-cell">
+			 <picker @change="turnChange($event,'ws')" :value="equipContrlForm.ws" :range="wsArr">
+				<text class="uni-input">{{wsArr[equipContrlForm.ws]}}</text>
+				<view class="arrow"></view>
+			</picker>
+			<u-modal v-model="wsModelShow" content="确定修改工作模式?"  show-cancel-button @confirm="wsConfirm" @cancel="wsCancel" ref="uModal" ></u-modal>
+		    <u-toast ref="wsToast" />
+		</view> -->
+		<view class="tit">
+			定时模式
+		</view>
+		<view class="uni-list-cell">
+			<picker @change="turnChange($event,'ts')" :value="equipContrlForm.ts" :range="tsArr">
+				<text class="uni-input">{{tsArr[equipContrlForm.ts]}}</text>
+				<view class="arrow"></view>
+			</picker>
+		</view>
+		<template v-if="equipContrlForm.ts==0">
+			<view class="tit">
+				定时时长(h)
+			</view>
+			<view class="">
+				<slider :value="equipContrlForm.tt" show-value="true" :min="1" :max="10" @change="sliderChange($event,'tt')"
+				 block-color="#57C878" activeColor="#57C878" step="1" />
+			</view>
+		</template>
+		<template v-if="equipContrlForm.ts==1">
+			<view class="tit">
+				开始结束时间
+			</view>
+			<view class="selectTime">
+				<view class="uni-list-cell time" @click="selectTime('st')">
+					<text>{{stLabel}}</text>
+					<u-icon name="clock"></u-icon>
+				</view>
+				<text class="line">-</text>
+				<view class="uni-list-cell time" @click="selectTime('et')">
+					<text>{{etLabel}}</text>
+					<u-icon name="clock"></u-icon>
+				</view>
+			</view>
+			<u-select v-model="stShow" mode="single-column" :list="list" @confirm="stConfirm"></u-select>
+			<u-select v-model="etShow" mode="single-column" :list="list" @confirm="etConfirm"></u-select>
+		</template>
+		<view class="tit">
+			落虫时间(min)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm.collt" show-value="true" :min="1" :max="20" @change="sliderChange($event,'collt')"
+			 block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			加热时间(min)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm.htim" show-value="true" :min="1" :max="20" @change="sliderChange($event,'htim')"
+			 block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			加热温度(℃)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm.hst" show-value="true" :min="75" :max="120" @change="sliderChange($event,'hst')"
+			 block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			高温保护阈值(℃)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm.tph" show-value="true" :min="50" :max="70" @change="sliderChange($event,'tph')"
+			 block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			低温保护阈值(℃)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm.tpl" show-value="true" :min="1" :max="10" @change="sliderChange($event,'tpl')"
+			 block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="tit">
+			数据上传间隔(min)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm.datt" show-value="true" :min="10" :max="60" @change="sliderChange($event,'datt')"
+			 block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="submit-box">
+			<u-button @click="submit" type="success">确定</u-button>
+		</view>
+		<u-toast ref="toast" />
+		<u-popup v-model="mqttShow">
+			<view class="mqtt-popup">
+				<u-field required v-model="mqttConfig.muid" label="MQTT用户名" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.mpwd" label="MQTT密码" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.mpi" label="MQTT地址" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.mport" label="MQTT端口" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.mpub" label="上传地址" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.msub" label="下发地址" label-width="180">
+				</u-field>
+				<u-field v-model="mqttConfig.fuid" label="FTP用户名" label-width="180">
+				</u-field>
+				<u-field v-model="mqttConfig.fpwd" label="FTP密码" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.fip" label="图片上传地址" label-width="180">
+				</u-field>
+				<u-field required v-model="mqttConfig.fport" label="图片上传接口" label-width="180">
+				</u-field>
+			</view>
+			<view class="mqtt-btn-box">
+				<u-button @click="" size="medium" type="success">确定</u-button>
+			</view>
+		</u-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				d_id: '',
+				dsArr: ['关机', '开机'],
+				dsIndex: 0,
+				wsArr: ['待机', '工作'],
+				wsIndex: 0,
+				tsArr: ['光控', '时控'],
+				tsIndex: 0,
+				imgresArr: ['高', '中', '低'],
+				imgresIndex: "",
+				wsModelShow: false,
+				equipContrlForm: {
+					ds: 0, //设备开关
+					ts: 0, //定时模式
+					tt: 1, //定时时长
+					ws: 0, //工作状态
+					collt: 1,
+					htim: 1,
+					hst: 75,
+					tph: 50,
+					tpl: 1,
+					datt: 10,
+					st: null,
+					et: null,
+				},
+				stShow: false,
+				etShow: false,
+				stLabel: '00:00',
+				etLabel: '00:00',
+				list: [{
+						value: 0,
+						label: '00:00'
+					},
+					{
+						value: 1,
+						label: '01:00'
+					},
+					{
+						value: 2,
+						label: '02:00'
+					},
+					{
+						value: 3,
+						label: '03:00'
+					},
+					{
+						value: 4,
+						label: '04:00'
+					},
+					{
+						value: 5,
+						label: '05:00'
+					},
+					{
+						value: 6,
+						label: '06:00'
+					},
+					{
+						value: 7,
+						label: '04:00'
+					}, {
+						value: 8,
+						label: '08:00'
+					},
+					{
+						value: 9,
+						label: '09:00'
+					},
+					{
+						value: 10,
+						label: '10:00'
+					},
+					{
+						value: 11,
+						label: '11:00'
+					},
+					{
+						value: 12,
+						label: '12:00'
+					},
+					{
+						value: 13,
+						label: '13:00'
+					},
+					{
+						value: 14,
+						label: '14:00'
+					}, {
+						value: 15,
+						label: '15:00'
+					},
+					{
+						value: 16,
+						label: '16:00'
+					},
+					{
+						value: 17,
+						label: '17:00'
+					},
+					{
+						value: 18,
+						label: '18:00'
+					},
+					{
+						value: 19,
+						label: '19:00'
+					},
+					{
+						value: 20,
+						label: '20:00'
+					},
+					{
+						value: 21,
+						label: '21:00'
+					}, {
+						value: 22,
+						label: '22:00'
+					},
+					{
+						value: 23,
+						label: '23:00'
+					},
+				],
+				mqttShow: false,
+				mqttConfig: {
+					muid: '',
+					mpwd: '',
+					mip: '',
+					mport: '',
+					mpub: '',
+					msub: '',
+					fuid: '',
+					fpwd: '',
+					fip: '',
+					fport: ''
+				},
+				myuser_type: false
+			}
+		},
+		onLoad(option) {
+			this.d_id = option.d_id
+			this.getInfo()
+			uni.getStorage({
+				key: "myuser_type",
+				success: (res) => {
+					if (Number(res.data) == 1) {
+						this.myuser_type = true
+					}
+				}
+			})
+		},
+		methods: {
+			turnChange(e, a) {
+				if (a == 'ds') {
+					// this.dsIndex = e.target.value
+					this.equipContrlForm.ds = e.target.value
+				} else if (a == 'ws') {
+					// this.wsIndex = e.target.value
+					this.wsModelShow = true
+					this.equipContrlForm.ws = e.target.value
+
+				} else if (a == 'ts') {
+					// this.tsIndex = e.target.value
+					this.equipContrlForm.ts = e.target.value
+				}
+			},
+			stConfirm(e) {
+				this.stLabel = e[0].label
+				this.equipContrlForm.st = e[0].value
+			},
+			etConfirm(e) {
+				this.etLabel = e[0].label
+				this.equipContrlForm.et = e[0].value
+			},
+			async wsConfirm() {
+				console.log(222)
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control',
+					data: {
+						device_type_id: 3,
+						d_id: this.d_id,
+						work_type: this.equipContrlForm.ws,
+					}
+				})
+				if (res) {
+					this.$refs.wsToast.show({
+						title: '修改成功',
+						type: 'success',
+					})
+				}
+			},
+			wsCancel() {
+				this.$refs.wsToast.show({
+					title: '取消修改',
+					type: 'default',
+				})
+			},
+			selectTime(a) {
+				if (a == 'st') {
+					this.stShow = true;
+				} else {
+					this.etShow = true;
+				}
+			},
+			sliderChange(e, a) {
+				let val = e.detail.value
+				switch (a) {
+					case 'tt':
+						this.equipContrlForm.tt = val;
+						break;
+					case 'collt':
+						this.equipContrlForm.collt = val;
+						break;
+					case 'htim':
+						this.equipContrlForm.htim = val;
+						break;
+					case 'hst':
+						this.equipContrlForm.hst = val;
+						break;
+					case 'tph':
+						this.equipContrlForm.tph = val;
+						break;
+					case 'tpl':
+						this.equipContrlForm.tpl = val;
+						break;
+					case 'datt':
+						this.equipContrlForm.datt = val;
+						break;
+				}
+			},
+			async getInfo() {
+				let res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control_info',
+					data: {
+						d_id: this.d_id,
+						cmd: 'paramconf'
+					}
+				})
+				this.stLabel =
+					res.st && res.st < 10 ? '0' + res.st + ':00' : res.st + ':00'
+				this.etLabel =
+					res.et && res.et < 10 ? '0' + res.et + ':00' : res.et + ':00'
+				this.equipContrlForm = res
+				console.log(this.equipContrlForm)
+			},
+			async submit() {
+				console.log(this.equipContrlForm)
+				this.equipContrlForm.st = String(this.equipContrlForm.st)
+				this.equipContrlForm.et = String(this.equipContrlForm.et)
+				let res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control',
+					data: {
+						device_type_id: 3,
+						d_id: this.d_id,
+						config: JSON.stringify(this.equipContrlForm)
+					}
+				})
+				if (res) {
+					this.$refs.toast.show({
+						title: '修改成功!',
+						type: 'success',
+						callback: function() {
+							uni.navigateBack({
+								delta: 1
+							});
+						}
+					})
+
+				}
+			},
+			async equipBtnControl(cmd) {
+				let res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.admin_device_control',
+					data: {
+						cmd,
+						device_type_id: 3,
+						d_id: this.d_id
+					}
+				})
+				if (res) {
+					this.$refs.toast.show({
+						title: '指令下发成功!',
+						type: 'success',
+					})
+				}
+			},
+			async mqttInfo() {
+				let res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control_info',
+					data: {
+						cmd: 'netconf',
+						d_id: this.d_id
+					}
+				})
+				if (res) {
+					let {
+						ftp,
+						mqtt
+					} = res
+					this.mqttConfig = {
+						muid: mqtt.uid,
+						mpwd: mqtt.pwd,
+						mip: mqtt.ip,
+						mport: mqtt.port,
+						mpub: mqtt.pub,
+						msub: mqtt.sub,
+						fuid: ftp.uid,
+						fpwd: ftp.pwd,
+						fip: ftp.ip,
+						fport: ftp.port
+					}
+				}
+				this.mqttShow = true
+			},
+			async mqttSubm() {
+				let obj = {
+					mqtt: {
+						uid: this.mqttConfig.muid,
+						pwd: this.mqttConfig.mpwd,
+						ip: this.mqttConfig.mip,
+						port: this.mqttConfig.mport,
+						pub: this.mqttConfig.mpub,
+						sub: this.mqttConfig.msub,
+						keepalive: 60,
+						lastwill: '/yfkj/cbd/offline/'
+					},
+					ftp: {
+						uid: this.mqttConfig.fuid,
+						pwd: this.mqttConfig.fpwd,
+						ip: this.mqttConfig.fip,
+						port: this.mqttConfig.fport
+					}
+				}
+				let res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control',
+					data: {
+						device_type_id: 3,
+						d_id: this.d_id,
+						cmd: 'setnet',
+						config: JSON.stringify(obj)
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		padding: 20rpx;
+		box-sizing: border-box;
+
+		.tit {
+			line-height: 30rpx;
+			font-size: 30rpx;
+			padding-left: 20rpx;
+			border-left-width: 2px;
+			border-left-style: solid;
+			border-left-color: $uni-color-success;
+			margin: 30rpx 0;
+		}
+
+		.adminTit {
+			border-left-color: #e64340;
+		}
+
+		.btns {
+			display: flex;
+			justify-content: flex-start;
+			flex-wrap: no-wrap;
+
+			button {
+				margin: 0;
+				margin-right: 10rpx;
+				padding: 0 25rpx;
+			}
+		}
+
+		.uni-list-cell {
+			background: #F7F8FA;
+			padding: 10rpx 40rpx;
+			font-size: 28rpx;
+			box-sizing: border-box;
+
+			.arrow {
+				display: inline-block;
+				border-width: 12rpx 8rpx;
+				border-style: solid;
+				float: right;
+				margin-top: 10rpx;
+				border-color: #888 transparent transparent transparent;
+			}
+		}
+
+		.selectTime {
+			display: flex;
+
+			.time {
+				width: 350rpx;
+				display: flex;
+				justify-content: space-between;
+			}
+
+			.line {
+				width: 50rpx;
+				text-align: center;
+			}
+		}
+
+		.submit-box {
+			margin-top: 60rpx
+		}
+
+		.mqtt-popup {
+			width: 580rpx;
+
+		}
+
+		.mqtt-btn-box {
+			margin-top: 50rpx;
+			text-align: center;
+		}
+	}
+</style>

+ 435 - 0
pages/cb/cbd/equip-set/historyfile.vue

@@ -0,0 +1,435 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="历史数据"></uni-nav-bar>
+			</view>
+			<view class="shuju_one">
+				<view class="shuju_one_title">
+					<view :class="titleidnex==index?'title_text_color':'tltle_text'" v-for="(item,index) in titletext" :key="index"
+					 @click="changeindex(index)">
+						{{item}}
+					</view>
+				</view>
+				<view class="canvastishi" v-if="!canvastishiTF">
+					暂无数据
+				</view>
+				<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
+				 @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+			</view>
+			<view class="refresh" @click="refresh">
+				刷 新
+			</view>
+			<view class="condition">
+				<scroll-view scroll-top="0" scroll-x="true" class="scroll-X">
+					<table class="table">
+						<tr class="tr">
+							<th class="th" v-for="(item,index) in thdata" :key="'a'+index">{{item}}</th>
+						</tr>
+						<tr class="tr" v-for="(items,indexs) in historylistdata" :key="'b'+indexs" v-if="!forbidden">
+							<td class="td">{{items.d_h_t.addtime|timeFormat()}}</td>
+							<td class="td">{{items.d_h_t.at==""?"--":items.d_h_t.at}}</td>
+							<td class="td">{{items.d_h_t.ah==""?"--":items.d_h_t.ah}}</td>
+							<td class="td">{{items.d_h_t.hrt}}</td>
+							<td class="td">{{items.d_h_t.rps==0?"正常":"雨控"}}</td>
+							<td class="td">{{items.d_h_t.tps==0?"正常":"温控"}}</td>
+							<td class="td">{{items.d_h_t.lps==0?"正常":"光控"}}</td>
+							<td class="td">{{items.d_h_t.dg}}</td>
+							<td class="td">{{items.d_h_t.csq}}</td>
+							<td class="td">{{items.d_h_t.current}}</td>
+							<td class="td">{{items.d_h_t.vbat}}</td>
+							<td class="td">{{items.d_h_t.lng}}</td>
+							<td class="td">{{items.d_h_t.lat}}</td>
+						</tr>
+						<tr class="tr" v-if="forbidden">
+							<td class="td" v-for="item in 13">暂无数据</td>
+						</tr>
+					</table>
+				</scroll-view>
+				<view class="pagenumber">
+					<button @click="prev">上一页</button>
+					<view class="pagenumber_page">
+						第 {{page}} 页
+					</view>
+					<view class="pagenumber_page">
+						共 {{pagesum}} 页
+					</view>
+					<button @click="next" :disabled="forbidden">下一页</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uCharts from '../../../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvaColumnA = null;
+	export default {
+		data() {
+			return {
+				styles: {
+					// width: "650rpx",
+					height: "400rpx"
+				},
+				d_id: '',
+				start_time: "",
+				end_time: "",
+				historydatas: [],
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				titleidnex: 0,
+				device_id: '',
+				page: 1,
+				historylistdata: [],
+				thdata: ["上报时间", "环境温度(°C)", "环境湿度(%)", "加热仓温度(°C)", "雨控状态", "温控状态", "光控状态", "灯管状态", "信号强度", "电流(mA)", "电压(V)",
+					"经度", "纬度"
+				],
+				forbidden: false,
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+				canvastishiTF: false,
+				pagesum: null
+			}
+		},
+		methods: {
+			async history() { //历史数据列表折线图
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_polyline_data',
+					data: {
+						device_type_id: 3,
+						d_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000)
+					}
+				})
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (this.historydatas.length == 0) {
+					this.canvastishiTF = false
+				} else {
+					this.canvastishiTF = true
+
+					var arr1 = []
+					var arr2 = []
+					var arr3 = []
+					var xtitle = []
+					for (var i = 0; i < res.length; i++) {
+						var times = new Date(res[i].addtime * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getMinutes())
+						arr1.unshift(res[i].temperature == "" ? "0" : res[i].temperature)
+						arr2.unshift(res[i].humidity == "" ? "0" : res[i].humidity)
+						arr3.unshift(res[i].others == "" ? "0" : res[i].others)
+					}
+					// console.log(arr1)
+					var obj = [{
+						name: '温度',
+						data: arr1,
+						color: '#00E29D'
+					}, {
+						name: '湿度',
+						data: arr2,
+						color: '#6CBBFF'
+					}, {
+						name: '加热仓温度',
+						data: arr3,
+						color: '#FF3F3F'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+				}
+			},
+			//forecast.worm_lamp.device_history_data历史数据列表
+			async historylist() { //历史数据列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+					data: {
+						device_type_id: 3,
+						device_id: this.device_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+						page: this.page
+					}
+				})
+				this.historylistdata = res.data
+				this.pagesum = Math.ceil(res.counts / 10) + 1
+				if (res.data.length == 0) {
+					this.forbidden = true
+					console.log(res.data.length)
+				} else {
+					this.forbidden = false
+					console.log(res.data.length)
+				}
+				for (var i = 0; i < this.historylistdata.length; i++) {
+					if (Number(this.historylistdata[i].d_h_t.ws) == 0) {
+						this.historylistdata[i].d_h_t.dg = "待机"
+					} else if (Number(this.historylistdata[i].d_h_t.ws) == 1) {
+						if (Number(this.historylistdata[i].d_h_t.lamp) == 0) {
+							this.historylistdata[i].d_h_t.dg = "工作"
+						} else if (Number(this.historylistdata[i].d_h_t.lamp) == 1) {
+							this.historylistdata[i].d_h_t.dg = "异常"
+						}
+					}
+				}
+				console.log(this.historylistdata)
+			},
+			// forecast.send_control.get_device_config 获取当前时间的数据
+			async newdata() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.get_device_config',
+					data: {
+						device_type_id: 3,
+						d_id: this.d_id,
+						control_type: "data"
+					}
+				})
+				if(res){
+					uni.showToast({
+						title: '刷新成功',
+						duration: 2000,
+						icon: "none"
+					});
+					uni.navigateBack({
+						delta: 1
+					})
+				}else{
+					uni.showToast({
+						title: '刷新失败',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			refresh() { //获取当前时间的数据
+				this.newdata()
+			},
+			changeindex(index) {
+				this.titleidnex = index
+				var now = new Date()
+				this.$forceUpdate()
+				if (index == 0) {
+					this.start_time = this.end_time - 24 * 60 * 60 * 1000
+					this.history()
+					this.historylist()
+				} else if (index == 1) {
+					var oldtime = now.setMonth(now.getMonth() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 2) {
+					var oldtime = now.setMonth(now.getMonth() - 6)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 3) {
+					var oldtime = now.setFullYear(now.getFullYear() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				}
+			},
+			prev() { //上一页
+				if (this.page > 1) {
+					this.page--
+					this.historylist()
+				}
+			},
+			next() { //下一页
+				this.page++
+				this.historylist()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showColumn(id, xtitle, xinfo) {
+				var _self = this
+				canvaColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position: "top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle,
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				console.log(e)
+				canvaColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvaColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvaColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+		},
+		onLoad(option) {
+			this.d_id = option.d_id
+			this.device_id = option.device_id
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+		},
+		onShow(){
+			this.end_time = +new  Date() + 1000
+			this.start_time = this.end_time - 24 * 60 * 60 * 1000
+			setTimeout(()=>{
+				this.history()
+				this.historylist()
+			},1000)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.shuju_one,
+	.shuju_two {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		height: 550rpx;
+
+		.canvastishi {
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+
+		.shuju_one_title {
+			width: 70%;
+			margin: 0 auto;
+			display: flex;
+
+			.tltle_text {
+				width: 25%;
+				border: 2rpx solid #B2B2B2;
+				color: #B2B2B2;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+
+			.title_text_color {
+				width: 25%;
+				border: 2rpx solid #28AE4F;
+				color: #28AE4F;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+		}
+	}
+
+	.refresh {
+		position: absolute;
+		top: 700rpx;
+		left: 5%;
+		width: 160rpx;
+		height: 50rpx;
+		background-color: #28AE4F;
+		color: #FFFFFF;
+		line-height: 50rpx;
+		text-align: center;
+	}
+
+	.condition {
+		position: absolute;
+		top: 770rpx;
+		display: flex;
+		flex-wrap: wrap;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-bottom: 30rpx;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+			.table{
+				width: 1672px;
+			}
+			.tr {
+				display: flex;
+				overflow: hidden;
+
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 240rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+
+				.th:first-child,
+				.td:first-child {
+					width: 300rpx;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+			}
+
+			.pagenumber_page {
+				width: 100rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 337 - 0
pages/cb/cbd/equip-set/imgpage.vue

@@ -0,0 +1,337 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="查看图片" rightIcon="camera" @clickRight="clickRight"></uni-nav-bar>
+			</view>
+			<p class="tishi" v-if="tishi">暂无数据</p>
+			<view class="timeshow">
+				<view class="timeshow_tate" @click="selecttimestate">
+					{{timestate|timeFormat()}}
+				</view>
+				<view class="timeshow_end" @click="selecttimeend">
+					{{timeend|timeFormat()}}
+				</view>
+				<u-icon name="search" size="36" @click="search"></u-icon>
+				<u-picker mode="time" v-model="timeshow" :params="params" @confirm="confirm"></u-picker>
+			</view>
+			<view class="imglist">
+				<view class="imglist_box" v-for="(item,index) in imglists" :key="index">
+					<view class="imglist_left">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/cb/jiazai.ui.gif'" mode=""></image>
+						<image :src="item.addr" mode="" @click="examine(index)"></image>
+					</view>
+					<view class="imglist_right">
+						<view class="icon_box" @click="delimg(item.id)">
+							<p class="iconfont icon-shanchu">删除</p>
+						</view>
+						<view class="icon_box" @click="shibie(item.id)">
+							<p class="iconfont icon-shibie">识别</p>
+						</view>
+						<view class="icon_box" @click="tongji(item.id)">
+							<p class="iconfont icon-tongji2">手动统计</p>
+						</view>
+						<view class="icon_box" @click="add(item.id)">
+							<p class="iconfont icon-iconzhengli_shouxieqianpi">手动添加</p>
+						</view>
+						<p style="color: #06B535;">{{item.addtime|timeFormat()}}</p>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				page: 1,
+				imglists: [],
+				tishi: true,
+				d_id: '',
+				timeend: null, //当前时间 也是搜索的结束时间
+				timestate: null,
+				timeshow: false,
+				params: {
+					year: true,
+					month: true,
+					day: true,
+					hour: true,
+					minute: true,
+					second: false
+				},
+				flag:1,
+				self:true,
+				isTop:false
+			}
+		},
+		methods: {
+			//forecast.forecast_system.equip_photofo
+			async imglistdata(time_begin,time_end) { //获取图片列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.forecast_system.equip_photo',
+					data: {
+						device_id: this.device_id,
+						page: this.page,
+						ret: "list",
+						time_begin:time_begin,//开始时间
+						time_end:time_end,//结束时间
+					}
+				})
+				this.imglists = this.imglists.concat(res.data)
+				console.log(this.imglists)
+				if (this.imglists.length == 0) {
+					this.tishi = true
+				} else {
+					this.tishi = false
+				}
+			},
+			//forecast.forecast_system.equip_photo_del
+			async del(id) { //删除图片
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.forecast_system.equip_photo_del',
+					data: {
+						device_id: this.device_id,
+						addrlist: id
+					}
+				})
+			},
+			//forecast.forecast_system.equip_photo_discern识别
+			async discern(id) { //识别图片
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.forecast_system.equip_photo_discern',
+					data: {
+						img_id: id,
+						ret: "see"
+					}
+				})
+			},
+			//forecast.forecast_system.equip_photo_species  pest_list
+			//forecast.forecast_system.equip_photo_species统计
+			async species(id) { //统计
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.forecast_system.equip_photo_species',
+					data: {
+						ret: "photo_desc",
+						img_id: id
+					}
+				})
+			},
+			//forecast.send_control.admin_device_control 拍照 
+			async takephoto() { //统计
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.admin_device_control',
+					data: {
+						device_type_id: 3,
+						d_id: this.d_id,
+						cmd: "takephoto"
+					}
+				})
+				console.log(res)
+				if (res == true) {
+					uni.showToast({
+						title: '指令下发成功!',
+						duration: 2000
+					});
+				}
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			delimg(id) { //删除图片
+				uni.showModal({
+					title: '提示',
+					content: '是否删除此图片?',
+					success: function(res) {
+						if (res.confirm) {
+							// this.del(id)
+							console.log('用户点击确定');
+						} else if (res.cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				});
+			},
+			shibie(id) { //识别
+				this.discern(id)
+			},
+			tongji(id) { //统计
+				this.species(id)
+			},
+			add(id) {
+				uni.navigateTo({
+					url: "./addimg?id=" + id + "&device_id" + this.device_id
+				})
+			},
+			examine(index) {
+				var imgarr = []
+				for(var i=0;i<this.imglists.length;i++){
+					imgarr.push(this.imglists[i].addr)
+				}
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr,
+					current:index
+				});
+			},
+			clickRight() { //下发拍照指令
+				this.takephoto()
+			},
+			confirm(val){//时间选择框确定按钮
+				
+				var time = val.year+"-"+val.month+"-"+val.day+" "+val.hour+":"+val.minute+":00"
+				if(this.flag==1){
+					this.timestate = +new Date(time)/1000
+				}else if(this.flag==2){
+					this.timeend = +new Date(time)/1000
+				}
+			},
+			selecttimestate(){//开始时间选择
+				this.timeshow = !this.timeshow
+				this.flag = 1
+			},
+			selecttimeend(){//结束时间选择
+				this.timeshow = !this.timeshow
+				this.flag = 2
+			},
+			search(){//按时间搜索
+				this.imglists=[]
+				this.page = 1
+				this.imglistdata(parseInt(this.timestate),parseInt(this.timeend))
+				this.self = false
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad(option) {
+			console.log(option)
+			this.device_id = option.device_id
+			this.d_id = option.d_id
+		},
+		onShow(){
+			setTimeout(()=>{
+				this.imglistdata('','')
+			},1000)
+			this.timeend = +new Date() / 1000
+			this.timestate = this.timeend - 60 * 60 * 24
+		},
+		onReachBottom() {
+			this.page++
+			if(this.self){
+				this.imglistdata('','')
+			}else{
+				this.imglistdata(parseInt(this.timestate),parseInt(this.timeend))
+			}
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.tishi {
+		position: absolute;
+		top: 104px;
+		width: 95%;
+		left: 2.5%;
+		text-align: center;
+		font-size: 40rpx;
+	}
+
+	.timeshow {
+		width: 96%;
+		height: 50rpx;
+		background-color: #FFFFFF;
+		position: fixed;
+		top: 104px;
+		left: 2.5%;
+		display: flex;
+		z-index: 100;
+		padding-top: 10px;
+
+		.timeshow_tate,
+		.timeshow_end {
+			height: 50rpx;
+			width: 45%;
+			line-height: 50rpx;
+			text-align: center;
+			margin-right: 10rpx;
+			background-color: #56C877;
+			color: #FFFFFF;
+		}
+	}
+	.imglist {
+		position: absolute;
+		top: 84px;
+		width: 95%;
+		left: 2.5%;
+		.imglist_box {
+			display: flex;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx;
+			margin-bottom: 20rpx;
+		}
+		.imglist_left {
+			width: 50%;
+			position: relative;
+
+			image {
+				position: absolute;
+				top: 0;
+				left: 0;
+				width: 100%;
+				height: 280rpx;
+			}
+		}
+
+		.imglist_right {
+			margin-left: 40rpx;
+			padding: 10rpx 0;
+
+			.icon_box {
+				margin-bottom: 12rpx;
+				font-size: 24rpx;
+
+				.iconfont {
+					margin-right: 20rpx;
+					color: #56C877;
+					font-size: 32rpx;
+				}
+			}
+
+			p:last-child {
+				margin-bottom: 0;
+			}
+
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 396 - 0
pages/cb/cbd/equip-set/note.vue

@@ -0,0 +1,396 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="短信预警"></uni-nav-bar>
+			</view>
+			<view class="earlywarning">
+				<view class="kind">
+					<view class="kind_top">
+						<p class="kind_top_title">目标种类预警</p>
+						<u-switch v-model="checked1" size="30" style="margin-top: 6rpx;" active-color="#58C876"></u-switch>
+					</view>
+					<view class="kind_bot">
+						<p class="kind_bot_title">害虫种类数量设置:</p>
+						<input type="number" v-model="form.pestCategoryNum" :disabled="!checked1" />
+					</view>
+					<p class="hint">(每天害虫种类数量达到此数量时,短信预警)</p>
+				</view>
+				<view class="kind">
+					<view class="kind_top">
+						<p class="kind_top_title">指定害虫数量预警</p>
+						<u-switch v-model="checked2" size="30" style="margin-top: 6rpx;" active-color="#58C876"></u-switch>
+					</view>
+					<view class="kind_box" v-for="item,index in kindnum" :key="index" v-if="appointPestNames[index]">
+						<view class="kind_bot">
+							<p class="kind_bot_title">害虫种类:</p>
+							<view class="input" @click="pickerchange(index)">
+								<input type="text" v-model="selector[Number(appointPestNames[index])]" :disabled="!checked2" />
+								<u-icon name="arrow-down" class="icon"></u-icon>
+							</view>
+						</view>
+						<view class="kind_bot">
+							<p class="kind_bot_title">害虫数量:</p>
+							<input type="number" v-model="appointPestNums[index]" :disabled="!checked2" />
+						</view>
+						<u-icon name="plus-circle" class="icons" size="40" color="#28AE4F" @click="addkindnum(index)" v-if="index==0"></u-icon>
+						<u-icon name="trash" class="icons" size="40" color="#ff0000" @click="jiankindnum(index)" v-else></u-icon>
+					</view>
+					<u-picker v-model="pickertf" mode="selector" @confirm="confirmFun2" :default-selector="[Number(appointPestNames[datasindex])]" :range="selector"></u-picker>
+					<p class="hint">(每天指定害虫数量达到此数量时,短信预警)</p>
+				</view>
+				<view class="kind">
+					<view class="kind_top">
+						<p class="kind_top_title">害虫数量总和预警</p>
+						<u-switch v-model="checked3" size="30" style="margin-top: 6rpx;" active-color="#58C876"></u-switch>
+					</view>
+					<view class="kind_bot">
+						<p class="kind_bot_title">害虫总和数量设置:</p>
+						<input type="number" v-model="form.pestTotalNum" :disabled="!checked3" />
+					</view>
+					<p class="hint">(每天害虫数量总和达到此数量时,短信预警)</p>
+				</view>
+				<view class="kind">
+					<view class="kind_top">
+						<p class="kind_top_title">综合预警</p>
+						<u-switch v-model="checked4" size="30" style="margin-top: 6rpx;" active-color="#58C876"></u-switch>
+					</view>
+					<view class="kind_bot">
+						<p class="kind_bot_title">每天检测害虫种类及数量,短信预警</p>
+					</view>
+				</view>
+				<view class="kind">
+					<view class="kind_top">
+						<p class="kind_top_title">信息接收</p>
+					</view>
+					<view class="kind_bot">
+						<p class="kind_bot_title">信息接受手机号:</p>
+						<input type="number" v-model="form.phone" @blur="phonereg" />
+					</view>
+					<p class="hint" v-if="phonetf">请输入正确的手机号</p>
+				</view>
+				<view class="tijiao" @click="btn">
+					确 定
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import cbddatas from "../../../../static/data/cbd_pest_library.js"
+	export default {
+		data() {
+			return {
+				checked1: false,
+				checked2: false,
+				checked3: false,
+				checked4: false,
+				pickertf: false,
+				device_id: '',
+				conf: "",
+				form: {},
+				phonetf: false,
+				selector: [],
+				kindnum:1,
+				kindtf:-1,
+				datasindex:null,
+				appointPestNames:[-1],//害虫名称
+				appointPestNums:[],//害虫数量
+			}
+		},
+		methods: {
+			async notealloc() { //查询短信配置
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.forecast_system.cbd_msg_conf',
+					data: {
+						device_id: this.device_id,
+						conf: this.conf
+					}
+				})
+				console.log(res)
+				this.form = JSON.parse(res)
+				console.log(this.form)
+				if(this.conf==""){
+					this.appointPestNames = this.form.appointPestName.split("#")
+					this.appointPestNums = this.form.appointPestNum.split("#")
+					if(this.appointPestNames.length==0){
+						this.kindnum = 1
+					}else{
+						this.kindnum = this.appointPestNames.length
+					}
+					if (this.form.pestCategory == "on") {
+						this.checked1 = true
+					} else {
+						this.checked1 = false
+					}
+					//pestTotal 总和开关
+					if (this.form.pestTotal == "on") {
+						this.checked3 = true
+					} else {
+						this.checked3 = false
+					}
+					//pestWarn综合预警
+					if (this.form.pestWarn == "on") {
+						this.checked4 = true
+					} else {
+						this.checked4 = false
+					}
+					//appointPest指定害虫
+					if (this.form.appointPest == "on") {
+						this.checked2 = true
+					} else {
+						this.checked2 = false
+					}
+				}else{
+					if(res){
+						uni.showToast({
+							title: '操作成功!',
+							duration: 2000,
+							icon:"none"
+						});
+					}
+				}
+				//种类
+			},
+			btn() {
+				if(this.checked1==true || this.checked2==true || this.checked3==true || this.checked4==true){
+					if (this.checked1 == true) {
+						this.form.pestCategory = "on"
+					} else {
+						this.form.pestCategory = "off"
+					}
+					//pestTotal 总和开关
+					if (this.checked3 == true) {
+						this.form.pestTotal = "on"
+					} else {
+						this.form.pestTotal = "off"
+					}
+					//pestWarn综合预警
+					if (this.checked4 == true) {
+						this.form.pestWarn = "on"
+					} else {
+						this.form.pestWarn = "off"
+					}
+					//appointPest指定害虫
+					if (this.checked2 == true) {
+						this.form.appointPest = "on"
+					} else {
+						this.form.appointPest = "off"
+					}
+					var obj = {}
+					for(var i=0;i<this.kindnum;i++){
+						obj["appointPestName"+(i+1)] = this.appointPestNames[i]
+						obj["appointPestName"] = this.appointPestNames.join("#")
+						obj["appointPestNum"+(i+1)] = this.appointPestNums[i]
+						obj["appointPestNum"] = this.appointPestNums.join("#")
+					}
+					Object.assign(this.form,obj)
+					console.log(this.form)
+					this.conf = JSON.stringify(this.form)
+					var namesome = this.appointPestNames.some((item)=>{
+						return item == -1
+					})
+					var numsome = false;
+					if(this.appointPestNums.length != this.appointPestNames.length){
+						numsome = true
+					}
+					var arr = false
+					if(this.checked1){
+						if(!this.form.pestCategoryNum){
+							uni.showToast({
+								title: '请输入害虫种类数量!',
+								duration: 2000,
+								icon:"none"
+							});
+							arr=false
+						}else{
+							arr=true
+						}
+					}
+					if(this.checked2){
+						if(namesome){
+							uni.showToast({
+								title: '请将指定害虫数量信息填写完全!',
+								duration: 2000,
+								icon:"none"
+							});
+							arr=false
+						}else if(numsome){
+							uni.showToast({
+								title: '请将指定害虫数量信息填写完全!',
+								duration: 2000,
+								icon:"none"
+							});
+							arr=false
+						}else{
+							arr = true
+						}
+					}
+					if(this.checked3){
+						if(!this.form.pestTotalNum){
+							uni.showToast({
+								title: '请输入害虫种类总和数量!',
+								duration: 2000,
+								icon:"none"
+							});
+							arr=false
+						}else{
+							arr=true
+						}
+					}
+					if(this.form.phone){
+						if(!this.phonetf && arr){
+							this.notealloc()
+						}
+					}else{
+						uni.showToast({
+							title: '请输入手机号码!',
+							duration: 2000,
+							icon:"none"
+						});
+					}
+				}else{
+					uni.showToast({
+						title: '请在开启预警后点击确定!',
+						duration: 2000,
+						icon:"none"
+					});
+				}
+				
+			},
+			phonereg() {
+				if (/^1[23456789]\d{9}$/.test(this.form.phone)) {
+					this.phonetf = false
+				} else {
+					this.phonetf = true
+				}
+			},
+			confirmFun2(index) {
+				this.appointPestNames[this.datasindex] = index[0]
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			pickerchange(index){
+				if(this.checked2){
+					this.pickertf = !this.pickertf
+					this.datasindex = index
+				}else{
+					uni.showToast({
+						title: '请在开启预警后输入!',
+						duration: 2000,
+						icon:"none"
+					});
+				}
+			},
+			addkindnum(){
+				this.kindnum++
+				this.appointPestNames.push(-1)
+				console.log(this.appointPestNames)
+			},
+			jiankindnum(index){
+				console.log(index)
+				this.kindnum--
+				console.log(this.appointPestNames)
+				this.appointPestNames.splice(index,1)
+				this.appointPestNums.splice(index,1)
+			}
+		},
+		onLoad(option) {
+			this.device_id = option.device_id
+			this.notealloc()
+			for (var key in cbddatas) {
+				this.selector[key] = cbddatas[key]
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.earlywarning {
+		position: absolute;
+		top: 54px;
+		width: 100%;
+
+		.kind {
+			width: 90%;
+			margin: 0 auto 40rpx;
+
+			.kind_top {
+				display: flex;
+				justify-content: space-between;
+
+				.kind_top_title {
+					border-left: 8rpx solid #28AE4F;
+					height: 40rpx;
+					padding-left: 20rpx;
+				}
+			}
+			.kind_box{
+				position: relative;
+				.icons{
+					position: absolute;
+					top: 40rpx;
+					right: 50rpx;
+				}
+			}
+			.kind_bot {
+				display: flex;
+				padding-left: 28rpx;
+				margin: 30rpx 0 0;
+
+				.kind_bot_title {
+					font-size: 26rpx;
+					color: #A7A7A7;
+					margin-right: 10rpx;
+				}
+
+				input {
+					border: 2rpx solid #E4E4E4;
+					font-size: 26rpx;
+					width: 55%;
+					padding-left: 10rpx;
+				}
+
+				.input {
+					position: relative;
+					width: 55%;
+
+					input {
+						width: 100%;
+					}
+
+					.icon {
+						position: absolute;
+						top: 10rpx;
+						right: 0;
+					}
+				}
+
+			}
+
+			.hint {
+				font-size: 24rpx;
+				text-align: right;
+				color: #ff0000;
+				margin-top: 10rpx;
+			}
+		}
+
+		.tijiao {
+			width: 90%;
+			text-align: center;
+			font-size: 34rpx;
+			height: 60rpx;
+			line-height: 60rpx;
+			color: #FFFFFF;
+			background-color: #28AE4F;
+			margin: 80rpx auto 0;
+			border-radius: 30rpx;
+		}
+	}
+</style>

+ 614 - 0
pages/cb/cbd/equip-set/statistics.vue

@@ -0,0 +1,614 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="害虫统计"></uni-nav-bar>
+			</view>
+			<view class="statistics">
+				<view class="top_text">
+					<view :class="topindex==index?'title_text_color':'tltle_text'" v-for="(item,index) in toptext" :key="index" @click="changeindex(index)">
+						{{item}}
+					</view>
+				</view>
+				<view class="shuju_one">
+					<p class="shuju_one_title">害虫趋势统计</p>
+					<view class="shuju_one_btn">
+						<view class="schedule_box">
+							<view class="schedule" @click="pickertfone=!pickertfone">
+								<p class="schedule_value">{{titletext[indexone]}}</p>
+								<p class="schedule_icon">
+									<u-icon name="arrow-down"></u-icon>
+								</p>
+							</view>
+							<u-picker v-model="pickertfone" mode="selector" @confirm="confirmFun" :default-selector="[indexone]" :range="titletext"></u-picker>
+							<view class="schedule" @click="pickertftwo=!pickertftwo" v-if="tishitf">
+								<p class="schedule_value">{{wormdata[indextwo]}}</p>
+								<p class="schedule_icon">
+									<u-icon name="arrow-down"></u-icon>
+								</p>
+								<u-picker v-model="pickertftwo" mode="selector" @confirm="confirmFun2" :default-selector="[indextwo]" :range="wormdata"></u-picker>
+							</view>
+						</view>
+					</view>
+					<view class="canvastishi" v-if="!canvastishiTF">
+						暂无数据
+					</view>
+					<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
+					 @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+				</view>
+				<view class="shuju_two">
+					<p class="shuju_one_title">害虫比例</p>
+					<view class="canvastishi" v-if="!canvastishiTF">
+						暂无数据
+					</view> 
+					<canvas v-if="canvastishiTF" canvas-id="canvasRing" id="canvasRing" class="charts" @touchstart="touchRing" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<style lang="scss">
+	.top_text {
+		width: 90%;
+		position: absolute;
+		top: 54px;
+		display: flex;
+		left: 5%;
+
+		.tltle_text {
+			width: 50%;
+			border: 2rpx solid #F0F0F0;
+			text-align: center;
+		}
+
+		.title_text_color {
+			width: 50%;
+			border: 2rpx solid #64CC82;
+			text-align: center;
+		}
+	}
+
+	.tishi {
+		position: absolute;
+		top: 250rpx;
+		left: 40%;
+		font-size: 32rpx;
+		color: #7A7373;
+	}
+
+	.shuju_one_title {
+		font-size: 32rpx;
+		font-weight: 700;
+		width: 100%;
+		text-align: center;
+		margin-bottom: 20rpx;
+	}
+
+	.shuju_one_btn {
+		width: 90%;
+		margin: 0 auto;
+		display: flex;
+		justify-content: space-between;
+
+		.schedule_box {
+			display: flex;
+		}
+
+		.schedule {
+			display: flex;
+			width: 280rpx;
+			height: 50rpx;
+			border: 2rpx solid #F0F0F0;
+			margin-left: 20rpx;
+
+			.schedule_value {
+				width: 70%;
+				text-align: center;
+				line-height: 50rpx;
+				font-size: 24rpx;
+			}
+
+			.schedule_icon {
+				width: 30%;
+				background-color: #F2F2F2;
+				text-align: center;
+				line-height: 50rpx;
+			}
+		}
+	}
+</style>
+<script>
+	import uCharts from '../../../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvaColumnA = null;
+	var canvasRing = null;
+	var newtime = +new Date()
+	var strrttime = newtime - 24 * 60 * 60 * 1000
+	export default {
+		data() {
+			return {
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+				canvastishiTF: false,
+				d_id: '',
+				start_time: strrttime,
+				end_time: newtime,
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				device_id: '',
+				pest_name: '',
+				wormdata: [],
+				pickertfone: false,
+				pickertftwo: false,
+				indexone: 0,
+				indextwo: 0,
+				tishitf: false,
+				tishi: false,
+				toptext: ["自动统计", "手动统计"],
+				topindex: 0
+			}
+		},
+		methods: {
+			async historys() { //获取统计虫子 自动统计 初始化统计 没有传入害虫名称
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.pest_statistics',
+					data: {
+						d_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+					}
+				})
+
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (this.historydatas.date.length == 0) {
+					this.canvastishiTF = false
+					this.tishitf = false
+				} else {
+					this.canvastishiTF = true
+					this.tishitf = true
+					this.wormdata = []
+					for (var i = 0; i < res.percentage.length; i++) {
+						this.wormdata.unshift(res.percentage[i].name_num)
+					}
+					var arr1 = []
+					var arr2 = []
+					var arr3 = []
+					var xtitle = []
+					var ringarr = []
+					for (var i = 0; i < res.date.length; i++) {
+						var times = new Date(res.date[i].addtime * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
+						arr1.unshift(res.date[i].temperature == "" ? "0" : res.date[i].temperature)
+						arr2.unshift(res.date[i].humidity == "" ? "0" : res.date[i].humidity)
+						arr3.unshift(res.date[i]._sums == "" ? "0" : res.date[i]._sums)
+					}
+					for(var i = 0; i < res.percentage.length; i++){
+						var obj = {}
+						obj.name = res.percentage[i].name_num
+						obj.data = Number(res.percentage[i].num)
+						ringarr.unshift(obj)
+					}
+					console.log(ringarr)
+					var obj = [{
+						name: '温度',
+						data: arr1,
+						color: '#00E29D'
+					}, {
+						name: '湿度',
+						data: arr2,
+						color: '#6CBBFF'
+					}, {
+						name: '害虫总数',
+						data: arr3,
+						color: '#FF3F3F'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+					this.showRing(ringarr)
+				}
+			},
+			async history() { //获取统计虫子 //自动统计 传入害虫名称统计  在historys之后
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.pest_statistics',
+					data: {
+						pest_name: this.pest_name,
+						d_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000)
+					}
+				})
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (this.historydatas.date.length == 0) {
+					this.canvastishiTF = false
+					this.tishitf = false
+				} else {
+					this.canvastishiTF = true
+					this.tishitf = true
+					var arr1 = []
+					var arr2 = []
+					var arr3 = []
+					var xtitle = []
+					for (var i = 0; i < res.date.length; i++) {
+						var times = new Date(res.date[i].addtime * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
+						arr1.unshift(res.date[i].temperature == "" ? "0" : res.date[i].temperature)
+						arr2.unshift(res.date[i].humidity == "" ? "0" : res.date[i].humidity)
+						arr3.unshift(res.date[i]._sums == "" ? "0" : res.date[i]._sums)
+					}
+					var obj = [{
+						name: '温度',
+						data: arr1,
+						color: '#00E29D'
+					}, {
+						name: '湿度',
+						data: arr2,
+						color: '#6CBBFF'
+					}, {
+						name: '害虫总数',
+						data: arr3,
+						color: '#FF3F3F'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+				}
+			},
+			// forecast.worm_lamp.pest_manual_statistics手动统计
+			async selfhistorys() { //获取统计虫子 手动统计 初始化统计 不传入害虫名称
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.pest_manual_statistics',
+					data: {
+						device_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000)
+					}
+				})
+				console.log(res)
+				if (res.date.length == 0) {
+					this.tishitf = false
+					this.canvastishiTF = false
+				} else {
+					this.tishitf = true
+					this.canvastishiTF = true
+					this.wormdata = []
+					for (var i = 0; i < res.date.length; i++) {
+						this.wormdata.unshift(res.date[i].pest_name)
+					}
+					var arr1 = []
+					var xtitle = []
+					var ringarr = []
+					for (var i = 0; i < res.date.length; i++) {
+						var times = new Date(res.date[i].add_time * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
+						arr1.unshift(res.date[i].pest_num == "" ? "0" : res.date[i].pest_num)
+						var obj ={}
+						obj.name = res.date[i].pest_name
+						obj.data = Number(res.date[i].pest_num)
+						ringarr.unshift(obj)
+					}
+					var obj = [{
+						name: '害虫总数',
+						data: arr1,
+						color: '#00E29D'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+					this.showRing(ringarr)
+				}
+			},
+			async selfhistory() { //获取统计虫子 //手动统计  传入害虫名称
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.pest_manual_statistics',
+					data: {
+						pest_name: this.pest_name,
+						device_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000)
+					}
+				})
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (res.date.length == 0) {
+					this.tishitf = false
+					this.canvastishiTF = false
+				} else {
+					this.tishitf = true
+					this.canvastishiTF = true
+					var arr1 = []
+					var xtitle = []
+					for (var i = 0; i < res.pests.pest_list.length; i++) {
+						var times = new Date(res.pests.pest_list[i].add_time * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getSeconds())
+						arr1.unshift(res.pests.pest_list[i].pest_num == "" ? "0" : res.pests.pest_list[i].pest_num)
+					}
+					var obj = [{
+						name: '害虫总数',
+						data: arr1,
+						color: '#00E29D'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+				}
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			confirmFun(index) {
+				this.indexone = index[0]
+				var now = new Date()
+				this.$forceUpdate()
+				if (index[0] == 0) {
+					this.start_time = strrttime
+					if (this.topindex == 0) {
+						if (this.pest_name == '') {
+							this.historys()
+						} else {
+							this.history()
+						}
+					} else {
+						if (this.pest_name == '') {
+							this.selfhistorys()
+						} else {
+							this.selfhistory()
+						}
+					}
+				} else if (index[0] == 1) {
+					var oldtime = now.setMonth(now.getMonth() - 1)
+					this.start_time = parseInt(oldtime)
+					if (this.topindex == 0) {
+						if (this.pest_name == '') {
+							this.historys()
+						} else {
+							this.history()
+						}
+					} else {
+						if (this.pest_name == '') {
+							this.selfhistorys()
+						} else {
+							this.selfhistory()
+						}
+					}
+				} else if (index[0] == 2) {
+					var oldtime = now.setMonth(now.getMonth() - 6)
+					this.start_time = parseInt(oldtime)
+					if (this.topindex == 0) {
+						if (this.pest_name == '') {
+							this.historys()
+						} else {
+							this.history()
+						}
+					} else {
+						if (this.pest_name == '') {
+							this.selfhistorys()
+						} else {
+							this.selfhistory()
+						}
+					}
+				} else if (index[0] == 3) {
+					var oldtime = now.setFullYear(now.getFullYear() - 1)
+					this.start_time = parseInt(oldtime)
+					if (this.topindex == 0) {
+						if (this.pest_name == '') {
+							this.historys()
+						} else {
+							this.history()
+						}
+					} else {
+						if (this.pest_name == '') {
+							this.selfhistorys()
+						} else {
+							this.selfhistory()
+						}
+					}
+				}
+			},
+			confirmFun2(index) {
+				console.log(index)
+				console.log(this.wormdata)
+				this.indextwo = index[0]
+				this.pest_name = this.wormdata[this.indextwo]
+				if (this.topindex == 0) {
+					this.history()
+				} else {
+					this.selfhistory()
+				}
+			},
+			changeindex(index) {
+				this.topindex = index
+				if (this.topindex == 0) {
+					this.pest_name = ''
+					this.tishitf = false
+					this.historys()
+				} else {
+					this.pest_name = ''
+					this.tishitf = false
+					this.selfhistorys()
+				}
+			},
+			showColumn(id, xtitle, xinfo) {
+				var _self = this
+				canvaColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position: "top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle,
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 5, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				console.log(e)
+				canvaColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvaColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvaColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+			showRing(data) {
+				var _self = this
+				canvasRing = new uCharts({
+					canvasId: "canvasRing",
+					type: 'ring',
+					fontSize: 11,
+					legend: true,
+					extra: {
+						pie: {
+							offsetAngle: -45,
+							ringWidth: 40 * _self.pixelRatio,
+							labelWidth: 15
+						}
+					},
+					background: '#FFFFFF',
+					pixelRatio: _self.pixelRatio,
+					series: data,
+					animation: true,
+					width: _self.cWidth * _self.pixelRatio,
+					height: _self.cHeight * _self.pixelRatio,
+					disablePieStroke: true,
+					dataLabel: true,
+				});
+			},
+			touchRing(e) {
+				canvasRing.showToolTip(e, {
+					format: function(item) {
+						return item.name + ':' + item.data
+					}
+				});
+			},
+		},
+		onLoad(option) {
+			this.d_id = option.d_id
+			this.device_id = option.device_id
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+			this.historys()
+		}
+	}
+</script>
+
+<style lang="scss">
+	.shuju_one{
+		position: absolute;
+		top: 84px;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		box-sizing: border-box;
+		height: 650rpx;
+
+		.canvastishi {
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+	}
+	.shuju_two{
+		position: absolute;
+		top: 840rpx;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		box-sizing: border-box;
+		height: 650rpx;
+		margin-bottom: 40rpx;
+		.canvastishi {
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+	} 
+	.condition {
+		position: absolute;
+		top: 600rpx;
+		display: flex;
+		flex-wrap: wrap;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-bottom: 30rpx;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+
+			.tr {
+				display: flex;
+				overflow: hidden;
+
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 240rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+			}
+
+			.pagenumber_page {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 51 - 0
pages/cb/cbd/equip-set/test/test.vue

@@ -0,0 +1,51 @@
+<template>
+	<view id="chart">
+
+	</view>
+</template>
+
+<script>
+	import Highcharts from 'highcharts'
+	export default {
+		data() {
+			return {
+				options: {
+					chart: {
+						type: 'bar' //指定图表的类型,默认是折线图(line)
+					},
+					title: {
+						text: '我的第一个图表' // 标题
+					},
+					xAxis: {
+						categories: ['苹果', '香蕉', '橙子'] // x 轴分类
+					},
+					yAxis: {
+						title: {
+							text: '吃水果个数' // y 轴标题
+						}
+					},
+					series: [{ // 数据列
+						name: '小明', // 数据列名
+						data: [1, 0, 4] // 数据
+					}, {
+						name: '小红',
+						data: [5, 7, 3]
+					}]
+				}
+			}
+		},
+		onLoad() {
+			HighCharts.chart("chart",options)
+		},
+		methods: {
+
+		}
+	}
+</script>
+
+<style lang="scss">
+#chart{
+	width:750rpx;
+	height:500rpx;
+}
+</style>

+ 792 - 0
pages/cb/equip-detail/equip-detail.vue

@@ -0,0 +1,792 @@
+<template>
+	<view>
+		<view :class="['info',equipInfo.is_online==1?'on':'off']">
+			<view class="" @click="copy(equipInfo)">
+				设备ID:{{equipInfo.imei||equipInfo.device_id}}
+				<image src="http://static.yfpyx.com/bigdata_app/image/environment/fuzhi.png" mode="" class="tishi"></image>
+			</view>
+			<view class="">
+				设备名称:{{equipInfo.device_name}}
+			</view>
+			<view class="">
+				设备类型:{{equipInfo.type|equipType}}{{equipInfo.type_name}}
+			</view>
+			<view class="">
+				最新上报时间:{{equipInfo.addtime||equipInfo.uptime | timeFormat}}
+			</view>
+			<view class="">
+				设备地址:{{equipInfo.address?equipInfo.address:"--"}}
+			</view>
+			<view v-if="type==7" @click="setTime(equipInfo.d_id)">
+				<text space="emsp">载玻片、培养液更换时间</text>
+				<u-icon name="edit-pen" color="#f0ad4e" size="28"></u-icon>
+			</view>
+			<view v-if="type==4" @click="addYx(equipInfo.d_id)">
+				<text space="emsp">添加诱芯</text>
+				<u-icon name="edit-pen" color="#f0ad4e" size="28"></u-icon>
+			</view>
+			<u-popup v-model="setTimeShow" mode="center" width="600rpx">
+				<u-field label="载玻片更换时间" placeholder="选择日期" label-width='240' required :error-message="glassErr" v-model="glass_slide_time"
+				 @click="glass_show=true">
+				</u-field>
+				<u-field label="培养液更换时间" placeholder="选择日期" label-width='240' required :error-message="culErr" v-model="cultivate_time"
+				 @click="cultivate_show=true">
+				</u-field>
+				<view class="btn-box">
+					<u-button @click="setTimeSubmit" size="mini" type="success">确定</u-button>
+				</view>
+				<u-calendar v-model="glass_show" mode="date" @change="timeChange($event,'glass')"></u-calendar>
+				<u-calendar v-model="cultivate_show" mode="date" @change="timeChange($event,'cultivate')"></u-calendar>
+			</u-popup>
+			<u-popup v-model="yxShow" mode="center" width="600rpx">
+				<u-field label="监测害虫名称" label-width='240' required :error-message="xyErr" v-model="decoy" class="field">
+				</u-field>
+				<view class="btn-box">
+					<u-button @click="yxSubmit" size="mini" type="success">确定</u-button>
+				</view>
+			</u-popup>
+			<u-toast ref="toast" />
+		</view>
+		<view class="equip_part">
+			<template v-if="equipInfo.type==7">
+				<view class="item1" v-for="item in bzy" v-if="item.tf" @click="partClick(item.path)">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+item.icon" mode="widthFix"></image>
+					<view class="">
+						{{item.tex}}
+					</view>
+				</view>
+			</template>
+			<template v-else-if="equipInfo.type==3">
+				<view class="item2" v-for="item in curEquip" v-if="item.tf" @click="partClick(item.path)">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+item.icon" mode="widthFix"></image>
+					<view class="">
+						{{item.tex}}
+					</view>
+				</view>
+			</template>
+			<template v-else>
+				<view class="item3" v-for="item in curEquip" v-if="item.tf" @click="partClick(item.path)">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+item.icon" mode="widthFix"></image>
+					<view class="">
+						{{item.tex}}
+					</view>
+				</view>
+			</template>
+		</view>
+		<view class="tit">
+			<p>实时数据</p>
+			<p class="span" @click="partClicks">历史数据>>></p>
+		</view>
+		<view class="newtishi" v-if="!newtishitf">
+			暂无数据
+		</view>
+		<view class="newState" v-else>
+			<view class="item" v-for="item in curState">
+				<image :src="'http://static.yfpyx.com/bigdata_app'+item.icon" mode="widthFix"></image>
+				<view class="info-con">
+					<view class="active">
+						{{item.txt}}
+					</view>
+					<view class="val">
+						{{item.value | formatValue(item.txt,type)}}
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import equipState from "../../../static/js/equipState_dict.json"
+	export default {
+		data() {
+			return {
+				city:"",
+				type: null, //设备类型
+				device_status: null,
+				equipInfo: {},
+				cbd: [{
+					icon: '/image/cb/1.png',
+					tex: '查看图片',
+					path: '/pages/cb/cbd/equip-set/imgpage',
+					tf:false
+				}, 
+				// {
+				// 	icon: '/image/cb/2.png',
+				// 	tex: '历史数据',
+				// 	path: '/pages/cb/cbd/equip-set/historyfile',
+				// 	tf:false
+				// }, 
+				{
+					icon: '/image/cb/3.png',
+					tex: '害虫统计',
+					path: '/pages/cb/cbd/equip-set/statistics',
+					tf:false
+				}, {
+					icon: '/image/cb/4.png',
+					tex: '设备控制',
+					path: '/pages/cb/cbd/equip-set/equip-set',
+					tf:false
+				}, {
+					icon: '/image/cb/5.png',
+					tex: '短信预警',
+					path: '/pages/cb/cbd/equip-set/note',
+					tf:false
+				}, {
+					icon: '/image/cb/6.png',
+					tex: 'sim卡详情',
+					path: '/pages/cb/sim/sim',
+					tf:true
+				},{
+					icon: '/image/environment/7.png',
+					tex: '一键报修',
+					path: '/pages/afterSale/addafter',
+					tf:true
+				}],
+				bzy: [{
+					icon: '/image/cb/4.png',
+					tex: '设备控制',
+					path: '/pages/cb/bzy/equip-set/equip-set',
+					tf:false
+				}, {
+					icon: '/image/cb/1.png',
+					tex: '查看图片',
+					path: '/pages/cb/cbd/equip-set/imgpage',
+					tf:false
+				}, 
+				// {
+				// 	icon: '/image/cb/2.png',
+				// 	tex: '历史数据',
+				// 	path: '/pages/cb/bzy/equip-set/bzyhistoryile',
+				// 	tf:false
+				// }, 
+				{
+					icon: '/image/cb/6.png',
+					tex: 'sim卡详情',
+					path: '/pages/cb/sim/sim',
+					tf:false
+				},{
+					icon: '/image/environment/7.png',
+					tex: '一键报修',
+					path: '/pages/afterSale/addafter',
+					tf:true
+				}],
+				xy: [{
+					icon: '/image/cb/4.png',
+					tex: '设备控制',
+					path: '/pages/cb/xy/equip-set/equip-set',
+					tf:false
+				}, {
+					icon: '/image/cb/6.png',
+					tex: 'sim卡详情',
+					path: '/pages/cb/sim/sim',
+					tf:false
+				}, {
+					icon: '/image/cb/2.png',
+					tex: '历史数据',
+					path: '/pages/cb/xy/equip-set/xyhistoryile',
+					tf:false
+				},{
+					icon: '/image/environment/7.png',
+					tex: '一键报修',
+					path: '/pages/afterSale/addafter',
+					tf:true
+				}],
+				newState: {}, //设备最新状态
+				setTimeShow: false,
+				glass_show: false,
+				cultivate_show: false,
+				cultivate_time: "",
+				glass_slide_time: "",
+				glassErr: '',
+				culErr: '',
+				yxShow: false, //诱芯弹框
+				xyErr: '',
+				decoy: '',
+				newtishitf:false,
+			}
+		},
+		computed: {
+			curEquip() {
+				switch (this.type) {
+					case 3:
+						return this.cbd;
+					case 7:
+						return this.bzy;
+					case 4:
+						return this.xy
+				}
+			},
+			curState() {
+				switch (this.type) {
+					case 3:
+						let blbs = "" //灯管状态
+						if (this.newState.lamp != undefined) {
+							if (this.newState.ws == 1) {
+								if (this.newState.lamp == 1) {
+									blbs = "工作中";
+								} else if (equipState.lux == 0) {
+									blbs = "N/A(未检测到传感器)";
+								} else {
+									blbs = "异常";
+								}
+							} else {
+								blbs = "关闭";
+							}
+						} else {
+							blbs = "--";
+						}
+						return [{
+								icon: '/image/cb/icon02.png',
+								txt: '在线状态',
+								value: Number(this.device_status) == 1 ? '在线' : '离线',
+							},
+							{
+								icon: '/image/cb/icon05.png',
+								txt: '开关状态',
+								value: Number(this.newState.ds) == 1 ? '开机' : '关机'
+							},
+							{
+								icon: '/image/cb/icon13.png',
+								txt: '通道状态',
+								value: Number(this.newState.upds) == 1 ? '落虫' : '排水'
+							},
+							{
+								icon: '/image/cb/icon10.png',
+								txt: '加热状态',
+								value: Number(this.newState.hs) == 1 ? '加热' : '正常'
+							}, {
+								icon: '/image/cb/icon08.png',
+								txt: '环境温度(℃)',
+								value: this.newState.at=="2.5"||this.newState.at=="25"||this.newState.at==""?this.newState.new_tem:this.newState.at
+							}, {
+								icon: '/image/cb/icon07.png',
+								txt: '环境湿度(%)',
+								value:this.newState.ah=="30"||this.newState.ah=="3.0"||this.newState.ah==""?this.newState.new_hum:this.newState.ah
+							}, {
+								icon: '/image/cb/icon16.png',
+								txt: '信号强度',
+								value: this.newState.csq
+							}, {
+								icon: '/image/cb/icon12.png',
+								txt: '设备版本',
+								value: this.newState.dver
+							},
+							{
+								icon: '/image/cb/icon17.png',
+								txt: '雨控状态',
+								value: Number(this.newState.rps) == 1 ? "雨控" : '正常'
+							}, {
+								icon: '/image/cb/icon14.png',
+								txt: '温控状态',
+								value: Number(this.newState.tps) == 1 ? "温控" : '正常'
+							}, {
+								icon: '/image/cb/icon06.png',
+								txt: '光控状态',
+								value: Number(this.newState.lps) == 1 ? "光控" : '正常'
+							}, {
+								icon: '/image/cb/icon01.png',
+								txt: '灯管状态',
+								value: blbs
+							}, {
+								icon: '/image/cb/icon11.png',
+								txt: '上仓门',
+								value: Number(this.newState.upds) == 1 ? "打开" : '关闭'
+							}, {
+								icon: '/image/cb/icon15.png',
+								txt: '下仓门',
+								value: Number(this.newState.dnds) == 1 ? "打开" : '关闭'
+							}
+						]
+					case 7:
+						return [{
+								icon: '/image/cb/icon02.png',
+								txt: '在线状态',
+								value: Number(this.device_status) == 1 ? '在线' : '离线',
+							},
+							{
+								icon: '/image/cb/icon05.png',
+								txt: '设备开关',
+								value: Number(this.newState.ds) == 1 ? '开启' : '关闭'
+							},
+							{
+								icon: '/image/cb/bzy/3.png',
+								txt: '摄像头状态',
+								value: this.newState.usb_sta == 1 ? '异常' : '正常'
+							},
+							{
+								icon: '/image/prevention/44.png',
+								txt: '当前电压',
+								value: this.newState.v_bat
+							}, {
+								icon: '/image/cb/icon08.png',
+								txt: '环境温度(℃)',
+								value: this.newState.at=="2.5"||this.newState.at=="25"||this.newState.at==""?this.newState.new_tem:this.newState.at
+							}, {
+								icon: '/image/prevention/66.png',
+								txt: '环境湿度(%)',
+								value:this.newState.ah=="30"||this.newState.ah=="3.0"||this.newState.ah==""?this.newState.new_hum:this.newState.ah
+							}, {
+								icon: '/image/cb/icon16.png',
+								txt: '信号强度',
+								value: this.newState.csq
+							}, {
+								icon: '/image/cb/bzy/8.png',
+								txt: '已培养时间',
+								value: this.newState.staytime
+							}, {
+								icon: '/image/cb/icon12.png',
+								txt: '设备版本',
+								value: this.newState.dver
+							}, {
+								icon: '/image/cb/icon09.png',
+								txt: '保温仓当前温度',
+								value: this.newState.pre_temp
+							}, {
+								icon: '/image/cb/icon08.png',
+								txt: '保温仓设定温度',
+								value: this.newState.set_temp
+							}
+						];
+					case 4:
+						return [{
+								icon: '/image/cb/icon02.png',
+								txt: '在线状态',
+								value: Number(this.device_status) == 1 ? '在线' : '离线',
+							},
+							{
+								icon: '/image/cb/icon05.png',
+								txt: '设备开关',
+								value: this.newState.ds == 1 ? '开启' : '关闭'
+							},
+							{
+								icon: '/image/cb/icon02.png',
+								txt: '工作状态',
+								value: this.newState.ws == 1 ? '工作' : ' 待机'
+							},
+							{
+								icon: '/image/cb/icon12.png',
+								txt: '设备版本',
+								value: this.newState.dver
+							},
+							{
+								icon: '/image/cb/icon08.png',
+								txt: '环境温度(℃)',
+								value: this.newState.at=="2.5"||this.newState.at=="25"||this.newState.at==""?this.newState.new_tem:this.newState.at
+							},
+							{
+								icon: '/image/cb/icon07.png',
+								txt: '环境湿度(%)',
+								value:this.newState.ah=="30"||this.newState.ah=="3.0"||this.newState.ah==""?this.newState.new_hum:this.newState.ah
+							},
+							{
+								icon: '/image/prevention/105.png',
+								txt: '充电电压',
+								value: this.newState.cv
+							},
+							{
+								icon: '/image/prevention/106.png',
+								txt: '电池电压',
+								value: this.newState.bv
+							},
+							{
+								icon: '/image/cb/icon16.png',
+								txt: '信号强度',
+								value: this.newState.csq
+							},
+							{
+								icon: '/image/cb/xy/9.png',
+								txt: '充电状态',
+								value: Number(this.newState.cs) == 1 ? '充电' : '正常'
+							},
+							{
+								icon: '/image/cb/xy/10.png',
+								txt: '电池状态',
+								value: this.newState.bs
+							},
+						]
+				}
+			}
+		},
+		filters: {
+			equipType(type) {
+				switch (type) {
+					case 3:
+						return "虫情测报灯";
+					case 7:
+						return "孢子仪";
+					case 4:
+						return "性诱测报"
+
+				}
+			},
+			formatValue(val, a1, a2) {
+				if (a2 == 4 && a1 == "电池状态") {
+					switch (Number(val)) {
+						case 0:
+							return '正常';
+							break;
+						case 1:
+							return '欠压';
+							break;
+						case 2:
+							return '过压';
+							break;
+					}
+				} else {
+
+					return val ? val : '无'
+				}
+			}
+		},
+		onLoad(option) {
+			this.equipInfo = JSON.parse(option.info)
+			this.type = Number(this.equipInfo.type) || Number(this.equipInfo.equip_type)
+			this.device_status = this.equipInfo.is_online
+			this.getState()
+			console.log(this.equipInfo)
+			this.selectaddress(this.lat,this.lng)
+			
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "测报系统"
+					})
+					console.log(items)
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "虫情测报灯"
+					})
+					let items3 = items[0].children.filter((item)=>{
+						return item.purview_name == "性诱测报"
+					})
+					let items4 = items[0].children.filter((item)=>{
+						return item.purview_name == "孢子仪"
+					})
+					console.log(items2)
+					var arr = items2[0].children
+					for(var i =0;i<arr.length;i++){
+						switch (arr[i].purview_name){
+							case "数据详情":
+								this.cbd[1].tf = true
+								break
+							case "查看图片":
+								this.cbd[0].tf = true
+								break
+							case "设备控制":
+								this.cbd[3].tf = true
+								break
+							case "害虫统计":
+								this.cbd[2].tf = true
+								this.cbd[4].tf = true
+								break
+							case "SIM卡":
+								this.cbd[5].tf = true
+								break
+						}
+					}
+					console.log(items3[0].children)
+					var arr2 = items3[0].children
+					for(var i =0;i<arr2.length;i++){
+						switch (arr2[i].purview_name){
+							case "设备控制":
+								this.xy[0].tf = true
+								break;
+							case "SIM卡":
+								this.xy[1].tf = true
+								break;
+							case "数据详情":
+								this.xy[2].tf = true
+								break;
+						}
+					}
+					console.log(items4[0].children)
+					var arr3 = items4[0].children
+					for(var i =0;i<arr3.length;i++){
+						switch (arr3[i].purview_name){
+							case "设备控制":
+								this.bzy[0].tf = true
+								break;
+							case "查看图片":
+								this.bzy[1].tf = true
+								break;
+							case "数据详情":
+								this.bzy[2].tf = true
+								break;
+							case "SIM卡":
+								this.bzy[3].tf = true
+								break;
+						}
+					}
+				}
+			})
+		},
+		methods: {
+			async getState() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+					data: {
+						device_type_id: this.equipInfo.type || this.equipInfo.equip_type,
+						device_id: this.equipInfo.imei || this.equipInfo.device_id,
+						page: 1,
+						page_size: 1,
+					}
+				})
+				console.log(res)
+				console.log(1222)
+				if(res.counts!=0){
+					this.newState = res.data[0].d_h_t
+					this.newtishitf = true
+				}else{
+					this.newtishitf = false
+				}
+			},
+			partClick(path) {
+				console.log(path)
+				uni.navigateTo({
+					url: path + '?d_id=' + this.equipInfo.d_id + "&device_id=" + this.equipInfo.imei + "&device_type="+this.type
+				});
+			},
+			partClicks(){
+				var path = ""
+				if(this.type==3){
+					path="/pages/cb/cbd/equip-set/historyfile"
+				}else if(this.type == 7){
+					path="/pages/cb/bzy/equip-set/bzyhistoryile"
+				}
+				uni.navigateTo({
+					url: path + '?d_id=' + this.equipInfo.d_id + "&device_id=" + this.equipInfo.imei + "&device_type="+this.type
+				});
+			},
+			async setTime(d_id) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=device.device_manage.get_spore_time',
+					data: {
+						device_type_id: this.type,
+						d_id
+					}
+				})
+				this.glass_slide_time = res.glass_slide_time ? this.formatTime(res.glass_slide_time * 1000, 'yyyy-MM-dd') : ''
+				this.cultivate_time = res.cultivate_time ? this.formatTime(res.cultivate_time * 1000, 'yyyy-MM-dd') : ''
+				this.setTimeShow = true
+			},
+			timeChange(e, a) {
+				if (a == 'glass') {
+					this.glass_slide_time = e.result
+					this.glassErr = ''
+				} else {
+					this.cultivate_time = e.result
+					this.culErr = ''
+				}
+			},
+			async setTimeSubmit() {
+				if (!this.glass_slide_time) {
+					this.glassErr = "请填写载玻片更换时间"
+				}
+				if (!this.cultivate_time) {
+					this.culErr = "请填写培养液更换时间"
+					return
+				}
+				let glass = parseInt(
+					new Date(this.glass_slide_time).getTime() / 1000
+				);
+				let cultivate = parseInt(
+					new Date(this.cultivate_time).getTime() / 1000
+				);
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=device.device_manage.updata_spore_time',
+					data: {
+						device_type_id: this.type,
+						d_id: this.equipInfo.d_id,
+						glass_slide_time: glass,
+						cultivate_time: cultivate
+					}
+				})
+				if (res) {
+					this.$refs.toast.show({
+						title: '修改成功!',
+						type: 'success',
+					})
+				}
+				this.setTimeShow = false
+			},
+			async addYx(d_id) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=device.device_manage.get_spore_time',
+					data: {
+						device_type_id: this.type,
+						d_id
+					}
+				})
+				this.decoy = res.decoy;
+				this.yxShow = true
+			},
+			async yxSubmit() {
+				if (!this.decoy) {
+					this.xyErr = "请填写监测害虫名称";
+					return false
+				}
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=device.device_manage.updata_spore_time',
+					data: {
+						device_type_id: this.type,
+						d_id: this.equipInfo.d_id,
+						decoy: this.decoy
+					}
+				})
+				if (res) {
+					this.xyErr = ""
+					this.yxShow = false
+				}
+			},
+			selectaddress(lat,lng) { //获取分布位置
+				uni.request({
+					url: '/dpc/ws/geocoder/v1/?location='+lat+","+lng+"&key=B2EBZ-2UW6P-RDJDG-LCMLE-AIQUS-CGFMJ",
+					success: (res) => {
+						if(res==0){
+							this.city = res.data.result.address
+						}
+					}
+				})
+			},
+			copy(item){
+				console.log(item)
+				uni.setClipboardData({
+				    data: item.imei||item.device_id,
+				    success: function () {
+				        console.log('success');
+				    }
+				});
+			},
+		},
+	}
+</script>
+
+<style lang='scss'>
+	page {
+		padding: 20rpx;
+		box-sizing: border-box;
+		.info {
+			padding: 20rpx 40rpx;
+			color: #fff;
+			line-height: 50rpx;
+			font-size: 26rpx;
+			background-size: 100% auto;
+			background-repeat: no-repeat;
+			background-color: #0DC6B6;
+			background-position: top left;
+			box-sizing: border-box;
+			width: 100%;
+			.tishi{
+				width: 28rpx;
+				height: 28rpx;
+				margin: 0rpx 0 0 20rpx;
+			}
+		}
+
+		.on {
+			background-image: url('http://static.yfpyx.com/bigdata_app/image/cb/onBg.png')
+		}
+
+		.off {
+			background-image: url('http://static.yfpyx.com/bigdata_app/image/cb/offBg.png')
+		}
+
+		.equip_part {
+			display: flex;
+			flex-wrap: wrap;
+			text-align: center;
+			font-size: 28rpx;
+			color: #666;
+			line-height: 50rpx;
+			image {
+				width: 52rpx;
+			}
+
+			.item1 {
+				padding: 20rpx 0;
+				box-sizing: border-box;
+				flex-basis: 25%;
+			}
+
+			.item2 {
+				padding: 20rpx 10rpx;
+				box-sizing: border-box;
+				flex-basis: 33%;
+				/* flex-grow: 1; */
+			}
+			.item3{
+				padding: 20rpx 0;
+				box-sizing: border-box;
+				flex-basis: 25%;
+			}
+		}
+
+		.tit {
+			font-weight: 800;
+			height: 50rpx;
+			font-size: 30rpx;
+			margin-bottom: 20rpx;
+			display: flex;
+			justify-content: space-between;
+			.span{
+				color: #6e6c76;
+				font-size: 24rpx;
+				display: flex;
+				justify-content: space-between;
+				/* margin-top: 12rpx; */
+			}
+		}
+		.newtishi{
+			width: 90%;
+			margin: 0 auto;
+			text-align: center;
+			padding-top: 40rpx;
+			font-size: 32rpx;
+		}
+		.newState {
+			display: flex;
+			flex-wrap: wrap;
+			text-align: center;
+			margin: 0 -10rpx;
+
+			.item {
+				display: flex;
+				flex-wrap: nowrap;
+				margin: 10rpx;
+				width: 345rpx;
+				justify-content: flex-start;
+				padding: 20rpx 10rpx;
+				box-sizing: border-box;
+				border-radius: 4px;
+				box-shadow: 0px 0px 5px 3px rgba(136, 136, 136, .1);
+				font-size: 24rpx;
+
+				.info-con {
+					padding-left: 30rpx;
+					text-align: left;
+					line-height: 40rpx;
+				}
+
+				image {
+					width: 70rpx;
+				}
+			}
+		}
+
+		.btn-box {
+			text-align: center;
+			padding: 30rpx;
+		}
+		.field {
+			/deep/.uni-input-input {
+				border: 2rpx solid #FF0000;
+				border-radius: 24rpx;
+				width: 140px;
+				padding-left: 10rpx;
+				box-sizing: border-box;
+			}
+		}
+	}
+</style>

+ 276 - 0
pages/cb/index/index.vue

@@ -0,0 +1,276 @@
+<template>
+	<view class="">
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickRight="clickRight" @clickLeft="clickLeft" left-icon="back" left-text="返回" right-icon="search"
+				 title="测报系统"></uni-nav-bar>
+				<view>
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/cb/banner.jpg'" mode="widthFix"></image>
+				</view>
+				<view class="tab-box">
+					<view v-for="(item,index) in equipArr" :key="item.type" v-if="item.tf" @click="tabClick(index)" :class="['tab-item',active==index?'active':'']">
+						<text>{{item.name}}</text>
+						<text class="bottom-line"></text>
+					</view>
+				</view>
+			</view>
+			<view class="" style="position: absolute;top: 180px;width: 100%;">
+				<view class="content">
+					<template v-for="(item,index) in equipArr[active].list">
+						<equipItem @click.native="itemClick(item)" v-bind:item="item" :key="index">
+							<view class="date">
+								<p>设备名称:{{item.device_name==""?"无":item.device_name}}</p>
+								<p>最新上报时间:{{item.addtime|timeFormat}}</p>
+							</view>
+						</equipItem>
+					</template>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import equipItem from "../../../components/equip-item/equip-item"
+	import uniNavBar from "@/components/uni-nav-bar/uni-nav-bar.vue"
+	export default {
+		data() {
+			return {
+				active: 0, //默认选中虫情测报
+				equipArr: [{
+						name: '虫情测报',
+						type: 3, //3虫情测报灯 7孢子仪 4智能性诱
+						list: [],
+						pageIndex: 1,
+						tf:false,
+					}, {
+						name: '孢子仪',
+						type: 7, //3虫情测报灯 7孢子仪 4智能性诱
+						list: [],
+						pageIndex: 1,
+						tf:false,
+					}, {
+						name: '性诱测报',
+						type: 4, //3虫情测报灯 7孢子仪 4智能性诱
+						list: [],
+						pageIndex: 1,
+						tf:false,
+					},
+					{
+						name: '性诱2.0',
+						type: 10, //3虫情测报灯 7孢子仪 4智能性诱 性诱2.0
+						list: [],
+						pageIndex: 1,
+						tf:false
+					}
+				],
+				device_id: '3', //筛选的设备id
+				isTop: false,
+			}
+		},
+		onLoad() {
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "测报系统"
+					})
+					var arr = items[0].children
+					for(var i =0;i<arr.length;i++){
+						switch (arr[i].purview_name){
+							case "虫情测报灯":
+								this.equipArr[0].tf = true
+								this.getEquipList(0)
+								break
+							case "性诱测报":
+								this.equipArr[2].tf = true
+								this.getEquipList(2)
+								break
+							case "孢子仪":
+								this.equipArr[1].tf = true
+								this.getEquipList(1)
+								break
+							case "性诱2.0":
+								this.equipArr[3].tf = true
+								this.getxyEquipList(3)
+								break
+						}
+					}
+				}
+			})
+		},
+		onShow() {
+
+		},
+		onHide() {
+
+		},
+		onUnload() {
+
+		},
+		onPullDownRefresh() {
+			this.equipArr[this.active].pageIndex = 1
+			this.equipArr[this.active].list = []
+			if(this.active==3){
+				this.getxyEquipList(3)
+			}else{
+				this.getEquipList(this.active)
+			}
+			setTimeout(() => {
+				uni.stopPullDownRefresh()
+			}, 1000)
+		},
+		onReachBottom() {
+			let act = this.active
+			if (this.equipArr[act].list.length < this.equipArr[act].pageIndex * 10) { //判断是否数据请求完
+				return false
+			}
+			this.equipArr[act].pageIndex++;
+			if(this.active==3){
+				this.getxyEquipList(3)
+			}else{
+				this.getEquipList(act)
+			}
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+		methods: {
+			async getEquipList(act) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: this.equipArr[act].type,
+						page: this.equipArr[act].pageIndex,
+						page_size: 10,
+					}
+				})
+				console.log(res)
+				this.equipArr[act].list = [...this.equipArr[act].list, ...res.data]
+				console.log(this.equipArr[act].list)
+			},
+			async getxyEquipList(act) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_list',
+					data: {
+						device_type_id: this.equipArr[act].type,
+						page: this.equipArr[act].pageIndex,
+						page_size: 10,
+					}
+				})
+				console.log(res)
+				this.equipArr[act].list = [...this.equipArr[act].list, ...res.data]
+				console.log(this.equipArr[act].list)
+			},
+			tabClick(index) {
+				this.active = index;
+				this.device_id = this.equipArr[index].type
+			},
+			clickRight() {
+				uni.navigateTo({
+					url: "./search?device_id=" + this.device_id
+				})
+			},
+			itemClick(item) {
+				item.type = this.equipArr[this.active].type
+				let data = JSON.stringify(item)
+				if (item.type == 10) {
+					uni.navigateTo({
+						url: '/pages/cb/xy2.0/particulars?info=' + data
+					});
+				} else {
+					uni.navigateTo({
+						url: '/pages/cb/equip-detail/equip-detail?info=' + data
+					});
+				}
+			},
+			clickLeft() {
+				uni.switchTab({
+					url: "../../index/index"
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		components: {
+			equipItem,
+			uniNavBar
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: $uni-bg-color-grey;
+
+		.content {
+			padding: 0 20rpx 20rpx 20rpx;
+			box-sizing: border-box;
+		}
+	}
+
+	image {
+		width: 100%;
+	}
+
+	.tab-box {
+		display: flex;
+		justify-content: space-around;
+		font-size: 30rpx;
+		line-height: 80rpx;
+		background-color: #FFFFFF;
+		margin-top: -10rpx;
+
+		.tab-item {
+			cursor: pointer;
+			position: relative;
+		}
+
+		;
+
+		.tab-item.active {
+			.bottom-line {
+				bottom: 0;
+				position: absolute;
+				display: inline-block;
+				width: 90rpx;
+				height: 6rpx;
+				left: 0;
+				right: 0;
+				margin: auto;
+				background: $uni-color-success;
+			}
+		}
+	}
+
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+
+		image {
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 253 - 0
pages/cb/index/search.vue

@@ -0,0 +1,253 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 44px;">
+			<view style="position: fixed;z-index: 100;padding-top: 20rpx;background-color: #FFFFFF;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回"></uni-nav-bar>
+				<view class="search_top_input">
+					<input type="text" value="" placeholder="请输入设备ID" v-model="imports" @input="searchinp" />
+					<u-icon name="search" size="40" class="icon" @click="search"></u-icon>
+				</view>
+			</view>
+			<view class="nonetishi" v-if="none">
+				暂无此设备
+			</view>
+			<view class="prevents" v-else>
+				<view class="prevents_item" v-for="item,index in eqlistdata" :key="index" @click="eqdetails(item)">
+					<image :src="item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/prevention/6.png':'http://static.yfpyx.com/bigdata_app/image/prevention/7.png'" mode=""
+					 class="prevents_item_img"></image>
+					<view class="prevents_item_top">
+						<p>设备 ID:{{item.imei || item.device_id}}</p>
+						<p :class="item.is_online==1?'green':'red'" v-text="item.is_online==1?'在线':'离线'"></p>
+					</view>
+					<view class="prevents_item_bot">
+						<p>设备名称:{{item.device_name}}</p>
+						<p>最新上报时间:{{item.addtime|timeFormat()}}</p>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				imports:"",
+				device_id:'',
+				page:1,
+				eqlistdata:[],
+				isTop:false,
+				none:false
+			}
+		},
+		methods: {
+			async searchEquip() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: this.device_id,
+						device_id: this.imports,
+						page:this.page
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.data)
+				console.log(res)
+				if(this.eqlistdata.length==0){
+					this.none = true
+				}else{
+					this.none = false
+				}
+			},
+			async getxyEquipList(act) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_list',
+					data: {
+						device_type_id: this.device_id,
+						page: this.page,
+						page_size: 10,
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.data)
+				console.log(res)
+				if(this.eqlistdata.length==0){
+					this.none = true
+				}else{
+					this.none = false
+				}
+			},
+			searchinp(){
+				Debounce(() => {
+					this.eqlistdata = []
+					this.page = 1
+					if(this.device_id==10){
+						this.getxyEquipList()
+					}else{
+						this.searchEquip()
+					}
+				}, 1000)()
+			},
+			search(){
+				this.eqlistdata = []
+				this.page = 1
+				if(this.device_id==10){
+					this.getxyEquipList()
+				}else{
+					this.searchEquip()
+				}
+			},
+			clickLeft(){
+				uni.navigateTo({
+					url:"./index"
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			},
+			eqdetails(item){
+				item.type = Number(this.device_id)
+				console.log(item)
+				let data = JSON.stringify(item)
+				if(item.type==10){
+					uni.navigateTo({
+						url: '/pages/cb/xy2.0/particulars?info=' + data
+					});
+				}else{
+					uni.navigateTo({
+						url: '/pages/cb/equip-detail/equip-detail?info=' + data
+					});
+				}
+			}
+		},
+		onLoad(option){
+			this.device_id = option.device_id
+		},
+		onReachBottom() {
+			this.page++
+			console.log(1)
+			if(this.device_id==10){
+				this.getxyEquipList()
+			}else{
+				this.searchEquip()
+			}
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.search_top_input {
+		width: 80%;
+		height: 54rpx;
+		background-color: #E4E4E4;
+		border-radius: 27rpx;
+		position: absolute;
+		top: 33rpx;
+		right: 18rpx;
+		padding-top: 8rpx;
+		box-sizing: border-box;
+	
+		input {
+			width: 85%;
+			// text-indent: 1rem;
+			font-size: 26rpx;
+			padding-left: 20px;
+			box-sizing: border-box;
+		}
+	
+		.icon {
+			position: absolute;
+			top: 8rpx;
+			right: 26rpx;
+		}
+	}
+	.nonetishi{
+		width: 100%;
+		position: absolute;
+		top: 60px;
+		height: 200rpx;
+		text-align: center;
+		line-height: 200rpx;
+		font-size: 22px;
+	}
+	.prevents {
+		width: 100%;
+		position: absolute;
+		top: 60px;
+		.prevents_item {
+			width: 95%;
+			margin: 0 auto 30rpx;
+			border-radius: 10rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 40rpx 20rpx 80rpx;
+			box-sizing: border-box;
+			position: relative;
+	
+			.prevents_item_img {
+				width: 30rpx;
+				height: 50rpx;
+				position: absolute;
+				top: -4rpx;
+				left: 30rpx;
+			}
+	
+			.prevents_item_top {
+				display: flex;
+				justify-content: space-between;
+				height: 60rpx;
+				border-bottom: 2rpx solid #F4F4F4;
+				line-height: 60rpx;
+				font-size: 26rpx;
+	
+				.red {
+					color: #ff0000;
+				}
+	
+				.green {
+					color: #7DBB91;
+				}
+			}
+	
+			.prevents_item_bot {
+				margin-top: 20rpx;
+				font-size: 26rpx;
+				color: #BDBDBD;
+			}
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>
+

+ 225 - 0
pages/cb/sim/sim.vue

@@ -0,0 +1,225 @@
+<template>
+	<view>
+		<view class="section">
+			<view class="tit">
+				<image mode="widthFix" src="http://static.yfpyx.com/bigdata_app/image/cb/sim1.png" ></image>
+				sim卡流量
+			</view>
+			<view class="item">
+				<text>ICCID:</text>
+				<text>{{sim.iccid}}</text>
+			</view>
+			<view class="item">
+				<text>状态:</text>
+				<text>{{sim.account_status|simStatus}}</text>
+			</view>
+			<view class="item">
+				<text>套餐:</text>
+				<text>{{sim.data_plan}}MB</text>
+			</view>
+			<view class="item">
+				<text>已用流量:</text>
+				<text>{{sim.data_usage}}MB</text>
+			</view>
+			<view class="item">
+				<text>剩余流量:</text>
+				<text>{{sim.data_balance}}MB</text>
+			</view>
+			<view class="item">
+				<text>到期时间:</text>
+				<text>{{sim.expiry_date|timeFormat}}</text>
+			</view>
+		</view>
+		<template v-if="showHksimFlag">
+			<view class="section">
+				<view class="tit">
+					<image mode="widthFix" src="http://static.yfpyx.com/bigdata_app/image/cb/sim2.png" ></image>
+					海康sim卡流量
+				</view>
+				<view class="item">
+					<text>ICCID:</text>
+					<text>{{hksim.iccid}}</text>
+				</view>
+				<view class="item">
+					<text>状态:</text>
+					<text>{{hksim.account_status|simStatus}}</text>
+				</view>
+				<view class="item">
+					<text>套餐:</text>
+					<text>{{hksim.data_plan}}MB</text>
+				</view>
+				<view class="item">
+					<text>已用流量:</text>
+					<text>{{hksim.data_usage}}MB</text>
+				</view>
+				<view class="item">
+					<text>剩余流量:</text>
+					<text>{{hksim.data_balance}}MB</text>
+				</view>
+				<view class="item">
+					<text>到期时间:</text>
+					<text>{{hksim.expiry_date|timeFormat}}</text>
+				</view>
+				<view class="item">
+					<text>更换ICCID:</text>
+					<u-input v-model="hksiminp" type="text" :custom-style="sty"  />
+				</view>
+				<view class="submit-box">
+					<u-button  @click="submit" type="warning">确定</u-button>
+				</view>
+				<u-toast ref="toast" />
+			</view>
+		</template>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				sim: {
+			        iccid: "",
+			        account_status: 0, //卡状态 0-7 未知 测试期 沉默期 使用中 停机 停机保号 预销号 销号
+			        data_plan: 0, //套餐大小
+			        data_usage: 0, //当月用量
+			        data_balance: 0, //剩余流量
+			        expiry_date: 0, //到期日期
+			      },
+				showHksimFlag: true, //是否显示hksim卡标识
+				hksim: {
+					iccid: "",
+					account_status: 0, //卡状态 0-7 未知 测试期 沉默期 使用中 停机 停机保号 预销号 销号
+					data_plan: 0, //套餐大小
+					data_usage: 0, //当月用量
+					data_balance: 0, //剩余流量
+					expiry_date: 0, //到期日期
+				  },
+				hksiminp:'',//更换ICCID
+				d_id:'',
+				sty:{
+					'background':'#F7F8FA'
+				}
+			}
+		},
+		onLoad(option){
+			this.d_id=option.d_id
+			this.lookSIMCode('sim')
+			this.lookSIMCode('hksim')
+		},
+		 filters: {
+			simStatus(val) {
+			  switch (val) {
+				case 0:
+				  return "未知";
+				case 1:
+				  return "测试期";
+				case 2:
+				  return "沉默期";
+				case 3:
+				  return "使用中";
+				case 4:
+				  return "停机";
+				case 5:
+				  return "停机保号";
+				case 6:
+				  return "预销号";
+				case 7:
+				  return "销号";
+			  }
+			},
+		  },
+		methods: {
+			async lookSIMCode(flag){
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.device_sim',
+					data:{
+						d_id:this.d_id,
+						type:flag
+					}
+				})
+				let res2=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.sim_query',
+					data:{
+						iccid:res[0].iccid,
+					}
+				})
+				let obj=eval('('+res2.data+')').data
+				if(flag=='sim'){
+					this.sim={
+						iccid: res[0].iccid,
+						account_status: obj.account_status, //卡状态 0-7 未知 测试期 沉默期 使用中 停机 停机保号 预销号 销号
+						data_plan: obj.data_plan, //套餐大小
+						data_usage: obj.data_usage, //当月用量
+						data_balance:obj.data_balance, //剩余流量
+						expiry_date:obj.expiry_date, //到期日期
+					}
+					
+				}else if(flag=='hksim'){
+					this.hksim={
+						iccid: res[0].iccid,
+						account_status: obj.account_status, //卡状态 0-7 未知 测试期 沉默期 使用中 停机 停机保号 预销号 销号
+						data_plan: obj.data_plan, //套餐大小
+						data_usage: obj.data_usage, //当月用量
+						data_balance:obj.data_balance, //剩余流量
+						expiry_date: obj.expiry_date, //到期日期
+					}
+				}
+			},
+			async submit(){
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.device_sim',
+					data:{
+						d_id: this.d_id,
+						 iccid: this.hksiminp,
+						 type: "change",
+					}
+				})
+				this.$refs.toast.show({
+					title: '修改成功!',
+					type: 'success',
+					callback:function(){
+						uni.navigateBack({
+							delta: 1
+						});	
+					}
+				})	
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		padding:30rpx;
+		box-sizing: border-box;
+		.section{
+			padding:30rpx;
+			box-shadow: 0px 0px 5px 3px rgba(136,136,136,.1);
+			margin-bottom:20rpx;
+			box-sizing: border-box;
+			.item{
+				line-height:56rpx;
+				font-size:26rpx;
+				text:nth-child(1){
+					margin-right:10rpx;
+				}
+				display:flex;
+			}
+			.tit{
+				margin-bottom:20rpx;
+				font-size:28rpx;
+				image{
+					width:22rpx;
+					margin-right:10rpx;
+				
+				}
+			}
+			.submit-box{
+				margin-top:20rpx;
+			}
+		}
+	}
+	
+
+</style>

+ 277 - 0
pages/cb/xy/equip-set/equip-set.vue

@@ -0,0 +1,277 @@
+<template>
+	<view>
+		<view class="" v-if="myuser_type">
+			<view class="tit adminTit">
+				操作
+			</view>
+			<view class="btns">
+				 <button type="warn" @click="equipBtnControl('update')" size="mini">升级</button>
+				 <button type="warn" @click="equipBtnControl('reboot')" size="mini">重启</button>
+				 <button type="warn" @click="equipBtnControl('clearworm')" size="mini">清网</button>
+			</view>
+			<view class="tit adminTit">
+				设备开关
+			</view>
+			<view class="uni-list-cell"  @click="cell">
+				<text class="uni-input">{{equipContrlForm1.ds=="0"?'关机':'开机'}}</text>
+				<view class="arrow"></view>
+				<u-select v-model="ds_show" mode="single-column" :list="ds_list" @confirm="confirm($event,'ds')"></u-select>
+			</view>
+			<view class="tit adminTit">
+				时控开关
+			</view>
+			<view class="uni-list-cell"  @click="shicell">
+				<text class="uni-input">{{equipContrlForm1.timctrl=="0"?'关':'开'}}</text>
+				<view class="arrow"></view>
+				<u-select v-model="timctrl_show" mode="single-column" :list="timctrl_list" @confirm="confirm($event,'timctrl')"></u-select>
+			</view>
+		</view>
+		<view class="" v-if="Number(equipContrlForm1.timctrl)">
+				<view class="tit">
+					时控时长
+				</view>
+				<view class="selectTime">
+					<view class="uni-list-cell time" @click="selectTime('st')">
+						<text>{{time.time1||'开始时间'}}</text>
+						<u-icon name="clock"></u-icon>
+					</view>
+					<text class="line">-</text>
+					<view class="uni-list-cell time" @click="selectTime('et')">
+						<text>{{time.time2||'结束时间'}}</text>
+						<u-icon name="clock"></u-icon>
+					</view>
+					<u-select v-model="timeShow" mode="single-column" :list="timeList" @confirm="timeConfirm($event,timeType)"></u-select>
+				</view>
+		</view>
+		<view class="tit">
+			数据频率(min)
+		</view>
+		<view class="">
+			<slider :value="equipContrlForm1.dat_f" show-value="true" :min="10" :max="40" @change="sliderChange"  block-color="#57C878" activeColor="#57C878" step="1" />
+		</view>
+		<view class="submit-box">
+			<u-button  @click="submit" type="success">确定</u-button>
+		</view>
+		<u-toast ref="toast" />
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				d_id:'',
+				equipContrlForm1: {
+			        st: '', //时控开始时间
+			        et: '', //时控结束时间
+			        dat_f: 10 ,//数据上传时间间隔
+			        ds:'',//开关,1开机,0关机
+					timctrl:''//时控开关 1开,0关
+			    },	
+				time:{
+					time1:'',
+					time2:''
+				},
+				ds_list:[{
+					value:0,
+					label:'关机'
+				},{
+					value:1,
+					label:'开机'
+				}
+				],
+				ds_show:false,
+				timctrl_list:[
+					{
+						value:0,
+						label:'关'
+					},{
+						value:1,
+						label:'开'
+					}
+				],
+				timctrl_show:false,
+				timeList:[],
+				timeShow:false,
+				timeType:'',
+				myuser_type:false
+			}
+		},
+		onLoad(option){
+			this.d_id=option.d_id
+			this.equipSet()
+			uni.getStorage({
+				key: "myuser_type",
+				success: (res) => {
+					if (Number(res.data) == 1) {
+						this.myuser_type = true
+					}
+				}
+			})	
+		},
+		methods: {
+			//回显设备控制参数
+			async equipSet(){
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.device_control_info',
+					data:{
+						d_id:this.d_id,
+						cmd: "paramconf" 
+					}
+				})
+				console.log(res)
+			  let obj = {
+				  st: res.work_tim.st,
+				  et: res.work_tim.et,
+				  timctrl: res.work_tim.timctrl,
+				  ds: res.power.ds,
+				  dat_f: res.data_tim.dat_f,
+				};
+				this.equipContrlForm1=obj
+				this.time.time1= obj.st && obj.st < 10 ? "0" + obj.st + ":00" : obj.st + ":00";
+				this.time.time2= obj.et && obj.et < 10 ? "0" + obj.et + ":00" : obj.et + ":00";
+			},
+			async equipBtnControl(cmd){
+					let res=await this.$myRequest({
+						url:'/api/api_gateway?method=forecast.send_control.admin_device_control',
+						data:{
+							cmd,
+							device_type_id: 4,
+							d_id: this.d_id
+						}
+					})
+					if(res){
+						this.$refs.toast.show({
+							title: '指令下发成功!',
+							type: 'success',
+						})
+					}
+			},
+			sliderChange(e){
+				this.equipContrlForm1.dat_f=e.detail.value
+			},
+			selectTime(a){
+				this.timeType=a
+				if(this.timeList.length==0){
+					let arr=[]
+					for(let i=0;i<24;i++){
+						let label=i<10?`0${i}:00`:`${i}:00`
+						arr.push({
+							value:i,
+							label
+						})
+					}
+					arr.unshift({
+						value:'',
+						label:'重置'
+					})
+					this.timeList=arr
+				}
+			this.timeShow=true
+			},
+			confirm(e,a){
+				if(a=='ds'){
+					this.equipContrlForm1.ds=e[0].value
+				}else if(a=='timctrl'){
+					this.equipContrlForm1.timctrl=e[0].value
+				}
+			},
+			timeConfirm(e,a){
+				if(a=='st'){
+					this.time.time1=e[0].label
+					this.equipContrlForm1.st=e[0].value
+				}else{
+					this.time.time2=e[0].label
+					this.equipContrlForm1.et=e[0].value
+				}
+			},
+			cell(){//设备开关
+					this.ds_show=true
+			},
+			shicell(){
+					this.timctrl_show=true
+			},
+			async submit(){
+				console.log(this.equipContrlForm1)
+				let obj = {
+					work_tim: { 
+						timctrl: this.equipContrlForm1.timctrl,
+						st: this.equipContrlForm1.st,
+						et: this.equipContrlForm1.et ,
+						},
+					data_tim: { dat_f: this.equipContrlForm1.dat_f },
+					power: { ds: this.equipContrlForm1.ds },
+				};
+				let res=await this.$myRequest({
+					url:'/api/api_gateway?method=forecast.send_control.device_control',
+					data:{
+							device_type_id: 4,
+							d_id: this.d_id,
+							config: JSON.stringify(obj),
+					}
+				})
+				if(res){
+					this.$refs.toast.show({
+						title: '修改成功!',
+						type: 'success',
+						callback:function(){
+							uni.navigateBack({
+								delta: 1
+							});	
+						}
+					})	
+					
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+page{
+	padding:20rpx;
+	box-sizing: border-box;
+	.tit{
+		line-height:30rpx;
+		font-size:30rpx;
+		padding-left:20rpx;
+		border-left-width:2px;
+		border-left-style: solid;
+		border-left-color:$uni-color-success;
+		margin:30rpx 0;
+		}
+	.adminTit{border-left-color:#e64340;}
+	.btns{
+		display:flex;
+		justify-content: flex-start;
+		flex-wrap:no-wrap;
+		button{margin:0;margin-right:10rpx;padding:0 25rpx;}
+	}
+	.uni-list-cell{
+		background:#F7F8FA;
+		padding:10rpx 40rpx;
+		font-size:28rpx;
+		.arrow{
+			display:inline-block;
+			border-width:12rpx 8rpx ;
+			border-style: solid;
+			float:right;
+			margin-top:10rpx;
+			border-color:#888 transparent transparent transparent;
+		}
+	}
+	.selectTime{
+		display:flex;
+		margin-bottom:20rpx;
+		.time{
+			width:350rpx;
+			display:flex;
+			justify-content: space-between;
+		}
+		.line{width:50rpx;text-align: center;}
+	}
+	.submit-box{
+		margin-top:60rpx
+	}
+}
+</style>

+ 492 - 0
pages/cb/xy/equip-set/xyhistoryile.vue

@@ -0,0 +1,492 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="历史数据"></uni-nav-bar>
+			</view>
+			<view class="shuju_one">
+				<view class="shuju_one_title">
+					<view :class="titleidnex==index?'title_text_color':'tltle_text'" v-for="(item,index) in titletext" :key="index"
+					 @click="changeindex(index)">
+						{{item}}
+					</view>
+				</view>
+				<view class="canvastishi" v-if="!canvastishiTF">
+					暂无数据
+				</view>
+				<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
+				 @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+			</view>
+			<view class="wind">
+				<p class="wind_titie">风速、风向</p>
+				<view class="wind_text">
+					<view class="wind_speed">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/cb/xy/1c24243bb184e84ffd13540367569ba.png'" mode=""></image>
+						<p>风速:{{wind_sped}}(m/s)</p>
+					</view>
+					<view class="wind_direction">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/cb/xy/c44ae038324e1040a1eaa702e6d71a5.png'" mode=""></image>
+						<p>风速:{{wind_drec}}</p>
+					</view>
+				</view>
+			</view>
+			<view class="refresh" @click="refresh">
+				刷 新
+			</view>
+			<view class="condition">
+				<scroll-view scroll-top="0" scroll-x="true" class="scroll-X">
+					<!-- @scrolltoupper="upper" @scrolltolower="lower" @scroll="scroll" -->
+					<table class="table">
+						<tr class="tr">
+							<th class="th" v-for="(item,index) in thdata" :key="'a'+index">{{item}}</th>
+						</tr>
+						<tr class="tr" v-for="(items,indexs) in historylistdata" :key="'b'+indexs" v-if="!forbidden">
+							<td class="td">{{items.d_h_t.addtime|timeFormat()}}</td>
+							<td class="td">{{items.d_h_t.proj}}</td>
+							<td class="td">{{items.d_h_t.ds==0?"关":"开"}}</td>
+							<td class="td">{{items.d_h_t.ws==0?"待机":"工作"}}</td>
+							<td class="td">{{items.d_h_t.at}}</td>
+							<td class="td">{{items.d_h_t.ah}}</td>
+							<td class="td">{{items.d_h_t.cv}}</td>
+							<td class="td">{{items.d_h_t.bv}}</td>
+							<td class="td">{{items.d_h_t.bs}}</td>
+							<td class="td">{{items.d_h_t.cs?"正常":"充电"}}</td>
+							<td class="td">{{items.d_h_t.infr_ct}}</td>
+							<td class="td">{{items.d_h_t.csq}}</td>
+							<td class="td">{{items.d_h_t.dver}}</td>
+						</tr>
+						<tr class="tr" v-if="forbidden">
+							<td class="td" v-for="item in 13">暂无数据</td>
+						</tr>
+					</table>
+				</scroll-view>
+				<view class="pagenumber">
+					<button @click="prev">上一页</button>
+					<view class="pagenumber_page">
+						第 {{page}} 页
+					</view>
+					<view class="pagenumber_page">
+						第 {{pagesum}} 页
+					</view>
+					<button @click="next" :disabled="forbidden">下一页</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	import uCharts from '../../../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvaColumnA = null;
+	export default {
+		data() {
+			return {
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+				canvastishiTF: false,
+				d_id: '',
+				start_time: "",
+				end_time: "",
+				historydatas: [],
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				titleidnex: 0,
+				device_id: '',
+				page: 1,
+				historylistdata: [],
+				thdata: ["上报时间", "型号", "设备开关", "工作状态", "环境温度(°C)", "环境湿度(%)", "充电电压(V)", "电池电压(V)", "电池状态", "充电状态", "红外计数值", "信号强度",
+					"版本号"
+				],
+				forbidden: false,
+				wind_sped: '', //风速
+				wind_drec: '',
+				pagesum: null
+			}
+		},
+		methods: {
+			//forecast.worm_lamp.device_polyline_data 历史数据折线图
+			// device_type_id          必传(string)                  设备类型  3虫情测报灯 7孢子仪 4智能性诱 2杀虫灯  9糖醋测报灯  10测报灯rtu
+			//    d_id                    必传                            设备id
+			//    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
+			//    end_time
+			async history() { //历史数据折线图
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_polyline_data',
+					data: {
+						device_type_id: 4,
+						d_id: this.d_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000)
+					}
+				})
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (res.length == 0) {
+					this.wind_sped = "--"
+					this.wind_drec = "--"
+				} else {
+					this.wind_sped = res[0].others.wind_sped
+					if (22 < res[0].others.wind_drec && 67 < res[0].others.wind_drec) {
+						this.wind_drec = "东北"
+					} else if (67 < res[0].others.wind_drec && 112 > res[0].others.wind_drec) {
+						this.wind_drec = "东"
+					} else if (112 < res[0].others.wind_drec && 157 > res[0].others.wind_drec) {
+						this.wind_drec = "东南"
+					} else if (157 < res[0].others.wind_drec && 202 > res[0].others.wind_drec) {
+						this.wind_drec = "南"
+					} else if (202 < res[0].others.wind_drec && 247 > res[0].others.wind_drec) {
+						this.wind_drec = "西南"
+					} else if (247 < res[0].others.wind_drec && 292 > res[0].others.wind_drec) {
+						this.wind_drec = "西"
+					} else if (292 < res[0].others.wind_drec && 337 > res[0].others.wind_drec) {
+						this.wind_drec = "西北"
+					} else {
+						this.wind_drec = "北"
+					}
+				}
+				if (this.historydatas.length == 0) {
+					this.canvastishiTF = false
+				} else {
+					this.canvastishiTF = true
+
+					var arr1 = []
+					var arr2 = []
+					var xtitle = []
+					for (var i = 0; i < res.length; i++) {
+						var times = new Date(res[i].addtime * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getMinutes())
+						arr1.unshift(res[i].temperature==""?"0":res[i].temperature)
+						arr2.unshift(res[i].humidity==""?"0":res[i].humidity)
+					}
+					var obj = [{
+						name: '温度',
+						data: arr1,
+						color: '#00E29D'
+					}, {
+						name: '湿度',
+						data: arr2,
+						color: '#6CBBFF'
+					}]
+					this.showColumn("canvasColumnA", xtitle, obj)
+				}
+			},
+			//forecast.worm_lamp.device_history_data历史数据列表
+			async historylist() { //历史数据列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+					data: {
+						device_type_id: 4,
+						device_id: this.device_id,
+						start_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+						page: this.page
+					}
+				})
+				this.historylistdata = res.data
+				this.pagesum = Math.ceil(res.counts / 10)+1
+				if (res.data.length == 0) {
+					this.forbidden = true
+				} else {
+					this.forbidden = false
+				}
+				for (var i = 0; i < this.historylistdata.length; i++) {
+					if (res.data[i].d_h_t.bs == 0) {
+						this.historylistdata[i].d_h_t.bs = "正常"
+					} else if (res.data[i].d_h_t.bs == 1) {
+						this.historylistdata[i].d_h_t.bs = "欠压"
+					} else if (res.data[i].d_h_t.bs == 2) {
+						this.historylistdata[i].d_h_t.bs = "超压"
+					}
+				}
+				console.log(this.historylistdata)
+			},
+			changeindex(index) {
+				this.titleidnex = index
+				var now = new Date()
+				this.$forceUpdate()
+				if (index == 0) {
+					this.start_time = this.end_time - 24 * 60 * 60 * 1000
+					this.history()
+					this.historylist()
+				} else if (index == 1) {
+					var oldtime = now.setMonth(now.getMonth() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 2) {
+					var oldtime = now.setMonth(now.getMonth() - 6)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 3) {
+					var oldtime = now.setFullYear(now.getFullYear() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				}
+			},
+			prev() { //上一页
+				if (this.page > 1) {
+					this.page--
+					this.historylist()
+				}
+			},
+			next() { //下一页
+				this.page++
+				this.historylist()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showColumn(id, xtitle, xinfo) {
+				var _self = this
+				canvaColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position: "top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle,
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				console.log(e)
+				canvaColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvaColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvaColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+			async newdata() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.get_device_config',
+					data: {
+						device_type_id: 4,
+						d_id: this.d_id,
+						control_type: "data"
+					}
+				})
+				if(res){
+					uni.showToast({
+						title: '刷新成功',
+						duration: 2000,
+						icon: "none"
+					});
+					uni.navigateBack({
+						delta: 1
+					})
+				}else{
+					uni.showToast({
+						title: '刷新失败',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			refresh() { //获取当前时间的数据
+				this.newdata()
+			},
+		},
+		onLoad(option) {
+			this.d_id = option.d_id
+			this.device_id = option.device_id
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+		},
+		onShow() {
+			this.end_time = +new Date() + 1000
+			this.start_time = this.end_time - 24 * 60 * 60 * 1000
+			setTimeout(()=>{
+				this.history()
+				this.historylist()
+			},1000)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.shuju_one,
+	.shuju_two {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		height: 550rpx;
+
+		.canvastishi {
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+
+		.shuju_one_title {
+			width: 70%;
+			margin: 0 auto;
+			display: flex;
+
+			.tltle_text {
+				width: 25%;
+				border: 2rpx solid #B2B2B2;
+				color: #B2B2B2;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+
+			.title_text_color {
+				width: 25%;
+				border: 2rpx solid #28AE4F;
+				color: #28AE4F;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+		}
+	}
+
+	.wind {
+		position: absolute;
+		top: 700rpx;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding: 20rpx;
+		box-sizing: border-box;
+
+		.wind_titie {
+			border-left: 6rpx solid #26D696;
+			height: 34rpx;
+			padding-left: 20rpx;
+		}
+
+		.wind_text {
+			display: flex;
+
+			.wind_speed,
+			.wind_direction {
+				width: 50%;
+				text-align: center;
+				margin-top: 30rpx;
+
+				image {
+					width: 160rpx;
+					height: 130rpx;
+				}
+			}
+		}
+	}
+	.refresh{
+		position: absolute;
+		top: 1000rpx;
+		left: 5%;
+		width: 160rpx;
+		height: 50rpx;
+		background-color: #28AE4F;
+		color: #FFFFFF;
+		line-height: 50rpx;
+		text-align: center;
+	}
+	.condition {
+		position: absolute;
+		top: 1070rpx;
+		display: flex;
+		flex-wrap: wrap;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-bottom: 30rpx;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+			.table{
+				width: 1672px;
+			}
+			.tr {
+				display: flex;
+				overflow: hidden;
+
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 240rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+
+				.th:first-child,
+				.td:first-child {
+					width: 300rpx;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+			}
+
+			.pagenumber_page {
+				width: 100rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 429 - 0
pages/cb/xy2.0/historydatas.vue

@@ -0,0 +1,429 @@
+<template>
+	<view>
+		<view class="">
+			<view class="shuju_one">
+				<view class="shuju_one_title">
+					<view :class="titleidnex==index?'title_text_color':'tltle_text'" v-for="(item,index) in titletext" :key="index"
+					 @click="changeindex(index)">
+						{{item}}
+					</view>
+				</view>
+				<view class="canvastishi" v-if="!canvastishiTF">
+					暂无数据
+				</view>
+				<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
+				 @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+			</view>
+			<view class="refresh" @click="refresh">
+				刷 新
+			</view>
+			<view class="condition">
+				<scroll-view scroll-top="0" scroll-x="true" class="scroll-X">
+					<table class="table">
+						<tr class="tr">
+							<th class="th" v-for="(item,index) in thdata" :key="'a'+index">{{item}}</th>
+						</tr>
+						<tr class="tr" v-for="(items,indexs) in historylistdata" :key="'b'+indexs" v-if="!forbidden">
+							<td class="td">{{items.xy_addtime|timeFormat()}}</td>
+							<td class="td">{{items.at==""?"--":items.at}}</td>
+							<td class="td">{{items.ah==""?"--":items.ah}}</td>
+							<td class="td">{{items.warn==""?"--":items.warn}}</td>
+							<td class="td">{{items.b_V==""?"--":items.b_V}}</td>
+							<td class="td">{{items.b_c==""?"--":items.b_c}}</td>
+							<td class="td">{{items.p_v==""?"--":items.p_v}}</td>
+							<td class="td">{{items.p_c==""?"--":items.p_c}}</td>
+						</tr>
+						<tr class="tr" v-if="forbidden">
+							<td class="td" v-for="item in 8">暂无数据</td>
+						</tr>
+					</table>
+				</scroll-view>
+				<view class="pagenumber">
+					<button @click="prev">上一页</button>
+					<view class="pagenumber_page">
+						第 {{page}} 页
+					</view>
+					<view class="pagenumber_page">
+						共 {{pagesum}} 页
+					</view>
+					<button @click="next" :disabled="forbidden">下一页</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uCharts from '../../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvaColumnA = null;
+	export default {
+		data() {
+			return {
+				styles: {
+					// width: "650rpx",
+					height: "400rpx"
+				},
+				d_id: '',
+				start_time: "",
+				end_time: "",
+				historydatas: [],
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				titleidnex: 0,
+				device_id: '',
+				page: 1,
+				historylistdata: [],
+				thdata: ["上报时间", "环境温度(°C)", "环境湿度(%)", "虫害预警", "电池电压", "电池电流", "太阳能板电压", "太阳能板电流"],
+				forbidden: false,
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+				canvastishiTF: false,
+				pagesum: null,
+				worms:[]
+			}
+		},
+		methods: {
+			async history() { //历史数据列表折线图
+				this.Chistory()
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_line_chart',
+					data: {
+						device_id: this.device_id,
+						strat_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+						status: "at_ah"
+					}
+				})
+				this.historydatas = res
+				console.log(this.historydatas)
+				if (this.historydatas.length == 0) {
+					this.canvastishiTF = false
+				} else {
+					this.canvastishiTF = true
+					var arr1 = []
+					var arr2 = []
+					var arr3 = []
+					var xtitle = []
+					for (var i = 0; i < res.length; i++) {
+						var times = new Date(res[i].xy_addtime)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getMinutes())
+						arr1.unshift(res[i].ah == "" ? "0" : res[i].ah)
+						arr2.unshift(res[i].at == "" ? "0" : res[i].at)
+					}
+					for(var j = 0; j < this.worms.length; j++){
+						var times = new Date(res[i].xy_addtime)
+						arr3.unshift(res[i].pest_num == "" ? "0" : res[i].pest_num)
+					}
+					this.$nextTick(()=>{
+						var obj = [{
+							name: '温度',
+							data: arr1,
+							color: '#00E29D'
+						}, {
+							name: '湿度',
+							data: arr2,
+							color: '#6CBBFF'
+						},{
+							name: '诱虫次数',
+							data: arr3,
+							color: '#ff0000'
+						}]
+						this.showColumn("canvasColumnA", xtitle, obj)
+					})
+				}
+			},
+			async Chistory() { //历史数据列表折线图
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_line_chart',
+					data: {
+						device_id: this.device_id,
+						strat_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+						status: "pest"
+					}
+				})
+				this.worms = res
+			},
+			//forecast.worm_lamp.device_history_data历史数据列表
+			async historylist() { //历史数据列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_history',
+					data: {
+						device_type_id: 3,
+						device_id: this.device_id,
+						strat_time: parseInt(this.start_time / 1000),
+						end_time: parseInt(this.end_time / 1000),
+						page: this.page
+					}
+				})
+				this.historylistdata = res.data
+				console.log(res.data)
+				this.pagesum = Math.ceil(res.nums / 10) + 1
+				if (res.data.length == 0) {
+					this.forbidden = true
+				} else {
+					this.forbidden = false
+				}
+				console.log(this.historylistdata)
+			},
+			// forecast.send_control.get_device_config 获取当前时间的数据
+			async newdata() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_mqtt',
+					data: {
+						d_id: this.d_id
+					}
+				})
+				if(res){
+					uni.showToast({
+						title: '刷新成功',
+						duration: 2000,
+						icon: "none"
+					});
+					uni.navigateBack({
+						delta: 1
+					})
+				}else{
+					uni.showToast({
+						title: '刷新失败',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			refresh() { //获取当前时间的数据
+				this.newdata()
+			},
+			changeindex(index) {
+				this.titleidnex = index
+				var now = new Date()
+				this.$forceUpdate()
+				if (index == 0) {
+					this.start_time = this.end_time - 24 * 60 * 60 * 1000
+					this.history()
+					this.historylist()
+				} else if (index == 1) {
+					var oldtime = now.setMonth(now.getMonth() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 2) {
+					var oldtime = now.setMonth(now.getMonth() - 6)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				} else if (index == 3) {
+					var oldtime = now.setFullYear(now.getFullYear() - 1)
+					this.start_time = parseInt(oldtime)
+					this.history()
+					this.historylist()
+				}
+			},
+			prev() { //上一页
+				if (this.page > 1) {
+					this.page--
+					this.historylist()
+				}
+			},
+			next() { //下一页
+				this.page++
+				this.historylist()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showColumn(id, xtitle, xinfo) {
+				var _self = this
+				canvaColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position: "top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle,
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				console.log(e)
+				canvaColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvaColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvaColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+		},
+		onLoad(option) {
+			console.log(option)
+			this.d_id = option.d_id
+			this.device_id = option.device_id
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+		},
+		onShow(){
+			this.end_time = +new  Date() + 1000
+			this.start_time = this.end_time - 24 * 60 * 60 * 1000
+			setTimeout(()=>{
+				this.history()
+				this.historylist()
+			},1000)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.shuju_one,
+	.shuju_two {
+		position: absolute;
+		top: 10px;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		height: 550rpx;
+
+		.canvastishi {
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+
+		.shuju_one_title {
+			width: 70%;
+			margin: 0 auto;
+			display: flex;
+
+			.tltle_text {
+				width: 25%;
+				border: 2rpx solid #B2B2B2;
+				color: #B2B2B2;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+
+			.title_text_color {
+				width: 25%;
+				border: 2rpx solid #28AE4F;
+				color: #28AE4F;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+		}
+	}
+
+	.refresh {
+		position: absolute;
+		top: 630rpx;
+		left: 5%;
+		width: 160rpx;
+		height: 50rpx;
+		background-color: #28AE4F;
+		color: #FFFFFF;
+		line-height: 50rpx;
+		text-align: center;
+	}
+
+	.condition {
+		position: absolute;
+		top: 720rpx;
+		display: flex;
+		flex-wrap: wrap;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-bottom: 30rpx;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+			.table{
+				width: 1042px;
+			}
+			.tr {
+				display: flex;
+				overflow: hidden;
+
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 240rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+
+				.th:first-child,
+				.td:first-child {
+					width: 300rpx;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+			}
+
+			.pagenumber_page {
+				width: 100rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>
+

+ 430 - 0
pages/cb/xy2.0/particulars.vue

@@ -0,0 +1,430 @@
+<template>
+	<view>
+		<view class="">
+			<view :class="['info',equipInfo.is_online==1?'on':'off']">
+				<p @click="copy(newState.device_id)">设备ID:{{newState.device_id}}<image src="http://static.yfpyx.com/bigdata_app/image/environment/fuzhi.png" mode="" class="tishi"></image></p>
+				<p>设备名称:{{newState.device_name}}</p>
+				<p>最新上报时间:{{newState.uptime | timeFormat}}</p>
+				<p>最新地址:{{newState.addr}}</p>
+				<p class="fillin" @click="addxy">测报害虫:<input type="text" v-model="newState.decoy" disabled v-if="newState.decoy"/><u-icon name="edit-pen" color="#f0ad4e" size="28"></u-icon></p>
+				<p @click="glass_show=true">诱芯更换时间:<span style="margin:0 20rpx;">{{yxchangetime}}</span><u-icon name="edit-pen" color="#f0ad4e" size="28"></u-icon></p>
+				<p @click="glass_showtwo=true">诱芯到期时间:<span style="margin:0 20rpx;">{{yxendtime}}</span><u-icon name="edit-pen" color="#f0ad4e" size="28"></u-icon></p>
+				<u-calendar v-model="glass_show" mode="date" @change="timeChange"></u-calendar>
+				<u-calendar v-model="glass_showtwo" mode="date" :max-date="date" @change="timeChangetwo"></u-calendar>
+			</view>
+			<view class="control">
+				<view class="control_item" @click="repairs">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/7.png'" mode=""></image>
+					<p>一键报修</p>
+				</view>
+				<view class="control_item" @click="toggle">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/cb/2.png'" mode=""></image>
+					<p>历史数据</p>
+				</view>
+			</view>
+			<view class="realtime">
+				<view class="realtime_title">
+					<p>实时数据</p>
+				</view>
+				<view class="realtime_text">
+					<view class="realtime_item">
+						<image src="http://static.yfpyx.com/bigdata_app/image/cb/xy2.0/wendu.png" mode=""></image>
+						<view class="text">
+							<p>环境温度</p>
+							<p>{{newState.at}}℃</p>
+						</view>
+					</view>
+					<view class="realtime_item">
+						<image src="http://static.yfpyx.com/bigdata_app/image/cb/xy2.0/shidu.png" mode=""></image>
+						<view class="text">
+							<p>环境湿度</p>
+							<p>{{newState.ah}}%</p>
+						</view>
+					</view>
+					<view class="realtime_item">
+						<image src="http://static.yfpyx.com/bigdata_app/image/cb/xy2.0/tianqi.png" mode=""></image>
+						<view class="text">
+							<p>天气</p>
+							<p>{{newState.type}}</p>
+						</view>
+					</view>
+					<view class="realtime_item">
+						<image src="http://static.yfpyx.com/bigdata_app/image/cb/xy2.0/xiayu.png" mode=""></image>
+						<view class="text">
+							<p>是否下雨</p>
+							<p>{{newState.rain}}</p>
+						</view>
+					</view>
+					<view class="realtime_item">
+						<image src="http://static.yfpyx.com/bigdata_app/image/cb/xy2.0/fengxiang.png" mode=""></image>
+						<view class="text">
+							<p>风力风向</p>
+							<p>{{newState.wind}}</p>
+						</view>
+					</view>
+					<view class="realtime_item">
+						<image src="http://static.yfpyx.com/bigdata_app/image/cb/xy2.0/yujing.png" mode=""></image>
+						<view class="text">
+							<p>虫害情报</p>
+							<p>{{newState.warn==""?"暂无":newState.warn}}</p>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="sim" v-if="simTF">
+				<p class="sim_title">sim卡详情</p>
+				<view class="sim_text">
+					<p class="p">ICCID:{{simdata.iccid}}</p>
+					<p class="p">状态:{{simstate[simdata.account_status]}}</p>
+					<view class="sim_plan">
+						套餐流量:
+						<view class="sim_plan_text">
+							<p style="width: 100%;"></p>
+						</view>
+						{{simdata.data_plan}}MB
+					</view>
+					<view class="sim_plan">
+						已用流量:
+						<view class="sim_plan_text">
+							<p :style="{width:usedBeliel+'%'}"></p>
+						</view>
+						{{simdata.data_plan - simdata.data_balance.toFixed(2)}}MB
+					</view>
+					<view class="sim_plan">
+						剩余流量:
+						<view class="sim_plan_text">
+							<p :style="{width:residueBeliel+'%'}"></p>
+						</view>
+						{{simdata.data_balance.toFixed(2)}}MB
+					</view>
+					<p class="p">到期时间:{{simdata.expiry_date | timeFormat}}</p>
+				</view>
+			</view>
+			<u-popup v-model="yxShow" mode="center" width="600rpx">
+				<u-field label="害虫名称" label-width='240' required :error-message="xyErr" v-model="decoy" class="field">
+				</u-field>
+				<view class="btn-box">
+					<u-button @click="yxSubmit" size="mini" type="success" class="box-item">确定</u-button>
+				</view>
+			</u-popup>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				equipInfo:[],
+				newState:{},
+				simdata:{},
+				simstate:['未知','测试期','沉默期','使用中','停机','停机保号','预销号','销号'],
+				usedBeliel:'',
+				residueBeliel:"",
+				simTF:false,
+				expiretext:"",
+				yxShow:false,
+				xyErr:"",
+				decoy:"",
+				yxchangetime:0,//更换诱芯时间
+				yxendtime:0,//诱芯到期时间
+				glass_show:false,//更换诱芯时间选择
+				glass_showtwo:false,//诱芯到期时间选择
+				date:""
+			}
+		},
+		methods: {
+			async getState(d_id) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_details',
+					data: {
+						d_id: d_id,
+					}
+				})
+				this.newState = res[0]
+				if(res[0].xy_expire_time==0){
+					this.yxendtime = "暂无"
+				}else{
+					var times = new Date(res[0].xy_expire_time*1000)
+					var month = times.getMonth()+1
+					month = month<10?"0"+month:month
+					var date = times.getDate()<10?"0"+times.getDate():times.getDate()
+					this.yxendtime = times.getFullYear() + "-" + month + "-" + date
+				}
+				if(res[0].xy_uptime==0){
+					this.yxendtime = "暂无"
+				}else{
+					var times = new Date(res[0].xy_uptime*1000)
+					var month = times.getMonth()+1
+					month = month<10?"0"+month:month
+					var date = times.getDate()<10?"0"+times.getDate():times.getDate()
+					this.yxchangetime = times.getFullYear() + "-" + month + "-" + date
+				}
+			},
+			async getSim(d_id) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_sim',
+					data: {
+						d_id: d_id,
+					}
+				})
+				console.log(res)
+				if(res.data != null){
+					this.simdata = res.data.card_list[0]
+					this.usedBeliel = (this.simdata.data_plan-this.simdata.data_balance)/ this.simdata.data_plan *100
+					this.residueBeliel = this.simdata.data_balance/this.simdata.data_plan * 100
+					this.simTF = true
+				}else{
+					this.simTF = false
+				}
+			},
+			async getworm(data,info) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_set_lure',
+					data: data
+				})
+				console.log(res)
+				if(res.code == 200){
+					uni.showToast({
+						title: "设置成功",
+						icon: "none"
+					})
+					if(data.expire_time){
+						this.yxendtime = info
+					}else if(data.pest_name){
+						this.newState.decoy = info
+					}else if(data.addtime){
+						this.yxchangetime = info
+					}
+				}
+			},
+			toggle(){
+				uni.navigateTo({
+					url:"./historydatas?device_id="+this.equipInfo.device_id + "&d_id=" + this.equipInfo.d_id
+				})
+			},
+			addxy(){
+				this.yxShow =true
+				this.decoy = this.newState.decoy
+			},
+			yxSubmit(){
+				if(this.decoy == ""){
+					this.xyErr = "请填写害虫名称"
+				}else{
+					this.xyErr = ""
+					var obj = {
+						d_id: this.equipInfo.d_id,
+						pest_name:this.decoy
+					}
+					this.getworm(obj,this.decoy)
+					console.log(this.decoy)
+					this.yxShow =false
+				}
+			},
+			timeChange(e){
+				console.log(e)
+				var obj = {
+					d_id: this.equipInfo.d_id,
+					addtime:+new Date(e.result)/1000
+				}
+				this.getworm(obj,e.result)
+			},
+			timeChangetwo(e){
+				console.log(e)
+				var obj = {
+					d_id: this.equipInfo.d_id,
+					expire_time:+new Date(e.result)/1000
+				}
+				this.getworm(obj,e.result)
+			},
+			copy(item){
+				console.log(item)
+				uni.setClipboardData({
+				    data: item,
+				    success: function () {
+				        console.log('success');
+				    }
+				});
+			},
+			repairs(){
+				uni.navigateTo({
+					url: "../../afterSale/addafter?device_id="+ this.newState.device_id +"&device_type="+ 10
+				})
+			}
+		},
+		onLoad(option) {
+			this.equipInfo = JSON.parse(option.info)
+			console.log(this.equipInfo)
+			this.getState(this.equipInfo.d_id)
+			this.getSim(this.equipInfo.d_id)
+			var times = new Date()
+			this.date = times.getFullYear()+1 + "-" + Number(times.getMonth()+1) + "-" + times.getDate()
+			console.log(this.date)
+			// uni.getStorage({ 待开发
+			// 	key:"jurisdiction",
+			// 	success:(res)=>{
+			// 		console.log(JSON.parse(res.data))
+			// 		let items = JSON.parse(res.data).filter((item)=>{
+			// 			return item.purview_name == "测报系统"
+			// 		})
+			// 		let items2 = items[0].children.filter((item)=>{
+			// 			return item.purview_name == "性诱2.0"
+			// 		})
+			// 		console.log(items2)
+			// 	},
+			// })	
+		}
+	}
+</script>
+
+<style lang="scss">
+	.info {
+		padding: 20rpx 40rpx;
+		color: #fff;
+		line-height: 50rpx;
+		font-size: 26rpx;
+		background-size: 100% auto;
+		background-repeat: no-repeat;
+		background-color: #0DC6B6;
+		background-position: top left;
+		box-sizing: border-box;
+		width: 95%;
+		margin: 0 auto;
+		p:first-child{
+			font-size: 32rpx;
+		}
+		.expiretishi{
+			font-size: 24rpx;
+			color: #FF0000;
+		}
+		.tishi{
+			width: 28rpx;
+			height: 28rpx;
+			margin: 0rpx 0 0 20rpx;
+		}
+		.fillin{
+			display: flex;
+			input{
+				width: 200rpx;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				text-indent: 1em;
+			}
+		}
+	}
+
+	.on {
+		background-image: url('http://static.yfpyx.com/bigdata_app/image/cb/onBg.png')
+	}
+
+	.off {
+		background-image: url('http://static.yfpyx.com/bigdata_app/image/cb/offBg.png')
+	}
+	.control {
+		width: 90%;
+		display: flex;
+		text-align: center;
+		box-sizing: border-box;
+		margin: 30rpx auto;
+		.control_item {
+			width: 120rpx;
+			height: 120rpx;
+			margin-right: 40rpx;
+			image {
+				width: 70rpx;
+				height: 70rpx;
+			}
+	
+			p {
+				font-size: 24rpx;
+			}
+		}
+	}
+	
+	.realtime{
+		width: 95%;
+		margin: 0rpx auto;
+		.realtime_title{
+			font-size: 36rpx;
+			display: flex;
+			justify-content: space-between;
+			.span{
+				color: #6e6c76;
+				font-size: 24rpx;
+				display: flex;
+				justify-content: space-between;
+				margin-top: 12rpx;
+			}
+		}
+		.realtime_text{
+			margin-top: 20rpx;
+			display: flex;
+			justify-content: space-between;
+			flex-wrap: wrap;
+			.realtime_item{
+				width: 48%;
+				height: 100rpx;
+				display: flex;
+				box-shadow: 0 0 10rpx #bcb9ca;
+				margin-top: 20rpx;
+				padding: 20rpx 0;
+				image{
+					width: 60rpx;
+					height: 60rpx;
+					margin: 20rpx 20rpx 20rpx 40rpx;
+				}
+				.text{
+					padding: 10rpx 0 10rpx 30rpx;
+				}
+			}
+		}
+	}
+	.sim{
+		width: 95%;
+		margin: 40rpx auto;
+		.sim_title{
+			font-size: 36rpx;
+		}
+		.sim_text{
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 30rpx;
+			margin-top: 40rpx;
+			.p{
+				margin-top: 20rpx;
+			}
+			.sim_plan{
+				display: flex;
+				margin-top: 20rpx;
+				.sim_plan_text{
+					width: 60%;
+					height: 16rpx;
+					background-color: #cccccc;
+					border-radius:8rpx ;
+					margin: 10rpx 20rpx 0 0;
+					p{
+						height: 16rpx;
+						background-color: #0dc6b6;
+						border-radius:8rpx ;
+					}
+				}
+			}
+		}
+	}
+	.field {
+		/deep/.fild-body{
+			margin-left: -30px;
+		}
+		/deep/.uni-input-input {
+			border: 2rpx solid #FF0000;
+			border-radius: 24rpx;
+			width: 140px;
+			padding-left: 20rpx;
+			box-sizing: border-box;
+		}
+	}
+	.btn-box {
+		text-align: center;
+		padding: 20rpx 30rpx;
+	}
+</style>

+ 318 - 0
pages/disandpests/index.vue

@@ -0,0 +1,318 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 44px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="病虫害识别"></uni-nav-bar>
+			</view>
+			<view class="image_box">
+				<image :src="path" mode="" class="image" @click="examine(path)"></image>
+			</view>
+			<view class="recognition" v-if="datasTF">
+				<p class="recognition_title">{{name}}</p>
+				<view :class="tishi?'recognition_img':'recognition_img_two'">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+path2" mode="" @error="error" @click="examine(path2)"></image>
+				</view>
+				<button class="recognition_details" v-if="tishi" @click="examines">查看详情</button>
+				<button class="recognition_details" v-if="!tishi" @click="show=!show">再拍一张</button>
+			</view>
+			<view class="datas" v-else>
+				<p class="datas_title">{{name}}</p>
+				<view v-for="(item,index) in preventionArr" :key="index" class="prevention">
+					<view class="prevention_title">
+						<u-icon name="play-right-fill" size="24" color="#55A92D"></u-icon>
+						<p>{{regexptitle[index]}}:</p>
+					</view>
+					<p class="prevention_con">{{item}}</p>
+				</view>
+				<button class="recognition_details" v-if="tishi" @click="examines">查看图片</button>
+			</view>
+			<u-modal v-model="show" :mask-close-able="true" title="" :show-cancel-button="true" confirm-text="拍病害" cancel-text="拍虫害"
+			 content="拍照识别病虫害" @confirm="confirm" @cancel="cancel"></u-modal>
+		</view>
+		<kps-image-cutter @ok="onok" @cancel="oncancle" :url="imgdata" :fixed="false" :blob="true"></kps-image-cutter>
+		<view class="loading" v-if="loadTF">
+			<u-loading  mode="flower" size="100" :show="true" ></u-loading>
+		</view>
+	</view>
+</template>
+
+<script>
+	import kpsImageCutter from "@/components/ksp-image-cutter/ksp-image-cutter.vue";
+	export default {
+		components: {
+			kpsImageCutter
+		},
+		data() {
+			return {
+				path: "",
+				path2: "",
+				tishi: true,
+				name: "",
+				prevention: "",
+				datasTF: true,
+				show: false,
+				imgdata: "",
+				preventionArr: [],
+				regexptitle: [],
+				loadTF:false
+			}
+		},
+		methods: {
+			clickLeft() {
+				uni.switchTab({
+					url: "../index/index"
+				})
+			},
+			examines() {
+				this.datasTF = !this.datasTF
+			},
+			confirm() {
+				this.flag = 1
+				var that = this
+				// console.log(1)
+				uni.chooseImage({
+					count: 1, //默认9
+					// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['camera', 'album'], //从相册选择
+					success: (res) => {
+						that.imgdata = res.tempFilePaths[0]
+						that.path = res.tempFilePaths[0]
+					},
+				});
+			},
+			cancel() {
+				var that = this
+				this.flag = 2
+				uni.chooseImage({
+					count: 1, //默认9
+					// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['camera', 'album'], //从相册选择
+					success: (res) => {
+						that.imgdata = res.tempFilePaths[0]
+						that.path = res.tempFilePaths[0]
+					}
+				});
+			},
+			onok(ev) {
+				this.loadTF = !this.loadTF
+				if (this.flag == 2) {
+					// pest.pests.insect_discern 虫害
+					uni.uploadFile({
+						// url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+						url: 'http://182.92.193.64:8002/api/api_gateway?method=pest.pests.insect_discern', //仅为示例,非真实的接口地址
+						filePath: ev.path,
+						name: 'img_file',
+						formData: {
+							'user': 'test'
+						},
+						success: (uploadFileRes) => {
+							console.log(JSON.parse(uploadFileRes.data))
+							this.loadTF = !this.loadTF
+							this.optionverify(JSON.parse(uploadFileRes.data).data)
+						}
+					});
+				} else if (this.flag == 1) {
+					//pest.pests.insect_discern病害识别
+					uni.uploadFile({
+						// url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+						url: 'http://182.92.193.64:8002/api/api_gateway?method=pest.pests.plant_discern', //仅为示例,非真实的接口地址
+						filePath: ev.path,
+						name: 'img_file',
+						formData: {
+							'user': 'test'
+						},
+						success: (uploadFileRes) => {
+							console.log(JSON.parse(uploadFileRes.data))
+							this.loadTF = !this.loadTF
+							this.optionverify(JSON.parse(uploadFileRes.data).data)
+						}
+					});
+				}
+				this.imgdata = "";
+			},
+			oncancle() {
+				// url设置为空,隐藏控件
+				this.imgdata = ''
+			},
+			error() {
+				this.path2 = "/image/e1cd85dc59139760f43ddbac15136f2.png"
+			},
+			optionverify(data) {
+				console.log(data)
+				if (data == null) {
+					this.name = "识别失败,请换张图片"
+					this.tishi = false
+					this.path2 = "/image/10ca93e17420371a82826073c8425c0.png"
+				} else {
+					if(data.img_urls==""){
+						this.path2 = "/image/e1cd85dc59139760f43ddbac15136f2.png"
+					}else{
+						this.path2 = data.img_urls
+					}
+					this.name = data.name
+					this.tishi = true
+					this.prevention = data.prevention
+					var regex2 = /\[(.+?)\]/g; // [] 中括号
+					var str = this.prevention
+					var arr = str.match(regex2)
+					var arrindex = []
+					for (var i = 0; i < arr.length; i++) {
+						arrindex.push(str.indexOf(arr[i]))
+					}
+					for (var i = 0; i < arr.length; i++) {
+						if(str.slice(arrindex[i] + arr[i].length, arrindex[i + 1]) == " null" || str.slice(arrindex[i] + arr[i].length, arrindex[i + 1])== "" ||str.slice(arrindex[i] + arr[i].length, arrindex[i + 1]) == "null"){
+							this.preventionArr.push("暂无信息")
+						}else{
+							this.preventionArr.push(str.slice(arrindex[i] + arr[i].length, arrindex[i + 1]))
+						}
+					}
+					
+					for (var i = 0; i < arr.length; i++) {
+						arr[i] = arr[i].slice(1, arr[i].length - 1)
+					}
+					this.regexptitle = arr
+				}
+			},
+			examine(url) {
+				var imgarr =[]
+				imgarr.push(url)
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			},
+		},
+		onLoad(option) {
+			console.log(option)
+			this.path = option.path
+			this.optionverify(JSON.parse(option.datas).data)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.loading{
+		position: absolute;
+		top: 0;
+		left: 0;
+		z-index: 100;
+		width:100%;
+		height: 100vh;
+		background-color: rgba(0,0,0,0.5);
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+	.image_box {
+		position: absolute;
+		top: 44px;
+		width: 100%;
+		height: 400rpx;
+
+		.image {
+			width: 100%;
+			height: 400rpx;
+		}
+	}
+
+	.recognition {
+		position: absolute;
+		top: 254px;
+		width: 100%;
+		height: 800rpx;
+
+		.recognition_title {
+			width: 100%;
+			text-align: center;
+			font-size: 36rpx;
+			font-weight: 700;
+			margin: 60rpx 0;
+		}
+
+		.recognition_img {
+			border: 2rpx dashed #06B535;
+			width: 450rpx;
+			height: 450rpx;
+			border-radius: 50%;
+			margin: 0 auto;
+			text-align: center;
+			line-height: 450rpx;
+
+			image {
+				margin-top: 50rpx;
+				width: 340rpx;
+				height: 340rpx;
+			}
+		}
+
+		.recognition_img_two {
+			width: 450rpx;
+			height: 450rpx;
+			border-radius: 50%;
+			margin: 0 auto;
+			text-align: center;
+			line-height: 450rpx;
+
+			image {
+				margin-top: 10rpx;
+				width: 340rpx;
+				height: 340rpx; 
+			}
+		}
+		.recognition_details {
+			width: 400rpx;
+			height: 80rpx;
+			border-radius: 40rpx;
+			margin: 30rpx auto;
+			font-size: 30rpx;
+			background-color: #67B25F;
+			color: #FFFFFF;
+		}
+	}
+
+	.datas {
+		position: absolute;
+		top: 284px;
+		width: 95%;
+		left: 2.5%;
+
+		.datas_title {
+			font-size: 32rpx;
+			font-weight: 700;
+			margin-left: 30rpx;
+		}
+
+		.recognition_details {
+			width: 400rpx;
+			height: 80rpx;
+			border-radius: 40rpx;
+			margin: 30rpx auto;
+			font-size: 30rpx;
+			background-color: #67B25F;
+			color: #FFFFFF;
+		}
+	}
+
+	.prevention {
+		font-size: 28rpx;
+		color: #919191;
+		width: 95%;
+		margin: 20rpx auto;
+
+		.prevention_title {
+			display: flex;
+
+			p {
+				margin-left: 20rpx;
+				color: #000000;
+				font-size: 28rpx;
+				font-weight: 700;
+			}
+		}
+
+		.prevention_con {
+			padding-left: 6%;
+		}
+	}
+</style>

+ 820 - 0
pages/distribution/index.vue

@@ -0,0 +1,820 @@
+<!-- <template>
+	<view>
+		<view class="page-body">
+			<view class="utabs">
+				<view style="width: 95%;margin: 0 auto;">
+					<u-tabs :list="list" :is-scroll="true" :current="current" @change="change" item-width="140" font-size="24" gutter="20"
+					 bar-width="60" active-color="#42b983"></u-tabs>
+				</view>
+			</view>
+			<view class="LocationAndDetails">
+				<view class="search">
+					<input type="text" v-model="device_id" placeholder="请输入设备ID"/>
+				</view>
+				<view class="Location">
+					<view class="particulars_par" @click="eqinfo">
+						查看详情
+					</view>
+					<view class="particulars_ser" @click="serTFs">
+						查看位置
+					</view>
+				</view>
+			</view>
+			<view class="page-section page-section-gap">
+				<map class="map" scale="3" :markers="covers" :enable-zoom="true"
+				 @markertap="markertap" >
+				</map>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				id: 0, // 使用 marker点击事件 需要填写id
+				title: 'map',
+				covers: [],
+				list: [{
+					name: "全部"
+				}, {
+					name: "杀虫灯"
+				}, {
+					name: "测报灯"
+				}, {
+					name: "性诱测报"
+				}, {
+					name: "环境检测"
+				}, {
+					name: "监控设备"
+				}, {
+					name: "孢子仪",
+				},{
+					name: "性诱2.0"
+				}],
+				current: 0,
+				icon: [{
+						id: '', //全部
+						url: "../../static/images/distribution/7610e3983eb33ed5b9ad72ebdfc8ed2.png"
+					},
+					{
+						id: 2, //杀虫灯
+						url: "../../static/images/distribution/1bd535eb7dbb0809940030d40c64b4c.png"
+					},
+					{
+						id: 3, //测报灯
+						url: "../../static/images/distribution/0b551e50be351dbc14f0dd6470e3443.png"
+					},
+					{
+						id: 4, //性诱测报
+						url: "../../static/images/distribution/be5c1cfed22713a9544f020cf41c25f.png"
+					},
+					{
+						id: 5, //环境检测
+						url: "../../static/images/distribution/8325b1b6079456ce43f952ce13d2919.png"
+					},
+					{
+						id: 6, //监控设备
+						url: "../../static/images/distribution/2eb9e550709430a1bd8178568c14785.png"
+					},
+					{
+						id: 7, //孢子仪
+						url: "../../static/images/distribution/54a96e2b0ad4efeecbd4a7b5e6deda3.png"
+					},
+					{
+						id: 10, //性诱2.0
+						url: "../../static/images/distribution/515ea6143e0aaff4a823270c7aa00a6.png"
+					},
+				],
+				type: '', //设备类型
+				typeindex: null, //设备选择
+				device_id: '', //设备号
+				serTF: false, //设备搜索显示隐藏
+				punctuationTF: false, //判断是否以点击标点
+				punctuation_id: "", //点击标点的id
+				punctuation_did: '',
+				punctuation_type: '',
+				listindex:1,//以选择设备名称
+				disstyle:{
+					position:"absolute",
+					bottom:"0rpx"
+				},
+				facilitydatas:[]
+			}
+		},
+		onLoad() {
+			this.history()
+		},
+		methods: {
+			async history() { //获取分布位置
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.equip_map_location',
+					data: {
+						equip_type: this.type,
+						device_id: this.device_id
+					}
+				})
+				console.log(res)
+				this.covers = []
+				for (var i = 0; i < res.length; i++) {
+					var obj = {}
+					obj.latitude = Number(res[i].lat)
+					obj.longitude = Number(res[i].lng)
+					obj.id = parseInt(i)
+					obj.title = res[i].device_name || res[i].device_id
+					obj.width = 30
+					obj.height = 30
+					for (var j = 0; j < this.icon.length; j++) {
+						if (res[i].device_type_id == this.icon[j].id) {
+							obj.iconPath = this.icon[j].url
+						}
+					}
+					this.covers.push(obj)
+				}
+				this.facilitydatas = res
+				if(res.length == 0){
+					uni.showToast({
+						title: '未查询到设备',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			change(index) {
+				console.log(index)
+				this.current = index
+				if (index == 0) {
+					this.type = ''
+				} else if(index == 7){
+					this.type = index + 3
+				} else {
+					this.type = index + 1
+				}
+				this.history()
+			},
+			markertap(e) {
+				console.log(e)
+				console.log(this.facilitydatas[e.detail.markerId])
+				this.device_id = this.facilitydatas[e.detail.markerId].device_id
+				this.punctuation_did = this.facilitydatas[e.detail.markerId].d_id
+				this.punctuation_type = this.facilitydatas[e.detail.markerId].device_type_id
+			},
+			serTFs() {
+				this.history()
+			},
+			eqinfo() { //设备信息
+				if (this.punctuation_type == '') {
+					uni.showToast({
+						title: '请点击需查看的设备',
+						duration: 2000,
+						icon: "none"
+					});
+				} else {
+					switch (this.punctuation_type) {
+						case 2:
+							uni.navigateTo({
+								url: "../prevention/ucharts?d_id=" + this.punctuation_did + "&imei=" + this.device_id
+							})
+							break;
+						case 3:
+							uni.navigateTo({
+								url: "../cb/cbd/equip-set/historyfile?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 4:
+							uni.navigateTo({
+								url: "../cb/xy/equip-set/xyhistoryile?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 5:
+							uni.navigateTo({
+								url: "../environment/history?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 6:
+							// uni.navigateTo({
+							// 	url: "../prevention/ucharts?d_id=" + this.punctuation_did + "&device_id=" + this.punctuation_id
+							// })
+							break;
+						case 7:
+							uni.navigateTo({
+								url: "../cb/bzy/equip-set/bzyhistoryile?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 10:
+							uni.navigateTo({
+								url:"../cb/xy2.0/historydatas?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+					}
+
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.utabs {
+		width: 100%;
+		position: fixed;
+		top: 0px;
+		z-index: 100;
+		background-color: #FFFFFF;
+	}
+	.LocationAndDetails{
+		width: 100%;
+		height: 200rpx;
+		position: fixed;
+		top: 54px;
+		.search{
+			display: flex;
+			input{
+				width: 90%;
+				font-size: 28rpx;
+				margin-left: 40rpx;
+				border: 1px solid #cfccc9;
+				height: 60rpx;
+				padding-left: 15px;
+				box-sizing: border-box;
+				border-radius: 60rpx;
+			}
+		}
+		.Location{
+			display: flex;
+			margin-top: 20rpx;
+			justify-content: space-around;
+			.particulars_par {
+				background-color: #F1F1F1;
+				text-align: center;
+				width: 40%;
+				height: 80rpx;
+				line-height: 80rpx;
+				font-size: 28rpx;
+				border-radius: 40rpx;
+			}
+			.particulars_ser {
+				background-color: #57C87B;
+				text-align: center;
+				width: 40%;
+				height: 80rpx;
+				line-height: 80rpx;
+				font-size: 28rpx;
+				color: #FFFFFF;
+				border-radius: 40rpx;
+			}
+		}
+	}
+	.page-section {
+		margin-top: 144px;
+		height: 80vh;
+		// position: fixed;
+		// top: 144px;
+		.map{
+			width: 100%;
+			height: 100%;
+		}
+	}
+	.particulars {
+		width: 100%;
+		height: 160rpx;
+		position: absolute;
+		bottom: 0;
+		.search_btn_top {
+			width: 100%;
+			height: 80rpx;
+			line-height: 80rpx;
+			font-size: 32rpx;
+			padding-left: 30rpx;
+			box-sizing: border-box;
+		}
+		.search_btn_bot {
+			width: 100%;
+			display: flex;
+		}
+		
+	}
+
+	.distri_ser {
+		position: absolute;
+		bottom: 0rpx;
+		right: 0px;
+		width: 100%;
+		height: 440rpx;
+		background-color: #FFFFFF;
+		.distri_ser_input {
+			width: 90%;
+			margin: 20rpx auto;
+			display: flex;
+			background-color: #F1F1F1;
+			height: 60rpx;
+			border-radius: 30rpx;
+			padding: 10rpx 20rpx;
+			box-sizing: border-box;
+
+			input {
+				width: 90%;
+				font-size: 28rpx;
+				margin-right: 20rpx;
+			}
+		}
+
+		.distri_ser_title {
+			width: 90%;
+			margin: 0 auto;
+			padding-left: 20rpx;
+			border-left: 4rpx solid #57C87B;
+			font-size: 28rpx;
+		}
+
+		.distri_ser_type {
+			width: 90%;
+			margin: 20rpx auto;
+			display: flex;
+			justify-content: space-around;
+
+			.type_items {
+				height: 120rpx;
+				width: 120rpx;
+				padding: 20rpx 0;
+			}
+
+			.type_items_bor {
+				height: 120rpx;
+				width: 120rpx;
+				border: 2rpx solid #57C87B;
+				padding: 20rpx 0;
+			}
+
+			.type_items_img {
+				width: 70rpx;
+				height: 70rpx;
+				margin-left: 20rpx;
+			}
+
+			.type_items_p {
+				font-size: 24rpx;
+				text-align: center;
+			}
+		}
+	}
+
+	.search_btn {
+		width: 100%;
+		display: flex;
+
+		.btn_f,
+		.btn_t {
+			width: 50%;
+			text-align: center;
+			height: 80rpx;
+			line-height: 80rpx;
+			font-size: 28rpx;
+		}
+
+		.btn_f {
+			background-color: #F1F1F1;
+		}
+
+		.btn_t {
+			background-color: #57C87B;
+			color: #FFFFFF;
+		}
+	}
+</style> -->
+<template>
+	<view>
+		<view class="page-body">
+			<view class="utabs">
+				<view style="width: 95%;margin: 0 auto;">
+					<u-tabs :list="list" :is-scroll="true" :current="current" @change="change" item-width="140" font-size="24" gutter="20"
+					 bar-width="60" active-color="#42b983"></u-tabs>
+				</view>
+			</view>
+			<view class="LocationAndDetails">
+				<view class="search">
+					<input type="text" v-model="device_id" placeholder="请输入设备ID"/>
+				</view>
+				<view class="Location">
+					<view class="particulars_par" @click="eqinfo">
+						查看详情
+					</view>
+					<view class="particulars_ser" @click="serTFs">
+						查看位置
+					</view>
+				</view>
+			</view>
+			<view class="page-section page-section-gap">
+				<map class="map" scale="3" :markers="covers" :enable-zoom="true"
+				 @markertap="markertap" >
+				</map>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				id: 0, // 使用 marker点击事件 需要填写id
+				title: 'map',
+				covers: [],
+				list: [{
+					name: "全部"
+				}],
+				current: 0,
+				icon: [{
+						id: '', //全部
+						url: "../../static/images/distribution/7610e3983eb33ed5b9ad72ebdfc8ed2.png",
+						name: "全部"
+					},
+					{
+						id: 2, //杀虫灯
+						url: "../../static/images/distribution/1bd535eb7dbb0809940030d40c64b4c.png",
+						name: "杀虫灯"
+					},
+					{
+						id: 3, //测报灯
+						url: "../../static/images/distribution/0b551e50be351dbc14f0dd6470e3443.png",
+						name: "测报灯"
+					},
+					{
+						id: 4, //性诱测报
+						url: "../../static/images/distribution/be5c1cfed22713a9544f020cf41c25f.png",
+						name: "性诱测报"
+					},
+					{
+						id: 5, //环境检测
+						url: "../../static/images/distribution/8325b1b6079456ce43f952ce13d2919.png",
+						name: "环境检测"
+					},
+					{
+						id: 6, //监控设备
+						url: "../../static/images/distribution/2eb9e550709430a1bd8178568c14785.png",
+						name: "监控设备"
+					},
+					{
+						id: 7, //孢子仪
+						url: "../../static/images/distribution/54a96e2b0ad4efeecbd4a7b5e6deda3.png",
+						name: "孢子仪",
+					},
+					{
+						id: 10, //性诱2.0
+						url: "../../static/images/distribution/515ea6143e0aaff4a823270c7aa00a6.png",
+						name: "性诱2.0"
+					},
+				],
+				type: '', //设备类型
+				typeindex: null, //设备选择
+				device_id: '', //设备号
+				serTF: false, //设备搜索显示隐藏
+				punctuationTF: false, //判断是否以点击标点
+				punctuation_id: "", //点击标点的id
+				punctuation_did: '',
+				punctuation_type: '',
+				listindex:1,//以选择设备名称
+				disstyle:{
+					position:"absolute",
+					bottom:"0rpx"
+				},
+				facilitydatas:[],
+			}
+		},
+		onShow() {
+			this.device_id = ""
+			this.list = [{
+					name: "全部"
+				}]
+			uni.getStorage({
+				key: "jurisdiction",
+				success: (res) => {
+					console.log(JSON.parse(res.data))
+					var res = JSON.parse(res.data)
+					for (var i = 0; i < res.length; i++) {
+						switch (res[i].purview_name) {
+							case "测报系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name=="虫情测报灯"?"测报灯":res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+							case "监控系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+							case "环境监测系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+							case "防治系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+						}
+					}
+					for (var i = 0; i < this.icon.length; i++) {
+						if (this.list[0].name == this.icon[i].name) {
+							this.type = this.icon[i].id
+						}
+					}
+					this.history()
+				},
+			})
+		},
+		methods: {
+			async history() { //获取分布位置
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.equip_map_location',
+					data: {
+						equip_type: this.type,
+						device_id: this.device_id
+					}
+				})
+				console.log(res)
+				this.covers = []
+				for (var i = 0; i < res.length; i++) {
+					var obj = {}
+					obj.latitude = Number(res[i].lat)
+					obj.longitude = Number(res[i].lng)
+					obj.id = parseInt(i)
+					obj.title = res[i].device_name || res[i].device_id
+					obj.width = 30
+					obj.height = 30
+					for (var j = 0; j < this.icon.length; j++) {
+						if (res[i].device_type_id == this.icon[j].id) {
+							obj.iconPath = this.icon[j].url
+						}
+					}
+					this.covers.push(obj)
+				}
+				this.facilitydatas = res
+				if(res.length == 0){
+					uni.showToast({
+						title: '未查询到设备',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			change(index) {
+				console.log(index)
+				this.current = index
+				if (index == 0) {
+					this.type = ''
+				}else{
+					for (var i = 0; i < this.icon.length; i++) {
+						if (this.list[index].name == this.icon[i].name) {
+							console.log(this.icon[i].id)
+							this.type = this.icon[i].id
+						}
+					}
+				}
+				this.history()
+			},
+			markertap(e) {
+				console.log(e)
+				console.log(this.facilitydatas[e.detail.markerId])
+				this.device_id = this.facilitydatas[e.detail.markerId].device_id
+				this.punctuation_did = this.facilitydatas[e.detail.markerId].d_id
+				this.punctuation_type = this.facilitydatas[e.detail.markerId].device_type_id
+			},
+			serTFs() {
+				this.history()
+			},
+			eqinfo() { //设备信息
+				if (this.punctuation_type == '') {
+					uni.showToast({
+						title: '请点击需查看的设备',
+						duration: 2000,
+						icon: "none"
+					});
+				} else {
+					switch (this.punctuation_type) {
+						case 2:
+							uni.navigateTo({
+								url: "../prevention/ucharts?d_id=" + this.punctuation_did + "&imei=" + this.device_id
+							})
+							break;
+						case 3:
+							uni.navigateTo({
+								url: "../cb/cbd/equip-set/historyfile?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 4:
+							uni.navigateTo({
+								url: "../cb/xy/equip-set/xyhistoryile?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 5:
+							uni.navigateTo({
+								url: "../environment/history?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 6:
+							// uni.navigateTo({
+							// 	url: "../prevention/ucharts?d_id=" + this.punctuation_did + "&device_id=" + this.punctuation_id
+							// })
+							break;
+						case 7:
+							uni.navigateTo({
+								url: "../cb/bzy/equip-set/bzyhistoryile?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+						case 10:
+							uni.navigateTo({
+								url:"../cb/xy2.0/historydatas?d_id=" + this.punctuation_did + "&device_id=" + this.device_id
+							})
+							break;
+					}
+
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.utabs {
+		width: 100%;
+		position: fixed;
+		top: 0px;
+		z-index: 100;
+		background-color: #FFFFFF;
+	}
+	.LocationAndDetails{
+		width: 100%;
+		height: 200rpx;
+		position: fixed;
+		top: 54px;
+		.search{
+			display: flex;
+			input{
+				width: 90%;
+				font-size: 28rpx;
+				margin-left: 40rpx;
+				border: 1px solid #cfccc9;
+				height: 60rpx;
+				padding-left: 15px;
+				box-sizing: border-box;
+				border-radius: 60rpx;
+			}
+		}
+		.Location{
+			display: flex;
+			margin-top: 20rpx;
+			justify-content: space-around;
+			.particulars_par {
+				background-color: #F1F1F1;
+				text-align: center;
+				width: 40%;
+				height: 80rpx;
+				line-height: 80rpx;
+				font-size: 28rpx;
+				border-radius: 40rpx;
+			}
+			.particulars_ser {
+				background-color: #57C87B;
+				text-align: center;
+				width: 40%;
+				height: 80rpx;
+				line-height: 80rpx;
+				font-size: 28rpx;
+				color: #FFFFFF;
+				border-radius: 40rpx;
+			}
+		}
+	}
+	.page-section {
+		margin-top: 144px;
+		height: 80vh;
+		// position: fixed;
+		// top: 144px;
+		.map{
+			width: 100%;
+			height: 100%;
+		}
+	}
+	.particulars {
+		width: 100%;
+		height: 160rpx;
+		position: absolute;
+		bottom: 0;
+		.search_btn_top {
+			width: 100%;
+			height: 80rpx;
+			line-height: 80rpx;
+			font-size: 32rpx;
+			padding-left: 30rpx;
+			box-sizing: border-box;
+		}
+		.search_btn_bot {
+			width: 100%;
+			display: flex;
+		}
+		
+	}
+
+	.distri_ser {
+		position: absolute;
+		bottom: 0rpx;
+		right: 0px;
+		width: 100%;
+		height: 440rpx;
+		background-color: #FFFFFF;
+		.distri_ser_input {
+			width: 90%;
+			margin: 20rpx auto;
+			display: flex;
+			background-color: #F1F1F1;
+			height: 60rpx;
+			border-radius: 30rpx;
+			padding: 10rpx 20rpx;
+			box-sizing: border-box;
+
+			input {
+				width: 90%;
+				font-size: 28rpx;
+				margin-right: 20rpx;
+			}
+		}
+
+		.distri_ser_title {
+			width: 90%;
+			margin: 0 auto;
+			padding-left: 20rpx;
+			border-left: 4rpx solid #57C87B;
+			font-size: 28rpx;
+		}
+
+		.distri_ser_type {
+			width: 90%;
+			margin: 20rpx auto;
+			display: flex;
+			justify-content: space-around;
+
+			.type_items {
+				height: 120rpx;
+				width: 120rpx;
+				padding: 20rpx 0;
+			}
+
+			.type_items_bor {
+				height: 120rpx;
+				width: 120rpx;
+				border: 2rpx solid #57C87B;
+				padding: 20rpx 0;
+			}
+
+			.type_items_img {
+				width: 70rpx;
+				height: 70rpx;
+				margin-left: 20rpx;
+			}
+
+			.type_items_p {
+				font-size: 24rpx;
+				text-align: center;
+			}
+		}
+	}
+
+	.search_btn {
+		width: 100%;
+		display: flex;
+
+		.btn_f,
+		.btn_t {
+			width: 50%;
+			text-align: center;
+			height: 80rpx;
+			line-height: 80rpx;
+			font-size: 28rpx;
+		}
+
+		.btn_f {
+			background-color: #F1F1F1;
+		}
+
+		.btn_t {
+			background-color: #57C87B;
+			color: #FFFFFF;
+		}
+	}
+</style>
+
+
+

+ 216 - 0
pages/environment/contros.vue

@@ -0,0 +1,216 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备控制"></uni-nav-bar>
+			</view>
+			<view class="operation">
+				<p class="operation_title">操作</p>
+				<view class="operation_btn">
+					<button @click="chongqi">重 启</button>
+					<button @click="shengji">升 级</button>
+					<button @click="search">查询时间上传间隔</button>
+				</view>
+			</view>
+			<view class="viewing">
+				<p class="operation_title">显示屏设置</p>
+				<view class="viewing_text">
+					<view class="viewing_text_top">
+						标题文字设置 :
+						<input type="text" v-model="config.content" />
+					</view>
+					<view class="viewing_text_bot">
+						显示时间设置(min) :
+						<input type="number" v-model="config.timeout" />
+					</view>
+				</view>
+			</view>
+			<view class="timing">
+				<p class="operation_title">上传时间间隔(min)</p>
+				<view class="timing_text">
+					<slider value="1" @change="sliderChange" step="1" min="1" max="360" show-value block-size="18" activeColor="#57C878" />
+				</view>
+			</view>
+			<view class="ensure">
+				<view class="ensure_btn" @click="ensure">
+					确 定
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				config: {
+					content: "",
+					timeout: "",
+					interval: ""
+				},
+				id: ''
+			}
+		},
+		methods: {
+			//forecast.send_control.device_control  config: {"interval":10,"content":"content","timeout":"1"}
+			async timing(datas) { //提交数据
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=weather.weather.qxz_status',
+					data: {
+						device_type_id: 5,
+						d_id: this.id,
+						config: JSON.stringify(datas)
+					}
+				})
+			},
+			//forecast.send_control.admin_device_control
+			async restart(datas) { //重启
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.admin_device_control',
+					data: {
+						device_type_id: 5,
+						d_id: this.id,
+						cmd: datas
+					}
+				})
+				if (res == true) {
+					uni.showToast({
+						title: '指令下发成功!'
+					});
+				} else {
+					uni.showToast({
+						title: '指令下发失败!'
+					});
+				}
+			},
+			//forecast.send_control.get_device_config
+			async uploading() { //上传时间
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.get_device_config',
+					data: {
+						device_type_id: 5,
+						d_id: this.id,
+						control_type: "data"
+					}
+				})
+				console.log(res)
+				if (res == true) {
+					uni.showToast({
+						title: '指令下发成功!'
+					});
+				} else {
+					uni.showToast({
+						title: '指令下发失败!'
+					});
+				}
+			},
+			clickLeft() { //返回
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			ensure() { //提交
+				this.timing(this.config)
+			},
+			sliderChange(e) { //滑动块
+				this.config.interval = e.detail.value
+			},
+			chongqi() { //重启按钮
+				this.restart('reboot')
+			},
+			shengji() { //升级按钮
+				this.restart('update')
+			},
+			search() { //查询按钮
+				this.uploading()
+			}
+		},
+		onLoad(option) {
+			this.id = option.id
+		}
+	}
+</script>
+
+<style lang="scss">
+	.operation_title {
+		border-left: 6rpx solid #28AE4F;
+		padding-left: 20rpx;
+		margin-bottom: 20rpx;
+		height: 36rpx;
+	}
+
+	.operation {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+
+		.operation_btn {
+			display: flex;
+			padding-left: 20rpx;
+
+			button {
+				font-size: 24rpx;
+				padding: 0 38rpx;
+				background-color: #28AE4F;
+				color: #FFFFFF;
+			}
+
+			button:last-child {
+				width: 360rpx !important;
+			}
+		}
+	}
+
+	.viewing {
+		position: absolute;
+		top: 124px;
+		width: 90%;
+		left: 5%;
+
+		.viewing_text {
+
+			.viewing_text_top,
+			.viewing_text_bot {
+				display: flex;
+				background-color: #F7F8FA;
+				padding-left: 20rpx;
+				margin-bottom: 20rpx;
+				height: 60rpx;
+				line-height: 60rpx;
+				font-size: 24rpx;
+
+				input {
+					font-size: 24rpx;
+					margin-top: 16rpx;
+					width: 400rpx;
+				}
+			}
+		}
+	}
+
+	.timing {
+		position: absolute;
+		top: 234px;
+		width: 90%;
+		left: 5%;
+	}
+
+	.ensure {
+		width: 100%;
+		position: absolute;
+		top: 600rpx;
+		.ensure_btn {
+			width: 90%;
+			margin: 0 auto;
+			height: 60rpx;
+			line-height: 60rpx;
+			text-align: center;
+			background-color: #28AE4F;
+			color: #FFFFFF;
+			border-radius: 200rpx;
+		}
+	}
+</style>

+ 276 - 0
pages/environment/equipment.vue

@@ -0,0 +1,276 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备详情"></uni-nav-bar>
+			</view>
+			<view class="info">
+				<view class="info_item">
+					<image :src="eqinfo.item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/cb/onBg.png':'http://static.yfpyx.com/bigdata_app/image/cb/offBg.png'" mode=""
+					 class="bgi"></image>
+					<p style="font-size: 32rpx;" @click="copy(eqinfo.item)">设备 ID:{{eqinfo.item.equip_id||eqinfo.item.device_id}}
+					<image src="http://static.yfpyx.com/bigdata_app/image/environment/fuzhi.png" mode="" class="tishi"></image>
+					</p>
+					<p>设备名称:{{eqinfo.item.equip_name?eqinfo.item.equip_name:"无"}}</p>
+					<p>最近上报时间:{{eqinfo.item.uptime|timeFormat()}}</p>
+					<p>地址:{{city==""?"--":city}}</p>
+				</view>
+			</view>
+			<view class="control">
+				<view class="control_item" v-if="kongtf" @click="control">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/8.png'" mode=""></image>
+					<p>设备控制</p>
+				</view>
+				<view class="control_item" v-if="daydatatf" @click="repairs">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/7.png'" mode=""></image>
+					<p>一键报修</p>
+				</view>
+				<view class="control_item" v-if="shujutf" @click="charts">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/10.png'" mode=""></image>
+					<p>历史数据</p>
+				</view>
+			</view>
+			<view class="realtime">
+				<p class="realtime_title">实时数据</p>
+				<view class="realtime_text">
+					<view class="realtime_text_item">
+						<view class="realtime_text_item_info" v-for="(item,index) in olddata.conf" :key="index" v-if="item">
+							<view class="item_info_img" :style="{'background-color':olddatas[Math.floor(Math.random()*(5-0+1))]}">
+								<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/icon_'+olddata.dat[index][1]+'.png'" mode=""></image>
+							</view>
+							<view class="item_info_text">
+								<p>{{item}}</p>
+								<p style="margin-top: 20rpx;">{{parseFloat(olddata.dat[index][0]) == -99.99 ?'N/A':parseFloat(olddata.dat[index])}}</p>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				eqinfo: {},
+				olddata: {},
+				olddatas: ["#fba825", "#53d67c", "#008cf2", "#fb504d", "#d87ffc", "#4ec5f0"],
+				city: "",
+				kongtf:false,
+				daydatatf:false,
+				shujutf:false
+			}
+		},
+		methods: {
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			async history() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=weather.weather.qxz_status',
+					data: {
+						device_id: this.eqinfo.item.equip_id || this.eqinfo.item.device_id
+					}
+				})
+				this.olddata = res
+				for (var key in this.olddata.conf) {
+					if (this.olddata.conf[key].indexOf("#") != -1) {
+						this.olddata.conf[key] = this.olddata.conf[key].replace("#", "(") + ")"
+					}
+					this.olddata.dat[key] = this.olddata.dat[key].split("#")
+				}
+				console.log(this.olddata)
+			},
+			control() { //设备控制
+				uni.navigateTo({
+					url: "./contros?id=" + this.eqinfo.item.d_id
+				})
+			},
+			charts() { //历史数据
+				uni.navigateTo({
+					url: "./history?device_id=" + this.eqinfo.item.equip_id
+				})
+			},
+			reverseGeocode(lat,lng){
+				uni.request({
+					type: "GET",
+					url: "https://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + lng + "," +lat  + "&key=27273b81090f78759e4057f94474516f&radius=1000&extensions=all",
+					dataType: "json",
+					complete: ress => {
+						console.log(ress)
+						this.city = ress.data.regeocode.formatted_address
+					}  
+				});
+			},
+			copy(item){
+				uni.setClipboardData({
+				    data: item.equip_id||item.device_id,
+				    success: function () {
+				        console.log('success');
+				    }
+				});
+			},
+			repairs(){
+				console.log(this.eqinfo.item)
+				var device_id = this.eqinfo.item.equip_id||this.eqinfo.item.device_id
+				uni.navigateTo({
+					url: "../afterSale/addafter?device_id="+ device_id +"&device_type="+ 5
+				})
+			}
+		},
+		onLoad(option) {
+			this.$forceUpdate()
+			this.eqinfo.item = JSON.parse(option.shebei)
+			console.log(JSON.parse(option.shebei))
+			this.history()
+			if(this.eqinfo.item.lat==''||this.eqinfo.item.lng==""){
+				console.log(1)
+			}else{
+				this.reverseGeocode(this.eqinfo.item.lat,this.eqinfo.item.lng)
+			}
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "环境监测系统"
+					})
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "环境监测"
+					})
+					var arr = items2[0].children
+					console.log(arr)
+					for(var i =0;i<arr.length;i++){
+						switch (arr[i].purview_name){
+							case "设备控制":
+								this.kongtf = true
+								break
+							case "24小时数据":
+								this.daydatatf = true
+								break
+							case "历史数据":
+								this.shujutf = true
+								break
+						}
+					}
+				},
+			})
+		}
+	}
+</script>
+
+<style lang="scss">
+	.info {
+		width: 100%;
+		position: absolute;
+		top: 44px;
+		.info_item {
+			width: 90%;
+			margin: 0 auto;
+			height: 250rpx;
+			padding: 26rpx 50rpx;
+			position: relative;
+			box-sizing: border-box;
+			.bgi {
+				width: 100%;
+				height: 250rpx;
+				position: absolute;
+				top: 0;
+				left: 0;
+				z-index: -1;
+			}
+			p {
+				font-size: 24rpx;
+				color: #FFFFFF;
+				margin-bottom: 10rpx;
+				.tishi{
+					width: 30rpx;
+					height: 30rpx;
+					margin: 0rpx 0 0 20rpx;
+				}
+			}
+		}
+	}
+
+	.control {
+		width: 90%;
+		position: absolute;
+		top: 372rpx;
+		left: 5%;
+		display: flex;
+		text-align: center;
+		// padding: 0 30rpx;
+		box-sizing: border-box;
+
+		.control_item {
+			width: 128rpx;
+			height: 120rpx;
+			width: 33%;
+			image {
+				width: 70rpx;
+				height: 70rpx;
+			}
+
+			p {
+				font-size: 24rpx;
+			}
+		}
+	}
+
+	.realtime {
+		width: 100%;
+		position: absolute;
+		top: 500rpx;
+
+		.realtime_title {
+			font-weight: 700;
+			width: 90%;
+			margin: 0 auto;
+		}
+
+		.realtime_text {
+			width: 90%;
+			margin: 0 auto;
+
+			.realtime_text_item {
+				width: 100%;
+				display: flex;
+				justify-content: space-between;
+				flex-wrap: wrap;
+				margin-bottom: 50rpx;
+
+				.realtime_text_item_info {
+					width: 48%;
+					box-shadow: 0 0 10rpx #bcb9ca;
+					margin-top: 20rpx;
+					display: flex;
+					padding: 20rpx 0rpx 20rpx 20rpx;
+					box-sizing: border-box;
+
+					.item_info_img {
+						width: 90rpx;
+						text-align: center;
+						margin-right: 28rpx;
+						border-radius: 50%;
+						height: 90rpx;
+						image {
+							width: 64rpx;
+							height: 64rpx;
+							margin-top: 15rpx
+						}
+					}
+
+					.item_info_text {
+						font-size: 24rpx;
+					}
+				}
+			}
+		}
+
+	}
+</style>

+ 452 - 0
pages/environment/history.vue

@@ -0,0 +1,452 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 10000000;width: 100%;background-color: #000000;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="历史数据"></uni-nav-bar>
+			</view>
+			<view class="graph">
+				<view class="canvasbox">
+					<view class="canvastishi" v-if="!canvastishiTF">
+						暂无数据
+					</view>
+					<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)"
+					 @touchmove="moveLineA($event)" @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+				</view>
+				<view class="selecttimes">
+					<view class="newtimes">
+						<view class="newtimes_state" @click="pickshow = !pickshow">
+							<view class="oldtimes_left">
+								<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/prevention/841f87bfd8abb1b09610fa0789f9d8e.png'" mode=""></image>
+								开始时间:{{this.begintime|timeFormat()}}
+							</view>
+							<view class="oldtimes_left">
+								<u-icon name="arrow-down"></u-icon>
+							</view>
+							<u-picker mode="time" v-model="pickshow" :params="params" @confirm="pickone"></u-picker>
+						</view>
+						<view class="newtimes_end" @click="picktwoshow = !picktwoshow">
+							<view class="oldtimes_left">
+								<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/prevention/1acfe2751c01d3786cdc49b83d7e505.png'" mode=""></image>
+								结束时间:{{this.end|timeFormat()}}
+							</view>
+							<view class="oldtimes_left">
+								<u-icon name="arrow-down"></u-icon>
+							</view>
+							<u-picker mode="time" v-model="picktwoshow" :params="params" @confirm="picktwo"></u-picker>
+						</view>
+						<p class="tishi" v-if="tishiTF">请选择正确的结束时间</p>
+						<view class="btnser" @click="serter">
+							搜 索
+						</view>
+					</view>
+				</view>
+				<view class="condition">
+					<scroll-view scroll-top="0" scroll-x="true" class="scroll-X">
+						<!-- @scrolltoupper="upper" @scrolltolower="lower" @scroll="scroll" -->
+						<table class="table">
+							<tr class="tr">
+								<th class="th">日期</th>
+								<th class="th" v-for="key,index in historydatas.conf" :key="'a'+index" v-if="key">{{key.replace("#","(")+")"}}</th>
+							</tr>
+							<tr class="tr" v-for="(items,index) in historydatas.data" :key="'b'+index" v-if="!forbidden">
+								<td class="td">{{items.time|timeFormat()}}</td>
+								<td class="td" v-for="keys in items.dat" v-if="keys">{{parseFloat(keys)==-99.99?"N/A":parseFloat(keys)}}</td>
+							</tr>
+							<tr class="tr" v-if="forbidden">
+								<td class="td" v-for="item in 10">暂无数据</td>
+							</tr>
+						</table>
+					</scroll-view>
+					<view class="pagenumber">
+						<button @click="prev">上一页</button>
+						<view class="pagenumber_page">
+							第{{page}}页
+						</view>
+						<view class="pagenumber_page">
+							共 {{pagesum}} 页
+						</view>
+						<button @click="next" :disabled="forbidden">下一页</button>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uCharts from '../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvasColumnA = null;
+	var presenttime = +new Date();
+	export default {
+		data() {
+			return {
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+				canvastishiTF: false,
+				id: "",
+				begintime: '', //开始时间
+				end: '', //结束时间
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				titleidnex: 0,
+				pickshow: false, //选择时间一
+				picktwoshow: false, //选择时间二
+				params: { //时间格式
+					year: true,
+					month: true,
+					day: true,
+					hour: true,
+					minute: true,
+					second: false
+				},
+				tishiTF: false, //提示
+				historydatas: [],
+				page: 1,
+				forbidden: false,
+				pagesum: null
+			}
+		},
+		methods: { //weather.weather.qxz_detail
+			async listhistorydata(datas) { //上传时间 
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=weather.weather.qxz_detail',
+					data: {
+						device_id: datas,
+						begin: parseInt(this.begintime),
+						end: parseInt(this.end),
+						page: this.page
+					}
+				})
+				this.historydatas = res
+				console.log(res)
+				this.pagesum = Math.ceil(res.nums / 10) + 1
+				if (res.data.length == 0) {
+					this.forbidden = true
+				} else {
+					this.forbidden = false
+				}
+			},
+			async historydata(datas) { //上传时间 //折线图
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=weather.weather.qxz_data_chart',
+					data: {
+						device_id: datas,
+						begin: parseInt(this.begintime),
+						end: parseInt(this.end)
+					}
+				})
+				console.log(res)
+				if (res.data.length == 0) {
+					this.canvastishiTF = false
+				} else {
+					this.canvastishiTF = true
+					var xtitle = []
+					var linearr = []
+					for (var i = 0; i < res.data.length; i++) {
+						var times = new Date(res.data[i].time * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getMinutes())
+					}
+					for (var key in res.conf) {
+						var obj = {}
+						if (res.conf[key] != "") {
+							obj.name = res.conf[key]
+						}
+						var arr = []
+						for (var i = 0; i < res.data.length; i++) {
+							if (parseFloat(res.data[i].dat[key]) != -99.99) {
+								arr.push(parseFloat(res.data[i].dat[key]))
+							}
+						}
+						obj.data = arr
+						if (obj.name) {
+							linearr.push(obj)
+						}
+					}
+					this.canvastishiTF = linearr.some((item) => {
+						return item.data.length != 0;
+					})
+					console.log(this.canvastishiTF)
+					this.showColumn("canvasColumnA", xtitle, linearr)
+				}
+			},
+			pickone(e) { //开始时间
+				this.begintime = +new Date(e.year, e.month - 1, e.day, e.hour, e.minute) / 1000
+				if (this.newtime < this.oldtime) {
+					this.tishiTF = true
+				} else {
+					this.tishiTF = false
+				}
+			},
+			picktwo(e) { //结束时间
+				this.end = +new Date(e.year, e.month - 1, e.day, e.hour, e.minute) / 1000
+				if (this.newtime < this.oldtime) {
+					this.tishiTF = true
+				} else {
+					this.tishiTF = false
+				}
+			},
+			serter() {
+				if (this.tishiTF == false) {
+					this.historydata(this.id)
+					this.listhistorydata(this.id)
+					uni.showToast({
+						title: '搜索成功',
+						duration: 2000
+					});
+				}
+				
+			},
+			prev() { //上一页
+				if (this.page > 1) {
+					this.page--
+					this.listhistorydata(this.id)
+				}
+			},
+			next() { //下一页
+				this.page++
+				this.listhistorydata(this.id)
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showColumn(id, xtitle, xinfo) {
+				var _self = this
+				canvasColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position: "top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle,
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				canvasColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvasColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvasColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvasColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+		},
+		onLoad(option) {
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+			this.id = option.device_id
+			this.end = presenttime / 1000
+			this.begintime = presenttime / 1000 - 24 * 60 * 60
+			console.log(new Date(1616145097 * 1000), new Date(1616231497 * 1000))
+			this.historydata(option.device_id)
+			this.listhistorydata(option.device_id)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.graph {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+
+		.canvasbox {
+			width: 100%;
+			height: 550rpx;
+			position: relative;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			.charts{
+			}
+			.canvastishi {
+				font-size: 32rpx;
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				margin-left: -64rpx;
+				margin-top: -21rpx;
+			}
+		}
+
+		.none_hint {
+			font-size: 32rpx;
+			font-weight: 700;
+			position: absolute;
+			top: 0;
+			left: 50%;
+			margin-left: -64rpx;
+		}
+	}
+
+	.shuju_one_title {
+		width: 70%;
+		margin: 0 auto;
+		display: flex;
+
+		.tltle_text {
+			width: 25%;
+			border: 2rpx solid #B2B2B2;
+			color: #B2B2B2;
+			text-align: center;
+			font-size: 24rpx;
+			height: 50rpx;
+			line-height: 50rpx;
+		}
+
+		.title_text_color {
+			width: 25%;
+			border: 2rpx solid #28AE4F;
+			color: #28AE4F;
+			text-align: center;
+			font-size: 24rpx;
+			height: 50rpx;
+			line-height: 50rpx;
+		}
+	}
+
+	.selecttimes {
+		width: 100%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-top: 20rpx;
+
+		.tishi {
+			width: 90%;
+			margin: 0 auto;
+			color: #f00000;
+			text-align: center;
+			font-size: 24rpx;
+		}
+
+		.btnser {
+			width: 90%;
+			margin: 10rpx auto;
+			color: #FFFFFF;
+			text-align: center;
+			font-size: 28rpx;
+			background-color: #58BD4D;
+			border-radius: 20rpx;
+			height: 50rpx;
+			line-height: 50rpx;
+		}
+
+		.newtimes {
+			width: 100%;
+			padding: 20rpx 20rpx;
+			box-sizing: border-box;
+
+			.newtimes_state,
+			.newtimes_end {
+				display: flex;
+				justify-content: space-between;
+				margin-bottom: 20rpx;
+
+				.oldtimes_left {
+					position: relative;
+					padding-left: 36rpx;
+					font-size: 28rpx;
+
+					image {
+						width: 30rpx;
+						height: 30rpx;
+						vertical-align: top;
+						position: absolute;
+						top: 7rpx;
+						left: 0;
+					}
+				}
+			}
+		}
+	}
+
+	.condition {
+		display: flex;
+		flex-wrap: wrap;
+		width: 100%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin: 30rpx 0;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+			.table{
+				width: 1042px;
+			}
+			.tr {
+				display: flex;
+				overflow: hidden;
+
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 240rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+
+				.th:first-child,
+				.td:first-child {
+					width: 300rpx;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+			}
+
+			.pagenumber_page {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 160 - 0
pages/environment/index.vue

@@ -0,0 +1,160 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="环境监测系统" right-icon="search" @clickRight="clickRight"
+				 size="16"></uni-nav-bar>
+			</view>
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/1.png'" mode="" class="image"></image>
+			<view class="prevents">
+				<view class="prevents_item" v-for="item,index in eqlistdata" :key="index" @click="eqdetails(item)">
+					<image :src="item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/prevention/6.png':'http://static.yfpyx.com/bigdata_app/image/prevention/7.png'" mode=""
+					 class="prevents_item_img"></image>
+					<view class="prevents_item_top">
+						<p>设备 ID:{{item.equip_id}}</p>
+						<p :class="item.is_online==1?'green':'red'" v-text="item.is_online==1?'在线':'离线'"></p>
+					</view>
+					<view class="prevents_item_bot">
+						<p>设备名称:{{item.equip_name==""?"无":item.equip_name}}</p>
+						<p>最新上报时间:{{item.uptime|timeFormat()}}</p>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				page: 1,
+				size: 10,
+				eqlistdata: [],
+				isTop:false
+			}
+		},
+		methods: {
+			async eqlist() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=weather.weather.qxz_page',
+					data: {
+						page: this.page,
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.ids)
+				console.log(res.ids)
+			},
+			clickRight() {
+				uni.navigateTo({
+					url: "./search"
+				})
+			},
+			clickLeft() {
+				uni.switchTab({
+					url: "../index/index"
+				})
+			},
+			eqdetails(data) {
+				uni.navigateTo({
+					url: "./equipment?shebei=" + JSON.stringify(data)
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad() {
+			this.eqlist()
+		},
+		onReachBottom() {
+			this.page++
+			this.eqlist()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	/deep/.uni-icons {
+		font-size: 40rpx !important;
+	}
+
+	.image {
+		position: fixed;
+		top: 103px;
+		width: 100%;
+		height: 160rpx;
+		z-index: 555;
+	}
+
+	.prevents {
+		width: 100%;
+		position: absolute;
+		top: 140px;
+
+		.prevents_item {
+			width: 95%;
+			margin: 0 auto 30rpx;
+			border-radius: 10rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 40rpx 20rpx 80rpx;
+			box-sizing: border-box;
+			position: relative;
+
+			.prevents_item_img {
+				width: 30rpx;
+				height: 50rpx;
+				position: absolute;
+				top: -4rpx;
+				left: 30rpx;
+			}
+
+			.prevents_item_top {
+				display: flex;
+				justify-content: space-between;
+				height: 60rpx;
+				border-bottom: 2rpx solid #F4F4F4;
+				line-height: 60rpx;
+				font-size: 26rpx;
+
+				.red {
+					color: #ff0000;
+				}
+
+				.green {
+					color: #7DBB91;
+				}
+			}
+
+			.prevents_item_bot {
+				margin-top: 20rpx;
+				font-size: 26rpx;
+				color: #BDBDBD;
+			}
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 129 - 0
pages/environment/onedaythedata.vue

@@ -0,0 +1,129 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="24小时数据"></uni-nav-bar>
+			</view>
+			<view class="nonedata" v-if="olddata.length == 0">
+				暂无数据
+			</view>
+			<view class="datatimes" v-if="olddata.length != 0">
+				<view class="datatimes_box" v-for="(item,index) in olddata" :key="index">
+					<view class="datatimes_title" @click="textshowtf(index)">
+						<p class="datatimes_title_headline">{{item.ekey}}</p>
+						<p class="datatimes_title_chunk">{{item.enum[1]+item.enum[2]}}</p>
+					</view>
+					<view class="datatimes_text" v-show="textshow[index]">
+						<view class="datatimes_text_max">
+							<view class="">
+								<p>最大值</p>
+								<p>{{item.max==-99.99?"N/A":item.max}}</p>
+							</view>
+							<p>{{item.maxtime|timeFormat()}}</p>
+						</view>
+						<view class="datatimes_text_min">
+							<view class="">
+								<p>最小值</p>
+								<p>{{item.min==-99.99?"N/A":item.min}}</p>
+							</view>
+							<p>{{item.mintime|timeFormat()}}</p>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				textshow: {},
+				olddata: {}
+			}
+		},
+		methods: {
+			async daydatas(data) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=weather.weather.qxz_day_data',
+					data: {
+						device_id: data
+					}
+				})
+				this.olddata = res.data
+				for (let i = 0; i < this.olddata.length; i++) {
+					this.textshow[i] = false
+				}
+			},
+			textshowtf(index) {
+				this.textshow[index] = !this.textshow[index]
+				this.$forceUpdate()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			}
+		},
+		onLoad(option) {
+			this.daydatas(option.id)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.nonedata {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+		text-align: center;
+		font-size: 32rpx;
+	}
+
+	.datatimes {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+
+		.datatimes_box {
+			margin-bottom: 40rpx;
+		}
+
+		.datatimes_title {
+			display: flex;
+
+			.datatimes_title_headline {
+				height: 58rpx;
+				line-height: 58rpx;
+			}
+
+			.datatimes_title_chunk {
+				box-shadow: 0 0 10rpx #bcb9ca;
+				margin-left: 50rpx;
+				width: 90%;
+				padding: 10rpx;
+			}
+		}
+
+		.datatimes_text {
+			width: 88%;
+			padding-left: 12%;
+
+			.datatimes_text_max,
+			.datatimes_text_min {
+				display: flex;
+				width: 100%;
+				padding: 10rpx;
+				background-color: #F2F2F2;
+				margin-top: 20rpx;
+				font-size: 24rpx;
+				justify-content: space-between;
+				align-items: center;
+				box-sizing: border-box;
+			}
+		}
+	}
+</style>

+ 176 - 0
pages/environment/search.vue

@@ -0,0 +1,176 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回"></uni-nav-bar>
+				<view class="search_top_input">
+					<input type="text" value="" placeholder="请输入设备ID" v-model="imports" @input="searchinp" />
+					<u-icon name="search" size="40" class="icon" @click="search"></u-icon>
+				</view>
+			</view>
+			<view class="prevents">
+				<view class="prevents_item" v-for="item,index in eqlistdata" :key="index" @click="eqdetails(item)">
+					<image :src="item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/prevention/6.png':'http://static.yfpyx.com/bigdata_app/image/prevention/7.png'"
+					 mode="" class="prevents_item_img"></image>
+					<view class="prevents_item_top">
+						<p>设备 ID:{{item.imei}}</p>
+						<p :class="item.is_online==1?'green':'red'" v-text="item.is_online==1?'在线':'离线'"></p>
+					</view>
+					<view class="prevents_item_bot">
+						<p>设备名称:{{item.device_name==""?"无":item.device_name}}</p>
+						<p>最新上报时间:{{item.addtime|timeFormat()}}</p>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				imports: '',
+				eqlistdata: [],
+				page: 1,
+				size: 10,
+				show: false,
+				value: '',
+				options1: [{
+						text: "杀虫灯",
+						id: 2
+					},
+					{
+						text: "虫情测报",
+						id: 3
+					},
+					{
+						text: "孢子仪",
+						id: 7
+					},
+					{
+						text: "性诱设备",
+						id: 4
+					},
+				]
+			}
+		},
+		methods: {
+			async eqlist() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: 2,
+						page: this.page,
+						size: this.size,
+						device_id: this.imports
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.data)
+				console.log(this.eqlistdata)
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			search() {
+				this.eqlistdata = []
+				this.eqlist()
+			},
+			searchinp() {
+				Debounce(() => {
+					this.eqlistdata = []
+					this.eqlist()
+				}, 1000)()
+			},
+			actionSheetCallback(index) { //选择框
+				this.value = this.options1[index].text;
+				// this.id = this.options1[index].id
+			},
+			eqdetails(data) {
+				uni.navigateTo({
+					url: "./equipmentdetails?shebei=" + JSON.stringify(data)
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.search_top_input {
+		width: 80%;
+		height: 54rpx;
+		background-color: #E4E4E4;
+		border-radius: 27rpx;
+		position: absolute;
+		top: 18rpx;
+		right: 18rpx;
+		padding-top: 8rpx;
+		box-sizing: border-box;
+		input {
+			width: 85%;
+			// text-indent: 1rem;
+			font-size: 26rpx;
+			padding-left: 20px;
+			box-sizing: border-box;
+		}
+
+		.icon {
+			position: absolute;
+			top: 8rpx;
+			right: 26rpx;
+		}
+	}
+
+	.prevents {
+		width: 100%;
+		position: absolute;
+		top: 54px;
+
+		.prevents_item {
+			width: 95%;
+			margin: 0 auto 30rpx;
+			border-radius: 10rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 40rpx 20rpx 80rpx;
+			position: relative;
+			box-sizing: border-box;
+			.prevents_item_img {
+				width: 30rpx;
+				height: 50rpx;
+				position: absolute;
+				top: -4rpx;
+				left: 30rpx;
+			}
+
+			.prevents_item_top {
+				display: flex;
+				justify-content: space-between;
+				height: 60rpx;
+				border-bottom: 2rpx solid #F4F4F4;
+				line-height: 60rpx;
+				font-size: 26rpx;
+
+				.red {
+					color: #ff0000;
+				}
+
+				.green {
+					color: #7DBB91;
+				}
+			}
+
+			.prevents_item_bot {
+				margin-top: 20rpx;
+				font-size: 26rpx;
+				color: #BDBDBD;
+			}
+		}
+	}
+</style>

+ 440 - 0
pages/equipList/index.vue

@@ -0,0 +1,440 @@
+<template>
+	<view>
+		<view class="utabs_box" >
+			<view class="search_bot_input" @click="clickRight">
+				<input type="text" value="" placeholder="请输入设备ID" v-model="imports" @input="searchinput" disabled/>
+				<u-icon name="search" size="36" class="icon" @click="search" color="#949494"></u-icon>
+			</view>
+			<view class="utabs">
+				<u-tabs :list="list" :is-scroll="true" :current="current" @change="change" item-width="140" font-size="24" gutter="20"
+				 bar-width="60" active-color="#42b983"></u-tabs>
+			</view>
+		</view>
+		<view class="list">
+			<view class="list_item" v-for="(item,index) in eqlistdata" :key="index" @click="historys(item)">
+				<view class="list_item_top">
+					<p class="p1">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+imgpath[0].path" mode=""></image>
+						{{item.device_name==''?"--":item.device_name}}
+					</p>
+					<p :class="[item.is_online?'p2':'p_out']">{{item.is_online?"在线":"离线"}}</p>
+				</view>
+				<view class="list_item_text">
+					<p>设备ID:{{item.imei||item.device_id}}</p>
+					<p>适配用户:{{item.real_name==''?"无":item.real_name}}</p>
+					<p>添加设备时间:{{item.addtime|timeFormat()}}</p>
+					<p>添加设备时间:{{item.uptime|timeFormat()}}</p>
+					<p>设备已运行:{{item.days}}天</p>
+				</view>
+				<view class="list_item_btn" v-if="infoalter" @click.stop="modification(item)">
+					信息修改
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				list: [],
+				current: 0,
+				currents:0,
+				page: 1,
+				size: 10,
+				images: [{
+						name: "杀虫灯",
+						path: "/image/fourMoodBase/3.png", //
+						id: 2
+					},
+					{
+						name: "测报灯",
+						path: "/image/fourMoodBase/1.png",
+						id: 3
+					}, {
+						name: "性诱测报",
+						path: "/image/fourMoodBase/6.png",
+						id: 4
+					}, {
+						name: "环境监测",
+						path: "/image/fourMoodBase/5.png",
+						id: 5
+					}, {
+						name: "监控设备",
+						path: "/image/fourMoodBase/2.png",
+						id: 6
+					}, {
+						name: "孢子仪",
+						path: "/image/fourMoodBase/4.png",
+						id: 7
+					},
+					{
+						name: "性诱2.0",
+						path: "/image/fourMoodBase/10.png",
+						id: 10
+					}
+				],
+				eqlistdata: [],
+				isTop: false,
+				infoalter: false, // 权限设置,
+				type_id: 0, //设备类型,
+				imgpath:[]
+			}
+		},
+		methods: {
+			async eqlist(tf) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: this.type_id,
+						page: this.page,
+						page_size: this.size,
+					}
+				})
+				var newtime = +new Date() / 1000
+				if(tf){
+					this.eqlistdata = this.eqlistdata.concat(res.data)
+				}else{
+					this.eqlistdata = res.data
+				}
+				for (var i = 0; i < this.eqlistdata.length; i++) {
+					var days = (newtime - this.eqlistdata[i].uptime) / 60 / 60 / 24
+					this.eqlistdata[i].days = Math.round(days)
+				}
+				console.log(res)
+			},
+			async xyeqlist(tf) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_list',
+					data: {
+						device_type_id: this.type_id,
+						page: this.page,
+						page_size: this.size,
+					}
+				})
+				var newtime = +new Date() / 1000
+				if(tf){
+					this.eqlistdata = this.eqlistdata.concat(res.data)
+				}else{
+					this.eqlistdata = res.data
+				}
+				for (var i = 0; i < this.eqlistdata.length; i++) {
+					var days = (newtime - this.eqlistdata[i].uptime) / 60 / 60 / 24
+					this.eqlistdata[i].days = Math.round(days)
+				}
+				console.log(res)
+			},
+			//camera.camera_manage.list_camera
+			async camera() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=camera.camera_manage.list_camera',
+					data: {
+						page_size: 1,
+					}
+				})
+				this.accessToken = res.accessToken
+			},
+			change(index) { //头部导航栏的点击
+				this.current = index
+				this.currents = index
+				this.page = 1
+				this.eqlistdata = []
+				console.log(index)
+				for (var i = 0; i < this.images.length; i++) {
+					if (this.list[index].name == this.images[i].name) {
+						this.type_id = this.images[i].id
+					}
+				}
+				this.imgpath = this.images.filter((item)=>{
+					return item.id == this.type_id
+				})
+				if (this.type_id == 10) {
+					this.xyeqlist()
+				} else {
+					this.eqlist()
+				}
+			},
+			clickRight() { //搜索
+				uni.navigateTo({
+					url: "./search?id=" + this.type_id
+				})
+			},
+			modification(item) {
+				uni.navigateTo({
+					url: "./modification?data=" + JSON.stringify(item) + "&id=" + this.type_id,
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			},
+			historys(item) {
+				switch (this.type_id) {
+					case 2:
+						uni.navigateTo({
+							url: "../prevention/equipmentdetails?shebei=" + JSON.stringify(item)
+						})
+						break;
+					case 5:
+						console.log(item)
+						var obj = {}
+						obj.d_id = item.d_id
+						obj.equip_id = item.imei
+						obj.is_online = item.is_online
+						obj.lat = item.lat
+						obj.lng = item.lng
+						obj.equip_name = item.device_name
+						obj.uptime = item.addtime
+						uni.navigateTo({
+							url: "../environment/equipment?shebei=" + JSON.stringify(obj)
+						})
+						break;
+					case 6:
+						uni.navigateTo({
+							url: "/pages/webview?device_id=" + item.imei + "&accessToken=" + this.accessToken
+						})
+						break;
+					case 3:
+						item.type = this.type_id
+						uni.navigateTo({
+							url: "../cb/equip-detail/equip-detail?info=" + JSON.stringify(item)
+						})
+						break;
+					case 4:
+						item.type = this.type_id
+						uni.navigateTo({
+							url: "../cb/equip-detail/equip-detail?info=" + JSON.stringify(item)
+						})
+						break;
+					default:
+						item.type = this.type_id
+						uni.navigateTo({
+							url: "../cb/xy2.0/particulars?info=" + JSON.stringify(item)
+						})
+						break;
+				}
+			}
+		},
+		onShow() {
+			this.list=[]
+			this.camera()
+			this.current=0
+			this.currents=0
+			// console.log(this.current)
+			uni.getStorage({
+				key: "jurisdiction",
+				success: (res) => {
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item) => {
+						return item.purview_name == "设备管理"
+					})
+					let items2 = items[0].children.filter((item) => {
+						return item.purview_name == "设备列表"
+					})
+					console.log(items2[0].children)
+					this.infoalter = items2[0].children.some((item) => {
+						return item.purview_name == "修改名称" || item.purview_name == "添加位置"
+					})
+					console.log(this.infoalter)
+					var res = JSON.parse(res.data)
+					for (var i = 0; i < res.length; i++) {
+						switch (res[i].purview_name) {
+							case "测报系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name=="虫情测报灯"?"测报灯":res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+							case "监控系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+							case "环境监测系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+							case "防治系统":
+								for (var j = 0; j < res[i].children.length; j++) {
+									var obj = {
+										name: res[i].children[j].purview_name
+									}
+									this.list.push(obj)
+								}
+								break;
+						}
+					}
+					for (var i = 0; i < this.images.length; i++) {
+						if (this.list[this.current].name == this.images[i].name) {
+							this.type_id = this.images[i].id
+						}
+					}
+					this.imgpath = this.images.filter((item)=>{
+						return item.id == this.type_id
+					})
+					if (this.type_id == 10) {
+						this.xyeqlist(false)
+					} else {
+						this.eqlist(false)
+					}
+				},
+			})
+		},
+		onReachBottom() {
+			this.page++
+			if (this.type_id == 10) {
+				this.xyeqlist(true)
+			} else {
+				this.eqlist(true)
+			}
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	/deep/.uni-icons {
+		font-size: 40rpx !important;
+	}
+	.utabs_box {
+		width: 100%;
+		position: fixed;
+		top: 0px;
+		background-color: #FFFFFF;
+		z-index: 100;
+		.utabs {
+			width: 95%;
+			// margin: 64rpx auto;
+		}
+		.search_bot_input {
+			width: 90%;
+			height: 54rpx;
+			background-color: #ebebeb;
+			border-radius: 27rpx;
+			box-sizing: border-box;
+			padding-top: 8rpx;
+			margin: 0 auto;
+			position: relative;
+			input {
+				width: 100%;
+				// text-indent: 1rem;
+				font-size: 26rpx;
+				padding-left: 40px;
+			}
+			.icon {
+				position: absolute;
+				top: 8rpx;
+				left: 36rpx;
+			}
+		}
+	}
+
+	.list {
+		width: 100%;
+		background-color: #FDFDFD;
+		margin-top: 160rpx;
+		margin-bottom: 100rpx;
+		.list_item {
+			width: 90%;
+			margin: 20rpx auto;
+			padding: 20rpx 20rpx;
+			box-sizing: border-box;
+			position: relative;
+			background-color: #FFFFFF;
+			box-shadow: 0 0 10rpx #bcb9ca;
+
+			.list_item_top {
+				display: flex;
+				justify-content: space-between;
+
+				.p1 {
+					height: 60rpx;
+					line-height: 60rpx;
+					font-size: 28rpx;
+
+					image {
+						width: 40rpx;
+						height: 40rpx;
+						vertical-align: text-top;
+						margin-right: 20rpx;
+					}
+				}
+
+				.p2 {
+					height: 60rpx;
+					line-height: 60rpx;
+					font-size: 28rpx;
+					color: #42b983;
+				}
+
+				.p_out {
+					height: 60rpx;
+					line-height: 60rpx;
+					font-size: 28rpx;
+					color: red;
+				}
+			}
+
+			.list_item_text {
+				margin-top: 20rpx;
+
+				p {
+					font-size: 24rpx;
+					color: #636363;
+					margin-top: 10rpx;
+				}
+
+				p:first-child {
+					font-size: 28rpx;
+					font-weight: 700;
+				}
+			}
+
+			.list_item_btn {
+				width: 126rpx;
+				color: #42b983;
+				height: 40rpx;
+				text-align: center;
+				border: 1rpx solid #42b983;
+				border-radius: 25rpx;
+				font-size: 24rpx;
+				line-height: 35rpx;
+				position: absolute;
+				top: 136rpx;
+				right: 20rpx;
+			}
+		}
+	}
+
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+
+		image {
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 241 - 0
pages/equipList/modification.vue

@@ -0,0 +1,241 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" title="修改名称"></uni-nav-bar>
+			</view>
+			<view class="mod">
+				<view class="mod_name">
+					<p><span style="color: #ff0000;" v-if="quanxian.namealter">*</span>设备名称</p>
+					<input type="text" v-model="moddata.device_name" :class="quanxian.namealter?'namebg':''" :disabled="!quanxian.namealter"/>
+				</view>
+				<view class="mod_id">
+					<p>设备ID</p>
+					<input type="text" :value="moddata.imei||moddata.device_id" disabled />
+				</view>
+				<view class="mod_user">
+					<p>适配用户</p>
+					<input type="text" :value="moddata.real_name==''?'无':moddata.real_name" disabled />
+				</view>
+				<view class="mod_city" @click="amendcity">
+					<p><span style="color: #ff0000;" v-if="quanxian.cityalter">*</span>设备位置</p>
+					<view style="display: flex;">
+						<input type="text" :value="city" disabled style="width: 400rpx;" />
+						<u-icon name="arrow-right"></u-icon>
+					</view>
+				</view>
+				<view class="mod_time">
+					<p>设备添加时间</p>
+					<input type="text" :value="moddata.addtime|timeFormat()" disabled />
+				</view>
+				<p style="width: 90%;margin: 0 auto;text-align: right;color: #06B535;"><span style="color: #ff0000;">*</span>为可修改</p>
+				<view class="sub" v-if="quanxian.infoalter" @click="btn">
+					提 交
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				moddata: [],
+				city: "",
+				selectcityTF: false,
+				quanxian:{
+					namealter:false,
+					cityalter:false,
+					infoalter:false
+				}
+			}
+		},
+		methods: {
+			async eqlistcity(lat, lng) { //修改设备定位
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.revise_device',
+					data: {
+						device_id: this.moddata.imei,
+						lat: lat,
+						lng: lng
+					}
+				})
+				console.log(res)
+				if (res==false) {
+					uni.showModal({
+						title: "修改地址失败",
+						icon: "none"
+					})
+				}
+			},
+			async eqlistname() { //修改设备名称
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.revise_device',
+					data: {
+						device_id: this.moddata.imei,
+						device_name: this.moddata.device_name,
+					}
+				})
+				console.log(res)
+				if (res==false) {
+					uni.showModal({
+						title: "修改名称失败",
+						icon: "none"
+					})
+				}
+			},
+			async eqlistuser(id, imei) { //获取设备信息
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: id,
+						device_id: imei,
+					}
+				})
+				this.moddata = res.data[0]
+				console.log(res)
+				this.selectaddress(this.moddata.lng, this.moddata.lat)
+			},
+			async xyeqlistuser(imei) { //获取设备信息
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=sex_lure_nl.sex_lure.nl_device_list',
+					data: {
+						device_id: imei,
+					}
+				})
+				console.log(res)
+				this.moddata = res.data[0]
+				this.selectaddress(this.moddata.lng, this.moddata.lat)
+			},
+			btn() {
+				this.eqlistcity(this.moddata.lat, this.moddata.lng)
+				this.eqlistname()
+				uni.removeStorage({
+					key: "location"
+				})
+				this.clickLeft()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta:1
+				})
+			},
+			amendcity() { //修改设备地址
+				if(this.quanxian.cityalter){
+					this.selectcityTF = true
+					uni.navigateTo({
+						url: "../fourBase/city"
+					})
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			selectaddress(lng, lat) { //获取分布位置
+				uni.request({
+					type: "GET",
+					url: "https://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + lng + "," + lat +
+						"&key=27273b81090f78759e4057f94474516f&radius=1000&extensions=all",
+					dataType: "json",
+					complete: ress => {
+						// console.log(ress)
+						if (ress.data.regeocode.formatted_address.length == 0) {
+							this.city = "--"
+						} else {
+							this.city = ress.data.regeocode.formatted_address
+						}
+					}
+				});
+			},
+		},
+		onLoad(option) {
+			console.log(option)
+			if(option.id==10){
+				this.xyeqlistuser(JSON.parse(option.data).device_id)
+			}else{
+				this.eqlistuser(option.id, JSON.parse(option.data).imei)
+			}
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "设备管理"
+					})
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "设备列表"
+					})
+					this.quanxian.namealter = items2[0].children.some((item)=>{
+						return item.purview_name == "修改名称"
+					})
+					this.quanxian.cityalter = items2[0].children.some((item)=>{
+						return item.purview_name == "添加位置"
+					})
+					this.quanxian.infoalter = items2[0].children.some((item)=>{
+						return item.purview_name == "修改名称" || item.purview_name == "添加位置"
+					})
+				},
+			})
+		},
+		onShow(){
+			uni.getStorage({
+				key: "location",
+				success: (res) => {
+					// console.log(res);
+					this.moddata.lat = res.data[1]
+					this.moddata.lng = res.data[0]
+					this.selectaddress(this.moddata.lng, this.moddata.lat)
+				}
+			})
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color: #FAFAFA;
+	}
+	.mod {
+		width: 100%;
+		position: absolute;
+		top: 44px;
+		.mod_name,
+		.mod_id,
+		.mod_user,
+		.mod_time,
+		.mod_city {
+			width: 90%;
+			margin: 30rpx auto;
+			display: flex;
+			justify-content: space-between;
+			background-color: #FFFFFF;
+			padding: 20rpx 10rpx;
+			color: #57C77A;
+			line-height: 50rpx;
+			.namebg{
+				background-color: #FAFAFA;
+			}
+			input {
+				text-align: right;
+				font-size: 28rpx;
+				padding: 10rpx;
+			}
+		}
+	}
+
+	.sub {
+		width: 90%;
+		margin: 30rpx auto;
+		text-align: center;
+		height: 70rpx;
+		line-height: 70rpx;
+		background-color: #57C77A;
+		border-radius: 35rpx;
+		color: #FFFFFF;
+	}
+</style>

+ 324 - 0
pages/equipList/search.vue

@@ -0,0 +1,324 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view style="position: fixed;top: 44px; z-index: 100;height: 80rpx;background-color: #FFFFFF;padding-top: 10px;">
+			<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回"></uni-nav-bar>
+			<view class="search_bot_input">
+				<input type="text" value="" placeholder="请输入设备ID" v-model="imports" @input="searchinput" />
+				<u-icon name="search" size="40" class="icon" @click="search"></u-icon>
+			</view>
+		</view>
+		<view class="list">
+			<view class="list_item" v-for="(item,index) in eqlistdata" :key="index" @click="historys(item)">
+				<view class="list_item_top">
+					<p class="p1">
+						<image :src=" 'http://static.yfpyx.com/bigdata_app'+images[indexs-2].path" mode=""></image>
+						{{item.device_name==''?"--":item.device_name}}
+					</p>
+					<p :class="[item.is_online?'p2':'p_out']">{{item.is_online?"在线":"离线"}}</p>
+				</view>
+				<view class="list_item_text">
+					<p>设备ID:{{item.imei}}</p>
+					<p>适配用户:{{item.device_user==''?"无":item.device_user}}</p>
+					<p>添加设备时间:{{item.addtime|timeFormat()}}</p>
+					<p>添加设备时间:{{item.uptime|timeFormat()}}</p>
+					<p>设备已运行:{{item.days}}天</p>
+				</view>
+				<view class="list_item_btn" v-if="infoalter" @click.stop="modification(item)">
+					修改名称
+				</view>
+			</view>
+			<view class="none" v-if="eqlistdatatf">
+				暂无数据
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				imports: '',
+				eqlistdata: [],
+				images: [{
+						path: "/image/fourMoodBase/scd.png",
+						id: 2
+					},
+					{
+						path: "/image/fourMoodBase/cbd.png",
+						id: 3
+					}, {
+						path: "/image/fourMoodBase/xycb.png",
+						id: 4
+					}, {
+						path: "/image/fourMoodBase/qxz.png",
+						id: 5
+					}, {
+						path: "/image/fourMoodBase/jk.png",
+						id: 6
+					}, {
+						path: "/image/fourMoodBase/bzy.png",
+						id: 7
+					}
+				],
+				eqlistdatatf: false, //暂无数据
+				indexs: 2, //设备id
+				page: 1,
+				size: 10,
+				infoalter:false
+			}
+		},
+		methods: {
+			async eqlist() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: this.indexs,
+						device_id: this.imports,
+						page: this.page,
+						page_size: this.size,
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.data)
+				var newtime = +new Date()/1000
+				for(var i=0;i<this.eqlistdata.length;i++){
+					var days = (newtime-this.eqlistdata[i].uptime)/60/60/24
+					this.eqlistdata[i].days = Math.round(days)
+				} 
+				console.log(this.eqlistdata)
+				if (this.eqlistdata.length == 0) {
+					this.eqlistdatatf = true
+				} else {
+					this.eqlistdatatf = false
+				}
+			},
+			clickLeft() { //返回
+				uni.switchTab({
+					url: "./index"
+				})
+			},
+			search() { //搜索
+				this.eqlistdata = []
+				this.page = 1
+				this.eqlist()
+			},
+			searchinput() {
+				Debounce(() => {
+					this.eqlistdata = []
+					this.page = 1
+					this.eqlist()
+				}, 1000)()
+			},
+			modification(item) {
+				uni.navigateTo({
+					url: "./modification?data=" + JSON.stringify(item) + "&id=" + (this.indexs)
+				})
+			},
+			historys(item) {
+				switch (Number(this.indexs)) {
+					case 2:
+						uni.navigateTo({
+							url: "../prevention/equipmentdetails?shebei=" + JSON.stringify(item)
+						})
+						break;
+					case 5:
+						console.log(item)
+						var obj = {}
+						obj.d_id = item.d_id
+						obj.equip_id = item.imei
+						obj.is_online = item.is_online
+						obj.lat = item.lat
+						obj.lng = item.lng
+						obj.equip_name = item.device_name
+						obj.uptime = item.addtime
+						uni.navigateTo({
+							url: "../environment/equipment?shebei=" + JSON.stringify(obj)
+						})
+						break;
+					case 6:
+						uni.navigateTo({
+							url: "/pages/webview?device_id=" + item.imei + "&accessToken=" + this.accessToken
+						})
+						break;
+					default:
+						item.type = this.indexs
+						uni.navigateTo({
+							url: "../cb/equip-detail/equip-detail?info=" + JSON.stringify(item)
+						})
+						break;
+				}
+			}
+		},
+		onLoad(option) {
+			this.indexs = option.id
+			console.log(this.indexs)
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "设备管理"
+					})
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "分配设备"
+					})
+					this.infoalter = items2[0].children.some((item)=>{
+						return item.purview_name == "修改名称" || item.purview_name == "添加位置"
+					})
+				},
+			})
+		},
+		onReachBottom() {
+			this.page++
+			this.eqlist()
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+	}
+</script>
+<style lang="scss">
+	.search_top_input {
+		width: 80%;
+		height: 54rpx;
+		background-color: #E4E4E4;
+		border-radius: 27rpx;
+		position: absolute;
+		top: 18rpx;
+		right: 18rpx;
+		padding-top: 8rpx;
+		box-sizing: border-box;
+
+		input {
+			width: 85%;
+			text-indent: 1rem;
+			font-size: 26rpx;
+		}
+
+		.icon {
+			position: absolute;
+			top: 18rpx;
+			right: 32rpx;
+		}
+	}
+
+	.search_bot_input {
+		width: 80%;
+		height: 54rpx;
+		background-color: #E4E4E4;
+		border-radius: 27rpx;
+		position: absolute;
+		top: 18px;
+		right: 18rpx;
+		box-sizing: border-box;
+		padding-top: 8rpx;
+
+		input {
+			width: 85%;
+			// text-indent: 1rem;
+			font-size: 26rpx;
+			padding-left: 20px;
+		}
+
+		.icon {
+			position: absolute;
+			top: 8rpx;
+			right: 26rpx;
+		}
+	}
+
+	.list {
+		width: 100%;
+		background-color: #FDFDFD;
+		position: absolute;
+		top: 100px;
+
+		.list_item {
+			width: 95%;
+			margin: 20rpx auto;
+			padding: 10rpx 20rpx;
+			position: relative;
+			background-color: #FFFFFF;
+			box-sizing: border-box;
+			box-shadow: 0 0 10rpx #bcb9ca;
+
+			.list_item_top {
+				display: flex;
+				justify-content: space-between;
+
+				.p1 {
+					height: 60rpx;
+					line-height: 60rpx;
+					font-size: 28rpx;
+
+					image {
+						width: 40rpx;
+						height: 40rpx;
+						vertical-align: text-top;
+						margin-right: 20rpx;
+					}
+				}
+
+				.p2 {
+					height: 60rpx;
+					line-height: 60rpx;
+					font-size: 28rpx;
+					color: #42b983;
+				}
+
+				.p_out {
+					height: 60rpx;
+					line-height: 60rpx;
+					font-size: 28rpx;
+					color: red;
+				}
+			}
+
+			.list_item_text {
+				margin-top: 20rpx;
+
+				p {
+					font-size: 24rpx;
+					color: #636363;
+					margin-top: 10rpx;
+				}
+
+				p:first-child {
+					font-size: 28rpx;
+					font-weight: 700;
+				}
+			}
+
+			.list_item_btn {
+				width: 126rpx;
+				color: #42b983;
+				height: 40rpx;
+				text-align: center;
+				border: 1rpx solid #42b983;
+				border-radius: 25rpx;
+				font-size: 24rpx;
+				line-height: 35rpx;
+				position: absolute;
+				top: 136rpx;
+				right: 20rpx;
+			}
+		}
+
+		.none {
+			width: 100%;
+			height: 100rpx;
+			line-height: 100rpx;
+			font-size: 32rpx;
+			text-align: center;
+		}
+	}
+</style>

+ 294 - 0
pages/equipMange/index/addusers.vue

@@ -0,0 +1,294 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="用户新增"></uni-nav-bar>
+			</view>
+			<view class="addusers">
+				<u-form :model="form" ref="uForm" class="uForm">
+					<view class="uFormbg">
+						<u-form-item label="姓名" left-icon="account" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+						 prop="name" required>
+							<u-input v-model="form.name" :clearable="clearable" input-align="right" placeholder="请输入姓名" />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="电话" left-icon="phone" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+						 prop="intro" required>
+							<u-input v-model="form.intro" :clearable="clearable" input-align="right" placeholder="请输入电话" />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="密码" left-icon="lock" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+						 prop="passwold" required>
+							<u-input v-model="form.passwold" type="password" :clearable="clearable" input-align="right" placeholder="请输入密码" />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="角色类型" left-icon="account-fill" :left-icon-style="lefticonstyle" label-width="160rpx"
+						 :border-bottom="borderbottom">
+							<u-input v-model="form.typesofrole" type="select" :clearable="clearable" @click="typesofrole[0].show = true"
+							 input-align="right" placeholder="请选择角色类型" :select-open="typesofrole[0].show" />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="主题" left-icon="calendar" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom">
+							<u-input v-model="form.theme" :clearable="clearable" type="select" @click="theme_show = true" input-align="right"
+							 placeholder="请选择主题" :select-open="theme_show" />
+							<u-action-sheet :list="theme" v-model="theme_show" @click="themes" scroll-y="true"></u-action-sheet>
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="用户类型" left-icon="grid" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom">
+							<u-input v-model="form.usersofrole" type="select" :clearable="clearable" @click="usersofrole_show = true"
+							 input-align="right" :placeholder="usersofrole[0].text" :select-open="usersofrole_show" />
+							<u-action-sheet :list="usersofrole" v-model="usersofrole_show" @click="usersofroles"></u-action-sheet>
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="测试用户" left-icon="eye" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom">
+							<u-input v-model="form.testuser" type="select" :clearable="clearable" @click="testuser_show = true" input-align="right"
+							 :placeholder="testuser[0].text" :select-open="testuser_show" />
+							<u-action-sheet :list="testuser" v-model="testuser_show" @click="testusers"></u-action-sheet>
+						</u-form-item>
+					</view>
+				</u-form>
+			</view>
+			<button class="submitbtn" @click="addusers">确 定</button>
+			<u-popup v-model="typesofrole[0].show" mode="bottom" length="30%" class="pop-up">
+				<scroll-view scroll-y="true" class="sheet">
+					<view class="sheet-text" v-for="(item,index) in typesofrole[1]" :key="index">
+						<p @click="typesofroles(item.role_name,item.role_id)">{{item.role_name}}</p>
+					</view>
+				</scroll-view>
+				<button @click="typesofrole[0].show = false">取消</button>
+			</u-popup>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				borderbottom: false,
+				clearable: false,
+				form: {
+					name: null,
+					intro: null,
+					passwold: null,
+					typesofrole: null,
+					typesofrole_id: null,
+					theme: null,
+					usersofrole: null,
+					usersofrole_id: null,
+					testuser: null,
+				},
+				rules: {
+					name: [{
+							required: true,
+							message: '请输入姓名',
+							// 可以单个或者同时写两个触发验证方式
+							trigger: 'blur,change'
+						},
+						{
+							validator: (rule, value, callback) => {
+								// 上面有说,返回true表示校验通过,返回false表示不通过
+								// this.$u.test.mobile()就是返回true或者false的
+								return value.length < 10 && value.length > 1
+							},
+							message: '请输入2-10个字符',
+							// 触发器可以同时用blur和change
+							trigger: ['change', 'blur'],
+						}
+					],
+					intro: [{
+						required: true,
+						message: '请输入手机号',
+						// 可以单个或者同时写两个触发验证方式
+						trigger: 'blur,change'
+					}, {
+						// 自定义验证函数,见上说明
+						validator: (rule, value, callback) => {
+							// 上面有说,返回true表示校验通过,返回false表示不通过
+							// this.$u.test.mobile()就是返回true或者false的
+							return this.$u.test.mobile(value);
+						},
+						message: '手机号格式不正确',
+						// 触发器可以同时用blur和change
+						trigger: ['change', 'blur'],
+					}],
+					passwold: {
+						required: true,
+						message: '请输入密码',
+						// 可以单个或者同时写两个触发验证方式
+						trigger: 'blur,change'
+					}
+				},
+				lefticonstyle: {
+					'color': '#57C878'
+				},
+				typesofrole: [{
+					show: false
+				}],
+				theme_show: false,
+				theme: [],
+				usersofrole_show: false,
+				usersofrole: [{
+					text: "超级管理员"
+				}, {
+					text: "经销商"
+				}, {
+					text: "农林政府单位"
+				}, {
+					text: "普通用户"
+				}],
+				testuser_show: false,
+				testuser: [{
+					text: "是"
+				}, {
+					text: "否"
+				}]
+			}
+		},
+		methods: {
+			typesofroles(value, id) {
+				this.form.typesofrole = value;
+				this.form.typesofrole_id = id
+				this.typesofrole[0].show = false
+			},
+			themes(index) {
+				this.form.theme = this.theme[index].text;
+			},
+			usersofroles(index) {
+				this.form.usersofrole = this.usersofrole[index].text;
+				this.form.usersofrole_id = index + 1
+			},
+			testusers(index) {
+				this.form.testuser = this.testuser[index].text;
+			},
+			async getTypesofroles() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.perms.role_list'
+				})
+				this.typesofrole.push(res)
+				console.log(res)
+			},
+			async getThemes() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.warning_record.rolemanage_view'
+				})
+				console.log(res.data)
+				for (var i = 0; i < res.data.length; i++) {
+					let obj = {}
+					obj.text = res.data[i].role_describe
+					obj.role_id = res.data[i].id
+					if(obj.text != ''){
+						this.theme.push(obj)
+					}
+				}
+			},
+			async getaddusers() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.regiest',
+					data: {
+						username: this.form.name,
+						mobile: this.form.intro,
+						password: this.form.passwold,
+						role_id: this.form.typesofrole_id ? this.form.typesofrole_id : 1,
+						user_type: this.form.usersofrole_id ? this.form.usersofrole_id : 1,
+						cs_user: this.form.testuser == "是" ? 1 : 0
+					}
+				})
+			},
+			addusers() {
+				if (this.form.name && this.form.intro && this.form.passwold) {
+					this.getaddusers()
+					uni.navigateTo({
+						url: './index'
+					});
+				}
+			},
+			clickLeft() {
+				uni.navigateTo({
+					url: './index'
+				});
+			}
+		},
+		onLoad() {
+			this.getTypesofroles()
+			this.getThemes()
+		},
+		onReady() {
+			this.$refs.uForm.setRules(this.rules);
+		}
+	}
+</script>
+
+<style lang="scss">
+	.addusers {
+		width: 100%;
+		display: flex;
+		justify-content: center;
+
+		.uForm {
+			margin-top: 44px;
+			width: 90%;
+
+			.uFormbg {
+				width: 100%;
+				padding: 0 20rpx;
+				margin: 20rpx 0;
+				background-color: #F7F8FA;
+				box-sizing: border-box;
+
+				.u-form-item {
+					padding: 0 10rpx;
+				}
+			}
+
+		}
+	}
+
+	.submitbtn {
+		width: 95%;
+		position: absolute;
+		bottom: -80rpx;
+		background-color: $uni-color-success;
+		color: white;
+		left: 2.5%;
+		height: 70rpx;
+		font-size: 32rpx;
+		line-height: 70rpx;
+	}
+
+	.pop-up {
+		.sheet {
+			background-color: white;
+			height: 400rpx;
+			overflow: hidden;
+
+			.sheet-text {
+				height: 80rpx;
+
+				p {
+					text-align: center;
+					height: 80rpx;
+					line-height: 80rpx;
+					color: black;
+					font-size: 16px;
+				}
+			}
+
+		}
+
+		button {
+			color: black;
+			position: absolute;
+			bottom: 0;
+			width: 100%;
+			font-size: 16px;
+			height: 80rpx;
+		}
+	}
+</style>

+ 338 - 0
pages/equipMange/index/assignment.vue

@@ -0,0 +1,338 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;top:64px;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备分配"></uni-nav-bar>
+			</view>
+			<view class="utabs">
+				<view style="width: 95%;margin: 0 auto;">
+					<u-tabs :list="list" :is-scroll="true" :current="current" @change="change" item-width="140" font-size="24" gutter="20"
+					 bar-width="60" active-color="#42b983"></u-tabs>
+				</view>
+			</view>
+			<view class="ass_list">
+				<checkbox-group class="che_group" @change="checkboxchange">
+					<label class="equipment" v-for="(items,index) in assignment" :key="index">
+						<view class="equipment_top">
+							<image :src="'http://static.yfpyx.com/bigdata_app'+items.src" mode="" class="equipment_top_img"></image>
+							<span class="equipment_top_name">{{list[items.device_type_id-1].name}}</span>
+							<checkbox :value="String(items.d_id)" :checked="items.device_user==user_info.uid" class="ucheckbox" color="#42b983" />
+						</view>
+						<view class="equipment_bot">
+							<p class="equipment_bot_id">设备ID:{{items.device_id}}</p>
+							<p class="equipment_bot_name">设备名称:{{items.device_name}}</p>
+							<view class="equipment_state">在线</view>
+						</view>
+					</label>
+				</checkbox-group>
+			</view>
+			<view class="allocbtn">
+				<button @click="cancel" class="cancel">取消分配</button>
+				<button @click="canfirm" class="canfirm">确定分配</button>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				user_info: {},
+				list: [{
+					name: "全部"
+				}, {
+					name: "杀虫灯"
+				}, {
+					name: "测报灯"
+				}, {
+					name: "智能性诱"
+				}, {
+					name: "环境检测"
+				}, {
+					name: "监控设备"
+				}, {
+					name: "孢子仪"
+				}, {
+					name: "性诱设备"
+				}, {
+					name: "糖醋测报"
+				}, {
+					name: "性诱2.0"
+				}],
+				current: 0,
+				assignment: [],
+				data: {
+					devicetypeid: '',
+					pagesize: 10,
+					page: 1
+				},
+				images: [{
+						path: "/image/fourMoodBase/scd.png",
+						id: 2
+					},
+					{
+						path: "/image/fourMoodBase/cbd.png",
+						id: 3
+					}, {
+						path: "/image/fourMoodBase/xycb.png",
+						id: 4
+					}, {
+						path: "/image/fourMoodBase/qxz.png",
+						id: 5
+					}, {
+						path: "/image/fourMoodBase/jk.png",
+						id: 6
+					}, {
+						path: "/image/fourMoodBase/bzy.png",
+						id: 7
+					},
+					{
+						path: "/image/fourMoodBase/10.png",
+						id: 10
+					}
+				],
+				allocationvalues: [], //原始数据
+				allocationvalues2: [], //选项框更改后的数据
+				allocationvalues3: [], //头部导航栏点击后的数据
+				allocationvaluesTF: false, //判断选项框是否变动
+				topbarTF: false ,//判断头部导航栏是否变更
+				isTop:false
+			}
+		},
+		methods: {
+			deweight(arr) {
+				var newArr = []
+				for (var i = 0; i < arr.length; i++) {
+					if (newArr.indexOf(arr[i]) === -1) {
+						newArr.push(arr[i])
+					}
+				}
+				return newArr
+			},
+			clickLeft() { //返回上一页
+				uni.navigateTo({
+					url: './useroperation?item=' + JSON.stringify(this.user_info)
+				})
+			},
+			change(index) { //头部导航栏的点击
+				this.topbarTF = true //更改导航栏状态
+				// this.allocationvalues3 = this.deweight(this.allocationvalues3.concat(this.allocationvalues2)) //合并数据
+				console.log(this.allocationvalues3)
+				this.current = index
+				this.data.page = 1
+				this.data.devicetypeid = ''
+				uni.pageScrollTo({
+					scrollTop: 0
+				});
+				if (index == 0) {
+					this.assignment = []
+					this.getAssign(this.data)
+				} else {
+					this.assignment = []
+					this.data.devicetypeid = index + 1
+					this.getAssign(this.data)
+				}
+
+			},
+			async getAssign(data) { //获取设备信息
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=device.device_manage.user_device_info',
+					data: {
+						owner_uid: this.user_info.uid,
+						device_type_id: data.devicetypeid,
+						page_size: data.pagesize,
+						page: data.page
+					}
+				})
+				this.assignment = this.assignment.concat(res.data)
+				for (var i = 0; i < this.assignment.length; i++) {
+					if (this.assignment[i].device_user != 0) {
+						this.allocationvalues.push(this.assignment[i].d_id)
+					}
+					for (var j = 0; j < this.images.length; j++) {
+						if (this.assignment[i].device_type_id == this.images[j].id) {
+							this.assignment[i].src = this.images[j].path
+						}
+					}
+				}
+			},
+			async allocation(data) { //分配设备
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=device.device_manage.allot_device',
+					data: {
+						device_ids: data.device_ids,
+						uid: data.uid
+					}
+				})
+			},
+			checkboxchange(e) { //多选框变动时
+				this.allocationvaluesTF = e._processed
+				this.allocationvalues2 = e.detail.value
+				if (this.topbarTF) {
+					this.allocationvalues3 = this.allocationvalues3.concat(e.detail.value)
+					console.log(e.detail.value)
+				}
+			},
+			canfirm() { //确定分配
+				let data = {}
+				if (this.topbarTF) {
+					data.device_ids = this.deweight(this.allocationvalues3.concat(this.allocationvalues)).join(',')
+				} else {
+					if (this.allocationvaluesTF) {
+						this.allocationvalues2 = this.deweight(this.allocationvalues2)
+						data.device_ids = this.allocationvalues2.join(',')
+					} else {
+						data.device_ids = this.allocationvalues.join(',')
+					}
+				}
+
+				data.uid = this.user_info.uid
+				this.allocation(data)
+				uni.navigateTo({
+					url: './useroperation?item=' + JSON.stringify(this.user_info)
+				})
+			},
+			cancel() { //取消分配
+				uni.navigateTo({
+					url: './useroperation?item=' + JSON.stringify(this.user_info)
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad(option) {
+			this.user_info = JSON.parse(option.item)
+			this.getAssign(this.data)
+		},
+		onReachBottom() {
+			this.data.page++
+			this.getAssign(this.data)
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.utabs {
+		width: 100%;
+		position: fixed;
+		top: 108px;
+		z-index: 100;
+	}
+
+	.ass_list {
+		margin: 190rpx 0 0;
+
+		.che_group {
+			display: flex;
+			flex-direction: column;
+		}
+
+		.equipment {
+			width: 600rpx;
+			margin: 20rpx auto;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 30rpx;
+
+			.equipment_top {
+				height: 60rpx;
+				width: 100%;
+				border-bottom: 1px solid #dfe5ec;
+				position: relative;
+
+				.equipment_top_img {
+					width: 40rpx;
+					height: 40rpx;
+					position: absolute;
+				}
+
+				.equipment_top_name {
+					font-size: 24rpx;
+					margin-left: 60rpx;
+				}
+
+				.ucheckbox {
+					float: right;
+					margin: 0rpx -4rpx;
+					transform: scale(0.7);
+				}
+			}
+
+			.equipment_bot {
+				padding: 30rpx 0;
+				position: relative;
+
+				.equipment_bot_id {
+					font-weight: 700;
+					font-size: 15px;
+					margin-bottom: 16rpx;
+				}
+
+				.equipment_bot_name {
+					font-size: 10px;
+				}
+
+				.equipment_state {
+					position: absolute;
+					top: 20rpx;
+					right: 0;
+					width: 100rpx;
+					height: 100rpx;
+					text-align: center;
+					line-height: 100rpx;
+					color: #42b983;
+
+				}
+			}
+		}
+	}
+	.allocbtn {
+		width: 100%;
+		position: fixed;
+		bottom: 0;
+		z-index: 100;
+		display: flex;
+	
+		button {
+			width: 50%;
+			font-size: 24rpx;
+			height: 80rpx;
+			line-height: 80rpx;
+			border-radius: 0;
+		}
+	
+		.cancel {
+			background-color: #C8C7CC;
+			color: #555555;
+		}
+	
+		.canfirm {
+			color: white;
+			background-color: #42b983;
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 162 - 0
pages/equipMange/index/changepasswold.vue

@@ -0,0 +1,162 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="修改密码"></uni-nav-bar>
+			</view>
+			<u-form :model="form" ref="uForm" class="uForm">
+				<view class="uFormbg">
+					<u-form-item label="原始密码" left-icon="lock" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+					 prop="name">
+						<u-input v-model="form.oldpass" :clearable="clearable" input-align="right" placeholder="请输入原始密码" :type="type"
+						 @blur="oldpassblur"/>
+					</u-form-item>
+				</view>
+				<p class="tishi" v-if="oldpassisnull">请输入原始密码!</p>
+				<view class="uFormbg">
+					<u-form-item label="新密码" left-icon="lock" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+					 prop="name">
+						<u-input v-model="form.newpass" :clearable="clearable" input-align="right" placeholder="请输入新密码" :type="type"
+						 @blur="newpassblur" />
+					</u-form-item>
+				</view>
+				<p class="tishi" v-if="passisnull">请输入新密码!</p>
+				<view class="uFormbg">
+					<u-form-item label="确认新密码" left-icon="lock" :left-icon-style="lefticonstyle" label-width="200rpx" :border-bottom="borderbottom"
+					 prop="name">
+						<u-input v-model="form.newpasstwo" :clearable="clearable" input-align="right" placeholder="请再次输入新密码" :type="type"
+						 @blur="tnewpassblur" />
+					</u-form-item>
+				</view>
+				<p class="tishi" v-if="tpassisnull">请输入新密码</p>
+				<p class="tishi" v-if="passisdif">两次输入密码不一致!</p>
+			</u-form>
+			<view class="confirm">
+				<button @click="confirm">确定</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				user_info: {},
+				form: {
+					oldpass: '',
+					newpass: '',
+					newpasstwo: ''
+				},
+				borderbottom: false,
+				clearable: false,
+				lefticonstyle: {
+					'color': '#57C878'
+				},
+				oldpassisnull: false, //旧密码为空提示
+				passisdif: false, //俩次密码不一致提示
+				tpassisnull: false, //第二次新密码为空提示
+				passisnull: false, //第一次新密码为空提示
+				type: 'password'
+			}
+		},
+		methods: {
+			clickLeft() {
+				uni.navigateTo({
+					url: './useroperation?item=' + JSON.stringify(this.user_info)
+				})
+			},
+			async changepwd(data) { //分配设备
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.changepwd',
+					data: {
+						uid: this.user_info.uid,
+						old_password: this.form.oldpass,
+						new_password: this.form.newpass,
+						confirm_password: this.form.newpasstwo
+					}
+				})
+			},
+			confirm() { //确定按钮
+				if (!(this.passisdif && this.tpassisnull && this.oldpassisnull && this.passisnull)) {
+					this.changepwd()
+				}
+
+			},
+			newpassblur() { //第一次新密码框提示
+				if (this.form.newpass == "") {
+					this.passisnull = true
+				} else {
+					this.passisnull = false
+				}
+				this.form.newpass = this.form.newpass.replace(/[\u4E00-\u9FA5]/g,'')
+			},
+			tnewpassblur() { //第二次新密码框提示
+				if (this.form.newpasstwo == "") {
+					this.tpassisnull = true
+				} else {
+					this.tpassisnull = false
+					if (this.form.newpass != this.form.newpasstwo) {
+						this.passisdif = true
+					} else {
+						this.passisdif = false
+					}
+				}
+				this.form.newpasstwo = this.form.newpasstwo.replace(/[\u4E00-\u9FA5]/g,'')
+			},
+			oldpassblur() { //原始密码框提示
+				if (this.form.oldpass == "") {
+					this.oldpassisnull = true
+				} else {
+					this.oldpassisnull = false
+				}
+				this.form.oldpass = this.form.oldpass.replace(/[\u4E00-\u9FA5]/g,'')
+			}
+		},
+		onLoad(option) {
+			this.user_info = JSON.parse(option.item)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.uForm {
+		width: 100%;
+		position: relative;
+		top: 54px;
+		.uFormbg {
+			width: 90%;
+			background-color: #f3f3f3;
+			margin: 20rpx auto 0;
+
+			.u-form-item {
+				width: 90%;
+				padding: 10rpx 0;
+				margin: 0 auto;
+			}
+		}
+
+		.tishi {
+			width: 100%;
+			text-align: center;
+			color: red;
+			font-size: 12px;
+		}
+	}
+
+	.confirm {
+		width: 90%;
+		position: relative;
+		top: 150rpx;
+		left: 50%;
+		margin-left: -45%;
+
+		button {
+			height: 80rpx;
+			line-height: 80rpx;
+			background-color: $uni-color-success;
+			color: white;
+		}
+	}
+</style>

+ 215 - 0
pages/equipMange/index/index.vue

@@ -0,0 +1,215 @@
+<template>
+	<view class="">
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar left-icon="back" left-text="返回" right-icon="plus" title="用户管理" @clickRight="clickRight" @clickLeft="clickLeft"></uni-nav-bar>
+			</view>
+			<view class="uinput-box">
+				<view class="uinputs">
+					<u-input v-model="argument.username" :type="type" :border="border" placeholder="请输入用户名称" input-align="center"
+					 :clearable="border" :custom-style="uinputstyle" @input="searchinput" />
+					<u-icon name="search" class="search" size="30" @click="search"></u-icon>
+				</view>
+			</view>
+			<view class="userlists">
+				<view class="userlist-li" v-for="(item,index) in userlists" :kex="index" @click="userOperation(userlists[index])">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/fourMoodBase/touxiang.png'" mode=""></image>
+					<p class="userlist-li-city">{{item.username}}</p>
+					<p class="userlist-li-eamil">{{item.mobile}}</p>
+				</view>
+			</view>
+		</view> 
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				value: '',
+				type: 'text',
+				border: false,
+				uinputstyle: {
+					"margin": "16rpx 0",
+					'background': "#f3f3f3",
+					"border-radius": "25px"
+				},
+				userlists: [],
+				argument: {
+					page: 1,
+					page_size: 10,
+					username: ''
+				},
+				isTop:false,
+				addtf:false
+			}
+		},
+		methods: {
+			async getState(argument) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.users_info',
+					data: {
+						page: argument.page,
+						page_size: argument.page_size,
+						username: argument.username
+					}
+				})
+				this.userlists = this.userlists.concat(res.data)
+			},
+			clickRight() { //跳转增加用户页面
+				if(this.addtf){
+					uni.navigateTo({
+						url: './addusers',
+					})
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			clickLeft(){
+				uni.switchTab({
+					url:"../../index/index"
+				})
+			},
+			userOperation(item) { //跳转用户信息页面
+				item = JSON.stringify(item)
+				uni.navigateTo({
+					url: './useroperation?item=' + item,
+				})
+			},
+			search() { //搜索用户
+				this.userlists = []
+				this.getState(this.argument)
+			},
+			searchinput() {
+				this.argument.page=1
+				Debounce(() => {
+					this.userlists = []
+					this.getState(this.argument)
+				}, 1000)()
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		}, //user.login.users_info
+		onLoad() {
+			this.getState(this.argument)
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "系统管理"
+					})
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "用户管理"
+					})
+					var arr = items2[0].children
+					console.log(arr)
+					for(var i =0;i<arr.length;i++){
+						switch (arr[i].purview_name){
+							case "添加用户":
+								this.addtf = true
+								break
+						}
+					}
+				},
+			})
+		},
+		onReachBottom() {
+			this.argument.page++
+			this.getState(this.argument)
+		},
+		onPullDownRefresh() {
+			this.getState(this.argument)
+			setTimeout(function() {
+				uni.stopPullDownRefresh(); //停止下拉刷新动画
+			}, 1000);
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+1
+<style lang="scss">
+	/deep/.uni-icons{
+			font-size: 40rpx !important;
+		}
+	.uinput-box {
+		position: fixed;
+		top: 108px;
+		z-index: 100;
+		background-color: white;
+		width: 100%;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+
+		.uinputs {
+			width: 95%;
+			position: relative;
+
+			.search {
+				position: absolute;
+				top: 40rpx;
+				left: 200rpx;
+			}
+		}
+	}
+
+	.userlists {
+		width: 100%;
+		position: relative;
+		top: 180rpx;
+
+		.userlist-li {
+			width: 46%;
+			height: 270rpx;
+			margin: 20rpx 0 0 20rpx;
+			float: left;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			text-align: center;
+
+			image {
+				width: 80rpx;
+				height: 80rpx;
+				margin: 40rpx 0 20rpx;
+			}
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 466 - 0
pages/equipMange/index/useroperation.vue

@@ -0,0 +1,466 @@
+<template>
+	<view class="">
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar left-icon="back" left-text="返回" @clickLeft="clickLeft" title="用户详情"></uni-nav-bar>
+			</view>
+			<view class="useroperations">
+				<u-form :model="user_meg" ref="uForm" class="uForm">
+					<view class="uFormbg">
+						<u-form-item label="姓名" left-icon="account" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+						 prop="name">
+							<u-input v-model="user_meg.username" :clearable="clearable" input-align="right" :disabled="alterTF" :class="{'uuinput':alterTF==false}" />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="电话" left-icon="phone" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+						 prop="intro">
+							<u-input v-model="user_meg.mobile" :clearable="clearable" input-align="right" :disabled="alterTF" :class="{'uuinput':alterTF==false}"
+							 @blur="bluechange(user_meg.mobile)" />
+						</u-form-item>
+						<p class="tishi" v-if="tishitf">手机格式错误</p>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="主题" left-icon="calendar" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom"
+						 prop="passwold">
+							<u-input v-model="theme_items" :clearable="clearable" input-align="right" :disabled="true" :class="{'uuinput':alterTF==false}"
+							 type="selete" @click="theme_show = !alterTF" />
+							<u-action-sheet :list="theme" v-model="theme_show" @click="themes" scroll-y="true"></u-action-sheet>
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="用户类型" left-icon="grid" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom">
+							<u-input v-model="users_type[user_meg.user_type-1].text" :clearable="clearable" input-align="right" disabled />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="用户角色" left-icon="account-fill" :left-icon-style="lefticonstyle" label-width="160rpx"
+						 :border-bottom="borderbottom">
+							<u-input v-model="user_meg.role_name" :clearable="clearable" input-align="right" placeholder="请选择主题" :disabled="true"
+							 :class="{'uuinput':alterTF==false}" @click="users_type_show = !alterTF" />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="是否可用" left-icon="order" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom">
+							<u-input v-model="tf" :clearable="clearable" input-align="right" disabled />
+						</u-form-item>
+					</view>
+					<view class="uFormbg">
+						<u-form-item label="创建时间" left-icon="clock" :left-icon-style="lefticonstyle" label-width="160rpx" :border-bottom="borderbottom">
+							<u-input :clearable="clearable" input-align="right" disabled :value="user_meg.addtime|timeFormat()" />
+						</u-form-item>
+					</view>
+				</u-form>
+			</view>
+			<view class="operation_group">
+				<view class="group_one" v-if="btnTF">
+					<view class="group_one_top">
+						<!-- <button type="default" @click="recharge">充值</button> -->
+						<button type="default" @click="compile">编辑</button>
+						<button type="default" @click="forbidden" v-if="forbiddenTF" style="background-color: red;">禁用</button>
+						<button type="default" @click="forbidden" v-else>可用</button>
+						<button type="default" @click="changePassword">修改密码</button>
+					</view>
+					<view class="group_one_bot">
+						<button type="default" @click="assignment">分配设备</button>
+					</view>
+				</view>
+				<view class="group_two" v-else>
+					<button type="default" @click="modification" :disabled="tijiaotf">确定</button>
+				</view>
+			</view>
+			<u-popup v-model="users_type_show" mode="bottom" length="30%" class="pop-up">
+				<scroll-view scroll-y="true" class="sheet">
+					<view class="sheet-text" v-for="(item,index) in roles" :key="index">
+						<p @click="typesofroles(index)">{{item.text}}</p>
+					</view>
+				</scroll-view>
+				<button @click="users_type_show = false">取消</button>
+			</u-popup>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				user_meg: {},
+				lefticonstyle: {
+					'color': "#57C878"
+				},
+				borderbottom: false,
+				clearable: false,
+				tf: "",
+				usersofrole_show: true,
+				btnTF: true,
+				users_type: [{
+					text: '超级管理员'
+				}, {
+					text: '经销商'
+				}, {
+					text: '农林政府单位'
+				}, {
+					text: '普通用户'
+				}],
+				users_type_show: false,
+				forbiddenTF: null,
+				alterTF: true,
+				theme: [],
+				theme_show: false,
+				theme_items: '--',
+				roles: [],
+				roles_id: null,
+				tishitf: false,
+				tijiaotf: false,
+				quanxian:{//权限设置
+					chongzhi :false,
+					alters :false,
+					off :false,
+					pass: false,
+					shebeiitems:false
+				}
+			}
+		},
+		methods: {
+			async getForbidden() { //获取用户的使用状态
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.users_statu_updata',
+					data: {
+						uid: this.user_meg.uid,
+						state: this.user_meg.state == '1' ? 4 : 1 //1是正常  4是禁用
+					}
+				})
+				console.log(res)
+				if (this.user_meg.state == "1" && res == true) {
+					this.user_meg.state = '4'
+					console.log(this.user_meg.state)
+				} else {
+					this.user_meg.state = '1'
+					console.log(this.user_meg.state)
+				}
+
+				if (this.user_meg.state == '1') {
+					this.tf = "正常"
+					this.forbiddenTF = true
+				} else if (this.user_meg.state == '4') {
+					this.tf = "禁止使用"
+					this.forbiddenTF = false
+				}
+			},
+			async getGroup() { //获取用户的主题信息
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.warning_record.rolemanage_view'
+				})
+				for (var i = 0; i < res.data.length; i++) {
+					let obj = {}
+					obj.text = res.data[i].role_describe
+					obj.id = res.data[i].id
+					if(obj.text != ''){
+						this.theme.push(obj)
+					}
+					if (this.user_meg.user_group_id == res.data[i].id) { //根据主题id更改主题
+						this.theme_items = res.data[i].role_describe
+					}
+					console.log(this.theme)
+				}
+			},
+			async getThemes() { //获取用户角色
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.perms.role_list'
+				})
+				for (var i = 0; i < res.length; i++) {
+					let obj = {}
+					obj.text = res[i].role_name
+					obj.id = res[i].role_id
+					this.roles.push(obj)
+				}
+			},
+			compile() { //编辑按钮
+				if(this.quanxian.alters){
+					this.btnTF = !this.btnTF
+					this.alterTF = false
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			forbidden() { //禁用按钮
+				if(this.quanxian.off){
+					this.getForbidden()
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			themes(index) { //主题下拉框
+				this.theme_items = this.theme[index].text;
+				this.user_meg.user_group_id_index = this.theme[index].id;
+			},
+			async getModification() { //修改用户
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.users_info_updata',
+					data: {
+						username: this.user_meg.username,
+						uid: this.user_meg.uid,
+						mobile: this.user_meg.mobile,
+						user_group_id: this.user_meg.user_group_id_index || '',
+						user_type: this.user_meg.user_type,
+						role_id: this.roles_id || this.user_meg.role_id
+					},
+				})
+			},
+			modification() { //修改用户确认按钮
+				this.getModification()
+				this.btnTF = true
+				this.alterTF = true
+			},
+			typesofroles(idnex) { //主题下拉框选项按钮
+				this.user_meg.role_name = this.roles[idnex].text
+				this.users_type_show = false
+				this.roles_id = this.roles[idnex].id
+			},
+			bluechange(str) { //手机号框失去焦点时检测手机号
+				let regexp = /^1[23456789]\d{9}$/
+				this.tishitf = !regexp.test(str)
+				if (regexp.test(str)) {
+					this.tijiaotf = !regexp.test(str)
+				} else {
+					this.tijiaotf = regexp.test(str)
+				}
+
+			},
+			clickLeft() { //返回上一页按钮
+				uni.navigateTo({
+					url: './index'
+				});
+			},
+			changePassword() { //修改密码
+				if(this.quanxian.pass){
+					uni.navigateTo({
+						url: './changepasswold?item=' + JSON.stringify(this.user_meg)
+					});
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			assignment() { //分配设备
+				if(this.quanxian.shebeiitems){
+					uni.navigateTo({
+						url: './assignment?item=' + JSON.stringify(this.user_meg)
+					});
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			async getRecharge() { //修改用户
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.user_add_package_time',
+					data: {
+						uid: this.user_meg.uid,
+						user_test: 1
+					},
+				})
+			},
+			// recharge() { //充值按钮
+			// 	if(this.quanxian.chongzhi){
+			// 		uni.showModal({
+			// 			title: '提示',
+			// 			content: '是否向该用户充值一年费用?',
+			// 			success: function(res) {
+			// 				if (res.confirm) {
+			// 					this.getRecharge()
+			// 					console.log('用户点击确定');
+			// 				} else if (res.cancel) {
+			// 					console.log('用户点击取消');
+			// 				}
+			// 			}
+			// 		});
+			// 	}else{
+			// 		uni.showToast({
+			// 			title: "您暂无权限进行此操作,如有需要,请联系管理员",
+			// 			icon: "none"
+			// 		})
+			// 	}
+			// }
+		},
+		onLoad(option) {
+			this.user_meg = JSON.parse(option.item)
+			console.log(this.user_meg)
+			if (this.user_meg.state == '1') {
+				this.tf = "正常"
+				this.forbiddenTF = true
+			} else if (this.user_meg.state == '4') {
+				this.tf = "禁止使用"
+				this.forbiddenTF = false
+			}
+			this.getGroup()
+			this.getThemes()
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "系统管理"
+					})
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "用户管理"
+					})
+					let shebeiitems = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "设备管理"
+					})
+					this.quanxian.shebeiitems = shebeiitems[0].children.some((item)=>{
+						return item.purview_name == "分配设备"
+					})
+					var arr = items2[0].children
+					console.log(items)
+					for(var i =0;i<arr.length;i++){
+						switch (arr[i].purview_name){
+							case "充值":
+								this.quanxian.chongzhi = true
+								break
+							case "编辑":
+								this.quanxian.alters = true
+								break
+							case "禁用":
+								this.quanxian.off = true
+								break
+							case "密码":
+								this.quanxian.pass = true
+								break
+						}
+					}
+				},
+			})
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+	}
+</script>
+
+<style lang="scss">
+	.useroperations {
+		width: 100%;
+		display: flex;
+		justify-content: center;
+
+		.uForm {
+			margin-top: 44px;
+			width: 95%;
+
+			.uFormbg {
+				width: 100%;
+				background-color: #f3f3f3;
+				margin-top: 20rpx;
+			}
+
+			.tishi {
+				text-align: center;
+				font-size: 24rpx;
+				color: red;
+			}
+
+			.u-form-item {
+				width: 95%;
+				height: 80rpx;
+				margin: 0 auto;
+				padding: 5rpx 0;
+			}
+
+			.uuinput {
+				background-color: white;
+			}
+		}
+	}
+
+	.operation_group {
+		.group_one {
+			.group_one_top {
+				width: 90%;
+				margin: 20rpx auto;
+				display: flex;
+				justify-content: space-around;
+
+				button {
+					width: 23%;
+					height: 60rpx;
+					line-height: 60rpx;
+					background-color: $uni-color-success;
+					color: white;
+					font-size: 24rpx;
+				}
+			}
+
+			.group_one_bot {
+				width: 90%;
+				margin: 20rpx auto;
+
+				button {
+					height: 60rpx;
+					line-height: 60rpx;
+					background-color: $uni-color-success;
+					color: white;
+					font-size: 30rpx;
+				}
+			}
+		}
+
+		.group_two {
+			width: 90%;
+			margin: 20rpx auto;
+
+			button {
+				background-color: $uni-color-success;
+				color: white;
+				height: 80rpx;
+				line-height: 80rpx;
+				font-size: 30rpx;
+			}
+		}
+
+	}
+
+	.pop-up {
+		.sheet {
+			background-color: white;
+			height: 400rpx;
+			overflow: hidden;
+			.sheet-text {
+				height: 80rpx;
+				p {
+					text-align: center;
+					height: 80rpx;
+					line-height: 80rpx;
+					color: black;
+					font-size: 16px;
+				}
+			}
+
+		}
+
+		button {
+			color: black;
+			position: absolute;
+			bottom: 0;
+			width: 100%;
+			font-size: 16px;
+			height: 80rpx;
+		}
+	}
+</style>

+ 289 - 0
pages/expertDiagnosis/exchangeShare.vue

@@ -0,0 +1,289 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="交流圈">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/tianjiawenjian.png'" mode="" class="right_icon" @click="postmessage"></image>
+				</uni-nav-bar>
+			</view>
+			<u-action-sheet :list="actionSheetList" v-model="post_show" @click="message"></u-action-sheet>
+			<view class="invitations">
+				<view class="invitations_item" v-for="(items,index) in invitation" :key="index" @click="particulars(items)">
+					<view class="invitations_item_left">
+						<image :src="items.img_urls" mode="" v-if="items.img_urls!='' && items.img_urls!=null"></image>
+						<image :src="'http://static.yfpyx.com/projectimg'+defaultimg" mode="" v-else></image>
+					</view>
+					<view class="invitations_item_right">
+						<view class="invitations_item_right_top">
+							<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/6940a11a251770f1b0d8b7b10ebdf9b.png'" mode="" v-if="Number(items.heat) == 1"></image>
+							<span>{{items.title}}</span>
+						</view>
+						<view class="invitations_item_right_contert" v-html="items.content">
+						</view>
+						<view class="invitations_item_right_bot">
+							<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/d2014837228702eeceb762bc5302b3f.png'" mode=""></image>
+							<span>{{items.username}}</span>
+							<p>查看详情</p>
+						</view>
+						<view class="delinvit" v-if="myTF" @click.stop="delinvit(items.lower)">
+							删除
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				// pest.pests.pests_heat_rank
+				invitation: [],
+				actionSheetList: [{
+					text: "我的发帖"
+				}, {
+					text: "我要发帖"
+				}],
+				post_show: false,
+				defaultimg: '/images/expertDiagnosis/img01.png',
+				page:1,
+				myTF:false ,//判断是全部发帖还是我的发帖
+				isTop:false
+			}
+		},
+		methods: {
+			async getInvitation(str) { //获取全部发帖 自己发帖"my"
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_answers_list',
+					data: {
+						screen:str,
+						page:this.page,
+						page_size:10
+					}
+				})
+				this.invitation = this.invitation.concat(res.data)
+				for (var i = 0; i < this.invitation.length; i++) {
+					var index1 = this.invitation[i].content.indexOf("/>") + 2
+					var index2 = this.invitation[i].content.indexOf('<img')
+					var str = this.invitation[i].content.slice(index2, index1)
+					this.invitation[i].content = this.invitation[i].content.replace(str, '')
+				}
+				console.log(this.invitation)
+			},
+			//pest.pests.del_pests_card删除帖子
+			async delInvitation(data) { //获取全部发帖 自己发帖"my"
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.del_pests_card',
+					data: {
+						lower:data,
+						card:1  
+					}
+				})
+				if(res.code==200){
+					this.$forceUpdate()
+				}
+			},
+			clickLeft() {
+				uni.navigateTo({
+					url: './index'
+				})
+			},
+			particulars(items) { //详情页
+				uni.navigateTo({
+					url: "particulars?items=" + JSON.stringify(items)
+				})
+			},
+			postmessage() { //发帖
+				this.post_show = true
+			},
+			message(index) {
+				if (this.actionSheetList[index].text.includes("我要发帖")) {
+					uni.navigateTo({
+						url: "./postmessage"
+					})
+				} else if (this.actionSheetList[index].text.includes("我的发帖")) {
+					this.actionSheetList[index].text = "全部发帖"
+					this.pege =1
+					let str = "my"
+					this.invitation = []
+					this.getInvitation(str)
+					this.myTF = true
+				} else if (this.actionSheetList[index].text.includes("全部发帖")) {
+					this.pege =1
+					let str = ""
+					this.invitation = []
+					this.getInvitation(str)
+					this.myTF = false
+				}
+			},
+			delinvit(items){
+				uni.showModal({
+				    title: '提示',
+				    content: '是否删除该帖子?',
+				    success: (res)=> {
+				        if (res.confirm) {
+				            this.delInvitation(items)
+							this.pege =1
+							let str = "my"
+							this.invitation = []
+							this.getInvitation(str)
+				        } else if (res.cancel) {
+				            console.log('用户点击取消');
+				        }
+				    }
+				});
+				
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad() {
+			let str = ""
+			this.getInvitation(str)
+		},
+		onReachBottom(){
+			this.page ++ 
+			if(this.myTF){
+				let str = "my"
+				this.getInvitation(str)
+			}else{
+				let str = ""
+				this.getInvitation(str)
+			}
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.right_icon {
+		width: 40rpx;
+		height: 40rpx;
+		position: absolute;
+		top: 26rpx;
+		right: 26rpx;
+	}
+
+	.invitations {
+		width: 100%;
+		position: relative;
+		top: 88rpx;
+
+		.invitations_item {
+			width: 90%;
+			margin: 0 auto;
+			display: flex;
+			justify-content: space-between;
+			padding: 30rpx 0;
+
+			.invitations_item_left {
+				width: 26%;
+
+				image {
+					width: 100%;
+					height: 180rpx;
+				}
+			}
+
+			.invitations_item_right {
+				width: 71%;
+				position: relative;
+				
+				.invitations_item_right_top {
+					width: 100%;
+
+					image {
+						width: 32rpx;
+						height: 32rpx;
+						margin: 0 16rpx 0 0;
+						vertical-align: text-bottom;
+					}
+
+					span {
+						font-weight: 700;
+					}
+				}
+				.delinvit{
+					position: absolute;
+					right: 0;
+					top: 0;
+					color: #ff0000;
+				}
+				.invitations_item_right_contert {
+					width: 100%;
+					margin: 10rpx 0;
+					overflow: hidden;
+					-webkit-line-clamp: 2;
+					text-overflow: ellipsis;
+					display: -webkit-box;
+					-webkit-box-orient: vertical;
+				}
+
+				.invitations_item_right_bot {
+					display: flex;
+					position: absolute;
+					bottom: 12rpx;
+					height: 50rpx;
+					width: 100%;
+
+					image {
+						width: 50rpx;
+						height: 50rpx;
+						position: absolute;
+					}
+
+					span {
+						color: #B9B9B9;
+						margin-left: 74rpx;
+						line-height: 50rpx;
+					}
+
+					p {
+						width: 100rpx;
+						height: 40rpx;
+						font-size: 24rpx;
+						border: 2rpx solid #5FAE50;
+						line-height: 40rpx;
+						padding: 0 10rpx;
+						position: absolute;
+						right: 0;
+						top: 6rpx;
+						color: #5FAE50;
+					}
+				}
+			}
+		}
+	}
+	.top { 
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 201 - 0
pages/expertDiagnosis/index.vue

@@ -0,0 +1,201 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 44px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="专家诊断"></uni-nav-bar>
+			</view>
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/05571341dbb0771b23d0b271764ac2e.png'" class="expertimages"></image>
+			<view class="expert_details">
+				<view class="details_item" @click="worm">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/6612b1293fd1f45dd7ce6269a954999.png'"></image>
+					<p>虫情百科</p>
+				</view>
+				<view class="details_item" @click="virus">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/7f34f4eeba4d00819369cfa1b5ecce8.png'"></image>
+					<p>病害百科</p>
+				</view>
+				<view class="details_item" @click="exchange">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/aa6a168b9fb72b62b687a2debc04a9f.png'"></image>
+					<p>交流圈</p>
+				</view>
+			</view>
+			<view class="cooperation">
+				<view class="cooperation_item">
+					<p class="cooperation_item_title">合作单位</p>
+					<view class="zooid">
+						<view class="zooid_item" v-for="(item,index) in cooperation_unit" :key="index">
+							<image :src="item.img_urls" mode=""></image>
+							<p>{{item.name}}</p>
+						</view>
+					</view>
+				</view>
+				<view class="cooperation_item">
+					<p class="cooperation_item_title">合作院校</p>
+					<view class="zooid">
+						<view class="zooid_item" v-for="(item,index) in cooperation_academy" :key="index">
+							<image :src="item.img_urls" mode=""></image>
+							<p>{{item.name}}</p>
+						</view>
+					</view>
+				</view>
+				<view class="cooperation_item">
+					<p class="cooperation_item_title">合作专家</p>
+					<view class="zooid">
+						<view class="zooid_item" v-for="(item,index) in cooperation_specialist" :key="index">
+							<image :src="item.img_urls" mode=""></image>
+							<p>{{item.name}}</p>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				cooperation_academy: [], //合作院校信息
+				cooperation_unit: [], //合作单位信息
+				cooperation_specialist: [], //合作专家信息,
+				jurisdiction:false
+			}
+		},
+		methods: {
+			async getCooperation(code) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_expert',
+					data: {
+						code: code
+					}
+				})
+				console.log(res)
+				if (code == 1) {
+					this.cooperation_unit = res.data
+				} else if (code == 2) {
+					this.cooperation_academy = res.data
+				} else if (code == 3) {
+					this.cooperation_specialist = res.data
+				}
+			},
+			clickLeft() {
+				uni.switchTab({
+					url: "../index/index"
+				})
+			},
+			worm() {
+				uni.navigateTo({
+					url: "./wormcase?name=" + '虫情百科',
+				});
+			},
+			virus() {
+				uni.navigateTo({
+					url: "./wormcase?name=" + '病毒百科',
+				});
+			},
+			exchange() {
+				if(this.jurisdiction){
+					uni.navigateTo({
+						url: "./exchangeShare"
+					});
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			}
+		},
+		onLoad() {
+			this.getCooperation(1)
+			this.getCooperation(2)
+			this.getCooperation(3)
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "专家介绍"
+					})
+					this.jurisdiction = items[0].children.some((item)=>{
+						return item.purview_name == "发帖列表"
+					})
+				},
+			})
+		},
+		onBackPress(options) {
+			if (options.from === 'navigateBack') {
+				return false;
+			}
+			this.clickLeft();
+			return true;
+		},
+	}
+</script>
+
+<style lang="scss">
+	.expertimages {
+		width: 100%;
+		height: 200rpx;
+		margin-top: 88rpx;
+	}
+
+	.expert_details {
+		width: 100%;
+		height: 120rpx;
+		display: flex;
+		justify-content: space-around;
+		margin: 20rpx 0 30rpx;
+
+		.details_item {
+			width: 20%;
+			padding: 10rpx 20rpx;
+			text-align: center;
+			font-size: 24rpx;
+
+			image {
+				width: 70%;
+				height: 84rpx;
+			}
+		}
+	}
+
+	.cooperation {
+		width: 100%;
+		margin: 20rpx 0 60rpx;
+
+		.cooperation_item {
+			width: 95%;
+			margin: 20rpx auto;
+
+			.cooperation_item_title {
+				border-left: 8rpx solid #18B566;
+				text-indent: 16rpx;
+			}
+
+			.zooid {
+				width: 100%;
+				display: flex;
+				flex-wrap: wrap;
+				margin-top: 20rpx;
+
+				.zooid_item {
+					width: 22%;
+					margin: 10rpx;
+
+					image {
+						width: 100%;
+						height: 154rpx;
+					}
+
+					p {
+						font-size: 24rpx;
+						text-align: center;
+						margin: 10rpx 0;
+					}
+				}
+			}
+		}
+	}
+</style>

+ 133 - 0
pages/expertDiagnosis/introduce.vue

@@ -0,0 +1,133 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="详情"></uni-nav-bar>
+			</view>
+			<view class="img_box">
+				<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/loading-2.gif'" mode="" class="imgbg"></image>
+				<image :src="wormcasedata.img_urls" mode="" class="img" @click="examine(wormcasedata.img_urls)"></image>
+			</view>
+			<p class="name">{{wormcasedata.name}}</p>
+			<view v-for="(item,index) in preventionArr" :key="index" class="prevention">
+				<view class="prevention_title">
+					<u-icon name="play-right-fill" size="24" color="#55A92D"></u-icon>
+					<p>{{regexptitle[index]}}:</p>
+				</view>
+				<p class="prevention_con">{{item}}</p>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				wormcasedata: {},
+				unititle: '',
+				wormdata: { //虫子数据
+
+				},
+				disease: { //病害数据
+
+				},
+				preventionArr: [],
+				regexptitle: []
+			}
+		},
+		methods: {
+			async getIntroduce(data) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_info',
+					data: {
+						pest_id: data
+					}
+				})
+				console.log(res)
+				this.wormcasedata = res
+				var regex2 = /\[(.+?)\]/g; // [] 中括号
+				var str = this.wormcasedata.prevention
+				var arr = str.match(regex2)
+				var arrindex = []
+				for (var i = 0; i < arr.length; i++) {
+					arrindex.push(str.indexOf(arr[i]))
+				}
+				for (var i = 0; i < arr.length; i++) {
+					this.preventionArr.push(str.slice(arrindex[i] + arr[i].length, arrindex[i + 1]))
+				}
+				for (var i = 0; i < arr.length; i++) {
+					arr[i] = arr[i].slice(1, arr[i].length - 1)
+				}
+				this.regexptitle = arr
+			},
+			clickLeft() {
+				uni.navigateTo({
+					url: "./wormcase?name=" + this.unititle
+				})
+			},
+			examine(url) {
+				var imgarr =[]
+				imgarr.push(url)
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			}
+		},
+		onLoad(option) {
+			console.log(option)
+			this.unititle = option.title
+			this.getIntroduce(option.id)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.name {
+		font-size: 34rpx;
+		font-weight: 700;
+		width: 95%;
+		margin: 100rpx auto 0;
+	}
+	.img_box{
+		width: 100%;
+		height: 320rpx;
+		position: relative;
+		top: 44px;
+		.imgbg{
+			width: 30%;
+			height: 50%;
+			position: absolute;
+			top: 25%;
+			left: 35%;
+		}
+		.img{
+			width: 100%;
+			height: 100%;
+			position: absolute;
+		}
+	}
+	.prevention {
+		font-size: 28rpx;
+		color: #919191;
+		width: 95%;
+		margin: 20rpx auto;
+
+		.prevention_title {
+			display: flex;
+
+			p {
+				margin-left: 20rpx;
+				color: #000000;
+				font-size: 28rpx;
+				font-weight: 700;
+			}
+		}
+
+		.prevention_con {
+			padding-left: 6%;
+		}
+	}
+</style>

+ 286 - 0
pages/expertDiagnosis/particulars.vue

@@ -0,0 +1,286 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view style="position: fixed;top: 64px;">
+			<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="详情"></uni-nav-bar>
+			<u-swiper :list="list" height="428" @click="examine(list)"></u-swiper>
+			<view class="quiz">
+				<view class="quiz_username">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/expertDiagnosis/6940a11a251770f1b0d8b7b10ebdf9b.png'" mode="" v-if="Number(quizdata.heat)==1"></image>
+					<span>{{quizdata.title}}</span>
+				</view>
+				<view class="quiz_usertime">
+					<view style="display: flex;align-items: center;">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/fourMoodBase/touxiang.png'" mode=""></image>
+						<span>{{quizdata.username}}</span>
+					</view>
+					<view>
+						<span>{{quizdata.adtime|timeFormat()}}</span>
+					</view>
+				</view>
+				<view class="quiz_usercontert" v-html="quizdata.content"></view>
+			</view>
+			<view class="comment">
+				<p class="comment_title">评论</p>
+				<scroll-view class="scroll-view_H" :scroll-y="true" @scrolltolower="scroll" scroll-top="0">
+					<view class="comment_unit" v-for="(item,index) in commentdata" :key="index">
+						<view class="comment_unit_user">
+							<view class="username">
+								<image :src="item.image" mode=""></image>
+								<span style="font-size: 26rpx;color:#C1C1C1;">{{item.username}}</span>
+								<p v-if="Number(item.user_type) == 1">专家</p>
+							</view>
+							<view>
+								<span style="font-size: 26rpx;color:#C1C1C1;">{{item.uptime|timeFormat()}}</span>
+							</view>
+						</view>
+						<view class="comment_unit_con">
+							<p v-html="item.content"></p>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+		</view>
+		<view class="issue_box" :style="{position: 'absolute',bottom: height+'px'}">
+			<view class="issue">
+				<input type="text" v-model="issuedata" @focus="focus" :auto-blur="true" :adjust-position='false' @blur="blur"
+				 @confirm="confirm" />
+				<p @click="issue">发布</p>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				list: [{}],
+				quizdata: {},
+				commentdata: [],
+				issuedata: '',
+				defaultimg: '/images/expertDiagnosis/img01.png',
+				height: 0,
+				page: 1,
+			}
+		},
+		methods: { //
+			async getParticulars(datas) {//获取评论列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_answers_list',
+					data: {
+						lower: datas,
+						page: this.page,
+						page_size: 10
+					}
+				})
+				this.commentdata = this.commentdata.concat(res.data)
+				console.log(res.data)
+			},
+			async getDiscuss(data) {//发布评论
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_new_idea',
+					data: {
+						lower: data.lower,
+						content: data.content,
+					}
+				})
+				if(res.code==200){
+					this.commentdata = []
+					this.page = 1
+					this.getParticulars(this.quizdata.lower)
+				}
+				console.log(res)
+			},
+			clickLeft() {
+				uni.navigateTo({
+					url: "./exchangeShare"
+				})
+			},
+			issue() { //发布评论
+				let obj = {}
+				obj.lower = this.quizdata.lower
+				obj.content = this.issuedata
+				if (this.issuedata != '') {
+					this.getDiscuss(obj)
+					this.issuedata = ''
+				}
+			},
+			focus(e) {
+				this.height = e.detail.height
+			},
+			blur() {
+				this.height = 0
+			},
+			confirm() {
+				this.issue()
+			},
+			scroll(e) {
+				this.page++
+				this.getParticulars(this.quizdata.lower)
+			},
+			examine(list){
+				console.log(list)
+				var imgarr =[]
+				for(var i=0;i<list.length;i++){
+					imgarr.unshift(list[i].image)
+				}
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			}
+		},
+		onLoad(option) {
+			this.quizdata = JSON.parse(option.items)
+			console.log(this.quizdata.lower)
+			if (this.quizdata.img_urls == '' || this.quizdata.img_urls == null) {
+				this.list[0].image = 'http://static.yfpyx.com/projectimg' + this.defaultimg
+			} else {
+				this.list[0].image = this.quizdata.img_urls
+			}
+			this.getParticulars(this.quizdata.lower)
+		}
+	}
+</script>
+<style lang="scss">
+	.u-swiper-wrap {
+		width: 95%;
+		margin: 20rpx auto;
+	}
+
+	.quiz {
+		width: 95%;
+		margin: 20rpx auto;
+		border-bottom: 4rpx dashed #E8E8E8;
+
+		.quiz_username {
+			width: 100%;
+
+			image {
+				width: 40rpx;
+				height: 40rpx;
+				vertical-align: middle;
+				margin-right: 20rpx;
+			}
+
+			span {
+				font-weight: 700;
+				font-size: 32rpx;
+			}
+		}
+
+		.quiz_usertime {
+			width: 100%;
+			margin-top: 15rpx;
+			display: flex;
+			justify-content: space-between;
+
+			image {
+				width: 50rpx;
+				height: 50rpx;
+				margin-right: 20rpx;
+			}
+
+			span {
+				font-size: 24rpx;
+				color: #C1C1C1;
+				font-weight: 700;
+			}
+		}
+
+		.quiz_usercontert {
+			padding: 20rpx;
+			margin-bottom: 20rpx;
+		}
+	}
+
+	.comment {
+		width: 95%;
+		margin: 20rpx auto 0;
+
+		.comment_title {
+			font-weight: 700;
+			font-size: 32rpx;
+		}
+
+		.scroll-view_H {
+			height: 600rpx;
+		}
+
+		.comment_unit {
+			.comment_unit_user {
+				display: flex;
+				justify-content: space-between;
+				margin-top: 20rpx;
+
+				.username {
+					display: flex;
+					align-items: center;
+
+					image {
+						width: 50rpx;
+						height: 50rpx;
+						margin-right: 20rpx;
+						border-radius: 50%;
+					}
+
+					p {
+						width: 60rpx;
+						height: 30rpx;
+						color: white;
+						background-color: #5CA348;
+						font-size: 24rpx;
+						text-align: center;
+						line-height: 30rpx;
+						padding: 0 10rpx;
+						margin-left: 20rpx;
+						border-radius: 8rpx;
+					}
+				}
+			}
+
+			.comment_unit_con {
+				padding-left: 60rpx;
+
+				/deep/p {
+					margin-top: 20rpx;
+
+					img {
+						margin-top: 20rpx;
+						display: block;
+						width: 180rpx !important;
+						height: 180rpx !important;
+					}
+				}
+
+			}
+		}
+	}
+
+	.issue_box {
+		width: 100%;
+		background-color: #FFFFFF;
+	}
+
+	.issue {
+		width: 95%;
+		margin: 0 auto;
+		display: flex;
+		padding-bottom: 20rpx;
+
+		input {
+			width: 90%;
+			background-color: #F3F3F3;
+			height: 60rpx;
+			text-indent: 1em;
+		}
+
+		p {
+			width: 10%;
+			text-align: right;
+			line-height: 60rpx;
+			color: #7a7a7a;
+		}
+	}
+</style>

+ 200 - 0
pages/expertDiagnosis/postmessage.vue

@@ -0,0 +1,200 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="发帖"></uni-nav-bar>
+			<view class="post">
+				<view class="post_title">
+					<input type="text" placeholder="请输入标题" v-model="title" />
+				</view>
+				<view class="post_contert">
+					<textarea v-model="mainbody" placeholder="请输入正文" />
+					<view class="imgvideo_img">
+						<view @click="gainimg" class="imgbg">
+							<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/afterSale/eee1e84bb85f6f6ff5c5866a3a42779.png'" mode="" v-if="!uploadingTF"></image>
+						</view>
+						<view class="uploading" v-if="uploadingTF">
+							<u-icon name="close" class="delete" @click="deletes"></u-icon>
+							<image :src="path" mode="" class="uploading" @click="examine(path)"></image>
+						</view>
+					</view>
+				</view>
+				<button class="post_btn" @click="post">发布</button>
+			</view>
+		</view>
+		<kps-image-cutter @ok="onok" @cancel="oncancle" :url="url" :fixed="false" :blob="false" :maxWidth="500" :maxHeight="500"></kps-image-cutter>
+	</view>
+</template>
+
+<script>
+	import kpsImageCutter from "@/components/ksp-image-cutter/ksp-image-cutter.vue";
+	export default {
+		components:{
+			kpsImageCutter
+		},
+		data() {
+			return {
+				title:'',  
+				mainbody:'',
+				uploadingTF:false,
+				url:"",
+				path:""
+			}
+		},
+		methods: {
+			async getPostmessage(data) { //发帖
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_new_idea',
+					data:{
+						title:data.title,
+						content:data.content,
+						img_urls:this.path
+					}
+				})
+				console.log(res)
+			},
+			post(){
+				if(this.title!=''&&this.mainbody!=''){
+					let obj ={}
+					obj.title=this.title
+					obj.content=this.mainbody
+					this.getPostmessage(obj)
+					uni.navigateTo({
+						url: './exchangeShare'
+					})
+				}
+			},
+			clickLeft(){
+				uni.navigateTo({
+					url: './exchangeShare'
+				})
+			},
+			gainimg(){//添加图片
+				uni.chooseImage({
+				    count: 1, //默认9
+				    sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+				    sourceType: ['album','camera'], //从相册选择
+				    success: (res)=> {
+						console.log(res)
+						this.url = res.tempFilePaths[0]
+					}
+				});
+			},
+			onok(ev){
+				console.log(ev)
+				uni.uploadFile({
+				    url: 'http://182.92.193.64:8002/api/api_gateway?method=pest.pests.pests_img', //仅为示例,非真实的接口地址
+					filePath: ev.path,
+				    name: 'img_file',
+				    formData: {
+				        'user': 'test'
+				    },
+				    success: (uploadFileRes) => {
+						console.log(JSON.parse(uploadFileRes.data).data.src)
+						this.path = JSON.parse(uploadFileRes.data).data.src
+						this.uploadingTF=true
+				    }
+				});
+				this.url = ''
+			},
+			oncancle(){
+				
+			},
+			examine(url) {
+				var imgarr =[]
+				imgarr.push(url)
+				console.log(imgarr)
+				uni.previewImage({
+					urls: imgarr
+				});
+			},
+			deletes(){
+				this.path = ""
+				this.uploadingTF=false
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page{
+		background-color: #F5F5F5;
+	}
+	.post {
+		width: 100%;
+		padding-top: 16rpx;
+		.post_title {
+			padding: 40rpx 20rpx;
+			background-color: white;
+			width: 100%;
+			box-sizing: border-box;
+			input {
+				width: 90%;
+				margin: 0 auto;
+			}
+		}
+
+		.post_contert {
+			margin-top: 16rpx;
+			padding: 40rpx 20rpx;
+			background-color: white;
+			width: 100%;
+			height: 660rpx;
+			box-sizing: border-box;
+			textarea{
+				width: 90%;
+				margin: 0 auto;
+			}
+			.imgvideo_img{
+				width: 250rpx;
+				height: 250rpx;
+				border: 2rpx solid #57C878;
+				margin-left: 40rpx;
+				position: relative;
+				top: 0;
+				left: 0;
+				.imgbg{
+					width: 100%;
+					height: 100%;
+					display: flex;
+					justify-content: center;
+					align-items: center;
+					image{
+						width: 50rpx;
+						height: 50rpx;
+					}
+				}
+				.uploading{
+					width: 100%;
+					height: 100%;
+					.delete{
+						width: 36rpx;
+						height: 36rpx;
+						background-color: #FF0000;
+						border-radius: 50%;
+						padding: 2px 2px;
+						box-sizing: border-box;
+						position: absolute;
+						top: -18rpx;
+						right: -18rpx;
+						color: #FFFFFF;
+						z-index: 10;
+					}
+					.uploading{
+						width: 100%;
+						height: 100%;
+						position: absolute;
+						top: 0;
+					}
+				}
+			}
+		}
+		.post_btn{
+			width: 90%;
+			margin: 40rpx auto;
+			background-color: #57C878;
+			color: white;
+			font-size: 32rpx;
+		}
+	}
+</style>

+ 141 - 0
pages/expertDiagnosis/wormcase.vue

@@ -0,0 +1,141 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" :title="title"></uni-nav-bar>
+			</view>
+			<view class="particulars">
+				<view class="particulars_item" v-for="(item,index) in content" :key="index" @click="introduce(item.id)">
+					<view class="imgs">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/loading-2.gif'" mode="" class="imgbg"></image>
+						<image :src="item.img_urls" mode="" class="imgs_img"></image>
+					</view>
+					<p>{{item.name}}</p>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				title: '',
+				content: [],
+				data: {
+					code: null,
+					page: null
+				},
+				isTop:false
+			}
+		},
+		methods: {
+			async getCooperation(data) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=pest.pests.pests_search',
+					data: {
+						code: data.code,
+						page: data.page
+					}
+				})
+				this.content = this.content.concat(res.data)
+			},
+			clickLeft() {
+				uni.navigateTo({
+					url: "./index"
+				})
+			},
+			introduce(id) {
+				uni.navigateTo({
+					url: "./introduce?id=" + id + "&title=" + this.title
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			},
+		},
+		onLoad(option) {
+			this.title = option.name
+			if (option.name == "虫情百科") {
+				this.data.code = 2
+				this.data.page = 1
+				this.getCooperation(this.data)
+			} else {
+				this.data.code = 1
+				this.data.page = 1
+				this.getCooperation(this.data)
+			}
+		},
+		onReachBottom() {
+			this.data.page++
+			this.getCooperation(this.data)
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+<style lang="scss">
+	.particulars {
+		width: 100%;
+		position: relative;
+		top: 88rpx;
+		display: flex;
+		flex-wrap: wrap;
+
+		.particulars_item {
+			width: 50%;
+			padding: 20rpx;
+			box-sizing: border-box;
+
+			.imgs {
+				width: 100%;
+				height: 220rpx;
+				position: relative;
+
+				.imgbg {
+					width: 50%;
+					height: 50%;
+					position: absolute;
+					top: 25%;
+					left: 25%;
+				}
+
+				.imgs_img {
+					width: 100%;
+					height: 100%;
+					position: absolute;
+					top: 0;
+					left: 0;
+				}
+			}
+
+			p {
+				font-size: 24rpx;
+			}
+		}
+	}
+
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+
+		image {
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 357 - 0
pages/fourBase/addbase.vue

@@ -0,0 +1,357 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="新增基地"></uni-nav-bar>
+			</view>
+			<view class="addimg">
+				<view class="addimg_add" @click="gainimg">
+					<u-icon name="plus" size="60rpx" color="#A5A6A8"></u-icon>
+					<image :src="baseinfo.base_img" mode="" class="addimg_img"></image>
+				</view>
+			</view>
+			<view class="base_text">
+				<p class="title">基地信息</p>
+				<view class="base_text_item1">
+					<u-icon name="fangzi" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>基地名称</span>
+					<input type="text" v-model="baseinfo.base_name" placeholder="请输入基地名称" />
+				</view>
+				<view class="base_text_item1">
+					<u-icon name="ren1" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>负责人</span>
+					<input type="text" v-model="baseinfo.base_charge " placeholder="请输入基地负责人" />
+				</view>
+				<view class="base_text_item1">
+					<u-icon name="lianxidianhua" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>联系电话</span>
+					<input type="text" v-model="baseinfo.base_phone" placeholder="请输入联系电话" @blur="yanzheng" />
+				</view>
+				<view class="base_text_item1">
+					<u-icon name="mianji" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>面积(亩)</span>
+					<input type="number" v-model="baseinfo.base_area" placeholder="请输入基地面积" />
+				</view>
+				<view class="base_text_item2">
+					<u-icon name="miaoshu" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span>基地描述</span>
+					<textarea v-model="baseinfo.base_describe " maxlength="80" auto-height class="textarea" placeholder="请输入基地描述(不能大于80字)" />
+					</view>
+				<view class="base_text_item1" @click="map">
+					<u-icon name="Frame1" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>基地定位</span>
+					<input type="text" v-model="city" placeholder="请选择地址" disabled style="position: absolute;right: 60rpx;width: 60%;"/>
+					<u-icon name="arrow-right" class="iconright"></u-icon>
+				</view>
+				<view class="base_text_item1" @click="binding">
+					<u-icon name="bangding" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>设备绑定</span>
+					<u-icon name="arrow-right" class="iconright"></u-icon>
+				</view>
+				<view class="base_id_box">
+					<view class="base_id" v-for="(item,key,index) in base_id" :key="index">
+						<view class="base_id_item" v-for="(items,indexs) in item" :key="indexs">
+							<span>{{key}}</span>
+							<span>{{items}}</span>
+						</view>
+					</view>
+				</view>
+				<view class="btn" @click="tijiao">
+				确 定
+				</view>
+			</view>
+		</view>
+		<kps-image-cutter @ok="onok" @cancel="oncancle" :url="imgs" :fixed="false" :blob="false" :maxWidth="500" :maxHeight="500"></kps-image-cutter>
+	</view>
+</template>
+<script>
+	import kpsImageCutter from "@/components/ksp-image-cutter/ksp-image-cutter.vue";
+	export default {
+		components:{
+			kpsImageCutter
+		},
+		data() {
+			return {
+				base_id:{},
+				baseinfo:{
+					base_name:'',//必传(str)           基地名称
+					base_charge:'',//必传(str)           负责人
+					base_phone:'',//必传(str)           联系电话
+					base_img:'',// 必传(str)           基地图片
+					base_area:'',//必传(str)           基地面积
+					base_equip:'', //必传(str)           绑定设备 如果绑定多个设备传 289#299, 如果是单一设备传298
+					base_describe:'',//非必传(str)         基地描述
+					lng:'',//必传(str)           经度
+					lat:'',//必传(str)           纬度
+					ret:"add",//必传(str)           区分
+				},
+				city:'',
+				imgs:"",
+			}
+		},
+		methods: {
+			//base.bases.base_list新增基地
+			async addbase() { //获取分布位置
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=base.bases.base_list',
+					data: this.baseinfo
+				})
+			},
+			clickLeft(){
+				uni.navigateTo({
+					url:"./index"
+				})
+			},
+			binding(){
+				uni.navigateTo({
+					url:"./allocation"
+				})
+			},
+			gainimg() { //添加图片
+					uni.chooseImage({
+						count: 1, //默认9
+						sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+						sourceType: ['album', 'camera'], //从相册选择
+						success: (res) => {
+							this.imgs = res.tempFilePaths[0]
+						}
+					})
+			},
+			map(){
+				uni.navigateTo({
+					url:"city"
+				})
+			},
+			tijiao(){
+				if(this.baseinfo.base_img==''){
+					uni.showToast({
+					    title: '请选择基地图片', 
+					    duration: 2000,
+						icon:"none"
+					});
+				
+				}else if(this.baseinfo.base_name==''){
+					uni.showToast({
+					    title: '请填写正基地名称', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_charge==''){
+					uni.showToast({
+					    title: '请填写基地负责人', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_phone==''){
+					uni.showToast({
+					    title: '请填写手机号', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_area==''){
+					uni.showToast({
+					    title: '请填写基地面积', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.lng==''){
+					uni.showToast({
+					    title: '请选择基地地址', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_id==''){
+					uni.showToast({
+					    title: '请绑定基地设备', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else{
+					if(!/^1[23456789]\d{9}$/.test(this.baseinfo.base_phone)){
+						uni.showToast({
+						    title: '请填写正确的手机号', 
+						    duration: 2000,
+							icon:"none"
+						});
+					}else{
+						console.log(this.baseinfo)
+						this.addbase()
+						uni.removeStorage({
+						    key: 'id',
+						    success: function (res) {
+						       uni.navigateTo({
+						       	url:"./index"
+						       })
+						    }
+						});
+					}
+				}
+			},
+			yanzheng(){
+				if(!/^1[23456789]\d{9}$/.test(this.baseinfo.base_phone)){
+					uni.showToast({
+					    title: '请填写正确的手机号', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}
+			},
+			onok(ev){
+				uni.uploadFile({
+					url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+					filePath: ev.path,
+					name: 'img_file',
+					formData: {
+						'user': 'test'
+					},
+					success: (uploadFileRes) => {
+						this.baseinfo.base_img = JSON.parse(uploadFileRes.data).data.src
+						// this.$forceUpdate() //强制刷新视图
+					}
+				});
+				this.imgs = ''
+			},
+			oncancle(){
+				this.imgs = ''
+			}
+		},
+		onLoad() {
+		},
+		onShow(){
+			uni.getStorage({
+			    key: 'id',
+			    success: (res)=> {
+						this.base_id = JSON.parse(res.data)
+						var arr = []
+						for(var key in this.base_id){
+							arr.push(this.base_id[key].join("#"))
+						}
+						this.baseinfo.base_equip = arr.join("#")
+			    }
+			});
+		}
+	}
+</script>
+
+<style lang="scss">
+.addimg{
+	position: absolute;
+	top: 108rpx;
+	width: 100%;
+	.addimg_add{
+		position: relative;
+		width: 90%;
+		height: 276rpx;
+		margin: 0 auto;
+		background-color: #F7F8FA;
+		text-align: center;
+		line-height: 276rpx;
+		color: #A7A8AA;
+		.addimg_img{
+			position: absolute;
+			top: 0;
+			width: 100%;
+			left: 0;
+			height: 276rpx;
+		}
+	}
+}
+.base_text{
+	position: absolute;
+	top: 390rpx;
+	width: 100%;
+	.title{
+		width: 90%;
+		margin: 20rpx auto;
+	}
+	.base_text_item2{
+		width: 90%;
+		margin: 10rpx auto 20rpx;
+		padding: 16rpx 20rpx;
+		background-color: #F7F8FA;
+		display: flex;
+		box-sizing: border-box;
+		position: relative;
+		height: 200rpx;
+		.icon{
+			color: #5FBBA0;
+			height: 42rpx;
+		}
+		span{
+			margin: 0 20rpx;
+		}
+		.textarea{
+			font-size: 24rpx;
+			text-align: right;
+			position: absolute;
+			right: 20rpx;
+			width: 70%;
+			height: 200rpx;
+		}
+		
+	}
+	.base_text_item1{
+		display: flex;
+		position: relative;
+		width: 90%;
+		height: 70rpx;
+		margin: 10rpx auto 20rpx;
+		padding: 16rpx 20rpx;
+		background-color: #F7F8FA;
+		box-sizing: border-box;
+		.icon{
+			color: #5FBBA0;
+		}
+		span{
+			margin: 0 10rpx;
+		}
+		input{
+			position: absolute;
+			right: 20rpx;
+			width: 70%;
+			text-align: right;
+			font-size: 24rpx;
+			margin-top: 5rpx;
+		}
+		.iconright{
+			position: absolute;
+			right: 20rpx;
+			top: 28rpx;
+			color: #B5B6B8;
+			font-size: 24rpx;
+		}
+	}
+}
+.base_id_box{
+		width: 90%;
+		margin: 20rpx auto 70rpx;
+	}
+	.base_id{
+		width: 100%;
+		.base_id_item{
+			width: 95%;
+			padding: 10rpx 30rpx;
+			display: flex;
+			justify-content: space-between;
+			font-size: 28rpx;
+			background-color: #F7F8FA;
+			color: #616162;
+			box-sizing: border-box;
+			margin: 20rpx auto;
+		}
+	}
+	.btn{
+		width: 90%;
+		position: fixed;
+		bottom: 10rpx;
+		right: 5%;
+		text-align: center;
+		height: 70rpx;
+		line-height: 70rpx;
+		background-color: #359773;
+		font-size: 34rpx;
+		border-radius: 35rpx;
+		color: #FFFFFF;
+	}
+</style>

+ 328 - 0
pages/fourBase/allocation.vue

@@ -0,0 +1,328 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 44px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备分配"></uni-nav-bar>
+			</view>
+			<view class="utabs">
+				<view style="width: 95%;margin: 0 auto;">
+					<u-tabs :list="list" :is-scroll="true" :current="current" @change="change" item-width="140" font-size="24" gutter="20"
+					 bar-width="60" active-color="#42b983"></u-tabs>
+				</view>
+			</view>
+			<view class="ass_list">
+				<checkbox-group class="che_group" @change="checkboxchange">
+					<label class="equipment" v-for="(items,indexs) in assignments.children" :key="items.id">
+						<view class="equipment_top">
+							<image :src="'http://static.yfpyx.com/bigdata_app'+assignments.src" mode="" class="equipment_top_img"></image>
+							<span class="equipment_top_name">{{assignments.type_name}}</span>
+							<checkbox :value="String(items.type_name)" :checked="items.check" class="ucheckbox" color="#42b983" />
+						</view>
+						<view class="equipment_bot">
+							<p class="equipment_bot_id">设备ID:{{items.id}}</p>
+							<p class="equipment_bot_name">设备名称:{{items.type_name}}</p>
+							<view class="equipment_state">在线</view>
+						</view>
+					</label>
+				</checkbox-group>
+			</view>
+			<view class="allocbtn">
+				<button @click="cancel" class="cancel">取消分配</button>
+				<button @click="canfirm" class="canfirm">确定分配</button>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				search: '',
+				checken: false,
+				assignment: [],
+				assignments: [],
+				list: [],
+				current: 0,
+				assignment_items: [],
+				images: [{
+					path: "/image/fourMoodBase/1.png",
+					id: 3
+				}, {
+					path: "/image/fourMoodBase/5.png",
+					id: 5
+				}, {
+					path: "/image/fourMoodBase/2.png",
+					id: 6
+				}, {
+					path: "/image/fourMoodBase/4.png",
+					id: 7
+				},
+				{
+					path: "/image/fourMoodBase/10.png",
+					id: 10
+				}],
+				src: '',
+				obj: {},
+				addtype: [],
+				isTop:false
+			}
+		},
+		methods: {
+			async getFourbase() { //基地列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=base.bases.base_equip',
+				})
+				this.assignment = res.data
+				for (var i = 0; i < this.assignment.length; i++) {
+					let obj = {}
+					obj.name = this.assignment[i].type_name
+					this.list.push(obj)
+					for (var j = 0; j < this.images.length; j++) {
+						if (this.assignment[i].id == this.images[j].id) {
+							this.assignment[i].src = this.images[j].path
+						}
+					}
+				}
+				this.assignments = this.assignment[this.current]
+				for (let i = 0; i < this.assignments.children.length; i++) {
+					this.assignments.children[i].check = false
+					for (let j = 0; j < this.addtype.length; j++) {
+						if (this.assignments.children[i].type_name == this.addtype[j]) {
+							this.assignments.children[i].check = true
+							console.log(this.assignments.children[i].check)
+						}
+					}
+				}
+			},
+			forchange(obj) {
+				for (let i = 0; i < this.assignments.children.length; i++) {
+					this.assignments.children[i].check = false
+				}
+				for (let i = 0; i < this.assignments.children.length; i++) {
+					// this.assignments.children[i].check = false
+					for (let j = 0; j < this.addtype.length; j++) {
+						if (this.assignments.children[i].type_name == this.addtype[j]) {
+							this.assignments.children[i].check = true
+							console.log(this.assignments.children[i].check)
+						}
+					}
+				}
+				for (let key in obj) {
+					for (let i = 0; i < key.length; i++) {
+						for (let j = 0; j < this.assignments.children.length; j++) {
+							if (Number(obj[key][i]) == this.assignments.children[j].type_name) {
+								this.assignments.children[j].check = true
+
+							}
+						}
+					}
+				}
+				this.$forceUpdate()
+			},
+			change(index) {
+				this.current = index
+				this.assignments = this.assignment[index]
+				this.forchange(this.obj)
+				console.log(this.obj)
+			},
+			checkboxchange(e, items) {
+				this.obj[this.assignments.type_name] = e.detail.value
+				this.forchange(this.obj)
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			cancel() {
+				this.clickLeft()
+			},
+			canfirm() {
+				uni.setStorage({
+					key: "id",
+					data: JSON.stringify(this.obj),
+					success: () => {
+						uni.navigateBack({
+							delta: 1
+						})
+					}
+
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad(option) {
+			console.log(option)
+			if (option.type) {
+				this.addtype = option.type.split("#")
+				console.log(this.addtype)
+			}
+			this.getFourbase()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.utabs {
+		width: 100%;
+		position: fixed;
+		top: 88px;
+		z-index: 100;
+	}
+
+	.bases_search {
+		width: 100%;
+		position: fixed;
+		top: 84px;
+		z-index: 100;
+		background-color: #FFFFFF;
+		height: 80rpx;
+		padding-top: 20rpx;
+
+		.bases_search_text {
+			width: 90%;
+			margin: 0 auto;
+			background-color: #F8F8F8;
+			height: 60rpx;
+			border-radius: 30rpx;
+			display: flex;
+			line-height: 60rpx;
+
+			.search {
+				padding: 0 20rpx;
+				font-size: 34rpx;
+			}
+
+			input {
+				width: 80%;
+				margin-top: 10rpx;
+				font-size: 28rpx;
+			}
+		}
+	}
+
+	.ass_list {
+		position: absolute;
+		top: 84px;
+		width: 100%;
+		margin-bottom: 40px;
+
+		.che_group {
+			display: flex;
+			flex-direction: column;
+			width: 90%;
+			margin: 0 auto;
+		}
+
+		.equipment {
+			width: 90%;
+			margin: 20rpx auto;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 30rpx;
+
+			.equipment_top {
+				height: 60rpx;
+				width: 100%;
+				border-bottom: 1px solid #dfe5ec;
+				position: relative;
+
+				.equipment_top_img {
+					width: 40rpx;
+					height: 40rpx;
+					position: absolute;
+				}
+
+				.equipment_top_name {
+					font-size: 24rpx;
+					margin-left: 60rpx;
+				}
+
+				.ucheckbox {
+					float: right;
+					margin: 0rpx -4rpx;
+					transform: scale(0.7);
+				}
+			}
+
+			.equipment_bot {
+				padding: 30rpx 0;
+				position: relative;
+
+				.equipment_bot_id {
+					font-weight: 700;
+					font-size: 15px;
+					margin-bottom: 16rpx;
+				}
+
+				.equipment_bot_name {
+					font-size: 24rpx;
+				}
+
+				.equipment_state {
+					position: absolute;
+					top: 20rpx;
+					right: 0;
+					width: 100rpx;
+					height: 100rpx;
+					text-align: center;
+					line-height: 100rpx;
+					color: #42b983;
+
+				}
+			}
+		}
+	}
+
+	.allocbtn {
+		width: 100%;
+		position: fixed;
+		bottom: 0;
+		z-index: 100;
+		display: flex;
+
+		button {
+			width: 50%;
+			font-size: 24rpx;
+			height: 80rpx;
+			line-height: 80rpx;
+			border-radius: 0;
+		}
+
+		.cancel {
+			background-color: #C8C7CC;
+			color: #555555;
+		}
+
+		.canfirm {
+			color: white;
+			background-color: #42b983;
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image {
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 229 - 0
pages/fourBase/basefacility.vue

@@ -0,0 +1,229 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="基地设备"></uni-nav-bar>
+			</view>
+			<view class="ass_list">
+				<view class="equipment" v-for="(items,indexs) in assignments" :key="items.id" v-if="tishiTF" @click="skip(JSON.stringify(items))">
+					<view class="equipment_top">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+items.src" mode="" class="equipment_top_img"></image>
+						<span class="equipment_top_name">{{items.type_name}}</span>
+					</view>
+					<view class="equipment_bot">
+						<p class="equipment_bot_id">设备ID:{{items.d_id}}</p>
+						<p class="equipment_bot_name">设备名称:{{items.device_id}}</p>
+						<view class="equipment_state">在线</view>
+					</view>
+				</view>
+				<view class="tishi" v-if="!tishiTF">
+					暂无数据
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				base_id: "",
+				assignments: [],
+				images: [{
+					path: "/image/fourMoodBase/1.png",
+					id: 3
+				}, {
+					path: "/image/fourMoodBase/5.png",
+					id: 5
+				}, {
+					path: "/image/fourMoodBase/2.png",
+					id: 6
+				}, {
+					path: "/image/fourMoodBase/4.png",
+					id: 3
+				}, {
+					path: "/image/fourMoodBase/qxz.png",
+					id: 5
+				}, {
+					path: "/image/fourMoodBase/jk.png",
+					id: 6
+				}, {
+					path: "/image/fourMoodBase/bzy.png",
+					id: 7
+				},{
+					path: "/image/fourMoodBase/10.png",
+					id: 10
+				}],
+				tishiTF: false,
+				isTop:false
+			}
+		},
+		methods: {
+			async ybase(id) { //获取分布位置
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=base.bases.base_map_list',
+					data: {
+						base_id: id
+					}
+				})
+				this.assignments = res
+				console.log(this.assignments)
+				for (var i = 0; i < this.images.length; i++) {
+					for (var j = 0; j < this.assignments.length; j++) {
+						if (this.assignments[j].equip_type == this.images[i].id) {
+							this.assignments[j].src = this.images[i].path
+						}
+					}
+				}
+				if (this.assignments.length == 0) {
+					this.tishiTF = false
+				} else {
+					this.tishiTF = true
+				}
+			},
+			async camera() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=camera.camera_manage.list_camera',
+					data: {
+						page_size: 1,
+					}
+				})
+				this.accessToken = res.accessToken
+			},
+			clickLeft() {
+				uni.navigateTo({
+					url:"./index"
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			},
+			skip(items){
+				console.log(items)
+				var item = JSON.parse(items)
+				switch (item.equip_type){
+					case 5 :
+						uni.navigateTo({
+							url: "../environment/equipment?shebei=" + items
+						})
+					break
+					case 6 :
+						uni.navigateTo({
+							url: "/pages/webview?device_id=" + item.device_id + "&accessToken=" + this.accessToken
+						})
+					break
+					case 10 :
+						uni.navigateTo({
+							url: '/pages/cb/xy2.0/particulars?info=' + items
+						});
+					break
+					default:
+						uni.navigateTo({
+							url: '/pages/cb/equip-detail/equip-detail?info=' + items
+						});
+					break
+				}
+			}
+		},
+		onLoad(option) {
+			this.base_id = option.id
+			this.ybase(option.id)
+			this.camera()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.ass_list {
+		position: absolute;
+		top: 54px;
+		width: 100%;
+		margin-bottom: 40px;
+
+		.tishi {
+			width: 100%;
+			text-align: center;
+			height: 100rpx;
+			line-height: 100rpx;
+			font-size: 36rpx;
+		}
+
+		.equipment {
+			width: 90%;
+			margin: 20rpx auto;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 30rpx;
+			box-sizing: border-box;
+
+			.equipment_top {
+				height: 60rpx;
+				width: 100%;
+				border-bottom: 1px solid #dfe5ec;
+				position: relative;
+
+				.equipment_top_img {
+					width: 40rpx;
+					height: 40rpx;
+					position: absolute;
+				}
+
+				.equipment_top_name {
+					font-size: 28rpx;
+					margin-left: 60rpx;
+				}
+			}
+
+			.equipment_bot {
+				padding: 30rpx 0;
+				position: relative;
+
+				.equipment_bot_id {
+					font-weight: 700;
+					font-size: 15px;
+					margin-bottom: 16rpx;
+				}
+
+				.equipment_bot_name {
+					font-size: 13px;
+				}
+
+				.equipment_state {
+					position: absolute;
+					top: 20rpx;
+					right: 0;
+					width: 100rpx;
+					height: 100rpx;
+					text-align: center;
+					line-height: 100rpx;
+					color: #42b983;
+
+				}
+			}
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 43 - 0
pages/fourBase/city.vue

@@ -0,0 +1,43 @@
+<template>
+	<view>
+		<citySelect :getCity="getCity"></citySelect>	
+	</view>
+</template>
+
+<script>
+	import citySelect from '../../components/bazaar-city_list/index.vue';
+	export default {
+		components:{
+			citySelect
+		},
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			getCity({
+				city
+			}){
+				//city 城市名称
+				//name 定位名称
+				if(city.city == undefined){
+					var add = city
+				}else if(city.city != undefined){
+					var add = city.city
+				}
+				let pages = getCurrentPages()
+				let nowpage = pages[pages.length - 1]
+				let prevpage = pages[pages.length - 2]
+				prevpage.$vm.city = add
+				uni.navigateBack({
+					delta:1
+				})
+			}
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 347 - 0
pages/fourBase/index.vue

@@ -0,0 +1,347 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="四情基地"></uni-nav-bar>
+				<u-icon name="plus-circle" class="tianjia" @click="clickRight"></u-icon>
+			</view>
+			<view class="bases_search">
+				<view class="bases_search_text">
+					<u-icon name="search" class="search" @click="search"></u-icon>
+					<input type="text" v-model="data.search" placeholder="请输入基地名称" @input="searchinput" />
+				</view>
+			</view>
+			<view class="bases">
+				<view class="bases_list" v-for="(items,index) in baselist" :key="index" @click="details(items.id)">
+					<view class="bases_list_bgi">
+						<image :src="items.base_img" mode=""></image>
+						<view class="bgcolor">
+
+						</view>
+					</view>
+					<view class="bases_list_text">
+						<p><span style="margin-right: 30rpx;">{{items.base_name}}</span><span>{{items.base_area}}亩</span></p>
+						<p style="font-size: 24rpx;">联系人:{{items.base_charge}}</p>
+						<p style="font-size: 24rpx;">联系电话:{{items.base_phone}}</p>
+						<p style="font-size: 24rpx;">地址:{{items.base_name}}</p>
+					</view>
+					<u-icon name="more-dot-fill" class="bases_list_xiangqing" @click.native.stop="XQclick(items)"></u-icon>
+					<view class="photoshow">
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/fourMoodBase/1.png'" mode=""></image>
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/fourMoodBase/3.png'" mode=""></image>
+						<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/fourMoodBase/5.png'" mode=""></image>
+						<view class="photoshow_num">
+							{{items.num}}
+						</view>
+					</view>
+				</view>
+				<u-action-sheet :list="actionSheetList" v-model="post_show" @click="message"></u-action-sheet>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				data: {
+					ret: 'list',
+					search: '',
+					page_size: 10,
+					page: 1
+				},
+				baselist: [],
+				actionSheetList: [{
+					text: "编辑基地"
+				}, {
+					text: "删除基地"
+				}],
+				post_show: false,
+				delid: "",
+				facilitynum: "",
+				isTop:false,
+				jurisdiction:{
+					addbase:false,
+					alter:false
+				}
+			}
+		},
+		methods: {
+			async getFourbase() { //基地列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=base.bases.base_list',
+					data: this.data
+				})
+				this.baselist = this.baselist.concat(res.data)
+				console.log(this.baselist)
+				for (var i = 0; i < this.baselist.length; i++) {
+					var arr = this.baselist[i].base_equip.split("#")
+					if (arr[0] == '') {
+						arr.shift(1)
+					}
+					console.log(arr)
+					this.baselist[i].num = arr.length
+				}
+			},
+			async delbase() { //基地列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=base.bases.base_list',
+					data: {
+						ret: "del",
+						base_id: this.delid.id
+					}
+				})
+			},
+			clickLeft() { //返回主页
+				uni.switchTab({
+					url: "../index/index"
+				})
+			},
+			clickRight() { //添加基地
+				if(this.jurisdiction.addbase){
+					uni.navigateTo({
+						url: "./addbase"
+					})
+				}else{
+					uni.showToast({
+						title: "您暂无权限进行此操作,如有需要,请联系管理员",
+						icon: "none"
+					})
+				}
+			},
+			searchinput() { //搜索
+				this.data.page = 1
+				this.baselist = []
+				Debounce(() => {
+					this.getFourbase()
+				}, 1000)()
+			},
+			search() { //搜索按钮
+				this.data.page = 1
+				this.baselist = []
+				this.getFourbase()
+				this.$forceUpdate()
+			},
+			details(id) { //详情页
+				uni.navigateTo({
+					url: "./basefacility?id=" + id
+				})
+			},
+			XQclick(item) { //编辑
+				this.post_show = !this.post_show
+				this.delid = item
+			},
+			message(index) { //编辑或者删除
+				console.log(index)
+				if (index == 1) {
+					console.log(this.delid.id)
+					uni.showModal({
+						title: '提示',
+						content: '确定要删除该基地吗?',
+						success: (res) => {
+							if (res.confirm) {
+								this.delbase()
+							} else if (res.cancel) {
+								console.log('用户点击取消');
+							}
+						}
+					});
+				} else {
+					if(this.jurisdiction.addbase){
+						uni.navigateTo({
+							url: "./modification?id=" + JSON.stringify(this.delid)
+						})
+					}else{
+						uni.showToast({
+							title: "您暂无权限进行此操作,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				}
+				this.$forceUpdate()
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad() {
+			this.getFourbase()
+			uni.getStorage({
+				key:"jurisdiction",
+				success:(res)=>{
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item)=>{
+						return item.purview_name == "四情基地"
+					})
+					let items2 = items[0].children.filter((item)=>{
+						return item.purview_name == "基地管理"
+					})
+					console.log(items2)
+					this.jurisdiction.addbase =items2[0].children.some((item)=>{
+						return item.purview_name == "新增"
+					})
+					this.jurisdiction.alter =items2[0].children.some((item)=>{
+						return item.purview_name == "修改"
+					})
+				},
+			})
+		},
+		onReachBottom() { //滑动到底部加载
+			this.data.page++
+			this.getFourbase()
+		},
+		onShow() {
+			this.$forceUpdate()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+<style lang="scss">
+	.tianjia {
+		position: absolute;
+		top: 24rpx;
+		right: 24rpx;
+		font-size: 38rpx;
+	}
+
+	.bases_search {
+		width: 100%;
+		position: fixed;
+		top: 108px;
+		z-index: 100;
+		background-color: #FFFFFF;
+
+		.bases_search_text {
+			width: 90%;
+			margin: 0 auto;
+			background-color: #F8F8F8;
+			height: 60rpx;
+			border-radius: 30rpx;
+			display: flex;
+			line-height: 60rpx;
+
+			.search {
+				padding: 0 20rpx;
+				font-size: 34rpx;
+			}
+
+			input {
+				width: 80%;
+				margin-top: 10rpx;
+				font-size: 28rpx;
+			}
+		}
+	}
+
+	.bases {
+		width: 100%;
+		position: relative;
+		top: 170rpx;
+
+		.bases_list {
+			width: 90%;
+			margin: 0 auto 20rpx;
+			height: 276rpx;
+			position: relative;
+
+			.bases_list_bgi {
+				.bgcolor {
+					width: 100%;
+					height: 276rpx;
+					background-color: rgba(0, 0, 0, 0.3);
+					border-radius: 25rpx;
+				}
+
+				image {
+					position: absolute;
+					top: 0;
+					left: 0;
+					width: 100%;
+					height: 276rpx;
+					border-radius: 25rpx;
+					z-index: -1;
+				}
+			}
+
+			.bases_list_text {
+				position: absolute;
+				top: 0;
+				left: 0;
+				z-index: 10;
+				padding: 40rpx;
+				color: #FFFFFF;
+
+				p {
+					margin-bottom: 10rpx;
+				}
+			}
+
+			.bases_list_xiangqing {
+				position: absolute;
+				top: 20rpx;
+				right: 20rpx;
+				transform: rotate(90deg);
+				font-size: 26rpx;
+				color: #FFFFFF;
+			}
+
+			.photoshow {
+				width: 160rpx;
+				height: 34rpx;
+				display: flex;
+				position: absolute;
+				bottom: 26rpx;
+				right: 36rpx;
+				background-color: #a7a8a0;
+				border-radius: 18rpx;
+				padding: 4rpx;
+
+				image {
+					width: 32rpx;
+					height: 32rpx;
+					margin-right: 4rpx;
+				}
+
+				.photoshow_num {
+					width: 50rpx;
+					height: 30rpx;
+					border: 1px solid #FFFFFF;
+					border-radius: 17rpx;
+					text-align: center;
+					line-height: 28rpx;
+					font-size: 24rpx;
+					color: #FFFFFF;
+				}
+			}
+		}
+	}
+
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+
+		image {
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 361 - 0
pages/fourBase/modification.vue

@@ -0,0 +1,361 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="基地修改"></uni-nav-bar>
+			</view>
+			<view class="addimg">
+				<view class="addimg_add" @click="gainimg">
+					<u-icon name="plus" size="60rpx" color="#A5A6A8"></u-icon>
+					<image :src="baseinfo.base_img" mode="" class="addimg_img"></image>
+				</view>
+			</view>
+			<view class="base_text">
+				<p class="title">基地信息</p>
+				<view class="base_text_item1">
+					<u-icon name="fangzi" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>基地名称</span>
+					<input type="text" v-model="baseinfo.base_name" placeholder="请输入基地名称" />
+				</view>
+				<view class="base_text_item1">
+					<u-icon name="ren1" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>负责人</span>
+					<input type="text" v-model="baseinfo.base_charge " placeholder="请输入基地负责人" />
+				</view>
+				<view class="base_text_item1">
+					<u-icon name="lianxidianhua" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>联系电话</span>
+					<input type="text" v-model="baseinfo.base_phone" placeholder="请输入联系电话" />
+				</view>
+				<view class="base_text_item1">
+					<u-icon name="mianji" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span><span style="color: #ff0000;margin: 0;">*</span>面积(亩)</span>
+					<input type="number" v-model="baseinfo.base_area" placeholder="请输入基地面积" />
+				</view>
+				<view class="base_text_item2">
+					<u-icon name="miaoshu" custom-prefix="custom-icon" class="icon"></u-icon>
+					<span>基地描述</span>
+					<textarea v-model="baseinfo.base_describe " maxlength="80" auto-height class="textarea" placeholder="请输入基地描述(不能大于80字)" />
+					</view>
+			<view class="base_text_item1" @click="map">
+				<u-icon name="Frame1" custom-prefix="custom-icon" class="icon"></u-icon>
+				<span><span style="color: #ff0000;margin: 0;">*</span>基地定位</span>
+				<input type="text" v-model="city" placeholder="请选择地址" disabled style="position: absolute;right: 60rpx;width: 60%;"/>
+				<u-icon name="arrow-right" class="iconright"></u-icon>
+			</view>
+			<view class="base_text_item1" @click="binding">
+				<u-icon name="bangding" custom-prefix="custom-icon" class="icon"></u-icon>
+				<span><span style="color: #ff0000;margin: 0;">*</span>设备绑定</span>
+				<u-icon name="arrow-right" class="iconright"></u-icon>
+			</view>
+			<view class="base_id_box">
+				<view class="base_id" v-for="(item,key,index) in base_id" :key="index">
+					<view class="base_id_item" v-for="(items,indexs) in item" :key="indexs">
+						<span>{{key}}</span>
+						<span>{{items}}</span>
+					</view>
+				</view>
+			</view>
+			<view class="btn" @click="tijiao">
+				确 定
+			</view>
+		</view>
+		</view>
+		<kps-image-cutter @ok="onok" @cancel="oncancle" :url="imgs" :fixed="false" :blob="false" :maxWidth="500" :maxHeight="500"></kps-image-cutter>
+	</view>
+</template>
+<script>
+	import kpsImageCutter from "@/components/ksp-image-cutter/ksp-image-cutter.vue";
+	export default {
+		components:{
+			kpsImageCutter
+		},
+		data() {
+			return {
+				base_id:{},
+				baseinfo:{
+					base_name:'',//必传(str)           基地名称
+					base_charge:'',//必传(str)           负责人
+					base_phone:'',//必传(str)           联系电话
+					base_img:'',// 必传(str)           基地图片
+					base_area:'',//必传(str)           基地面积
+					base_equip:'', //必传(str)           绑定设备 如果绑定多个设备传 289#299, 如果是单一设备传298
+					base_describe:'',//非必传(str)         基地描述
+					lng:'',//必传(str)           经度
+					lat:'',//必传(str)           纬度
+				},
+				city:'',
+				imgs:""
+			}
+		},
+		methods: {
+			//base.bases.base_list新增基地 //modify 修改  list  列表
+			async addbase() { //获取分布位置 
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=base.bases.base_list',
+					data:this.baseinfo
+				})
+				console.log(res)
+			},
+			clickLeft(){
+				uni.navigateTo({
+					url:"./index"
+				})
+			},
+			binding(){
+				uni.navigateTo({
+					url:"./allocation?type="+this.baseinfo.base_equip
+				})
+			},
+			gainimg() { //添加图片
+				uni.chooseImage({
+						count: 1, //默认9
+						sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+						sourceType: ['album', 'camera'], //从相册选择
+						success: (res) => {
+							this.imgs = res.tempFilePaths[0]
+						}
+					})
+			},
+			map(){
+				uni.navigateTo({
+					url:"city"
+				})
+			},
+			tijiao(){
+				if(this.baseinfo.base_img==''){
+					uni.showToast({
+					    title: '请选择基地图片', 
+					    duration: 2000,
+						icon:"none"
+					});
+				
+				}else if(this.baseinfo.base_name==''){
+					uni.showToast({
+					    title: '请填写正基地名称', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_charge==''){
+					uni.showToast({
+					    title: '请填写基地负责人', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_phone==''){
+					uni.showToast({
+					    title: '请填写手机号', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_area==''){
+					uni.showToast({
+					    title: '请填写基地面积', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.lng==''){
+					uni.showToast({
+					    title: '请选择基地地址', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else if(this.baseinfo.base_id==''){
+					uni.showToast({
+					    title: '请绑定基地设备', 
+					    duration: 2000,
+						icon:"none"
+					});
+				}else{
+					if(!/^1[23456789]\d{9}$/.test(this.baseinfo.base_phone)){
+						uni.showToast({
+						    title: '请填写正确的手机号', 
+						    duration: 2000,
+							icon:"none"
+						});
+					}else{
+						console.log(this.baseinfo)
+						this.addbase()
+						localStorage.removeItem("id")
+						uni.navigateBack({
+							delta:1
+						})
+					}
+				}
+			},
+			selectaddress(lat,lng) { //获取分布位置
+				uni.request({
+					type: "GET",
+					url: "https://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + lng + "," +lat  + "&key=27273b81090f78759e4057f94474516f&radius=1000&extensions=all",
+					dataType: "json",
+					complete: ress => {
+						console.log(ress)
+						this.city = ress.data.regeocode.formatted_address
+					}  
+				});
+			},
+			onok(ev){
+				uni.uploadFile({
+					url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+					filePath: ev.path,
+					name: 'img_file',
+					formData: {
+						'user': 'test'
+					},
+					success: (uploadFileRes) => {
+						this.baseinfo.base_img = JSON.parse(uploadFileRes.data).data.src
+						// this.$forceUpdate() //强制刷新视图
+					}
+				});
+				this.imgs = ''
+			},
+			oncancle(){
+				this.imgs = ''
+			}
+		},
+		onLoad(option) {
+			console.log(JSON.parse(option.id))
+			this.baseinfo = JSON.parse(option.id)
+			this.baseinfo.base_id = JSON.parse(option.id).id
+			this.baseinfo.ret = "modify"
+			delete this.baseinfo.id
+			this.selectaddress(this.baseinfo.lat,this.baseinfo.lng)
+		},
+		onShow(){
+			uni.getStorage({
+			    key: 'id',
+			    success: (res)=> {
+					this.base_id = JSON.parse(res.data)
+					var arr = []
+					for(var key in this.base_id){
+						arr.push(this.base_id[key].join("#"))
+					}
+					this.baseinfo.base_equip = arr.join("#")
+			    }
+			});
+		}
+	}
+</script>
+
+<style lang="scss">
+.addimg{
+	position: absolute;
+	top: 108rpx;
+	width: 100%;
+	.addimg_add{
+		position: relative;
+		width: 90%;
+		height: 276rpx;
+		margin: 0 auto;
+		background-color: #F7F8FA;
+		text-align: center;
+		line-height: 276rpx;
+		color: #A7A8AA;
+		.addimg_img{
+			position: absolute;
+			top: 0;
+			width: 100%;
+			left: 0;
+			height: 276rpx;
+		}
+	}
+}
+.base_text{
+	position: absolute;
+	top: 390rpx;
+	width: 100%;
+	.title{
+		width: 90%;
+		margin: 20rpx auto;
+	}
+	.base_text_item2{
+		width: 90%;
+		margin: 10rpx auto 20rpx;
+		padding: 16rpx 20rpx;
+		background-color: #F7F8FA;
+		display: flex;
+		box-sizing: border-box;
+		position: relative;
+		height: 200rpx;
+		.icon{
+			color: #5FBBA0;
+			height: 42rpx;
+		}
+		span{
+			margin: 0 20rpx;
+		}
+		.textarea{
+			font-size: 24rpx;
+			text-align: right;
+			position: absolute;
+			right: 20rpx;
+			width: 70%;
+			height: 200rpx;
+		}
+		
+	}
+	.base_text_item1{
+		display: flex;
+		position: relative;
+		width: 90%;
+		height: 70rpx;
+		margin: 10rpx auto 20rpx;
+		padding: 16rpx 20rpx;
+		background-color: #F7F8FA;
+		box-sizing: border-box;
+		.icon{
+			color: #5FBBA0;
+		}
+		span{
+			margin: 0 10rpx;
+		}
+		input{
+			position: absolute;
+			right: 20rpx;
+			width: 70%;
+			text-align: right;
+			font-size: 24rpx;
+			margin-top: 5rpx;
+		}
+		.iconright{
+			position: absolute;
+			right: 10rpx;
+			top: 28rpx;
+			color: #B5B6B8;
+			font-size: 24rpx;
+		}
+	}
+}
+.base_id_box{
+		width: 90%;
+		margin: 20rpx auto 70rpx;
+	}
+	.base_id{
+		width: 100%;
+		.base_id_item{
+			width: 95%;
+			padding: 10rpx 30rpx;
+			display: flex;
+			justify-content: space-between;
+			font-size: 28rpx;
+			background-color: #F7F8FA;
+			color: #616162;
+			box-sizing: border-box;
+			margin: 20rpx auto;
+		}
+	}
+	.btn{
+		width: 90%;
+		position: fixed;
+		bottom: 10rpx;
+		right: 5%;
+		text-align: center;
+		height: 70rpx;
+		line-height: 70rpx;
+		background-color: #359773;
+		font-size: 34rpx;
+		border-radius: 35rpx;
+		color: #FFFFFF;
+	}
+</style>

+ 419 - 0
pages/index/index.vue

@@ -0,0 +1,419 @@
+<template>
+	<view class="content">
+		<u-swiper :list="list" mode="dot" class="index_uswiper" height='300'></u-swiper>
+		<view class="function">
+			<view class="function_item" v-for="(item,index) in functionimg" :key="index" @click="tabfunction(index)">
+				<image :src="'http://static.yfpyx.com/bigdata_app'+item.src" mode=""></image>
+				<p>{{item.text}}</p>
+			</view>
+		</view>
+		<view class="equipment">
+			<p class="equipment_p">系统设备</p>
+			<view class="equipment_item">
+				<view class="equipment_item_img" v-for="(item,index) in equipmentimg" :key="index" @click="tabequipment(index)">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+item.src" mode=""></image>
+				</view>
+			</view>
+		</view>
+		<u-modal v-model="show" :mask-close-able="true" title="" :show-cancel-button="true" confirm-text="拍病害" cancel-text="拍虫害"
+		 content="拍照识别病虫害" @confirm="confirm" @cancel="cancel"></u-modal>
+		<kps-image-cutter @ok="onok" @cancel="oncancle" :url="url" :fixed="false" :blob="true" :maxWidth="500" :maxHeight="380" :height="380"></kps-image-cutter>
+		<view class="loading" v-if="loadTF">
+			<u-loading  mode="flower" size="100" :show="true" ></u-loading>
+		</view>
+	</view>
+</template>
+
+<script>
+	import kpsImageCutter from "@/components/ksp-image-cutter/ksp-image-cutter.vue";
+	export default {
+		components: {
+			kpsImageCutter
+		},
+		data() {
+			return {
+				loadTF:false,
+				currentPage: 'tabBar1',
+				list: [{
+					image: 'http://static.yfpyx.com/bigdata_app/image/index/11.png'
+				}, ],
+				functionimg: [{
+						src: "/image/index/1.png",
+						text: "四情基地"
+					},
+					{
+						src: "/image/index/2.png",
+						text: "病虫识别"
+					},
+					{
+						src: "/image/index/3.png",
+						text: "专家诊断"
+					},
+					{
+						src: "/image/index/4.png",
+						text: "售后服务"
+					}
+				],
+				equipmentimg: [{
+						src: "/image/index/5.png"
+					},
+					{
+						src: "/image/index/6.png"
+					},
+					{
+						src: "/image/index/7.png"
+					},
+					{
+						src: "/image/index/8.png"
+					},
+					{
+						src: "/image/index/9.png"
+					},
+					{
+						src: "/image/index/10.png"
+					}
+				],
+				url: '',
+				path: '',
+				flag: 1,
+				show: false,
+				jurisdiction:{
+					cbtf:false,
+					jktf:false,
+					hjtf:false,
+					fztf:false,
+					sytf:false,
+					sbtf:false,
+					sqtf:false,
+					zjtf:false
+				}
+			}
+		},
+		onLoad() {
+			this.jurisdiction={
+					cbtf:false,
+					jktf:false,
+					hjtf:false,
+					fztf:false,
+					sytf:false,
+					sbtf:false,
+					sqtf:false,
+					zjtf:false
+				}
+			this.getUserlogin()
+		}, 
+		onShow(){
+			this.jurisdiction={
+					cbtf:false,
+					jktf:false,
+					hjtf:false,
+					fztf:false,
+					sytf:false,
+					sbtf:false,
+					sqtf:false,
+					zjtf:false
+				}
+			this.loadTF = false
+			this.getUserlogin()
+		},
+		methods: {
+			async getUserlogin() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.user_login_info',
+				})
+				uni.setStorage({
+					key: 'jurisdiction',
+					data: JSON.stringify(res.children),
+				})
+				uni.setStorage({
+					key: 'myuser_type',
+					data: JSON.stringify(res.myuser_type),
+				})
+				console.log(res.children)
+				for(var i=0;i<res.children.length;i++){
+					switch (res.children[i].purview_name){
+						case "测报系统":
+									this.jurisdiction.cbtf = true
+									break;
+						case "可视农业":
+									this.jurisdiction.jktf = true
+									break;
+						case "环境监测系统":
+									this.jurisdiction.hjtf = true
+									break;
+						case "防治系统":
+									this.jurisdiction.fztf = true
+									break;
+						case "溯源系统":
+									this.jurisdiction.sytf = true
+									break;
+						case "系统管理":
+									this.jurisdiction.sbtf = true
+									break;
+						case "四情基地":
+									this.jurisdiction.sqtf = true
+									break;
+						case "专家诊断":
+									this.jurisdiction.zjtf = true
+									break;
+					}
+				}
+			},
+			tabfunction(index) {
+				if (index == 0) {
+					if(this.jurisdiction.sqtf){
+						uni.navigateTo({
+							url: "../fourBase/index"
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 1) {
+					var that = this
+					this.show = true
+				} else if (index == 2) {
+					if(this.jurisdiction.zjtf){
+						uni.navigateTo({
+							url: "../expertDiagnosis/index",
+							 
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 3) {
+					uni.navigateTo({
+						url: "../afterSale/index"
+					})
+				}
+			},
+			tabequipment(index) {
+				if (index == 0) {
+					if(this.jurisdiction.cbtf){
+						uni.navigateTo({
+							url: "../cb/index/index"
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 1) {
+					if(this.jurisdiction.fztf){
+						uni.navigateTo({
+							url: "../prevention/index"
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 2) {
+					console.log(this.jurisdiction.jktf)
+					if(this.jurisdiction.jktf){
+						uni.navigateTo({
+							url: "/pages/monitor/index"
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 3) {
+					if(this.jurisdiction.hjtf){
+						uni.navigateTo({
+							url: "../environment/index"
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 4) {
+					console.log(this.jurisdiction.sbtf)
+					if(this.jurisdiction.sbtf){
+						uni.navigateTo({
+							url: "../equipMange/index/index"
+						})
+					}else{
+						uni.showToast({
+							title: "此账号未开启此模块,如有需要,请联系管理员",
+							icon: "none"
+						})
+					}
+				} else if (index == 5) {
+					uni.showToast({
+					    title: '此功能暂未开放',
+					    duration: 2000,
+						icon:"none"
+					});
+					// if(this.jurisdiction.cbtf){
+					// 	uni.navigateTo({
+					// 		url: "../cb/index/index"
+					// 	})
+					// }else{
+					// 	uni.showToast({
+					// 		title: "此账号未开启此模块,如有需要,请联系管理员",
+					// 		icon: "none"
+					// 	})
+					// }
+				}
+			},
+			onok(ev) {
+				this.path = this.url
+				console.log(ev)
+				this.loadTF = true
+				uni.showLoading({
+					mask:true,
+					success:function(){
+						console.log(999)
+					}
+				});
+				if(this.flag == 2){
+					console.log('111')
+					// pest.pests.insect_discern 虫害
+					uni.uploadFile({
+						// url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+						url: 'http://182.92.193.64:8002/api/api_gateway?method=pest.pests.insect_discern', //仅为示例,非真实的接口地址
+						filePath: ev.path,
+						name: 'img_file',
+						formData: {
+							'user': 'test'
+						},
+						success: (uploadFileRes) => {
+							console.log(JSON.parse(uploadFileRes.data))
+							uni.navigateTo({
+								url: "../disandpests/index?datas=" + uploadFileRes.data + "&path=" + ev.path
+							})
+						}
+					});
+				}else if(this.flag == 1){
+					//pest.pests.insect_discern病害识别
+					uni.showLoading({
+					    title: '加载中'
+					});
+					uni.uploadFile({
+						// url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+						url: 'http://182.92.193.64:8002/api/api_gateway?method=pest.pests.plant_discern', //仅为示例,非真实的接口地址
+						filePath: ev.path,
+						name: 'img_file',
+						formData: {
+							'user': 'test'
+						},
+						success: (uploadFileRes) => {
+							console.log(JSON.parse(uploadFileRes.data))
+							uni.navigateTo({
+								url: "../disandpests/index?datas="+uploadFileRes.data + "&path=" + ev.path
+							})
+						}
+					});
+				}
+				this.url = "";
+			},
+			oncancle() {
+				// url设置为空,隐藏控件
+				this.url = ''
+			},
+			confirm() {
+				this.flag = 1
+				uni.chooseImage({
+					count: 1, //默认9
+					// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['camera','album'], //从相册选择
+					success: (res) => {
+						this.url = res.tempFilePaths[0]
+					}
+				});
+				console.log(1)
+			},
+			cancel() {
+				this.flag = 2
+				uni.chooseImage({
+					count: 1, //默认9
+					// sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['camera','album'], //从相册选择
+					success: (res) => {
+						console.log(1)
+						this.url = res.tempFilePaths[0]
+					}
+				});
+			}
+		}
+	}
+</script>
+<style lang="scss">
+	.index_uswiper {
+		width: 95%;
+		margin: 0 auto;
+		border-radius: 20rpx !important;
+	}
+	.loading{
+		position: absolute;
+		top: 0;
+		left: 0;
+		z-index: 100;
+		width:100%;
+		height: 100vh;
+		background-color: rgba(0,0,0,0.5);
+		display: flex;
+		justify-content: center;
+		align-items: center;
+	}
+	.function {
+		width: 95%;
+		margin: 20rpx auto;
+		display: flex;
+		justify-content: space-around;
+
+		.function_item {
+			width: 18%;
+			text-align: center;
+
+			image {
+				width: 90rpx;
+				height: 90rpx;
+			}
+
+			p {
+				font-size: 24rpx;
+			}
+		}
+	}
+
+	.equipment {
+		width: 95%;
+		margin: 30rpx auto 0;
+
+		.equipment_p {
+			width: 90%;
+			border-left: 8rpx solid #4BB85F;
+			font-weight: 700;
+			padding-left: 20rpx;
+			margin-bottom: 20rpx;
+		}
+
+		.equipment_item {
+			display: flex;
+			flex-wrap: wrap;
+			justify-content: space-between;
+
+			.equipment_item_img {
+				width: 49%;
+				margin-top: 20rpx;
+				image {
+					width: 100%;
+					height: 190rpx;
+				}
+			}
+		}
+	}
+</style>

+ 455 - 0
pages/login/login.vue

@@ -0,0 +1,455 @@
+<template>
+	<view style="height: 100vh;">
+		<view class="status_bar"></view>
+		<view class="logo" @longpress="logoTime">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/login/8eef2e54055a5b072a5dc000919a7ae.png'" mode=""></image>
+		</view>
+		<view class="set" @click="set" v-if="setTF">
+			<u-icon name="setting-fill" size="40" color="#72CD9C"></u-icon>
+		</view>
+		<form @submit="formSubmit">
+			<view class="uni-form-item uni-column">
+				<view class="username">
+					<u-icon name="account" size="36" style="margin-right:30rpx;color: #72CD9C;"></u-icon>
+					<u-input class="uni-input" name="username" v-model="formdata.username" placeholder-class="icon iconfont icon-bianji1"
+					 placeholder="请输入用户名" @blur="blur" />
+				</view>
+				<view class="passwold">
+					<u-icon name="lock" size="36" style="margin-right:30rpx;color: #72CD9C;"></u-icon>
+					<u-input v-model="formdata.passwold" type="password" :password-icon="true" :clearable="false" placeholder="请输入密码"
+					 @confirm="formSubmit" @input="passwoldddata" class="uni-input"/>
+				</view>
+				<view class="aboutpass">
+					<u-checkbox-group>
+						<u-checkbox v-model="checked" :label-disabled="false" size="22" @change="rempass">记住密码</u-checkbox>
+					</u-checkbox-group>
+				</view>
+				<view class="uni-btn-v">
+					<button form-type="submit" @click="denglu">登 录</button>
+				</view>
+			</view>
+		</form>
+		<view class="bg">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/login/850c9307f4ef2d7dc6db1049711ab55.jpg'" mode=""></image>
+		</view>
+		<view class="setbg" v-if="setbgtf">
+			<view class="mengban" @click.stop="setbgtf = !setbgtf"></view>
+			<view class="set_http">
+				<view class="set_http_top">
+					<u-icon name="close" size="40" @click="setbgtf = !setbgtf"></u-icon>
+					<p>设置服务器地址</p>
+					<u-icon name="checkbox-mark" size="40" @click="sethttp"></u-icon>
+				</view>
+				<view class="set_http_bot">
+					<p>服务器访问地址</p>
+					<view class="set_http_bot_input">
+						<input type="text" v-model="value" placeholder="请在此处输入服务器地址(http://...)" />
+						<u-icon :name="arrowtf?'arrow-up':'arrow-down'" @click="arrow"></u-icon>
+					</view>
+					<scroll-view scroll-y="true" class="scroll-Y" v-if="arrowtf">
+						<view :id="'demo'+index" class="scroll-view-item uni-bg-red" v-for="item,index in httparr" :key="index" @click="value = item">{{item}}</view>
+					</scroll-view>
+				</view>
+			</view>
+		</view>
+		<!-- <u-modal title="升级中请勿随意操作" :show-confirm-button="false" v-model="showA" :content="contentA">
+			<view class="upgradeBox">
+				<u-line-progress v-show="isShow" active-color="#19be6b" :striped="true" :percent="percentNum" :striped-active="true"></u-line-progress>
+			</view>
+		</u-modal> -->
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				checked: false,
+				formdata: {
+					username: '',
+					passwold: ''
+				},
+				setbgtf: false,
+				setTF: false,
+				value: "http://8.136.98.49:8002",
+				httparr: ["http://8.136.98.49:8002", "http://182.92.193.64:8002"],
+				arrowtf: false,
+				showA: false, //
+				contentA: '',
+				isShow: false, //进度条
+				percentNum: 0, //在线下载进度
+				passvalue:false
+			}
+		},
+		onLoad() {
+			uni.getStorage({
+				key: 'user_pass',
+				success: (res) => {
+					if (res.data) {
+						this.formdata.passwold = res.data
+						this.checked = true
+					} else {
+						this.checked = false
+					}
+				}
+			})
+			uni.getStorage({
+				key: 'user_name',
+				success: (res) => {
+					this.formdata.username = res.data
+				}
+			})
+			uni.getStorage({
+				key: 'http',
+				success: (res) => {
+					this.value = res.data
+				}
+			})
+		},
+		onShow() {
+			this.getEquipList()
+		},
+		methods: {
+			async getEquipList() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.app_version_record',
+					data: {
+						ret: "first"
+					}
+				})
+				console.log(res)
+				this.appName = res[0].app_name
+				// this.versions = Number(res[0].app_num.match(/\d+/g).join(""))
+				// var id = Number(plus.runtime.version.match(/\d+/g).join(""))
+				// console.log(this.versions,id)
+				// if (this.versions > id) {
+				// 	uni.showModal({
+				// 		title: '提示',
+				// 		content: '检测到有新版本,是否更新?',
+				// 		success: (res) => {
+				// 			if (res.confirm) {
+				// 				console.log('用户点击确定');
+				// 				this.showA = true
+				// 				this.isShow = true
+				// 				this.upgrade()
+				// 			} else if (res.cancel) {
+				// 				plus.runtime.quit();
+				// 				console.log('用户点击取消');
+				// 			}
+				// 		}
+				// 	})
+				// } else {
+					uni.getStorage({
+						key: 'session_key',
+						success: (res) => {
+							console.log(res)
+							if (res.data != "") {
+								uni.switchTab({
+									url: "../index/index"
+								})
+							}
+						},
+					})
+				// }
+			},
+			// upgrade() {
+			// 	console.log(this.appName)
+			// 	var url = this.value + "/app_file/" + this.appName
+			// 	console.log(url)
+			// 	const downloadTask = uni.downloadFile({
+			// 		url: url, //仅为示例,并非真实的资源
+			// 		success: (res) => {
+			// 			console.log(res)
+			// 			if (res.statusCode === 200) {
+			// 				console.log('下载成功');
+			// 				console.log('安装包下载成功,即将安装:' + JSON.stringify(res, null, 4));
+			// 				plus.runtime.openFile(res.tempFilePath);
+			// 			}
+			// 		},
+			// 		fail: (err) => {
+			// 			console.log(err)
+			// 		},
+			// 		complete: (com) => {
+			// 			console.log(com)
+			// 		}
+			// 	});
+				// downloadTask.onProgressUpdate((res) => {
+				// 	this.percentNum = res.progress
+				// 	if (res.progress == 100) {
+				// 		console.log('下载完成了')
+				// 	}
+				// });
+			// },
+			async formSubmit() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.login_user',
+					data: {
+						username: this.formdata.username,
+						password: this.formdata.passwold
+					}
+				})
+				console.log(res.session_key)
+				let session_key = res.session_key
+				uni.setStorage({
+					key: 'session_key',
+					
+					data: session_key,
+					success: () => {
+						uni.switchTab({
+							url: "../index/index"
+						})
+					}
+				})
+			},
+			passwoldddata() {
+				this.formdata.passwold = this.formdata.passwold.replace(/[\u4E00-\u9FA5]/g, '')
+			},
+			rempass(val) {
+				this.passvalue = val.value
+				if (val.value) {
+					uni.setStorage({
+						key: 'user_pass',
+						data: this.formdata.passwold,
+						success: function() {
+							console.log('success');
+						}
+					})
+				}
+			},
+			blur(val) {
+				uni.setStorage({
+					key: 'user_name',
+					data: val,
+					success: function() {
+						console.log('success');
+					}
+				})
+			},
+			logoTime() {
+				this.setTF = true
+			},
+			set() {
+				this.setbgtf = true
+			},
+			sethttp() {
+				uni.setStorage({
+					key: 'http',
+					data: this.value,
+					success: () => {
+						// console.log(this.value);
+						this.setbgtf = false
+						uni.showToast({
+							title: "修改成功",
+							icon: "none"
+						})
+						this.getEquipList()
+					}
+				});
+
+			},
+			arrow() {
+				this.arrowtf = !this.arrowtf
+			},
+			denglu(){
+				if (this.passvalue) {
+					uni.setStorage({
+						key: 'user_pass',
+						data: this.formdata.passwold,
+						success: function() {
+							console.log('success');
+						}
+					})
+				} else {
+					uni.removeStorage({
+						key: 'user_pass',
+						success: function() {
+							console.log('success');
+						}
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.logo {
+		width: 100%;
+		height: 340rpx;
+		text-align: center;
+		display: flex;
+		align-items: center;
+		padding-top: 240rpx;
+
+		image {
+			width: 280rpx;
+			margin: 0 auto;
+			height: 120rpx;
+		}
+	}
+
+	.set {
+		position: absolute;
+		right: 50rpx;
+		top: 140rpx;
+	}
+
+	.bg {
+		width: 100%;
+		position: fixed;
+		bottom: 0;
+		z-index: -1;
+
+		image {
+			width: 100%;
+		}
+	}
+
+	/deep/.u-input__right-icon {
+		line-height: 35px !important;
+	}
+
+	.uni-form-item {
+		width: 100%;
+
+		.username {
+			width: 80%;
+			margin: 0 auto;
+			display: flex;
+			margin-bottom: 40rpx;
+			padding-bottom: 10rpx;
+			border-bottom: 2rpx solid #C3C3C3;
+			.u-icon__icon{
+				margin-top: 17rpx;
+			}
+			.uni-input{
+				width: 100%;
+			}
+		}
+
+		.passwold {
+			width: 80%;
+			margin: 0 auto;
+			display: flex;
+			margin-bottom: 40rpx;
+			padding-bottom: 10rpx;
+			border-bottom: 2rpx solid #C3C3C3;
+			.u-icon__icon{
+				margin-top: 17rpx;
+			}
+			.uni-input{
+				width: 100%;
+			}
+		}
+
+		.aboutpass {
+			width: 80%;
+			margin: 0 auto;
+			display: flex;
+			justify-content: flex-end;
+
+			p {
+				color: #C0C0C0;
+				font-size: 28rpx;
+			}
+
+			/deep/.u-checkbox__label {
+				font-size: 28rpx;
+				color: #C0C0C0;
+				margin-right: 0;
+			}
+		}
+
+		.uni-btn-v {
+			width: 80%;
+			margin: 112rpx auto 0;
+			position: relative;
+			z-index: 100;
+
+			button {
+				width: 100%;
+				height: 72rpx;
+				line-height: 75rpx;
+				background-color: #5DC18B;
+				color: #FFFFFF;
+				border-radius: 36rpx;
+				font-size: 28rpx;
+			}
+		}
+	}
+
+	.setbg {
+		width: 100%;
+		height: 100vh;
+		position: absolute;
+		top: 0;
+		z-index: 99999;
+
+		.mengban {
+			width: 100%;
+			height: 100vh;
+			position: absolute;
+			top: 0;
+			background-color: rgba($color: #000000, $alpha: 0.5);
+		}
+
+		.set_http {
+			position: absolute;
+			width: 90%;
+			left: 5%;
+			top: 30%;
+
+			.set_http_top {
+				display: flex;
+				justify-content: space-around;
+				background-color: #5DC18B;
+				height: 60px;
+				line-height: 60px;
+				color: #FFFFFF;
+				border-top-right-radius: 20px;
+				border-top-left-radius: 20px;
+				font-size: 32rpx;
+			}
+
+			.set_http_bot {
+				height: 150px;
+				background-color: #FFFFFF;
+				border-bottom-right-radius: 20px;
+				border-bottom-left-radius: 20px;
+				padding: 30px;
+
+				.set_http_bot_input {
+					margin-top: 20rpx;
+					border: 2rpx solid #bdb6a6;
+					border-radius: 20rpx;
+					padding: 10rpx 40rpx 0 20rpx;
+					font-size: 32rpx;
+					height: 30px;
+					display: flex;
+					justify-content: space-between;
+
+					input {
+						width: 90%;
+					}
+				}
+			}
+
+			.scroll-Y {
+				border: 2rpx solid #d0d0d0;
+				border-radius: 20rpx;
+
+				.scroll-view-item {
+					padding-left: 20rpx;
+					height: 70rpx;
+					font-size: 28rpx;
+					line-height: 70rpx;
+					border-bottom: 2rpx solid #d0d0d0;
+				}
+			}
+		}
+	}
+
+	.upgradeBox {
+		padding: 15rpx;
+	}
+</style>

+ 174 - 0
pages/monitor/index.vue

@@ -0,0 +1,174 @@
+<template>
+	<view class="">
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="监控系统"></uni-nav-bar>
+				<view class="" style="margin-top: -10rpx;">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/monitor/banner.png'" mode="widthFix"></image>
+				</view>
+			</view>
+			<view class="contenttf" v-if="contenttf">
+				暂无数据
+			</view>
+			<view class="content" v-else>
+				<template v-for="(item,index) in listArr">
+					<equipItem @click.native="itemClick(item)" v-bind:item="item" :key="index">
+						<view class="type-name">
+							<view class="iconfont icon-jiankong"></view>
+							<text>
+								监控
+							</text>
+						</view>
+					</equipItem>
+				</template>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import equipItem from "../../components/equip-item/equip-item"
+	export default {
+		data() {
+			return {
+				listArr: [],
+				page: 1,
+				accessToken: '',
+				counts: '',
+				isTop:false,
+				contenttf:false
+			}
+		},
+		onLoad() {
+			this.getEquipList()
+		},
+		onPullDownRefresh() {
+			this.page = 1
+			this.listArr = []
+			this.getEquipList()
+			setTimeout(() => {
+				uni.stopPullDownRefresh()
+			}, 1000)
+
+		},
+		onReachBottom() {
+			this.page++
+			if (this.counts == this.listArr.length) {
+				return false
+			}
+			this.getEquipList()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+		methods: {
+			async getEquipList() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=camera.camera_manage.list_camera',
+					data: {
+						page: this.page
+					}
+				})
+				console.log(res)
+				if(res.counts==0){
+					this.contenttf = true
+				}else{
+					this.contenttf = false
+				}
+				let data = res.data
+				let arr = data.map(item => {
+					item.imei=item.device_id
+					item.is_online=item.status
+					return {
+						...item,
+						device_status: item.status
+					}
+				})
+				console.log(res)
+				console.log(this.listArr)
+				this.listArr = [...this.listArr, ...arr]
+				this.accessToken = res.accessToken
+				this.counts = res.counts
+			},
+			clickLeft() {
+				uni.switchTab({
+					url: "../index/index"
+				})
+			},
+			itemClick(item) {
+				// uni.navigateTo({
+				// 	url:"/pages/monitor/detail?device_id="+item.device_id+"&accessToken="+this.accessToken
+				// })
+				// uni.setStorage({
+				// 	key: 'obj',
+				// 	data: JSON.stringify({
+				// 		device_id: item.device_id,
+				// 		accessToken: this.accessToken
+				// 	})
+				// })
+				uni.navigateTo({
+					url: "/pages/webview?device_id=" + item.device_id + "&accessToken=" + this.accessToken
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		components: {
+			equipItem
+		}
+
+	}
+</script>
+
+<style lang="scss">
+	image {
+		width: 100%;
+	}
+
+	.type-name {
+		color: #999;
+		display: flex;
+		justify-content: flex-start;
+		font-size: 12px;
+
+		text {
+			margin-left: 10px;
+		}
+	}
+	.contenttf{
+		position: absolute;
+		top: 170px;
+		width: 95%;
+		left: 2.5%;
+		text-align: center;
+		font-size: 20px;
+	}
+	.content{
+		position: absolute;
+		top: 130px;
+		width: 95%;
+		left: 2.5%;
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 228 - 0
pages/my/about/about.vue

@@ -0,0 +1,228 @@
+<template>
+	<view>
+		<view class="line"></view>
+		<view class="logo-box">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/c9b4eb88c03b2f7460e8479e80f40fc.png'" mode="widthFix"></image>
+			<view class="version">
+				<view>
+					云飞物联网
+				</view>
+				<view>
+					V{{id}}
+				</view>
+			</view>
+		</view>
+		<view class="line"></view>
+		<view class="part">
+			<view class="info-item">
+				<text class="tit">技术支持</text>
+				<text class="val">河南云飞科技发展有限公司</text>
+			</view>
+			<view class="divide"></view>
+			<view class="info-item">
+				<text class="tit">关注微信</text>
+				<text class="val">河南云飞科技发展有限公司</text>
+			</view>
+		</view>
+		<view class="line"></view>
+		<view class="part">
+			<view class="info-item">
+				<text class="tit">公司官网</text>
+				<text class="val">www.hnyfkj.cn</text>
+			</view>
+			<view class="divide"></view>
+			<view class="info-item">
+				<text class="tit">业务合作</text>
+				<text class="val">400-690-7990</text>
+			</view>
+			<view class="divide"></view>
+			<view class="info-item">
+				<text class="tit">公司邮箱</text>
+				<text class="val">hnyf826@163.com</text>
+			</view>
+		</view>
+		<view class="line"></view>
+		<!-- <view class="part">
+			<view class="info-item" @click="renewal">
+				<text class="tit">版本更新</text>
+				<u-icon name="arrow-right"></u-icon>
+			</view>
+		</view> -->
+		<view class="line"></view>
+		<view class="record">
+			<view class="info-item" @click="record">
+				<text class="tit">更新记录</text>
+				<u-icon name="arrow-right"></u-icon>
+			</view>
+		</view>
+		<view class="bottom">
+			©河南云飞科技发展有限公司
+		</view>
+		<u-modal title="升级中请勿随意操作" :show-confirm-button="false" v-model="showA" :content="contentA">
+			<view class="upgradeBox">
+				<u-line-progress v-show="isShow" active-color="#19be6b" :striped="true" :percent="percentNum" :striped-active="true"></u-line-progress>
+			</view>
+		</u-modal>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				 id:'',
+				 versions:'',
+				 showA: false, //
+				 contentA: '',
+				 isShow: false, //进度条
+				 percentNum: 0, //在线下载进度
+			}
+		},
+		methods: {
+			async getEquipList() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.app_version_record',
+					data: {
+						ret:"first"
+					}
+				})
+				console.log(res)
+				this.id = res[0].app_num
+			},
+			// 	this.versions = Number(res[0].app_num.match(/\d+/g).join(""))
+			// 	var ids = Number(this.id.match(/\d+/g).join(""))
+			// 	if (this.versions > ids) {
+			// 		uni.showModal({
+			// 			title: '提示',
+			// 			content: '检测到有新版本,是否更新?',
+			// 			success: (res) => {
+			// 				if (res.confirm) {
+			// 					console.log('用户点击确定');
+			// 					this.showA = true
+			// 					this.isShow = true
+			// 					this.upgrade()
+			// 				} else if (res.cancel) {
+			// 					plus.runtime.quit();
+			// 					console.log('用户点击取消');
+			// 				}
+			// 			}
+			// 		})
+			// 	}else{
+			// 		uni.showToast({
+			// 			title:"当前版本已是最新版本",
+			// 			icon:"none"
+			// 		})
+			// 	}
+			// },
+			// renewal(){
+			// 	this.getEquipList()
+			// },
+			// upgrade() {
+			// 	console.log(this.appName)
+			// 	var url = "http://182.92.193.64:8002/app_file/" + this.appName
+			// 	console.log(url)
+			// 	const downloadTask = uni.downloadFile({
+			// 		url: url, //仅为示例,并非真实的资源
+			// 		success: (res) => {
+			// 			console.log(res)
+			// 			if (res.statusCode === 200) {
+			// 				console.log('下载成功');
+			// 				console.log('安装包下载成功,即将安装:' + JSON.stringify(res, null, 4));
+			// 				plus.runtime.openFile(res.tempFilePath);
+			// 			}
+			// 		},
+			// 		fail: (err) => {
+			// 			console.log(err)
+			// 		},
+			// 		complete: (com) => {
+			// 			console.log(com)
+			// 		}
+			// 	});
+			// 	downloadTask.onProgressUpdate((res) => {
+			// 		this.percentNum = res.progress
+			// 		if (res.progress == 100) {
+			// 			console.log('下载完成了')
+			// 			plus.runtime.quit();
+			// 		}
+			// 	});
+			// },
+			record(){
+				uni.navigateTo({
+					url:"../record/record"
+				})
+			}
+		},
+		onLoad(){
+			this.getEquipList()
+		},
+		onShow() {
+			// this.id = plus.runtime.version
+		},
+		onBackPress(option){
+			uni.redirectTo({
+				url:"../index/index"
+			})
+		}
+	}
+</script>
+
+<style lang="scss">
+page {
+ 	background:$uni-bg-color-grey;
+}
+.line{
+	height:16rpx;
+	width:100%;
+	background:$uni-bg-color-grey;
+}
+.bottom{
+	height:190rpx;
+	line-height:190rpx;
+	font-size:8px;
+	text-align: center;
+}
+.logo-box{
+	background:#fff;
+	text-align: center;
+	padding:80rpx 0;
+	image{
+		width:150rpx;
+	}
+	.version{
+		font-size:24rpx;
+		margin-top:20rpx;
+	}
+}
+.part{
+	background:#fff;
+	padding:0 40rpx;
+	.divide{
+		width:100%;
+		height:1px;
+		background:$uni-bg-color-grey;
+		}
+	.info-item{
+		display:flex;
+		justify-content: space-between;
+		line-height:100rpx;
+		.tit{font-size:14px}
+		.val{
+			font-size:12px;
+			color:#666;
+		}
+	}
+}
+.record{
+	background:#fff;
+	padding:0 40rpx;
+	.info-item{
+		display:flex;
+		justify-content: space-between;
+		line-height:100rpx;
+		.tit{font-size:14px}
+	}
+}
+.upgradeBox {
+		padding: 15rpx;
+	}
+</style>

+ 59 - 0
pages/my/feedback/feedback.vue

@@ -0,0 +1,59 @@
+<template>
+	<view>
+		<view class="area">
+			<textarea placeholder-class="place" placeholder="请填写您的问题和意见"></textarea>
+		</view>
+		<view class="in-box">
+			<input type="text" placeholder-class="place" placeholder="请填写您的手机号方便我和您联系"/>
+		</view>
+		<view class="sub-btn">
+			提交
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style lang="scss">
+page{
+	.place{
+		font-size:24rpx;
+	}
+	background:$uni-bg-color-grey;
+	.area{
+		padding:20rpx;
+		background:#fff;
+		margin:20rpx 0;
+		textarea{
+			width:100%;						
+		}
+	}
+	.in-box{
+		padding:20rpx;
+		background:#fff;
+		margin-bottom:20rpx;
+	}
+	.sub-btn{
+		width:60%;
+		height:66rpx;
+		line-height:66rpx;
+		background:$uni-color-success;
+		margin:auto;
+		font-size:28rpx;
+		color:#fff;
+		text-align: center;
+		border-radius: 4px;;
+	}
+}
+</style>

+ 207 - 0
pages/my/index/index.vue

@@ -0,0 +1,207 @@
+<template>
+	<view>
+		<view class="subject">
+			<view style="width: 100%;background-color: #FFFFFF;position: relative;">
+				<view class="personal">
+					<view class="personal_left">
+						<image :src="userinfos.image" mode="" @error="error"></image>
+					</view>
+					<view class="personal_center">
+						<p>{{usernames}}</p>
+						<p>{{userinfos.email || userinfos.mobile}}</p>
+					</view>
+					<view class="personal_right" @click="userinfo">
+						<uni-icons type="compose" style="color: #FFFFFF;margin-right: 10rpx;"></uni-icons>
+						编辑
+					</view>
+				</view>
+			</view>
+			<view style="background-color: #FFFFFF;margin: 20rpx auto 0;">
+				<view class="AboutUs" @click="about">
+					<u-icon name="moban" custom-prefix="custom-icon" class="icon_left"></u-icon>
+					关于我们
+					<uni-icons type="arrowright" class="icon_right"></uni-icons>
+				</view>
+			</view>
+			<view style="background-color: #FFFFFF;">
+				<view class="quit" @click="outto">
+					<u-icon name="tuichu" custom-prefix="custom-icon" class="icon_left"></u-icon>
+					退出登录
+					<uni-icons type="arrowright" class="icon_right"></uni-icons>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				usernames: '',
+				userinfos: {
+
+				}
+			}
+		},
+		methods: {
+			//user.login.user_login_info
+			//home.homes.personal_center
+			async getUserlogin() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.user_login_info',
+				})
+				console.log(res.children)
+				this.usernames = res.username
+				this.getUsermsg(this.usernames)
+				uni.setStorage({
+					key: 'jurisdiction',
+					data: JSON.stringify(res.children),
+					success: () => {
+						
+					}
+				})
+			},
+			async getUsermsg(user) {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.personal_center',
+					data: {
+						username: user
+					}
+				})
+				console.log(res)
+				this.userinfos = res
+			}, //user.login.logout_user
+			async getlogout() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=user.login.logout_user',
+				})
+			},
+			about() {
+				uni.navigateTo({
+					url: "../about/about"
+				})
+			},
+			error(e){
+				this.userinfos.image = "../../../static/images/my/f856c0422304bdd24a008f4d75b76e3.png"
+			},
+			// feedback(){
+			// 	uni.navigateTo({
+			// 		url:"../feedback/feedback"
+			// 	})
+			// },
+			userinfo() {
+				uni.navigateTo({
+					url: "../user-info/user-info?data=" + JSON.stringify(this.userinfos)
+				})
+			},
+			outto() {
+				uni.showModal({
+					title: '提示',
+					content: '是否退出登录',
+					success: (res) => {
+						if (res.confirm) {
+							this.getlogout()
+							uni.removeStorage({
+								key:"session_key"
+							})
+							uni.navigateTo({
+								url: "../../login/login"
+							})
+						} else if (res.cancel) {
+							console.log('用户点击取消');
+						}
+					}
+				});
+			}
+		},
+		onLoad() {
+			this.getUserlogin()
+		},
+		onShow() {
+			this.getUserlogin()
+			this.$forceUpdate()
+		}
+	}
+</script>
+<style lang="scss">
+	.subject {
+		width: 100%;
+		height: 100vh;
+		background-color: #F9F9F9;
+	}
+
+	.personal {
+		width: 90%;
+		margin: 0 auto;
+		display: flex;
+		padding: 20rpx 0 40rpx;
+		box-sizing: border-box;
+		.personal_left {
+			width: 18%;
+			margin-right: 30rpx;
+
+			image {
+				width: 124rpx;
+				height: 120rpx;
+				border-radius: 60rpx;
+			}
+		}
+
+		.personal_center {
+			padding-top: 20rpx;
+
+			p:nth-child(1) {
+				font-size: 34rpx;
+				font-weight: 700;
+				margin-bottom: 10rpx;
+			}
+
+			p:nth-child(2) {
+				font-size: 24rpx;
+			}
+		}
+
+		.personal_right {
+			width: 150rpx;
+			background-color: #55C87B;
+			height: 60rpx;
+			text-align: center;
+			border-radius: 30rpx;
+			line-height: 60rpx;
+			color: #FFFFFF;
+			position: absolute;
+			top: 50rpx;
+			right: 30rpx;
+		}
+	}
+
+	.AboutUs,
+	.quit,
+	.opinion {
+		width: 90%;
+		height: 100rpx;
+		line-height: 100rpx;
+		margin: 20rpx auto 0;
+		position: relative;
+		padding-left: 20rpx;
+		font-size: 28rpx;
+
+		.icon_left {
+			margin-right: 20rpx;
+			color: #55C87B !important;
+			font-size: 32rpx;
+		}
+
+		.icon_right {
+			position: absolute;
+			top: 0;
+			right: 10rpx;
+			font-size: 32rpx !important;
+		}
+	}
+
+	.opinion {
+		margin: 0 auto;
+		border-top: 2rpx solid #EAEAEA;
+	}
+</style>

+ 105 - 0
pages/my/record/record.vue

@@ -0,0 +1,105 @@
+<template>
+	<view>
+		<view class="records">
+			<view class="records_itemtf" v-if="dataTF">
+				暂无更新记录
+			</view>
+			<view class="records_item" v-for="item,index in recordsdata" :key="index" @click="showtf(index)" v-else="dataTF">
+				<view class="records_item_top">
+					<view class="item_left">
+						<p>版本{{item.app_num}}主要更新</p>
+						<p>{{item.addtime|timeFormat()}}</p>
+					</view>
+					<view class="item_right">
+						<u-icon :name="indexnum == index?'arrow-down':'arrow-right'"></u-icon>
+					</view>
+				</view>
+				<view class="records_item_bot" v-if="indexnum == index">
+					<p v-for="items,index in item.app_desc" :key="index">{{index+1+'、'+items}}</p>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<style lang="scss">
+	page {
+		background-color: #f1f1f1;
+	}
+	.records{
+		margin-top: 20rpx;
+		.records_itemtf{
+			font-size: 30rpx;
+			width: 100%;
+			height: 100rpx;
+			line-height: 100rpx;
+			text-align: center;
+		}
+		.records_item{
+			margin-bottom: 10rpx;
+			.records_item_top{
+				width: 100%;
+				background-color: #FFFFFF;
+				height: 110rpx;
+				padding: 10rpx 28rpx;
+				display: flex;
+				justify-content: space-between;
+				box-sizing: border-box;
+				.item_left{
+					p{
+						color: #474747;
+					}
+					p:first-child{
+						font-size: 32rpx;
+						margin-bottom: 10rpx;
+					}
+					p:last-child{
+						font-size: 26rpx;
+					}
+				}
+				.item_right{
+					height: 110rpx;
+					line-height: 100rpx;
+				}
+			}
+			.records_item_bot{
+				padding: 10rpx 28rpx 0;
+				box-sizing: border-box;
+				p{
+					margin-bottom: 6rpx;
+				}
+			}
+		}
+	}
+</style>
+<script>
+	export default {
+		data() {
+			return {
+				recordsdata: [],
+				indexnum:0,
+				dataTF:false
+			}
+		},
+		methods: {
+			async getEquipList() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.app_version_record'
+				})
+				console.log(res)
+				this.recordsdata = res
+				if(res.length == 0){
+					this.dataTF = true
+				}else{
+					this.dataTF = false
+				}
+			},
+			showtf(index){
+				this.indexnum = index
+				console.log(this.indexnum)
+			}
+		},
+		onLoad() {
+			this.getEquipList()
+		}
+	}
+</script>

+ 203 - 0
pages/my/user-info/user-info.vue

@@ -0,0 +1,203 @@
+<template>
+	<view class="user-info">
+		<view class="info-item">
+			<text class="tit">头像</text>
+			<view class="avater" @click="gainimg">
+				<image :src="userinfos.image" mode="aspectFill"></image>
+			</view>
+		</view>
+		<view class="info-item">
+			<text class="tit">用户名</text>
+			<input type="text" v-model="userinfos.username" :class="compileTF?'valinput valinput2':'valinput'" :disabled="!compileTF"
+			 maxlength='8' />
+		</view>
+		<view class="info-item">
+			<text class="tit">用户身份</text>
+			<text class="val">管理员</text>
+		</view>
+		<view class="info-item">
+			<text class="tit">用户电话</text>
+			<input type="text" v-model="userinfos.mobile" :class="compileTF?'valinput valinput2':'valinput'" :disabled="!compileTF"
+			 @blur="verifyphone" />
+			<p class="hint" v-if="phonehint">手机号格式不正确</p>
+		</view>
+		<view class="info-item">
+			<text class="tit">E-mail</text>
+			<input type="text" v-model="userinfos.email" :class="compileTF?'valinput valinput2':'valinput'" :disabled="!compileTF"
+			 @blur="verifyemail" />
+			<p class="hint" v-if="emailhint">邮箱格式不正确</p>
+		</view>
+		<view class="info-item">
+			<text class="tit">我的地址</text>
+			<input type="text" v-model="location" :class="compileTF?'valinput valinput2':'valinput'"
+			 :disabled="!compileTF" />
+		</view>
+		<view class="compile">
+			<p @click="compile" v-if="!compileTF">编辑</p>
+			<p @click="submit" v-else>提交</p>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				userinfos: {},
+				location:'',
+				imageList: '',
+				compileTF: false,
+				phonehint: false,
+				emailhint: false
+			}
+		},
+		methods: {
+			gainimg() { //添加图片
+				if (this.compileTF) {
+					uni.chooseImage({
+						count: 1, //默认9
+						sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+						sourceType: ['album', 'camera'], //从相册选择
+						success: (res) => {
+							uni.uploadFile({
+								url: 'http://182.92.193.64:8002/api/api_gateway?method=base.bases.base_photo', //仅为示例,非真实的接口地址
+								filePath: res.tempFilePaths[0],
+								name: 'img_file',
+								formData: {
+									'user': 'test'
+								},
+								success: (uploadFileRes) => {
+									this.userinfos.image = JSON.parse(uploadFileRes.data).data.src
+									this.$forceUpdate() //强制刷新视图
+								}
+							});
+						}
+					})
+				}
+			}, //
+			async postusers() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=home.homes.personal_center',
+					data: {
+						ret: 'change',
+						username: this.userinfos.username,
+						mobile: this.userinfos.mobile,
+						province:  this.userinfos.province,
+						city:  this.userinfos.city,
+						district:  this.userinfos.district,
+						image: this.userinfos.image,
+						email: this.userinfos.email
+					}
+				})
+			},
+			compile() { //编辑按钮
+				this.compileTF = true
+			},
+			submit() {//提交按钮
+				if(this.phonehint == false &&this.emailhint == false){
+					this.userinfos.province = this.location.slice(0,this.location.indexOf("省")+1)
+					this.userinfos.city = this.location.slice(this.location.indexOf("省")+1,this.location.indexOf("市")+1)
+					this.userinfos.district = this.location.slice(this.location.indexOf("市")+1)
+					this.postusers()
+					this.compileTF = false
+					uni.redirectTo({
+						url:"../index/index"
+					})
+				}
+			},
+			verifyphone() { //手机号验证
+				var reg = /^1[356789]\d{9}$/;
+				if (!reg.test(this.userinfos.mobile)) {
+					this.phonehint = true
+				} else {
+					this.phonehint = false
+				}
+			},
+			verifyemail() { //邮箱验证
+				var reg = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
+				if (!reg.test(this.userinfos.email)) {
+					this.emailhint = true
+				} else {
+					this.emailhint = false
+				}
+			}
+		},
+		onLoad(option) {
+			this.userinfos = JSON.parse(option.data)
+			this.location = this.userinfos.province+this.userinfos.city+this.userinfos.district
+			console.log(this.userinfos)
+		}
+
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background: $uni-bg-color-grey;
+
+		.user-info {
+			background: #fff;
+			padding: 0 40rpx;
+
+			.info-item {
+				display: flex;
+				justify-content: space-between;
+				line-height: 100rpx;
+				position: relative;
+
+				.avater {
+					width: 100rpx;
+					height: 100rpx;
+					border-radius: 50%;
+					overflow: hidden;
+
+					image {
+						width: 100%;
+						height: 100%;
+					}
+				}
+
+				.tit {
+					font-size: 14px
+				}
+
+				.val {
+					font-size: 12px;
+					color: #666;
+				}
+
+				.valinput {
+					margin-top: 24rpx;
+					text-align: right;
+					font-size: 12px;
+					color: #666;
+					padding: 10rpx 0;
+					width: 360rpx;
+				}
+
+				.valinput2 {
+					background-color: #e1e5ee;
+				}
+
+				.hint {
+					position: absolute;
+					top: 40rpx;
+					right: 220rpx;
+					font-size: 24rpx;
+					color: #ff0000;
+				}
+			}
+
+			.compile {
+				width: 100%;
+				margin-top: 40rpx;
+				height: 60rpx;
+				line-height: 60rpx;
+				text-align: center;
+				background-color: #58C77A;
+				border-radius: 30rpx;
+				color: #FFFFFF;
+			}
+		}
+	}
+</style>

+ 371 - 0
pages/prevention/control.vue

@@ -0,0 +1,371 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备控制"></uni-nav-bar>
+			</view>
+			<view class="control">
+				<view class="control_restart" v-if="myuser_type">
+					<p class="title_p">管理员操作</p>
+					<view class="control_restart_but">
+						<button @click="restart">重启</button>
+						<button @click="upgrade">升级</button>
+					</view>
+				</view>
+				<view class="control_off">
+					<p class="title_p">设备开关</p>
+					<view class="control_off_off">
+						<p>{{condatas.ds == 1? "开机":"关机"}}</p>
+						<u-switch v-model="checked1" size="30" style="margin-top: 14rpx;" active-color="#58C876" @change="checkedTF"></u-switch>
+					</view>
+				</view>
+				<view class="control_mo">
+					<p class="title_p">定时模式</p>
+					<view class="control_off_off" @click="show1 = !show1">
+						<p>{{condatas.timctrl==1 ? "时控":"光控"}}</p>
+						<u-icon name="arrow-down-fill" size="12" color="#7F8082"></u-icon>
+					</view>
+					<u-action-sheet :list="options1" v-model="show1" @click="actionSheetCallback"></u-action-sheet>
+				</view>
+				<view class="control_time" v-if="condatas.timctrl== 0">
+					<p class="title_p">定时时长(h)</p>
+					<view class="control_off_off" @click="show2 = !show2">
+						<p>{{condatas.tt==0?'常亮':condatas.tt}}</p>
+						<u-icon name="arrow-down-fill" size="12" color="#7F8082"></u-icon>
+					</view>
+				</view>
+				<view class="control_time" v-else>
+					<p class="title_p">开始结束时间</p>
+					<view class="control_off_off" @click="show3 = !show3">
+						<p>开始时间:{{condatas.st}}:00</p>
+						<u-picker v-model="show3" mode="time" :params="params" @confirm="confirmFun"></u-picker>
+						<u-icon name="arrow-down-fill" size="12" color="#7F8082"></u-icon>
+					</view>
+					<view class="control_off_off" @click="show4 = !show4">
+						<p>结束时间:{{condatas.et}}:00</p>
+						<u-picker v-model="show4" mode="time" :params="params" @confirm="confirmFun2"></u-picker>
+						<u-icon name="arrow-down-fill" size="12" color="#7F8082"></u-icon>
+					</view>
+				</view>
+				<view class="control_interval">
+					<p class="title_p">上传时间间隔(min)</p>
+					<view class="slider">
+						<view class="" style="width: 90%;padding-top: 18rpx;">
+							<u-slider v-model="condatas.dattim" min="0" max="100" step="1" active-color="#58C876"></u-slider>
+						</view>
+						<view class="" style="width: 10%;text-align: center;">
+							{{condatas.dattim || 0}}
+						</view>
+					</view>
+				</view>
+				<view class="control_timing">
+					<p class="title_p">自清虫定时(min)</p>
+					<view class="slider">
+						<view class="" style="width: 90%;padding-top: 18rpx;">
+							<u-slider v-model="condatas.clt" min="0" max="100" step="1" active-color="#58C876"></u-slider>
+						</view>
+						<view class="" style="width: 10%;text-align: center;">
+							{{condatas.clt || 0}}
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="ensure">
+			<view class="ensure_btn" @click="ensure">
+				确 定
+			</view>
+		</view>
+		<u-popup v-model="show2" mode="bottom" length="30%" class="pop-up">
+			<scroll-view scroll-y="true" class="sheet">
+				<view class="sheet-text" v-for="(item,index) in options2" :key="index">
+					<p @click="typesofroles(index)">{{item.text}}</p>
+				</view>
+			</scroll-view>
+			<button @click="show2 = false">取消</button>
+		</u-popup>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				condatas: {},
+				checked1: false,
+				show1: false,
+				show2: false,
+				show3: false,
+				show4: false,
+				options1: [{
+						text: '光控'
+					},
+					{
+						text: '时控'
+					}
+				],
+				options2: [{
+						text: '常亮'
+					},
+					{
+						text: '1'
+					},
+					{
+						text: '2'
+					},
+					{
+						text: '3'
+					},
+					{
+						text: '4'
+					},
+					{
+						text: '5'
+					},
+					{
+						text: '6'
+					},
+					{
+						text: '7'
+					},
+					{
+						text: '8'
+					},
+					{
+						text: '9'
+					},
+					{
+						text: '10'
+					},
+					{
+						text: '00'
+					}
+				],
+				params: {
+					year: false,
+					month: false,
+					day: false,
+					hour: true,
+					minute: false,
+					second: false
+				},
+				myuser_type:false
+			}
+		},
+		methods: { //forecast.send_control.device_control_info
+			async controldata(data) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control_info',
+					data: {
+						d_id: data,
+						cmd: 'paramconf'
+					}
+				})
+				console.log(res)
+				this.condatas = res
+				if (this.condatas.ds == 1) {
+					this.checked1 = true
+				} else {
+					this.checked1 = false
+				}
+			},
+			//forecast.send_control.admin_device_control
+			async reorup(data) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.admin_device_control',
+					data: {
+						d_id: data.d_id,
+						device_type_id: 2,
+						cmd: data.cmd
+					}
+				})
+				if (res == true) {
+					uni.showToast({
+						title: '指令下发成功!'
+					});
+				} else {
+					uni.showToast({
+						title: '指令下发失败!'
+					});
+				}
+			},
+			//forecast.send_control.device_control
+			async controlby(data) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_control',
+					data: {
+						d_id: this.d_id,
+						device_type_id: 2,
+						config: data
+					}
+				})
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			typesofroles(index) {
+				this.condatas.tt = index
+				this.show2 = false
+			},
+			actionSheetCallback(index) {
+				this.condatas.timctrl = index
+			},
+			checkedTF(e) { //设备开关
+				if (e == true) {
+					this.condatas.ds = 1
+				} else {
+					this.condatas.ds = 0
+				}
+			},
+			confirmFun(e) { //开始时间
+				this.condatas.st = Number(e.hour)
+			},
+			confirmFun2(e) { //结束时间
+				this.condatas.et = Number(e.hour)
+			},
+			restart() { //重启
+					let obj = {
+						d_id: this.d_id,
+						cmd: 'reboot'
+					}
+					this.reorup(obj)
+			},
+			upgrade() { //升级
+					let obj = {
+						d_id: this.d_id,
+						cmd: 'update'
+					}
+					this.reorup(obj)
+			},
+			ensure() {
+				let str = JSON.stringify(this.condatas)
+				console.log(str)
+				this.controlby(str)
+				this.clickLeft()
+			}
+		},
+		onLoad(option) {
+			this.$forceUpdate()
+			this.controldata(option.id)
+			this.d_id = option.id
+			uni.getStorage({
+				key: "myuser_type",
+				success: (res) => {
+					if (Number(res.data) == 1) {
+						this.myuser_type = true
+					}
+				}
+			})
+		}
+	}
+</script>
+
+<style lang="scss">
+	.control {
+		position: absolute;
+		top: 50px;
+		width: 90%;
+		left: 5%;
+
+		.title_p {
+			padding-left: 20rpx;
+			border-left: 6rpx solid #28AE4F;
+			height: 40rpx;
+			margin-bottom: 20rpx;
+		}
+
+		.control_off_off {
+			display: flex;
+			justify-content: space-between;
+			margin-left: 24rpx;
+			padding: 0 30rpx;
+			background-color: #F7F8FA;
+			height: 60rpx;
+			line-height: 60rpx;
+			margin-bottom: 20rpx;
+		}
+
+		.slider {
+			display: flex;
+			padding: 0 30rpx 0 0;
+			margin-left: 24rpx;
+			margin-bottom: 20rpx;
+		}
+
+		.control_restart {
+			margin-bottom: 20rpx;
+
+			.title_p {
+				border-left: 6rpx solid #D17978;
+			}
+
+			.control_restart_but {
+				display: flex;
+				justify-content: flex-start;
+				margin-left: 24rpx;
+
+				button {
+					width: 110rpx;
+					height: 50rpx;
+					line-height: 50rpx;
+					font-size: 26rpx;
+					margin: 0 20rpx 0 0;
+					color: #FFFFFF;
+					background-color: #D17978;
+				}
+			}
+		}
+
+		.control_off {}
+	}
+
+	.pop-up {
+		.sheet {
+			background-color: white;
+			height: 400rpx;
+			overflow: hidden;
+
+			.sheet-text {
+				height: 80rpx;
+				border-bottom: 2rpx solid #F7F8FA;
+
+				p {
+					text-align: center;
+					height: 80rpx;
+					line-height: 80rpx;
+					color: black;
+					font-size: 16px;
+				}
+			}
+		}
+
+		button {
+			color: black;
+			position: absolute;
+			bottom: 0;
+			width: 100%;
+			font-size: 16px;
+			height: 80rpx;
+		}
+	}
+
+	.ensure {
+		width: 100%;
+		position: absolute;
+		bottom: 100rpx;
+
+		.ensure_btn {
+			width: 90%;
+			margin: 0 auto;
+			height: 60rpx;
+			line-height: 60rpx;
+			text-align: center;
+			background-color: #28AE4F;
+			color: #FFFFFF;
+			border-radius: 30rpx;
+		}
+	}
+</style>

+ 356 - 0
pages/prevention/equipmentdetails.vue

@@ -0,0 +1,356 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="设备详情"></uni-nav-bar>
+			</view>
+			<view class="info">
+				<view class="info_item">
+					<image :src="eqinfo.item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/cb/onBg.png':'http://static.yfpyx.com/bigdata_app/image/cb/offBg.png'"
+					 mode="" class="bgi"></image>
+					<p style="font-size: 32rpx;" @click="copy(eqinfo.item.imei)">设备 ID:{{eqinfo.item.imei}}
+					<image src="http://static.yfpyx.com/bigdata_app/image/environment/fuzhi.png" mode="" class="tishi"></image>
+					</p>
+					<p>设备名称:{{eqinfo.item.device_name}}</p>
+					<p>设备型号:{{eqinfo.item.dtype}}</p>
+					<p>最近上报时间:{{eqinfo.item.addtime|timeFormat()}}</p>
+					<p>设备地址:{{eqinfo.item.address}}</p>
+				</view>
+			</view>
+			<view class="control">
+				<view class="control_item" v-if="kongtf" @click="control">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/8.png'" mode=""></image>
+					<p>设备控制</p>
+				</view>
+				<view class="control_item" v-if="shujutf" @click="charts">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/10.png'" mode=""></image>
+					<p>历史数据</p>
+				</view>
+				<view class="control_item" v-if="simtf" @click="sim">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/9.png'" mode=""></image>
+					<p>SIM卡详情</p>
+				</view>
+				<view class="control_item" @click="repairs">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/environment/7.png'" mode=""></image>
+					<p>一键报修</p>
+				</view>
+			</view>
+			<view class="realtime">
+				<p class="realtime_title">实时数据</p>
+				<view class="realtime_text" v-if="newdatesTF">
+					<view class="realtime_text_item">
+						<view class="realtime_text_item_info" v-for="item,index in olddatas" :key="index">
+							<view class="item_info_img">
+								<image :src="'http://static.yfpyx.com/bigdata_app'+item.icon" mode=""></image>
+							</view>
+							<view class="item_info_text">
+								<p>{{item.txt}}</p>
+								<p style="margin-top: 20rpx;">{{item.value}}</p>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view class="realtime_tishi" v-else>
+					暂无数据
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		data() {
+			return {
+				eqinfo: {},
+				olddata: {},
+				olddatas: [],
+				newdatesTF: false,
+				work: "",
+				shujutf: false,
+				kongtf: false,
+				simtf: false
+			}
+		},
+		methods: {
+			modification() {
+				this.olddatas = [{
+						icon: '/image/cb/icon02.png',
+						txt: '设备开关',
+						value: Number(this.olddata.ds) == 1 ? '开机' : "关机",
+					},
+					{
+						icon: '/image/cb/icon05.png',
+						txt: '工作状态',
+						value: this.work
+					},
+					{
+						icon: '/image/prevention/44.png',
+						txt: '电击次数',
+						value: this.olddata.ct
+					},
+					{
+						icon: '/image/prevention/33.png',
+						txt: '定时时长',
+						value: this.olddata.tt
+					}, {
+						icon: '/image/cb/icon08.png',
+						txt: '环境温度(℃)',
+						value: this.olddata.new_tem
+					}, {
+						icon: '/image/cb/icon07.png',
+						txt: '环境湿度(%)',
+						value: this.olddata.new_hum
+					}, {
+						icon: '/image/prevention/icon16.png',
+						txt: '信号强度',
+						value: this.olddata.csq
+					}, {
+						icon: '/image/prevention/100.png',
+						txt: '清虫间隔(min)',
+						value: this.olddata.clt_t
+					}, {
+						icon: '/image/prevention/101.png',
+						txt: '雨控状态',
+						value: Number(this.olddata.rps) == 1 ? "雨控" : '正常'
+					}, {
+						icon: '/image/prevention/102.png',
+						txt: '温控状态',
+						value: Number(this.olddata.tps) == 1 ? "温控" : '正常'
+					},
+					{
+						icon: '/image/prevention/105.png',
+						txt: '充电电压',
+						value: this.olddata.cv
+					},
+					{
+						icon: '/image/prevention/106.png',
+						txt: '电池电压',
+						value: Number(this.olddata.bv)
+					}
+				]
+			},
+			async history() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+					data: {
+						device_type_id: 2,
+						device_id: this.eqinfo.item.imei
+					}
+				})
+				if (res.data.length != 0) {
+					this.olddata = res.data[0].d_h_t
+					this.newdatesTF = true
+					if (Number(this.olddata.ws) == 0) {
+						this.work = "待机"
+					} else if (Number(this.olddata.ws) == 1) {
+						this.work = "工作"
+					} else {
+						this.work = "充电"
+					}
+				} else {
+					this.newdatesTF = false
+				}
+				this.modification()
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			sim() {
+				// sim卡详情
+				uni.navigateTo({
+					url: "./sim?id=" + this.eqinfo.item.d_id
+				})
+			},
+			repairs(){
+				console.log(this.eqinfo.item)
+				var device_id = this.eqinfo.item.equip_id||this.eqinfo.item.device_id
+				uni.navigateTo({
+					url: "../afterSale/addafter?device_id="+ device_id +"&device_type="+ 5
+				})
+			},
+			control() { //设备控制
+				uni.navigateTo({
+					url: "./control?id=" + this.eqinfo.item.d_id
+				})
+			},
+			charts() { //历史数据
+				uni.navigateTo({
+					url: "./ucharts?d_id=" + this.eqinfo.item.d_id + "&imei=" + this.eqinfo.item.imei
+				})
+			},
+			copy(item){
+				uni.setClipboardData({
+				    data: item , 
+				    success: function () {
+				        console.log('success');
+				    }
+				});
+			},
+		},
+		onLoad(option) {
+			this.$forceUpdate()
+			this.eqinfo.item = JSON.parse(option.shebei)
+			console.log(JSON.parse(option.shebei))
+			this.history()
+			uni.getStorage({
+				key: "jurisdiction",
+				success: (res) => {
+					console.log(JSON.parse(res.data))
+					let items = JSON.parse(res.data).filter((item) => {
+						return item.purview_name == "防治系统"
+					})
+					let items2 = items[0].children.filter((item) => {
+						return item.purview_name == "杀虫灯"
+					})
+					var arr = items2[0].children
+					console.log(arr)
+					for (var i = 0; i < arr.length; i++) {
+						switch (arr[i].purview_name) {
+							case "设备操作":
+								this.kongtf = true
+								break
+							case "设备控制":
+								this.kongtf = true
+								break
+							case "SIM卡状态":
+								this.simtf = true
+								break
+							case "SIM卡":
+								this.simtf = true
+								break
+							case "数据详情":
+								this.shujutf = true
+								break
+						}
+					}
+				},
+			})
+		}
+	}
+</script>
+
+<style lang="scss">
+	.info {
+		width: 100%;
+		position: absolute;
+		top: 44px;
+
+		.info_item {
+			width: 90%;
+			margin: 0 auto;
+			height: 260rpx;
+			padding: 26rpx 50rpx;
+			position: relative;
+			box-sizing: border-box;
+
+			.bgi {
+				width: 100%;
+				height: 260rpx;
+				position: absolute;
+				top: 0;
+				left: 0;
+				z-index: -1;
+			}
+
+			p {
+				font-size: 24rpx;
+				color: #FFFFFF;
+				margin-bottom: 10rpx;
+				.tishi{
+					width: 30rpx;
+					height: 30rpx;
+					margin: 0rpx 0 0 20rpx;
+				}
+			}
+		}
+	}
+
+	.control {
+		width: 90%;
+		position: absolute;
+		top: 372rpx;
+		left: 5%;
+		display: flex;
+		justify-content: space-between;
+		text-align: center;
+		padding: 0 30rpx;
+		box-sizing: border-box;
+
+		.control_item {
+			width: 120rpx;
+			height: 120rpx;
+
+			image {
+				width: 70rpx;
+				height: 70rpx;
+			}
+
+			p {
+				font-size: 24rpx;
+			}
+		}
+	}
+
+	.realtime {
+		width: 100%;
+		position: absolute;
+		top: 500rpx;
+
+		.realtime_title {
+			font-weight: 700;
+			width: 90%;
+			margin: 0 auto;
+		}
+
+		.realtime_tishi {
+			width: 90%;
+			margin: 0 auto;
+			text-align: center;
+			font-size: 32rpx;
+			padding-top: 40rpx;
+		}
+
+		.realtime_text {
+			width: 90%;
+			margin: 0 auto;
+
+			.realtime_text_item {
+				width: 100%;
+				display: flex;
+				justify-content: space-between;
+				flex-wrap: wrap;
+				margin-bottom: 50rpx;
+
+				.realtime_text_item_info {
+					width: 48%;
+					box-shadow: 0 0 10rpx #bcb9ca;
+					margin-top: 20rpx;
+					display: flex;
+					padding: 20rpx 20rpx;
+					box-sizing: border-box;
+
+					.item_info_img {
+						width: 30%;
+						text-align: center;
+						margin-right: 30rpx;
+
+						image {
+							width: 64rpx;
+							height: 64rpx;
+							margin-top: 10rpx;
+						}
+					}
+
+					.item_info_text {
+						font-size: 24rpx;
+
+					}
+				}
+			}
+		}
+
+	}
+</style>

+ 161 - 0
pages/prevention/index.vue

@@ -0,0 +1,161 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="防治系统" right-icon="search" @clickRight="clickRight"
+				 size="16"></uni-nav-bar>
+			</view>
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/prevention/1.png'" mode="" class="image"></image>
+			<view class="prevents">
+				<view class="prevents_item" v-for="item,index in eqlistdata" :key="index" @click="eqdetails(item)">
+					<image :src="item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/prevention/6.png':'http://static.yfpyx.com/bigdata_app/image/prevention/7.png'"
+					 mode="" class="prevents_item_img"></image>
+					<view class="prevents_item_top">
+						<p>设备 ID:{{item.imei}}</p>
+						<p :class="item.is_online==1?'green':'red'" v-text="item.is_online==1?'在线':'离线'"></p>
+					</view>
+					<view class="prevents_item_bot">
+						最新上报时间:{{item.addtime|timeFormat()}}
+					</view>
+				</view>
+			</view>
+		</view>
+		<view class="top" v-if="isTop" @click="top">
+			<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/6209a98f0cb3b5086f2ca36152c9269.png'" mode=""></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				page: 1,
+				size: 10,
+				eqlistdata: [],
+				isTop:false
+			}
+		},
+		methods: {
+			async eqlist() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: 2,
+						page: this.page,
+						size: this.size,
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.data)
+				console.log(this.eqlistdata)
+			},
+			clickLeft() {
+				uni.switchTab({
+					url: "../index/index"
+				})
+			},
+			clickRight() {
+				uni.navigateTo({
+					url: "./search"
+				})
+			},
+			eqdetails(data) {
+				uni.navigateTo({
+					url: "./equipmentdetails?shebei=" + JSON.stringify(data)
+				})
+			},
+			top() {
+				uni.pageScrollTo({
+					scrollTop: 0,
+					duration: 500
+				})
+			}
+		},
+		onLoad() {
+			this.eqlist()
+		},
+		onReachBottom() {
+			this.page++
+			this.eqlist()
+		},
+		onPageScroll(e) { //nvue暂不支持滚动监听,可用bindingx代替
+			if (e.scrollTop > 200) { //距离大于200时显示
+				this.isTop = true
+			} else { //距离小于200时隐藏
+				this.isTop = false
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	/deep/.uni-icons {
+		font-size: 40rpx !important;
+	}
+
+	.image {
+		position: fixed;
+		top: 108px;
+		width: 100%;
+		height: 160rpx;
+		z-index: 555;
+	}
+
+	.prevents {
+		width: 100%;
+		position: absolute;
+		top: 140px;
+
+		.prevents_item {
+			width: 95%;
+			margin: 0 auto 30rpx;
+			border-radius: 10rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 40rpx 20rpx 80rpx;
+			position: relative;
+			box-sizing: border-box;
+
+			.prevents_item_img {
+				width: 30rpx;
+				height: 50rpx;
+				position: absolute;
+				top: -4rpx;
+				left: 30rpx;
+			}
+
+			.prevents_item_top {
+				display: flex;
+				justify-content: space-between;
+				height: 60rpx;
+				border-bottom: 2rpx solid #F4F4F4;
+				line-height: 60rpx;
+				font-size: 26rpx;
+
+				.red {
+					color: #ff0000;
+				}
+
+				.green {
+					color: #7DBB91;
+				}
+			}
+
+			.prevents_item_bot {
+				margin-top: 20rpx;
+				font-size: 26rpx;
+				color: #BDBDBD;
+			}
+		}
+	}
+	.top {
+		position: fixed;
+		right: 30px;
+		bottom: 100px;
+		z-index: 100;
+		image{
+			width: 100rpx;
+			height: 100rpx;
+		}
+	}
+</style>

+ 175 - 0
pages/prevention/search.vue

@@ -0,0 +1,175 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回"></uni-nav-bar>
+				<view class="search_top_input">
+					<input type="text" value="" placeholder="请输入设备ID" v-model="imports" @input="searchinp" />
+					<u-icon name="search" size="40" class="icon" @click="search"></u-icon>
+				</view>
+			</view>
+			<view class="prevents">
+				<view class="prevents_item" v-for="item,index in eqlistdata" :key="index" @click="eqdetails(item)">
+					<image :src="item.is_online==1?'http://static.yfpyx.com/bigdata_app/image/prevention/6.png':'http://static.yfpyx.com/bigdata_app/image/prevention/7.png'"
+					 mode="" class="prevents_item_img"></image>
+					<view class="prevents_item_top">
+						<p>设备 ID:{{item.imei}}</p>
+						<p :class="item.is_online==1?'green':'red'" v-text="item.is_online==1?'在线':'离线'"></p>
+					</view>
+					<view class="prevents_item_bot">
+						最新上报时间:{{item.addtime|timeFormat()}}
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		Debounce,
+		Throttle
+	} from "../../util/anitthro.js"
+	export default {
+		data() {
+			return {
+				imports: '',
+				eqlistdata: [],
+				page: 1,
+				size: 10,
+				show: false,
+				value: '',
+				options1: [{
+						text: "杀虫灯",
+						id: 2
+					},
+					{
+						text: "虫情测报",
+						id: 3
+					},
+					{
+						text: "孢子仪",
+						id: 7
+					},
+					{
+						text: "性诱设备",
+						id: 4
+					},
+				]
+			}
+		},
+		methods: {
+			async eqlist() { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.lamp_list',
+					data: {
+						device_type_id: 2,
+						page: this.page,
+						size: this.size,
+						device_id: this.imports
+					}
+				})
+				this.eqlistdata = this.eqlistdata.concat(res.data)
+				console.log(this.eqlistdata)
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			search() {
+				this.eqlistdata = []
+				this.eqlist()
+			},
+			searchinp() {
+				Debounce(() => {
+					this.eqlistdata = []
+					this.eqlist()
+				}, 1000)()
+			},
+			actionSheetCallback(index) { //选择框
+				this.value = this.options1[index].text;
+				// this.id = this.options1[index].id
+			},
+			eqdetails(data) {
+				uni.navigateTo({
+					url: "./equipmentdetails?shebei=" + JSON.stringify(data)
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.search_top_input {
+		width: 80%;
+		height: 54rpx;
+		background-color: #E4E4E4;
+		border-radius: 27rpx;
+		position: absolute;
+		top: 18rpx;
+		right: 18rpx;
+		padding-top: 8rpx;
+		box-sizing: border-box;
+		input {
+			width: 85%;
+			// text-indent: 1rem;
+			font-size: 26rpx;
+			padding-left: 20px;
+			box-sizing: border-box;
+		}
+
+		.icon {
+			position: absolute;
+			top: 8rpx;
+			right: 26rpx;
+		}
+	}
+
+	.prevents {
+		width: 100%;
+		position: absolute;
+		top: 54px;
+
+		.prevents_item {
+			width: 95%;
+			margin: 0 auto 30rpx;
+			border-radius: 10rpx;
+			box-shadow: 0 0 10rpx #bcb9ca;
+			padding: 20rpx 40rpx 20rpx 80rpx;
+			position: relative;
+			box-sizing: border-box;
+			.prevents_item_img {
+				width: 30rpx;
+				height: 50rpx;
+				position: absolute;
+				top: -4rpx;
+				left: 30rpx;
+			}
+
+			.prevents_item_top {
+				display: flex;
+				justify-content: space-between;
+				height: 60rpx;
+				border-bottom: 2rpx solid #F4F4F4;
+				line-height: 60rpx;
+				font-size: 26rpx;
+
+				.red {
+					color: #ff0000;
+				}
+
+				.green {
+					color: #7DBB91;
+				}
+			}
+
+			.prevents_item_bot {
+				margin-top: 20rpx;
+				font-size: 26rpx;
+				color: #BDBDBD;
+			}
+		}
+	}
+</style>

+ 122 - 0
pages/prevention/sim.vue

@@ -0,0 +1,122 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="sim卡详情"></uni-nav-bar>
+			</view>
+			<view class="sim_info">
+				<view class="sim_info_title">
+					<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/cb/sim1.png'" mode=""></image>
+					<p>sim卡查询</p>
+				</view>
+				<view class="sim_info_text">
+					<p>运营商:{{siminfo.data.carrier}}</p>
+					<p>ICCID:{{iccid}}</p>
+					<p>状态:{{state[siminfo.data.account_status]}}</p>
+					<p>套餐:{{siminfo.data.data_plan}}MB</p>
+					<p>已用流量:{{siminfo.data.data_usage}}MB</p>
+					<p>剩余流量:{{siminfo.data.data_balance}}MB</p>
+					<p>到期时间:{{siminfo.data.outbound_date|timeFormat()}}</p>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				iccid: '',
+				siminfo: {
+					data: {
+						carrier: "--",
+						account_status: "--",
+						data_plan: "--",
+						data_usage: "--",
+						data_balance: "--",
+						outbound_date: ""
+					}
+				},
+				state: ['未知', '测试期', '沉默期', '使用中', '停机', '停机保号', '预销号', '销号'],
+				id: ''
+			}
+		},
+		methods: {
+			async simid(data) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.device_sim',
+					data: {
+						d_id: data,
+						type: 'sim'
+					}
+				})
+				if(res.length!=0){
+					this.iccid = res[0].iccid
+					this.simdata(this.iccid)
+				}
+				
+			},
+			async simdata(data) { //设备列表
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.sim_query',
+					data: {
+						iccid: data
+					}
+				})
+				// console.log(res.data)
+				this.siminfo = res.data
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			}
+		},
+		onLoad(option) {
+			console.log(option)
+			this.id = option.id
+			this.simid(this.id)
+		}
+	}
+</script>
+
+<style lang="scss">
+	.sim_info {
+		width: 90%;
+		position: absolute;
+		top: 54px;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding: 30rpx 20rpx 50rpx;
+		border-radius: 20rpx;
+		box-sizing: border-box;
+
+		.sim_info_title {
+			width: 100%;
+			display: flex;
+
+			image {
+				width: 24rpx;
+				height: 32rpx;
+				margin: 6rpx 20rpx 0 0;
+			}
+
+			p {
+				font-weight: 700;
+			}
+		}
+
+		.sim_info_text {
+			width: 100%;
+			padding-left: 44rpx;
+
+			p {
+				height: 30rpx;
+				margin-top: 20rpx;
+				font-size: 26rpx;
+			}
+		}
+	}
+</style>

+ 651 - 0
pages/prevention/ucharts.vue

@@ -0,0 +1,651 @@
+<template>
+	<view>
+		<view class="status_bar"></view>
+		<view class="" style="position: relative;top: 64px;">
+			<view style="position: fixed;z-index: 100;width: 100%;color: #FFFFFF;">
+				<uni-nav-bar @clickLeft="clickLeft" left-icon="back" left-text="返回" title="历史数据"></uni-nav-bar>
+			</view>
+			<view class="shuju_one">
+				<view class="shuju_one_title">
+					<view :class="titleidnex==index?'title_text_color':'tltle_text'" v-for="(item,index) in titletext" :key="index"
+					 @click="changeindex(index)">
+						{{item}}
+					</view>
+				</view>
+				<view class="canvastishi" v-if="!canvastishiTF">
+					暂无数据
+				</view>
+				<canvas v-if="canvastishiTF" canvas-id="canvasColumnA" id="canvasColumnA" class="charts" @touchstart="touchLineA($event)" @touchmove="moveLineA($event)"
+				 @touchend="touchEndLineA($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+			</view>
+			<view class="shuju_two" >
+				<view class="canvastishi" v-if="!canvastishiTF">
+					暂无数据
+				</view>
+				<canvas v-if="canvastishiTF" canvas-id="canvasColumnB" id="canvasColumnB" class="charts" @touchstart="touchLineBb($event)" @touchmove="moveLineBb($event)"
+				 @touchend="touchEndLineBb($event)" disable-scroll=true :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"></canvas>
+			</view>
+			<view class="selecttimes">
+				<view class="newtimes">
+					<view class="newtimes_state" @click="pickshow = !pickshow">
+						<view class="oldtimes_left"> 
+							<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/prevention/841f87bfd8abb1b09610fa0789f9d8e.png'" mode=""></image>
+							开始时间:{{this.oldtime|timeFormat()}}
+						</view>
+						<view class="oldtimes_left">
+							<u-icon name="arrow-down"></u-icon>
+						</view>
+						<u-picker mode="time" v-model="pickshow" :params="params" @confirm="pickone"></u-picker>
+					</view>
+					<view class="newtimes_end" @click="picktwoshow = !picktwoshow">
+						<view class="oldtimes_left">
+							<image :src="'http://static.yfpyx.com/bigdata_app'+'/image/prevention/1acfe2751c01d3786cdc49b83d7e505.png'" mode=""></image>
+							结束时间:{{this.newtime|timeFormat()}}
+						</view>
+						<view class="oldtimes_left">
+							<u-icon name="arrow-down"></u-icon>
+						</view>
+						<u-picker mode="time" v-model="picktwoshow" :params="params" @confirm="picktwo"></u-picker>
+					</view>
+					<p class="tishi" v-if="tishiTF">请选择正确的结束时间</p>
+					<view class="btnser" @click="serter">
+						搜 索
+					</view>
+				</view>
+			</view>
+			<view class="refresh" @click="refresh">
+				刷 新
+			</view>
+			<view class="condition">
+				<scroll-view scroll-top="0" scroll-x="true" class="scroll-X">
+					<table class="table">
+						<tr class="tr">
+							<th class="th" v-for="(item,index) in thdata" :key="'a'+index">{{item}}</th>
+						</tr>
+						<tr class="tr" v-for="(items,indexs) in eqlistdata" :key="'b'+indexs" v-if="forbidden">
+							<td class="td">{{items.d_h_t.addtime|timeFormat()}}</td>
+							<td class="td">{{items.d_h_t.ds==0?"关机":"开机"}}</td>
+							<td class="td">{{items.d_h_t.ws==0?"待机":"工作"}}</td>
+							<td class="td">{{items.d_h_t.rps==0?"正常":"保护"}}</td>
+							<td class="td">{{items.d_h_t.tps==0?"正常":"保护"}}</td>
+							<td class="td">{{items.d_h_t.dps==0?"正常":"保护"}}</td>
+							<td class="td">{{items.d_h_t.tt}}</td>
+							<td class="td">{{items.d_h_t.ct}}</td>
+							<td class="td">{{items.d_h_t.at}}</td>
+							<td class="td">{{items.d_h_t.ah}}</td>
+							<td class="td">{{items.d_h_t.cv}}</td>
+							<td class="td">{{items.d_h_t.bv}}</td>
+						</tr>
+						<tr class="tr" v-if="!forbidden">
+							<td class="td" v-for="item in 12">暂无数据</td>
+						</tr>
+					</table>
+				</scroll-view>
+				<view class="pagenumber">
+					<button @click="prev">上一页</button>
+					<view class="pagenumber_page">
+						第{{page}}页
+					</view>
+					<view class="pagenumber_page">
+						共 {{pagesum}} 页
+					</view>
+					<button @click="next" :disabled="!forbidden">下一页</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<style lang="scss">
+
+</style>
+<script>
+	import uCharts from '../../components/js_sdk/u-charts/u-charts/u-charts.js';
+	var canvaColumnA = null;
+	var canvaColumnB = null;
+	var presenttime = null
+	// var oldpresenttime = presenttime - 24*60*60*1000
+	export default {
+		data() {
+			return {
+				thdata: ["上报时间","设备开关", "工作状态", "雨控状态", "温控状态", "倾倒状态", "定时(h)", "电击次数", "温度(℃)", "湿度(%)", "充电电压(v)", "电池电压(v)",	
+				],
+				eqlistdata: [],
+				cWidth: '400',
+				cHeight: '400',
+				pixelRatio: 1,
+				titletext: ["24小时", "近一个月", "近半年", "近一年"],
+				titleidnex: 0,
+				oldtime: '',
+				newtime: '',
+				page: 1,
+				forbidden: false, //暂无数据
+				params: {
+					year: true,
+					month: true,
+					day: true,
+					hour: true,
+					minute: true,
+					second: false
+				},
+				pickshow: false,
+				picktwoshow: false,
+				tishiTF: false,
+				times: {
+					d_id: null,
+					start_time: null,
+					end_time: null,
+					device_id: null
+				},
+				canvastishiTF:false,
+				pagesum:0
+			}
+		},
+		// 页面加载执行的函数
+		onLoad(option) {
+			this.times.d_id = option.d_id
+			this.times.imei = option.imei
+			this.cWidth = uni.upx2px(650);
+			this.cHeight = uni.upx2px(500);
+		},
+		onShow(){
+			presenttime = +new Date();
+			this.oldtime = parseInt((presenttime - 24 * 60 * 60 * 1000) / 1000)
+			this.newtime = parseInt(presenttime / 1000)
+			setTimeout(()=>{
+				this.getServerData(parseInt(presenttime / 1000), parseInt((presenttime - 24 * 60 * 60 * 1000) / 1000))
+				this.historydata(parseInt(presenttime / 1000), parseInt((presenttime - 24 * 60 * 60 * 1000) / 1000))
+			},1000)
+		},
+		methods: { // 
+			//forecast.worm_lamp.device_polyline_data
+			// 获取数据,发请求
+			async getServerData(newtime, oldtimes) { //设备折线图
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_polyline_data',
+					data: {
+						device_type_id: 2,
+						d_id: this.times.d_id,
+						end_time: newtime,
+						start_time: oldtimes
+					}
+				})
+				if(res.length == 0){
+					this.canvastishiTF = false
+				}else{
+					this.canvastishiTF = true
+					var xtitle = []
+					var arr = []
+					var arr1 = []
+					var arr2 = []
+					var arr3 = []
+					var arr4 = []
+					var arr5 = []
+					for (var i = 0; i < res.length; i++) {
+						var times = new Date(res[i].addtime * 1000)
+						xtitle.unshift(times.getMonth() + 1 + "/" + times.getDate() + "-" + times.getHours() + ":" + times.getMinutes())
+						arr1.unshift(res[i].temperature)
+						arr2.unshift(res[i].humidity)
+						arr3.unshift(Number(res[i].others.bv))
+						arr4.unshift(Number(res[i].others.cv))
+						arr5.unshift(res[i].others.ct)
+					}
+					arr.unshift(arr1,arr2,arr3,arr4)
+					var obj = [{
+						name: '温度',
+						data: arr[0],
+						color: '#F97000'
+					}, {
+						name: '湿度',
+						data:  arr[1],
+						color: '#00E29D'
+					}, {
+						name: '电池电压',
+						data:  arr[2],
+						color: '#FF3F3F'
+					}, {
+						name: '充电电压',
+						data:  arr[3],
+						color: '#6CBBFF'
+					}]
+					var obj2 =[{
+						name: '击虫次数',
+						data: arr5,
+						color: '#00E29D'
+					}]
+					this.showColumn("canvasColumnA",xtitle, obj)
+					this.showColumnb("canvasColumnB",xtitle, obj2)
+				}
+			},
+			changeindex(index) { //选择日期
+				this.titleidnex = index
+				var now = new Date();
+				if (index == 0) {
+					this.newtime = parseInt(+new Date(now) / 1000)
+					this.oldtime = parseInt((presenttime - 24 * 60 * 60 * 1000) / 1000)
+					this.getServerData(parseInt(presenttime / 1000), parseInt((presenttime - 24 * 60 * 60 * 1000) / 1000))
+					this.historydata(parseInt(presenttime / 1000), parseInt((presenttime - 24 * 60 * 60 * 1000) / 1000))
+				} else if (index == 1) {
+					this.newtime = parseInt(+new Date(now) / 1000)
+					var oldtime = now.setMonth(now.getMonth() - 1) / 1000
+					this.oldtime = parseInt(oldtime)
+					this.getServerData(parseInt(presenttime / 1000), parseInt(oldtime))
+					this.historydata(parseInt(presenttime / 1000), parseInt(oldtime))
+				} else if (index == 2) {
+					this.newtime = parseInt(+new Date(now) / 1000)
+					var oldtime = now.setMonth(now.getMonth() - 6) / 1000
+					this.oldtime = parseInt(oldtime)
+					this.getServerData(parseInt(presenttime / 1000), parseInt(oldtime))
+					this.historydata(parseInt(presenttime / 1000), parseInt(oldtime))
+				} else if (index == 3) {
+					this.newtime = parseInt(+new Date(now) / 1000)
+					var oldtime = now.setFullYear(now.getFullYear() - 1) / 1000
+					this.oldtime = parseInt(oldtime)
+					this.getServerData(parseInt(presenttime / 1000), parseInt(oldtime))
+					this.historydata(parseInt(presenttime / 1000), parseInt(oldtime))
+				}
+				if (this.newtime < this.oldtime) {
+					this.tishiTF = true
+				} else {
+					this.tishiTF = false
+				}
+			},
+			async historydata(newtime, oldtimes) { //设备表格数据
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.worm_lamp.device_history_data',
+					data: {
+						device_type_id: 2,
+						device_id: this.times.imei,
+						page: this.page,
+						page_size: 10,
+						start_time: oldtimes,
+						end_time: newtime
+					}
+				})
+				console.log(res.data)
+				this.pagesum = Math.ceil(res.counts/10)+1
+				this.eqlistdata = res.data
+				if (res.data.length == 0) {
+					this.forbidden = false
+				} else {
+					this.forbidden = true
+				}
+			},
+			prev() { //上一页
+				if (this.page != 1) {
+					this.page--
+				}
+				this.historydata(this.newtime, this.oldtime)
+			},
+			next() { //下一页
+				this.page++
+				this.historydata(this.newtime, this.oldtime)
+			},
+			pickone(e) {
+				this.oldtime = +new Date(e.year, e.month - 1, e.day, e.hour, e.minute) / 1000
+				if (this.newtime < this.oldtime) {
+					this.tishiTF = true
+				} else {
+					this.tishiTF = false
+				}
+			},
+			picktwo(e) {
+				this.newtime = +new Date(e.year, e.month - 1, e.day, e.hour, e.minute) / 1000
+				if (this.newtime < this.oldtime) {
+					this.tishiTF = true
+				} else {
+					this.tishiTF = false
+				}
+			},
+			serter() {
+				if (this.tishiTF == false) {
+					this.getServerData(parseInt(presenttime / 1000), parseInt(this.oldtime))
+					this.historydata(this.newtime, this.oldtime)
+					uni.showToast({
+						title: '搜索成功',
+						duration: 2000
+					});
+				}
+				
+			},
+			clickLeft() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+			showColumn(id,xtitle,xinfo) {
+				var _self = this
+				canvaColumnA = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position:"top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories:xtitle, 
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			showColumnb(id,xtitle,xinfo) {
+				var _self = this
+				canvaColumnB = new uCharts({
+					canvasId: id,
+					type: 'line',
+					legend: {
+						position:"top"
+					},
+					fontSize: 11,
+					background: '#FFFFFF',
+					pixelRatio: 1,
+					animation: true,
+					dataLabel: false,
+					categories: xtitle, 
+					series: xinfo,
+					enableScroll: true, //开启图表拖拽功能
+					xAxis: {
+						disableGrid: true,
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 4, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						// scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+					},
+					yAxis: {},
+					width: _self.cWidth * 1,
+					height: _self.cHeight * 1,
+					extra: {
+						line: {
+							type: 'curve'
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				console.log(e)
+				canvaColumnA.scrollStart(e);
+			},
+			moveLineA(e) {
+				canvaColumnA.scroll(e);
+			},
+			touchEndLineA(e) {
+				canvaColumnA.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnA.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + Number(item.data).toFixed(3)
+					}
+				});
+			},
+			touchLineBb(e) {
+				console.log(e)
+				canvaColumnB.scrollStart(e);
+			},
+			moveLineBb(e) {
+				canvaColumnB.scroll(e);
+			},
+			touchEndLineBb(e) {
+				canvaColumnB.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				canvaColumnB.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+			async newdata() {
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=forecast.send_control.get_device_config',
+					data: {
+						device_type_id: 2,
+						d_id: this.times.d_id,
+						control_type: "data"
+					}
+				})
+				if(res){
+					uni.showToast({
+						title: '刷新成功',
+						duration: 2000,
+						icon: "none"
+					});
+					uni.navigateBack({
+						delta: 1
+					})
+				}else{
+					uni.showToast({
+						title: '刷新失败',
+						duration: 2000,
+						icon: "none"
+					});
+				}
+			},
+			refresh() { //获取当前时间的数据
+				this.newdata()
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	/*样式的width和height一定要与定义的cWidth和cHeight相对应*/
+	.shuju_one,
+	.shuju_two {
+		position: absolute;
+		top: 54px;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		padding-top: 20rpx;
+		height: 550rpx;
+
+		.canvastishi{
+			font-size: 32rpx;
+			position: absolute;
+			top: 50%;
+			left: 50%;
+			margin-left: -64rpx;
+			margin-top: -21rpx;
+		}
+		.shuju_one_title {
+			width: 70%;
+			margin: 0 auto;
+			display: flex;
+
+			.tltle_text {
+				width: 25%;
+				border: 2rpx solid #B2B2B2;
+				color: #B2B2B2;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+
+			.title_text_color {
+				width: 25%;
+				border: 2rpx solid #28AE4F;
+				color: #28AE4F;
+				text-align: center;
+				font-size: 24rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+			}
+		}
+
+		.qiun-columns {
+			.qiun-charts {
+				width: 650upx;
+				height: 400upx;
+				background-color: #FFFFFF;
+			}
+
+			.charts {
+				width: 650upx;
+				height: 400upx;
+				background-color: #FFFFFF;
+			}
+		}
+	}
+
+	.shuju_two {
+		top: 700rpx;
+	}
+
+	.selecttimes {
+		position: absolute;
+		top: 1290rpx;
+		width: 90%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		left: 5%;
+
+		.tishi {
+			width: 90%;
+			margin: 0 auto;
+			color: #f00000;
+			text-align: center;
+			font-size: 24rpx;
+		}
+
+		.btnser {
+			width: 90%;
+			margin: 10rpx auto;
+			color: #FFFFFF;
+			text-align: center;
+			font-size: 28rpx;
+			background-color: #58BD4D;
+			border-radius: 20rpx;
+			height: 50rpx;
+			line-height: 50rpx;
+		}
+
+		.newtimes {
+			width: 100%;
+			padding: 20rpx 20rpx;
+			box-sizing: border-box;
+
+			.newtimes_state,
+			.newtimes_end {
+				display: flex;
+				justify-content: space-between;
+				margin-bottom: 20rpx;
+
+				.oldtimes_left {
+					position: relative;
+					padding-left: 36rpx;
+					font-size: 28rpx;
+
+					image {
+						width: 30rpx;
+						height: 30rpx;
+						vertical-align: top;
+						position: absolute;
+						top: 7rpx;
+						left: 0;
+					}
+				}
+			}
+		}
+	}
+	.refresh{
+		position: absolute;
+		top: 1530rpx;
+		left: 5%;
+		width: 160rpx;
+		height: 50rpx;
+		background-color: #28AE4F;
+		color: #FFFFFF;
+		line-height: 50rpx;
+		text-align: center;
+	}
+	.condition {
+		position: absolute;
+		top: 1600rpx;
+		display: flex;
+		flex-wrap: wrap;
+		width: 90%;
+		left: 5%;
+		box-shadow: 0 0 10rpx #bcb9ca;
+		margin-bottom: 30rpx;
+
+		.scroll-X {
+			width: 95%;
+			margin: 20rpx auto;
+			.table{
+				width: 1056px;
+			}
+			.tr {
+				display: flex;
+				overflow: hidden;
+
+				.th,
+				.td {
+					display: inline-block;
+					padding: 5rpx;
+					width: 140rpx;
+					text-align: center;
+					height: 52rpx;
+					line-height: 52rpx;
+					border: 2rpx solid #F1F1F1;
+				}
+
+				.th:first-child,
+				.td:first-child {
+					width: 300rpx;
+				}
+
+				.th:nth-last-child(1),
+				.th:nth-last-child(2),
+				.td:nth-last-child(1),
+				.td:nth-last-child(2) {
+					width: 200rpx;
+				}
+			}
+		}
+
+		.pagenumber {
+			display: flex;
+			margin: 20rpx auto;
+
+			button {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+				background-color: #17BB89;
+				color: #FFFFFF;
+			}
+
+			.pagenumber_page {
+				width: 150rpx;
+				height: 50rpx;
+				line-height: 50rpx;
+				font-size: 26rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 64 - 0
pages/webview.vue

@@ -0,0 +1,64 @@
+<template>
+	<view class="webview">
+		<web-view :src="url" id="webcon" @message="handleMessage">
+
+		</web-view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				url: '',
+				device_id: '',
+				accessToken: ''
+			}
+		},
+		onLoad(options) {
+			this.device_id = options.device_id
+			this.accessToken = options.accessToken
+			this.url = "/style/html/h52.html?device_id=" + this.device_id + "&accessToken=" + this.accessToken
+			// uni.setStorage({
+			// 	key: 'obj',
+			// 	data: JSON.stringify({
+			// 		device_id: this.device_id,
+			// 		accessToken: this.accessToken
+			// 	})
+			// })
+			//设置 webview 界面的状态栏的 title
+			uni.setNavigationBarTitle({
+				title: '监控详情'
+			});
+
+			// this.getWebviewPage()
+		},
+		methods: {
+			getWebviewPage(id) {
+				this.url = "/static/h5.html?device_id=" + this.device_id + "&accessToken=" + this.accessToken
+				// uni.setStorage({
+				// 	key: 'obj',
+				// 	data: JSON.stringify({
+				// 		device_id: this.device_id,
+				// 		accessToken: this.accessToken
+				// 	})
+				// })
+				//设置 webview 界面的状态栏的 title
+				uni.setNavigationBarTitle({
+					title: '监控详情'
+				});
+			},
+			handleMessage(evt) {
+				console.log('接收到的消息:' + JSON.stringify(evt.detail.data));
+			}
+
+		}
+	}
+</script>
+
+<style>
+	.webview {
+		width: 100vw;
+		height: 100vh;
+	}
+</style>

+ 75 - 0
project.config.json

@@ -0,0 +1,75 @@
+{
+  "description": "项目配置文件",
+  "packOptions": {
+    "ignore": []
+  },
+  "setting": {
+    "urlCheck": true,
+    "es6": true,
+    "enhance": false,
+    "postcss": true,
+    "preloadBackgroundData": false,
+    "minified": true,
+    "newFeature": false,
+    "coverView": true,
+    "nodeModules": false,
+    "autoAudits": false,
+    "showShadowRootInWxmlPanel": true,
+    "scopeDataCheck": false,
+    "uglifyFileName": false,
+    "checkInvalidKey": true,
+    "checkSiteMap": false,
+    "uploadWithSourceMap": true,
+    "compileHotReLoad": false,
+    "useMultiFrameRuntime": true,
+    "useApiHook": true,
+    "useApiHostProcess": true,
+    "babelSetting": {
+      "ignore": [],
+      "disablePlugins": [],
+      "outputPath": ""
+    },
+    "enableEngineNative": false,
+    "bundle": false,
+    "useIsolateContext": true,
+    "useCompilerModule": true,
+    "userConfirmedUseCompilerModuleSwitch": false,
+    "userConfirmedBundleSwitch": false,
+    "packNpmManually": false,
+    "packNpmRelationList": [],
+    "minifyWXSS": true
+  },
+  "compileType": "miniprogram",
+  "libVersion": "2.16.1",
+  "appid": "wx1cabf67f460e3a14",
+  "projectname": "miniprogram-1",
+  "debugOptions": {
+    "hidedInDevtools": []
+  },
+  "scripts": {},
+  "staticServerOptions": {
+    "baseURL": "",
+    "servePath": ""
+  },
+  "isGameTourist": false,
+  "condition": {
+    "search": {
+      "list": []
+    },
+    "conversation": {
+      "list": []
+    },
+    "game": {
+      "list": []
+    },
+    "plugin": {
+      "list": []
+    },
+    "gamePlugin": {
+      "list": []
+    },
+    "miniprogram": {
+      "list": []
+    }
+  }
+}

+ 336 - 0
static/data/cbd_pest_library.js

@@ -0,0 +1,336 @@
+// 害虫库
+var insect_dict = {'1':'金龟子',
+'2':'夜蛾',
+'3':'二点委夜蛾',
+'4':'梨剑纹夜蛾',
+'5':'杨扇舟蛾',
+'6':'舟蛾',
+'7':'旋幽夜蛾',
+'8':'蝼蛄',
+'9':'步甲',
+'10':'螟蛾',
+'11':'毛黄鳃金龟',
+'12':'尺蛾',
+'13':'剑纹夜蛾',
+'14':'粉缘钻夜蛾',
+'15':'夜蛾科',
+'16':'七星瓢虫',
+'17':'棉铃虫',
+'18':'蜻蜓',
+'19':'蚊',
+'20':'东方粘虫',
+'21':'叶蝉',
+'22':'春尺蠖',
+'23':'雄性春尺蠖',
+'24':'杨小舟蛾',
+'25':'甘蓝夜蛾',
+'26':'小地老虎',
+'27':'两点尼夜蛾',
+'28':'柳阴翅斑螟',
+'29':'桑褶翅尺蛾',
+'30':'宽胫夜蛾',
+'31':'尺蠖',
+'32':'一点钻夜蛾',
+'33':'天蛾',
+'34':'裳夜蛾',
+'35':'灯蛾',
+'36':'美国白蛾',
+'37':'八字白眉天蛾',
+'38':'陌夜蛾',
+'39':'豆天蛾',
+'40':'麦蛾',
+'41':'围连环夜蛾',
+'42':'亚美尺蛾',
+'43':'梨星毛虫',
+'44':'银锭夜蛾',
+'45':'黄臀灯蛾',
+'46':'大螟',
+'47':'燕尾舟蛾',
+'48':'榆津尺蛾',
+'49':'朽木夜蛾',
+'50':'黄地老虎',
+'51':'白钩粘夜蛾',
+'52':'桃蛀螟',
+'53':'甜菜夜蛾',
+'54':'斜纹夜蛾',
+'55':'蚀夜蛾',
+'56':'淡银锭夜蛾',
+'57':'齿美冬夜蛾',
+'58':'一点金刚钻',
+'59':'胡桃豹夜蛾',
+'60':'桑剑纹夜蛾',
+'61':'蓝目天蛾',
+'62':'黑绒绢金龟',
+'63':'烟青虫',
+'64':'暗黑鳃金龟',
+'65':'中华绒金龟',
+'66':'八字地老虎',
+'67':'榆绿天蛾',
+'68':'红星雪灯蛾',
+'69':'雀纹天蛾',
+'70':'铜绿丽金龟',
+'71':'水龟虫',
+'72':'曲线尼夜蛾',
+'73':'粘虫',
+'74':'瘦银锭夜蛾',
+'75':'红天蛾',
+'76':'鳃金龟',
+'77':'大黑鳃金龟',
+'78':'大地老虎',
+'79':'玉米螟',
+'80':'赤角盲蝽',
+'81':'槐尺蛾',
+'82':'银纹夜蛾',
+'83':'天牛',
+'84':'乏夜蛾',
+'85':'丁香天蛾',
+'86':'构月天蛾',
+'87':'虎甲',
+'88':'劳氏粘虫',
+'89':'白薯天蛾',
+'90':'广鹿蛾',
+'91':'二十八星瓢虫',
+'92':'腮金龟',
+'93':'人纹污夜蛾',
+'94':'叩甲',
+'95':'楸蠹野螟',
+'96':'丝绵木金星尺蛾',
+'97':'红缘灯蛾',
+'98':'黄褐丽金龟',
+'99':'螟蛾科',
+'100':'红棕灰夜蛾',
+'101':'黑绒绢金龟',
+'102':'广鹿灯蛾',
+'103':'蝽',
+'104':'蜂',
+'105':'大造桥虫',
+'106':'童剑纹夜蛾',
+'107':'晃剑纹夜蛾',
+'108':'钩粘虫',
+'109':'直影夜蛾',
+'110':'毛黄绢金龟',
+'111':'乌氏小尾天蚕蛾',
+'112':'褐边绿刺蛾',
+'113':'广鹿舟蛾',
+'114':'颜倾城',
+'115':'龙虱',
+'116':'双带盘瓢虫',
+'117':'槲犹冬夜蛾',
+'118':'洋槐天蛾',
+'119':'弧角散纹夜蛾',
+'120':'黄脉天蛾',
+'121':'葡萄天蛾',
+'122':'桃六点天蛾',
+'123':'异色瓢虫',
+'124':'榆黄足毒蛾',
+'125':'客来夜蛾',
+'126':'桦尺蛾',
+'127':'草地螟',
+'128':'细条纹野螟',
+'129':'污灯蛾属',
+'130':'杨二尾舟蛾',
+'131':'克什杆野螟',
+'132':'筱客来夜蛾',
+'133':'栗六点天蛾',
+'134':'紫光盾天蛾',
+'135':'款冬玉米螟',
+'136':'草蛉',
+'137':'亚麻篱灯蛾',
+'138':'扁连环夜蛾',
+'139':'圣蜣螂',
+'140':'白钩粘虫',
+'141':'苇实夜蛾',
+'142':'姬蜂',
+'143':'秘夜蛾',
+'144':'织网夜蛾',
+'145':'深色白眉天蛾',
+'146':'短扇舟蛾',
+'147':'白须天蛾',
+'148':'歌梦尼夜蛾',
+'149':'海安夜蛾',
+'150':'满丫纹夜蛾',
+'151':'蟋蟀',
+'152':'双斑青步甲',
+'153':'白条夜蛾',
+'154':'蟪蛄',
+'155':'负子蝽',
+'156':'脊青步甲',
+'157':'宽斑青步甲',
+'158':'稻从卷叶螟',
+'159':'淡剑夜蛾',
+'160':'甜菜白带野螟',
+'161': '樗蚕', 
+'162': '蒙古寒蝉',
+'163': '中带三角夜蛾', 
+'164': '蝗虫', 
+'165': '多色异丽金龟', 
+'166': '白色小卷蛾', 
+'167': '狭边青步甲',
+'168': '棉卷叶野螟', 
+'169': '豆荚野螟', 
+'170': '麻小食心虫', 
+'171': '星斑虎甲', 
+'172': '黄缘龙虱',
+'173': '无斑弧丽金龟', 
+'174': '白额鹰翅天蛾',
+'175': '日本真龙虱', 
+'176': '山东云斑螟',
+'177': '小文夜蛾', 
+'178': '三条蛀野螟', 
+'179': '榆掌舟蛾', 
+'180': '刺槐掌舟蛾', 
+'181': '星绒天蛾', 
+'182': '杨剑舟蛾', 
+'183': '刀夜蛾',
+'184': '红节天蛾', 
+'185': '星白雪灯蛾', 
+'186': '桃剑纹夜蛾', 
+'187': '谐夜蛾', 
+'188': '小剑纹夜蛾', 
+'189': '鸣鸣蝉', 
+'190': '姬夜蛾',
+'191': '落叶松毛虫', 
+'192': '苹六点天蛾', 
+'193': '四斑绢野螟', 
+'194': '甘薯天蛾', 
+'195': '小线角木蠹蛾', 
+'196': '三斑蕊夜蛾', 
+'197': '白雪灯蛾', 
+'198': '黄刺蛾', 
+'199': '茶翅蝽',
+'200': '杨树枯叶蛾',
+"201": "标瑙夜蛾",
+"202": "瓜绢野螟",
+"203": "稻绿蝽",
+"204": "杨雪毒蛾",
+"205": "榆白边舟蛾",
+"206": "扁刺蛾",
+"207": "绒黏夜蛾",
+"208": "庸肖毛翅夜蛾",
+"209": "中华婪步甲",
+"210": "褐黄前锹甲",
+"211": "旱柳原野螟",
+"212": "巨影夜蛾",
+"213": "食蚜蝇",
+"214": "双斑葬甲",
+"215": "黄毒蛾",
+"216": "婪步甲",
+"217": "土甲",
+"218": "中华真地鳖",
+"219": "紫线夜蛾",
+"220": "小黄鳃金龟",
+"221": "中华真土鳖",
+"222": "云斑虎甲",
+"223": "中华黧尺蛾",
+"224": "中华绿刺蛾",
+"225": "巨豹纹尺蛾",
+"226": "多斑豹蠹蛾",
+"227": "桑尺蛾",
+"228": "灰直纹螟",
+"229": "中国绿刺蛾",
+"230": "云杉梢斑螟",
+"231": "桑绢野螟",
+"232": "黄杨绢野螟",
+"233": "突背斑红蝽",
+"234": "高粱条螟",
+"235": "小麦负泥虫",
+"236": "苹掌舟蛾",
+"237": "绒粘夜蛾",
+"238": "灰白灯蛾",
+"239": "隐丫纹夜蛾",
+"240": "满纹夜蛾",
+"241": "黑剑狼夜蛾",
+"242": "蜣螂",
+"243": "福婆鳃金龟",
+"244": "雨尺蛾",
+"245": "优美苔蛾",
+"246": "黄斑野螟",
+"247": "疆夜蛾",
+"248": "六点天蛾",
+"249": "斜线夜蛾",
+"250": "石榴巾夜蛾",
+"251": "绒星天蛾",
+"252": "霜天蛾",
+"253": "大田鳖",
+"254": "灰双纹螟",
+"255": "青尺蛾",
+"256": "二线绿尺蛾",
+"257": "散纹夜蛾",
+"258": "红双线尺蛾",
+"259": "胞短栉夜蛾",
+"260": "飞虱科",
+"261": "桃多斑野螟",
+"262": "甜菜青野螟",
+"263": "核桃鹰翅天蛾",
+"264": "角顶尺蛾",
+"265": "葡萄缺角天蛾",
+"266": "绿尾大蚕蛾",
+"267": "杨褐枯叶蝶",
+"268": "双云尺蛾",
+"269": "斑拟兜夜蛾",
+"270": "阿莎尺蛾",
+"271": "榄绿岐角螟",
+"272": "青革土蝽",
+"273": "核桃美舟蛾",
+"274": "斑点卷叶螟",
+"275": "黄褐箩纹蛾",
+"276": "白环红天蛾",
+"277": "白腹网丛螟",
+"278": "枯叶蛾",
+"279": "丹日明夜蛾",
+"280": "仿白边舟蛾",
+"281": "槐羽舟蛾",
+"282": "草地贪夜蛾",
+"283": "环夜蛾",
+"284": "尘尺蛾",
+"285": "黄二星舟蛾",
+"286": "榆木蠹蛾",
+"287": "水黾",
+"288": "银装冬夜蛾",
+"289": "饰奇尺蛾",
+"290": "枯叶蝶",
+"291": "步甲",
+"292": "阔胸禾犀金龟",
+"293": "眼斑钩蛾",
+"294": "三开蜣螂",
+"295": "金星步甲",
+"296": "残夜蛾",
+"297": "野蚕蛾",
+"298": "芦苇豹蠹蛾",
+"299": "华晓扁犀金龟",
+"300": "灰胸突鳃金龟",
+"301": "龟纹瓢虫",
+"302": "麻皮蝽",
+"303": "斑须蝽",
+"304": "斜斑虎甲",
+"305": "地鳖",
+"306": "叶甲",
+"307": "燕夜蛾",
+"308": "黑纹北灯蛾",
+"309": "网夜蛾",
+"310": "棘翅夜蛾",
+"311": "规尺蛾",
+"312": "苜蓿银纹夜蛾",
+"313": "拟扇舟蛾",
+"314": "丁目大蚕蛾",
+"315": "金黄蛾",
+"316": "黄星雪灯蛾",
+"317": "暗纹紫褐螟",
+"318": "白眉天蛾",
+"319": "黄板盘瓢虫",
+"320": "玫岐角螟",
+"321":"枯黄贡尺蛾",
+"322":"小豆长喙天蛾",
+"323":"橙拟灯蛾",
+"324":"粉蝶灯蛾",
+"325":"纹散丽灯蛾",
+"326":"雪尾尺蛾",
+"327":"鹰翅天蛾",
+"328":"波纹蛾",
+"329":"黑条灰灯蛾",
+"330":"八点灰灯蛾",
+"331":"间纹弦夜蛾",
+"332":"缤夜蛾",
+}
+
+export default insect_dict

BIN
static/images/12.png


BIN
static/images/13.png


BIN
static/images/14.png


BIN
static/images/15.png


BIN
static/images/16.png


BIN
static/images/17.png


BIN
static/images/18.png


BIN
static/images/19.png


BIN
static/images/distribution/0b551e50be351dbc14f0dd6470e3443.png


BIN
static/images/distribution/1bd535eb7dbb0809940030d40c64b4c.png


+ 0 - 0
static/images/distribution/2eb9e550709430a1bd8178568c14785.png


Некоторые файлы не были показаны из-за большого количества измененных файлов