<template>
	<el-dialog :title="!dataForm.id ? '新建' : isDetail ? '详情' : '编辑'" :close-on-click-modal="false"
		:visible.sync="visible" class="NCC-dialog NCC-dialog_center" lock-scroll width="960px">
		<el-tabs v-model="mdxxTab" class="mdxx-form-tabs" @tab-click="onMdxxTabClick">
			<el-tab-pane label="基础信息" name="base">
		<el-row :gutter="15">
			<el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right"
				:disabled="!!isDetail" :rules="rules">
				<!-- 基础信息字段 -->
				<el-col :span="24" v-if="false">
					<el-form-item label="主键" prop="id">
						<el-input v-model="dataForm.id" />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="门店编码" prop="mdbm">
						<el-input v-model="dataForm.mdbm" placeholder="请输入" clearable />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="店名" prop="dm">
						<el-input v-model="dataForm.dm" placeholder="请输入" clearable />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="地址" prop="dz">
						<el-input v-model="dataForm.dz" placeholder="请输入完整地址" clearable>
							<el-button slot="append" icon="el-icon-location-outline"
								@click="handleOpenLocation">地图定位</el-button>
						</el-input>
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="经度" prop="longitude">
						<el-input v-model="dataForm.longitude" readonly placeholder="请通过地图定位选择" />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="纬度" prop="latitude">
						<el-input v-model="dataForm.latitude" readonly placeholder="请通过地图定位选择" />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="电子围栏">
						<div class="fence-status-bar">
							<el-tag :type="dataForm.fencePolygons && dataForm.fencePolygons.length ? 'success' : 'info'"
								size="medium">
								{{ (dataForm.fencePolygons && dataForm.fencePolygons.length) ? '已设置围栏 (1块)' : '未设置围栏' }}
							</el-tag>
							<el-button type="primary" size="mini" icon="el-icon-edit" class="fence-action-btn"
								:disabled="!dataForm.longitude || !dataForm.latitude" @click="handleOpenFence">
								设置围栏
							</el-button>
							<span v-if="!dataForm.longitude" class="hint-text">（请先完成地图定位）</span>
						</div>
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="正常打卡方式">
						<div class="att-punch-check-row">
							<el-checkbox :true-label="1" :false-label="0"
								v-model="dataForm.attendanceCheckFence">范围打卡（电子围栏）</el-checkbox>
							<el-checkbox :true-label="1" :false-label="0" v-model="dataForm.attendanceCheckWifi">Wi-Fi
								打卡</el-checkbox>
						</div>
						<div class="att-punch-hint">
							可同时勾选：<strong>两者都勾选</strong>时，员工在打卡<strong>范围内</strong>或满足<strong>门店
								Wi-Fi 规则</strong>，<strong>满足其一</strong>即可；仅勾选一项则只校验该项。
							Wi-Fi 以<strong>成对表</strong>维护（SSID + BSSID）；可选「校验对应」防同名热点，拿不到 BSSID 时需依赖<strong>围栏
								+ SSID</strong>。
						</div>
					</el-form-item>
				</el-col>
				<el-col :span="24" v-if="Number(dataForm.attendanceCheckWifi) === 1">
					<el-form-item label="Wi-Fi 白名单">
						<div v-if="!isDetail" class="wifi-pair-toolbar">
							<el-button type="primary" size="small" icon="el-icon-plus"
								@click="addWifiPair">添加一行</el-button>
						</div>
						<div class="wifi-pair-table">
							<div class="wifi-pair-head">
								<span class="wifi-pair-col-ssid">Wi-Fi 名称 (SSID)</span>
								<span class="wifi-pair-col-bssid">BSSID（路由器 MAC）</span>
								<span v-if="!isDetail" class="wifi-pair-col-act"></span>
							</div>
							<div v-for="(row, index) in dataForm.attendanceWifiPairList" :key="'wp-' + index"
								class="wifi-pair-row">
								<el-input v-model="row.ssid" size="small" :disabled="isDetail" maxlength="64"
									placeholder="与手机显示一致" />
								<el-input v-model="row.bssid" size="small" :disabled="isDetail" maxlength="64"
									placeholder="如 aa:bb:cc:dd:ee:ff" />
								<div v-if="!isDetail" class="wifi-pair-col-act">
									<el-button type="text" size="small" class="wifi-pair-del"
										@click="removeWifiPair(index)">删除</el-button>
								</div>
							</div>
							<div v-if="!dataForm.attendanceWifiPairList.length" class="store-tags-empty">请至少添加一行；建议 SSID
								与 BSSID 成对填写</div>
						</div>
					</el-form-item>
				</el-col>
				<el-col :span="24" v-if="Number(dataForm.attendanceCheckWifi) === 1">
					<el-form-item label=" ">
						<el-checkbox :true-label="1" :false-label="0" v-model="dataForm.attendanceWifiVerifyPair">
							校验 SSID 与 BSSID 为同一 AP（防同名热点）
						</el-checkbox>
						<div class="att-punch-hint wifi-verify-hint">
							<strong>开启</strong>：能获取 BSSID 时必须与表中<strong>同一行</strong>的 SSID、BSSID 同时一致；获取不到 BSSID
							时须<strong>在电子围栏内</strong>且 SSID 命中。<strong>关闭</strong>：当前网络的 SSID 或 BSSID
							命中表中<strong>任意一行</strong>的任一字段即可。
						</div>
					</el-form-item>
				</el-col>

				<!-- 其他业务字段 -->
				<el-col :span="12">
					<el-form-item label="城市" prop="cs">
						<el-input v-model="dataForm.cs" placeholder="请输入" clearable />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="最新状态" prop="zxzt">
						<el-select v-model="dataForm.zxzt" placeholder="请选择" clearable :style='{ "width": "100%" }'>
							<el-option v-for="(item, index) in zxztOptions" :key="index" :label="item.fullName"
								:value="item.id"></el-option>
						</el-select>
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="门店类别" prop="storeCategory">
						<el-select v-model="dataForm.storeCategory" placeholder="请选择" clearable
							:style='{ "width": "100%" }'>
							<el-option v-for="(item, index) in storeCategoryOptions" :key="index" :label="item.Name"
								:value="item.Value"></el-option>
						</el-select>
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="门店类型" prop="storeType">
						<el-select v-model="dataForm.storeType" placeholder="请选择" clearable
							:style='{ "width": "100%" }'>
							<el-option v-for="(item, index) in storeTypeOptions" :key="index" :label="item.Name"
								:value="item.Value"></el-option>
						</el-select>
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="姓名" prop="xm">
						<el-input v-model="dataForm.xm" placeholder="请输入" clearable />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="电话号码" prop="dhhm">
						<el-input v-model="dataForm.dhhm" placeholder="请输入" clearable />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="门店图片" prop="storeImages">
						<NCC-UploadImg v-model="dataForm.storeImages" :fileSize="5" sizeUnit="MB" :limit="9"
							:disabled="!!isDetail" />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="门店介绍" prop="storeDescription">
						<el-input v-model="dataForm.storeDescription" type="textarea" :rows="4" maxlength="1000"
							show-word-limit placeholder="请输入门店介绍" />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="营业时间设置" prop="businessHours">
						<el-input v-model="dataForm.businessHours" type="textarea" :rows="3" maxlength="500"
							show-word-limit placeholder="请输入营业时间设置" />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="交通提示" prop="trafficTips">
						<el-input v-model="dataForm.trafficTips" type="textarea" :rows="3" maxlength="500"
							show-word-limit placeholder="请输入交通提示" />
					</el-form-item>
				</el-col>
				<el-col :span="24">
					<el-form-item label="门店标签" prop="storeTags">
						<div class="store-tags-editor">
							<div class="store-tags-list">
								<el-tag v-for="(tag, index) in dataForm.storeTags" :key="`${tag}-${index}`"
									:disable-transitions="false" :closable="!isDetail" @close="handleRemoveTag(index)">
									{{ tag }}
								</el-tag>
								<span v-if="!dataForm.storeTags.length" class="store-tags-empty">暂无标签</span>
							</div>
							<div class="store-tags-action-row" v-if="!isDetail">
								<el-input v-if="inputTagVisible" ref="tagInput" v-model="inputTagValue"
									class="input-new-tag" size="small" maxlength="20" placeholder="请输入标签内容"
									@keyup.enter.native="handleInputTagConfirm" @blur="handleInputTagConfirm" />
								<el-button v-else class="button-new-tag tag-action-btn" size="small" icon="el-icon-plus"
									@click="showTagInput">
									新增标签
								</el-button>
							</div>
						</div>
					</el-form-item>
				</el-col>
			</el-form>
		</el-row>
			</el-tab-pane>
			<el-tab-pane v-if="dataForm.id" label="版本记录" name="version" lazy>
				<div class="mdxx-version-toolbar">
					<el-button size="small" icon="el-icon-refresh" @click="fetchStoreVersionLogs">刷新</el-button>
				</div>
				<NCC-table v-loading="versionLoading" :data="versionList" border class="mdxx-version-table">
					<el-table-column label="" width="40" align="center">
						<template slot-scope="scope">
							<i class="el-icon-coin" :class="versionRowIconClass(scope.row.versionNo)" />
						</template>
					</el-table-column>
					<el-table-column prop="versionNo" label="版本号" width="72" />
					<el-table-column prop="validFrom" label="修改时间" width="168" :show-overflow-tooltip="true" />
					<el-table-column prop="validTo" label="生效至" width="168" :show-overflow-tooltip="true">
						<template slot-scope="scope">
							<span>{{ scope.row.validTo || '当前' }}</span>
						</template>
					</el-table-column>
					<el-table-column prop="dm" label="店名快照" min-width="120" :show-overflow-tooltip="true">
						<template slot-scope="scope">
							<span>{{ scope.row.dm || '无' }}</span>
						</template>
					</el-table-column>
					<el-table-column prop="storeType" label="门店类型" width="88" :show-overflow-tooltip="true">
						<template slot-scope="scope">
							<span>{{ scope.row.storeType != null ? scope.row.storeType : '无' }}</span>
						</template>
					</el-table-column>
					<el-table-column prop="storeCategory" label="门店类别" width="88" :show-overflow-tooltip="true">
						<template slot-scope="scope">
							<span>{{ scope.row.storeCategory != null ? scope.row.storeCategory : '无' }}</span>
						</template>
					</el-table-column>
					<el-table-column prop="zxzt" label="状态" width="72" :show-overflow-tooltip="true">
						<template slot-scope="scope">
							<span>{{ scope.row.zxzt || '无' }}</span>
						</template>
					</el-table-column>
					<el-table-column prop="changeTrigger" label="触发" width="140" :show-overflow-tooltip="true" />
					<el-table-column prop="operatorUserName" label="操作人" width="100" :show-overflow-tooltip="true" />
					<el-table-column label="快照" width="100" align="left">
						<template slot-scope="scope">
							<el-button type="text" size="small" @click="openVersionJsonDialog(scope.row)">查看 JSON</el-button>
						</template>
					</el-table-column>
					<el-table-column v-if="!isDetail" label="操作" width="88" align="left">
						<template slot-scope="scope">
							<el-button type="text" size="small" class="version-restore-btn"
								@click="handleRestoreStoreVersion(scope.row)">还原</el-button>
						</template>
					</el-table-column>
				</NCC-table>
				<pagination
					:total="versionTotal"
					:page.sync="versionParams.currentPage"
					:limit.sync="versionParams.pageSize"
					@pagination="fetchStoreVersionLogs"
				/>
			</el-tab-pane>
		</el-tabs>
		<span slot="footer" class="dialog-footer">
			<el-button @click="visible = false">取 消</el-button>
			<el-button type="primary" @click="dataFormSubmit()" v-if="!isDetail">确 定</el-button>
		</span>

		<!-- 定位弹窗 -->
		<el-dialog title="门店地图定位" :visible.sync="locationVisible" width="800px" append-to-body class="map-dialog">
			<div class="map-container-wrapper">
				<div class="map-header-bar">
					<span>在地图上点击以选择门店位置，或通过地址检索定位</span>
					<div class="coordinate-info" v-if="tempMarker.lng">
						当前选择：{{ tempMarker.lng.toFixed(6) }}, {{ tempMarker.lat.toFixed(6) }}
					</div>
				</div>
				<div class="location-search-bar">
					<el-input v-model="locationSearchKeyword" placeholder="输入地址或关键词检索（如：成都市武侯区紫荆北路182号）" clearable
						size="small" class="search-input" @keyup.enter.native="handleSearchLocation">
						<el-button slot="append" icon="el-icon-search" @click="handleSearchLocation"
							:loading="locationSearchLoading">检索</el-button>
					</el-input>
				</div>
				<div id="location-map" class="map-canvas"></div>
			</div>
			<span slot="footer" class="dialog-footer">
				<el-button @click="locationVisible = false">取 消</el-button>
				<el-button type="primary" @click="confirmLocation" :disabled="!tempMarker.lng">确 定</el-button>
			</span>
		</el-dialog>

		<!-- 围栏设置弹窗 -->
		<el-dialog title="设置电子围栏" :visible.sync="fenceVisible" width="1000px" append-to-body class="map-dialog">
			<div class="fence-editor-layout">
				<div class="map-side-panel">
					<div class="panel-header">图形管理 ({{ fenceBuffer.length }})</div>
					<div class="shape-list">
						<div v-for="(shape, index) in fenceBuffer" :key="index" class="shape-item">
							<i :class="getShapeIcon(shape.type)"></i>
							<span class="shape-name">{{ getShapeName(shape.type) }} {{ index + 1 }}</span>
							<el-button type="text" icon="el-icon-delete" class="delete-btn"
								@click="removeBufferShape(index)"></el-button>
						</div>
						<div v-if="!fenceBuffer.length" class="empty-text">暂无图形，请在右侧绘制</div>
					</div>
					<div class="panel-footer">
						<p class="warning-text" v-if="fenceBuffer.length > 1">
							<i class="el-icon-warning"></i> 注意：最终只能保留1个围栏
						</p>
					</div>
				</div>
				<div class="map-main-area">
					<div class="map-toolbar">
						<div v-for="tool in fenceTools" :key="tool.id" class="tool-btn"
							:class="{ active: activeFenceTool === tool.id }" @click="changeFenceTool(tool.id)">
							<span class="tool-icon" :class="'tool-icon--' + tool.id"></span>
							<span class="tool-label">{{ tool.name }}</span>
						</div>
					</div>
					<div id="fence-map" class="map-canvas"></div>
				</div>
			</div>
			<span slot="footer" class="dialog-footer">
				<div class="footer-hint" v-if="fenceBuffer.length > 1">请删除多余图形，仅保留一个围栏后再保存</div>
				<el-button @click="fenceVisible = false">取 消</el-button>
				<el-button type="primary" @click="confirmFence" :disabled="fenceBuffer.length !== 1">确 定 保 存</el-button>
			</span>
		</el-dialog>

		<el-dialog :title="versionJsonTitle" :visible.sync="versionJsonVisible" width="720px" append-to-body
			class="NCC-dialog version-json-dialog" lock-scroll>
			<pre class="version-json-pre">{{ versionJsonText }}</pre>
			<span slot="footer" class="dialog-footer">
				<el-button @click="versionJsonVisible = false">关 闭</el-button>
			</span>
		</el-dialog>
	</el-dialog>
