From 7c906b4acf785180132f91db5d70c3a29fa85cd3 Mon Sep 17 00:00:00 2001
From: 马宇豪 <978517621@qq.com>
Date: 星期三, 21 六月 2023 09:39:13 +0800
Subject: [PATCH] 新增页面和配置,对接口

---
 src/util/validate.js                        |    6 
 src/views/Admin/Report.vue                  |   72 +
 src/components/Home/QuickNavigation.vue     |  119 +++
 src/views/Admin/msgRecord.vue               |   70 -
 config/env.production.js                    |    2 
 src/views/Admin/components/msgDetailMod.vue |  191 +++++
 src/assets/style/themeColor.less            |    1 
 src/components/Home/Review.vue              |   84 ++
 src/views/Admin/history.vue                 |   59 +
 src/util/AntDesign.js                       |    4 
 src/api/list.js                             |    9 
 src/views/Admin/notice.vue                  |  154 +++-
 config/env.development.js                   |    2 
 src/views/Admin/msgReview.vue               |   69 +
 src/layout/menuSider.vue                    |   17 
 src/views/Admin/components/userMod.vue      |    4 
 src/components/Home/Projecting.vue          |  123 ++-
 src/views/Admin/callRecord.vue              |   34 
 src/views/Admin/release.vue                 |   61 +
 src/util/request.js                         |   24 
 src/views/Admin/components/sameLevelMod.vue |    1 
 src/router/index.js                         |    8 
 /dev/null                                   |   54 -
 src/views/Admin/components/msgEditMod.vue   |  223 +++++-
 src/views/Admin/list.vue                    |   82 +
 src/layout/menu/index.js                    |  264 ++++++-
 src/views/Admin/HomeDefault.vue             |   16 
 src/views/Admin/massSend.vue                |   43 
 src/views/Admin/sameLevel.vue               |   18 
 src/views/Admin/userManage.vue              |   17 
 src/views/Admin/components/callListMod.vue  |   21 
 src/views/Home.vue                          |   25 
 src/components/Home/Dynamic.vue             |   65 +
 33 files changed, 1,399 insertions(+), 543 deletions(-)

diff --git a/config/env.development.js b/config/env.development.js
index 5d13ab3..9441e3b 100644
--- a/config/env.development.js
+++ b/config/env.development.js
@@ -1,5 +1,5 @@
 module.exports = {
     NODE_ENV: "development",
     baseUrl: 'http://192.168.0.38:8086',
-    // baseUrl: '121.239.169.30:33306',
+    // baseUrl: 'http://121.239.169.30:13001',
 }
\ No newline at end of file
diff --git a/config/env.production.js b/config/env.production.js
index 07f4c05..1ee261b 100644
--- a/config/env.production.js
+++ b/config/env.production.js
@@ -1,4 +1,4 @@
 module.exports = {
     NODE_ENV: "production",
-    baseUrl: '121.239.169.30:33306',
+    baseUrl: 'http://121.239.169.30:13001',
 }
\ No newline at end of file
diff --git a/src/api/list.js b/src/api/list.js
index 806dd84..1b9fef7 100644
--- a/src/api/list.js
+++ b/src/api/list.js
@@ -62,5 +62,10 @@
     })
 }
 
-
-
+// 删除文件
+export function deleteFile(id){
+    return request({
+        url: '/attachment/delete/' + id,
+        method: 'get'
+    })
+}
\ No newline at end of file
diff --git a/src/assets/style/themeColor.less b/src/assets/style/themeColor.less
index a7a9ba5..f219243 100644
--- a/src/assets/style/themeColor.less
+++ b/src/assets/style/themeColor.less
@@ -1,6 +1,7 @@
 @base: #1890ff;
 @link: #1890ff;
 @success: #52c41a;
+@green: #87d068;
 @warning: #faad14;
 @danger: #f5222d;
 @blackText: rgba(0,0,0,.65);
diff --git a/src/components/Home/Dynamic.vue b/src/components/Home/Dynamic.vue
index e3784ed..7fc8b45 100644
--- a/src/components/Home/Dynamic.vue
+++ b/src/components/Home/Dynamic.vue
@@ -3,51 +3,60 @@
     <a-list item-layout="horizontal" :data-source="lists">
       <a-list-item slot="renderItem" slot-scope="item">
         <a-list-item-meta
-          :description="item.created | filterTime"
+          :description="item.responseTime | filterTime"
         >
-          <a slot="title" href="#">{{ item.title }}</a>
+          <a slot="title" href="#" @click="openDetails(item.warnInfoId)">{{ item.publishingUnit }} 发布了 {{item.title}}</a>
           <a-avatar
             slot="avatar"
-            src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png"
+            :src="userImg"
           />
         </a-list-item-meta>
       </a-list-item>
     </a-list>
