123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- <template>
- <div class="duty-card">
- <div class="common-title gradient-text">指挥动态</div>
- <ul class="tabs">
- <li v-for="(tab, index) in tabs" :key="index" :class="{ active: tab.id === activeTab }" @click="setActiveTab(tab.id)">
- {{ tab.label }}
- </li>
- </ul>
- <div class="card-content">
- <!-- 任务跟踪部分 -->
- <RenWuGenZong v-if="activeTab === '任务跟踪'" :event-id="eventId" />
- <!-- 预案通知部分修改为卡片式布局 -->
- <div v-else-if="activeTab === '预案通知'" class="preplan-notification">
- <div v-if="notifications.length > 0" class="table-content">
- <div v-for="(notification, index) in notifications" :key="index" class="box1">
- <div :class="notification.status === '发送失败' ? 'error-icon' : 'success-icon'"></div>
- <div class="box2">
- <div class="box-header">
- <div class="header-left">
- <div class="box-title">{{ notification.unit }}</div>
- <div class="time">{{ notification.date }}</div>
- <div :class="notification.status === '发送失败' ? 'status error' : 'status success'">
- {{ notification.status === '发送失败' ? '发送失败' : `接收人:${notification.receiver}` }}
- </div>
- </div>
- <!-- 如果需要更新按钮,可以取消注释以下代码 -->
- <!--
- <div class="btn" @click="openUpdateDialog(notification)">
- 更新
- </div>
- -->
- </div>
- <div class="box-content">{{ notification.content }}</div>
- <template v-if="notification.leaders && notification.leaders.length">
- <div class="box-content">赶赴现场人员:{{ notification.name1 }} ({{ notification.phone1 }})</div>
- <div class="box-content">指挥部值守人员:{{ notification.name2 }} ({{ notification.phone2 }})</div>
- </template>
- <div v-if="!!notification.comment" class="box-content2">领导批示:{{ notification.comment }}</div>
- </div>
- </div>
- </div>
- <div v-else class="tip">暂无数据</div>
- </div>
- <!-- 资源调度部分保持不变 -->
- <div v-else-if="activeTab === '资源调度'" class="resource-scheduling">
- <div class="tip">暂无数据</div>
- </div>
- <!-- 事件简报部分 -->
- <ShiJianJieBao v-if="activeTab === '事件简报'" :event-id="eventId" />
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, reactive } from 'vue';
- import { taskList } from '@/api/duty/eventing';
- import RenWuGenZong from '@/views/emergencyCommandMap/RightSection/RenWuGenZong.vue'; // 确保 eventing.ts 的路径正确
- import ShiJianJieBao from '@/views/emergencyCommandMap/RightSection/ShiJianJieBao.vue';
- const props = defineProps<{
- eventId?: string; // 使用可选属性
- }>();
- // 定义 tabs
- const tabs = reactive([
- { id: '任务跟踪', label: '任务跟踪' },
- { id: '预案通知', label: '预案通知' },
- { id: '资源调度', label: '资源调度' },
- { id: '事件简报', label: '事件简报' }
- ]);
- const activeTab = ref('任务跟踪');
- const setActiveTab = (id) => {
- activeTab.value = id;
- if (id === '预案通知') {
- fetchData();
- }
- };
- // 定义 notifications
- const notifications = ref([]);
- // 请求数据
- const fetchData = async () => {
- try {
- if (!props.eventId) {
- console.error('eventId 未找到');
- return;
- }
- const response = await taskList({ eventId: props.eventId });
- // const response = await taskList({ eventId: "YJSJ3295457527" });
- if (response.code === 200) {
- console.log('查询成功预案:', response.data);
- updateTaskList(response.data);
- } else {
- console.error('预案查询失败:', response.msg);
- }
- } catch (error) {
- console.error('请求失败:', error);
- }
- };
- // 更新任务列表
- const updateTaskList = (tasks) => {
- notifications.value = tasks.map((task) => ({
- unit: task.dept_name,
- date: task.sent_time,
- status: task.sent_status === 0 ? '暂未发送' : '已发送',
- content: task.yzy_content,
- comment: task.comment,
- receiver: task.nick_name, // 假设所有的任务都有接收者
- name1: getLeaderNames(task.leaders, '赶赴现场人员'), // 赶赴现场人员姓名
- phone1: getLeaderPhones(task.leaders, '赶赴现场人员'), // 赶赴现场人员电话
- name2: getLeaderNames(task.leaders, '指挥部值守人员'), // 指挥部值守人员姓名
- phone2: getLeaderPhones(task.leaders, '指挥部值守人员'), // 指挥部值守人员电话
- leaders: task.leaders // 保留原始 leaders 数据用于模板中的条件判断
- }));
- nextFetchData();
- };
- // 获取特定类型的领导人姓名
- const getLeaderNames = (leaders, userType) => {
- return (
- leaders
- .filter((leader) => leader.user_type === userType)
- .map((leader) => leader.user_name)
- .join('、') || '-'
- );
- };
- // 获取特定类型的领导人电话
- const getLeaderPhones = (leaders, userType) => {
- return (
- leaders
- .filter((leader) => leader.user_type === userType)
- .map((leader) => leader.mobile)
- .join('、') || '-'
- );
- };
- // 设置定时器
- const fetchInterval = process.env.NODE_ENV === 'development' ? 60000 : 1500; // 每60秒刷新一次(刷新太频繁影响调试)
- const nextFetchData = () => {
- setTimeout(() => {
- if (notifications.value.length === 0) {
- fetchData();
- }
- }, fetchInterval);
- };
- watch(
- () => props.eventId,
- () => {
- if (!!props.eventId) {
- fetchData();
- }
- },
- {
- immediate: true
- }
- );
- </script>
- <style lang="scss" scoped>
- .tabs {
- display: flex;
- justify-content: flex-start; /* 选项卡靠左对齐 */
- padding: 0;
- margin-left: 80px;
- margin-top: 75px;
- .active {
- background: url('@/assets/images/emergencyCommandMap/tabActive.png') no-repeat;
- }
- li {
- cursor: pointer;
- padding: 20px;
- font-size: 44px;
- color: #fff;
- width: 349px;
- height: 118px;
- background: url('@/assets/images/emergencyCommandMap/tab.png') no-repeat;
- display: flex;
- justify-content: center;
- align-items: flex-end;
- font-family: YouSheBiaoTiHei;
- &:hover {
- background: url('@/assets/images/emergencyCommandMap/tabActive.png') no-repeat;
- }
- }
- }
- .preplan-notification {
- width: 100%;
- .table-content {
- height: 550px;
- overflow-y: auto;
- .box1 {
- width: 100%;
- display: flex;
- align-items: center;
- &:last-child {
- margin-bottom: 0;
- }
- .success-icon,
- .error-icon {
- margin-right: -50px;
- width: 123px;
- height: 79px;
- background-repeat: no-repeat;
- background-size: contain;
- }
- .success-icon {
- background-image: url('@/assets/images/taskTracking/success.png');
- }
- .error-icon {
- background-image: url('@/assets/images/taskTracking/processing.png');
- }
- .box2 {
- flex: 1;
- background-image: url('@/assets/images/taskTracking/box1.png');
- background-repeat: no-repeat;
- background-size: 1642px 377px;
- background-position: bottom left;
- padding: 20px 20px 20px 60px;
- margin-top: 20px;
- position: relative;
- &:first-child {
- margin-top: 0;
- }
- .box-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- .header-left {
- display: flex;
- align-items: center; // 垂直居中对齐
- }
- .box-title {
- font-size: 44px;
- font-family: YouSheBiaoTiHei;
- color: #ffffff;
- background-image: url('@/assets/images/taskTracking/titleBox.png');
- background-repeat: no-repeat;
- background-size: 311px 56px;
- background-position: bottom left;
- padding-left: 50px;
- }
- .time {
- font-size: 32px;
- color: #00e8ff;
- margin-left: 70px;
- }
- .status {
- width: 354px;
- height: 56px;
- line-height: 56px;
- font-size: 32px;
- color: #ffffff;
- border-radius: 10px;
- text-align: center;
- margin-left: 30px;
- }
- .success {
- background-color: #38c95a;
- }
- .error {
- background-color: #ff4d4f;
- }
- }
- .box-content {
- color: #fff;
- width: 100%;
- font-size: 38px;
- line-height: 1.5;
- margin-top: 10px;
- }
- .box-content2 {
- color: #ff4d4f;
- width: 100%;
- font-size: 38px;
- line-height: 1.5;
- margin-top: 10px;
- }
- }
- }
- }
- }
- .duty-card {
- width: 1968px;
- height: 812px;
- background: url('@/assets/images/commandDynamic/dialog.png') no-repeat;
- position: relative;
- color: #fff;
- animation-name: slideRight;
- animation-duration: 1s;
- .card-content {
- display: flex;
- flex-wrap: wrap;
- padding: 0 0 0 80px;
- width: 100%;
- }
- }
- .resource-scheduling {
- width: 100%;
- display: flex;
- justify-content: center;
- align-items: center;
- font-size: 36px;
- color: #fff;
- }
- .tip {
- font-size: 44px;
- text-align: center;
- }
- </style>
|