Compare commits

...

2 Commits

8 changed files with 1521 additions and 230 deletions

View File

@ -35,8 +35,10 @@ enum Api {
AddtaskFavorite = '/api/DroneCaseInfoSingle/AddtaskFavorite',
// 审核列表删除收藏
DeleteTaskCase = '/api/DroneCaseInfoSingle/DeleteTaskCase',
// 获取当前账号可以看见的乡镇
loadStreet = '/api/DroneCaseInfoSingle/loadStreet'
// 获取当前账号可以看见的乡镇
loadStreet = '/api/DroneCaseInfoSingle/loadStreet',
// 违法处理,待办任务列表
LoadTaskIllegalDetailList = '/api/DroneCaseInfoSingle/LoadTaskIllegalDetailList',
}
/**
@ -72,7 +74,7 @@ export function getLoadTaskDetailList(params?: taskInfoParams) {
export function addCaseFavorite(params?: addCaseFavoriteParams) {
return defHttp.post({ url: Api.AddCaseFavorite, params });
}
export function addTaskFavorite(params?: {taskId:string,favoriteUserId: string}) {
export function addTaskFavorite(params?: { taskId: string; favoriteUserId: string }) {
return defHttp.post({ url: Api.AddtaskFavorite, params });
}
export function deleteFavoriteCase(params: string) {
@ -91,8 +93,12 @@ export function getCaseInfoById(params?: { id: string }) {
export const updateDroneCaseInfo = (params: updateCaseInfoParams) =>
defHttp.post({ url: Api.UpdateDroneCaseInfo, params });
export const updateSupervise = (params: {id:string,supervise: number}) =>
export const updateSupervise = (params: { id: string; supervise: number }) =>
defHttp.post({ url: `${Api.Supervise}?id=${params.id}&supervise=${params.supervise}`, params });
export const getLoadParents = (params: {childId:Number}) =>
defHttp.get({ url: `${Api.LoadParents}?childId=${params.childId}`,});
export const getLoadParents = (params: { childId: Number }) =>
defHttp.get({ url: `${Api.LoadParents}?childId=${params.childId}` });
export function getLoadTaskIllegalDetailList(params?: taskInfoParams) {
return defHttp.get({ url: Api.LoadTaskIllegalDetailList, params });
}

View File

@ -0,0 +1,357 @@
<template>
<div class="screen-div">
<div class="screen-row">
<div class="screen-item">
<div class="screen-item-label" style="margin-right: 9px">年份</div>
<a-select
allowClear
style="width: 103px"
v-model:value="props.year"
:options="yearOptions"
@change="
(value) => {
emits('auditProgressScreenChange', value, 'year');
}
"
/>
</div>
<div class="screen-item" style="margin-left: 20px; margin-right: 17px">
<div class="screen-item-label" style="margin-right: 11px">图斑来源</div>
<a-select
allowClear
style="width: 142px"
v-model:value="props.patchSource"
:options="patchSourceOptions"
@change="
(value) => {
emits('auditProgressScreenChange', value, 'patchSource');
}
"
/>
</div>
<div class="screen-item">
<div class="screen-item-label" style="margin-right: 9px">批次</div>
<a-input
allowClear
class="item-input"
style="width: 117px"
v-model:value="props.batch"
@change="(value) => emits('auditProgressScreenChange', value.target.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', item)"
v-if="dataList.length > 0"
>
<div class="name-div">
<!-- <div class="item-mark"></div> -->
<div class="icon-name">
<img src="/positioning.png" class="item-mark" />
<div class="item-label">{{ item.areaname }}</div>
</div>
<!-- <div class="progress-div">
<div class="progress-label progress-color">进度</div>
<div class="progress-data" style="width:97px">
<span style="color: #086DEC;">{{item.verificatedtask}}</span>/{{item.totaltask}}
</div>
</div>
<div class="progress-div">
<div class="progress-label extended-color">超期</div>
<div class="progress-data" style="width:40px">
<span style="color: #D03542">{{item.overduetask}}</span>
</div>
</div> -->
<div class="progress-div">
<div class="progress-label reviewed-color" style="width: 70px">待审核</div>
<div class="progress-data" style="width: 31px">
<span style="color: #ec7908">{{ item.verifytask }}</span>
</div>
</div>
</div>
<div class="info-data-div">
<div class="info-data-item">
<div class="info-data-label">下发</div>
<div class="info-data-data">{{item.makeupcase}}</div>
</div>
<div
style="
width: 1px;
margin-right: 15px;
margin-left: 15px;
background-color: #ededed;
height: 15px;
"
></div>
<div class="info-data-item">
<div class="info-data-label">接收</div>
<div class="info-data-data">{{item.receivetask}}</div>
</div>
<div
style="
width: 1px;
margin-right: 15px;
margin-left: 15px;
background-color: #ededed;
height: 15px;
"
></div>
<div class="info-data-item">
<div class="info-data-label">非粮化</div>
<div class="info-data-data">{{ item.nonfoodcase }}</div>
</div>
<div
style="
width: 1px;
margin-right: 15px;
margin-left: 15px;
background-color: #ededed;
height: 15px;
"
></div>
<div class="info-data-item">
<div class="info-data-label">拆除复耕</div>
<div class="info-data-data">{{ item.rehabilitationcase }}</div>
</div>
<div
style="
width: 1px;
margin-right: 15px;
margin-left: 15px;
background-color: #ededed;
height: 15px;
"
></div>
<div class="info-data-item">
<div class="info-data-label">补办手续</div>
<div class="info-data-data">{{ item.makeupcase }}</div>
</div>
</div>
<!-- <div class="data-div">
<spam style="color: #086dec">{{ item.count }}</spam>
</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 Icon from '@/components/Icon/Icon.vue';
import { Empty } from 'ant-design-vue';
import { patchSourceOptions } from '../util.ts';
const props = defineProps([
'year',
'batch',
'patchSource',
'batchOptions',
'yearOptions',
'dataList',
]);
const emits = defineEmits(['auditProgressScreenChange', 'showInfo']);
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
// function changeParam(val,type) {
// emits('auditProgressScreenChange', val, type);
// }
</script>
<style lang="less" scoped>
.screen-div {
padding: 22px 12px 14px 13px;
.screen-row {
display: flex;
height: 39px;
.screen-item {
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 17px;
color: #000000;
// width: 33.3%;
display: flex;
.item-input {
width: 223px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 17px;
color: #000000;
line-height: 30px;
box-shadow: 2px 3px 3px 1px rgba(13, 13, 13, 0.05);
}
.screen-item-label {
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 17px;
color: #000000;
line-height: 30px;
display: flex;
align-items: center;
}
:deep(.ant-select-selector) {
display: flex;
align-items: center;
font-family: HarmonyOS Sans;
font-weight: 500;
font-size: 19px;
color: #000000;
line-height: 30px;
height: 39px;
box-shadow: 2px 3px 3px 1px rgba(13, 13, 13, 0.05);
}
}
}
}
.data-list {
height: calc(100% - 85px);
// background: darkgoldenrod;
// background: @component-background;
margin-top: 10px;
padding: 0px 11px 0px 13px;
.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 {
cursor: pointer;
width: 100%;
background: #fff;
border-radius: 11px;
padding: 0px 17px 0px 12px;
margin-bottom: 8px;
.name-div {
display: flex;
height: 57px;
align-items: center;
padding: 10px 0px;
border-bottom: 1px solid #e5e5e5;
justify-content: space-between;
.icon-name {
display: flex;
align-items: center;
}
}
.info-data-div {
height: 61px;
display: flex;
align-items: center;
padding-left: 2px;
// justify-content: space-between;
// margin-top: 10px;
.info-data-item {
display: flex;
align-items: center;
// flex: 1;
justify-content: center;
// border-right: 1px solid #EDEDED;
.info-data-label {
font-family: Alibaba PuHuiTi;
font-weight: 400;
font-size: 16px;
color: #959494;
display: flex;
line-height: 30px;
margin-right: 11px;
}
.info-data-data {
font-family: HarmonyOS Sans;
font-weight: 500;
font-size: 16px;
color: #000000;
line-height: 30px;
display: flex;
}
}
.info-data-item:nth-last-child(1) {
border-right: 0px;
}
}
.data-div {
font-weight: 500;
margin-right: 5px;
}
.item-mark {
width: 17px;
height: 17px;
// background: #086dec;
// margin-left: 7px;
// margin-right: 7px;
}
.item-label {
width: 122px;
padding-left: 9px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 23px;
color: #000000;
line-height: 30px;
}
.progress-div {
display: flex;
// font-weight: 500;
// font-size: 16px;
// line-height: 30px;
margin-right: 17px;
.progress-label {
font-family: Alibaba PuHuiTi;
color: #ffffff;
width: 50px;
height: 27px;
border-radius: 13px 0px 0px 13px;
display: flex;
align-items: center;
justify-content: center;
}
.progress-data {
background: #efefef;
height: 27px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 0px 0px 11px 0px;
font-family: HarmonyOS Sans;
font-weight: 500;
font-size: 19px;
// color: #086DEC;
line-height: 30px;
}
.progress-color {
background: #086dec;
}
.extended-color {
background: #d03542;
}
.reviewed-color {
background: #ec7908;
}
}
}
.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,708 @@
<template>
<div class="map-list-content">
<div class="screen-div">
<div class="screen-item" style="margin-right:20px;margin-bottom:15px;">
<div class="screen-item-label">年份</div>
<a-select
allowClear
style="width:130px;"
v-model:value="params.year"
:options="props.yearOptions"
/>
</div>
<div class="screen-item" style="margin-right:17px;margin-bottom:15px;">
<div class="screen-item-label">图斑来源</div>
<a-select
allowClear
style="width:130px;"
v-model:value="params.tubanlaiyuan"
:options="patchSourceOptions"
/>
</div>
<div class="screen-item" style="margin-bottom:15px;">
<div class="screen-item-label">批次</div>
<a-input
allowClear
class="item-input"
style="width:103px;"
v-model:value="params.picihao"
/>
</div>
<div class="screen-item" style="margin-right:13px;">
<div class="screen-item-label">举证</div>
<a-select
allowClear
style="width:130px;"
v-model:value="params.is_build_name"
:options="markTypeOptions"
/>
</div>
<div class="screen-item" style="margin-right:51px;">
<!-- <div class="screen-item-label">图斑号</div> -->
<a-input allowClear v-model:value="params.geomid" class="item-input" placeholder="请输入图斑编号"/>
</div>
<div class="screen-item" style="display: flex; justify-content: end;margin-bottom: 0px;">
<a-button type="primary" class="item-button" :icon="h(SearchOutlined)" @click="query"></a-button>
</div>
</div>
<div class="sift-div">
<div class="layout-div">
<RollbackOutlined class="back-button" @click="emits('changeShowParent')"/>
<div class="interval-div"></div>
<div class="sift-item" @click="dataListSort('area')">
<div class="sift-label">总面积</div>
<div class="sift-icon">
<div :style="`${showSortMark('area',1)? 'color: #086DEC;': ''}`">&#9650</div>
<div :style="`${showSortMark('area',2)? 'color: #086DEC;': ''}`">&#9660</div>
</div>
</div>
<div class="sift-item" @click="dataListSort('gengdi_area')">
<div class="sift-label">耕地面积</div>
<div class="sift-icon">
<div :style="`${showSortMark('gengdi_area',1)? 'color: #086DEC;': ''}`">&#9650</div>
<div :style="`${showSortMark('gengdi_area',2)? 'color: #086DEC;': ''}`">&#9660</div>
</div>
</div>
<div class="sift-item" @click="dataListSort('yongjiujibennongtian_area')">
<div class="sift-label">基本农田</div>
<div class="sift-icon">
<div :style="`${showSortMark('yongjiujibennongtian_area',1)? 'color: #086DEC;': ''}`">&#9650</div>
<div :style="`${showSortMark('yongjiujibennongtian_area',2)? 'color: #086DEC;': ''}`">&#9660</div>
</div>
</div>
<div class="sift-item" @click="dataListSort('CreateDate')">
<div class="sift-label">下发时间</div>
<div class="sift-icon">
<div :style="`${showSortMark('CreateDate',1)? 'color: #086DEC;': ''}`">&#9650</div>
<div :style="`${showSortMark('CreateDate',2)? 'color: #086DEC;': ''}`">&#9660</div>
</div>
</div>
</div>
<div class="collect-div">
<Icon
:style="`font-size: 30px; cursor: pointer;${openCollect? 'color:#F7710F': ''}`"
icon="mdi:folder-star"
@click="getCollectList"
/>
</div>
</div>
<div class="data-list-div" style="padding-top: 3px;">
<div
v-for="(item, index) in dataList"
:key="index"
class="data-list-item"
v-if="dataList.length > 0"
>
<div class="data-list-layout-div">
<div class="data-list-title-div">
<img src="/positioning.png" class="map-mark" @click="locationFun(item)"/>
<div class="label-div">
<div class="item-label">{{item.countyname}}</div>
<div class="item-sub-label">
<span style="margin-right:12px;">{{item.streetname}}</span>
<span>{{item.case_no}}</span>
</div>
</div>
<div class="item-mark" v-if="item.is_build_name">{{item.is_build_name}}</div>
</div>
<div
class="data-item-type-div"
:style="`border-color:${item.is_illegal === 0? '#086DEC': item.is_illegal === 1? '#D03542': '#F7710F'}`"
@click="goAudit(item)">
<div>
<div class="type-title">举证</div>
<div class="type-data" :style="`background:${item.is_illegal === 0? '#086DEC': item.is_illegal === 1? '#D03542': '#F7710F'};`">
{{item.is_illegal === 0? '合法': item.is_illegal === 1? '违法': '其他'}}
</div>
</div>
</div>
</div>
<div class="data-list-info-div">
<div class="info-layout-div">
<div class="info-item">
<div class="info-label"></div>
<div class="info-data">{{item.area}}</div>
</div>
<div class="info-item">
<div class="info-label"></div>
<div class="info-data">{{item.gengdi_area}}</div>
</div>
<div class="info-item">
<div class="info-label"></div>
<div class="info-data">{{item.yongjiujibennongtian_area}}</div>
</div>
<div class="info-item">
<div class="info-label"></div>
<div class="info-data">{{item.nongyongdi_area}}</div>
</div>
</div>
<div class="info-layout-div">
<div>
<Icon
:style="`font-size: 30px; color: #314A8C; cursor: pointer;${item.isouttime === 2? 'color: #D03542;': item.isouttime === 1? 'color: #F7710F;': 'color: #314A8C;'}`"
icon="icon-park-solid:timer"
@click="()=>{}"
/>
</div>
<div style="background: rgb(237, 237, 237);width: 1px;height: 100%;margin-right: 10px;margin-left: 10px;"></div>
<div>
<Icon
:style="`font-size: 30px; cursor: pointer;${item.Fid? 'color:#F7710F': ''}`"
icon="mdi:folder-star-outline"
@click="collectItem(item)"
/>
</div>
</div>
</div>
</div>
</div>
<div class="pagination-div" v-if="dataList.length > 0">
<a-pagination
size="small"
v-model:current="pageNumber"
v-model:pageSize="pageSizeNumber"
:total="total"
show-size-changer
show-quick-jumper
@change="changePagination"
/>
</div>
<a-modal
width="100%"
wrap-class-name="full-modal"
v-model:open="auditOpen"
title="审核"
footer=""
:destroyOnClose="true"
>
<template #footer> </template>
<div class="handoff">
<a-button
type="primary"
style="margin-right: 25px;"
@click="prevData"
>上一条</a-button>
<a-button
type="primary"
@click="nextData"
>下一条</a-button>
</div>
<Audit
v-if="handoffShow"
ref="posRef"
:processId="processId"
:taskId="taskId"
:isRead="isRead"
:type="type"
@closeModel="closeMolder"
/>
</a-modal>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, defineEmits, computed, h } from 'vue';
import { StarOutlined,StarFilled } from '@ant-design/icons-vue';
import Icon from '@/components/Icon/Icon.vue';
import { getLoadTaskIllegalDetailList, updateSupervise, addTaskFavorite, deleteTaskCase } from '@/api/tiankongdi/index';
import { flowStore } from '@/store/modules/flow';
import { getDetail } from '@/api/sys/WFSchemeInfo';
import { Audit } from '@/views/demo/workflow/task/process/page';
import { Empty } from 'ant-design-vue';
import { message } from 'ant-design-vue';
import { useUserStore } from '@/store/modules/user.ts'
import { SearchOutlined, RollbackOutlined } from '@ant-design/icons-vue';
import { patchSourceOptions } from '../util.ts'
const userStore = useUserStore()
const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE;
const emits = defineEmits(['changeTask', 'changeShowParent']);
const flowWfDataStore = flowStore();
const props = defineProps(['areaId', 'yearOptions', 'year','level','batch','patchSource','batchOptions']);
const processId = ref('');
const taskId = ref('');
const isRead: any = ref(0);
const type = ref('');
const order = ref(0)
const auditOpen = ref(false);
const showDataIndex = ref()
const handoffShow = ref(true)
const openCollect = computed(() => {
if(params.value.type === null) return false
return true
})
const params = ref({
page: 1,
limit: 10,
level: props.level,
areaid: props.areaId,
geomid: null,
year: props.year,
picihao: props.batch,
tubanlaiyuan: props.patchSource,
is_build_name: null,
type: null,
sort: null,
order: null,
});
const markTypeOptions = ref([
{ label: '非粮化', value: '非粮化' },
{ label: '拆除复耕', value: '拆除复耕' },
{ label: '补办手续', value: '补办手续' },
]);
const dataList = ref([]);
const total = ref(0);
const pageNumber = ref(1)
const pageSizeNumber = ref(10)
function query() {
params.value.page = 1;
getTaskList();
}
async function getTaskList() {
console.log(params.value);
const data = await getLoadTaskIllegalDetailList(params.value);
dataList.value = data.items;
total.value = data.total;
}
function changePagination(page, pageSize) {
console.log(page, pageSize);
params.value.page = page;
params.value.limit = pageSize;
getTaskList();
}
async function goAudit(record) {
showDataIndex.value = dataList.value.findIndex(item => item.taskeid === record.taskeid)
let data = await getDetail({ code: record.processcode });
let scheme = JSON.parse(data.scheme.content);
let wfData = scheme.wfData;
flowWfDataStore.setWfDataAll(wfData);
auditOpen.value = true;
processId.value = record.processid;
taskId.value = record.taskeid;
type.value = record.type;
}
async function locationFun(record) {
emits('changeTask', record);
}
onMounted(() => {
getTaskList();
});
const changeSupervise = (item) => {
if(item.cancelsupervise === 0 && item.issupervise === 1){
message.error('取消改督办权限不足')
return
}
let params = {
id: item.processid,
supervise: 1,
}
if(item.issupervise === 1){
params.supervise = 0
}
updateSupervise(params).then(res => {
if(params.supervise === 1){
message.success('成功发起督办')
}else{
message.success('取消督办成功')
}
getTaskList();
})
}
const prevData = async () => {
if(showDataIndex.value === 0){
if(params.value.page === 1){
message.warning('已经是第一条数据了')
return
}
pageNumber.value = pageNumber.value - 1
params.value.page = params.value.page -1
await getTaskList();
showDataIndex.value = dataList.value.length -1
}else{
showDataIndex.value = showDataIndex.value -1
}
handoffShow.value = false
let record = dataList.value[showDataIndex.value]
let data = await getDetail({ code: record.processcode });
let scheme = JSON.parse(data.scheme.content);
let wfData = scheme.wfData;
flowWfDataStore.setWfDataAll(wfData);
processId.value = record.processid;
taskId.value = record.taskeid;
type.value = record.type;
handoffShow.value = true
}
const nextData = async () => {
if(showDataIndex.value === dataList.value.length -1){
if(Math.ceil(total.value / pageSizeNumber.value) === pageNumber.value){
message.warning('已经是最后一条数据了')
return
}
pageNumber.value = pageNumber.value + 1
params.value.page = params.value.page + 1
await getTaskList();
showDataIndex.value = 0
}else{
showDataIndex.value = showDataIndex.value + 1
}
handoffShow.value = false
let record = dataList.value[showDataIndex.value]
let data = await getDetail({ code: record.processcode });
let scheme = JSON.parse(data.scheme.content);
let wfData = scheme.wfData;
flowWfDataStore.setWfDataAll(wfData);
processId.value = record.processid;
taskId.value = record.taskeid;
type.value = record.type;
handoffShow.value = true
}
const cancelCollectItem = (item) => {
deleteTaskCase(item.Fid).then(res => {
message.success('取消收藏成功')
getTaskList();
})
}
const collectItem = (item) => {
if(item.Fid){
cancelCollectItem(item)
return
}
let userInfo = userStore.getUserInfo
let params = {
taskId: item.taskeid,
favoriteUserId: userInfo.id
}
addTaskFavorite(params).then(res => {
message.success('收藏成功')
getTaskList();
})
}
const getCollectList = () => {
if(params.value.type === null){
params.value.type = 1
}else if(params.value.type === 1){
params.value.type = null
}
params.value.page = 1
pageNumber.value = 1
getTaskList();
}
const showSortMark = (key, sort) => {
if(params.value.sort === key && sort === order.value){
return true
}
return false
}
const dataListSort = (type) => {
if(params.value.sort === null || params.value.sort === type){
order.value = (order.value + 1) % 3
}else{
order.value = 1
}
// emits('infoDataListSort', type, order.value)
switch(order.value){
case 0:
params.value.sort = null
params.value.order = null
break
case 1:
params.value.sort = type
params.value.order = 'asc'
break
case 2:
params.value.sort = type
params.value.order = 'desc'
break
}
getTaskList();
}
const closeMolder = () => {
getTaskList();
}
</script>
<style lang="less">
.full-modal {
.ant-modal {
max-width: 100%;
top: 0;
}
.ant-modal-content {
height: calc(100vh);
}
.ant-modal-body {
height: 85%;
}
}
</style>
<style lang="less" scoped>
.handoff{
width: 100%;
display: flex;
justify-content: flex-end;
padding-right: 25px;
}
.map-list-content {
height: 100%;
display: flex;
flex-direction: column;
}
.screen-div {
padding: 22px 12px 19px 13px;
display: flex;
width: 590px;
// margin-top: 10px;
flex-wrap: wrap;
// background: @component-background;
.screen-item {
// width: 33.3%;
display: flex;
// margin-bottom: 15px;
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 17px;
color: #000000;
height: 39px;
.screen-item-label {
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 17px;
color: #000000;
line-height: 30px;
display: flex;
align-items: center;
margin-right: 9px;
}
:deep(.ant-select-selector){
display: flex;
align-items: center;
font-family: HarmonyOS Sans;
font-weight: 500;
font-size: 19px;
color: #000000;
line-height: 30px;
height: 39px;
box-shadow: 2px 3px 3px 1px rgba(13,13,13,0.05);
}
.item-input{
font-family: Alibaba PuHuiTi;
font-weight: 400;
font-size: 19px;
color: #000000;
line-height: 30px;
width:223px;
box-shadow: 2px 3px 3px 1px rgba(13,13,13,0.05);
}
.item-button{
font-family: Alibaba PuHuiTi;
font-weight: 400;
font-size: 19px;
color: #FFFFFF;
line-height: 30px;
height:39px;
width: 97px;
background:#086DEC;
}
}
.screen-button-div {
display: flex;
justify-content: space-between;
width: 100%;
}
}
.sift-div{
background:#fff;
height: 77px;
padding:19px 13px;
margin-left: 10px;
margin-right: 10px;
border-radius: 10px 10px 0px 0px;
display: flex;
justify-content: space-between;
.layout-div{
display:flex;
.back-button{
font-size:22px;
cursor:pointer;
}
.interval-div{
height:100%;
width:1px;
background:#EDEDED;
margin-left: 10px;
margin-right: 10px;
}
.sift-item{
display: flex;
align-items: center;
margin-right:15px;
cursor:pointer;
user-select:none;
.sift-label{
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 19px;
color: #000000;
}
.sift-icon{
font-size: 9px;
margin-left:5px;
opacity: 0.53;
}
}
}
.collect-div{
display:flex;
align-items:center;
}
}
.data-list-div {
flex: 1;
overflow: auto;
padding: 10px;
// margin-top: 10px;
height: 60vh;
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
.data-list-item{
background:#fff;
padding:10px;
// border-radius:6px;
margin-bottom:4px;
.data-list-layout-div{
display:flex;
justify-content: space-between;
padding-bottom: 8px;
border-bottom: 1px solid #E5E5E5;
height: 45px;
.data-list-title-div{
display:flex;
align-items: center;
.map-mark{
width:17px;
height:17px;
cursor:pointer;
}
.label-div{
display: flex;
align-items: baseline;
margin-right: 12px
}
.item-label{
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 23px;
color: #000000;
margin-left: 9px;
margin-right:10px;
}
.item-sub-label{
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 17px;
color: #000000;
}
.item-mark{
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 13px;
color: #FFFFFF;
background: rgba(0,0,0,0.59);
padding: 5px 8px;
border-radius: 14px;
}
}
.data-item-type-div{
font-family: Alibaba PuHuiTi;
font-weight: 500;
font-size: 15px;
color: #000000;
border: 1px solid;
width: 37px;
height: 37px;
border-radius: 4px;
cursor: pointer;
user-select: none;
.type-title{
display:flex;
align-items:center;
justify-content: center;
}
.type-data{
background:#086DEC;
color:#fff;
display:flex;
align-items:center;
justify-content: center;
}
}
}
.data-list-info-div{
display: flex;
justify-content: space-between;
margin-top: 10px;
height: 40px;
.info-layout-div{
display:flex;
align-items: center;
.info-time{
font-family: HarmonyOS Sans;
font-weight: 500;
font-size: 15px;
color: #000000;
margin-right: 5px;
}
}
.info-item{
display:flex;
background: rgba(237, 237, 237, 0.55);
align-items: center;
width: 80px;
border-radius: 7px;
margin-right: 8px;
height: 33px;
justify-content: center;
.info-label{
font-family: Alibaba PuHuiTi;
font-weight: 400;
font-size: 16px;
color: #959494;
// width:45%;
display: flex;
justify-content: center;
padding-right: 5px;
}
.info-data{
font-family: HarmonyOS Sans;
font-weight: 500;
font-size: 16px;
color: #000000;
}
}
}
}
.data-list-item:nth-last-child(1){
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
}
.data-list-div::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.pagination-div {
background: @component-background;
padding: 0 10px 10px;
}
.no-data {
padding: 20px 0;
}
.rollback {
background: @component-background;
padding: 10px;
}
</style>

View File

@ -0,0 +1,234 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<PermissionBtn @btn-event="onBtnClicked" />
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction :actions="createActions(record)" />
</template>
</template>
</BasicTable>
<a-modal
style="width: 100vw; top: 0px; left: 0px; margin: 0px; padding: 0px"
wrap-class-name="full-modal"
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 lang="ts" setup>
import { ref, reactive } from 'vue';
import { BasicTable, useTable, TableAction, EditRecordRow } from '@/components/Table';
import { loadCaseInfoIllegalList, dealIllegalCaseInfo } from '@/api/demo/system';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './illegaltreatment.data';
import { getAppEnvConfig } from '@/utils/env';
import axios from 'axios';
import ShowInfoModal from '@/views/demo/tiankongdi/curbspotcity/MapList/ShowInfoModal/index.vue';
import { getCaseInfoById } from '@/api/tiankongdi/index';
import { useMessage } from '@/hooks/web/useMessage';
import { cloneDeep } from 'lodash-es';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const { createMessage } = useMessage();
defineOptions({ name: 'RoleManagement' });
const searchInfo = reactive<Recordable>({
countyid: null,
});
const showInfoData = ref();
const showInfoOpen = ref(false);
const searchParams = ref();
const [registerTable] = useTable({
title: '违法处理',
api: loadCaseInfoIllegalList,
columns,
formConfig: {
labelWidth: 120,
showAdvancedButton: false,
schemas: searchFormSchema,
},
useSearchForm: true,
showTableSetting: true,
tableSetting: { fullScreen: true },
//
handleSearchInfoFn(info) {
searchParams.value = info;
return info;
},
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
});
const currentEditKeyRef = ref('');
function createActions(record: EditRecordRow): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.Id : false,
onClick: handleEdit.bind(null, record),
},
{
// icon: 'ant-design:ellipsis-outlined',
label: '查看',
onClick: viewAccount.bind(null, record),
},
];
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record),
},
},
];
}
function handleEdit(record: EditRecordRow) {
console.log(record);
currentEditKeyRef.value = record.Id;
record.onEdit?.(true);
}
function handleCancel(record: EditRecordRow) {
currentEditKeyRef.value = '';
record.onEdit?.(false, false);
}
async function handleSave(record: EditRecordRow) {
console.log(record);
//
createMessage.loading({ content: '正在保存...', duration: 0, key: 'saving' });
const valid = await record.onValid?.();
console.log(valid);
if (valid) {
try {
const data = cloneDeep(record.editValueRefs);
console.log(data);
let querys = { ...data };
querys.id = record.Id;
console.log(querys);
//TODO
const res = await dealIllegalCaseInfo(querys);
console.log(res);
if (res) {
//
const pass = await record.onEdit?.(false, true);
if (pass) {
currentEditKeyRef.value = '';
}
createMessage.success({ content: '数据已保存', key: 'saving' });
}
} catch (error) {
createMessage.error({ content: '保存失败', key: 'saving' });
}
} else {
// const pass = await record.onEdit?.(false, true);
createMessage.error({ content: '请填写正确的数据', key: 'saving' });
}
}
//
function handleExport() {
let params = { ...searchParams.value };
params.countyid = searchInfo?.countyid;
axios({
method: 'post',
url: VITE_GLOB_API_URL + '/api/DroneCaseInfoSingle/ExportCaseInfoIllegalList',
params: params,
headers: {
'X-Token': localStorage.getItem('X-Token'),
},
responseType: 'blob',
}).then((res) => {
console.log('excel', res);
let fileName = '违法处理统计报表' + new Date().getTime() + '.xls';
const elink = document.createElement('a');
elink.download = fileName;
elink.style.display = 'none';
elink.href = URL.createObjectURL(res.data);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href);
document.body.removeChild(elink);
});
}
function onBtnClicked(domId) {
switch (domId) {
case 'btnExport':
handleExport();
break;
default:
break;
}
}
function viewAccount(record) {
console.log(record);
getCaseInfoById({ id: record.Id }).then((res) => {
showInfoData.value = res;
showInfoOpen.value = true;
});
}
</script>
<style lang="scss" scoped>
.data-preview-container {
width: 100%;
height: calc(100% - 0px);
position: absolute;
padding: 30px 10px;
top: 0px;
left: 0px;
background: #fff;
}
.data-preview-container-option {
width: 120px;
height: 40px;
position: absolute;
top: 30px;
right: 0px;
}
.data-preview-container-option div {
width: 40px;
height: 40px;
line-height: 40px;
float: left;
text-align: center;
cursor: pointer;
}
.full-modal {
.ant-modal {
min-width: 100vw;
top: 0px;
padding: 0px;
margin: 0px;
}
.ant-modal-content {
display: flex;
flex-direction: column;
}
.ant-modal-body {
flex: 1;
}
}
</style>

View File

@ -1,234 +1,205 @@
<template>
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<PermissionBtn @btn-event="onBtnClicked" />
</template>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction :actions="createActions(record)" />
</template>
</template>
</BasicTable>
<a-modal
style="width: 100vw; top: 0px; left: 0px; margin: 0px; padding: 0px"
wrap-class-name="full-modal"
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 class="curb-spot-city">
<div class="show-list">
<AuditProgress
v-if="showParent"
:year="year"
:batch="batch"
:batchOptions="batchOptions"
:yearOptions="yearOptions"
:dataList="dataList"
@auditProgressScreenChange="auditProgressScreenChange"
@showInfo="changeShowInfo"
/>
<MapList
@changeTask="changeTask"
@changeShowParent="changeShowParent"
:areaId="areaId"
:level="level"
:year="year"
:batch="batch"
:patchSource="patchSource"
:yearOptions="yearOptions"
:batchOptions="batchOptions"
v-else
/>
</div>
<div class="map-box-div">
<MapboxMap
:mapConfig="mapConfig"
@handlerDrawComplete="handlerDrawComplete"
@mapOnLoad="onMapboxLoad"
ref="MapboxComponent"
/>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue';
import { BasicTable, useTable, TableAction, EditRecordRow } from '@/components/Table';
import { loadCaseInfoIllegalList, dealIllegalCaseInfo } from '@/api/demo/system';
import { PermissionBtn } from '@/components/PermissionBtn/index';
import { columns, searchFormSchema } from './illegaltreatment.data';
import { getAppEnvConfig } from '@/utils/env';
import axios from 'axios';
import ShowInfoModal from '@/views/demo/tiankongdi/curbspotcity/MapList/ShowInfoModal/index.vue';
import { getCaseInfoById } from '@/api/tiankongdi/index';
<script setup lang="ts">
import { ref, onMounted, onUnmounted, 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 { getLoadTaskCount } from '@/api/tiankongdi/index';
import { getGeom,getConfig } from '@/api/sys/layerManagement';
import { getDetail } from '@/api/sys/WFSchemeInfo';
import { useMessage } from '@/hooks/web/useMessage';
import { cloneDeep } from 'lodash-es';
const { VITE_GLOB_API_URL } = getAppEnvConfig();
const { createMessage } = useMessage();
defineOptions({ name: 'RoleManagement' });
const searchInfo = reactive<Recordable>({
countyid: null,
});
const showInfoData = ref();
const showInfoOpen = ref(false);
const searchParams = ref();
const [registerTable] = useTable({
title: '违法处理',
api: loadCaseInfoIllegalList,
columns,
formConfig: {
labelWidth: 120,
showAdvancedButton: false,
schemas: searchFormSchema,
},
useSearchForm: true,
showTableSetting: true,
tableSetting: { fullScreen: true },
//
handleSearchInfoFn(info) {
searchParams.value = info;
return info;
},
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
},
});
const MapboxMap = defineAsyncComponent(() => import('@/components/MapboxMaps/MapComponent.vue'));
const MapboxComponent = ref();
const mapConfig = ref({ isShowMap: false });
const currentEditKeyRef = ref('');
function createActions(record: EditRecordRow): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.Id : false,
onClick: handleEdit.bind(null, record),
},
{
// icon: 'ant-design:ellipsis-outlined',
label: '查看',
onClick: viewAccount.bind(null, record),
},
];
function onMapboxLoad():void {
getConfig({code:"mapsetting"}).then(res=>{
mapConfig.value = JSON.parse(res.codeValue)
})
}
const showParent = ref(true);
const year = ref();
const batch = ref();
const patchSource = ref()
const batchOptions = ref([
{ value: '第一批', label: '第一批' },
{ value: '第二批', label: '第二批' },
{ value: '第三批', label: '第三批' },
]);
const yearOptions = ref([
{ value: '2024', label: '2024' },
{ value: '2023', label: '2023' },
{ value: '2022', label: '2022' },
{ value: '2021', label: '2021' },
{ value: '2020', label: '2020' },
]);
const dataList = ref([]);
const areaId = ref('');
const level = ref()
const auditProgressScreenChange = (value, type) => {
switch (type) {
case 'year':
year.value = value;
break;
case 'batch':
batch.value = value;
break;
case 'patchSource':
patchSource.value = value;
break;
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record),
},
},
];
getCountList();
};
const changeShowInfo = (item) => {
console.log(item);
showParent.value = false;
areaId.value = item.areaid;
level.value = item.level
};
function changeShowParent() {
getCountList()
showParent.value = true;
}
function handleEdit(record: EditRecordRow) {
console.log(record);
currentEditKeyRef.value = record.Id;
record.onEdit?.(true);
async function getCountList() {
const data = await getLoadTaskCount({
year: year.value,
tubanlaiyuan: patchSource.value,
picihao: batch.value,
});
dataList.value = data;
}
function handleCancel(record: EditRecordRow) {
currentEditKeyRef.value = '';
record.onEdit?.(false, false);
onMounted(() => {
getYearList();
getCountList();
});
function getYearList() {
let num = 10;
const currentYear = new Date().getFullYear();
//
let list: any = [];
//
// year.value = Number(`${currentYear}`);
list.push({
value: Number(`${currentYear}`),
label: Number(`${currentYear}`),
});
//
for (let i = 1; i <= num; i++) {
list.push({
value: Number(`${currentYear - i}`),
label: Number(`${currentYear - i}`),
});
}
yearOptions.value = list;
}
async function handleSave(record: EditRecordRow) {
console.log(record);
//
createMessage.loading({ content: '正在保存...', duration: 0, key: 'saving' });
const valid = await record.onValid?.();
console.log(valid);
if (valid) {
try {
const data = cloneDeep(record.editValueRefs);
console.log(data);
let querys = { ...data };
querys.id = record.Id;
console.log(querys);
//TODO
const res = await dealIllegalCaseInfo(querys);
console.log(res);
if (res) {
//
const pass = await record.onEdit?.(false, true);
if (pass) {
currentEditKeyRef.value = '';
function changeTask(record) {
if(record?.geomid){
// handlerGetMapConfigByFormId(record.processcode);
let val = record.geomid
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('当前数据没有图斑!');
}
createMessage.success({ content: '数据已保存', key: 'saving' });
}
} catch (error) {
createMessage.error({ content: '保存失败', key: 'saving' });
});
} else {
createMessage.error('当前数据没有图斑!');
}
} else {
// const pass = await record.onEdit?.(false, true);
createMessage.error({ content: '请填写正确的数据', key: 'saving' });
}
}
//
function handleExport() {
let params = { ...searchParams.value };
params.countyid = searchInfo?.countyid;
axios({
method: 'post',
url: VITE_GLOB_API_URL + '/api/DroneCaseInfoSingle/ExportCaseInfoIllegalList',
params: params,
headers: {
'X-Token': localStorage.getItem('X-Token'),
},
responseType: 'blob',
}).then((res) => {
console.log('excel', res);
let fileName = '违法处理统计报表' + new Date().getTime() + '.xls';
const elink = document.createElement('a');
elink.download = fileName;
elink.style.display = 'none';
elink.href = URL.createObjectURL(res.data);
document.body.appendChild(elink);
elink.click();
URL.revokeObjectURL(elink.href);
document.body.removeChild(elink);
});
}
function onBtnClicked(domId) {
switch (domId) {
case 'btnExport':
handleExport();
break;
default:
break;
// id
function handlerGetMapConfigByFormId(id){
if(id){
getDetail({ code: id }).then(res=>{
let data = res;
let scheme = JSON.parse(data.scheme.content);
let wfData = scheme.wfData;
let startFlow = wfData.find((item,index)=>{
return item.type == "bpmn:StartEvent";
})
if(startFlow?.mapConfig){
mapConfig.value = startFlow?.mapConfig
}
});
}
}
function viewAccount(record) {
console.log(record);
getCaseInfoById({ id: record.Id }).then((res) => {
showInfoData.value = res;
showInfoOpen.value = true;
});
}
</script>
<style lang="scss" scoped>
.data-preview-container {
width: 100%;
height: calc(100% - 0px);
position: absolute;
padding: 30px 10px;
top: 0px;
left: 0px;
background: #fff;
}
.data-preview-container-option {
width: 120px;
height: 40px;
position: absolute;
top: 30px;
right: 0px;
}
.data-preview-container-option div {
width: 40px;
height: 40px;
line-height: 40px;
float: left;
text-align: center;
cursor: pointer;
}
.full-modal {
.ant-modal {
min-width: 100vw;
top: 0px;
padding: 0px;
margin: 0px;
.curb-spot-city {
height: 100%;
display: flex;
.show-list {
width: 590px;
background: #EFEFEF;
}
.ant-modal-content {
display: flex;
flex-direction: column;
}
.ant-modal-body {
flex: 1;
.map-box-div {
width: 65%;
}
}
</style>

View File

@ -0,0 +1,10 @@
export const patchSourceOptions = [
{
label: '全域巡查',
value: '全域巡查',
},
{
label: '卫片下发',
value: '卫片下发',
}
]

View File

@ -7,7 +7,8 @@
button-style="solid"
style="width:100%">
<a-radio-button :value="0" class="radio-item">农用地</a-radio-button>
<a-radio-button :value="1" class="radio-item">建设用地推堆土</a-radio-button>
<a-radio-button :value="1" class="radio-item">建设用地</a-radio-button>
<a-radio-button :value="2" class="radio-item">推堆土</a-radio-button>
</a-radio-group>
</div>
<div class="screen-div">
@ -15,7 +16,7 @@
<div class="screen-item-label">年份</div>
<a-select
allowClear
style="width:103px;"
style="width:130px;"
v-model:value="props.infoScreenData.year"
:options="yearOptions"
@change="(value) => emits('mapListScreenChange',value,'year')"
@ -25,7 +26,7 @@
<div class="screen-item-label" style="margin-right: 11px;">图斑来源</div>
<a-select
allowClear
style="width:142px;"
style="width:130px;"
v-model:value="props.infoScreenData.patchSource"
:options="patchSourceOptions"
@change="(value) => emits('mapListScreenChange',value,'patchSource')"
@ -34,23 +35,24 @@
<div class="screen-item" style="margin-bottom:12px;">
<div class="screen-item-label">批次</div>
<a-input
allowClear
class="item-input"
style="width:117px;"
style="width:103px;"
v-model:value="props.infoScreenData.batch"
@change="(value) => emits('mapListScreenChange',value.target.value,'batch')"
/>
</div>
<div class="screen-item" style="margin-right:15px;margin-bottom:22px;">
<div class="screen-item" style="margin-right:15px;margin-bottom:12px;">
<div class="screen-item-label">标注</div>
<a-select
allowClear
style="width:136px;"
style="width:130px;"
v-model:value="props.infoScreenData.markType"
:options="markTypeOptions"
@change="(value) => emits('mapListScreenChange',value,'markType')"
/>
</div>
<div class="screen-item" style="margin-bottom:22px;">
<div class="screen-item" style="margin-bottom:12px;">
<div class="screen-item-label" style="margin-right: 10px;">下发时间</div>
<a-range-picker
:format="'YYYY-MM-DD'"
@ -64,7 +66,7 @@
<div class="screen-item-label">乡镇</div>
<a-select
allowClear
style="width:136px;"
style="width:130px;"
v-model:value="props.infoScreenData.streetId"
:options="streetsAreaOptions"
@change="(value) => emits('mapListScreenChange',value,'streetId')"
@ -137,7 +139,7 @@
:options="isOverdueOptions"></a-checkbox-group>
</div>
</div>
<div style="display:flex;">
<div style="display:flex;align-items: center;">
<div>图斑面积</div>
<div style="display:flex;">
<a-input style="width:30%;"
@ -145,24 +147,26 @@
@change="(e) => emits('mapListScreenChange',e.target.value,'mapAreaFirst')"
/>
<span>---</span>
<a-input style="width:30%;"
<a-input style="width:30%;margin-right: 4px;"
v-model:value="props.infoScreenData.mapAreaLast"
@change="(e) => emits('mapListScreenChange',e.target.value,'mapAreaLast')"
/>
</div>
</div>
<div style="display:flex;">
<div style="display:flex;margin-top: 4px;">
<div>耕地面积</div>
<div style="display:flex;">
<div style="display:flex;align-items: center;">
<a-input style="width:30%;"
v-model:value="props.infoScreenData.arableAreaFirst"
@change="(e) => emits('mapListScreenChange',e.target.value,'arableAreaFirst')"
/>
<span>---</span>
<a-input style="width:30%;"
<a-input style="width:30%;margin-right: 4px;"
v-model:value="props.infoScreenData.arableAreaLast"
@change="(e) => emits('mapListScreenChange',e.target.value,'arableAreaLast')"
/>
</div>
</div>
</template>
@ -627,7 +631,7 @@ const closeMolder = () => {
background: #086DEC;
}
.radio-item{
width:50%;
width:33%;
text-align: center;
height: 40px;
user-select: none;

View File

@ -27,6 +27,7 @@ export const mapStatusOptions = [
{ label: '待接收', value: '待接收' },
{ label: '待填报', value: '待填报' },
{ label: '待整改', value: '待整改' },
{ label: '已退回', value: '已退回' },
]
export const markTypeOptions = [
{ label: '在建', value: '在建' },