<template>
	<div class="build">
		<contentmenu ref="contentmenu"></contentmenu>
		<imglist ref="imglist" @change="handleSetimg"></imglist>
		<headers ref="headers"></headers>
		<top ref="top"></top>
		<div class="app" :class="{ 'app--none': !menuFlag }">
			<div
				class="menu"
				v-show="menuFlag && menuShow"
				@click.self="handleInitActive"
			>
				<p class="title">图层</p>
				<layer ref="layer" style="padding: 0 5px" :nav="nav"></layer>
			</div>
			<!-- 中间区域 -->
			<div ref="section" @contextmenu.prevent="() => {}" class="section">
				<sketch-rule
					:thick="thick"
					:scale="scale"
					:width="width"
					:height="height"
					:startX="startX"
					:startY="startY"
					:palette="palette"
					:shadow="shadow"
					:horLineArr="lines.h"
					:verLineArr="lines.v"
				/>
				<div
					ref="screensRef"
					class="screens"
					@mousedown="handleInitActive"
					@wheel="handleWheel"
					@scroll="handleScroll"
				>
					<div ref="containerRef" class="screen-container">
						<div class="canvas" ref="canvas" :style="canvasStyle">
							<container
								ref="container"
								:wscale="scale"
							></container>
						</div>
					</div>
				</div>
			</div>
			<div class="menu params" v-show="menuFlag && paramsShow">
				<el-tabs
					class="menu__tabs"
					@tab-click="handleTabClick"
					stretch
					v-model="menuTabs"
				>
					<el-tab-pane name="0">
						<template #label>
							<span>
								<el-icon>
									<el-icon-setting></el-icon-setting>
								</el-icon>
								配置
							</span>
						</template>
						<el-form label-width="110px" label-position="left">
							<!-- 多选配置选项 -->
							<template v-if="isSelectActive">
								<el-form-item label="水平方式">
									<el-tooltip
										content="左对齐"
										placement="top"
									>
										<i
											class="el-icon-s-fold icon"
											@click="
												$refs.container.handlePostionSelect(
													'left'
												)
											"
										></i>
									</el-tooltip>
									<el-tooltip
										content="居中对齐"
										placement="top"
									>
										<i
											class="el-icon-s-operation icon"
											@click="
												$refs.container.handlePostionSelect(
													'center'
												)
											"
										></i>
									</el-tooltip>
									<el-tooltip
										content="右对齐"
										placement="top"
									>
										<i
											class="el-icon-s-unfold icon"
											@click="
												$refs.container.handlePostionSelect(
													'right'
												)
											"
										></i>
									</el-tooltip>
								</el-form-item>
								<el-form-item label="垂直方式">
									<el-tooltip
										content="顶对齐"
										placement="top"
									>
										<i
											class="el-icon-s-fold icon"
											@click="
												$refs.container.handlePostionSelect(
													'top'
												)
											"
										></i>
									</el-tooltip>
									<el-tooltip
										content="中部对齐"
										placement="top"
									>
										<i
											class="el-icon-s-operation icon"
											@click="
												$refs.container.handlePostionSelect(
													'middle'
												)
											"
										></i>
									</el-tooltip>
									<el-tooltip
										content="底对齐"
										placement="top"
									>
										<i
											class="el-icon-s-unfold icon"
											@click="
												$refs.container.handlePostionSelect(
													'bottom'
												)
											"
										></i>
									</el-tooltip>
								</el-form-item>
								<el-form-item label-width="0">
									<el-button
										type="primary"
										class="block"
										@click="handleFolder"
										>成组</el-button
									>
								</el-form-item>
								<el-form-item label-width="0">
									<el-button
										type="danger"
										class="block"
										@click="handleDeleteSelect"
										>删除</el-button
									>
								</el-form-item>
							</template>
							<!-- 组件配置 -->
							<template v-else-if="activeIndex">
								<p class="title">{{ activeObj.title }}</p>
								<el-form-item label="图层名称">
									<avue-input
										v-model="activeObj.name"
									></avue-input>
								</el-form-item>
								<template v-if="!isFolder">
									<el-form-item label="隐藏">
										<avue-switch
											v-model="activeObj.display"
										></avue-switch>
									</el-form-item>
									<el-form-item label="锁定">
										<avue-switch
											v-model="activeObj.lock"
										></avue-switch>
									</el-form-item>
								</template>
								<template v-if="validProp('colorList')">
									<el-form-item label="系统配色">
										<avue-switch
											v-model="activeOption.switchTheme"
										></avue-switch>
									</el-form-item>
								</template>
								<component
									:is="activeComponent.prop + 'Option'"
								></component>
								<main-option></main-option>
							</template>
							<!-- 主屏的配置项 -->
							<template v-else>
								<el-form-item label="大屏大小">
									<div class="flex">
										<avue-input-number
											style="width: 130px"
											v-model="config.width"
										></avue-input-number>
										&nbsp;x&nbsp;
										<avue-input-number
											style="width: 130px"
											v-model="config.height"
										></avue-input-number>
									</div>
								</el-form-item>
								<el-form-item label="大屏简介">
									<avue-input
										v-model="config.info"
										type="textarea"
										:min-rows="5"
									></avue-input>
								</el-form-item>
								<el-form-item label="背景颜色">
									<avue-input-color
										v-model="config.backgroundColor"
									></avue-input-color>
								</el-form-item>
								<el-form-item label="背景图片">
									<img
										:src="config.backgroundImage"
										@click="
											handleOpenImg(
												'config.backgroundImage',
												'background'
											)
										"
										alt=""
										width="100%"
									/>
									<el-input
										clearable
										v-model="config.backgroundImage"
									>
										<template #append>
											<div
												@click="
													handleOpenImg(
														'config.backgroundImage',
														'background'
													)
												"
											>
												<i
													class="iconfont icon-img"
												></i>
											</div>
										</template>
									</el-input>
								</el-form-item>
								<el-form-item label="预览方式">
									<el-radio-group v-model="config.screen">
										<el-radio label="x"
											>X轴铺满，Y轴自适应滚动</el-radio
										>
										<el-radio label="y"
											>Y轴铺满，X轴自适应滚动</el-radio
										>
										<el-radio label="xy"
											>强行拉伸画面，填充所有视图</el-radio
										>
									</el-radio-group>
								</el-form-item>
								<el-form-item label-width="0">
									<el-button
										type="primary"
										class="block"
										@click="globShow = true"
										>更多设置</el-button
									>
								</el-form-item>
							</template>
						</el-form>
					</el-tab-pane>
					<template v-if="isActive && !isSelectActive">
						<!-- 数据配置 -->
						<el-tab-pane name="1" v-if="validProp('dataList')">
							<template #label>
								<span
									><i class="el-icon-document-copy"></i
									>数据</span
								>
							</template>
							<template v-if="menuTabs == 1">
								<el-form
									label-width="120px"
									label-position="left"
								>
									<el-form-item label="数据类型">
										<avue-select
											v-model="activeObj.dataType"
											:dic="dicOption.dataType"
										></avue-select>
									</el-form-item>
									<template v-if="isSql">
										<el-form-item label="数据源选择">
											<avue-select
												:dic="DIC.sql"
												v-model="db"
											></avue-select>
										</el-form-item>
										<el-form-item
											label="SQL语句"
											label-position="top"
										>
											<monaco-editor
												v-model="sql"
												language="sql"
												height="100"
											></monaco-editor>
										</el-form-item>
									</template>
									<template v-else-if="isApi">
										<el-form-item label="接口地址">
											<avue-input
												v-model="activeObj.url"
											></avue-input>
										</el-form-item>
										<el-form-item label="请求方式">
											<avue-select
												v-model="activeObj.dataMethod"
												:dic="dicOption.dataMethod"
											></avue-select>
										</el-form-item>
									</template>
									<template v-else-if="isWs">
										<el-form-item label="WS地址">
											<el-input v-model="activeObj.wsUrl">
											</el-input>
										</el-form-item>
									</template>
									<template v-else-if="isRecord">
										<el-form-item label="数据集选择">
											<avue-select
												:dic="DIC.data"
												v-model="activeObj.record"
											></avue-select>
										</el-form-item>
									</template>
									<el-form-item
										label="刷新时间"
										v-if="isApi || isWs || isSql"
									>
										<avue-input-number
											v-model="activeObj.time"
											placeholder="0"
										></avue-input-number>
									</el-form-item>
									<el-form-item label-width="0">
										<el-button
											type="primary"
											class="block"
											@click="handleSetting"
											>更多设置</el-button
										>
									</el-form-item>
									<el-form-item label-width="0">
										<el-button
											type="danger"
											class="block"
											@click="
												openCode(
													'stylesFormatter',
													'编辑样式'
												)
											"
											>编辑样式</el-button
										>
									</el-form-item>
									<el-form-item label-width="0">
										<el-button
											type="primary"
											class="block"
											@click="handleRes"
											>请求数据</el-button
										>
									</el-form-item>
									<el-form-item label-width="0">
										<monaco-editor
											v-model="dataRes"
											disabled
											height="400"
										></monaco-editor>
									</el-form-item>
								</el-form>
							</template>
						</el-tab-pane>
						<!-- 交互事件配置 -->
						<el-tab-pane name="2" v-if="validProp('eventList')">
							<template #label>
								<span><i class="el-icon-thumb"></i>交互</span>
							</template>
							<el-form label-width="120px" label-position="left">
								<el-form-item label="子类">
									<avue-select
										multiple
										v-model="activeObj.child.index"
										:dic="childList"
										:props="childProps"
									>
									</avue-select>
								</el-form-item>
								<el-form-item label="参数名称">
									<avue-input
										v-model="activeObj.child.paramName"
									></avue-input>
								</el-form-item>
								<el-form-item label="映射字段">
									<avue-input
										v-model="activeObj.child.paramValue"
										placeholder="默认为value"
									></avue-input>
								</el-form-item>
							</el-form>
						</el-tab-pane>
						<!-- 其他事件配置 -->
						<el-tab-pane name="3" v-if="!isFolder">
							<template #label>
								<span><i class="el-icon-mouse"></i>事件</span>
							</template>
							<el-form label-width="120px" label-position="left">
								<el-form-item label="点击事件">
									<el-button
										type="primary"
										@click="
											openCode(
												'clickFormatter',
												'点击事件'
											)
										"
										>编辑</el-button
									>
								</el-form-item>
								<template
									v-if="validProp('labelFormatterList')"
								>
									<el-form-item label="提示事件">
										<el-button
											type="primary"
											@click="
												openCode(
													'formatter',
													'提示事件'
												)
											"
											>编辑</el-button
										>
									</el-form-item>
									<el-form-item label="标题事件">
										<el-button
											type="primary"
											@click="
												openCode(
													'labelFormatter',
													'标题事件'
												)
											"
											>编辑</el-button
										>
									</el-form-item>
								</template>
							</el-form>
						</el-tab-pane>
						<!-- 基本参数配置 -->
						<el-tab-pane name="4">
							<template #label>
								<span><i class="el-icon-folder"></i>参数</span>
							</template>
							<el-form
								label-width="90px"
								label-position="left"
								v-if="menuTabs == 4"
							>
								<el-form-item label="序号">
									<avue-input
										@click="handleCopyIndex"
										v-model="activeIndex"
										disabled
									>
									</avue-input>
								</el-form-item>
								<el-form-item label="配置">
									<monaco-editor
										v-model="activeObj"
										disabled
										language="javascript"
										height="100"
									></monaco-editor>
								</el-form-item>
								<template v-if="!isFolder">
									<el-form-item label="进入动画">
										<avue-select
											filterable
											allow-create
											v-model="activeComponent.animated"
											:dic="dicOption.animated"
										></avue-select>
										<div>
											<a
												href="https://www.dowebok.com/demo/2014/98/"
												target="_blank"
												>点击查看动画类型</a
											>
										</div>
									</el-form-item>
									<el-form-item label="位置">
										<div class="flex">
											<avue-input-number
												style="width: 130px"
												v-model="activeObj.left"
											></avue-input-number>
											&nbsp;x&nbsp;
											<avue-input-number
												style="width: 130px"
												v-model="activeObj.top"
											></avue-input-number>
										</div>
									</el-form-item>
									<el-form-item label="尺寸">
										<div class="flex">
											<avue-input-number
												style="width: 130px"
												v-model="activeComponent.width"
											></avue-input-number>
											&nbsp;x&nbsp;
											<avue-input-number
												style="width: 130px"
												v-model="activeComponent.height"
											></avue-input-number>
										</div>
									</el-form-item>
									<el-form-item label="字体">
										<avue-input
											v-model="activeComponent.fontFamily"
											placeholder="输入字体库的url"
										>
										</avue-input>
									</el-form-item>
									<el-form-item label="透视">
										<avue-slider
											v-model="
												activeComponent.perspective
											"
											:max="1000"
										></avue-slider>
									</el-form-item>
									<el-form-item label="缩放">
										<avue-slider
											v-model="activeComponent.scale"
											:max="10"
										></avue-slider>
									</el-form-item>
									<el-form-item label="透明度">
										<avue-slider
											:step="0.1"
											v-model="activeComponent.opacity"
											:max="1"
										></avue-slider>
									</el-form-item>
									<el-form-item label="X旋转度">
										<avue-slider
											v-model="activeComponent.rotateX"
											:min="-360"
											:max="360"
										></avue-slider>
									</el-form-item>
									<el-form-item label="Y旋转度">
										<avue-slider
											v-model="activeComponent.rotateY"
											:min="-360"
											:max="360"
										></avue-slider>
									</el-form-item>
									<el-form-item label="Z旋转度">
										<avue-slider
											v-model="activeComponent.rotateZ"
											:min="-360"
											:max="360"
										></avue-slider>
									</el-form-item>
								</template>
							</el-form>
						</el-tab-pane>
					</template>
				</el-tabs>
			</div>
		</div>
		<codeedit
			@submit="closeCode"
			v-if="code.box"
			:title="code.title"
			:type="code.type"
			v-model="code.obj"
			v-model:visible="code.box"
		></codeedit>
		<el-dialog
			append-to-body
			top="1%"
			title="更多设置"
			:close-on-click-modal="false"
			v-model="globShow"
			width="70%"
		>
			<el-form label-width="130px">
				<el-form-item label="全局请求地址">
					<avue-input
						v-model="config.url"
						placeholder="/"
					></avue-input>
				</el-form-item>
				<el-form-item label="全局请求参数">
					<monaco-editor
						v-model="config.query"
						language="javascript"
						disabled
						height="100"
					></monaco-editor>
					<el-button
						type="primary"
						icon="el-icon-edit"
						@click="openCode('query', '全局请求参数')"
						>编辑</el-button
					>
				</el-form-item>
				<el-form-item label="全局请求头">
					<monaco-editor
						v-model="config.header"
						language="javascript"
						disabled
						height="100"
					></monaco-editor>
					<el-button
						type="primary"
						icon="el-icon-edit"
						@click="openCode('header', '全局请求头')"
						>编辑</el-button
					>
				</el-form-item>
				<el-form-item label="大屏水印">
					<avue-switch v-model="config.mark.show"></avue-switch>
				</el-form-item>
				<template v-if="config.mark.show">
					<el-form-item label="内容">
						<avue-input v-model="config.mark.text"></avue-input>
					</el-form-item>
					<el-form-item label="大小">
						<avue-input-number
							v-model="config.mark.fontSize"
						></avue-input-number>
					</el-form-item>
					<el-form-item label="颜色">
						<avue-input-color
							v-model="config.mark.color"
						></avue-input-color>
					</el-form-item>
					<el-form-item label="角度">
						<avue-input-number
							v-model="config.mark.degree"
						></avue-input-number>
					</el-form-item>
				</template>
			</el-form>
		</el-dialog>
		<el-dialog
			append-to-body
			top="1%"
			title="更多设置"
			:close-on-click-modal="false"
			v-model="show"
			width="70%"
		>
			<el-form label-width="130px">
				<el-form-item label="数据类型">
					<avue-select
						v-model="activeObj.dataType"
						:dic="dicOption.dataType"
					></avue-select>
				</el-form-item>
				<template v-if="isStatic">
					<el-form-item label="数据值" label-position="top">
						<el-button
							type="primary"
							icon="el-icon-edit"
							@click="openCode('data', '数据值')"
							>编辑数据值</el-button
						>
						&nbsp;
						<el-upload
							:show-file-list="false"
							:auto-upload="false"
							style="display: inline-block"
							accept=".xls,.xlsx"
							:on-change="handleImport"
						>
							<el-button icon="el-icon-upload" type="success"
								>导入数据(Excel)</el-button
							>
						</el-upload>
					</el-form-item>
				</template>
				<template v-else-if="isSql">
					<el-form-item label="数据源选择">
						<avue-select :dic="DIC.sql" v-model="db"></avue-select>
					</el-form-item>

					<el-form-item label="SQL语句" label-position="top">
						<el-tooltip
							effect="dark"
							content="如果要获取变量，直接写成函数返回sql语句即可"
							placement="top"
						>
							<i class="el-icon-info"></i>
						</el-tooltip>
						<monaco-editor
							v-model="sql"
							language="sql"
							style="width: 100%"
							height="100"
						></monaco-editor>
					</el-form-item>
				</template>
				<template v-else-if="isApi">
					<el-form-item label="接口地址">
						<avue-input v-model="activeObj.url"></avue-input>
					</el-form-item>
					<el-form-item label="请求方式">
						<avue-select
							v-model="activeObj.dataMethod"
							:dic="dicOption.dataMethod"
						></avue-select>
					</el-form-item>
				</template>
				<template v-else-if="isWs">
					<el-form-item label="WS地址">
						<el-input v-model="activeObj.wsUrl"> </el-input>
					</el-form-item>
				</template>
				<template v-else-if="isRecord">
					<el-form-item label="数据集选择">
						<avue-select
							:dic="DIC.data"
							v-model="activeObj.record"
						></avue-select>
					</el-form-item>
				</template>
				<el-form-item label="请求配置" v-if="isWs || isApi">
					<el-tabs class="menu__tabs" v-model="dataTabs">
						<el-tab-pane label="请求参数（Body）" name="0">
							<template v-if="dataTabs == 0">
								<el-radio-group
									v-if="
										['post', 'put'].includes(
											activeObj.dataMethod
										)
									"
									v-model="activeObj.dataQueryType"
								>
									<el-radio label="json">JSON数据</el-radio>
									<el-radio label="form">FORM表单</el-radio>
								</el-radio-group>
								<monaco-editor
									v-model="activeObj.dataQuery"
									language="javascript"
									disabled
									height="100"
								></monaco-editor>
								<el-button
									type="primary"
									icon="el-icon-edit"
									@click="openCode('dataQuery', '请求参数')"
									>编辑</el-button
								>
							</template>
						</el-tab-pane>
						<el-tab-pane
							label="请求头（Headers）"
							name="1"
							v-if="isApi"
						>
							<template v-if="dataTabs == 1">
								<monaco-editor
									v-model="activeObj.dataHeader"
									language="javascript"
									disabled
									height="100"
								></monaco-editor>
								<el-button
									type="primary"
									icon="el-icon-edit"
									@click="openCode('dataHeader', '请求头')"
									>编辑</el-button
								>
							</template>
						</el-tab-pane>
					</el-tabs>
				</el-form-item>
				<el-form-item label="过滤器">
					<monaco-editor
						v-model="activeObj.dataFormatter"
						language="javascript"
						disabled
						height="100"
					></monaco-editor>
					<el-button
						type="primary"
						icon="el-icon-edit"
						@click="openCode('dataFormatter', '编辑过滤器')"
						>编辑</el-button
					>
				</el-form-item>
				<el-form-item label="响应数据">
					<monaco-editor
						v-model="dataRes"
						disabled
						height="200"
					></monaco-editor>
				</el-form-item>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button
						type="primary"
						icon="el-icon-refresh"
						@click="handleRes"
						>请求数据</el-button
					>
				</span>
			</template>
		</el-dialog>
	</div>