</template>

<script>
import request from '@/utils/request'
import { getStoreProfileVersionLogs, restoreStoreProfileVersion } from '@/api/extend/storeProfileVersion'

// 腾讯地图 WebService API Key（与地图脚本共用，需在腾讯控制台开启 WebServiceAPI）
const TMAP_WS_KEY = 'YRXBZ-NEV6T-K7SXH-VJPMF-G5IQF-F3FCJ'

// JSONP 调用（绕过 CORS，腾讯 WebService API 前端需用 JSONP）
function jsonp(url) {
	return new Promise((resolve, reject) => {
		const cbName = '_tmap_jsonp_' + Date.now() + '_' + Math.random().toString(36).slice(2);
		const script = document.createElement('script');
		script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'output=jsonp&callback=' + cbName;
		window[cbName] = function (res) {
			if (script.parentNode) script.parentNode.removeChild(script);
			delete window[cbName];
			resolve(res);
		};
		script.onerror = function () {
			if (script.parentNode) script.parentNode.removeChild(script);
			delete window[cbName];
			reject(new Error('JSONP request failed'));
		};
		document.body.appendChild(script);
	});
}

export default {
	data() {
		return {
			loading: false,
			visible: false,
			isDetail: false,
			dataForm: {
				id: undefined,
				mdbm: undefined,
				dm: undefined,
				dz: undefined,
				cs: undefined,
				xm: undefined,
				dhhm: undefined,
				zxzt: undefined,
				storeCategory: undefined,
				storeType: undefined,
				longitude: null,
				latitude: null,
				fencePolygons: [],
				storeImages: [],
				storeDescription: '',
				storeTags: [],
				businessHours: '',
				trafficTips: '',
				attendanceCheckFence: 0,
				attendanceCheckWifi: 0,
				attendanceWifiPairList: [],
				attendanceWifiVerifyPair: 0,
			},
			rules: {
				mdbm: [{ required: true, message: '请输入门店编码', trigger: 'blur' }],
				dm: [{ required: true, message: '请输入店名', trigger: 'blur' }],
				dz: [{ required: true, message: '请输入地址', trigger: 'blur' }],
			},
			zxztOptions: [{ fullName: '开店', id: '开店' }, { fullName: '闭店', id: '闭店' }],
			storeCategoryOptions: [],
			storeTypeOptions: [],

			// 定位弹窗相关
			locationVisible: false,
			locationMap: null,
			locationMarkerLayer: null,
			tempMarker: { lng: null, lat: null },
			locationSearchKeyword: '',
			locationSearchLoading: false,

			// 围栏弹窗相关
			fenceVisible: false,
			fenceMap: null,
			fenceEditor: null,
			fenceDrawLayers: {},     // 绘图图层（只保留多边形 / 圆形）
			fenceDisplayLayer: null, // 展示层（显示 buffer 中的图形）
			activeFenceTool: 'polygon',
			fenceBuffer: [], // 临时存放绘制的多个图形：[{ id, type, points, geometry }]
			// 目前仅支持多边形 / 圆形两个工具，矩形与椭圆功能取消
			fenceTools: [
				{ id: 'polygon', name: '多边形' },
				{ id: 'circle', name: '圆形' }
			],
			inputTagVisible: false,
			inputTagValue: '',

			mdxxTab: 'base',
			versionLoading: false,
			versionList: [],
			versionTotal: 0,
			versionParams: { currentPage: 1, pageSize: 20 },
			versionJsonVisible: false,
			versionJsonTitle: '',
			versionJsonText: ''
		}
	},
	created() {
		this.loadStoreCategoryOptions();
		this.loadStoreTypeOptions();
	},
	methods: {
		loadStoreCategoryOptions() {
			request({ url: '/api/Extend/lqmdxx/Selector/StoreCategory', method: 'get' })
				.then(res => { this.storeCategoryOptions = res.data || []; });
		},
		loadStoreTypeOptions() {
			request({ url: '/api/Extend/lqmdxx/Selector/StoreType', method: 'get' })
				.then(res => { this.storeTypeOptions = res.data || []; });
		},

		onMdxxTabClick(tab) {
			if (tab.name === 'version' && this.dataForm.id) {
				this.fetchStoreVersionLogs();
			}
		},
		fetchStoreVersionLogs() {
			if (!this.dataForm.id) return;
			this.versionLoading = true;
			getStoreProfileVersionLogs({
				storeId: this.dataForm.id,
				currentPage: this.versionParams.currentPage,
				pageSize: this.versionParams.pageSize
			}).then(res => {
				const rawList = (res.data && res.data.list) || [];
				// 后端 Newtonsoft DefaultContractResolver 输出 PascalCase，表格与还原需统一为 camelCase
				this.versionList = rawList.map(r => this.normalizeStoreProfileVersionRow(r));
				this.versionTotal = (res.data.pagination && res.data.pagination.total) || 0;
			}).catch(() => {
				this.versionList = [];
				this.versionTotal = 0;
			}).finally(() => {
				this.versionLoading = false;
			});
		},
		/** 门店版本行：兼容 API 返回 PascalCase */
		normalizeStoreProfileVersionRow(row) {
			if (!row) return row;
			const pick = (a, b) => (a !== undefined && a !== null ? a : b);
			return {
				id: pick(row.id, row.Id),
				storeId: pick(row.storeId, row.StoreId),
				versionNo: pick(row.versionNo, row.VersionNo),
				validFrom: pick(row.validFrom, row.ValidFrom),
				validTo: pick(row.validTo, row.ValidTo),
				operatorUserId: pick(row.operatorUserId, row.OperatorUserId),
				operatorUserName: pick(row.operatorUserName, row.OperatorUserName),
				changeTrigger: pick(row.changeTrigger, row.ChangeTrigger),
				dm: pick(row.dm, row.Dm),
				storeType: pick(row.storeType, row.StoreType),
				storeCategory: pick(row.storeCategory, row.StoreCategory),
				zxzt: pick(row.zxzt, row.Zxzt),
				dhhm: pick(row.dhhm, row.Dhhm),
				status: pick(row.status, row.Status),
				attendanceSnapshotJson: pick(row.attendanceSnapshotJson, row.AttendanceSnapshotJson),
				fullExtensionJson: pick(row.fullExtensionJson, row.FullExtensionJson)
			};
		},
		versionRowIconClass(versionNo) {
			const n = Number(versionNo) || 0;
			const m = n % 3;
			if (m === 0) return 'mdxx-version-icon mdxx-version-icon--primary';
			if (m === 1) return 'mdxx-version-icon mdxx-version-icon--success';
			return 'mdxx-version-icon mdxx-version-icon--muted';
		},
		openVersionJsonDialog(row) {
			const r = this.normalizeStoreProfileVersionRow(row);
			this.versionJsonTitle = '版本 ' + (r.versionNo != null ? r.versionNo : '') + ' 快照';
			let text = '';
			try {
				const att = r.attendanceSnapshotJson ? JSON.parse(r.attendanceSnapshotJson) : null;
				const full = r.fullExtensionJson ? JSON.parse(r.fullExtensionJson) : null;
				text = JSON.stringify({ attendanceSnapshotJson: att, fullExtensionJson: full }, null, 2);
			} catch (e) {
				text = JSON.stringify({
					attendanceSnapshotJson: r.attendanceSnapshotJson,
					fullExtensionJson: r.fullExtensionJson
				}, null, 2);
			}
			this.versionJsonText = text || '无';
			this.versionJsonVisible = true;
		},

		/** 将 GET LqMdxx 详情合并进 dataForm（init / 还原后刷新共用） */
		applyMdxxApiRaw(raw) {
			raw = raw || {};
			this.dataForm = {
				...this.dataForm,
				...raw,
				longitude: raw.longitude != null ? raw.longitude : (raw.Longitude != null ? raw.Longitude : this.dataForm.longitude),
				latitude: raw.latitude != null ? raw.latitude : (raw.Latitude != null ? raw.Latitude : this.dataForm.latitude)
			};
			const fpRaw = raw.fencePolygons != null ? raw.fencePolygons : (raw.fence_polygons != null ? raw.fence_polygons : raw.FencePolygons);
			if (typeof fpRaw === 'string') {
				try {
					this.dataForm.fencePolygons = JSON.parse(fpRaw) || [];
				} catch (e) {
					this.dataForm.fencePolygons = [];
				}
			} else if (Array.isArray(fpRaw)) {
				this.dataForm.fencePolygons = fpRaw;
			} else {
				this.dataForm.fencePolygons = Array.isArray(this.dataForm.fencePolygons) ? this.dataForm.fencePolygons : [];
			}
			this.dataForm.storeImages = this.parseJsonArray(raw.storeImages);
			this.dataForm.storeTags = this.parseJsonStringArray(raw.storeTags);
			this.dataForm.storeDescription = raw.storeDescription || '';
			this.dataForm.businessHours = raw.businessHours || '';
			this.dataForm.trafficTips = raw.trafficTips || '';
			const acf = raw.attendanceCheckFence != null ? Number(raw.attendanceCheckFence) : (raw.AttendanceCheckFence != null ? Number(raw.AttendanceCheckFence) : null);
			const acw = raw.attendanceCheckWifi != null ? Number(raw.attendanceCheckWifi) : (raw.AttendanceCheckWifi != null ? Number(raw.AttendanceCheckWifi) : null);
			this.dataForm.attendanceCheckFence = acf != null ? acf : 1;
			this.dataForm.attendanceCheckWifi = acw != null ? acw : 0;
			const avp = raw.attendanceWifiVerifyPair != null ? Number(raw.attendanceWifiVerifyPair) : (raw.AttendanceWifiVerifyPair != null ? Number(raw.AttendanceWifiVerifyPair) : null);
			this.dataForm.attendanceWifiVerifyPair = avp != null ? avp : 0;
			const apRaw = raw.attendanceWifiPairs != null ? raw.attendanceWifiPairs : raw.AttendanceWifiPairs;
			this.dataForm.attendanceWifiPairList = this.parseWifiPairList(apRaw);
		},

		handleRestoreStoreVersion(row) {
			if (this.isDetail) return;
			const r = this.normalizeStoreProfileVersionRow(row);
			const versionId = r && r.id;
			if (!versionId) {
				this.$message.error('缺少版本主键，请刷新版本列表后重试');
				return;
			}
			this.$confirm('确定将当前门店主档还原为该版本快照吗？未保存的编辑将丢失，并会新增一条版本记录。', '还原确认', {
				type: 'warning',
				confirmButtonText: '确定还原',
				cancelButtonText: '取消'
			}).then(() => {
				return restoreStoreProfileVersion({ versionId: versionId });
			}).then(() => {
				this.$message.success('已还原');
				this.fetchStoreVersionLogs();
				if (this.dataForm.id) {
					return request({ url: '/api/Extend/LqMdxx/' + this.dataForm.id, method: 'get' });
				}
				return Promise.resolve(null);
			}).then(res => {
				if (res && res.data) {
					this.applyMdxxApiRaw(res.data);
				}
			}).catch(err => {
				if (err === 'cancel' || err === 'close') return;
			});
		},

		init(id, isDetail) {
			this.dataForm.id = id || 0;
			this.visible = true;
			this.isDetail = isDetail || false;
			this.mdxxTab = 'base';
			this.versionParams.currentPage = 1;
			this.versionList = [];
			this.versionTotal = 0;
			this.inputTagVisible = false;
			this.inputTagValue = '';
			this.$nextTick(() => {
				this.$refs['elForm'].resetFields();
				if (this.dataForm.id) {
					request({ url: '/api/Extend/LqMdxx/' + this.dataForm.id, method: 'get' })
						.then(res => {
							this.applyMdxxApiRaw(res.data || {});
						});
				} else {
					// 新建时重置经纬度与围栏
					this.dataForm.longitude = null;
					this.dataForm.latitude = null;
					this.dataForm.fencePolygons = [];
					this.dataForm.storeImages = [];
					this.dataForm.storeDescription = '';
					this.dataForm.storeTags = [];
					this.dataForm.businessHours = '';
					this.dataForm.trafficTips = '';
					this.dataForm.attendanceCheckFence = 0;
					this.dataForm.attendanceCheckWifi = 0;
					this.dataForm.attendanceWifiPairList = [];
					this.dataForm.attendanceWifiVerifyPair = 0;
				}
			})
		},

		addWifiPair() {
			if (this.isDetail) return;
			this.dataForm.attendanceWifiPairList.push({ ssid: '', bssid: '' });
		},

		removeWifiPair(index) {
			if (this.isDetail) return;
			this.dataForm.attendanceWifiPairList.splice(index, 1);
		},

		parseWifiPairList(value) {
			const arr = this.parseJsonArray(value);
			if (!arr.length) return [];
			return arr.map((item) => {
				if (item && typeof item === 'object') {
					return {
						ssid: (item.ssid != null ? String(item.ssid) : (item.Ssid != null ? String(item.Ssid) : '')).trim(),
						bssid: (item.bssid != null ? String(item.bssid) : (item.Bssid != null ? String(item.Bssid) : '')).trim()
					};
				}
				return { ssid: '', bssid: '' };
			}).filter((p) => p.ssid || p.bssid);
		},

		parseJsonArray(value) {
			if (!value) return [];
			if (Array.isArray(value)) return value;
			if (typeof value === 'string') {
				try {
					const parsed = JSON.parse(value);
					return Array.isArray(parsed) ? parsed : [];
				} catch (e) {
					return [];
				}
			}
			return [];
		},

		parseJsonStringArray(value) {
			const parsed = this.parseJsonArray(value);
			return parsed.map(item => (item || '').toString().trim()).filter(Boolean);
		},

		showTagInput() {
			this.inputTagVisible = true;
			this.$nextTick(() => {
				if (this.$refs.tagInput && this.$refs.tagInput.$refs && this.$refs.tagInput.$refs.input) {
					this.$refs.tagInput.$refs.input.focus();
				}
			});
		},

		handleInputTagConfirm() {
			const value = (this.inputTagValue || '').trim();
			if (value && !this.dataForm.storeTags.includes(value)) {
				this.dataForm.storeTags.push(value);
			}
			this.inputTagVisible = false;
			this.inputTagValue = '';
		},

		handleRemoveTag(index) {
			if (this.isDetail) return;
			this.dataForm.storeTags.splice(index, 1);
		},

		loadTMapScript() {
			return new Promise((resolve, reject) => {
				if (window.TMap) return resolve();
				const script = document.createElement('script');
				script.src = 'https://map.qq.com/api/gljs?v=1.exp&key=YRXBZ-NEV6T-K7SXH-VJPMF-G5IQF-F3FCJ&libraries=tools,geometry';
				script.onload = resolve;
				script.onerror = reject;
				document.body.appendChild(script);
			});
		},

		// --- 门店定位逻辑 ---
		handleOpenLocation() {
			this.locationVisible = true;
			// 若已有经纬度，则以门店经纬度为中心；否则先不设置，等 IP 定位
			this.tempMarker = {
				lng: this.dataForm.longitude,
				lat: this.dataForm.latitude
			};
			// 仅作为默认检索关键字，不自动发起检索
			this.locationSearchKeyword = this.dataForm.dz || '';

			this.$nextTick(() => {
				// 如果已有经纬度，直接按门店坐标初始化地图
				if (this.dataForm.longitude && this.dataForm.latitude) {
					this.initLocationMap();
				} else {
					// 无经纬度时，优先用 IP 做一个大概定位，再初始化地图
					this.initLocationWithIp();
				}
			});
		},

		// 使用腾讯地图 IP 定位作为初始中心（仅在没有门店经纬度时调用）
		initLocationWithIp() {
			const ipUrl = 'https://apis.map.qq.com/ws/location/v1/ip?key=' + TMAP_WS_KEY;
			// 先尝试 IP 定位（JSONP），成功后设置 tempMarker 再初始化地图；失败则走默认中心
			jsonp(ipUrl)
				.then((res) => {
					if (res.status === 0 && res.result && res.result.location) {
						const loc = res.result.location;
						this.tempMarker = { lng: loc.lng, lat: loc.lat };
						// 同步一下城市，便于后续检索时 region 使用
						if (res.result.ad_info && res.result.ad_info.city && !this.dataForm.cs) {
							this.dataForm.cs = res.result.ad_info.city;
						}
					}
					this.initLocationMap();
				})
				.catch(() => {
					this.initLocationMap();
				});
		},

		// 地址检索：使用腾讯地图 WebService API（地址解析 + 地点搜索）
		handleSearchLocation() {
			const keyword = (this.locationSearchKeyword || '').trim();
			if (!keyword) {
				this.$message.warning('请输入地址或关键词');
				return;
			}
			this.locationSearchLoading = true;
			const region = this.dataForm.cs || '';

			// 1. 先调用地址解析 API（适合完整地址），使用 JSONP 绕过 CORS
			const geocoderUrl = 'https://apis.map.qq.com/ws/geocoder/v1/?address=' + encodeURIComponent(keyword) + '&key=' + TMAP_WS_KEY + (region ? '&region=' + encodeURIComponent(region) : '');
			jsonp(geocoderUrl)
				.then((res) => {
					if (res.status === 0 && res.result && res.result.location) {
						const loc = res.result.location;
						this.applySearchResult(loc.lat, loc.lng);
						this.locationSearchLoading = false;
						this.$message.success('检索成功');
					} else {
						this.searchByKeyword(keyword, region);
					}
				})
				.catch(() => {
					this.searchByKeyword(keyword, region);
				});
		},

		// 关键词搜索：使用腾讯地图地点搜索 WebService API
		searchByKeyword(keyword, region) {
			const cityName = region || '全国';
			const boundary = 'region(' + cityName + ',1)';
			const searchUrl = 'https://apis.map.qq.com/ws/place/v1/search?keyword=' + encodeURIComponent(keyword) + '&boundary=' + encodeURIComponent(boundary) + '&page_size=10&key=' + TMAP_WS_KEY;
			jsonp(searchUrl)
				.then((res) => {
					this.locationSearchLoading = false;
					if (res.status === 0 && res.data && res.data.length > 0) {
						const first = res.data[0];
						const loc = first.location;
						this.applySearchResult(loc.lat, loc.lng);
						this.$message.success('检索成功');
					} else {
						this.$message.warning('未找到匹配结果，请尝试其他关键词或在地图上直接点击选择');
					}
				})
				.catch(() => {
					this.locationSearchLoading = false;
					this.$message.error('检索失败，请稍后再试');
				});
		},

		// 将检索结果应用到地图（移动中心、设置标记）
		applySearchResult(lat, lng) {
			this.tempMarker = { lng: lng, lat: lat };
			if (window.TMap && this.locationMarkerLayer) {
				const TMap = window.TMap;
				this.locationMarkerLayer.setGeometries([{ id: 'm', position: new TMap.LatLng(lat, lng) }]);
			}
			if (window.TMap && this.locationMap) {
				const TMap = window.TMap;
				this.locationMap.setCenter(new TMap.LatLng(lat, lng));
				this.locationMap.setZoom(16);
			}
		},

		initLocationMap() {
			this.loadTMapScript().then(() => {
				const TMap = window.TMap;
				const centerLat = this.tempMarker.lat || 30.656149; // 成都
				const centerLng = this.tempMarker.lng || 104.065735;
				const center = new TMap.LatLng(centerLat, centerLng);

				this.locationMap = new TMap.Map('location-map', { center, zoom: 14 });
				this.locationMarkerLayer = new TMap.MultiMarker({ map: this.locationMap, geometries: [] });

				if (this.tempMarker.lng) {
					this.locationMarkerLayer.setGeometries([{ id: 'm', position: new TMap.LatLng(this.tempMarker.lat, this.tempMarker.lng) }]);
				}

				this.locationMap.on('click', (evt) => {
					if (!evt.latLng) return;
					const lat = evt.latLng.getLat();
					const lng = evt.latLng.getLng();
					this.tempMarker = { lng, lat };
					this.locationMarkerLayer.setGeometries([{ id: 'm', position: evt.latLng }]);
				});
			});
		},

		confirmLocation() {
			this.dataForm.longitude = this.tempMarker.lng;
			this.dataForm.latitude = this.tempMarker.lat;
			this.locationVisible = false;
		},

		// --- 围栏设置逻辑 ---
		handleOpenFence() {
			if (!this.dataForm.longitude) return;
			this.fenceVisible = true;
			// 初始化 Buffer：历史上如果有多块，只保留第一块，保证始终至多一个围栏
			const polygons = Array.isArray(this.dataForm.fencePolygons) ? this.dataForm.fencePolygons : [];
			if (polygons.length > 0 && Array.isArray(polygons[0])) {
				this.fenceBuffer = [{
					id: `old-${Date.now()}`,
					type: 'polygon',
					points: polygons[0]
				}];
			} else {
				this.fenceBuffer = [];
			}
			this.$nextTick(() => {
				this.initFenceMap();
			});
		},

		initFenceMap() {
			this.loadTMapScript().then(() => {
				const TMap = window.TMap;
				const center = new TMap.LatLng(this.dataForm.latitude, this.dataForm.longitude);
				this.fenceMap = new TMap.Map('fence-map', { center, zoom: 16 });

				// 1. 门店位置固定标点
				this.fenceStoreMarkerLayer = new TMap.MultiMarker({
					map: this.fenceMap,
					geometries: [{ id: 'store', position: center }]
				});

				// 2. 初始化展示层
				this.fenceDisplayLayer = new TMap.MultiPolygon({
					map: this.fenceMap,
					geometries: [],
					styles: {
						default: new TMap.PolygonStyle({
							color: 'rgba(41,182,246,0.2)',
							borderColor: 'rgba(41,182,246,0.9)',
							borderWidth: 2
						})
					}
				});

				// 3. 构建临时绘制图层：
				//    - 一个多边形图层 polygonLayer
				//    - 一个圆形图层 circleLayer
				const polygonLayer = new TMap.MultiPolygon({
					map: this.fenceMap,
					geometries: [],
					styles: {
						default: new TMap.PolygonStyle({
							color: 'rgba(255,152,0,0.2)',
							borderColor: '#FF9800',
							borderWidth: 2
						})
					}
				});
				const circleLayer = new TMap.MultiCircle({
					map: this.fenceMap,
					geometries: [],
					styles: {
						default: new TMap.CircleStyle({
							color: 'rgba(255,152,0,0.2)',
							borderColor: '#FF9800',
							borderWidth: 2
						})
					}
				});
				this.fenceDrawLayers = {
					polygon: polygonLayer,
					circle: circleLayer
				};

				// 4. 初始化唯一编辑器（后续不再整体销毁，只清空内容）
				this.fenceEditor = new TMap.tools.GeometryEditor({
					map: this.fenceMap,
					overlayList: [
						{ overlay: polygonLayer, id: 'polygon' },
						{ overlay: circleLayer, id: 'circle' }
					],
					actionMode: TMap.tools.constants.EDITOR_ACTION.DRAW,
					activeOverlayId: 'polygon',
					snappable: true
				});

				// 5. 监听绘制完毕事件：每次只保留当前绘制结果为唯一围栏
				this.fenceEditor.on('draw_complete', (geometry) => {
					const toolId = this.activeFenceTool;
					const points = this._extractPoints(toolId, geometry);

					if (points && points.length >= 3) {
						// 业务约束：无论之前画了什么，本次绘制即为“唯一围栏”
						this.fenceBuffer = [{
							id: `shape-${Date.now()}`,
							type: toolId,
							points: points
						}];
						this.refreshFenceDisplay();
					}

					// 绘制完毕后：不销毁 Editor，只清空对应图层的临时几何
					const drawLayer = this.fenceDrawLayers[toolId];
					if (drawLayer && typeof drawLayer.setGeometries === 'function') {
						drawLayer.setGeometries([]);
					}

					// 延迟一帧重置绘制状态，避免与内部事件冲突
					setTimeout(() => {
						if (this.fenceEditor && window.TMap && window.TMap.tools && window.TMap.tools.constants) {
							this.fenceEditor.setActiveOverlay(toolId);
							this.fenceEditor.setActionMode(window.TMap.tools.constants.EDITOR_ACTION.DRAW);
						}
					}, 20);
				});

				this.refreshFenceDisplay();
			});
		},

		changeFenceTool(id) {
			this.activeFenceTool = id;
			if (this.fenceEditor) {
				// 清除可能画了一半的所有绘制层（去重后防止同一图层重复清理）
				const uniqueLayers = Object.values(this.fenceDrawLayers).filter((layer, index, arr) => arr.indexOf(layer) === index);
				uniqueLayers.forEach(layer => {
					if (layer && typeof layer.setGeometries === 'function') {
						layer.setGeometries([]);
					}
				});

				this.fenceEditor.setActiveOverlay(id);
				this.fenceEditor.setActionMode(window.TMap.tools.constants.EDITOR_ACTION.DRAW);
			}
		},

		refreshFenceDisplay() {
			if (!this.fenceDisplayLayer) return;
			const TMap = window.TMap;
			const geometries = this.fenceBuffer.map(item => {
				const path = item.points.map(p => new TMap.LatLng(p.lat, p.lng));
				// 闭合
				if (path[0].getLat() !== path[path.length - 1].getLat() || path[0].getLng() !== path[path.length - 1].getLng()) {
					path.push(path[0]);
				}
				return { id: item.id, paths: [path] };
			});
			this.fenceDisplayLayer.setGeometries(geometries);
		},

		removeBufferShape(index) {
			this.fenceBuffer.splice(index, 1);
			this.refreshFenceDisplay();
		},

		confirmFence() {
			if (this.fenceBuffer.length !== 1) {
				this.$message.warning('请确保最终只保留一个围栏');
				return;
			}
			this.dataForm.fencePolygons = [this.fenceBuffer[0].points];
			this.fenceVisible = false;
		},

		// 将 GeometryEditor 返回的几何统一转换为点数组
		_extractPoints(toolId, geometry) {
			if (!geometry) return []

			// 通用：从 geometry 中尝试解析点数组（paths 或 path，一维或二维）
			let pointsArray = []
			if (Array.isArray(geometry.paths) && geometry.paths.length) {
				const first = geometry.paths[0]
				pointsArray = Array.isArray(first) ? first : geometry.paths
			} else if (Array.isArray(geometry.path) && geometry.path.length) {
				const first = geometry.path[0]
				pointsArray = Array.isArray(first) ? first : geometry.path
			}

			// 多边形 / 矩形 / 椭圆：统一按点数组处理
			if (['polygon', 'rectangle', 'ellipse'].includes(toolId)) {
				if (!Array.isArray(pointsArray) || !pointsArray.length) return []
				return pointsArray.map(p => ({
					lng: typeof p.getLng === 'function' ? p.getLng() : p.lng,
					lat: typeof p.getLat === 'function' ? p.getLat() : p.lat
				}))
			}

			// 圆形：用中心 + 半径近似成 36 边多边形
			if (toolId === 'circle' && geometry.center && geometry.radius) {
				const center = geometry.center
				const r = geometry.radius
				const cLat = typeof center.getLat === 'function' ? center.getLat() : center.lat
				const cLng = typeof center.getLng === 'function' ? center.getLng() : center.lng
				const R = 6378137
				const latRad = (cLat * Math.PI) / 180
				return Array.from({ length: 36 }, (_, i) => {
					const angle = (2 * Math.PI * i) / 36
					return {
						lat: cLat + (r * Math.cos(angle)) / R * (180 / Math.PI),
						lng: cLng + (r * Math.sin(angle)) / (R * Math.cos(latRad)) * (180 / Math.PI)
					}
				})
			}

			return []
		},

		getShapeIcon(type) {
			const icons = { polygon: 'el-icon-picture', circle: 'el-icon-loading', rectangle: 'el-icon-full-screen', ellipse: 'el-icon-help' };
			return icons[type] || 'el-icon-info';
		},

		getShapeName(type) {
			const names = { polygon: '多边形', circle: '圆形', rectangle: '矩形', ellipse: '椭圆' };
			return names[type] || '图形';
		},

		dataFormSubmit() {
			this.$refs['elForm'].validate((valid) => {
				if (!valid) return;
				if (Number(this.dataForm.attendanceCheckWifi) === 1) {
					const pairs = (this.dataForm.attendanceWifiPairList || []).map((r) => ({
						ssid: (r.ssid || '').trim(),
						bssid: (r.bssid || '').trim()
					})).filter((p) => p.ssid || p.bssid);
					if (!pairs.length) {
						this.$message.warning('开启 Wi-Fi 打卡时请至少添加一行 Wi-Fi 白名单');
						return;
					}
				}
				const isNew = !this.dataForm.id;
				// 提交前：fencePolygons 若为数组则序列化为 JSON 字符串，与后端约定一致
				const submitData = { ...this.dataForm };
				if (Array.isArray(submitData.fencePolygons)) {
					submitData.fencePolygons = JSON.stringify(submitData.fencePolygons);
				}
				if (Array.isArray(submitData.storeImages)) {
					submitData.storeImages = JSON.stringify(submitData.storeImages);
				}
				if (Array.isArray(submitData.storeTags)) {
					submitData.storeTags = JSON.stringify(submitData.storeTags);
				}
				delete submitData.attendanceWifiPairList;
				const pairRows = (this.dataForm.attendanceWifiPairList || []).map((r) => ({
					ssid: (r.ssid || '').trim(),
					bssid: (r.bssid || '').trim()
				})).filter((p) => p.ssid || p.bssid);
				submitData.attendanceWifiPairs = JSON.stringify(pairRows);
				submitData.attendanceWifiVerifyPair = this.dataForm.attendanceWifiVerifyPair != null ? Number(this.dataForm.attendanceWifiVerifyPair) : 0;
				request({
					url: isNew ? '/api/Extend/LqMdxx' : `/api/Extend/LqMdxx/${this.dataForm.id}`,
					method: isNew ? 'POST' : 'PUT',
					data: submitData
				}).then((res) => {
					this.$message({
						message: res.msg,
						type: 'success',
						duration: 1000,
						onClose: () => {
							this.visible = false;
							this.$emit('refresh', true);
						}
					})
				})
			})
		}
	}
}
</script>

