<!-- 
    filename: index.vue
    author: liubin
    date: 2023-09-04 09:34:52
    description: 设备状态时序图
-->

<template>
	<div
		class="status-timegraph-container"
		style="background: #f2f4f9; flex: 1; display: flex; flex-direction: column">
		<el-row
			class=""
			style="
				margin-bottom: 12px;
				background: #fff;
				padding: 16px 16px 0;
				border-radius: 8px;
			">
			<div class="blue-title">生产节拍时序图</div>
			<SearchBar
				:formConfigs="searchBarFormConfig"
				ref="search-bar"
				:remove-blue="true"
				@select-changed="handleSearchBarSelectChange"
				@headBtnClick="handleSearchBarBtnClick" />
		</el-row>

		<el-row
			class=""
			style="
				height: 1px;
				flex: 1;
				margin-bottom: 12px;
				background: #fff;
				padding: 16px 16px 32px;
				border-radius: 8px;
				display: flex;
				flex-direction: column;
			">
			<el-row :gutter="20">
				<el-col :span="6">
					<div class="blue-title">设备状态时序图</div>
				</el-col>
				<el-col :span="18" class="legend-row">
					<div class="legend">
						<div class="icon running"></div>
						<div>运行中</div>
					</div>
					<div class="legend">
						<div class="icon fault"></div>
						<div>故障</div>
					</div>
					<div class="legend">
						<div class="icon stop"></div>
						<div>计划停机</div>
					</div>
				</el-col>
			</el-row>
			<div
				class="main-area"
				style="flex: 1; display: flex; flex-direction: column">
				<div
					class="graphs"
					v-show="graphList.length"
					id="status-chart"
					style="height: 1px; flex: 1"></div>
				<h2 v-if="!graphList || graphList.length == 0" class="no-data-bg"></h2>
			</div>
		</el-row>

		<!-- 对话框(添加 / 修改) -->
		<base-dialog
			dialogTitle="添加设备"
			:dialogVisible="open"
			width="500px"
			@close="open = false"
			@cancel="open = false"
			@confirm="submitForm">
			<el-select
				v-if="open"
				style="width: 100%"
				filterable
				clearable
				v-model="queryParams.equipmentId"
				placeholder="请选择一个设备">
				<el-option
					v-for="eq in eqList"
					:key="eq.id"
					:value="eq.id"
					:label="eq.name"></el-option>
			</el-select>
		</base-dialog>
	</div>
</template>

<script>
import Gantt from './chart';
import moment from 'moment';

