784 lines
22 KiB
Vue
784 lines
22 KiB
Vue
<template>
|
||
<PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
|
||
<LayerTree
|
||
ref="treeRef"
|
||
class="w-1/4 xl:w-1/5"
|
||
@select="handleSelect"
|
||
@flyToLayer="flyToLayer"
|
||
@edit="editLayer"
|
||
@add="addLayer"
|
||
@checked="checkedLayer"
|
||
@remove="tableVisible = false"
|
||
/>
|
||
<div class="map-container w-3/4 xl:w-4/5">
|
||
<Map @onLoad="onMapLoad" />
|
||
<!-- 数据列表 -->
|
||
<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-dropdown>
|
||
<template #overlay>
|
||
<a-menu>
|
||
<a-menu-item key="1" @click="addData('point')">
|
||
<UserOutlined />
|
||
点数据
|
||
</a-menu-item>
|
||
<a-menu-item key="2" @click="addData('polyline')">
|
||
<UserOutlined />
|
||
线数据
|
||
</a-menu-item>
|
||
<a-menu-item key="3" @click="addData('polygon')">
|
||
<UserOutlined />
|
||
面数据
|
||
</a-menu-item>
|
||
</a-menu>
|
||
</template>
|
||
<a-button>
|
||
添加
|
||
<DownOutlined />
|
||
</a-button>
|
||
</a-dropdown>
|
||
|
||
<a-button type="primary" @click="exportTemplate"> 导出模版 </a-button>
|
||
<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'">
|
||
<div class="detail-content">
|
||
<a-descriptions title="详情" :column="columnVal">
|
||
<a-descriptions-item
|
||
v-for="(item, index) in detailData"
|
||
:key="index"
|
||
:label="item.label"
|
||
>{{ item.value }}</a-descriptions-item
|
||
>
|
||
</a-descriptions>
|
||
</div>
|
||
<div class="detail-button">
|
||
<a-button type="primary" @click="detailToEdit"> 编辑 </a-button>
|
||
|
||
<a-button type="primary" @click="closeDetail" danger> 关闭 </a-button>
|
||
|
||
</div>
|
||
</div>
|
||
<!-- 编辑 -->
|
||
<div class="data-edit" v-if="showTable == 'edit' || showTable == 'add'">
|
||
<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.title"
|
||
:name="item"
|
||
:key="index"
|
||
>
|
||
<a-input v-model:value="formState[item.dataIndex]" />
|
||
</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"
|
||
>
|
||
<p class="ant-upload-drag-icon">
|
||
<inbox-outlined></inbox-outlined>
|
||
</p>
|
||
<p class="ant-upload-text">上传SLD文件</p>
|
||
</a-upload-dragger>
|
||
<div v-if="fileUrl">
|
||
<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" @editorCancel="editorCancel" />
|
||
<a-modal
|
||
:keyboard="false"
|
||
:maskClosable="false"
|
||
wrapClassName="batch-modal-wrap"
|
||
class="BatchProcessingModal"
|
||
width="1660px"
|
||
v-model:open="batchProcessingModalOpen"
|
||
:footer="null"
|
||
:closable="false"
|
||
:destroyOnClose="true"
|
||
style="top: 50px"
|
||
>
|
||
<BatchProcessingModal
|
||
:applicationName="applicationName"
|
||
: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,
|
||
addTableData,
|
||
uploadSldStyle,
|
||
getSldFilePath,
|
||
} 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';
|
||
|
||
import { EventBus } from '@/utils/eventBus';
|
||
|
||
import {
|
||
GetGeometryCenter,
|
||
EditDrawingGeometry,
|
||
AddDrawingGeometry,
|
||
PreviewDrawingGeometry,
|
||
DrawingEnd,
|
||
GeojsonToWkt,
|
||
} from './geometryHandler.ts';
|
||
|
||
import * as mars3d from 'mars3d';
|
||
|
||
const { VITE_GLOB_GEOSERVER_BASE_URL } = getAppEnvConfig();
|
||
|
||
let globalMap: mars3d.Map;
|
||
|
||
const onMapLoad = (map) => {
|
||
globalMap = map;
|
||
};
|
||
|
||
EventBus.on('editLayerEnd', function (e) {
|
||
formState.value.geom = e;
|
||
});
|
||
|
||
// 图层目录树控制逻辑
|
||
const handlerLoadLayer = (node) => {
|
||
|
||
if(node.node.tableName){ // 图层节点
|
||
handlerToggleLayer(node.node);
|
||
}else{ // 分类节点
|
||
node.node.child?.forEach((item,index)=>{
|
||
if(!node.node.checked){
|
||
item.checked = node.node.checked;
|
||
handlerToggleLayer(item);
|
||
}
|
||
})
|
||
}
|
||
};
|
||
|
||
const handlerToggleLayer = (node)=>{
|
||
if(!node.checked){
|
||
let layer = globalMap.getLayerById(node.id);
|
||
if(layer){
|
||
layer.show = true
|
||
}else{
|
||
let tileLayer = new mars3d.layer.WmsLayer({
|
||
name: node.applicationName,
|
||
id:node.id,
|
||
url: VITE_GLOB_GEOSERVER_BASE_URL+"/geoserver/my_workspace/wms",
|
||
layers: "my_workspace:"+node.tableName,
|
||
parameters: {
|
||
transparent: true,
|
||
format: 'image/png',
|
||
},
|
||
crs: "EPSG:4326",
|
||
getFeatureInfoParameters: {
|
||
feature_count: 10
|
||
},
|
||
// 单击高亮及其样式
|
||
highlight: {
|
||
type: "wallP",
|
||
diffHeight: 100,
|
||
materialType: mars3d.MaterialType.LineFlow,
|
||
materialOptions: {
|
||
image: "https://data.mars3d.cn/img/textures/fence.png",
|
||
color: "#ffff00",
|
||
speed: 10, // 速度,建议取值范围1-100
|
||
axisY: true
|
||
}
|
||
},
|
||
popup: "all",
|
||
flyTo: false,
|
||
featureToGraphic:function(e){ // 获取点击查询到的数据
|
||
let wkt = GeojsonToWkt(e.data.geometry);
|
||
let editData = {...e.data.properties}
|
||
editData.geom = wkt;
|
||
viewData(editData)
|
||
}
|
||
})
|
||
globalMap.addLayer(tileLayer);
|
||
}
|
||
}else{
|
||
let layer = globalMap.getLayerById(node.id);
|
||
if(layer){
|
||
layer.show = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
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, setPagination, getColumns },
|
||
] = 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 applicationName = 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],
|
||
});
|
||
}
|
||
|
||
if (showTable.value == 'edit') {
|
||
updateTableData(params).then((res) => {
|
||
console.log('res', res);
|
||
if (res) {
|
||
createMessage.success('编辑成功!');
|
||
DrawingEnd();
|
||
showTable.value = '';
|
||
} else {
|
||
createMessage.error('编辑失败!');
|
||
}
|
||
});
|
||
} else if (showTable.value == 'add') {
|
||
params.list = [];
|
||
|
||
headData.value?.forEach((item, index) => {
|
||
params.list.push({
|
||
name: item.dataIndex,
|
||
value: formState.value[item] ? formState.value[item] : null,
|
||
});
|
||
});
|
||
console.log('params', params.list);
|
||
|
||
addTableData(params).then((res) => {
|
||
console.log('res', res);
|
||
if (res) {
|
||
createMessage.success('添加成功!');
|
||
DrawingEnd();
|
||
showTable.value = '';
|
||
} else {
|
||
createMessage.error('添加失败!');
|
||
}
|
||
});
|
||
}
|
||
//清空图层
|
||
DrawingEnd();
|
||
})
|
||
.catch((error: ValidateErrorEntity<FormState>) => {
|
||
console.log('error', error);
|
||
});
|
||
};
|
||
const resetForm = () => {
|
||
showTable.value = '';
|
||
DrawingEnd();
|
||
};
|
||
|
||
const handleSelect = (record) => {
|
||
tableName.value = record.tableName;
|
||
applicationName.value = record.applicationName;
|
||
tableVisible.value = true;
|
||
keyWord.value = null;
|
||
keyValue.value = null;
|
||
showTable.value = '';
|
||
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 checkedLayer = (node) => {
|
||
handlerLoadLayer(node);
|
||
}
|
||
|
||
const flyToLayer = (id) => {
|
||
let layer = globalMap.getLayerById(id);
|
||
if(layer){
|
||
layer.flyTo();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
const hanlerLoadLayer = () => {};
|
||
const handleSuccess = () => {
|
||
treeRef.value.fetch();
|
||
};
|
||
const addData = (type) => {
|
||
AddDrawingGeometry(globalMap, type);
|
||
showTable.value = 'add';
|
||
};
|
||
const detailData = ref([]);
|
||
const editData = (record) => {
|
||
selectVal.value = record;
|
||
formState.value = record;
|
||
showTable.value = 'edit';
|
||
|
||
EditDrawingGeometry(globalMap, record.geom);
|
||
};
|
||
|
||
const viewData = (record) => {
|
||
PreviewDrawingGeometry(globalMap, record.geom);
|
||
selectVal.value = record;
|
||
formState.value = record;
|
||
showTable.value = 'detail';
|
||
detailData.value = [];
|
||
for (const key in record) {
|
||
for (var i = 0; i < headData.value.length; i++) {
|
||
if (headData.value[i].dataIndex == key) {
|
||
detailData.value.push({
|
||
label: headData.value[i].title,
|
||
value: record[key],
|
||
});
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
const detailToEdit = () => {
|
||
editData(formState.value);
|
||
showTable.value = 'edit';
|
||
};
|
||
|
||
const detailClose = ()=>{
|
||
showTable.value = ''
|
||
DrawingEnd();
|
||
}
|
||
|
||
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) => {
|
||
let centerLngLat = GetGeometryCenter(record.geom);
|
||
globalMap.flyToPoint(centerLngLat, { radius: 500 });
|
||
};
|
||
|
||
const styleHandle = () => {
|
||
showTable.value = 'style';
|
||
getSldFilePath({ tablename: tableName.value }).then((res) => {
|
||
if (res) {
|
||
fileUrlView.value.name = res.filepath;
|
||
fileUrl.value = res.filepath;
|
||
fileUrlView.value.url = res.filepath;
|
||
fileUrlView.value.id = res.fileid;
|
||
styleName.value = res.stylename;
|
||
} else {
|
||
fileUrl.value = '';
|
||
fileUrlView.value = {};
|
||
styleName.value = '';
|
||
}
|
||
});
|
||
};
|
||
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,
|
||
id: fileUrlView.value.id,
|
||
};
|
||
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) => {
|
||
searchData.page = values.current;
|
||
searchData.limit = values.pageSize;
|
||
getList();
|
||
};
|
||
const getList = () => {
|
||
if (!tableName.value) {
|
||
tableVisible.value = false;
|
||
message.warning('当前图层没有关联空间数据表');
|
||
return;
|
||
}
|
||
let realUseKeyWord = getColumns().find(item => item.dataIndex == keyWord.value || item.title == keyWord.value)
|
||
const querys = {
|
||
...searchData,
|
||
tablename: tableName.value,
|
||
keyword: realUseKeyWord? realUseKeyWord.dataIndex: '',
|
||
keyvalue: keyValue.value,
|
||
};
|
||
tableDataByTableName(querys).then((res) => {
|
||
setTableData(res.data);
|
||
let arr: any = [];
|
||
res.headName.forEach((element, index) => {
|
||
arr.push({
|
||
title: element.comment ? element.comment : element.columnName,
|
||
dataIndex: element.columnName,
|
||
});
|
||
});
|
||
headData.value = arr;
|
||
setPagination({ total: res.total });
|
||
setColumns(arr);
|
||
});
|
||
};
|
||
const exportTemplate = () => {
|
||
openTempeleteModel(true);
|
||
};
|
||
onMounted(() => {});
|
||
const editorCancel = () => {
|
||
fileList.value = [];
|
||
fileUrlView.value = {};
|
||
fileUrl.value = '';
|
||
};
|
||
const closeDetail = () => {
|
||
showTable.value = ''
|
||
DrawingEnd()
|
||
}
|
||
</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;
|
||
background-color: @component-background;
|
||
|
||
button {
|
||
margin-left: 10px;
|
||
}
|
||
}
|
||
.detail-content {
|
||
overflow-y: scroll;
|
||
height: 80vh;
|
||
}
|
||
}
|
||
.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>
|