吴洪双 6 yıl önce
ebeveyn
işleme
b37125af83

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1447 - 0
common/uni.css


+ 146 - 0
common/util.js

@@ -0,0 +1,146 @@
+function formatTime(time) {
+	if (typeof time !== 'number' || time < 0) {
+		return time
+	}
+
+	var hour = parseInt(time / 3600)
+	time = time % 3600
+	var minute = parseInt(time / 60)
+	time = time % 60
+	var second = time
+
+	return ([hour, minute, second]).map(function(n) {
+		n = n.toString()
+		return n[1] ? n : '0' + n
+	}).join(':')
+}
+
+function formatLocation(longitude, latitude) {
+	if (typeof longitude === 'string' && typeof latitude === 'string') {
+		longitude = parseFloat(longitude)
+		latitude = parseFloat(latitude)
+	}
+
+	longitude = longitude.toFixed(2)
+	latitude = latitude.toFixed(2)
+
+	return {
+		longitude: longitude.toString().split('.'),
+		latitude: latitude.toString().split('.')
+	}
+}
+var dateUtils = {
+	UNITS: {
+		'年': 31557600000,
+		'月': 2629800000,
+		'天': 86400000,
+		'小时': 3600000,
+		'分钟': 60000,
+		'秒': 1000
+	},
+	humanize: function(milliseconds) {
+		var humanize = '';
+		for (var key in this.UNITS) {
+			if (milliseconds >= this.UNITS[key]) {
+				humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
+				break;
+			}
+		}
+		return humanize || '刚刚';
+	},
+	format: function(dateStr) {
+		var date = this.parse(dateStr)
+		var diff = Date.now() - date.getTime();
+		if (diff < this.UNITS['天']) {
+			return this.humanize(diff);
+		}
+		var _format = function(number) {
+			return (number < 10 ? ('0' + number) : number);
+		};
+		return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDay()) + '-' +
+			_format(date.getHours()) + ':' + _format(date.getMinutes());
+	},
+	parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
+		var a = str.split(/[^0-9]/);
+		return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
+	},
+	formateDate: function(newdate, format) {
+		const date = {
+			'M+': newdate.getMonth() + 1,
+			'd+': newdate.getDate(),
+			'h+': newdate.getHours(),
+			'm+': newdate.getMinutes(),
+			's+': newdate.getSeconds(),
+			'q+': Math.floor((newdate.getMonth() + 3) / 3),
+			'S+': newdate.getMilliseconds()
+		};
+		if (/(y+)/i.test(format)) {
+			format = format.replace(RegExp.$1, (newdate.getFullYear() + '').substr(4 - RegExp.$1.length));
+		}
+		for (const k in date) {
+			if (new RegExp('(' + k + ')').test(format)) {
+				format = format.replace(RegExp.$1, RegExp.$1.length === 1 ?
+					date[k] : ('00' + date[k]).substr(('' + date[k]).length));
+			}
+		}
+		return format;
+	},
+	getFirstDayOfWeek: function(date) {
+		var day = date.getDay() || 7;
+		var result = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1 - day);
+		return result;
+	},
+	getLastDayOfWeek: function(date) {
+		var day = date.getDay() || 7;
+		var result = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7 - day);
+		return result;
+	},
+	/**获取当年第一天 */
+	getCurrentYearFirstDate: function(now) {
+		const nowyear = now.getFullYear() + ''; // 获取年(yyyy)
+		// 调用格式化方法
+		const firstDate = new Date(nowyear + '/01' + '/01');
+		return firstDate;
+	},
+	/**获取当年最后一天 */
+	getCurrentYearLastDate: function(now) {
+		const year = now.getFullYear() + 1; // 获取年(yyyy)
+		// 调用格式化方法
+		const nextyear = new Date(year + '/01' + '/01');
+		nextyear.setDate(nextyear.getDate() - 1);
+		return nextyear;
+	},
+	/**获取当月月第一天 */
+	getCurrentMonFirstDate: function(now) {
+		const nowyear = now.getFullYear() + ''; // 获取年(yyyy)
+		let nowmonth = now.getMonth() + 1 + ''; // 获取月份(0-11,0代表1月)
+		// 调用格式化方法
+		nowmonth = this.dateformat(nowmonth);
+		const firstDate = new Date(nowyear + '/' + nowmonth + '/01');
+		return firstDate;
+	},
+	/**获取当月月最后一天 */
+	getCurrentMonLastDate: function(now) {
+		const nextMonFirstDate = this.getNextMonFirstDate(now);
+		nextMonFirstDate.setDate(nextMonFirstDate.getDate() - 1);
+		return nextMonFirstDate;
+	},
+	/**获取下个月第一天 */
+	getNextMonFirstDate: function(now) {
+		const currentMonFirstDate = this.getCurrentMonFirstDate(now);
+		currentMonFirstDate.setMonth(currentMonFirstDate.getMonth() + 1);
+		return currentMonFirstDate;
+	},
+	dateformat: function(fmt) {
+		if (fmt.length === 1) {
+			fmt = '0' + fmt;
+		}
+		return fmt;
+	}
+};
+
+module.exports = {
+	formatTime: formatTime,
+	formatLocation: formatLocation,
+	dateUtils: dateUtils
+}

+ 270 - 0
components/Charts/MyChartsColumn.vue