export default {
	name: 'SGStatus',
	components: {},
	props: {},
	data() {
		const today = new Date();
		const todayStart = new Date(
			today.getFullYear(),
			today.getMonth(),
			today.getDate()
		);
		return {
			chart: null,
			searchBarFormConfig: [
				{
					type: 'select',
					label: '产线',
					placeholder: '请选择产线',
					selectOptions: [],
					param: 'lineId',
					onchange: true,
				},
				{
					type: 'select',
					label: '工段',
					placeholder: '请选择工段',
					selectOptions: [],
					param: 'sectionId',
				},
				// 时间段
				{
					type: 'datePicker',
					label: '时间段',
					dateType: 'date',
					format: 'yyyy-MM-dd',
					valueFormat: 'yyyy-MM-dd HH:mm:ss',
					rangeSeparator: '-',
					placeholder: '选择日期',
					param: 'recordTime',
					required: true,
					defaultSelect: moment(todayStart).format('YYYY-MM-DD HH:mm:ss'),
				},
				{
					type: 'button',
					btnName: '查询',
					name: 'search',
					color: 'primary',
				},
				{
					type: 'separate',
				},
				{
					type: 'button',
					btnName: '添加对比',
					name: 'compare',
					color: 'primary',
					plain: true,
				},
			],
			queryParams: {
				lineId: null,
				sectionId: null,
				equipmentId: null,
				recordTime: null,
			},
			graphList: [],
			existingEquipments: [],
			open: false,
			eqList: [],
			startTime: null,
			gantt: null,
			// demo: [
			// 	[
			// 		{
			// 			equipmentName: '下片机',
			// 			duration: 30,
			// 			relativeDuration: 0.6,
			// 			status: 0,
			// 			startPos: 0,
			//             startTime: 1691568181000,
			// 		},
			// 		{
			// 			equipmentName: '下片机',
			// 			duration: 20,
			// 			relativeDuration: 0.4,
			// 			status: 2,
			// 			startPos: 30,
			//             startTime: 1691569981000
			// 		},
			// 	],
			// ],
		};
	},
	computed: {},
	created() {
		this.initProductline();
		this.initWorksection();
		this.initEquipment();
		// this.getList();
	},
	mounted() {},
	watch: {
		graphList: {
			handler(val) {
				if (val && val.length) {
					this.$nextTick(() => {
						if (!this.gantt) {
							this.gantt = new Gantt('#status-chart', this.startTime);
							this.gantt.init(val);
							return;
						}
						this.gantt.update(val);
					});
				}
				return;
			},
			deep: true,
			immediate: true,
		},
	},
	methods: {
		findMin() {
			let min = 0;
			this.graphList.forEach((arr) => {
				arr.forEach((item) => {
					if (min < item.startTime) min = item.startTime;
				});
			});
			return min;
		},

		/** 重置查询条件 */
		initQuery() {
			this.queryParams.lineId = null;
			this.queryParams.equipmentId = null;
			this.queryParams.sectionId = null;
			this.queryParams.recordTime = null;
		},

		/** 对象到数组的转换 */
		objectToArray(obj) {
			return Object.keys(obj).map((key) => {
				obj[key].sort((a, b) => a.startTime - b.startTime);
				obj[key].key = key;
				return obj[key];
			});
		},

		async getList() {
			const { code, data } = await this.$axios({
				url: '/monitoring/equipment-monitor/status-series',
				method: 'get',
				params: this.queryParams,
			});
			if (code == 0) {
				this.existingEquipments = Object.values(data).map(
					(eq) => eq[0].equipmentId
				);
				this.graphList = this.objectToArray(data);
			}
		},

		/** 准备设备数据 */
		async initEquipment() {
			const { code, data } = await this.$axios({
				url: '/base/core-equipment/listAll',
				method: 'get',
			});
			if (code == 0) {
				this.eqList = data.map((item) => {
					return {
						name: item.name,
						id: item.id,
					};
				});
			}
		},

		/** 准备产线数据 */
		async initProductline() {
			const { code, data } = await this.$axios({
				url: '/base/core-production-line/listAll',
				method: 'get',
			});
			if (code == 0) {
				this.searchBarFormConfig[0].selectOptions = data.map((item) => {
					return {
						name: item.name,
						id: item.id,
					};
				});
			}
		},

		/** 准备工段数据 */
		async initWorksection() {
			const { code, data } = await this.$axios({
				url: '/base/core-workshop-section/listAll',
				method: 'get',
			});
			if (code == 0) {
				this.searchBarFormConfig[1].selectOptions = data.map((item) => {
					return {
						name: item.name,
						id: item.id,
					};
				});
			}
		},

		handleSearchBarSelectChange({ param, value }) {
			if (!value) {
				this.searchBarFormConfig[1].selectOptions = [];
				return;
			}
			switch (param) {
				case 'lineId':
					this.$axios({
						url: '/base/core-workshop-section/listByParentId',
						method: 'get',
						params: {
							id: value,
						},
					}).then(({ code, data }) => {
						if (code == 0) {
							this.searchBarFormConfig[1].selectOptions = data.map((item) => {
								return {
									name: item.name,
									id: item.id,
								};
							});
						}
					});
			}
		},

		handleSearchBarBtnClick({ btnName, ...payload }) {
			switch (btnName) {
				case 'search':
					if (!payload.recordTime || payload.recordTime.length <= 0) {
						this.$message.error('请选择时间段');
						return;
					}

					this.startTime = new Date(payload.recordTime);
					this.queryParams.lineId = payload.lineId || null;
					this.queryParams.sectionId = payload.sectionId || null;
					this.queryParams.equipmentId = payload.equipmentId || null;
					this.queryParams.recordTime = payload.recordTime
						? [
								payload.recordTime,
								new Date(
									new Date(payload.recordTime).getTime() + 24 * 3600 * 1000
								)
									.toLocaleDateString()
									.split('/')
									.map((value, index) => {
										if (index == 1 || index == 2) {
											return value.padStart(2, '0');
										}
										return value;
									})
									.join('-') + ' 00:00:00',
						  ]
						: null;
					this.getList();
					break;
				case 'compare':
					this.open = true;
					break;
			}
		},

		async submitForm() {
			if (this.existingEquipments.indexOf(this.queryParams.equipmentId) >= 0) {
				this.$message.error('该设备已存在');
				return;
			}
			const { code, data } = await this.$axios({
				url: '/monitoring/equipment-monitor/status-series',
				method: 'get',
				params: {
					recordTime: this.queryParams.recordTime,
					equipmentId: this.queryParams.equipmentId,
				},
			});
			if (code == 0) {
				const newEqlist = this.objectToArray(data);
				if (!newEqlist || newEqlist.length == 0) {
					this.$message.error('该设备没有状态数据');
					return;
				}
				this.graphList.push(newEqlist[0]);
			}
			this.open = false;
		},
	},
};
</script>

