소스 검색

我要发布详情接口联调

Liuzhenyu 1 개월 전
부모
커밋
3630949d1c
22개의 변경된 파일1591개의 추가작업 그리고 301개의 파일을 삭제
  1. 21 0
      src/api/notificationInfoManage/myPublish.ts
  2. 3 2
      src/components/FileUpload/index.vue
  3. 103 8
      src/components/notificationDetailsParts/addNewVesselsDrawer.vue
  4. 39 71
      src/components/notificationDetailsParts/mattersListDrawer.vue
  5. 122 28
      src/components/notificationDetailsParts/questionInformation.vue
  6. 623 0
      src/components/notificationDetailsParts/waterSafetyInformation copy.vue
  7. 18 156
      src/components/notificationDetailsParts/waterSafetyInformation.vue
  8. 7 0
      src/libs/commonMeth.ts
  9. 2 2
      src/router/index.ts
  10. 5 3
      src/views/notificationInfoManage/myPublish/components/detail.vue
  11. 11 3
      src/views/notificationInfoManage/myPublish/index.vue
  12. 6 11
      src/views/notificationInfoManage/myReceptionDisposal/components/detail.vue
  13. 4 1
      src/views/notificationInfoManage/myReceptionDisposal/config/content.config.ts
  14. 8 14
      src/views/notificationInfoManage/myReceptionDisposal/config/search.config.ts
  15. 11 2
      src/views/notificationInfoManage/myReceptionDisposal/index.vue
  16. 143 0
      src/views/notificationInfoManage/viewHistoricalData/components/detail.vue
  17. 53 0
      src/views/notificationInfoManage/viewHistoricalData/components/receivingUnitDealOpinion.vue
  18. 49 0
      src/views/notificationInfoManage/viewHistoricalData/components/receivingUnitOpinion.vue
  19. 24 0
      src/views/notificationInfoManage/viewHistoricalData/config/content.config.ts
  20. 76 0
      src/views/notificationInfoManage/viewHistoricalData/config/detail.config.ts
  21. 131 0
      src/views/notificationInfoManage/viewHistoricalData/config/search.config.ts
  22. 132 0
      src/views/notificationInfoManage/viewHistoricalData/index.vue

+ 21 - 0
src/api/notificationInfoManage/myPublish.ts

@@ -15,4 +15,25 @@ export function fetchReleaseDetail(releasedId) {
         url: `/business/released/${releasedId}`,
         method: 'get',
     })
+}
+
+// 导出我要发布列表
+
+
+// 上传
+export function uploadFile(data) {
+    return request({
+        url: `/business/common/upload`,
+        method: 'post',
+        data,
+    })
+}
+
+// 获取所有未使用的通报事项清单
+export function fetchUnusedItem(params?) {
+    return request({
+        url: `/business/lonm/getUnusedItem`,
+        method: 'get',
+        params
+    })
 }

+ 3 - 2
src/components/FileUpload/index.vue

