From 0bab85897653f65df1932edb829f2af2bf58b846 Mon Sep 17 00:00:00 2001
From: 马宇豪 <978517621@qq.com>
Date: 星期三, 19 七月 2023 10:37:14 +0800
Subject: [PATCH] 修改

---
 src/views/Admin/Report.vue                    |    7 
 vue.config.js                                 |   18 
 package-lock.json                             |  151 +++++++
 src/views/Admin/callRecord.vue                |    7 
 src/api/user.js                               |   88 ++++
 src/views/Admin/release.vue                   |   10 
 src/views/Admin/msgRecord.vue                 |    7 
 src/router/index.js                           |    6 
 src/views/Admin/components/msgEditMod.vue     |    3 
 src/views/Admin/addressBook.vue               |  269 ++++++++++++++
 src/views/Admin/list.vue                      |    7 
 src/layout/menu/index.js                      |   10 
 src/views/Admin/massSend.vue                  |  136 ++++++
 src/views/Admin/components/groupListMod.vue   |  208 ++++++++++
 src/views/Admin/userManage.vue                |    1 
 package.json                                  |    1 
 src/views/Admin/history.vue                   |   19 
 src/views/Admin/components/addressUserMod.vue |  149 +++++++
 src/App.vue                                   |    4 
 src/assets/example.xlsx                       |    0 
 src/views/Admin/notice.vue                    |    3 
 21 files changed, 1,062 insertions(+), 42 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index 31888de..fbb87fc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -30,6 +30,7 @@
         "@vue/cli-plugin-vuex": "~4.5.0",
         "@vue/cli-service": "~4.5.0",
         "babel-plugin-import": "^1.13.3",
+        "file-loader": "^6.2.0",
         "less": "^3.0.4",
         "less-loader": "^5.0.0",
         "vue-template-compiler": "^2.6.11"
@@ -2412,6 +2413,48 @@
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true,
       "optional": true
+    },
+    "node_modules/@vue/cli-service/node_modules/file-loader": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmmirror.com/file-loader/-/file-loader-4.3.0.tgz",
+      "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==",
+      "dev": true,
+      "dependencies": {
+        "loader-utils": "^1.2.3",
+        "schema-utils": "^2.5.0"
+      },
+      "engines": {
+        "node": ">= 8.9.0"
+      },
+      "peerDependencies": {
+        "webpack": "^4.0.0"
+      }
+    },
+    "node_modules/@vue/cli-service/node_modules/file-loader/node_modules/json5": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
+      "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+      "dev": true,
+      "dependencies": {
+        "minimist": "^1.2.0"
+      },
+      "bin": {
+        "json5": "lib/cli.js"
+      }
+    },
+    "node_modules/@vue/cli-service/node_modules/file-loader/node_modules/loader-utils": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz",
+      "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+      "dev": true,
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^1.0.1"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
     },
     "node_modules/@vue/cli-service/node_modules/has-flag": {
       "version": "4.0.0",
@@ -6321,19 +6364,47 @@
       "integrity": "sha1-tO7oFIq7Adzx0aw0Nn1Z4S+mHW4="
     },
     "node_modules/file-loader": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz",
-      "integrity": "sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8=",
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/file-loader/-/file-loader-6.2.0.tgz",
+      "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
       "dev": true,
       "dependencies": {
-        "loader-utils": "^1.2.3",
-        "schema-utils": "^2.5.0"
+        "loader-utils": "^2.0.0",
+        "schema-utils": "^3.0.0"
       },
       "engines": {
-        "node": ">= 8.9.0"
+        "node": ">= 10.13.0"
       },
       "peerDependencies": {
-        "webpack": "^4.0.0"
+        "webpack": "^4.0.0 || ^5.0.0"
+      }
+    },
+    "node_modules/file-loader/node_modules/loader-utils": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+      "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+      "dev": true,
+      "dependencies": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^3.0.0",
+        "json5": "^2.1.2"
+      },
+      "engines": {
+        "node": ">=8.9.0"
+      }
+    },
+    "node_modules/file-loader/node_modules/schema-utils": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+      "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+      "dev": true,
+      "dependencies": {
+        "@types/json-schema": "^7.0.8",
+        "ajv": "^6.12.5",
+        "ajv-keywords": "^3.5.2"
+      },
+      "engines": {
+        "node": ">= 10.13.0"
       }
     },
     "node_modules/file-uri-to-path": {
@@ -18527,6 +18598,38 @@
           "dev": true,
           "optional": true
         },
+        "file-loader": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmmirror.com/file-loader/-/file-loader-4.3.0.tgz",
+          "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==",
+          "dev": true,
+          "requires": {
+            "loader-utils": "^1.2.3",
+            "schema-utils": "^2.5.0"
+          },
+          "dependencies": {
+            "json5": {
+              "version": "1.0.2",
+              "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz",
+              "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+              "dev": true,
+              "requires": {
+                "minimist": "^1.2.0"
+              }
+            },
+            "loader-utils": {
+              "version": "1.4.2",
+              "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz",
+              "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==",
+              "dev": true,
+              "requires": {
+                "big.js": "^5.2.2",
+                "emojis-list": "^3.0.0",
+                "json5": "^1.0.1"
+              }
+            }
+          }
+        },
         "has-flag": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -21852,13 +21955,37 @@
       "integrity": "sha1-tO7oFIq7Adzx0aw0Nn1Z4S+mHW4="
     },
     "file-loader": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npm.taobao.org/file-loader/download/file-loader-4.3.0.tgz",