<style lang="scss" scoped>
.att-punch-check-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px 24px;
}

.att-punch-hint {
	margin-top: 8px;
	font-size: 12px;
	color: #909399;
	line-height: 1.5;
}

.wifi-verify-hint {
	margin-top: 6px;
}

.wifi-pair-toolbar {
	margin-bottom: 10px;
}

.wifi-pair-table {
	width: 100%;
	border: 1px solid #ebeef5;
	border-radius: 4px;
	overflow: hidden;
}

.wifi-pair-head {
	display: grid;
	grid-template-columns: 1fr 1fr 56px;
	gap: 8px;
	align-items: center;
	padding: 8px 10px;
	background: #f5f7fa;
	font-size: 12px;
	color: #606266;
	font-weight: 500;
}

.wifi-pair-row {
	display: grid;
	grid-template-columns: 1fr 1fr 56px;
	gap: 8px;
	align-items: center;
	padding: 8px 10px;
	border-top: 1px solid #ebeef5;
}

.wifi-pair-col-act {
	text-align: right;
}

.wifi-pair-del {
	color: #f56c6c;
	padding: 0;
}

.fence-status-bar {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	column-gap: 10px;
	row-gap: 8px;
	padding: 5px 0;

	.fence-action-btn {
		margin-left: 0;
		min-height: 30px;
		padding: 0 14px;
		font-weight: 500;
		transition: background-color 0.2s, border-color 0.2s, box-shadow 0.2s, color 0.2s;

		&:hover,
		&:focus {
			background-color: #66b1ff;
			border-color: #66b1ff;
		}

		&:active {
			background-color: #3a8ee6;
			border-color: #3a8ee6;
			box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
		}

		&.is-disabled {
			opacity: 0.75;
		}
	}

	.hint-text {
		font-size: 12px;
		color: #f56c6c;
		margin-left: 0;
	}
}

