feat(request): 重构 axios 请求并添加新功能
- 创建独立的 request 实例,避免全局 axios 默认配置冲突 - 添加文件上传下载功能 - 新增 get、post 方法的 loading 控制 -优化请求拦截器,统一处理 Token 和 loading - 重构响应拦截器,统一处理登录失效和请求错误master
parent
087daf26a9
commit
4ed118ed74
|
@ -15,5 +15,7 @@
|
|||
<script type="text/javascript" src="/cesium91/CesiumUnminified/Cesium.js"></script>
|
||||
<script type="text/javascript" src="/cesium91/CustomCesiumSDK.js"></script>
|
||||
<link href="/cesium91/CesiumUnminified/Widgets/widgets.css" rel="stylesheet"/>
|
||||
<script type="text/javascript"
|
||||
src="https://api.map.baidu.com/api?v=1.0&type=webgl&ak=OElqFYoKiAH8KFtph8ftLKF5NlNrbCUr"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
<template>
|
||||
<suspense>
|
||||
<template #default>
|
||||
<router-view />
|
||||
<el-config-provider :locale="zhCn">
|
||||
<router-view />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
<template #fallback>
|
||||
<div>加载中...</div>
|
||||
|
@ -9,6 +11,8 @@
|
|||
</suspense>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
<script setup>
|
||||
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
|
@ -17,102 +17,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 生成1-50的margin和padding(正负)
|
||||
@for $i from 1 through 50 {
|
||||
.m-#{$i} {
|
||||
margin: #{$i}px;
|
||||
}
|
||||
.mt-#{$i} {
|
||||
margin-top: #{$i}px;
|
||||
}
|
||||
.mr-#{$i} {
|
||||
margin-right: #{$i}px;
|
||||
}
|
||||
.mb-#{$i} {
|
||||
margin-bottom: #{$i}px;
|
||||
}
|
||||
.ml-#{$i} {
|
||||
margin-left: #{$i}px;
|
||||
}
|
||||
.mtb-#{$i} {
|
||||
margin-top: #{$i}px;
|
||||
margin-bottom: #{$i}px;
|
||||
}
|
||||
.mlr-#{$i} {
|
||||
margin-left: #{$i}px;
|
||||
margin-right: #{$i}px;
|
||||
}
|
||||
.p-#{$i} {
|
||||
padding: #{$i}px;
|
||||
}
|
||||
.pt-#{$i} {
|
||||
padding-top: #{$i}px;
|
||||
}
|
||||
.pr-#{$i} {
|
||||
padding-right: #{$i}px;
|
||||
}
|
||||
.pb-#{$i} {
|
||||
padding-bottom: #{$i}px;
|
||||
}
|
||||
.pl-#{$i} {
|
||||
padding-left: #{$i}px;
|
||||
}
|
||||
.ptb-#{$i} {
|
||||
padding-top: #{$i}px;
|
||||
padding-bottom: #{$i}px;
|
||||
}
|
||||
.plr-#{$i} {
|
||||
padding-left: #{$i}px;
|
||||
padding-right: #{$i}px;
|
||||
}
|
||||
.m--#{$i} {
|
||||
margin: -#{$i}px;
|
||||
}
|
||||
.mt--#{$i} {
|
||||
margin-top: -#{$i}px;
|
||||
}
|
||||
.mr--#{$i} {
|
||||
margin-right: -#{$i}px;
|
||||
}
|
||||
.mb--#{$i} {
|
||||
margin-bottom: -#{$i}px;
|
||||
}
|
||||
.ml--#{$i} {
|
||||
margin-left: -#{$i}px;
|
||||
}
|
||||
.mtb--#{$i} {
|
||||
margin-top: -#{$i}px;
|
||||
margin-bottom: -#{$i}px;
|
||||
}
|
||||
.mlr--#{$i} {
|
||||
margin-left: -#{$i}px;
|
||||
margin-right: -#{$i}px;
|
||||
}
|
||||
.p--#{$i} {
|
||||
padding: -#{$i}px;
|
||||
}
|
||||
.pt--#{$i} {
|
||||
padding-top: -#{$i}px;
|
||||
}
|
||||
.pr--#{$i} {
|
||||
padding-right: -#{$i}px;
|
||||
}
|
||||
.pb--#{$i} {
|
||||
padding-bottom: -#{$i}px;
|
||||
}
|
||||
.pl--#{$i} {
|
||||
padding-left: -#{$i}px;
|
||||
}
|
||||
.ptb--#{$i} {
|
||||
padding-top: -#{$i}px;
|
||||
padding-bottom: -#{$i}px;
|
||||
}
|
||||
.plr--#{$i} {
|
||||
padding-left: -#{$i}px;
|
||||
padding-right: -#{$i}px;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
|
@ -145,13 +49,158 @@ a {
|
|||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
.end {
|
||||
.el-form-item__content {
|
||||
justify-content: end;
|
||||
}
|
||||
}
|
||||
|
||||
.p0.el-descriptions__content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.p0 .el-descriptions tr {
|
||||
.el-descriptions__label {
|
||||
border-left: none !important;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
&:first-child .el-descriptions__cell {
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
&:last-child .el-descriptions__cell {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.p20 {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.mt {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.ml {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mr {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mb {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.text-blue {
|
||||
color: #0000ff;
|
||||
}
|
||||
|
||||
.text-yellow {
|
||||
color: #bebe05;
|
||||
}
|
||||
|
||||
.text-orange {
|
||||
color: #de9004;
|
||||
}
|
||||
|
||||
.text-red {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.text-green {
|
||||
color: #0bb20c;
|
||||
}
|
||||
|
||||
.tc {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.tr {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.tl {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.dn {
|
||||
display: none;
|
||||
}
|
||||
|
||||
//.print_use {
|
||||
// display: none;
|
||||
//}
|
||||
|
||||
.viewer-zoom-in, .viewer-zoom-out, .viewer-one-to-one, .viewer-reset, .viewer-prev, .viewer-play, .viewer-next, .viewer-rotate-left, .viewer-rotate-right, .viewer-flip-horizontal, .viewer-flip-vertical, .viewer-fullscreen, .viewer-fullscreen-exit, .viewer-close {
|
||||
&::before {
|
||||
font-size: unset !important;
|
||||
}
|
||||
}
|
||||
|
||||
.iframe{
|
||||
position: relative;
|
||||
border: none;
|
||||
.vue-pdf__wrapper-annotation-layer {
|
||||
height: 0 !important;
|
||||
}
|
||||
|
||||
.w-e-bar-divider {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// 打印时去掉页眉页脚
|
||||
@page {
|
||||
size: auto;
|
||||
margin: 3mm;
|
||||
}
|
||||
|
||||
@media print {
|
||||
@page {
|
||||
size: auto;
|
||||
}
|
||||
body, html { //如果vue最外层id,默认是#app。如果设置了height:100%;,那么#app也加
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.print_use {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
display: table;
|
||||
|
||||
td, th {
|
||||
border: 1px solid #eaeaea;
|
||||
padding: 8px;
|
||||
line-height: 1.6;
|
||||
text-align: center;
|
||||
color: #000 !important;
|
||||
}
|
||||
tr {
|
||||
color: #000 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.print_no_use {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.my_primary{
|
||||
width: calc(100vw - 252px);
|
||||
background: #ffffff;
|
||||
padding: 10px;
|
||||
position: fixed;
|
||||
left: 231px;
|
||||
bottom: 0;
|
||||
box-shadow: 0 0 10px #cccccc;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.my_main{
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
.el-select, .el-cascader, .el-date-editor.el-input, .el-date-editor.el-input__wrapper, .el-input__wrapper, .el-input-number {
|
||||
width: 100% !important;
|
||||
}
|
||||
.el-pagination--small .el-select{
|
||||
width: 100px !important;
|
||||
}
|
||||
.el-table .el-table__cell {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.el-descriptions__label {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.el-divider__text {
|
||||
font-size: 16px !important;
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
--el-dialog-margin-top: 50px !important;
|
||||
|
||||
.el-dialog__header {
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
border-top: 1px solid #f1f1f1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table {
|
||||
* {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
th.el-table__cell {
|
||||
--el-table-header-bg-color: rgb(245, 247, 250);
|
||||
font-weight: bold;
|
||||
color: rgb(0, 0, 0);
|
||||
}
|
||||
|
||||
.el-table__cell {
|
||||
padding: 8px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-page-header {
|
||||
border-bottom: 1px solid #eaeaea;
|
||||
padding: 0 20px 20px 20px;
|
||||
margin: 0 -20px 20px -20px;
|
||||
|
||||
.el-page-header__content {
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-pagination .el-select{
|
||||
width: 100px !important;
|
||||
}
|
||||
|
||||
.el-scrollbar__wrap{
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import {
|
||||
getDataDictionary,
|
||||
getDataDictionaryTree,
|
||||
getDepartmentTree,
|
||||
} from "@/request/data_dictionary";
|
||||
import { ref } from "vue";
|
||||
|
||||
// 学历
|
||||
export const layoutFnGetDegree = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "ddce2eac1cf27e4b114231051ec9123b",
|
||||
});
|
||||
return ref(resData.dictionariesList);
|
||||
};
|
||||
// 评审模板类型
|
||||
export const layoutFnGetCheckTemplateType = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "918ff8ae621595c86ed95d2c77484e1c",
|
||||
});
|
||||
return ref(resData.dictionariesList);
|
||||
};
|
||||
// 评审周期
|
||||
export const layoutFnGetReviewCycle = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "4034603a5ae1042827340bc86fe26454",
|
||||
});
|
||||
return ref(resData.dictionariesList);
|
||||
};
|
||||
// 无法确定parentId的数据字典
|
||||
export const layoutFnGetDataDictionary = async (parentId) => {
|
||||
const resData = await getDataDictionary({ parentId });
|
||||
return ref(resData.dictionariesList);
|
||||
};
|
||||
// 部门
|
||||
export const layoutFnGetDepartmentTree = async (parentId) => {
|
||||
const resData = await getDepartmentTree(parentId);
|
||||
return ref(resData.deptTree);
|
||||
};
|
||||
// 企业类型
|
||||
export const fnGetEnterpriseTypeList = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "71eb9a7f6fb55afdb8f9b4bea9b3e368",
|
||||
});
|
||||
return ref(resData.dictionariesList);
|
||||
};
|
||||
// 企业类型
|
||||
export const fnGetHiddenTypeList = async () => {
|
||||
const resData = await getDataDictionaryTree({
|
||||
parentId: "e3af692a2137d4bcf90ec53f5590b176",
|
||||
});
|
||||
return ref(resData.dictionariesList);
|
||||
};
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<el-cascader
|
||||
ref="cascaderRef"
|
||||
v-model="modelValue"
|
||||
:props="administrativeDivisionProps"
|
||||
@change="change"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { layoutFnGetDataDictionary } from "@/assets/js/data_dictionary.js";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import { ref } from "vue";
|
||||
|
||||
defineOptions({
|
||||
name: "LayoutCascader",
|
||||
});
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
level: {
|
||||
type: [Number, String],
|
||||
default: 3,
|
||||
},
|
||||
checkStrictly: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
dictionariesId: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
isPressLevelSetLeaf: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:modelValue", "update:name"]);
|
||||
const { modelValue, name } = useVModels(props, emits);
|
||||
const cascaderRef = ref(null);
|
||||
const administrativeDivisionProps = {
|
||||
lazy: true,
|
||||
lazyLoad: async (node, resolve) => {
|
||||
const resData = await layoutFnGetDataDictionary(
|
||||
node.data.dictionariesId || props.dictionariesId
|
||||
);
|
||||
resolve(
|
||||
resData.value.map((item) => {
|
||||
return {
|
||||
dictionariesId: item.dictionariesId,
|
||||
bianma: item.bianma,
|
||||
name: item.name,
|
||||
leaf: props.isPressLevelSetLeaf
|
||||
? node.level >= props.level
|
||||
: item.hasChildren === 0,
|
||||
};
|
||||
})
|
||||
);
|
||||
},
|
||||
value: "bianma",
|
||||
id: "dictionariesId",
|
||||
label: "name",
|
||||
children: "children",
|
||||
checkStrictly: props.checkStrictly,
|
||||
};
|
||||
const change = () => {
|
||||
name.value = getCheckedNodes()[0].pathLabels;
|
||||
};
|
||||
const getCheckedNodes = () => {
|
||||
return cascaderRef.value.getCheckedNodes();
|
||||
};
|
||||
defineExpose({
|
||||
getCheckedNodes,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,71 @@
|
|||
<template>
|
||||
<el-col :span="24">
|
||||
<div style="display: flex">
|
||||
<el-form-item
|
||||
label="经度"
|
||||
:prop="longitudeProps"
|
||||
:rules="longitudeRules"
|
||||
style="flex: 1"
|
||||
>
|
||||
<el-input :model-value="longitude" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="纬度"
|
||||
:prop="latitudeProps"
|
||||
:rules="latitudeRules"
|
||||
style="flex: 1"
|
||||
>
|
||||
<el-input :model-value="latitude" disabled />
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!disabled" label-width="10px">
|
||||
<el-button class="ml-10" type="primary" @click="mapVisible = true">
|
||||
点击定位
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
<app-map
|
||||
v-model:visible="mapVisible"
|
||||
v-model:longitude="longitude"
|
||||
v-model:latitude="latitude"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import AppMap from "@/components/map/map.vue";
|
||||
|
||||
defineProps({
|
||||
longitudeProps: {
|
||||
type: String,
|
||||
default: "LONGITUDE",
|
||||
},
|
||||
latitudeProps: {
|
||||
type: String,
|
||||
default: "LATITUDE",
|
||||
},
|
||||
longitudeRules: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
latitudeRules: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
});
|
||||
const longitude = defineModel("longitude", {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
});
|
||||
const latitude = defineModel("latitude", {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
});
|
||||
const mapVisible = ref(false);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<el-dialog v-model="visible" title="编辑坐标">
|
||||
<el-form label-position="right" label-width="100px">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="关键字搜索">
|
||||
<el-input v-model="localSearch" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label-width="10px">
|
||||
<el-button type="primary" @click="fnLocalSearch">搜索</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="坐标">
|
||||
<el-input disabled :model-value="currentLongitude || longitude" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label-width="10px">
|
||||
<el-input disabled :model-value="currentLatitude || latitude" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div
|
||||
v-loading="loading"
|
||||
element-loading-text="地图正在加载中..."
|
||||
element-loading-background="rgba(0, 0, 0, 0.5)"
|
||||
>
|
||||
<div id="map_container" style="width: 100%; height: 500px" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">关闭</el-button>
|
||||
<el-button type="primary" @click="fnConfirm"> 确定 </el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { nextTick, ref, watch } from "vue";
|
||||
|
||||
defineOptions({
|
||||
name: "AppMap",
|
||||
});
|
||||
let mapInstance;
|
||||
const visible = defineModel("visible", { type: Boolean, required: true });
|
||||
const longitude = defineModel("longitude", {
|
||||
type: [Number, String],
|
||||
required: true,
|
||||
});
|
||||
const latitude = defineModel("latitude", {
|
||||
type: [Number, String],
|
||||
required: true,
|
||||
});
|
||||
const loading = ref(false);
|
||||
const currentLongitude = ref("");
|
||||
const currentLatitude = ref("");
|
||||
const localSearch = ref("");
|
||||
const emits = defineEmits(["submit"]);
|
||||
const fnMapInit = async () => {
|
||||
loading.value = true;
|
||||
await nextTick();
|
||||
mapInstance = new window.BMapGL.Map("map_container");
|
||||
mapInstance.centerAndZoom(
|
||||
new window.BMapGL.Point(
|
||||
longitude.value || "116.3972282409668",
|
||||
latitude.value || "39.90960456049752"
|
||||
),
|
||||
16
|
||||
);
|
||||
mapInstance.enableScrollWheelZoom(true);
|
||||
loading.value = false;
|
||||
if (longitude.value && latitude.value) {
|
||||
const point = new window.BMapGL.Point(longitude.value, latitude.value);
|
||||
const marker = new window.BMapGL.Marker(point);
|
||||
mapInstance.addOverlay(marker);
|
||||
}
|
||||
mapInstance.addEventListener("click", function (event) {
|
||||
mapInstance.clearOverlays();
|
||||
const point = new window.BMapGL.Point(event.latlng.lng, event.latlng.lat);
|
||||
const marker = new window.BMapGL.Marker(point);
|
||||
mapInstance.addOverlay(marker);
|
||||
currentLatitude.value = event.latlng.lat;
|
||||
currentLongitude.value = event.latlng.lng;
|
||||
});
|
||||
};
|
||||
const fnLocalSearch = () => {
|
||||
if (localSearch.value) {
|
||||
const local = new window.BMapGL.LocalSearch(mapInstance, {
|
||||
renderOptions: { map: mapInstance },
|
||||
});
|
||||
local.search(localSearch.value);
|
||||
}
|
||||
};
|
||||
const fnClose = () => {
|
||||
if (mapInstance) {
|
||||
mapInstance.destroy();
|
||||
mapInstance = null;
|
||||
}
|
||||
currentLatitude.value = "";
|
||||
currentLongitude.value = "";
|
||||
localSearch.value = "";
|
||||
visible.value = false;
|
||||
};
|
||||
const fnConfirm = () => {
|
||||
latitude.value = currentLatitude.value;
|
||||
longitude.value = currentLongitude.value;
|
||||
emits("submit", {
|
||||
latitude: currentLatitude.value,
|
||||
longitude: currentLongitude.value,
|
||||
});
|
||||
fnClose();
|
||||
};
|
||||
watch(
|
||||
() => visible.value,
|
||||
(val) => {
|
||||
if (val && !mapInstance) {
|
||||
fnMapInit();
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<el-pagination
|
||||
small
|
||||
:current-page="pagination.currentPage || 1"
|
||||
:page-size="pagination.pageSize || 10"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pagination.total || 0"
|
||||
@update:current-page="handleCurrentChange"
|
||||
@update:page-size="handleSizeChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineOptions({
|
||||
name: "AppPagination",
|
||||
});
|
||||
const emits = defineEmits(["get-data"]);
|
||||
const pagination = defineModel("pagination", { type: Object, required: true });
|
||||
const handleCurrentChange = (val) => {
|
||||
pagination.value = {
|
||||
currentPage: val,
|
||||
pageSize: pagination.value.pageSize,
|
||||
total: pagination.value.total,
|
||||
};
|
||||
emits("get-data");
|
||||
};
|
||||
const handleSizeChange = (val) => {
|
||||
pagination.value = {
|
||||
currentPage: 1,
|
||||
pageSize: val,
|
||||
total: pagination.value.total,
|
||||
};
|
||||
emits("get-data");
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<el-form
|
||||
:model="modelValue"
|
||||
:label-width="labelWidth"
|
||||
@submit.prevent="emits('submit', 'search')"
|
||||
>
|
||||
<el-row :class="className">
|
||||
<slot :collapse="collapse"></slot>
|
||||
<el-col :span="showCollapseButton ? (collapse ? 6 : span) : span">
|
||||
<el-form-item label-width="10px" class="end">
|
||||
<el-button type="primary" native-type="submit"> 搜索 </el-button>
|
||||
<el-button native-type="reset" @click="emits('submit', 'reset')">
|
||||
重置
|
||||
</el-button>
|
||||
<app-search-collapse-button
|
||||
v-if="showCollapseButton"
|
||||
:change-search-collapse="changeSearchCollapse"
|
||||
:collapse="collapse"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="slots.button" :span="24">
|
||||
<el-form-item label-width="0">
|
||||
<slot name="button"></slot>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AppSearchCollapseButton from "@/components/search_collapse_button/index.vue";
|
||||
import useSearchCollapse from "@/hooks/useSearchCollapse.js";
|
||||
import { onMounted, ref, useSlots } from "vue";
|
||||
import { uniqueId } from "lodash-es";
|
||||
|
||||
const slots = useSlots();
|
||||
const { collapse, changeSearchCollapse } = useSearchCollapse();
|
||||
defineOptions({
|
||||
name: "AppSearch",
|
||||
});
|
||||
defineProps({
|
||||
labelWidth: {
|
||||
type: String,
|
||||
default: "100px",
|
||||
},
|
||||
});
|
||||
const className = ref(uniqueId("_"));
|
||||
const span = ref(6);
|
||||
const showCollapseButton = ref(false);
|
||||
const modelValue = defineModel({ type: Object, required: true });
|
||||
const emits = defineEmits(["submit"]);
|
||||
onMounted(() => {
|
||||
const colEl = document.querySelectorAll(`.${className.value} .el-col`);
|
||||
const colElLength = colEl.length;
|
||||
const excludeLast = colElLength - (slots.button ? 2 : 1);
|
||||
span.value = { 0: 24, 1: 18, 2: 12, 3: 6 }[excludeLast % 4];
|
||||
showCollapseButton.value = excludeLast > 3;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<el-button
|
||||
v-if="collapse"
|
||||
:icon="ArrowDown"
|
||||
link
|
||||
text
|
||||
type="primary"
|
||||
@click="changeSearchCollapse"
|
||||
>
|
||||
展开
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="!collapse"
|
||||
:icon="ArrowUp"
|
||||
link
|
||||
text
|
||||
type="primary"
|
||||
@click="changeSearchCollapse"
|
||||
>
|
||||
收起
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ArrowDown, ArrowUp } from "@element-plus/icons-vue";
|
||||
|
||||
defineOptions({
|
||||
name: "AppSearchCollapseButton",
|
||||
});
|
||||
defineProps({
|
||||
collapse: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
changeSearchCollapse: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
|
@ -0,0 +1,196 @@
|
|||
<template>
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
size="small"
|
||||
:data="data"
|
||||
:border="border"
|
||||
:stripe="stripe"
|
||||
:height="height"
|
||||
:max-height="maxHeight"
|
||||
:highlight-current-row="highlightCurrentRow"
|
||||
:row-key="getRowKey"
|
||||
:row-class-name="rowClassName"
|
||||
:row-style="rowStyle"
|
||||
:show-header="showHeader"
|
||||
:show-summary="showSummary"
|
||||
:summary-method="summaryMethod"
|
||||
:span-method="spanMethod"
|
||||
:default-expand-all="defaultExpandAll"
|
||||
:tree-props="treeProps"
|
||||
:header-cell-style="headerCellStyle"
|
||||
:cell-style="cellStyle"
|
||||
:show-overflow-tooltip="showOverflowTooltip"
|
||||
style="width: 100%"
|
||||
@row-click="rowClick"
|
||||
@row-dblclick="rowDblclick"
|
||||
>
|
||||
<el-table-column
|
||||
v-if="showSelection"
|
||||
type="selection"
|
||||
:selectable="selectable"
|
||||
reserve-selection
|
||||
width="60"
|
||||
:show-overflow-tooltip="false"
|
||||
/>
|
||||
<template v-if="showIndex">
|
||||
<el-table-column v-if="showPagination" label="序号" width="60">
|
||||
<template #default="{ $index }">
|
||||
{{ serialNumber(pagination, $index) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-if="!showPagination"
|
||||
label="序号"
|
||||
width="60"
|
||||
type="index"
|
||||
/>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</el-table>
|
||||
<div v-if="showPagination || slots.button" class="table_footer">
|
||||
<div>
|
||||
<slot name="button"></slot>
|
||||
</div>
|
||||
<app-pagination
|
||||
v-if="showPagination"
|
||||
v-model:pagination="pagination"
|
||||
@get-data="emits('get-data')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useSlots, ref } from "vue";
|
||||
import AppPagination from "@/components/pagination/index.vue";
|
||||
import { serialNumber } from "@/assets/js/utils.js";
|
||||
|
||||
const slots = useSlots();
|
||||
defineOptions({
|
||||
name: "AppTable",
|
||||
});
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
showPagination: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showIndex: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showSelection: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
stripe: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
border: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
showHeader: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
highlightCurrentRow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showSummary: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
defaultExpandAll: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
rowKey: {
|
||||
type: [String, Function],
|
||||
},
|
||||
maxHeight: {
|
||||
type: [String, Number],
|
||||
},
|
||||
height: {
|
||||
type: [String, Number],
|
||||
},
|
||||
rowClassName: {
|
||||
type: Function,
|
||||
},
|
||||
rowStyle: {
|
||||
type: Function,
|
||||
},
|
||||
summaryMethod: {
|
||||
type: Function,
|
||||
},
|
||||
spanMethod: {
|
||||
type: Function,
|
||||
},
|
||||
selectable: {
|
||||
type: Function,
|
||||
},
|
||||
treeProps: {
|
||||
type: Object,
|
||||
default: () => ({ hasChildren: "hasChildren", children: "children" }),
|
||||
},
|
||||
headerCellStyle: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
cellStyle: {
|
||||
type: [Object, Function],
|
||||
default: () => ({}),
|
||||
},
|
||||
showOverflowTooltip: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
const pagination = defineModel("pagination", {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
}),
|
||||
});
|
||||
const emits = defineEmits(["get-data", "row-click", "row-dblclick"]);
|
||||
const tableRef = ref(null);
|
||||
const getRowKey = (row) => {
|
||||
if (!props.rowKey) return;
|
||||
if (typeof props.rowKey === "string") return row[props.rowKey];
|
||||
else return props.rowKey(row);
|
||||
};
|
||||
const rowClick = (row, column, event) => {
|
||||
emits("row-click", row, column, event);
|
||||
};
|
||||
const rowDblclick = (row, column, event) => {
|
||||
emits("row-dblclick", row, column, event);
|
||||
};
|
||||
const getSelectionRows = () => {
|
||||
return tableRef.value.getSelectionRows();
|
||||
};
|
||||
const clearSelection = () => {
|
||||
return tableRef.value.clearSelection();
|
||||
};
|
||||
const toggleRowSelection = (value, selected = true) => {
|
||||
tableRef.value.toggleRowSelection(value, selected);
|
||||
};
|
||||
defineExpose({
|
||||
getSelectionRows,
|
||||
clearSelection,
|
||||
toggleRowSelection,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.table_footer {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,160 @@
|
|||
import { nextTick, ref } from "vue";
|
||||
import { getDataType } from "@/assets/js/utils.js";
|
||||
import {
|
||||
getQueryCriteria,
|
||||
setQueryCriteria,
|
||||
} from "@/hooks/useQueryCriteria.js";
|
||||
|
||||
const verificationParameter = (api, options) => {
|
||||
if (getDataType(api) !== "Function") throw new Error("api必须是一个函数");
|
||||
if (getDataType(options) !== "Object")
|
||||
throw new Error("options必须是一个对象");
|
||||
if (options.immediate && getDataType(options.immediate) !== "Boolean")
|
||||
throw new Error("options.immediate必须是一个布尔值");
|
||||
if (options.usePagination && getDataType(options.usePagination) !== "Boolean")
|
||||
throw new Error("options.usePagination必须是一个布尔值");
|
||||
if (options.key && getDataType(options.key) !== "String")
|
||||
throw new Error("options.key必须是一个字符串");
|
||||
if (
|
||||
options.callback &&
|
||||
getDataType(options.callback) !== "Function" &&
|
||||
getDataType(options.callback) !== "AsyncFunction"
|
||||
)
|
||||
throw new Error("options.callback必须是一个函数");
|
||||
if (
|
||||
options.beforeGetData &&
|
||||
getDataType(options.beforeGetData) !== "Function" &&
|
||||
getDataType(options.beforeGetData) !== "AsyncFunction"
|
||||
)
|
||||
throw new Error("options.beforeGetData必须是一个函数");
|
||||
if (
|
||||
options.defaultSearchForm &&
|
||||
getDataType(options.defaultSearchForm) !== "Object"
|
||||
)
|
||||
throw new Error("options.defaultSearchForm必须是一个对象");
|
||||
if (
|
||||
options.clearSelection &&
|
||||
getDataType(options.clearSelection) !== "Boolean"
|
||||
)
|
||||
throw new Error("options.clearSelection必须是一个布尔值");
|
||||
if (
|
||||
options.params &&
|
||||
getDataType(options.params) !== "Object" &&
|
||||
getDataType(options.params) !== "Function"
|
||||
)
|
||||
throw new Error("options.params必须是一个对象或者一个函数");
|
||||
if (
|
||||
options.isStorageQueryCriteria &&
|
||||
getDataType(options.isStorageQueryCriteria) !== "Boolean"
|
||||
)
|
||||
throw new Error("options.isStorageQueryCriteria必须是一个布尔值");
|
||||
if (
|
||||
options.tabsActiveName &&
|
||||
getDataType(options.tabsActiveName) !== "String"
|
||||
)
|
||||
throw new Error("options.tabsActiveName必须是一个字符串");
|
||||
};
|
||||
|
||||
const getOptionParams = (params) => {
|
||||
if (params) {
|
||||
if (getDataType(params) === "Object") return params;
|
||||
const paramsValue = params();
|
||||
if (getDataType(paramsValue) !== "Object")
|
||||
throw new Error("options.params为函数时必须存在返回值并且必须是一个对象");
|
||||
else return paramsValue;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param api {Function} 接口函数
|
||||
* @param options {Object?: {callback, params, defaultSearchForm, immediate, usePagination, key, beforeGetData}} 配置项
|
||||
* @param options.callback {Function?} 回调函数(返回值【第一个参数表格数据,第二个参数后台返回的所有数据】)
|
||||
* @param options.beforeGetData {Function?} 调用请求之前(返回值【第一个参数searchForm搜索表单数据】)
|
||||
* @param options.params {(Object | Function)?} 其它接口参数
|
||||
* @param options.defaultSearchForm {Object?} searchForm默认值
|
||||
* @param options.immediate {Boolean?} 是否立即执行接口函数(默认是)
|
||||
* @param options.usePagination {Boolean?} 是否使用分页(默认是)
|
||||
* @param options.clearSelection {Boolean?} 调用resetPagination时是否清空表格选择数据(默认是)
|
||||
* @param options.key {String?} 返回的存放数组的key(默认list)
|
||||
* @param options.isStorageQueryCriteria {Boolean?} 是否保存查询条件(默认是)
|
||||
* @param options.tabsActiveName {String?} 存在tabs组件时,当前tabs的activeName,用于缓存查询条件
|
||||
* @return {Object} 返回对象包含以下属性:list 表格数据,pagination 分页数据,searchForm 搜索表单数据,tableRef 表格实例,getData 获取数据函数,resetPagination 重置分页函数
|
||||
*/
|
||||
|
||||
export default function useListData(api, options = {}) {
|
||||
verificationParameter(api, options);
|
||||
const immediate = options.immediate ?? true;
|
||||
const usePagination = options.usePagination ?? true;
|
||||
const key = options.key ?? "list";
|
||||
const defaultSearchForm = options.defaultSearchForm ?? {};
|
||||
const clearSelection = options.clearSelection ?? true;
|
||||
const isStorageQueryCriteria = options.isStorageQueryCriteria ?? true;
|
||||
const defaultPagination = { currentPage: 1, pageSize: 10, total: 0 };
|
||||
const list = ref([]);
|
||||
const queryCriteria = getQueryCriteria();
|
||||
const pagination = ref(queryCriteria.pagination || defaultPagination);
|
||||
const searchForm = ref(JSON.parse(JSON.stringify(defaultSearchForm)));
|
||||
let beforeGetDataParams = {};
|
||||
const tableRef = ref(null);
|
||||
const getData = async (params = {}) => {
|
||||
if (options.beforeGetData) {
|
||||
beforeGetDataParams = JSON.parse(
|
||||
JSON.stringify(queryCriteria.searchForm || searchForm.value)
|
||||
);
|
||||
options.beforeGetData(beforeGetDataParams);
|
||||
}
|
||||
const resData = await api({
|
||||
...(usePagination
|
||||
? {
|
||||
curPage: pagination.value.currentPage,
|
||||
limit: pagination.value.pageSize,
|
||||
}
|
||||
: {}),
|
||||
...searchForm.value,
|
||||
...beforeGetDataParams,
|
||||
...(queryCriteria.searchForm || {}),
|
||||
...(getOptionParams(options.params) || {}),
|
||||
...(getDataType(params) === "Object" ? params : {}),
|
||||
});
|
||||
if (usePagination) list.value = resData.page[key];
|
||||
else list.value = resData[key];
|
||||
if (usePagination) pagination.value.total = resData.page.totalCount;
|
||||
options.callback && options.callback(list.value, resData);
|
||||
!usePagination &&
|
||||
clearSelection &&
|
||||
tableRef.value &&
|
||||
tableRef.value.clearSelection();
|
||||
if (isStorageQueryCriteria) {
|
||||
setQueryCriteria({
|
||||
searchForm: {
|
||||
...(queryCriteria.searchForm || {}),
|
||||
...searchForm.value,
|
||||
},
|
||||
pagination: pagination.value,
|
||||
tabsActiveName: options.tabsActiveName,
|
||||
});
|
||||
await nextTick();
|
||||
searchForm.value = queryCriteria.searchForm || searchForm.value;
|
||||
}
|
||||
};
|
||||
immediate && getData().then();
|
||||
const resetPagination = async (params) => {
|
||||
list.value = [];
|
||||
pagination.value = defaultPagination;
|
||||
await nextTick();
|
||||
await getData(params);
|
||||
clearSelection && tableRef.value && tableRef.value.clearSelection();
|
||||
const cloneSearchForm = searchForm.value;
|
||||
searchForm.value = {};
|
||||
await nextTick();
|
||||
searchForm.value = cloneSearchForm;
|
||||
};
|
||||
return {
|
||||
list,
|
||||
pagination,
|
||||
searchForm,
|
||||
tableRef,
|
||||
getData: async (params) => await getData(params),
|
||||
resetPagination: async (params) => await resetPagination(params),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { ref } from "vue";
|
||||
|
||||
const useSearchCollapse = () => {
|
||||
const collapse = ref(true);
|
||||
const changeSearchCollapse = () => {
|
||||
collapse.value = !collapse.value;
|
||||
};
|
||||
return {
|
||||
collapse,
|
||||
changeSearchCollapse,
|
||||
};
|
||||
};
|
||||
export default useSearchCollapse;
|
|
@ -1,6 +1,7 @@
|
|||
import { createApp } from "vue";
|
||||
import "@/assets/css/common.scss";
|
||||
import "@/assets/css/transition.scss";
|
||||
import "@/assets/css/element.scss";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import App from "./App";
|
||||
import pinia from "./pinia";
|
||||
|
|
|
@ -4,7 +4,7 @@ import router from "../router";
|
|||
import pinia from "../pinia";
|
||||
import { useUserStore } from "@/pinia/user.js";
|
||||
import refreshToken from "@/assets/js/refreshToken.js";
|
||||
import { getBaseUrl } from "@/assets/js/utils.js";
|
||||
import { getDataType } from "@/assets/js/utils.js";
|
||||
|
||||
let loading = null;
|
||||
let isTipTokenFailure = false;
|
||||
|
@ -20,10 +20,16 @@ function endLoading() {
|
|||
loading && loading.close();
|
||||
}
|
||||
|
||||
axios.defaults.baseURL = getBaseUrl();
|
||||
axios.defaults.timeout = 1000 * 60 * 10;
|
||||
const request = axios.create({
|
||||
baseURL: import.meta.env.VITE_BASE_URL,
|
||||
timeout: 1000 * 60 * 10,
|
||||
// headers: {
|
||||
// 'Content-type': 'application/x-www-form-urlencoded;charset=UTF-8'
|
||||
// }
|
||||
});
|
||||
|
||||
// axios.defaults.withCredentials = true;
|
||||
axios.interceptors.request.use(
|
||||
request.interceptors.request.use(
|
||||
async (config) => {
|
||||
const userStore = useUserStore(pinia);
|
||||
config.headers.Token = userStore.getToken;
|
||||
|
@ -38,13 +44,13 @@ axios.interceptors.request.use(
|
|||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
axios.interceptors.response.use(
|
||||
request.interceptors.response.use(
|
||||
(config) => {
|
||||
if (config.config.method === "get" || config.config.method === "GET") {
|
||||
if (config.config.params.loading !== false) endLoading();
|
||||
}
|
||||
if (config.config.method === "post" || config.config.method === "POST") {
|
||||
if (config.config.headers["Content-Type"] === "multipart/form-data") {
|
||||
if (getDataType(config.config.data) === "FormData") {
|
||||
endLoading();
|
||||
} else {
|
||||
if (JSON.parse(config.config.data)?.loading !== false) endLoading();
|
||||
|
@ -53,7 +59,7 @@ axios.interceptors.response.use(
|
|||
if (config.data.code === 401) {
|
||||
if (!isTipTokenFailure) {
|
||||
isTipTokenFailure = true;
|
||||
ElMessage.error("登录失效,请重新登录");
|
||||
ElMessage.error("登录失效,请重新登陆");
|
||||
router.push("/login").then();
|
||||
isTipTokenFailure = false;
|
||||
}
|
||||
|
@ -76,10 +82,10 @@ axios.interceptors.response.use(
|
|||
}
|
||||
);
|
||||
|
||||
export function post(url, params = {}) {
|
||||
export function post(url, params) {
|
||||
const userStore = useUserStore(pinia);
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
request
|
||||
.post(url, {
|
||||
corpinfoId: userStore.getUserInfo.corpinfoId,
|
||||
userId: userStore.getUserInfo.userId,
|
||||
|
@ -99,16 +105,14 @@ export function post(url, params = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
export function get(url, params = {}) {
|
||||
export function get(url, params) {
|
||||
const userStore = useUserStore(pinia);
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
request
|
||||
.get(url, {
|
||||
params: {
|
||||
corpinfoId: userStore.getUserInfo.corpinfoId,
|
||||
userId: userStore.getUserInfo.userId,
|
||||
...params,
|
||||
},
|
||||
corpinfoId: userStore.getUserInfo.corpinfoId,
|
||||
userId: userStore.getUserInfo.userId,
|
||||
...params,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data.result === "success") {
|
||||
|
@ -124,9 +128,9 @@ export function get(url, params = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
export function upload(url, params = {}) {
|
||||
export function upload(url, params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
axios
|
||||
request
|
||||
.post(url, params, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data",
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { post } from "./axios";
|
||||
|
||||
// 获取部门
|
||||
export const getDepartmentTree = (parentId = "0") =>
|
||||
post("/oa/department/getTree", {
|
||||
loading: false,
|
||||
parentId,
|
||||
});
|
||||
// 获取数据字典
|
||||
export const getDataDictionary = (params) =>
|
||||
post("/sys/dictionaries/list", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
// 获取数据字典树
|
||||
export const getDataDictionaryTree = (params) =>
|
||||
post("/sys/dictionaries/listTree", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import { post } from "./axios";
|
||||
|
||||
/*
|
||||
* 应急储备库信息表
|
||||
*/
|
||||
export const getEmergencyStoragePage = (params) =>
|
||||
post("/busEmergencyStorage/listPage", params); // 获取应急储备库信息表
|
||||
export const setEmergencyStorageDelete = (params) =>
|
||||
post("/busEmergencyStorage/delete", params); // 获取应急储备库信息表
|
||||
export const setEmergencyStorageAdd = (params) =>
|
||||
post("/busEmergencyStorage/save", params);
|
||||
export const setEmergencyStorageUpdate = (params) =>
|
||||
post("/busEmergencyStorage/update", params);
|
||||
|
||||
/*
|
||||
* 山洪村信息
|
||||
*/
|
||||
export const getMountainFloodVillagePage = (params) =>
|
||||
post("/busMountainFloodVillage/listPage", params); // 获取山洪村信息表
|
||||
export const setMountainFloodVillageDelete = (params) =>
|
||||
post("/busMountainFloodVillage/delete", params);
|
||||
export const setMountainFloodVillageAdd = (params) =>
|
||||
post("/busMountainFloodVillage/save", params);
|
||||
export const setMountainFloodVillageUpdate = (params) =>
|
||||
post("/busMountainFloodVillage/update", params);
|
||||
|
||||
/*
|
||||
*城市防涝点
|
||||
*/
|
||||
export const getUrbanFloodPointPage = (params) =>
|
||||
post("/busUrbanFloodPoint/listPage", params);
|
||||
export const setUrbanFloodPointDelete = (params) =>
|
||||
post("/busUrbanFloodPoint/delete", params);
|
||||
export const setUrbanFloodPointAdd = (params) =>
|
||||
post("/busUrbanFloodPoint/save", params);
|
||||
export const setUrbanFloodPointUpdate = (params) =>
|
||||
post("/busUrbanFloodPoint/update", params);
|
||||
|
||||
/*
|
||||
*地质灾害点信息
|
||||
*/
|
||||
export const getGeologicalDisasterPage = (params) =>
|
||||
post("/busGeologicalDisaster/listPage", params);
|
||||
export const setGeologicalDisasterDelete = (params) =>
|
||||
post("/busGeologicalDisaster/delete", params);
|
||||
export const setGeologicalDisasterAdd = (params) =>
|
||||
post("/busGeologicalDisaster/save", params);
|
||||
export const setGeologicalDisasterUpdate = (params) =>
|
||||
post("/busGeologicalDisaster/update", params);
|
||||
|
||||
/*
|
||||
* 水库信息BusReservoirBasicEntity
|
||||
*/
|
||||
export const getReservoirBasicPage = (params) =>
|
||||
post("/busReservoirBasic/listPage", params);
|
||||
export const setReservoirBasicDelete = (params) =>
|
||||
post("/busReservoirBasic/delete", params);
|
||||
export const setReservoirBasicAdd = (params) =>
|
||||
post("/busReservoirBasic/save", params);
|
||||
export const setReservoirBasicUpdate = (params) =>
|
||||
post("/busReservoirBasic/update", params);
|
||||
|
||||
/*
|
||||
* 河流 BusRiverEntity
|
||||
*/
|
||||
export const getRiverPage = (params) => post("/busRiver/listPage", params);
|
||||
export const setRiverDelete = (params) => post("/busRiver/delete", params);
|
||||
export const setRiverAdd = (params) => post("/busRiver/save", params);
|
||||
export const setRiverUpdate = (params) => post("/busRiver/update", params);
|
||||
/*
|
||||
* 河道行洪隐患区村庄清单 BusRiverRiskVillagesEntity
|
||||
*/
|
||||
export const getRiverRiskVillagePage = (params) =>
|
||||
post("/busRiverRiskVillages/listPage", params);
|
||||
export const setRiverRiskVillageDelete = (params) =>
|
||||
post("/busRiverRiskVillages/delete", params);
|
||||
export const setRiverRiskVillageAdd = (params) =>
|
||||
post("/busRiverRiskVillages/save", params);
|
||||
export const setRiverRiskVillageUpdate = (params) =>
|
||||
post("/busRiverRiskVillages/update", params);
|
||||
/*
|
||||
* 河流县区段信息 BusRiverSectionsEntity
|
||||
*/
|
||||
export const setRiverSectionsListPage = (params) =>
|
||||
post("/busRiverSections/listPage", params);
|
||||
export const setRiverSectionsDelete = (params) =>
|
||||
post("/busRiverSections/delete", params);
|
||||
export const setRiverSectionsAdd = (params) =>
|
||||
post("/busRiverSections/save", params);
|
||||
export const setRiverSectionsUpdate = (params) =>
|
||||
post("/busRiverSections/update", params);
|
|
@ -0,0 +1,47 @@
|
|||
import { post } from "./axios";
|
||||
|
||||
export const getScheduleJobList = (params) =>
|
||||
post("/sys/schedule/list", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const getScheduleJobInfo = (params) =>
|
||||
post("/sys/schedule/info", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const addScheduleJob = (params) =>
|
||||
post("/sys/schedule/save", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const updateScheduleJob = (params) =>
|
||||
post("/sys/schedule/update", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const deleteScheduleJob = (params) =>
|
||||
post("/sys/schedule/delete", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const pauseScheduleJob = (params) =>
|
||||
post("/sys/schedule/pause", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const resumeScheduleJob = (params) =>
|
||||
post("/sys/schedule/resume", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const runScheduleJob = (params) =>
|
||||
post("/sys/schedule/run", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
||||
export const getPayCode = (params) =>
|
||||
post("/pay/getPayCode", {
|
||||
loading: false,
|
||||
...params,
|
||||
});
|
|
@ -0,0 +1,27 @@
|
|||
import { post } from "@/request/axios";
|
||||
|
||||
export const getRoleList = (params) => post("/sys/role/listPage", params); // 角色管理列表
|
||||
export const getRoleListAll = (params) => post("/sys/role/listAll", params); // 角色管理列表所有
|
||||
export const setRoleDelete = (params) => post("/sys/role/delete", params); // 角色管理删除
|
||||
export const setRoleAdd = (params) => post("/sys/role/save", params); // 角色管理添加
|
||||
export const setRoleEdit = (params) => post("/sys/role/update", params); // 角色管理修改
|
||||
export const getRoleView = (params) => post("/sys/role/info", params); // 角色管理查看
|
||||
export const getDataDictionaryList = (params) =>
|
||||
post("/sys/dictionaries/listPage", params); // 数据字典列表
|
||||
export const setDataDictionaryDelete = (params) =>
|
||||
post("/sys/dictionaries/delete", params); // 数据字典删除
|
||||
export const setDataDictionaryAdd = (params) =>
|
||||
post("/sys/dictionaries/save", params); // 数据字典添加
|
||||
export const setDataDictionaryEdit = (params) =>
|
||||
post("/sys/dictionaries/update", params); // 数据字典修改
|
||||
export const getDataDictionaryInfo = (params) =>
|
||||
post("/sys/dictionaries/info", params); // 数据字典查看
|
||||
export const getDataDictionaryRepeat = (params) =>
|
||||
post("/sys/dictionaries/findByBianma", params); // 数据字典验证编码是否重复
|
||||
export const getRouteList = (params) => post("/sys/menu/list", params); // 菜单管理列表
|
||||
export const getRouteView = (params) => post("/sys/menu/info", params); // 菜单管理查看
|
||||
export const setRouteAdd = (params) => post("/sys/menu/save", params); // 菜单管理添加
|
||||
export const setRouteEdit = (params) => post("/sys/menu/update", params); // 菜单管理修改
|
||||
export const setRouteDelete = (params) => post("/sys/menu/delete", params); // 菜单管理删除
|
||||
export const setRouteIcon = (params) => post("/sys/menu/icon", params); // 菜单管理修改图标
|
||||
export const getLogsListPage = (params) => post("/sys/log/list", params);
|
|
@ -0,0 +1,28 @@
|
|||
import { post, upload } from "@/request/axios";
|
||||
export const getDepartmentList = (params) =>
|
||||
post("/oa/department/listPage", params); // 部门管理列表
|
||||
export const setDepartmentDelete = (params) =>
|
||||
post("/oa/department/delete", params); // 部门管理删除
|
||||
export const setDepartmentAdd = (params) => post("/oa/department/save", params); // 部门管理添加
|
||||
export const setDepartmentEdit = (params) =>
|
||||
post("/oa/department/update", params); // 部门管理修改
|
||||
export const getDepartmentView = (params) =>
|
||||
post("/oa/department/info", params); // 部门管理查看
|
||||
export const getJobList = (params) => post("/oa/post/listPage", params); // 岗位管理列表
|
||||
export const getJobListAll = (params) => post("/oa/post/listAll", params); // 岗位管理列表所有
|
||||
export const setJobDelete = (params) => post("/oa/post/delete", params); // 岗位管理删除
|
||||
export const getJobView = (params) => post("/oa/post/info", params); // 岗位管理查看
|
||||
export const setJobAdd = (params) => post("/oa/post/save", params); // 岗位管理添加
|
||||
export const setJobEdit = (params) => post("/oa/post/update", params); // 岗位管理修改
|
||||
export const getUserList = (params) => post("/sys/user/list", params); // 用户管理列表
|
||||
export const getUserListAll = (params) => post("sys/user/listAll", params); // 用户管理列表所有
|
||||
export const setUserDelete = (params) => post("/sys/user/delete", params); // 用户管理删除
|
||||
export const setUserResetPassword = (params) =>
|
||||
post("/sys/user/resetPassword", params); // 用户管理重置密码
|
||||
export const getUserView = (params) => post("/sys/user/getInfo", params); // 用户管理查看
|
||||
export const getUserUserNameRepeat = (params) =>
|
||||
post("/sys/user/hasUser", params); // 用户管理用户名去重
|
||||
export const setUserAdd = (params) => upload("/sys/user/save", params); // 用户管理添加
|
||||
export const setUserEdit = (params) => upload("/sys/user/update", params); // 用户管理修改
|
||||
export const setUserExercisesImport = (params) =>
|
||||
upload("/sys/user/readExcel", params); // 人员导入
|
|
@ -12,7 +12,7 @@ const routes = [
|
|||
{
|
||||
path: "/",
|
||||
name: "app",
|
||||
redirect: "/map",
|
||||
redirect: "/login",
|
||||
meta: { isLogin: true },
|
||||
component: children,
|
||||
children: [
|
||||
|
@ -49,6 +49,109 @@ const routes = [
|
|||
meta: { title: "首页" },
|
||||
component: () => import("@/views/index/index"),
|
||||
},
|
||||
{
|
||||
path: "/river",
|
||||
name: "/river",
|
||||
meta: {
|
||||
title: "河流信息",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/river/index"),
|
||||
},
|
||||
{
|
||||
path: "/river/risk_village",
|
||||
name: "/river/risk_village",
|
||||
meta: {
|
||||
title: "河道行洪隐患区村庄",
|
||||
breadcrumb: true,
|
||||
isMenu: false,
|
||||
isSubMenu: true,
|
||||
isBack: true,
|
||||
activeMenu: "/river",
|
||||
},
|
||||
component: () => import("@/views/river/river_risk_village/index"),
|
||||
},
|
||||
{
|
||||
path: "/river/river_section",
|
||||
name: "/river/river_section",
|
||||
meta: {
|
||||
title: "河道流经县区",
|
||||
breadcrumb: true,
|
||||
isMenu: false,
|
||||
isSubMenu: true,
|
||||
isBack: true,
|
||||
activeMenu: "/river",
|
||||
},
|
||||
component: () => import("@/views/river/river_section/index"),
|
||||
},
|
||||
{
|
||||
path: "/reservoir_info",
|
||||
name: "/reservoir_info",
|
||||
meta: {
|
||||
title: "水库信息",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/reservoir_info/index"),
|
||||
},
|
||||
{
|
||||
path: "/geological_disaster",
|
||||
name: "/geological_disaster",
|
||||
meta: {
|
||||
title: "地质灾害点信息",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/geological_disaster/index"),
|
||||
},
|
||||
{
|
||||
path: "/urban_flood_point",
|
||||
name: "/urban_flood_point",
|
||||
meta: {
|
||||
title: "城市防涝点详情",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/urban_flood_point/index"),
|
||||
},
|
||||
{
|
||||
path: "/mountain_flood_info",
|
||||
name: "/mountain_flood_info",
|
||||
meta: {
|
||||
title: "山洪灾害村",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/mountain_flood_info/index"),
|
||||
},
|
||||
{
|
||||
path: "/emergency_storage",
|
||||
name: "/emergency_storage",
|
||||
meta: {
|
||||
title: "应急储备库信息",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/emergency_storage/index"),
|
||||
},
|
||||
{
|
||||
path: "/system_management/data_dictionary",
|
||||
name: "/system_management/data_dictionary",
|
||||
meta: {
|
||||
title: "数据字典",
|
||||
breadcrumb: true,
|
||||
isMenu: true,
|
||||
isSubMenu: false,
|
||||
},
|
||||
component: () => import("@/views/system_management/data_dictionary/index"),
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="100px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="应急库名称" prop="storageName">
|
||||
<el-input
|
||||
v-model="form.storageName"
|
||||
placeholder="请输入应急库名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="form.area"
|
||||
v-model:name="form.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="应急库类型" prop="storageType">
|
||||
<el-select
|
||||
v-model="form.storageType"
|
||||
placeholder="请选择应急库类型"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in storageTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="管理单位" prop="managementUnit">
|
||||
<el-input
|
||||
v-model="form.managementUnit"
|
||||
placeholder="请输入应急库名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<div style="display: flex">
|
||||
<el-form-item label="经度" prop="longitude" style="flex: 1">
|
||||
<el-input v-model="form.longitude" placeholder="请选择经度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度" prop="latitude" style="flex: 1">
|
||||
<el-input v-model="form.latitude" placeholder="请选择纬度" />
|
||||
</el-form-item>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button
|
||||
class="ml-10"
|
||||
type="primary"
|
||||
@click="fnSelectedPosition(form)"
|
||||
>
|
||||
点击定位
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
|
||||
<app-map
|
||||
v-model:visible="mapDialog.visible"
|
||||
v-model:longitude="mapDialog.longitude"
|
||||
v-model:latitude="mapDialog.latitude"
|
||||
@submit="fnMapSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import AppMap from "@/components/map/map.vue";
|
||||
import {
|
||||
setEmergencyStorageAdd,
|
||||
setEmergencyStorageUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
const storageTypeList = ref([]);
|
||||
const fnGetStorageTypeList = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y",
|
||||
});
|
||||
storageTypeList.value = resData.dictionariesList;
|
||||
};
|
||||
fnGetStorageTypeList();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const data = reactive({
|
||||
rules: {
|
||||
storageName: [
|
||||
{ required: true, message: "请输入应急库名称", trigger: "blur" },
|
||||
],
|
||||
area: [{ required: true, message: "请输入应急库区域", trigger: "blur" }],
|
||||
longitude: [{ required: true, message: "请输入经度", trigger: "blur" }],
|
||||
latitude: [{ required: true, message: "请输入纬度", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const mapDialog = ref({
|
||||
visible: false,
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
});
|
||||
const fnSelectedPosition = ({ longitude, latitude }) => {
|
||||
mapDialog.value.visible = true;
|
||||
mapDialog.value.longitude = longitude;
|
||||
mapDialog.value.latitude = latitude;
|
||||
};
|
||||
const fnMapSubmit = ({ longitude, latitude }) => {
|
||||
form.value.longitude = longitude;
|
||||
form.value.latitude = latitude;
|
||||
};
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const form = props.form;
|
||||
const param = {
|
||||
...form,
|
||||
areaName: form.areaName.join("-"),
|
||||
province: form.area[0],
|
||||
city: form.area[1],
|
||||
county: form.area[2],
|
||||
village: form.area[3],
|
||||
street: form.area[4],
|
||||
};
|
||||
delete param.area;
|
||||
if (props.type === "add") {
|
||||
await setEmergencyStorageAdd({
|
||||
...param,
|
||||
});
|
||||
}
|
||||
if (props.type === "edit")
|
||||
await setEmergencyStorageUpdate({
|
||||
...param,
|
||||
});
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="应急库名称" prop="storageName">
|
||||
<el-input
|
||||
v-model="searchForm.storageName"
|
||||
placeholder="请输入应急库名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="searchForm.area"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="true"
|
||||
:level="5"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="应急库类型" prop="storageType">
|
||||
<el-select
|
||||
v-model="searchForm.storageType"
|
||||
placeholder="请选择矿山类别"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in storageTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="storageName" label="应急库名称" />
|
||||
<el-table-column prop="areaName" label="属地" />
|
||||
<el-table-column prop="storageTypeName" label="应急库类型" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.emergencyStorageId)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')">
|
||||
新增
|
||||
</el-button>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick } from "vue";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import {
|
||||
getEmergencyStoragePage,
|
||||
setEmergencyStorageDelete,
|
||||
} from "@/request/kangzai.js";
|
||||
import Add from "./components/add.vue";
|
||||
|
||||
const storageTypeList = ref([]);
|
||||
const fnGetStorageTypeList = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y",
|
||||
});
|
||||
storageTypeList.value = resData.dictionariesList;
|
||||
};
|
||||
fnGetStorageTypeList();
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
getEmergencyStoragePage,
|
||||
{
|
||||
beforeGetData: (searchForm) => {
|
||||
const area = searchForm.area || [];
|
||||
|
||||
searchForm.province = area[0];
|
||||
searchForm.city = area[1];
|
||||
searchForm.county = area[2];
|
||||
searchForm.village = area[3];
|
||||
searchForm.street = area[4];
|
||||
},
|
||||
callback: (list) => {
|
||||
list.forEach((item) => {
|
||||
item.storageTypeName = storageTypeList.value.filter((temp) => {
|
||||
return temp.bianma === item.storageType;
|
||||
})[0]?.name;
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
storageName: "",
|
||||
storageType: "",
|
||||
area: [],
|
||||
areaName: [],
|
||||
managementUnit: "",
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (emergencyStorageId) => {
|
||||
await ElMessageBox.confirm(`确定要删除吗?`, {
|
||||
type: "warning",
|
||||
});
|
||||
await setEmergencyStorageDelete({ emergencyStorageId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.form = {};
|
||||
data.addOrEditDialog.type = type;
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = row;
|
||||
data.addOrEditDialog.form.area = [
|
||||
row.province,
|
||||
row.city,
|
||||
row.county,
|
||||
row.village,
|
||||
row.street,
|
||||
];
|
||||
data.addOrEditDialog.form.areaName = row.areaName.split("-");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,353 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="100px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="灾害点名称" prop="disasterName">
|
||||
<el-input
|
||||
v-model="form.disasterName"
|
||||
placeholder="请输入灾害点名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="form.area"
|
||||
v-model:name="form.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="地形地貌" prop="terrain">
|
||||
<el-select v-model="form.terrain" placeholder="请选择地形地貌">
|
||||
<el-option
|
||||
v-for="item in terrainList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="灾害类型" prop="disasterType">
|
||||
<el-select v-model="form.disasterType" placeholder="请选择灾害类型">
|
||||
<el-option
|
||||
v-for="item in disasterTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="规模" prop="scale">
|
||||
<el-select v-model="form.scale" placeholder="请选择规模">
|
||||
<el-option
|
||||
v-for="item in scaleList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="稳定性" prop="stability">
|
||||
<el-select v-model="form.stability" placeholder="请选择稳定性">
|
||||
<el-option
|
||||
v-for="item in stabilityList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="户数" prop="households">
|
||||
<el-input-number
|
||||
v-model="form.households"
|
||||
placeholder="请输入户数"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="人口数" prop="population">
|
||||
<el-input-number
|
||||
v-model="form.population"
|
||||
placeholder="请输入人口数"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="险情等级" prop="dangerousSituation">
|
||||
<el-select
|
||||
v-model="form.dangerousSituation"
|
||||
placeholder="请选择险情等级"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dangerousSituationList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="勘察情况" prop="surveySituation">
|
||||
<el-input
|
||||
v-model="form.surveySituation"
|
||||
placeholder="请输入勘察情况"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="治理情况" prop="governanceSituation">
|
||||
<el-input
|
||||
v-model="form.governanceSituation"
|
||||
placeholder="请输入治理情况"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="搬迁情况" prop="relocationSituation">
|
||||
<el-input
|
||||
v-model="form.relocationSituation"
|
||||
placeholder="请输入搬迁情况"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="风险等级" prop="riskLevel">
|
||||
<el-select v-model="form.riskLevel" placeholder="请选择风险等级">
|
||||
<el-option label="低风险" value="1" />
|
||||
<el-option label="中风险" value="2" />
|
||||
<el-option label="高风险" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="规模与形态描述" prop="scaleDescription">
|
||||
<el-input
|
||||
v-model="form.scaleDescription"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入规模与形态描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<div style="display: flex">
|
||||
<el-form-item label="经度" prop="longitude" style="flex: 1">
|
||||
<el-input v-model="form.longitude" placeholder="请选择经度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度" prop="latitude" style="flex: 1">
|
||||
<el-input v-model="form.latitude" placeholder="请选择纬度" />
|
||||
</el-form-item>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button
|
||||
class="ml-10"
|
||||
type="primary"
|
||||
@click="fnSelectedPosition"
|
||||
>点击定位</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
|
||||
<app-map
|
||||
v-model:visible="mapDialog.visible"
|
||||
v-model:longitude="mapDialog.longitude"
|
||||
v-model:latitude="mapDialog.latitude"
|
||||
@submit="fnMapSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import AppMap from "@/components/map/map.vue";
|
||||
import {
|
||||
setGeologicalDisasterAdd,
|
||||
setGeologicalDisasterUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
// 字典数据
|
||||
const terrainList = ref([]);
|
||||
const disasterTypeList = ref([]);
|
||||
const scaleList = ref([]);
|
||||
const stabilityList = ref([]);
|
||||
const dangerousSituationList = ref([]);
|
||||
|
||||
const fnGetDictData = async () => {
|
||||
const [
|
||||
terrainRes,
|
||||
disasterTypeRes,
|
||||
scaleRes,
|
||||
stabilityRes,
|
||||
dangerousSituationRes,
|
||||
] = await Promise.all([
|
||||
getDataDictionary({ parentId: "b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q" }),
|
||||
getDataDictionary({ parentId: "c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r" }),
|
||||
getDataDictionary({ parentId: "7d3a1b2c8e4f5947a6b0c8d9e0f1a2b3" }),
|
||||
getDataDictionary({ parentId: "a4f5c6d7e8291047b3a2b1c0d9e8f7a6" }),
|
||||
getDataDictionary({ parentId: "c8e9f0a1b2c347d56e7f8a9b0c1d2e3f" }),
|
||||
]);
|
||||
terrainList.value = terrainRes.dictionariesList;
|
||||
disasterTypeList.value = disasterTypeRes.dictionariesList;
|
||||
scaleList.value = scaleRes.dictionariesList;
|
||||
stabilityList.value = stabilityRes.dictionariesList;
|
||||
dangerousSituationList.value = dangerousSituationRes.dictionariesList;
|
||||
};
|
||||
fnGetDictData();
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
disasterName: [
|
||||
{ required: true, message: "请输入灾害点名称", trigger: "blur" },
|
||||
],
|
||||
area: [{ required: true, message: "请选择区域", trigger: "blur" }],
|
||||
disasterType: [
|
||||
{ required: true, message: "请选择灾害类型", trigger: "change" },
|
||||
],
|
||||
scale: [{ required: true, message: "请选择规模", trigger: "change" }],
|
||||
stability: [{ required: true, message: "请选择稳定性", trigger: "change" }],
|
||||
households: [{ required: true, message: "请输入户数", trigger: "blur" }],
|
||||
population: [{ required: true, message: "请输入人口数", trigger: "blur" }],
|
||||
dangerousSituation: [
|
||||
{ required: true, message: "请选择险情等级", trigger: "change" },
|
||||
],
|
||||
surveySituation: [
|
||||
{ required: true, message: "请选择勘察情况", trigger: "change" },
|
||||
],
|
||||
governanceSituation: [
|
||||
{ required: true, message: "请选择治理情况", trigger: "change" },
|
||||
],
|
||||
relocationSituation: [
|
||||
{ required: true, message: "请选择搬迁情况", trigger: "change" },
|
||||
],
|
||||
riskLevel: [
|
||||
{ required: true, message: "请选择风险等级", trigger: "change" },
|
||||
],
|
||||
longitude: [{ required: true, message: "请输入经度", trigger: "blur" }],
|
||||
latitude: [{ required: true, message: "请输入纬度", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const mapDialog = ref({
|
||||
visible: false,
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
});
|
||||
const fnSelectedPosition = () => {
|
||||
mapDialog.value.visible = true;
|
||||
mapDialog.value.longitude = form.value.longitude;
|
||||
mapDialog.value.latitude = form.value.latitude;
|
||||
};
|
||||
const fnMapSubmit = ({ longitude, latitude }) => {
|
||||
form.value.longitude = longitude;
|
||||
form.value.latitude = latitude;
|
||||
};
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const param = {
|
||||
...form.value,
|
||||
areaName: form.value.areaName.join("-"),
|
||||
province: form.value.area[0],
|
||||
city: form.value.area[1],
|
||||
county: form.value.area[2],
|
||||
village: form.value.area[3],
|
||||
street: form.value.area[4],
|
||||
};
|
||||
delete param.area;
|
||||
|
||||
if (props.type === "add") {
|
||||
await setGeologicalDisasterAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setGeologicalDisasterUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,199 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="灾害点名称" prop="disasterName">
|
||||
<el-input
|
||||
v-model="searchForm.disasterName"
|
||||
placeholder="请输入灾害点名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="searchForm.area"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="true"
|
||||
:level="5"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="地形地貌" prop="terrain">
|
||||
<el-select v-model="searchForm.terrain" placeholder="请选择地形地貌">
|
||||
<el-option
|
||||
v-for="item in terrainList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="灾害类型" prop="disasterType">
|
||||
<el-select
|
||||
v-model="searchForm.disasterType"
|
||||
placeholder="请选择灾害类型"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in disasterTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="disasterName" label="灾害点名称" />
|
||||
<el-table-column prop="areaName" label="属地" />
|
||||
<el-table-column prop="terrainName" label="地形地貌" />
|
||||
<el-table-column prop="disasterTypeName" label="灾害类型" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.geologicalDisasterId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick } from "vue";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import {
|
||||
getGeologicalDisasterPage,
|
||||
setGeologicalDisasterDelete,
|
||||
} from "@/request/kangzai.js";
|
||||
import Add from "./components/add.vue";
|
||||
|
||||
const terrainList = ref([]);
|
||||
const disasterTypeList = ref([]);
|
||||
|
||||
const fnGetDictData = async () => {
|
||||
const [terrainRes, disasterTypeRes] = await Promise.all([
|
||||
getDataDictionary({ parentId: "b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q" }),
|
||||
getDataDictionary({ parentId: "c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r" }),
|
||||
]);
|
||||
terrainList.value = terrainRes.dictionariesList;
|
||||
disasterTypeList.value = disasterTypeRes.dictionariesList;
|
||||
};
|
||||
fnGetDictData();
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
getGeologicalDisasterPage,
|
||||
{
|
||||
beforeGetData: (searchForm) => {
|
||||
const area = searchForm.area || [];
|
||||
searchForm.province = area[0];
|
||||
searchForm.city = area[1];
|
||||
searchForm.county = area[2];
|
||||
searchForm.village = area[3];
|
||||
searchForm.street = area[4];
|
||||
},
|
||||
callback: (list) => {
|
||||
list.forEach((item) => {
|
||||
item.terrainName =
|
||||
terrainList.value.find((dict) => dict.bianma === item.terrain)
|
||||
?.name || item.terrain;
|
||||
item.disasterTypeName =
|
||||
disasterTypeList.value.find(
|
||||
(dict) => dict.bianma === item.disasterType
|
||||
)?.name || item.disasterType;
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
disasterName: "",
|
||||
province: "",
|
||||
city: "",
|
||||
county: "",
|
||||
village: "",
|
||||
street: "",
|
||||
area: [],
|
||||
areaName: [],
|
||||
terrain: "",
|
||||
disasterType: "",
|
||||
scaleDescription: "",
|
||||
scale: "",
|
||||
stability: "",
|
||||
households: "",
|
||||
population: "",
|
||||
dangerousSituation: "",
|
||||
surveySituation: "",
|
||||
governanceSituation: "",
|
||||
relocationSituation: "",
|
||||
riskLevel: "",
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = async (geologicalDisasterId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setGeologicalDisasterDelete({ geologicalDisasterId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.form = {};
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = row;
|
||||
data.addOrEditDialog.form.area = [
|
||||
row.province,
|
||||
row.city,
|
||||
row.county,
|
||||
row.village,
|
||||
row.street,
|
||||
];
|
||||
data.addOrEditDialog.form.areaName = row.areaName.split("-");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,412 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="160px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="村庄名称" prop="villageName">
|
||||
<el-input v-model="form.villageName" placeholder="请输入村庄名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="form.area"
|
||||
v-model:name="form.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="县级预警负责人" prop="countyWarningOfficer">
|
||||
<el-input
|
||||
v-model="form.countyWarningOfficer"
|
||||
placeholder="请输入预警负责人"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="县级预警负责人电话" prop="countyWarningPhone">
|
||||
<el-input
|
||||
v-model="form.countyWarningPhone"
|
||||
placeholder="请输入县级预警负责人电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="县级责任人" prop="countyOfficer">
|
||||
<el-input
|
||||
v-model="form.countyOfficer"
|
||||
placeholder="请输入县级责任人"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="县级责任人职务" prop="countyOfficerPosition">
|
||||
<el-input
|
||||
v-model="form.countyOfficerPosition"
|
||||
placeholder="请输入县级责任人职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="县级责任人电话" prop="countyOfficerPhone">
|
||||
<el-input
|
||||
v-model="form.countyOfficerPhone"
|
||||
placeholder="请输入县级责任人电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="乡级责任人" prop="townshipOfficer">
|
||||
<el-input
|
||||
v-model="form.townshipOfficer"
|
||||
placeholder="请输入乡级责任人姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="乡级责任人职务" prop="townshipOfficerPosition">
|
||||
<el-input
|
||||
v-model="form.townshipOfficerPosition"
|
||||
placeholder="请输入乡级责任人职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="乡级责任人电话" prop="townshipOfficerPhone">
|
||||
<el-input
|
||||
v-model="form.townshipOfficerPhone"
|
||||
placeholder="请输入乡级责任人电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="村级责任人" prop="villageOfficer">
|
||||
<el-input
|
||||
v-model="form.villageOfficer"
|
||||
placeholder="请输入村级责任人姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="村级责任人职务" prop="villageOfficerPosition">
|
||||
<el-input
|
||||
v-model="form.villageOfficerPosition"
|
||||
placeholder="请输入村级责任人职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="村级责任人电话" prop="villageOfficerPhone">
|
||||
<el-input
|
||||
v-model="form.villageOfficerPhone"
|
||||
placeholder="请输入村级责任人电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="监测员姓名" prop="monitorName">
|
||||
<el-input
|
||||
v-model="form.monitorName"
|
||||
placeholder="请输入监测员姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="监测员职务" prop="monitorPosition">
|
||||
<el-input
|
||||
v-model="form.monitorPosition"
|
||||
placeholder="请输入监测员职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="监测员电话" prop="monitorPhone">
|
||||
<el-input
|
||||
v-model="form.monitorPhone"
|
||||
placeholder="请输入监测员电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="预警员姓名" prop="warningOfficerName">
|
||||
<el-input
|
||||
v-model="form.warningOfficerName"
|
||||
placeholder="请输入请输入预警员姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="预警员职务" prop="warningOfficerPosition">
|
||||
<el-input
|
||||
v-model="form.warningOfficerPosition"
|
||||
placeholder="请输入预警员职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="请输入预警员电话" prop="warningOfficerPhone">
|
||||
<el-input
|
||||
v-model="form.warningOfficerPhone"
|
||||
placeholder="请输入请输入预警员电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="转移员姓名" prop="transferOfficerName">
|
||||
<el-input
|
||||
v-model="form.transferOfficerName"
|
||||
placeholder="请输入转移员姓名"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="转移员职务" prop="transferOfficerPosition">
|
||||
<el-input
|
||||
v-model="form.transferOfficerPosition"
|
||||
placeholder="请输入转移员职务"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="转移员电话" prop="transferOfficerPhone">
|
||||
<el-input
|
||||
v-model="form.transferOfficerPhone"
|
||||
placeholder="请输入转移员电话"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<div style="display: flex">
|
||||
<el-form-item label="经度" prop="longitude" style="flex: 1">
|
||||
<el-input v-model="form.longitude" placeholder="请选择经度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度" prop="latitude" style="flex: 1">
|
||||
<el-input v-model="form.latitude" placeholder="请选择纬度" />
|
||||
</el-form-item>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button
|
||||
class="ml-10"
|
||||
type="primary"
|
||||
@click="fnSelectedPosition(form)"
|
||||
>点击定位</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
|
||||
<app-map
|
||||
v-model:visible="mapDialog.visible"
|
||||
v-model:longitude="mapDialog.longitude"
|
||||
v-model:latitude="mapDialog.latitude"
|
||||
@submit="fnMapSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import AppMap from "@/components/map/map.vue";
|
||||
import {
|
||||
setMountainFloodVillageAdd,
|
||||
setMountainFloodVillageUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
villageName: [
|
||||
{ required: true, message: "请输入村庄名称", trigger: "blur" },
|
||||
],
|
||||
area: [{ required: true, message: "请输入村庄区域", trigger: "blur" }],
|
||||
countyWarningOfficer: [
|
||||
{ required: true, message: "请输入县级预警负责人", trigger: "blur" },
|
||||
],
|
||||
countyWarningOfficerPhone: [
|
||||
{ required: true, message: "请输入县级预警负责人手机号", trigger: "blur" },
|
||||
],
|
||||
countyOfficer: [
|
||||
{ required: true, message: "请输入县级责任人姓名", trigger: "blur" },
|
||||
],
|
||||
countyOfficerPosition: [
|
||||
{ required: true, message: "请输入县级责任人职务", trigger: "blur" },
|
||||
],
|
||||
countyOfficerPhone: [
|
||||
{ required: true, message: "请输入县级责任人电话", trigger: "blur" },
|
||||
],
|
||||
townshipOfficer: [
|
||||
{ required: true, message: "请输入乡级责任人姓名", trigger: "blur" },
|
||||
],
|
||||
townshipOfficerPosition: [
|
||||
{ required: true, message: "请输入乡级责任人职务", trigger: "blur" },
|
||||
],
|
||||
townshipOfficerPhone: [
|
||||
{ required: true, message: "请输入乡级责任人电话", trigger: "blur" },
|
||||
],
|
||||
villageOfficer: [
|
||||
{ required: true, message: "请输入村级责任人姓名", trigger: "blur" },
|
||||
],
|
||||
villageOfficerPosition: [
|
||||
{ required: true, message: "请输入村级责任人职务", trigger: "blur" },
|
||||
],
|
||||
villageOfficerPhone: [
|
||||
{ required: true, message: "请输入村级责任人电话", trigger: "blur" },
|
||||
],
|
||||
monitorName: [
|
||||
{ required: true, message: "请输入监测员姓名", trigger: "blur" },
|
||||
],
|
||||
monitorPosition: [
|
||||
{ required: true, message: "请输入监测员职务", trigger: "blur" },
|
||||
],
|
||||
monitorPhone: [
|
||||
{ required: true, message: "请输入监测员电话", trigger: "blur" },
|
||||
],
|
||||
warningOfficerName: [
|
||||
{ required: true, message: "请输入预警员姓名", trigger: "blur" },
|
||||
],
|
||||
warningOfficerPosition: [
|
||||
{ required: true, message: "请输入预警员职务", trigger: "blur" },
|
||||
],
|
||||
warningOfficerPhone: [
|
||||
{ required: true, message: "请输入预警员电话", trigger: "blur" },
|
||||
],
|
||||
transferOfficerName: [
|
||||
{ required: true, message: "请输入转移员姓名", trigger: "blur" },
|
||||
],
|
||||
transferOfficerPosition: [
|
||||
{ required: true, message: "请输入转移员职务", trigger: "blur" },
|
||||
],
|
||||
transferOfficerPhone: [
|
||||
{ required: true, message: "请输入转移员电话", trigger: "blur" },
|
||||
],
|
||||
longitude: [{ required: true, message: "请输入经度", trigger: "blur" }],
|
||||
latitude: [{ required: true, message: "请输入纬度", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const mapDialog = ref({
|
||||
visible: false,
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
});
|
||||
const fnSelectedPosition = ({ longitude, latitude }) => {
|
||||
mapDialog.value.visible = true;
|
||||
mapDialog.value.longitude = longitude;
|
||||
mapDialog.value.latitude = latitude;
|
||||
};
|
||||
const fnMapSubmit = ({ longitude, latitude }) => {
|
||||
form.value.longitude = longitude;
|
||||
form.value.latitude = latitude;
|
||||
};
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const param = {
|
||||
...form.value,
|
||||
areaName: form.value.areaName.join("-"),
|
||||
province: form.value.area[0],
|
||||
city: form.value.area[1],
|
||||
county: form.value.area[2],
|
||||
village: form.value.area[3],
|
||||
street: form.value.area[4],
|
||||
};
|
||||
delete param.area;
|
||||
|
||||
if (props.type === "add") {
|
||||
await setMountainFloodVillageAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setMountainFloodVillageUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="村庄名称" prop="villageName">
|
||||
<el-input
|
||||
v-model="searchForm.villageName"
|
||||
placeholder="请输入村庄名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="searchForm.area"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="true"
|
||||
:level="5"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="预警负责人" prop="countyWarningOfficer">
|
||||
<el-input
|
||||
v-model="searchForm.countyWarningOfficer"
|
||||
placeholder="请输入预警负责人"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="villageName" label="村庄名称" />
|
||||
<el-table-column prop="areaName" label="属地" />
|
||||
<el-table-column prop="countyWarningOfficer" label="县级预警负责人" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.mountainFloodVillageId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, nextTick } from "vue";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import {
|
||||
getMountainFloodVillagePage,
|
||||
setMountainFloodVillageDelete,
|
||||
} from "@/request/kangzai.js";
|
||||
import Add from "./components/add.vue";
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
getMountainFloodVillagePage,
|
||||
{
|
||||
beforeGetData: (searchForm) => {
|
||||
const area = searchForm.area || [];
|
||||
|
||||
searchForm.province = area[0];
|
||||
searchForm.city = area[1];
|
||||
searchForm.county = area[2];
|
||||
searchForm.village = area[3];
|
||||
searchForm.street = area[4];
|
||||
},
|
||||
callback: () => {},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
villageName: "",
|
||||
province: "",
|
||||
city: "",
|
||||
county: "",
|
||||
village: "",
|
||||
street: "",
|
||||
area: [],
|
||||
areaName: [],
|
||||
// 责任人信息
|
||||
countyWarningOfficer: "",
|
||||
countyWarningPhone: "",
|
||||
countyOfficer: "",
|
||||
countyOfficerPosition: "",
|
||||
countyOfficerPhone: "",
|
||||
townshipOfficer: "",
|
||||
townshipOfficerPosition: "",
|
||||
townshipOfficerPhone: "",
|
||||
villageOfficer: "",
|
||||
villageOfficerPosition: "",
|
||||
villageOfficerPhone: "",
|
||||
// 其他人员
|
||||
monitorName: "",
|
||||
monitorPosition: "",
|
||||
monitorPhone: "",
|
||||
remarks: "",
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = debounce(
|
||||
1000,
|
||||
async (mountainFloodVillageId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setMountainFloodVillageDelete({ mountainFloodVillageId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.form = {};
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = row;
|
||||
data.addOrEditDialog.form.area = [
|
||||
row.province,
|
||||
row.city,
|
||||
row.county,
|
||||
row.village,
|
||||
row.street,
|
||||
];
|
||||
data.addOrEditDialog.form.areaName = row.areaName.split("-");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,212 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="200px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="水库名称" prop="reservoirName">
|
||||
<el-input
|
||||
v-model="form.reservoirName"
|
||||
placeholder="请输入水库名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="水库类型" prop="reservoirType">
|
||||
<el-select
|
||||
v-model="form.reservoirType"
|
||||
placeholder="请选择水库类型"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in reservoirTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="水库等级" prop="reservoirLevel">
|
||||
<el-select
|
||||
v-model="form.reservoirLevel"
|
||||
placeholder="请选择水库等级"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in reservoirLevelList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="极限库容(万立方米)" prop="maxCapacity">
|
||||
<el-input v-model="form.maxCapacity" placeholder="请输入极限库容" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="当前库容(万立方米)" prop="currentCapacity">
|
||||
<el-input
|
||||
v-model="form.currentCapacity"
|
||||
placeholder="请输入当前库容"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<div style="display: flex">
|
||||
<el-form-item label="经度" prop="longitude" style="flex: 1">
|
||||
<el-input v-model="form.longitude" placeholder="请选择经度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度" prop="latitude" style="flex: 1">
|
||||
<el-input v-model="form.latitude" placeholder="请选择纬度" />
|
||||
</el-form-item>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button
|
||||
class="ml-10"
|
||||
type="primary"
|
||||
@click="fnSelectedPosition"
|
||||
>点击定位</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
|
||||
<app-map
|
||||
v-model:visible="mapDialog.visible"
|
||||
v-model:longitude="mapDialog.longitude"
|
||||
v-model:latitude="mapDialog.latitude"
|
||||
@submit="fnMapSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import AppMap from "@/components/map/map.vue";
|
||||
import {
|
||||
setReservoirBasicAdd,
|
||||
setReservoirBasicUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
// 字典数据
|
||||
const reservoirTypeList = ref([]);
|
||||
const reservoirLevelList = ref([]);
|
||||
|
||||
const fnGetDictData = async () => {
|
||||
const [typeRes, levelRes] = await Promise.all([
|
||||
getDataDictionary({ parentId: "848f91ce29ee1f2d078bc6ec69d440df" }),
|
||||
getDataDictionary({ parentId: "a8b7c6d5e4f3g2h1i0j9k8l7m6n5o4p" }),
|
||||
]);
|
||||
reservoirTypeList.value = typeRes.dictionariesList;
|
||||
reservoirLevelList.value = levelRes.dictionariesList;
|
||||
};
|
||||
fnGetDictData();
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
reservoirName: [
|
||||
{ required: true, message: "请输入水库名称", trigger: "blur" },
|
||||
],
|
||||
reservoirType: [
|
||||
{ required: true, message: "请选择水库类型", trigger: "change" },
|
||||
],
|
||||
reservoirLevel: [
|
||||
{ required: true, message: "请选择水库等级", trigger: "change" },
|
||||
],
|
||||
longitude: [{ required: true, message: "请输入经度", trigger: "blur" }],
|
||||
latitude: [{ required: true, message: "请输入纬度", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const mapDialog = ref({
|
||||
visible: false,
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
});
|
||||
const fnSelectedPosition = () => {
|
||||
mapDialog.value.visible = true;
|
||||
mapDialog.value.longitude = form.value.longitude;
|
||||
mapDialog.value.latitude = form.value.latitude;
|
||||
};
|
||||
const fnMapSubmit = ({ longitude, latitude }) => {
|
||||
form.value.longitude = longitude;
|
||||
form.value.latitude = latitude;
|
||||
};
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const param = {
|
||||
...form.value,
|
||||
};
|
||||
|
||||
if (props.type === "add") {
|
||||
await setReservoirBasicAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setReservoirBasicUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,161 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="水库名称" prop="reservoirName">
|
||||
<el-input
|
||||
v-model="searchForm.reservoirName"
|
||||
placeholder="请输入水库名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="水库类型" prop="reservoirType">
|
||||
<el-select
|
||||
v-model="searchForm.reservoirType"
|
||||
placeholder="请选择水库类型"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in reservoirTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="水库等级" prop="reservoirLevel">
|
||||
<el-select
|
||||
v-model="searchForm.reservoirLevel"
|
||||
placeholder="请选择水库等级"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in reservoirLevelList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="reservoirName" label="水库名称" />
|
||||
<el-table-column label="水库类型" prop="reservoirTypeLabel" />
|
||||
<el-table-column label="水库等级" prop="reservoirLevelLabel" />
|
||||
<el-table-column prop="maxCapacity" label="极限库容(万立方米)" />
|
||||
<el-table-column prop="currentCapacity" label="当前库容(万立方米)" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.reservoirBasicId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick } from "vue";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import {
|
||||
getReservoirBasicPage,
|
||||
setReservoirBasicDelete,
|
||||
} from "@/request/kangzai.js";
|
||||
import Add from "./components/add.vue";
|
||||
|
||||
const reservoirTypeList = ref([]);
|
||||
const reservoirLevelList = ref([]);
|
||||
|
||||
const fnGetDictData = async () => {
|
||||
const [typeRes, levelRes] = await Promise.all([
|
||||
getDataDictionary({ parentId: "848f91ce29ee1f2d078bc6ec69d440df" }),
|
||||
getDataDictionary({ parentId: "a8b7c6d5e4f3g2h1i0j9k8l7m6n5o4p" }),
|
||||
]);
|
||||
reservoirTypeList.value = typeRes.dictionariesList;
|
||||
reservoirLevelList.value = levelRes.dictionariesList;
|
||||
};
|
||||
fnGetDictData();
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
getReservoirBasicPage,
|
||||
{
|
||||
callback: (list) => {
|
||||
list.forEach((item) => {
|
||||
item.reservoirTypeLabel =
|
||||
reservoirTypeList.value.find(
|
||||
(dict) => dict.bianma === item.reservoirType
|
||||
)?.name || item.reservoirType;
|
||||
item.reservoirLevelLabel =
|
||||
reservoirLevelList.value.find(
|
||||
(dict) => dict.bianma === item.reservoirLevel
|
||||
)?.name || item.reservoirLevel;
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
reservoirName: "",
|
||||
reservoirType: "",
|
||||
reservoirLevel: "",
|
||||
maxCapacity: "",
|
||||
currentCapacity: "",
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = async (reservoirBasicId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setReservoirBasicDelete({ reservoirBasicId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.form = {};
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = row;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="200px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="河流名称" prop="riverName">
|
||||
<el-input v-model="form.riverName" placeholder="请输入河流名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="全长(km)" prop="totalLength">
|
||||
<el-input
|
||||
v-model.number="form.totalLength"
|
||||
placeholder="请输入全长(km)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="流域面积(km²)" prop="basinArea">
|
||||
<el-input
|
||||
v-model.number="form.basinArea"
|
||||
placeholder="请输入流域面积(km²)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item
|
||||
label="占全市国土面积百分比(%)"
|
||||
prop="cityAreaPercentage"
|
||||
>
|
||||
<el-input
|
||||
v-model.number="form.cityAreaPercentage"
|
||||
placeholder="请输入百分比"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="我市境内河长(km)" prop="inCityRiverLength">
|
||||
<el-input
|
||||
v-model.number="form.inCityRiverLength"
|
||||
placeholder="请输入境内河长(km)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="我市境内流域面积(km²)" prop="inCityBasinArea">
|
||||
<el-input
|
||||
v-model.number="form.inCityBasinArea"
|
||||
placeholder="请输入境内流域面积(km²)"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import { setRiverAdd, setRiverUpdate } from "@/request/kangzai.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
riverName: [{ required: true, message: "请输入河流名称", trigger: "blur" }],
|
||||
totalLength: [
|
||||
{ required: true, message: "请输入全长(km)", trigger: "blur" },
|
||||
],
|
||||
basinArea: [
|
||||
{ required: true, message: "请输入流域面积(km²)", trigger: "blur" },
|
||||
],
|
||||
cityAreaPercentage: [
|
||||
{ required: true, message: "请输入百分比(%)", trigger: "blur" },
|
||||
],
|
||||
inCityRiverLength: [
|
||||
{ required: true, message: "请输入境内河长(km)", trigger: "blur" },
|
||||
],
|
||||
inCityBasinArea: [
|
||||
{ required: true, message: "请输入境内流域面积(km²)", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const param = { ...form.value };
|
||||
|
||||
if (props.type === "add") {
|
||||
await setRiverAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setRiverUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="河流名称" prop="riverName">
|
||||
<el-input
|
||||
v-model="searchForm.riverName"
|
||||
placeholder="请输入河流名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="全长(km)" prop="totalLength">
|
||||
<el-input v-model="searchForm.totalLength" placeholder="请输入全长" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="流域面积(km²)" prop="basinArea">
|
||||
<el-input
|
||||
v-model="searchForm.basinArea"
|
||||
placeholder="请输入流域面积"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="riverName" label="河流名称" />
|
||||
<el-table-column prop="totalLength" label="全长(km)" />
|
||||
<el-table-column prop="basinArea" label="流域面积(km²)" />
|
||||
<el-table-column
|
||||
prop="cityAreaPercentage"
|
||||
label="占全市国土面积百分比(%)"
|
||||
/>
|
||||
<el-table-column prop="inCityRiverLength" label="我市境内河长(km)" />
|
||||
<el-table-column prop="inCityBasinArea" label="我市境内流域面积(km²)" />
|
||||
<el-table-column prop="countyCount" label="流经区县数" />
|
||||
<el-table-column prop="riskVillageCount" label="河道行洪隐患区村庄数" />
|
||||
<el-table-column label="操作" width="120" :show-overflow-tooltip="false">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/river/risk_village',
|
||||
query: { riverId: row.riverId },
|
||||
})
|
||||
"
|
||||
>
|
||||
查看隐患村
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/river/river_section',
|
||||
query: { riverId: row.riverId },
|
||||
})
|
||||
"
|
||||
>
|
||||
查看流经县区
|
||||
</el-button>
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button type="primary" text link @click="fnDelete(row.riverId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, nextTick } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import { getRiverPage, setRiverDelete } from "@/request/kangzai.js";
|
||||
import Add from "./components/add.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const { list, pagination, searchForm, resetPagination, getData } =
|
||||
useListData(getRiverPage);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
riverName: "",
|
||||
totalLength: "",
|
||||
basinArea: "",
|
||||
cityAreaPercentage: "",
|
||||
inCityRiverLength: "",
|
||||
inCityBasinArea: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = async (riverId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setRiverDelete({ riverId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.form = {};
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = row;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,136 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="120px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="所属区县" prop="area">
|
||||
<layout-cascader
|
||||
v-model="form.area"
|
||||
v-model:name="form.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="隐患等级" prop="riskLevel">
|
||||
<el-select v-model="form.riskLevel" placeholder="请选择隐患等级">
|
||||
<el-option label="低风险" value="1" />
|
||||
<el-option label="中风险" value="2" />
|
||||
<el-option label="高风险" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="隐患描述" prop="riskDescription">
|
||||
<el-input
|
||||
v-model="form.riskDescription"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入隐患描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import {
|
||||
setRiverRiskVillageAdd,
|
||||
setRiverRiskVillageUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
riverId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
area: [{ required: true, message: "请输入所属区县", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const form = props.form;
|
||||
const param = {
|
||||
...form,
|
||||
riverId: props.riverId,
|
||||
areaName: form.areaName.join("-"),
|
||||
province: form.area[0],
|
||||
city: form.area[1],
|
||||
county: form.area[2],
|
||||
village: form.area[3],
|
||||
street: form.area[4],
|
||||
};
|
||||
delete param.area;
|
||||
if (props.type === "add") {
|
||||
await setRiverRiskVillageAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setRiverRiskVillageUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,157 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="searchForm.area"
|
||||
v-model:name="searchForm.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="隐患等级" prop="riskLevel">
|
||||
<el-select
|
||||
v-model="searchForm.riskLevel"
|
||||
placeholder="请选择隐患等级"
|
||||
>
|
||||
<el-option label="低风险" value="1" />
|
||||
<el-option label="中风险" value="2" />
|
||||
<el-option label="高风险" value="3" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="areaName" label="村庄名称" />
|
||||
<el-table-column prop="riskLevelLabel" label="隐患等级" />
|
||||
<el-table-column prop="riskDescription" label="隐患描述" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.riverRiskVillagesId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
:river-id="riverId"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import Add from "./components/add.vue";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import {
|
||||
getRiverRiskVillagePage,
|
||||
setRiverRiskVillageDelete,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
// 从路由获取 riverId
|
||||
const riverId = ref(route.query.riverId);
|
||||
|
||||
if (!riverId.value) {
|
||||
ElMessage.error("缺少关联河流ID");
|
||||
// 可根据需要跳回河流列表
|
||||
}
|
||||
|
||||
const riskLevelMap = {
|
||||
1: "低风险",
|
||||
2: "中风险",
|
||||
3: "高风险",
|
||||
};
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
getRiverRiskVillagePage,
|
||||
{
|
||||
defaultSearchForm: {
|
||||
riverId: riverId.value,
|
||||
},
|
||||
beforeGetData: (searchForm) => {
|
||||
const area = searchForm.area || [];
|
||||
|
||||
searchForm.province = area[0];
|
||||
searchForm.city = area[1];
|
||||
searchForm.county = area[2];
|
||||
searchForm.village = area[3];
|
||||
searchForm.street = area[4];
|
||||
},
|
||||
callback: (list) => {
|
||||
list.forEach((item) => {
|
||||
item.riskLevelLabel = riskLevelMap[item.riskLevel] || "未知";
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
villageName: "",
|
||||
area: [],
|
||||
areaName: [],
|
||||
riskLevel: "",
|
||||
riskDescription: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = async (riverRiskVillagesId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setRiverRiskVillageDelete({ riverRiskVillagesId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = { ...row };
|
||||
data.addOrEditDialog.form.area = [
|
||||
row.province,
|
||||
row.city,
|
||||
row.county,
|
||||
row.village,
|
||||
row.street,
|
||||
];
|
||||
data.addOrEditDialog.form.areaName = row.areaName.split("-");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,176 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="150px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="form.area"
|
||||
v-model:name="form.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="2"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="县区段长度(km)" prop="sectionLength">
|
||||
<el-input
|
||||
v-model.number="form.sectionLength"
|
||||
placeholder="请输入县区段长度"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="最小河宽(m)" prop="riverWidthMin">
|
||||
<el-input
|
||||
v-model.number="form.riverWidthMin"
|
||||
placeholder="请输入最小河宽"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="最大河宽(m)" prop="riverWidthMax">
|
||||
<el-input
|
||||
v-model.number="form.riverWidthMax"
|
||||
placeholder="请输入最大河宽"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="平均河宽(m)" prop="riverWidthAvg">
|
||||
<el-input
|
||||
v-model.number="form.riverWidthAvg"
|
||||
placeholder="请输入平均河宽"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="河段特征描述" prop="sectionDescription">
|
||||
<el-input
|
||||
v-model="form.sectionDescription"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入河段特征描述"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import {
|
||||
setRiverSectionsAdd,
|
||||
setRiverSectionsUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
riverId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
area: [{ required: true, message: "请选择属地", trigger: "change" }],
|
||||
sectionLength: [
|
||||
{ required: true, message: "请输入县区段长度", trigger: "blur" },
|
||||
],
|
||||
riverWidthMin: [
|
||||
{ required: true, message: "请输入最小河宽", trigger: "blur" },
|
||||
],
|
||||
riverWidthMax: [
|
||||
{ required: true, message: "请输入最大河宽", trigger: "blur" },
|
||||
],
|
||||
riverWidthAvg: [
|
||||
{ required: true, message: "请输入平均河宽", trigger: "blur" },
|
||||
],
|
||||
sectionDescription: [
|
||||
{ required: true, message: "请输入河段特征描述", trigger: "blur" },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const param = {
|
||||
...form.value,
|
||||
riverId: props.riverId,
|
||||
province: form.value.area[0],
|
||||
city: form.value.area[1],
|
||||
county: form.value.area[2],
|
||||
areaName: form.value.areaName.join("-"),
|
||||
};
|
||||
|
||||
delete param.area;
|
||||
|
||||
if (props.type === "add") {
|
||||
await setRiverSectionsAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setRiverSectionsUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,140 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="县区" prop="area">
|
||||
<layout-cascader
|
||||
v-model="searchForm.area"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="2"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="areaName" label="地区" />
|
||||
<el-table-column prop="sectionLength" label="县区段长度(km)" />
|
||||
<el-table-column prop="riverWidthMin" label="最小河宽(m)" />
|
||||
<el-table-column prop="riverWidthMax" label="最大河宽(m)" />
|
||||
<el-table-column prop="riverWidthAvg" label="平均河宽(m)" />
|
||||
<el-table-column prop="sectionDescription" label="河段特征描述" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.riverSectionsId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
:river-id="riverId"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import Add from "./components/add.vue";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import {
|
||||
setRiverSectionsDelete,
|
||||
setRiverSectionsListPage,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const route = useRoute();
|
||||
const riverId = ref(route.query.riverId);
|
||||
|
||||
if (!riverId.value) {
|
||||
ElMessage.error("缺少关联河流ID");
|
||||
}
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
setRiverSectionsListPage,
|
||||
{
|
||||
defaultSearchForm: {
|
||||
riverId: riverId.value,
|
||||
},
|
||||
beforeGetData: (searchForm) => {
|
||||
const area = searchForm.area || [];
|
||||
|
||||
searchForm.province = area[0];
|
||||
searchForm.city = area[1];
|
||||
searchForm.county = area[2];
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
province: "",
|
||||
city: "",
|
||||
county: "",
|
||||
areaName: [],
|
||||
sectionLength: "",
|
||||
riverWidthMin: "",
|
||||
riverWidthMax: "",
|
||||
riverWidthAvg: "",
|
||||
sectionDescription: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = async (riverSectionsId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setRiverSectionsDelete({ riverSectionsId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = { ...row };
|
||||
data.addOrEditDialog.form.area = [row.province, row.city, row.county];
|
||||
data.addOrEditDialog.form.areaName = row.areaName.split("-");
|
||||
} else {
|
||||
data.addOrEditDialog.form = {
|
||||
province: "",
|
||||
city: "",
|
||||
county: "",
|
||||
areaName: [],
|
||||
sectionLength: "",
|
||||
riverWidthMin: "",
|
||||
riverWidthMax: "",
|
||||
riverWidthAvg: "",
|
||||
sectionDescription: "",
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item label="上级菜单">
|
||||
<el-tag>{{ parentName }}</el-tag>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="编码" prop="bianma">
|
||||
<el-input
|
||||
v-model="form.bianma"
|
||||
:disabled="type === 'edit'"
|
||||
placeholder="请输入编码"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="orderBy">
|
||||
<el-input v-model.number="form.orderBy" placeholder="请输入排序" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="descr">
|
||||
<el-input
|
||||
v-model="form.descr"
|
||||
:autosize="{ minRows: 1 }"
|
||||
type="textarea"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
getDataDictionaryRepeat,
|
||||
setDataDictionaryAdd,
|
||||
setDataDictionaryEdit,
|
||||
} from "@/request/system_management.js";
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
parentName: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
parentId: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
const { validate, formRef } = useFormValidate();
|
||||
const data = reactive({
|
||||
rules: {
|
||||
name: [
|
||||
{ required: true, message: "字典名称不能为空", trigger: "change" },
|
||||
{ min: 2, max: 30, message: "长度在2到30个字符", trigger: "blur" },
|
||||
],
|
||||
bianma: [
|
||||
{ required: true, message: "字典编码名称不能为空", trigger: "change" },
|
||||
{ min: 2, max: 30, message: "长度在2到30个字符", trigger: "blur" },
|
||||
],
|
||||
orderBy: [
|
||||
{ required: true, message: "排序不能为空", trigger: ["change", "blur"] },
|
||||
{
|
||||
type: "number",
|
||||
message: "排序必须为数字",
|
||||
trigger: ["change", "blur"],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
const fnClose = () => {
|
||||
formRef.value.resetFields();
|
||||
visible.value = false;
|
||||
};
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
if (props.type === "add") {
|
||||
const { dictionaries } = await getDataDictionaryRepeat({
|
||||
bianma: form.value.bianma,
|
||||
});
|
||||
if (dictionaries) {
|
||||
ElMessage.error("添加失败,编码重复");
|
||||
return;
|
||||
}
|
||||
await setDataDictionaryAdd({
|
||||
...form.value,
|
||||
parentId: props.parentId,
|
||||
dictionariesId: undefined,
|
||||
});
|
||||
}
|
||||
if (props.type === "edit")
|
||||
await setDataDictionaryEdit({
|
||||
...form.value,
|
||||
});
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column label="名称">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="
|
||||
router.push({
|
||||
path: '/system_management/data_dictionary',
|
||||
query: {
|
||||
parentName: row.name,
|
||||
parentId: row.dictionariesId,
|
||||
},
|
||||
})
|
||||
"
|
||||
>
|
||||
{{ row.name }} <el-icon><arrow-right /></el-icon>
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="bianma" label="编码" />
|
||||
<el-table-column prop="dictionariesId" label="ID" width="300" />
|
||||
<el-table-column prop="orderBy" label="排序" width="50" />
|
||||
<el-table-column label="操作" width="100">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnAddOrEdit(row.dictionariesId, 'edit')"
|
||||
>
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.dictionariesId)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="parentId !== '0'"
|
||||
:icon="ArrowLeft"
|
||||
@click="router.back()"
|
||||
>
|
||||
返回
|
||||
</el-button>
|
||||
</template>
|
||||
</app-table>
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:parent-name="parentName"
|
||||
:parent-id="parentId"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ArrowLeft, ArrowRight } from "@element-plus/icons-vue";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useRouter, onBeforeRouteUpdate, useRoute } from "vue-router";
|
||||
import {
|
||||
setDataDictionaryDelete,
|
||||
getDataDictionaryList,
|
||||
getDataDictionaryInfo,
|
||||
} from "@/request/system_management.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import Add from "./components/add.vue";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const parentIdDefault = "0";
|
||||
const parentNameDefault = "(无)此项为顶级菜单";
|
||||
const parentId = ref(route.query.parentId || parentIdDefault);
|
||||
const parentName = ref(route.query.parentName || parentNameDefault);
|
||||
const { list, pagination, getData, resetPagination } = useListData(
|
||||
getDataDictionaryList,
|
||||
{
|
||||
params: () => ({ parentId: parentId.value }),
|
||||
}
|
||||
);
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
name: "",
|
||||
bianma: "",
|
||||
orderBy: "",
|
||||
descr: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
onBeforeRouteUpdate((to) => {
|
||||
parentId.value = to.query.parentId || parentIdDefault;
|
||||
parentName.value = to.query.parentName || parentNameDefault;
|
||||
resetPagination();
|
||||
});
|
||||
const fnDelete = async (dictionariesId) => {
|
||||
await ElMessageBox.confirm(`确定要删除吗?`, { type: "warning" });
|
||||
await setDataDictionaryDelete({ dictionariesId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
const fnAddOrEdit = async (dictionariesId, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
data.addOrEditDialog.type = type;
|
||||
if (type === "edit") {
|
||||
const resData = await getDataDictionaryInfo({ dictionariesId });
|
||||
data.addOrEditDialog.form = resData.dictionaries;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
|
@ -0,0 +1,213 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
:title="type === 'edit' ? '修改' : '新增'"
|
||||
:before-close="fnClose"
|
||||
>
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="data.rules"
|
||||
label-width="100px"
|
||||
style="margin-top: 20px"
|
||||
>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="防涝点名称" prop="pointName">
|
||||
<el-input v-model="form.pointName" placeholder="请输入防涝点名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="form.area"
|
||||
v-model:name="form.areaName"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="false"
|
||||
:level="4"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="类型" prop="pointType">
|
||||
<el-select v-model="form.pointType" placeholder="请选择类型">
|
||||
<el-option
|
||||
v-for="item in pointTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="当前水位" prop="currentWaterLevel">
|
||||
<el-input
|
||||
v-model="form.currentWaterLevel"
|
||||
placeholder="请输入当前水位"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input
|
||||
v-model="form.remarks"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入备注"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<div style="display: flex">
|
||||
<el-form-item label="经度" prop="longitude" style="flex: 1">
|
||||
<el-input
|
||||
v-model="form.longitude"
|
||||
placeholder="请选择经度"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度" prop="latitude" style="flex: 1">
|
||||
<el-input
|
||||
v-model="form.latitude"
|
||||
placeholder="请选择纬度"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label-width="10px">
|
||||
<el-button
|
||||
class="ml-10"
|
||||
type="primary"
|
||||
@click="fnSelectedPosition"
|
||||
>点击定位</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="fnClose">取 消</el-button>
|
||||
<el-button type="primary" @click="fnSubmit">确 定</el-button>
|
||||
</template>
|
||||
|
||||
<app-map
|
||||
v-model:visible="mapDialog.visible"
|
||||
v-model:longitude="mapDialog.longitude"
|
||||
v-model:latitude="mapDialog.latitude"
|
||||
@submit="fnMapSubmit"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { debounce } from "throttle-debounce";
|
||||
import useFormValidate from "@/hooks/useFormValidate.js";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useVModels } from "@vueuse/core";
|
||||
import AppMap from "@/components/map/map.vue";
|
||||
import {
|
||||
setUrbanFloodPointAdd,
|
||||
setUrbanFloodPointUpdate,
|
||||
} from "@/request/kangzai.js";
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: "",
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({}),
|
||||
},
|
||||
});
|
||||
const { validate, formRef } = useFormValidate();
|
||||
|
||||
const emits = defineEmits(["update:visible", "update:form", "getData"]);
|
||||
const { visible, form } = useVModels(props, emits);
|
||||
|
||||
const pointTypeList = ref([]);
|
||||
|
||||
const fnGetPointTypeList = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s", // 新字典ID
|
||||
});
|
||||
pointTypeList.value = resData.dictionariesList || [];
|
||||
};
|
||||
|
||||
fnGetPointTypeList();
|
||||
|
||||
const data = reactive({
|
||||
rules: {
|
||||
pointName: [
|
||||
{ required: true, message: "请输入防涝点名称", trigger: "blur" },
|
||||
],
|
||||
area: [{ required: true, message: "请选择区域", trigger: "blur" }],
|
||||
pointType: [{ required: true, message: "请选择类型", trigger: "change" }],
|
||||
longitude: [{ required: true, message: "请输入经度", trigger: "blur" }],
|
||||
latitude: [{ required: true, message: "请输入纬度", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
|
||||
const mapDialog = ref({
|
||||
visible: false,
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
});
|
||||
const fnSelectedPosition = () => {
|
||||
mapDialog.value.visible = true;
|
||||
mapDialog.value.longitude = form.value.longitude;
|
||||
mapDialog.value.latitude = form.value.latitude;
|
||||
};
|
||||
const fnMapSubmit = ({ longitude, latitude }) => {
|
||||
form.value.longitude = longitude;
|
||||
form.value.latitude = latitude;
|
||||
};
|
||||
|
||||
const fnClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const fnSubmit = debounce(
|
||||
1000,
|
||||
async () => {
|
||||
await validate();
|
||||
const param = {
|
||||
...form.value,
|
||||
areaName: form.value.areaName.join("-"),
|
||||
province: form.value.area[0],
|
||||
city: form.value.area[1],
|
||||
county: form.value.area[2],
|
||||
village: form.value.area[3],
|
||||
street: form.value.area[4],
|
||||
};
|
||||
delete param.area;
|
||||
|
||||
if (props.type === "add") {
|
||||
await setUrbanFloodPointAdd(param);
|
||||
} else if (props.type === "edit") {
|
||||
await setUrbanFloodPointUpdate(param);
|
||||
}
|
||||
|
||||
ElMessage.success("操作成功");
|
||||
fnClose();
|
||||
emits("getData");
|
||||
},
|
||||
{ atBegin: true }
|
||||
);
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
|
@ -0,0 +1,168 @@
|
|||
<template>
|
||||
<div>
|
||||
<app-search v-model="searchForm" @submit="resetPagination">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="防涝点名称" prop="pointName">
|
||||
<el-input
|
||||
v-model="searchForm.pointName"
|
||||
placeholder="请输入防涝点名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="属地" prop="area">
|
||||
<layout-cascader
|
||||
v-model="searchForm.area"
|
||||
:dictionaries-id="'e725d2a91b8248f4b8f49889038df7de'"
|
||||
:check-strictly="true"
|
||||
:level="5"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item label="类型" prop="pointType">
|
||||
<el-select v-model="searchForm.pointType" placeholder="请选择类型">
|
||||
<el-option
|
||||
v-for="item in pointTypeList"
|
||||
:key="item.bianma"
|
||||
:label="item.name"
|
||||
:value="item.bianma"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</app-search>
|
||||
|
||||
<app-table v-model:pagination="pagination" :data="list" @get-data="getData">
|
||||
<el-table-column prop="pointName" label="防涝点名称" />
|
||||
<el-table-column prop="areaName" label="属地" />
|
||||
<el-table-column label="类型" prop="pointTypeLabel" />
|
||||
<el-table-column prop="currentWaterLevel" label="当前水位" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" text link @click="fnAddOrEdit(row, 'edit')"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
text
|
||||
link
|
||||
@click="fnDelete(row.urbanFloodPointId)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #button>
|
||||
<el-button type="primary" @click="fnAddOrEdit('', 'add')"
|
||||
>新增</el-button
|
||||
>
|
||||
</template>
|
||||
</app-table>
|
||||
|
||||
<add
|
||||
v-model:form="data.addOrEditDialog.form"
|
||||
v-model:visible="data.addOrEditDialog.visible"
|
||||
:type="data.addOrEditDialog.type"
|
||||
@get-data="resetPagination"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick } from "vue";
|
||||
import { getDataDictionary } from "@/request/data_dictionary.js";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import LayoutCascader from "@/components/layout_cascader/index.vue";
|
||||
import AppTable from "@/components/table/index.vue";
|
||||
import AppSearch from "@/components/search/index.vue";
|
||||
import useListData from "@/hooks/useListData.js";
|
||||
import {
|
||||
getUrbanFloodPointPage,
|
||||
setUrbanFloodPointDelete,
|
||||
} from "@/request/kangzai.js";
|
||||
import Add from "./components/add.vue";
|
||||
|
||||
// 防涝点类型字典
|
||||
const pointTypeList = ref([]);
|
||||
const fnGetPointTypeList = async () => {
|
||||
const resData = await getDataDictionary({
|
||||
parentId: "d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s", // 新字典ID
|
||||
});
|
||||
pointTypeList.value = resData.dictionariesList || [];
|
||||
};
|
||||
fnGetPointTypeList();
|
||||
|
||||
const { list, pagination, searchForm, resetPagination, getData } = useListData(
|
||||
getUrbanFloodPointPage,
|
||||
{
|
||||
beforeGetData: (searchForm) => {
|
||||
const area = searchForm.area || [];
|
||||
|
||||
searchForm.province = area[0];
|
||||
searchForm.city = area[1];
|
||||
searchForm.county = area[2];
|
||||
searchForm.village = area[3];
|
||||
searchForm.street = area[4];
|
||||
},
|
||||
callback: (list) => {
|
||||
list.forEach((item) => {
|
||||
item.pointTypeLabel =
|
||||
pointTypeList.value.find((dict) => dict.bianma === item.pointType)
|
||||
?.name || item.pointType;
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const data = reactive({
|
||||
addOrEditDialog: {
|
||||
visible: false,
|
||||
type: "",
|
||||
form: {
|
||||
pointName: "",
|
||||
province: "",
|
||||
city: "",
|
||||
county: "",
|
||||
village: "",
|
||||
street: "",
|
||||
area: [],
|
||||
areaName: [],
|
||||
pointType: "",
|
||||
currentWaterLevel: "",
|
||||
longitude: "",
|
||||
latitude: "",
|
||||
remarks: "",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fnDelete = async (urbanFloodPointId) => {
|
||||
await ElMessageBox.confirm("确定要删除吗?", { type: "warning" });
|
||||
await setUrbanFloodPointDelete({ urbanFloodPointId });
|
||||
ElMessage.success("删除成功");
|
||||
resetPagination();
|
||||
};
|
||||
|
||||
const fnAddOrEdit = async (row, type) => {
|
||||
data.addOrEditDialog.visible = true;
|
||||
await nextTick();
|
||||
data.addOrEditDialog.form = {};
|
||||
data.addOrEditDialog.type = type;
|
||||
|
||||
if (type === "edit") {
|
||||
data.addOrEditDialog.form = row;
|
||||
data.addOrEditDialog.form.area = [
|
||||
row.province,
|
||||
row.city,
|
||||
row.county,
|
||||
row.village,
|
||||
row.street,
|
||||
];
|
||||
data.addOrEditDialog.form.areaName = row.areaName.split("-");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
Loading…
Reference in New Issue