疗休养优化1.5

This commit is contained in:
2026-06-17 11:43:19 +08:00
parent a8abd16c7a
commit 47e971ebc8
6 changed files with 249 additions and 0 deletions
@@ -1,21 +1,30 @@
package com.budwk.app.zhgh.dayofficework.tour.controller;
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.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.dayofficework.tour.service.TourUserAssignmentService;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -47,6 +56,23 @@ public class TourBranchUserAssignmentController {
personType, keyword));
}
/**
* 按分工会人员分配页面当前查询条件导出数据,导出范围不受分页限制。
*/
@At
@SaCheckPermission("tour.branchUserAssignment")
@Ok("void")
public void exportData(PageForm pageForm, Integer year, String settingId, String matterId,
String personType, String keyword, HttpServletResponse response) {
List<NutMap> rows = tourUserAssignmentService.branchAssignmentExportRows(pageForm, year, settingId, matterId,
personType, keyword);
ExportParams exportParams = new ExportParams();
exportParams.setSheetName("分工会人员分配");
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, assignmentExportEntities(), rows);
CommonDownloadUtil.download("分工会人员分配.xlsx", workbook, response);
}
/**
* 分页查询候选人员,候选范围由疗休养配置可参加人员范围和当前登录人所在分工会共同决定;userIds 仅作为人员选择器筛选条件。
*/
@@ -188,4 +214,30 @@ public class TourBranchUserAssignmentController {
List<String> list = Json.fromJsonAsList(String.class, userIds);
return Lang.isEmpty(list) ? Collections.emptyList() : list;
}
/**
* 定义人员分配导出字段,保持与页面列表核心字段一致并补充人员基础信息。
*/
private List<ExcelExportEntity> assignmentExportEntities() {
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 12));
entities.add(new ExcelExportEntity("疗休养配置", "settingName", 24));
entities.add(new ExcelExportEntity("姓名", "userName", 14));
entities.add(new ExcelExportEntity("工号", "loginName", 16));
entities.add(new ExcelExportEntity("性别", "gender", 10));
entities.add(new ExcelExportEntity("年龄", "age", 10));
entities.add(new ExcelExportEntity("身份证号", "idCard", 24));
entities.add(new ExcelExportEntity("手机号", "mobile", 18));
entities.add(new ExcelExportEntity("所属分工会", "unionName", 24));
entities.add(new ExcelExportEntity("所在单位", "unitName", 24));
entities.add(new ExcelExportEntity("线路", "lineName", 30));
entities.add(new ExcelExportEntity("出行时间", "travelPeriod", 26));
entities.add(new ExcelExportEntity("乘车地点", "boardingPlace", 18));
entities.add(new ExcelExportEntity("分配类别", "assignSourceText", 16));
entities.add(new ExcelExportEntity("人员类型", "personTypeText", 14));
entities.add(new ExcelExportEntity("是否退出", "cancelledText", 14));
entities.add(new ExcelExportEntity("分配时间", "assignedAt", 22));
entities.add(new ExcelExportEntity("分配人", "assignedName", 14));
return entities;
}
}
@@ -1,12 +1,18 @@
package com.budwk.app.zhgh.dayofficework.tour.controller;
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.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.zhgh.dayofficework.tour.models.TourUserAssignment;
import com.budwk.app.zhgh.dayofficework.tour.service.TourUserAssignmentService;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
@@ -18,6 +24,8 @@ import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -49,6 +57,23 @@ public class TourSchoolUserAssignmentController {
unionId, personType, keyword, assignSource));
}
/**
* 按校工会人员分配页面当前查询条件导出数据,导出范围不受分页限制。
*/
@At
@SaCheckPermission("tour.schoolUserAssignment")
@Ok("void")
public void exportData(PageForm pageForm, Integer year, String settingId, String matterId, String unionId,
String personType, String keyword, String assignSource, HttpServletResponse response) {
List<NutMap> rows = tourUserAssignmentService.schoolAssignmentExportRows(pageForm, year, settingId, matterId,
unionId, personType, keyword, assignSource);
ExportParams exportParams = new ExportParams();
exportParams.setSheetName("校工会人员分配");
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, assignmentExportEntities(), rows);
CommonDownloadUtil.download("校工会人员分配.xlsx", workbook, response);
}
/**
* 分页查询候选人员,候选范围由疗休养配置的可参加人员范围决定;userIds 仅作为人员选择器筛选条件。
*/
@@ -204,4 +229,30 @@ public class TourSchoolUserAssignmentController {
List<NutMap> list = Json.fromJsonAsList(NutMap.class, assignItems);
return Lang.isEmpty(list) ? Collections.emptyList() : list;
}
/**
* 定义人员分配导出字段,保持与页面列表核心字段一致并补充人员基础信息。
*/
private List<ExcelExportEntity> assignmentExportEntities() {
List<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("年度", "year", 12));
entities.add(new ExcelExportEntity("疗休养配置", "settingName", 24));
entities.add(new ExcelExportEntity("姓名", "userName", 14));
entities.add(new ExcelExportEntity("工号", "loginName", 16));
entities.add(new ExcelExportEntity("性别", "gender", 10));
entities.add(new ExcelExportEntity("年龄", "age", 10));
entities.add(new ExcelExportEntity("身份证号", "idCard", 24));
entities.add(new ExcelExportEntity("手机号", "mobile", 18));
entities.add(new ExcelExportEntity("所属分工会", "unionName", 24));
entities.add(new ExcelExportEntity("所在单位", "unitName", 24));
entities.add(new ExcelExportEntity("线路", "lineName", 30));
entities.add(new ExcelExportEntity("出行时间", "travelPeriod", 26));
entities.add(new ExcelExportEntity("乘车地点", "boardingPlace", 18));
entities.add(new ExcelExportEntity("分配类别", "assignSourceText", 16));
entities.add(new ExcelExportEntity("人员类型", "personTypeText", 14));
entities.add(new ExcelExportEntity("是否退出", "cancelledText", 14));
entities.add(new ExcelExportEntity("分配时间", "assignedAt", 22));
entities.add(new ExcelExportEntity("分配人", "assignedName", 14));
return entities;
}
}
@@ -26,6 +26,22 @@ public interface TourUserAssignmentService extends BaseService<TourUserAssignmen
Pagination<NutMap> schoolAssignmentPage(PageForm pageForm, Integer year, String settingId, String matterId,
String unionId, String personType, String keyword, String assignSource);
/**
* 按校工会人员分配页面当前筛选条件查询导出数据,不做分页截断。
*
* @param pageForm 排序参数,导出顺序与页面当前排序保持一致
* @param year 疗休养年度
* @param settingId 疗休养配置ID
* @param matterId 疗休养事项ID
* @param unionId 所属分工会ID
* @param personType 人员类型:FORMAL 正式人员,BACKUP 替补人员
* @param keyword 姓名或工号关键字
* @param assignSource 分配类别:SCHOOL_UNION 校工会分配,BRANCH_UNION 分工会分配;为空时查询全部
* @return 符合当前页面查询条件的人员分配导出数据
*/
List<NutMap> schoolAssignmentExportRows(PageForm pageForm, Integer year, String settingId, String matterId,
String unionId, String personType, String keyword, String assignSource);
/**
* 分页查询校工会可分配候选人,候选人来自疗休养配置的可参加人员范围,并排除同一配置下已分配人员。
*
@@ -52,6 +68,20 @@ public interface TourUserAssignmentService extends BaseService<TourUserAssignmen
Pagination<NutMap> branchAssignmentPage(PageForm pageForm, Integer year, String settingId, String matterId,
String personType, String keyword);
/**
* 按分工会人员分配页面当前筛选条件查询导出数据,不做分页截断。
*
* @param pageForm 排序参数,导出顺序与页面当前排序保持一致
* @param year 疗休养年度
* @param settingId 疗休养配置ID
* @param matterId 疗休养事项ID
* @param personType 人员类型:FORMAL 正式人员,BACKUP 替补人员
* @param keyword 姓名或工号关键字
* @return 当前登录人所在分工会下符合页面查询条件的人员分配导出数据
*/
List<NutMap> branchAssignmentExportRows(PageForm pageForm, Integer year, String settingId, String matterId,
String personType, String keyword);
/**
* 分页查询当前登录人所在分工会可分配候选人,候选人来自疗休养配置的可参加人员范围。
*
@@ -81,6 +81,14 @@ public class TourUserAssignmentServiceImpl extends BaseServiceImpl<TourUserAssig
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
}
@Override
public List<NutMap> schoolAssignmentExportRows(PageForm pageForm, Integer year, String settingId, String matterId,
String unionId, String personType, String keyword, String assignSource) {
List<NutMap> rows = assignmentExportRows(pageForm, year, settingId, matterId, unionId, personType, keyword, assignSource);
fillAssignmentExportText(rows);
return rows;
}
@Override
public Pagination<NutMap> schoolCandidatePage(PageForm pageForm, String settingId, String unionId, String keyword, List<String> userIds) {
TourSetting setting = fetchSettingForAssignment(settingId);
@@ -112,6 +120,19 @@ public class TourUserAssignmentServiceImpl extends BaseServiceImpl<TourUserAssig
TourUserAssignment.ASSIGN_SOURCE_BRANCH_UNION);
}
@Override
public List<NutMap> branchAssignmentExportRows(PageForm pageForm, Integer year, String settingId, String matterId,
String personType, String keyword) {
String unionId = SecurityUtil.getUnionId();
if (StrUtil.isBlank(unionId)) {
return Collections.emptyList();
}
List<NutMap> rows = assignmentExportRows(pageForm, year, settingId, matterId, unionId, personType, keyword,
TourUserAssignment.ASSIGN_SOURCE_BRANCH_UNION);
fillAssignmentExportText(rows);
return rows;
}
@Override
public Pagination<NutMap> branchCandidatePage(PageForm pageForm, String settingId, String keyword, List<String> userIds) {
String unionId = SecurityUtil.getUnionId();
@@ -121,6 +142,79 @@ public class TourUserAssignmentServiceImpl extends BaseServiceImpl<TourUserAssig
return schoolCandidatePage(pageForm, settingId, unionId, keyword, userIds);
}
/**
* 构建人员分配导出查询,筛选条件与页面分页列表保持一致,但导出时不追加分页。
*/
private List<NutMap> assignmentExportRows(PageForm pageForm, Integer year, String settingId, String matterId,
String unionId, String personType, String keyword, String assignSource) {
Sql sql = Sqls.create("""
SELECT
a.*,
s.`year` AS `year`,
s.configName AS settingName,
CASE
WHEN IFNULL(m.travelStartTime, '') <> '' AND IFNULL(m.travelEndTime, '') <> ''
THEN CONCAT(m.travelStartTime, ' 至 ', m.travelEndTime)
ELSE ''
END AS travelPeriod
FROM tour_user_assignment a
LEFT JOIN tour_setting s ON s.id = a.settingId
LEFT JOIN tour_matter m ON m.id = a.matterId AND m.delFlag = 0
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("a.delFlag", "=", false);
cnd.andEX("a.assignSource", "=", assignSource);
cnd.andEX("s.`year`", "=", year);
cnd.andEX("a.settingId", "=", settingId);
cnd.andEX("a.matterId", "=", matterId);
cnd.andEX("a.unionId", "=", unionId);
cnd.andEX("a.personType", "=", personType);
if (StrUtil.isNotBlank(keyword)) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("a.userName", keyword);
group.orLike("a.loginName", keyword);
cnd.and(group);
}
appendAssignmentOrder(cnd, pageForm);
sql.setCondition(cnd);
return listMap(sql);
}
/**
* 为 Excel 导出补充字典文本,避免前端标签渲染值直接出现在表格里。
*/
private void fillAssignmentExportText(List<NutMap> rows) {
if (Lang.isEmpty(rows)) {
return;
}
rows.forEach(row -> {
row.put("assignSourceText", assignmentSourceText(row.getString("assignSource")));
row.put("personTypeText", assignmentPersonTypeText(row.getString("personType")));
row.put("cancelledText", Boolean.TRUE.equals(row.getBoolean("cancelled")) ? "已退出" : "未退出");
});
}
/**
* 转换分配来源编码为页面可读文本。
*/
private String assignmentSourceText(String assignSource) {
if (TourUserAssignment.ASSIGN_SOURCE_BRANCH_UNION.equals(assignSource)) {
return "分工会分配";
}
if (TourUserAssignment.ASSIGN_SOURCE_SCHOOL_UNION.equals(assignSource)) {
return "校工会分配";
}
return StrUtil.isBlank(assignSource) ? "" : assignSource;
}
/**
* 转换人员类型编码为页面可读文本。
*/
private String assignmentPersonTypeText(String personType) {
return TourUserAssignment.PERSON_TYPE_BACKUP.equals(personType) ? "替补人员" : "正式人员";
}
@Override
public List<NutMap> listEnabledSettingOptions(Integer year) {
Sql sql = Sqls.create("""
@@ -54,6 +54,7 @@ layout("/layouts/platform.html"){
<i class="el-icon-user"></i>
人员分配
</el-button>
<el-button type="primary" size="medium" icon="el-icon-download" @click="exportData">导出</el-button>
</table-tool>
<el-table
v-loading="tableLoading"
@@ -451,6 +452,16 @@ layout("/layouts/platform.html"){
}
})
},
exportData() {
const params = new URLSearchParams()
;["year", "settingId", "matterId", "personType", "keyword", "pageOrderName", "pageOrderBy"].forEach(key => {
const value = this.pageForm[key]
if (value !== undefined && value !== null && value !== "") {
params.append(key, value)
}
})
window.location.href = loc() + "/exportData?" + params.toString()
},
openAssign() {
const year = this.pageForm.year || moment().format("YYYY")
this.assignForm = this.defaultAssignForm(year)
@@ -64,6 +64,7 @@ layout("/layouts/platform.html"){
<i class="el-icon-user"></i>
人员分配
</el-button>
<el-button type="primary" size="medium" icon="el-icon-download" @click="exportData">导出</el-button>
</table-tool>
<el-table
v-loading="tableLoading"
@@ -441,6 +442,16 @@ layout("/layouts/platform.html"){
}
})
},
exportData() {
const params = new URLSearchParams()
;["year", "settingId", "matterId", "unionId", "personType", "assignSource", "keyword", "pageOrderName", "pageOrderBy"].forEach(key => {
const value = this.pageForm[key]
if (value !== undefined && value !== null && value !== "") {
params.append(key, value)
}
})
window.location.href = loc() + "/exportData?" + params.toString()
},
openAssign() {
const year = this.pageForm.year || moment().format("YYYY")
this.assignForm = this.defaultAssignForm(year)