فهرست منبع

1、我要发布详情区分新增修改相求。2、修复搜索组件数据更新不及时问题

Liuzhenyu 22 ساعت پیش
والد
کامیت
f8948c7b3c

+ 95 - 60
src/components/components/pageSearch.vue

@@ -7,14 +7,10 @@
       size="large"
       class="search-form"
     >
-      <!-- 第一行:筛选项(自动换行,每行3列) -->
+      <!-- 第一行:筛选项 -->
       <el-row :gutter="12" class="form-row">
         <template v-for="item in searchConfig.formItems" :key="item.prop">
-          <!-- 响应式列:大屏3列,中屏2列,小屏1列 -->
-          <el-col
-            :span="item.span || 6"
-            class="form-col"
-          >
+          <el-col :span="item.span || 6" class="form-col">
             <el-form-item :label="item.label" :prop="item.prop">
               <template v-if="item.type === 'input'">
                 <el-input v-model="searchForm[item.prop]" :placeholder="item.placeholder" />
@@ -70,7 +66,7 @@
         </template>
       </el-row>
 
-      <!-- 第二行:按钮区域(独立成行,右对齐) -->
+      <!-- 第二行:按钮区域 -->
       <el-row class="btn-row">
         <el-col :span="24">
           <div class="btns">
@@ -85,18 +81,19 @@
 
 <script setup lang="ts" name="page-search">
 import type { ElForm } from 'element-plus';
-import { reactive, ref, computed } from 'vue';
+import { reactive, ref, defineProps, defineEmits, watch, nextTick } from 'vue';
 import useSystemStore from '@/store/main';
 import useUserStore from '@/store/modules/user';
 import { parseTime } from '@/utils/ruoyi';
 import dayjs from 'dayjs';
 import { useSharedValueStore } from './sharedValueStore';
+import { storeToRefs } from 'pinia';
 
 // 初始化数据
 const formRef = ref<InstanceType<typeof ElForm>>();
 const systemStore = useSystemStore();
 const sharedValueStore = useSharedValueStore();
-const { searchObj } = storeToRefs(systemStore);
+const { searchObj, pageList } = storeToRefs(systemStore); // 监听 pageList 变化
 const userStore = useUserStore().userInfo.userName === 'admin' ? '' : useUserStore().userInfo.userId;
 
 // Props 定义
