种植规划

This commit is contained in:
lzc 2025-03-11 15:58:05 +08:00
parent cffd50a4fe
commit 197ea5d1a4
10 changed files with 1543 additions and 150 deletions

View File

@ -5,8 +5,15 @@
<el-dropdown-menu v-if="!isEmpty(actions)">
<template v-for="item in actions" :key="item.name">
<el-dropdown-item v-if="onPermission(item)" @click="item.event(data)">
<el-button :type="item.type ?? 'primary'" :icon="item.icon" :size="item.size" :disabled="item.disabled" text>
{{ item.name }}
<el-button
:type="item.type ?? 'primary'"
:icon="typeof item.name === 'function' ? item.icon(data) : item.icon"
:size="item.size"
:disabled="item.disabled"
text
>
<!-- {{ item.name }} -->
{{ typeof item.name === 'function' ? item.name(data) : item.name }}
</el-button>
</el-dropdown-item>
</template>

View File

@ -0,0 +1,33 @@
import request from '@/utils/axios';
//基础信息维护——字典项管理
//种植产物相关
export function getPlanType(params = {}) {
return request('land-resource/baseInfo/planTypePage', {
method: 'GET',
params,
});
}
export function savePlanType(data) {
return request('land-resource/baseInfo/planTypeSave', {
method: 'POST',
data,
});
}
export function upPlanType(data = {}) {
return request('land-resource/baseInfo/planTypeEdit', {
method: 'PUT',
data,
});
}
export function exportPlanType(params = {}) {
return request('/land-resource/baseInfo/planTypeExport', {
method: 'GET',
params,
responseType: 'blob',
});
}

View File

@ -25,3 +25,11 @@ export function CommonUpload(data, params) {
params,
});
}
//云南省所有区域信息
export function getRegion(code) {
let codeVal = code ? code : '530000';
return request('/system/area/region?areaCode=' + codeVal, {
method: 'GET',
});
}

View File

