<template>
|
<div
|
v-drag="true"
|
class="spatialBox"
|
>
|
<!-- v-resizable="'right, bottom'" -->
|
<div class="spatialTitle">
|
<label>空间查询</label>
|
<div>
|
<el-icon
|
@click="setSpatialDownload"
|
:size="20"
|
style="margin-right: 20px;"
|
>
|
<Download />
|
</el-icon>
|
<el-icon
|
@click="setSpatialClose"
|
:size="20"
|
>
|
<Close />
|
</el-icon>
|
|
</div>
|
</div>
|
<div class="spatialContentBox">
|
<div class="spatialMenu">
|
<ul>
|
<li
|
v-for="item in menuList"
|
@click="setMenuListClick(item)"
|
:class="{'isActive':isActive==item.id}"
|
>{{ item.cnName }}</li>
|
</ul>
|
</div>
|
<div class="spatialContent">
|
<div>
|
<el-row :gutter="20">
|
<el-col :span="16">
|
<el-input
|
v-model="listData.filter"
|
type="text"
|
placeholder="请选择..."
|
disabled
|
/>
|
</el-col>
|
<el-col :span="8">
|
<el-button
|
:icon="Plus"
|
type="success"
|
@click="dialogVisible = true"
|
>高级查询</el-button>
|
<el-button
|
:icon="Refresh"
|
type="info"
|
@click="setdialogRefresh"
|
>重置</el-button>
|
</el-col>
|
</el-row>
|
</div>
|
<div class="spatialTable">
|
|
<el-table
|
:data="tableData"
|
style="width: 100%; height: 73%;"
|
>
|
<el-table-column
|
align="center"
|
type="index"
|
label="序号"
|
width="70"
|
/>
|
<el-table-column
|
label="定位"
|
width="100"
|
align="center"
|
>
|
<template #default="scope">
|
<el-button
|
class="el-icon-map"
|
size="small"
|
@click.prevent="spaceLocation(scope.$index, scope.row)"
|
>
|
</el-button>
|
</template>
|
</el-table-column>
|
<el-table-column
|
v-for="(item, index) in attributeData"
|
:key="index"
|
:label="item.alias"
|
:prop="item.field"
|
show-overflow-tooltip
|
align="center"
|
:fit="true"
|
width="120"
|
></el-table-column>
|
|
</el-table>
|
<div class="spatialBottom">
|
<el-pagination
|
v-model:current-page="listData.pageIndex"
|
v-model:page-size="listData.pageSize"
|
:page-sizes="[10, 20, 100, 200]"
|
small="small"
|
:disabled="false"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="listData.count"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
/>
|
</div>
|
</div>
|
|
</div>
|
</div>
|
|
<!-- 高级查询 -->
|
<el-dialog
|
v-model="dialogVisible"
|
title="高级查询"
|
width="30%"
|
:show-close="false"
|
:close-on-click-modal="false"
|
:close-on-press-escape="false"
|
>
|
<div>
|
<el-row :gutter="20">
|
<el-col :span="8">
|
<el-select
|
v-model="formSql.field"
|
class="m-2"
|
placeholder="Select"
|
@change="setFieldChange($event)"
|
>
|
<el-option
|
v-for="item in fieldOption"
|
:key="item.field"
|
:label="item.alias"
|
:value="item.field"
|
/>
|
</el-select>
|
</el-col>
|
<el-col :span="8">
|
<el-select
|
v-model="formSql.type"
|
class="m-2"
|
placeholder="Select"
|
>
|
<el-option
|
v-for="item in condOption"
|
:key="item.value"
|
:label="item.label"
|
:value="item.value"
|
/>
|
</el-select>
|
</el-col>
|
<el-col :span="8">
|
<el-input v-model="formSql.value"></el-input>
|
</el-col>
|
|
</el-row>
|
|
</div>
|
<template #footer>
|
<span class="dialog-footer">
|
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button
|
type="primary"
|
@click="setInsertDialog"
|
> 添加 </el-button>
|
</span>
|
</template>
|
</el-dialog>
|
<!-- 下载信息 -->
|
<el-dialog
|
v-model="downloaVisible"
|
title="下载"
|
width="30%"
|
:show-close="false"
|
>
|
<div
|
class="spatialTable"
|
style="max-height: 40vh;"
|
>
|
<el-table
|
:data="downTable"
|
@selection-change="handleSelectionChange"
|
style="width: 100%; height: 28vh;"
|
>
|
<el-table-column
|
type="selection"
|
width="55"
|
/>
|
<el-table-column
|
align="center"
|
type="index"
|
label="序号"
|
width="70"
|
/>
|
<el-table-column
|
align="center"
|
label="表名"
|
prop="cnName"
|
/>
|
</el-table>
|
<el-form
|
ref="downFormRef"
|
class="setdownFrom"
|
:model="downFrom"
|
:rules="rules"
|
label-width="180px"
|
>
|
<el-form-item
|
label="请输入密码:"
|
prop="pass"
|
>
|
<el-input
|
type="password"
|
v-model="downFrom.pass"
|
autocomplete="off"
|
show-password
|
placeholder="请输入密码"
|
></el-input>
|
</el-form-item>
|
<el-form-item
|
label="请再次输入密码:"
|
prop="repass"
|
>
|
<el-input
|
type="password"
|
show-password
|
v-model="downFrom.repass"
|
autocomplete="off"
|
placeholder="请再次输入密码"
|
></el-input>
|
</el-form-item>
|
<el-form-item>
|
<el-button
|
type="primary"
|
size="small"
|
@click="submitForm(downFormRef)"
|
>提交</el-button>
|
<el-button
|
size="small"
|
@click="setCloseSpatialDownload"
|
>取消</el-button>
|
</el-form-item>
|
</el-form>
|
</div>
|
</el-dialog>
|
<iframe
|
id="Iframe1"
|
src=""
|
style="display: none; border: 0; padding: 0; height: 0; width: 0"
|
></iframe>
|
</div>
|
</template>
|
|
<script lang="ts" setup>
|
window.encrypt = null;
|
import {
|
ref,
|
onMounted,
|
onBeforeUnmount,
|
reactive,
|
defineProps,
|
defineEmits,
|
nextTick,
|
} from "vue";
|
import menuTool from "@/assets/js/Map/menuTool";
|
// import config from "../../../public/config/config.js";
|
import { User, Lock, Plus, Refresh, Location } from "@element-plus/icons-vue";
|
import {
|
dataQuery_selectByPage,
|
dataQuery_selectFields,
|
dataQuery_downloadDbData,
|
sign_getPublicKey,
|
} from "@/api/api";
|
import { ElMessage } from "element-plus";
|
import store from "@/store";
|
import WKT from "terraformer-wkt-parser";
|
import type { FormInstance, FormRules } from "element-plus";
|
import { removeToken, getToken } from "@/utils/auth";
|
import JSEncrypt from "jsencrypt";
|
const emits = defineEmits(["SETspatialClose"]);
|
const setSpatialClose = () => {
|
menuTool.setClearLocation("空间查询");
|
emits("SETspatialClose", false);
|
};
|
var encrypt = new JSEncrypt();
|
const dialogVisible = ref(false);
|
const listData = ref({
|
pageIndex: 1,
|
pageSize: 10,
|
count: 0,
|
wkt: null,
|
hasGeom: 1,
|
filter: "",
|
name: "",
|
});
|
|
const condOption = ref([]);
|
const fieldOption = ref([]);
|
const attributeData = ref([]);
|
const tableData = ref([]);
|
const menuList = ref([]);
|
const downTable = ref([]);
|
const formSql = ref({
|
field: "",
|
type: "",
|
value: "",
|
cut: "",
|
});
|
const downloaVisible = ref(false);
|
const isActive = ref(null);
|
const multipleSelection = ref([]);
|
const downFormRef = ref<FormInstance>();
|
const downFrom = ref({
|
pass: "",
|
repass: "",
|
});
|
|
const validatepass = (rule: any, value: any, callback: any) => {
|
var passwordreg =
|
/^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W!@#$%^&*`~()\\-_+=,.?;<>]+$)(?![a-z0-9]+$)(?![a-z\W!@#$%^&*`~()\\-_+=,.?;<>]+$)(?![0-9\W!@#$%^&*`~()\\-_+=,.?;<>]+$)[a-zA-Z0-9\W!@#$%^&*`~()\\-_+=,.?;<>]{12,20}$/;
|
if (!passwordreg.test(value)) {
|
callback(new Error("密码必须由数字、字母、特殊字符组合,请输入13-20位"));
|
} else {
|
callback();
|
}
|
};
|
const validaterepass = (rule: any, value: any, callback: any) => {
|
var passwordreg =
|
/^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\W!@#$%^&*`~()\\-_+=,.?;<>]+$)(?![a-z0-9]+$)(?![a-z\W!@#$%^&*`~()\\-_+=,.?;<>]+$)(?![0-9\W!@#$%^&*`~()\\-_+=,.?;<>]+$)[a-zA-Z0-9\W!@#$%^&*`~()\\-_+=,.?;<>]{12,20}$/;
|
if (!passwordreg.test(value)) {
|
callback(new Error("密码必须由数字、字母、特殊字符组合,请输入13-20位"));
|
} else if (value != downFrom.value.pass) {
|
callback(new Error("两次输入密码不一致,请重新输入"));
|
} else {
|
callback();
|
}
|
};
|
const rules = reactive<FormRules<typeof downFrom>>({
|
pass: [{ validator: validatepass, trigger: "blur" }],
|
repass: [{ validator: validaterepass, trigger: "blur" }],
|
});
|
|
const submitForm = (formEl: FormInstance | undefined) => {
|
if (!formEl) return;
|
formEl.validate((valid) => {
|
if (valid) {
|
if (multipleSelection.value.length <= 0) {
|
ElMessage.error("请选择要下载的表");
|
} else {
|
setDownLoadFrom();
|
}
|
} else {
|
return false;
|
}
|
});
|
};
|
const getpublickey = async () => {
|
const res = await sign_getPublicKey();
|
if (res && res.code == 200) {
|
encrypt.setPublicKey(res.result);
|
}
|
};
|
const setDownLoadFrom = async () => {
|
downloaVisible.value = false;
|
var entities = [];
|
var tabs = [];
|
|
for (var i in multipleSelection.value) {
|
var tab = multipleSelection.value[i].tab;
|
if (tab.indexOf("moon:") > -1) {
|
tab = tab.replaceAll("moon:", "");
|
}
|
tabs.push(tab);
|
var entity = tab;
|
if (entity.indexOf("_") > -1) {
|
entity = entity.replaceAll("_", "");
|
}
|
entities.push(entity);
|
}
|
|
var obj = {
|
pwd: encrypt.encrypt(downFrom.value.pass),
|
filter: listData.value.filter,
|
tabs: tabs,
|
entities: entities,
|
wkt: listData.value.wkt,
|
};
|
const data = await dataQuery_downloadDbData(obj);
|
|
if (data.code != 200 && !data.result) {
|
setClearDownload();
|
return ElMessage.error("数据下载失败");
|
}
|
|
var token = getToken();
|
var url =
|
config.proxy +
|
"/dataLib/downloadFile?token=" +
|
token +
|
"&guid=" +
|
data.result +
|
"&pwd=" +
|
encodeURIComponent(downFrom.value.pass);
|
$("#Iframe1").attr("src", url).click();
|
setClearDownload();
|
};
|
const setClearDownload = () => {
|
downFrom.value = {
|
pass: "",
|
repass: "",
|
};
|
multipleSelection.value = [];
|
downTable.value = [];
|
};
|
const handleSelectionChange = (res) => {
|
multipleSelection.value = res;
|
};
|
//下载
|
const setSpatialDownload = () => {
|
downTable.value = menuList.value;
|
downloaVisible.value = true;
|
};
|
const setCloseSpatialDownload = () => {
|
downloaVisible.value = false;
|
setClearDownload();
|
};
|
//定位显示
|
const spaceLocation = (index, row) => {
|
var geom = menuTool.decr(row.geom);
|
|
var wkt = WKT.parse(geom);
|
menuTool.spaceLocation(wkt);
|
};
|
const handleSizeChange = (res) => {
|
listData.value.pageSize = res;
|
setQueySpatialData();
|
};
|
const handleCurrentChange = (res) => {
|
listData.value.pageIndex = res;
|
setQueySpatialData();
|
};
|
const setMenuListClick = (res) => {
|
if (res.tab && res.tab.indexOf("moon:") > -1) {
|
listData.value.name = res.tab.replaceAll("moon:", "");
|
} else {
|
listData.value.name = res.tab;
|
}
|
|
isActive.value = res.id;
|
listData.value.filter = "";
|
listData.value.pageIndex = 1;
|
listData.value.pageSize = 10;
|
setQueySpatialFields();
|
};
|
const setInsertDialog = () => {
|
if (!formSql.value.value) {
|
return ElMessage.error("请输入要查询的参数");
|
}
|
dialogVisible.value = false;
|
if (listData.value.filter != "") {
|
listData.value.filter += " and ";
|
}
|
const val = null;
|
if (formSql.value.cut === "long" || formSql.value.cut === "integer") {
|
val = parseInt(formSql.value.value);
|
} else if (formSql.value.cut === "double") {
|
if (formSql.value.value.indexOf(".") != -1) {
|
val = parseInt(formSql.value.value);
|
} else {
|
val = parseFloat(formSql.value.value).toFixed(1);
|
}
|
} else if (formSql.value.cut == "date" || formSql.value.cut == "datetime") {
|
var time = new Date(formSql.value.value);
|
var m = time.getMonth() + 1;
|
var d = time.getDate();
|
var y = time.getFullYear();
|
val = "'" + y + "-" + add0(m) + "-" + add0(d) + "'";
|
} else {
|
val = "'" + formSql.value.value + "'";
|
}
|
listData.value.filter +=
|
formSql.value.field + " " + formSql.value.type + " " + val;
|
|
var res = attributeData.value[0];
|
conditionChange(res);
|
setQueySpatialData();
|
};
|
|
const setdialogRefresh = () => {
|
listData.value.filter = "";
|
listData.value.pageIndex = 1;
|
listData.value.pageSize = 10;
|
|
var res = attributeData.value[0];
|
conditionChange(res);
|
setQueySpatialData();
|
};
|
|
//格式化时间
|
const add0 = (m) => {
|
return m < 10 ? "0" + m : m;
|
};
|
//查询列表数据
|
const setQueySpatialData = async () => {
|
listData.value.name = listData.value.name.replaceAll("_", "");
|
const data = await dataQuery_selectByPage(listData.value);
|
if (data.code != 200) {
|
return ElMessage.error("空间查询失败");
|
}
|
listData.value.count = data.count;
|
var val = data.result.filter((res) => {
|
if (res.apprTime) {
|
res.apprTime = format(res.apprTime);
|
}
|
if (res.createtime) {
|
res.apprTime = format(res.createtime);
|
}
|
if (res.updatetime) {
|
res.apprTime = format(res.updatetime);
|
}
|
return res;
|
});
|
tableData.value = val;
|
};
|
//格式化时间
|
const format = (shijianchuo) => {
|
//shijianchuo是整数,否则要parseInt转换
|
var time = new Date(shijianchuo);
|
var y = time.getFullYear();
|
var m = time.getMonth() + 1;
|
var d = time.getDate();
|
var h = time.getHours();
|
var mm = time.getMinutes();
|
var s = time.getSeconds();
|
return y + "-" + add01(m) + "-" + add01(d) + " " + h + ":" + mm + ":" + s;
|
};
|
//格式化时间
|
const add01 = (m) => {
|
return m < 10 ? "0" + m : m;
|
};
|
const setQueySpatialFields = async () => {
|
const data = await dataQuery_selectFields({
|
ns: "mn",
|
tab: listData.value.name,
|
});
|
if (data.code != 200) {
|
return ElMessage.error("字段查询失败");
|
}
|
|
var std = data.result.filter((res) => {
|
if (res.showtype > 0) {
|
return res;
|
}
|
});
|
|
var val = std.filter((res) => {
|
if (res.field.indexOf("_") > -1) {
|
var str = res.field.split("_");
|
res.field = str[0] + str[1][0].toUpperCase() + str[1].slice(1);
|
return res;
|
} else {
|
return res;
|
}
|
});
|
attributeData.value = val;
|
fieldOption.value = val;
|
conditionChange(data.result[0]);
|
setQueySpatialData();
|
};
|
const setFieldChange = (res) => {
|
const val = fieldOption.value;
|
const str = [];
|
for (var i in val) {
|
if (val[i].id === res) {
|
str.push(val[i]);
|
}
|
}
|
if (str.length > 0) {
|
conditionChange(str[0]);
|
}
|
};
|
const conditionChange = (res) => {
|
formSql.value.value = "";
|
formSql.value.field = res.field;
|
formSql.value.cut = res.type;
|
var type = res.type;
|
var std = [];
|
if (type == "text" || type == "blob") {
|
std = config.conditions[0];
|
} else if (type == "date" || type == "datetime") {
|
std = config.conditions[2];
|
} else {
|
std = config.conditions[1];
|
}
|
var str = [];
|
for (var i in std) {
|
str.push({
|
label: std[i],
|
value: std[i],
|
});
|
}
|
condOption.value = str;
|
formSql.value.type = std[0];
|
};
|
|
//页面初始化
|
const startQueryData = () => {
|
var std = store.state.chekNowLayers;
|
if (std.length <= 0) {
|
ElMessage.error("请选择要查询的图层");
|
setSpatialClose();
|
return;
|
}
|
var str = std.filter((res) => {
|
if (res.isLayer == 1 && res.tab) {
|
return res;
|
}
|
});
|
|
menuList.value = str;
|
listData.value.wkt = store.state.spatialQueryData.wkt;
|
listData.value.name = menuList.value[0].tab.replaceAll("moon:", "");
|
isActive.value = menuList.value[0].id;
|
listData.value.hasGeom = 1;
|
//
|
setQueySpatialFields();
|
};
|
|
onMounted(() => {
|
startQueryData();
|
getpublickey();
|
});
|
</script>
|
|
<style lang="less" scoped>
|
.spatialBox {
|
width: 900px;
|
height: 400px;
|
display: flex;
|
flex-direction: column;
|
position: absolute;
|
bottom: 5%;
|
right: 5%;
|
background: rgba(7, 8, 14, 0.8);
|
border: 1px solid #d6e4ff;
|
z-index: 10;
|
box-shadow: inset 0px 10px 40px 10px rgba(38, 47, 71, 1);
|
.spatialTitle {
|
padding: 10px;
|
width: calc(100% - 20px);
|
height: 66px;
|
color: #d6e4ff;
|
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
height: 30px;
|
label {
|
font-size: 16px;
|
}
|
}
|
.spatialContentBox {
|
height: calc(100% - 40px);
|
width: 100%;
|
display: flex;
|
}
|
.spatialMenu {
|
width: calc(20% - 20px);
|
height: calc(100% - 26px);
|
padding: 10px;
|
border-right: 1px solid #d6e4ff;
|
overflow: auto;
|
font-family: Source Han Sans SC;
|
ul {
|
li {
|
color: #d6e4ff;
|
font-size: 12px;
|
height: 20px;
|
border-bottom: 1px solid #409eff;
|
box-shadow: inset 0px 5px 20px 5px rgba(38, 47, 71, 1);
|
padding: 10px 10px;
|
display: flex;
|
align-items: center;
|
}
|
li :hover {
|
color: #409eff;
|
}
|
}
|
.isActive {
|
color: #409eff;
|
}
|
}
|
.spatialContent {
|
height: calc(100% - 10px);
|
width: calc(80% - 20px);
|
padding: 10px;
|
}
|
.spatialBottom {
|
padding: 10px;
|
height: 40px;
|
}
|
|
/deep/.el-pagination button {
|
background: transparent;
|
color: #d6e4ff;
|
}
|
/deep/.el-pager li {
|
background: transparent;
|
color: #d6e4ff;
|
}
|
/deep/.el-pager li.is-active {
|
color: #409eff;
|
}
|
/deep/.el-pagination__total {
|
color: #d6e4ff;
|
}
|
/deep/.el-pagination__goto {
|
color: #d6e4ff;
|
}
|
/deep/.el-pagination__classifier {
|
color: #d6e4ff;
|
}
|
/deep/.el-input.is-disabled .el-input__wrapper {
|
background: transparent !important;
|
color: #d6e4ff;
|
}
|
/deep/.el-input.is-disabled .el-input__inner {
|
color: #d6e4ff !important;
|
}
|
/deep/ .el-dialog {
|
background: rgba(7, 8, 14, 0.8);
|
border: 1px solid #d6e4ff;
|
z-index: 10;
|
box-shadow: inset 0px 10px 40px 10px rgba(38, 47, 71, 1);
|
}
|
/deep/.el-dialog__title {
|
color: #d6e4ff !important;
|
}
|
/* 修改滚动条的宽度为10px,颜色为白色 */
|
::-webkit-scrollbar {
|
width: 5px;
|
height: 10px;
|
background: rgba(38, 47, 71, 0);
|
border-radius: 10px;
|
}
|
|
/* 修改滚动条的轨道和滑块颜色 */
|
::-webkit-scrollbar-track {
|
background: rgba(38, 47, 71, 0);
|
}
|
|
::-webkit-scrollbar-thumb {
|
background: #d6e4ff;
|
}
|
|
/* hover时滚动条轨道和滑块变色 */
|
::-webkit-scrollbar-thumb:hover {
|
background: #d6e4ff;
|
}
|
|
::-webkit-scrollbar-track:hover {
|
background: rgba(38, 47, 71, 0);
|
}
|
.spatialTable {
|
margin-top: 10px;
|
width: 100%;
|
height: 100%;
|
position: relative;
|
|
.el-table /deep/ .el-table__header-wrapper tr th {
|
background-color: rgba(38, 47, 71, 1) !important;
|
color: #d6e4ff;
|
}
|
// 修改每行样式:
|
.el-table /deep/ .el-table__row {
|
background-color: rgba(38, 47, 71, 1) !important;
|
color: #d6e4ff;
|
}
|
.el-table /deep/ .el-table__body tr.current-row > td {
|
background-color: rgba(38, 47, 71, 1) !important;
|
}
|
.el-table /deep/ .el-table__body tr:hover > td {
|
background-color: rgba(38, 47, 71, 1) !important;
|
}
|
// 修改表格每行边框的样式:
|
.el-table /deep/ td,
|
.el-table /deep/ th.is-leaf {
|
// border-bottom: 1px solid #409eff;
|
// border-right: 1px solid #409eff;
|
}
|
.el-table /deep/ .el-table__cell {
|
padding: 8px 0;
|
}
|
// 设置表格每行的高度:
|
.el-table /deep/ .el-table__header tr,
|
.el-table /deep/ .el-table__header th {
|
height: 50px;
|
}
|
.el-table__body tr,
|
.el-table__body td {
|
height: 50px;
|
padding: 0;
|
}
|
// 设置表格边框颜色:
|
|
.el-table--border::after,
|
.el-table--group::after {
|
width: 0;
|
}
|
.el-table::before {
|
height: 0;
|
}
|
}
|
.setdownFrom {
|
margin-top: 10px;
|
/deep/.el-form-item__label {
|
color: #d6e4ff !important;
|
}
|
}
|
.el-icon-map {
|
background: url("../../assets/img/location.png") center no-repeat;
|
background-size: 100% 100%;
|
border: transparent;
|
}
|
.el-icon-map:before {
|
content: "定位";
|
font-size: 0;
|
visibility: hidden;
|
}
|
}
|
</style>
|
<style lang="less" >
|
.el-scrollbar {
|
background: rgba(7, 8, 14) !important;
|
border: 1px solid #4472cb;
|
color: #d6e4ff !important;
|
box-shadow: inset 0px 1px 40px 1px rgba(38, 47, 71, 1);
|
// .el-dropdown-menu {
|
// background: rgba(7, 8, 14, 0.8) !important;
|
// }
|
.el-select-dropdown__item {
|
color: #d6e4ff;
|
}
|
.el-select-dropdown__item:hover {
|
background: rgba(38, 47, 71, 1) !important;
|
}
|
.el-select-dropdown__item.hover,
|
.el-select-dropdown__item:hover {
|
background: rgba(38, 47, 71, 1) !important;
|
}
|
}
|
.el-table__header-wrapper {
|
border: 1px siolid #409eff;
|
}
|
</style>
|