@@ -125,13 +122,31 @@ interface IProps {
 const props = defineProps<IProps>();
 const emit = defineEmits(['datePickerChange', 'handleSure']);
 
-// 表单数据初始化
-const initialForm: Record<string, any> = {};
-for (const item of props.searchConfig.formItems) {
-  initialForm[item.prop] = item.initialValue ?? '';
-}
+// 动态生成初始值
+const generateInitialForm = () => {
+  const form: Record<string, any> = {};
+  props.searchConfig.formItems.forEach(item => {
+    form[item.prop] = item.initialValue === undefined ? '' : structuredClone(item.initialValue);
+  });
+  return form;
+};
+
+// 初始化表单数据
+let initialForm = generateInitialForm();
 const searchForm = reactive<Record<string, any>>(initialForm);
 
+// 监听表单配置变化,动态更新初始值
+watch(
+  () => props.searchConfig.formItems,
+  () => {
+    initialForm = generateInitialForm();
+    Object.keys(searchForm).forEach(key => {
+      searchForm[key] = initialForm[key];
+    });
+  },
+  { deep: true }
+);
+
 // 禁用日期(月份选择器)
 const disabledDate = (date: Date) => {
   const current = new Date();
@@ -139,52 +154,75 @@ const disabledDate = (date: Date) => {
     (date.getFullYear() === current.getFullYear() && date.getMonth() > current.getMonth());
 };
 
-// 重置表单
-const handleResetClick = () => {
-  formRef.value?.resetFields();
-  // 重置为初始值
-  Object.assign(searchForm, initialForm);
-  fetchPageListData();
-  sharedValueStore.upDatePageNum(2);
+const handleResetClick = async () => {
+  if (formRef.value) {
+    await formRef.value.resetFields(); 
+  }
+
+  const newInitialForm = generateInitialForm();
+  Object.keys(searchForm).forEach(key => {
+    searchForm[key] = newInitialForm[key]; // 避免直接替换对象导致响应式失效
+  });
+
+  // 3. 等待数据更新完成后再请求
+  await nextTick(); 
+  fetchPageListData(); // 请求初始数据
+  sharedValueStore.upDatePageNum(2); // 同步页码状态
 };
 
-// 查询表单
 const handleQueryClick = async () => {
-  // 格式化日期范围(如需要)
+  const formattedSearchForm = { ...searchForm };
   props.searchConfig.formItems.forEach(item => {
-    if (item.type === 'date-picker' && searchForm[item.prop]) {
-      searchForm[item.prop][0] = parseTimeWithCheck(searchForm[item.prop][0]);
-      searchForm[item.prop][1] = parseTimeWithCheck(searchForm[item.prop][1]);
+    if (item.type === 'date-picker' && formattedSearchForm[item.prop]) {
+      formattedSearchForm[item.prop] = [
+        parseTimeWithCheck(formattedSearchForm[item.prop][0]),
+        parseTimeWithCheck(formattedSearchForm[item.prop][1])
+      ];
     }
-    if (item.type === 'date-month' && searchForm[item.prop]) {
-      searchForm[item.prop][0] = dayjs(searchForm[item.prop][0]).format('YYYY-MM');
-      searchForm[item.prop][1] = dayjs(searchForm[item.prop][1]).format('YYYY-MM');
+    if (item.type === 'date-month' && formattedSearchForm[item.prop]) {
+      formattedSearchForm[item.prop] = [
+        dayjs(formattedSearchForm[item.prop][0]).format('YYYY-MM'),
+        dayjs(formattedSearchForm[item.prop][1]).format('YYYY-MM')
+      ];
     }
   });
 
-  await fetchPageListData(searchForm);
-  searchObj.value = { ...searchForm };
+  // 2. 等待数据格式化完成后请求
+  await nextTick(); 
+  await fetchPageListData(formattedSearchForm); // 等待请求完成
+  searchObj.value = { ...formattedSearchForm }; // 解构赋值触发 Pinia 状态更新
   sharedValueStore.upDatePageNum(2);
   emit('handleSure');
 };
 
-// 请求列表数据
-function fetchPageListData(queryInfo: Record<string, any> = {}) {
+async function fetchPageListData(queryInfo: Record<string, any> = {}) {
   systemStore.pageInfo.pageNum = 1;
-  systemStore.getPageListDataAction(props.searchConfig.pageName, {
-    pageNum: 1,
-    pageSize: systemStore.pageInfo.pageSize,
-    userId: userStore,
-    status: props.searchConfig.status,
-    createUser: props.searchConfig.createUser,
-    oneself: props.searchConfig.oneself,
-    ...queryInfo,
-    ...props.searchConfig.pageListParams,
-  });
+
+  try {
+    const res = await systemStore.getPageListDataAction(
+      props.searchConfig.pageName,
+      {
+        pageNum: 1,
+        pageSize: systemStore.pageInfo.pageSize,
+        userId: userStore,
+        status: props.searchConfig.status,
+        createUser: props.searchConfig.createUser,
+        oneself: props.searchConfig.oneself,
+        ...queryInfo,
+        ...props.searchConfig.pageListParams,
+      }
+    );
+    await nextTick(); 
+    return res;
+  } catch (error) {
+    console.error('请求列表数据失败:', error);
+    throw error;
+  }
 }
 
-// 工具函数:格式化时间
+// 工具函数:格式化时间(带空值检查)
 function parseTimeWithCheck(value: any) {
+  if (!value) return '';
   if (/^\d{8}$/.test(value)) return value;
   return parseTime(value)?.slice(0, 10).replaceAll('-', '') || '';
 }
@@ -193,7 +231,10 @@ function parseTimeWithCheck(value: any) {
 const onDatePickerChange = (date: any) => {
   emit('datePickerChange', date);
 };
-const getMonthDate = (event: any, prop: string) => { /* 实现月份处理逻辑 */ };
+
+const getMonthDate = (event: any, prop: string) => {
+  // 月份选择器处理逻辑(根据业务需求补充)
+};
 
 // 暴露方法
 defineExpose({
@@ -209,50 +250,44 @@ defineExpose({
   background-color: #fff;
   padding: 15px 20px;
   border-radius: 5px;
-  overflow: hidden; /* 防止内部元素溢出 */
+  overflow: hidden;
 
   .search-form {
     width: 100%;
   }
 
-  /* 筛选项行样式 */
   .form-row {
-    margin-bottom: 15px; /* 与按钮行保持间距 */
+    margin-bottom: 15px;
   }
 
-  /* 筛选项列样式 */
   .form-col {
-    padding: 0 8px; /* 微调列间距,避免 gutter 过大 */
+    padding: 0 8px;
   }
 
-  /* 表单项目样式 */
   .el-form-item {
     margin-bottom: 0;
-    padding: 5px 0; /* 减少内部 padding,避免行高过大 */
+    padding: 5px 0;
 
     .el-form-item__content {
-      width: 100%; /* 确保输入框容器占满列宽 */
+      width: 100%;
     }
   }
 
-  /* 输入框/选择器样式 */
   :deep(.el-input--large),
   :deep(.el-select--large) {
-    width: 100% !important; /* 强制占满列宽,自适应列宽变化 */
-    min-width: 200px; /* 最小宽度,避免过度压缩 */
+    width: 100% !important;
+    min-width: 200px;
   }
 
-  /* 按钮行样式 */
   .btn-row {
     .btns {
       display: flex;
-      justify-content: flex-end; /* 按钮右对齐 */
-      gap: 10px; /* 按钮间距 */
+      justify-content: flex-end;
+      gap: 10px;
       padding: 10px 0;
     }
   }
 
-  /* 响应式调整:小屏幕下优化间距 */
   @media (max-width: 768px) {
     .form-col {
       padding: 0 4px;

+ 106 - 102
src/components/notificationDetailsParts/questionInformation.vue

@@ -3,13 +3,15 @@
     <!-- 折叠面板 -->
     <el-collapse v-model="activeNames" class="collapse-panel">
       <el-collapse-item title="涉事主体基本信息" name="1" :border="false">
+        <!-- 动态显示添加按钮或表单 -->
         <div v-if="isShowAdd" class="flex-cc">
           <el-button @click="onAddVessels" :icon="Plus">添加船舶</el-button>
           <el-tooltip content="Bottom center" placement="bottom" effect="light">
-              <el-button link :icon="Warning">业务说明</el-button>
+            <el-button link :icon="Warning">业务说明</el-button>
           </el-tooltip>
         </div>
         <div v-else>
+          <!-- 表单核心:通过 isEditable 控制禁用 -->
           <el-form
             ref="ruleFormRef"
             :model="formData"
@@ -25,7 +27,7 @@
                   <el-input 
                     v-model="formData.chineseName" 
                     placeholder="请填写中文船名"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -34,7 +36,7 @@
                   <el-input 
                     v-model="formData.englishName" 
                     placeholder="请填写英文船名"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -43,7 +45,7 @@
                   <el-input 
                     v-model="formData.vesselId" 
                     placeholder="请填写船舶识别号"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -56,7 +58,7 @@
                   <el-input 
                     v-model="formData.mmsi" 
                     placeholder="请填写MMSI"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -65,7 +67,7 @@
                   <el-input 
                     v-model="formData.imoNumber" 
                     placeholder="请填写IMO编号"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -74,7 +76,7 @@
                   <el-input 
                     v-model="formData.callSign" 
                     placeholder="请填写呼号"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -87,7 +89,7 @@
                   <el-input 
                     v-model="formData.registrationNo" 
                     placeholder="请填写牌薄号"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -96,7 +98,7 @@
                   <el-select 
                     v-model="formData.vesselType" 
                     placeholder="请选择船舶种类"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   >
                     <el-option label="散货船" value="bulkCarrier" />
                     <el-option label="集装箱船" value="containerShip" />
@@ -110,7 +112,7 @@
                   <el-input 
                     v-model="formData.portOfRegistry" 
                     placeholder="请填写船籍港"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -123,7 +125,7 @@
                   <el-input 
                     v-model="formData.nationality" 
                     placeholder="请填写国籍"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -136,7 +138,7 @@
                   <el-input 
                     v-model="formData.owner" 
                     placeholder="请填写船舶所有人"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -145,7 +147,7 @@
                   <el-input 
                     v-model="formData.ownerPhone" 
                     placeholder="请填写船舶所有人联系电话"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -158,7 +160,7 @@
                   <el-input 
                     v-model="formData.operator" 
                     placeholder="请填写船舶经营人"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -167,7 +169,7 @@
                   <el-input 
                     v-model="formData.operatorPhone" 
                     placeholder="请填写船舶经营人联系电话"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -180,7 +182,7 @@
                   <el-input 
                     v-model="formData.otherOrg" 
                     placeholder="请填写其他相关组织"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -189,7 +191,7 @@
                   <el-input 
                     v-model="formData.otherOrgPhone" 
                     placeholder="请填写其他相关组织联系电话"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
@@ -204,13 +206,15 @@
                     placeholder="请填写船舶信息描述"
                     type="textarea" 
                     :rows="4"
-                    :disabled="isUnknownVessel"
+                    :disabled="!isEditable"
                   />
                 </el-form-item>
               </el-col>
             </el-row>
           </el-form>
-          <div class="form-actions">
+
+          <!-- 表单操作按钮:根据 isEditable 控制显示 -->
+          <div class="form-actions" v-if="isEditable">
             <el-button 
               type="default" 
               text 
@@ -220,7 +224,7 @@
               船舶信息重置
             </el-button>
             <el-tooltip content="Bottom center" placement="bottom" effect="light">
-                <el-button link :icon="Warning">业务说明</el-button>
+              <el-button link :icon="Warning">业务说明</el-button>
             </el-tooltip>
           </div>
         </div>
@@ -234,16 +238,23 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive } from 'vue';
-import type { FormInstance, FormRules } from 'element-plus';  // 导入表单类型
+import { ref, reactive, computed, onMounted, watch } 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';
 
+// 路由参数获取
+const route = useRoute();
+const currentType = ref<'add' | 'edit' | 'detail'>('add'); // 当前页面类型
+
+// 表单基础配置
 const ruleFormRef = ref<FormInstance>();
 const activeNames = ref(['1']);
-const isUnknownVessel = ref(false);
-const isShowAdd = ref(true);
 const drawerVisible = ref(false);
+const isShowAdd = ref(true); // 是否显示添加按钮
+
+// 表单数据与验证规则
 const formData = reactive({
   chineseName: '',
   englishName: '',
@@ -292,93 +303,86 @@ const formRules = reactive<FormRules>({
   ]
 });
 
-// 重置按钮功能
+// 根据路由类型控制可编辑状态
+const isEditable = computed(() => {
+  return currentType.value === 'add' || currentType.value === 'edit';
+});
+
+// 初始化逻辑:获取路由参数 + 加载数据
+onMounted(() => {
+  // 从路由参数获取 type(默认 'add')
+  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') {
+    fetchShipData(); // 模拟从接口加载船舶数据
+  } else if (currentType.value === 'add') {
+    // 新增场景可预设默认值
+    formData.vesselType = 'bulkCarrier'; // 默认为散货船
+  }
+});
+
+// 模拟加载船舶数据(edit/detail 场景)
+const fetchShipData = () => {
+  // 实际项目中替换为接口请求
+  setTimeout(() => {
+    formData.chineseName = '扬子10';
+    formData.englishName = 'YANGZE 10';
+    formData.mmsi = '636017533';
+    formData.imoNumber = '9574444';
+    formData.callSign = 'D5LK6';
+    formData.vesselType = 'bulkCarrier'; // 散货船
+    formData.portOfRegistry = '蒙罗维亚';
+    formData.nationality = '利比里亚';
+    formData.owner = '扬子航运有限公司';
+    formData.operator = '扬子船务代理公司';
+    isShowAdd.value = false; // 编辑/详情场景隐藏添加按钮
+  }, 500);
+};
+
+// 监听路由参数变化(支持页面内切换类型)
+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; // 新增场景显示添加按钮
+      }
+    }
+  }
+);
+
+// 重置表单
 const handleReset = () => {
   if (!ruleFormRef.value) return;
-  
-  // 重置表单(清除验证状态 + 恢复初始数据)
   ruleFormRef.value.resetFields();
-  
-  // (可选)如需自定义默认值,取消以下注释并修改
-  // formData.chineseName = '扬子10';
-  // formData.vesselType = 'bulkCarrier';
+  // 重置后恢复默认值(新增场景)
+  if (currentType.value === 'add') {
+    formData.vesselType = 'bulkCarrier';
+  }
 };
 
-formData.chineseName = '扬子10';
-formData.englishName = 'YANGZE 10';
-formData.mmsi = '636017533';
-formData.imoNumber = '9574444';
-formData.callSign = 'D5LK6';
-formData.vesselType = 'bulkCarrier'; // 散货船
-formData.portOfRegistry = '蒙罗维亚';
-formData.nationality = '利比里亚';
-
+// 选择船舶回调
 const handleSelectShip = (data) => {
-  console.log(data);
-  drawerVisible.value = false
-  isShowAdd.value = false
-}
+  console.log('选择船舶数据:', data);
+  drawerVisible.value = false;
+  isShowAdd.value = false; // 隐藏添加按钮,显示表单
+};
 
+// 打开添加船舶抽屉
 const onAddVessels = () => {
-  drawerVisible.value = true
-}
+  drawerVisible.value = true;
+};
 </script>
 
 <style scoped lang="scss">
-.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__content {
-  padding-top: 25px;
-}
-
-/* 表单容器 */
-.form-container {
-  margin-top: 10px;
-}
-
-/* 按钮区域 */
-.form-actions {
-  display: flex;
-  justify-content: center;
-  margin-top: 30px;
-  gap: 20px;
-  
-  .reset-btn {
-    color: #f56c6c;
-  }
-}
-
-/* 适配小屏幕 */
-@media (max-width: 1024px) {
-  .el-row {
-    .el-col {
-      &:nth-child(3n) {
-        margin-bottom: 15px;
-      }
-    }
-  }
-}
-
-@media (max-width: 768px) {
-  .el-col {
-    flex: 0 0 100% !important;
-    max-width: 100% !important;
-    margin-bottom: 15px;
-  }
-}
+@import "@/styles/questionInformation.scss";
 </style>

+ 290 - 219
src/components/notificationDetailsParts/waterSafetyInformation.vue

@@ -15,9 +15,8 @@
           <!-- 通报信息标题 + 删除按钮 -->
           <div class="notification-header">
             <div class="notification-matters">{{ '通报信息' + (index + 1) }}</div>
-            <!-- 删除按钮:仅当表单数量 > 1 时显示 -->
             <el-button
-              v-if="noticeItems.length > 1"
+              v-if="noticeItems.length > 1 && isEditable"
               type="danger"
               text
               size="small"
@@ -33,14 +32,14 @@
             <el-col :span="24">
               <el-form-item label="通报事项" prop="noticeItem" required>
                 <el-button
-                  v-if="!drawerVisible && !item.noticeItem"
+                  v-if="!drawerVisible && !item.noticeItem && isEditable"
                   @click="onClickNotice(index)"
-                  type="primary">
-                    请选择通报事项
+                  type="primary"
+                  :disabled="!isEditable"
+                >
+                  请选择通报事项
                 </el-button>
-                <div v-else>
-                  {{ item.noticeItem }}
-                </div>
+                <el-input v-else disabled v-model="item.noticeItem" />
               </el-form-item>
             </el-col>
           </el-row>
@@ -54,6 +53,7 @@
                   placeholder="请输入通报依据,内容1000字以内"
                   maxlength="1000"
                   show-word-limit
+                  :disabled="!isEditable"
                 />
               </el-form-item>
             </el-col>
@@ -63,7 +63,7 @@
           <el-row :gutter="24">
             <el-col :span="24">
               <el-form-item label="通报类别" prop="noticeType" required>
-                <el-radio-group v-model="item.noticeType">
+                <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>
@@ -82,6 +82,7 @@
                   placeholder="违法违规信息(内容3000字以内)"
                   maxlength="3000"
                   show-word-limit
+                  :disabled="!isEditable"
                 />
                 <div class="example-text mt-1 text-primary">
                   通报标准1:具体行为列举<br>
@@ -99,6 +100,7 @@
                   v-model="item.receiveUnit"
                   placeholder="请选择单位名称"
                   style="width: 100%"
+                  :disabled="!isEditable"
                 >
                   <el-option label="单位名称1" value="unit1" />
                   <el-option label="单位名称2" value="unit2" />
@@ -114,6 +116,7 @@
                 <el-select
                   v-model="item.industryType"
                   placeholder="请选择行业外分类"
+                  :disabled="!isEditable"
                 >
                   <el-option label="海警机构" value="marine" />
                   <el-option label="公安机关" value="public" />
@@ -126,53 +129,113 @@
                   v-model="item.otherUnit"
                   placeholder="请输入行业外接收单位名称 如:XXX1海警机构,XXX2海警机构,XX公安机关"
                   maxlength="200"
+                  :disabled="!isEditable"
                 />
               </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="#"
-                    multiple
+                    :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__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="#"
-                    multiple
+                    :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__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="#"
-                    multiple
+                    :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__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以内。
@@ -192,27 +255,47 @@
                   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
-                  class="upload-demo mt-2"
+                  v-else-if="isEditable"
+                  class="upload-demo"
                   action="#"
-                  multiple
+                  :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>
+                  <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>
+
+                <div class="upload-tip text-danger text-sm">
+                  提示:目前支持的文件格式:*.gif, *.jpeg, *.jpg, *.png, *.rar, *.zip, *.doc, *.ppt, *.xls, *.pdf, *.docx *.xlsx, *.bmp, *.xml,*.ofd,*.wps。文件大小支持:100M以内。
+                </div>
               </el-form-item>
-              <div class="upload-tip text-danger text-sm">
-                提示:目前支持的文件格式:*.gif, *.jpeg, *.jpg, *.png, *.rar, *.zip, *.doc, *.ppt, *.xls, *.pdf, *.docx *.xlsx, *.bmp, *.xml,*.ofd,*.wps。文件大小支持:100M以内。
-              </div>
             </el-col>
           </el-row>
 
@@ -220,7 +303,7 @@
           <el-row :gutter="24">
             <el-col :span="24">
               <el-form-item label="是否需要反馈" prop="needFeedback" required>
-                <el-radio-group v-model="item.needFeedback" disabled>
+                <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>
@@ -233,39 +316,63 @@
         </el-form>
 
         <!-- 添加通报事项按钮 -->
-        <div class="add-matters">
+        <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" />
+      @updateSelectedRow="updateSelectedRow"
+      :disabled="!isEditable"
+    />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, defineEmits, defineExpose } from 'vue';
-import type { FormInstance, FormRules } from 'element-plus';
-import { UploadFilled, Plus, Delete } from '@element-plus/icons-vue';
+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']);
-const drawerVisible = ref(false);
 
-const noticeItems = ref([
-  {
-    noticeItem: '',
-    noticeStandard: '',
-    noticeType: 'info',
-    safetyInfo: '',
-    receiveUnit: '',
-    industryType: '',
-    otherUnit: '',
-    safetySuggestion: '',
-    needFeedback: 'no'
-  },
+// 附件类型定义
+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[]>([
   {
     noticeItem: '',
     noticeStandard: '',
@@ -275,12 +382,20 @@ const noticeItems = ref([
     industryType: '',
     otherUnit: '',
     safetySuggestion: '',
-    needFeedback: 'no'
+    needFeedback: 'no',
+    attachments: {
+      punishment: [],
+      evidence: [],
+      other: [],
+      suggestion: []
+    }
   }
 ]);
 
+// 表单引用
 const noticeFormRefs = ref<(FormInstance | undefined)[]>([]);
 
+// 表单验证规则
 const formRules = reactive<FormRules>({
   noticeItem: [
     { required: true, message: '请填写通报事项', trigger: 'blur' },
@@ -300,13 +415,6 @@ const formRules = reactive<FormRules>({
   receiveUnit: [
     { required: true, message: '请选择接收单位名称', trigger: 'change' }
   ],
-  otherUnit: [
-    { 
-      pattern: /^[\u4e00-\u9fa5a-zA-Z0-9,,\s]{0,200}$/, 
-      message: '请输入合法的单位名称(支持中文、字母、数字和逗号)', 
-      trigger: 'blur' 
-    }
-  ],
   safetySuggestion: [
     { required: true, message: '请填写安全管理建议', trigger: 'blur' },
     { max: 200, message: '长度不能超过200个字符', trigger: 'blur' }
@@ -316,19 +424,112 @@ const formRules = reactive<FormRules>({
   ]
 });
 
+// 抽屉控制
+const drawerVisible = ref(false);
 const selectNoticeId = ref(0);
 
-const onClickNotice = (id) => {
-  console.log(id);
+// 初始化
+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) => {
-  noticeItems[selectNoticeId.value] = row;
+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('至少保留一个通报事项');
@@ -336,9 +537,9 @@ const handleDelete = (index: number) => {
   }
   noticeItems.value.splice(index, 1);
   noticeFormRefs.value.splice(index, 1);
-  noticeFormRefs.value = [];
 };
 
+// 添加通报事项
 const addNoticeItem = () => {
   noticeItems.value.push({
     noticeItem: '',
@@ -349,194 +550,64 @@ const addNoticeItem = () => {
     industryType: '',
     otherUnit: '',
     safetySuggestion: '',
-    needFeedback: 'no'
+    needFeedback: 'no',
+    attachments: {
+      punishment: [],
+      evidence: [],
+      other: [],
+      suggestion: []
+    }
   });
-  // 添加后表单实例会通过:ref自动绑定到noticeFormRefs
 };
 
-// 批量校验所有动态表单
+// 表单校验
 const validateForm = async () => {
   let isAllValid = true;
-  const invalidForms: { formIndex: number; fields: any }[] = [];
-
   for (let i = 0; i < noticeFormRefs.value.length; i++) {
     const formRef = noticeFormRefs.value[i];
     if (!formRef) continue;
-
     try {
       await formRef.validate();
-    } catch (error: any) {
+    } catch (error) {
       isAllValid = false;
-      invalidForms.push({ formIndex: i, fields: error.fields });
     }
   }
-
-  emit('validate', isAllValid, invalidForms);
+  emit('validate', isAllValid);
   return isAllValid;
 };
 
-// 重置所有表单
+// 重置表单
 const resetAllForms = () => {
-  noticeFormRefs.value.forEach(formRef => {
-    formRef?.resetFields();
-  });
+  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, invalidForms?: { formIndex: number; fields: any }[]): void;
+  (e: 'validate', isValid: boolean): void;
 }>();
 
-// 暴露方法给父组件
 defineExpose({
   validateForm,
   resetAllForms
 });
-
-// 文件上传前校验(示例)
-const beforeUpload = (file: File) => {
-  console.log('文件上传前校验:', file.name);
-  return false; // 阻止默认上传,实际项目中替换为真实上传逻辑
-};
 </script>
-
 <style scoped lang="scss">
-.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__content {
-  padding-top: 25px;
-}
-
-// 表单标题+删除按钮容器
-.notification-header {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  margin-bottom: 20px;
-}
-
-// 通报事项标题样式
-.notification-matters {
-  font-size: 20px;
-  color: #163a8a;
-  font-weight: 500;
-  margin-bottom: 0;
-}
-
-// 删除按钮样式
-:deep .el-button--text {
-  color: #f56c6c;
-  &:hover {
-    color: #ff4d4f;
-    background: rgba(245, 108, 108, 0.1);
-  }
-}
-
-// 表单样式
-.notice-form {
-  .el-form-item__label {
-    color: #333;
-    font-weight: 500;
-  }
-
-  .el-form-item {
-    align-items: center;
-    margin-bottom: 15px;
-  }
-
-  .example-text {
-    font-size: 14px;
-    line-height: 1.5;
-  }
-
-  .industry-row {
-    margin-top: 15px;
-  }
-
-  .upload-area {
-    margin: 20px 0;
-
-    .upload-tip {
-      font-size: 14px;
-      line-height: 1.5;
-      margin-bottom: 15px;
-    }
-
-    .upload-cards {
-      display: flex;
-      gap: 20px;
-      flex-wrap: wrap;
-
-      .upload-card {
-        flex: 1;
-        min-width: 250px;
-        border: 1px dashed #e0e0e0;
-        border-radius: 4px;
-        padding: 15px;
-
-        .card-title {
-          font-weight: 500;
-          margin-bottom: 10px;
-          color: #333;
-
-          .required-mark {
-            color: #f56c6c;
-          }
-        }
-      }
-    }
-  }
-
-  .upload-tip {
-    font-size: 14px;
-    line-height: 1.5;
-    margin-bottom: 20px;
-  }
-}
-
-// 上传组件样式
-:deep .el-upload--text {
-  .el-upload-dragger {
-    padding: 30px 0;
-  }
-}
-
-// 添加按钮样式
-.add-matters {
-  display: flex;
-  justify-content: center;
-  margin-top: 20px;
-}
-
-// 分隔线样式
-:deep .el-divider {
-  margin: 25px 0;
-  border-color: #f0f0f0;
-}
-
-// 响应式调整
-@media (max-width: 768px) {
-  .notice-form .upload-cards {
-    flex-direction: column;
-  }
-
-  .notification-matters {
-    font-size: 18px;
-  }
-}
+@import "@/styles/waterSafetyInformation.scss";
 </style>

+ 53 - 0
src/styles/questionInformation.scss

@@ -0,0 +1,53 @@
+// 涉事主体基本信息
+.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__content {
+  padding-top: 25px;
+}
+
+/* 表单容器 */
+.form-container {
+  margin-top: 10px;
+}
+
+/* 按钮区域 */
+.form-actions {
+  display: flex;
+  justify-content: center;
+  margin-top: 30px;
+  gap: 20px;
+  
+  .reset-btn {
+    color: #f56c6c;
+  }
+}
+
+/* 适配小屏幕 */
+@media (max-width: 1024px) {
+  .el-row .el-col {
+    &:nth-child(3n) {
+      margin-bottom: 15px;
+    }
+  }
+}
+
+@media (max-width: 768px) {
+  .el-col {
+    flex: 0 0 100% !important;
+    max-width: 100% !important;
+    margin-bottom: 15px;
+  }
+}

+ 124 - 0
src/styles/waterSafetyInformation.scss

@@ -0,0 +1,124 @@
+// 水上交通安全通报信息样式
+.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__content) {
+  padding-top: 25px;
+}
+
+// 表单标题+删除按钮容器
+.notification-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+// 通报事项标题样式
+.notification-matters {
+  font-size: 20px;
+  color: #163a8a;
+  font-weight: 500;
+  margin-bottom: 0;
+}
+
+// 文件链接列表样式
+.file-link-list {
+  padding: 10px;
+  .file-link-item {
+    margin-bottom: 8px;
+    a {
+      display: inline-flex;
+      align-items: center;
+      color: #409eff;
+      &:hover {
+        color: #67c23a;
+      }
+      .el-icon {
+        margin-right: 5px;
+      }
+    }
+  }
+}
+
+// 文件空状态样式
+.file-empty {
+  color: #909399;
+  padding: 20px;
+  text-align: center;
+  background: #f5f5f5;
+  border-radius: 4px;
+}
+
+// 上传卡片样式
+.upload-cards {
+  display: flex;
+  gap: 20px;
+  flex-wrap: wrap;
+  .upload-card {
+    flex: 1;
+    min-width: 250px;
+    border: 1px dashed #e0e0e0;
+    border-radius: 4px;
+    padding: 15px;
+    .card-title {
+      font-weight: 500;
+      margin-bottom: 15px;
+      color: #333;
+      .required-mark {
+        color: #f56c6c;
+      }
+    }
+  }
+}
+
+// 上传区域提示
+.upload-tip {
+  font-size: 14px;
+  line-height: 1.5;
+  margin-top: 15px;
+}
+
+.el-upload__tip {
+  margin-top: 0;
+}
+
+:deep(.el-button--text) {
+  color: #f56c6c;
+  &:hover {
+    color: #ff4d4f;
+    background: rgba(245, 108, 108, 0.1);
+  }
+}
+
+.add-matters {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+
+:deep(.el-divider) {
+  margin: 25px 0;
+  border-color: #f0f0f0;
+}
+
+@media (max-width: 768px) {
+  .upload-cards {
+    flex-direction: column;
+  }
+  .notification-matters {
+    font-size: 18px;
+  }
+}

+ 6 - 0
src/utils/enums.ts

@@ -0,0 +1,6 @@
+// 接收单位
+export const ReceivingUnit = {
+  Basic: 'basic',
+  Business: 'EnterpriseEdition',
+  Ultimate: 'UltimateEdition',
+};

+ 0 - 0
src/views/myPublish/config/btnsTypes.ts


+ 4 - 4
src/views/myPublish/config/content.config.ts

@@ -8,11 +8,11 @@ const contentConfig = {
 		{ 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: 'TODO', width: 120 },
-		{ type: 'normal', label: '通报事项', prop: 'TODO' },
-		{ type: 'custom', label: '接收单位', prop: 'TODO', width: 220 },
+		{ type: 'normal', label: '通报事项类别', prop: 'notificationCategory', width: 120 },
+		{ type: 'normal', label: '通报事项', prop: 'notificationMatters' },
+		{ type: 'custom', label: '接收单位', prop: 'receivingUnitName', width: 220 },
 		{ type: 'custom', label: '通报状整体状态', prop: 'TODO', width: 220 },
-		{ type: 'custom', label: '是否需要反馈', prop: 'TODO', width: 220 },
+		{ type: 'custom', label: '是否需要反馈', prop: 'wfir', width: 220 },
 		{ type: 'normal', label: '发布日期', prop: 'releasedDate', width: 140 },
 		{ type: 'normal', label: '发布人员', prop: 'TODO', width: 140 },
 		{ type: 'handler', label: '操作', slotName: 'operate', width: 180},

+ 24 - 164
src/views/myPublish/config/search.config.ts

@@ -1,4 +1,4 @@
-interface Inew {
+interface OptionsType {
 	label: string;
 	value: string;
 }
@@ -15,252 +15,112 @@ const searchConfig = {
 		},
 		{
 			label: '通报类型',
-			prop: 'report_type',
+			prop: 'notificationCategory',
 			type: 'select',
-			options: [
-				{
-					label: '内部',
-					value: 'inner',
-				},
-				{
-					label: '外部',
-					value: 'outer',
-				},
-			] as Array<Inew>,
+			options: [],
 			placeholder: '请选择通报类型',
 			span: 6,
 		},
 		{
 			label: '通报事项类别',
-			prop: 'report_event_type',
+			prop: 'notificationMattersTypes',
 			type: 'select',
-			options: [
-				{
-					label: '信息告知类',
-					value: 'msg',
-				},
-				{
-					label: '协助处理类',
-					value: 'assist',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择通报事项类别',
 		},
 		{
 			label: '通报事项',
-			prop: 'report_event',
+			prop: 'notificationMatters',
 			type: 'input',
 			span: 6,
 			placeholder: '请输入通报事项',
 		},
 		{
 			label: '发出单位',
-			prop: 'send_unit',
+			prop: 'releasedUnit',
 			type: 'select',
 			multiple: true,
-			options: [
-				{
-					label: '全部',
-					value: 'all',
-				},
-				{
-					label: '上海海事',
-					value: 'msg',
-				},
-				{
-					label: '广州海事',
-					value: 'assist',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择发出单位',
 		},
 		{
 			label: '接收单位',
-			prop: 'receive_unit',
+			prop: 'receivingUnitName',
 			type: 'select',
 			multiple: true,
-			options: [
-				{
-					label: '全部',
-					value: 'all',
-				},
-				{
-					label: '上海海事',
-					value: 'msg',
-				},
-				{
-					label: '广州海事',
-					value: 'assist',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择接收单位',
 		},
 		{
 			label: '通报状态',
-			prop: 'report_status',
+			prop: 'TODO',
 			type: 'select',
 			multiple: true,
-			options: [
-				{
-					label: '全部',
-					value: 'all',
-				},
-				{
-					label: '已发布待处置',
-					value: '1',
-				},
-				{
-					label: '已接收待处置',
-					value: '2',
-				},
-				{
-					label: '已退回',
-					value: '3',
-				},
-				{
-					label: '已提出补正要求',
-					value: '4',
-				},
-				{
-					label: '已处理待处置完整',
-					value: '5',
-				},
-				{
-					label: '待接收',
-					value: '6',
-				},
-				{
-					label: '已接收',
-					value: '7',
-				},
-				{
-					label: '已处置完成',
-					value: '8',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择通报状态',
 		},
 		{
 			label: '采取措施',
-			prop: 'take_steps',
+			prop: 'TODO',
 			type: 'select',
 			multiple: true,
-			options: [
-				{
-					label: '全部',
-					value: 'all',
-				},
-				{
-					label: '约谈',
-					value: '1',
-				},
-				{
-					label: '通报',
-					value: '2',
-				},
-				{
-					label: '审慎发证',
-					value: '3',
-				},
-				{
-					label: '信用管理',
-					value: '4',
-				},
-				{
-					label: '其他',
-					value: '5',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择采取措施',
 		},
 		{
 			label: '超期状态',
-			prop: 'over_status',
+			prop: 'TODO',
 			type: 'select',
 			multiple: true,
-			options: [
-				{
-					label: '全部',
-					value: 'all',
-				},
-				{
-					label: '正常',
-					value: '1',
-				},
-				{
-					label: '接收超期',
-					value: '2',
-				},
-				{
-					label: '处理超期',
-					value: '4',
-				},
-				{
-					label: '处置完成超期',
-					value: '4',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
-			placeholder: '请选择采取措施',
+			placeholder: '请选择超期状态',
 		},
 		{
 			label: '船舶名称',
-			prop: 'ship_name',
+			prop: 'vesselName',
 			type: 'input',
 			span: 6,
 			placeholder: '请输入船舶名称',
 		},
 		{
 			label: '船舶所有人',
-			prop: 'ship_owner',
+			prop: 'TODO',
 			type: 'input',
 			span: 6,
 			placeholder: '请输入船舶所有人',
 		},
 		{
 			label: '船舶经营人',
-			prop: 'ship_operator',
+			prop: 'TODO',
 			type: 'input',
 			span: 6,
 			placeholder: '请输入船舶经营人',
 		},
 		{
 			label: '是否需要反馈',
-			prop: 'is_feedback',
+			prop: 'wfir',
 			type: 'select',
 			multiple: true,
-			options: [
-				{
-					label: '全部',
-					value: 'all',
-				},
-				{
-					label: '是',
-					value: '1',
-				},
-				{
-					label: '否',
-					value: '2',
-				},
-			] as Array<Inew>,
+			options: [] as OptionsType[],
 			span: 6,
 			placeholder: '请选择采取措施',
 		},
 		{
 			label: '发布日期',
-			prop: 'createDate',
+			prop: 'releasedDate',
 			type: 'date-picker',
 			span: 6,
 			placeholder: '请选择发布日期',
 		},
 		{
 			label: '受理日期',
-			prop: 'accept_date',
+			prop: 'TODO',
 			type: 'date-picker',
 			span: 6,
 			placeholder: '请选择发布日期',

+ 37 - 21
src/views/myPublish/index.vue

@@ -2,21 +2,23 @@
 	<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>
-				<el-button type="primary" @click="handleAdd()">导出</el-button>
-			</template>
-			<template #operate="scope">
-				<el-button type="primary" link @click="handleEdit(scope.row.rentalCompanyId)"> 查看 </el-button>
-				<el-button type="primary" link @click="handleEdit(scope.row.rentalCompanyId)"> 编辑 </el-button>
-				<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)"> 删除 </el-button>
-				<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)"> 撤回 </el-button>
-				<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)"> 重新发布 </el-button>
-				<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)"> 补正信息 </el-button>
-				<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)"> 结案操作 </el-button>
-			</template>
-		</pageContent>
+			<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">
+							<el-button type="primary" link @click="handleDetails(scope.row.rentalCompanyId)">
+									查看
+							</el-button>
+							<el-button type="primary" link @click="handleEdit(scope.row.rentalCompanyId)">
+									编辑
+							</el-button>
+							<el-button type="primary" link @click="handleDelete(scope.row.rentalCompanyId)">
+									删除
+							</el-button>
+					</template>
+			</pageContent>
 	</div>
 </template>
 
@@ -28,11 +30,17 @@ 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();
@@ -49,8 +57,17 @@ const { modalRef, handleNewDataClick, handleEditDataClick, handleCheckDataClick,
 	usePageModal();
 
 const handleEdit = async (id: string) => {
-	await handlePageDetail(id);
-	await handleEditDataClick();
+	router.push({
+    name: 'addPublish',
+    query: { type: 'edit' }
+  });
+};
+
+const handleDetails = async (id: string) => {
+	router.push({
+    name: 'addPublish',
+    query: { type: 'detail' }
+  });
 };
 
 // 新增按钮
@@ -91,9 +108,9 @@ function handleDelete(value: any) {
 // 筛选-状态赋值
 async function searchItem() {
 	searchConfig.formItems.forEach(item => {
-		if (item.prop === 'status') {
-			// item.options = searchList.value;
-		}
+			if (item.prop === 'notificationCategory') {
+					item.options = categoryOnm
+			}
 	});
 }
 searchItem();
@@ -102,7 +119,6 @@ searchItem();
 <style scoped lang="scss">
 .sensitive-words {
 	margin: 20px;
-	// background-color: #fff;
 }
 
 .status {