徐景良 2024-07-03 15:35:19 +08:00
commit 07d46e6420
14 changed files with 1456 additions and 74 deletions

View File

@ -1,6 +1,6 @@
// WFProcess 流程模版基本信息
import { defHttp } from '@/utils/http/axios';
import { taskCountParams, caseInfoParams, countModel, taskInfoParams } from './model/index';
import { taskCountParams, caseInfoParams, countModel, taskInfoParams, addCaseFavoriteParams } from './model/index';
enum Api {
// 获取待办任务统计数据
@ -11,6 +11,11 @@ enum Api {
LoadDroneCaseInfoDetail = '/api/DroneCaseInfoSingle/LoadDroneCaseInfoDetail',
// 分页获取任务信息列表
LoadTaskDetailList = '/api/DroneCaseInfoSingle/LoadTaskDetailList',
// 收藏案件
AddCaseFavorite = '/api/DroneCaseinfo/AddCaseFavorite',
// 获取收藏案件列表
FavoriteCaseList = '/api/DroneCaseinfo/FavoriteCaseList',
DeleteFavoriteCase = '/api/DroneCaseinfo/DeleteFavoriteCase',
}
/**
@ -39,3 +44,14 @@ export function getLoadDroneCaseInfoDetail(params?: caseInfoParams) {
export function getLoadTaskDetailList(params?: taskInfoParams) {
return defHttp.get({ url: Api.LoadTaskDetailList, params });
}
export function addCaseFavorite(params?: addCaseFavoriteParams) {
return defHttp.post({ url: Api.AddCaseFavorite, params });
}
export function deleteFavoriteCase(params: string){
return defHttp.post({ url: Api.DeleteFavoriteCase, data:params });
}
export function getFavoriteCaseList(params?: {uid:string}) {
return defHttp.get({ url: Api.FavoriteCaseList, params });
}

View File

@ -12,6 +12,12 @@ export interface taskInfoParams {
is_build_complete?: number;
}
export interface addCaseFavoriteParams {
id: string,
caseNo: string,
favoriteUserId: string,
}
export interface caseInfoParams {
page?: number;
limit?: number;

View File

@ -109,6 +109,7 @@
align-items: center;
padding: 10px;
justify-content: space-between;
border-bottom: 1px solid #ececec;
.name-div {
display: flex;
align-items: center;
@ -138,7 +139,7 @@
}
}
}
.no-data{
.no-data {
padding: 20px 0;
}
</style>

View File

@ -52,7 +52,7 @@
>
<div class="select-mark"></div>
<Icon
style="font-size: 30px; color: #bf0000; cursor: pointer"
style="font-size: 30px; color: #0a6dea; cursor: pointer"
icon="gis:poi-alt"
@click="locationFun(item)"
/>
@ -60,7 +60,9 @@
<div class="item-info-div">
<div class="item-info-id">{{ item.case_no }}</div>
<div class="item-info-layout">
<div class="item-info-address" :title="item.address">{{ item.address }}</div>
<div class="item-info-address" :title="item.address">
<a-tag color="processing" v-if="item.address">{{ item.address }}</a-tag>
</div>
<div class="item-info-batch">
<a-tag color="success">{{ item.unitname }}</a-tag>
</div>
@ -170,7 +172,7 @@
{ label: '已建成', value: 1 },
{ label: '持续变化', value: 2 },
]);
const dataList = ref([]);
const total = ref(0);
async function getTaskList() {
@ -274,12 +276,10 @@
margin-bottom: 5px;
.item-info-id {
width: 178px;
background: #bf2c64;
color: #fff;
border-radius: 11px;
display: flex;
align-items: center;
justify-content: center;
// justify-content: center;
height: 22px;
}
.item-info-layout {
@ -289,7 +289,7 @@
justify-content: space-between;
}
.item-info-address {
width: 120px;
// width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
@ -338,12 +338,14 @@
}
}
.button-div {
flex: 1;
width: 100%;
height: 100%;
height: 30px;
width: 30px;
display: flex;
justify-content: space-evenly;
font-size: 20px;
border: 1px solid #d9d9d9;
border-radius: 50%;
margin-left: 10px;
.collect-button:hover {
color: rgb(255, 205, 42);
}

View File

@ -102,7 +102,7 @@
//
let list: any = [];
//
year.value = Number(`${currentYear}`);
// year.value = Number(`${currentYear}`);
list.push({
value: Number(`${currentYear}`),
label: Number(`${currentYear}`),

View File

@ -0,0 +1,144 @@
<template>
<div class="screen-div">
<div class="screen-row">
<div class="screen-item">
<div class="screen-item-label">年份</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.year"
:options="yearOptions"
@change="
(value) => {
emits('auditProgressScreenChange', value, 'year');
}
"
/>
</div>
<div class="screen-item">
<div class="screen-item-label">批次</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.batch"
:options="batchOptions"
@change="
(value) => {
emits('auditProgressScreenChange', value, 'batch');
}
"
/>
</div>
</div>
</div>
<div class="data-list">
<!-- <div class="data-title">审核进度</div> -->
<div class="show-data-list-content">
<div
class="data-item"
v-for="(item, index) in dataList"
:key="index"
@click="emits('showInfo', true, item)"
v-if="dataList.length > 0"
>
<div class="name-div">
<div class="item-mark"></div>
<div class="item-label">{{ item.areaname }}</div>
</div>
<div class="data-div">
<span>{{ item.count }}</span>
</div>
</div>
<div v-else class="no-data">
<a-empty :image="simpleImage" />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, defineProps, defineEmits, toRefs } from 'vue';
import { batchOptions, yearOptions } from '@/views/demo/bootstraps/curbspotcity/util.ts';
import { Empty } from 'ant-design-vue';
const props = defineProps(['year', 'batch', 'dataList']);
const emits = defineEmits(['auditProgressScreenChange', 'showInfo']);
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
</script>
<style lang="less" scoped>
.screen-div {
background: @component-background;
padding: 10px;
.screen-row {
display: flex;
.screen-item {
flex: 1;
display: flex;
.screen-item-label {
width: 55px;
padding-left: 10px;
display: flex;
align-items: center;
font-size: 15px;
}
}
}
}
.data-list {
height: calc(100% - 52px);
background: @component-background;
margin-top: 10px;
// background: darkgoldenrod;
.data-title {
height: 40px;
background: #bab9b7;
font-size: 18px;
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
color: #366198;
}
.show-data-list-content {
.data-item {
width: 100%;
display: flex;
height: 50px;
align-items: center;
padding: 10px;
justify-content: space-between;
border-bottom: 1px solid #ececec;
.name-div {
display: flex;
align-items: center;
}
.data-div {
font-weight: 500;
margin-right: 5px;
}
.item-mark {
width: 5px;
height: 5px;
background: #086dec;
margin-left: 7px;
margin-right: 7px;
}
.item-label {
font-size: 16px;
font-weight: 600;
margin-left: 5px;
}
}
.data-item:hover {
background-color: rgba(8, 109, 236, 0.08);
}
.data-item:nth-child(2n) {
background: #ececec;
}
}
}
.no-data {
padding: 20px 0;
}
</style>

View File

@ -0,0 +1,117 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="飞地调整" @ok="handleSubmit">
<BasicForm @register="registerForm" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form';
import { accountFormSchema } from './account.data';
import { addAccount } from '@/api/demo/system';
import { useMessage } from '@/hooks/web/useMessage';
import md5 from 'js-md5';
import { fun_getCaseInfo } from '@/api/demo/query';
const { createMessage } = useMessage();
defineOptions({ name: 'AccountModal' });
const emit = defineEmits(['success', 'register']);
const isUpdate = ref(true);
const rowId = ref('');
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100,
baseColProps: { span: 24 },
schemas: [
{
field: 'id',
label: '县区',
component: 'Input',
required: true,
},
{
field: 'account',
label: '乡镇',
component: 'Input',
// helpMessage: ['', 'admin'],
rules: [
{
required: true,
message: '请输入账号',
},
// {
// trigger: 'blur',
// validator(_, value) {
// return new Promise((resolve, reject) => {
// if (!value) return resolve();
// isAccountExist(value)
// .then(resolve)
// .catch((err) => {
// reject(err.message || '');
// });
// });
// },
// },
],
},
{
field: 'name',
label: '村/社区',
component: 'Input',
required: true,
},
],
showActionButtonGroup: false,
actionColOptions: {
span: 23,
},
});
const case_no = ref();
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
console.log(data);
isUpdate.value = !!data?.isUpdate;
case_no.value = data.record.id;
getDetail();
if (unref(isUpdate)) {
rowId.value = data.record.id;
setFieldsValue({
...data.record,
});
}
});
async function getDetail() {
const data = await fun_getCaseInfo({
id: case_no.value,
});
console.log(data);
setFieldsValue({
...data,
});
}
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
if (values.password) {
values.password = md5(values.password);
}
const data = await addAccount(values);
console.log(data);
if (data) {
// TODO custom api
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
return createMessage.success('成功');
} else {
return createMessage.error('失败');
}
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>

View File

@ -0,0 +1,522 @@
<template>
<div class="content">
<div class="rollback">
<Icon
style="font-size: 20px; cursor: pointer"
icon="ant-design:arrow-left-outlined"
@click="emits('closeShowInfo', false)"
/>
</div>
<div class="screen-div">
<div class="screen-item">
<div class="screen-item-label">年份</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.year"
:options="yearOptions"
@change="(value) => emits('mapListScreenChange', value, 'year')"
/>
</div>
<div class="screen-item">
<div class="screen-item-label">批次</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.batch"
:options="batchOptions"
@change="(value) => emits('mapListScreenChange', value, 'batch')"
/>
</div>
<div class="screen-item">
<div class="screen-item-label">图斑号</div>
<a-input
allowClear
v-model:value="props.infoScreenData.mapNo"
style="flex: 1"
@change="(value) => emits('mapListScreenChange', value.target.value, 'mapNo')"
/>
</div>
<div class="screen-item" v-if="cityType.level === 0">
<div class="screen-item-label">市级区划</div>
<a-select
disabled
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.countyId"
:options="props.municipalAreaOptions"
@change="(value) => emits('mapListScreenChange', value, 'countyId')"
/>
</div>
<div class="screen-item" v-if="cityType.level === 0">
<div class="screen-item-label">县级区划</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.streetId"
:options="props.countiesAreaOptions"
@change="(value) => emits('mapListScreenChange', value, 'streetId')"
/>
</div>
<div class="screen-item" v-if="cityType.level !== 0">
<div class="screen-item-label">县级区划</div>
<a-select
disabled
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.countyId"
:options="props.municipalAreaOptions"
@change="(value) => emits('mapListScreenChange', value, 'countyId')"
/>
</div>
<div class="screen-item" v-if="cityType.level !== 0">
<div class="screen-item-label">镇级区划</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.streetId"
:options="props.countiesAreaOptions"
@change="(value) => emits('mapListScreenChange', value, 'streetId')"
/>
</div>
<div class="screen-item">
<div class="screen-item-label">图斑类型</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.mapType"
:options="mapTypeOptions"
@change="(value) => emits('mapListScreenChange', value, 'mapType')"
/>
</div>
<div class="screen-item" v-if="props.infoScreenData.mapType === 1">
<div class="screen-item-label">违法类型</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.illegalType"
:options="illegalTypeOptions"
@change="(value) => emits('mapListScreenChange', value, 'illegalType')"
/>
</div>
<div class="screen-item" v-if="props.infoScreenData.illegalType === 0">
<div class="screen-item-label">整改措施</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.measure"
:options="measureOptions"
@change="(value) => emits('mapListScreenChange', value, 'measure')"
/>
</div>
<div class="screen-item">
<div class="screen-item-label">图斑状态</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.mapStatus"
:options="mapStatusOptions"
@change="(value) => emits('mapListScreenChange', value, 'mapStatus')"
/>
</div>
<div class="screen-item">
<div class="screen-item-label">标注类型</div>
<a-select
allowClear
style="flex: 1"
v-model:value="props.infoScreenData.markType"
:options="markTypeOptions"
@change="(value) => emits('mapListScreenChange', value, 'markType')"
/>
</div>
<div class="screen-button-div">
<a-button type="primary" @click="dataListSort('area')">
{{ `排序(图斑面积) ${props.infoScreenData.sort === 'area' ? orderMark() : '-'}` }}
</a-button>
<a-button type="primary" @click="dataListSort('gengdi_area')">
{{ `排序(耕地面积) ${props.infoScreenData.sort === 'gengdi_area' ? orderMark() : '-'}` }}
</a-button>
<a-button type="primary">导出</a-button>
<!-- <a-button
type="primary"
:style="openCollect && 'background: #bf0000;'"
@click="getCollectList"
>我的收藏</a-button
> -->
<a-button @click="emits('getInfoList')"></a-button>
</div>
</div>
<div class="data-list-div">
<div
v-if="props.infoDataList.length > 0"
v-for="(item, index) in props.infoDataList"
:key="index"
class="data-list-item"
>
<div class="select-mark"></div>
<Icon
style="font-size: 30px; color: #0a6dea; cursor: pointer"
icon="gis:poi-alt"
@click="locationFun(item)"
/>
<div class="data-list-item-content">
<div class="item-info-div">
<div class="item-info-id">{{ item.case_no }}</div>
<div class="item-info-layout">
<div class="item-info-batch">
<a-tag color="processing" v-if="item.address">{{ item.address }}</a-tag>
</div>
<div class="item-info-batch">
<a-tag color="success" v-if="item.case_description">{{
item.case_description
}}</a-tag>
</div>
</div>
</div>
<div class="item-data-div">
<div class="item-data-item" v-if="item.area">
<div class="item-mark-div sum-mark"></div>
{{ item.area }}
</div>
<div class="item-data-item" v-if="item.gengdi_area">
<div class="item-mark-div plowland-mark"></div>
{{ item.gengdi_area }}
</div>
<div class="item-data-item" v-if="item.nongyongdi_area">
<div class="item-mark-div farmland-mark"></div>
{{ item.nongyongdi_area }}
</div>
<div class="item-data-item" v-if="item.zhongdianquyu_area">
<div class="item-mark-div adjust-mark"></div>
{{ item.zhongdianquyu_area }}
</div>
<div class="item-data-item" v-if="item.guotukongjianguihua_area">
<div class="item-mark-div guihua-mark"></div>
{{ item.guotukongjianguihua_area }}
</div>
<div class="item-data-item" v-if="item.shengtaibaohuhongxian_area">
<div class="item-mark-div shengtai-mark"></div>
{{ item.shengtaibaohuhongxian_area }}
</div>
</div>
</div>
<div class="button-div">
<!-- <StarOutlined class="collect-button" /> -->
<Icon
title="飞地调整"
style="font-size: 20px"
icon="ant-design:send-outlined"
@click="changeArea(item)"
/>
</div>
<div class="button-div">
<!-- <StarOutlined class="collect-button" /> -->
<Icon
title="详情"
style="font-size: 20px; color: #0960bd"
icon="bx:detail"
@click="showInfo(item)"
/>
</div>
</div>
<div v-else class="no-data">
<a-empty :image="simpleImage" />
</div>
</div>
<div class="pagination-div">
<a-pagination
size="small"
v-model:pageSize="props.pageSize"
v-model:current="props.pageNo"
:total="props.total"
show-size-changer
show-quick-jumper
@change="changePage"
/>
</div>
<Amend @register="registerModal" @success="handleSuccess" />
<a-modal
width="80%"
v-model:open="showInfoOpen"
title="详情"
:footer="null"
:maskClosable="true"
:destroyOnClose="true"
@cancel="showInfoOpen = false"
>
<div class="modal-content">
<ShowInfoModal :showInfoData="showInfoData" />
</div>
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, defineEmits, defineProps, computed } from 'vue';
import { StarOutlined } from '@ant-design/icons-vue';
import Icon from '@/components/Icon/Icon.vue';
import {
addCaseFavorite,
getFavoriteCaseList,
deleteFavoriteCase,
} from '@/api/bootstraps/index.ts';
import { getLoadDroneCaseInfoDetail } from '@/api/bootstraps/index.ts';
import {
batchOptions,
yearOptions,
mapTypeOptions,
illegalTypeOptions,
measureOptions,
mapStatusOptions,
markTypeOptions,
} from '@/views/demo/bootstraps/curbspotcity/util.ts';
import Amend from './amend.vue';
import { useModal } from '@/components/Modal';
import { Empty } from 'ant-design-vue';
import ShowInfoModal from '@/views/demo/bootstraps/curbspotcity/MapList/ShowInfoModal/index.vue';
const [registerModal, { openModal }] = useModal();
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
const emits = defineEmits([
'closeShowInfo',
'mapListScreenChange',
'changeInfoPage',
'getInfoList',
'changeTask',
'infoDataListSort',
'collectChange',
]);
const props = defineProps([
'infoScreenData',
'cityType',
'municipalAreaOptions',
'countiesAreaOptions',
'pageNo',
'pageSize',
'total',
'infoDataList',
]);
const order = ref(0); // 0: 1: 2:
const orderMark = () => {
switch (order.value) {
case 0:
return '-';
case 1:
return '↑';
case 2:
return '↓';
}
};
const showInfoOpen = ref(false);
const openCollect = computed(() => {
if (props.infoScreenData.type === '') return false;
return true;
});
const showInfoData = ref();
onMounted(() => {
console.log('onMounted');
});
async function locationFun(record) {
console.log(record);
emits('changeTask', record.geomid);
}
const changePage = (page, pageSize) => {
console.log(page, pageSize);
emits('changeInfoPage', page, pageSize);
};
const collectItem = (item) => {
console.log(item);
let userInfo = userStore.getUserInfo;
let params = {
id: item.id,
caseNo: item.case_no,
favoriteUserId: userInfo.id,
};
addCaseFavorite(params).then((res) => {
console.log(res);
message.success('收藏成功');
emits('getInfoList');
});
};
const cancelCollectItem = (item) => {
deleteFavoriteCase(item.Fid).then((res) => {
message.success('取消收藏成功');
emits('getInfoList');
});
};
const getCollectList = () => {
let collect = props.infoScreenData.type;
let value: number | string = '';
if (collect === '') {
value = 1;
} else if (collect === 1) {
value = '';
}
emits('collectChange', value);
};
const dataListSort = (type) => {
order.value = (order.value + 1) % 3;
emits('infoDataListSort', type, order.value);
};
const showInfo = (item) => {
console.log(item);
showInfoData.value = item;
showInfoOpen.value = true;
};
function changeArea(record) {
console.log(record);
openModal(true, {
record: record,
});
}
function handleSuccess() {}
</script>
<style lang="less" scoped>
.content {
height: 100%;
display: flex;
flex-direction: column;
}
.screen-div {
padding: 10px;
background: @component-background;
display: flex;
width: 100%;
flex-wrap: wrap;
margin-top: 10px;
.screen-item {
width: 50%;
display: flex;
margin-bottom: 3px;
.screen-item-label {
width: 75px;
padding-left: 10px;
display: flex;
align-items: center;
font-size: 15px;
}
}
.screen-button-div {
// display: flex;
// justify-content: space-between;
width: 100%;
button {
margin: 10px 10px 0 0;
}
}
}
.data-list-div {
flex: 1;
overflow: auto;
padding: 10px;
background: @component-background;
margin-top: 10px;
.data-list-item {
display: flex;
height: 60px;
align-items: center;
border-bottom: 1px solid #cdcccc;
.select-mark {
width: 3px;
height: 100%;
}
.data-list-item-content {
padding-left: 5px;
width: 80%;
.item-info-div {
display: flex;
align-items: center;
margin-bottom: 5px;
.item-info-id {
width: 185px;
border-radius: 11px;
display: flex;
align-items: center;
// justify-content: center;
height: 22px;
}
.item-info-layout {
padding-left: 15px;
display: flex;
flex: 1;
justify-content: space-between;
}
.item-info-batch {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.item-data-div {
display: flex;
justify-content: space-between;
.item-data-item {
display: flex;
align-items: center;
.item-mark-div {
width: 20px;
height: 20px;
color: #fff;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 7px;
}
.sum-mark {
background: rgb(46 90 173);
}
.plowland-mark {
background: #01692a;
}
.adjust-mark {
background: #c06b1a;
width: 40px;
}
.farmland-mark {
background: #7d2bb1;
}
.guihua-mark {
background: #c06b1a;
}
.shengtai-mark {
background: #09b66d;
}
}
}
}
.button-div {
height: 30px;
width: 30px;
display: flex;
justify-content: space-evenly;
font-size: 20px;
border: 1px solid #d9d9d9;
border-radius: 50%;
margin-left: 10px;
cursor: pointer;
.collect-button:hover {
color: rgb(255, 205, 42);
}
}
}
}
.pagination-div {
height: 30px;
display: flex;
align-items: center;
background: @component-background;
justify-content: center;
}
.no-data {
padding: 20px 0;
}
.rollback {
background: @component-background;
padding: 10px;
}
</style>

View File

@ -0,0 +1,316 @@
<template>
<div class="curb-spot-city">
<div class="show-list">
<AuditProgress
v-if="!showInfo"
:year="year"
:batch="batch"
:batchOptions="batchOptions"
:yearOptions="yearOptions"
:dataList="dataList"
@auditProgressScreenChange="auditProgressScreenChange"
@showInfo="changeShowInfo"
/>
<MapList
v-if="showInfo"
:infoScreenData="infoScreenData"
:cityType="cityType"
:pageNo="pageNo"
:pageSize="pageSize"
:total="total"
:infoDataList="infoDataList"
:municipalAreaOptions="municipalAreaOptions"
:countiesAreaOptions="countiesAreaOptions"
@infoDataListSort="infoDataListSort"
@changeInfoPage="changeInfoPage"
@getInfoList="getInfoList"
@mapListScreenChange="mapListScreenChange"
@closeShowInfo="changeShowInfo"
@changeTask="changeTask"
@collectChange="collectChange"
/>
</div>
<div class="map-box-div">
<MapboxMap
:mapConfig="mapConfig"
@handlerDrawComplete="handlerDrawComplete"
@mapOnLoad="onMapboxLoad"
ref="MapboxComponent"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, defineAsyncComponent } from 'vue';
import mapboxgl, { Map } from 'mapbox-gl';
import { MapboxConfig, MapboxDefaultStyle } from '@/components/MapboxMaps/src/config.ts';
import AuditProgress from './AuditProgress/index.vue';
import MapList from './MapList/index.vue';
import { getLoadDroneCaseInfoCount, getLoadDroneCaseInfoDetail } from '@/api/bootstraps/index.ts';
import { batchOptions, yearOptions } from '@/views/demo/bootstraps/curbspotcity/util.ts';
import { getChildrenTree } from '@/api/demo/system.ts';
import { getGeom } from '@/api/sys/layerManagement';
const MapboxMap = defineAsyncComponent(() => import('@/components/MapboxMaps/MapComponent.vue'));
const MapboxComponent = ref();
const mapConfig = ref({ isShowMap: false });
const showInfo = ref(false);
const year = ref<number>();
const batch = ref();
const dataList = ref<any>([]);
const infoDataList = ref<any>([]);
const infoScreenData = ref({
year: '',
batch: '',
mapNo: '',
countyId: '',
streetId: '',
mapType: '',
illegalType: '',
measure: '',
mapStatus: '',
markType: '',
sort: '',
order: '',
type: '', //
});
const pageNo = ref(1);
const pageSize = ref(10);
const total = ref(0);
const municipalAreaOptions = ref([]);
const countiesAreaOptions = ref([{ label: '全部', value: '' }]);
const cityType = ref();
const auditProgressScreenChange = (value, type) => {
switch (type) {
case 'year':
year.value = value;
break;
case 'batch':
batch.value = value;
break;
}
let params = {
year: year.value,
};
getLoadDroneCaseInfoCount(params).then((res) => {
console.log(res);
dataList.value = res;
});
};
const mapListScreenChange = (value, type) => {
switch (type) {
case 'year':
infoScreenData.value.year = value;
break;
case 'batch':
infoScreenData.value.batch = value;
break;
case 'mapNo':
infoScreenData.value.mapNo = value;
break;
case 'countyId':
infoScreenData.value.countyId = value;
break;
case 'streetId':
infoScreenData.value.streetId = value;
break;
case 'mapType':
infoScreenData.value.mapType = value;
if (value !== 1) {
infoScreenData.value.illegalType = '';
infoScreenData.value.measure = '';
}
break;
case 'illegalType':
infoScreenData.value.illegalType = value;
if (value !== 0) {
infoScreenData.value.measure = '';
}
break;
case 'measure':
infoScreenData.value.measure = value;
break;
case 'mapStatus':
infoScreenData.value.mapStatus = value;
break;
case 'markType':
infoScreenData.value.markType = value;
break;
}
};
const changeShowInfo = (value, item) => {
showInfo.value = value;
if (item) {
cityType.value = item;
infoScreenData.value.countyId = item.areaid;
municipalAreaOptions.value = [{ label: item.areaname, value: item.areaid }];
getChildrenTree({ parentId: item.areaid }).then((res) => {
console.log(res);
res.forEach((cityItem) => {
countiesAreaOptions.value.push({
label: cityItem.name,
value: cityItem.id,
});
});
});
getInfoList();
} else {
cityType.value = null;
}
console.log(item);
};
const getParams = () => {
let result = {};
let params = {
year: infoScreenData.value.year,
// batch: batch.value,
countyid: infoScreenData.value.countyId,
streetid: infoScreenData.value.streetId,
geomid: infoScreenData.value.mapNo,
is_illegal: infoScreenData.value.mapType,
weifaleixing: infoScreenData.value.illegalType,
measure_name: infoScreenData.value.measure,
handle_status_id: infoScreenData.value.mapStatus,
is_build_complete: infoScreenData.value.markType,
areaid: cityType.value.areaid,
level: cityType.value.level,
page: pageNo.value,
limit: pageSize.value,
sort: infoScreenData.value.sort,
order: infoScreenData.value.order,
type: infoScreenData.value.type,
};
Object.keys(params).forEach((key) => {
if (params[key] !== '' && params[key] !== null) {
result[key] = params[key];
}
});
return result;
};
watch(
() => year.value,
(newVal) => {
infoScreenData.value.year = newVal;
},
);
watch(
() => batch.value,
(newVal) => {
infoScreenData.value.batch = newVal;
},
);
let map: Map;
onMounted(() => {
mapboxgl.accessToken = MapboxConfig.ACCESS_TOKEN;
// map = initMap();
getLoadDroneCaseInfoCount()
.then((res) => {
dataList.value = res;
})
.catch((err) => {
console.log(err);
});
});
onUnmounted(() => {
map && map.remove();
});
const initMap = () => {
return new mapboxgl.Map({
container: 'showMap',
language: 'zh-cmn',
projection: 'equirectangular', // wgs84
style: MapboxDefaultStyle,
maxZoom: 22,
minZoom: 6,
zoom: 10,
// ...props.mapOptions,
center: [117.984425, 35.270654],
});
};
const getInfoList = () => {
getLoadDroneCaseInfoDetail(getParams()).then((res) => {
total.value = res.total;
infoDataList.value = res.items;
});
};
const changeInfoPage = (page, limit) => {
pageNo.value = page;
pageSize.value = limit;
getInfoList();
};
const collectChange = (value) => {
pageNo.value = 1;
infoScreenData.value.type = value;
getInfoList();
};
function changeTask(val) {
console.log(val);
let getGeomPrams = {
TableName: 'drone_shp_data ',
FieldName: 'gid',
FieldValue: val,
page: 1,
limit: 999,
key: null,
};
if (val) {
getGeom(getGeomPrams).then((res) => {
let geoms = [];
if (res) {
if (res.items?.length > 0) {
res.items.forEach((item, index) => {
let geom = {
key: item.gid,
mapgeom: item.geometry,
};
geoms.push(geom);
});
}
// MapboxComponent.value.handlerDraw(status,mapgemoList.value, false);
MapboxComponent.value.handlerDraw('Details', geoms, false);
} else {
createMessage.error('当前数据没有图斑!');
}
});
} else {
createMessage.error('当前数据没有图斑!');
}
}
const infoDataListSort = (type, order) => {
switch (order) {
case 0:
infoScreenData.value.sort = '';
infoScreenData.value.order = '';
break;
case 1:
infoScreenData.value.sort = type;
infoScreenData.value.order = 'asc';
break;
case 2:
infoScreenData.value.sort = type;
infoScreenData.value.order = 'desc';
break;
}
getLoadDroneCaseInfoDetail(getParams()).then((res) => {
total.value = res.total;
infoDataList.value = res.items;
pageNo.value = 1;
});
};
</script>
<style lang="scss" scoped>
.curb-spot-city {
height: 100%;
display: flex;
.show-list {
width: 35%;
}
.map-box-div {
width: 65%;
}
}
</style>

View File

@ -0,0 +1,36 @@
export const batchOptions = [
{value: '第一批', label: '第一批'},
{value: '第二批', label: '第二批'},
{value: '第三批', label: '第三批'},
]
export const yearOptions = [
{ value: '2024', label: 2024 },
{ value: '2023', label: 2023 },
{ value: '2022', label: 2022 },
{ value: '2021', label: 2021 },
{ value: '2020', label: 2020 },
]
export const mapTypeOptions = [
{ label: '合法', value: 0 },
{ label: '违法', value: 1 },
{ label: '其他', value: 2 },
]
export const illegalTypeOptions = [
{ label: '非农化', value: 0 },
{ label: '非粮化', value: 1 },
]
export const measureOptions = [
{ label: '拆除复耕', value: 0},
{ label: '补办手续', value: 1},
]
export const mapStatusOptions = [
{ label: '待接收', value: 0 },
{ label: '待判定', value: 1 },
{ label: '待整改', value: 2 },
{ label: '待审核', value: 3 },
{ label: '已完成', value: 4 },
]
export const markTypeOptions = [
{ label: '建设中', value: 0 },
{ label: '已建成', value: 1 },
]

View File

@ -0,0 +1,46 @@
<template>
<a-descriptions
:column="2"
bordered
:contentStyle="{
'text-align': 'center',
'min-width': '250px',
'word-break': 'break-all'
}">
<a-descriptions-item label="id">{{ id }}</a-descriptions-item>
<a-descriptions-item label="案件编号">{{ case_no }}</a-descriptions-item>
<a-descriptions-item label="案件名称">{{ case_name }}</a-descriptions-item>
<a-descriptions-item label="案件描述">{{ case_description }}</a-descriptions-item>
<a-descriptions-item label="案件地址">{{ address }}</a-descriptions-item>
<a-descriptions-item label="总面积">{{ area? area: '-' }} </a-descriptions-item>
<a-descriptions-item label="耕地面积">{{ gengdi_area? gengdi_area: '-' }} </a-descriptions-item>
<a-descriptions-item label="国土空间规划面积">{{ guotukongjianguihua_area? guotukongjianguihua_area: '-' }} </a-descriptions-item>
<a-descriptions-item label="农用地面积">{{ nongyongdi_area? nongyongdi_area: '-' }} </a-descriptions-item>
<a-descriptions-item label="生态保护红线面积">{{ shengtaibaohuhongxian_area? shengtaibaohuhongxian_area: '-' }} </a-descriptions-item>
<a-descriptions-item label="永久基本农田面积">{{ yongjiujibennongtian_area? yongjiujibennongtian_area: '-' }} </a-descriptions-item>
<a-descriptions-item label="重点区域面积">{{ zhongdianquyu_area? zhongdianquyu_area: '-' }} </a-descriptions-item>
<a-descriptions-item label="创建时间">{{ createtime }}</a-descriptions-item>
</a-descriptions>
</template>
<script setup lang="ts">
import { defineProps } from "vue"
const props = defineProps(["showInfoData"])
const {
address,
area,
case_description,
case_name,
case_no,
createtime,
gengdi_area,
guotukongjianguihua_area,
id,
nongyongdi_area,
shengtaibaohuhongxian_area,
yongjiujibennongtian_area,
zhongdianquyu_area
} = props.showInfoData
</script>
<style lang="scss" scoped></style>

View File

@ -122,37 +122,72 @@
/>
</div>
<div class="screen-button-div">
<a-button type="primary" size="small" @click="emits('closeShowInfo', false)">返回</a-button>
<a-button type="primary" size="small">排序(图斑面积)</a-button>
<a-button type="primary" size="small">排序(耕地面积)</a-button>
<!-- <a-button type="primary" size="small" @click="emits('closeShowInfo', false)">返回</a-button> -->
<a-button type="primary" size="small" @click="dataListSort('area')" >
{{`排序(图斑面积) ${props.infoScreenData.sort === 'area'? orderMark(): '-'}`}}
</a-button>
<a-button type="primary" size="small" @click="dataListSort('gengdi_area')">
{{`排序(耕地面积) ${props.infoScreenData.sort === 'gengdi_area'? orderMark(): '-'}`}}
</a-button>
<a-button type="primary" size="small">导出</a-button>
<a-button type="primary" size="small">我的收藏</a-button>
<a-button type="primary" :style="openCollect && 'background: #bf0000;' " size="small" @click="getCollectList"></a-button>
<a-button size="small" @click="emits('getInfoList')"></a-button>
</div>
</div>
<div class="data-list-div">
<div v-for="(item, index) in props.infoDataList" :key="index" class="data-list-item">
<div class="select-mark"></div>
<Icon style="font-size: 30px; color: #bf0000" icon="gis:poi-alt" @click="locationFun(item)" />
<Icon style="font-size: 30px; color: #086DEC" icon="gis:poi-alt" @click="locationFun(item)" />
<div class="data-list-item-content">
<div class="item-info-div">
<div class="item-info-id">{{ item.case_no }}</div>
<div class="item-info-layout">
<div class="item-info-batch">{{ item.address }}</div>
<div class="item-info-batch">{{ item.batch }}</div>
<div class="item-info-batch">
<a-tag color="blue" v-if="item.address">
{{ item.address }}
</a-tag>
</div>
<div class="item-info-batch">
<a-tag color="green" v-if="item.createtime">
{{ item.createtime }}
</a-tag>
</div>
</div>
</div>
<div class="item-data-div" style="margin-bottom: 4px;">
<div class="item-data-item">
<div class="item-mark-div sum-mark"></div>
<div class="area-data">{{ item.area? item.area: '-'}}</div>
</div>
<div class="item-data-item">
<div class="item-mark-div plowland-mark"></div>
<div class="area-data">{{ item.gengdi_area? item.gengdi_area: '-'}}</div>
</div>
<div class="item-data-item">
<div class="item-mark-div farmland-mark"></div>
<div class="area-data">{{ item.yongjiujibennongtian_area? item.yongjiujibennongtian_area: '-'}}</div>
</div>
</div>
<div class="item-data-div">
<div class="item-data-item"><div class="item-mark-div sum-mark"></div>{{ item.area }} </div>
<div class="item-data-item"><div class="item-mark-div plowland-mark"></div>{{ item.gengdi_area }}</div>
<div class="item-data-item"><div class="item-mark-div adjust-mark">可调</div>{{ item.adjustable }}</div>
<div class="item-data-item"><div class="item-mark-div farmland-mark"></div>{{ item.nongyongdi_area }}</div>
<div class="item-data-item">
<div class="item-mark-div focus-area"></div>
<div class="area-data">{{ item.zhongdianquyu_area? item.zhongdianquyu_area: '-'}}</div>
</div>
<div class="item-data-item">
<div class="item-mark-div padding-mark"></div>
<div class="area-data">{{ item.guotukongjianguihua_area? item.guotukongjianguihua_area: '-'}}</div>
</div>
<div class="item-data-item">
<div class="item-mark-div adjust-mark"></div>
<div class="area-data">{{ item.shengtaibaohuhongxian_area? item.shengtaibaohuhongxian_area: '-'}}</div>
</div>
</div>
</div>
<div class="button-div">
<StarOutlined class="collect-button"/>
<Icon style="font-size: 20px" icon="bx:detail" />
<StarFilled v-if="item.Fid" style="color: rgb(255, 205, 42);cursor: pointer;" @click="cancelCollectItem(item)"/>
<StarOutlined v-else class="collect-button" @click="collectItem(item)"/>
<Icon style="font-size: 20px;cursor: pointer;" icon="bx:detail" @click="showInfo(item)"/>
</div>
</div>
</div>
@ -166,14 +201,28 @@
show-quick-jumper
@change="changePage" />
</div>
<a-modal
style="top:10px"
width="100%"
v-model:open="showInfoOpen"
title="详情"
:footer="null"
:maskClosable="true"
:destroyOnClose="true"
@cancel="showInfoOpen = false"
>
<div class="modal-content">
<ShowInfoModal :showInfoData="showInfoData"/>
</div>
</a-modal>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, defineEmits, defineProps } from "vue"
import { StarOutlined } from '@ant-design/icons-vue';
import { ref, onMounted, defineEmits, defineProps, computed } from "vue"
import { StarOutlined, StarFilled } from '@ant-design/icons-vue';
import Icon from '@/components/Icon/Icon.vue';
import { getLoadDroneCaseInfoDetail } from '@/api/bootstraps/index.ts'
import { addCaseFavorite,getFavoriteCaseList, deleteFavoriteCase } from '@/api/bootstraps/index.ts';
import {
batchOptions,
yearOptions,
@ -183,13 +232,19 @@ import {
mapStatusOptions,
markTypeOptions,
} from '@/views/demo/bootstraps/curbspotcity/util.ts'
import { useUserStore } from '@/store/modules/user.ts'
import { message } from "ant-design-vue";
import ShowInfoModal from './ShowInfoModal/index.vue'
const userStore = useUserStore()
const emits = defineEmits([
"closeShowInfo",
"mapListScreenChange",
"changeInfoPage",
"getInfoList",
"changeTask"
"changeTask",
"infoDataListSort",
"collectChange",
])
const props = defineProps([
"infoScreenData",
@ -201,7 +256,23 @@ const props = defineProps([
"total",
"infoDataList"
])
const order = ref(0) // 0: 1: 2:
const orderMark = () => {
switch(order.value){
case 0:
return '-'
case 1:
return '↑'
case 2:
return '↓'
}
}
const showInfoOpen = ref(false)
const openCollect = computed(() => {
if(props.infoScreenData.type === '') return false
return true
})
const showInfoData = ref()
onMounted(() => {
console.log('onMounted')
})
@ -215,6 +286,45 @@ const changePage = (page, pageSize) => {
console.log(page,pageSize)
emits('changeInfoPage',page,pageSize)
}
const collectItem = (item) => {
console.log(item)
let userInfo = userStore.getUserInfo
let params = {
id: item.id,
caseNo: item.case_no,
favoriteUserId: userInfo.id
}
addCaseFavorite(params).then(res => {
console.log(res)
message.success('收藏成功')
emits('getInfoList')
})
}
const cancelCollectItem = (item) => {
deleteFavoriteCase(item.Fid).then(res => {
message.success('取消收藏成功')
emits('getInfoList')
})
}
const getCollectList = () => {
let collect = props.infoScreenData.type
let value: number|string = ''
if(collect === ''){
value = 1
}else if(collect === 1){
value = ''
}
emits('collectChange', value)
}
const dataListSort = (type) => {
order.value = (order.value + 1) % 3
emits('infoDataListSort', type, order.value)
}
const showInfo = (item) => {
console.log(item)
showInfoData.value = item
showInfoOpen.value = true
}
</script>
<style lang="scss" scoped>
@ -253,7 +363,7 @@ const changePage = (page, pageSize) => {
padding: 10px;
.data-list-item{
display: flex;
height: 60px;
height: 90px;
align-items: center;
border-bottom: 1px solid #cdcccc;
.select-mark{
@ -269,13 +379,15 @@ const changePage = (page, pageSize) => {
margin-bottom: 5px;
.item-info-id{
width: 185px;
background: #bf2c64;
color: #fff;
/* background: #bf2c64; */
color: #000;
border-radius: 11px;
display: flex;
align-items: center;
justify-content: center;
// justify-content: center;
height: 22px;
font-weight: 500;
font-size: 15px;
}
.item-info-layout{
padding-left: 15px;
@ -295,11 +407,14 @@ const changePage = (page, pageSize) => {
.item-data-item{
display:flex;
align-items: center;
border-radius: 6px 6px 0px 6px;
border: 1px solid #dddddd;
margin-right: 10px;
.item-mark-div{
width: 20px;
height: 20px;
color: #fff;
border-radius: 6px;
border-radius: 4px 4px 0px 4px;
display: flex;
align-items: center;
justify-content: center;
@ -313,11 +428,19 @@ const changePage = (page, pageSize) => {
}
.adjust-mark{
background: #c06b1a;
width: 40px;
}
.farmland-mark{
background: #7d2bb1;
}
.focus-area{
background: rgb(225 91 91);
}
.padding-mark{
background: #36afa4;;
}
.area-data{
width: 55px;
}
}
}
}
@ -335,10 +458,14 @@ const changePage = (page, pageSize) => {
}
}
.pagination-div{
height: 30px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
}
.modal-content{
padding: 30px;
height: 860px;
overflow: auto;
}
</style>