@@ -0,0 +1,270 @@
+<template>
+	<view class="qiun-columns">
+		<view class="qiun-bg-white qiun-title-bar qiun-common-mt">
+			<view class="qiun-title-dot-light">{{chartTitle}}</view>
+			<view style="text-align: center;position: relative;">
+				<image @click="pre()" style="position: absolute;left: 40upx; width: 40upx;height: 40upx;" src="/static/img/leftTriangle.png"></image>
+				<span v-if="this.chartType==='day'">{{startDate}}</span>
+				<span v-if="this.chartType!=='day'">{{startDate}} 至 {{endDate}}</span>
+				<image @click="next()" style="position: absolute;right: 40upx; width: 40upx;height: 40upx;" src="/static/img/rightTriangle.png"></image>
+			</view>
+		</view>
+		<view class="qiun-charts" style="background-color: #E5FDC3;">
+			<canvas :canvas-id="canvasId" :id="canvasId" class="charts" disable-scroll=true @touchstart="touchLineA" @touchmove="moveLineA"
+			 @touchend="touchEndLineA" style="background-color: #E5FDC3;"></canvas>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		mapState,
+		mapActions,
+		mapMutations
+	} from 'vuex';
+	import {
+		dateUtils
+	} from '@/common/util.js';
+	import uCharts from '@/components/u-charts/u-charts.js';
+	var _self;
+	var canvaColumn = null;
+	export default {
+		name: 'MyChartsColumn',
+		props: {
+			canvasId: String,
+			chartTitle: String,
+			chartType: String,
+			equipmentId: '',
+			adminId: '',
+		},
+		data() {
+			return {
+				cWidth: '',
+				cHeight: '',
+				pixelRatio: 1,
+				serverData: '',
+				canvaColumn: Object,
+				startDate: String,
+				endDate: String,
+			}
+		},
+		computed: {
+			...mapState(['loginUser']),
+		},
+		mounted() {
+			_self = this;
+			this.$data.type = this.chartType;
+			this.cWidth = uni.upx2px(750);
+			this.cHeight = uni.upx2px(500);
+			this.init();
+		},
+		methods: {
+			...mapActions('chart', ['getStatistics','getMainStatistics']),
+			init() {
+				this.initDateRang(new Date());
+				this.getStatisticsData();
+			},
+			initDateRang(day) {
+				const daystr = dateUtils.formateDate(day, 'yyyy/MM/dd');
+				let startDate = daystr;
+				let endDate = daystr;
+				if (this.chartType === 'week') {
+					startDate = dateUtils.formateDate(dateUtils.getFirstDayOfWeek(day), 'yyyy/MM/dd');
+					endDate = dateUtils.formateDate(dateUtils.getLastDayOfWeek(day), 'yyyy/MM/dd');
+				}
+				if (this.chartType === 'month') {
+					startDate = dateUtils.formateDate(dateUtils.getCurrentMonFirstDate(day), 'yyyy/MM/dd');
+					endDate = dateUtils.formateDate(dateUtils.getCurrentMonLastDate(day), 'yyyy/MM/dd');
+				}
+				if (this.chartType === 'year') {
+					startDate = dateUtils.formateDate(dateUtils.getCurrentYearFirstDate(day), 'yyyy/MM/dd');
+					endDate = dateUtils.formateDate(dateUtils.getCurrentYearLastDate(day), 'yyyy/MM/dd');
+				}
+				this.$data.startDate = startDate;
+				this.$data.endDate = endDate;
+			},
+			/**上一个 */
+			pre() {
+				const day = new Date(this.$data.startDate);
+				if (this.chartType === 'day') { // 日
+					day.setDate(day.getDate() - 1);
+				}
+				if(this.chartType === 'week'){ // 周
+					day.setDate(day.getDate() - 7);
+				}
+				if (this.chartType === 'month') { // 月
+					day.setMonth(day.getMonth() - 1);
+				}
+				if (this.chartType === 'year') { // 年
+					day.setFullYear(day.getFullYear() - 1);
+				}
+				this.initDateRang(day);
+				this.getStatisticsData();
+			},
+			/**下一个 */
+			next() {
+				const day = new Date(this.$data.startDate);
+				if (this.chartType === 'day') { // 日
+					day.setDate(day.getDate() + 1);
+				}
+				if(this.chartType === 'week'){ // 周
+					day.setDate(day.getDate() + 7);
+				}
+				if (this.chartType === 'month') { // 月
+					day.setMonth(day.getMonth() + 1);
+				}
+				if (this.chartType === 'year') { // 年
+					day.setFullYear(day.getFullYear() + 1);
+				}
+				this.initDateRang(day);
+				this.getStatisticsData();
+			},
+			getStatisticsData() {
+				const param = {
+					'startDate': this.$data.startDate,
+					'endDate': this.$data.endDate,
+					'chartType': this.chartType
+				};
+				// console.log('chartType:' + param.chartType)
+				if(this.adminId){ // 子组件,则拿传过来的参
+					param['adminId'] = this.adminId;
+				}else if ('admin' !== this.loginUser['username']) { //否则为主页,拿登录用户
+					param['adminId'] = this.loginUser['id'];
+				}
+				if (this.equipmentId) {
+					param['equipmentId'] = this.equipmentId;
+				}
+				setTimeout(() => {
+					this.getStatistics(param)
+						.then(data => [uni.stopPullDownRefresh(), this.showColumn(this.canvasId, data)]
+						, _ => void [uni.stopPullDownRefresh(),this.showColumn(this.canvasId, {categories:[],series:[]})]);
+				}, 0);
+			},
+			showColumn(canvasId, chartData) {
+				this.canvaColumn = new uCharts({
+					$this: _self,
+					canvasId: canvasId,
+					enableScroll: true,
+					type: 'column',
+					legend: true,
+					fontSize: 11,
+					background: '#E5FDC3',
+					pixelRatio: _self.pixelRatio,
+					animation: true,
+					categories: chartData.categories,
+					series: chartData.series,
+					xAxis: {
+						type: 'grid',
+						gridType: 'dash',
+						itemCount: 5, //x轴单屏显示数据的数量,默认为5个
+						scrollShow: true, //新增是否显示滚动条,默认false
+						scrollAlign: 'left', //滚动条初始位置
+						scrollBackgroundColor: '#F7F7FF', //默认为 #EFEBEF
+						scrollColor: '#DEE7F7', //默认为 #A6A6A6
+						// disableGrid:true,
+					},
+					yAxis: {
+						//disabled:true
+					},
+					dataLabel: true,
+					width: _self.cWidth * _self.pixelRatio,
+					height: _self.cHeight * _self.pixelRatio,
+					extra: {
+						column: {
+							// width: _self.cWidth*_self.pixelRatio*0.45/chartData.categories.length
+							width: 30
+						}
+					}
+				});
+			},
+			touchColumn(e) {
+				this.canvaColumn.showToolTip(e, {
+					format: function(item, category) {
+						if (typeof item.data === 'object') {
+							return category + ' ' + item.name + ':' + item.data.value
+						} else {
+							return category + ' ' + item.name + ':' + item.data
+						}
+					}
+				});
+			},
+			touchLineA(e) {
+				this.canvaColumn.scrollStart(e);
+			},
+			moveLineA(e) {
+				this.canvaColumn.scroll(e);
+			},
+			touchEndLineA(e) {
+				this.canvaColumn.scrollEnd(e);
+				//下面是toolTip事件,如果滚动后不需要显示,可不填写
+				this.canvaColumn.showToolTip(e, {
+					format: function(item, category) {
+						return category + ' ' + item.name + ':' + item.data
+					}
+				});
+			},
+
+		}
+	}
+</script>
+
+<style>
+	page {
+		background: #F2F2F2;
+		width: 750upx;
+		overflow-x: hidden;
+	}
+
+	.qiun-padding {
+		padding: 2%;
+		width: 96%;
+	}
+
+	.qiun-wrap {
+		display: flex;
+		flex-wrap: wrap;
+	}
+
+	.qiun-rows {
+		display: flex;
+		flex-direction: row !important;
+	}
+
+	.qiun-columns {
+		display: flex;
+		flex-direction: column !important;
+	}
+
+	.qiun-common-mt {
+		margin-top: 10upx;
+	}
+
+	.qiun-bg-white {
+		background: #FFFFFF;
+	}
+
+	.qiun-title-bar {
+		width: 96%;
+		padding: 10upx 2%;
+		flex-wrap: nowrap;
+	}
+
+	.qiun-title-dot-light {
+		border-left: 10upx solid #0ea391;
+		padding-left: 10upx;
+		font-size: 32upx;
+		color: #000000
+	}
+
+	.qiun-charts {
+		width: 750upx;
+		height: 500upx;
+		background-color: #FFFFFF;
+	}
+
+	.charts {
+		width: 750upx;
+		height: 500upx;
+		background-color: #FFFFFF;
+	}
+</style>