.store-tags-editor {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 10px;

	.store-tags-list {
		display: flex;
		flex-wrap: wrap;
		align-items: center;
		gap: 8px;
		min-height: 32px;
	}

	.store-tags-empty {
		font-size: 12px;
		color: #909399;
	}

	.store-tags-action-row {
		display: flex;
		align-items: center;
		gap: 8px;
	}

	.input-new-tag {
		width: 220px;
		max-width: 100%;
	}

	.button-new-tag {
		padding: 0 12px;
	}

	.tag-action-btn {
		min-height: 32px;
		padding: 0 14px;
		font-weight: 500;
		color: #409eff;
		border-color: #b3d8ff;
		background-color: #f3f9ff;
		transition: color 0.2s, border-color 0.2s, background-color 0.2s, box-shadow 0.2s;

		&:hover,
		&:focus {
			color: #409eff;
			border-color: #409eff;
			background-color: #eaf3ff;
			box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.12);
		}

		&:active {
			color: #fff;
			border-color: #3a8ee6;
			background-color: #3a8ee6;
			box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12);
		}
	}
}

@media (max-width: 768px) {
	.fence-status-bar {
		align-items: flex-start;

		.fence-action-btn {
			width: 100%;
		}
	}

	.store-tags-editor {

		.input-new-tag,
		.tag-action-btn {
			width: 100%;
		}

		.store-tags-action-row {
			align-items: stretch;
		}
	}
}