@ -5,9 +5,15 @@ export default [
path: '/sub-government-affairs-service/productOperateMain',
name: 'productOperateMain',
component: Layout,
redirect: '/sub-government-affairs-service/individual',
redirect: '/sub-government-affairs-service/home',
meta: { title: '生产经营主体', icon: 'icon-shop' },
children: [
{
path: '/sub-government-affairs-service/home',
component: () => import('@/views/productOperateMain/home/index.vue'),
name: 'home',
meta: { title: '数据可视化管理', icon: 'Document' },
},
{
path: '/sub-government-affairs-service/individual',
component: () => import('@/views/productOperateMain/individual/index.vue'),

View File

@ -23,7 +23,8 @@
</template>
<template #status="{ row }">
{{ !row.status ? '是' : '否' }}
<el-tag v-if="row.status == 1" type="success" size="small">启用</el-tag>
<el-tag v-if="row.status == 0" type="danger" size="small">禁用</el-tag>
</template>
<template #menu="scope">
@ -73,37 +74,13 @@ import { CRUD_OPTIONS } from '@/config';
import { isEmpty, downloadFile } from '@/utils';
import { useUserStore } from '@/store/modules/user';
import { compact } from 'lodash';
import {
getOperationRecord,
saveOperationRecord,
editOperationRecord,
delOperationRecord,
exportOperationRecord,
getAddrCropByLand,
importOperationRecord,
} from '@/apis/land';
import { getPlanType, savePlanType, upPlanType, exportPlanType } from '@/apis/baseInfo';
const { VITE_APP_BASE_API } = import.meta.env;
const app = useApp();
const UserStore = useUserStore();
const crudRef = ref(null);
const stateCrudRef = ref(null);
const handleLandChange = async (value, form, done) => {
if (!value || !value.item || !value.item.id) return; //
let val = {};
getAddrCropByLand(value.item?.id || '')
.then((res) => {
if (res.code === 200) {
val = res.data || {};
}
})
.catch((err) => {
val = {};
})
.finally(() => {});
state.form.crop = val?.crop || value.item?.crop;
state.form.address = val?.county + val?.town + val?.village || value.item?.address;
};
const stageOptions = reactive([
{ value: '0', label: '苗期' },
@ -131,10 +108,11 @@ const state = reactive({
options: {
...CRUD_OPTIONS,
addBtnText: '新增',
selection: false,
column: [
{
label: '编号',
prop: 'executor',
prop: 'id',
fixed: true,
addDisplay: false,
editDisabled: true,
@ -147,8 +125,7 @@ const state = reactive({
{
label: '种植产物',
prop: 'crop',
width: '240px',
editDisabled: true,
editDisabled: false,
showOverflowTooltip: true,
rules: {
required: true,
@ -158,11 +135,11 @@ const state = reactive({
},
{
label: '种植时间',
prop: 'operationDate',
prop: 'planDate',
type: 'date',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
width: 200,
width: 160,
rules: {
required: true,
message: '请选择作业日期',
@ -188,6 +165,15 @@ const state = reactive({
icon: 'edit',
event: ({ row }) => rowEdit(row),
},
{
name: ({ row }) => {
return row.status == 1 ? '禁用' : '启用';
},
icon: ({ row }) => {
return row.status == 1 ? 'Close' : 'Check';
},
event: ({ row }) => rowStatus(row),
},
],
},
pageData: {
@ -263,26 +249,26 @@ const stageState = reactive({
//
const loadData = () => {
// state.loading = true;
// getOperationRecord(state.query)
// .then((res) => {
// if (res.code === 200) {
// const { current, size, total, records } = res.data;
// state.data = records;
// state.pageData = {
// currentPage: current || 1,
// pageSize: size || 10,
// total: total,
// };
// }
// })
// .catch((err) => {
// app.$message.error(err.msg);
// state.data = [];
// })
// .finally(() => {
// state.loading = false;
// });
state.loading = true;
getPlanType(state.query)
.then((res) => {
if (res.code === 200) {
const { current, size, total, records } = res.data;
state.data = records;
state.pageData = {
currentPage: current || 1,
pageSize: size || 10,
total: total,
};
}
})
.catch((err) => {
app.$message.error(err.msg);
state.data = [];
})
.finally(() => {
state.loading = false;
});
};
loadData();
@ -320,8 +306,12 @@ const selectionChange = (rows) => {
//
const rowSave = (row, done, loading) => {
// console.info('', row);
saveOperationRecord(row)
console.info('新增', row);
let parmer = {
planDate: row.planDate || '',
crop: row.crop || '',
};
savePlanType(parmer)
.then((res) => {
if (res.code === 200) {
app.$message.success('添加成功!');
@ -349,39 +339,39 @@ const onExport = () => {
app.$message.error('当前暂时没有可供导出的数据!');
return;
}
// state.loading = true;
const fileName = '土地巡查明细表';
// exportOperationRecord(state.query)
// .then((res) => {
// if (res.status === 200) {
// downloadFile(res.data, `${fileName}.xlsx`, 'blob');
// app.$message.success('');
// }
// })
// .catch((err) => {
// app.$message.error('');
// })
// .finally(() => {
// state.loading = false;
// });
state.loading = true;
const fileName = '种植产物明细表';
exportPlanType(state.query)
.then((res) => {
if (res.status === 200) {
downloadFile(res.data, `${fileName}.xlsx`, 'blob');
app.$message.success('导出成功!');
}
})
.catch((err) => {
app.$message.error('导出失败!');
})
.finally(() => {
state.loading = false;
});
};
const rowUpdate = (row, index, done, loading) => {
console.info('更新');
// editOperationRecord(row)
// .then((res) => {
// if (res.code === 200) {
// app.$message.success('');
// done();
// loadData();
// }
// })
// .catch((err) => {
// app.$message.error(err.msg);
// })
// .finally(() => {
// loading();
// });
upPlanType(row)
.then((res) => {
if (res.code === 200) {
app.$message.success('更新成功!');
done();
loadData();
}
})
.catch((err) => {
app.$message.error(err.msg);
})
.finally(() => {
loading();
});
};
//
@ -391,6 +381,25 @@ const stageRefresh = () => {
app.$message.success('刷新成功');
};
const rowStatus = (row) => {
console.info('操作状态');
let parmer = {
...row,
status: row.status == 1 ? 0 : 1,
};
upPlanType(parmer)
.then((res) => {
if (res.code === 200) {
app.$message.success('更新成功!');
loadData();
}
})
.catch((err) => {
app.$message.error(err.msg);
})
.finally(() => {});
};
const rowClick = (row) => {
state.currentRow = { ...row };
console.info('rowClick', state.currentRow);

View File

@ -3,7 +3,13 @@
<div>
<el-row :gutter="20">
<el-col :span="6">
<el-tree style="max-width: 600px" :data="typeTree" :props="{ children: 'children', label: 'label' }" @node-click="handleNodeClick" />
<el-tree
style="max-width: 600px"
:data="typeTree"
node-key="areaCode"
:props="{ children: 'areaChildVOS', label: 'areaName' }"
@node-click="handleNodeClick"
/>
</el-col>
<el-col :span="18">
<avue-crud
@ -42,6 +48,7 @@ import { useApp } from '@/hooks';
import { CRUD_OPTIONS } from '@/config';
import CustomCard from '@/components/CustomCard.vue';
import { useUserStore } from '@/store/modules/user';
import { getRegion } from '@/apis/index';
const { VITE_APP_BASE_API } = import.meta.env;
const app = useApp();
@ -119,31 +126,31 @@ const state = reactive({
currentRow: {},
});
let typeTree = reactive([
{
label: '耿马县',
id: '0',
level: '0',
children: [
{
label: '镇1',
level: '1',
id: '01',
children: [
{ label: '村1', children: [], id: '0101', pId: '01', level: '2' },
{ label: '村2', children: [], id: '0102', pId: '01', level: '2' },
],
pId: '0',
},
{ label: '镇2', level: '1', children: [], id: '02', pId: '0' },
],
},
{
label: '县1',
id: '1',
level: '0',
children: [{ label: '镇1', children: [], id: '11', pId: '10', level: '1' }],
},
let typeTree = ref([
// {
// label: '',
// id: '0',
// level: '0',
// children: [
// {
// label: '1',
// level: '1',
// id: '01',
// children: [
// { label: '1', children: [], id: '0101', pId: '01', level: '2' },
// { label: '2', children: [], id: '0102', pId: '01', level: '2' },
// ],
// pId: '0',
// },
// { label: '2', level: '1', children: [], id: '02', pId: '0' },
// ],
// },
// {
// label: '1',
// id: '1',
// level: '0',
// children: [{ label: '1', children: [], id: '11', pId: '10', level: '1' }],
// },
]);
let townOptions = reactive([]);
@ -179,7 +186,18 @@ const loadData = () => {
// });
};
const getTree = () => {
getRegion().then((res) => {
if (res.code === 200) {
const { code, data } = res;
typeTree.value = data;
console.info('区域信息', typeTree.value);
}
});
};
onMounted(() => {
getTree();
loadData();
});
@ -215,25 +233,23 @@ const selectionChange = (rows) => {
};
const handleNodeClick = (data) => {
if (data.level == '2') {
return;
}
// console.info('data', data);
if (data.level == '0') {
infoData.countyId = data.id;
infoData.townId = '';
}
if (data.level == '1') {
let countys =
typeTree.filter((m) => {
return m.id == data.pId;
}) || [];
let town = countys[0] && countys[0].children ? countys[0].children : [];
townOptions = town;
infoData.townId = data.id;
infoData.countyId = data.pId;
}
// if (data.level == '2') {
// return;
// }
// if (data.level == '0') {
// infoData.countyId = data.id;
// infoData.townId = '';
// }
// if (data.level == '1') {
// let countys =
// typeTree.filter((m) => {
// return m.id == data.pId;
// }) || [];
// let town = countys[0] && countys[0].children ? countys[0].children : [];
// townOptions = town;
// infoData.townId = data.id;
// infoData.countyId = data.pId;
// }
// console.info('infoData', infoData);
};
//

View File

@ -418,26 +418,26 @@ const state = reactive({
//
const loadData = () => {
state.loading = true;
getOperationRecord(state.query)
.then((res) => {
if (res.code === 200) {
const { current, size, total, records } = res.data;
state.data = records;
state.pageData = {
currentPage: current || 1,
pageSize: size || 10,
total: total,
};
}
})
.catch((err) => {
app.$message.error(err.msg);
state.data = [];
})
.finally(() => {
state.loading = false;
});
// state.loading = true;
// getOperationRecord(state.query)
// .then((res) => {
// if (res.code === 200) {
// const { current, size, total, records } = res.data;
// state.data = records;
// state.pageData = {
// currentPage: current || 1,
// pageSize: size || 10,
// total: total,
// };
// }
// })
// .catch((err) => {
// app.$message.error(err.msg);
// state.data = [];
// })
// .finally(() => {
// state.loading = false;
// });
};
loadData();

View File

@ -0,0 +1,140 @@
<template>
<div ref="chartContainer" style="width: 600px; height: 400px"></div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import * as echarts from 'echarts';
import geoJsonData from '../components/530926geo.json'; //
const chartContainer = ref(null);
let chartInstance = null;
//
const initChart = () => {
//
chartInstance = echarts.init(chartContainer.value);
//
echarts.registerMap('gengma', geoJsonData); // 使'gengma'
//
const option = {
title: {
text: '耿马县地图散点图',
left: 'center',
},
tooltip: {
trigger: 'item',
formatter: function (params) {
if (params.seriesType === 'effectScatter') {
return `${params.name}: (${params.value[0]}, ${params.value[1]})`;
}
return params.name;
},
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
dataView: { readOnly: false },
restore: {},
saveAsImage: {},
},
},
geo: {
map: 'gengma',
roam: true,
zoom: 1.2,
itemStyle: {
normal: {
areaColor: '#1f77b4', //
borderColor: '#000', //
},
emphasis: {
areaColor: '#ff7f0e', //
borderColor: '#fff', //
},
},
},
series: [
//
{
name: '镇边界',
type: 'map',
mapType: 'gengma',
roam: true,
zoom: 1.2,
itemStyle: {
normal: {
borderColor: '#000', //
borderWidth: 1, //
areaColor: 'transparent', //
},
emphasis: {
borderColor: '#fff',
borderWidth: 2,
},
},
},
//
{
name: '闪烁散点',
type: 'effectScatter', // 使 effectScatter
coordinateSystem: 'geo',
data: [
//
{
name: '孟定镇',
value: [99.081993, 23.554045, 100], // , ,
itemStyle: {
color: '#FF0000', //
},
},
{
name: '勐永镇',
value: [99.406653, 23.534142, 80], // , ,
itemStyle: {
color: '#00FF00', //
},
},
],
symbolSize: function (val) {
return val[2] ? val[2] / 10 : 10; //
},
label: {
formatter: '{b}',
position: 'right',
show: false,
},
rippleEffect: {
period: 4, //
scale: 3, //
brushType: 'stroke', // 'stroke' 'fill'
},
hoverAnimation: true,
},
],
};
//
chartInstance.setOption(option);
};
//
onMounted(() => {
initChart();
});
//
onBeforeUnmount(() => {
if (chartInstance) {
chartInstance.dispose();
}
});
</script>
<style scoped>
/* 可以根据需要添加样式 */
</style>

View File

@ -0,0 +1,12 @@
<template>
<div>
<mapSplashed></mapSplashed>
</div>
</template>
<script setup>
// import { reactive, ref } from 'vue';
// import { useApp } from '@/hooks';
import mapSplashed from '../home/components/mapSplashed.vue';
</script>
<style></style>