change
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.budwk</groupId>
|
<groupId>com.budwk</groupId>
|
||||||
<artifactId>zhgh_jshvc</artifactId>
|
<artifactId>mini</artifactId>
|
||||||
<version>5.6.0-plus</version>
|
<version>5.6.0-plus</version>
|
||||||
<build>
|
<build>
|
||||||
<resources>
|
<resources>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<groupId>com.budwk</groupId>
|
<groupId>com.budwk</groupId>
|
||||||
<artifactId>zhgh_jshvc</artifactId>
|
<artifactId>mini</artifactId>
|
||||||
<version>5.6.0-plus</version>
|
<version>5.6.0-plus</version>
|
||||||
<properties>
|
<properties>
|
||||||
<nutzboot.version>2.6.0-SNAPSHOT</nutzboot.version>
|
<nutzboot.version>2.6.0-SNAPSHOT</nutzboot.version>
|
||||||
|
|||||||
+14
@@ -18,6 +18,7 @@ import org.nutz.mvc.annotation.At;
|
|||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -68,6 +69,19 @@ public class MemberPersonalInfoMaintainController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出个人信息维护列表数据,导出条件与页面查询保持一致,具体 Excel 生成逻辑放在 service 层。
|
||||||
|
*
|
||||||
|
* @param pageForm 页面查询和显示列参数
|
||||||
|
* @param response 文件下载响应
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission(value = {"member.info.maintain", "member.info.group"}, mode = SaMode.OR)
|
||||||
|
public void doExport(MemberInfoPageForm pageForm, HttpServletResponse response) {
|
||||||
|
memberInfoService.exportPersonalMaintain(pageForm, response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询个人信息维护详情,返回只读会员信息和可编辑子女信息。
|
* 查询个人信息维护详情,返回只读会员信息和可编辑子女信息。
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ public interface MemberInfoService extends BaseService<Sys_user> {
|
|||||||
*/
|
*/
|
||||||
void savePersonalMaintainMarriage(String userId, String marriage);
|
void savePersonalMaintainMarriage(String userId, String marriage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出个人信息维护列表数据,查询条件与页面列表保持一致,并汇总导出家庭主要成员信息。
|
||||||
|
*
|
||||||
|
* @param pageForm 页面查询和显示列参数
|
||||||
|
* @param response 文件下载响应
|
||||||
|
*/
|
||||||
|
void exportPersonalMaintain(MemberInfoPageForm pageForm, HttpServletResponse response);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取会员历史
|
* 获取会员历史
|
||||||
* @param pageForm
|
* @param pageForm
|
||||||
|
|||||||
+207
@@ -20,11 +20,24 @@ import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
|||||||
import com.budwk.app.sys.models.Sys_user;
|
import com.budwk.app.sys.models.Sys_user;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.zhgh.staffmanage.member.models.MemberHistory;
|
import com.budwk.app.zhgh.staffmanage.member.models.MemberHistory;
|
||||||
|
import com.budwk.app.zhgh.staffmanage.member.models.MemberChild;
|
||||||
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberInfoPageForm;
|
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberInfoPageForm;
|
||||||
import com.budwk.app.zhgh.staffmanage.member.service.MemberInfoService;
|
import com.budwk.app.zhgh.staffmanage.member.service.MemberInfoService;
|
||||||
import com.budwk.app.zhgh.staffmanage.member.vo.MemberImportVo;
|
import com.budwk.app.zhgh.staffmanage.member.vo.MemberImportVo;
|
||||||
|
import org.apache.poi.ss.usermodel.BorderStyle;
|
||||||
import org.apache.poi.ss.formula.functions.T;
|
import org.apache.poi.ss.formula.functions.T;
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
|
import org.apache.poi.ss.usermodel.FillPatternType;
|
||||||
|
import org.apache.poi.ss.usermodel.Font;
|
||||||
|
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||||
|
import org.apache.poi.ss.usermodel.IndexedColors;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.VerticalAlignment;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Chain;
|
import org.nutz.dao.Chain;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
@@ -41,9 +54,12 @@ import org.nutz.lang.util.NutMap;
|
|||||||
import org.nutz.mvc.upload.TempFile;
|
import org.nutz.mvc.upload.TempFile;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -208,6 +224,197 @@ public class MemberInfoServiceImpl extends BaseServiceImpl<Sys_user> implements
|
|||||||
dao().update(Sys_user.class, Chain.make("marriage", marriage), Cnd.where("id", "=", userId));
|
dao().update(Sys_user.class, Chain.make("marriage", marriage), Cnd.where("id", "=", userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出个人信息维护列表,人员数据复用页面查询 SQL,家庭主要成员按同一人员汇总到一行。
|
||||||
|
*
|
||||||
|
* @param pageForm 页面查询和显示列参数
|
||||||
|
* @param response 文件下载响应
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void exportPersonalMaintain(MemberInfoPageForm pageForm, HttpServletResponse response) {
|
||||||
|
Sql sql = getPersonalMaintainSql(pageForm);
|
||||||
|
List<NutMap> list = listMap(sql);
|
||||||
|
fillChildExportData(list);
|
||||||
|
List<Map<String, String>> personColumns = Lang.isNotEmpty(pageForm.getColumns())
|
||||||
|
? pageForm.getColumns()
|
||||||
|
: buildDefaultPersonalMaintainColumns();
|
||||||
|
Workbook workbook = buildPersonalMaintainWorkbook(personColumns, list);
|
||||||
|
CommonDownloadUtil.download("人员信息维护.xlsx", workbook, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为查询结果追加子女信息汇总字段,多个子女之间使用“ | ”分隔。
|
||||||
|
*
|
||||||
|
* @param list 页面查询出的人员数据
|
||||||
|
*/
|
||||||
|
private void fillChildExportData(List<NutMap> list) {
|
||||||
|
if (Lang.isEmpty(list)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> userIds = list.stream().map(item -> item.getString("id")).filter(StrUtil::isNotBlank).toList();
|
||||||
|
if (Lang.isEmpty(userIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Query child records in batch so exported child data follows the same people returned by the page query.
|
||||||
|
Map<String, List<MemberChild>> childMap = dao().query(MemberChild.class, Cnd.where("userId", "in", userIds).asc("createdAt"))
|
||||||
|
.stream().collect(Collectors.groupingBy(MemberChild::getUserId));
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
for (NutMap item : list) {
|
||||||
|
List<MemberChild> children = childMap.get(item.getString("id"));
|
||||||
|
item.put("childRelation", joinChildField(children, MemberChild::getRelation));
|
||||||
|
item.put("childName", joinChildField(children, MemberChild::getName));
|
||||||
|
item.put("childSex", joinChildField(children, MemberChild::getSex));
|
||||||
|
item.put("childBirthday", joinChildField(children, child -> child.getBirthday() == null ? "" : dateFormat.format(child.getBirthday())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聚合子女信息单个字段,保持每个子女字段在同一导出行内的顺序一致。
|
||||||
|
*
|
||||||
|
* @param children 子女信息列表
|
||||||
|
* @param getter 字段取值函数
|
||||||
|
* @return 使用“ | ”分隔的字段内容
|
||||||
|
*/
|
||||||
|
private String joinChildField(List<MemberChild> children, Function<MemberChild, String> getter) {
|
||||||
|
if (Lang.isEmpty(children)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
// Keep child field order consistent across all exported child columns.
|
||||||
|
return children.stream()
|
||||||
|
.map(child -> StrUtil.nullToEmpty(getter.apply(child)))
|
||||||
|
.collect(Collectors.joining(" | "));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面未传显示列时,使用个人信息维护列表当前默认显示列作为导出字段。
|
||||||
|
*
|
||||||
|
* @return 默认人员信息导出列
|
||||||
|
*/
|
||||||
|
private List<Map<String, String>> buildDefaultPersonalMaintainColumns() {
|
||||||
|
List<Map<String, String>> columns = new ArrayList<>();
|
||||||
|
addExportColumn(columns, "工号", "loginname");
|
||||||
|
addExportColumn(columns, "姓名", "username");
|
||||||
|
addExportColumn(columns, "性别", "sex");
|
||||||
|
addExportColumn(columns, "出生年月", "birthday");
|
||||||
|
addExportColumn(columns, "民族", "nation");
|
||||||
|
addExportColumn(columns, "联系电话", "mobile");
|
||||||
|
addExportColumn(columns, "政治面貌", "political");
|
||||||
|
addExportColumn(columns, "在职状态", "userState");
|
||||||
|
addExportColumn(columns, "教职工类别", "personType");
|
||||||
|
addExportColumn(columns, "编制类别", "preparedBy");
|
||||||
|
addExportColumn(columns, "所属工会", "unionName");
|
||||||
|
addExportColumn(columns, "所属单位", "unitName");
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加导出列配置,使用有序 Map 保持 Excel 列顺序。
|
||||||
|
*/
|
||||||
|
private void addExportColumn(List<Map<String, String>> columns, String label, String prop) {
|
||||||
|
Map<String, String> column = new LinkedHashMap<>();
|
||||||
|
column.put("label", label);
|
||||||
|
column.put("prop", prop);
|
||||||
|
columns.add(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建带“人员信息 / 子女信息”分组表头的 Excel。
|
||||||
|
*
|
||||||
|
* @param personColumns 人员信息列
|
||||||
|
* @param list 导出数据
|
||||||
|
* @return Excel 工作簿
|
||||||
|
*/
|
||||||
|
private Workbook buildPersonalMaintainWorkbook(List<Map<String, String>> personColumns, List<NutMap> list) {
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
Workbook workbook = new XSSFWorkbook();
|
||||||
|
Sheet sheet = workbook.createSheet("人员信息维护");
|
||||||
|
CellStyle groupStyle = createExportCellStyle(workbook, true, IndexedColors.PALE_BLUE.getIndex());
|
||||||
|
CellStyle childGroupStyle = createExportCellStyle(workbook, true, IndexedColors.LIGHT_GREEN.getIndex());
|
||||||
|
CellStyle headerStyle = createExportCellStyle(workbook, true, IndexedColors.GREY_25_PERCENT.getIndex());
|
||||||
|
CellStyle dataStyle = createExportCellStyle(workbook, false, IndexedColors.WHITE.getIndex());
|
||||||
|
|
||||||
|
List<Map<String, String>> childColumns = new ArrayList<>();
|
||||||
|
addExportColumn(childColumns, "关系", "childRelation");
|
||||||
|
addExportColumn(childColumns, "姓名", "childName");
|
||||||
|
addExportColumn(childColumns, "性别", "childSex");
|
||||||
|
addExportColumn(childColumns, "出生日期", "childBirthday");
|
||||||
|
|
||||||
|
Row groupRow = sheet.createRow(0);
|
||||||
|
Row headerRow = sheet.createRow(1);
|
||||||
|
int colIndex = 0;
|
||||||
|
createMergedCell(sheet, groupRow, 0, Math.max(personColumns.size() - 1, 0), "人员信息", groupStyle);
|
||||||
|
for (Map<String, String> column : personColumns) {
|
||||||
|
createCell(headerRow, colIndex++, column.get("label"), headerStyle);
|
||||||
|
}
|
||||||
|
int childStartIndex = colIndex;
|
||||||
|
createMergedCell(sheet, groupRow, childStartIndex, childStartIndex + childColumns.size() - 1, "子女信息", childGroupStyle);
|
||||||
|
for (Map<String, String> column : childColumns) {
|
||||||
|
createCell(headerRow, colIndex++, column.get("label"), headerStyle);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Row dataRow = sheet.createRow(i + 2);
|
||||||
|
int dataCol = 0;
|
||||||
|
NutMap data = list.get(i);
|
||||||
|
for (Map<String, String> column : personColumns) {
|
||||||
|
createCell(dataRow, dataCol++, data.getString(column.get("prop"), ""), dataStyle);
|
||||||
|
}
|
||||||
|
for (Map<String, String> column : childColumns) {
|
||||||
|
createCell(dataRow, dataCol++, data.getString(column.get("prop"), ""), dataStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < colIndex; i++) {
|
||||||
|
sheet.setColumnWidth(i, 20 * 256);
|
||||||
|
}
|
||||||
|
return workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建导出单元格样式,统一表头和数据区的边框、对齐、换行。
|
||||||
|
*/
|
||||||
|
private CellStyle createExportCellStyle(Workbook workbook, boolean bold, short fillColor) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
style.setWrapText(true);
|
||||||
|
style.setFillForegroundColor(fillColor);
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setBold(bold);
|
||||||
|
style.setFont(font);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建普通单元格并写入文本值。
|
||||||
|
*/
|
||||||
|
private void createCell(Row row, int colIndex, String value, CellStyle style) {
|
||||||
|
Cell cell = row.createCell(colIndex);
|
||||||
|
cell.setCellValue(value == null ? "" : value);
|
||||||
|
cell.setCellStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建横向合并单元格,作为 Excel 分组表头。
|
||||||
|
*/
|
||||||
|
private void createMergedCell(Sheet sheet, Row row, int firstCol, int lastCol, String value, CellStyle style) {
|
||||||
|
createCell(row, firstCol, value, style);
|
||||||
|
if (lastCol > firstCol) {
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(row.getRowNum(), row.getRowNum(), firstCol, lastCol));
|
||||||
|
for (int i = firstCol + 1; i <= lastCol; i++) {
|
||||||
|
createCell(row, i, "", style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Sql getMemberHistorySql(MemberInfoPageForm pageForm) {
|
public Sql getMemberHistorySql(MemberInfoPageForm pageForm) {
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ layout("/layouts/platform.html"){
|
|||||||
列设置
|
列设置
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
|
<el-button type="primary" size="small" icon="el-icon-download" @click="doExport">导出</el-button>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
|
|
||||||
<el-table :data="tableData" style="width: 100%" row-key="id" @sort-change="pageOrder" :size="tableSize" class="vi-table">
|
<el-table :data="tableData" style="width: 100%" row-key="id" @sort-change="pageOrder" :size="tableSize" class="vi-table">
|
||||||
@@ -157,6 +158,21 @@ layout("/layouts/platform.html"){
|
|||||||
this.tableLoading = false
|
this.tableLoading = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
doExport() {
|
||||||
|
const pageForm = clone(this.pageForm)
|
||||||
|
pageForm.userStates = Array.isArray(this.pageForm.userStates) ? JSON.stringify(this.pageForm.userStates) : this.pageForm.userStates
|
||||||
|
pageForm.personTypes = Array.isArray(this.pageForm.personTypes) ? JSON.stringify(this.pageForm.personTypes) : this.pageForm.personTypes
|
||||||
|
pageForm.preparedBys = Array.isArray(this.pageForm.preparedBys) ? JSON.stringify(this.pageForm.preparedBys) : this.pageForm.preparedBys
|
||||||
|
pageForm.columns = JSON.stringify(this.tableColumns.filter((column) => {
|
||||||
|
return this.checkedFields.includes(column.prop)
|
||||||
|
}).map((column) => {
|
||||||
|
return {
|
||||||
|
label: column.label,
|
||||||
|
prop: column.prop
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
this.$downLoad(loc() + "/doExport", pageForm)
|
||||||
|
},
|
||||||
checkAll() {
|
checkAll() {
|
||||||
this.checkedFields = this.tableColumns.map(c => c.prop)
|
this.checkedFields = this.tableColumns.map(c => c.prop)
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user