违法用地-持续监管-增加图片选择、修改上传、增加导出shp

main
滕嵩 2025-05-29 17:30:58 +08:00
parent 2d5128f263
commit 40b8d68c4c
4 changed files with 211 additions and 72 deletions

View File

@ -144,8 +144,12 @@ enum Api {
UpdateCxjgData = '/api/DroneCaseInfoSingle/UpdateCxjgData',
// 持续监管-审核
CheckCxjgPic = '/api/DroneCaseInfoSingle/CheckCxjgPic',
// 持续监管-详情
GetCxjgCaseInfoById = '/api/DroneCaseInfoSingle/GetCxjgCaseInfoById',
// 持续监管-迁入违法专题
MoveInIllegalSubejct = '/api/DroneCaseInfoSingle/MoveInIllegalSubejct',
MoveInIllegalSubject = '/api/DroneCaseInfoSingle/MoveInIllegalSubject',
// 持续监管-导出
ExportCaseInfoCxjgShapefile = '/api/DroneCaseInfoSingle/ExportCaseInfoCxjgShapefile',
}
export const getPositionsTree = (params?: AccountParams) =>
defHttp.get<AccountListGetResultModel>({ url: Api.PositionsTree, params });
@ -548,6 +552,12 @@ export const UpdateCxjgData = (params) =>
// 持续监管-审核
export const CheckCxjgPic = (params) =>
defHttp.get({ url: Api.CheckCxjgPic, params });
// 持续监管-详情
export const GetCxjgCaseInfoById = (params) =>
defHttp.get({ url: Api.GetCxjgCaseInfoById, params });
// 持续监管-迁入违法专题
export const MoveInIllegalSubejct = (params) =>
defHttp.post({ url: Api.MoveInIllegalSubejct, params });
export const MoveInIllegalSubject = (params) =>
defHttp.post({ url: Api.MoveInIllegalSubject, params });
// 持续监管-导出
export const ExportCaseInfoCxjgShapefile = (params) =>
defHttp.post({ url: Api.ExportCaseInfoCxjgShapefile, params });

View File

