Merge pull request 'refactor(sub-government-affairs-service): 重构新增网格' (#4) from 新增网格重构 into dev
Reviewed-on: #4
This commit is contained in:
commit
2a7d36761d
@ -0,0 +1,43 @@
|
|||||||
|
import request from '@/utils/axios';
|
||||||
|
|
||||||
|
// 新增(POST)
|
||||||
|
export function createGrid(data = {}) {
|
||||||
|
return request('/land-resource/gridManage/save', {
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 删除(DELETE)
|
||||||
|
export function deleteGrid(id) {
|
||||||
|
return request(`/land-resource/gridManage/${id}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 修改(PUT)
|
||||||
|
export function updateGrid(data = {}) {
|
||||||
|
return request('//land-resource/gridManage/edit', {
|
||||||
|
method: 'PUT',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 查询列表(GET)
|
||||||
|
export function fetchGridList(params) {
|
||||||
|
return request('/land-resource/gridManage/page', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 获取详情(GET)
|
||||||
|
export function getGridDetail(id) {
|
||||||
|
return request(`/land-resource/gridManage/${id}`, {
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 导出(GET + Blob)
|
||||||
|
export function exportGrid(params = {}) {
|
||||||
|
return request('/land-resource/gridManage/export', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
responseType: 'blob',
|
||||||
|
});
|
||||||
|
}
|
@ -1,40 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="area-cascader-container" :style="{ width: width + 'px' }">
|
<div class="area-cascader-container" :style="containerStyle">
|
||||||
<!-- 一行显示模式 -->
|
<!-- 一行显示模式 -->
|
||||||
<template v-if="!splitRows">
|
<template v-if="!splitRows">
|
||||||
<div v-if="label" class="area-cascader-label">{{ label }}</div>
|
<div v-if="label" class="area-cascader-label">{{ label }}</div>
|
||||||
<div style="display: flex; gap: 8px; flex: 1">
|
<div class="controls">
|
||||||
<el-cascader
|
<el-cascader v-model="regionModel" :options="areaOptions" :props="cascaderProps" :placeholder="areaPlaceholder" style="flex: 1" clearable />
|
||||||
v-model="selectedAreaCode"
|
|
||||||
:options="areaOptions"
|
|
||||||
:props="cascaderProps"
|
|
||||||
:placeholder="areaPlaceholder"
|
|
||||||
style="flex: 1"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
<span v-if="showSeparator" class="area-cascader-separator">{{ separator }}</span>
|
<span v-if="showSeparator" class="area-cascader-separator">{{ separator }}</span>
|
||||||
<el-select v-model="selectedGridId" :placeholder="gridPlaceholder" style="flex: 1" clearable :disabled="!selectedAreaCode">
|
<el-select v-model="gridModel" :placeholder="gridPlaceholder" style="flex: 1" :disabled="!regionModel" clearable>
|
||||||
<el-option v-for="item in gridOptions" :key="item.gridName" :label="item.gridName" :value="item.id" />
|
<el-option v-for="item in gridOptions" :key="item.id" :label="item.gridName" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 两行显示模式 -->
|
<!-- 两行显示模式 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="area-item">
|
<div class="area-item">
|
||||||
<div class="area-cascader-label">所属行政区域</div>
|
<div class="area-cascader-label">所属行政区域</div>
|
||||||
<el-cascader
|
<el-cascader v-model="regionModel" :options="areaOptions" :props="cascaderProps" :placeholder="areaPlaceholder" clearable />
|
||||||
v-model="selectedAreaCode"
|
|
||||||
:options="areaOptions"
|
|
||||||
:props="cascaderProps"
|
|
||||||
:placeholder="areaPlaceholder"
|
|
||||||
style="flex: 1"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="area-item">
|
<div class="area-item">
|
||||||
<div class="area-cascader-label">网格</div>
|
<div class="area-cascader-label">网格</div>
|
||||||
<el-select v-model="selectedGridId" :placeholder="gridPlaceholder" style="flex: 1" clearable :disabled="!selectedAreaCode">
|
<el-select v-model="gridModel" :placeholder="gridPlaceholder" :disabled="!regionModel" clearable>
|
||||||
<el-option v-for="item in gridOptions" :key="item.gridName" :label="item.gridName" :value="item.id" />
|
<el-option v-for="item in gridOptions" :key="item.id" :label="item.gridName" :value="item.id" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -42,152 +29,49 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, onMounted, computed } from 'vue';
|
import { ref, onMounted, computed } from 'vue';
|
||||||
import { ElCascader, ElSelect, ElOption } from 'element-plus';
|
|
||||||
import request from '@/utils/axios';
|
import request from '@/utils/axios';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
regionCode: {
|
regionCode: { type: String, default: '' },
|
||||||
type: String,
|
gridId: { type: [String, Number], default: '' },
|
||||||
default: '',
|
label: { type: String, default: '行政区域-网格:' },
|
||||||
},
|
areaPlaceholder: { type: String, default: '请选择区域' },
|
||||||
gridId: {
|
gridPlaceholder: { type: String, default: '请选择网格' },
|
||||||
type: [String, Number],
|
width: { type: [Number, String], default: 500 },
|
||||||
default: '',
|
showSeparator: { type: Boolean, default: false },
|
||||||
},
|
separator: { type: String, default: '-' },
|
||||||
label: {
|
splitRows: { type: Boolean, default: false },
|
||||||
type: String,
|
|
||||||
default: '行政区域-网格:',
|
|
||||||
},
|
|
||||||
areaPlaceholder: {
|
|
||||||
type: String,
|
|
||||||
default: '请选择区域',
|
|
||||||
},
|
|
||||||
gridPlaceholder: {
|
|
||||||
type: String,
|
|
||||||
default: '请选择网格',
|
|
||||||
},
|
|
||||||
width: {
|
|
||||||
type: [Number, String],
|
|
||||||
default: 500,
|
|
||||||
},
|
|
||||||
showSeparator: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
separator: {
|
|
||||||
type: String,
|
|
||||||
default: '-',
|
|
||||||
},
|
|
||||||
splitRows: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:regionCode', 'update:gridId']);
|
const emit = defineEmits(['update:regionCode', 'update:gridId']);
|
||||||
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const areaOptions = ref([]);
|
const areaOptions = ref([]);
|
||||||
const gridOptions = ref([]);
|
const gridOptions = ref([]);
|
||||||
|
|
||||||
// 本地绑定值
|
// computed 双向绑定 regionModel & gridModel
|
||||||
const selectedAreaCode = ref(props.regionCode);
|
const regionModel = computed({
|
||||||
const selectedGridId = ref(props.gridId);
|
get() {
|
||||||
|
return props.regionCode;
|
||||||
// 获取行政区域数据
|
|
||||||
const fetchAreaData = async () => {
|
|
||||||
try {
|
|
||||||
// 使用 request 发起请求,将查询参数放在 params 中
|
|
||||||
const res = await request.get('/system/area/region', {
|
|
||||||
params: {
|
|
||||||
areaCode: '530000',
|
|
||||||
},
|
},
|
||||||
});
|
set(val) {
|
||||||
areaOptions.value = res.data ?? [];
|
|
||||||
} catch (err) {
|
|
||||||
console.error('区域数据加载失败', err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取网格列表
|
|
||||||
const fetchGridList = async (regionCode) => {
|
|
||||||
if (!regionCode) return;
|
|
||||||
try {
|
|
||||||
// 使用 request 发起请求,将查询参数放在 params 中
|
|
||||||
const res = await request.get('/land-resource/gridManage/page', {
|
|
||||||
params: {
|
|
||||||
regionCode: regionCode,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
gridOptions.value = res.data?.records ?? [];
|
|
||||||
} catch (err) {
|
|
||||||
console.error('网格数据加载失败', err);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const selectedAreaLabel = computed(() => {
|
|
||||||
const findLabel = (options, code) => {
|
|
||||||
for (const item of options) {
|
|
||||||
if (item.areaCode === code) return item.areaName;
|
|
||||||
if (item.areaChildVOS?.length) {
|
|
||||||
const res = findLabel(item.areaChildVOS, code);
|
|
||||||
if (res) return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
};
|
|
||||||
return findLabel(areaOptions.value, selectedAreaCode.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
const selectedGridLabel = computed(() => {
|
|
||||||
const item = gridOptions.value.find((g) => g.id === selectedGridId.value);
|
|
||||||
return item?.gridName || '';
|
|
||||||
});
|
|
||||||
|
|
||||||
// 外部更新时同步内部
|
|
||||||
watch(
|
|
||||||
() => props.regionCode,
|
|
||||||
(val) => {
|
|
||||||
selectedAreaCode.value = val;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.gridId,
|
|
||||||
(val) => {
|
|
||||||
selectedGridId.value = val;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// 内部更新时同步外部
|
|
||||||
watch(selectedAreaCode, (val) => {
|
|
||||||
emit('update:regionCode', val);
|
emit('update:regionCode', val);
|
||||||
selectedGridId.value = ''; // 重置 gridId
|
// reset grid when region changes
|
||||||
emit('update:gridId', '');
|
emit('update:gridId', '');
|
||||||
|
gridOptions.value = [];
|
||||||
fetchGridList(val);
|
fetchGridList(val);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
const gridModel = computed({
|
||||||
watch(selectedGridId, (val) => {
|
get() {
|
||||||
|
return props.gridId;
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
emit('update:gridId', val);
|
emit('update:gridId', val);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 更新外部 v-model:value
|
|
||||||
// const updateValue = () => {
|
|
||||||
// console.log('update:value更新外部值', selectedAreaCode.value, selectedGridName.value, selectedGridId.value);
|
|
||||||
// emit('update:value', {
|
|
||||||
// regionCode: selectedAreaCode.value,
|
|
||||||
// gridName: selectedGridName.value,
|
|
||||||
// gridId: selectedGridId.value,
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
fetchAreaData();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 自定义字段映射
|
|
||||||
const cascaderProps = computed(() => ({
|
const cascaderProps = computed(() => ({
|
||||||
label: 'areaName',
|
label: 'areaName',
|
||||||
value: 'areaCode',
|
value: 'areaCode',
|
||||||
@ -195,37 +79,61 @@ const cascaderProps = computed(() => ({
|
|||||||
emitPath: false,
|
emitPath: false,
|
||||||
expandTrigger: 'hover',
|
expandTrigger: 'hover',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
async function fetchAreaData() {
|
||||||
|
try {
|
||||||
|
const res = await request.get('/system/area/region', { params: { areaCode: '530000' } });
|
||||||
|
areaOptions.value = res.data || [];
|
||||||
|
} catch (err) {
|
||||||
|
console.error('区域数据加载失败', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function fetchGridList(regionCode) {
|
||||||
|
if (!regionCode) return;
|
||||||
|
try {
|
||||||
|
const res = await request.get('/land-resource/gridManage/page', { params: { regionCode } });
|
||||||
|
gridOptions.value = res.data?.records || [];
|
||||||
|
} catch (err) {
|
||||||
|
console.error('网格数据加载失败', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(fetchAreaData);
|
||||||
|
|
||||||
|
// 样式计算
|
||||||
|
const containerStyle = computed(() => ({
|
||||||
|
width: typeof props.width === 'number' ? `${props.width}px` : props.width,
|
||||||
|
display: 'flex',
|
||||||
|
gap: '18px',
|
||||||
|
flexDirection: props.splitRows ? 'column' : 'row',
|
||||||
|
}));
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.area-cascader-container {
|
.area-cascader-container {
|
||||||
display: flex;
|
|
||||||
gap: 18px;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
/* 分行显示时垂直排列 */
|
|
||||||
flex-direction: v-bind('splitRows ? "column" : "row"');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.area-cascader-label {
|
.area-cascader-label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
line-height: 32px;
|
line-height: 32px;
|
||||||
box-sizing: border-box;
|
|
||||||
width: 120px;
|
width: 120px;
|
||||||
padding-right: v-bind('splitRows ? "12px" : "0"');
|
|
||||||
}
|
}
|
||||||
|
.controls {
|
||||||
.area-cascader-separator {
|
display: flex;
|
||||||
align-self: center;
|
gap: 8px;
|
||||||
font-size: 16px;
|
flex: 1;
|
||||||
color: #606266;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
.area-item {
|
.area-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.area-cascader-separator {
|
||||||
|
align-self: center;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #606266;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -24,7 +24,7 @@ const props = defineProps({
|
|||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Array,
|
type: [Array, String],
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
label: {
|
label: {
|
||||||
@ -39,6 +39,10 @@ const props = defineProps({
|
|||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 500,
|
default: 500,
|
||||||
},
|
},
|
||||||
|
emitPath: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
@ -46,14 +50,35 @@ const emit = defineEmits(['update:modelValue']);
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
const areaOptions = ref([]);
|
const areaOptions = ref([]);
|
||||||
const selectedAreaPath = ref([...props.modelValue]);
|
|
||||||
|
// 检查计算属性有没有循环依赖用
|
||||||
|
// const selectedAreaPath = props.emitPath ? ref([].concat(props.modelValue)) : ref(props.modelValue);
|
||||||
|
|
||||||
|
const selectedAreaPath = computed({
|
||||||
|
get() {
|
||||||
|
// 初始回显 & 外部变更都走这里
|
||||||
|
if (props.emitPath) {
|
||||||
|
return Array.isArray(props.modelValue) ? props.modelValue : [];
|
||||||
|
} else {
|
||||||
|
return typeof props.modelValue === 'string' ? props.modelValue : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
// 组件内部选中时走这里
|
||||||
|
if (props.emitPath) {
|
||||||
|
emit('update:modelValue', Array.isArray(val) ? val : []);
|
||||||
|
} else {
|
||||||
|
emit('update:modelValue', typeof val === 'string' ? val : '');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// 自定义字段映射
|
// 自定义字段映射
|
||||||
const cascaderProps = computed(() => ({
|
const cascaderProps = computed(() => ({
|
||||||
label: 'areaName',
|
label: 'areaName',
|
||||||
value: 'areaCode',
|
value: 'areaCode',
|
||||||
children: 'areaChildVOS',
|
children: 'areaChildVOS',
|
||||||
emitPath: true,
|
emitPath: props.emitPath,
|
||||||
expandTrigger: 'hover',
|
expandTrigger: 'hover',
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -70,7 +95,7 @@ const fetchAreaData = async () => {
|
|||||||
console.error('加载行政区域失败', err);
|
console.error('加载行政区域失败', err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// !!!禁止使用外部更新,会造成循环依赖
|
||||||
// // 外部更新 => 内部同步
|
// // 外部更新 => 内部同步
|
||||||
// watch(
|
// watch(
|
||||||
// () => props.modelValue,
|
// () => props.modelValue,
|
||||||
@ -80,9 +105,19 @@ const fetchAreaData = async () => {
|
|||||||
// );
|
// );
|
||||||
|
|
||||||
// 内部更新 => 外部同步
|
// 内部更新 => 外部同步
|
||||||
watch(selectedAreaPath, (val) => {
|
watch(
|
||||||
emit('update:modelValue', val);
|
selectedAreaPath,
|
||||||
});
|
(val) => {
|
||||||
|
if (props.emitPath) {
|
||||||
|
// 期望数组模式,确保输出数组
|
||||||
|
emit('update:modelValue', Array.isArray(val) ? val : []);
|
||||||
|
} else {
|
||||||
|
// 期望字符串模式,确保输出字符串
|
||||||
|
emit('update:modelValue', typeof val === 'string' ? val : '');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchAreaData();
|
fetchAreaData();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
:auto-upload="true"
|
:auto-upload="true"
|
||||||
:disabled="readonly"
|
:disabled="readonly"
|
||||||
:accept="accept"
|
:accept="accept"
|
||||||
|
@preview="handlePreview"
|
||||||
>
|
>
|
||||||
<el-icon v-if="fileList.length < limit"><Plus /></el-icon>
|
<el-icon v-if="fileList.length < limit"><Plus /></el-icon>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
@ -24,78 +25,74 @@ import { ref, computed } from 'vue';
|
|||||||
import { Plus } from '@element-plus/icons-vue';
|
import { Plus } from '@element-plus/icons-vue';
|
||||||
import { CommonUpload } from '@/apis/index';
|
import { CommonUpload } from '@/apis/index';
|
||||||
|
|
||||||
|
// 1. props & emit
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: { type: [Array, String], default: () => [] },
|
||||||
type: Array,
|
ossUrl: { type: String, default: 'http://gov-cloud.oss-cn-chengdu.aliyuncs.com/' },
|
||||||
default: () => [],
|
limit: { type: Number, default: 5 },
|
||||||
},
|
accept: { type: String, default: 'image/*' },
|
||||||
ossUrl: {
|
readonly: { type: Boolean, default: false },
|
||||||
type: String,
|
|
||||||
default: 'http://gov-cloud.oss-cn-chengdu.aliyuncs.com/',
|
|
||||||
},
|
|
||||||
limit: {
|
|
||||||
type: Number,
|
|
||||||
default: 5,
|
|
||||||
},
|
|
||||||
accept: {
|
|
||||||
type: String,
|
|
||||||
default: 'image/*',
|
|
||||||
},
|
|
||||||
readonly: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['update:modelValue']);
|
const emit = defineEmits(['update:modelValue']);
|
||||||
|
|
||||||
// 构造 el-upload 所需 file-list
|
// 2. 中间层 computed:统一成数组,写时根据 limit 决定发出数组还是字符串
|
||||||
const fileList = computed(() => {
|
const selectedFiles = computed({
|
||||||
return props.modelValue.map((path, idx) => ({
|
get() {
|
||||||
name: `image_${idx}`,
|
// 回显:如果父传字符串且 limit===1,就把它当成长度 1 数组
|
||||||
url: props.ossUrl + path,
|
if (props.limit === 1 && typeof props.modelValue === 'string' && props.modelValue) {
|
||||||
uid: `${idx}`,
|
return [props.modelValue];
|
||||||
}));
|
}
|
||||||
|
// 其他情况,确保数组
|
||||||
|
return Array.isArray(props.modelValue) ? props.modelValue : [];
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
// 内部操作后:如果单文件场景,传字符串;多文件场景,传数组
|
||||||
|
if (props.limit === 1) {
|
||||||
|
emit('update:modelValue', val.length ? val[0] : '');
|
||||||
|
} else {
|
||||||
|
emit('update:modelValue', val);
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 预览
|
// 3. fileList & previewList 都基于 selectedFiles
|
||||||
|
const fileList = computed(() =>
|
||||||
|
selectedFiles.value.map((path, idx) => ({
|
||||||
|
name: `file_${idx}`,
|
||||||
|
url: props.ossUrl + path,
|
||||||
|
uid: `${idx}`,
|
||||||
|
}))
|
||||||
|
);
|
||||||
const previewShow = ref(false);
|
const previewShow = ref(false);
|
||||||
const previewList = computed(() => fileList.value.map((item) => item.url));
|
|
||||||
const previewIndex = ref(0);
|
const previewIndex = ref(0);
|
||||||
|
const previewList = computed(() => fileList.value.map((f) => f.url));
|
||||||
|
|
||||||
// 上传请求内部实现
|
// 4. 上传 & 移除
|
||||||
const customUploadRequest = async ({ file, onSuccess, onError }) => {
|
const customUploadRequest = async ({ file, onSuccess, onError }) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
try {
|
try {
|
||||||
const res = await CommonUpload(formData);
|
const res = await CommonUpload(formData);
|
||||||
// 假设后端返回 { code:200, data: { url: 'relative/path.jpg' } }
|
|
||||||
onSuccess(res, file);
|
onSuccess(res, file);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
onError(err);
|
onError(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 上传成功回调,推入 modelValue
|
|
||||||
function handleUploadSuccess(res) {
|
function handleUploadSuccess(res) {
|
||||||
const relative = res.data?.url;
|
const relative = res.data?.url;
|
||||||
if (relative) {
|
if (!relative) return;
|
||||||
const newArr = [...props.modelValue, relative];
|
// 推入中间层
|
||||||
emit('update:modelValue', newArr);
|
selectedFiles.value = [...selectedFiles.value, relative];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// 删除图片
|
|
||||||
function handleRemove(file) {
|
function handleRemove(file) {
|
||||||
const fullUrl = file.url;
|
const rel = file.url.replace(props.ossUrl, '');
|
||||||
const relative = fullUrl.replace(props.ossUrl, '');
|
selectedFiles.value = selectedFiles.value.filter((p) => p !== rel);
|
||||||
const newArr = props.modelValue.filter((path) => path !== relative);
|
|
||||||
emit('update:modelValue', newArr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 点击预览
|
// 5. 预览
|
||||||
function handlePreview(file) {
|
function handlePreview(file) {
|
||||||
const idx = fileList.value.findIndex((item) => item.uid === file.uid);
|
const idx = fileList.value.findIndex((item) => item.uid === file.uid);
|
||||||
if (idx !== -1) {
|
if (idx >= 0) {
|
||||||
previewIndex.value = idx;
|
previewIndex.value = idx;
|
||||||
previewShow.value = true;
|
previewShow.value = true;
|
||||||
}
|
}
|
||||||
|
@ -95,16 +95,7 @@
|
|||||||
<el-input v-model="formDataProperty.landCode" placeholder="请输入产权编号" />
|
<el-input v-model="formDataProperty.landCode" placeholder="请输入产权编号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产权证书" prop="propertyCertificateUrl">
|
<el-form-item label="产权证书" prop="propertyCertificateUrl">
|
||||||
<el-upload
|
<FileUploader v-model="formDataProperty.propertyCertificateUrl" :limit="1" />
|
||||||
:http-request="customUploadRequest"
|
|
||||||
:on-success="(res, file) => handleUploadSuccess(res, file, 'property')"
|
|
||||||
multiple
|
|
||||||
:show-file-list="true"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<el-button type="primary">点击上传</el-button>
|
|
||||||
</template>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@ -147,7 +138,7 @@
|
|||||||
<el-input v-model="viewEditFormData.address" />
|
<el-input v-model="viewEditFormData.address" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="所属网格" prop="gridId">
|
<el-form-item label="所属网格" prop="gridId">
|
||||||
<AreaCascader v-model:grid-id="viewEditFormData.gridId" :width="500" label="" />
|
<AreaCascader v-model="viewEditFormData.regionCode" v-model:grid-id="viewEditFormData.gridId" :width="500" label="" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="土壤类型" prop="soilTypeId">
|
<el-form-item label="土壤类型" prop="soilTypeId">
|
||||||
<url-select
|
<url-select
|
||||||
@ -160,20 +151,7 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="土地照片" prop="landUrl">
|
<el-form-item label="土地照片" prop="landUrl">
|
||||||
<template v-if="viewEditFormData.landUrl">
|
<FileUploader v-model="viewEditFormData.landUrl" :limit="1" />
|
||||||
<img :src="`${ossUrl}${viewEditFormData.landUrl}`" alt="土地照片" class="preview-image" />
|
|
||||||
</template>
|
|
||||||
<el-upload
|
|
||||||
v-if="!isView"
|
|
||||||
:http-request="customUploadRequest"
|
|
||||||
:on-success="(res, file) => handleUploadSuccess(res, file, 'viewEditBasic')"
|
|
||||||
multiple
|
|
||||||
:show-file-list="true"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<el-button type="primary">点击上传</el-button>
|
|
||||||
</template>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="土地范围" prop="scope">
|
<el-form-item label="土地范围" prop="scope">
|
||||||
<el-input v-model="viewEditFormData.scope" />
|
<el-input v-model="viewEditFormData.scope" />
|
||||||
@ -190,20 +168,7 @@
|
|||||||
<el-input v-model="viewEditFormData.landCode" />
|
<el-input v-model="viewEditFormData.landCode" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="产权证书" prop="propertyCertificateUrl">
|
<el-form-item label="产权证书" prop="propertyCertificateUrl">
|
||||||
<template v-if="viewEditFormData.propertyCertificateUrl">
|
<FileUploader v-model="viewEditFormData.propertyCertificateUrl" :limit="1" />
|
||||||
<img :src="`${ossUrl}${viewEditFormData.propertyCertificateUrl}`" alt="产权证书" class="preview-image" />
|
|
||||||
</template>
|
|
||||||
<el-upload
|
|
||||||
v-if="!isView"
|
|
||||||
:http-request="customUploadRequest"
|
|
||||||
:on-success="(res, file) => handleUploadSuccess(res, file, 'viewEditProperty')"
|
|
||||||
multiple
|
|
||||||
:show-file-list="true"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<el-button type="primary">点击上传</el-button>
|
|
||||||
</template>
|
|
||||||
</el-upload>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
>
|
>
|
||||||
<el-icon><Plus /></el-icon>
|
<el-icon><Plus /></el-icon>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
|
<!-- <FileUploader v-model="localForm.cooperativePhoto" :limit="1" /> -->
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
@ -45,7 +46,7 @@
|
|||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<el-form-item label="营业执照">
|
<el-form-item label="营业执照">
|
||||||
<el-upload
|
<!-- <el-upload
|
||||||
action="#"
|
action="#"
|
||||||
:http-request="customUploadRequest"
|
:http-request="customUploadRequest"
|
||||||
:on-success="(res, file) => handleUploadSuccess(res, file, 'businessLicence')"
|
:on-success="(res, file) => handleUploadSuccess(res, file, 'businessLicence')"
|
||||||
@ -56,7 +57,8 @@
|
|||||||
:on-remove="() => handleRemove('businessLicence')"
|
:on-remove="() => handleRemove('businessLicence')"
|
||||||
>
|
>
|
||||||
<el-icon><Plus /></el-icon>
|
<el-icon><Plus /></el-icon>
|
||||||
</el-upload>
|
</el-upload> -->
|
||||||
|
<FileUploader v-model="localForm.businessLicence" :limit="1" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
@ -2,391 +2,260 @@
|
|||||||
<div class="custom-page">
|
<div class="custom-page">
|
||||||
<avue-crud
|
<avue-crud
|
||||||
ref="crudRef"
|
ref="crudRef"
|
||||||
v-model="state.form"
|
v-model:page="pageData"
|
||||||
v-model:search="state.query"
|
:data="crudData"
|
||||||
v-model:page="state.pageData"
|
:option="crudOptions"
|
||||||
:table-loading="state.loading"
|
:table-loading="loading"
|
||||||
:data="state.data"
|
@refresh-change="handleRefresh"
|
||||||
:option="state.options"
|
@current-change="handleCurrentChange"
|
||||||
@refresh-change="refreshChange"
|
@size-change="handleSizeChange"
|
||||||
@search-reset="searchChange"
|
|
||||||
@search-change="searchChange"
|
|
||||||
@selection-change="selectionChange"
|
|
||||||
@current-change="currentChange"
|
|
||||||
@size-change="sizeChange"
|
|
||||||
@row-save="rowSave"
|
|
||||||
@row-update="rowUpdate"
|
|
||||||
@row-del="rowDel"
|
|
||||||
>
|
>
|
||||||
<template #search="{ size }">
|
<template #search>
|
||||||
<AreaCascader v-model:value="state.query" placeholder="选择行政区域与网格" :width="400" />
|
<div class="custom-search">
|
||||||
</template>
|
<AreaCascader v-model:region-code="searchForm.regionCode" v-model:grid-id="searchForm.id" :width="600" />
|
||||||
|
<el-button type="primary" @click="handleSearch"> 搜索 </el-button>
|
||||||
<template #menu-left>
|
<el-button @click="resetSearch"> 重置 </el-button>
|
||||||
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #menu="scope">
|
|
||||||
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #detail="scope">
|
|
||||||
<el-tabs type="border-card">
|
|
||||||
<el-tab-pane label="基本信息">
|
|
||||||
<avue-detail :option="baseDetailOption" :data="scope.row"></avue-detail>
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane label="网格地图">
|
|
||||||
<div v-if="scope.row.mapUrl" style="height: 400px">
|
|
||||||
<img :src="scope.row.mapUrl" style="max-width: 100%; max-height: 100%" />
|
|
||||||
</div>
|
</div>
|
||||||
<el-empty v-else description="暂无地图数据"></el-empty>
|
</template>
|
||||||
</el-tab-pane>
|
<template #menu-left>
|
||||||
<el-tab-pane label="其他信息">
|
<el-button type="primary" icon="Plus" @click="handleAdd">新增网格</el-button>
|
||||||
<avue-detail :option="otherDetailOption" :data="scope.row"></avue-detail>
|
<!-- <el-button type="success" icon="download" @click="handleExport">导出</el-button> -->
|
||||||
</el-tab-pane>
|
</template>
|
||||||
</el-tabs>
|
<template #menu="scope">
|
||||||
|
<custom-table-operate :actions="crudOptions.actions" :data="scope" />
|
||||||
</template>
|
</template>
|
||||||
</avue-crud>
|
</avue-crud>
|
||||||
|
<el-dialog :key="dialogTitle" v-model="visible" :title="dialogTitle" width="60%" align-center :draggable="true">
|
||||||
|
<el-form ref="form" :model="formData" :rules="rules" :disabled="isReadonly" label-width="100px" class="form-item">
|
||||||
|
<p class="form-title">填写网格信息</p>
|
||||||
|
<el-form-item label="网格名称" prop="gridName">
|
||||||
|
<el-input v-model="formData.gridName" placeholder="请输入网格名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属行政区域" prop="gridAreaCode">
|
||||||
|
<AreaSelect v-model="formData.gridAreaCode" :label="null" :emit-path="false" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="网格化地图" prop="scopeImg">
|
||||||
|
<FileUploader v-model="formData.scopeImg" :limit="1" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="note">
|
||||||
|
<el-input v-model="formData.note" placeholder="请输入备注" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
|
<el-button v-if="!isReadonly" type="primary" @click="handleSubmit()"> 保存 </el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { useApp } from '@/hooks';
|
|
||||||
import { CRUD_OPTIONS } from '@/config';
|
|
||||||
import { isEmpty, downloadFile } from '@/utils';
|
|
||||||
import { useUserStore } from '@/store/modules/user';
|
|
||||||
import { compact } from 'lodash';
|
|
||||||
import { GetEntityList, AddEntity, UpdateEntity, DeleteEntity, ExportEntity } from '@/apis/resource/grid';
|
|
||||||
|
|
||||||
const { VITE_APP_BASE_API } = import.meta.env;
|
<script setup>
|
||||||
const app = useApp();
|
// ---------------------------------------------------------------------
|
||||||
|
// avue-crud 通用代码
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
import { ref, reactive, watch, onMounted, computed, nextTick } from 'vue';
|
||||||
|
import { CRUD_OPTIONS } from '@/config';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
|
||||||
const UserStore = useUserStore();
|
const UserStore = useUserStore();
|
||||||
const crudRef = ref(null);
|
const user = UserStore.getUserInfo();
|
||||||
const state = reactive({
|
console.log('admin 属性:', user.admin);
|
||||||
loading: false,
|
|
||||||
query: {
|
const loading = ref(false);
|
||||||
current: 1,
|
|
||||||
size: 10,
|
const visible = ref(false);
|
||||||
|
const isReadonly = ref(false);
|
||||||
|
const dialogTitle = ref();
|
||||||
|
const formData = ref({
|
||||||
gridName: '',
|
gridName: '',
|
||||||
|
gridAreaCode: '',
|
||||||
|
scope: '',
|
||||||
|
scopeImg: '',
|
||||||
|
note: '',
|
||||||
|
});
|
||||||
|
const initialFormData = { ...formData.value };
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = { ...initialFormData };
|
||||||
|
};
|
||||||
|
|
||||||
|
const pageData = ref({
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
const searchForm = ref({
|
||||||
|
gridName: '',
|
||||||
|
keyword: '',
|
||||||
regionCode: '',
|
regionCode: '',
|
||||||
},
|
id: '',
|
||||||
form: {},
|
status: -1,
|
||||||
selection: [],
|
});
|
||||||
options: {
|
const initialSearchForm = { ...searchForm.value };
|
||||||
|
const resetSearch = () => {
|
||||||
|
searchForm.value = { ...initialSearchForm };
|
||||||
|
};
|
||||||
|
// 过滤对象,只保留有值的属性
|
||||||
|
const filterObject = (obj) => {
|
||||||
|
const newObj = {};
|
||||||
|
Object.keys(obj).forEach((key) => {
|
||||||
|
const value = obj[key];
|
||||||
|
// 检查值是否有效,排除空字符串、null 和 undefined
|
||||||
|
if (value !== '' && value !== null && value !== undefined) {
|
||||||
|
newObj[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return newObj;
|
||||||
|
};
|
||||||
|
|
||||||
|
const crudData = ref([]);
|
||||||
|
const crudOptions = reactive({
|
||||||
...CRUD_OPTIONS,
|
...CRUD_OPTIONS,
|
||||||
addBtnText: '添加网格',
|
addBtn: false,
|
||||||
// detail: true,
|
searchBtn: false,
|
||||||
// detailTitle: '详情',
|
emptyBtn: false,
|
||||||
column: [
|
column: [
|
||||||
{
|
{ label: '网格编号', prop: 'id' },
|
||||||
label: '网格编号',
|
{ label: '网格名称', prop: 'gridName' },
|
||||||
prop: 'id',
|
{ label: '所属行政区域', prop: 'gridAreaName' },
|
||||||
addDisplay: false,
|
{ label: '备注', prop: 'note' },
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '网格名称',
|
|
||||||
prop: 'gridName',
|
|
||||||
rules: {
|
|
||||||
required: true,
|
|
||||||
message: '请输入',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '所属行政区域',
|
|
||||||
prop: 'gridAreaName',
|
|
||||||
addDisplay: false,
|
|
||||||
viewDisplay: true,
|
|
||||||
rules: {
|
|
||||||
required: true,
|
|
||||||
message: '请输入',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '所属行政区域',
|
|
||||||
prop: 'cities',
|
|
||||||
type: 'cascader',
|
|
||||||
hide: true,
|
|
||||||
span: 24,
|
|
||||||
width: 300,
|
|
||||||
addDisplay: true,
|
|
||||||
editDisplay: true,
|
|
||||||
viewDisplay: false,
|
|
||||||
emitPath: false,
|
|
||||||
props: {
|
|
||||||
label: 'areaName',
|
|
||||||
value: 'areaCode',
|
|
||||||
children: 'areaChildVOS',
|
|
||||||
},
|
|
||||||
dicUrl: `${VITE_APP_BASE_API}/system/area/region?areaCode=530000`,
|
|
||||||
dicHeaders: {
|
|
||||||
authorization: UserStore.token,
|
|
||||||
},
|
|
||||||
dicFormatter: (res) => res.data ?? [],
|
|
||||||
rules: {
|
|
||||||
required: true,
|
|
||||||
message: '请选择',
|
|
||||||
trigger: 'blur',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '网格地图',
|
|
||||||
prop: 'mapUrl',
|
|
||||||
type: 'upload',
|
|
||||||
hide: true,
|
|
||||||
// action: `${VITE_APP_BASE_API}/system/file/upload`,
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// label: '网格名称',
|
|
||||||
// prop: 'gridName',
|
|
||||||
// type: 'select',
|
|
||||||
// addDisplay: false,
|
|
||||||
// hide: true,
|
|
||||||
// // search: true,
|
|
||||||
// searchLabelWidth: 100,
|
|
||||||
// dicUrl: `${VITE_APP_BASE_API}/land-resource/gridManage/page?regionCode={{key}}`,
|
|
||||||
// props: {
|
|
||||||
// label: 'gridName',
|
|
||||||
// value: 'gridName',
|
|
||||||
// },
|
|
||||||
// dicHeaders: {
|
|
||||||
// authorization: UserStore.token,
|
|
||||||
// },
|
|
||||||
// dicFormatter: (res) => res.data?.records,
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
label: '备注',
|
|
||||||
prop: 'note',
|
|
||||||
type: 'textarea',
|
|
||||||
span: 24,
|
|
||||||
rows: 4,
|
|
||||||
overHidden: true,
|
|
||||||
// width: 200,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '创建时间',
|
|
||||||
prop: 'createTime',
|
|
||||||
width: 200,
|
|
||||||
hide: true,
|
|
||||||
display: false,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
name: '查看',
|
name: '查看',
|
||||||
icon: 'view',
|
icon: 'view',
|
||||||
event: ({ row }) => rowView(row),
|
event: ({ row }) => handleView(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '编辑',
|
name: '编辑',
|
||||||
icon: 'edit',
|
icon: 'edit',
|
||||||
event: ({ row }) => rowEdit(row),
|
event: ({ row }) => handleEdit(row),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'danger',
|
type: 'danger',
|
||||||
name: '删除',
|
name: '删除',
|
||||||
icon: 'delete',
|
icon: 'delete',
|
||||||
event: ({ row }) => rowDel(row),
|
event: ({ row }) => handleDelete(row),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
|
||||||
pageData: {
|
|
||||||
total: 0,
|
|
||||||
currentPage: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
},
|
|
||||||
data: [],
|
|
||||||
currentRow: {},
|
|
||||||
});
|
});
|
||||||
const baseDetailOption = {
|
const handleRefresh = async () => {
|
||||||
column: [
|
searchForm.value = { ...initialSearchForm };
|
||||||
{
|
getData();
|
||||||
label: '网格名称',
|
|
||||||
prop: 'gridName',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '所属行政区域',
|
|
||||||
prop: 'gridAreaName',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '备注',
|
|
||||||
prop: 'note',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
const handleCurrentChange = (val) => {
|
||||||
const otherDetailOption = {
|
pageData.value.currentPage = val;
|
||||||
column: [
|
|
||||||
{
|
|
||||||
label: '创建时间',
|
|
||||||
prop: 'createTime',
|
|
||||||
},
|
|
||||||
// 可以添加更多字段...
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
const handleSizeChange = (val) => {
|
||||||
// 加载
|
pageData.value.pageSize = val;
|
||||||
const loadData = () => {
|
|
||||||
state.loading = true;
|
|
||||||
GetEntityList(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,
|
|
||||||
};
|
};
|
||||||
}
|
const handleView = (row) => {
|
||||||
})
|
isReadonly.value = true;
|
||||||
.catch((err) => {
|
formData.value = { ...row };
|
||||||
app.$message.error(err.msg);
|
dialogTitle.value = '查看网格';
|
||||||
state.data = [];
|
visible.value = true;
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
state.loading = false;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
const handleEdit = (row) => {
|
||||||
loadData();
|
isReadonly.value = false;
|
||||||
|
formData.value = { ...row };
|
||||||
// 页数
|
dialogTitle.value = '编辑网格';
|
||||||
const currentChange = (current) => {
|
visible.value = true;
|
||||||
state.query.current = current;
|
|
||||||
loadData();
|
|
||||||
};
|
};
|
||||||
|
const handleDelete = async (row) => {
|
||||||
// 条数
|
try {
|
||||||
const sizeChange = (size) => {
|
await ElMessageBox.confirm('确认删除该网格吗?', '提示', {
|
||||||
state.query.size = size;
|
|
||||||
loadData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 搜索
|
|
||||||
const searchChange = (params, done) => {
|
|
||||||
if (done) done();
|
|
||||||
state.query = params;
|
|
||||||
state.query.current = 1;
|
|
||||||
loadData();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 刷新
|
|
||||||
const refreshChange = () => {
|
|
||||||
loadData();
|
|
||||||
app.$message.success('刷新成功');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 选择
|
|
||||||
const selectionChange = (rows) => {
|
|
||||||
state.selection = rows;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查看
|
|
||||||
const rowView = (row) => {
|
|
||||||
crudRef.value.rowView(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setCity = (row) => {
|
|
||||||
if (!isEmpty(row.cities)) {
|
|
||||||
row.provinceCode = row?.cities[0] ?? null;
|
|
||||||
row.cityCode = row?.cities[1] ?? null;
|
|
||||||
row.gridAreaCode = row?.cities[4] ?? null;
|
|
||||||
row.townCode = row?.cities[3] ?? null;
|
|
||||||
row.village = row?.cities[4] ?? null;
|
|
||||||
// row.village = row?.cities.join(',');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增
|
|
||||||
const rowSave = (row, done, loading) => {
|
|
||||||
setCity(row);
|
|
||||||
row.gridAreaCode = row.cities;
|
|
||||||
AddEntity(row)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
app.$message.success('添加成功!');
|
|
||||||
done();
|
|
||||||
loadData();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
app.$message.error(err.msg);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 编辑
|
|
||||||
const rowEdit = (row) => {
|
|
||||||
const village = !isEmpty(row.village) ? row.village : [];
|
|
||||||
row.cities = compact([row.provinceCode, row.cityCode, row.gridAreaCode ?? '', row.townCode ?? '', ...village]);
|
|
||||||
crudRef.value.rowEdit(row);
|
|
||||||
};
|
|
||||||
const rowUpdate = (row, index, done, loading) => {
|
|
||||||
setCity(row);
|
|
||||||
UpdateEntity(row)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
app.$message.success('更新成功!');
|
|
||||||
done();
|
|
||||||
loadData();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
app.$message.error(err.msg);
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
const rowDel = (row, index, done) => {
|
|
||||||
if (isEmpty(row)) return;
|
|
||||||
app
|
|
||||||
.$confirm(`删除后信息将不可查看,确认要删除吗?`, '确定删除', {
|
|
||||||
confirmButtonText: '确定',
|
confirmButtonText: '确定',
|
||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
DeleteEntity({ id: row.id })
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
app.$message.success('删除成功!');
|
|
||||||
loadData();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
app.$message.error(err.msg);
|
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.catch(() => {});
|
const response = await deleteGrid(row.id);
|
||||||
|
|
||||||
|
ElMessage.success('删除成功');
|
||||||
|
getData();
|
||||||
|
} catch (error) {
|
||||||
|
if (error === 'cancel') {
|
||||||
|
ElMessage.info('已取消删除');
|
||||||
|
} else {
|
||||||
|
ElMessage.error('删除失败');
|
||||||
|
console.error('删除异常:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 导出
|
const handleSubmit = async () => {
|
||||||
const onExport = () => {
|
console.log('提交表单:', formData.value);
|
||||||
if (isEmpty(state.data)) {
|
try {
|
||||||
app.$message.error('当前暂时没有可供导出的数据!');
|
if (dialogTitle.value === '新增网格') {
|
||||||
return;
|
await createGrid(formData.value);
|
||||||
|
ElMessage.success('新增成功');
|
||||||
|
} else {
|
||||||
|
await updateGrid(formData.value);
|
||||||
|
ElMessage.success('更新成功');
|
||||||
}
|
}
|
||||||
state.loading = true;
|
} catch (error) {
|
||||||
const fileName = '网格明细表';
|
ElMessage.error(error.message || '新增失败,请重试');
|
||||||
ExportEntity(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;
|
import { createGrid, updateGrid, deleteGrid, fetchGridList, getGridDetail, exportGrid } from '@/apis/landResourceManagement/gridManagement';
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData();
|
||||||
});
|
});
|
||||||
|
const getData = async () => {
|
||||||
|
const filteredParams = filterObject(searchForm.value);
|
||||||
|
const response = await fetchGridList(filteredParams);
|
||||||
|
crudData.value = Array.isArray(response.data.records) ? response.data.records : [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAdd = () => {
|
||||||
|
console.log('handleAdd');
|
||||||
|
resetForm();
|
||||||
|
isReadonly.value = false;
|
||||||
|
dialogTitle.value = '新增网格';
|
||||||
|
visible.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSearch = () => {
|
||||||
|
getData();
|
||||||
|
};
|
||||||
|
const handleCancel = () => {
|
||||||
|
visible.value = false;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
:deep(.el-dialog__body) {
|
||||||
|
padding: 20px;
|
||||||
|
height: calc(100vh - 300px);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.form-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 30px 0;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
.form-item {
|
||||||
|
width: 500px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.custom-search {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -0,0 +1,392 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-page">
|
||||||
|
<avue-crud
|
||||||
|
ref="crudRef"
|
||||||
|
v-model="state.form"
|
||||||
|
v-model:search="state.query"
|
||||||
|
v-model:page="state.pageData"
|
||||||
|
:table-loading="state.loading"
|
||||||
|
:data="state.data"
|
||||||
|
:option="state.options"
|
||||||
|
@refresh-change="refreshChange"
|
||||||
|
@search-reset="searchChange"
|
||||||
|
@search-change="searchChange"
|
||||||
|
@selection-change="selectionChange"
|
||||||
|
@current-change="currentChange"
|
||||||
|
@size-change="sizeChange"
|
||||||
|
@row-save="rowSave"
|
||||||
|
@row-update="rowUpdate"
|
||||||
|
@row-del="rowDel"
|
||||||
|
>
|
||||||
|
<template #search="{ size }">
|
||||||
|
<AreaCascader v-model:value="state.query" placeholder="选择行政区域与网格" :width="400" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #menu-left>
|
||||||
|
<el-button type="success" icon="download" @click="onExport">导出</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #menu="scope">
|
||||||
|
<custom-table-operate :actions="state.options.actions" :data="scope" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #detail="scope">
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane label="基本信息">
|
||||||
|
<avue-detail :option="baseDetailOption" :data="scope.row"></avue-detail>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="网格地图">
|
||||||
|
<div v-if="scope.row.mapUrl" style="height: 400px">
|
||||||
|
<img :src="scope.row.mapUrl" style="max-width: 100%; max-height: 100%" />
|
||||||
|
</div>
|
||||||
|
<el-empty v-else description="暂无地图数据"></el-empty>
|
||||||
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="其他信息">
|
||||||
|
<avue-detail :option="otherDetailOption" :data="scope.row"></avue-detail>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</template>
|
||||||
|
</avue-crud>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { useApp } from '@/hooks';
|
||||||
|
import { CRUD_OPTIONS } from '@/config';
|
||||||
|
import { isEmpty, downloadFile } from '@/utils';
|
||||||
|
import { useUserStore } from '@/store/modules/user';
|
||||||
|
import { compact } from 'lodash';
|
||||||
|
import { GetEntityList, AddEntity, UpdateEntity, DeleteEntity, ExportEntity } from '@/apis/resource/grid';
|
||||||
|
|
||||||
|
const { VITE_APP_BASE_API } = import.meta.env;
|
||||||
|
const app = useApp();
|
||||||
|
const UserStore = useUserStore();
|
||||||
|
const crudRef = ref(null);
|
||||||
|
const state = reactive({
|
||||||
|
loading: false,
|
||||||
|
query: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
gridName: '',
|
||||||
|
regionCode: '',
|
||||||
|
},
|
||||||
|
form: {},
|
||||||
|
selection: [],
|
||||||
|
options: {
|
||||||
|
...CRUD_OPTIONS,
|
||||||
|
addBtnText: '添加网格',
|
||||||
|
// detail: true,
|
||||||
|
// detailTitle: '详情',
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '网格编号',
|
||||||
|
prop: 'id',
|
||||||
|
addDisplay: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '网格名称',
|
||||||
|
prop: 'gridName',
|
||||||
|
rules: {
|
||||||
|
required: true,
|
||||||
|
message: '请输入',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '所属行政区域',
|
||||||
|
prop: 'gridAreaName',
|
||||||
|
addDisplay: false,
|
||||||
|
viewDisplay: true,
|
||||||
|
rules: {
|
||||||
|
required: true,
|
||||||
|
message: '请输入',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '所属行政区域',
|
||||||
|
prop: 'cities',
|
||||||
|
type: 'cascader',
|
||||||
|
hide: true,
|
||||||
|
span: 24,
|
||||||
|
width: 300,
|
||||||
|
addDisplay: true,
|
||||||
|
editDisplay: true,
|
||||||
|
viewDisplay: false,
|
||||||
|
emitPath: false,
|
||||||
|
props: {
|
||||||
|
label: 'areaName',
|
||||||
|
value: 'areaCode',
|
||||||
|
children: 'areaChildVOS',
|
||||||
|
},
|
||||||
|
dicUrl: `${VITE_APP_BASE_API}/system/area/region?areaCode=530000`,
|
||||||
|
dicHeaders: {
|
||||||
|
authorization: UserStore.token,
|
||||||
|
},
|
||||||
|
dicFormatter: (res) => res.data ?? [],
|
||||||
|
rules: {
|
||||||
|
required: true,
|
||||||
|
message: '请选择',
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '网格地图',
|
||||||
|
prop: 'mapUrl',
|
||||||
|
type: 'upload',
|
||||||
|
hide: true,
|
||||||
|
// action: `${VITE_APP_BASE_API}/system/file/upload`,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// label: '网格名称',
|
||||||
|
// prop: 'gridName',
|
||||||
|
// type: 'select',
|
||||||
|
// addDisplay: false,
|
||||||
|
// hide: true,
|
||||||
|
// // search: true,
|
||||||
|
// searchLabelWidth: 100,
|
||||||
|
// dicUrl: `${VITE_APP_BASE_API}/land-resource/gridManage/page?regionCode={{key}}`,
|
||||||
|
// props: {
|
||||||
|
// label: 'gridName',
|
||||||
|
// value: 'gridName',
|
||||||
|
// },
|
||||||
|
// dicHeaders: {
|
||||||
|
// authorization: UserStore.token,
|
||||||
|
// },
|
||||||
|
// dicFormatter: (res) => res.data?.records,
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
prop: 'note',
|
||||||
|
type: 'textarea',
|
||||||
|
span: 24,
|
||||||
|
rows: 4,
|
||||||
|
overHidden: true,
|
||||||
|
// width: 200,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '创建时间',
|
||||||
|
prop: 'createTime',
|
||||||
|
width: 200,
|
||||||
|
hide: true,
|
||||||
|
display: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
name: '查看',
|
||||||
|
icon: 'view',
|
||||||
|
event: ({ row }) => rowView(row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '编辑',
|
||||||
|
icon: 'edit',
|
||||||
|
event: ({ row }) => rowEdit(row),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'danger',
|
||||||
|
name: '删除',
|
||||||
|
icon: 'delete',
|
||||||
|
event: ({ row }) => rowDel(row),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
pageData: {
|
||||||
|
total: 0,
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
data: [],
|
||||||
|
currentRow: {},
|
||||||
|
});
|
||||||
|
const baseDetailOption = {
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '网格名称',
|
||||||
|
prop: 'gridName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '所属行政区域',
|
||||||
|
prop: 'gridAreaName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '备注',
|
||||||
|
prop: 'note',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const otherDetailOption = {
|
||||||
|
column: [
|
||||||
|
{
|
||||||
|
label: '创建时间',
|
||||||
|
prop: 'createTime',
|
||||||
|
},
|
||||||
|
// 可以添加更多字段...
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载
|
||||||
|
const loadData = () => {
|
||||||
|
state.loading = true;
|
||||||
|
GetEntityList(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();
|
||||||
|
|
||||||
|
// 页数
|
||||||
|
const currentChange = (current) => {
|
||||||
|
state.query.current = current;
|
||||||
|
loadData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 条数
|
||||||
|
const sizeChange = (size) => {
|
||||||
|
state.query.size = size;
|
||||||
|
loadData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const searchChange = (params, done) => {
|
||||||
|
if (done) done();
|
||||||
|
state.query = params;
|
||||||
|
state.query.current = 1;
|
||||||
|
loadData();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 刷新
|
||||||
|
const refreshChange = () => {
|
||||||
|
loadData();
|
||||||
|
app.$message.success('刷新成功');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 选择
|
||||||
|
const selectionChange = (rows) => {
|
||||||
|
state.selection = rows;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查看
|
||||||
|
const rowView = (row) => {
|
||||||
|
crudRef.value.rowView(row);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setCity = (row) => {
|
||||||
|
if (!isEmpty(row.cities)) {
|
||||||
|
row.provinceCode = row?.cities[0] ?? null;
|
||||||
|
row.cityCode = row?.cities[1] ?? null;
|
||||||
|
row.gridAreaCode = row?.cities[4] ?? null;
|
||||||
|
row.townCode = row?.cities[3] ?? null;
|
||||||
|
row.village = row?.cities[4] ?? null;
|
||||||
|
// row.village = row?.cities.join(',');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
const rowSave = (row, done, loading) => {
|
||||||
|
setCity(row);
|
||||||
|
row.gridAreaCode = row.cities;
|
||||||
|
AddEntity(row)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
app.$message.success('添加成功!');
|
||||||
|
done();
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
app.$message.error(err.msg);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑
|
||||||
|
const rowEdit = (row) => {
|
||||||
|
const village = !isEmpty(row.village) ? row.village : [];
|
||||||
|
row.cities = compact([row.provinceCode, row.cityCode, row.gridAreaCode ?? '', row.townCode ?? '', ...village]);
|
||||||
|
crudRef.value.rowEdit(row);
|
||||||
|
};
|
||||||
|
const rowUpdate = (row, index, done, loading) => {
|
||||||
|
setCity(row);
|
||||||
|
UpdateEntity(row)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
app.$message.success('更新成功!');
|
||||||
|
done();
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
app.$message.error(err.msg);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const rowDel = (row, index, done) => {
|
||||||
|
if (isEmpty(row)) return;
|
||||||
|
app
|
||||||
|
.$confirm(`删除后信息将不可查看,确认要删除吗?`, '确定删除', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
DeleteEntity({ id: row.id })
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
app.$message.success('删除成功!');
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
app.$message.error(err.msg);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 导出
|
||||||
|
const onExport = () => {
|
||||||
|
if (isEmpty(state.data)) {
|
||||||
|
app.$message.error('当前暂时没有可供导出的数据!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.loading = true;
|
||||||
|
const fileName = '网格明细表';
|
||||||
|
ExportEntity(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;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user