Hwf 6 месяцев назад
Родитель
Сommit
1c6ea1ad6c

+ 9 - 0
src/router/routes.ts

@@ -333,6 +333,15 @@ export const constantRoutes: Array<RouteRecordRaw> = [
       noCache: true
     }
   },
+  {
+    path: "/personSubmitted",
+    name: "PersonSubmitted",
+    component: () => import("@/views/InformationReception/personSubmitted.vue"),
+    meta: {
+      title: "响应人员报送",
+      noCache: true
+    }
+  }
 ];
 
 // 领导端动态菜单

+ 122 - 0
src/styles/index.less

@@ -113,3 +113,125 @@ a:hover {
     border: 1px solid #DCE0EE !important;
   }
 }
+
+.common-form-container {
+  width: 100%;
+  height: 100%;
+  background-color: #f4f8fa;
+  padding: 8px 16px 89px;
+  overflow-y: auto;
+  position: relative;
+  .form-item {
+    background-color: #fff;
+    padding: 12px 16px;
+    margin-top: 16px;
+    &:first-child {
+      margin-top: 0;
+    }
+  }
+  .form-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    .form-header-left {
+      display: flex;
+      align-items: center;
+      .line-icon {
+        display: inline-block;
+        width: 6px;
+        height: 16px;
+        background-image: linear-gradient(180deg, #00E1FC 0%, #2C81FF 100%);
+        border-radius: 3px 0 3px 0;
+        margin-right: 3px;
+      }
+      .form-title {
+        margin-right: 12px;
+        font-size: 16px;
+        color: #414F64;
+        font-weight: 600;
+        letter-spacing: 0;
+        line-height: 26px;
+      }
+    }
+    .form-header-right {
+      display: flex;
+      align-items: center;
+      font-size: 12px;
+      color: #2C81FF;
+      .add-icon {
+        margin-right: 3px;
+      }
+    }
+  }
+  .common-form-item {
+    .sub-box {
+      display: flex;
+      align-content: center;
+      justify-content: space-between;
+      .sub-title {
+        font-size: 14px;
+        font-weight: bold;
+        line-height: 26px;
+        color: #414F64;
+      }
+      .sub-delete-box {
+        font-size: 14px;
+        line-height: 26px;
+        color: #FF2F3C;
+      }
+    }
+
+    .van-cell {
+      padding: 6px 0;
+    }
+    .van-cell:after {
+      display: none;
+    }
+    .van-field__label {
+      margin-right: 9px;
+      color: #414F64;
+    }
+    .van-field__body {
+      border: 1px solid #DCE0EE;
+      border-radius: 2px;
+      .van-field__control {
+        height: 30px;
+        padding: 0 5px;
+        color: #414F64;
+      }
+    }
+  }
+  .common-form-footer {
+    position: fixed;
+    left: 0;
+    bottom: 0;
+    width: 100%;
+    height: 81px;
+    background: #FFFFFF;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    .btn {
+      width: 90px;
+      height: 40px;
+      border: 1px solid #D1D1D1;
+      background: #FFFFFF;
+      border-radius: 2px;
+      font-size: 16px;
+      color: #B3B3B3;
+      margin-left: 24px;
+      &:first-child {
+        margin-left: 0;
+      }
+    }
+    .primary-btn {
+      width: 110px;
+      height: 40px;
+      border: 1px solid #2C81FF;
+      background: #2C81FF;
+      border-radius: 2px;
+      font-size: 16px;
+      color: #ffffff;
+    }
+  }
+}

+ 8 - 0
src/typings/informationReception/personSubmitted.d.ts

@@ -0,0 +1,8 @@
+interface Person {
+    name: string;
+    phone: string;
+}
+interface PersonSubmittedForm {
+    data1: Person[];
+    data2: Person[];
+}

+ 0 - 298
src/views/InformationReception/index copy.bak

