parent
cde7ea6e08
commit
608a91da19
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5a848505"],{"2a80":function(t,n,e){"use strict";e.r(n),e.d(n,"excelExport",(function(){return c}));e("5d63"),e("697e"),e("7b93"),e("dc64"),e("737f"),e("e508");var o=e("391f");function c(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"export-excel",c=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"xlsx",r=arguments.length>4&&void 0!==arguments[4]&&arguments[4];n.length||(n=Object.keys(t[0])),e||(e="export-excel"),c||(c="xlsx");var h=[],a=[];n.forEach((function(t){"string"===typeof t?(h.push(t),a.push(t)):(h.push(Object.values(t)[0]),a.push(Object.keys(t)[0]))}));var u=[];u.push(h),t.forEach((function(t){var n=[];a.forEach((function(e){n.push(t[e])})),u.push(n)}));var i=o["b"].book_new(),s=o["b"].aoa_to_sheet(u);if(r){for(var l=u.map((function(t){return t.map((function(t){return null==t?{wch:10}:t.toString().charCodeAt(0)>255?{wch:2*t.toString().length+2}:{wch:t.toString().length+3}}))})),f=l[0],p=1;p<l.length;p++)for(var v=0;v<l[p].length;v++)f[v]["wch"]<l[p][v]["wch"]&&(f[v]["wch"]=l[p][v]["wch"]);s["!cols"]=f}else{var g=[];h.forEach((function(t){var n={};null===t||void 0===t?n.wch=10:t.toString().charCodeAt(0)>255?n.wch=2*t.toString().length+2:n.wch=t.toString().length+2,g.push(n)})),s["!cols"]=g}o["b"].book_append_sheet(i,s,e),o["c"](i,e+"."+c)}},ae0a:function(t,n,e){var o=e("d50f"),c=e("a63b"),r=e("307f"),h=e("8280"),a=e("dc05").f,u=c(a),i=c([].push),s=function(t){return function(n){var e,c=h(n),a=r(c),s=a.length,l=0,f=[];while(s>l)e=a[l++],o&&!u(c,e)||i(f,t?[e,c[e]]:c[e]);return f}};t.exports={entries:s(!0),values:s(!1)}},dc64:function(t,n,e){var o=e("50c8"),c=e("ae0a").values;o({target:"Object",stat:!0},{values:function(t){return c(t)}})}}]);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -17,6 +17,7 @@
|
|||
"e-icon-picker": "^1.1.7",
|
||||
"echarts": "5.3.3",
|
||||
"element-ui": "2.15.8",
|
||||
"file-saver": "^2.0.5",
|
||||
"fuse.js": "3.6.1",
|
||||
"js-cookie": "3.0.1",
|
||||
"normalize.css": "8.0.1",
|
||||
|
@ -24,10 +25,12 @@
|
|||
"path-to-regexp": "6.2.1",
|
||||
"qrcode.vue": "1.7.0",
|
||||
"screenfull": "5.2.0",
|
||||
"script-loader": "^0.7.2",
|
||||
"vue": "2.6.14",
|
||||
"vue-router": "3.5.4",
|
||||
"vuex": "3.6.2",
|
||||
"wangeditor": "4.7.15"
|
||||
"wangeditor": "4.7.15",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "4.5.12",
|
||||
|
|
|
@ -89,6 +89,17 @@ export function disable(data) {
|
|||
data
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 会员导入
|
||||
* @param {array} data 请求数据
|
||||
*/
|
||||
export function imports(data) {
|
||||
return request({
|
||||
url: url + 'import',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 会员统计
|
||||
* @param {array} params 请求参数
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
import * as XLSX from 'xlsx'
|
||||
|
||||
/**
|
||||
* 导出
|
||||
* @param {array} data 数据
|
||||
* @param {array} header 表头,eg:[{ member_id: '会员id' }, { username: '会员名' }]
|
||||
* @param {string} fileName 文件名
|
||||
* @param {string} bookType 文件类型:xlsx, csv, txt
|
||||
* @param {bool} autoWidth 宽度是否自适应
|
||||
*/
|
||||
export function excelExport(data, header = [], fileName = 'export-excel', bookType = 'xlsx', autoWidth = false) {
|
||||
if (!header.length) {
|
||||
header = Object.keys(data[0])
|
||||
}
|
||||
|
||||
if (!fileName) {
|
||||
fileName = 'export-excel'
|
||||
}
|
||||
|
||||
if (!bookType) {
|
||||
bookType = 'xlsx'
|
||||
}
|
||||
|
||||
// 表头名称,导出字段
|
||||
const headerName = []
|
||||
const headerField = []
|
||||
header.forEach((ihn) => {
|
||||
if (typeof ihn === 'string') {
|
||||
headerName.push(ihn)
|
||||
headerField.push(ihn)
|
||||
} else {
|
||||
headerName.push(Object.values(ihn)[0])
|
||||
headerField.push(Object.keys(ihn)[0])
|
||||
}
|
||||
})
|
||||
|
||||
// 导出数据
|
||||
const xlsxData = []
|
||||
xlsxData.push(headerName)
|
||||
data.forEach((id) => {
|
||||
const rowData = []
|
||||
headerField.forEach((ihf) => {
|
||||
rowData.push(id[ihf])
|
||||
})
|
||||
xlsxData.push(rowData)
|
||||
})
|
||||
|
||||
const workbook = XLSX.utils.book_new()
|
||||
const worksheet = XLSX.utils.aoa_to_sheet(xlsxData)
|
||||
|
||||
// 设置列宽
|
||||
if (autoWidth) {
|
||||
const colWidth = xlsxData.map(row => row.map(val => {
|
||||
if (val == null) {
|
||||
return {
|
||||
'wch': 10
|
||||
}
|
||||
} else if (val.toString().charCodeAt(0) > 255) {
|
||||
return {
|
||||
'wch': val.toString().length * 2 + 2
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
'wch': val.toString().length + 3
|
||||
}
|
||||
}
|
||||
}))
|
||||
const cols = colWidth[0]
|
||||
for (let i = 1; i < colWidth.length; i++) {
|
||||
for (let j = 0; j < colWidth[i].length; j++) {
|
||||
if (cols[j]['wch'] < colWidth[i][j]['wch']) {
|
||||
cols[j]['wch'] = colWidth[i][j]['wch']
|
||||
}
|
||||
}
|
||||
}
|
||||
worksheet['!cols'] = cols
|
||||
} else {
|
||||
const cols = []
|
||||
headerName.forEach((val) => {
|
||||
const col = {}
|
||||
if (val === null || val === undefined) {
|
||||
col.wch = 10
|
||||
} else if (val.toString().charCodeAt(0) > 255) {
|
||||
col.wch = val.toString().length * 2 + 2
|
||||
} else {
|
||||
col.wch = val.toString().length + 2
|
||||
}
|
||||
cols.push(col)
|
||||
})
|
||||
worksheet['!cols'] = cols
|
||||
}
|
||||
|
||||
// 下载文件
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, fileName)
|
||||
XLSX.writeFile(workbook, fileName + '.' + bookType)
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<div style="display:flex;float:right">
|
||||
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls, .csv" @change="handleClick">
|
||||
<el-button :loading="loading" @click="handleUpload">{{ title }}</el-button>
|
||||
<el-dialog :title="dialogTitle" :visible.sync="dialogSync" top="5vh" width="70%" :close-on-click-modal="false" :close-on-press-escape="false">
|
||||
<el-form label-width="0">
|
||||
<el-form-item label="" prop="">
|
||||
<el-table v-loading="loading" :data="excelData.results" :height="height">
|
||||
<el-table-column v-for="item of excelData.header" :key="item" :prop="item" :label="item" />
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :loading="loading" @click="cancel">取消</el-button>
|
||||
<el-button :loading="loading" type="primary" @click="submit">导入</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as XLSX from 'xlsx'
|
||||
import screenHeight from '@/utils/screen-height'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
limitSize: { type: Number, default: 1 },
|
||||
title: { type: String, default: '导入' }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
height: 580,
|
||||
dialogTitle: '导入预览',
|
||||
dialogSync: false,
|
||||
excelData: {
|
||||
header: null,
|
||||
results: null
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.height = screenHeight()
|
||||
},
|
||||
methods: {
|
||||
cancel() {
|
||||
this.dialogSync = false
|
||||
},
|
||||
submit() {
|
||||
this.dialogSync = false
|
||||
this.$emit('on-import', this.excelData)
|
||||
},
|
||||
generateData({ header, results }) {
|
||||
this.excelData.header = header
|
||||
this.excelData.results = results
|
||||
this.dialogSync = true
|
||||
},
|
||||
handleDrop(e) {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
if (this.loading) return
|
||||
const files = e.dataTransfer.files
|
||||
if (files.length !== 1) {
|
||||
this.$message.error('只能上传一个文件')
|
||||
return
|
||||
}
|
||||
const rawFile = files[0]
|
||||
|
||||
if (!this.isExcel(rawFile)) {
|
||||
this.$message.error('文件类型仅支持 xlsx、xls、csv')
|
||||
return false
|
||||
}
|
||||
this.upload(rawFile)
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
},
|
||||
handleUpload() {
|
||||
this.$refs['excel-upload-input'].click()
|
||||
},
|
||||
handleClick(e) {
|
||||
const files = e.target.files
|
||||
const rawFile = files[0]
|
||||
if (!rawFile) return
|
||||
this.upload(rawFile)
|
||||
},
|
||||
upload(rawFile) {
|
||||
this.$refs['excel-upload-input'].value = null
|
||||
|
||||
if (!this.beforeUpload) {
|
||||
this.readerData(rawFile)
|
||||
return
|
||||
}
|
||||
const before = this.beforeUpload(rawFile)
|
||||
if (before) {
|
||||
this.readerData(rawFile)
|
||||
}
|
||||
},
|
||||
beforeUpload(file) {
|
||||
const limitSize = this.limitSize
|
||||
const fileSize = file.size / 1024 / 1024
|
||||
|
||||
if (fileSize > limitSize) {
|
||||
this.$message.error(`文件大小不能大于 ${limitSize} m`)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
readerData(rawFile) {
|
||||
this.loading = true
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader()
|
||||
reader.onload = e => {
|
||||
const data = e.target.result
|
||||
const workbook = XLSX.read(data, { type: 'array' })
|
||||
const firstSheetName = workbook.SheetNames[0]
|
||||
const worksheet = workbook.Sheets[firstSheetName]
|
||||
const header = this.getHeaderRow(worksheet)
|
||||
const results = XLSX.utils.sheet_to_json(worksheet)
|
||||
this.generateData({ header, results })
|
||||
this.loading = false
|
||||
resolve()
|
||||
}
|
||||
reader.readAsArrayBuffer(rawFile)
|
||||
})
|
||||
},
|
||||
getHeaderRow(sheet) {
|
||||
const headers = []
|
||||
const range = XLSX.utils.decode_range(sheet['!ref'])
|
||||
let C
|
||||
const R = range.s.r
|
||||
for (C = range.s.c; C <= range.e.c; ++C) {
|
||||
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
|
||||
let hdr = 'UNKNOWN ' + C
|
||||
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
|
||||
headers.push(hdr)
|
||||
}
|
||||
return headers
|
||||
},
|
||||
isExcel(file) {
|
||||
return /\.(xlsx|xls|csv)$/.test(file.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.excel-upload-input{
|
||||
display: none;
|
||||
z-index: -9999;
|
||||
}
|
||||
</style>
|
|
@ -69,8 +69,12 @@
|
|||
<el-button title="重置密码" @click="selectOpen('repwd')">密码</el-button>
|
||||
<el-button title="是否禁用" @click="selectOpen('disable')">禁用</el-button>
|
||||
<el-button title="删除" @click="selectOpen('dele')">删除</el-button>
|
||||
<el-button title="导出" @click="selectOpen('export')">导出</el-button>
|
||||
<el-button v-if="recycle" type="primary" @click="selectOpen('reco')">恢复</el-button>
|
||||
<el-button v-else type="primary" @click="add()">添加</el-button>
|
||||
<el-tooltip class="item" effect="dark" content="表头:昵称,用户名,手机,邮箱,密码" placement="left">
|
||||
<excel-import v-if="checkPermission(['admin/member.Member/export'])" :limit-size="1" title="导入" @on-import="imports" />
|
||||
</el-tooltip>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-dialog :title="selectTitle" :visible.sync="selectDialog" top="20vh" :close-on-click-modal="false" :close-on-press-escape="false">
|
||||
|
@ -100,6 +104,20 @@
|
|||
<span v-if="recycle" style="color:red">确定要彻底删除选中的{{ name }}吗?删除后不可恢复!</span>
|
||||
<span v-else style="color:red">确定要删除选中的{{ name }}吗?</span>
|
||||
</el-form-item>
|
||||
<div v-else-if="selectType==='export'">
|
||||
<el-form-item label="文件名称" prop="">
|
||||
<el-input v-model="exportFileName" placeholder="请输入文件名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="文件类型" prop="">
|
||||
<el-select v-model="exportBookType">
|
||||
<el-option v-for="item in ['xlsx','csv', 'txt']" :key="item" :label="item" :value="item" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="自动宽度" prop="">
|
||||
<el-switch v-model="exportAutoWidth" :active-value="true" :inactive-value="false" />
|
||||
<span> 宽度是否自适应</span>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item v-else-if="selectType==='reco'" label="" prop="">
|
||||
<span style="color:red">确定要恢复选中的{{ name }}吗?</span>
|
||||
</el-form-item>
|
||||
|
@ -290,16 +308,18 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import checkPermission from '@/utils/permission' // 权限判断函数
|
||||
import screenHeight from '@/utils/screen-height'
|
||||
import Pagination from '@/components/Pagination'
|
||||
import FileManage from '@/components/FileManage'
|
||||
import clip from '@/utils/clipboard'
|
||||
import ExcelImport from '@/components/ExcelImport/index.vue'
|
||||
import { arrayColumn } from '@/utils/index'
|
||||
import { list, info, add, edit, dele, region, repwd, disable, recover, recoverReco, recoverDele } from '@/api/member/member'
|
||||
import { list, info, add, edit, dele, region, repwd, disable, imports, recover, recoverReco, recoverDele } from '@/api/member/member'
|
||||
|
||||
export default {
|
||||
name: 'Member',
|
||||
components: { Pagination, FileManage },
|
||||
components: { Pagination, FileManage, ExcelImport },
|
||||
data() {
|
||||
return {
|
||||
name: '会员',
|
||||
|
@ -350,7 +370,10 @@ export default {
|
|||
region_id: 0,
|
||||
password: '',
|
||||
is_disable: 0,
|
||||
fileDialog: false
|
||||
fileDialog: false,
|
||||
exportFileName: '',
|
||||
exportBookType: 'xlsx',
|
||||
exportAutoWidth: false
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -359,6 +382,7 @@ export default {
|
|||
this.list()
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
// 列表
|
||||
list() {
|
||||
this.loading = true
|
||||
|
@ -489,6 +513,14 @@ export default {
|
|||
this.selectTitle = '是否禁用'
|
||||
} else if (selectType === 'dele') {
|
||||
this.selectTitle = '删除' + this.name
|
||||
} else if (selectType === 'export') {
|
||||
var date = new Date()
|
||||
var month = date.getMonth() + 1
|
||||
month = month < 10 ? '0' + month : month
|
||||
this.exportFileName = this.name + date.getFullYear() + '-' + month + '-' + date.getDate()
|
||||
this.selectTitle = '导出'
|
||||
} else if (selectType === 'import') {
|
||||
this.selectTitle = '导入'
|
||||
} else if (selectType === 'reco') {
|
||||
this.selectTitle = '恢复' + this.name
|
||||
}
|
||||
|
@ -512,6 +544,10 @@ export default {
|
|||
this.disable(this.selection, true)
|
||||
} else if (selectType === 'dele') {
|
||||
this.dele(this.selection)
|
||||
} else if (selectType === 'export') {
|
||||
this.export(this.selection)
|
||||
} else if (selectType === 'import') {
|
||||
this.import(this.selection)
|
||||
} else if (selectType === 'reco') {
|
||||
this.reco(this.selection)
|
||||
}
|
||||
|
@ -604,6 +640,35 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
// 导出
|
||||
export(row) {
|
||||
this.loading = true
|
||||
import('@/components/ExcelExport/index').then(excel => {
|
||||
const header = [
|
||||
{ member_id: '会员id' },
|
||||
{ nickname: '昵称' },
|
||||
{ username: '用户名' },
|
||||
{ phone: '手机' },
|
||||
{ email: '邮箱' },
|
||||
{ remark: '备注' },
|
||||
{ create_time: '注册时间' }
|
||||
]
|
||||
excel.excelExport(row, header, this.exportFileName, this.exportBookType, this.exportAutoWidth)
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 导入,results数据,header表头
|
||||
imports({ results, header }) {
|
||||
this.loading = true
|
||||
imports({
|
||||
import: results
|
||||
}).then(res => {
|
||||
this.list()
|
||||
this.$message.success(res.msg)
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
// 恢复
|
||||
reco(row) {
|
||||
if (!row.length) {
|
||||
|
|
Loading…
Reference in New Issue