会员升级

This commit is contained in:
Paidax
2025-10-22 09:45:32 +08:00
parent 2d7a74fd87
commit 9427e8057e
8 changed files with 257 additions and 51 deletions
@@ -259,24 +259,37 @@ public class MemberChangeManageController {
Sql sql = memberCommonService.getSql(pageForm);
List<NutMap> list = memberCommonService.listMap(sql);
List<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("工号", "loginname", 20));
exportEntities.add(new ExcelExportEntity("姓名", "username", 20));
exportEntities.add(new ExcelExportEntity("性别", "sex", 20));
exportEntities.add(new ExcelExportEntity("出生年月", "birthday", 20));
exportEntities.add(new ExcelExportEntity("联系电话", "mobile", 20));
exportEntities.add(new ExcelExportEntity("福利号码", "welfareMobile", 20));
exportEntities.add(new ExcelExportEntity("在职状态", "userState", 20));
exportEntities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
exportEntities.add(new ExcelExportEntity("人员类型", "personType", 20));
exportEntities.add(new ExcelExportEntity("所属工会", "unionName", 20));
exportEntities.add(new ExcelExportEntity("所属单位", "unitName", 30));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
try {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
Workbook workbook = null;
if (Lang.isNotEmpty(pageForm.getColumns())) {
List<ExcelExportEntity> exportEntities = new ArrayList<>();
pageForm.getColumns().forEach(column -> {
exportEntities.add(new ExcelExportEntity(column.get("label"), column.get("prop"), 20));
});
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
} else {
List<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("工号", "loginname", 20));
exportEntities.add(new ExcelExportEntity("姓名", "username", 20));
exportEntities.add(new ExcelExportEntity("性别", "sex", 20));
exportEntities.add(new ExcelExportEntity("出生年月", "birthday", 20));
exportEntities.add(new ExcelExportEntity("联系电话", "mobile", 20));
exportEntities.add(new ExcelExportEntity("福利号码", "welfareMobile", 20));
exportEntities.add(new ExcelExportEntity("在职状态", "userState", 20));
exportEntities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
exportEntities.add(new ExcelExportEntity("人员类型", "personType", 20));
exportEntities.add(new ExcelExportEntity("所属工会", "unionName", 20));
exportEntities.add(new ExcelExportEntity("所属单位", "unitName", 30));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
}
CommonDownloadUtil.download("会员名单.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
@@ -1,5 +1,9 @@
package com.budwk.app.zhgh.staffmanage.member.controller.statistics;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.DesensitizedUtil;
import com.budwk.app.base.page.Pagination;
@@ -12,11 +16,13 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
@@ -63,9 +69,24 @@ public class MemberComprehensiveController {
List<NutMap> list = memberStatisticsService.listMap(sql);
for (NutMap row : list) {
row.put("mobile", DesensitizedUtil.mobilePhone(row.getString("mobile")));
row.put("idCard", DesensitizedUtil.idCardNum(row.getString("idCard"), 3, 4));
}
try {
Workbook workbook = memberInfoService.setHistoryExcelData(list);
Workbook workbook = null;
if (Lang.isNotEmpty(pageForm.getColumns())) {
List<ExcelExportEntity> exportEntities = new ArrayList<>();
pageForm.getColumns().forEach(column -> {
exportEntities.add(new ExcelExportEntity(column.get("label"), column.get("prop"), 20));
});
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
} else {
workbook = memberInfoService.setHistoryExcelData(list);
}
CommonDownloadUtil.download("会员综合统计表.xlsx", workbook, response);
} catch (Exception e) {
e.printStackTrace();
@@ -6,6 +6,7 @@ import com.budwk.app.base.param.PageForm;
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.Cnd;
@@ -14,6 +15,7 @@ import org.nutz.dao.util.cri.Static;
import org.nutz.lang.Lang;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
@@ -59,6 +61,9 @@ public class MemberManagePageForm extends PageForm {
//变更来源
private List<Integer> changeOrigins;
@ApiModelProperty("导出的数据")
private List<Map<String, String>> columns;
public static void buildSearch(Cnd cnd, MemberManagePageForm pageForm) {
if (cnd == null) {
cnd = Cnd.NEW();
@@ -7,6 +7,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
@@ -97,4 +98,7 @@ public class MemberStatisticsPageForm extends PageForm {
@ApiModelProperty(value = "结束离会时间(会员)")
private String endLeaveDate;
@ApiModelProperty("导出的数据")
private List<Map<String, String>> columns;
}
@@ -71,21 +71,35 @@ public class MemberCommonServiceImpl extends BaseServiceImpl<Sys_user> implement
Sql sql = Sqls.create("""
SELECT
u.id,
u.sex,
u.loginname,
u.username,
u.mobile,
u.unitId,
u.unitName,
u.unionId,
u.unionName,
u.sex,
u.birthday,
u.manyUnit,
u.member,
u.userState,
u.preparedBy,
u.political,
u.joinPartyDate,
u.nation,
u.nativePlace,
u.nationality,
u.idCardType,
u.idCard,
u.mobile,
u.welfareMobile,
u.education,
u.academicDegree,
u.technicalTitle,
u.technicalTitleLevel,
u.position,
u.positionLevel,
u.employeeLevel,
u.arrivalAtSchoolDate,
u.personType,
u.welfareMember,
u.preparedBy,
u.identityType,
u.userState,
u.unionName,
u.unitName,
u.member,
u.postDoctoralJoinDate,
his.id hisId,
his.changeTypes,
his.changeTime
@@ -145,6 +145,7 @@ public class MemberStatisticsServiceImpl extends BaseServiceImpl<Sys_user> imple
u.idCardType,
u.idCard,
u.mobile,
u.welfareMobile,
u.education,
u.academicDegree,
u.technicalTitle,
@@ -74,15 +74,48 @@ layout("/layouts/platform.html"){
<el-button type="primary" size="small" icon="el-icon-printer" @click="exportNotEqPhoneExcel"
v-if="$auth.hasRoleOr('SYSADMIN,SCHOOL_UNION_ADMIN')">导出会员福利号码不一致名单
</el-button>
<el-popover
placement="bottom"
trigger="click"
width="200">
<div style="padding:4px 0;border-bottom:1px solid #eee;">
<el-button size="mini" @click="checkAll">全选</el-button>
<el-button size="mini" @click="invertCheck">反选</el-button>
</div>
<div style="max-height:40vh;overflow-y:auto;padding:6px 0;">
<el-checkbox-group v-model="checkedFields">
<el-checkbox
v-for="f in tableColumns"
:key="f.prop"
:label="f.prop"
style="display:block;margin:6px 0;">
{{ f.label }}
</el-checkbox>
</el-checkbox-group>
</div>
<el-button
slot="reference"
type="text"
icon="el-icon-s-operation"
size="small"
style="margin-left:12px;">
列设置
</el-button>
</el-popover>
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
class="vi-table" ref="table" row-key="id" style="width: 100%">
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px"></el-table-column>
label="序号" type="index" width="80px" fixed="left"></el-table-column>
<el-table-column :label="column.label" :prop="column.prop"
:sortable="column.sortable" :width="column.width"
align="center" header-align="center" min-width="100px"
v-if="checkedFields.includes(column.prop)" :fixed="column.fixed"
show-overflow-tooltip v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='loginname'">
<el-link @click="openView(row.id)" type="primary">{{row.loginname}}</el-link>
@@ -128,8 +161,7 @@ layout("/layouts/platform.html"){
</el-table-column>
<el-table-column align="center" header-align="center" label="操作"
prop="userOnline"
width="100px">
prop="userOnline" width="100px" fixed="right">
<template scope="{row}">
<el-dropdown @command="dropdownCommand">
<el-button plain size="mini">
@@ -191,7 +223,7 @@ layout("/layouts/platform.html"){
message: '请输入有效的手机号码',
trigger: 'blur'
}]">
<el-input v-model="welfareFormData.welfareMobile"></el-input>
<el-input v-model="welfareFormData.welfareMobile" placeholder="请输入福利号码" maxlength="11"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
@@ -254,18 +286,41 @@ layout("/layouts/platform.html"){
units: [],
id: "",
tableColumns: [
{prop: 'loginname', label: '工号', sortable: true},
{prop: 'username', label: '姓名', sortable: true},
{prop: 'sex', label: '性别', sortable: true, width: '100px'},
{prop: 'birthday', label: '出生年月', sortable: true},
{prop: 'personType', label: '人员类型', sortable: true},
{prop: 'userState', label: '在职状态', sortable: true},
{prop: 'unionName', label: '所属工会', sortable: true},
{prop: 'unitName', label: '所属单位', sortable: true},
{ prop: "loginname", label: "工号", width: 120, fixed: "left"},
{ prop: "username", label: "姓名", width: 120, fixed: "left" },
{ prop: "sex", label: "性别", width: 120},
{ prop: "birthday", label: "出生年月", width: 120, sortable: true },
{ prop: "nation", label: "民族", width: 120, sortable: true, checked: 0 },
{ prop: "nationality", label: "国籍", width: 120, sortable: true, checked: 0 },
{ prop: "nativePlace", label: "籍贯", width: 120, sortable: true, checked: 0 },
{ prop: "education", label: "学历", width: 120, sortable: true, checked: 0 },
{ prop: "academicDegree", label: "学位", width: 120, sortable: true, checked: 0 },
{ prop: "mobile", label: "联系电话", width: 120 },
{ prop: "welfareMobile", label: "福利手机号码", width: 120 },
{ prop: "political", label: "政治面貌", width: 120, sortable: true},
{ prop: "userState", label: "在职状态", width: 120, sortable: true },
{ prop: "personType", label: "教职工类别", width: 120, sortable: true },
{ prop: "preparedBy", label: "聘用方式", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", width: 120, sortable: true },
{ prop: "unionName", label: "所属工会", width: 120, sortable: true },
{ prop: "unitName", label: "所属单位", width: 120, sortable: true },
{ prop: "identityType", label: "身份类型", width: 120, sortable: true },
{ prop: "idCardType", label: "证件类型", width: 120, sortable: true, checked: 0 },
{ prop: "idCard", label: "证件号码", width: 120, sortable: true, checked: 0 },
{ prop: "arrivalAtSchoolDate", label: "来校年月", width: 120, sortable: true },
{ prop: "joinPartyDate", label: "入党时间", width: 120, sortable: true, checked: 0 },
{ prop: "position", label: "职务", width: 120, sortable: true, checked: 0 },
{ prop: "positionLevel", label: "职务级别", width: 120, sortable: true, checked: 0 },
{ prop: "employeeLevel", label: "职员级别", width: 120, sortable: true, checked: 0 },
{ prop: "technicalTitle", label: "技术职称", width: 120, sortable: true, checked: 0 },
{ prop: "technicalTitleLevel", label: "技术职称级别", width: 120, sortable: true, checked: 0 }
],
changeWelfareMobileVisible: false,
welfareFormData: {}
welfareFormData: {},
checkedFields: []
},
components: {
"member-info": MEMBER_INFO,
@@ -367,6 +422,10 @@ layout("/layouts/platform.html"){
*/
exportExcel() {
const pageForm = clone(this.pageForm)
const data = this.tableColumns.filter(item => this.checkedFields.includes(item.prop)).map(item => {
return {prop: item.prop, label: item.label}
})
pageForm.columns = JSON.stringify(data)
this.$downLoad("/platform/member/change/manage/doExport", pageForm)
},
exportNotEqPhoneExcel(){
@@ -390,8 +449,23 @@ layout("/layouts/platform.html"){
this.units = data
})
}
},
checkAll() {
this.checkedFields = this.tableColumns.map(c => c.prop);
},
invertCheck() {
const all = this.tableColumns.map(c => c.prop);
this.checkedFields = all.filter(p => !this.checkedFields.includes(p));
}
},
computed: {
showColumns() {
return this.tableColumns.filter(c => this.checkedFields.includes(c.prop));
}
},
mounted() {
this.checkedFields = this.tableColumns.filter(c => c.checked !== 0).map(c => c.prop);
},
created() {
this.initData()
this.pageData()
@@ -48,6 +48,39 @@ layout("/layouts/platform.html"){
</el-select>
<el-button icon="el-icon-printer" class="m10" type="primary" style="float: right" size="small" @click="doExport">导出</el-button>
<el-popover
placement="bottom"
trigger="click"
width="200">
<div style="padding:4px 0;border-bottom:1px solid #eee;">
<el-button size="mini" @click="checkAll">全选</el-button>
<el-button size="mini" @click="invertCheck">反选</el-button>
</div>
<div style="max-height:40vh;overflow-y:auto;padding:6px 0;">
<el-checkbox-group v-model="checkedFields">
<el-checkbox
v-for="f in tableColumns"
:key="f.prop"
:label="f.prop"
style="display:block;margin:6px 0;">
{{ f.label }}
</el-checkbox>
</el-checkbox-group>
</div>
<el-button
slot="reference"
type="text"
icon="el-icon-s-operation"
size="small"
style="margin-left:12px;">
列设置
</el-button>
</el-popover>
</table-tool>
<el-table
:data="tableData"
@@ -62,6 +95,7 @@ layout("/layouts/platform.html"){
align="center"
header-align="center"
type="index"
fixed="left"
:index="indexMethod"
label="序号"
width="80px"
@@ -71,9 +105,11 @@ layout("/layouts/platform.html"){
header-align="center"
v-for="column in tableColumns"
show-overflow-tooltip
v-if="checkedFields.includes(column.prop)"
:label="column.label"
:prop="column.prop"
:width="column.width"
:fixed="column.fixed"
:sortable="column.sortable"
>
<template v-if="column.prop==='memberJoinTime'" scope="{row}">{{$moment(row.memberJoinTime).format('YYYY-MM-DD')}}</template>
@@ -83,7 +119,7 @@ layout("/layouts/platform.html"){
</template>
</el-table-column>
<el-table-column align="center" header-align="center" label="操作" width="100px">
<el-table-column align="center" header-align="center" label="操作" width="100px" fixed="right">
<template scope="{row}">
<el-button size="mini" @click="openView(row.id)" type="primary">查看</el-button>
</template>
@@ -114,20 +150,38 @@ layout("/layouts/platform.html"){
units: [],
childrenData: {},
tableColumns: [
{ prop: "loginname", label: "工号", fixed: "left" },
{ prop: "username", label: "姓名", fixed: "left" },
{ prop: "sex", label: "性别" },
{ prop: "loginname", label: "工号", width: 120, fixed: "left"},
{ prop: "username", label: "姓名", width: 120, fixed: "left" },
{ prop: "sex", label: "性别", width: 120},
{ prop: "birthday", label: "出生年月", width: 120, sortable: true },
{ prop: "mobile", label: "联系电话" },
{ prop: "nation", label: "民族", width: 120, sortable: true, checked: 0 },
{ prop: "nationality", label: "国籍", width: 120, sortable: true, checked: 0 },
{ prop: "nativePlace", label: "籍贯", width: 120, sortable: true, checked: 0 },
{ prop: "education", label: "学历", width: 120, sortable: true, checked: 0 },
{ prop: "academicDegree", label: "学位", width: 120, sortable: true, checked: 0 },
{ prop: "mobile", label: "联系电话", width: 120 },
{ prop: "welfareMobile", label: "福利手机号码", width: 120 },
{ prop: "political", label: "政治面貌", width: 120, sortable: true},
{ prop: "userState", label: "在职状态", width: 120, sortable: true },
{ prop: "personType", label: "教职工类别", width: 120, sortable: true },
{ prop: "preparedBy", label: "聘用方式", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true },
{ prop: "identityType", label: "身份类型", width: 120, sortable: true },
{ prop: "postDoctoralJoinDate", label: "进站时间", width: 120, sortable: true },
{ prop: "unionName", label: "所属工会", width: 120, sortable: true },
{ prop: "unitName", label: "所属单位", width: 120, sortable: true },
{ prop: "arrivalAtSchoolDate", label: "来校年月", width: 120, sortable: true }
]
{ prop: "identityType", label: "身份类型", width: 120, sortable: true },
{ prop: "idCardType", label: "证件类型", width: 120, sortable: true, checked: 0 },
{ prop: "idCard", label: "证件号码", width: 120, sortable: true, checked: 0 },
{ prop: "arrivalAtSchoolDate", label: "来校年月", width: 120, sortable: true },
{ prop: "joinPartyDate", label: "入党时间", width: 120, sortable: true, checked: 0 },
{ prop: "position", label: "职务", width: 120, sortable: true, checked: 0 },
{ prop: "positionLevel", label: "职务级别", width: 120, sortable: true, checked: 0 },
{ prop: "employeeLevel", label: "职员级别", width: 120, sortable: true, checked: 0 },
{ prop: "technicalTitle", label: "技术职称", width: 120, sortable: true, checked: 0 },
{ prop: "technicalTitleLevel", label: "技术职称级别", width: 120, sortable: true, checked: 0 }
],
checkedFields: []
}
},
components: {
@@ -148,6 +202,10 @@ layout("/layouts/platform.html"){
pageForm.memberTypes = JSON.stringify(this.pageForm.memberTypes)
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
const data = this.tableColumns.filter(item => this.checkedFields.includes(item.prop)).map(item => {
return {prop: item.prop, label: item.label}
})
pageForm.columns = JSON.stringify(data)
this.$downLoad("/platform/member/statistics/comprehensive/doExport", pageForm)
},
search(pageForm) {
@@ -188,7 +246,23 @@ layout("/layouts/platform.html"){
this.$message.error(res.msg)
}
})
},
checkAll() {
this.checkedFields = this.tableColumns.map(c => c.prop);
},
invertCheck() {
const all = this.tableColumns.map(c => c.prop);
this.checkedFields = all.filter(p => !this.checkedFields.includes(p));
}
},
computed: {
showColumns() {
return this.tableColumns.filter(c => this.checkedFields.includes(c.prop));
}
},
mounted() {
this.checkedFields = this.tableColumns.filter(c => c.checked !== 0).map(c => c.prop);
}
})
</script>