Sidebar-Basic-Components.js 11.8 KB
(function () {
	// Adds Atlassian shapes
	Sidebar.prototype.addBasicComponentsPalette = function () {
		this.setCurrentSearchEntryLibrary('basicComponent');
		const dt = 'basicComponent'
		const gn = `mxgraph.${dt}`
		const currentDate = getCurrentDate();
		const basicAttr = this.enumCellBasicAttribute
		const componentType = this.enumComponentType
		const { INTERACTION, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE } = this.enumPermissionPanel
		const transparentBg = 'text;strokeColor=none;fillColor=none;html=1;fontSize=24;fontStyle=1;verticalAlign=middle;align=center;'
		const fns = [
			this.addEntry(this.getTagsForStencil(gn, 'Title', dt).join(' '), mxUtils.bind(this, function () {
				const cell = new mxCell('Title', new mxGeometry(0, 0, 100, 40), transparentBg);
				cell.setVertex(true)
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.TITLE })
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, 'Title');
			})),

			this.addEntry(this.getTagsForStencil(gn, 'variable', dt).join(' '), mxUtils.bind(this, function () {
				const cell = new mxCell('变量', new mxGeometry(0, 0, 100, 40), transparentBg);
				cell.setVertex(true)
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.VARIABLE })
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '变量');
			})),

			this.addEntry(this.getTagsForStencil(gn, 'line', dt).join(' '), mxUtils.bind(this, function () {
				const style = 'shape=filledEdge;rounded=1;fixDash=1;endArrow=none;strokeWidth=10;fillColor=none;edgeStyle=orthogonalEdgeStyle;flowAnimation=1;strokeColor=#6666FF;endFill=1;metaEdit=0;backgroundOutline=0;'
				const cell = new mxCell('', new mxGeometry(0, 0, 60, 40), style);
				cell.geometry.setTerminalPoint(new mxPoint(0, 40), true);
				cell.geometry.setTerminalPoint(new mxPoint(60, 0), false);
				cell.geometry.relative = true;
				cell.edge = true;
				cell.setVertex(true)
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.LINE })
				return this.createEdgeTemplateFromCells([cell], 60, 40, '线条');
			})),
			this.addEntry('real time', mxUtils.bind(this, function () {
				const template = `<div class="thingKit-component__real-time"><div class="real-time__date">%currentDate%</div> <div style="font-size:30px" class="real-time__now">HH:mm:ss</div></div>`
				const cell = new mxCell(template, new mxGeometry(0, 0, 180, 60), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;');
				cell.vertex = true;
				this.setCellAttributes(cell, {
					[basicAttr.COMPONENT_TYPE]: componentType.REAL_TIME,
					placeholders: '1',
					currentDate: currentDate,
				})
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '实时时间');
			})),
			this.addEntry(this.getTagsForStencil(gn, '变量图片', 'basic').join(' '), mxUtils.bind(this, function () {
				const cell = new mxCell('', new mxGeometry(0, 0, 194, 95), 'image;image=images/thingskit/img-placeholder.png;imageAspect=0;');
				cell.setVertex(true)
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.VAR_IMAGE })
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '变量图片');
			})),
			this.addEntry(this.getTagsForStencil(gn, '视频', 'basic').join(' '), mxUtils.bind(this, function () {
				const template = createVideoTemplate(300, 150)
				const cell = new mxCell(template, new mxGeometry(0, 0, 300, 150), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;');
				cell.setVertex(true)
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.VIDEO })
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '视频');
			})),
			this.addEntry(this.getTagsForStencil(gn, '图片', 'basic').join(' '), mxUtils.bind(this, function () {
				const cell = new mxCell(`<img class="basic-component__image" src="${Proxy_Prefix}/images/thingskit/img-placeholder.png" />`, new mxGeometry(0, 0, 190, 190), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;');
				cell.setVertex(true)
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.IMAGE })
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '图片');
			})),

			this.addEntry(this.getTagsForStencil(gn, '告警列表', 'basic').join(' '), mxUtils.bind(this, function () {
				const id = AlarmListComponent.genId()
				const template = AlarmListComponent.createAlarmList(null, 280, 200, id)
				const cell = new mxCell(template, new mxGeometry(0, 0, 280, 200), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;');
				cell.setVertex(true)
				const { UUID } = AlarmListComponent.getAttributeKeys()
				this.setCellAttributes(cell, { [basicAttr.COMPONENT_TYPE]: componentType.ALARM_LIST, [UUID]: id })
				return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '告警列表');
			})),
		];

		this.addPaletteFunctions(dt, '基础元件', true, fns);
		this.setCurrentSearchEntryLibrary();
	};

	Sidebar.prototype.isVideo = function (cell) {
		const basicAttr = Sidebar.prototype.enumCellBasicAttribute
		const componentType = Sidebar.prototype.enumComponentType
		return cell.getAttribute(basicAttr.COMPONENT_TYPE) === componentType.VIDEO
	}


	Sidebar.prototype.isAlarmList = function (cell) {
		const basicAttr = Sidebar.prototype.enumCellBasicAttribute
		const componentType = Sidebar.prototype.enumComponentType
		return cell.getAttribute(basicAttr.COMPONENT_TYPE) === componentType.ALARM_LIST
	}

	/**
 * @description charts cell发生resize时改变charts size
 * @type {Function}
 */
	const cellResized = mxGraph.prototype.cellResized
	mxGraph.prototype.cellResized = function (cell, rect) {
		if (Sidebar.prototype.isVideo(cell)) {
			const { width, height } = rect
			cell.setAttribute('label', createVideoTemplate(width, height))
		}

		if (AlarmListComponent.isAlarmList(cell)) {
			const { width, height } = rect

			cell.setAttribute('label', AlarmListComponent.createAlarmList(null, width, height))
		}
		cellResized.apply(this, arguments)
	}

	function createVideoTemplate(width = '100%', height = '100%') {
		const m3u8 = 'http://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8'
		// const m3u8 = 'http://113.204.115.250:83/openUrl/iVnkGzK/live.m3u8'
		const mp4 = 'http://vjs.zencdn.net/v/oceans.mp4'
		const m3u8Type = 'application/x-mpegURL'
		const mp4Type = 'video/mp4'
		const poster = `${Proxy_Prefix}/images/youtube.png`

		// const cell = new mxCell('<video></video>', new mxGeometry(0, 0, 100, 95), 'image;image=images/thingskit/video.svg;imageAspect=0;');
		const template = `<video controls preload="auto" muted="muted" width="${width}" height="${height}" poster="${poster}" data-setup='{}'>
													<source src="${m3u8}" type="${m3u8Type}">
													<p class="vjs-no-js">
														要查看此视频,请启用JavaScript,并考虑升级web浏览器.
													</p>
											</video>`
		return template
	}

	//封装日期函数
	function getCurrentDate() {
		var date = new Date(); //创建日期对象
		var year = date.getFullYear();
		var month = date.getMonth() + 1;
		var dates = date.getDate();
		arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
		var day = date.getDay();
		return year + '年' + month + '月' + dates + '日 ' + arr[day];
	}

	/**
	 * @description 初始化实时事件组件
	 */
	function initRealTimeComponent() {
		RAFSetInterval(() => {
			const allTimeNode = document.querySelectorAll('.thingKit-component__real-time .real-time__now')
			const allDateNode = document.querySelectorAll('.thingKit-component__real-time .real-time__date')
			for (const time of allTimeNode) {
				const date = new Date()
				time.innerHTML = [date.getHours(), date.getMinutes(), date.getSeconds()].map(item => item.toString().padStart(2, 0)).join(':')
			}

			for (const date of allDateNode) {
				date.innerHTML = getCurrentDate()
			}
		}, 1000)
	}

	initRealTimeComponent()

})();