.map-dialog {
	::v-deep .el-dialog__body {
		padding: 10px 20px;
	}
}

.map-container-wrapper {
	.map-header-bar {
		display: flex;
		justify-content: space-between;
		font-size: 13px;
		color: #606266;
		margin-bottom: 8px;

		.coordinate-info {
			color: #409eff;
			font-weight: bold;
		}
	}

	.location-search-bar {
		margin-bottom: 10px;

		.search-input {
			width: 100%;
		}
	}
}

.map-canvas {
	width: 100%;
	height: 450px;
	border-radius: 4px;
	border: 1px solid #dcdfe6;
}

.fence-editor-layout {
	display: flex;
	height: 500px;
	gap: 15px;

	.map-side-panel {
		width: 220px;
		border: 1px solid #ebeef5;
		border-radius: 4px;
		display: flex;
		flex-direction: column;

		.panel-header {
			padding: 10px;
			background: #f5f7fa;
			border-bottom: 1px solid #ebeef5;
			font-weight: bold;
			font-size: 14px;
		}

		.shape-list {
			flex: 1;
			overflow-y: auto;
			padding: 10px;

			.shape-item {
				display: flex;
				align-items: center;
				padding: 8px;
				margin-bottom: 8px;
				background: #fdfdfd;
				border: 1px solid #f2f2f2;
				border-radius: 4px;

				i {
					margin-right: 8px;
					color: #409eff;
				}

				.shape-name {
					flex: 1;
					font-size: 12px;
				}

				.delete-btn {
					color: #f56c6c;
					padding: 0;
				}
			}

			.empty-text {
				text-align: center;
				color: #909399;
				font-size: 12px;
				margin-top: 50px;
			}
		}

		.panel-footer {
			padding: 10px;
			border-top: 1px solid #ebeef5;

			.warning-text {
				font-size: 11px;
				color: #e6a23c;
				margin: 0;
			}
		}
	}

	.map-main-area {
		flex: 1;
		display: flex;
		flex-direction: column;

		.map-toolbar {
			display: flex;
			padding: 0 0 10px 0;
			gap: 8px;

			.tool-btn {
				display: flex;
				align-items: center;
				padding: 5px 12px;
				border: 1px solid #dcdfe6;
				border-radius: 4px;
				cursor: pointer;
				background: #fff;
				transition: all 0.2s;

				&:hover {
					border-color: #409eff;
					color: #409eff;
				}

				&.active {
					background: #ecf5ff;
					border-color: #409eff;
					color: #409eff;
				}

				.tool-icon {
					width: 16px;
					height: 16px;
					margin-right: 6px;
					background-size: cover;
				}

				.tool-label {
					font-size: 12px;
				}
			}

			.tool-icon--polygon {
				background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/polygon.png');
			}

			.tool-icon--circle {
				background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/circle.png');
			}

			.tool-icon--rectangle {
				background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/rectangle.png');
			}

			.tool-icon--ellipse {
				background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/ellipse.png');
			}
		}
	}
}

.footer-hint {
	color: #f56c6c;
	font-size: 12px;
	margin-right: 20px;
	display: inline-block;
}

.mdxx-form-tabs {
	::v-deep .el-tabs__content {
		overflow: visible;
	}
}

.mdxx-version-toolbar {
	text-align: left;
	margin-bottom: 8px;
}

.mdxx-version-icon {
	font-size: 16px;
}

.mdxx-version-icon--primary {
	color: #409eff;
}

.mdxx-version-icon--success {
	color: #67c23a;
}

.mdxx-version-icon--muted {
	color: #909399;
}

.version-json-pre {
	max-height: 420px;
	overflow: auto;
	font-size: 12px;
	line-height: 1.4;
	margin: 0;
	white-space: pre-wrap;
	word-break: break-all;
}
</style>
