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