function AlarmListComponent() {

}

/**
 * 
 * @param {{deviceName: string, status: string, startTs: string}[]} list 
 * @param {number} width 
 * @param {number} height 
 * @param {string} id 
 * @returns 
 */
AlarmListComponent.createAlarmList = function (list, width = 280, height = 200, id) {

	list = list || Array.from({ length: 10 }, ((_, index) => ({
		deviceName: `示例设备${index + 1}`, startTs: Date.now(), status: [
			"CLEARED_UNACK",
			"ACTIVE_UNACK",
			"CLEARED_ACK",
			"ACTIVE_ACK"
		][index % 4]
	})))

	id = id || AlarmListComponent.genId()

	var template = `  
		<div id="${id}" class="alarm-list" style="overflow-y: auto; overflow-x: hidden; width: ${width}px; height: ${height}px;">
			<div class="list-wrapper" style="font-size: 12px;" data-auto-scroll>
				${AlarmListComponent.createAlarmItem(list)}
			</div>
		</div>
			`
	return template.replace(/\n/g, '')
}

/**
 * 
 * @param {{deviceName: string, status: string, startTs: string}[] | {deviceName: string, status: string, startTs: string}} record 
 * @returns 
 */
AlarmListComponent.createAlarmItem = function (record) {
	if (record && !Array.isArray(record)) {
		record = [record]
	}

	var itemHeight = 50

	function formatTime(time) {
		try {
			var date = new Date(time)
			var year = date.getFullYear()
			var month = date.getMonth() + 1
			var day = date.getDate()
			var hour = date.getHours()
			var minute = date.getMinutes()
			var second = date.getSeconds()
			return `${year}-${month.toString().padStart(2, 0)}-${day.toString().padStart(2, 0)} ${hour.toString().padStart(2, 0)}:${minute.toString().padStart(2, 0)}:${second.toString().padStart(2, 0)}`
		} catch (error) {
			return '暂无时间	'
		}
	}

	return (record || []).map(item => {
		var { alias, deviceName, status, startTs,deviceAlias } = item || {}

		var stateStyle = {
			CLEARED_UNACK: 'color: #cf1322;background: #fff1f0;border-color: #ffa39e;',
			ACTIVE_UNACK: 'color: #d46b08;background: #fff7e6;border-color: #ffd591;',
			CLEARED_ACK: 'color: #08979c;background: #e6fffb;border-color: #87e8de;',
			ACTIVE_ACK: 'color: #389e0d;background: #f6ffed;border-color: #b7eb8f;',
		}

		var stateName = {
			CLEARED_UNACK: '清除未确认',
			ACTIVE_UNACK: '激活未确认',
			CLEARED_ACK: '清除已确认',
			ACTIVE_ACK: '激活已确认',
		}

		var template = `
	<div class="alarm-list-item"	style="height: ${itemHeight}px; box-sizing: border-box; display: flex; flex-direction: column; justify-content: center; border-bottom: 1px solid black; text-align: left; min-width: 280px; width: 100%;">
		<div style="padding: 0 10px;">
			<span style="margin-right: 5px;">设备:</span>
			<span>${deviceAlias || deviceName}</span>
		</div>
		<div style="padding: 5px 10px;">
			<span style="margin-right: 5px;">时间:</span>
			<span>${formatTime(startTs)}</span>
			<span	style="padding: 5px; border-radius: 5px; margin-left: 5px; border: 1px solid; font-size: 12px; ${stateStyle[status]}">${stateName[status]}</span>
		</div>
	</div>`
		return template
	}).join('').replace(/\n/g, '')
}

AlarmListComponent.genId = function () {
	return `alarm-list-${Number(Math.random().toString().substring(2)).toString(16)}`
}

AlarmListComponent.isAlarmList = function (cell) {
	const basicAttr = Sidebar.prototype.enumCellBasicAttribute
	const componentType = Sidebar.prototype.enumComponentType
	return cell.getAttribute(basicAttr.COMPONENT_TYPE) === componentType.ALARM_LIST
}

AlarmListComponent.getAttributeKeys = function () {
	return {
		UUID: 'uuid',
	}
}

AlarmListComponent.setAutoScroll = function (cell) {
	// RAFSetInterval(() => {
	// 	console.log(cell)		
	// }, 2000)
}