+ 99 - 0
components/uni-badge/uni-badge.vue

@@ -0,0 +1,99 @@
+<template>
+	<text v-if="text" :class="inverted ? 'uni-badge-' + type + ' uni-badge--' + size + ' uni-badge-inverted' : 'uni-badge-' + type + ' uni-badge--' + size" class="uni-badge" @click="onClick()">{{ text }}</text>
+</template>
+
+<script>
+	export default {
+		name: 'UniBadge',
+		props: {
+			type: {
+				type: String,
+				default: 'default'
+			},
+			inverted: {
+				type: Boolean,
+				default: false
+			},
+			text: {
+				type: [String, Number],
+				default: ''
+			},
+			size: { // small.normal
+				type: String,
+				default: 'normal'
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-badge {
+		font-family: 'Helvetica Neue', Helvetica, sans-serif;
+		box-sizing: border-box;
+		font-size: 12px;
+		line-height: 1;
+		display: inline-block;
+		padding: 3px 6px;
+		color: #333;
+		border-radius: 100px;
+		background-color: #f1f1f1
+	}
+
+	.uni-badge.uni-badge-inverted {
+		padding: 0 5px 0 0;
+		color: #999;
+		background-color: transparent
+	}
+
+	.uni-badge-primary {
+		color: #fff;
+		background-color: #007aff
+	}
+
+	.uni-badge-primary.uni-badge-inverted {
+		color: #007aff;
+		background-color: transparent
+	}
+
+	.uni-badge-success {
+		color: #fff;
+		background-color: #4cd964
+	}
+
+	.uni-badge-success.uni-badge-inverted {
+		color: #4cd964;
+		background-color: transparent
+	}
+
+	.uni-badge-warning {
+		color: #fff;
+		background-color: #f0ad4e
+	}
+
+	.uni-badge-warning.uni-badge-inverted {
+		color: #f0ad4e;
+		background-color: transparent
+	}
+
+	.uni-badge-error {
+		color: #fff;
+		background-color: #dd524d
+	}
+
+	.uni-badge-error.uni-badge-inverted {
+		color: #dd524d;
+		background-color: transparent
+	}
+
+	.uni-badge--small {
+		transform: scale(.8);
+		transform-origin: center center
+	}
+</style>

+ 224 - 0
components/uni-collapse-item/uni-collapse-item.vue

@@ -0,0 +1,224 @@
+<template>
+	<view :class="['uni-collapse-cell',{'uni-collapse-cell--disabled':disabled,'uni-collapse-cell--open':isOpen}]" :hover-class="disabled ? '' : 'uni-collapse-cell--hover'">
+		<view class="uni-collapse-cell__title" @click="onClick">
+			<view v-if="thumb" class="uni-collapse-cell__title-extra">
+				<image :src="thumb" class="uni-collapse-cell__title-img" />
+			</view>
+			<view class="uni-collapse-cell__title-inner">
+				<view class="uni-collapse-cell__title-text">{{ title }}</view>
+			</view>
+			<view :class="{'uni-active':isOpen,'uni-collapse-cell--animation':showAnimation===true}" class="uni-collapse-cell__title-arrow">
+				<uni-icon color="#bbb" size="20" type="arrowdown" />
+			</view>
+		</view>
+		<view :class="{'uni-collapse-cell--animation':showAnimation===true}" :style="{height:isOpen ? height : '0px'}" class="uni-collapse-cell__content">
+			<view class="view" :id="elId">
+				<slot />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniIcon from '../uni-icon/uni-icon.vue'
+	export default {
+		name: 'UniCollapseItem',
+		components: {
+			uniIcon
+		},
+		props: {
+			title: { // 列表标题
+				// type: String,
+				default: ''
+			},
+			name: { // 唯一标识符
+				type: [Number, String],
+				default: 0
+			},
+			disabled: { // 是否禁用
+				type: Boolean,
+				default: false
+			},
+			showAnimation: { // 是否显示动画
+				type: Boolean,
+				default: false
+			},
+			open: { // 是否展开
+				type: Boolean,
+				default: false
+			},
+			thumb: { // 缩略图
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			/**
+			 * TODO 兼容新旧编译器
+			 * 新编译器(自定义组件模式)下必须使用固定数值,否则部分平台下会获取不到节点。
+			 * 随机数值是在旧编译器下使用的,旧编译器模式已经不推荐使用,后续直接废掉随机数值的写法。
+			 */
+			const elId = this.__call_hook ? 'uni_collapse_item' : `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
+			return {
+				isOpen: false,
+				height: 'auto',
+				elId: elId
+			}
+		},
+		watch: {
+			open(val) {
+				this.isOpen = val
+			}
+		},
+		inject: ['collapse'],
+		created() {
+			this.isOpen = this.open
+			this.nameSync = this.name ? this.name : this.collapse.childrens.length
+			this.collapse.childrens.push(this)
+			if (this.collapse.accordion) {
+				if (this.isOpen) {
+					let lastEl = this.collapse.childrens[this.collapse.childrens.length - 2]
+					if (lastEl) {
+						this.collapse.childrens[this.collapse.childrens.length - 2].isOpen = false
+					}
+				}
+			}
+		},
+		// #ifdef H5
+		mounted() {
+			this.getSize()
+		},
+		// #endif
+		// #ifndef H5
+		onReady() {
+			this.getSize()
+		},
+		// #endif
+		methods: {
+			getSize() {
+				if (this.showAnimation) {
+					uni.createSelectorQuery().in(this).select(`#${this.elId}`).boundingClientRect().exec((ret) => {
+						this.height = ret[0].height + 'px'
+					})
+				}
+			},
+			onClick() {
+				if (this.disabled) {
+					return
+				}
+				if (this.collapse.accordion) {
+					this.collapse.childrens.forEach(vm => {
+						if (vm === this) {
+							return
+						}
+						vm.isOpen = false
+					})
+				}
+				this.isOpen = !this.isOpen
+				this.collapse.onChange && this.collapse.onChange()
+			}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-collapse-cell {
+		position: relative
+	}
+
+	.uni-collapse-cell--hover {
+		background-color: #f1f1f1
+	}
+
+	.uni-collapse-cell--open {
+		background-color: #f1f1f1
+	}
+
+	.uni-collapse-cell--disabled {
+		opacity: .3
+	}
+
+	.uni-collapse-cell--animation {
+		transition: all .3s
+	}
+
+	.uni-collapse-cell:after {
+		position: absolute;
+		z-index: 3;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc
+	}
+
+	.uni-collapse-cell__title {
+		padding: 24upx 30upx;
+		width: 100%;
+		box-sizing: border-box;
+		flex: 1;
+		position: relative;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center
+	}
+
+	.uni-collapse-cell__title-extra {
+		margin-right: 18upx;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center
+	}
+
+	.uni-collapse-cell__title-img {
+		height: 52upx;
+		width: 52upx
+	}
+
+	.uni-collapse-cell__title-arrow {
+		width: 20px;
+		height: 20px;
+		display: flex;
+		align-items: center;
+		transform: rotate(0);
+		transform-origin: center center
+	}
+
+	.uni-collapse-cell__title-arrow.uni-active {
+		transform: rotate(-180deg)
+	}
+
+	.uni-collapse-cell__title-inner {
+		flex: 1;
+		overflow: hidden;
+		display: flex;
+		flex-direction: column
+	}
+
+	.uni-collapse-cell__title-text {
+		font-size: 32upx;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		color: inherit;
+		line-height: 1.5;
+		overflow: hidden
+	}
+
+	.uni-collapse-cell__content {
+		position: relative;
+		width: 100%;
+		overflow: hidden;
+		background: #fff
+	}
+
+	.uni-collapse-cell__content .view {
+		font-size: 28upx
+	}
+</style>

+ 75 - 0
components/uni-collapse/uni-collapse.vue

@@ -0,0 +1,75 @@
+<template>
+	<view class="uni-collapse">
+		<slot />
+	</view>
+</template>
+<script>
+	export default {
+		name: 'UniCollapse',
+		props: {
+			accordion: { // 是否开启手风琴效果
+				type: Boolean,
+				default: false
+			}
+		},
+		data() {
+			return {}
+		},
+		provide() {
+			return {
+				collapse: this
+			}
+		},
+		created() {
+			this.childrens = []
+		},
+		methods: {
+			onChange() {
+				let activeItem = []
+				this.childrens.forEach((vm, index) => {
+					if (vm.isOpen) {
+						activeItem.push(vm.nameSync)
+					}
+				})
+				this.$emit('change', activeItem)
+			}
+		}
+	}
+</script>
+<style>
+	@charset "UTF-8";
+
+	.uni-collapse {
+		background-color: #fff;
+		position: relative;
+		width: 100%;
+		display: flex;
+		flex-direction: column
+	}
+
+	.uni-collapse:after {
+		position: absolute;
+		z-index: 10;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc
+	}
+
+	.uni-collapse:before {
+		position: absolute;
+		z-index: 10;
+		right: 0;
+		top: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc
+	}
+</style>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 419 - 0
components/uni-icon/uni-icon.vue


+ 199 - 0
components/uni-list-item/uni-list-item.vue

@@ -0,0 +1,199 @@
+<template>
+	<view :class="disabled ? 'uni-list-item--disabled' : ''" :hover-class="disabled || showSwitch ? '' : 'uni-list-item--hover'" class="uni-list-item" @click="onClick">
+		<view class="uni-list-item__container">
+			<view v-if="thumb" class="uni-list-item__icon">
+				<image :src="thumb" class="uni-list-item__icon-img" />
+			</view>
+			<view v-else-if="showExtraIcon" class="uni-list-item__icon">
+				<uni-icon class="uni-icon-wrapper" :color="extraIcon.color" :size="extraIcon.size" :type="extraIcon.type" />
+			</view>
+			<view class="uni-list-item__content">
+				<view class="uni-list-item__content-title">{{ title }}</view>
+				<view v-if="note" class="uni-list-item__content-note">{{ note }}</view>
+			</view>
+			<view v-if="showBadge || showArrow || showSwitch" class="uni-list-item__extra">
+				<uni-badge v-if="showBadge" :type="badgeType" :text="badgeText" />
+				<switch v-if="showSwitch" :disabled="disabled" :checked="switchChecked" @change="onSwitchChange" />
+				<uni-icon class="uni-icon-wrapper" v-if="showArrow" :size="20" color="#bbb" type="arrowright" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uniIcon from '../uni-icon/uni-icon.vue'
+	import uniBadge from '../uni-badge/uni-badge.vue'
+	export default {
+		name: 'UniListItem',
+		components: {
+			uniIcon,
+			uniBadge
+		},
+		props: {
+			title: {
+				type: String,
+				default: ''
+			}, // 列表标题
+			note: {
+				type: String,
+				default: ''
+			}, // 列表描述
+			disabled: { // 是否禁用
+				type: Boolean,
+				default: false
+			},
+			showArrow: { // 是否显示箭头
+				type: Boolean,
+				default: true
+			},
+			showBadge: { // 是否显示数字角标
+				type: Boolean,
+				default: false
+			},
+			showSwitch: { // 是否显示Switch
+				type: Boolean,
+				default: false
+			},
+			switchChecked: { // Switch是否被选中
+				type: Boolean,
+				default: false
+			},
+			badgeText: {
+				type: [String, Number],
+				default: ''
+			}, // badge内容
+			badgeType: { // badge类型
+				type: String,
+				default: 'success'
+			},
+			thumb: {
+				type: String,
+				default: ''
+			}, // 缩略图
+			showExtraIcon: { // 是否显示扩展图标
+				type: Boolean,
+				default: false
+			},
+			extraIcon: {
+				type: Object,
+				default () {
+					return {
+						type: 'contact',
+						color: '#000000',
+						size: 20
+					}
+				}
+			}
+		},
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			onClick() {
+				this.$emit('click')
+			},
+			onSwitchChange(e) {
+				this.$emit('switchChange', e.detail)
+			}
+		}
+	}
+</script>
+
+<style>
+	@charset "UTF-8";
+
+	.uni-list-item {
+		font-size: 32upx;
+		position: relative;
+		display: flex;
+		flex-direction: column;
+		justify-content: space-between;
+		align-items: center
+	}
+
+	.uni-list-item--disabled {
+		opacity: .3
+	}
+
+	.uni-list-item--hover {
+		background-color: #f1f1f1
+	}
+
+	.uni-list-item__container {
+		padding: 24upx 30upx;
+		width: 100%;
+		box-sizing: border-box;
+		flex: 1;
+		position: relative;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center
+	}
+
+	.uni-list-item__container:after {
+		position: absolute;
+		z-index: 3;
+		right: 0;
+		bottom: 0;
+		left: 30upx;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc
+	}
+
+	.uni-list-item__content {
+		flex: 1;
+		overflow: hidden;
+		display: flex;
+		flex-direction: column
+	}
+
+	.uni-list-item__content-title {
+		font-size: 32upx;
+		text-overflow: ellipsis;
+		white-space: nowrap;
+		color: inherit;
+		line-height: 1.5;
+		overflow: hidden
+	}
+
+	.uni-list-item__content-note {
+		color: #999;
+		font-size: 28upx;
+		white-space: normal;
+		display: -webkit-box;
+		-webkit-box-orient: vertical;
+		-webkit-line-clamp: 2;
+		overflow: hidden
+	}
+
+	.uni-list-item__extra {
+		width: 25%;
+		display: flex;
+		flex-direction: row;
+		justify-content: flex-end;
+		align-items: center
+	}
+
+	.uni-list-item__icon {
+		margin-right: 18upx;
+		display: flex;
+		flex-direction: row;
+		justify-content: center;
+		align-items: center
+	}
+
+	.uni-list-item__icon-img {
+		height: 52upx;
+		width: 52upx
+	}
+
+	.uni-list>.uni-list-item:last-child .uni-list-item-container:after {
+		height: 0
+	}
+</style>

+ 47 - 0
components/uni-list/uni-list.vue

@@ -0,0 +1,47 @@
+<template>
+	<view class="uni-list">
+		<slot />
+	</view>
+</template>
+<script>
+	export default {
+		name: 'UniList'
+	}
+</script>
+<style>
+	@charset "UTF-8";
+
+	.uni-list {
+		background-color: #fff;
+		position: relative;
+		width: 100%;
+		display: flex;
+		flex-direction: column
+	}
+
+	.uni-list:after {
+		position: absolute;
+		z-index: 10;
+		right: 0;
+		bottom: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc
+	}
+
+	.uni-list:before {
+		position: absolute;
+		z-index: 10;
+		right: 0;
+		top: 0;
+		left: 0;
+		height: 1px;
+		content: '';
+		-webkit-transform: scaleY(.5);
+		transform: scaleY(.5);
+		background-color: #c8c7cc
+	}
+</style>

+ 92 - 0
pages/Charts/mainStatistics.vue

@@ -0,0 +1,92 @@
+<template>
+	<view>
+		<view class="qiun-title-bar">
+			<view class="qiun-title-dot-light">今日收入总额: {{dayTotalMoney}}</view>
+			<view class="qiun-title-dot-light">本周收入总额: {{weekTotalMoney}}</view>
+			<view class="qiun-title-dot-light">本月收入总额: {{monthTotalMoney}}</view>
+			<view class="qiun-title-dot-light">本年度收入总额: {{yearTotalMoney}}</view>
+		</view>
+		
+		<MyChartsColumn canvasId="column1" chartTitle="今日销售情况" chartType='day' :adminId="this.adminId" :equipmentId="this.equipmentId"></MyChartsColumn>
+		<MyChartsColumn canvasId="column2" chartTitle="本周销售情况" chartType='week' :adminId="this.adminId" :equipmentId="this.equipmentId"></MyChartsColumn>
+		<MyChartsColumn canvasId="column3" chartTitle="本月销售情况" chartType='month' :adminId="this.adminId" :equipmentId="this.equipmentId"></MyChartsColumn>
+		<MyChartsColumn canvasId="column4" chartTitle="本年销售情况" chartType='year' :adminId="this.adminId" :equipmentId="this.equipmentId"></MyChartsColumn>
+	</view>
+</template>
+
+<script>
+	import { mapState, mapActions, mapMutations } from 'vuex';
+	export default {
+		name: 'mainStatistics',
+		props: {
+			equipmentId: '',
+			adminId: '',
+		},
+		data() {
+			return {
+				dayTotalMoney:0,
+				weekTotalMoney:0,
+				monthTotalMoney:0,
+				yearTotalMoney:0,
+			}
+		},
+		computed: {
+			...mapState(['loginUser']),
+		},
+		onLoad(state){
+			this.getMainStatisticsData();
+		},
+		mounted() {
+			this.getMainStatisticsData();
+		},
+		methods: {
+			...mapActions('chart', ['getStatistics','getMainStatistics']),
+			getMainStatisticsData(){
+				setTimeout(() => {
+					const param = {};
+					if(this.adminId){ // 子组件,则拿传过来的参
+						param['adminId'] = this.adminId;
+					}else if ('admin' !== this.loginUser['username']) { //否则为主页,拿登录用户
+						param['adminId'] = this.loginUser['id'];
+					}
+					if (this.equipmentId) {
+						param['equipmentId'] = this.equipmentId;
+					}
+					console.log('getMainStatisticsData:{}',param)
+					this.getMainStatistics(param)
+						.then(data => {
+							for (let bean of data) {
+								if(bean['categorie']==='day'){
+									this.dayTotalMoney=bean['salePrice'];
+								}
+								if(bean['categorie']==='week'){
+									this.weekTotalMoney=bean['salePrice'];
+								}
+								if(bean['categorie']==='month'){
+									this.monthTotalMoney=bean['salePrice'];
+								}
+								if(bean['categorie']==='year'){
+									this.yearTotalMoney=bean['salePrice'];
+								}
+							}
+							uni.stopPullDownRefresh();
+						}
+						, _ => void uni.stopPullDownRefresh());
+				}, 0);
+			}
+		}
+	}
+</script>
+<style>
+	.qiun-title-dot-light {
+		border-left: 10upx solid #ca8019;
+		padding-left: 10upx;
+		font-size: 32upx;
+		color: #000000
+	}
+	.qiun-title-bar {
+		width: 96%;
+		padding: 10upx 2%;
+		flex-wrap: nowrap;
+	}
+</style>

+ 111 - 0
pages/User/merchantList.vue

@@ -0,0 +1,111 @@
+<template>
+	<view v-if="merchantList.length>1">
+		<uni-collapse :accordion="true">
+			<view v-for="(merchant,index) in merchantList" :key="merchant.id" >
+				<uni-collapse-item :title="getMerchantTitle(merchant)" :open="index===0">
+					<view style="padding: 20upx;background-color: aliceblue;">
+						<view v-if="merchant.equipmentList.length==0" style="text-align: center;">暂无数据</view>
+						<view v-if="merchant.equipmentList.length>0">
+							<uni-collapse :accordion="true">
+								<uni-collapse-item title="总销售情况">
+									<view style="padding: 20upx;">
+										<mainStatistics :adminId="merchant.id"></mainStatistics>
+									</view>
+								</uni-collapse-item>
+								<view v-for="equipment in merchant.equipmentList" :key="equipment.id">
+									<uni-collapse-item :title="getEquipmentTitle(equipment)">
+										<view style="padding: 20upx;">
+											<mainStatistics :equipmentId="equipment.id"></mainStatistics>
+										</view>
+									</uni-collapse-item>
+								</view>
+							</uni-collapse>	
+						</view>
+					</view>
+				</uni-collapse-item>
+			</view>
+		</uni-collapse>
+	</view>
+	<view v-else>
+		<view v-if="merchantList[0].equipmentList.length>1">
+			<uni-collapse :accordion="true">
+				<uni-collapse-item title="总销售情况">
+					<view style="padding: 20upx;">
+						<mainStatistics :adminId="merchantList[0].id"></mainStatistics>
+					</view>
+				</uni-collapse-item>
+				<view v-for="equipment in merchantList[0].equipmentList" :key="equipment.id">
+					<uni-collapse-item :title="getEquipmentTitle(equipment)">
+						<view style="padding: 20upx;">
+							<mainStatistics :equipmentId="equipment.id"></mainStatistics>
+						</view>
+					</uni-collapse-item>
+				</view>
+			</uni-collapse>	
+		</view>
+		<view v-else style="text-align: center;">暂无数据</view>
+	</view>
+</template>
+
+<script>
+    import {mapState,mapActions,mapMutations} from 'vuex'
+	import uniCollapse from '@/components/uni-collapse/uni-collapse.vue'
+	import uniCollapseItem from '@/components/uni-collapse-item/uni-collapse-item.vue'
+	import uniList from '@/components/uni-list/uni-list.vue'
+	import uniListItem from '@/components/uni-list-item/uni-list-item.vue'
+	
+    export default {
+		components: {
+			uniCollapse,
+			uniCollapseItem,
+			uniList,
+			uniListItem
+		},
+		data() {
+			return {
+				merchantList:[{equipmentList:[]}],
+				extraIcon: {
+					color: '#4cd964',
+					size: '22',
+					type: 'spinner'
+				}
+			}
+		},
+		computed: {
+			...mapState(['loginUser']),
+		},
+		onLoad(state){
+			this.getEquipmentListData();
+		},
+		methods: {
+			...mapActions('chart', ['getEquipmentListByUser']),
+			change(e) {
+				// console.log(e)
+			},
+			showEquipment(merchant){
+				 merchant['ifShow']=!merchant['ifShow'];
+			},
+			showLabel(merchant){
+				return merchant['ifShow']?'收起':'展开';
+			},
+			getMerchantTitle(merchant){
+				return merchant.name?merchant.name:merchant.username;
+			},
+			getEquipmentTitle(equipment){
+				return equipment.name?equipment.name:equipment.clientId;
+			},
+			getEquipmentListData(){
+				this.getEquipmentListByUser(this.loginUser)
+				.then(data => {
+					this.merchantList = data;
+					uni.stopPullDownRefresh();
+				}
+				, _ => void uni.stopPullDownRefresh());
+			}
+		}
+    }
+</script>
+
+<style>
+	
+</style>

+ 122 - 0
pages/User/merchantList2.vue

@@ -0,0 +1,122 @@
+<template>
+	<view v-if="merchantList.length>1">
+		<uni-collapse :accordion="true">
+			<view v-for="(merchant,index) in merchantList" :key="merchant.id" >
+				<uni-collapse-item :title="getMerchantTitle(merchant)" :open="index===0">
+					<view style="padding: 20upx;background-color: aliceblue;">
+						<view v-if="merchant.equipmentList.length==0" style="text-align: center;">暂无数据</view>
+						<view v-if="merchant.equipmentList.length>0">
+							<uni-collapse :accordion="true">
+								<view style="position: relative;" v-for="equipment in merchant.equipmentList" :key="equipment.id">
+									<span class="status-css" :class="equipment.hasTodayAlarm===true?statusError : statusNormal"></span>
+									<uni-collapse-item :title="getEquipmentTitle(equipment)">
+										<view style="padding: 20upx;background-color: antiquewhite;">
+											<view><span>机器唯一码:</span><span>{{equipment.clientId}}</span></view>
+											<view><span>所在地:</span><span>{{equipment.fullName}}</span></view>
+											<view><span>温度:</span><span>{{equipment.cabinetTm}}</span></view>
+											<view><span>湿度:</span><span>{{equipment.cabinetHd}}</span></view>
+											<view><span>转速:</span><span>{{equipment.furnaceSp}}</span></view>
+											<view><span>报警内容:</span><span>{{equipment.occurrenceTime}}  {{equipment.alarmContent}}</span></view>
+										</view>
+									</uni-collapse-item>
+								</view>
+							</uni-collapse>	
+						</view>
+					</view>
+				</uni-collapse-item>
+			</view>
+		</uni-collapse>
+	</view>
+	<view v-else>
+		<uni-collapse :accordion="true">
+			<view style="position: relative;" v-for="equipment in merchantList[0].equipmentList" :key="equipment.id">
+				<span class="status-css" :class="equipment.hasTodayAlarm===true?statusError : statusNormal"></span>
+				<uni-collapse-item :title="getEquipmentTitle(equipment)">
+					<view style="padding: 20upx;background-color: antiquewhite;">
+						<view><span>机器唯一码:</span><span>{{equipment.clientId}}</span></view>
+						<view><span>所在地:</span><span>{{equipment.fullName}}</span></view>
+						<view><span>温度:</span><span>{{equipment.cabinetTm}}</span></view>
+						<view><span>湿度:</span><span>{{equipment.cabinetHd}}</span></view>
+						<view><span>转速:</span><span>{{equipment.furnaceSp}}</span></view>
+						<view><span>报警内容:</span><span>{{equipment.occurrenceTime}}  {{equipment.alarmContent}}</span></view>
+					</view>
+				</uni-collapse-item>
+			</view>
+		</uni-collapse>	
+	</view>
+	
+</template>
+
+<script>
+    import {mapState,mapActions,mapMutations} from 'vuex'
+	import uniCollapse from '@/components/uni-collapse/uni-collapse.vue'
+	import uniCollapseItem from '@/components/uni-collapse-item/uni-collapse-item.vue'
+	import uniList from '@/components/uni-list/uni-list.vue'
+	import uniListItem from '@/components/uni-list-item/uni-list-item.vue'
+	import {dateUtils} from '@/common/util.js';
+    export default {
+		components: {
+			uniCollapse,
+			uniCollapseItem,
+			uniList,
+			uniListItem,
+		},
+		data() {
+			return {
+				merchantList:[{equipmentList:[]}],
+				extraIcon: {
+					color: '#4cd964',
+					size: '22',
+					type: 'spinner'
+				},
+				statusNormal:'status-normal',
+				statusError:'status-error',
+			}
+		},
+		computed: {
+			...mapState(['loginUser']),
+			
+		},
+		onLoad(state){
+			this.getEquipmentListData();
+		},
+		methods: {
+			...mapActions('chart', ['getEquipmentListByUser']),
+			change(e) {
+				// console.log(e)
+			},
+			showEquipment(merchant){
+				 merchant['ifShow']=!merchant['ifShow'];
+			},
+			showLabel(merchant){
+				return merchant['ifShow']?'收起':'展开';
+			},
+			getMerchantTitle(merchant){
+				return merchant.name?merchant.name:merchant.username;
+			},
+			getEquipmentTitle(equipment){
+				return equipment.name?equipment.name:'暂无名称';
+			},
+			getEquipmentListData(){
+				this.getEquipmentListByUser(this.loginUser)
+				.then(data => {
+					this.merchantList = data;
+					uni.stopPullDownRefresh();
+				}
+				, _ => void uni.stopPullDownRefresh());
+			}
+		}
+    }
+</script>
+
+<style>
+	.status-css {
+		position: absolute;width: 30upx;height: 30upx;right: 86upx;top: 30upx;border-radius: 30upx;
+	}
+	.status-error {
+		background-color: #dd524d
+	}
+	.status-normal {
+		background-color: #4cd964
+	}
+</style>

BIN
static/img/equipment.png


BIN
static/img/equipmentHL.png


BIN
static/img/leftTriangle.png


BIN
static/img/merchantList.png


BIN
static/img/merchantListHL.png


BIN
static/img/rightTriangle.png