Merge branch 'dev' of http://192.168.18.88:8077/sznyb/daimp-front into dev
This commit is contained in:
commit
329b47255c
@ -5,18 +5,22 @@
|
||||
import { ref, reactive, watchEffect } from 'vue';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useEcharts } from '../../hooks/useEcharts';
|
||||
|
||||
export default {
|
||||
name: 'CustomEchartBar',
|
||||
props: {
|
||||
chartData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
required: true,
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: 'bar',
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
@ -25,14 +29,11 @@ export default {
|
||||
type: String,
|
||||
default: 'calc(100vh - 78px)',
|
||||
},
|
||||
seriesColor: {
|
||||
type: String,
|
||||
default: '#1890ff',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
emits: ['click'],
|
||||
setup(props, { emit }) {
|
||||
const chartRef = ref(null);
|
||||
const { setOptions } = useEcharts(chartRef);
|
||||
const { setOptions, getInstance } = useEcharts(chartRef);
|
||||
const option = reactive({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -44,6 +45,12 @@ export default {
|
||||
},
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
top: 30,
|
||||
},
|
||||
grid: {
|
||||
top: 60,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
@ -51,14 +58,7 @@ export default {
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'bar',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
color: props.seriesColor,
|
||||
},
|
||||
],
|
||||
series: [],
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
@ -69,16 +69,36 @@ export default {
|
||||
if (props.option) {
|
||||
Object.assign(option, cloneDeep(props.option));
|
||||
}
|
||||
let seriesData = props.chartData.map((item) => {
|
||||
return item.value;
|
||||
let typeArr = Array.from(new Set(props.chartData.map((item) => item.type)));
|
||||
let xAxisData = Array.from(new Set(props.chartData.map((item) => item.name)));
|
||||
let seriesData = [];
|
||||
typeArr.forEach((type, index) => {
|
||||
const barStyle = props.option?.barStyle ?? {};
|
||||
let obj = { name: type, type: props.type, ...barStyle };
|
||||
let data = [];
|
||||
xAxisData.forEach((x) => {
|
||||
let dataArr = props.chartData.filter((item) => type === item.type && item.name == x);
|
||||
if (dataArr && dataArr.length > 0) {
|
||||
data.push(dataArr[0].value);
|
||||
} else {
|
||||
data.push(null);
|
||||
}
|
||||
});
|
||||
obj['data'] = data;
|
||||
if (props.option?.color) {
|
||||
obj.color = props.option?.color[index];
|
||||
}
|
||||
seriesData.push(obj);
|
||||
});
|
||||
let xAxisData = props.chartData.map((item) => {
|
||||
return item.name;
|
||||
});
|
||||
option.series[0].data = seriesData;
|
||||
option.series[0].color = props.seriesColor;
|
||||
option.series = seriesData;
|
||||
option.xAxis.data = xAxisData;
|
||||
setOptions(option);
|
||||
getInstance()?.off('click', onClick);
|
||||
getInstance()?.on('click', onClick);
|
||||
}
|
||||
|
||||
function onClick(params) {
|
||||
emit('click', params);
|
||||
}
|
||||
return { chartRef };
|
||||
},
|
||||
|
@ -7,7 +7,7 @@ import { cloneDeep } from 'lodash';
|
||||
import { useEcharts } from '../../hooks/useEcharts';
|
||||
|
||||
export default {
|
||||
name: 'CustomEchartMultiLine',
|
||||
name: 'CustomEchartLine',
|
||||
props: {
|
||||
chartData: {
|
||||
type: Array,
|
85
main/src/components/custom-echart-mixin/index.vue
Normal file
85
main/src/components/custom-echart-mixin/index.vue
Normal file
@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div ref="chartRef" :style="{ height, width }"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive, watchEffect } from 'vue';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { useEcharts } from '../../hooks/useEcharts';
|
||||
|
||||
export default {
|
||||
name: 'CustomEchartMixin',
|
||||
props: {
|
||||
chartData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
option: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%',
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: 'calc(100vh - 78px)',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const chartRef = ref(null);
|
||||
const { setOptions } = useEcharts(chartRef);
|
||||
const option = reactive({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow',
|
||||
label: {
|
||||
show: true,
|
||||
backgroundColor: '#333',
|
||||
},
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: [],
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'bar',
|
||||
type: 'bar',
|
||||
data: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
props.chartData && initCharts();
|
||||
});
|
||||
|
||||
function initCharts() {
|
||||
if (props.option) {
|
||||
Object.assign(option, cloneDeep(props.option));
|
||||
}
|
||||
let typeArr = Array.from(new Set(props.chartData.map((item) => item.type)));
|
||||
let xAxisData = Array.from(new Set(props.chartData.map((item) => item.name)));
|
||||
let seriesData = [];
|
||||
typeArr.forEach((type, index) => {
|
||||
let obj = { name: type };
|
||||
let chartArr = props.chartData.filter((item) => type === item.type);
|
||||
obj['data'] = chartArr.map((item) => item.value);
|
||||
obj['type'] = chartArr[0].seriesType;
|
||||
seriesData.push(obj);
|
||||
});
|
||||
option.series = seriesData;
|
||||
option.xAxis.data = xAxisData;
|
||||
setOptions(option);
|
||||
}
|
||||
return { chartRef };
|
||||
},
|
||||
};
|
||||
</script>
|
@ -4,6 +4,7 @@ import CustomImportExcel from './custom-import-excel';
|
||||
import CustomRichEditor from './custom-rich-editor';
|
||||
import CustomEchartBar from './custom-echart-bar';
|
||||
import CustomEchartPie from './custom-echart-pie';
|
||||
import CustomEchartMultiLine from './custom-echart-multi-line';
|
||||
import CustomEchartLine from './custom-echart-line';
|
||||
import CustomEchartMixin from './custom-echart-mixin';
|
||||
|
||||
export { SvgIcon, CustomTableOperate, CustomImportExcel, CustomRichEditor, CustomEchartBar, CustomEchartPie, CustomEchartMultiLine };
|
||||
export { SvgIcon, CustomTableOperate, CustomImportExcel, CustomRichEditor, CustomEchartBar, CustomEchartPie, CustomEchartLine, CustomEchartMixin };
|
||||
|
@ -3,7 +3,7 @@
|
||||
* @Author: zenghua.wang
|
||||
* @Date: 2023-06-20 11:48:41
|
||||
* @LastEditors: zenghua.wang
|
||||
* @LastEditTime: 2025-02-28 13:50:00
|
||||
* @LastEditTime: 2025-03-04 10:42:19
|
||||
*/
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import Layout from '@/layouts/index.vue';
|
||||
@ -12,7 +12,7 @@ import resourceRouter from './modules/resource';
|
||||
import plantingAndBreedingRouter from './modules/plantingAndBreeding';
|
||||
import landsRoutes from './modules/lands';
|
||||
import annualplanRoutes from './modules/annualplan';
|
||||
import statisticsRoutes from './modules/statistics';
|
||||
import statisticsRoutes from './modules/statisticAnalysis';
|
||||
import dictRoutes from './modules/dict';
|
||||
|
||||
export const constantRoutes = [
|
||||
|
@ -0,0 +1,32 @@
|
||||
import Layout from '@/layouts/index.vue';
|
||||
import Views from '@/layouts/Views.vue';
|
||||
|
||||
export default [
|
||||
{
|
||||
path: '/sub-government-affairs-service/analysis',
|
||||
name: 'analysis',
|
||||
component: Layout,
|
||||
redirect: '/sub-government-affairs-service/analysis-land',
|
||||
meta: { title: '统计分析', icon: 'icon-test' },
|
||||
children: [
|
||||
{
|
||||
path: '/sub-government-affairs-service/analysis-land',
|
||||
component: () => import('@/views/statisticAnalysis/land/index.vue'),
|
||||
name: 'analysis-land',
|
||||
meta: { title: '土地利用与规划分析', icon: 'Document' },
|
||||
},
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/analysis-agriculture',
|
||||
// name: 'analysis-agriculture',
|
||||
// component: () => import('@/views/statisticAnalysis/agriculture/index.vue'),
|
||||
// meta: { title: '农业生产效率分析', icon: 'Document' },
|
||||
// },
|
||||
// {
|
||||
// path: '/sub-government-affairs-service/analysis-environment',
|
||||
// name: 'analysis-environment',
|
||||
// component: () => import('@/views/statisticAnalysis/environment/index.vue'),
|
||||
// meta: { title: '环境影响与经济效益分析', icon: 'Document' },
|
||||
// },
|
||||
],
|
||||
},
|
||||
];
|
@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<el-upload
|
||||
ref="upload"
|
||||
class="upload-demo"
|
||||
:limit="props.limit"
|
||||
:auto-upload="false"
|
||||
:file-list="fileList"
|
||||
:on-change="fileChange"
|
||||
:before-remove="handleDelFile"
|
||||
>
|
||||
<el-button type="primary" :disabled="fileList.length == 5">点击上传</el-button>
|
||||
<template #tip>
|
||||
<div v-if="props.format.length" class="el-upload__tip">只能上传{{ props.format.join() }} 文件,且不超过20MB</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const emit = defineEmits(['update:list']);
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
limit: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
},
|
||||
format: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
});
|
||||
|
||||
/* --------------- data --------------- */
|
||||
// #region
|
||||
|
||||
const fileList = ref([]);
|
||||
watch(
|
||||
() => props.list,
|
||||
(val) => {
|
||||
fileList.value = val;
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
// #endregion
|
||||
|
||||
/* --------------- methods --------------- */
|
||||
// #region
|
||||
|
||||
function fileChange(file, list) {
|
||||
let formatReg = true;
|
||||
if (props.format.length > 0) {
|
||||
formatReg = props.format.includes(file.name.slice(file.name.lastIndexOf('.') + 1));
|
||||
}
|
||||
const fileSize = file.size / 1024 / 1024 < props.size;
|
||||
if (!formatReg) {
|
||||
ElMessage.error(`上传文件格式不正确,仅支持${props.format.join('/ ')}格式`);
|
||||
delAttr(file.uid, list);
|
||||
}
|
||||
if (!fileSize) {
|
||||
ElMessage.error(`上传文件大小不能超过${props.size}MB`);
|
||||
delAttr(file.uid, list);
|
||||
}
|
||||
fileList.value = list;
|
||||
}
|
||||
function handleDelFile(file) {
|
||||
delAttr(file.uid, fileList.value);
|
||||
}
|
||||
function delAttr(id, list = []) {
|
||||
if (!id || !list) return false;
|
||||
let i = list.findIndex((v) => v.uid == id);
|
||||
if (i < 0) return;
|
||||
else list.splice(i, 1);
|
||||
}
|
||||
// #endregion
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-dialog v-model="_visible" title="案件登记处理" append-to="#app" @close="handleClose">
|
||||
<el-dialog v-model="_visible" :width="800" title="案件登记处理" append-to="#app" @close="handleClose">
|
||||
<h3>案件信息></h3>
|
||||
<section class="case_info">
|
||||
<div v-for="item in info" :key="`${item.key}_box`" :style="{ '--w': item.line ? '100%' : 'calc(50% - 12px)' }">
|
||||
@ -7,14 +7,40 @@
|
||||
<div class="text">{{ item.value }}</div>
|
||||
</div>
|
||||
</section>
|
||||
<h3>案件处理></h3>
|
||||
<el-form></el-form>
|
||||
<h3>案件结果></h3>
|
||||
<el-form :model="form" label-width="140px">
|
||||
<h3>案件处理></h3>
|
||||
<el-form-item label="案情记录:" prop="record">
|
||||
<el-input v-model="form.record" type="textarea" placeholder="请输入"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="现场取证:(照片、视频)" label-width="200px"></el-form-item>
|
||||
<el-form-item label="执法文书:">
|
||||
<section>
|
||||
<el-radio-group v-model="form.document">
|
||||
<el-radio :value="0" label="协助调查函"></el-radio>
|
||||
<el-radio :value="1" label="抽样取样凭证"></el-radio>
|
||||
<el-radio :value="2" label="检测报告"></el-radio>
|
||||
<el-radio :value="3" label="其他文书"></el-radio>
|
||||
</el-radio-group>
|
||||
<FileUpload v-model:list="form.proof" />
|
||||
</section>
|
||||
</el-form-item>
|
||||
<h3>案件结果></h3>
|
||||
<el-form-item label="案件处理结果:" class="result_content">
|
||||
<el-radio-group v-model="form.result">
|
||||
<el-radio :value="0" label="正常营业,无违规行为"></el-radio>
|
||||
<el-radio :value="1" label="简易程序,当场行政处罚"></el-radio>
|
||||
<el-radio :value="2" label="普通程序,当场处罚立案审批"></el-radio>
|
||||
<el-radio :value="3" label="移送程序,案件移送"></el-radio>
|
||||
<el-radio :value="4" label="特殊程序,案件终止"></el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from 'vue';
|
||||
import FileUpload from './FileUpload.vue';
|
||||
|
||||
const emit = defineEmits(['update:visible']);
|
||||
const props = defineProps({
|
||||
@ -23,16 +49,21 @@ const props = defineProps({
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
watch(
|
||||
() => props.visible,
|
||||
(val) => {
|
||||
_visible.value = val;
|
||||
}
|
||||
);
|
||||
|
||||
/* --------------- data --------------- */
|
||||
// #region
|
||||
|
||||
const _visible = ref(false);
|
||||
watch(
|
||||
() => props.visible,
|
||||
(val) => {
|
||||
_visible.value = val;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
const info = reactive([
|
||||
{
|
||||
label: '案件名称',
|
||||
@ -76,7 +107,13 @@ const info = reactive([
|
||||
line: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const form = reactive({
|
||||
record: '',
|
||||
proof: [],
|
||||
document: 1,
|
||||
attrs: [],
|
||||
result: 1,
|
||||
});
|
||||
// #endregion
|
||||
|
||||
/* --------------- methods --------------- */
|
||||
@ -109,4 +146,12 @@ function handleClose() {
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep() {
|
||||
.result_content {
|
||||
.el-radio-group {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<CustomCard>
|
||||
<avue-crud
|
||||
ref="crudRef"
|
||||
v-model:page="page"
|
||||
v-model:search="searchData"
|
||||
:option="option"
|
||||
@ -10,29 +11,41 @@
|
||||
@size-change="handleSizeChange"
|
||||
@search-change="handleSearch"
|
||||
@row-save="handleRowSave"
|
||||
@row-update="handleExamine"
|
||||
>
|
||||
<template #menu="{ row }">
|
||||
<el-button type="primary" @click="handleInfo(row)">登记处理</el-button>
|
||||
</template>
|
||||
<template #sceneProof-form>
|
||||
<section>
|
||||
<span>(照片、视频)</span>
|
||||
</section>
|
||||
</template>
|
||||
<template #attrs_-form>
|
||||
<FileUpload v-model:list="examineForm.attrs" :format="['rar', 'zip', 'doc', 'docx', 'pdf']" />
|
||||
</template>
|
||||
</avue-crud>
|
||||
</CustomCard>
|
||||
<Register v-model:visible="caseInfo.visible" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { ref, reactive, h } from 'vue';
|
||||
import { CRUD_OPTIONS } from '@/config';
|
||||
import CustomCard from '@/components/CustomCard.vue';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
import Register from './common/Register.vue';
|
||||
import FileUpload from './common/FileUpload.vue';
|
||||
import { add } from 'lodash';
|
||||
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
const UserStore = useUserStore();
|
||||
|
||||
/* --------------- data --------------- */
|
||||
// #region
|
||||
const crudRef = ref();
|
||||
const searchData = ref({
|
||||
code: '',
|
||||
caseNum: '',
|
||||
process: '',
|
||||
});
|
||||
const page = ref({
|
||||
@ -43,8 +56,8 @@ const page = ref({
|
||||
const _loading = ref(false);
|
||||
const data = ref([
|
||||
{
|
||||
id: '1',
|
||||
code: '111111111',
|
||||
id_: '1',
|
||||
caseNum: '111111111',
|
||||
name: '张三',
|
||||
unit: '123333333333333333333333333333',
|
||||
owner: '张三',
|
||||
@ -52,8 +65,8 @@ const data = ref([
|
||||
date: '2020-02-02',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
code: '222222222',
|
||||
id_: '2',
|
||||
caseNum: '222222222',
|
||||
name: '张三',
|
||||
unit: '123333333333333333333333333333',
|
||||
owner: '张三',
|
||||
@ -61,8 +74,8 @@ const data = ref([
|
||||
date: '2020-02-02',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
code: '333333333333',
|
||||
id_: '3',
|
||||
caseNum: '333333333333',
|
||||
name: '张三',
|
||||
unit: '123333333333333333333333333333',
|
||||
owner: '张三',
|
||||
@ -73,19 +86,27 @@ const data = ref([
|
||||
const option = ref({
|
||||
...CRUD_OPTIONS,
|
||||
refreshBtn: false,
|
||||
editTitle: '案件登记处理',
|
||||
rowKey: 'id_',
|
||||
column: [
|
||||
{
|
||||
label: '案件编号',
|
||||
prop: 'code',
|
||||
prop: 'caseNum',
|
||||
search: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '案件名称',
|
||||
prop: 'name',
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '关联单位',
|
||||
prop: 'unit',
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '关联土地·',
|
||||
@ -107,25 +128,31 @@ const option = ref({
|
||||
authorization: UserStore.token,
|
||||
},
|
||||
dicFormatter: (res) => res?.data?.records ?? [],
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '联系电话',
|
||||
prop: 'phone',
|
||||
viewDisplay: true,
|
||||
// addDisplay: true,
|
||||
hide: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '法定代表人',
|
||||
prop: 'onwer',
|
||||
addDisplay: true,
|
||||
hide: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '统一社会信用代码',
|
||||
prop: 'code',
|
||||
addDisplay: true,
|
||||
hide: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '违法情况',
|
||||
@ -135,12 +162,16 @@ const option = ref({
|
||||
hide: true,
|
||||
width: '100%',
|
||||
span: 24,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '负责人',
|
||||
prop: 'owner',
|
||||
display: false,
|
||||
addDisplay: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '案件进度',
|
||||
@ -148,12 +179,16 @@ const option = ref({
|
||||
display: false,
|
||||
search: true,
|
||||
addDisplay: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '案件结果',
|
||||
prop: 'result',
|
||||
display: false,
|
||||
addDisplay: true,
|
||||
editDisplay: false,
|
||||
viewDisplay: false,
|
||||
},
|
||||
{
|
||||
label: '处理时间',
|
||||
@ -161,12 +196,178 @@ const option = ref({
|
||||
display: false,
|
||||
addDisplay: false,
|
||||
editDisplay: true,
|
||||
viewDisplay: false,
|
||||
},
|
||||
],
|
||||
group: [
|
||||
{
|
||||
label: '案件信息>',
|
||||
prop: 'caseInfo',
|
||||
addDisplay: false,
|
||||
column: [
|
||||
{
|
||||
label: '案件名称',
|
||||
prop: 'name',
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.name);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '案件编号',
|
||||
prop: 'caseNum',
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.caseNum);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '关联单位',
|
||||
prop: 'unit',
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.unit);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '关联地块',
|
||||
prop: 'land',
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.land);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '法定代表人',
|
||||
prop: 'onwer',
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.onwer);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '联系电话',
|
||||
prop: 'phone',
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.phone);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '统一社会信用代码',
|
||||
prop: 'code',
|
||||
span: 24,
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.code);
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '违法情况',
|
||||
prop: 'result',
|
||||
span: 24,
|
||||
render: ({ row }) => {
|
||||
return h('span', {}, row.result);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '案件处理>',
|
||||
prop: 'caseHandle',
|
||||
addDisplay: false,
|
||||
column: [
|
||||
{
|
||||
label: '案情记录',
|
||||
prop: 'caseRecords',
|
||||
type: 'textarea',
|
||||
span: 24,
|
||||
display: true,
|
||||
editDisplay: true,
|
||||
},
|
||||
{
|
||||
label: '现场取证',
|
||||
prop: 'sceneProof',
|
||||
span: 24,
|
||||
display: true,
|
||||
editDisplay: true,
|
||||
},
|
||||
{
|
||||
label: '执法文书',
|
||||
prop: 'document',
|
||||
labelSuffix: '件',
|
||||
span: 24,
|
||||
display: true,
|
||||
type: 'radio',
|
||||
editDisplay: true,
|
||||
dicData: [
|
||||
{
|
||||
label: '协助调查函',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '抽样取样凭证',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '检测报告',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '其他文书',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
prop: 'attrs_',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '处理结果>',
|
||||
prop: 'caseResult_',
|
||||
addDisplay: false,
|
||||
column: [
|
||||
{
|
||||
label: '案件处理结果',
|
||||
prop: 'caseResult',
|
||||
type: 'radio',
|
||||
value: 0,
|
||||
dicData: [
|
||||
{
|
||||
label: '正常营业,无违规行为',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '简易程序,当场行政处罚',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '普通程序,当场处罚立案审批',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '移送程序,案件移送',
|
||||
value: 3,
|
||||
},
|
||||
{
|
||||
label: '特殊程序,案件终止',
|
||||
value: 4,
|
||||
},
|
||||
],
|
||||
span: 24,
|
||||
display: true,
|
||||
editDisplay: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
const caseInfo = ref({
|
||||
visible: false,
|
||||
});
|
||||
const examineForm = reactive({
|
||||
record: '',
|
||||
proof: [],
|
||||
document: 1,
|
||||
attrs: [],
|
||||
result: 1,
|
||||
});
|
||||
// #endregion
|
||||
|
||||
/* --------------- methods --------------- */
|
||||
@ -182,7 +383,9 @@ function handleSizeChange(val) {
|
||||
}
|
||||
function handleInfo(row) {
|
||||
console.log('row', row);
|
||||
caseInfo.value.visible = true;
|
||||
// caseInfo.value.visible = true;
|
||||
crudRef.value.rowEdit(row);
|
||||
// crudRef.value.rowView(row);
|
||||
}
|
||||
function handleSearch(form, done) {
|
||||
console.log('search', form);
|
||||
@ -201,7 +404,22 @@ function handleRowSave(val, done, loading) {
|
||||
done();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function handleExamine(val, done, loading) {
|
||||
console.log('val', val);
|
||||
console.log('done', done);
|
||||
console.log('loading', loading);
|
||||
loading();
|
||||
}
|
||||
// #endregion
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
::v-deep() {
|
||||
.attrs_ {
|
||||
.el-form-item__label {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,284 +0,0 @@
|
||||
<template>
|
||||
<el-drawer v-model="_visible" title="土地信息" :size="800" @close="handleClose">
|
||||
<el-card>
|
||||
<div class="title_">基础信息</div>
|
||||
<el-form ref="baseForm" :model="baseInfo" :disabled="props.rowData.isDetails" class="base_form" label-width="120px" :rules="rules">
|
||||
<el-form-item label="土地名称" prop="landName">
|
||||
<el-input v-model="baseInfo.landName" placeholder="请输入名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属网格" prop="gridId">
|
||||
<CustomSelect
|
||||
v-model:value="baseInfo.gridId"
|
||||
:set="{
|
||||
url: '/land-resource/gridManage/page',
|
||||
props: {
|
||||
value: 'id',
|
||||
label: 'gridName',
|
||||
},
|
||||
}"
|
||||
placeholder="请选择所属网格"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用地分类" prop="landClassificationType">
|
||||
<LandClassificationType v-model:value="baseInfo.landClassificationType" placeholder="请选择用地分类" />
|
||||
</el-form-item>
|
||||
<el-form-item label="位置" prop="villageCode">
|
||||
<el-input v-model="baseInfo.villageCode" placeholder="请输入"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否土地流转" prop="isTransfer">
|
||||
<LandIsTransfer v-model:value="baseInfo.isTransfer" />
|
||||
</el-form-item>
|
||||
<el-form-item label="面积" prop="area">
|
||||
<el-input v-model="baseInfo.area" placeholder="请输入面积"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="产权人" prop="owner">
|
||||
<el-input v-model="baseInfo.owner" placeholder="请输入产权人姓名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="土壤类型">
|
||||
<el-input v-model="baseInfo.soilType" placeholder="请输入土壤类型"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<br />
|
||||
<el-card>
|
||||
<div class="title_">土地产权信息</div>
|
||||
<el-form ref="propertyForm" :model="propertyInfo" :disabled="props.rowData.isDetails" class="property_form" label-width="120px">
|
||||
<el-form-item label="产权人姓名" prop="propertyName">
|
||||
<el-input v-model="propertyInfo.propertyName" placeholder="请输入联系人"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="产权人联系电话" prop="propertyPhone">
|
||||
<el-input v-model="propertyInfo.propertyPhone" placeholder="请输入联系人"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="产权编号" prop="landCode" class="land_code">
|
||||
<el-input v-model="propertyInfo.landCode" placeholder="请输入联系人"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="产权证书" prop="propertyCertificateUrl" class="attrs_content">
|
||||
<el-upload class="custom-form__uploader" action="#" :show-file-list="false" accept="image/*" :limit="20" :http-request="rowUploadPicture">
|
||||
<el-icon class="custom-form__uploader__icon"><Plus /></el-icon>
|
||||
</el-upload>
|
||||
<div v-for="item in propertyInfo.propertyCertificateUrl" :key="`attr_${item.id}`" class="attrs_content__item">
|
||||
<img :src="item.url" :alt="item.name" style="width: 100%; height: 100%" />
|
||||
<el-icon class="clear_btn" @click="handleClearAttr(item.id)"><CircleCloseFilled /></el-icon>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<section class="btns">
|
||||
<el-button type="primary" :disabled="props.rowData.isDetails" @click="handleSubmit">保存并提交审核</el-button>
|
||||
<!-- <el-button type="warning" :disabled="props.rowData.info" @click="handleSubmit">保存草稿</el-button> -->
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
</section>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue';
|
||||
import LandClassificationType from '@/components/LandClassificationType.vue';
|
||||
import CustomSelect from '@/components/CustomSelect.vue';
|
||||
import LandIsTransfer from '@/components/LandIsTransfer.vue';
|
||||
import { saveLand } from '@/apis/land';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { CommonUpload } from '@/apis';
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
landType: {
|
||||
type: String,
|
||||
default: '0',
|
||||
},
|
||||
rowData: {
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['close']);
|
||||
/* --------------- data --------------- */
|
||||
// #region
|
||||
|
||||
const _visible = ref(false);
|
||||
const editId = ref(null);
|
||||
const baseInfo = reactive({
|
||||
landName: '',
|
||||
gridId: '',
|
||||
landClassificationType: '',
|
||||
villageCode: '',
|
||||
isTransfer: '1',
|
||||
area: '',
|
||||
owner: '',
|
||||
soilType: '',
|
||||
});
|
||||
const propertyInfo = reactive({
|
||||
propertyName: '',
|
||||
propertyPhone: '',
|
||||
landCode: '',
|
||||
propertyCertificateUrl: [],
|
||||
});
|
||||
watch(
|
||||
() => props.visible,
|
||||
() => {
|
||||
_visible.value = props.visible;
|
||||
if (!props.rowData.id) {
|
||||
editId.value = props.rowData.id;
|
||||
} else {
|
||||
for (let key in baseInfo) {
|
||||
baseInfo[key] = props.rowData[key];
|
||||
}
|
||||
baseInfo.isTransfer = props.rowData.landTransfer || '0';
|
||||
for (let key in propertyInfo) {
|
||||
propertyInfo[key] = props.rowData[key];
|
||||
}
|
||||
if (propertyInfo.propertyCertificateUrl) {
|
||||
propertyInfo.propertyCertificateUrl = props.rowData.propertyCertificateUrl.map((item, i) => {
|
||||
return {
|
||||
url: item.url,
|
||||
id: `id_${i}_${Date.now()}`,
|
||||
name: item.name || `name_${i}_${Date.now()}`,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => baseInfo,
|
||||
() => {
|
||||
console.log('---', baseInfo);
|
||||
}
|
||||
);
|
||||
const baseForm = ref();
|
||||
const propertyForm = ref();
|
||||
const rules = reactive({
|
||||
landName: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
||||
gridId: [{ required: true, message: '请选择所属网格', trigger: 'blur' }],
|
||||
landClassificationType: [{ required: true, message: '请选择用地分类', trigger: 'blur' }],
|
||||
villageCode: [{ required: true, message: '请输入位置', trigger: 'blur' }],
|
||||
});
|
||||
// #endregion
|
||||
|
||||
/* --------------- methods --------------- */
|
||||
// #region
|
||||
const rowUploadPicture = async ({ file }) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
const res = await CommonUpload(formData);
|
||||
if (res.code === 200) {
|
||||
propertyInfo.propertyCertificateUrl.push({
|
||||
...res.data,
|
||||
id: 'id_' + Date.now(),
|
||||
});
|
||||
console.log('---', res);
|
||||
// state.form.productUrl = res.data.url;
|
||||
// const base64 = await imageToBase64(file);
|
||||
// state.form.base64 = base64;
|
||||
}
|
||||
};
|
||||
function handleClearAttr(id) {
|
||||
propertyInfo.propertyCertificateUrl = propertyInfo.propertyCertificateUrl.filter((item) => item.id !== id);
|
||||
}
|
||||
async function handleSubmit() {
|
||||
baseForm.value.validate().then(async () => {
|
||||
const data = {
|
||||
...baseInfo,
|
||||
...propertyInfo,
|
||||
isDraftsSave: 0,
|
||||
landType: props.landType,
|
||||
};
|
||||
let ids = [];
|
||||
propertyInfo.propertyCertificateUrl.map((item) => ids.push(item.url));
|
||||
data.propertyCertificateUrl = ids.join();
|
||||
editId.value && (data.id = editId.value);
|
||||
const res = await saveLand(data);
|
||||
if (res.code == 200) {
|
||||
ElMessage.success('保存成功');
|
||||
resFrom();
|
||||
}
|
||||
});
|
||||
}
|
||||
function handleClose() {
|
||||
resFrom();
|
||||
emit('close');
|
||||
}
|
||||
function resFrom() {
|
||||
baseForm.value.resetFields();
|
||||
propertyForm.value.resetFields();
|
||||
for (let key in baseInfo) {
|
||||
baseInfo[key] = '';
|
||||
}
|
||||
for (let key in propertyInfo) {
|
||||
propertyInfo[key] = '';
|
||||
}
|
||||
propertyInfo.propertyCertificateUrl = [];
|
||||
}
|
||||
|
||||
// #endregion
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.title_ {
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.base_form,
|
||||
.property_form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
.btns {
|
||||
margin-top: 12px;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
grid-template-columns: auto auto auto;
|
||||
gap: 12px;
|
||||
}
|
||||
.attrs_content__item {
|
||||
position: relative;
|
||||
padding: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
img {
|
||||
border-radius: 2px;
|
||||
}
|
||||
.clear_btn {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
font-size: 18px;
|
||||
color: #f15c5c;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
background-color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&:hover {
|
||||
.clear_btn {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
::v-deep() {
|
||||
.land_code {
|
||||
.el-form-item__content {
|
||||
align-items: baseline;
|
||||
}
|
||||
}
|
||||
.attrs_content {
|
||||
.el-form-item__content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
> div {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -13,6 +13,7 @@
|
||||
:data="data"
|
||||
:option="option"
|
||||
:before-close="handleCloseFrom"
|
||||
:table-loading="loading"
|
||||
@current-change="handlePageChange"
|
||||
@size-change="handleSizeChange"
|
||||
@search-reset="handleResetSearch"
|
||||
@ -61,9 +62,7 @@ import { useUserStore } from '@/store/modules/user';
|
||||
import { getLandsList, exportLands, delLand, saveLand, importLands } from '@/apis/land.js';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import useLandHook from './useLandHook';
|
||||
import { CommonUpload } from '@/apis';
|
||||
import Attrs from './common/Attrs.vue';
|
||||
import { add } from 'lodash';
|
||||
|
||||
const { landType, landsType, landClassificationType, handleIficationType } = useLandHook();
|
||||
const { VITE_APP_BASE_API } = import.meta.env;
|
||||
@ -79,8 +78,9 @@ const local_ = ref([102.833669, 24.88149, '昆明市']);
|
||||
const local = ref(JSON.parse(JSON.stringify(local_.value)));
|
||||
/* --------------- data --------------- */
|
||||
// #region
|
||||
const loading = ref(false);
|
||||
const crudRef = ref();
|
||||
const pageData = reactive({
|
||||
const pageData = ref({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
@ -88,8 +88,8 @@ const pageData = reactive({
|
||||
const data = ref([]);
|
||||
const option = reactive({
|
||||
...CRUD_OPTIONS,
|
||||
selection: false,
|
||||
menuWidth: 120,
|
||||
selection: false,
|
||||
column: [
|
||||
{
|
||||
label: '地块名',
|
||||
@ -375,30 +375,33 @@ const rowData = ref([]);
|
||||
// #region
|
||||
|
||||
async function getList() {
|
||||
loading.value = true;
|
||||
const params = {
|
||||
current: pageData.currentPage,
|
||||
size: pageData.pageSize,
|
||||
current: pageData.value.currentPage,
|
||||
size: pageData.value.pageSize,
|
||||
landType: landType.value,
|
||||
...searchData,
|
||||
};
|
||||
let res = await getLandsList(params);
|
||||
loading.value = false;
|
||||
if (res.code == 200) {
|
||||
data.value = res.data.records;
|
||||
const { total, records } = res.data;
|
||||
data.value = records;
|
||||
data.value.forEach((v) => {
|
||||
v.isTransfer = v.landTransfer || 1;
|
||||
v.isTransferView = v.landTransfer == 1 ? '否' : '是';
|
||||
v.landClassificationTypeView = handleIficationType(v.handleIficationType);
|
||||
v.coordinateView = v.coordinate;
|
||||
});
|
||||
pageData.total = res.data.total;
|
||||
pageData.value.total = total;
|
||||
}
|
||||
}
|
||||
function handlePageChange(val) {
|
||||
pageData.currentPage = val;
|
||||
pageData.value.currentPage = val;
|
||||
getList();
|
||||
}
|
||||
function handleSizeChange(val) {
|
||||
pageData.pageSize = val;
|
||||
pageData.value.pageSize = val;
|
||||
getList();
|
||||
}
|
||||
async function handleSearch(form, done) {
|
||||
@ -412,9 +415,9 @@ async function handleResetSearch() {
|
||||
for (let key in searchData) {
|
||||
searchData[key] = '';
|
||||
}
|
||||
pageData.currentPage = 1;
|
||||
pageData.pageSize = 10;
|
||||
pageData.total = 0;
|
||||
pageData.value.currentPage = 1;
|
||||
pageData.value.pageSize = 10;
|
||||
pageData.value.total = 0;
|
||||
await getList();
|
||||
}
|
||||
const attrNames = reactive(landsType.map((v) => v.label));
|
||||
|
@ -0,0 +1,185 @@
|
||||
<template>
|
||||
<div class="analysis">
|
||||
<!-- <h3 class="analysis-title">土地利用与规划分析</h3> -->
|
||||
<el-row :gutter="16" style="margin-bottom: 10px">
|
||||
<el-col :span="12">
|
||||
<el-card shadow="hover">
|
||||
<custom-echart-pie :chart-data="state.landData" height="460px" :option="state.landOption" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card shadow="hover">
|
||||
<custom-echart-bar :chart-data="state.cropData" height="460px" :option="state.cropOption" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="24">
|
||||
<el-card shadow="hover">
|
||||
<custom-echart-line :chart-data="state.landTrendData" height="500px" :option="state.landTrendOption" type="line" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive } from 'vue';
|
||||
|
||||
const state = reactive({
|
||||
landOption: {
|
||||
color: ['#3685fe', '#41b879', '#ffd500'],
|
||||
title: {
|
||||
text: '土地用途分析',
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['耕地', '林地', '建设用地'],
|
||||
},
|
||||
label: {
|
||||
color: '#333',
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: [80, 140],
|
||||
roseType: 'area',
|
||||
itemStyle: {
|
||||
borderRadius: 20,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
landData: [
|
||||
{ value: 100, name: '耕地' },
|
||||
{ value: 105, name: '林地' },
|
||||
{ value: 217, name: '建设用地' },
|
||||
],
|
||||
cropOption: {
|
||||
title: {
|
||||
text: '作物种植结构',
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['土豆', '西红柿', '玉米', '花生', '水稻'],
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '面积(亩)',
|
||||
// splitLine: {
|
||||
// show: false,
|
||||
// },
|
||||
},
|
||||
barStyle: {
|
||||
// barWidth: 50,
|
||||
showBackground: true,
|
||||
itemStyle: {
|
||||
borderRadius: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
cropData: [
|
||||
{ value: 230, name: '土豆' },
|
||||
{ value: 165, name: '西红柿' },
|
||||
{ value: 217, name: '玉米' },
|
||||
{ value: 200, name: '花生' },
|
||||
{ value: 305, name: '水稻' },
|
||||
],
|
||||
landTrendOption: {
|
||||
color: ['#3685fe', '#41b879', '#ffd500'],
|
||||
title: {
|
||||
text: '土地变更趋势',
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
},
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
name: '年份',
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
name: '面积(亩)',
|
||||
// splitLine: {
|
||||
// show: false,
|
||||
// },
|
||||
},
|
||||
},
|
||||
landTrendData: [
|
||||
{
|
||||
type: '耕地',
|
||||
value: 40,
|
||||
name: '2022',
|
||||
},
|
||||
{
|
||||
type: '林地',
|
||||
value: 146,
|
||||
name: '2022',
|
||||
},
|
||||
{
|
||||
type: '建设用地',
|
||||
value: 81,
|
||||
name: '2022',
|
||||
},
|
||||
{
|
||||
type: '耕地',
|
||||
value: 60,
|
||||
name: '2023',
|
||||
},
|
||||
{
|
||||
type: '林地',
|
||||
value: 186,
|
||||
name: '2023',
|
||||
},
|
||||
{
|
||||
type: '建设用地',
|
||||
value: 101,
|
||||
name: '2023',
|
||||
},
|
||||
{
|
||||
type: '耕地',
|
||||
value: 230,
|
||||
name: '2024',
|
||||
},
|
||||
{
|
||||
type: '林地',
|
||||
value: 256,
|
||||
name: '2024',
|
||||
},
|
||||
{
|
||||
type: '建设用地',
|
||||
value: 301,
|
||||
name: '2024',
|
||||
},
|
||||
{
|
||||
type: '耕地',
|
||||
value: 160,
|
||||
name: '2025',
|
||||
},
|
||||
{
|
||||
type: '林地',
|
||||
value: 286,
|
||||
name: '2025',
|
||||
},
|
||||
{
|
||||
type: '建设用地',
|
||||
value: 161,
|
||||
name: '2025',
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.analysis {
|
||||
&-title {
|
||||
font-size: 20px;
|
||||
color: #000;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
x
Reference in New Issue
Block a user