Przeglądaj źródła

feat: 完成管理规定与通知部分

wyf 7 miesięcy temu
rodzic
commit
6ed503f3b1

+ 92 - 0
src/api/traffic-regulation/traffic-regulation.ts

@@ -0,0 +1,92 @@
+import { http } from '@/utils/http/axios';
+import type { QueryPageRequest, QueryPageResponse } from '@/types/basic-query';
+
+import {
+  TableSearchQuery,
+  CreateRegulationQuery,
+  RegulationDetailResponse,
+  NoticeDetailResponse,
+  UpdateNoticeQuery,
+  CreateNoticeQuery,
+} from '@/views/traffic/regulation/types';
+
+export const getRegulationList = (params: QueryPageRequest<TableSearchQuery>) => {
+  return http.request<QueryPageResponse<RegulationDetailResponse>>({
+    url: '/ruleNotice/queryRuleNoticeInfoPage',
+    method: 'post',
+    params,
+  });
+};
+
+export const createRegulation = (data: CreateRegulationQuery) => {
+  return http.request({
+    url: '/ruleNotice/saveRuleNoticeInfo',
+    method: 'post',
+    data,
+  });
+};
+
+export const updateRegulation = (data: CreateRegulationQuery) => {
+  return http.request({
+    url: '/ruleNotice/updateRuleNoticeInfo',
+    method: 'post',
+    data,
+  });
+};
+
+export const getRegulationDetail = (id: number) => {
+  return http.request<RegulationDetailResponse>({
+    url: `/ruleNotice/queryRuleNoticeInfo?id=${id}`,
+    method: 'post',
+  });
+};
+
+// export const changeRegulationState = (data: { id: number; effectState: number }) => {
+//   return http.request({
+//     url: '/ruleNotice/updateRuleNoticeInfo',
+//     method: 'post',
+//     data,
+//   });
+// };
+
+export const deleteRegulation = (id: number) => {
+  return http.request({
+    url: `/ruleNotice/deleteRuleNoticeInfo?id=${id}`,
+    method: 'post',
+  });
+};
+
+export const getNoticeList = (params: QueryPageRequest<TableSearchQuery>) => {
+  return getRegulationList(params);
+};
+
+export const createNotice = (data: CreateNoticeQuery) => {
+  return http.request({
+    url: '/ruleNotice/saveRuleNoticeInfo',
+    method: 'post',
+    data,
+  });
+};
+
+export const updateNotice = (data: UpdateNoticeQuery) => {
+  return http.request({
+    url: '/ruleNotice/updateRuleNoticeInfo',
+    method: 'post',
+    data,
+  });
+};
+
+export const getNoticeDetail = (id: number) => {
+  return http.request<NoticeDetailResponse>({
+    url: `/ruleNotice/queryRuleNoticeInfo?id=${id}`,
+    method: 'post',
+  });
+};
+
+// export const changeNoticeState = (data: { id: number; effectState: number }) => {
+//   return changeRegulationState(data);
+// };
+
+export const deleteNotice = (id: number) => {
+  return deleteRegulation(id);
+};

+ 23 - 0
src/styles/basic-table-file.scss

@@ -0,0 +1,23 @@
+.file-container--div {
+  margin: 6px 0;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  &__icon {
+    cursor: pointer;
+    width: 24px;
+  }
+  &__name {
+    cursor: pointer;
+    margin: 0 10px;
+    max-width: 120px;
+        white-space: nowrap; /* 防止文本换行 */
+    overflow: hidden; /* 隐藏溢出的文本 */
+    text-overflow: ellipsis; /* 显示省略号 */
+  }
+  &__download {
+    cursor: pointer;
+    width: 20px;
+  }
+}

+ 6 - 1
src/views/traffic/regulation/Regulation.vue

@@ -20,8 +20,13 @@
 <script setup lang="ts">
   import { ref, computed, defineAsyncComponent } from 'vue';
   import { TRAFFIC_REGULATION_SUBPAGES } from './constants';
+  import { useRoute } from 'vue-router';
 