<style scoped lang="scss">
.graph {
	// border: 1px solid #ccc;
	// padding: 12px 12px 28px 12px;
	// margin: 64px 0;
	position: relative;
	display: flex;
}

.graph-title {
	// position: absolute;
	// top: -64px;
	// left: -1px;
	// padding: 8px 18px;
	padding: 0 12px;
	font-size: 14px;
	line-height: 1;
}

.graph-content {
	display: flex;
	flex: 1;
	padding: 22px 12px;
	border: 1px solid #ccc;
	border-bottom-width: 2px;
	border-top: none;
	position: relative;
}

.graph-content::after,
.graph-content::before {
	content: '';
	position: absolute;
	width: 3px;
	height: 80%;
	background: #fff;
	right: -1px;
	top: 0;
}

.graph-content::before {
	right: unset;
	left: -1px;
}

.graph-item,
.graph-item-fixed {
	// height: 88px;
	// width: 24px;
	flex: 1;
	// border: 1px solid #ccc;
	position: relative;
}

.graph-item-fixed {
	flex: unset;
}

.graph-item::before,
.graph-item-fixed::before {
	position: absolute;
	bottom: -16px;
	left: 0;
	content: attr(data-time);
	// font-size - js
	// rotate - js
	// color - js, default:
	color: #777;
	transform-origin: left top;
	transform: rotate(12deg);
}

.graph-item-fixed::after,
.graph-item::after {
	content: '';
	position: absolute;
	left: 0;
	bottom: -3px;
	display: inline-block;
}

.graph-item.tick::after,
.graph-item-fixed.tick::after {
	width: 1px;
	height: 6px;
	border-left: 1px solid #777;
}

.running {
	background-color: #288aff;
	// background-color: #84f04e;
}

.waiting {
	background-color: #5ad8a6;
	// background-color: #409eff;
}

.fault {
	// background-color: #ea5b5b;
	background-color: #fc9c91;
}

.full {
	// background-color: #e6a23c;
	background-color: #598fff;
}

.lack {
	// background-color: #a69c8d;
	background-color: #7585a2;
}

.stop {
	background-color: #ffdc94;
}

.legend-row {
	margin: 6px 0;
	padding-right: 12px;
	display: flex;
	justify-content: flex-end;

	> .legend:not(:last-child) {
		margin-right: 12px;
	}

	.legend {
		display: flex;
		align-items: center;
	}

	.icon {
		width: 8px;
		height: 8px;
		border-radius: 2px;
		margin-right: 4px;
		margin-top: 1px;
	}
}

.blue-title {
	position: relative;
	padding: 4px 0;
	padding-left: 12px;
	font-size: 14px;
	color: #606266;
	font-weight: 700;
	margin-bottom: 12px;

	&::before {
		content: '';
		position: absolute;
		left: 0;
		top: 6px;
		height: 16px;
		width: 4px;
		border-radius: 1px;
		background: #0b58ff;
	}
}

.echarts__status-chart {
	background: #ccc;
}

.echarts__status-chart > div {
	height: 100% !important;
	width: 100% !important;
}
</style>