@@ -1,298 +0,0 @@
-<template>
-  <div class="table-content">
-    <!-- 搜索框 -->
-    <div class="search-box">
-      <el-input
-        v-model="searchQuery"
-        class="search-input"
-        placeholder="请输入内容"
-        prefix-icon="el-icon-search"
-        clearable
-        @keyup.enter="onSearch"
-      />
-    </div>
-    <!-- 筛选和排序区域 -->
-    <div class="filter-sort-area">
-      <div class="filter-item">
-        <span>类型:</span>
-        <span class="type-trigger" @click="showTypePicker">
-          {{ selectedType || "请选择类型" }}
-          <i class="el-icon-arrow-down" />
-        </span>
-      </div>
-      <!-- 类型选择抽屉 -->
-      <el-drawer
-        v-model="typeDrawerVisible"
-        title="选择类型"
-        direction="btt"
-        size="30%"
-      >
-        <ul>
-          <li v-for="type in types" :key="type" @click="selectType(type)">
-            {{ type }}
-          </li>
-        </ul>
-      </el-drawer>
-      <div class="filter-item">
-        <span>时间:</span>
-        <span class="time-label" @click="showTimePicker">
-          {{ selectedTimeLabel || "请选择时间" }}
-        </span>
-        <i class="el-icon-arrow-down" />
-      </div>
-      <div class="filter-item">
-        <span>排序:</span>
-        <span class="sort-order" @click="toggleSortOrder">
-          {{ sortOrder === "asc" ? "↑" : "↓" }}
-          <i
-            :class="['el-icon-arrow-up', sortOrder === 'asc' ? 'active' : '']"
-          />
-          <i
-            :class="[
-              'el-icon-arrow-down',
-              sortOrder === 'desc' ? 'active' : ''
-            ]"
-          />
-        </span>
-      </div>
-    </div>
-
-    <!-- 信息列表 -->
-    <div v-for="(item, index) in sortedDataList" :key="index" class="info-box">
-      <div class="status-icon" :class="getStatusClass(item.examine_status)" />
-      <div class="info-content">
-        <div class="info-header">
-          <div class="info-title">{{ item.title }}</div>
-          <div class="info-time">{{ item.publish_time }}</div>
-        </div>
-        <div class="info-description">
-          <div>发布人:{{ item.nick_name }}</div>
-          <div>部门:{{ item.dept_name }}</div>
-          <div>发布渠道:{{ item.publish_channel }}</div>
-          <div>阅读次数:{{ item.user_count }}</div>
-          <div>审核状态:{{ item.examine_status }}</div>
-          <div>发布状态:{{ item.publish_status }}</div>
-        </div>
-      </div>
-    </div>
-    <!-- 时间选择抽屉 -->
-    <el-drawer
-      v-model="drawerVisible"
-      title="选择时间"
-      direction="btt"
-      size="30%"
-    >
-      <el-date-picker
-        v-model="selectedTime"
-        type="daterange"
-        range-separator="至"
-        start-placeholder="开始日期"
-        end-placeholder="结束日期"
-        @change="handleTimeChange"
-      />
-      <span class="drawer-footer">
-        <el-button @click="drawerVisible = false">取消</el-button>
-        <el-button type="primary" @click="confirmTime">确定</el-button>
-      </span>
-    </el-drawer>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import { ref, onMounted, onUnmounted, watch, computed } from "vue";
-import { InformationList } from "@/api/InformationReception/InformationReception";
-import { parseTime } from "@/utils/ruoyi";
-import {
-  ElInput,
-  ElDrawer,
-  ElDatePicker,
-  ElButton,
-  ElIconArrowDown
-} from "element-plus";
-
-const dataList = ref([]);
-const selectedType = ref("↓");
-const types = ref(["预警", "灾情", "处置", "指挥救援", "公众防范"]);
-const selectedTime = ref([null, null]);
-const sortOrder = ref("desc");
-const drawerVisible = ref(false); // 确保使用 ref 定义
-const selectedTimeLabel = ref("↓");
-const typeDrawerVisible = ref(false);
-const searchQuery = ref("");
-
-const sortedDataList = computed(() => {
-  return dataList.value.slice().sort((a, b) => {
-    if (sortOrder.value === "asc") {
-      return new Date(a.publish_time) - new Date(b.publish_time);
-    } else {
-      return new Date(b.publish_time) - new Date(a.publish_time);
-    }
-  });
-});
-
-const showTypePicker = () => {
-  typeDrawerVisible.value = true;
-};
-
-const selectType = type => {
-  selectedType.value = type;
-  typeDrawerVisible.value = false;
-  fetchData(); // 重新获取数据
-};
-
-const fetchData = async () => {
-  try {
-    const params = {
-      publish_group: "",
-      publish_status: "0",
-      examine_status: "0",
-      page: "1",
-      page_size: "20"
-    };
-    const res = await InformationList(params);
-    dataList.value = res.data.map(item => {
-      item.publish_time = parseTime(item.publish_time);
-      return item;
-    });
-    sortedDataList.value = dataList.value;
-  } catch (error) {
-    console.error("请求任务数据失败:", error);
-  }
-};
-
-onMounted(() => {
-  fetchData();
-});
-
-onUnmounted(() => {
-  // 清除定时器等资源
-});
-
-const toggleSortOrder = () => {
-  sortOrder.value = sortOrder.value === "asc" ? "desc" : "asc";
-};
-
-watch(
-  () => [selectedType.value, selectedTime.value, sortOrder.value],
-  () => {
-    fetchData();
-  }
-);
-
-const showTimePicker = () => {
-  drawerVisible.value = true;
-};
-
-const handleTimeChange = value => {
-  selectedTimeLabel.value = value ? `${value[0]} 至 ${value[1]}` : "请选择时间";
-};
-
-const confirmTime = () => {
-  drawerVisible.value = false;
-  fetchData(); // 重新获取数据
-};
-
-const getStatusClass = (status: string): string => {
-  switch (status) {
-    case "审核中":
-      return "warning-icon";
-    case "待审批":
-      return "pending-icon";
-    case "已通过":
-      return "success-icon";
-    case "已拒绝":
-      return "error-icon";
-    default:
-      return "";
-  }
-};
-
-//搜索
-const onSearch = () => {
-  // 执行搜索操作
-  console.log("搜索内容:", searchQuery.value);
-  // 这里可以添加搜索的逻辑,比如调用 API 或更新数据列表
-};
-</script>
-
-<style scoped>
-.table-content {
-  display: flex;
-  flex-direction: column;
-}
-
-.filter-sort-area {
-  display: flex;
-  justify-content: space-between;
-  margin-bottom: 16px;
-}
-
-.filter-item {
-  display: flex;
-  align-items: center;
-  margin-right: 16px;
-}
-
-.info-box {
-  display: flex;
-  align-items: center;
-  padding: 10px;
-  border-bottom: 1px solid #eee;
-}
-
-.status-icon {
-  width: 20px;
-  height: 20px;
-  margin-right: 10px;
-}
-
-.info-content {
-  flex: 1;
-}
-
-.info-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-}
-
-.info-title {
-  font-weight: bold;
-}
-
-.info-time {
-  font-size: 0.8em;
-  color: #888;
-}
-
-.info-description {
-  color: #333;
-}
-
-.el-icon-arrow-down {
-  margin-left: 8px;
-}
-
-.sort-order {
-  cursor: pointer;
-  display: flex;
-  align-items: center;
-}
-
-.el-icon-arrow-up,
-.el-icon-arrow-down {
-  margin-left: 5px;
-}
-
-.search-box {
-  padding: 10px;
-  background-color: #f5f5f5;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
-
-.search-input {
-  width: 300px;
-}
-</style>

+ 39 - 8
src/views/InformationReception/index.vue

@@ -52,13 +52,37 @@
             <div :class="['info_type', get_info_type_color(item.info_type)]">
               {{ get_info_type_text(item.info_type) }}
             </div>
-            <div class="item-title-text">
-              {{ item.publish_time }}
+            <div class="item-title-text">{{ item.title }}</div>
+          </div>
+          <!--预案通知-->
+          <div v-if="item.info_type === '0'" class="item-content">
+            <div class="line-item">
+              <div class="item-label">预案名称:</div>
+              <div class="item-value">茂名市自然灾害救助应急预案</div>
+            </div>
+            <div class="line-item">
+              <div class="item-label">响应级别:</div>
+              <div class="item-value">Ⅰ级响应</div>
+            </div>
+            <div class="line-item">
+              <div class="item-label">发布时间:</div>
+              <div class="item-value">{{ item.publish_time }}</div>
+            </div>
+            <div class="line-item">
+              <div class="item-label">任务内容:</div>
+              <div class="item-value">{{ item.content || "暂无内容" }}</div>
             </div>
           </div>
-          <div class="item-content">
-            {{ item.content || "暂无内容"}}
+        <div v-else class="item-content">
+          <div class="line-item">
+            <div class="item-label">发布时间:</div>
+            <div class="item-value">{{ item.publish_time }}</div>
           </div>
+          <div class="line-item">
+            <div class="item-label">任务内容:</div>
+            <div class="item-value">{{ item.content || "暂无内容" }}</div>
+          </div>
+        </div>
       </div>
     </van-list>
   </div>
@@ -215,14 +239,14 @@ const getList = () => {
   }
   .item-title {
     display: flex;
+    align-items: center;
     justify-content: flex-start;
-    min-height: 36px;
     background-image: linear-gradient(180deg, #f3f7fd 0%, #ffffff 100%);
-    padding: 0 12px 0 90px;
+    padding: 0 12px 8px 90px;
     .item-title-text {
-      font-size: 14px;
-      line-height: 26px;
+      font-size: 16px;
       color: #414F64;
+      font-weight: bold;
     }
 
     .info_type {
@@ -258,6 +282,13 @@ const getList = () => {
       padding: 0 12px 12px;
       font-size: 14px;
       color: #414f64;
+    .line-item {
+      display: flex;
+      padding: 3px 0;
+      .item-label {
+        flex-shrink: 0;
+      }
+    }
   }
 }
 .van-dropdown-menu {

+ 11 - 2
src/views/InformationReception/infoDetails.vue

@@ -21,6 +21,9 @@
         </div>
       </div>
     </div>
+    <div v-if="infoDetail.info_type === '0'" class="box1">
+      <div class="confirm-btn" @click="handleSubmitted">响应人员报送</div>
+    </div>
     <div v-if="infoDetail.response_type === 1" class="box1">
       <div v-show="infoDetail.response_status === 0" class="confirm-btn" @click="handleReceive">确认收到</div>
       <div v-show="infoDetail.response_status === 1" class="tip">
@@ -28,7 +31,7 @@
         已确认收到此通知
       </div>
     </div>
-    <div v-if="infoDetail.response_type === 2" class="box1">
+    <div v-if="infoDetail.info_type !== '0' && infoDetail.response_type === 2" class="box1">
       <div v-show="infoDetail.response_status === 0" class="confirm-btn" @click="handleShowSignature">签名确认</div>
       <van-image v-show="infoDetail.response_status === 2 && infoDetail.signature" :src="infoDetail.signature" height="100" />
     </div>
@@ -41,13 +44,15 @@
 
 <script lang="ts" setup name="infoDetails">
 import {onMounted, ref} from "vue";
-import {useRoute} from "vue-router";
+import {useRoute, useRouter} from "vue-router";
 import {download2} from "@/utils/request";
 import { InformationDetail, confirmReceived, confirmSignature } from "@/api/InformationReception/InformationReception";
 import { showFailToast } from "vant";
 
 const route = useRoute();
+const router = useRouter();
 const infoDetail = ref({
+  info_type: '',
   // 0阅读 1点击确认 2签字确认
   response_type: 0,
   // 签收状态 0 未确认 1已确认
@@ -63,6 +68,10 @@ let infoId = ref();
 let showSignature = ref(false);
 const baseUrl = import.meta.env.VITE_BASE_API;
 
+const handleSubmitted = () => {
+  router.push({ name: 'PersonSubmitted'})
+};
+
 const handleReceive = () => {
   confirmReceived({id: infoId.value}).then((res)=>{
     infoDetail.value.response_status = res.data.response_status;

+ 161 - 0
src/views/InformationReception/personSubmitted.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="common-form-container">
+    <van-form label-width="60" @submit="onSubmit">
+      <div v-for="(item, index) in form.data1" :key="index" class="form-item">
+        <div v-if="index === 0" class="form-header">
+          <div class="form-header-left">
+            <i class="line-icon" />
+            <div class="form-title">赶赴现场人员</div>
+          </div>
+          <div class="form-header-right" @click="handleAddItem('data1')">
+            <van-icon class="add-icon" name="plus" color="#1989fa" />
+            新增人员
+          </div>
+        </div>
+        <div class="common-form-content">
+          <div class="common-form-item">
+            <div class="sub-box" @click="handleDeleteItem('data1', item)">
+              <div class="sub-title">人员{{index + 1}}</div>
+              <div v-if="index !== 0" class="sub-delete-box">
+                <van-icon class="delete-icon" name="plus" color="#FF2F3C" />
+                移除
+              </div>
+            </div>
+
+            <van-field
+                v-model="item.name"
+                label="姓名:"
+                placeholder="请输入姓名"
+                :rules="rules.name"
+            />
+            <van-field
+                v-model="item.phone"
+                type="tel"
+                label="联系方式:"
+                placeholder="请输入联系方式"
+                :rules="rules.phone"
+            />
+          </div>
+          <van-cell-group inset>
+
+          </van-cell-group>
+        </div>
+      </div>
+      <div v-for="(item, index) in form.data2" :key="index" class="form-item">
+        <div v-if="index === 0" class="form-header">
+          <div class="form-header-left">
+            <i class="line-icon" />
+            <div class="form-title">指挥部值守人员</div>
+          </div>
+          <div class="form-header-right" @click="handleAddItem('data2')">
+            <van-icon class="add-icon" name="plus" color="#1989fa" />
+            新增人员
+          </div>
+        </div>
+        <div class="common-form-content">
+          <div class="common-form-item">
+            <div class="sub-box" @click="handleDeleteItem('data2', item)">
+              <div class="sub-title">人员{{index + 1}}</div>
+              <div v-if="index !== 0" class="sub-delete-box">
+                <van-icon class="delete-icon" name="plus" color="#FF2F3C" />
+                移除
+              </div>
+            </div>
+            <van-field
+                v-model="item.name"
+                label="姓名:"
+                placeholder="请输入姓名"
+                :rules="rules.name"
+            />
+            <van-field
+                v-model="item.phone"
+                type="tel"
+                label="联系方式:"
+                placeholder="请输入联系方式"
+                :rules="rules.phone"
+            />
+          </div>
+          <van-cell-group inset>
+
+          </van-cell-group>
+        </div>
+      </div>
+      <div class="common-form-footer">
+        <van-button class="btn" @click="onCancel">取消</van-button>
+        <van-button class="btn primary-btn" :loading="submitting" type="primary" native-type="submit">提交</van-button>
+      </div>
+    </van-form>
+  </div>
+</template>
+
+<script lang="ts" setup name="personSubmitted">
+import { reactive, ref } from "vue";
+import { validatePhone } from "@/utils/validate";
+import { showConfirmDialog, showSuccessToast } from "vant";
+import { useRouter } from "vue-router";
+
+const router = useRouter();
+// 表单数据
+const form = ref<PersonSubmittedForm>({
+  // 赶赴现场人员
+  data1: [
+    { name: '', phone: '' }
+  ],
+  // 指挥部值守人员
+  data2: [
+    { name: '', phone: '' }
+  ]
+});
+// 表单校验规则
+const rules = reactive({
+  name: [{ required: true, message: '姓名不能为空' }],
+  phone: [
+    { required: true, message: '联系方式不能为空' },
+    { validator: validatePhone, message: '请输入正确格式的联系方式' }
+  ]
+})
+// 是否在提交
+let submitting = ref(false);
+
+// 添加人员
+const handleAddItem = (key: string) => {
+  form.value[key].push({ name: '', phone: '' });
+}
+
+// 移除人员
+const handleDeleteItem = (key: string, person: Person) => {
+  if (!!person.name && !!person.phone) {
+    showConfirmDialog({
+      title: '提示',
+      message: '是否确认移除' + person.name,
+      confirmButtonText: '取消',
+      cancelButtonText: ''
+    }).then(() => {
+      form.value[key].splice(key, 1);
+    })
+  } else {
+    form.value[key].splice(key, 1);
+  }
+}
+// 返回
+const onCancel = () => {
+  router.go(-1);
+};
+
+// 提交表单
+const onSubmit = () => {
+  if (submitting.value) return;
+  submitting.value = true;
+  setTimeout(() => {
+    submitting.value = false;
+    showSuccessToast('提交成功');
+    onCancel();
+  }, 1500);
+}
+</script>
+
+<style lang="scss" scoped>
+.form-header {
+  margin-bottom: 5px;
+}
+</style>