@ -228,7 +228,11 @@
<a-tab-pane
key="3"
tab="整改情况"
v-if="props.showInfoData.is_illegal == 1 && props.showInfoData.weifaleixing == 0 && !['建设用地', '推堆土'].includes(props.showInfoData.typename)"
v-if="
props.showInfoData.is_illegal == 1 &&
props.showInfoData.weifaleixing == 0 &&
!['建设用地', '推堆土'].includes(props.showInfoData.typename)
"
>
<a-descriptions
:column="2"
@ -442,26 +446,62 @@
style="display: flex; justify-content: right; margin-top: 10px"
v-if="isKeepSupervision"
>
<a-button type="primary" @click="funMoveInIllegalSubejct"></a-button>
<a-button type="primary" @click="moveInIllegalSubejctOpen = true">
转入违法用地
</a-button>
</div>
</a-tab-pane>
</a-tabs>
</div>
<!-- File Preview && Download Start -->
<a-modal
v-model:open="previewFileModalVisible"
style="width: 100vw"
title="文件预览"
wrap-class-name="full-modal"
>
<FilePreview v-if="previewFileModalVisible" :fileUrl="previewFileUrl"></FilePreview>
<template #footer>
<a-button key="cancel" @click="handleCancelPreviewFile"></a-button>
<a-button key="confirm" type="primary" @click="handlerDownloadFle"></a-button>
</template>
</a-modal>
<!-- File Preview && Download Start -->
<a-modal
v-model:open="previewFileModalVisible"
style="width: 100vw"
title="文件预览"
wrap-class-name="full-modal"
>
<FilePreview v-if="previewFileModalVisible" :fileUrl="previewFileUrl"></FilePreview>
<template #footer>
<a-button key="cancel" @click="handleCancelPreviewFile"></a-button>
<a-button key="confirm" type="primary" @click="handlerDownloadFle"></a-button>
</template>
</a-modal>
<!--File Preview && Download End -->
<a-modal
v-model:open="moveInIllegalSubejctOpen"
style="width: 40vw; height: 40vw"
title="图斑照片选择"
@ok="funMoveInIllegalSubject"
>
<div class="moveListAllChoose">
<a-checkbox v-model:checked="moveListChecked" @change="moveListAllChoose">
按顺序全选
</a-checkbox>
</div>
<div class="moveModal">
<a-image-preview-group
:preview="{
visible: false,
}"
>
<template v-for="(imageItem, imageIndex) in casepicList" :key="imageIndex">
<div class="moveList">
<img
v-if="imageItem"
:src="`${VITE_GLOB_INFO_IMAGE_URL}/${imageItem}`"
style="cursor: pointer; width: 110px; height: 110px; margin: 5px"
@click="moveListAddOrRemove(imageItem)"
/>
<div v-if="moveList.findIndex((item) => item == imageItem) != -1" class="move">
{{ moveList.findIndex((item) => item == imageItem) + 1 }}
</div>
</div>
</template>
</a-image-preview-group>
</div>
</a-modal>
</div>
</template>
@ -469,7 +509,7 @@
import { defineProps, ref, computed, onBeforeMount, watch } from 'vue';
import MapboxMap from '@/components/MapboxMaps/MapComponent.vue';
import { getConfig, getGeom } from '@/api/sys/layerManagement';
import { MoveInIllegalSubejct } from '@/api/demo/system';
import { MoveInIllegalSubject } from '@/api/demo/system';
import { getLoadCaseImgList } from '@/api/tiankongdi';
import { useMessage } from '@/hooks/web/useMessage';
import axios from 'axios';
@ -491,11 +531,11 @@
const MapboxComponent = ref();
const mapConfig = ref({});
const props = defineProps(['showInfoData','hiddenInfoMap']);
const props = defineProps(['showInfoData', 'hiddenInfoMap']);
const activeKey = ref('1');
const geomsList = ref();
const imageList = ref([]);
console.log('props',props.showInfoData)
console.log('props', props.showInfoData);
watch(
() => props.showInfoData,
() => {
@ -506,7 +546,10 @@
},
);
async function getCaseImgList() {
imageList.value = await getLoadCaseImgList({ caseid: props.showInfoData.id,category:'违法用地' });
imageList.value = await getLoadCaseImgList({
caseid: props.showInfoData.id,
category: '违法用地',
});
MapboxComponent.value.handlerLoadPictureAzimuth(imageList.value);
//
@ -544,18 +587,18 @@
if (e && !isInitImageLisener.value) {
setTimeout(function () {
const targetNode = document.getElementsByClassName('ant-image-preview-img');
targetNode?.forEach((node,index)=>{
let imageObserver = new MutationObserver((mutationsList)=>{
for(const mutation of mutationsList){
if (node.getAttribute(mutation.attributeName).match('http')){
targetNode?.forEach((node, index) => {
let imageObserver = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (node.getAttribute(mutation.attributeName).match('http')) {
handlerPreviewImage(0, node.getAttribute(mutation.attributeName));
}
}
})
});
const config = { attributes: true };
imageObserver.observe(node, config);
isInitImageLisener.value = true;
})
});
}, 250);
}
}
@ -691,22 +734,22 @@
import FilePreview from '@/components/Upload/src/components/FilePreview.vue';
const previewFileModalVisible = ref(false);
const previewFileUrl = ref("");
const previewFileUrl = ref('');
const hanlderPreViewFile = (url)=>{
const hanlderPreViewFile = (url) => {
previewFileUrl.value = `${VITE_GLOB_INFO_IMAGE_URL}/${url}`;
previewFileModalVisible.value = true;
}
};
const handlerDownloadFle = ()=>{
const handlerDownloadFle = () => {
window.open(previewFileUrl.value, 'mozillaTab');
}
};
const handleCancelPreviewFile = ()=>{
const handleCancelPreviewFile = () => {
previewFileModalVisible.value = false;
}
};
///////
const getContainer = () => {
return document.getElementById('info-container');
};
@ -734,12 +777,33 @@
//
const isKeepSupervision = window.location.href.includes('/tiankongdi/keepSupervision');
//
const moveInIllegalSubejctOpen = ref(false);
const moveList: any = ref([]);
function moveListAddOrRemove(value) {
if (moveList.value.includes(value)) {
moveList.value = moveList.value.filter((item) => item !== value);
} else {
moveList.value.push(value);
}
}
//
const moveListChecked = ref(false);
function moveListAllChoose(e) {
if (e.target.checked) {
moveList.value = props.showInfoData.casepic.split(',');
} else {
moveList.value = [];
}
}
//
const funMoveInIllegalSubejct = async () => {
const funMoveInIllegalSubject = async () => {
let querys = {
caseId: props.showInfoData.id,
caseId: props.showInfoData.Id || props.showInfoData.id,
casepic: moveList.value.toString(),
};
await MoveInIllegalSubejct(querys).then((res) => {
await MoveInIllegalSubject(querys).then((res) => {
if (res) {
createMessage.success('转移成功!');
}
@ -817,4 +881,49 @@
overflow: auto;
padding-right: 10px;
}
//
.moveListAllChoose {
display: flex;
align-items: center;
justify-content: left;
margin-left: 30px;
height: 30px;
//
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE/Edge */
user-select: none;
}
.moveModal {
position: relative;
margin-left: 24px;
margin-right: 24px;
width: 100%;
display: flex;
flex-wrap: wrap;
max-height: 600px;
overflow-y: auto;
.moveList {
position: relative;
width: 120px;
height: 120px;
.move {
position: absolute;
bottom: 5px;
right: 5px;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
background: red;
color: azure;
}
}
}
</style>

View File

@ -65,16 +65,6 @@
</template>
</BasicTable>
</div>
<a-modal v-model:open="open" title="导出文件类型" :footer="null">
<div>
<a-button class="exportbutton" @click="handleExport('excel')">
持续监管列表统计报表execl
</a-button>
<a-button class="exportbutton" @click="handleExport('shp')">
持续监管列表矢量数据shp
</a-button>
</div>
</a-modal>
<a-modal
style="width: 100vw; top: 0px; left: 0px; margin: 0px; padding: 0px"
wrap-class-name="full-modal"
@ -112,7 +102,11 @@
<script lang="ts" setup>
import { ref, reactive, onMounted, watch } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { LoadCaseInfoCxjgTuBanList, loadCaseInfoTuBanList } from '@/api/demo/system';
import {
LoadCaseInfoCxjgTuBanList,
GetCxjgCaseInfoById,
ExportCaseInfoCxjgShapefile,
} from '@/api/demo/system';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './keepSupervision.data';
import { getAppEnvConfig } from '@/utils/env';
@ -176,7 +170,7 @@
});
const [registerTable, { setTableData, reload, clearSelectedRowKeys, setPagination, setLoading }] =
useTable({
title: '图斑列表',
title: '持续监管列表',
dataSource: tableData.value,
columns,
rowKey: 'id',
@ -199,18 +193,13 @@
});
//
function handleExport(exportType) {
console.log(searchParams);
function handleExport() {
let params = { ...searchParams.value };
let url = '';
let fileName = '';
if (exportType == 'excel') {
url = VITE_GLOB_API_URL + '/api/DroneCaseInfoSingle/ExportCaseInfoTuBanList';
fileName = '图斑列表统计报表' + new Date().getTime() + '.xls';
} else if (exportType == 'shp') {
url = VITE_GLOB_API_URL + '/api/DroneCaseInfoSingle/ExportCaseInfoShapefile';
fileName = '图斑列表矢量数据' + new Date().getTime() + '.zip';
}
delete params['page'];
delete params['limit'];
console.log(params);
let url = VITE_GLOB_API_URL + '/api/DroneCaseInfoSingle/ExportCaseInfoShapefile';
let fileName = '图斑列表矢量数据' + new Date().getTime() + '.zip';
axios({
method: 'post',
url: url,
@ -231,14 +220,13 @@
});
}
const open = ref<boolean>(false);
function onBtnClicked(domId) {
switch (domId) {
case 'btnUpload':
uploadOpen.value = true;
break;
case 'btnExport':
open.value = true;
handleExport();
break;
default:
break;
@ -249,7 +237,7 @@
getDetailData();
}
function getDetailData() {
getCaseInfoById({ id: showInfoId.value }).then((res) => {
GetCxjgCaseInfoById({ id: showInfoId.value }).then((res) => {
showInfoData.value = res;
showInfoOpen.value = true;
});

View File

@ -71,14 +71,25 @@
<a-tag color="success" v-if="record.status == 'done'"></a-tag>
<a-tag color="error" v-if="record.status == 'error'"></a-tag>
<a-tag color="green" v-if="record.status == 'updateSuccess'"></a-tag>
<a-tag color="red" v-if="record.status == 'updateError'"></a-tag>
<a-tag color="red" v-if="record.status == 'updateError'"></a-tag>
</template>
<template v-if="column.dataIndex === 'url' || column.dataIndex === 'message'">
{{ record.url || record.message }}
</template>
</template>
</a-table>
<div class="update">
<div class="updateDiv">
<a-tooltip
v-if="
fileList && fileList.length > 0 && fileList.find((item) => item.status == 'updateError')
"
>
<template #title>在报有未审核的图片不允许上传的错误时可以点击</template>
<a-button type="primary" @click="funCheckCxjgPic" style="margin-right: 10px">
审核图片
</a-button>
</a-tooltip>
<!-- {{ .length }} -->
<a-button type="primary" @click="startUploadCXJGData">
将上传成功的图片插入到数据库
</a-button>
@ -93,6 +104,7 @@
import axios from 'axios';
import { UpdateCxjgData, CheckCxjgPic } from '@/api/demo/system';
import { uploadColumns } from './keepSupervision.data';
import { message } from 'ant-design-vue';
const { VITE_GLOB_INFO_IMAGE_URL } = getAppEnvConfig();
@ -179,14 +191,12 @@
...fileList.value[index],
status: 'updateSuccess',
};
return true;
} else {
//
fileList.value[index] = {
...fileList.value[index],
status: 'updateError',
};
return false;
}
} else {
//
@ -194,7 +204,7 @@
...fileList.value[index],
status: 'updateError',
};
return false;
message.error('有未审核的图片,不允许上传');
}
} catch (error) {
console.error('上传或审核出错:', error);
@ -202,7 +212,28 @@
...fileList.value[index],
status: 'updateError',
};
return false;
}
}
// -
async function funCheckCxjgPic() {
const list = fileList.value;
if (!list || list.length === 0) return;
for (let i = 0; i < list.length; i++) {
const item = list[i];
if (item.status === 'updateError') {
// true
let caseid = item.name.split('.').slice(0, -1).join('.');
if (caseid.includes('_')) {
caseid = caseid.split('_').slice(0, 1).join('_');
}
await CheckCxjgPic({ id: caseid });
const index = fileList.value.findIndex((item) => item.uid === item.uid);
fileList.value[index] = {
...fileList.value[index],
status: 'updateSuccess',
};
}
}
}
</script>
@ -216,10 +247,11 @@
margin-left: 20px;
margin-right: 20px;
}
.update {
.updateDiv {
position: absolute;
bottom: 10px;
right: 10px;
gap: 10px;
}
::v-deep .ant-select-selection-item {