+    <msg-detail-mod ref="msgDetail"></msg-detail-mod>
   </a-card>
 </template>
 
 <script>
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
+import {getResponseRecord} from "@/api/list";
+
 export default {
   name: "Dynamic",
+  components: { msgDetailMod },
   data() {
     return {
-      lists: [
-        {
-          title: "阿勒泰地区莽村 李有田 在 20230301大风红色预警提示 进行了“已安排部署”叫应。",
-          created: '2023-03-1 12:12:12'
-        },
-        {
-          title: "李宏伟 在 20230301大风红色预警提示 进行了“已安排部署”叫应。",
-          created: '2023-03-12 12:12:12'
-        },
-        {
-          title: "李宏伟 在 20230301大风红色预警提示 进行了“已安排部署”叫应。",
-          created: '2023-03-12 12:12:12'
-        },
-        {
-          title: "李宏伟 在 20230301大风红色预警提示 进行了“已安排部署”叫应。",
-          created: '2023-03-12 12:12:12'
-        },
-        {
-          title: "阿勒泰地区莽村 李有田 在 20230311大风红色预警工作通知 进行了“已安排部署”叫应。",
-          created: '2023-03-12 12:12:12'
-        },
-        {
-          title: "木木  在 20230301大风红色预警提示 进行了“已安排部署”叫应。",
-          created: '2023-03-12 12:12:12'
+      search:{
+        pageIndex: 1,
+        pageSize: 6,
+        searchParams:{
+          emergType: null,
+          startTime: '',
+          endTime: ''
         }
-      ],
+      },
+      lists: [],
+      userImg: require('@/assets/user.png')
     };
   },
+  created() {
+    this.getData()
+  },
+  methods: {
+    async getData(){
+      const t = this
+      const res = await getResponseRecord(this.search)
+      if(res.data.code == 100){
+        t.lists = res.data.data
+      }else{
+        this.$message.error(res.data.msg)
+      }
+    },
+    openDetails(id){
+      const t = this
+      t.$refs.msgDetail.getDetails(id)
+      t.$refs.msgDetail.visible = true
+    }
+  }
 };
 </script>
diff --git a/src/components/Home/Projecting.vue b/src/components/Home/Projecting.vue
index 84dba18..6f4557b 100644
--- a/src/components/Home/Projecting.vue
+++ b/src/components/Home/Projecting.vue
@@ -1,69 +1,89 @@
 <template>
   <a-card title="近期通知" class="projecting">
-    <a slot="extra" href="#" style="color: rgb(19, 194, 194)">全部通知</a>
-    <a-card-grid style="width:33.33%;text-align:center" v-for="(item, index) in lists" :key="'projecting' + index">
+    <a slot="extra" href="release" class="tapBtn">全部通知</a>
+    <a-card-grid style="width:33.33%;text-align:center" v-for="(item, index) in lists" :key="'projecting' + index" @click="openDetails(item.id)">
       <div class="title">
-        <img :src="item.img" :alt="item.title">
-        <span>{{ item.title }}</span>
+        <img :src="img" :alt="item.title">
+        <span>{{ getRiskName(item.disasterType)}} {{getLevelName(item.warningLevel)}}</span>
       </div>
       <p>{{ item.content }}</p>
       <div class="project-item">
-        <b>{{ item.name }}</b>
-        <span>{{ item.created | filterTime }}</span>
+        <b>{{ item.publishingUnit }}</b>
+        <span>{{ item.publishingTime | filterTime }}</span>
       </div>
     </a-card-grid>
+    <msg-detail-mod ref="msgDetail"></msg-detail-mod>
   </a-card>
 </template>
 
 <script>
+import {getPublishRecord} from "@/api/list";
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
 export default {
   name: 'projecting',
+  components: { msgDetailMod },
   data () {
     return {
-      lists: [
-        { 
-          img: require('@/assets/user.png'),
-          title: '气象 红色预警',//显示灾害种类和对应颜色级别
-          content: '根据中央气象台消息,全疆近日气温将……',
-          name: '自治区',
-          created: '2020-10-12 12:12:12'
-        },
-        { 
-          img: require('@/assets/user.png'),
-          title: '气象 红色预警',
-          content: '今日阿勒泰地区将持续低温,请各单位……',
-          name: '阿勒泰地区',
-          created: '2021-08-21 12:12:12'
-        },
-        { 
-          img: require('@/assets/user.png'),
-          title: '气象 黄色预警',
-          content: '根据中央气象台消息,全疆近日气温将……',
-          name: '自治区',
-          created: '2022-10-12 12:12:12'
-        },
-        { 
-          img: require('@/assets/user.png'),
-          title: '气象 红色预警',
-          content: '根据中央气象台消息,全疆近日气温将……',
-          name: '自治区',
-          created: '2022-08-21 12:12:12'
-        },
-        { 
-          img: require('@/assets/user.png'),
-          title: '气象 红色预警',
-          content: '根据中央气象台消息,全疆近日气温将……',
-          name: '自治区',
-          created: '2022-10-12 12:12:12'
-        },
-        { 
-          img: require('@/assets/user.png'),
-          title: '气象 红色预警',
-          content: '根据中央气象台消息,全疆近日气温将……',
-          name: '自治区',
-          created: '2022-08-25 12:12:12'
+      search:{
+        pageIndex: 1,
+        pageSize: 6,
+        searchParams:{
+          emergType: null,
+          startTime: '',
+          endTime: ''
         }
+      },
+      lists: [],
+      img: require('@/assets/user.png'),
+      riskOptions: [
+        {name: '地震',value: 1},
+        {name: '洪涝',value: 2},
+        {name: '气象',value: 3},
+        {name: '泥石流',value: 4},
+        {name: '水旱',value: 5},
+        {name: '森林草原火灾',value: 6}
+      ],
+      levelOptions: [
+        {name: '红色预警',value: 1},
+        {name: '橙色预警',value: 2},
+        {name: '黄色预警',value: 3},
+        {name: '蓝色预警',value: 4}
       ]
+      // lists: [
+      //   {
+      //     img: require('@/assets/user.png'),
+      //     title: '气象 红色预警',//显示灾害种类和对应颜色级别
+      //     content: '根据中央气象台消息,全疆近日气温将……',
+      //     name: '自治区',
+      //     created: '2020-10-12 12:12:12'
+      //   }
+      // ]
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods:{
+    async getData(){
+      const t = this
+      const res = await getPublishRecord(t.search)
+      if(res.data.code == 100){
+        t.lists = res.data.data
+      }else{
+        this.$message.error(res.data.msg)
+      }
+    },
+    getRiskName(disasterType){
+      return this.riskOptions.find(i => i.value === disasterType)?.name;
+    },
+
+    getLevelName(warningLevel){
+      return this.levelOptions.find(i => i.value === warningLevel)?.name;
+    },
+    openDetails(id){
+      const t = this
+      t.$refs.msgDetail.getDetails(id)
+      t.$refs.msgDetail.visible = true
     }
   }
 }
@@ -71,6 +91,13 @@
 
 <style lang="less" scoped>
 .projecting {
+  .tapBtn{
+    color: #333;
+    &:hover{
+      color: @link;
+    }
+  }
+
   .title {
     text-align: left;
     margin-bottom: 10px;
diff --git a/src/components/Home/QuickNavigation.vue b/src/components/Home/QuickNavigation.vue
index 86ebd58..ef920be 100644
--- a/src/components/Home/QuickNavigation.vue
+++ b/src/components/Home/QuickNavigation.vue
@@ -1,17 +1,103 @@
 <template>
   <a-card title="快捷操作" class="quick">
-	<a style="color:blue">待叫应(1)</a>
-	<a >待审核</a>
-    <a>发布通知</a>
-    <a>查看统计</a>
-    <a>用户管理</a>
+    <a-tooltip overlayClassName="tip">
+      <template #title v-if="toResponse == 0">
+        暂无待叫应信息
+      </template>
+      <a :class="toResponse>0?'resColor':''" @click="toRes" v-if="userinfo.role.id == 3 && userinfo.unittype !==1">待叫应<span v-if="toResponse > 0">({{toResponse}})</span></a>
+    </a-tooltip>
+
+    <a-tooltip overlayClassName="tip">
+      <template #title v-if="toReview == 0">
+        暂无待审核信息
+      </template>
+      <a :class="toReview>0?'resColor':''" @click="toRev" v-if="userinfo.role.id == 2">待审核<span v-if="toReview > 0">({{toReview}})</span></a>
+    </a-tooltip>
+  <a href="massSend" v-if="userinfo.role.id == 3">发布通知</a>
+  <a>查看统计</a>
+  <a href="user" v-if="userinfo.role.id == 3">用户管理</a>
     <!-- <a-button><a-icon type="plus" />添加</a-button> -->
   </a-card>
 </template>
 
 <script>
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
+import {getMsgRecord, getResponseRecord} from "@/api/list";
+import {getUserInfo} from "@/util/storage";
+import {getReviewRecord} from "@/api/review";
+
 export default {
-  name: 'quick-navigation'
+  name: 'quick-navigation',
+  data() {
+    return {
+      userinfo: getUserInfo(),
+      toResponse: null,
+      toReview: null,
+    };
+  },
+  created() {
+    const t = this
+    t.getResData()
+    t.getReviewData()
+  },
+  methods: {
+    async getResData(){
+      const t = this
+      const res = await getMsgRecord({
+        pageIndex: 1,
+        pageSize: 10,
+        searchParams:{
+          responseStatus: 1,
+          startTime: '',
+          endTime: ''
+        }
+      })
+      if(res.data.code == 100){
+        t.toResponse = res.data.total
+      }else{
+        this.$message.error(res.data.msg)
+      }
+    },
+
+    async getReviewData(){
+      const t = this
+      const res = await getReviewRecord({
+        pageIndex: 1,
+        pageSize: 10,
+        searchParams:{
+          reviewStatus: 1,
+          startTime: '',
+          endTime: ''
+        }
+      })
+      if(res.data.code == 100){
+        t.toReview = res.data.total
+      }else{
+        this.$message.error(res.data.msg)
+      }
+    },
+
+    toRes(){
+      if(this.toResponse>0){
+        this.$router.push({
+          name: 'list',
+          query: {
+            type: 1
+          }
+        })
+      }
+    },
+    toRev(){
+      if(this.toReview>0){
+        this.$router.push({
+          name: 'msgReview',
+          query: {
+            type: 1
+          }
+        })
+      }
+    }
+  }
 }
 </script>
 
@@ -19,10 +105,31 @@
 .quick {
   a {
     display: inline-block;
+    text-align: center;
     width: 25%;
     font-size: 14px;
     margin-bottom: 13px;
     color: #333;
+
+    &:hover{
+      color: @link;
+    }
+  }
+  .resColor{
+    color: @danger;
   }
 }
 </style>
+<style lang="less">
+.tip{
+  .ant-tooltip-inner {
+  // 这里是框框
+    color: #333;
+    background-color: #fff!important;
+  }
+  .ant-tooltip-arrow::before {
+  // 这里是小三角形
+    background-color: #fff!important;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/Home/Review.vue b/src/components/Home/Review.vue
new file mode 100644
index 0000000..fd70f71
--- /dev/null
+++ b/src/components/Home/Review.vue
@@ -0,0 +1,84 @@
+<template>
+  <a-card title="最新审核记录">
+    <a slot="extra" href="msgReview" class="tapBtn">更多记录</a>
+    <a-list item-layout="horizontal" :data-source="lists">
+      <a-list-item slot="renderItem" slot-scope="item">
+        <a-list-item-meta
+          :description="item.gmtReviewSubmit | filterTime"
+        >
+          <a slot="title" v-if="item.reviewStatus == 1" href="#" @click="openDetails(item.id)">{{item.title}} <span class="orange">未审核</span></a>
+          <a slot="title" v-if="item.reviewStatus == 2" href="#" @click="openDetails(item.id)">{{item.title}} <span class="blue">已审核</span></a>
+          <a slot="title" v-if="item.reviewStatus == 3" href="#" @click="openDetails(item.id)">{{item.title}} <span class="red">审核已驳回</span></a>
+          <a-avatar
+            slot="avatar"
+            :src="userImg"
+          />
+        </a-list-item-meta>
+      </a-list-item>
+    </a-list>
+    <msg-detail-mod ref="msgDetail"></msg-detail-mod>
+  </a-card>
+</template>
+
+<script>
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
+import {getResponseRecord} from "@/api/list";
+import {getReviewRecord} from "@/api/review";
+
+export default {
+  name: "Dynamic",
+  components: { msgDetailMod },
+  data() {
+    return {
+      search:{
+        pageIndex: 1,
+        pageSize: 10,
+        searchParams:{
+          reviewStatus: null,
+          startTime: '',
+          endTime: ''
+        }
+      },
+      lists: [],
+      userImg: require('@/assets/user.png')
+    };
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    async getData(){
+      const t = this
+      const res = await getReviewRecord(this.search)
+      if(res.data.code == 100){
+        t.lists = res.data.data
+      }else{
+        this.$message.error(res.data.msg)
+      }
+    },
+    openDetails(id){
+      const t = this
+      t.$refs.msgDetail.getDetails(id)
+      t.$refs.msgDetail.visible = true
+    }
+  }
+};
+</script>
+<style lang="less" scoped>
+.tapBtn{
+  color: #333;
+  &:hover{
+    color: @link;
+  }
+}
+.blue{
+  color: @base;
+}
+
+.orange{
+  color: @warning;
+}
+.red{
+  color: @danger;
+}
+</style>
\ No newline at end of file
diff --git a/src/layout/menu/index.js b/src/layout/menu/index.js
index 44cb324..f1e46de 100644
--- a/src/layout/menu/index.js
+++ b/src/layout/menu/index.js
@@ -1,12 +1,13 @@
-const menuData = [{
+const menu = {
+	adminMenu: [{
 		MenuTitle: "首页",
 		Icon: "home",
 		MenuID: "1",
 		Children: [{
-				MenuID: "11",
-				MenuTitle: "控制面板",
-				MenuPath: "/home",
-			},
+			MenuID: "11",
+			MenuTitle: "控制面板",
+			MenuPath: "/home",
+		},
 			{
 				MenuID: "18",
 				MenuTitle: "实时气象",
@@ -29,79 +30,214 @@
 			}
 		],
 	},
-	{
-		MenuTitle: "预警信息管理",
-		Icon: "mail",
-		MenuID: "2",
-		Children: [{
+		{
+			MenuTitle: "预警信息管理",
+			Icon: "mail",
+			MenuID: "2",
+			Children: [{
 				MenuID: "21",
 				MenuTitle: "信息编辑",
 				MenuPath: "/notice",
 			},
-			{
-				MenuID: "22",
-				MenuTitle: "信息审核",
-				MenuPath: "/msgReview",
-			},
-			{
-				MenuID: "23",
-				MenuTitle: "信息发布",
-				MenuPath: "/report",
-			},
-			{
-				MenuID: "24",
-				MenuTitle: "历史信息",
-				MenuPath: "/history",
-			},
-			{
-				MenuID: "25",
-				MenuTitle: "叫应记录",
-				MenuPath: "/callRecord",
-			},
-		],
-	},
-	{
-		MenuTitle: "短信管理",
-		Icon: "message",
-		MenuID: "3",
-		Children: [{
+				{
+					MenuID: "22",
+					MenuTitle: "信息审核",
+					MenuPath: "/msgReview",
+				},
+				{
+					MenuID: "23",
+					MenuTitle: "信息发布",
+					MenuPath: "/report",
+				},
+				{
+					MenuID: "24",
+					MenuTitle: "历史信息",
+					MenuPath: "/history",
+				},
+				{
+					MenuID: "25",
+					MenuTitle: "叫应记录",
+					MenuPath: "/callRecord",
+				},
+			],
+		},
+		{
+			MenuTitle: "短信管理",
+			Icon: "message",
+			MenuID: "3",
+			Children: [{
 				MenuID: "31",
 				MenuTitle: "常规群发",
 				MenuPath: "/massSend",
 			},
-			{
-				MenuID: "32",
-				MenuTitle: "短信记录",
-				MenuPath: "/msgRecord",
-			},
-			{
-				MenuID: "33",
-				MenuTitle: "平级接收人管理",
-				MenuPath: "/samelevel",
-			},
-		],
-	},
-	{
-		MenuTitle: "设置",
-		Icon: "setting",
-		MenuID: "4",
-		Children: [{
+				{
+					MenuID: "32",
+					MenuTitle: "短信记录",
+					MenuPath: "/msgRecord",
+				},
+				{
+					MenuID: "33",
+					MenuTitle: "平级接收人管理",
+					MenuPath: "/samelevel",
+				},
+			],
+		},
+		{
+			MenuTitle: "设置",
+			Icon: "setting",
+			MenuID: "4",
+			Children: [{
 				MenuID: "41",
 				MenuTitle: "用户管理",
 				MenuPath: "/user",
 			},
+				{
+					MenuID: "42",
+					MenuTitle: "短信平台设置",
+					MenuPath: "/smsSetting",
+				},
+				// {
+				// 	MenuID: "43",
+				// 	MenuTitle: "菜单权限",
+				// 	MenuPath: "/menu",
+				// },
+			],
+		},
+	],
+	leaderMenu: [{
+		MenuTitle: "首页",
+		Icon: "home",
+		MenuID: "1",
+		Children: [{
+			MenuID: "11",
+			MenuTitle: "控制面板",
+			MenuPath: "/home",
+		},
 			{
-				MenuID: "42",
-				MenuTitle: "短信平台设置",
-				MenuPath: "/smsSetting",
+				MenuID: "18",
+				MenuTitle: "实时气象",
+				MenuPath: "/wendy",
 			},
-			// {
-			// 	MenuID: "43",
-			// 	MenuTitle: "菜单权限",
-			// 	MenuPath: "/menu",
-			// },
+			{
+				MenuID: "13",
+				MenuTitle: "数据统计",
+				MenuPath: "/audit"
+			}
 		],
 	},
-]
+		{
+			MenuTitle: "预警信息管理",
+			Icon: "mail",
+			MenuID: "2",
+			Children: [
+				{
+					MenuID: "22",
+					MenuTitle: "信息审核",
+					MenuPath: "/msgReview",
+				},
+			],
+		}
+	],
+	workerMenu: [{
+		MenuTitle: "首页",
+		Icon: "home",
+		MenuID: "1",
+		Children: [{
+			MenuID: "11",
+			MenuTitle: "控制面板",
+			MenuPath: "/home",
+		},
+			{
+				MenuID: "18",
+				MenuTitle: "实时气象",
+				MenuPath: "/wendy",
+			},
+			{
+				MenuID: "12",
+				MenuTitle: "我收到的",
+				MenuPath: "/list"
+			},
+			{
+				MenuID: "14",
+				MenuTitle: "我发布的",
+				MenuPath: "/release"
+			},
+			{
+				MenuID: "13",
+				MenuTitle: "数据统计",
+				MenuPath: "/audit"
+			}
+		],
+	},
+		{
+			MenuTitle: "预警信息管理",
+			Icon: "mail",
+			MenuID: "2",
+			Children: [{
+				MenuID: "21",
+				MenuTitle: "信息编辑",
+				MenuPath: "/notice",
+			},
+				{
+					MenuID: "23",
+					MenuTitle: "信息发布",
+					MenuPath: "/report",
+				},
+				{
+					MenuID: "24",
+					MenuTitle: "历史信息",
+					MenuPath: "/history",
+				},
+				{
+					MenuID: "25",
+					MenuTitle: "叫应记录",
+					MenuPath: "/callRecord",
+				},
+			],
+		},
+		{
+			MenuTitle: "短信管理",
+			Icon: "message",
+			MenuID: "3",
+			Children: [{
+				MenuID: "31",
+				MenuTitle: "常规群发",
+				MenuPath: "/massSend",
+			},
+				{
+					MenuID: "32",
+					MenuTitle: "短信记录",
+					MenuPath: "/msgRecord",
+				},
+				{
+					MenuID: "33",
+					MenuTitle: "平级接收人管理",
+					MenuPath: "/samelevel",
+				},
+			],
+		},
+		{
+			MenuTitle: "设置",
+			Icon: "setting",
+			MenuID: "4",
+			Children: [{
+				MenuID: "41",
+				MenuTitle: "用户管理",
+				MenuPath: "/user",
+			},
+				{
+					MenuID: "42",
+					MenuTitle: "短信平台设置",
+					MenuPath: "/smsSetting",
+				},
+				// {
+				// 	MenuID: "43",
+				// 	MenuTitle: "菜单权限",
+				// 	MenuPath: "/menu",
+				// },
+			],
+		},
+	]
+}
 
-export default menuData;
\ No newline at end of file
+export default menu;
\ No newline at end of file
diff --git a/src/layout/menuSider.vue b/src/layout/menuSider.vue
index 53b9b33..656f81e 100644
--- a/src/layout/menuSider.vue
+++ b/src/layout/menuSider.vue
@@ -21,15 +21,28 @@
 </template>
 
 <script>
-import menuData from './menu'
+import menu from './menu'
+import { getUserInfo } from "@/util/storage";
 export default {
   name: "menu-sider",
   data() {
     return {
-      navData: menuData,
+      userInfo: {},
+      navData: [],
       openKeys: ['1','2','3','4']
     };
   },
+  created() {
+    const t = this
+    t.userInfo = getUserInfo()
+    if(t.userInfo.role.id == 1){
+      t.navData = menu.adminMenu
+    }else if(t.userInfo.role.id == 3){
+      t.navData = menu.workerMenu
+    }else{
+      t.navData = menu.leaderMenu
+    }
+  },
   methods: {
     onOpenChange(openKeys) {
       if (openKeys.length !== 0) {
diff --git a/src/router/index.js b/src/router/index.js
index 8cbbfaa..d03f95e 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -41,12 +41,6 @@
 	    component: () => import('@/views/Admin/list'),
 	  },
 	  {
-	    path: '/details',
-	    name: 'detail',
-	    meta: { title: '信息详情' },
-	    component: () => import('@/views/Admin/Details'),
-	  },
-	  {
 	    path: '/audit',
 	    name: 'audit',
 	    meta: { title: '数据统计' },
@@ -60,7 +54,7 @@
       },
 		{
 			path: '/msgReview',
-			name: '/msgReview',
+			name: 'msgReview',
 			meta: { title: '信息审核' },
 			component: () => import('@/views/Admin/msgReview'),
 		},
diff --git a/src/util/AntDesign.js b/src/util/AntDesign.js
index 2c484ef..68899f4 100644
--- a/src/util/AntDesign.js
+++ b/src/util/AntDesign.js
@@ -28,6 +28,6 @@
   Cascader,
   Pagination,
   FormModel,
-  message
+  Upload,
 } from "ant-design-vue";
-Vue.use(Alert).use(Pagination).use(Tag).use(Switch).use(FormModel).use(Modal).use(Cascader).use(TreeSelect).use(Button).use(Layout).use(Menu).use(Icon).use(Form).use(Input).use(Tabs).use(Checkbox).use(Row).use(Col).use(Avatar).use(Divider).use(Card).use(List).use(Tooltip).use(Dropdown).use(Select).use(Radio).use(DatePicker).use(Table);
+Vue.use(Alert).use(Pagination).use(Upload).use(Tag).use(Switch).use(FormModel).use(Modal).use(Cascader).use(TreeSelect).use(Button).use(Layout).use(Menu).use(Icon).use(Form).use(Input).use(Tabs).use(Checkbox).use(Row).use(Col).use(Avatar).use(Divider).use(Card).use(List).use(Tooltip).use(Dropdown).use(Select).use(Radio).use(DatePicker).use(Table);
diff --git a/src/util/request.js b/src/util/request.js
index 2fb29a4..74f0b2f 100644
--- a/src/util/request.js
+++ b/src/util/request.js
@@ -36,25 +36,23 @@
     (response) => {
         // 对响应数据做点什么
         if (response.data.code && response.data.code === 401) {
-            message.error('用户不存在');
-            loginOut()
-                .then(() => {
-                    Session.clear();
-                    window.location.href = '/';
-                });
-            // useLoginApi()
-            //     .signOut()
-            //     .then(() => {
-            //         Session.clear();
-            //         window.location.href = '/';
-            //     });
+            // message.error('用户不存在')
+            setTimeout(()=>{
+                loginOut()
+                    .then(() => {
+                        Session.clear();
+                        window.location.href = '/';
+                    });
+            },2000)
         } else if (response.data.code && response.data.code === 405) {
-            message.error('token失效');
+            message.error('token失效')
+            setTimeout(()=>{
             loginOut()
                 .then(() => {
                     Session.clear();
                     window.location.href = '/';
                 });
+            },2000)
         }
         return Promise.resolve(response);
     },
diff --git a/src/util/validate.js b/src/util/validate.js
index 3338c7f..60c609b 100644
--- a/src/util/validate.js
+++ b/src/util/validate.js
@@ -215,6 +215,12 @@
     else return true;
 }
 
+// 简单校验手机号(十一位数字则通过)
+export function verifySimplePhone(val) {
+    var regex = /^\d{11}$/;  // 正则表达式,\d 匹配数字,{11} 表示匹配11次
+    return regex.test(val);
+}
+
 /**
  * 国内电话号码
  * @param val 当前值字符串
diff --git a/src/views/Admin/Details.vue b/src/views/Admin/Details.vue
deleted file mode 100644
index 76e1adf..0000000
--- a/src/views/Admin/Details.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-<template>
-	<div class="inner">
-		<h2>标题:{{title}}</h2>
-		<p><b>类别:</b>{{category}}</p>
-		<p><b>级别:</b><a-tag :color="level === '黄色' ? 'yellow' :level === '橙色'? 'orange':level === '红色'?'red':'blue'">
-					{{ level }}
-				</a-tag></p>
-		<p><b>发布单位:</b>{{department}}</p>
-		<p><b>短信内容:</b><i>{{smsmessage}}</i></p>
-		<p><b>附件内容:</b><a :href=attachment.url><a-icon type="link" />  {{attachment.title}}</a></p>
-		<p><b>响应状态:</b>
-		<span v-if="receipt=='待叫应'"
-					style='background-color:blue;padding:5px;color:#fff;border-radius: 5px;'>{{receipt}}</span>
-				<span v-else-if="receipt=='已叫应'"
-					style='background-color:limegreen;padding:5px;color:#2a2a2a;border-radius: 5px;'>{{receipt}}</span>
-				<span v-else style='background-color:red;padding:5px;color:#fff;border-radius: 5px;'>{{receipt}}
-				</span></p>
-	</div>
-</template>
-
-<script>
-	export default{
-		data(){
-			return{
-						key: 1,
-						id:1001,
-						time: '2023年5月3日 15:30',
-						department: '自治区预警中心',
-						category: '气象',
-						level: '黄色',
-						title: '标题:全疆(地区)高温橙色预警',
-						attachment: {
-							title:'中央气象台2023年5月3日报告',
-							url:'http://www.baidu.com'
-						},
-						smsmessage: '【自然灾害预警提示】中央气象台2023年5月3日报告,我省南部将持续高温天气,请各部门注意采取相应措施。发布单位:自治区预警中心',
-						receipt: '已叫应'
-			}
-		}
-	}
-</script>
-
-<style scoped> 
-p{
-	font-size:16px;
-}
-i{
-	background-color: aliceblue;
-	padding: 2px 5px;
-}
-.inner{
-	padding:25px 25px;
-}
-</style>
\ No newline at end of file
diff --git a/src/views/Admin/HomeDefault.vue b/src/views/Admin/HomeDefault.vue
index f3a24e2..2d308e2 100644
--- a/src/views/Admin/HomeDefault.vue
+++ b/src/views/Admin/HomeDefault.vue
@@ -6,8 +6,8 @@
         <div class="content-left">
           <img src="./../../assets/user.png" alt="">
           <div class="user">
-            <h2>{{ dateTime}},{{userName}},欢迎使用自治区自然灾害综合风险预警发布及响应联动系统</h2>
-            <p>自治区预警中心干部  工作人员</p>
+            <h2>{{ dateTime}},{{userInfo.realName}},欢迎使用自治区自然灾害综合风险预警发布及响应联动系统</h2>
+            <p>{{userInfo.company}}  {{userInfo.role.roleName}}</p>
           </div>
         </div>
         <div class="content-right">
@@ -29,9 +29,12 @@
       </div>
     </div>
     <div class="home-default-content">
-      <div class="left">
+      <div class="left" v-if="userInfo.role.id == 1 || userInfo.role.id == 3">
         <Projecting />
         <Dynamic style="margin-top: 20px"/>
+      </div>
+      <div class="left" v-if="userInfo.role.id == 2">
+        <Review />
       </div>
       <div class="right">
         <QuickNavigation />
@@ -45,27 +48,30 @@
 <script>
 import Projecting from '@/components/Home/Projecting'
 import Dynamic from '@/components/Home/Dynamic'
+import Review from '@/components/Home/Review'
 import QuickNavigation from '@/components/Home/QuickNavigation'
 import IndexEcharts from '@/components/Home/IndexEcharts'
 import Team from '@/components/Home/Team'
 import Cookies from "js-cookie";
+import {getUserInfo} from "@/util/storage";
 
 export default {
   name: 'home-default',
   components: {
     Projecting,
     Dynamic,
+    Review,
     QuickNavigation,
     IndexEcharts,
     Team
   },
   data() {
     return {
-      userName: ''
+      userInfo: getUserInfo()
     };
   },
   created() {
-    this.userName = JSON.parse(Cookies.get('userInfo')).realName
+
   },
   computed: {
     dateTime () {
diff --git a/src/views/Admin/Report.vue b/src/views/Admin/Report.vue
index d90fbd7..0ef6c22 100644
--- a/src/views/Admin/Report.vue
+++ b/src/views/Admin/Report.vue
@@ -45,9 +45,11 @@
         <template #disasterType="text">
           {{ getRiskName(text) }}
         </template>
-        <template #attachment="text">
-          <span v-if="text==='无'">无</span>
-          <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
+        <template #attachment="attachment">
+          <span v-if="attachment===null|| attachment===[]">无</span>
+          <div v-else>
+            <a-button @click="viewFile(item)" type="link" v-for="(item,index) in attachment" :key="index"><a-icon type="paper-clip"/>{{item.attachmentName}}</a-button>
+          </div>
         </template >
         <template #reviewStatus="reviewStatus">
           <a-tag
@@ -58,7 +60,7 @@
         </template>
         <template #operation="text, record, index">
           <a-button type="primary" v-if="record.reviewStatus == 2" @click="confirmPost(record.id)">确认发布</a-button>
-          <a-button type="link" v-if="record.reviewStatus == 2 || record.reviewStatus == 3" @click="openMod('view',record)">查看信息详情</a-button>
+          <a-button type="link" @click="openMod('view',record)">查看信息详情</a-button>
           <a-button class="del" type="link" @click="delData(record.id)">删除</a-button>
         </template>
       </a-table>
@@ -73,6 +75,9 @@
 import msgEditMod from '@/views/Admin/components/msgEditMod'
 import {delRecipient} from "@/api/user";
 import {deleteMsg, publishMsg} from "@/api/send";
+import Cookies from "js-cookie";
+import axios from "axios";
+import {getUserInfo} from "@/util/storage";
 
 export default {
   name: 'msgReview',
@@ -143,6 +148,7 @@
           scopedSlots: {
             customRender: 'attachment'
           },
+          width: '15%'
         },
         {
           title: '审核情况',
@@ -160,6 +166,11 @@
         },
       ],
       data: []
+    }
+  },
+  mounted() {
+    if(getUserInfo().role.id == 1){
+      this.columns = this.columns.filter(i=>i.dataIndex !== 'operation')
     }
   },
   created() {
@@ -209,14 +220,15 @@
         cancelText: '取消',
         okText: '确认',
         centered: true,
-        async onOk() {
-          let res = await publishMsg(id)
-          if(res.data.code == 100){
-            t.$message.success('信息发布成功');
-            t.getData()
-          }else{
-            t.$message.warning(res.data.msg);
-          }
+        onOk() {
+          publishMsg(id).then(res=>{
+            if(res.data.code == 100){
+              t.$message.success('信息发布成功');
+              t.getData()
+            }else{
+              t.$message.warning(res.data.msg);
+            }
+          })
         },
         onCancel() {
           console.log('Cancel');
@@ -232,14 +244,15 @@
         cancelText: '取消',
         okText: '确认',
         centered: true,
-        async onOk() {
-          let res = await deleteMsg(id)
-          if(res.data.code == 100){
-            t.$message.success('信息删除成功');
-            t.getData()
-          }else{
-            t.$message.warning(res.data.msg);
-          }
+        onOk() {
+          deleteMsg(id).then(res=>{
+            if(res.data.code == 100){
+              t.$message.success('信息删除成功');
+              t.getData()
+            }else{
+              t.$message.warning(res.data.msg);
+            }
+          })
         },
         onCancel() {
           console.log('Cancel');
@@ -247,6 +260,25 @@
       });
     },
 
+    viewFile(item){
+      const t = this
+      const { baseUrl } = require('../../../config/env.' + process.env.NODE_ENV)
+      axios.get(baseUrl + item.attachment,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+        if (res) {
+          const link = document.createElement('a')
+          let blob = new Blob([res.data],{type: res.data.type})
+          link.style.display = "none";
+          link.href = URL.createObjectURL(blob); // 创建URL
+          link.setAttribute("download", item.attachmentName);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+        } else {
+          this.$message.error('获取文件失败')
+        }
+      })
+    },
+
     openMod(type,data){
       const t = this
       getReviewDetail(data.id).then(res=>{
diff --git a/src/views/Admin/callRecord.vue b/src/views/Admin/callRecord.vue
index 7615f63..1b8e387 100644
--- a/src/views/Admin/callRecord.vue
+++ b/src/views/Admin/callRecord.vue
@@ -36,7 +36,7 @@
 
     <!-- 表格实体部分-->
     <div class="table-cont">
-      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
+      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination" :rowKey="record=>record.id">
         <template #index="text,record,index">
           {{ index + 1 }}
         </template>
@@ -53,18 +53,18 @@
           </a-tag>
         </template >
         <template #operation="text, record, index">
-<!--          <a-button type="primary">叫应列表</a-button>-->
-          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
+          <a-button type="link" @click="openDetails(record.warnInfoId)">查看详情</a-button>
         </template>
       </a-table>
-      <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
+      <msg-detail-mod ref="msgDetail"></msg-detail-mod>
     </div>
   </div>
 </template>
 <script>
 import {getHistoryRecord, getMsgRecord, getPublishRecord, getResponseRecord} from "@/api/list";
-import msgEditMod from "@/views/Admin/components/msgEditMod";
-import {getReviewDetailByWorker} from "@/api/review";
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
+import {getUserInfo} from "@/util/storage";
+
 const columns = [{
   title: '序号',
   dataIndex: 'index',
@@ -128,7 +128,7 @@
 ];
 export default {
   name: 'release',
-  components: { msgEditMod },
+  components: { msgDetailMod },
   data() {
     return {
       search:{
@@ -170,6 +170,11 @@
       ]
     }
   },
+  mounted() {
+    if(getUserInfo().role.id == 1){
+      this.columns = this.columns.filter(i=>i.dataIndex !== 'operation')
+    }
+  },
   created() {
     const t = this
     t.getData()
@@ -186,19 +191,10 @@
       }
     },
 
-    openMod(type,data){
+    openDetails(id){
       const t = this
-      getReviewDetailByWorker(data.warnInfoId).then(res=>{
-        if(res.data.code == 100){
-          if(res.data.data){
-            t.$refs.msgEdit.openMod(type,res.data.data)
-          }else{
-            t.$message.error('查询信息详情失败')
-          }
-        }else{
-          this.$message.error(res.data.msg)
-        }
-      })
+      t.$refs.msgDetail.getDetails(id)
+      t.$refs.msgDetail.visible = true
     },
 
     onPageChange(page, pageSize) {
diff --git a/src/views/Admin/components/callListMod.vue b/src/views/Admin/components/callListMod.vue
index 7b4e630..10b3bec 100644
--- a/src/views/Admin/components/callListMod.vue
+++ b/src/views/Admin/components/callListMod.vue
@@ -23,6 +23,11 @@
           {{ unittype==1?'省级':unittype==2?'地(市、州)级':unittype==3?'区县级':unittype==4?'村(乡、镇)级':'管理员' }}
         </a-tag>
       </template >
+      <template #responseStatus="text">
+        <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
+          {{text == 1 ? '待叫应' : text == 2 ?'已叫应':text == 3 ?'超时未叫应' : ''}}
+        </a-tag>
+      </template>
     </a-table>
   </a-modal>
 </template>
@@ -62,18 +67,12 @@
         {
           title: '接收人单位',
           dataIndex: 'receiveUnit',
-          width: '20%',
-          scopedSlots: {
-            customRender: 'receiveUnit'
-          }
+          width: '20%'
         },
         {
           title: '接收人',
           dataIndex: 'recipienterName',
-          width: '20%',
-          scopedSlots: {
-            customRender: 'recipienterName'
-          }
+          width: '20%'
         },
         {
           title: '级别',
@@ -84,11 +83,11 @@
           },
         },
         {
-          title: '叫应时间',
-          dataIndex: 'responseTime',
+          title: '叫应状态',
+          dataIndex: 'responseStatus',
           width: '15%',
           scopedSlots: {
-            customRender: 'responseTime'
+            customRender: 'responseStatus'
           } //设置定制化表格数据
         }
       ]
diff --git a/src/views/Admin/components/msgDetailMod.vue b/src/views/Admin/components/msgDetailMod.vue
new file mode 100644
index 0000000..b55b369
--- /dev/null
+++ b/src/views/Admin/components/msgDetailMod.vue
@@ -0,0 +1,191 @@
+<template>
+  <a-modal
+      title="信息详情"
+      centered
+      :visible="visible"
+      :confirm-loading="confirmLoading"
+      width="50%"
+      cancelText="取消"
+      okText="确认"
+      @ok="handleCancel"
+      @cancel="handleCancel"
+      :afterClose="clearMod"
+  >
+    <div class="detail-mod">
+      <a-row :gutter="24" v-if="details.title"><a-col :span="4">标题</a-col><a-col class="noBorder" :span="14" style="font-size: 24px;font-weight: bolder">{{details.title}}</a-col></a-row>
+      <a-row :gutter="24" v-if="details.emergType"><a-col :span="4">紧急类型</a-col>
+        <a-col :span="14" class="noBorder">
+          <a-tag :color="details.emergType == 1? 'red': 'blue'" style="font-size: 18px;padding: 5px 15px">
+            {{ details.emergType == 1?'紧急':details.emergType == 2?'常规':''}}
+          </a-tag>
+        </a-col>
+      </a-row>
+      <a-row :gutter="24" v-if="details.disasterType"><a-col :span="4">灾种类型</a-col><a-col :span="14">{{ getRiskName(details.disasterType)}}</a-col></a-row>
+      <a-row :gutter="24" v-if="details.warningLevel"><a-col :span="4">预警级别</a-col>
+        <a-col :span="14" class="noBorder">
+          <a-tag :color="details.warningLevel == 1? 'red': details.warningLevel == 2?'orange':details.warningLevel == 3?'yellow':'blue'" style="font-size: 18px;padding: 5px 15px">
+            {{ getLevelName(details.warningLevel)}}
+          </a-tag>
+        </a-col>
+      </a-row>
+      <a-row :gutter="24" v-if="details.publishingUnit"><a-col :span="4">发布单位</a-col><a-col :span="14">{{details.publishingUnit}}</a-col></a-row>
+      <a-row :gutter="24" v-if="details.content"><a-col :span="4">信息内容</a-col><a-col :span="14">{{details.content}}</a-col></a-row>
+      <a-row :gutter="24" v-if="details.acceptingUnitIds && details.acceptingUnitIds.length>0">
+        <a-col :span="4">接收人</a-col>
+        <a-col :span="20">
+          <div v-for="(item,index) in details.acceptingUnitIds" :key="index" class="table">
+            <div style="width: 20%">
+              {{item.recipienterName}}
+            </div>
+            <div style="width: 20%">
+              {{item.recipienterPhone}}
+            </div>
+            <div style="width: 60%">
+              {{item.receiveUnit}}
+            </div>
+          </div>
+        </a-col>
+      </a-row>
+      <a-row :gutter="24" v-if="details.attachments && details.attachments.length > 0"><a-col :span="4">附件内容</a-col>
+        <a-col :span="14" class="noBorder">
+          <a-button @click="viewFile(item)" type="link" v-for="(item,index) in details.attachments" :key="index"><a-icon type="paper-clip"/>{{item.attachementName}}</a-button>
+        </a-col>
+      </a-row>
+    </div>
+  </a-modal>
+</template>
+
+<script>
+import {getReviewDetailByWorker} from "@/api/review";
+import axios from "axios";
+import Cookies from "js-cookie";
+export default {
+  name: 'msgDetailMod',
+  data () {
+    return {
+      visible: false,
+      confirmLoading: false,
+      details: {},
+      riskOptions: [
+        {name: '地震',value: 1},
+        {name: '洪涝',value: 2},
+        {name: '气象',value: 3},
+        {name: '泥石流',value: 4},
+        {name: '水旱',value: 5},
+        {name: '森林草原火灾',value: 6}
+      ],
+      levelOptions: [
+        {name: '红色预警',value: 1},
+        {name: '橙色预警',value: 2},
+        {name: '黄色预警',value: 3},
+        {name: '蓝色预警',value: 4}
+      ]
+    }
+  },
+  created() {
+    const t = this
+  },
+  methods:{
+    clearMod(){
+
+    },
+
+    async getDetails(id){
+      const t = this
+      const res = await getReviewDetailByWorker(id)
+      if(res.data.code == 100){
+        if(res.data.data){
+          t.details = res.data.data
+        }else{
+          t.$message.error('查询信息详情失败')
+        }
+      }else{
+        this.$message.error(res.data.msg)
+      }
+    },
+
+    viewFile(item){
+      const t = this
+      const { baseUrl } = require('../../../../config/env.' + process.env.NODE_ENV)
+      axios.get(baseUrl + item.attachement,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+        if (res) {
+          const link = document.createElement('a')
+          let blob = new Blob([res.data],{type: res.data.type})
+          link.style.display = "none";
+          link.href = URL.createObjectURL(blob); // 创建URL
+          link.setAttribute("download", item.attachementName);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+        } else {
+          this.$message.error('获取文件失败')
+        }
+      })
+    },
+
+    handleOk(e) {
+      const t = this
+      t.confirmLoading = true;
+    },
+    handleCancel(e) {
+      const t = this
+      t.visible = false;
+    },
+    onChange(value) {
+      console.log(value);
+    },
+
+    getRiskName(disasterType){
+      return this.riskOptions.find(i => i.value === disasterType)?.name;
+    },
+    getLevelName(warningLevel){
+      return this.levelOptions.find(i => i.value === warningLevel)?.name;
+    }
+
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.detail-mod{
+  font-size: 16px;
+
+  .ant-row{
+    margin-bottom: 24px;
+    display: flex;
+    align-items: center;
+
+    &:first-of-type{
+      margin-bottom: 12px;
+    }
+
+    .ant-col{
+      &:first-of-type{
+        text-align: right;
+      }
+
+      &:last-of-type{
+        border: 1px solid #d9d9d9;
+        padding: 5px 10px;
+      }
+    }
+
+    .noBorder{
+      border: none !important;
+      padding: 5px 10px;
+    }
+
+    .table{
+      display: flex;
+      align-items: center;
+      border-bottom: 1px solid @blackBorder;
+      &:last-of-type{
+        border-bottom: none;
+      }
+      &>div{
+        padding: 5px 10px;
+      }
+    }
+  }
+}
+</style>
diff --git a/src/views/Admin/components/msgEditMod.vue b/src/views/Admin/components/msgEditMod.vue
index 4a69812..fd3139a 100644
--- a/src/views/Admin/components/msgEditMod.vue
+++ b/src/views/Admin/components/msgEditMod.vue
@@ -59,7 +59,23 @@
         </a-form-model-item>
         <a-row>
           <a-col :span="12">
-            <a-button>上传附件</a-button>
+            <a-upload
+                :disabled="disable"
+                :action="uploadUrl"
+                :file-list="fileList"
+                @change="fileChange"
+                :headers="header"
+                accept=".doc, .docx, .word, .pdf, .zip, .xlsx, .rar"
+                :data="{module: 'naturalDisasterPath'}"
+                @download="downloadFile"
+                :remove="(file)=>{removeFile(file)}"
+                :showUploadList="{
+                  showRemoveIcon: true,
+                  showDownloadIcon: true
+                }"
+            >
+              <a-button> <a-icon type="upload" />上传附件</a-button>
+            </a-upload>
           </a-col>
           <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
             <b style="margin-bottom: 24px">超时设置:</b>
@@ -102,7 +118,7 @@
           </a-col>
           <a-col :span="12">
             <b style="margin-bottom: 6px">平级接收人选择:</b>
-            <a-form-model-item prop="recipient">
+            <a-form-model-item>
               <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle" :disabled="disable">
                 <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                   {{ item.recipientName }}
@@ -126,7 +142,7 @@
             <b style="margin-bottom: 6px">选择审批领导:</b>
             <a-form-model-item prop="reviewId">
               <a-select show-search v-model="form.reviewId" placeholder="请选择审批领导">
-                <a-select-option v-for="(item,index) in leaders" :value="item.id" :key="index">{{item.name}}</a-select-option>
+                <a-select-option v-for="(item,index) in leaders" :value="item.id" :key="index">{{item.realName}}</a-select-option>
               </a-select>
             </a-form-model-item>
           </a-col>
@@ -142,9 +158,8 @@
         <h2>短信预览</h2>
         <div class="mobile">
           <div class="mesg">
-            <P>【{{form.title}}】{{form.content}}。发布单位:{{form.publishingUnit}}</P>
+            <P>【自然灾害风险预警提示】{{form.content}}<br>发布单位:{{form.publishingUnit}}</P>
           </div>
-
         </div>
       </div>
     </a-form-model>
@@ -152,11 +167,13 @@
 </template>
 
 <script>
-import {getAreaWithUserIfo, getPeerRecipient, getLeaders} from '@/api/user'
+import {getAreaWithUserIfo, getPeerRecipient, getLeaders, delRecipient} from '@/api/user'
 import {getUserInfo} from "@/util/storage";
 import Cookies from "js-cookie";
 import {massSend, msgSend} from "@/api/send";
 import {postReview} from "@/api/review";
+import axios from "axios";
+import {deleteFile} from "@/api/list";
 export default {
   name: "msgEditMod",
   data() {
@@ -217,16 +234,26 @@
         timeout: [{ required: true, message: '请输入超时时间', trigger: 'blur'}],
         receiver: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
         reviewId: [{ required: true, message: '请选择审批人', trigger: 'change'}],
-        recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
+        // recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
         // acceptingUnitIds: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
         // peerRecipientIds: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
-      }
+      },
+      uploadUrl: '',
+      fileList: [],
+      header: {
+        uid: null,
+        tk: Cookies.get('resTk')
+      },
+      delList: []
     };
   },
   components: {},
   created() {
     const t = this
+    const { baseUrl } = require('../../../../config/env.' + process.env.NODE_ENV)
+    t.uploadUrl= baseUrl + '/attachment/upload/detail'
     t.userInfo = getUserInfo()
+    t.header.uid = t.userInfo.uid
     t.form.districtId = t.userInfo.districtId
     t.form.publishingUnit = t.userInfo.company
     t.getSameLevel()
@@ -236,31 +263,62 @@
   methods: {
     openMod(type,data){
       const t = this
-      for(let i in data){
-        if(t.isValidKey(i,t.form)){
-          t.form[i] = data[i]
-        }
-      }
-      const arr = data.acceptingUnitIds.map((i)=>{return {
-        value: i.districtId
-      }})
-      t.form.receiver = JSON.parse(JSON.stringify(arr)).filter(
-          (item, index) => JSON.parse(JSON.stringify(arr)).findIndex(obj => obj.value === item.value) === index
-      )
-      t.form.recipient = data.peerRecipientIds.map(i=>i.recipienterId)
       t.form.acceptingUnitIds = []
       t.form.peerRecipientIds = []
-      if(type == 'review') {
-        t.title = '信息审核'
-        t.disable = false
-      }else if(type == 'view'){
-        t.title = '信息详情'
-        t.disable = true
+      if(type == 'review' || type == 'view') {
+        for(let i in data){
+          if(t.isValidKey(i,t.form)){
+            t.form[i] = data[i]
+          }
+        }
+        if(data.attachments && data.attachments.length>0){
+          t.fileList = data.attachments.map((i)=>{
+            return {
+              uid: i.id,
+              name: i.attachementName,
+              status: 'done',
+              url: i.attachement
+            }
+          })
+        }else{
+          t.fileList = []
+        }
+        const arr = data.acceptingUnitIds.map((i)=>{return {
+          value: i.districtId
+        }})
+        t.form.receiver = JSON.parse(JSON.stringify(arr)).filter(
+            (item, index) => JSON.parse(JSON.stringify(arr)).findIndex(obj => obj.value === item.value) === index
+        )
+        t.form.recipient = data.peerRecipientIds.map(i=>i.recipienterId)
+        if(type == 'review'){
+          t.title = '信息审核'
+          t.disable = false
+        }else{
+          t.title = '信息详情'
+          t.disable = true
+        }
       }else{
+        t.form.title = data.title
+        t.form.emergType = data.emergType
+        t.form.disasterType = data.disasterType
+        t.form.warningLevel = data.warningLevel
+        t.form.content = data.content
+        t.form.timeout = data.timeout
+        if(data.attachments && data.attachments.length>0){
+          t.fileList = data.attachments.map((i)=>{
+            return {
+              uid: i.id,
+              name: i.attachementName,
+              status: 'done',
+              url: i.attachement
+            }
+          })
+        }else{
+          t.fileList = []
+        }
         t.title = '信息转发'
         t.getLeaders()
         t.disable = false
-
       }
       t.visible = true
     },
@@ -276,7 +334,7 @@
         if(res.data.data){
           t.filteredOptions = res.data.data
         }else{
-          this.$message.warning('暂无数据');
+          console.log('暂无数据')
         }
       }else{
         this.$message.warning(res.data.msg);
@@ -289,13 +347,13 @@
       let res = await getAreaWithUserIfo()
       if(res.data.code == 100){
         if(res.data.data){
-          const treeD = []
+          // const treeD = []
           t.userTitTree(res.data.data)
-          treeD.push(t.findNodeById(res.data.data,t.userInfo.districtId))
-          t.areaUsers = treeD
+          // treeD.push(t.findNodeById(res.data.data,t.userInfo.districtId))
+          t.areaUsers = t.findNodeById(res.data.data,t.userInfo.districtId).children
           t.unittype = this.findNodeById(this.areaUsers,t.userInfo.districtId)?.type
         }else{
-          this.$message.warning('暂无数据');
+          console.log('暂无数据')
         }
       }else{
         this.$message.warning(res.data.msg);
@@ -310,7 +368,7 @@
         if(res.data.data){
           t.leaders = res.data.data
         }else{
-          this.$message.warning('暂无数据');
+          console.log('暂无数据')
         }
       }else{
         this.$message.warning(res.data.msg);
@@ -334,12 +392,54 @@
       }
     },
 
+    fileChange(info) {
+      let fileList = [...info.fileList];
+      // 2. read from response and show file link
+      fileList = fileList.map(file => {
+        if(file.status == 'done'){
+          if (file.response) {
+            const res = file.response
+            if(res.code == 100){
+              this.$message.success('文件上传成功')
+            }else{
+              this.$message.error('文件上传失败')
+            }
+            // Component will show file.url as link
+            file.url = res.data.fileUrl
+          }
+        }
+        return file;
+      });
+      this.fileList = fileList;
+    },
+
+    removeFile(file){
+      this.delList.push(file.uid)
+    },
+
+    async deleteFile(){
+      const t = this
+      for(let i of t.delList){
+        const res = await deleteFile(i)
+        if(res.data.code == 100){
+          console.log('文件删除成功')
+        }else{
+          t.$message.error(res.data.msg)
+        }
+      }
+    },
+
     confirmSend(status){
       this.$refs.ruleForm.validate(valid => {
         if (valid) {
           this.form.acceptingUnitIds = []
           this.form.peerRecipientIds = []
+          this.form.attachments = []
           const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
+          if(aList.includes(null)){
+            this.$message.error('选择接收单位时存在无用户的单位')
+            return
+          }
           const newAList = [].concat(...aList)
           for(let i of newAList){
             const {realName,...data} = i
@@ -347,11 +447,24 @@
             const obj = { recipienterId, recipienterName, recipienterPhone, receiveUnit,...rest}
             this.form.acceptingUnitIds.push(obj)
           }
-          const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
-          for(let i of bList){
-            const {id:recipienterId,recipientName: recipienterName,phone: recipienterPhone, company: receiveUnit,...rest} = i
-            const obj = {recipienterId, recipienterName,recipienterPhone,receiveUnit,unittype:this.unittype,...rest}
-            this.form.peerRecipientIds.push(obj)
+          if(this.form.recipient.length>0){
+            const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
+            for(let i of bList){
+              const {id:recipienterId,recipientName: recipienterName,phone: recipienterPhone, company: receiveUnit,...rest} = i
+              const obj = {recipienterId, recipienterName,recipienterPhone,receiveUnit,unittype:this.unittype,...rest}
+              this.form.peerRecipientIds.push(obj)
+            }
+          }
+          if(this.fileList.length == 0){
+            this.form.attachments = []
+          }else{
+            this.form.attachments = this.fileList.map((i)=>{
+              if(i.response){
+                return i.response.data.id
+              }else{
+                return i.uid
+              }
+            })
           }
           if(status == 2 || status == 3){
             const {receiver,recipient,reviewId,...data} = this.form
@@ -359,31 +472,56 @@
             postReview(data).then( res =>{
               if(res.data.code == 100){
                 this.$message.success('审核已提交')
-                this.$emit('refresh')
-                this.visible = false
+                this.deleteFile()
               }else{
                 this.$message.error(res.data.msg)
               }
+              this.visible = false
+              this.$emit('refresh')
               this.$refs.ruleForm.clearValidate()
               this.$refs.ruleForm.resetFields()
+              this.delList = []
+              this.fileList = []
             })
           }else{
             const {receiver,recipient,id,...data} = this.form
             msgSend(data).then( res =>{
               if(res.data.code == 100){
                 this.$message.success('信息已提交审核')
+                this.deleteFile()
               }else{
                 this.$message.error(res.data.msg)
               }
-              this.$emit('refresh')
               this.visible = false
+              this.$emit('refresh')
               this.$refs.ruleForm.clearValidate()
               this.$refs.ruleForm.resetFields()
+              this.delList = []
+              this.fileList = []
             })
           }
         }else{
           console.log('error submit!!');
           return false;
+        }
+      })
+    },
+
+    downloadFile(file){
+      const t = this
+      const { baseUrl } = require('../../../../config/env.' + process.env.NODE_ENV)
+      axios.get(baseUrl + file.url,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+        if (res) {
+          const link = document.createElement('a')
+          let blob = new Blob([res.data],{type: res.data.type})
+          link.style.display = "none";
+          link.href = URL.createObjectURL(blob); // 创建URL
+          link.setAttribute("download", file.name);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+        } else {
+          this.$message.error('获取文件失败')
         }
       })
     },
@@ -432,6 +570,7 @@
     userTitTree(treeData) {
       for(const node of treeData){
         if(node.users){
+          node.users = node.users.filter(i=>i.roleId == 3)
           node.users = node.users.map((i)=>{
             return{
               ...i,
@@ -439,7 +578,7 @@
               districtId: node.id
             }
           })
-          node.name = node.name + '('+node.users.map(i=>i.name +' '+ i.phone).join(',')+')'
+          node.name = node.name + '('+node.users.map(i=>i.realName +' '+ i.phone).join(',')+')'
         }
         if(node.children){
           this.userTitTree(node.children)
diff --git a/src/views/Admin/components/sameLevelMod.vue b/src/views/Admin/components/sameLevelMod.vue
index a86fd14..210a5dd 100644
--- a/src/views/Admin/components/sameLevelMod.vue
+++ b/src/views/Admin/components/sameLevelMod.vue
@@ -132,7 +132,6 @@
         if (valid) {
           if(this.title == '新增用户'){
             const { id,...data } = this.form
-            console.log(data,'data')
             addRecipient(data).then((res)=>{
               if(res.data.code == 100){
                 this.$message.success('新增平级接收人成功')
diff --git a/src/views/Admin/components/userMod.vue b/src/views/Admin/components/userMod.vue
index 499ef98..4428956 100644
--- a/src/views/Admin/components/userMod.vue
+++ b/src/views/Admin/components/userMod.vue
@@ -81,7 +81,7 @@
 
 <script>
 import {addUser, updateUser} from '@/api/user'
-import {verifyPasswordPowerful, verifyPhone} from "@/util/validate";
+import {verifyPasswordPowerful, verifyPhone, verifySimplePhone} from "@/util/validate";
 export default {
   name: 'userMod',
   props: ['unitType'],
@@ -101,7 +101,7 @@
       if(value === ''){
         callback(new Error('请输入手机号'))
       }else{
-        if(!verifyPhone(value)){
+        if(!verifySimplePhone(value)){
           callback(new Error('手机号格式有误'))
         }else{
           callback()
diff --git a/src/views/Admin/history.vue b/src/views/Admin/history.vue
index 1e91970..d16edc6 100644
--- a/src/views/Admin/history.vue
+++ b/src/views/Admin/history.vue
@@ -54,8 +54,11 @@
             {{ getLevelName(text) }}
           </a-tag>
         </template>
-        <template #attachment="text">
-          <a><b><a-icon type="paper-clip" /></b></a>
+        <template #attachment="attachment">
+          <span v-if="attachment===null|| attachment.length == 0">无</span>
+          <div v-else>
+            <a-button @click="viewFile(item)" type="link" v-for="(item,index) in attachment" :key="index"><a-icon type="paper-clip"/>{{item.attachmentName}}</a-button>
+          </div>
         </template >
         <template #responseSituation="text">
           <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
@@ -64,19 +67,22 @@
         </template>
         <template #operation="text, record, index">
           <a-button type="primary" @click="openList(record.id)">叫应列表</a-button>
-          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
+          <a-button type="link" @click="openDetails(record.id)">查看详情</a-button>
         </template>
       </a-table>
-      <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
+      <msg-detail-mod ref="msgDetail"></msg-detail-mod>
       <call-list-mod ref="callList" @refresh="getData"></call-list-mod>
     </div>
   </div>
 </template>
 <script>
 import {getHistoryRecord, getMsgRecord, getPublishRecord} from "@/api/list";
-import msgEditMod from "@/views/Admin/components/msgEditMod";
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
 import callListMod from "@/views/Admin/components/callListMod";
 import {getReviewDetailByWorker} from "@/api/review";
+import axios from "axios";
+import Cookies from "js-cookie";
+import {getUserInfo} from "@/util/storage";
 const columns = [{
   title: '序号',
   dataIndex: 'index',
@@ -122,7 +128,7 @@
   {
     title: '附件',
     dataIndex: 'attachment',
-    width: '6%',
+    width: '15%',
     scopedSlots: {
       customRender: 'attachment'
     },
@@ -145,7 +151,7 @@
 ];
 export default {
   name: 'release',
-  components: { msgEditMod, callListMod },
+  components: { msgDetailMod, callListMod },
   data() {
     return {
       search:{
@@ -187,6 +193,11 @@
       ]
     }
   },
+  mounted() {
+    if(getUserInfo().role.id == 1){
+      this.columns = this.columns.filter(i=>i.dataIndex !== 'operation')
+    }
+  },
   created() {
     const t = this
     t.getData()
@@ -208,19 +219,10 @@
       t.$refs.callList.openMod(id)
     },
 
-    openMod(type,data){
+    openDetails(id){
       const t = this
-      getReviewDetailByWorker(data.id).then(res=>{
-        if(res.data.code == 100){
-          if(res.data.data){
-            t.$refs.msgEdit.openMod(type,res.data.data)
-          }else{
-            t.$message.error('查询信息详情失败')
-          }
-        }else{
-          this.$message.error(res.data.msg)
-        }
-      })
+      t.$refs.msgDetail.getDetails(id)
+      t.$refs.msgDetail.visible = true
     },
 
     onPageChange(page, pageSize) {
@@ -238,6 +240,25 @@
       }
     },
 
+    viewFile(item){
+      const t = this
+      const { baseUrl } = require('../../../config/env.' + process.env.NODE_ENV)
+      axios.get(baseUrl + item.attachment,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+        if (res) {
+          const link = document.createElement('a')
+          let blob = new Blob([res.data],{type: res.data.type})
+          link.style.display = "none";
+          link.href = URL.createObjectURL(blob); // 创建URL
+          link.setAttribute("download", item.attachmentName);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+        } else {
+          this.$message.error('获取文件失败')
+        }
+      })
+    },
+
     timeOk(value) {
       console.log('onOk: ', value);
     },
diff --git a/src/views/Admin/list.vue b/src/views/Admin/list.vue
index 8a45500..f88ec4a 100644
--- a/src/views/Admin/list.vue
+++ b/src/views/Admin/list.vue
@@ -38,7 +38,7 @@
     </a-row>
 		<!-- 表格实体部分-->
     <div class="table-cont">
-      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
+      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination" :rowKey="record=>record.id">
         <template #index="text,record,index">
           {{index + 1}}
         </template>
@@ -53,8 +53,11 @@
             {{ getLevelName(text) }}
           </a-tag>
         </template>
-        <template #attachment="text">
-          <a><b><a-icon type="paper-clip" /> {{text}}</b></a>
+        <template #attachment="attachment">
+          <span v-if="attachment===null|| attachment===[]">无</span>
+          <div v-else>
+            <a-button @click="viewFile(item)" type="link" v-for="(item,index) in attachment" :key="index"><a-icon type="paper-clip"/>{{item.attachmentName}}</a-button>
+          </div>
         </template >
         <template #responseStatus="text">
           <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
@@ -75,11 +78,12 @@
         <template #operation="text, record, index">
           <a-button type="primary" v-if="record.responseStatus == 1" style="margin-right: 12px" @click="confirmResponce(record.id)">确认已收到</a-button>
           <a-button type="primary" @click="openMod('repost',record)">转发</a-button>
-          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
+          <a-button type="link" @click="openDetails(record,record.warnInfoId)">查看详情</a-button>
         </template>
       </a-table>
     </div>
     <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
+    <msg-detail-mod ref="msgDetail"></msg-detail-mod>
 		<!-- 对话框 -->
 <!--		<a-modal title="回执" -->
 <!--		okText="确认已安排部署"-->
@@ -94,14 +98,19 @@
 <script>
 import {getMsgRecord, readById, responseMsg} from "@/api/list";
 import msgEditMod from "@/views/Admin/components/msgEditMod";
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
 import {publishMsg} from "@/api/send";
 import {getReviewDetail, getReviewDetailByWorker} from "@/api/review";
+import axios from "axios";
+import Cookies from "js-cookie";
+import {getUserInfo} from "@/util/storage";
 
   export default {
     name: 'list',
-    components: { msgEditMod },
+    components: { msgEditMod, msgDetailMod },
 		data() {
 			return {
+        userInfo: getUserInfo(),
         search:{
           pageIndex: 1,
           pageSize: 10,
@@ -116,7 +125,6 @@
           {
             title: '序号',
             dataIndex: 'index',
-            width: '5%',
             scopedSlots: {
               customRender: 'index'
             },
@@ -124,7 +132,6 @@
           {
             title: '发布时间',
             dataIndex: 'publishingTime',
-            width: '15%',
             scopedSlots: {
               customRender: 'publishingTime'
             }, //设置定制化表格数据
@@ -132,12 +139,10 @@
           {
             title: '发布单位',
             dataIndex: 'publishingUnit',
-            width: '12%',
           },
           {
             title: '灾种',
             dataIndex: 'disasterType',
-            width: '8%',
             scopedSlots: {
               customRender: 'disasterType'
             }
@@ -148,17 +153,15 @@
             scopedSlots: {
               customRender: 'warningLevel'
             }, //设置定制化表格数据
-            width: '8%',
           },
           {
             title: '信息标题',
             dataIndex: 'title',
-            width: '16%',
           },
           {
             title: '附件',
             dataIndex: 'attachment',
-            width: '6%',
+            width: '15%',
             scopedSlots: {
               customRender: 'attachment'
             },
@@ -166,7 +169,6 @@
           {
             title: '叫应状态',
             dataIndex: 'responseStatus',
-            width: '10%',
             scopedSlots: {
               customRender: 'responseStatus'
             }, //设置定制化表格数据
@@ -174,6 +176,7 @@
           {
             title: '操作',
             dataIndex: 'operation',
+            width: '15%',
             scopedSlots: {
               customRender: 'operation'
             },
@@ -211,8 +214,16 @@
         ]
 			};
 		},
+    mounted() {
+      if(this.userInfo.role.id == 1){
+        this.columns = this.columns.filter(i=>i.dataIndex !== 'operation')
+      }
+    },
     created() {
       const t = this
+      if(t.$route.query){
+        t.search.searchParams.responseStatus = t.$route.query.type
+      }
       t.getData()
     },
     methods: {
@@ -242,6 +253,25 @@
         }
       },
 
+      viewFile(item){
+        const t = this
+        const { baseUrl } = require('../../../config/env.' + process.env.NODE_ENV)
+        axios.get(baseUrl + item.attachment,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+          if (res) {
+            const link = document.createElement('a')
+            let blob = new Blob([res.data],{type: res.data.type})
+            link.style.display = "none";
+            link.href = URL.createObjectURL(blob); // 创建URL
+            link.setAttribute("download", item.attachmentName);
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link);
+          } else {
+            this.$message.error('获取文件失败')
+          }
+        })
+      },
+
       resetSearch(){
         const t = this
         t.search = {
@@ -265,14 +295,15 @@
           cancelText: '取消',
           okText: '确认',
           centered: true,
-          async onOk() {
-            let res = await responseMsg(id)
-            if(res.data.code == 100){
-              t.$message.success('信息叫应成功');
-              t.getData()
-            }else{
-              t.$message.warning(res.data.msg);
-            }
+          onOk() {
+            responseMsg(id).then(res=>{
+              if(res.data.code == 100){
+                t.$message.success('信息叫应成功');
+                t.getData()
+              }else{
+                t.$message.warning(res.data.msg);
+              }
+            })
           },
           onCancel() {
             console.log('Cancel');
@@ -285,7 +316,6 @@
         getReviewDetailByWorker(data.warnInfoId).then(res=>{
           if(res.data.code == 100){
             if(res.data.data){
-              t.read(data.id)
               t.$refs.msgEdit.openMod(type,res.data.data)
             }else{
               t.$message.error('查询信息详情失败')
@@ -296,11 +326,19 @@
         })
       },
 
+      openDetails(data,id){
+        const t = this
+        t.read(data.id)
+        t.$refs.msgDetail.getDetails(id)
+        t.$refs.msgDetail.visible = true
+      },
+
       async read(id){
         const t = this
         const res = await readById(id)
         if(res.data.code == 100){
           console.log('已读')
+          t.getData()
         }else{
           t.$message.error('设置已读出错')
         }
diff --git a/src/views/Admin/massSend.vue b/src/views/Admin/massSend.vue
index 3e2d999..2bc3f52 100644
--- a/src/views/Admin/massSend.vue
+++ b/src/views/Admin/massSend.vue
@@ -1,5 +1,13 @@
 <template>
 	<div class="inner">
+    <a-alert
+        message="管理员身份无法进行短信群发操作"
+        banner
+        closable
+        v-if="userInfo.role.id === 1"
+        type="error"
+        style="margin-bottom: 12px"
+    />
 		<h2>预警信息发布</h2>
     <a-form-model ref="ruleForm" :model="form" :rules="rules" :wrapper-col="wrapperCol">
 		<div class="left">
@@ -96,7 +104,7 @@
           <div>
             <b>平级接收人选择:</b>
           </div>
-          <a-form-model-item prop="recipient">
+          <a-form-model-item>
             <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle">
               <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                 {{ item.recipientName }}
@@ -122,7 +130,7 @@
 <!--				</a-select>-->
 <!--      </div>-->
       <div style="display: flex;justify-content: right">
-        <a-button type="primary" style="width: 250px;" @click="confirmSend()">
+        <a-button type="primary" style="width: 250px;" @click="confirmSend()" :disabled="userInfo.role.id==1?true:false">
           确认发送
         </a-button>
       </div>
@@ -149,7 +157,7 @@
 		name: "massSend",
 		data() {
 			return {
-        userInfo: {},
+        userInfo: getUserInfo(),
 				department: '自治区自然灾害综合监测预警中心',
         filteredOptions:[],
         wrapperCol: { span: 24 },
@@ -193,7 +201,7 @@
           warningLevel: [{ required: true, message: '请选择预警级别', trigger: 'change'}],
           content: [{ required: true, message: '请输入信息内容', trigger: 'blur'}],
           receiver: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
-          recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
+          // recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
           // verticalRecipient: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
           // horizontalRecipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
         }
@@ -202,7 +210,6 @@
 		components: {},
     created() {
       const t = this
-      t.userInfo = getUserInfo()
       t.form.publishingUnit = t.userInfo.company
       t.getSameLevel()
       t.getAreaUsers()
@@ -218,7 +225,7 @@
           if(res.data.data){
             t.filteredOptions = res.data.data
           }else{
-            this.$message.warning('暂无数据');
+            console.log('暂无数据')
           }
         }else{
           this.$message.warning(res.data.msg);
@@ -235,8 +242,9 @@
             t.userTitTree(res.data.data)
             treeD.push(t.findNodeById(res.data.data,t.userInfo.districtId))
             t.areaUsers = treeD
+            console.log(t.areaUsers,t.unittype,'696969')
           }else{
-            this.$message.warning('暂无数据');
+            console.log('暂无数据')
           }
         }else{
           this.$message.warning(res.data.msg);
@@ -271,18 +279,25 @@
             this.form.verticalRecipient = []
             this.form.horizontalRecipient = []
             const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
+            if(aList.includes(null)){
+              this.$message.error('选择接收单位时存在无用户的单位')
+              return
+            }
             const newAList = [].concat(...aList)
             for(let i of newAList){
-              const {realName,...data} = i
+              const {realName,id,...data} = i
               const {company: recipientUnit,...rest} = data
               const obj = {recipientUnit,recipientType:1,...rest}
               this.form.verticalRecipient.push(obj)
             }
-            const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
-            for(let i of bList){
-              const {recipientName: name, company: recipientUnit,...rest} = i
-              const obj = {name,recipientUnit,recipientType:2,...rest}
-              this.form.horizontalRecipient.push(obj)
+            if(this.form.recipient.length>0){
+              const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
+              for(let i of bList){
+                const {recipientName: name, company: recipientUnit,...rest} = i
+                const obj = {name,recipientUnit,recipientType:2,...rest}
+                const {id,...noId} = obj
+                this.form.horizontalRecipient.push(noId)
+              }
             }
             const {receiver,recipient,...data} = this.form
             massSend(data).then( res =>{
@@ -372,7 +387,7 @@
       userTitTree(treeData) {
         for(const node of treeData){
           if(node.users){
-            node.name = node.name + '('+node.users.map(i=>i.name +' '+ i.phone).join(',')+')'
+            node.name = node.name + '('+node.users.map(i=>i.realName +' '+ i.phone).join(',')+')'
           }
           if(node.children){
             this.userTitTree(node.children)
diff --git a/src/views/Admin/msgRecord.vue b/src/views/Admin/msgRecord.vue
index 3cf0327..87c3624 100644
--- a/src/views/Admin/msgRecord.vue
+++ b/src/views/Admin/msgRecord.vue
@@ -42,54 +42,31 @@
         </a-card>
       </div>
     </div>
-    <a-pagination v-model="search.pageIndex" :total="total" :show-total="total => `共 ${total} 条数据`" show-less-items/>
-    <a-modal v-model="visible" width="40%" title="短信详情" @ok="handleOk" cancelText="取消" okText="确认" centered>
-      <div class="detail-mod">
-        <a-row :gutter="24"><a-col :span="4" style="text-align: right">{{ details.emergType == 1?'紧急':details.emergType == 2?'常规':'' }}</a-col></a-row>
-        <a-row :gutter="24"><a-col :span="4" style="text-align: right">发送时间</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{details.gmtCreate}}</a-col></a-row>
-        <a-row :gutter="24"><a-col :span="4" style="text-align: right">灾种类型</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{ getRiskName(details.disasterType)}}</a-col></a-row>
-        <a-row :gutter="24"><a-col :span="4" style="text-align: right">预警级别</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{ getLevelName(details.warningLevel)}}</a-col></a-row>
-        <a-row :gutter="24"><a-col :span="4" style="text-align: right">信息内容</a-col><a-col :span="14" style="border: 1px solid #d9d9d9;padding: 5px 10px !important;">{{details.content}}</a-col></a-row>
-        <a-row :gutter="24">
-          <a-col :span="4" style="text-align: right">接收人</a-col>
-          <a-col :span="20" style="border: 1px solid #d9d9d9;padding: 0 !important;">
-            <div v-for="(item,index) in details.recipients" :key="index" class="table">
-            <div style="width: 20%">
-              {{item.name}}
-            </div>
-            <div style="width: 20%">
-              {{item.phone}}
-            </div>
-            <div style="width: 60%">
-              {{item.recipientUnit}}
-            </div>
-            </div>
-          </a-col>
-        </a-row>
-      </div>
-    </a-modal>
+    <a-pagination class="pageItem" v-model="search.pageIndex" :total="total" :defaultPageSize="search.pageSize" @change="onPageChange" :show-total="total => `共 ${total} 条数据`"/>
+    <msg-detail-mod ref="msgDetail"></msg-detail-mod>
   </div>
 </template>
 
 <script>
 import {getUser} from '@/api/user'
 import {getMassRecord} from "@/api/send";
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
 
 export default {
   name: 'msgRecord',
-  components: {},
+  components: {msgDetailMod},
   data () {
     return {
       search:{
         pageIndex: 1,
-        pageSize: 10,
+        pageSize: 5,
         searchParams:{
           startTime: '',
           endTime: ''
         }
       },
       timeRange: [],
-      total: 0,
+      total: null,
       msg: [],
       visible: false,
       details: {},
@@ -119,7 +96,7 @@
       const res = await getMassRecord(this.search)
       if(res.data.code == 200){
         t.msg = res.data.data
-        t.pagination.total = res.data.total
+        t.total = res.data.total
       }else{
         this.$message.error(res.data.msg)
       }
@@ -139,6 +116,12 @@
       t.getData()
     },
 
+    onPageChange(page, pageSize) {
+      const t= this
+      t.search.pageIndex = page
+      t.getData()
+    },
+
     timeChange(value, dateString) {
       const t = this
       if(dateString){
@@ -151,8 +134,8 @@
     },
     viewDetails(item){
       const t = this
-      t.details = item
-      t.visible = true
+      t.$refs.msgDetail.details = item
+      t.$refs.msgDetail.visible = true
     },
 
     getRiskName(disasterType){
@@ -203,29 +186,6 @@
           white-space: nowrap;
           overflow: hidden;
           text-overflow: ellipsis;
-        }
-      }
-    }
-  }
-}
-.detail-mod{
-  font-size: 16px;
-
-  .ant-row{
-    margin-bottom: 24px;
-
-    .table{
-      display: flex;
-      align-items: center;
-      border-bottom: 1px solid @blackBorder;
-      &:last-of-type{
-        border-bottom: none;
-      }
-      &>div{
-        border-right: 1px solid @blackBorder;
-        padding: 5px 10px;
-        &:last-of-type{
-          border-right: none;
         }
       }
     }
diff --git a/src/views/Admin/msgReview.vue b/src/views/Admin/msgReview.vue
index 011ba5d..f12dfe5 100644
--- a/src/views/Admin/msgReview.vue
+++ b/src/views/Admin/msgReview.vue
@@ -38,16 +38,18 @@
     </a-row>
 
     <div class="table-cont">
-      <a-table :columns="columns" :data-source="data" bordered :rowKey="record=>record.id">
+      <a-table :columns="columns" :data-source="data" bordered :rowKey="record=>record.id" :pagination="pagination">
         <template #index="text,record,index">
           {{ index+1 }}
         </template>
         <template #disasterType="text">
           {{ getRiskName(text) }}
         </template>
-        <template #attachment="text">
-          <span v-if="text==='无'">无</span>
-          <a v-else><b><a-icon type="paper-clip" /> {{text}}</b></a>
+        <template #attachment="attachment">
+          <span v-if="attachment===null|| attachment===[]">无</span>
+          <div v-else>
+            <a-button @click="viewFile(item)" type="link" v-for="(item,index) in attachment" :key="index"><a-icon type="paper-clip"/>{{item.attachmentName}}</a-button>
+          </div>
         </template >
         <template #reviewStatus="reviewStatus">
           <a-tag
@@ -57,12 +59,13 @@
           </a-tag>
         </template>
         <template #operation="text, record, index">
-          <a-button type="link" v-if="record.reviewStatus == 2 || record.reviewStatus == 3" @click="openMod('view',record)">查看信息详情</a-button>
+          <a-button type="link" v-if="record.reviewStatus == 2 || record.reviewStatus == 3" @click="openDetails(record.id)">查看信息详情</a-button>
           <a-button type="primary" v-if="record.reviewStatus == 1" @click="openMod('review',record)">查看并审核</a-button>
         </template>
       </a-table>
     </div>
     <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
+    <msg-detail-mod ref="msgDetail"></msg-detail-mod>
   </div>
 </template>
 
@@ -70,12 +73,17 @@
 
 import {getReviewDetail, getReviewRecord} from "@/api/review";
 import msgEditMod from '@/views/Admin/components/msgEditMod'
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
+import axios from "axios";
+import Cookies from "js-cookie";
+import {getUserInfo} from "@/util/storage";
 
 export default {
   name: 'msgReview',
-  components: { msgEditMod },
+  components: { msgEditMod, msgDetailMod },
   data () {
     return {
+      userInfo: getUserInfo(),
       search:{
         pageIndex: 1,
         pageSize: 10,
@@ -94,6 +102,14 @@
         {name: '水旱',value: 5},
         {name: '森林草原火灾',value: 6}
       ],
+      pagination: {
+        current: 1,
+        defaultCurrent: 1,
+        defaultPageSize: 10,
+        total: 0,
+        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
+        showTotal: total => `共 ${total} 条`
+      },
       columns: [
         {
           title: '序号',
@@ -132,6 +148,7 @@
           scopedSlots: {
             customRender: 'attachment'
           },
+          width: '15%'
         },
         {
           title: '审核情况',
@@ -151,8 +168,16 @@
       data: []
     }
   },
+  mounted() {
+    if(getUserInfo().role.id == 1){
+      this.columns = this.columns.filter(i=>i.dataIndex !== 'operation')
+    }
+  },
   created() {
     const t = this
+    if(t.$route.query){
+      t.search.searchParams.reviewStatus = t.$route.query.type
+    }
     t.getData()
   },
   methods:{
@@ -190,6 +215,32 @@
       }
     },
 
+    onPageChange(page, pageSize) {
+      const t= this
+      t.pagination.current = page
+      t.search.pageIndex = page
+      t.getData()
+    },
+
+    viewFile(item){
+      const t = this
+      const { baseUrl } = require('../../../config/env.' + process.env.NODE_ENV)
+      axios.get(baseUrl + item.attachment,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+        if (res) {
+          const link = document.createElement('a')
+          let blob = new Blob([res.data],{type: res.data.type})
+          link.style.display = "none";
+          link.href = URL.createObjectURL(blob); // 创建URL
+          link.setAttribute("download", item.attachmentName);
+          document.body.appendChild(link);
+          link.click();
+          document.body.removeChild(link);
+        } else {
+          this.$message.error('获取文件失败')
+        }
+      })
+    },
+
     openMod(type,data){
       const t = this
       getReviewDetail(data.id).then(res=>{
@@ -201,6 +252,12 @@
       })
     },
 
+    openDetails(id){
+      const t = this
+      t.$refs.msgDetail.getDetails(id)
+      t.$refs.msgDetail.visible = true
+    },
+
     onOk(value) {
       console.log('onOk: ', value);
     },
diff --git a/src/views/Admin/notice.vue b/src/views/Admin/notice.vue
index aa3a28d..1511dac 100644
--- a/src/views/Admin/notice.vue
+++ b/src/views/Admin/notice.vue
@@ -1,5 +1,13 @@
 <template>
 	<div class="inner">
+    <a-alert
+        message="管理员身份无法进行信息编辑操作"
+        banner
+        closable
+        v-if="userInfo.role.id === 1"
+        type="error"
+        style="margin-bottom: 12px"
+    />
     <h2>预警信息发布</h2>
     <a-form-model ref="ruleForm" :model="form" :rules="rules" :wrapper-col="wrapperCol">
       <div class="left">
@@ -52,7 +60,17 @@
         </a-form-model-item>
         <a-row>
           <a-col :span="12">
-            <a-button>上传附件</a-button>
+            <a-upload
+                :action="uploadUrl"
+                :file-list="fileList"
+                @change="fileChange"
+                :headers="header"
+                accept=".doc, .docx, .word, .pdf, .zip, .xlsx, .rar"
+                :data="{module: 'naturalDisasterPath'}"
+                :remove="(file)=>{removeFile(file)}"
+            >
+              <a-button> <a-icon type="upload" />上传附件</a-button>
+            </a-upload>
           </a-col>
           <a-col :span="12" style="display: flex;align-items: center;justify-content: right">
             <b style="margin-bottom: 24px">超时设置:</b>
@@ -108,25 +126,23 @@
             <b style="margin-bottom: 6px">选择审批领导:</b>
             <a-form-model-item prop="reviewId">
               <a-select show-search v-model="form.reviewId" placeholder="请选择审批领导" style="width: 300px">
-                <a-select-option v-for="(item,index) in leaders" :value="item.id" :key="index">{{item.name}}</a-select-option>
+                <a-select-option v-for="(item,index) in leaders" :value="item.id" :key="index">{{item.realName}}</a-select-option>
               </a-select>
             </a-form-model-item>
           </a-col>
           <a-col :span="12" style="text-align: right">
-            <a-button type="primary" style="width: 250px;" @click="confirmSend()">
+            <a-button type="primary" style="width: 250px;" @click="confirmSend()" :disabled="userInfo.role.id==1?true:false">
               确认并提交审核
             </a-button>
           </a-col>
         </a-row>
       </div>
-
       <div class="right">
         <h2>短信预览</h2>
         <div class="mobile">
           <div class="mesg">
-            <P>【{{form.title}}】{{form.content}}。发布单位:{{form.publishingUnit}}</P>
+            <P>【自然灾害风险预警提示】{{form.content}}<br>发布单位:{{form.publishingUnit}}</P>
           </div>
-
         </div>
       </div>
     </a-form-model>
@@ -137,7 +153,9 @@
 import {getAreaWithUserIfo, getPeerRecipient, getLeaders} from '@/api/user'
   import {getUserInfo} from "@/util/storage";
   import Cookies from "js-cookie";
+  import axios from "axios";
 import {massSend, msgSend} from "@/api/send";
+import {deleteFile} from "@/api/list";
 	export default {
 		name: "notice",
 		data() {
@@ -197,13 +215,23 @@
           recipient: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
           // acceptingUnitIds: [{ required: true, message: '请选择接收单位', trigger: 'change'}],
           // peerRecipientIds: [{ required: true, message: '请选择平级接收人', trigger: 'change'}]
-        }
+        },
+        uploadUrl: '',
+        fileList: [],
+        header: {
+          uid: null,
+          tk: Cookies.get('resTk')
+        },
+        delList: []
 			};
 		},
 		components: {},
     created() {
       const t = this
+      const { baseUrl } = require('../../../config/env.' + process.env.NODE_ENV)
+      t.uploadUrl= baseUrl + '/attachment/upload/detail'
       t.userInfo = getUserInfo()
+      t.header.uid = t.userInfo.uid
       t.form.districtId = t.userInfo.districtId
       t.form.publishingUnit = t.userInfo.company
       t.getSameLevel()
@@ -220,7 +248,7 @@
           if(res.data.data){
             t.filteredOptions = res.data.data
           }else{
-            this.$message.warning('暂无数据');
+            console.log('暂无数据')
           }
         }else{
           this.$message.warning(res.data.msg);
@@ -233,14 +261,14 @@
         let res = await getAreaWithUserIfo()
         if(res.data.code == 100){
           if(res.data.data){
-            const treeD = []
+            // const treeD = []
             t.userTitTree(res.data.data)
-            const obj = t.findNodeById(res.data.data,t.userInfo.districtId)
-            treeD.push(t.removeNodesWithoutUsers(obj))
-            t.areaUsers = treeD
+            // treeD.push(t.findNodeById(res.data.data,t.userInfo.districtId))
+            console.log(res.data.data)
+            t.areaUsers = t.findNodeById(res.data.data,t.userInfo.districtId).children
             t.unittype = this.findNodeById(this.areaUsers,t.userInfo.districtId)?.type
           }else{
-            this.$message.warning('暂无数据');
+            console.log('暂无数据')
           }
         }else{
           this.$message.warning(res.data.msg);
@@ -255,7 +283,7 @@
           if(res.data.data){
             t.leaders = res.data.data
           }else{
-            this.$message.warning('暂无数据');
+            console.log('暂无数据')
           }
         }else{
           this.$message.warning(res.data.msg);
@@ -279,34 +307,79 @@
         }
       },
 
+      fileChange(info) {
+        let fileList = [...info.fileList];
+        // 2. read from response and show file link
+        fileList = fileList.map(file => {
+          if(file.status == 'done'){
+            if (file.response) {
+              const res = file.response
+              if(res.code == 100){
+                this.$message.success('文件上传成功')
+              }else{
+                this.$message.error('文件上传失败')
+              }
+              // Component will show file.url as link
+              file.url = res.data.fileUrl
+            }
+          }
+          return file;
+        });
+        this.fileList = fileList;
+      },
+
+      removeFile(file){
+        this.delList.push(file.uid)
+      },
+
+      async deleteFile(){
+        const t = this
+        for(let i of t.delList){
+          const res = await deleteFile(i)
+          if(res.data.code == 100){
+            console.log('文件删除成功')
+          }else{
+            t.$message.error(res.data.msg)
+          }
+        }
+      },
+
       confirmSend(){
         this.$refs.ruleForm.validate(valid => {
           if (valid) {
             this.form.acceptingUnitIds = []
             this.form.peerRecipientIds = []
             const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
-            console.log(aList,'a')
+            if(aList.includes(null)){
+              this.$message.error('选择接收单位时存在无用户的单位')
+              return
+            }
             const newAList = [].concat(...aList)
-            console.log(newAList,'b')
             for(let i of newAList){
               const {realName,...data} = i
               const {id:recipienterId,name: recipienterName,phone: recipienterPhone,company: receiveUnit,...rest} = data
               const obj = { recipienterId, recipienterName, recipienterPhone, receiveUnit,...rest}
               this.form.acceptingUnitIds.push(obj)
             }
-            const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
-            for(let i of bList){
-              const {id:recipienterId,recipientName: recipienterName,phone: recipienterPhone, company: receiveUnit,...rest} = i
-              const obj = {recipienterId, recipienterName,recipienterPhone,receiveUnit,unittype:this.unittype,...rest}
-              this.form.peerRecipientIds.push(obj)
+            if(this.form.recipient.length>0){
+              const bList = this.form.recipient.map(item => this.filteredOptions.find(i=>i.id == item))
+              for(let i of bList){
+                const {id:recipienterId,recipientName: recipienterName,phone: recipienterPhone, company: receiveUnit,...rest} = i
+                const obj = {recipienterId, recipienterName,recipienterPhone,receiveUnit,unittype:this.unittype,...rest}
+                this.form.peerRecipientIds.push(obj)
+              }
             }
+            this.form.attachments = this.fileList.map(i=>i.response.data.id)
             const {receiver,recipient,id,...data} = this.form
             msgSend(data).then( res =>{
               if(res.data.code == 100){
+                this.deleteFile()
                 this.$message.success('信息已提交审核')
               }else{
                 this.$message.error(res.data.msg)
               }
+              this.fileList = []
+              this.delList = []
               this.$refs.ruleForm.clearValidate()
               this.$refs.ruleForm.resetFields()
             })
@@ -353,6 +426,7 @@
       userTitTree(treeData) {
         for(const node of treeData){
           if(node.users){
+            node.users = node.users.filter(i=>i.roleId == 3)
             node.users = node.users.map((i)=>{
               return{
                 ...i,
@@ -360,7 +434,7 @@
                 districtId: node.id
               }
             })
-            node.name = node.name + '('+node.users.map(i=>i.name +' '+ i.phone).join(',')+')'
+            node.name = node.name + '('+node.users.map(i=>i.realName +' '+ i.phone).join(',')+')'
           }
           if(node.children){
             this.userTitTree(node.children)
@@ -369,15 +443,15 @@
         return treeData
       },
       // 将users为null的节点删除
-      removeNodesWithoutUsers(node) {
-          if (node.users === null) {
-            return null; // 返回 null 表示删除节点
-          }
-          if (node.children && node.children.length > 0) {
-            node.children = node.children.map(child => this.removeNodesWithoutUsers(child)).filter(Boolean);
-          }
-          return node;
-      },
+      // removeNodesWithoutUsers(node) {
+      //     if (node.users === null && node.children === null) {
+      //       return null; // 返回 null 表示删除节点
+      //     }
+      //     if (node.children && node.children.length > 0) {
+      //       node.children = node.children.map(child => this.removeNodesWithoutUsers(child)).filter(Boolean);
+      //     }
+      //     return node;
+      // },
 
       onSearch() {
         console.log(...arguments);
@@ -395,24 +469,6 @@
       handleLevel(selectedItems) {
         // this.selectedItems = selectedItems;
       },
-
-			onChange(){
-				console.log(this.value)
-			},
-			handleChange(value) {
-				console.log(`selected ${value}`);
-			},
-			handleBlur() {
-				console.log('blur');
-			},
-			handleFocus() {
-				console.log('focus');
-			},
-			filterOption(input, option) {
-				return (
-					option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
-				);
-			},
 		},
 	}
 </script>
diff --git a/src/views/Admin/release.vue b/src/views/Admin/release.vue
index 162678b..3a7589a 100644
--- a/src/views/Admin/release.vue
+++ b/src/views/Admin/release.vue
@@ -36,7 +36,7 @@
 
 	  <!-- 表格实体部分-->
     <div class="table-cont">
-      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination">
+      <a-table :columns="columns" :data-source="data" bordered :pagination="pagination" :rowKey="record=>record.id">
         <template #index="text,record,index">
           {{ index + 1 }}
         </template>
@@ -54,8 +54,11 @@
             {{ getLevelName(text) }}
           </a-tag>
         </template>
-        <template #attachment="text">
-          <a><b><a-icon type="paper-clip"/></b></a>
+        <template #attachment="attachment">
+          <span v-if="attachment===null|| attachment===[]">无</span>
+          <div v-else>
+            <a-button @click="viewFile(item)" type="link" v-for="(item,index) in attachment" :key="index"><a-icon type="paper-clip"/>{{item.attachmentName}}</a-button>
+          </div>
         </template >
         <template #responseSituation="text">
           <a-tag :color="text === 3 ? 'red' :text === 2? 'green':text === 1?'orange':'blue'">
@@ -64,10 +67,10 @@
         </template>
         <template #operation="text, record, index">
           <a-button type="primary" @click="openList(record.id)">叫应列表</a-button>
-          <a-button type="link" @click="openMod('view',record)">查看详情</a-button>
+          <a-button type="link" @click="openDetails(record.id)">查看详情</a-button>
         </template>
       </a-table>
-      <msg-edit-mod ref="msgEdit" @refresh="getData"></msg-edit-mod>
+      <msg-detail-mod ref="msgDetail"></msg-detail-mod>
       <call-list-mod ref="callList" @refresh="getData"></call-list-mod>
     </div>
 	  <!-- 对话框 -->
@@ -80,9 +83,12 @@
 </template>
 <script>
 import {getMsgRecord, getPublishRecord} from "@/api/list";
-import msgEditMod from "@/views/Admin/components/msgEditMod";
+import msgDetailMod from "@/views/Admin/components/msgDetailMod";
 import callListMod from "@/views/Admin/components/callListMod";
 import {getReviewDetailByWorker} from "@/api/review";
+import axios from "axios";
+import Cookies from "js-cookie";
+import {getUserInfo} from "@/util/storage";
   const columns = [{
 			title: '序号',
 			dataIndex: 'index',
@@ -128,7 +134,7 @@
 		{
 			title: '附件',
 			dataIndex: 'attachment',
-			width: '6%',
+			width: '15%',
 			scopedSlots: {
 				customRender: 'attachment'
 			},
@@ -151,7 +157,7 @@
 	];
 	export default {
     name: 'release',
-    components: { msgEditMod, callListMod },
+    components: { msgDetailMod, callListMod },
 		data() {
 			return {
         search:{
@@ -193,6 +199,11 @@
         ]
 			}
 		},
+    mounted() {
+      if(getUserInfo().role.id == 1){
+        this.columns = this.columns.filter(i=>i.dataIndex !== 'operation')
+      }
+    },
     created() {
       const t = this
       t.getData()
@@ -214,19 +225,10 @@
         t.$refs.callList.openMod(id)
       },
 
-      openMod(type,data){
+      openDetails(id){
         const t = this
-        getReviewDetailByWorker(data.id).then(res=>{
-          if(res.data.code == 100){
-            if(res.data.data){
-              t.$refs.msgEdit.openMod(type,res.data.data)
-            }else{
-              t.$message.error('查询信息详情失败')
-            }
-          }else{
-            this.$message.error(res.data.msg)
-          }
-        })
+        t.$refs.msgDetail.getDetails(id)
+        t.$refs.msgDetail.visible = true
       },
 
       onPageChange(page, pageSize) {
@@ -244,6 +246,25 @@
         }
       },
 
+      viewFile(item){
+        const t = this
+        const { baseUrl } = require('../../../config/env.' + process.env.NODE_ENV)
+        axios.get(baseUrl + item.attachment,{headers:{'Content-Type': 'application/json','tk': `${Cookies.get('resTk')}`,'uid':`${Cookies.get('resUid')}`},responseType: 'blob'}).then(res=>{
+          if (res) {
+            const link = document.createElement('a')
+            let blob = new Blob([res.data],{type: res.data.type})
+            link.style.display = "none";
+            link.href = URL.createObjectURL(blob); // 创建URL
+            link.setAttribute("download", item.attachmentName);
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link);
+          } else {
+            this.$message.error('获取文件失败')
+          }
+        })
+      },
+
       timeOk(value) {
         console.log('onOk: ', value);
       },
diff --git a/src/views/Admin/sameLevel.vue b/src/views/Admin/sameLevel.vue
index 09231d2..23317e6 100644
--- a/src/views/Admin/sameLevel.vue
+++ b/src/views/Admin/sameLevel.vue
@@ -119,7 +119,6 @@
   },
   created() {
     const t = this
-    console.log(getUserInfo(),'id')
     t.unittype = getUserInfo().unittype
     t.districtId = getUserInfo().districtId
     t.getUserList()
@@ -189,14 +188,15 @@
         cancelText: '取消',
         okText: '确认',
         centered: true,
-        async onOk() {
-          let res = await delRecipient(row.id)
-          if(res.data.code == 100){
-            t.$message.success('删除用户信息成功');
-            t.getUserList()
-          }else{
-            t.$message.warning(res.data.msg);
-          }
+        onOk() {
+          delRecipient(row.id).then(res=>{
+            if(res.data.code == 100){
+              t.$message.success('删除用户信息成功');
+              t.getUserList()
+            }else{
+              t.$message.warning(res.data.msg);
+            }
+          })
         },
         onCancel() {
           console.log('Cancel');
diff --git a/src/views/Admin/userManage.vue b/src/views/Admin/userManage.vue
index 7c24e36..585a1d8 100644
--- a/src/views/Admin/userManage.vue
+++ b/src/views/Admin/userManage.vue
@@ -215,14 +215,15 @@
         cancelText: '取消',
         okText: '确认',
         centered: true,
-        async onOk() {
-          let res = await delUser(row.id)
-          if(res.data.code == 100){
-            t.$message.success('删除用户信息成功');
-            t.getUserList()
-          }else{
-            t.$message.warning(res.data.msg);
-          }
+        onOk() {
+          delUser(row.id).then(res=>{
+            if(res.data.code == 100){
+              t.$message.success('删除用户信息成功');
+              t.getUserList()
+            }else{
+              t.$message.warning(res.data.msg);
+            }
+          })
         },
         onCancel() {
           console.log('Cancel');
diff --git a/src/views/Home.vue b/src/views/Home.vue
index abcedf0..e62029e 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -57,7 +57,7 @@
 		name: "Home",
 		data() {
 			return {
-        userInfo: {},
+        userInfo: getUserInfo(),
 				collapsed: false, //返回logo图片或表述
 				pageList: [],
 				activePage: '',
@@ -70,8 +70,6 @@
       pwdMod
 		},
 		created() {
-      this.userInfo = getUserInfo()
-      // this.getDistrictInfo()
 			const route = this.$route
 			if (this.pageList.findIndex(item => item.path === route.path) === -1) {
 				this.pageList.push(this.createPage(route))
@@ -122,16 +120,17 @@
           cancelText: '取消',
           okText: '确认',
           centered: true,
-          async onOk() {
-            const res = await loginOut()
-            if (res.data.code === 100) {
-              Session.clear(); // 清除缓存/token等
-              // 使用 reload 时,不需要调用 resetRoute() 重置路由
-              t.$router.push('/')
-              // window.location.reload();
-            } else {
-              this.$message.warning(res.data.msg);
-            }
+          onOk() {
+            loginOut().then(res=>{
+              if (res.data.code === 100) {
+                Session.clear(); // 清除缓存/token等
+                // 使用 reload 时,不需要调用 resetRoute() 重置路由
+                t.$router.push('/')
+                // window.location.reload();
+              } else {
+                this.$message.warning(res.data.msg);
+              }
+            })
           },
           onCancel() {
             console.log('Cancel');

--
Gitblit v1.9.2