@@ -80,12 +80,12 @@ const props = defineProps({
     },
     action: {
         type: String,
-        default: '/common/upload',
+        default: 'business/common/upload',
     },
     // 按钮文字
     btnText: {
         type: String,
-        default: '选取文件',
+        default: '点击上传文件',
     },
     // 文件列表是否显示
     showFileList: {
@@ -159,6 +159,7 @@ function handleExceed() {
 // 上传失败
 function handleUploadError(err: any) {
     proxy!.$modal.msgError('上传文件失败');
+    proxy!.$modal.closeLoading();
 }
 
 // 上传成功回调

+ 103 - 8
src/components/notificationDetailsParts/addNewVesselsDrawer.vue

@@ -91,16 +91,61 @@
               />
             </el-form-item>
           </el-col>
+
+          <el-col :span="8">
+            <el-button type="primary" class="search-btn" @click="onSearch">
+              搜索
+            </el-button>
+            <el-button type="default" @click="handleReset">
+              重置
+            </el-button>
+          </el-col>
         </el-row>
-        <div class="demo-drawer__footer">
-          <el-button type="primary" class="search-btn" @click="emit('selectShip', searchForm)">
-            新增
-          </el-button>
-          <el-button type="default" @click="handleReset">
-            重置
-          </el-button>
-        </div>
       </el-form>
+      <el-table 
+        :data="shipList" 
+        border 
+        stripe 
+        style="width: 100%"
+      >
+        <el-table-column prop="chineseName" label="中文船名" width="100" />
+        <el-table-column prop="englishName" label="英文船名" width="120" />
+        <el-table-column prop="initialRegNo" label="初次登记号" width="90" />
+        <el-table-column prop="regNo1" label="船检登记号" width="170" />
+        <el-table-column prop="regNo2" label="船舶登记号" width="170" />
+        <el-table-column prop="portOfRegistry" label="船籍港" width="100" />
+        <el-table-column prop="vesselId" label="船舶识别号" width="220" />
+        <el-table-column prop="imoNo" label="IMO编号" />
+        <el-table-column prop="licenseNo" label="牌薄号" width="90" />
+        <el-table-column prop="vesselType" label="船舶种类" width="90" />
+        <el-table-column prop="buildDate" label="建造日期" width="110" />
+        <el-table-column label="操作" width="80" fixed="right">
+          <template #default="scope">
+            <el-button 
+              type="primary" 
+              text 
+              @click="handleAdd(scope.row)"
+            >
+              添加
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="pagination-container">
+        <el-pagination
+          v-model:current-page="pagination.currentPage"
+          v-model:page-size="pagination.pageSize"
+          :page-sizes="[10, 20, 50, 100]"
+          :small="false"
+          :disabled="total <= 0"
+          :background="true"
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="total"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
     </el-drawer>
   </div>
 </template>
@@ -133,9 +178,40 @@ const searchForm = reactive({
   licenseNo: ''
 });
 
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  pageSizes: [10, 20, 50, 100]
+});
+
+const total = ref(30);
+
 // 表单实例
 const searchFormRef = ref<FormInstance>();
 
+const shipList = ref([
+  {
+    chineseName: '扬子10',
+    englishName: 'YANGZE 10',
+    portOfRegistry: '蒙罗维亚',
+    imoNo: '9574444',
+    vesselType: '散货船',
+    buildDate: '2010-05-15'
+  },
+  {
+    chineseName: '109韩化',
+    englishName: '109 HYO-',
+    imoNo: '9253897',
+    buildDate: '2002-03-20'
+  },
+  {
+    chineseName: '艾斯10',
+    englishName: 'GRAND A-',
+    imoNo: '9443877',
+    buildDate: '2008-03-12'
+  }
+]);
+
 // 重置按钮事件
 const handleReset = () => {
   if (searchFormRef.value) {
@@ -143,6 +219,25 @@ const handleReset = () => {
   }
 };
 
+const onSearch = () => {
+  // TODO 搜索接口
+}
+
+// 分页事件处理
+const handleSizeChange = (val: number) => {
+  console.log(`每页 ${val} 条`);
+  pagination.currentPage = 1; // 页码重置为1
+};
+
+const handleCurrentChange = (val: number) => {
+  console.log(`当前页: ${val}`);
+};
+
+const handleAdd = (row) => {
+  emit('selectShip', row);
+  emit('update:visible', false);
+}
+
 // 监听抽屉显示状态变化,通知父组件
 watch(
   () => visible.value,

+ 39 - 71
src/components/notificationDetailsParts/mattersListDrawer.vue

@@ -34,14 +34,14 @@
               </el-col>
               <el-col :span="8">
                 <el-form-item label="通报事项">
-                  <el-input v-model="searchForm.reportItem" placeholder="请输入通报事项"></el-input>
+                  <el-input v-model="searchForm.deliveryUnit" placeholder="请输入通报事项"></el-input>
                 </el-form-item>
               </el-col>
           </el-row>
           <el-row>
               <el-col :span="8">
                 <el-form-item label="通报依据">
-                  <el-input v-model="searchForm.reportItem" placeholder="请输入通报事项"></el-input>
+                  <el-input v-model="searchForm.deliveryUnit" placeholder="请输入通报事项"></el-input>
                 </el-form-item>
               </el-col>
               <el-col :span="8">
@@ -64,7 +64,7 @@
           <el-row>
               <el-col :span="8">
                 <el-form-item label="通报依据">
-                  <el-input v-model="searchForm.reportItem" placeholder="请输入通报事项"></el-input>
+                  <el-input v-model="searchForm.deliveryUnit" placeholder="请输入通报事项"></el-input>
                 </el-form-item>
               </el-col>
               <el-col :span="8">
@@ -84,30 +84,31 @@
           border
           stripe
           size="small"
-          :row-class-name="rowClassName"
-          @row-click="handleRowClick"
           :highlight-current-row="true"
         >
-          <el-table-column fixed type="radio" label="序号" width="50" align="center">
-            <template #default="{ row }">
-              <el-radio 
-                :label="row.id" 
-                v-model="selectedId"
-                @change="() => handleRadioChange(row)"
-              />
+          <el-table-column fixed type="index" label="序号" width="50" align="center"></el-table-column>
+          <el-table-column prop="deliveryUnit" label="发布单位" min-width="200"></el-table-column>
+          <el-table-column sortable prop="notificationType" label="通报类型" min-width="120"></el-table-column>
+          <el-table-column sortable prop="conm" label="通报事项类别" min-width="120"></el-table-column>
+          <el-table-column sortable prop="notificationMatters" label="通报事项" min-width="120"></el-table-column>
+          <el-table-column prop="notificationStandards" label="通报标准" min-width="120"></el-table-column>
+          <el-table-column prop="notificationBasis" label="通报依据" min-width="120"></el-table-column>
+          <el-table-column sortable prop="TODO" label="处置建议" min-width="120"></el-table-column>
+          <el-table-column prop="deliveryUnit" label="发出单位" min-width="120"></el-table-column>
+          <el-table-column prop="lonmMiddle" label="接收单位" min-width="120"></el-table-column>
+          <el-table-column prop="addDate" label="创建日期" min-width="120"></el-table-column>
+          <el-table-column prop="addName" label="创建人员" min-width="120"></el-table-column>
+          <el-table-column label="操作" width="180" align="center" fixed="right">
+            <template #default="scope">
+              <el-button 
+                type="primary" 
+                text 
+                @click="confirmSelection(scope.row)"
+              >
+                确认选择
+              </el-button>
             </template>
           </el-table-column>
-          <el-table-column prop="reportItem" label="发布单位" min-width="200"></el-table-column>
-          <el-table-column sortable prop="itemType" label="通报类型" min-width="120"></el-table-column>
-          <el-table-column sortable prop="createDate" label="通报事项类别" min-width="120"></el-table-column>
-          <el-table-column sortable prop="createDate" label="通报事项" min-width="120"></el-table-column>
-          <el-table-column prop="createDate" label="通报标准" min-width="120"></el-table-column>
-          <el-table-column prop="createDate" label="通报依据" min-width="120"></el-table-column>
-          <el-table-column sortable prop="createDate" label="处置建议" min-width="120"></el-table-column>
-          <el-table-column prop="createDate" label="发出单位" min-width="120"></el-table-column>
-          <el-table-column prop="createDate" label="接收单位" min-width="120"></el-table-column>
-          <el-table-column prop="createDate" label="创建日期" min-width="120"></el-table-column>
-          <el-table-column prop="createDate" label="创建人员" min-width="120"></el-table-column>
         </el-table>
 
         <!-- 分页器 -->
@@ -120,92 +121,59 @@
           />
         </div>
       </div>
-
-      <div class="drawer-footer">
-        <el-button @click="emit('update:visible', false)">取消</el-button>
-        <el-button 
-          type="primary" 
-          @click="confirmSelection" 
-          :disabled="!selectedRow"
-        >
-          确认选择
-        </el-button>
-      </div>
     </el-drawer>
   </div>
 </template>
 
 <script setup lang="ts">
 import { ref, reactive, watch, defineProps, defineEmits } from 'vue';
+import { fetchUnusedItem } from '@/api/notificationInfoManage/myPublish';
+import { outTypeList } from '@/libs/commonMeth';
 
 // 接收父组件传递的参数
 const props = defineProps({
   visible: { type: Boolean, default: false },
 });
 
-// 向父组件发送事件(v-model语法糖)
+// 向父组件发送事件
 const emit = defineEmits(['update:visible', 'update:selectedRow']);
 
+// 通报事项类别
+const categoryOnm = outTypeList('bj_category_onm');
+
 // 单选状态管理
-const selectedId = ref<number>(0);          // 选中行的ID
-const selectedRow = ref<any>(null);         // 选中的行数据
-const tableData = ref<any[]>([]);           // 表格数据
+const tableData = ref<any[]>([]);
 const pagination = reactive({ currentPage: 1, pageSize: 10, total: 0 });
-const searchForm = reactive({ reportType: '', reportItem: '' });
+const searchForm = reactive({ reportType: '', deliveryUnit: '' });
 
 // 监听抽屉打开/关闭
 watch(
   () => props.visible,
   (newVal) => {
     if (newVal) {
-      // 抽屉打开时:加载数据 + 回显已选择项
       fetchTableData();
-    } else {
-      // 抽屉关闭时:重置选中状态(可选,根据需求保留)
-      selectedId.value = 0;
-      selectedRow.value = null;
     }
   }
 );
 
 // 加载表格数据(模拟接口)
-const fetchTableData = () => {
+const fetchTableData = async() => {
+  const response = await fetchUnusedItem()
   // 实际项目中替换为接口调用
-  tableData.value = [
-    { id: 1, reportItem: '船舶硫含量超标燃油使用', itemType: '信息告知类', createDate: '2024-07-22' },
-    { id: 2, reportItem: '水路运输市场监管违规', itemType: '协助处置类', createDate: '2023-07-07' },
-    { id: 3, reportItem: '船舶超核定载重线航行', itemType: '信息告知类', createDate: '2024-07-22' }
-  ];
+  tableData.value = response.data;
   pagination.total = tableData.value.length;
 };
 
-// 点击行选中(单选逻辑)
-const handleRowClick = (row: any) => {
-  selectedId.value = row.id;
-  selectedRow.value = row;
-};
-
-// 单选框变更事件
-const handleRadioChange = (row: any) => {
-  selectedRow.value = row;
-};
-
 // 确认选择(向父组件传递选中数据并关闭抽屉)
-const confirmSelection = () => {
-  if (selectedRow.value) {
-    emit('update:selectedRow', selectedRow.value);  // 传递选中行数据
-    emit('update:visible', false);                  // 关闭抽屉
-  }
+const confirmSelection = (row) => {
+    emit('update:selectedRow', row);
+    emit('update:visible', false);
 };
 
 // 搜索/重置
 const handleSearch = () => { /* 实际项目中调用接口 */ };
-const handleReset = () => Object.assign(searchForm, { reportType: '', reportItem: '' });
+const handleReset = () => Object.assign(searchForm, { reportType: '', deliveryUnit: '' });
 
-// 行样式(高亮选中行)
-const rowClassName = ({ row }: { row: any }) => {
-  return row.id === selectedId.value ? 'selected-row' : '';
-};
 </script>
 
 <style scoped lang="scss">

+ 122 - 28
src/components/notificationDetailsParts/questionInformation.vue

@@ -238,23 +238,37 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, computed, onMounted, watch } from 'vue';
+import { ref, reactive, computed, onMounted, watch, defineExpose } from 'vue';
 import { useRoute } from 'vue-router';
 import type { FormInstance, FormRules } from 'element-plus';
 import { Plus, Warning } from '@element-plus/icons-vue';
 import AddNewVesselsDrawer from './addNewVesselsDrawer.vue';
 
+// 类型定义
+export interface ShipFormExpose {
+  validateForm: () => Promise<FormValidationResult>;
+  resetForm: () => void;
+  getFormData: () => Record<string, any>;
+}
+
+interface FormValidationResult {
+  valid: boolean;
+  data?: Record<string, any>;
+  errors?: any;
+  firstErrorField?: string;
+}
+
 // 路由参数获取
 const route = useRoute();
-const currentType = ref<'add' | 'edit' | 'detail'>('add'); // 当前页面类型
+const currentType = ref<'add' | 'edit' | 'detail'>('add');
 
-// 表单基础配置
+// 表单引用和状态
 const ruleFormRef = ref<FormInstance>();
 const activeNames = ref(['1']);
 const drawerVisible = ref(false);
-const isShowAdd = ref(true); // 是否显示添加按钮
+const isShowAdd = ref(true);
 
-// 表单数据与验证规则
+// 表单数据
 const formData = reactive({
   chineseVesselName: '',
   englishVesselName: '',
@@ -275,6 +289,7 @@ const formData = reactive({
   sid: ''
 });
 
+// 表单验证规则
 const formRules = reactive<FormRules>({
   chineseVesselName: [
     { required: true, message: '请输入中文船名', trigger: 'blur' },
@@ -303,6 +318,34 @@ const formRules = reactive<FormRules>({
   ]
 });
 
+// 表单校验-暴露给父组件
+const validateForm = async (): Promise<FormValidationResult> => {
+  if (!ruleFormRef.value) {
+    return { valid: false, errors: '表单未初始化' };
+  }
+
+  try {
+    await ruleFormRef.value.validate();
+    return { 
+      valid: true, 
+      data: JSON.parse(JSON.stringify(formData)) 
+    };
+  } catch (errors) {
+    return {
+      valid: false,
+      errors,
+    };
+  }
+};
+
+const resetForm = () => {
+  ruleFormRef.value?.resetFields();
+};
+
+const getFormData = () => {
+  return JSON.parse(JSON.stringify(formData));
+};
+
 // 根据路由类型控制可编辑状态
 const isEditable = computed(() => {
   return currentType.value === 'add' || currentType.value === 'edit';
@@ -318,62 +361,113 @@ onMounted(() => {
 
   // 根据类型加载数据
   if (currentType.value === 'edit' || currentType.value === 'detail') {
-    fetchShipData(); // 模拟从接口加载船舶数据
+    fetchShipData();
   } else if (currentType.value === 'add') {
-    // 新增场景可预设默认值
-    formData.vesselType = 'bulkCarrier'; // 默认为散货船
+    formData.vesselType = 'bulkCarrier';
   }
 });
 
-// 模拟加载船舶数据(edit/detail 场景)
+// 模拟加载船舶数据
 const fetchShipData = () => {
   const { info } = route.query;
   if (typeof info === 'string') {
-    Object.assign(formData, JSON.parse(info));
+    try {
+      const parsedData = JSON.parse(info);
+      Object.assign(formData, parsedData);
+      isShowAdd.value = false;
+    } catch (e) {
+      console.error('解析船舶数据失败:', e);
+    }
   }
-  isShowAdd.value = false;
 };
 
-// 监听路由参数变化(支持页面内切换类型)
+const handleReset = () => {
+  // 重置 formData
+}
+
+// 监听路由参数变化
 watch(
   () => route.query.type,
   (newType) => {
     if (['add', 'edit', 'detail'].includes(newType as string)) {
       currentType.value = newType as 'add' | 'edit' | 'detail';
-      // 重新加载数据
       if (currentType.value === 'edit' || currentType.value === 'detail') {
         fetchShipData();
       } else {
-        handleReset(); // 新增场景重置表单
-        isShowAdd.value = true; // 新增场景显示添加按钮
+        resetForm();
+        isShowAdd.value = true;
       }
     }
   }
 );
 
-// 重置表单
-const handleReset = () => {
-  if (!ruleFormRef.value) return;
-  ruleFormRef.value.resetFields();
-  // 重置后恢复默认值(新增场景)
-  if (currentType.value === 'add') {
-    formData.vesselType = 'bulkCarrier';
-  }
-};
-
 // 选择船舶回调
-const handleSelectShip = (data) => {
+const handleSelectShip = (data: any) => {
   console.log('选择船舶数据:', data);
+  Object.assign(formData, data);
   drawerVisible.value = false;
-  isShowAdd.value = false; // 隐藏添加按钮,显示表单
+  isShowAdd.value = false;
 };
 
 // 打开添加船舶抽屉
 const onAddVessels = () => {
   drawerVisible.value = true;
 };
+
+// 暴露方法给父组件
+defineExpose<ShipFormExpose>({
+  validateForm,
+  resetForm,
+  getFormData
+});
+
 </script>
 
 <style scoped lang="scss">
-@import "@/styles/questionInformation.scss";
+.ship-info-form {
+  background: #fff;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
+}
+
+.collapse-panel {
+  :deep(.el-collapse-item__header) {
+    color: #5070ae;
+    font-size: 16px;
+    font-weight: bold;
+    background: linear-gradient(135deg, #d2e8ff, #fcfeff);
+    box-shadow: 0 8px 20px #fcfeff;
+    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+    padding-left: 20px;
+    height: 50px;
+  }
+
+  :deep(.el-collapse-item__wrap) {
+    padding: 20px;
+  }
+}
+
+.form-container {
+  .el-form-item {
+    margin-bottom: 18px;
+  }
+}
+
+.form-actions {
+  margin-top: 20px;
+  text-align: center;
+  
+  .reset-btn {
+    margin-right: 20px;
+  }
+}
+
+.flex-cc {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 20px;
+  padding: 20px 0;
+}
 </style>

+ 623 - 0
src/components/notificationDetailsParts/waterSafetyInformation copy.vue

@@ -0,0 +1,623 @@
+<template>
+  <div class="ship-info-form">
+    <el-collapse v-model="activeNames">
+      <el-collapse-item title="水上交通安全通报信息" name="1" :border="false">
+        <el-form
+          v-for="(item, index) in noticeItems"
+          :key="index"
+          :ref="(el) => noticeFormRefs[index] = el"
+          :model="item"
+          :rules="formRules"
+          label-width="160px"
+          size="default"
+          class="notice-form"
+        >
+          <!-- 通报信息标题 + 删除按钮 -->
+          <div class="notification-header">
+            <div class="notification-matters">{{ '通报信息' + (index + 1) }}</div>
+            <el-button
+              v-if="noticeItems.length > 1 && isEditable"
+              type="danger"
+              text
+              size="small"
+              :icon="Delete"
+              @click="handleDelete(index)"
+            >
+              删除
+            </el-button>
+          </div>
+
+          <!-- 通报事项 -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="通报事项" prop="noticeItem" required>
+                <el-button
+                  v-if="!drawerVisible && !item.noticeItem && isEditable"
+                  @click="onClickNotice(index)"
+                  type="primary"
+                  :disabled="!isEditable"
+                >
+                  请选择通报事项
+                </el-button>
+                <el-input v-else disabled v-model="item.noticeItem" />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 通报标准或具体行为 -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="通报标准或具体行为" prop="noticeStandard" required>
+                <el-input
+                  v-model="item.noticeStandard"
+                  placeholder="请输入通报依据,内容1000字以内"
+                  maxlength="1000"
+                  show-word-limit
+                  :disabled="!isEditable"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 通报类别(单选框) -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="通报类别" prop="noticeType" required>
+                <el-radio-group v-model="item.noticeType" :disabled="!isEditable">
+                  <el-radio label="info" border>信息告知类</el-radio>
+                  <el-radio label="assist" border>协助处置类</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 水上交通安全信息(多行文本) -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="水上交通安全信息" prop="safetyInfo" required>
+                <el-input
+                  v-model="item.safetyInfo"
+                  type="textarea"
+                  :rows="4"
+                  placeholder="违法违规信息(内容3000字以内)"
+                  maxlength="3000"
+                  show-word-limit
+                  :disabled="!isEditable"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 接收单位名称(下拉选择) -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="接收单位名称" prop="receiveUnit" required>
+                <el-select
+                  v-model="item.receiveUnit"
+                  placeholder="请选择单位名称"
+                  style="width: 100%"
+                  :disabled="!isEditable"
+                >
+                  <el-option label="单位名称1" value="unit1" />
+                  <el-option label="单位名称2" value="unit2" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 行业外分类和接收单位 -->
+          <el-row :gutter="24" class="industry-row">
+            <el-col :span="6">
+              <el-form-item label="行业外分类" prop="industryType">
+                <el-select
+                  v-model="item.industryType"
+                  placeholder="请选择行业外分类"
+                  :disabled="!isEditable"
+                >
+                  <el-option label="海警机构" value="marine" />
+                  <el-option label="公安机关" value="public" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="18">
+              <el-form-item label="行业外接收单位名称" prop="otherUnit">
+                <el-input
+                  v-model="item.otherUnit"
+                  placeholder="请输入行业外接收单位名称 如:XXX1海警机构,XXX2海警机构,XX公安机关"
+                  maxlength="200"
+                  :disabled="!isEditable"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row :gutter="24">
+            <el-col :span="8">
+              <el-form-item label="安全管理建议" prop="penaltyFile">
+                <FileUpload v-model="item.penaltyFile"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="通报事项的相关证据" prop="safetySuggestion">
+                <FileUpload v-model="item.penaltyFile"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="通报事项的其他材料" prop="safetySuggestion">
+                <FileUpload v-model="item.penaltyFile"/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+
+          <!-- 上传附件区域(核心改造) -->
+          <el-row :gutter="24" class="upload-area">
+            <el-col :span="24">
+              <div class="upload-cards">
+                <!-- 1. 行政处罚决定 -->
+                <div class="upload-card">
+                  <div class="card-title">行政处罚决定</div>
+                  <!-- 查看模式:显示下载链接 -->
+                  <div v-if="!isEditable && item.attachments?.punishment?.length" class="file-link-list">
+                    <div v-for="file in item.attachments.punishment" :key="file.id" class="file-link-item">
+                      <el-link :href="file.url" target="_blank" :underline="false">
+                        <el-icon><Document /></el-icon>
+                        {{ file.name }}
+                      </el-link>
+                    </div>
+                  </div>
+                  <!-- 编辑模式:上传组件(支持覆盖) -->
+                  <el-upload
+                    v-else-if="isEditable"
+                    class="upload-demo"
+                    drag
+                    action="#"
+                    :limit="1"
+                    :file-list="item.attachments?.punishment || []"
+                    :on-change="(file) => handleFileChange(file, item, 'punishment')"
+                    :before-upload="beforeUpload"
+                  >
+                    <el-icon class="el-icon-upload"><UploadFilled /></el-icon>
+                    <div class="el-upload__text">点击上传文件</div>
+                    <div class="el-upload__tip" v-if="item.attachments?.punishment?.length">
+                      当前已上传:{{ item.attachments.punishment[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
+                    </div>
+                  </el-upload>
+                  <!-- 无文件时显示空状态 -->
+                  <div v-else class="file-empty">暂无附件</div>
+                </div>
+                <!-- 2. 通报事项的相关证据(必填) -->
+                <div class="upload-card">
+                  <div class="card-title">通报事项的相关证据 <span class="required-mark">*</span></div>
+                  <!-- 查看模式:显示下载链接 -->
+                  <div v-if="!isEditable && item.attachments?.evidence?.length" class="file-link-list">
+                    <div v-for="file in item.attachments.evidence" :key="file.id" class="file-link-item">
+                      <el-link :href="file.url" target="_blank" :underline="false">
+                        <el-icon><Document /></el-icon>
+                        {{ file.name }}
+                      </el-link>
+                    </div>
+                  </div>
+                  <!-- 编辑模式:上传组件(支持覆盖) -->
+                  <el-upload
+                    v-else-if="isEditable"
+                    class="upload-demo"
+                    drag
+                    action="#"
+                    :limit="1"
+                    :file-list="item.attachments?.evidence || []"
+                    :on-change="(file) => handleFileChange(file, item, 'evidence')"
+                    :before-upload="beforeUpload"
+                  >
+                    <el-icon class="el-icon-upload"><UploadFilled /></el-icon>
+                    <div class="el-upload__text">点击上传文件</div>
+                    <div class="el-upload__tip" v-if="item.attachments?.evidence?.length">
+                      当前已上传:{{ item.attachments.evidence[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
+                    </div>
+                  </el-upload>
+                  <!-- 无文件时显示空状态 -->
+                  <div v-else class="file-empty">暂无附件</div>
+                </div>
+
+                <!-- 3. 通报事项的其他材料 -->
+                <div class="upload-card">
+                  <div class="card-title">通报事项的其他材料</div>
+                  <!-- 查看模式:显示下载链接 -->
+                  <div v-if="!isEditable && item.attachments?.other?.length" class="file-link-list">
+                    <div v-for="file in item.attachments.other" :key="file.id" class="file-link-item">
+                      <el-link :href="file.url" target="_blank" :underline="false">
+                        <el-icon><Document /></el-icon>
+                        {{ file.name }}
+                      </el-link>
+                    </div>
+                  </div>
+                  <!-- 编辑模式:上传组件(支持覆盖) -->
+                  <el-upload
+                    v-else-if="isEditable"
+                    class="upload-demo"
+                    drag
+                    action="#"
+                    :limit="1"
+                    :file-list="item.attachments?.other || []"
+                    :on-change="(file) => handleFileChange(file, item, 'other')"
+                    :before-upload="beforeUpload"
+                  >
+                    <el-icon class="el-icon-upload"><UploadFilled /></el-icon>
+                    <div class="el-upload__text">点击上传文件</div>
+                    <div class="el-upload__tip" v-if="item.attachments?.other?.length">
+                      当前已上传:{{ item.attachments.other[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
+                    </div>
+                  </el-upload>
+                  <!-- 无文件时显示空状态 -->
+                  <div v-else class="file-empty">暂无附件</div>
+                </div>
+                <!-- <div class="upload-tip text-danger">
+                  提示:目前支持的文件格式:*.gif, *.jpeg, *.jpg, *.png, *.rar, *.zip, *.doc, *.ppt, *.xls, *.pdf, *.docx *.xlsx, *.bmp, *.xml,*.ofd,*.wps。文件大小支持:100M以内。
+                </div> -->
+              </div>
+            </el-col>
+          </el-row>
+
+          <!-- 安全管理建议 -->
+          <el-row :gutter="24" class="mt-4">
+            <el-col :span="24">
+              <el-form-item label="安全管理建议" prop="safetySuggestion" required>
+                <el-input
+                  v-model="item.safetySuggestion"
+                  type="textarea"
+                  :rows="2"
+                  placeholder="安全管理建议(内容200字以内)"
+                  maxlength="200"
+                  show-word-limit
+                  :disabled="!isEditable"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 安全管理建议附件(核心改造) -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="安全管理建议附件">
+                <!-- 查看模式:显示下载链接 -->
+                <div v-if="!isEditable && item.attachments?.suggestion?.length" class="file-link-list">
+                  <div v-for="file in item.attachments.suggestion" :key="file.id" class="file-link-item">
+                    <el-link :href="file.url" target="_blank" :underline="false">
+                      <el-icon><Document /></el-icon>
+                      {{ file.name }}
+                    </el-link>
+                  </div>
+                </div>
+                <!-- 编辑模式:上传组件(支持覆盖) -->
+                <el-upload
+                  v-else-if="isEditable"
+                  class="upload-demo"
+                  action="#"
+                  :limit="1"
+                  :file-list="item.attachments?.suggestion || []"
+                  :on-change="(file) => handleFileChange(file, item, 'suggestion')"
+                  :before-upload="beforeUpload"
+                >
+                  <el-button size="small" type="primary">上传文件</el-button>
+                  <!-- <div class="el-upload__tip" v-if="item.attachments?.suggestion?.length">
+                    当前已上传:{{ item.attachments.suggestion[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
+                  </div> -->
+                </el-upload>
+                <!-- 无文件时显示空状态 -->
+                <div v-else class="file-empty mt-2">暂无附件</div>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 是否需要反馈 -->
+          <el-row :gutter="24">
+            <el-col :span="24">
+              <el-form-item label="是否需要反馈" prop="needFeedback" required>
+                <el-radio-group v-model="item.needFeedback" :disabled="!isEditable">
+                  <el-radio label="no" border>否</el-radio>
+                  <el-radio label="yes" border>是</el-radio>
+                </el-radio-group>
+              </el-form-item>
+            </el-col>
+          </el-row>
+
+          <!-- 分隔线(区分多个通报事项) -->
+          <el-divider v-if="index !== noticeItems.length - 1" />
+        </el-form>
+
+        <!-- 添加通报事项按钮 -->
+        <div class="add-matters" v-if="isEditable">
+          <el-button type="primary" plain :icon="Plus" @click="addNoticeItem">添加通报事项</el-button>
+        </div>
+      </el-collapse-item>
+    </el-collapse>
+    <MattersListDrawer
+      v-model:visible="drawerVisible"
+      @updateSelectedRow="updateSelectedRow"
+      :disabled="!isEditable"
+    />
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, defineEmits, defineExpose, onMounted, watch, computed } from 'vue';
+import { useRoute } from 'vue-router';
+import type { FormInstance, FormRules, UploadFile } from 'element-plus';
+import { UploadFilled, Plus, Delete, Document } from '@element-plus/icons-vue';
+import { ElMessage } from 'element-plus';
+import MattersListDrawer from './mattersListDrawer.vue';
+
+// 路由参数获取
+const route = useRoute();
+const currentType = ref<'add' | 'edit' | 'detail'>('add');
+const isEditable = computed(() => currentType.value === 'add' || currentType.value === 'edit');
+const activeNames = ref(['1']);
+
+// 附件类型定义
+interface AttachmentFile {
+  id: string; // 文件唯一标识
+  name: string; // 文件名
+  url: string; // 下载链接(查看模式)
+  raw?: File; // 原始文件(编辑模式上传用)
+  uid?: string; // element-plus upload 内部标识
+}
+
+// 通报事项类型定义
+interface NoticeItem {
+  noticeItem: string;
+  noticeStandard: string;
+  noticeType: 'info' | 'assist';
+  safetyInfo: string;
+  receiveUnit: string;
+  industryType: string;
+  otherUnit: string;
+  safetySuggestion: string;
+  needFeedback: 'yes' | 'no';
+  attachments?: {
+    punishment?: AttachmentFile[]; // 行政处罚决定
+    evidence?: AttachmentFile[];    // 通报事项的相关证据
+    other?: AttachmentFile[];       // 通报事项的其他材料
+    suggestion?: AttachmentFile[];  // 安全管理建议附件
+  };
+}
+
+// 表单数据
+const noticeItems = ref([
+  {
+    noticeItem: '',
+    noticeStandard: '',
+    noticeType: 'info',
+    safetyInfo: '',
+    receiveUnit: '',
+    industryType: '',
+    otherUnit: '',
+    safetySuggestion: '',
+    needFeedback: 'no',
+    penaltyFile: '',
+    attachments: {
+      punishment: [],
+      evidence: [],
+      other: [],
+      suggestion: []
+    }
+  }
+]);
+
+// 表单引用
+const noticeFormRefs = ref<(FormInstance | undefined)[]>([]);
+
+// 表单验证规则
+const formRules = reactive<FormRules>({
+  noticeItem: [
+    { required: true, message: '请填写通报事项', trigger: 'blur' },
+    { max: 500, message: '长度不能超过500个字符', trigger: 'blur' }
+  ],
+  noticeStandard: [
+    { required: true, message: '请输入通报标准或具体行为', trigger: 'blur' },
+    { max: 1000, message: '长度不能超过1000个字符', trigger: 'blur' }
+  ],
+  noticeType: [
+    { required: true, message: '请选择通报类别', trigger: 'change' }
+  ],
+  safetyInfo: [
+    { required: true, message: '请填写水上交通安全信息', trigger: 'blur' },
+    { max: 3000, message: '长度不能超过3000个字符', trigger: 'blur' }
+  ],
+  receiveUnit: [
+    { required: true, message: '请选择接收单位名称', trigger: 'change' }
+  ],
+  safetySuggestion: [
+    { required: true, message: '请填写安全管理建议', trigger: 'blur' },
+    { max: 200, message: '长度不能超过200个字符', trigger: 'blur' }
+  ],
+  needFeedback: [
+    { required: true, message: '请选择是否需要反馈', trigger: 'change' }
+  ]
+});
+
+// 抽屉控制
+const drawerVisible = ref(false);
+const selectNoticeId = ref(0);
+
+// 初始化
+onMounted(() => {
+  // 从路由获取页面类型
+  const type = route.query.type as 'add' | 'edit' | 'detail';
+  if (['add', 'edit', 'detail'].includes(type)) {
+    currentType.value = type;
+  }
+
+  // 编辑/详情模式加载数据
+  if (currentType.value === 'edit' || currentType.value === 'detail') {
+    fetchNoticeData();
+  }
+});
+
+// 监听路由变化
+watch(
+  () => route.query.type,
+  (newType) => {
+    if (['add', 'edit', 'detail'].includes(newType as string)) {
+      currentType.value = newType as 'add' | 'edit' | 'detail';
+      currentType.value === 'add' ? resetAllForms() : fetchNoticeData();
+    }
+  }
+);
+
+// 模拟加载数据(edit/detail 场景)
+const fetchNoticeData = () => {
+  setTimeout(() => {
+    noticeItems.value = [
+      {
+        noticeItem: '未按规定配备救生设备',
+        noticeStandard: '根据《内河交通安全管理条例》第23条,船舶应配备符合标准的救生设备',
+        noticeType: 'info',
+        safetyInfo: '2023年10月15日,"扬子10"轮在长江口航行时,未按规定配备救生衣,违反安全管理规定。',
+        receiveUnit: 'unit1',
+        industryType: 'marine',
+        otherUnit: '东海海警机构',
+        safetySuggestion: '立即整改,配备足额救生设备并组织船员培训。',
+        needFeedback: 'yes',
+        attachments: {
+          // 模拟后端返回的附件数据(查看模式显示链接)
+          punishment: [
+            {
+              id: '1',
+              name: '行政处罚决定书.pdf',
+              url: 'https://example.com/files/punishment1.pdf'
+            }
+          ],
+          evidence: [
+            {
+              id: '2',
+              name: '现场检查照片.jpg',
+              url: 'https://example.com/files/evidence1.jpg'
+            }
+          ],
+          suggestion: [
+            {
+              id: '3',
+              name: '整改建议.docx',
+              url: 'https://example.com/files/suggestion1.docx'
+            }
+          ]
+        }
+      }
+    ];
+  }, 500);
+};
+
+// 通报事项选择
+const onClickNotice = (id: number) => {
+  selectNoticeId.value = id;
+  drawerVisible.value = true;
+};
+
+const updateSelectedRow = (row: any) => {
+  noticeItems.value[selectNoticeId.value] = { ...noticeItems.value[selectNoticeId.value], ...row };
+  drawerVisible.value = false;
+};
+
+// 文件上传变化(覆盖逻辑)
+const handleFileChange = (file: UploadFile, item: NoticeItem, type: 'punishment' | 'evidence' | 'other' | 'suggestion') => {
+  // 初始化附件对象
+  if (!item.attachments) {
+    item.attachments = {
+      punishment: [],
+      evidence: [],
+      other: [],
+      suggestion: []
+    };
+  }
+  // 覆盖上传(只保留最新1个文件)
+  item.attachments[type] = [file as AttachmentFile];
+};
+
+// 文件上传前校验
+const beforeUpload = (file: File) => {
+  // 实际项目中替换为真实上传逻辑
+  console.log('文件待上传:', file);
+  return false; // 阻止默认上传
+};
+
+// 删除通报事项
+const handleDelete = (index: number) => {
+  if (noticeItems.value.length <= 1) {
+    ElMessage.warning('至少保留一个通报事项');
+    return;
+  }
+  noticeItems.value.splice(index, 1);
+  noticeFormRefs.value.splice(index, 1);
+};
+
+// 添加通报事项
+const addNoticeItem = () => {
+  noticeItems.value.push({
+    noticeItem: '',
+    noticeStandard: '',
+    noticeType: 'info',
+    safetyInfo: '',
+    receiveUnit: '',
+    industryType: '',
+    otherUnit: '',
+    safetySuggestion: '',
+    needFeedback: 'no',
+    attachments: {
+      punishment: [],
+      evidence: [],
+      other: [],
+      suggestion: []
+    }
+  });
+};
+
+// 表单校验
+const validateForm = async () => {
+  let isAllValid = true;
+  for (let i = 0; i < noticeFormRefs.value.length; i++) {
+    const formRef = noticeFormRefs.value[i];
+    if (!formRef) continue;
+    try {
+      await formRef.validate();
+    } catch (error) {
+      isAllValid = false;
+    }
+  }
+  emit('validate', isAllValid);
+  return isAllValid;
+};
+
+// 重置表单
+const resetAllForms = () => {
+  noticeItems.value = [{
+    noticeItem: '',
+    noticeStandard: '',
+    noticeType: 'info',
+    safetyInfo: '',
+    receiveUnit: '',
+    industryType: '',
+    otherUnit: '',
+    safetySuggestion: '',
+    needFeedback: 'no',
+    attachments: {
+      punishment: [],
+      evidence: [],
+      other: [],
+      suggestion: []
+    }
+  }];
+  noticeFormRefs.value.forEach(formRef => formRef?.resetFields());
+};
+
+// 暴露方法给父组件
+const emit = defineEmits<{
+  (e: 'validate', isValid: boolean): void;
+}>();
+
+defineExpose({
+  validateForm,
+  resetAllForms
+});
+</script>
+<style scoped lang="scss">
+@import "@/styles/waterSafetyInformation.scss";
+</style>

+ 18 - 156
src/components/notificationDetailsParts/waterSafetyInformation.vue

@@ -130,113 +130,21 @@
               </el-form-item>
             </el-col>
           </el-row>
-
-          <!-- 上传附件区域(核心改造) -->
-          <el-row :gutter="24" class="upload-area">
-            <el-col :span="24">
-              <div class="upload-cards">
-                <!-- 1. 行政处罚决定 -->
-                <div class="upload-card">
-                  <div class="card-title">行政处罚决定</div>
-                  <!-- 查看模式:显示下载链接 -->
-                  <div v-if="!isEditable && item.attachments?.punishment?.length" class="file-link-list">
-                    <div v-for="file in item.attachments.punishment" :key="file.id" class="file-link-item">
-                      <el-link :href="file.url" target="_blank" :underline="false">
-                        <el-icon><Document /></el-icon>
-                        {{ file.name }}
-                      </el-link>
-                    </div>
-                  </div>
-                  <!-- 编辑模式:上传组件(支持覆盖) -->
-                  <el-upload
-                    v-else-if="isEditable"
-                    class="upload-demo"
-                    drag
-                    action="#"
-                    :limit="1"
-                    :file-list="item.attachments?.punishment || []"
-                    :on-change="(file) => handleFileChange(file, item, 'punishment')"
-                    :before-upload="beforeUpload"
-                  >
-                    <el-icon class="el-icon-upload"><UploadFilled /></el-icon>
-                    <div class="el-upload__text">点击上传文件(最多1个)</div>
-                    <div class="el-upload__tip" v-if="item.attachments?.punishment?.length">
-                      当前已上传:{{ item.attachments.punishment[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
-                    </div>
-                  </el-upload>
-                  <!-- 无文件时显示空状态 -->
-                  <div v-else class="file-empty">暂无附件</div>
-                </div>
-
-                <!-- 2. 通报事项的相关证据(必填) -->
-                <div class="upload-card">
-                  <div class="card-title">通报事项的相关证据 <span class="required-mark">*</span></div>
-                  <!-- 查看模式:显示下载链接 -->
-                  <div v-if="!isEditable && item.attachments?.evidence?.length" class="file-link-list">
-                    <div v-for="file in item.attachments.evidence" :key="file.id" class="file-link-item">
-                      <el-link :href="file.url" target="_blank" :underline="false">
-                        <el-icon><Document /></el-icon>
-                        {{ file.name }}
-                      </el-link>
-                    </div>
-                  </div>
-                  <!-- 编辑模式:上传组件(支持覆盖) -->
-                  <el-upload
-                    v-else-if="isEditable"
-                    class="upload-demo"
-                    drag
-                    action="#"
-                    :limit="1"
-                    :file-list="item.attachments?.evidence || []"
-                    :on-change="(file) => handleFileChange(file, item, 'evidence')"
-                    :before-upload="beforeUpload"
-                  >
-                    <el-icon class="el-icon-upload"><UploadFilled /></el-icon>
-                    <div class="el-upload__text">点击上传文件(最多1个)</div>
-                    <div class="el-upload__tip" v-if="item.attachments?.evidence?.length">
-                      当前已上传:{{ item.attachments.evidence[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
-                    </div>
-                  </el-upload>
-                  <!-- 无文件时显示空状态 -->
-                  <div v-else class="file-empty">暂无附件</div>
-                </div>
-
-                <!-- 3. 通报事项的其他材料 -->
-                <div class="upload-card">
-                  <div class="card-title">通报事项的其他材料</div>
-                  <!-- 查看模式:显示下载链接 -->
-                  <div v-if="!isEditable && item.attachments?.other?.length" class="file-link-list">
-                    <div v-for="file in item.attachments.other" :key="file.id" class="file-link-item">
-                      <el-link :href="file.url" target="_blank" :underline="false">
-                        <el-icon><Document /></el-icon>
-                        {{ file.name }}
-                      </el-link>
-                    </div>
-                  </div>
-                  <!-- 编辑模式:上传组件(支持覆盖) -->
-                  <el-upload
-                    v-else-if="isEditable"
-                    class="upload-demo"
-                    drag
-                    action="#"
-                    :limit="1"
-                    :file-list="item.attachments?.other || []"
-                    :on-change="(file) => handleFileChange(file, item, 'other')"
-                    :before-upload="beforeUpload"
-                  >
-                    <el-icon class="el-icon-upload"><UploadFilled /></el-icon>
-                    <div class="el-upload__text">点击上传文件(最多1个)</div>
-                    <div class="el-upload__tip" v-if="item.attachments?.other?.length">
-                      当前已上传:{{ item.attachments.other[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
-                    </div>
-                  </el-upload>
-                  <!-- 无文件时显示空状态 -->
-                  <div v-else class="file-empty">暂无附件</div>
-                </div>
-                <!-- <div class="upload-tip text-danger">
-                  提示:目前支持的文件格式:*.gif, *.jpeg, *.jpg, *.png, *.rar, *.zip, *.doc, *.ppt, *.xls, *.pdf, *.docx *.xlsx, *.bmp, *.xml,*.ofd,*.wps。文件大小支持:100M以内。
-                </div> -->
-              </div>
+          <el-row :gutter="24">
+            <el-col :span="8">
+              <el-form-item label="安全管理建议" prop="penaltyFile">
+                <FileUpload v-model="item.penaltyFile"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="通报事项的相关证据" prop="safetySuggestion">
+                <FileUpload v-model="item.penaltyFile"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="通报事项的其他材料" prop="safetySuggestion">
+                <FileUpload v-model="item.penaltyFile"/>
+              </el-form-item>
             </el-col>
           </el-row>
 
@@ -261,32 +169,7 @@
           <el-row :gutter="24">
             <el-col :span="24">
               <el-form-item label="安全管理建议附件">
-                <!-- 查看模式:显示下载链接 -->
-                <div v-if="!isEditable && item.attachments?.suggestion?.length" class="file-link-list">
-                  <div v-for="file in item.attachments.suggestion" :key="file.id" class="file-link-item">
-                    <el-link :href="file.url" target="_blank" :underline="false">
-                      <el-icon><Document /></el-icon>
-                      {{ file.name }}
-                    </el-link>
-                  </div>
-                </div>
-                <!-- 编辑模式:上传组件(支持覆盖) -->
-                <el-upload
-                  v-else-if="isEditable"
-                  class="upload-demo"
-                  action="#"
-                  :limit="1"
-                  :file-list="item.attachments?.suggestion || []"
-                  :on-change="(file) => handleFileChange(file, item, 'suggestion')"
-                  :before-upload="beforeUpload"
-                >
-                  <el-button size="small" type="primary">上传文件(最多1个)</el-button>
-                  <!-- <div class="el-upload__tip" v-if="item.attachments?.suggestion?.length">
-                    当前已上传:{{ item.attachments.suggestion[0].name }} <span class="text-danger">(再次上传将覆盖)</span>
-                  </div> -->
-                </el-upload>
-                <!-- 无文件时显示空状态 -->
-                <div v-else class="file-empty mt-2">暂无附件</div>
+                <FileUpload v-model="item.penaltyFile"/>
               </el-form-item>
             </el-col>
           </el-row>
@@ -364,7 +247,7 @@ interface NoticeItem {
 }
 
 // 表单数据
-const noticeItems = ref<NoticeItem[]>([
+const noticeItems = ref([
   {
     noticeItem: '',
     noticeStandard: '',
@@ -375,6 +258,7 @@ const noticeItems = ref<NoticeItem[]>([
     otherUnit: '',
     safetySuggestion: '',
     needFeedback: 'no',
+    penaltyFile: '',
     attachments: {
       punishment: [],
       evidence: [],
@@ -499,28 +383,6 @@ const updateSelectedRow = (row: any) => {
   drawerVisible.value = false;
 };
 
-// 文件上传变化(覆盖逻辑)
-const handleFileChange = (file: UploadFile, item: NoticeItem, type: 'punishment' | 'evidence' | 'other' | 'suggestion') => {
-  // 初始化附件对象
-  if (!item.attachments) {
-    item.attachments = {
-      punishment: [],
-      evidence: [],
-      other: [],
-      suggestion: []
-    };
-  }
-  // 覆盖上传(只保留最新1个文件)
-  item.attachments[type] = [file as AttachmentFile];
-};
-
-// 文件上传前校验
-const beforeUpload = (file: File) => {
-  // 实际项目中替换为真实上传逻辑
-  console.log('文件待上传:', file);
-  return false; // 阻止默认上传
-};
-
 // 删除通报事项
 const handleDelete = (index: number) => {
   if (noticeItems.value.length <= 1) {

+ 7 - 0
src/libs/commonMeth.ts

@@ -58,3 +58,10 @@ export function computedTypeList(type: string) {
 		globalList,
 	};
 }
+
+// 匹配字典中的译文
+export function getStatusLabel (list, value) {
+	if (list && value) {
+		return list.find(item => item.value === value).label
+	}
+}

+ 2 - 2
src/router/index.ts

@@ -150,13 +150,13 @@ export const constantRoutes: RouteRecordRaw[] = [
 			},
 			{
 				path: 'viewHistoricalData',
-				component: () => import('@/views/notificationInfoManage/myReceptionDisposal/index.vue'),
+				component: () => import('@/views/notificationInfoManage/viewHistoricalData/index.vue'),
 				name: 'viewHistoricalData',
 				meta: { title: '历史数据查看', icon: 'user' },
 			},
 			{
 				path: 'viewHistoricalDataDetail',
-				component: () => import('@/views/notificationInfoManage/myReceptionDisposal/components/detail.vue'),
+				component: () => import('@/views/notificationInfoManage/viewHistoricalData/components/detail.vue'),
 				name: 'viewHistoricalDataDetail',
 				meta: { title: '查看历史数据查看', icon: 'user' },
 			},

+ 5 - 3
src/views/notificationInfoManage/myPublish/components/detail.vue

@@ -7,11 +7,11 @@
 		<!-- 发布单位信息 -->
 		<PublishUnitInformation :information="formData" class="mb20" />
 		<!-- 涉事主体基本信息 -->
-		<QuestionInformation :information="formData" />
+		<QuestionInformation ref="shipFormRef" :information="formData" />
 		<!-- 水上交通安全通报信息 -->
 		<WaterSafetyInformation ref="noticeChildRef" :information="formData" />
 		<!-- 操作记录 -->
-		<operationLog />
+		<operationLog v-if="route.query.type !== 'add'" />
 		<!-- 底部按钮区 -->
 		<div class="form-actions">
 			<slot name="btn">
@@ -39,6 +39,7 @@ const pageTitle = ref(''); // 页面标题
 const isDetail = ref(false); // 是否为详情模式
 const isEdit = ref(false); // 是否为编辑模式
 const noticeChildRef = ref<any>();
+const shipFormRef = ref<any>();
 const formData = ref()
 
 onMounted(async () => {
@@ -84,8 +85,9 @@ const onClickSave = () => {
 const handleSubmit = async () => {
   // 调用子组件的校验方法
   const isValid = await noticeChildRef.value.validateForm();
+  const { valid } = await shipFormRef.value.validateForm();
   
-  if (isValid) {
+  if (isValid && valid) {
     console.log('校验通过,执行提交逻辑');
   } else {
     console.log('校验失败,请检查表单');

+ 11 - 3
src/views/notificationInfoManage/myPublish/index.vue

@@ -5,8 +5,9 @@
 			<pageContent ref="tableListRef" :total="total" :contentConfig="contentConfig" :pageList="tableData">
 					<template #button>
 							<el-button type="primary" @click="handleAdd()">新增</el-button>
-							<el-button type="primary" @click="handleAdd()">导出</el-button>
+							<el-button type="primary" @click="handleExport()">导出</el-button>
 					</template>
+					<!-- 接收单位 -->
 					<template #names="scope">
 						<el-popover placement="bottom" :width="800" trigger="click">
 							<template #reference>
@@ -43,6 +44,10 @@
 							</div>
 						</el-popover>
 					</template>
+					<!-- 通报整体状态 -->
+					<!-- <template #releaseStatusStr="scope">
+						{{ getStatusLabel(allNotificationStatus, scope.row.releaseStatusStr) }}
+					</template> -->
 					<template #operate="scope">
 							<el-button type="primary" link @click="handleDetails(scope.row.releasedId)">
 									查看
@@ -66,7 +71,7 @@ import pageContent from '@/components/components/pageContent.vue';
 import searchConfig from './config/search.config';
 import pageSearch from '@/components/components/pageSearch.vue';
 import useSystemStore from '@/store/main';
-import { outTypeList } from '@/libs/commonMeth';
+import { outTypeList, getStatusLabel } from '@/libs/commonMeth';
 import { fetchNotificationMattersList, fetchReleaseDetail } from '@/api/notificationInfoManage/myPublish';
 // 通报整体状态
 const allNotificationStatus = outTypeList('bj_notify_os');
@@ -91,7 +96,6 @@ const router = useRouter();
 const mattersList = ref([])
 
 const getNotificationMattersList = async(id) => {
-	console.log(searchTableRef.value.searchForm);
 	const params = {
 		releasedId: id,
 		notificationStatus: searchTableRef.value.searchForm.notificationStatus,
@@ -131,6 +135,10 @@ const handleAdd = () => {
 		query: { type: 'add' },
 	});
 };
+// 导出
+const handleExport = () => {
+	
+}
 const searchTableRef = ref();
 // 删除按钮
 function handleDelete(value: any) {

+ 6 - 11
src/views/notificationInfoManage/myReceptionDisposal/components/detail.vue

@@ -7,7 +7,7 @@
 		<!-- 发布单位信息 -->
 		<PublishUnitInformation class="mb20" />
 		<!-- 涉事主体基本信息 -->
-		<QuestionInformation />
+		<QuestionInformation :information="formData" />
 		<!-- 水上交通安全通报信息 -->
 		<WaterSafetyInformation ref="noticeChildRef" />
 		<OperationLog />
@@ -37,7 +37,6 @@ import QuestionInformation from '@/components/notificationDetailsParts/questionI
 import ReceivingUnitDealOpinion from './receivingUnitDealOpinion.vue';
 import WaterSafetyInformation from '@/components/notificationDetailsParts/waterSafetyInformation.vue';
 import ReceivingUnitOpinion from './receivingUnitOpinion.vue';
-import operationLog from '@/components/notificationDetailsParts/operationLog.vue';
 
 const route = useRoute();
 const router = useRouter();
@@ -46,19 +45,15 @@ const pageTitle = ref(''); // 页面标题
 const isDetail = ref(false); // 是否为详情模式
 const isEdit = ref(false); // 是否为编辑模式
 const noticeChildRef = ref<any>();
+const formData = ref()
 
 onMounted(async () => {
-	const { type, id } = route.query;
+	const { type, info } = route.query;
+	if (typeof info === 'string') {
+		formData.value = JSON.parse(info)
+	}
 	try {
 		switch (type as string) {
-			case 'add':
-				pageTitle.value = '水上交通安全信息发布与处置完成管理 新增发布';
-				isEdit.value = false;
-				break;
-			case 'edit':
-				pageTitle.value = '水上交通安全信息发布与处置完成管理 编辑发布';
-				isEdit.value = true;
-				break;
 			case 'detail':
 				pageTitle.value = '信息处置管理查看';
 				isDetail.value = true;

+ 4 - 1
src/views/notificationInfoManage/myReceptionDisposal/config/content.config.ts

@@ -12,8 +12,11 @@ const contentConfig = {
 		{ type: 'normal', label: '通报事项', prop: 'notificationMatters' },
 		{ type: 'normal', label: '接收单位', prop: 'receivingUnitName', width: 220 },
 		{ type: 'normal', label: '联络人电话', prop: 'receivingUnitName', width: 220 },
-		{ type: 'normal', label: '通报状态', prop: 'TODO', width: 220 },
+		{ type: 'custom', label: '通报状态', prop: 'TODO', width: 220 },
 		{ type: 'normal', label: '超期状态', prop: 'wfir', width: 220 },
+		{ type: 'normal', label: '通报整体状态', prop: 'wfir', width: 220 },
+		{ type: 'normal', label: '采取措施', prop: 'wfir', width: 220 },
+		{ type: 'normal', label: '是否需要反馈', prop: 'wfir', width: 220 },
 		{ type: 'normal', label: '发布日期', prop: 'releasedDate', width: 140 },
 		{ type: 'normal', label: '受理日期', prop: 'releasedDate', width: 140 },
 		{ type: 'normal', label: '发布人员', prop: 'TODO', width: 140 },

+ 8 - 14
src/views/notificationInfoManage/myReceptionDisposal/config/search.config.ts

@@ -4,7 +4,7 @@ interface OptionsType {
 }
 
 const searchConfig = {
-	pageName: 'rentalCompany',
+	pageName: 'released',
 	formItems: [
 		{
 			label: '违法事件编号',
@@ -40,7 +40,6 @@ const searchConfig = {
 			label: '发出单位',
 			prop: 'releasedUnit',
 			type: 'select',
-			multiple: true,
 			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择发出单位',
@@ -49,34 +48,30 @@ const searchConfig = {
 			label: '接收单位',
 			prop: 'receivingUnitName',
 			type: 'select',
-			multiple: true,
 			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择接收单位',
 		},
 		{
 			label: '通报状态',
-			prop: 'TODO',
+			prop: 'notificationStatus',
 			type: 'select',
-			multiple: true,
 			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择通报状态',
 		},
 		{
 			label: '采取措施',
-			prop: 'TODO',
+			prop: 'takeMeasures',
 			type: 'select',
-			multiple: true,
 			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择采取措施',
 		},
 		{
 			label: '超期状态',
-			prop: 'TODO',
+			prop: 'overdueStatus',
 			type: 'select',
-			multiple: true,
 			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择超期状态',
@@ -90,14 +85,14 @@ const searchConfig = {
 		},
 		{
 			label: '船舶所有人',
-			prop: 'TODO',
+			prop: 'theShipowner',
 			type: 'input',
 			span: 6,
 			placeholder: '请输入船舶所有人',
 		},
 		{
 			label: '船舶经营人',
-			prop: 'TODO',
+			prop: 'shipOperators',
 			type: 'input',
 			span: 6,
 			placeholder: '请输入船舶经营人',
@@ -106,21 +101,20 @@ const searchConfig = {
 			label: '是否需要反馈',
 			prop: 'wfir',
 			type: 'select',
-			multiple: true,
 			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择是否需要反馈',
 		},
 		{
 			label: '发布日期',
-			prop: 'releasedDate',
+			prop: 'releasedDates',
 			type: 'date-picker',
 			span: 6,
 			placeholder: '请选择发布日期',
 		},
 		{
 			label: '受理日期',
-			prop: 'TODO',
+			prop: 'acceptanceDates',
 			type: 'date-picker',
 			span: 6,
 			placeholder: '请选择发布日期',

+ 11 - 2
src/views/notificationInfoManage/myReceptionDisposal/index.vue

@@ -4,7 +4,6 @@
 
 			<pageContent ref="tableListRef" :total="total" :contentConfig="contentConfig" :pageList="tableData">
 					<template #button>
-							<el-button type="primary" @click="handleAdd()">新增</el-button>
 							<el-button type="primary" @click="handleAdd()">导出</el-button>
 					</template>
 					<template #operate="scope">
@@ -55,6 +54,7 @@ const { modalRef, handleNewDataClick, handleEditDataClick, handleCheckDataClick,
 	usePageModal();
 
 const handleDetails = async (id: string) => {
+	// TODO 携带info参数跳转
 	router.push({
     name: 'myReceptionDisposalDetail',
     query: { type: 'detail' }
@@ -99,12 +99,21 @@ function handleDelete(value: any) {
 // 筛选-状态赋值
 async function searchItem() {
 	searchConfig.formItems.forEach(item => {
-			if (item.prop === 'notificationMattersTypes') {
+		if (item.prop === 'notificationMattersTypes') {
 					item.options = categoryOnm
 			}
 			if (item.prop === 'wfir') {
 					item.options = isFeedback
 			}
+			if (item.prop === 'notificationStatus') {
+					item.options = notificationStatus
+			}
+			if (item.prop === 'takeMeasures') {
+					item.options = takeMeasures
+			}
+			if (item.prop === 'overdueStatus') {
+					item.options = overdueStatus
+			}
 			
 	});
 }

+ 143 - 0
src/views/notificationInfoManage/viewHistoricalData/components/detail.vue

@@ -0,0 +1,143 @@
+<template>
+	<div class="form-page">
+		<div class="page-header">
+			<h2 class="page-title">{{ pageTitle }}</h2>
+		</div>
+
+		<!-- 发布单位信息 -->
+		<PublishUnitInformation class="mb20" />
+		<!-- 涉事主体基本信息 -->
+		<QuestionInformation />
+		<!-- 水上交通安全通报信息 -->
+		<WaterSafetyInformation ref="noticeChildRef" />
+		<OperationLog />
+		<!-- 接收单位处置意见 如果需要反馈则隐藏 -->
+		<ReceivingUnitOpinion />
+		<!-- 接收单位处理意见 -->
+		<ReceivingUnitDealOpinion />
+		<div class="book flex">
+			<div>水上交通安全相关通报文书:</div>
+			<div class="blue">《水上交通安全信息通报函》</div>
+		</div>
+		<!-- 底部按钮区 -->
+		<div class="form-actions">
+			<slot name="btn">
+				<el-button type="primary" @click="handleSubmit">附件材料一键下载</el-button>
+				<el-button type="primary" @click="router.back">返回</el-button>
+			</slot>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts" name="CommonForm">
+import { ref, onMounted, onBeforeUnmount } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import PublishUnitInformation from '@/components/notificationDetailsParts/publishUnitInformation.vue';
+import QuestionInformation from '@/components/notificationDetailsParts/questionInformation.vue';
+import ReceivingUnitDealOpinion from './receivingUnitDealOpinion.vue';
+import WaterSafetyInformation from '@/components/notificationDetailsParts/waterSafetyInformation.vue';
+import ReceivingUnitOpinion from './receivingUnitOpinion.vue';
+import operationLog from '@/components/notificationDetailsParts/operationLog.vue';
+
+const route = useRoute();
+const router = useRouter();
+
+const pageTitle = ref(''); // 页面标题
+const isDetail = ref(false); // 是否为详情模式
+const isEdit = ref(false); // 是否为编辑模式
+const noticeChildRef = ref<any>();
+
+onMounted(async () => {
+	const { type, id } = route.query;
+	try {
+		switch (type as string) {
+			case 'add':
+				pageTitle.value = '水上交通安全信息发布与处置完成管理 新增发布';
+				isEdit.value = false;
+				break;
+			case 'edit':
+				pageTitle.value = '水上交通安全信息发布与处置完成管理 编辑发布';
+				isEdit.value = true;
+				break;
+			case 'detail':
+				pageTitle.value = '信息处置管理查看';
+				isDetail.value = true;
+				break;
+			default:
+				throw new Error(`无效操作类型: ${type}`);
+		}
+	} catch (error) {
+		handleBack();
+	} finally {}
+});
+
+const handleBack = () => {
+	router.go(-1);
+};
+
+onBeforeUnmount(() => {
+	isDetail.value = false;
+	isEdit.value = false;
+});
+
+const handleSubmit = async () => {
+  // 调用子组件的校验方法
+  const isValid = await noticeChildRef.value.validateForm();
+  
+  if (isValid) {
+    console.log('校验通过,执行提交逻辑');
+  } else {
+    console.log('校验失败,请检查表单');
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.form-page {
+	padding: 20px;
+	background-color: #fff;
+}
+
+.page-header {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	width: 100%;
+	margin-bottom: 30px;
+
+	.page-title {
+		font-size: 22px;
+		font-weight: 500;
+		color: #5070ae;
+	}
+}
+
+.form-actions {
+	display: flex;
+	justify-content: center;
+	margin-top: 40px;
+	gap: 16px;
+
+	.el-button {
+		padding: 8px 24px;
+	}
+}
+
+.book {
+	font-size: 14px;
+	margin-top: 20px;
+}
+
+// 响应式调整
+@media (max-width: 768px) {
+	.form-container {
+		padding: 15px;
+	}
+
+	.page-header {
+		flex-direction: column;
+		align-items: flex-start;
+		gap: 10px;
+	}
+}
+</style>

+ 53 - 0
src/views/notificationInfoManage/viewHistoricalData/components/receivingUnitDealOpinion.vue

@@ -0,0 +1,53 @@
+<template>
+  <div class="ship-info-form">
+    <el-collapse class="el-collapse" v-model="activeNames">
+      <el-collapse-item name="1">
+        <template #title="{ isActive }">
+          <div class="collapse-title">
+            接收单位处理意见
+          </div>
+        </template>
+        <div class="content">
+          <div>处置措施类型:处置</div>
+          <div>采取措施:其他</div>
+          <div>其他措施说明:船东已整改</div>
+          <div>信息处理人员:陈</div>
+          <div>信息处理时间:2025-10-1</div>
+          <div>信息处理接收单位:柳州船舶检验中心</div>
+          <div>附件查看:xxx.doc</div>
+          <div>接收流转单位:单位1</div>
+        </div>
+      </el-collapse-item>
+    </el-collapse>
+  </div>
+</template>
+
+<script setup lang="ts">
+  const activeNames = ref(['1']);
+</script>
+
+<style scoped>
+.ship-info-form {
+  background: #fff;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
+}
+:deep .el-collapse-item__header {
+  color: #5070ae;
+  size: 24px;
+  background: linear-gradient(135deg, #d2e8ff, #fcfeff);
+	box-shadow: 0 8px 20px #fcfeff;
+	text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+  padding-left: 20px;
+}
+
+:deep .el-collapse-item__wrap {
+  padding: 20px;
+}
+
+.content {
+  font-size: 14px;
+}
+
+</style>

+ 49 - 0
src/views/notificationInfoManage/viewHistoricalData/components/receivingUnitOpinion.vue

@@ -0,0 +1,49 @@
+<template>
+  <div class="ship-info-form">
+    <el-collapse class="el-collapse" v-model="activeNames">
+      <el-collapse-item name="1">
+        <template #title="{ isActive }">
+          <div class="collapse-title">
+            接收单位处置意见
+          </div>
+        </template>
+        <div class="content">
+          <div>处置措施类型:接收</div>
+          <div>信息处置人员:陈海东</div>
+          <div>信息处置时间:2025-04-02</div>
+          <div>信息处置接收单位:柳州船舶检验中心</div>
+        </div>
+      </el-collapse-item>
+    </el-collapse>
+  </div>
+</template>
+
+<script setup lang="ts">
+  const activeNames = ref(['1']);
+</script>
+
+<style scoped>
+.ship-info-form {
+  background: #fff;
+  border-radius: 8px;
+  padding: 20px;
+  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
+}
+:deep .el-collapse-item__header {
+  color: #5070ae;
+  size: 24px;
+  background: linear-gradient(135deg, #d2e8ff, #fcfeff);
+	box-shadow: 0 8px 20px #fcfeff;
+	text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
+  padding-left: 20px;
+}
+
+:deep .el-collapse-item__wrap {
+  padding: 20px;
+}
+
+.content {
+  font-size: 14px;
+}
+
+</style>

+ 24 - 0
src/views/notificationInfoManage/viewHistoricalData/config/content.config.ts

@@ -0,0 +1,24 @@
+const contentConfig = {
+	pageName: 'released',
+	header: {
+		title: '',
+	},
+	propsList: [
+		{ type: 'index', label: '序号', fixed: true  },
+		{ type: 'normal', label: '违法事件编号', prop: 'violationNumber', width: 140  },
+		{ type: 'normal', label: '发布单位', prop: 'releasedUnit', width: 140 },
+		{ type: 'normal', label: '船舶名称', prop: 'vesselName', width: 140 },
+		{ type: 'normal', label: '通报事项类别', prop: 'notificationCategory', width: 120 },
+		{ type: 'normal', label: '通报事项', prop: 'notificationMatters' },
+		{ type: 'normal', label: '接收单位', prop: 'receivingUnitName', width: 220 },
+		{ type: 'normal', label: '联络人电话', prop: 'receivingUnitName', width: 220 },
+		{ type: 'normal', label: '通报状态', prop: 'TODO', width: 220 },
+		{ type: 'normal', label: '超期状态', prop: 'wfir', width: 220 },
+		{ type: 'normal', label: '发布日期', prop: 'releasedDate', width: 140 },
+		{ type: 'normal', label: '受理日期', prop: 'releasedDate', width: 140 },
+		{ type: 'normal', label: '发布人员', prop: 'TODO', width: 140 },
+		{ type: 'handler', label: '操作', slotName: 'operate', width: 180},
+	],
+};
+
+export default contentConfig;

+ 76 - 0
src/views/notificationInfoManage/viewHistoricalData/config/detail.config.ts

@@ -0,0 +1,76 @@
+const modalConfig = {
+    pageName: 'rentalCompany',
+    addTitle: '新增行业内违法信息通报通讯录',
+    editTitle: '编辑行业内违法信息通报通讯录',
+    detailTitle: '查看行业内违法信息通报通讯录',
+    labelWidth: '150px',
+    formRules: {
+        rentalCompanyCode: [{ required: true, message: '请选择单位名称', trigger: 'change' }],
+        rentalCompanyName: [{ required: true, message: '请输入联络人名称', trigger: 'change' }],
+        deptId: [{ required: true, message: '请选择关联部门', trigger: 'change' }],
+        calculationFormulaName: [{ required: true, message: '请输入费用计算公式', trigger: 'change' }],
+    },
+    formItems: [
+        {
+            label: '单位名称',
+            prop: 'rentalCompanyCode',
+            type: 'select',
+            placeholder: '请选择单位名称',
+        },
+        {
+            label: '联络人名称',
+            prop: 'rentalCompanyName',
+            type: 'input',
+            placeholder: '请输入联络人名称',
+        },
+        {
+            label: '所属部门',
+            prop: 'rentalCompanyCode',
+            type: 'select',
+            placeholder: '请选择所属部门',
+        },
+        {
+            label: '所属职务',
+            prop: 'rentalCompanyCode',
+            type: 'select',
+            placeholder: '请选择所属职务',
+        },
+        {
+            label: '微信号',
+            prop: 'rentalCompanyName',
+            type: 'input',
+            placeholder: '请输入微信号',
+        },
+        {
+            label: '联系电话',
+            prop: 'rentalCompanyName',
+            type: 'input',
+            placeholder: '请输入联系电话',
+        },
+        {
+            label: '固定电话',
+            prop: 'rentalCompanyName',
+            type: 'input',
+            placeholder: '请输入固定电话',
+        },
+        {
+            label: '传真号',
+            prop: 'rentalCompanyName',
+            type: 'input',
+            placeholder: '请输入传真号',
+        },
+        {
+            label: '电子邮箱',
+            prop: 'rentalCompanyName',
+            type: 'input',
+            placeholder: '请输入电子邮箱',
+        },
+        {
+            label: '短信接收人',
+            prop: 'textMessage',
+            type: 'textMessage',
+        },
+    ],
+};
+
+export default modalConfig;

+ 131 - 0
src/views/notificationInfoManage/viewHistoricalData/config/search.config.ts

@@ -0,0 +1,131 @@
+interface OptionsType {
+	label: string;
+	value: string;
+}
+
+const searchConfig = {
+	pageName: 'rentalCompany',
+	formItems: [
+		{
+			label: '违法事件编号',
+			prop: 'violationNumber',
+			type: 'input',
+			placeholder: '请输入选违法事件编号',
+			span: 6,
+		},
+		{
+			label: '通报类型',
+			prop: 'notificationCategory',
+			type: 'select',
+			options: [],
+			placeholder: '请选择通报类型',
+			span: 6,
+		},
+		{
+			label: '通报事项类别',
+			prop: 'notificationMattersTypes',
+			type: 'select',
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择通报事项类别',
+		},
+		{
+			label: '通报事项',
+			prop: 'notificationMatters',
+			type: 'input',
+			span: 6,
+			placeholder: '请输入通报事项',
+		},
+		{
+			label: '发出单位',
+			prop: 'releasedUnit',
+			type: 'select',
+			multiple: true,
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择发出单位',
+		},
+		{
+			label: '接收单位',
+			prop: 'receivingUnitName',
+			type: 'select',
+			multiple: true,
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择接收单位',
+		},
+		{
+			label: '通报状态',
+			prop: 'TODO',
+			type: 'select',
+			multiple: true,
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择通报状态',
+		},
+		{
+			label: '采取措施',
+			prop: 'TODO',
+			type: 'select',
+			multiple: true,
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择采取措施',
+		},
+		{
+			label: '超期状态',
+			prop: 'TODO',
+			type: 'select',
+			multiple: true,
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择超期状态',
+		},
+		{
+			label: '船舶名称',
+			prop: 'vesselName',
+			type: 'input',
+			span: 6,
+			placeholder: '请输入船舶名称',
+		},
+		{
+			label: '船舶所有人',
+			prop: 'TODO',
+			type: 'input',
+			span: 6,
+			placeholder: '请输入船舶所有人',
+		},
+		{
+			label: '船舶经营人',
+			prop: 'TODO',
+			type: 'input',
+			span: 6,
+			placeholder: '请输入船舶经营人',
+		},
+		{
+			label: '是否需要反馈',
+			prop: 'wfir',
+			type: 'select',
+			multiple: true,
+			options: [] as OptionsType[],
+			span: 6,
+			placeholder: '请选择是否需要反馈',
+		},
+		{
+			label: '发布日期',
+			prop: 'releasedDate',
+			type: 'date-picker',
+			span: 6,
+			placeholder: '请选择发布日期',
+		},
+		{
+			label: '受理日期',
+			prop: 'TODO',
+			type: 'date-picker',
+			span: 6,
+			placeholder: '请选择发布日期',
+		},
+	],
+};
+
+export default searchConfig;

+ 132 - 0
src/views/notificationInfoManage/viewHistoricalData/index.vue

@@ -0,0 +1,132 @@
+<template>
+	<div class="sensitive-words">
+		<pageSearch ref="searchTableRef" :searchConfig="searchConfig" />
+
+			<pageContent ref="tableListRef" :total="total" :contentConfig="contentConfig" :pageList="tableData">
+					<template #button>
+							<el-button type="primary" @click="handleAdd()">导出</el-button>
+					</template>
+					<template #operate="scope">
+							<el-button type="primary" link @click="handleDetails(scope.row.rentalCompanyId)">
+									查看
+							</el-button>
+							<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)">
+									处理
+							</el-button>
+					</template>
+			</pageContent>
+			<router-view></router-view>
+	</div>
+</template>
+
+<script setup lang="ts">
+import { useRouter } from 'vue-router';
+import contentConfig from './config/content.config';
+import pageContent from '@/components/components/pageContent.vue';
+import searchConfig from './config/search.config';
+import pageSearch from '@/components/components/pageSearch.vue';
+import useSystemStore from '@/store/main';
+import { outTypeList } from '@/libs/commonMeth';
+// 通报整体状态
+const allNotificationStatus = outTypeList('bj_notify_os');
+// 通报事项类别
+const categoryOnm = outTypeList('bj_category_onm');
+// 通报状态
+const notificationStatus = outTypeList('bj_notification_status');
+// 是否需要反馈
+const isFeedback = outTypeList('bj_is_feedback');
+// 超期状态
+const overdueStatus = outTypeList('bj_overdue_status');
+// 采取措施
+const takeMeasures = outTypeList('bj_take_measures');
+
+const systemStore = useSystemStore();
+
+const total = ref(0);
+const pageSize = ref([10, 20, 30]);
+const tableData = ref([]);
+const tableListRef = ref();
+const router = useRouter();
+
+// 操作弹框
+import usePageModal from '@/components/components/hooks/usePageDetails';
+const { modalRef, handleNewDataClick, handleEditDataClick, handleCheckDataClick, handlePageDetail } =
+	usePageModal();
+
+const handleDetails = async (id: string) => {
+	router.push({
+    name: 'myReceptionDisposalDetail',
+    query: { type: 'detail' }
+  });
+};
+
+// 新增按钮
+const handleAdd = () => {
+	router.push({
+		name: 'addPublish',
+		query: { type: 'add' },
+	});
+};
+const searchTableRef = ref();
+const onClickDeleta = async (row: any) => {
+	ElMessageBox.confirm('确认删除此条数据吗?', '删除', {
+		confirmButtonText: '确认',
+		cancelButtonText: '取消',
+		type: 'warning',
+	}).then(() => {
+		// 删除后的回调
+	});
+};
+// 删除按钮
+function handleDelete(value: any) {
+	ElMessageBox.confirm('是否删除这条数据?', '删除提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(() => {
+			systemStore.deletePageDataAction(contentConfig.pageName, value);
+		})
+		.catch(() => {
+			ElMessage({
+				type: 'info',
+				message: '取消删除',
+			});
+		});
+}
+
+// 筛选-状态赋值
+async function searchItem() {
+	searchConfig.formItems.forEach(item => {
+			if (item.prop === 'notificationMattersTypes') {
+					item.options = categoryOnm
+			}
+			if (item.prop === 'wfir') {
+					item.options = isFeedback
+			}
+			
+	});
+}
+searchItem();
+</script>
+
+<style scoped lang="scss">
+.sensitive-words {
+	margin: 20px;
+}
+
+.status {
+	cursor: pointer;
+	position: relative;
+
+	.status-tip {
+		position: absolute;
+		top: 2px;
+		left: 60px;
+	}
+}
+
+.dialog-tip {
+	text-align: center;
+}
+</style>