</template>
<script>
import MonacoEditor from "@/datav/page/components/editor.vue";
import layer from "./group/layer.vue";
import top from "./group/top.vue";
import headers from "./group/header.vue";
import imglist from "./group/imglist.vue";
import contentmenu from "./group/contentmenu.vue";
import codeedit from "./group/code.vue";
import { dicOption } from "@/datav/option/config";
import init from "@/datav/mixins/";
import { createFile } from "@/datav/utils/utils";
import components from "@/datav/option/components";
import { SketchRule } from "vue3-sketch-ruler";
import "vue3-sketch-ruler/lib/style.css";
import dataSourceService from "@/api/database/dataSourceService";
import dataSetService from "@/api/database/dataSetService";
import crypto from "@/datav/utils/crypto";

export default {
	mixins: [init, components],
	data() {
		return {
			currentHistoryIndex: -1,
			menuId: "avue-data-menu",
			menuShow: true,
			paramsShow: true,
			globShow: false,
			show: false,
			cacheList: {
				timer: null,
				nav: null,
				copy: null,
				history: [],
			},
			keys: {
				ctrl: false,
			},
			dataRes: "",
			db: "",
			sql: "",
			nav: [],
			DIC: {
				sql: [],
				data: [],
			},
			loading: "",
			childProps: {
				label: "name",
				value: "index",
			},
			key: "",
			menuFlag: true,
			code: {
				title: "",
				box: false,
				type: "",
				obj: "",
			},
			form: {},
			dicOption: dicOption,
			menuTabs: "0",
			dataTabs: "0",
			// 标尺
			width: document.body.clientWidth - 550,
			height: document.body.clientHeight - 104,
			scale: 0.94,
			startX: 0,
			startY: 0,
			palette: {
				bgColor: "#18181c",
				longfgColor: "#BABBBC",
				shortfgColor: "#9C9C9C",
				fontColor: "#fff",
				shadowColor: "#18181c",
				lineColor: "#EB5648",
				borderColor: "#B5B5B5",
				cornerActiveColor: "#fff",
			},
			lines: {
				h: [],
				v: [],
			},
			thick: 20,
		};
	},
	components: {
		MonacoEditor,
		imglist,
		layer,
		codeedit,
		top,
		headers,
		contentmenu,
		SketchRule,
	},
	computed: {
		shadow() {
			return {
				x: 0,
				y: 0,
				width: this.width,
				height: this.height,
			};
		},
		// 能否撤销
		canUndo() {
			return this.currentHistoryIndex > 0;
		},
		canRedo() {
			return this.cacheList.history.length > this.currentHistoryIndex + 1;
		},
		isKeysCtrl() {
			return this.keys.ctrl == true;
		},
		isStatic() {
			return this.activeObj.dataType == 0;
		},
		isApi() {
			return this.activeObj.dataType == 1;
		},
		isSql() {
			return this.activeObj.dataType == 2;
		},
		isWs() {
			return this.activeObj.dataType === 3;
		},
		isRecord() {
			return this.activeObj.dataType == 4;
		},
		isFolder() {
			return this.activeObj.children;
		},
		isActive() {
			return this.activeIndex;
		},
		isSelectActive() {
			return this.active.length > 1;
		},
		childList() {
			return this.list.filter((ele) => {
				if (ele.children) return false;
				let component = ele.component || {};
				return !["tabs"].includes(component.prop);
			});
		},
		activeComponent() {
			return this.activeObj.component || {};
		},
		activeOption() {
			return this.activeObj.option || {};
		},
		activeObj() {
			let item = this.findList(this.activeIndex) || {};
			if (!item.child) item.child = {};
			return item;
		},
		activeList() {
			let result = [];
			this.active.forEach((ele) => {
				let item = this.findnav(ele);
				result.push(item.item);
			});
			return result;
		},
		canvasStyle() {
			return {
				width: this.setPx(this.width),
				height: this.setPx(this.height),
				transform: `scale(${this.scale})`,
			};
		},
	},
	watch: {
		nav: {
			handler(val) {
				this.recordHistoryCache(val);
			},
			deep: true,
		},
		activeObj: {
			handler() {
				if (this.activeObj.sql && this.isSql) {
					let mode = JSON.parse(crypto.decrypt(this.activeObj.sql));
					this.db = mode.id;
					this.sql = mode.sql;
				} else {
					this.db = "";
					this.sql = "";
				}
			},
			deep: true,
		},
		"activeObj.dataType"() {
			this.dataTabs = "0";
		},
		activeOverIndex(n, o) {
			[o, n].forEach((ele, index) => {
				if (!ele) return;
				this.setActive(ele, index === 1, "setOverActive");
			});
		},
		active(n, o) {
			[o, n].forEach((ele, index) => {
				ele.forEach((item) => {
					this.setActive(item, index === 1, "setActive");
				});
			});
			// 初始化选项卡
			this.menuTabs = "0";
		},
	},
	created() {
		this.initDataList();
	},
	mounted() {
		setTimeout(() => {
			this.initFun();
			this.initSize();
			this.listenKey();
		});
	},
	methods: {
		handleCopyIndex() {
			this.$Clipboard({
				text: this.activeObj.index,
			})
				.then(() => {
					this.$message.success("复制成功");
				})
				.catch(() => {
					this.$message.error("复制失败");
				});
		},
		handleTabClick(tab) {
			if (tab.index == "1") {
				this.handleRes(false);
			}
		},
		handleImport(file) {
			this.$Export.xlsx(file.raw).then((data) => {
				this.activeObj.data = data.results;
				this.$message.success("导入成功");
				this.handleRes();
			});
		},
		handleRefresh() {
			return this.$refs.container.handleRefresh();
		},
		handleRes(tip = true) {
			if (this.isSql) {
				this.activeObj.sql = crypto.encrypt(
					JSON.stringify({
						id: this.db,
						sql: this.sql,
					})
				);
			}
			this.handleRefresh().then((res = {}) => {
				if (!this.validatenull(res)) {
					this.dataRes = JSON.stringify(res, null, 4);
				} else {
					this.dataRes = "";
				}
				if (tip) this.$message.success("请求数据成功");
			});
		},
		handleParams(type, obj) {
			const deepList = (list, flag) => {
				list.forEach((ele) => {
					ele[type] = flag;
					if (ele.children) deepList(ele.children, flag);
				});
			};
			if (obj) {
				obj[type] = !obj[type];
				deepList([obj], obj[type]);
			} else {
				this.active.forEach((ele) => {
					let { item } = this.findnav(ele);
					item[type] = !item[type];
					deepList([item], item[type]);
				});
			}
			this.handleInitActive();
		},
		handleSetting() {
			this.dataTabs = 0;
			this.dataRes = "";
			this.handleRes(false);
			this.show = true;
		},
		initDataList() {
			dataSourceService.list().then((data) => {
				this.DIC.sql = data.records.map((ele) => {
					return {
						label: ele.name,
						value: ele.id,
					};
				});
			});
			dataSetService.list().then((data) => {
				this.DIC.data = data.records.map((ele) => {
					return {
						label: ele.name,
						value: ele.id,
					};
				});
			});
		},
		closeCode(value) {
			if (this.configData.includes(this.code.type)) {
				this.config[this.code.type] = value;
			} else {
				this.activeObj[this.code.type] = value;
			}
			this.handleRes(false);
		},
		openCode(type, title) {
			this.code.type = type;
			this.code.title = title;
			if (this.configData.includes(type)) {
				this.code.obj = this.config[type];
			} else {
				this.code.obj = this.activeObj[type];
			}
			this.code.box = true;
		},
		initFun() {
			["setScale"].forEach((ele) => {
				this[ele] = this.$refs.container[ele];
			});
		},
		// 右键菜单
		handleContextMenu(item = {}, done) {
			if (!item.index || this.isKeysCtrl) return;
			else if (!this.isSelectActive) {
				this.active = [item.index];
				this.activeIndex = item.index;
			}
			done();
		},
		//监听键盘的按键
		listenKey() {
			let section = this.$refs.section;
			section.onkeydown = (e) => {
				const keyCode = e.keyCode;
				e.preventDefault();
				if (keyCode == 17) {
					this.keys.ctrl = true;
				} else if (keyCode == 76 && this.isKeysCtrl) {
					if (!this.activeObj) return;
					this.handleParams("lock");
					this.handleInitActive();
				} else if (keyCode == 67 && this.isKeysCtrl) {
					if (!this.activeObj) return;
					this.$refs.contentmenu.handleCopy((fn) => {
						this.cacheList.copy = fn;
						this.$message.success("复制组件成功");
					});
				} else if (keyCode == 86 && this.isKeysCtrl) {
					if (!this.cacheList.copy) return;
					let active = [];
					this.cacheList.copy.forEach((ele) => {
						active = active.concat(ele());
					});
					setTimeout(() => this.selectNav(active));
					this.$message.success("粘贴组件成功");
				} else if (keyCode == 90 && this.isKeysCtrl) {
					this.editorUndo();
				} else if (keyCode == 89 && this.isKeysCtrl) {
					this.editorRedo();
				} else if (keyCode == 83 && this.isKeysCtrl) {
					this.$refs.headers.handleBuild();
				} else if (keyCode == 8 || keyCode == 46) {
					this.$refs.contentmenu.handleDel();
				}
			};
			section.onkeyup = (e) => {
				const keyCode = e.keyCode;
				if (keyCode == 17) {
					this.keys.ctrl = false;
				}
			};
		},
		setActive(val, result, fun) {
			const obj = this.$refs.container.getListRef(val);
			if (obj) obj[fun](result);
		},
		//批量成组
		handleFolder() {
			let folder = createFile();
			this.active.forEach((index) => {
				let { itemList, itemIndex } = this.findnav(index);
				let obj = itemList.splice(itemIndex, 1)[0];
				folder.children.push(obj);
			});
			this.nav.push(folder);
			this.handleInitActive();
		},
		//批量删除
		handleDeleteSelect() {
			this.$confirm(`是否批量删除所选图层?`, "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			}).then(() => {
				this.active.forEach((index) => {
					let { itemList, itemIndex } = this.findnav(index);
					itemList.splice(itemIndex, 1);
				});
				this.handleInitActive();
			});
		},
		validProp(name) {
			return this.dicOption[name].includes(this.activeComponent.prop);
		},
		formatTooltip(val) {
			return parseInt(val);
		},
		//打开图库
		handleOpenImg(item, type) {
			this.$refs.imglist.openImg(item, type);
		},
		//图库框回调赋值
		handleSetimg(val, type) {
			let params = type.split(".")[1];
			if (type.includes("config")) {
				this.config[params] = val;
			} else if (type.includes("activeObj.data.value")) {
				this.activeObj.data.value = val;
			} else if (type.includes("activeObj.data")) {
				this.activeObj.data = val;
			} else if (type.includes("activeObj")) {
				this.activeObj[params] = val;
			} else if (type.includes("activeOption")) {
				this.activeOption[params] = val;
			}
		},
		handleScroll() {
			this.$nextTick(() => {
				const screensRect =
					this.$refs.screensRef.getBoundingClientRect();
				const canvasRect = this.$refs.canvas.getBoundingClientRect();
				// 标尺开始的刻度
				const startX =
					(screensRect.left + this.thick - canvasRect.left) /
					this.scale;
				const startY =
					(screensRect.top + this.thick - canvasRect.top) /
					this.scale;
				this.startX = startX >> 0;
				this.startY = startY >> 0;
			});
		},
		// 控制缩放值
		handleWheel(e) {
			if (e.ctrlKey || e.metaKey) {
				e.preventDefault();
				const nextScale = parseFloat(
					Math.max(0.2, this.scale - e.deltaY / 500).toFixed(2)
				);
				this.scale = nextScale;
			}
			this.$nextTick(() => {
				this.handleScroll();
			});
		},
		// 初始化标尺数值
		initSize() {
			// 滚动居中
			let containerRect = this.$refs.containerRef.getBoundingClientRect();
			let screensRect = this.$refs.screensRef.getBoundingClientRect();
			this.$refs.screensRef.scrollLeft = containerRect.width / 2 - 10;
			this.$refs.screensRef.scrollTop = containerRect.height / 2 - 50;
		},
		selectNav(item) {
			if (this.isKeysCtrl) {
				if (Array.isArray(item)) {
					this.active = this.active.concat(item);
				} else {
					this.active.push(item);
				}
			}
			if (Array.isArray(item)) {
				this.active = item;
				this.activeIndex = item[item.length - 1];
			} else if (this.active.includes(item)) {
				this.activeIndex = item;
			} else {
				this.active = [item];
				this.activeIndex = item;
			}
		},
		recordHistoryCache(val) {
			const debounce = (func, delay) => {
				return () => {
					let context = this;
					let args = arguments;
					clearTimeout(this.cacheList.timer);
					this.cacheList.timer = setTimeout(() => {
						func.apply(context, args);
					}, delay);
				};
			};
			const callback = () => {
				let nav = JSON.stringify(val);
				if (nav != this.cacheList.nav) {
					this.cacheList.nav = nav;
					this.addHistoryCache(val);
				}
			};
			debounce(callback, 300)();
		},
		addHistoryCache(val) {
			if (this.currentHistoryIndex + 1 < this.cacheList.history.length) {
				this.cacheList.history.splice(this.currentHistoryIndex + 1);
			}
			this.cacheList.history.push({
				nav: this.deepClone(val),
			});
			this.cacheList.history.splice(100);
			this.currentHistoryIndex++;
		},
		editorUndo() {
			if (!this.canUndo) return;
			this.currentHistoryIndex--;
			this.recoveryHistoryCache();
		},
		editorRedo() {
			if (!this.canRedo) return;
			this.currentHistoryIndex++;
			this.recoveryHistoryCache();
		},
		recoveryHistoryCache() {
			const prevState = this.cacheList.history[this.currentHistoryIndex];
			this.nav = this.deepClone(prevState.nav);
			this.cacheList.nav = JSON.stringify(prevState.nav);
		},
	},
};
</script>
<style lang="scss">
@import "../styles/style.scss";
.screens {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	overflow: auto;
}

.screen-container {
	position: relative;
	width: 5000px;
	height: 3000px;
	background: url("../../datav/img/screen.png") repeat;
}

.dragghanle {
	cursor: pointer;
}
.canvas {
	position: absolute;
	top: 50%;
	left: 50%;
}
.section {
	flex: 1;
	overflow: hidden;
	position: relative;
}
</style>
