LinYeFangHuo/src/views/demo/layer/index.vue

573 lines
16 KiB
Vue

<template>
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
<LayerTree
ref="treeRef"
class="w-1/4 xl:w-1/5"
@select="handleSelect"
@edit="editLayer"
@add="addLayer"
@remove="tableVisible = false"
/>
<div class="map-container w-3/4 xl:w-4/5">
<Map />
<!-- 数据列表 -->
<div class="table-constainer" v-show="tableVisible">
<div class="drawer-title-box">
<a-input
v-model:value="keyWord"
placeholder="字段"
style="width: 200px; margin-right: 10px"
/>
<a-input
v-model:value="keyValue"
placeholder="字段值"
style="width: 200px; margin-right: 10px"
/>
<a-button type="primary" @click="getList"> 查询 </a-button>
<a-button type="primary" @click="exportTemplate"> 导出模版 </a-button>
<a-upload
:accept="'.xlsx,.csv,.xls,.zip'"
:showUploadList="false"
:custom-request="customRequest"
style="margin-right: 0px;"
>
<a-button type="primary"> 数据导入 </a-button>
</a-upload>
<a-button type="primary" @click="changeBatchProcessingModal(true)"> 批量操作 </a-button>
<a-button type="primary" @click="styleHandle"> 样式配置 </a-button>
</div>
<div class="close-icon" @click="tableVisible = false">
<CloseOutlined />
</div>
<div class="table-content">
<BasicTable @register="registerTable" @change="handleTableChange">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '定位',
onClick: posData.bind(null, record),
},
{
label: '编辑',
onClick: editData.bind(null, record),
},
{
label: '查看',
onClick: viewData.bind(null, record),
},
{
label: '删除',
color: 'error',
onClick: delData.bind(null, record),
},
]"
/>
</template>
</template>
</BasicTable>
</div>
</div>
<!-- 详情 -->
<div class="data-detail" v-if="showTable == 'detail'">
<a-descriptions title="详情" :column="columnVal">
<a-descriptions-item v-for="(val, key) in selectVal" :key="key" :label="key">{{
val
}}</a-descriptions-item>
</a-descriptions>
<div class="detail-button">
<a-button type="primary" @click="showTable = 'edit'"> 编辑 </a-button>
<a-button type="primary" @click="showTable = ''" danger> 关闭 </a-button>
</div>
</div>
<!-- 编辑 -->
<div class="data-edit" v-if="showTable == 'edit'">
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-item
v-for="(item, index) in headData"
:ref="item"
:label="item"
:name="item"
:key="index"
>
<a-input v-model:value="formState[item]" />
</a-form-item>
</a-form>
<div class="data-button">
<a-button type="primary" @click="onSubmit">保存</a-button>
<a-button style="margin-left: 10px" @click="resetForm">取消</a-button>
</div>
</div>
<!-- 样式配置 -->
<div class="data-style" v-if="showTable == 'style'">
<div class="img-box">
<a-input v-model:value="styleName" placeholder="样式名称" style="margin-bottom: 10px" />
<p style="color: #ed6f6f" v-if="styleName == ''">请输入样式名称</p>
<a-upload-dragger
v-model:fileList="fileList"
name="file"
@change="handleChange"
:multiple="false"
:maxCount="1"
:customRequest="handleCustomRequest"
v-if="!fileUrl"
>
<p class="ant-upload-drag-icon">
<inbox-outlined></inbox-outlined>
</p>
<p class="ant-upload-text">上传SLD文件</p>
</a-upload-dragger>
<div v-else>
<p>{{ fileUrlView.name }}</p>
<a-button type="primary" @click="editorHandle">在编辑器中打开</a-button>
</div>
</div>
<div class="data-button">
<a-button type="primary" @click="showTable = ''" danger> 关闭 </a-button>
<a-button @click="styleCancel"> 取消 </a-button>
<a-button type="primary" @click="styleSubmit"> 提交 </a-button>
</div>
</div>
</div>
<AddModel @register="registerAddModal" :treeData="treeData" @success="handleSuccess" />
<EditorModel @register="registerEditorModal" />
<a-modal
wrapClassName="batch-modal-wrap"
class="BatchProcessingModal"
width="1660px"
v-model:open="batchProcessingModalOpen"
:footer="null"
:closable="false"
:destroyOnClose="true"
style="top: 50px"
>
<BatchProcessingModal
:tableName="tableName"
@changeBatchProcessingModal="changeBatchProcessingModal"
/>
</a-modal>
<TempeleteModel @register="registerTempeleteModel" :tableName="tableName" />
</PageWrapper>
</template>
<script setup lang="ts">
import { LayerTree, AddModel, Map, EditorModel, TempeleteModel } from './page';
import { ref, UnwrapRef, reactive, onMounted } from 'vue';
import { PageWrapper } from '@/components/Page';
import { useModal } from '@/components/Modal';
import { CloseOutlined, InboxOutlined } from '@ant-design/icons-vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { columns } from './data';
import { tableDataByTableName, updateTableData, uploadSldStyle } from '@/api/application/layer';
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface';
import { useMessage } from '@/hooks/web/useMessage';
import { uploadFile, fun_Delete } from '@/api/demo/files';
import { getAppEnvConfig } from '@/utils/env';
import BatchProcessingModal from './BatchProcessingModal/index.vue';
import { Upload, UploadShape, UploadExcelAll } from '@/api/demo/BatchProcessingModal'
import { message } from 'ant-design-vue';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const { createConfirm, createMessage } = useMessage();
const showTable = ref('');
const tableVisible = ref(false);
const selectVal = ref();
const columnVal = ref(1);
const fileList = ref([]);
const batchProcessingModalOpen = ref(false);
const [registerAddModal, { openModal: openAddModal }] = useModal();
const [registerEditorModal, { openModal: openEditorModal }] = useModal();
const [registerTempeleteModel, { openModal: openTempeleteModel }] = useModal();
const labelCol = { span: 6 };
const wrapperCol = { span: 18 };
const keyWord = ref(null);
const keyValue = ref(null);
const headData = ref();
const [registerTable, { reload, getSelectRows, clearSelectedRowKeys, setTableData, setColumns }] =
useTable({
//
title: '',
//
dataSource: [],
// BasicColumn[]
columns,
rowKey: 'id',
// 使
useSearchForm: false,
//
showTableSetting: true,
//
bordered: true,
//
showIndexColumn: false,
//
handleSearchInfoFn(info) {
return info;
},
actionColumn: {
width: 200,
title: '',
dataIndex: 'action',
// slots: { customRender: 'action' },
fixed: 'right',
},
});
const treeRef = ref();
const treeData = ref();
const formRef = ref();
const formState = ref({});
const tableName = ref();
const styleName = ref();
const rules = {
name: [
{ required: true, message: 'Please input Activity name', trigger: 'blur' },
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
],
region: [{ required: true, message: 'Please select Activity zone', trigger: 'change' }],
date1: [{ required: true, message: 'Please pick a date', trigger: 'change', type: 'object' }],
type: [
{
type: 'array',
required: true,
message: 'Please select at least one activity type',
trigger: 'change',
},
],
resource: [{ required: true, message: 'Please select activity resource', trigger: 'change' }],
desc: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
};
const onSubmit = () => {
formRef.value
.validate()
.then(() => {
const params = {
tableName: tableName.value,
list: [],
};
for (const key in formState.value) {
params.list.push({
name: key,
value: formState.value[key],
});
}
updateTableData(params).then((res) => {
console.log('res', res);
if (res) {
createMessage.success('编辑成功!');
showTable.value = '';
} else {
createMessage.error('编辑失败!');
}
});
})
.catch((error: ValidateErrorEntity<FormState>) => {
console.log('error', error);
});
};
const resetForm = () => {
showTable.value = '';
};
const handleSelect = (record) => {
tableName.value = record.serverId;
tableVisible.value = true;
keyWord.value = null;
keyValue.value = null;
getList();
};
const editLayer = (node) => {
treeData.value = treeRef.value.treeData;
openAddModal(true, {
node,
isUpdate: true,
});
};
const addLayer = () => {
treeData.value = treeRef.value.treeData;
openAddModal(true, {
isUpdate: false,
});
};
const handleSuccess = () => {
treeRef.value.fetch();
};
const editData = (record) => {
selectVal.value = record;
formState.value = record;
showTable.value = 'edit';
};
const viewData = (record) => {
console.log('record', record);
selectVal.value = record;
formState.value = record;
showTable.value = 'detail';
};
const delData = (record) => {
createConfirm({
iconType: 'info',
title: '删除',
content: '确定要删除当前数据吗?',
onOk: async () => {
// let result = await functionDeleteForm(query);
// if (result) {
// createMessage.success('数据成功!');
// } else {
// createMessage.error('数据失败!');
// }
reload();
},
});
};
const fileUrl = ref('');
const fileUrlView: any = ref({});
const posData = (record) => {};
const styleHandle = () => {
fileUrl.value = '';
fileUrlView.value = {};
styleName.value = '';
showTable.value = 'style';
};
const handleChange = (info) => {
fileList.value = info.fileList;
};
// 上传文件接口
const handleCustomRequest = (options) => {
fileList.value = [];
const formData = new FormData();
formData.append('files', options.file);
fileUrlView.value.name = options.file.name;
uploadFile(formData)
.then((res: any) => {
fileUrl.value = res[0].filePath;
fileUrlView.value.url = res[0].filePath;
fileUrlView.value.id = res[0].id;
createMessage.success('上传成功!');
})
.catch((err) => {
options.onError(err);
});
};
const styleSubmit = () => {
if (!styleName.value) {
return createMessage.warning('样式名称不能为空!');
}
const params = {
filepath: fileUrl.value,
styleName: styleName.value,
tablename: tableName.value,
};
uploadSldStyle(params).then((res) => {
console.log(res);
if (res) {
showTable.value = '';
createMessage.success('提交成功!');
} else {
createMessage.error('提交失败!');
}
});
};
const styleCancel = () => {
if (fileUrlView.value.id) {
const params = [fileUrlView.value.id];
createConfirm({
iconType: 'info',
title: '取消',
content: '取消会删除当前文件',
onOk: async () => {
fun_Delete(params).then((res) => {
createMessage.success('删除成功!');
showTable.value = '';
});
},
});
} else {
showTable.value = '';
}
};
const editorHandle = () => {
if (!styleName.value) {
return createMessage.warning('样式名称不能为空!');
}
openEditorModal(true, {
urlData: fileUrlView.value,
styleName: styleName.value,
tableName: tableName.value,
});
};
const changeBatchProcessingModal = (type: boolean) => {
batchProcessingModalOpen.value = type;
};
const searchData = reactive({
page: 1,
limit: 10,
});
const handleTableChange = (values: any) => {
console.log(values);
searchData.page = values.current;
searchData.limit = values.pageSize;
getList();
};
const getList = () => {
const querys = {
...searchData,
tablename: tableName.value,
keyword: keyWord.value,
keyvalue: keyValue.value,
};
tableDataByTableName(querys).then((res) => {
setTableData(res.data);
headData.value = res.head;
let arr: any = [];
res.head.forEach((element) => {
arr.push({
title: element,
dataIndex: element,
});
});
setColumns(arr);
});
};
const exportTemplate = () => {
openTempeleteModel(true);
};
onMounted(() => {});
const customRequest = (file) => {
console.log('handleCustomRequest',file)
const name = file.file.name.toLowerCase();
if (name.endsWith('.zip')){
const formData = new FormData()
formData.append('files', file.file)
Upload(formData).then(res => {
console.log(res)
const filePath = res[0].filePath
let params = {
tableName: tableName.value,
zipFilePath: filePath
}
UploadShape(params).then(result => {
message.success('导入成功')
reload()
})
})
}else{
const formData = new FormData()
formData.append('file', file.file)
UploadExcelAll({File: formData, tableName: tableName.value}).then(res => {
message.success('导入成功')
reload()
})
}
// procedure.value ++
return false
}
</script>
<style lang="less" scoped>
.map-container {
position: relative;
}
.table-constainer {
padding: 20px;
width: 99%;
height: 40vh;
position: absolute;
bottom: 0;
left: 5px;
z-index: 2;
background-color: @component-background;
border-radius: 4px;
}
.drawer-title-box {
span {
margin-right: 100px;
}
button {
margin-right: 10px;
}
}
.close-icon {
position: absolute;
top: 20px;
right: 20px;
cursor: pointer;
}
.data-detail {
position: absolute;
top: 0;
right: 0;
background-color: @component-background;
z-index: 3;
width: 30%;
height: 100%;
padding: 20px;
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.2);
.detail-button {
position: absolute;
bottom: 30px;
right: 40px;
button {
margin-left: 10px;
}
}
}
.data-edit {
position: absolute;
top: 0;
right: 0;
background-color: @component-background;
z-index: 3;
width: 40%;
height: 100%;
padding: 20px;
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.2);
.data-button {
position: absolute;
width: 90%;
bottom: 30px;
display: flex;
justify-content: flex-end;
button {
margin-left: 10px;
}
}
}
.data-style {
position: absolute;
top: 0;
right: 0;
background-color: @component-background;
z-index: 3;
width: 30%;
height: 100%;
padding: 20px;
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.2);
.img-box {
height: 200px;
}
.data-button {
position: absolute;
width: 100%;
bottom: 30px;
button {
margin-left: 10px;
}
}
}
</style>
<style>
.batch-modal-wrap .ant-modal {
transform: scale(0.75) !important;
transform-origin: center !important;
}
</style>