-  const activeName = ref(TRAFFIC_REGULATION_SUBPAGES[0].value);
+  const route = useRoute();
+
+  const subpage = route.query.subpage as string;
+
+  const activeName = ref(subpage || TRAFFIC_REGULATION_SUBPAGES[0].value);
 
   const dynamicComponent = computed(() => {
     switch (activeName.value) {

+ 34 - 13
src/views/traffic/regulation/components/NoticeCreate.vue

@@ -1,7 +1,7 @@
 <template>
   <main class="safety-platform-container__main">
     <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
-      <template #noticeFiles>
+      <template #attachment>
         <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
       </template>
       <template #isPush>
@@ -32,16 +32,19 @@
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { useUserInfoHook } from '@/views/disaster/hooks';
   import { IS_PUSH } from '../constants';
+  import { ElMessage } from 'element-plus';
   import { NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES } from '../configs/form';
-  import { FileItem, NoticeRuleForm } from '../types';
+  import { FileItem, CreateNoticeRuleForm, CreateNoticeQuery } from '../types';
   import { onMounted, ref } from 'vue';
+  import { createNotice } from '@/api/traffic-regulation/traffic-regulation';
   import UploadLoading from '@/components/UploadLoading.vue';
   import { useRouter } from 'vue-router';
+  import { formatAttachmentList } from '../utils';
 
   const { realname } = useUserInfoHook();
 
   const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
-    useFormConfigHook<NoticeRuleForm>(NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES);
+    useFormConfigHook<CreateNoticeRuleForm>(NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES);
 
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
   const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
@@ -51,7 +54,7 @@
   };
 
   const handleUploadSuccess = (fileList: FileItem[]) => {
-    ruleFormData.noticeFiles = fileList;
+    ruleFormData.attachment = fileList;
   };
 
   const handleValidate = async () => {
@@ -64,24 +67,42 @@
     return parentValidateResult && childValidateResult;
   };
 
-  const getFormData = () => {
+  const getFormData = async () => {
     if (!ruleFormData.isPush) {
       ruleFormData.userGroupList = [];
     }
     cloneRuleFormData();
-    return ruleFormData;
+    const res: CreateNoticeQuery = {
+      managementType: 2,
+      name: ruleFormData.name,
+      content: ruleFormData.content,
+      attachment: JSON.stringify(await formatAttachmentList(ruleFormData.attachment)),
+      isPush: ruleFormData.isPush,
+      userGroupList: ruleFormData.userGroupList?.join(','),
+      remark: ruleFormData.remark,
+      effectState: 0,
+    };
+    return res;
   };
 
   const formLoading = ref(false);
   const router = useRouter();
-  const handleSubmit = () => {
-    handleValidate();
-  };
 
-  // defineExpose({
-  //   handleValidate,
-  //   getFormData,
-  // });
+  const handleSubmit = async () => {
+    const res = await handleValidate();
+    if (!res) return;
+    try {
+      formLoading.value = true;
+      const params = await getFormData();
+      await createNotice(params);
+      ElMessage.success('创建成功');
+      router.back();
+    } catch (e) {
+      console.log(e);
+    } finally {
+      formLoading.value = false;
+    }
+  };
 
   onMounted(() => {
     ruleFormData.realname = realname;

+ 53 - 18
src/views/traffic/regulation/components/NoticeEdit.vue

@@ -1,8 +1,13 @@
 <template>
   <main class="safety-platform-container__main">
     <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
-      <template #noticeFiles>
-        <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
+      <template #attachment>
+        <UploadFiles
+          label="上传附件"
+          ref="uploadFilesRef"
+          :fileList="ruleFormData.attachment"
+          @uploadSuccess="handleUploadSuccess"
+        />
       </template>
       <template #isPush>
         <el-radio-group v-model="ruleFormData.isPush">
@@ -31,31 +36,42 @@
   import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { IS_PUSH } from '../constants';
+  import { ElMessage } from 'element-plus';
   import { NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES } from '../configs/form';
-  import { FileItem, NoticeRuleForm } from '../types';
+  import { FileItem, CreateNoticeRuleForm, CreateNoticeQuery, UpdateNoticeQuery } from '../types';
   import { onMounted, ref } from 'vue';
   import UploadLoading from '@/components/UploadLoading.vue';
   import { useRouter } from 'vue-router';
+  import { stringToArray, unformatAttachment, formatAttachmentList } from '../utils';
+  import { getNoticeDetail, updateNotice } from '@/api/traffic-regulation/traffic-regulation';
 
   const props = defineProps<{
     id: number;
   }>();
-  const getNoticeDetail = async () => {
-    // TODO 获取详情并写入表单
-  };
 
   const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
-    useFormConfigHook<NoticeRuleForm>(NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES);
+    useFormConfigHook<CreateNoticeRuleForm>(NOTICE_FORM_CONFIG, NOTICE_FORM_DATA, NOTICE_FORM_RULES);
 
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
   const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
 
+  const getDetail = async () => {
+    const res = await getNoticeDetail(props.id);
+    ruleFormData.name = res.name;
+    ruleFormData.content = res.content;
+    ruleFormData.attachment = unformatAttachment(res.attachment)!;
+    ruleFormData.remark = res.remark;
+    ruleFormData.realname = res.creatName;
+    ruleFormData.isPush = res.isPush;
+    ruleFormData.userGroupList = stringToArray(res.userGroupList);
+  };
+
   const handleUserGroupListChange = (userGroupList: number[]) => {
     ruleFormData.userGroupList = userGroupList;
   };
 
   const handleUploadSuccess = (fileList: FileItem[]) => {
-    ruleFormData.noticeFiles = fileList;
+    ruleFormData.attachment = fileList;
   };
 
   const handleValidate = async () => {
@@ -68,27 +84,46 @@
     return parentValidateResult && childValidateResult;
   };
 
-  const getFormData = () => {
+  const getFormData = async () => {
     if (!ruleFormData.isPush) {
       ruleFormData.userGroupList = [];
     }
     cloneRuleFormData();
-    return ruleFormData;
+    const res: UpdateNoticeQuery = {
+      id: props.id,
+      managementType: 2,
+      name: ruleFormData.name,
+      content: ruleFormData.content,
+      attachment: JSON.stringify(await formatAttachmentList(ruleFormData.attachment)),
+      isPush: ruleFormData.isPush,
+      userGroupList: ruleFormData.userGroupList?.join(','),
+      remark: ruleFormData.remark,
+      effectState: 0,
+    };
+    return res;
   };
 
   const formLoading = ref(false);
   const router = useRouter();
-  const handleSubmit = () => {
-    handleValidate();
-  };
 
-  // defineExpose({
-  //   handleValidate,
-  //   getFormData,
-  // });
+  const handleSubmit = async () => {
+    const res = await handleValidate();
+    if (!res) return;
+    try {
+      formLoading.value = true;
+      const params = await getFormData();
+      await updateNotice(params);
+      ElMessage.success('编辑成功');
+      router.back();
+    } catch (e) {
+      console.log(e);
+    } finally {
+      formLoading.value = false;
+    }
+  };
 
   onMounted(async () => {
-    await getNoticeDetail();
+    await getDetail();
     cloneRuleFormData();
     beforeRouteLeave();
   });

+ 179 - 9
src/views/traffic/regulation/components/NoticeTable.vue

@@ -9,13 +9,13 @@
       <div class="regulation-search">
         <el-input
           class="regulation-search-input"
-          v-model="searchData"
+          v-model="searchData.searchName"
           placeholder="输入通知标题或文件名称"
           :prefix-icon="Search"
           clearable
         >
         </el-input>
-        <el-button type="primary" @click="getTabelData"> 查询 </el-button>
+        <el-button type="primary" @click="handleSearch"> 查询 </el-button>
       </div>
     </header>
     <!-- 表格 -->
@@ -25,6 +25,86 @@
       @update:pageSize="handleSizeChange"
       @update:pageNumber="handleCurrentChange"
     >
+      <template #attachment="scope">
+        <div class="file-container--div" v-for="item in unformatAttachment(scope.row.attachment)" :key="item.fileId">
+          <img
+            class="file-container--div__icon"
+            @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
+            :src="FILE_TYPE_ICON[item.fileType]"
+          />
+          <span
+            class="file-container--div__name"
+            @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
+            >{{ item.fileName }}</span
+          >
+          <img
+            class="file-container--div__download"
+            :src="DownloadIcon"
+            @click="downloadFile(item.fileUrl, item.fileName)"
+          />
+        </div>
+      </template>
+      <template #effectState="scope">
+        <div class="effect-state" v-if="scope.row.effectState === 1">
+          <div style="background-color: #52c41a; width: 5px; height: 5px; border-radius: 50%; margin-right: 5px"></div>
+          <span>已生效</span>
+        </div>
+        <div class="effect-state" v-else-if="scope.row.effectState === 0">
+          <div style="background-color: #ff4d4f; width: 5px; height: 5px; border-radius: 50%; margin-right: 5px"></div>
+          <span>未生效</span>
+        </div>
+      </template>
+      <template #action="scope">
+        <div class="action-container--div">
+          <ActionButton text="查看" @click="handleViewNotice(scope.row.id)" />
+          <ActionButton
+            text="编辑"
+            v-if="trafficManagementPermission && scope.row.effectState === 0"
+            @click="handleEditNotice(scope.row.id)"
+          />
+          <ActionButton
+            v-if="trafficManagementPermission && scope.row.effectState === 0"
+            text="发布"
+            :popconfirm="{
+              title: '确定要发布吗?',
+            }"
+            @confirm="
+              handleChangeNoticeState({
+                id: scope.row.id,
+                managementType: 2,
+                name: scope.row.name,
+                content: scope.row.content,
+                attachment: scope.row.attachment,
+                isPush: scope.row.isPush,
+                effectState: 1,
+              })
+            "
+          />
+          <ActionButton
+            v-if="trafficManagementPermission && scope.row.effectState === 1"
+            text="撤回"
+            @click="
+              handleChangeNoticeState({
+                id: scope.row.id,
+                managementType: 2,
+                name: scope.row.name,
+                content: scope.row.content,
+                attachment: scope.row.attachment,
+                isPush: scope.row.isPush,
+                effectState: 0,
+              })
+            "
+          />
+          <ActionButton
+            v-if="trafficManagementPermission"
+            text="删除"
+            :popconfirm="{
+              title: '确定要删除?',
+            }"
+            @confirm="handleDelete(scope.row.id)"
+          />
+        </div>
+      </template>
     </BasicTable>
   </div>
 </template>
@@ -32,29 +112,54 @@
 <script setup lang="ts">
   import BasicTable from '@/components/BasicTable.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
-  import { TABLE_OPTIONS, REGULATION_TABLE_COLUMNS } from '../configs/tables';
+  import ActionButton from '@/components/ActionButton.vue';
+  import { ElMessage } from 'element-plus';
+  import { TABLE_OPTIONS, NOTICE_TABLE_COLUMNS, NOTICE_TABLE_COLUMNS_CHECKONLY } from '../configs/tables';
   import { ref, reactive, onMounted } from 'vue';
   import { Search, Plus } from '@element-plus/icons-vue';
   import { useRouter } from 'vue-router';
+  import type { QueryPageRequest } from '@/types/basic-query';
+  import type { UpdateNoticeQuery, RegulationDetailResponse, TableSearchQuery } from '../types';
+  import { getNoticeList, updateNotice, deleteNotice } from '@/api/traffic-regulation/traffic-regulation';
+  import DownloadIcon from '@/views/disaster/disaster-control/src/svg/download.svg';
+  import { downloadFile } from '@/views/disaster/utils';
+  import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
+  import { FILE_TYPE_ICON } from '@/views/disaster/constant';
+  import { unformatAttachment } from '../utils';
+
+  import { useUserInfoHook } from '@/hooks/useUserInfoHook';
+  import { TRAFFIC_MANAGEMENT_PERMISSION } from '../constants';
+
+  const { permissions } = useUserInfoHook();
+
+  const trafficManagementPermission = ref<Boolean>(
+    Boolean(permissions.find((item: { code: string }) => item.code === TRAFFIC_MANAGEMENT_PERMISSION)),
+  );
 
   const router = useRouter();
 
   // 搜索栏
-  const searchData = ref('');
+  const searchData = reactive<TableSearchQuery>({
+    searchName: null,
+    managementType: 2, // 1-管理规定,2-管理通知
+  });
   function handleSearch() {
     tabelQuery.value.queryParam = searchData;
     getTabelData();
   }
 
   // 表格
-  const { tableConfig, pagination } = useTableConfig(REGULATION_TABLE_COLUMNS, TABLE_OPTIONS);
+  const { tableConfig, pagination } = useTableConfig(
+    trafficManagementPermission.value ? NOTICE_TABLE_COLUMNS : NOTICE_TABLE_COLUMNS_CHECKONLY,
+    TABLE_OPTIONS,
+  );
 
-  const tableData = ref<any[]>([]);
+  const tableData = ref<RegulationDetailResponse[]>([]);
 
-  const tabelQuery = ref({
+  const tabelQuery = ref<QueryPageRequest<TableSearchQuery>>({
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
-    queryParam: {},
+    queryParam: searchData,
   });
 
   const handleSizeChange = (value: number) => {
@@ -68,7 +173,21 @@
     getTabelData();
   };
 
-  async function getTabelData() {}
+  async function getTabelData() {
+    const res = await getNoticeList(tabelQuery.value);
+    tableData.value = res.records;
+    tableData.value = res.records;
+    pagination.total = res.totalRow;
+    tableConfig.loading = false;
+  }
+
+  // 预览
+  const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
+  const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
+    if (url) {
+      previewOnlineRef.value?.open(url, type);
+    }
+  };
 
   onMounted(async () => {
     getTabelData();
@@ -82,10 +201,55 @@
       },
     });
   }
+
+  function handleViewNotice(id: number) {
+    router.push({
+      name: 'traffic-regulation-item',
+      query: {
+        id,
+        operate: 'notice-view',
+      },
+    });
+  }
+  function handleEditNotice(id: number) {
+    router.push({
+      name: 'traffic-regulation-item',
+      query: {
+        id,
+        operate: 'notice-edit',
+      },
+    });
+  }
+  async function handleChangeNoticeState(data: UpdateNoticeQuery) {
+    tableConfig.loading = true;
+    try {
+      await updateNotice(data);
+    } catch (e) {
+      ElMessage.error('修改失败');
+      return;
+    } finally {
+      tableConfig.loading = false;
+    }
+    getTabelData();
+  }
+  async function handleDelete(id: number) {
+    tableConfig.loading = true;
+    try {
+      await deleteNotice(id);
+    } catch (e) {
+      ElMessage.error('删除失败');
+      return;
+    } finally {
+      tableConfig.loading = false;
+    }
+    getTabelData();
+  }
 </script>
 
 <style scoped lang="scss">
   @use '@/styles/page-main-layout.scss' as *;
+  @use '@/styles/basic-table-action.scss' as *;
+  @use '@/styles/basic-table-file.scss' as *;
   .regulation-search-input {
     max-width: 500px;
   }
@@ -95,4 +259,10 @@
     justify-content: space-between;
     width: 100%;
   }
+
+  .effect-state {
+    display: flex;
+    align-items: center;
+    justify-self: center;
+  }
 </style>

+ 27 - 10
src/views/traffic/regulation/components/NoticeView.vue

@@ -13,10 +13,10 @@
       <span class="title" v-else>{{ NoticeDetail?.name }}</span>
       <div class="notice">
         <p class="info-item">
-          创建人:<span class="info-content">{{ NoticeDetail?.realname }}</span>
+          创建人:<span class="info-content">{{ NoticeDetail?.creatName }}</span>
         </p>
         <p class="info-item">
-          发布时间:<span class="info-content">{{ NoticeDetail?.releaseTime }}</span>
+          发布时间:<span class="info-content">{{ NoticeDetail?.pushTime }}</span>
         </p>
       </div>
     </header>
@@ -24,14 +24,14 @@
     <section class="content">
       <div v-html="NoticeDetail?.content"></div>
     </section>
-    <section class="file" v-if="NoticeDetail?.noticeFiles.length">
-      <span class="info-content" style="font-size: 14px">文件({{ NoticeDetail?.noticeFiles.length }})</span>
+    <section class="file" v-if="NoticeDetail?.attachment.length">
+      <span class="info-content" style="font-size: 14px">附件({{ NoticeDetail?.attachment.length }})</span>
       &nbsp;
       <a @click="downloadAll">下载全部</a>
       <div class="file-list">
         <div
           class="file-item"
-          v-for="item in NoticeDetail?.noticeFiles"
+          v-for="item in NoticeDetail.attachment"
           :key="item.fileId"
           @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
         >
@@ -56,29 +56,46 @@
   import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
   import { downloadFile } from '@/views/disaster/utils';
   import { FILE_TYPE_ICON } from '../constants';
-  import { NoticeDetailResponse } from '../types';
+  import { unformatAttachment } from '../utils';
+  import { getNoticeDetail } from '@/api/traffic-regulation/traffic-regulation';
 
   const props = defineProps<{
     id: number;
   }>();
 
   const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
-
   const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
     if (url) {
       previewOnlineRef.value?.open(url, type);
     }
   };
 
-  const NoticeDetail = ref<NoticeDetailResponse>();
+  const NoticeDetail = ref();
+
+  const getDetail = async () => {
+    const res = await getNoticeDetail(props.id);
+    NoticeDetail.value = {
+      id: props.id,
+      content: res.content,
+      attachment: unformatAttachment(res.attachment),
+      effectState: res.effectState,
+      pushTime: res.pushTime,
+      isPush: res.isPush,
+      remark: res.remark,
+      creatName: res.creatName,
+      name: res.name,
+    };
+  };
 
   const downloadAll = () => {
-    NoticeDetail.value?.noticeFiles.forEach((item) => {
+    NoticeDetail.value?.attachment.forEach((item) => {
       downloadFile(item.fileUrl, item.fileName);
     });
   };
 
-  onMounted(() => {});
+  onMounted(async () => {
+    await getDetail();
+  });
 </script>
 
 <style scoped lang="scss">

+ 36 - 17
src/views/traffic/regulation/components/RegulationCreate.vue

@@ -1,7 +1,7 @@
 <template>
   <main class="safety-platform-container__main">
     <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
-      <template #regulationFiles>
+      <template #attachment>
         <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
       </template>
       <template #isPush>
@@ -12,7 +12,7 @@
         <SelectGroup
           v-if="ruleFormData.isPush === IS_PUSH.PUSH"
           ref="selectGroupRef"
-          :userGroupList="ruleFormData.userGroupList || []"
+          :userGroupList="ruleFormData.userGroupList as number[] || []"
           @userGroupListChange="handleUserGroupListChange"
         />
       </template>
@@ -26,22 +26,25 @@
 </template>
 
 <script setup lang="ts">
+  import { onMounted, ref } from 'vue';
+  import { useRouter } from 'vue-router';
+  import { ElMessage } from 'element-plus';
   import BasicForm from '@/components/BasicForm.vue';
   import UploadFiles from '@/views/disaster/components/UploadFiles.vue';
   import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
+  import UploadLoading from '@/components/UploadLoading.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { useUserInfoHook } from '@/views/disaster/hooks';
   import { IS_PUSH } from '../constants';
+  import { createRegulation } from '@/api/traffic-regulation/traffic-regulation';
   import { REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES } from '../configs/form';
-  import { FileItem, RegulationRuleForm } from '../types';
-  import { onMounted, ref } from 'vue';
-  import UploadLoading from '@/components/UploadLoading.vue';
-  import { useRouter } from 'vue-router';
+  import type { FileItem, CreateRegulationRuleForm, CreateRegulationQuery } from '../types';
+  import { formatAttachmentList } from '../utils';
 
   const { realname } = useUserInfoHook();
 
   const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
-    useFormConfigHook<RegulationRuleForm>(REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES);
+    useFormConfigHook<CreateRegulationRuleForm>(REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES);
 
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
   const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
@@ -51,7 +54,7 @@
   };
 
   const handleUploadSuccess = (fileList: FileItem[]) => {
-    ruleFormData.regulationFiles = fileList;
+    ruleFormData.attachment = fileList;
   };
 
   const handleValidate = async () => {
@@ -64,25 +67,41 @@
     return parentValidateResult && childValidateResult;
   };
 
-  const getFormData = () => {
+  const getFormData = async () => {
     if (!ruleFormData.isPush) {
       ruleFormData.userGroupList = [];
     }
     cloneRuleFormData();
-    return ruleFormData;
+    const res: CreateRegulationQuery = {
+      managementType: 1,
+      name: ruleFormData.name,
+      attachment: JSON.stringify(await formatAttachmentList(ruleFormData.attachment)),
+      isPush: ruleFormData.isPush,
+      userGroupList: ruleFormData.userGroupList?.join(','),
+      remark: ruleFormData.remark,
+      effectState: 0,
+    };
+    return res;
   };
 
   const formLoading = ref(false);
   const router = useRouter();
-  const handleSubmit = () => {
-    handleValidate();
+  const handleSubmit = async () => {
+    const res = await handleValidate();
+    if (!res) return;
+    try {
+      formLoading.value = true;
+      const params = await getFormData();
+      await createRegulation(params);
+      ElMessage.success('创建成功');
+      router.back();
+    } catch (e) {
+      console.log(e);
+    } finally {
+      formLoading.value = false;
+    }
   };
 
-  // defineExpose({
-  //   handleValidate,
-  //   getFormData,
-  // });
-
   onMounted(() => {
     ruleFormData.realname = realname;
     cloneRuleFormData();

+ 49 - 17
src/views/traffic/regulation/components/RegulationEdit.vue

@@ -1,8 +1,13 @@
 <template>
   <main class="safety-platform-container__main">
     <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
-      <template #regulationFiles>
-        <UploadFiles label="上传附件" ref="uploadFilesRef" @uploadSuccess="handleUploadSuccess" />
+      <template #attachment>
+        <UploadFiles
+          label="上传附件"
+          ref="uploadFilesRef"
+          :fileList="ruleFormData.attachment"
+          @uploadSuccess="handleUploadSuccess"
+        />
       </template>
       <template #isPush>
         <el-radio-group v-model="ruleFormData.isPush">
@@ -31,31 +36,40 @@
   import SelectGroup from '@/components/PersonGroup/SelectGroup.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { IS_PUSH } from '../constants';
+  import { ElMessage } from 'element-plus';
   import { REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES } from '../configs/form';
-  import { FileItem, RegulationRuleForm } from '../types';
+  import type { FileItem, CreateRegulationRuleForm, UpdateRegulationQuery } from '../types';
   import { onMounted, ref } from 'vue';
   import UploadLoading from '@/components/UploadLoading.vue';
   import { useRouter } from 'vue-router';
+  import { stringToArray, unformatAttachment, formatAttachmentList } from '../utils';
+  import { getRegulationDetail, updateRegulation } from '@/api/traffic-regulation/traffic-regulation';
 
   const props = defineProps<{
     id: number;
   }>();
 
   const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData, beforeRouteLeave } =
-    useFormConfigHook<RegulationRuleForm>(REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES);
+    useFormConfigHook<CreateRegulationRuleForm>(REGULATION_FORM_CONFIG, REGULATION_FORM_DATA, REGULATION_FORM_RULES);
 
   const basicFormRef = ref<InstanceType<typeof BasicForm>>();
   const selectGroupRef = ref<InstanceType<typeof SelectGroup>>();
 
-  const getRegulationDetail = async () => {
-    // TODO 获取详情并写入表单
+  const getDetail = async () => {
+    const res = await getRegulationDetail(props.id);
+    ruleFormData.name = res.name;
+    ruleFormData.attachment = unformatAttachment(res.attachment)!;
+    ruleFormData.remark = res.remark;
+    ruleFormData.realname = res.creatName;
+    ruleFormData.isPush = res.isPush;
+    ruleFormData.userGroupList = stringToArray(res.userGroupList);
   };
   const handleUserGroupListChange = (userGroupList: number[]) => {
     ruleFormData.userGroupList = userGroupList;
   };
 
   const handleUploadSuccess = (fileList: FileItem[]) => {
-    ruleFormData.regulationFiles = fileList;
+    ruleFormData.attachment = fileList;
   };
 
   const handleValidate = async () => {
@@ -68,27 +82,45 @@
     return parentValidateResult && childValidateResult;
   };
 
-  const getFormData = () => {
+  const getFormData = async () => {
     if (!ruleFormData.isPush) {
       ruleFormData.userGroupList = [];
     }
     cloneRuleFormData();
-    return ruleFormData;
+    const res: UpdateRegulationQuery = {
+      id: props.id,
+      managementType: 1,
+      name: ruleFormData.name,
+      attachment: JSON.stringify(await formatAttachmentList(ruleFormData.attachment)),
+      isPush: ruleFormData.isPush,
+      userGroupList: ruleFormData.userGroupList?.join(','),
+      remark: ruleFormData.remark,
+      effectState: 0,
+    };
+    return res;
   };
 
   const formLoading = ref(false);
   const router = useRouter();
-  const handleSubmit = () => {
-    handleValidate();
-  };
 
-  // defineExpose({
-  //   handleValidate,
-  //   getFormData,
-  // });
+  const handleSubmit = async () => {
+    const res = await handleValidate();
+    if (!res) return;
+    try {
+      formLoading.value = true;
+      const params = await getFormData();
+      await updateRegulation(params);
+      ElMessage.success('编辑成功');
+      router.back();
+    } catch (e) {
+      console.log(e);
+    } finally {
+      formLoading.value = false;
+    }
+  };
 
   onMounted(async () => {
-    await getRegulationDetail();
+    await getDetail();
     cloneRuleFormData();
     beforeRouteLeave();
   });

+ 163 - 11
src/views/traffic/regulation/components/RegulationTable.vue

@@ -3,19 +3,19 @@
     <header>
       <!-- 按钮 -->
       <el-button type="primary" class="search-table-container--button" :icon="Plus" @click="handleCreateRegulation">
-        创建演练计划
+        新建管理规定
       </el-button>
 
       <div class="regulation-search">
         <el-input
           class="regulation-search-input"
-          v-model="searchData"
+          v-model="searchData.searchName"
           placeholder="输入规定标题或文件名称"
           :prefix-icon="Search"
           clearable
         >
         </el-input>
-        <el-button type="primary" @click="getTabelData"> 查询 </el-button>
+        <el-button type="primary" @click="handleSearch"> 查询 </el-button>
       </div>
     </header>
     <!-- 表格 -->
@@ -25,36 +25,134 @@
       @update:pageSize="handleSizeChange"
       @update:pageNumber="handleCurrentChange"
     >
+      <template #attachment="scope">
+        <div class="file-container--div" v-for="item in unformatAttachment(scope.row.attachment)" :key="item.fileId">
+          <img
+            class="file-container--div__icon"
+            @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
+            :src="FILE_TYPE_ICON[item.fileType]"
+          />
+          <span
+            class="file-container--div__name"
+            @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
+            >{{ item.fileName }}</span
+          >
+          <img
+            class="file-container--div__download"
+            :src="DownloadIcon"
+            @click="downloadFile(item.fileUrl, item.fileName)"
+          />
+        </div>
+      </template>
+      <template #effectState="scope">
+        <div class="effect-state" v-if="scope.row.effectState === 1">
+          <div style="background-color: #52c41a; width: 5px; height: 5px; border-radius: 50%; margin-right: 5px"></div>
+          <span>已生效</span>
+        </div>
+        <div class="effect-state" v-else-if="scope.row.effectState === 0">
+          <div style="background-color: #ff4d4f; width: 5px; height: 5px; border-radius: 50%; margin-right: 5px"></div>
+          <span>未生效</span>
+        </div>
+      </template>
+      <template #action="scope">
+        <div class="action-container--div">
+          <ActionButton v-if="scope.row.effectState === 0" text="编辑" @click="handleEditRegulation(scope.row.id)" />
+          <ActionButton
+            v-if="scope.row.effectState === 0"
+            text="发布"
+            :popconfirm="{
+              title: '确定要发布吗?',
+            }"
+            @confirm="
+              handleChangeRegulationState({
+                id: scope.row.id,
+                managementType: 1,
+                name: scope.row.name,
+                attachment: scope.row.attachment,
+                isPush: scope.row.isPush,
+                effectState: 1,
+              })
+            "
+          />
+          <ActionButton
+            v-if="scope.row.effectState === 1"
+            text="撤回"
+            @click="
+              handleChangeRegulationState({
+                id: scope.row.id,
+                managementType: 1,
+                name: scope.row.name,
+                attachment: scope.row.attachment,
+                isPush: scope.row.isPush,
+                effectState: 0,
+              })
+            "
+          />
+          <ActionButton
+            text="删除"
+            :popconfirm="{
+              title: '确定要删除?',
+            }"
+            @confirm="handleDelete(scope.row.id)"
+          />
+        </div>
+      </template>
     </BasicTable>
+    <PreviewOnline ref="previewOnlineRef" />
   </div>
 </template>
 
 <script setup lang="ts">
   import BasicTable from '@/components/BasicTable.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
-  import { TABLE_OPTIONS, REGULATION_TABLE_COLUMNS } from '../configs/tables';
+  import ActionButton from '@/components/ActionButton.vue';
+  import { ElMessage } from 'element-plus';
   import { ref, reactive, onMounted } from 'vue';
-  import { Search, Plus } from '@element-plus/icons-vue';
   import { useRouter } from 'vue-router';
+  import { Search, Plus } from '@element-plus/icons-vue';
+  import type { QueryPageRequest } from '@/types/basic-query';
+  import { getRegulationList, updateRegulation, deleteRegulation } from '@/api/traffic-regulation/traffic-regulation';
+  import { TABLE_OPTIONS, REGULATION_TABLE_COLUMNS, REGULATION_TABLE_COLUMNS_CHECKONLY } from '../configs/tables';
+  import type { UpdateRegulationQuery, RegulationDetailResponse, TableSearchQuery } from '../types';
+  import DownloadIcon from '@/views/disaster/disaster-control/src/svg/download.svg';
+  import { downloadFile } from '@/views/disaster/utils';
+  import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
+  import { FILE_TYPE_ICON } from '@/views/disaster/constant';
+  import { unformatAttachment } from '../utils';
+
+  import { useUserInfoHook } from '@/hooks/useUserInfoHook';
+  import { TRAFFIC_MANAGEMENT_PERMISSION } from '../constants';
+
+  const { permissions } = useUserInfoHook();
+
+  const trafficManagementPermission = ref<Boolean>(
+    Boolean(permissions.find((item: { code: string }) => item.code === TRAFFIC_MANAGEMENT_PERMISSION)),
+  );
 
   const router = useRouter();
 
   // 搜索栏
-  const searchData = ref('');
+  const searchData = reactive<TableSearchQuery>({
+    searchName: null,
+    managementType: 1,
+  });
   function handleSearch() {
     tabelQuery.value.queryParam = searchData;
     getTabelData();
   }
 
   // 表格
-  const { tableConfig, pagination } = useTableConfig(REGULATION_TABLE_COLUMNS, TABLE_OPTIONS);
+  const { tableConfig, pagination } = useTableConfig(
+    trafficManagementPermission ? REGULATION_TABLE_COLUMNS : REGULATION_TABLE_COLUMNS_CHECKONLY,
+    TABLE_OPTIONS,
+  );
 
-  const tableData = ref<any[]>([]);
+  const tableData = ref<RegulationDetailResponse[]>([]);
 
-  const tabelQuery = ref({
+  const tabelQuery = ref<QueryPageRequest<TableSearchQuery>>({
     pageNumber: pagination.pageNumber,
     pageSize: pagination.pageSize,
-    queryParam: {},
+    queryParam: searchData,
   });
 
   const handleSizeChange = (value: number) => {
@@ -68,7 +166,19 @@
     getTabelData();
   };
 
-  async function getTabelData() {}
+  async function getTabelData() {
+    const res = await getRegulationList(tabelQuery.value);
+    tableData.value = res.records;
+    pagination.total = res.totalRow;
+    tableConfig.loading = false;
+  }
+  // 预览
+  const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
+  const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
+    if (url) {
+      previewOnlineRef.value?.open(url, type);
+    }
+  };
 
   onMounted(async () => {
     getTabelData();
@@ -82,10 +192,46 @@
       },
     });
   }
+  function handleEditRegulation(id: number) {
+    router.push({
+      name: 'traffic-regulation-item',
+      query: {
+        id,
+        operate: 'regulation-edit',
+      },
+    });
+  }
+  async function handleChangeRegulationState(data: UpdateRegulationQuery) {
+    tableConfig.loading = true;
+    try {
+      await updateRegulation(data);
+    } catch (e) {
+      ElMessage.error('修改失败');
+      return;
+    } finally {
+      tableConfig.loading = false;
+    }
+    getTabelData();
+  }
+  async function handleDelete(id: number) {
+    tableConfig.loading = true;
+    try {
+      await deleteRegulation(id);
+    } catch (e) {
+      ElMessage.error('删除失败');
+      return;
+    } finally {
+      tableConfig.loading = false;
+    }
+    getTabelData();
+  }
 </script>
 
 <style scoped lang="scss">
   @use '@/styles/page-main-layout.scss' as *;
+  @use '@/styles/basic-table-action.scss' as *;
+  @use '@/styles/basic-table-file.scss' as *;
+
   .regulation-search-input {
     max-width: 500px;
   }
@@ -95,4 +241,10 @@
     justify-content: space-between;
     width: 100%;
   }
+
+  .effect-state {
+    display: flex;
+    align-items: center;
+    justify-self: center;
+  }
 </style>

+ 10 - 10
src/views/traffic/regulation/configs/form.ts

@@ -12,9 +12,9 @@ export const REGULATION_FORM_CONFIG: FormConfig[] = [
     },
   },
   {
-    prop: 'regulationFiles',
+    prop: 'attachment',
     label: '规定文件:',
-    slot: 'regulationFiles',
+    slot: 'attachment',
   },
   {
     prop: 'isPush',
@@ -23,7 +23,7 @@ export const REGULATION_FORM_CONFIG: FormConfig[] = [
   },
   {
     label: '备注:',
-    prop: 'memo',
+    prop: 'remark',
     component: 'ElInput',
     componentProps: {
       type: 'textarea',
@@ -44,9 +44,9 @@ export const REGULATION_FORM_CONFIG: FormConfig[] = [
 
 export const REGULATION_FORM_DATA = {
   name: '',
-  regulationFiles: [],
+  attachment: [],
   isPush: null,
-  memo: '',
+  remark: '',
   realname: '',
 };
 
@@ -79,9 +79,9 @@ export const NOTICE_FORM_CONFIG: FormConfig[] = [
     },
   },
   {
-    prop: 'noticeFiles',
+    prop: 'attachment',
     label: '通知文件:',
-    slot: 'noticeFiles',
+    slot: 'attachment',
   },
   {
     prop: 'isPush',
@@ -90,7 +90,7 @@ export const NOTICE_FORM_CONFIG: FormConfig[] = [
   },
   {
     label: '备注:',
-    prop: 'memo',
+    prop: 'remark',
     component: 'ElInput',
     componentProps: {
       type: 'textarea',
@@ -112,9 +112,9 @@ export const NOTICE_FORM_CONFIG: FormConfig[] = [
 export const NOTICE_FORM_DATA = {
   name: '',
   content: '',
-  noticeFiles: [],
+  attachment: [],
   isPush: null,
-  memo: '',
+  remark: '',
   realname: '',
 };
 

+ 81 - 17
src/views/traffic/regulation/configs/tables.ts

@@ -16,32 +16,30 @@ export const REGULATION_TABLE_COLUMNS: TableColumnProps[] = [
   },
   {
     label: '规定名称',
-    prop: 'regulationName',
-    slot: 'regulationName',
+    prop: 'name',
     align: 'center',
-    minWidth: '120px',
+    minWidth: '200px',
   },
-
   {
     label: '规定文件',
-    prop: 'regulationDocument',
-    slot: 'regulationDocument',
+    prop: 'attachment',
+    slot: 'attachment',
     align: 'center',
-    minWidth: '120px',
+    minWidth: '360px',
   },
   {
     label: '生效状态',
-    prop: 'status',
+    prop: 'effectState',
+    slot: 'effectState',
     align: 'center',
     minWidth: '120px',
   },
   {
     label: '发布时间',
-    prop: 'dueCompleteTime',
+    prop: 'pushTime',
     align: 'center',
-    width: '200px',
+    minWidth: '200px',
   },
-
   {
     label: '操作',
     prop: 'action',
@@ -52,6 +50,34 @@ export const REGULATION_TABLE_COLUMNS: TableColumnProps[] = [
   },
 ];
 
+export const REGULATION_TABLE_COLUMNS_CHECKONLY: TableColumnProps[] = [
+  {
+    label: '序号',
+    align: 'center',
+    width: '80px',
+    type: 'index',
+  },
+  {
+    label: '规定名称',
+    prop: 'name',
+    align: 'center',
+    minWidth: '200px',
+  },
+  {
+    label: '规定文件',
+    prop: 'attachment',
+    slot: 'attachment',
+    align: 'center',
+    minWidth: '360px',
+  },
+  {
+    label: '发布时间',
+    prop: 'pushTime',
+    align: 'center',
+    minWidth: '200px',
+  },
+];
+
 export const NOTICE_TABLE_COLUMNS: TableColumnProps[] = [
   {
     label: '序号',
@@ -61,30 +87,68 @@ export const NOTICE_TABLE_COLUMNS: TableColumnProps[] = [
   },
   {
     label: '通知标题',
-    prop: 'noticeName',
-    slot: 'noticeName',
+    prop: 'name',
     align: 'center',
     minWidth: '120px',
   },
 
   {
     label: '通知文件',
-    prop: 'noticeDocument',
-    slot: 'noticeDocument',
+    prop: 'attachment',
+    slot: 'attachment',
     align: 'center',
     minWidth: '120px',
   },
   {
     label: '生效状态',
-    prop: 'status',
+    prop: 'effectState',
+    slot: 'effectState',
     align: 'center',
     minWidth: '120px',
   },
   {
     label: '发布时间',
-    prop: 'dueCompleteTime',
+    prop: 'pushTime',
     align: 'center',
+    minWidth: '120px',
+  },
+
+  {
+    label: '操作',
+    prop: 'action',
+    slot: 'action',
+    fixed: 'right',
     width: '200px',
+    align: 'center',
+  },
+];
+
+export const NOTICE_TABLE_COLUMNS_CHECKONLY: TableColumnProps[] = [
+  {
+    label: '序号',
+    align: 'center',
+    width: '80px',
+    type: 'index',
+  },
+  {
+    label: '通知标题',
+    prop: 'name',
+    align: 'center',
+    minWidth: '120px',
+  },
+
+  {
+    label: '通知文件',
+    prop: 'attachment',
+    slot: 'attachment',
+    align: 'center',
+    minWidth: '120px',
+  },
+  {
+    label: '发布时间',
+    prop: 'pushTime',
+    align: 'center',
+    minWidth: '120px',
   },
 
   {

+ 3 - 0
src/views/traffic/regulation/constants.ts

@@ -27,3 +27,6 @@ export const FILE_TYPE_ICON = {
   ppt: ppt,
   pdf: pdf,
 };
+
+//管理权限
+export const TRAFFIC_MANAGEMENT_PERMISSION = 'traffic_business_module:rule_notice';

+ 47 - 27
src/views/traffic/regulation/types.ts

@@ -1,44 +1,64 @@
-export interface RegulationRuleForm {
+export interface FileItem {
+  fileId: number;
+  fileName: string;
+  fileType: string;
+  fileSize: string;
+  fileUrl?: string;
+  file?: File;
+}
+
+export interface CreateRegulationRuleForm {
   name: string;
-  regulationFiles: FileItem[];
+  attachment: FileItem[];
   isPush: number | null;
   userGroupList?: number[];
-  memo?: string;
-  realname: string;
+  remark?: string;
+  realname?: string | null;
 }
 
-export interface NoticeRuleForm {
+export interface CreateRegulationQuery {
+  managementType: number;
   name: string;
+  attachment?: string;
+  isPush?: number | null;
+  userGroupList?: string;
+  remark?: string;
+  effectState: number;
+}
+
+export interface UpdateRegulationQuery extends CreateRegulationQuery {
+  id: number;
+}
+
+export interface CreateNoticeRuleForm extends CreateRegulationRuleForm {
   content: string;
-  noticeFiles: FileItem[];
-  isPush: number | null;
-  userGroupList?: number[];
-  memo?: string;
-  realname: string;
 }
 
-export interface FileItem {
-  fileId: number;
-  fileName: string;
-  fileType: string;
-  fileSize: string;
-  fileUrl?: string;
-  file?: File;
+export interface CreateNoticeQuery extends CreateRegulationQuery {
+  content: string;
+}
+
+export interface UpdateNoticeQuery extends CreateNoticeQuery {
+  id: number;
 }
 
 export interface RegulationDetailResponse {
+  id: number;
   name: string;
-  regulationFiles: FileItem[];
-  memo?: string;
-  realname: string;
-  releaseTime: string;
+  attachment: string;
+  effectState: number; // 生效状态:0-未生效,1-生效
+  pushTime: string;
+  isPush: number;
+  remark?: string;
+  userGroupList?: string;
+  creatName: string | null;
 }
 
-export interface NoticeDetailResponse {
-  name: string;
+export interface NoticeDetailResponse extends RegulationDetailResponse {
   content: string;
-  noticeFiles: FileItem[];
-  memo?: string;
-  realname: string;
-  releaseTime: string;
+}
+
+export interface TableSearchQuery {
+  searchName: string | null;
+  managementType: number; // 管理类型:1-管理规定,2-管理通知
 }

+ 41 - 0
src/views/traffic/regulation/utils.ts

@@ -0,0 +1,41 @@
+import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
+import type { FileItem } from '@/views/disaster/types';
+
+export function stringToArray(str?: string): number[] | undefined {
+  if (!str) return undefined;
+  return JSON.parse('[' + str + ']');
+}
+
+export function unformatAttachment(file?: string) {
+  if (!file) return undefined;
+  const fileData: FileItem[] = JSON.parse(file);
+  return fileData;
+}
+
+const formatAttachment = async (data: FileItem) => {
+  if (!data.file) return data;
+  const fileName = data.fileName;
+  const res = await uploadFileApi({ bizType: UPLOAD_BIZ_TYPE.ATTACHMENT, fileName, file: data.file });
+  const fileType = data.fileType;
+  const fileSize = data.fileSize;
+  const fileId = data.fileId;
+  const fileUrl = res.url;
+  return {
+    fileName,
+    fileType,
+    fileSize,
+    fileUrl,
+    fileId,
+  };
+};
+
+export const formatAttachmentList = async (data: FileItem[]) => {
+  if (!data || data.length === 0) return null;
+  const res = await Promise.all(
+    data.map(async (item) => {
+      const res = await formatAttachment(item);
+      return res;
+    }),
+  );
+  return res;
+};

+ 2 - 2
utils/devProxy/staff/proxy.ts

@@ -3,8 +3,8 @@ import path from 'path';
 
 // staff环境
 const proxyStaff: PROXY_TYPE = {
-  serverHost: 'http://192.168.13.68:8802/',
-  // serverHost: 'http://192.168.22.121:8802/',
+  // serverHost: 'http://192.168.13.68:8802/',
+  serverHost: 'http://192.168.22.121:8802/',
   // serverHost: 'http://192.168.22.146:8802/',
   loginHost: 'http://192.168.13.68:7200/login/#/',
   fileUploadHost: 'http://192.168.13.102:9000/',