util.js
* exportExcelFile 导出xlsx 文件
/**
* @method exportExcelFile 导出xlsx 文件
* @param {Array} excelData 需要装成xlsx 文件的数组
* @param {String} fileName xlsx 文件名,非必传,不传就是'下载文件'
* @example exportExcelFile([['姓名','年龄'],['王大锤',18],['Ghf','23']], '人员信息表') 数组格式为Arrays
*
*/
export function exportExcelFile(excelData, fileName = '下载文件') {
const ws = XLSX.utils.aoa_to_sheet(excelData);
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "SheetJS");
XLSX.writeFile(wb, `${fileName}.xlsx`);
}
页面引用
<template>
<div class="list-of-participants">
<!-- 搜索框 -->
<div class="search-panel">
<div class="list-of-participants-list-title">参会人列表</div>
<query-search-white :search="searchlist" @submit="onSubmit"></query-search-white>
</div>
<div class="list-of-participants-box">
<div class="list-of-participants-title flex-between">
<div class="list-of-participants-title-left flex-top-end">
<el-checkbox v-model="isAll" class="select-all flex-center" @change="selectAll"
>全选</el-checkbox
>
<div class="selected-num flex-start">
已选择 <span>{{ isAll == true ? total : selectionNum }}</span
>个
</div>
</div>
<div class="flex-end">
<!-- 添加到标签 -->
<div class="btn-mg">
<el-popover placement="bottom" trigger="manual" width="352" v-model="labelPopover">
<div class="add-to-label-panel">
<div class="add-to-label-title">将{{ selectionNum }}位参会人添加以下标签</div>
<div class="add-to-label-search">
<el-input
placeholder="搜索:标签名称"
v-model="searchAddLable"
class="input-with-select"
>
<el-button slot="append" icon="el-icon-search" @click="searchLable"></el-button>
</el-input>
</div>
<div class="add-to-label-cont flex-row-wrap">
<div
class="add-to-label-item"
@click="selectLables(index, item.participantsLabelId)"
v-for="(item, index) in lableItem"
:key="index"
:class="checkList.indexOf(index) === -1 ? '' : 'labelActive'"
>
{{ item.labelName }}
</div>
</div>
<el-button
v-show="showAddBtn"
type="text"
class="add-label-text"
icon="el-icon-plus"
@click="addLable"
>新建标签</el-button
>
<div class="add-label-panel flex-start" v-show="showAddIpt">
<div class="add-label-ipt">
<el-input
type="text"
placeholder="请输入标签名称"
v-model="labelName"
maxlength="10"
show-word-limit
>
</el-input>
</div>
<el-button
type="text"
class="add-label-ok"
:loading="submitFlag"
@click="addLabelName"
>确定</el-button
>
<el-button
type="text"
class="add-label-canel"
style="color: rgba(36, 46, 66, 0.8) !important"
@click="canelAddLable"
>取消</el-button
>
</div>
<div class="add-lable-btn">
<el-button
type="primary"
class="small-com-botton"
:loading="submitFlag"
@click="okAddLabels"
>确定</el-button
>
<el-button class="small-com-botton" @click="canelLabelPopover">取消</el-button>
</div>
</div>
<el-button slot="reference" class="white-botton" @click="addToLabel"
>添加到标签
</el-button>
</el-popover>
</div>
<el-button class="white-botton" @click="goManageTags">管理标签</el-button>
<el-button class="white-botton" @click="exportDataDetails">导出参会人</el-button>
<el-button class="blue-botton" @click="goSendTo">发送短信</el-button>
</div>
</div>
<div class="list-of-participants-cont">
<div class="list-of-participants-table com-table-white">
<el-table
ref="multipleTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="participantsName" label="姓名" min-width="130"></el-table-column>
<el-table-column
prop="participantsPhone"
label="手机号"
min-width="130"
></el-table-column>
<el-table-column label="邮箱" min-width="130">
<template slot-scope="scope">
{{ scope.row.participantsEmail || '—' }}
</template>
</el-table-column>
<el-table-column label="单位(公司)" min-width="200">
<template slot-scope="scope">
{{ scope.row.participantsCompany || '—' }}
</template></el-table-column
>
<el-table-column label="职务" min-width="200">
<template slot-scope="scope">
{{ scope.row.participantsPosition || '—' }}
</template></el-table-column
>
<el-table-column
prop="attendanceRecord"
label="总参会次数"
min-width="100"
></el-table-column>
<el-table-column prop="payOrderAmount" label="标签" min-width="240">
<template slot-scope="scope">
<span v-if="scope.row.labelNameList">
<el-tag
type="info"
class="tab-el-tag"
disable-transitions
v-for="(item, index) in scope.row.labelNameList.split(',')"
:key="index"
style="margin: 0.04rem"
>{{ item }}</el-tag
></span
>
<span v-else>—</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="100">
<template slot-scope="scope">
<el-button type="text" @click="editAttendees(scope.$index, scope.row)"
>编辑
</el-button>
</template>
</el-table-column>
<div slot="empty" class="empty">
<img :src="`${ASSET_HOST}/event/activity_null.png`" />
<span>暂无数据</span>
</div>
</el-table>
</div>
<div class="pagination-panel flex-end">
<div class="total-pages">
共
<span>{{ total }}</span> 条数据
</div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="pageIndex"
:page-size="pageSize"
layout="sizes, prev, pager, next,jumper"
:total="total"
></el-pagination>
</div>
</div>
</div>
<!--发送对象 -->
<database-send-to v-model="showSendTo"></database-send-to>
<!--编辑参会人 -->
<edit-attendees v-model="showAttendees" :attendeesData="attendeesData"></edit-attendees>
</div>
</template>
<script>
import { mapState} from 'vuex';
import {exportExcelFile} from '@/util/util';
export default {
components: {
querySearchWhite: () => import('@/components/common/query-search-white.vue'),
'database-send-to': () => import('@/pages/event-management/database-send-to.vue'), // 发送对象
'edit-attendees': () => import('@/pages/event-management/edit-attendees.vue'), // 编辑参会人
},
data() {
return {
pageIndex: 1,
pageSize: 10,
total: 0,
isAll: false,
submitFlag: false, //防重复点击
labelPopover: false, //添加到标签
searchAddLable: '', //搜索标签
inputItem: {
keyword: '',
participantsLabelId: '',
},
searchlist: [
{
type: 'input',
model: '',
placeholder: '可按姓名、手机号、邮箱、单位(公司)、职务搜索',
key: 'keyword',
},
],
lableItem: [], //添加到标签弹框之标签列表
checkList: [], //添加到标签弹框之选中的标签
checkLabelList: [], //选中的标签id
isFleg: false, //是否自主选择时间
tableData: [], //列表数据(分页)
allTableData: [], //全部列表数据
labelName: '', //标签名
showAddBtn: true, //添加标签按钮
showAddIpt: false, //添加标签文本框
multipleSelection: [], //选中
selectionNum: 0, //已选择条数
dataBaseExcel: [['姓名', '手机号', '邮箱', '单位(公司)', '职务', '总参会次数', '标签']],
showSendTo: false, //发送对象弹框
showAttendees: false, //编辑参会人
attendeesData: {}, ///编辑的参会人数据
};
},
computed: {
...mapState('activityMange', ['curActivityDetail']),
},
methods: {
//提交查询
onSubmit(data) {
if (data.type == 1) {
//重置
this.searchlist = data.reset;
}
this.inputItem = data.dataInfo;
this.pageIndex = 1;
this.getDataDetailList();
},
// 获取参会人标签
getAllLabel() {
this.$api.activityManageApi
.getAllLabel({})
.then((res) => {
let { code, data } = res;
if (code == 0) {
this.participantLabel = data;
var participantList = data;
var participantListInfo = [];
participantList.forEach((item) => {
participantListInfo.push({ label: item.labelName, value: item.participantsLabelId });
});
this.searchlist.push({
type: 'select',
model: '',
key: 'participantsLabelId',
selecType: participantListInfo,
placeholder: '请选择参会人标签',
});
}
})
.catch(() => {});
},
// 获取标签列表
getLabelList() {
let params = `/${this.searchAddLable || '{keyword}'}?page=1&pageSize=100000`;
this.$api.activityManageApi
.getLabelList(params)
.then((res) => {
let { code, data } = res;
if (code == 0) {
this.lableItem = data.list;
}
})
.catch(() => {});
},
// 点击按钮查询标签列表
addToLabel() {
if (this.multipleSelection.length <= 0) {
this.$message({
message: '请选中需要添加标签的参会人',
type: 'warning',
});
return;
}
this.getLabelList(); //获取标签列表
this.labelPopover = true; //打开弹框
},
// 搜索标签
searchLable() {
this.getLabelList();
},
// 添加到标签
addLable() {
this.showAddBtn = false;
this.showAddIpt = true;
},
// 关闭新建标签
canelAddLable() {
this.showAddBtn = true;
this.showAddIpt = false;
this.labelName = '';
},
// 选择标签
selectLables(type, id) {
if (this.checkList.indexOf(type) == -1) {
this.checkList.push(type);
this.checkLabelList.push(id); //id集合
} else {
let index = this.checkList.findIndex((item) => item === type);
let id = this.checkLabelList.findIndex((item) => item === id);
this.checkList.splice(index, 1);
this.checkLabelList.splice(id, 1); //清除id
}
},
// 添加标签
addLabelName() {
let params = {
labelName: this.labelName,
participantsLabelId: null,
};
this.$api.activityManageApi.addEditLabel(params).then(({ code, data, msg }) => {
this.submitFlag = true;
if (code === 0 && data) {
this.getLabelList();
this.submitFlag = false;
this.searchAddLable = ''; //置空数据
} else {
this.$message.error(msg);
}
});
},
// 确定添加标签
okAddLabels() {
if (this.multipleSelection.length > 0) {
this.submitFlag = true;
let data = this.multipleSelection;
let idList = data.map((item) => {
let parmas = {
labelIdList: this.checkLabelList.toString(),
participantsDatabaseUserId: item.participantsDatabaseUserId,
};
return parmas;
});
this.$api.activityManageApi
.addParticipants(idList)
.then((res) => {
let { code, msg } = res;
if (code == 0) {
this.submitFlag = false;
this.$refs.multipleTable.clearSelection();
this.getDataDetailList();
this.$message({
message: '添加成功',
type: 'success',
});
this.labelPopover = false;
} else {
this.$message({
message: msg,
type: 'warning',
});
}
})
.catch(() => {});
} else {
this.$message({
message: '请先选择要添加标签的参会人',
type: 'warning',
});
}
},
canelLabelPopover() {
this.$refs.multipleTable.clearSelection(); //清空复选框选中行
this.checkList = []; //清空标签选中效果
this.checkLabelList = []; //清空选中id
this.labelPopover = false; //关闭弹框
this.showAddBtn = true; //显示添加按钮
this.showAddIpt = false; //隐藏添加标签的ipt
this.labelName = ''; //清空标签
},
// 获取参会人列表
getDataDetailList() {
let { participantsLabelId, keyword } = this.inputItem;
this.$api.activityManageApi
.getDatabaseList({
page: this.pageIndex,
pageSize: this.pageSize,
keyword,
participantsLabelId,
})
.then((res) => {
let { code, data, msg } = res;
if (code == 0 && data) {
this.tableData = data.list;
this.total = Number(data.pagination.total);
} else {
this.$message({
message: msg,
type: 'warning',
});
}
})
.catch(() => {});
},
// 复选框选中
handleSelectionChange(val) {
this.multipleSelection = val;
this.selectionNum = val.length;
},
// 全选
selectAll() {
if (this.isAll == true) {
this.$refs.multipleTable.clearSelection();
this.$nextTick(() => {
// let newData = [...this.tableData, ...this.allTableData];
this.tableData.forEach((item) => {
// 根据后端返回是否勾选的字段判断是否勾选
this.$refs.multipleTable.toggleRowSelection(item);
});
});
} else {
this.$refs.multipleTable.clearSelection();
}
},
// 编辑参会人
editAttendees(index, item) {
this.attendeesData = item;
this.$nextTick(() => {
this.showAttendees = true;
});
},
// 跳转管理标签
goManageTags() {
this.$router.push({ path: '/manage-tags' });
},
getAllTableList() {
let { participantsLabelId, keyword } = this.inputItem;
this.$api.activityManageApi
.getDatabaseList({
page: 1,
pageSize: 100000,
keyword,
participantsLabelId,
})
.then((res) => {
let { code, data } = res;
if (code == 0 && data) {
this.allTableData = data.list;
}
});
},
// 发送短信
goSendTo() {
this.showSendTo = true;
},
//导出参会人列表
exportDataDetails() {
this.dialogExport = false;
// 接口全部导出
if (this.multipleSelection.length <= 0) {
this.$api.commonApi.exportExcelFile(
`/participants/export?page=1&pageSize=${this.total}`,
'参会人列表.xls',
);
return;
} else {
// 全选全部导出
if (this.isAll) {
let data = this.allTableData;
let excelData = [
['姓名', '手机号', '邮箱', '单位(公司)', '职务', '总参会次数', '标签'],
];
for (let i in data) {
let temp = [];
temp.push(data[i].participantsName);
temp.push(data[i].participantsPhone);
temp.push(data[i].participantsEmail);
temp.push(data[i].participantsCompany);
temp.push(data[i].participantsPosition);
temp.push(data[i].attendanceRecord);
temp.push(data[i].labelNameList);
excelData.push(temp);
}
exportExcelFile(excelData, '参会人列表');
return;
} else {
let dataList = this.multipleSelection;
let excelData = [
['姓名', '手机号', '邮箱', '单位(公司)', '职务', '总参会次数', '标签'],
];
for (let i in dataList) {
let temp = [];
temp.push(dataList[i].participantsName);
temp.push(dataList[i].participantsPhone);
temp.push(dataList[i].participantsEmail);
temp.push(dataList[i].participantsCompany);
temp.push(dataList[i].participantsPosition);
temp.push(dataList[i].attendanceRecord);
temp.push(dataList[i].labelNameList);
excelData.push(temp);
}
exportExcelFile(excelData, '参会人列表');
return;
}
}
},
// 分页
handleSizeChange(val) {
this.pageSize = val;
this.getDataDetailList();
this.isAll = false; //分页取消全选
},
handleCurrentChange(val) {
this.pageIndex = val;
this.getDataDetailList();
this.isAll = false; //分页取消全选
},
},
created() {
// 活动ID
this.activityId = this.curActivityDetail.id;
// 获取参会人标签
this.getAllLabel();
// 获取表单信息
this.getDataDetailList();
// 获取参会人所有信息
this.getAllTableList();
},
mounted: function () {
this.$nextTick(function () {
this.$on('getDataDetailList', function () {
console.log('监听成功');
});
});
},
};
</script>
<style lang="scss">
// 添加到标签
.add-to-label-panel {
.add-to-label-title {
font-size: 0.14rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #242e42;
line-height: 20px;
}
.add-to-label-search {
margin: 0.14rem 0 0.18rem 0;
}
.add-to-label-item {
padding: 0.05rem 0.08rem;
font-size: 0.12rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #505868;
border-radius: 0.04rem;
border: 1px solid #979797;
margin: 0 0.08rem 0.08rem 0;
cursor: pointer;
}
.labelActive {
background: rgba(235, 238, 245, 1);
border: 1px solid rgba(235, 238, 245, 1);
color: #242e42;
}
/deep/.add-label-text {
font-size: 0.14rem;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #0064ff;
}
.add-label-panel {
width: 100%;
}
.add-label-ipt {
flex: 1;
margin-right: 0.08rem;
}
.add-lable-btn {
margin-top: 0.15rem;
text-align: right;
}
}
</style>
<style lang="scss" scoped>
.list-of-participants {
.btn-mg {
margin-right: 10px;
}
.list-of-participants-list-title {
font-size: 18px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: bold;
color: #242e42;
margin-bottom: 0.16rem;
}
// 搜索
.search-panel {
background: #ffffff;
border-radius: 0.02rem;
padding: 0.24rem 0.24rem 0.16rem 0.24rem;
margin-bottom: 0.08rem;
}
// 标题
.list-of-participants-box {
width: 100%;
height: auto;
background: #ffffff;
box-shadow: 0 0.02rem 0.04rem 0 rgba(97, 131, 155, 0.06);
border-radius: 0.04rem;
}
.list-of-participants-title {
padding: 0.13rem 0.2rem;
.list-of-participants-title-left {
.select-all {
font-size: 0.14rem;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: bold;
color: #242e42;
margin-right: 0.08rem;
/deep/.el-checkbox__label {
padding-left: 4px;
}
}
.selected-num {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #7c828e;
line-height: 20px;
}
}
}
// 内容
.list-of-participants-cont {
padding: 0 0.22rem 0.17rem 0.2rem;
}
}
</style>