-      "integrity": "sha1-eA8ED3KbPRgBnyBgX3I+hEuKWK8=",
+      "version": "6.2.0",
+      "resolved": "https://registry.npmmirror.com/file-loader/-/file-loader-6.2.0.tgz",
+      "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==",
       "dev": true,
       "requires": {
-        "loader-utils": "^1.2.3",
-        "schema-utils": "^2.5.0"
+        "loader-utils": "^2.0.0",
+        "schema-utils": "^3.0.0"
+      },
+      "dependencies": {
+        "loader-utils": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+          "dev": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
+        "schema-utils": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
+          "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
+          "dev": true,
+          "requires": {
+            "@types/json-schema": "^7.0.8",
+            "ajv": "^6.12.5",
+            "ajv-keywords": "^3.5.2"
+          }
+        }
       }
     },
     "file-uri-to-path": {
diff --git a/package.json b/package.json
index 484ca2f..27b03ee 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
     "@vue/cli-plugin-vuex": "~4.5.0",
     "@vue/cli-service": "~4.5.0",
     "babel-plugin-import": "^1.13.3",
+    "file-loader": "^6.2.0",
     "less": "^3.0.4",
     "less-loader": "^5.0.0",
     "vue-template-compiler": "^2.6.11"
diff --git a/src/App.vue b/src/App.vue
index 487663f..1f80fff 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -11,8 +11,8 @@
   -moz-osx-font-smoothing: grayscale;
 }
 * {
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
 }
 .inner{
 	background-color: #fff;
diff --git a/src/api/user.js b/src/api/user.js
index 3ed0cc0..a8df775 100644
--- a/src/api/user.js
+++ b/src/api/user.js
@@ -75,7 +75,7 @@
     return request({
         url:'/mesmanager/recipient/add',
         method:'post',
-        data:data,
+        data:data
     })
 }
 
@@ -83,7 +83,7 @@
     return request({
         url:'/mesmanager/recipient/update',
         method:'post',
-        data:data,
+        data:data
     })
 }
 
@@ -102,9 +102,93 @@
     })
 }
 
+// 获取原通讯录用户
+export function getAddressBook(data){
+    return request({
+        url: '/addressbook/user/page',
+        method: 'post',
+        data:data
+    })
+}
 
+// 新增原通讯录用户
+export function addGroupUser(data){
+    return request({
+        url: '/addressbook/user/add',
+        method: 'post',
+        data:data
+    })
+}
 
+// 修改原通讯录用户
+export function updateGroupUser(data){
+    return request({
+        url: '/addressbook/user/update',
+        method: 'post',
+        data:data
+    })
+}
 
+// 删除原通讯录用户
+export function delGroupUser(data){
+    return request({
+        url: '/addressbook/user/delete',
+        method: 'post',
+        data:data
+    })
+}
 
+// 获取通讯录分组
+export function getGroupList(){
+    return request({
+        url: '/addressbook/group/listAll',
+        method: 'get'
+    })
+}
 
+// 新增通讯录分组
+export function addGroup(data){
+    return request({
+        url: '/addressbook/group/add',
+        method: 'post',
+        data:data
+    })
+}
 
+// 修改通讯录分组
+export function updateGroup(data){
+    return request({
+        url: '/addressbook/group/update',
+        method: 'post',
+        data:data
+    })
+}
+
+// 删除通讯录分组
+export function delGroup(data){
+    return request({
+        url: '/addressbook/group/delete',
+        method: 'post',
+        data:data
+    })
+}
+
+// 获取分组和组员
+export function getUserByGroup(){
+    return request({
+        url: '/addressbook/group/listUserByGroup',
+        method: 'get'
+    })
+}
+
+// 导入通讯录
+export function importFile(data){
+    return request({
+        headers: {
+            "Content-Type": "multipart/form-data",
+        },
+        url: '/addressbook/user/import',
+        method: 'post',
+        data: data
+    })
+}
\ No newline at end of file
diff --git a/src/assets/example.xlsx b/src/assets/example.xlsx
new file mode 100644
index 0000000..1800858
--- /dev/null
+++ b/src/assets/example.xlsx
Binary files differ
diff --git a/src/layout/menu/index.js b/src/layout/menu/index.js
index f1e46de..5d1f033 100644
--- a/src/layout/menu/index.js
+++ b/src/layout/menu/index.js
@@ -80,6 +80,11 @@
 					MenuTitle: "平级接收人管理",
 					MenuPath: "/samelevel",
 				},
+				{
+					MenuID: "34",
+					MenuTitle: "原通讯录",
+					MenuPath: "/addressBook",
+				}
 			],
 		},
 		{
@@ -214,6 +219,11 @@
 					MenuTitle: "平级接收人管理",
 					MenuPath: "/samelevel",
 				},
+				{
+					MenuID: "34",
+					MenuTitle: "原通讯录",
+					MenuPath: "/addressBook",
+				}
 			],
 		},
 		{
diff --git a/src/router/index.js b/src/router/index.js
index d03f95e..dbbe9ea 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -94,6 +94,12 @@
 	    meta: { title: '平级接收人管理' },
 	    component: () => import('@/views/Admin/sameLevel'),
 	  },
+		{
+			path: '/addressBook',
+			name: 'addressBook',
+			meta: { title: '原通讯录' },
+			component: () => import('@/views/Admin/addressBook'),
+		},
       {
         path: '/user',
         name: 'user',
diff --git a/src/views/Admin/Report.vue b/src/views/Admin/Report.vue
index 79369d2..5588b32 100644
--- a/src/views/Admin/Report.vue
+++ b/src/views/Admin/Report.vue
@@ -30,7 +30,7 @@
             />
           </a-col>
           <a-col :span="4">
-            <a-button type="primary" @click="getData">查询</a-button>
+            <a-button type="primary" @click="searchData()">查询</a-button>
             <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
           </a-col>
         </a-row>
@@ -190,6 +190,11 @@
       }
     },
 