View File

@ -1,32 +1,36 @@
<template>
<div class="curb-spot-city">
<div class="show-list">
<AuditProgress
v-if="!showInfo"
:year="year"
:batch="batch"
:batchOptions="batchOptions"
:yearOptions="yearOptions"
:dataList="dataList"
@auditProgressScreenChange="auditProgressScreenChange"
@showInfo="changeShowInfo"
/>
<MapList
v-if="showInfo"
:infoScreenData="infoScreenData"
:cityType="cityType"
:pageNo="pageNo"
:pageSize="pageSize"
:total="total"
:infoDataList="infoDataList"
:municipalAreaOptions="municipalAreaOptions"
:countiesAreaOptions="countiesAreaOptions"
@changeInfoPage="changeInfoPage"
@getInfoList="getInfoList"
@mapListScreenChange="mapListScreenChange"
@closeShowInfo="changeShowInfo"
@changeTask="changeTask"
/>
<a-spin :spinning="spinning">
<AuditProgress
v-if="!showInfo"
:year="year"
:batch="batch"
:batchOptions="batchOptions"
:yearOptions="yearOptions"
:dataList="dataList"
@auditProgressScreenChange="auditProgressScreenChange"
@showInfo="changeShowInfo"
/>
<MapList
v-if="showInfo"
:infoScreenData="infoScreenData"
:cityType="cityType"
:pageNo="pageNo"
:pageSize="pageSize"
:total="total"
:infoDataList="infoDataList"
:municipalAreaOptions="municipalAreaOptions"
:countiesAreaOptions="countiesAreaOptions"
@infoDataListSort="infoDataListSort"
@changeInfoPage="changeInfoPage"
@getInfoList="getInfoList"
@mapListScreenChange="mapListScreenChange"
@closeShowInfo="changeShowInfo"
@changeTask="changeTask"
@collectChange="collectChange"
/>
</a-spin>
</div>
<!-- <div id="showMap" class="map"></div> -->
<MapboxMap
@ -69,6 +73,9 @@ const infoScreenData = ref({
measure: '',
mapStatus: '',
markType: '',
sort: '',
order: '',
type: '', //
})
const pageNo = ref(1)
const pageSize = ref(10)
@ -78,6 +85,7 @@ const countiesAreaOptions = ref([
{ label: '全部', value: '' },
])
const cityType = ref()
const spinning = ref(false)
const auditProgressScreenChange = (value, type) => {
switch(type){
case 'year':
@ -90,9 +98,12 @@ const auditProgressScreenChange = (value, type) => {
let params = {
year: year.value,
}
spinning.value = true
getLoadDroneCaseInfoCount(params).then(res => {
console.log(res)
dataList.value = res
}).finally(() => {
spinning.value = false
})
}
const mapListScreenChange = (value, type) => {
@ -136,8 +147,8 @@ const mapListScreenChange = (value, type) => {
break
}
}
const changeShowInfo = (value, item) => {
showInfo.value = value
const changeShowInfo = async (value, item) => {
if(item){
cityType.value = item
infoScreenData.value.countyId = item.areaid
@ -151,9 +162,11 @@ const changeShowInfo = (value, item) => {
})
});
})
getInfoList()
await getInfoList()
showInfo.value = value
}else{
cityType.value = null
showInfo.value = value
}
console.log(item)
}
@ -174,6 +187,9 @@ const getParams = () => {
level: cityType.value.level,
page: pageNo.value,
limit: pageSize.value,
sort: infoScreenData.value.sort,
order: infoScreenData.value.order,
type: infoScreenData.value.type,
}
Object.keys(params).forEach(key => {
if(params[key] !== '' && params[key] !== null){
@ -215,9 +231,12 @@ const initMap = () => {
});
};
const getInfoList = () => {
getLoadDroneCaseInfoDetail(getParams()).then(res => {
spinning.value = true
return getLoadDroneCaseInfoDetail(getParams()).then(res => {
total.value = res.total
infoDataList.value = res.items
}).finally(() => {
spinning.value = false
})
}
const changeInfoPage = (page, limit) => {
@ -225,6 +244,11 @@ const changeInfoPage = (page, limit) => {
pageSize.value = limit
getInfoList()
}
const collectChange = (value) => {
pageNo.value = 1
infoScreenData.value.type = value
getInfoList()
}
function changeTask(val) {
console.log(val);
@ -259,16 +283,42 @@ function changeTask(val) {
createMessage.error('当前数据没有图斑!');
}
}
const infoDataListSort = (type, order) => {
switch(order){
case 0:
infoScreenData.value.sort = ''
infoScreenData.value.order = ''
break
case 1:
infoScreenData.value.sort = type
infoScreenData.value.order = 'asc'
break
case 2:
infoScreenData.value.sort = type
infoScreenData.value.order = 'desc'
break
}
getLoadDroneCaseInfoDetail(getParams()).then(res => {
total.value = res.total
infoDataList.value = res.items
pageNo.value = 1
})
}
</script>
<style lang="scss" scoped>
.curb-spot-city{
height: 100%;
display: flex;
.show-list{
width: 35%;
:deep(.ant-spin-nested-loading){
height: 100%;
}
:deep(.ant-spin-container){
height: 100%;
}
}
.map{
width: 65%;

View File

@ -38,7 +38,7 @@
<a-input
v-model:value="db.tableName"
:disabled="!isNewTable(db)"
@change="if (!db.tableName) db.tableName = db.name;"
@change="db.tableName = db.tableName.toLowerCase();"
/>
</a-col>
<a-col class="gutter-row" :span="11">
@ -811,7 +811,7 @@
saveFormDatas.scheme.scheme = scheme_replace;
// db
// db.name = db.tableName;
db.name = db.tableName;
db.dbColumnInfoList?.forEach((d, d_index) => {
d.tableName = db.tableName;
db.dbColumnInfoList[d_index] = d;
@ -940,7 +940,6 @@
let escapedItem = itemToReplace.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
let regex = new RegExp(escapedItem, 'g');
let replacedJsonString = jsonString.replace(regex, newItem);
return replacedJsonString;
}