|
@@ -1,59 +1,56 @@
|
|
|
<template>
|
|
|
- <el-dialog ref="formDialogRef" v-model="props.modelValue" :title="props.title" width="1000px" append-to-body @close="closeDialog">
|
|
|
- <div class="start-plan-content">
|
|
|
+ <el-dialog ref="dialogRef" v-model="visible" :title="title" width="1000px" append-to-body @close="onClose">
|
|
|
+ <div class="plan-content">
|
|
|
+ <!-- 响应等级选择和操作按钮 -->
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="12">
|
|
|
<div class="section-title select-level-container">
|
|
|
<span>响应等级</span>
|
|
|
<el-select v-model="selectedLevel" placeholder="请选择响应等级" class="select-level">
|
|
|
- <el-option v-for="level in levels" :key="level.value" :label="level.name" :value="level.value"></el-option>
|
|
|
+ <el-option v-for="level in responseLevels" :key="level.value" :label="level.name" :value="level.value"></el-option>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
</el-col>
|
|
|
- <el-col :span="12" class="buttons-container">
|
|
|
- <el-button type="primary" @click="handleStartPlan">启动预案</el-button>
|
|
|
- <el-button type="primary" @click="taskDelivery">预案任务下发内容</el-button>
|
|
|
+ <el-col :span="12" class="button-container">
|
|
|
+ <el-button type="primary" @click="onStartPlan">启动预案</el-button>
|
|
|
+ <el-button type="primary" @click="onTaskDelivery">预案任务下发</el-button>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
- <h2>xxx预案名称</h2>
|
|
|
- <el-row shadow="hover" class="fixed-width-row">
|
|
|
- <el-tabs v-model="activeName" type="border-card" class="demo-tabs" @tab-click="handleClick2">
|
|
|
- <el-tab-pane label="总则" name="first">
|
|
|
+ <!-- 预案名称 -->
|
|
|
+ <h2>{{ planTitle }}</h2>
|
|
|
+ <!-- 预案内容的标签页 -->
|
|
|
+ <el-row class="content-row">
|
|
|
+ <el-tabs v-model="activeTab" type="border-card" @tab-click="onTabClick">
|
|
|
+ <el-tab-pane label="总则" name="principles">
|
|
|
<div>
|
|
|
+ <!-- 锚点导航 -->
|
|
|
<el-row>
|
|
|
<el-col :span="4">
|
|
|
- <el-anchor :container="containerRef" direction="vertical" type="default" :offset="30" @click="handleClick1">
|
|
|
- <el-anchor-link href="#part1" title="编制目的" />
|
|
|
- <el-anchor-link href="#part2" title="编制依据" />
|
|
|
- <el-anchor-link href="#part3" title="适用范围" />
|
|
|
- <el-anchor-link href="#part4" title="工作原则" />
|
|
|
+ <el-anchor :container="contentContainer" direction="vertical" type="default" :offset="30">
|
|
|
+ <el-anchor-link href="#purpose" title="编制目的" />
|
|
|
+ <el-anchor-link href="#basis" title="编制依据" />
|
|
|
+ <el-anchor-link href="#scope" title="适用范围" />
|
|
|
+ <el-anchor-link href="#principles" title="工作原则" />
|
|
|
</el-anchor>
|
|
|
</el-col>
|
|
|
+ <!-- 可滚动的内容区域 -->
|
|
|
<el-col :span="20">
|
|
|
- <div ref="containerRef" style="height: 300px; overflow-y: auto">
|
|
|
- <div id="part1" style="height: auto; margin-top: 20px; font-size: 14px">
|
|
|
- <h3 style="font-weight: 600">1.1 编制目的</h3>
|
|
|
- <span style="text-indent: 2em"
|
|
|
- >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
|
|
|
- >
|
|
|
+ <div ref="contentContainer" style="height: 300px; overflow-y: auto">
|
|
|
+ <div id="purpose" style="margin-top: 20px; font-size: 14px">
|
|
|
+ <h3>1.1 编制目的</h3>
|
|
|
+ <p>{{ planData.purpose }}</p>
|
|
|
</div>
|
|
|
- <div id="part2" style="height: auto; margin-top: 15px; font-size: 14px">
|
|
|
- <h3 style="font-weight: 600">1.2 编制依据</h3>
|
|
|
- <span style="text-indent: 28px"
|
|
|
- >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
|
|
|
- >
|
|
|
+ <div id="basis" style="margin-top: 15px; font-size: 14px">
|
|
|
+ <h3>1.2 编制依据</h3>
|
|
|
+ <p>{{ planData.basis }}</p>
|
|
|
</div>
|
|
|
- <div id="part3" style="height: auto; margin-top: 15px; font-size: 14px">
|
|
|
- <h3 style="font-weight: 600">1.3 适用范围</h3>
|
|
|
- <span style="text-indent: 28px"
|
|
|
- >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
|
|
|
- >
|
|
|
+ <div id="scope" style="margin-top: 15px; font-size: 14px">
|
|
|
+ <h3>1.3 适用范围</h3>
|
|
|
+ <p>{{ planData.scope }}</p>
|
|
|
</div>
|
|
|
- <div id="part4" style="height: auto; margin-top: 15px; font-size: 14px">
|
|
|
- <h3 style="font-weight: 600">1.4 工作原则</h3>
|
|
|
- <span style="text-indent: 28px"
|
|
|
- >这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容这是内容</span
|
|
|
- >
|
|
|
+ <div id="principles" style="margin-top: 15px; font-size: 14px">
|
|
|
+ <h3>1.4 工作原则</h3>
|
|
|
+ <p>{{ planData.principles }}</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
</el-col>
|
|
@@ -69,79 +66,166 @@
|
|
|
</el-tabs>
|
|
|
</el-row>
|
|
|
</div>
|
|
|
- <TaskDelivery v-model="taskDeliveryState.show" :title="taskDeliveryState.title" />
|
|
|
+ <TaskDelivery v-model="taskDeliveryState.show" :title="taskDeliveryState.title" :plan-id="planData.plan_id" :event-id="props.eventId" />
|
|
|
</el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { defineProps, defineEmits, ref, watch } from 'vue';
|
|
|
+import { ref, watch, defineProps, defineEmits, reactive } from 'vue';
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
import TaskDelivery from './TaskDelivery.vue';
|
|
|
-const visible = ref(false);
|
|
|
+import { matchingPlan, launchPlan } from '@/api/duty/eventing';
|
|
|
+
|
|
|
+// 定义组件接收的属性类型
|
|
|
interface Props {
|
|
|
modelValue: boolean;
|
|
|
eventId: string;
|
|
|
title: string;
|
|
|
}
|
|
|
-const props = withDefaults(defineProps<Props>(), {
|
|
|
- modelValue: false,
|
|
|
- eventId: '',
|
|
|
- title: ''
|
|
|
+
|
|
|
+// 初始化组件属性
|
|
|
+const props = defineProps<Props>();
|
|
|
+
|
|
|
+// 内部状态
|
|
|
+const visible = ref(props.modelValue); // 对话框是否可见
|
|
|
+const planTitle = ref(''); // 预案名称
|
|
|
+const selectedLevel = ref(''); // 默认响应等级为空
|
|
|
+const responseLevels = [
|
|
|
+ // 响应等级选项
|
|
|
+ { value: '1', name: '特重大(I级)' },
|
|
|
+ { value: '2', name: '重大(II级)' },
|
|
|
+ { value: '3', name: '较大(III级)' },
|
|
|
+ { value: '4', name: '一般(IV级)' }
|
|
|
+];
|
|
|
+const activeTab = ref('principles'); // 当前激活的标签页
|
|
|
+const planData = reactive({
|
|
|
+ purpose: '这是内容...', // 编制目的
|
|
|
+ basis: '这是内容...', // 编制依据
|
|
|
+ scope: '这是内容...', // 适用范围
|
|
|
+ principles: '这是内容...', // 工作原则
|
|
|
+ plan_id: '' // 添加 plan_id 属性
|
|
|
});
|
|
|
|
|
|
// 定义事件发射器
|
|
|
-const emits = defineEmits(['update:modelValue']);
|
|
|
-
|
|
|
-// 内部响应式变量
|
|
|
-const innerModelValue = ref(props.modelValue);
|
|
|
-// 响应等级选择
|
|
|
-const selectedLevel = ref('');
|
|
|
-
|
|
|
-// 响应等级选项
|
|
|
-const levels = [
|
|
|
- { value: '1', name: '一级' },
|
|
|
- { value: '2', name: '二级' },
|
|
|
- { value: '3', name: '三级' }
|
|
|
-];
|
|
|
+const emit = defineEmits(['update:modelValue']);
|
|
|
|
|
|
-// 当props.modelValue改变时,更新内部变量
|
|
|
+// 监听 modelValue 变化
|
|
|
watch(
|
|
|
() => props.modelValue,
|
|
|
(newValue) => {
|
|
|
- innerModelValue.value = newValue;
|
|
|
+ visible.value = newValue;
|
|
|
}
|
|
|
);
|
|
|
|
|
|
// 对话框关闭时执行的操作
|
|
|
-const closeDialog = () => {
|
|
|
- emits('update:modelValue', false);
|
|
|
+const onClose = () => {
|
|
|
+ emit('update:modelValue', false);
|
|
|
};
|
|
|
|
|
|
// 处理启动预案的函数
|
|
|
-const handleStartPlan = () => {
|
|
|
- console.log('启动预案');
|
|
|
-};
|
|
|
+const onStartPlan = async () => {
|
|
|
+ // 检查是否选择了响应等级
|
|
|
+ if (!selectedLevel.value) {
|
|
|
+ ElMessage.error('请先选择响应等级!');
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
-const containerRef = ref<HTMLElement | null>(null);
|
|
|
-const handleClick1 = (e: MouseEvent) => {
|
|
|
- e.preventDefault();
|
|
|
-};
|
|
|
+ // 收集数据
|
|
|
+ const data = {
|
|
|
+ response_level: selectedLevel.value,
|
|
|
+ eventId: props.eventId,
|
|
|
+ plan_id: planData.plan_id // 确保 planData 中包含正确的 plan_id
|
|
|
+ };
|
|
|
|
|
|
-const activeName = ref('first');
|
|
|
-const handleClick2 = (tab: TabsPaneContext, event: Event) => {
|
|
|
- console.log(tab, event);
|
|
|
+ try {
|
|
|
+ // 调用后端API启动预案
|
|
|
+ const response = await launchPlan(data);
|
|
|
+ if (response && response.code === 200) {
|
|
|
+ ElMessage.success('预案启动成功!');
|
|
|
+ } else if (response && response.code !== 200) {
|
|
|
+ ElMessage.error(`预案启动失败,后端返回错误码:${response.code}`);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('启动预案时发生的错误:', error);
|
|
|
+ if (error.response && error.response.data && error.response.data.message) {
|
|
|
+ ElMessage.error(error.response.data.message);
|
|
|
+ } else if (error.response && error.response.status) {
|
|
|
+ ElMessage.error(`启动预案时发生错误,HTTP 状态码:${error.response.status}`);
|
|
|
+ } else {
|
|
|
+ ElMessage.error('启动预案时发生未知错误,请稍后再试。');
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+// 处理标签页点击事件
|
|
|
+const onTabClick = (tab: any, event: Event) => {
|
|
|
+ // 实现标签页点击的逻辑
|
|
|
};
|
|
|
+
|
|
|
// 控制 taskDelivery 弹窗的显示状态
|
|
|
const taskDeliveryState = reactive({
|
|
|
- show: false,
|
|
|
- title: ''
|
|
|
+ show: ref(false),
|
|
|
+ title: '' as string
|
|
|
});
|
|
|
+
|
|
|
// 处理预案任务下发内容的函数
|
|
|
-const taskDelivery = () => {
|
|
|
- console.log('taskDelivery');
|
|
|
+const onTaskDelivery = () => {
|
|
|
taskDeliveryState.title = '预案任务下发';
|
|
|
taskDeliveryState.show = true;
|
|
|
};
|
|
|
+
|
|
|
+// 调用接口获取预案数据
|
|
|
+const fetchPlanData = async () => {
|
|
|
+ try {
|
|
|
+ if (!props.eventId) {
|
|
|
+ ElMessage.warning('eventId 为空,无法获取预案数据');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const response = await matchingPlan({ eventId: props.eventId });
|
|
|
+ if (response && response.code === 200) {
|
|
|
+ const data = response.data;
|
|
|
+ planTitle.value = `预案名称: ${data.plan_name}`;
|
|
|
+ if (data.response_level) {
|
|
|
+ const isValidLevel = responseLevels.some((level) => level.value === data.response_level);
|
|
|
+ if (isValidLevel) {
|
|
|
+ selectedLevel.value = data.response_level;
|
|
|
+ } else {
|
|
|
+ ElMessage.error('无效的响应等级,请检查数据');
|
|
|
+ selectedLevel.value = '';
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ selectedLevel.value = '';
|
|
|
+ }
|
|
|
+ planData.purpose = data.purpose || '这是内容...';
|
|
|
+ planData.basis = data.basis || '这是内容...';
|
|
|
+ planData.scope = data.scope || '这是内容...';
|
|
|
+ planData.principles = data.principles || '这是内容...';
|
|
|
+ planData.plan_id = data.plan_id; // 确保 planData 中包含 plan_id
|
|
|
+ } else {
|
|
|
+ ElMessage.error('未能从服务器获取有效的预案数据');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('获取预案数据失败');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 在组件挂载时尝试获取预案数据
|
|
|
+onMounted(() => {
|
|
|
+ if (props.eventId) {
|
|
|
+ fetchPlanData();
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 监听 eventId 变化
|
|
|
+watch(
|
|
|
+ () => props.eventId,
|
|
|
+ (newEventId) => {
|
|
|
+ if (newEventId) {
|
|
|
+ fetchPlanData();
|
|
|
+ }
|
|
|
+ }
|
|
|
+);
|
|
|
</script>
|
|
|
+
|
|
|
<style scoped>
|
|
|
.start-plan-content .section-title {
|
|
|
display: flex;
|
|
@@ -162,13 +246,21 @@ const taskDelivery = () => {
|
|
|
.select-level {
|
|
|
flex-grow: 1; /* 让下拉框尽可能占据剩余空间 */
|
|
|
}
|
|
|
+h2 {
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+/* 样式 */
|
|
|
+.plan-content {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
|
|
|
-.buttons-container {
|
|
|
+.button-container {
|
|
|
display: flex;
|
|
|
- justify-content: flex-end; /* 靠右对齐 */
|
|
|
- gap: 10px; /* 设置按钮之间的间距 */
|
|
|
+ justify-content: flex-end;
|
|
|
}
|
|
|
-h2 {
|
|
|
- text-align: center;
|
|
|
+
|
|
|
+.content-row {
|
|
|
+ margin-top: 20px;
|
|
|
}
|
|
|
</style>
|