feat: 立即排班弹窗

This commit is contained in:
huangchenhao 2026-04-15 18:00:52 +08:00
parent 9bf98c53cd
commit 788961bc66
4 changed files with 204 additions and 109 deletions

View File

@ -45,7 +45,8 @@ export default () => {
await getMenuList();
const firstMenuItem = menuList.value[0]?.children?.[0];
if (firstMenuItem) {
handleMenuClick(firstMenuItem);
// 注释掉进入页面点击第一项的逻辑 后续记得打开
// handleMenuClick(firstMenuItem);
}
}
}, { immediate: true });

View File

@ -2,91 +2,46 @@
<div class="detail-container">
<el-form ref="formRef" :model="form" label-position="right" label-width="auto"
style="max-height: 60vh; overflow-y: auto; padding-right: 50px" :rules="rules">
<div class="form-part">
<el-row>
<h4 style="margin: 0 0 20px 0;">气象信息</h4>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="预警标题" prop="预警标题">
<el-input v-model="form.headline" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="预警时间" prop="预警时间">
<el-col :span="11">
<el-date-picker v-model="form.onset" type="date" placeholder="开始时间" style="width: 100%" />
</el-col>
<el-col :span="2" class="text-center">
<span class="text-gray-500">-</span>
</el-col>
<el-col :span="11">
<el-date-picker v-model="form.expires" type="date" placeholder="过期时间" style="width: 100%" />
</el-col>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="气象类型" prop="气象类型">
<el-select v-model="form.eventType" clearable placeholder="请选择">
<el-option v-for="(item, index) in [
{ label: '道路结冰', value: '道路结冰' },
{ label: '暴雪', value: '暴雪' },
{ label: '暴雨', value: '暴雨' },
]" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="气象来源" prop="气象来源">
<el-select v-model="form.weatherSource" clearable placeholder="请选择">
<el-option v-for="(item, index) in [
{ label: '市级', value: '1' },
{ label: '部级', value: '2' },
{ label: '区县', value: '3' },
]" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="预警等级" prop="预警等级">
<el-select v-model="form.urgency" clearable placeholder="请选择">
<el-option v-for="(item, index) in [
{ label: '1级红色预警', value: '1' },
{ label: '2级橙色预警', value: '2' },
{ label: '3级黄色预警', value: '3' },
{ label: '4级蓝色预警', value: '4' },
]" :key="index" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="风险区县" prop="风险区县">
<el-select v-model="form.areaCodes" clearable placeholder="请选择" multiple>
<el-option v-for="(item, index) in areaList" :key="index" :label="item.qxmc" :value="item.xzdm" />
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<el-form-item label="" prop="schedules">
<div class="tree-transfer-container">
<!-- 左侧树形结构 -->
<div class="tree-panel">
<el-tree :data="treeOrgs" :props="{
children: 'children',
label: 'orgName'
}" node-key="orgId" :expand-on-click-node="false" :default-expand-all="false" highlight-current
style="height: 400px; overflow-y: auto;"
@node-click="handleNodeClick">
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ node.label }}</span>
</span>
</template>
</el-tree>
</div>
<!-- 中间空白区域 -->
<div class="middle-panel">
<!-- 暂留空后续使用 -->
</div>
<!-- 右侧空白区域 -->
<div class="right-panel">
<!-- 暂留空后续使用 -->
</div>
</div>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import { ref, onMounted, watch, computed } from "vue";
import { ref, computed, onMounted } from "vue";
import { request } from "@/utils/request";
import FileUpload from '@/component/FileUpload/FileUpload.vue'
import { ElMessage } from 'element-plus';
const formRef = ref(null);
defineExpose({ formRef });
@ -97,47 +52,144 @@ const props = defineProps({
},
});
const areaList = ref([])
//
const getAreaList = async () => {
const rules = computed(() => {
return {
};
});
//
const userOrgs = ref([]);
//
const treeOrgs = ref([]);
//
const getUserOrgs = async () => {
try {
const res = await request({
url: '/snow-ops-platform/infrastructure-asset/counties',
method: 'get',
url: '/snow-ops-platform/user/userOrgs',
method: 'GET',
})
if (res.code === '00000') {
areaList.value = res.data
userOrgs.value = res.data.data
//
treeOrgs.value = buildOrgTree(userOrgs.value)
} else {
throw new Error(res.message)
}
} catch (error) {
ElMessage.error(error.message)
console.log(error)
ElMessage.error('获取组织失败');
console.error('获取组织失败:', error);
}
}
/**
* 构建组织树形结构
* @param {Array} orgList 组织列表
* @returns {Array} 树形结构数据
*/
const buildOrgTree = (orgList) => {
if (!orgList || !orgList.length) return [];
// 便
const orgMap = {};
orgList.forEach(org => {
orgMap[org.orgId] = {
...org,
children: []
};
});
const tree = [];
orgList.forEach(org => {
const currentOrg = orgMap[org.orgId];
// orgParentId-1orgPids"[-1],"
if (org.orgParentId === -1 || org.orgPids === "[-1],") {
tree.push(currentOrg);
} else {
//
// orgPidsorgId
let parentId = null;
// 1orgPidsID
if (org.orgPids) {
const pidMatches = org.orgPids.match(/\d+/g);
if (pidMatches && pidMatches.length > 0) {
// ID-1
const parentIds = pidMatches.filter(id => id !== '-1');
if (parentIds.length > 0) {
parentId = parseInt(parentIds[parentIds.length - 1]);
}
}
}
// 2orgPids使orgParentId
if (parentId === null && org.orgParentId && org.orgParentId !== -1) {
parentId = org.orgParentId;
}
// children
if (parentId && orgMap[parentId]) {
orgMap[parentId].children.push(currentOrg);
} else {
//
tree.push(currentOrg);
}
}
});
// orgSort
const sortTree = (tree) => {
tree.sort((a, b) => (a.orgSort || 0) - (b.orgSort || 0));
tree.forEach(node => {
if (node.children && node.children.length) {
sortTree(node.children);
}
});
return tree;
};
return sortTree(tree);
}
//
const handleNodeClick = (data, node) => {
//
if (!node.childNodes || node.childNodes.length === 0) {
//
getUsersByOrgId(data.orgId);
}
}
// ID
const getUsersByOrgId = async (orgId) => {
try {
const res = await request({
url: '/snow-ops-platform/user/orgUsers',
method: 'GET',
params: {
orgId
}
})
if (res.code === '00000') {
console.log('@@@@@@用户列表',res.data);
} else {
throw new Error(res.message)
}
} catch (error) {
ElMessage.error('获取用户失败');
console.error('获取用户失败:', error);
}
}
onMounted(() => {
getAreaList()
getUserOrgs();
})
const rules = computed(() => {
return {
// mc: [
// {
// required: true,
// validator: (rule, value, callback) => {
// if (props.form.mc) {
// callback();
// } else {
// callback(new Error(""));
// }
// },
// trigger: "blur",
// },
// ],
};
});
</script>
<style scoped>
@ -148,4 +200,46 @@ const rules = computed(() => {
.text-center {
text-align: center;
}
.tree-transfer-container {
display: flex;
gap: 20px;
width: 100%;
}
.tree-panel {
flex: 1;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
background-color: #fff;
}
.empty-panel {
}
.middle-panel {
flex: 2;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
background-color: #fff;
}
.right-panel {
flex: 2;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 10px;
background-color: #fff;
}
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
font-size: 14px;
padding-right: 8px;
}
</style>

View File

@ -102,7 +102,7 @@ const getTableData = async (filterData = {}) => {
// 打开发布预警弹窗
const openAddDialog = () => {
model.title = '发布预警';
model.title = '立即排班';
Object.assign(form, INIT_FORM);
model.props = {
form: form,
@ -113,14 +113,14 @@ const openAddDialog = () => {
};
model.onConfirm = async () => {
await dialogRef?.value?.dynamicComponentRef?.formRef.validate().then(async () => {
console.log('@@@@@发布预警', form);
console.log('@@@@@立即排班', form);
// await publishWarning(form)
})
.catch((err) => {
ElMessage.error('请处理表单中的错误项');
});
};
model.width = "50%"
model.width = "70%"
modelVisible.value = true;
}

View File

@ -7,7 +7,7 @@
value-format="YYYY-MM-DD HH:mm:ss" />
</div>
<div class="event-box">
<el-button type="primary" @click="">立即排班</el-button>
<el-button type="primary" @click="script.openAddDialog">立即排班</el-button>
<!-- <el-button type="primary" @click="script.gotoLedgerPage">驻地台账</el-button> -->
<!-- <el-button type="primary" @click="script.openAddDialog">上报项目</el-button> -->
</div>