+    searchData(){
+      this.search.pageIndex = 1
+      this.getData()
+    },
+
     resetSearch(){
       const t = this
       t.search = {
diff --git a/src/views/Admin/addressBook.vue b/src/views/Admin/addressBook.vue
new file mode 100644
index 0000000..7618f47
--- /dev/null
+++ b/src/views/Admin/addressBook.vue
@@ -0,0 +1,269 @@
+<template>
+  <div class="inner">
+    <a-row type="flex" justify="space-between" style="margin-bottom: 20px">
+      <a-col :span="8">
+        <a-button v-if="unittype && unittype !== null" type="primary" @click="editData('add',{})">新增</a-button>
+        <a-button v-if="unittype && unittype !== null" type="primary" @click="visible = true" style="margin: 0 12px">导入通讯录表</a-button>
+        <a-button v-if="unittype && unittype !== null" type="primary" @click="openGroup()">分组管理</a-button>
+      </a-col>
+      <a-col :span="16">
+        <a-row type="flex" justify="end" :gutter="14">
+          <a-col :span="6">
+            <a-input v-model="search.searchParams.company" placeholder="单位名称" style="width: 100%"/>
+          </a-col>
+          <a-col :span="6">
+            <a-select v-model="search.searchParams.addressBookGroupId" placeholder="选择分组" style="width: 100%" @change="handleChange">
+              <a-select-option v-for="item in groupData" :value="item.id" :key="item.id">{{item.name}}</a-select-option>
+            </a-select>
+          </a-col>
+          <a-col :span="4">
+            <a-button type="primary" @click="searchData()">查询</a-button>
+            <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
+          </a-col>
+        </a-row>
+      </a-col>
+    </a-row>
+    <div class="table-cont">
+      <a-table :columns="columns" :data-source="tableData" :pagination="pagination" :rowKey="record=>record.id" bordered>
+        <template #group="groupId">
+          {{ getGroupName(groupId) }}
+        </template>
+        <template #action="action,row">
+          <a-button type="link" @click="editData('edit',row)">编辑</a-button>
+          <a-button type="link" class="delBtn" @click="delData(row)">删除</a-button>
+        </template>
+      </a-table>
+    </div>
+    <address-user-mod ref="addressRef" :groupList="groupData" @refresh="getAddressBook"></address-user-mod>
+    <group-list-mod ref="groupRef" @refresh="getGroupList"></group-list-mod>
+    <a-modal v-model="visible" title="导入通讯录" ok-text="导入通讯录" :confirmLoading="uploadLoading" cancel-text="取消" @ok="uploadFile" centered :afterClose="clearMod">
+      <a-form-model ref="ruleForm" :label-col="labelCol" :wrapper-col="wrapperCol" :colon="false">
+        <a-form-model-item label="通讯录表格模板" extra="导入通讯录须依据此模板">
+          <a-button type="primary" @click="downloadFile">下载模板</a-button>
+        </a-form-model-item>
+        <a-form-model-item label="通讯录表格文件">
+          <a-upload :file-list="fileList" :remove="handleRemove" :before-upload="beforeUpload" accept=".xlsx,.xls">
+            <a-button> <a-icon type="upload"/> 点击上传 </a-button>
+          </a-upload>
+        </a-form-model-item>
+      </a-form-model>
+    </a-modal>
+  </div>
+</template>
+<script>
+import {delGroupUser, getAddressBook, getGroupList, importFile} from '@/api/user'
+import {getUserInfo} from "@/util/storage"
+import addressUserMod from "@/views/Admin/components/addressUserMod"
+import groupListMod from "@/views/Admin/components/groupListMod";
+import exampleFile from '@/assets/example.xlsx'
+export default {
+  name: 'addressBook',
+  components: { addressUserMod,groupListMod },
+  data () {
+    return {
+      groupData: [],
+      unittype: null,
+      districtId: null,
+      search:{
+        pageIndex: 1,
+        pageSize: 20,
+        searchParams:{
+          company: '',
+          addressBookGroupId: null
+        }
+      },
+      columns:[
+        {
+          title: '分组',
+          dataIndex: 'addressBookGroupId',
+          key: 'addressBookGroupId',
+          scopedSlots: { customRender: 'group' }
+        },
+        {
+          title: '单位',
+          dataIndex: 'company',
+          key: 'company'
+        },
+        {
+          title: '姓名',
+          dataIndex: 'name',
+          key: 'name'
+        },
+        {
+          title: '手机号码',
+          dataIndex: 'phone',
+          key: 'phone'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          scopedSlots: { customRender: 'action' }
+        },
+      ],
+      tableData: [],
+      pagination: {
+        current: 1,
+        defaultCurrent: 1,
+        defaultPageSize: 20,
+        total: 0,
+        onChange: ( page, pageSize ) => this.onPageChange(page,pageSize),
+        showTotal: total => `共 ${total} 条`
+      },
+      visible: false,
+      labelCol: { span: 8 },
+      wrapperCol: { span: 14 },
+      exampleFile,
+      fileList: [],
+      delList: [],
+      uploadLoading: false
+    }
+  },
+  created() {
+    const t = this
+    t.unittype = getUserInfo().unittype
+    t.districtId = getUserInfo().districtId
+    t.getAddressBook()
+    t.getGroupList()
+  },
+  methods:{
+    async getAddressBook(){
+      const t = this
+      const res = await getAddressBook(t.search)
+      if(res.data.code == 100){
+        t.tableData = res.data.data
+        t.pagination.total = res.data.total
+      }else{
+        t.$message.warning(res.data.msg);
+      }
+    },
+
+    async getGroupList(){
+      let res = await getGroupList()
+      if(res.data.code == 100){
+        this.groupData = res.data.data
+      } else {
+        this.$message.warning(res.data.msg);
+      }
+    },
+
+    handleChange(value) {
+      console.log(`selected ${value}`);
+    },
+
+    searchData(){
+      this.search.pageIndex = 1
+      this.getAddressBook()
+    },
+
+    resetSearch(){
+      const t = this
+      t.search = {
+        pageIndex: 1,
+        pageSize: 20,
+        searchParams:{
+          company: '',
+          addressBookGroupId: null
+        }
+      }
+      t.getAddressBook()
+    },
+
+    editData(type,data){
+      const t = this
+      t.$refs.addressRef.openDialog(type,data)
+    },
+    openGroup(){
+      this.$refs.groupRef.openDialog()
+    },
+
+    async delData(row){
+      const t = this
+      this.$confirm({
+        title: '提示',
+        content: h => <div>是否删除该条用户信息?</div>,
+        cancelText: '取消',
+        okText: '确认',
+        centered: true,
+        onOk() {
+          delGroupUser({id: row.id}).then(res=>{
+            if(res.data.code == 100){
+              t.$message.success('删除用户信息成功');
+              t.getAddressBook()
+            }else{
+              t.$message.warning(res.data.msg);
+            }
+          })
+        },
+        onCancel() {
+          console.log('Cancel');
+        },
+      });
+    },
+
+    onPageChange(page, pageSize) {
+      const t= this
+      t.pagination.current = page
+      t.search.pageIndex = page
+      t.getAddressBook()
+    },
+    getGroupName(id){
+      return this.groupData.find(i => i.id === id)?.name;
+    },
+
+    downloadFile(){
+      const link = document.createElement('a')
+      link.href = exampleFile
+      link.target = '_blank'
+      link.download = '通讯录导入模板.xlsx'
+      link.click()
+    },
+
+    handleRemove(file) {
+      const index = this.fileList.indexOf(file)
+      const newFileList = this.fileList.slice()
+      newFileList.splice(index, 1)
+      this.fileList = newFileList;
+    },
+    beforeUpload(file) {
+      this.fileList = [...this.fileList, file]
+      this.fileList = this.fileList.slice(-1)
+      return false;
+    },
+
+    async uploadFile(){
+      if(this.fileList.length == 0){
+        this.$message.warning('请先上传通讯录表格');
+        return
+      }else{
+        this.uploadLoading = true
+        const { fileList } = this;
+        const formData = new FormData();
+        fileList.forEach((file) => {
+          formData.append('file', file)
+        })
+        const res = await importFile(formData)
+        if(res.data.code == 100){
+          this.$message.success(res.data.msg,2);
+          this.fileList = []
+          this.uploadLoading = false
+          this.visible = false
+          this.getAddressBook()
+        }else{
+          this.$message.warning(res.data.msg);
+          this.uploadLoading = false
+        }
+      }
+    },
+
+    clearMod(){
+      this.fileList = []
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.delBtn{
+  color: @danger
+}
+</style>
diff --git a/src/views/Admin/callRecord.vue b/src/views/Admin/callRecord.vue
index 7c40087..0b887e5 100644
--- a/src/views/Admin/callRecord.vue
+++ b/src/views/Admin/callRecord.vue
@@ -27,7 +27,7 @@
             />
           </a-col>
           <a-col :span="4">
-            <a-button type="primary" @click="getData">查询</a-button>
+            <a-button type="primary" @click="searchData">查询</a-button>
             <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
           </a-col>
         </a-row>
@@ -216,6 +216,11 @@
       console.log('onOk: ', value);
     },
 
+    searchData(){
+      this.search.pageIndex = 1
+      this.getData()
+    },
+
     resetSearch(){
       const t = this
       t.search = {
diff --git a/src/views/Admin/components/addressUserMod.vue b/src/views/Admin/components/addressUserMod.vue
new file mode 100644
index 0000000..9d0cc3f
--- /dev/null
+++ b/src/views/Admin/components/addressUserMod.vue
@@ -0,0 +1,149 @@
+<template>
+  <a-modal
+      :title="title"
+      :visible="visible"
+      centered
+      :confirm-loading="confirmLoading"
+      width="50%"
+      cancelText="取消"
+      okText="确认"
+      @ok="onSubmit"
+      @cancel="handleCancel"
+      :afterClose="clearMod"
+  >
+    <a-form-model ref="ruleForm" :rules="rules" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol" :colon="false">
+      <a-form-model-item label="姓名" prop="name">
+        <a-input v-model="form.name"/>
+      </a-form-model-item>
+      <a-form-model-item label="手机号码" prop="phone">
+        <a-input v-model="form.phone"/>
+      </a-form-model-item>
+      <a-form-model-item label="单位名称" prop="company">
+        <a-input v-model="form.company"/>
+      </a-form-model-item>
+      <a-form-model-item label="分组" prop="addressBookGroupId">
+        <a-select v-model="form.addressBookGroupId" placeholder="选择分组">
+          <a-select-option v-for="item in groupList" :value="item.id" :key="item.id">{{item.name}}</a-select-option>
+        </a-select>
+      </a-form-model-item>
+    </a-form-model>
+  </a-modal>
+</template>
+
+<script>
+import {addGroupUser, addUser, updateGroupUser, updateUser} from '@/api/user'
+import {verifySimplePhone} from "@/util/validate";
+export default {
+  name: 'addressUserMod',
+  props: ['groupList'],
+  data () {
+    let validatePhone = (rule, value, callback)=>{
+      if(value === ''){
+        callback(new Error('请输入手机号'))
+      }else{
+        if(!verifySimplePhone(value)){
+          callback(new Error('手机号格式有误'))
+        }else{
+          callback()
+        }
+      }
+    }
+
+    return {
+      title: '新增用户',
+      visible: false,
+      confirmLoading: false,
+      labelCol: { span: 4 },
+      wrapperCol: { span: 14 },
+      form: {
+        id: null,
+        name: '',
+        phone: '',
+        company: '',
+        addressBookGroupId: null
+      },
+      rules: {
+        name: [{ required: true, message: '请输入姓名', trigger: 'blur'}],
+        phone: [{ required: true, validator: validatePhone, trigger: 'blur'}],
+        company: [{ required: true, message: '请输入单位名称', trigger: 'blur'}],
+        addressBookGroupId: [{ required: true, message: '请选择分组', trigger: 'change'}],
+      }
+    }
+  },
+  created() {
+    const t = this
+  },
+  methods:{
+    openDialog(type,data){
+      const t = this
+      if(type == 'add'){
+        t.title = '新增用户'
+        t.form = {
+          id: null,
+          name: '',
+          phone: '',
+          company: '',
+          addressBookGroupId: null
+        }
+      }else{
+        t.title = '编辑用户'
+        for(let i in data){
+          if(t.isValidKey(i,t.form)){
+            t.form[i] = data[i]
+          }
+        }
+      }
+      t.visible = true
+    },
+    isValidKey(key, object){
+      return key in object;
+    },
+
+    clearMod(){
+      this.$refs.ruleForm.clearValidate()
+      this.$refs.ruleForm.resetFields()
+    },
+
+    onSubmit() {
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          if(this.title == '新增用户'){
+            const { id,...data } = this.form
+            addGroupUser(data).then((res)=>{
+              if(res.data.code == 100){
+                this.$message.success('新增用户成功')
+                this.$emit('refresh')
+                this.visible = false
+              }else{
+                this.$message.error(res.data.msg)
+              }
+            })
+          }else{
+            updateGroupUser(this.form).then((res)=>{
+              if(res.data.code == 100){
+                this.$message.success('修改用户成功')
+                this.$emit('refresh')
+                this.visible = false
+              }else{
+                this.$message.error(res.data.msg)
+              }
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+
+    handleCancel(e) {
+      const t = this
+      t.visible = false;
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+
+</style>
diff --git a/src/views/Admin/components/groupListMod.vue b/src/views/Admin/components/groupListMod.vue
new file mode 100644
index 0000000..3a900be
--- /dev/null
+++ b/src/views/Admin/components/groupListMod.vue
@@ -0,0 +1,208 @@
+<template>
+  <a-modal
+      title="分组管理"
+      :visible="visible"
+      centered
+      :confirm-loading="confirmLoading"
+      width="50%"
+      cancelText="取消"
+      okText="确认"
+      @ok="handleOk"
+      @cancel="handleCancel"
+      :afterClose="refreshGroup"
+  >
+    <a-button type="primary" @click="editData('add',{})" style="margin-bottom: 12px">新增分组</a-button>
+    <div class="table-cont">
+      <a-table :columns="columns" :data-source="tableData" :pagination="false" :rowKey="record=>record.id" bordered>
+        <template #action="action,row">
+          <a-button type="link" @click="editData('edit',row)">编辑</a-button>
+          <a-button type="link" class="delBtn" @click="delData(row)">删除</a-button>
+        </template>
+      </a-table>
+    </div>
+    <a-modal
+        :title="editTitle"
+        :visible="editVisible"
+        centered
+        :confirm-loading="confirmLoading"
+        width="30%"
+        cancelText="取消"
+        okText="确认"
+        @ok="onSubmit"
+        @cancel="editVisible = false"
+        :afterClose="clearMod"
+    >
+      <a-form-model ref="ruleForm" :rules="rules" :model="form" :label-col="labelCol" :wrapper-col="wrapperCol" :colon="false">
+        <a-form-model-item label="分组名称" prop="name">
+          <a-input v-model="form.name"/>
+        </a-form-model-item>
+      </a-form-model>
+    </a-modal>
+  </a-modal>
+</template>
+
+<script>
+import {addGroup, delGroup, getGroupList, updateGroup, updateUser} from '@/api/user'
+export default {
+  name: 'groupListMod',
+  props: [],
+  data () {
+    return {
+      editTitle: '新增分组',
+      visible: false,
+      editVisible: false,
+      confirmLoading: false,
+      labelCol: { span: 4 },
+      wrapperCol: { span: 14 },
+      columns:[
+        {
+          title: '分组名称',
+          dataIndex: 'name',
+          key: 'name'
+        },
+        {
+          title: 'id',
+          dataIndex: 'id',
+          key: 'id'
+        },
+        {
+          title: '操作',
+          key: 'action',
+          scopedSlots: { customRender: 'action' }
+        },
+      ],
+      tableData: [],
+      form: {
+        id: null,
+        name: '',
+      },
+      rules: {
+        name: [{ required: true, message: '请输入组名', trigger: 'blur'}]
+      }
+    }
+  },
+  created() {
+    const t = this
+  },
+  methods:{
+    openDialog(){
+      const t = this
+      t.getGroupList()
+      t.visible = true
+    },
+
+    async getGroupList(){
+      let res = await getGroupList()
+      if(res.data.code == 100){
+        this.tableData = res.data.data
+      } else {
+        this.$message.warning(res.data.msg);
+      }
+    },
+
+    editData(type,data){
+      const t = this
+      if(type == 'add'){
+        t.editTitle = '新增分组'
+        t.form = {
+          id: null,
+          name: '',
+        }
+      }else{
+        t.editTitle = '编辑分组'
+        for(let i in data){
+          if(t.isValidKey(i,t.form)){
+            t.form[i] = data[i]
+          }
+        }
+      }
+      t.editVisible = true
+    },
+
+    isValidKey(key, object){
+      return key in object;
+    },
+
+    onSubmit() {
+      this.$refs.ruleForm.validate(valid => {
+        if (valid) {
+          if(this.editTitle == '新增分组'){
+            const { id,...data } = this.form
+            addGroup(data).then((res)=>{
+              if(res.data.code == 100){
+                this.$message.success('新增分组成功')
+                this.getGroupList()
+                this.editVisible = false
+              }else{
+                this.$message.error(res.data.msg)
+              }
+            })
+          }else{
+            updateGroup(this.form).then((res)=>{
+              if(res.data.code == 100){
+                this.$message.success('修改分组成功')
+                this.getGroupList()
+                this.editVisible = false
+              }else{
+                this.$message.error(res.data.msg)
+              }
+            })
+          }
+        } else {
+          console.log('error submit!!');
+          return false;
+        }
+      });
+    },
+
+    async delData(row){
+      const t = this
+      this.$confirm({
+        title: '提示',
+        content: h => <div>是否删除该条分组?</div>,
+        cancelText: '取消',
+        okText: '确认',
+        centered: true,
+        onOk() {
+          delGroup({id: row.id}).then(res=>{
+            if(res.data.code == 100){
+              t.$message.success('删除分组成功');
+              t.getGroupList()
+            }else{
+              t.$message.warning(res.data.msg);
+            }
+          })
+        },
+        onCancel() {
+          console.log('Cancel');
+        },
+      });
+    },
+
+    clearMod(){
+      this.$refs.ruleForm.clearValidate()
+      this.$refs.ruleForm.resetFields()
+    },
+
+    refreshGroup(){
+      this.$emit('refresh')
+    },
+
+    handleOk(e) {
+      const t = this
+      t.visible = false;
+    },
+
+    handleCancel(e) {
+      const t = this
+      t.visible = false;
+    }
+  }
+}
+</script>
+
+<style lang="less" scoped>
+.delBtn{
+  color: @danger
+}
+</style>
diff --git a/src/views/Admin/components/msgEditMod.vue b/src/views/Admin/components/msgEditMod.vue
index cefb82c..ac30da2 100644
--- a/src/views/Admin/components/msgEditMod.vue
+++ b/src/views/Admin/components/msgEditMod.vue
@@ -97,6 +97,7 @@
             </div>
             <a-form-model-item prop="receiver" style="margin-bottom: 6px">
               <a-tree-select
+                  :maxTagCount="3"
                   show-search
                   tree-checkable
                   treeCheckStrictly
@@ -127,7 +128,7 @@
               </a-checkbox>
             </div>
             <a-form-model-item>
-              <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle" :disabled="disable">
+              <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle" :disabled="disable" :maxTagCount="3">
                 <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                   {{ item.recipientName }}({{item.company}} {{item.phone}})
                 </a-select-option>
diff --git a/src/views/Admin/history.vue b/src/views/Admin/history.vue
index 0556fae..dd5ace3 100644
--- a/src/views/Admin/history.vue
+++ b/src/views/Admin/history.vue
@@ -30,7 +30,7 @@
             <a-input v-model="search.searchParams.publishingUnit" placeholder="单位名称" style="width: 100%"/>
           </a-col>
           <a-col :span="4">
-            <a-button type="primary" @click="getData">查询</a-button>
+            <a-button type="primary" @click="searchData">查询</a-button>
             <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
           </a-col>
         </a-row>
@@ -63,9 +63,9 @@
             <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'">
-            {{text == 1 ? '待叫应' : text == 2 ?'已叫应':text == 3 ?'超时未叫应' : ''}}
+        <template #responsesRate="text">
+          <a-tag :color="Number(text.split('%')[0]) == 100 ? 'green' :Number(text.split('%')[0]) == 0? 'red':'orange'">
+            {{ text }}
           </a-tag>
         </template>
         <template #operation="text, record, index">
@@ -131,10 +131,10 @@
     },
   },
   {
-    title: '叫应情况',
-    dataIndex: 'responseSituation',
+    title: '叫应率',
+    dataIndex: 'responsesRate',
     scopedSlots: {
-      customRender: 'responseSituation'
+      customRender: 'responsesRate'
     }, //设置定制化表格数据
   },
   {
@@ -260,6 +260,11 @@
       console.log('onOk: ', value);
     },
 
+    searchData(){
+      this.search.pageIndex = 1
+      this.getData()
+    },
+
     resetSearch(){
       const t = this
       t.search = {
diff --git a/src/views/Admin/list.vue b/src/views/Admin/list.vue
index 008c24f..bbad73a 100644
--- a/src/views/Admin/list.vue
+++ b/src/views/Admin/list.vue
@@ -30,7 +30,7 @@
             />
           </a-col>
           <a-col :span="4">
-            <a-button type="primary" @click="getData">查询</a-button>
+            <a-button type="primary" @click="searchData">查询</a-button>
             <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
           </a-col>
         </a-row>
@@ -272,6 +272,11 @@
         })
       },
 
+      searchData(){
+        this.search.pageIndex = 1
+        this.getData()
+      },
+
       resetSearch(){
         const t = this
         t.search = {
diff --git a/src/views/Admin/massSend.vue b/src/views/Admin/massSend.vue
index bea7eff..6bebbd2 100644
--- a/src/views/Admin/massSend.vue
+++ b/src/views/Admin/massSend.vue
@@ -75,6 +75,35 @@
       <a-row :gutter="24">
         <a-col :span="12">
           <div style="display:flex;justify-content: space-between;align-items: center;">
+            <b>原通讯录接收人:</b>
+            <a-checkbox :checked="checkTxlAll" @change="checkTxlChange">
+              全选
+            </a-checkbox>
+          </div>
+          <a-form-model-item prop="txlUsers">
+            <a-tree-select
+                show-search
+                tree-checkable
+                style="width: 100%"
+                v-model="form.txlUsers"
+                :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
+                placeholder="选择原通讯录接收人"
+                allow-clear
+                multiple
+                :maxTagCount="3"
+                @change="onTxlChanges"
+                @search="onTxlSearch"
+                @select="onTxlSelect"
+                :tree-data="addressBook"
+                :replaceFields="replaceTxlFields"
+            >
+            </a-tree-select>
+          </a-form-model-item>
+        </a-col>
+      </a-row>
+      <a-row :gutter="24">
+        <a-col :span="12">
+          <div style="display:flex;justify-content: space-between;align-items: center;">
 			    <b>选择接收单位:</b>
           <a-checkbox :checked="checkAll" @change="checkChange">
             全选
@@ -91,6 +120,7 @@
                 placeholder="选择工作通知接收单位"
                 allow-clear
                 multiple
+                :maxTagCount="3"
                 @change="onChanges"
                 @search="onSearch"
                 @select="onSelect"
@@ -109,7 +139,7 @@
           </div>
           <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">
+              <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id" :maxTagCount="3">
                 {{ item.recipientName }}({{item.company}} {{item.phone}})
               </a-select-option>
             </a-select>
@@ -153,7 +183,8 @@
 </template>
 
 <script>
-import { getPeerRecipient, getAreaWithUserIfo } from '@/api/user'
+import {getPeerRecipient, getAreaWithUserIfo, getUserByGroup} from '@/api/user'
+import { TreeSelect } from 'ant-design-vue';
 import { massSend } from "@/api/send";
 import {getUserInfo} from "@/util/storage";
 	export default {
@@ -171,13 +202,23 @@
           warningLevel: undefined,
           content: '',
           publishingUnit: '',
+          txlUsers: [],
           receiver: [],
           recipient: [],
+          addressBookRecipient: [],
           verticalRecipient: [],
           horizontalRecipient: []
         },
+        checkTxlAll: false,
         checkAll: false,
         checkSlAll: false,
+        addressBook: [],
+        replaceTxlFields: {
+          children:'userInfos',
+          title:'name',
+          key:'id',
+          value: 'id'
+        },
         areaUsers: [],
         replaceFields: {
           children:'children',
@@ -215,12 +256,42 @@
     created() {
       const t = this
       t.form.publishingUnit = t.userInfo.company
+      t.getUserByGroup()
       t.getSameLevel()
       t.getAreaUsers()
     },
     computed: {
 		},
 		methods: {
+      // 获取原通讯录
+      async getUserByGroup(){
+        let t = this
+        let res = await getUserByGroup()
+        if(res.data.code == 100){
+          if(res.data.data){
+            let bookData = []
+            bookData = res.data.data
+            for(let i in bookData){
+              if(!bookData[i].userInfos || bookData[i].userInfos.length == 0){
+                bookData.splice(i, 1)
+              }
+            }
+            for(let j of bookData){
+              j.id = j.id.toString() + '-' + '1'
+              j.userInfos.map((item)=>{
+                  item.name = item.name + '('+ item.company + ' ' + item.phone + ')'
+                  return item
+              })
+            }
+            t.addressBook = bookData
+          }else{
+            console.log('暂无数据')
+          }
+        }else{
+          this.$message.warning(res.data.msg);
+        }
+      },
+
       // 获取同级接收人
       async getSameLevel(){
         let t = this
@@ -254,16 +325,34 @@
         }
       },
 
+      //选择子部门部分
+      onTxlChanges(value,label,extra) {
+        const t = this
+        if(t.form.txlUsers.length == 0){
+          t.checkTxlAll = false
+        }
+      },
+      checkTxlChange(e) {
+        const t = this
+        this.checkTxlAll = !this.checkTxlAll
+        if(t.checkTxlAll == true){
+          let res = []
+          for(let i of t.addressBook){
+            if(i.userInfos && i.userInfos.length>0)
+            res = res.concat(...i.userInfos)
+          }
+          t.form.txlUsers = res.map(i=>i.id)
+        }else{
+          t.form.txlUsers = []
+        }
+      },
+
 			//选择子部门部分
 			onChanges(value,label,extra) {
         const t = this
         if(t.form.receiver.length == 0){
           t.checkAll = false
         }
-
-        // for(let i of value){
-        //   t.form.verticalRecipient = [...t.form.verticalRecipient,...t.findNodeById(t.areaUsers,i.value).users]
-        // }
       },
 
       checkChange(e) {
@@ -299,8 +388,20 @@
       confirmSend(){
         this.$refs.ruleForm.validate(valid => {
           if (valid) {
+            this.form.addressBookRecipient = []
             this.form.verticalRecipient = []
             this.form.horizontalRecipient = []
+
+            const address = this.form.txlUsers.map((item)=>
+                {
+                  this.findUserById(item).recipientType = 3
+                  const {addressBookGroupId,...data} = this.findUserById(item)
+                  data.name = data.name.split('(')[0]
+                  return data
+                }
+            )
+            this.form.addressBookRecipient = address
+
             const aList = this.form.receiver.map(item=>this.findNodeById(this.areaUsers,item.value)?.users)
             if(aList.includes(null)){
               this.$message.error('选择接收单位时存在无用户的单位')
@@ -313,6 +414,7 @@
               const obj = {recipientUnit,recipientType:1,...rest}
               this.form.verticalRecipient.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){
@@ -322,13 +424,14 @@
                 this.form.horizontalRecipient.push(noId)
               }
             }
-            const {receiver,recipient,...data} = this.form
+            const {txlUsers,receiver,recipient,...data} = this.form
             massSend(data).then( res =>{
               if(res.data.code == 100){
                 this.$message.success('信息群发成功')
                 this.$refs.ruleForm.clearValidate()
                 this.$refs.ruleForm.resetFields()
                 this.form.recipient = []
+                this.checkTxlAll = false
                 this.checkAll = false
                 this.checkSlAll = false
               }else{
@@ -348,6 +451,12 @@
         // console.log(...arguments);
       },
       onSelect() {
+        // console.log(...arguments);
+      },
+      onTxlSearch() {
+        // console.log(...arguments);
+      },
+      onTxlSelect() {
         // console.log(...arguments);
       },
 			//选择平级部门部分
@@ -391,6 +500,19 @@
         return null;
       },
 
+      findUserById(id){
+        for(let i of this.addressBook){
+          if(i.userInfos && i.userInfos.length>0){
+            for(let j of i.userInfos){
+              if(j.id == id){
+                return j
+              }
+            }
+          }
+        }
+        return null
+      },
+
       // 将树状数据所有id和name放入对象数组
       traverseTree(treeData) {
         let result = [];
diff --git a/src/views/Admin/msgRecord.vue b/src/views/Admin/msgRecord.vue
index 3faef87..9969882 100644
--- a/src/views/Admin/msgRecord.vue
+++ b/src/views/Admin/msgRecord.vue
@@ -12,7 +12,7 @@
         />
       </a-col>
       <a-col :span="4">
-        <a-button type="primary" @click="getData">查询</a-button>
+        <a-button type="primary" @click="searchData()">查询</a-button>
         <a-button style="margin-left: 12px" @click="resetSearch">重置</a-button>
       </a-col>
     </a-row>
@@ -102,6 +102,11 @@
       }
     },
 
+    searchData(){
+      this.search.pageIndex = 1
+      this.getData()
+    },
+
     resetSearch(){
       const t = this
       t.search = {
diff --git a/src/views/Admin/notice.vue b/src/views/Admin/notice.vue
index 09c6b7c..4fdcbc7 100644
--- a/src/views/Admin/notice.vue
+++ b/src/views/Admin/notice.vue
@@ -93,6 +93,7 @@
             <a-form-model-item prop="receiver" style="margin-bottom: 6px">
               <a-tree-select
                   show-search
+                  :maxTagCount="3"
                   tree-checkable
                   treeCheckStrictly
                   style="width: 100%"
@@ -121,7 +122,7 @@
               </a-checkbox>
             </div>
             <a-form-model-item prop="recipient">
-              <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle">
+              <a-select mode="multiple" placeholder="选择平级接收单位" v-model="form.recipient" @change="handle" :maxTagCount="3">
                 <a-select-option v-for="item in filteredOptions" :key="item.id" :value="item.id">
                   {{ item.recipientName }}({{item.company}} {{item.phone}})
                 </a-select-option>
diff --git a/src/views/Admin/release.vue b/src/views/Admin/release.vue
index 6adf908..00707b5 100644
--- a/src/views/Admin/release.vue
+++ b/src/views/Admin/release.vue
@@ -60,9 +60,9 @@
             <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 ? 'green' :text === 2? 'blue':text === 1?'orange':'red'">
-            {{text == 1 ? '均未叫应' : text == 2 ?'部分叫应':text == 3 ?'全部叫应' : ''}}
+        <template #responsesRate="text">
+          <a-tag :color="Number(text.split('%')[0]) == 100 ? 'green' :Number(text.split('%')[0]) == 0? 'red':'orange'">
+            {{ text }}
           </a-tag>
         </template>
         <template #operation="text, record, index">
@@ -141,10 +141,10 @@
 		},
 		{
 			title: '叫应情况',
-			dataIndex: 'responseSituation',
+			dataIndex: 'responsesRate',
 			width: '10%',
 			scopedSlots: {
-				customRender: 'responseSituation'
+				customRender: 'responsesRate'
 			}, //设置定制化表格数据
 		},
 		{
diff --git a/src/views/Admin/userManage.vue b/src/views/Admin/userManage.vue
index 585a1d8..340998f 100644
--- a/src/views/Admin/userManage.vue
+++ b/src/views/Admin/userManage.vue
@@ -268,7 +268,6 @@
     onChange(value) {
       const t = this
       t.search.searchParams.districtId = value[value.length - 1]
-      console.log(value,'val')
     },
     findAreaById(data,value) {
       for (const node of data) {
diff --git a/vue.config.js b/vue.config.js
index dc354e9..1048b70 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -10,4 +10,22 @@
             ],
         },
     },
+    configureWebpack: {
+        module: {
+            rules: [
+                {
+                    test: /\.(xlsx|xls)$/,
+                    use: [
+                        {
+                            loader: 'file-loader',
+                            options: {
+                                name: '[name].[ext]', // 保留原始文件名和扩展名
+                                outputPath: 'assets', // 输出文件的文件夹路径,可以根据需要更改
+                            },
+                        },
+                    ],
+                },
+            ],
+        },
+    }
 };

--
Gitblit v1.9.2