commit
This commit is contained in:
@@ -2,6 +2,8 @@ package com.budwk.app.flow.service;
|
||||
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 学校 OA 待办同步服务。
|
||||
*/
|
||||
@@ -41,4 +43,24 @@ public interface SchoolOaTodoService {
|
||||
* @param processInstanceId 本系统流程实例 ID,用于定位最后一个已完成审批任务并把学校 OA 节点名称改为完结
|
||||
*/
|
||||
void updateFlowFinishedStepName(Long processInstanceId);
|
||||
|
||||
/**
|
||||
* 创建福利选择提醒待办。
|
||||
*
|
||||
* @param projectId 福利项目ID,用于构造学校OA业务标识
|
||||
* @param title 待办标题,学校OA接口没有独立正文时用于展示提醒内容
|
||||
* @param pcUrl PC端福利选择地址
|
||||
* @param appUrl 手机端福利选择地址
|
||||
* @param creatorId 待办创建人ID
|
||||
* @param receiverIds 待办接收人ID集合
|
||||
*/
|
||||
void createWelfareReminderTodos(String projectId, String title, String pcUrl, String appUrl, String creatorId, List<String> receiverIds);
|
||||
|
||||
/**
|
||||
* 删除用户已完成福利选择对应的学校OA提醒待办。
|
||||
*
|
||||
* @param projectId 福利项目ID
|
||||
* @param userId 完成选择的用户ID
|
||||
*/
|
||||
void deleteWelfareReminderTodo(String projectId, String userId);
|
||||
}
|
||||
|
||||
@@ -200,6 +200,41 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
throw new BaseException("学校OA待办修改失败:未找到可修改的已完成流程任务,instanceId={}", processInstanceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createWelfareReminderTodos(String projectId, String title, String pcUrl, String appUrl, String creatorId, List<String> receiverIds) {
|
||||
if (!isSchoolOaEnabled("创建福利选择提醒待办", null, null)) {
|
||||
return;
|
||||
}
|
||||
if (StrUtil.hasBlank(projectId, title, pcUrl, appUrl, creatorId) || receiverIds == null || receiverIds.isEmpty()) {
|
||||
throw new BaseException("学校OA福利选择提醒待办参数不完整");
|
||||
}
|
||||
|
||||
Sys_user creator = dao.fetch(Sys_user.class, creatorId);
|
||||
if (creator == null || StrUtil.hasBlank(creator.getLoginname(), creator.getUsername())) {
|
||||
throw new BaseException("学校OA福利选择提醒待办创建人工号或姓名为空,userId={}", creatorId);
|
||||
}
|
||||
|
||||
String creatorTime = formatTime(System.currentTimeMillis());
|
||||
for (String receiverId : receiverIds) {
|
||||
Sys_user receiver = dao.fetch(Sys_user.class, receiverId);
|
||||
if (receiver == null || StrUtil.hasBlank(receiver.getLoginname(), receiver.getUsername())) {
|
||||
throw new BaseException("学校OA福利选择提醒待办接收人工号或姓名为空,userId={}", receiverId);
|
||||
}
|
||||
sendWelfareReminderTodo(projectId, title, pcUrl, appUrl, creator, receiver, creatorTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteWelfareReminderTodo(String projectId, String userId) {
|
||||
if (!isSchoolOaEnabled("删除福利选择提醒待办", null, null) || StrUtil.hasBlank(projectId, userId)) {
|
||||
return;
|
||||
}
|
||||
String uniqueId = buildWelfareReminderUniqueId(projectId, userId);
|
||||
String deleteUrl = requireConfig("school-oa.todo.delete-url").replace("{uniqueId}", uniqueId);
|
||||
sendTodoRequest(deleteUrl, "学校OA福利选择提醒待办删除失败", "学校OA福利选择提醒待办删除异常");
|
||||
log.info("学校OA福利选择提醒待办删除成功,projectId={},userId={},uniqueId={}", projectId, userId, uniqueId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用学校 OA 创建待办接口,接口失败时直接抛出异常,让本系统事务回滚。
|
||||
*/
|
||||
@@ -354,6 +389,59 @@ public class SchoolOaTodoServiceImpl implements SchoolOaTodoService {
|
||||
return baseUrl + separator + "taskId=" + task.getId() + "&instanceId=" + task.getProcessInstanceId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 按学校OA固定待办格式创建福利选择提醒,标题承载自定义提醒内容。
|
||||
*/
|
||||
private void sendWelfareReminderTodo(String projectId, String title, String pcUrl, String appUrl,
|
||||
Sys_user creator, Sys_user receiver, String creatorTime) {
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("flowTypeName", "福利选择");
|
||||
body.set("flowId", "welfare_reminder_" + projectId);
|
||||
body.set("title", title);
|
||||
body.set("stepName", "福利选择提醒");
|
||||
body.set("creatorCode", creator.getLoginname());
|
||||
body.set("creatorName", creator.getUsername());
|
||||
body.set("creatorTime", creatorTime);
|
||||
body.set("pcUrl", pcUrl);
|
||||
body.set("appUrl", appUrl);
|
||||
body.set("pcPreviewUrl", pcUrl);
|
||||
body.set("appPreviewUrl", appUrl);
|
||||
body.set("uniqueId", buildWelfareReminderUniqueId(projectId, receiver.getId()));
|
||||
body.set("receiveCode", receiver.getLoginname());
|
||||
body.set("receiveName", receiver.getUsername());
|
||||
body.set("receiveTime", creatorTime);
|
||||
|
||||
String insertUrl = requireConfig("school-oa.todo.insert-url");
|
||||
String requestBody = JSONUtil.toJsonStr(body);
|
||||
log.info("学校OA福利选择提醒待办创建请求,url={},projectId={},receiveCode={},body={}",
|
||||
insertUrl, projectId, receiver.getLoginname(), requestBody);
|
||||
try {
|
||||
HttpRequest request = HttpUtil.createPost(insertUrl);
|
||||
setTodoRequestHeaders(request);
|
||||
request.body(requestBody);
|
||||
String responseBody = request.execute().body();
|
||||
JSONObject response = JSONUtil.parseObj(responseBody);
|
||||
if (response.getInt("state", 0) != 200) {
|
||||
throw new BaseException("学校OA福利选择提醒待办创建失败:{}", response.getStr("message", responseBody));
|
||||
}
|
||||
log.info("学校OA福利选择提醒待办创建成功,projectId={},receiveCode={},response={}",
|
||||
projectId, receiver.getLoginname(), responseBody);
|
||||
} catch (BaseException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
log.error("学校OA福利选择提醒待办创建异常,url={},projectId={},receiveCode={},body={}",
|
||||
insertUrl, projectId, receiver.getLoginname(), requestBody, e);
|
||||
throw new BaseException("学校OA福利选择提醒待办创建异常:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 福利提醒待办按项目和接收人保持唯一;用户完成选择后可据此精确删除待办。
|
||||
*/
|
||||
private String buildWelfareReminderUniqueId(String projectId, String userId) {
|
||||
return "welfare_reminder_" + projectId + "_" + userId;
|
||||
}
|
||||
|
||||
private String buildAppTaskUrl(String h5FormKey, ProcessTask task) {
|
||||
// 部分流程没有配置 H5 审核页,学校 OA 的移动端地址为空时按要求传固定域名兜底。
|
||||
if (StrUtil.isBlank(h5FormKey)) {
|
||||
|
||||
+23
@@ -94,9 +94,32 @@ public class WelfareSelectionSituationController {
|
||||
welfareUserSelection.setSelectTime(new Date());
|
||||
}
|
||||
dao.insert(selections);
|
||||
situationService.clearReminderTodo(projectId, userId);
|
||||
return Result.success("选择成功");
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("welfare.selection.situation")
|
||||
@ApiOperation("预览福利选择提醒接收人数")
|
||||
public Result previewReminder(@Valid @Param("pageForm") WelfareSelectionSituationPageForm pageForm, @Param("userIds") String[] userIds) {
|
||||
return Result.success(situationService.countReminderRecipients(pageForm, userIds));
|
||||
}
|
||||
|
||||
@At
|
||||
@SLog(type = "welfare", tag = "选择情况", msg = "发送福利选择提醒")
|
||||
@SaCheckPermission("welfare.selection.situation")
|
||||
@ApiOperation("发送福利选择提醒")
|
||||
public Result sendReminder(@Valid @Param("pageForm") WelfareSelectionSituationPageForm pageForm, @Param("userIds") String[] userIds, String content) {
|
||||
if (StrUtil.isBlank(content)) {
|
||||
return Result.error("提醒内容不能为空");
|
||||
}
|
||||
int recipientCount = situationService.sendReminder(pageForm, userIds, content.trim());
|
||||
if (recipientCount == 0) {
|
||||
return Result.error("当前筛选条件下没有可提醒的人员");
|
||||
}
|
||||
return Result.success("提醒已发送给" + recipientCount + "人");
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("welfare.selection.situation")
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.budwk.app.zhgh.welfare.model.WelfareList;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
|
||||
import com.budwk.app.zhgh.welfare.service.WelfareProjectService;
|
||||
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
@@ -37,6 +38,8 @@ public class WelfareUserSelectController {
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private WelfareProjectService welfareProjectService;
|
||||
@Inject
|
||||
private WelfareSelectionSituationService situationService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/welfare/select/index.html")
|
||||
@@ -103,6 +106,7 @@ public class WelfareUserSelectController {
|
||||
welfareUserSelection.setSelectTime(new Date());
|
||||
}
|
||||
dao.insert(selections);
|
||||
situationService.clearReminderTodo(projectId, SecurityUtil.getUserId());
|
||||
return Result.success("选择成功");
|
||||
}
|
||||
|
||||
|
||||
+27
@@ -14,4 +14,31 @@ public interface WelfareSelectionSituationService extends BaseService<WelfareLis
|
||||
void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
||||
void receiveXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 统计当前筛选范围内可接收提醒的人员数量。
|
||||
*
|
||||
* @param pageForm 当前页面筛选条件
|
||||
* @param userIds 已勾选的人员ID;为空时按筛选条件查询全部人员
|
||||
* @return 去重后的接收人数量
|
||||
*/
|
||||
int countReminderRecipients(WelfareSelectionSituationPageForm pageForm, String[] userIds);
|
||||
|
||||
/**
|
||||
* 向当前筛选范围内的人员发送福利选择提醒。
|
||||
*
|
||||
* @param pageForm 当前页面筛选条件
|
||||
* @param userIds 已勾选的人员ID;为空时按筛选条件查询全部人员
|
||||
* @param content 自定义提醒内容
|
||||
* @return 实际发送的去重后接收人数量
|
||||
*/
|
||||
int sendReminder(WelfareSelectionSituationPageForm pageForm, String[] userIds, String content);
|
||||
|
||||
/**
|
||||
* 用户完成福利选择后清除对应的学校OA提醒待办。
|
||||
*
|
||||
* @param projectId 福利项目ID
|
||||
* @param userId 完成选择的用户ID
|
||||
*/
|
||||
void clearReminderTodo(String projectId, String userId);
|
||||
|
||||
}
|
||||
|
||||
+120
-6
@@ -13,10 +13,15 @@ import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
//import com.budwk.app.sys.models.Sys_file;
|
||||
import com.budwk.app.base.sms.SmsService;
|
||||
import com.budwk.app.flow.service.SchoolOaTodoService;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.services.SysFileService;
|
||||
import com.budwk.app.web.commons.base.Globals;
|
||||
//import com.budwk.app.sys.utils.SysFileMinIoUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.message.strategy.impl.LocalMessageSendStrategy;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareList;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareProject;
|
||||
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
|
||||
@@ -51,6 +56,12 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
|
||||
@Inject
|
||||
private SysFileService sysFileService;
|
||||
@Inject
|
||||
private LocalMessageSendStrategy localMessageSendStrategy;
|
||||
@Inject
|
||||
private SmsService smsService;
|
||||
@Inject
|
||||
private SchoolOaTodoService schoolOaTodoService;
|
||||
@Override
|
||||
public Pagination pageData(WelfareSelectionSituationPageForm pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
@@ -113,6 +124,107 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countReminderRecipients(WelfareSelectionSituationPageForm pageForm, String[] userIds) {
|
||||
return getReminderRecipientIds(pageForm, userIds).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int sendReminder(WelfareSelectionSituationPageForm pageForm, String[] userIds, String content) {
|
||||
List<String> recipientIds = getReminderRecipientIds(pageForm, userIds);
|
||||
if (recipientIds.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
String title = "福利选择提醒";
|
||||
String pcUrl = buildWelfareSelectionUrl("/platform/welfare/userSelect");
|
||||
String appUrl = buildWelfareSelectionUrl("/platform/h5/welfare/userSelect/list");
|
||||
|
||||
// 本地消息始终发送,确保外部渠道关闭时仍可在系统内查看提醒。
|
||||
localMessageSendStrategy.send(title, content, 2, recipientIds, null);
|
||||
|
||||
List<String> receiverLoginNames = dao().query(Sys_user.class, Cnd.where(Sys_user::getId, "in", recipientIds)).stream()
|
||||
.map(Sys_user::getLoginname)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
// AppSms 控制学校消息平台发送,消息链接跳转到手机端福利选择列表。
|
||||
if (Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSms")) && !receiverLoginNames.isEmpty()) {
|
||||
smsService.massSend(receiverLoginNames, title, content, appUrl);
|
||||
}
|
||||
// AppSchoolOa 控制学校OA待办;学校OA没有正文栏位,标题使用自定义提醒内容。
|
||||
if (Boolean.TRUE.equals(Globals.MyConfig.getBoolean("AppSchoolOa"))) {
|
||||
schoolOaTodoService.createWelfareReminderTodos(pageForm.getProjectId(), title + ":" + content,
|
||||
pcUrl, appUrl, SecurityUtil.getUserId(), recipientIds);
|
||||
}
|
||||
return recipientIds.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearReminderTodo(String projectId, String userId) {
|
||||
try {
|
||||
schoolOaTodoService.deleteWelfareReminderTodo(projectId, userId);
|
||||
} catch (Exception e) {
|
||||
// 学校OA删除失败不能影响用户完成福利选择,后续可根据日志人工处理。
|
||||
log.error("删除学校OA福利选择提醒待办失败,projectId={},userId={}", projectId, userId, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用系统配置的绝对域名构造学校外部平台可访问的福利选择地址。
|
||||
*/
|
||||
private String buildWelfareSelectionUrl(String path) {
|
||||
return StrUtil.removeSuffix(Globals.AppDomain, "/") + path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据当前筛选条件和数据权限获取提醒接收人,避免前端传入范围外人员。
|
||||
*/
|
||||
private List<String> getReminderRecipientIds(WelfareSelectionSituationPageForm pageForm, String[] userIds) {
|
||||
if (StrUtil.isBlank(pageForm.getProjectId())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT DISTINCT
|
||||
t1.userId
|
||||
FROM
|
||||
welfare_list t1
|
||||
LEFT JOIN welfare_project_user_selection t2 ON t2.welfareId = t1.projectId AND t2.selectUserId = t1.userId
|
||||
LEFT JOIN sys_user t4 ON t4.id = t1.userId
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name()) || AuthUtil.hasRole(RoleConstant.BRANCH_UNION_ADMIN.name()) || AuthUtil.hasRole(RoleConstant.BRANCH_UNION_WENTI_SPORTS.name())) {
|
||||
cnd.and("t1.welfareUnionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
|
||||
cnd.and("t1.projectId", "=", pageForm.getProjectId());
|
||||
cnd.andEX("t2.selectOptionId", "=", pageForm.getWelfareOptionId());
|
||||
if (StrUtil.isNotBlank(pageForm.getUserName())) {
|
||||
cnd.where().andLike("t4.username", pageForm.getUserName());
|
||||
}
|
||||
if (StrUtil.isNotBlank(pageForm.getLoginName())) {
|
||||
cnd.where().andLike("t4.loginname", pageForm.getLoginName());
|
||||
}
|
||||
cnd.andEX("t1.welfareUnitId", "in", pageForm.getUnitIds());
|
||||
cnd.andEX("t1.welfareUnionId", "=", pageForm.getUnionId());
|
||||
if (pageForm.getIsSelect() != null) {
|
||||
cnd.and("t2.id", pageForm.getIsSelect() ? "IS NOT" : "IS", null);
|
||||
}
|
||||
|
||||
List<String> selectedUserIds = Arrays.stream(userIds == null ? new String[0] : userIds)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
cnd.andEX("t1.userId", "in", selectedUserIds.toArray(new String[0]));
|
||||
sql.setCondition(cnd);
|
||||
return listMap(sql).stream()
|
||||
.map(map -> map.getString("userId"))
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportXlsx(WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
|
||||
Sql sql = Sqls.create("""
|
||||
@@ -124,6 +236,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
|
||||
GROUP_CONCAT(DISTINCT t2.userName) AS userName2,
|
||||
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
|
||||
GROUP_CONCAT(DISTINCT CASE WHEN t2.createdBy IS NOT NULL AND t2.createdBy <> t2.selectUserId THEN CONCAT(t5.username, '代选') END) AS remark,
|
||||
t4.username AS userName,
|
||||
t4.loginname AS loginName,
|
||||
t4.sex
|
||||
@@ -132,6 +245,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
LEFT JOIN welfare_project_user_selection t2 ON t2.welfareId = t1.projectId AND t2.selectUserId = t1.userId
|
||||
LEFT JOIN welfare_project_subject_option t3 ON t3.id = t2.selectOptionId
|
||||
LEFT JOIN sys_user t4 ON t4.id = t1.userId
|
||||
LEFT JOIN sys_user t5 ON t5.id = t2.createdBy
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
@@ -189,6 +303,8 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
if(project.getProvideMode() == 3){
|
||||
entities.add(new ExcelExportEntity("收货地址", "receiveAddress", 40));
|
||||
}
|
||||
// 备注仅反映当前选择记录的创建人;本人重新选择后创建人变为本人,备注自动为空。
|
||||
entities.add(new ExcelExportEntity("备注", "remark", 20));
|
||||
|
||||
// 设置导出参数
|
||||
ExportParams exportParams = new ExportParams();
|
||||
@@ -257,9 +373,9 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
return map;
|
||||
}).toList();
|
||||
|
||||
// 分组
|
||||
// 按所属工会分组生成工作表;历史名单可能缺少工会名称,统一归入未分配工会,避免空分组键导致导出失败。
|
||||
Map<String, List<Map<String, Object>>> listMap = safeList.stream()
|
||||
.collect(Collectors.groupingBy(n -> (String) n.get("welfareUnionName")));
|
||||
.collect(Collectors.groupingBy(n -> StrUtil.blankToDefault((String) n.get("welfareUnionName"), "未分配工会")));
|
||||
|
||||
// 构建 Excel 列
|
||||
List<ExcelExportEntity> entities = new ArrayList<>();
|
||||
@@ -268,10 +384,8 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
|
||||
optionList.forEach(option -> {
|
||||
entities.add(new ExcelExportEntity(option.getOptionName(), option.getOptionName(), 20));
|
||||
});
|
||||
ExcelExportEntity userSignEntity = new ExcelExportEntity("签字", "userSign", 20);
|
||||
userSignEntity.setType(2);
|
||||
userSignEntity.setExportImageType(2);
|
||||
entities.add(userSignEntity);
|
||||
// 签字功能已取消,保留空白文本列供线下签字,不能按图片类型导出。
|
||||
entities.add(new ExcelExportEntity("签字", "userSign", 20));
|
||||
|
||||
// 导出
|
||||
Workbook workbook = new HSSFWorkbook();
|
||||
|
||||
+11
-3
@@ -387,6 +387,8 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
||||
exportEntities.add(new ExcelExportEntity("所在分工会", "welfareUnionName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所在单位", "welfareUnitName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所选福利", "selectOptionName", 50));
|
||||
// 备注仅反映当前选择记录的创建人;本人重新选择后创建人变为本人,备注自动为空。
|
||||
exportEntities.add(new ExcelExportEntity("备注", "remark", 20));
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -397,13 +399,15 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
||||
wpus.mobile,
|
||||
wpus.selectOptionId,
|
||||
wpso.optionName,
|
||||
GROUP_CONCAT(DISTINCT wpso.optionName, '(', wpus.selectNum, '份)') selectOptionName
|
||||
GROUP_CONCAT(DISTINCT wpso.optionName, '(', wpus.selectNum, '份)') selectOptionName,
|
||||
GROUP_CONCAT(DISTINCT CASE WHEN wpus.createdBy IS NOT NULL AND wpus.createdBy <> wpus.selectUserId THEN CONCAT(selectOperator.username, '代选') END) AS remark
|
||||
FROM
|
||||
welfare_project_user_selection wpus
|
||||
LEFT JOIN welfare_list wl ON wl.userId = wpus.selectUserId
|
||||
AND wl.projectId = wpus.welfareId
|
||||
LEFT JOIN sys_user u ON u.id = wpus.selectUserId
|
||||
LEFT JOIN welfare_project_subject_option wpso ON wpso.id = wpus.selectOptionId
|
||||
LEFT JOIN sys_user selectOperator ON selectOperator.id = wpus.createdBy
|
||||
WHERE
|
||||
wpus.welfareId = @projectId
|
||||
GROUP BY
|
||||
@@ -498,11 +502,15 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
|
||||
|
||||
for (NutMap union : mapUnions) {
|
||||
// 福利人数
|
||||
long teacherSum = welfareSelectionList.stream().filter(v -> v.getString("welfareUnionId").equals(union.getString("id"))).count();
|
||||
long teacherSum = welfareSelectionList.stream()
|
||||
.filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId").equals(union.getString("id")))
|
||||
.count();
|
||||
union.put("teacherSum", teacherSum);
|
||||
|
||||
// 已选人数
|
||||
long selectedNum = welfareSelectionList.stream().filter(v -> v.getString("welfareUnionId").equals(union.getString("id")) && v.getBoolean("has_selected")).count();
|
||||
long selectedNum = welfareSelectionList.stream()
|
||||
.filter(v -> StrUtil.isNotBlank(v.getString("welfareUnionId")) && v.getString("welfareUnionId").equals(union.getString("id")) && v.getBoolean("has_selected"))
|
||||
.count();
|
||||
union.put("selectedNum", selectedNum);
|
||||
|
||||
// 未选人数
|
||||
|
||||
@@ -66,11 +66,9 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool :app="this" label="选择情况">
|
||||
<el-radio-group v-model="pageForm.isSelect" size="small" @change="doSearch">
|
||||
<el-radio-button :label="null">全部</el-radio-button>
|
||||
<el-radio-button :label="true">已选择</el-radio-button>
|
||||
<el-radio-button :label="false">未选择</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-button type="primary" size="small" icon="el-icon-message" @click="openReminder">
|
||||
一键提醒
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="exportXlsx">
|
||||
导出选择情况表
|
||||
@@ -79,17 +77,25 @@ layout("/layouts/platform.html"){
|
||||
<el-button type="primary" size="small" icon="el-icon-download" style="margin-left: 10px" @click="receiveXlsx">
|
||||
导出领取表
|
||||
</el-button>
|
||||
|
||||
<el-radio-group v-model="pageForm.isSelect" size="small" @change="doSearch">
|
||||
<el-radio-button :label="null">全部</el-radio-button>
|
||||
<el-radio-button :label="true">已选择</el-radio-button>
|
||||
<el-radio-button :label="false">未选择</el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
|
||||
<el-table
|
||||
:data="tableData"
|
||||
:size="tableSize"
|
||||
@sort-change="pageOrder"
|
||||
@selection-change="handleSelectionChange"
|
||||
ref="tableRef"
|
||||
row-key="id"
|
||||
style="width: 100%"
|
||||
v-loading="tableLoading"
|
||||
>
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
|
||||
<el-table-column
|
||||
@@ -118,6 +124,19 @@ layout("/layouts/platform.html"){
|
||||
<el-dialog title="代选" :visible.sync="optionSelectVisible" width="60%">
|
||||
<option-select ref="optionSelectRef" @refresh="optionSelectVisible=false;doSearch();"></option-select>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="发送福利选择提醒" :visible.sync="reminderVisible" width="500px" :close-on-click-modal="false">
|
||||
<el-alert :title="'本次将向' + reminderCount + '人发送消息'" type="warning" :closable="false"></el-alert>
|
||||
<el-form label-width="80px" class="mt20">
|
||||
<el-form-item label="提醒内容">
|
||||
<el-input v-model="reminderContent" type="textarea" :rows="5" maxlength="500" show-word-limit placeholder="请输入提醒内容"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer">
|
||||
<el-button @click="closeReminder">取消</el-button>
|
||||
<el-button type="primary" :loading="reminderSending" @click="sendReminder">确认发送</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
@@ -150,7 +169,12 @@ layout("/layouts/platform.html"){
|
||||
{ prop: "selectedOptions", label: "所选福利", sortable: true },
|
||||
{ prop: "mobile", label: "联系电话", sortable: true }
|
||||
],
|
||||
optionSelectVisible: false
|
||||
optionSelectVisible: false,
|
||||
selectedRows: [],
|
||||
reminderVisible: false,
|
||||
reminderContent: "",
|
||||
reminderCount: 0,
|
||||
reminderSending: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -204,6 +228,75 @@ layout("/layouts/platform.html"){
|
||||
this.$downLoad("/platform/welfare/selection/situation/receiveXlsx", { pageForm: JSON.stringify(this.pageForm) })
|
||||
},
|
||||
|
||||
// 记录当前表格勾选人员;未勾选时提醒当前筛选范围内的全部人员。
|
||||
handleSelectionChange(rows) {
|
||||
this.$set(this, "selectedRows", rows)
|
||||
},
|
||||
|
||||
// 构建提醒请求参数,数组参数使用表单格式,保证后端可以绑定为 String[]。
|
||||
buildReminderRequest() {
|
||||
const params = ["pageForm=" + encodeURIComponent(JSON.stringify(this.pageForm))]
|
||||
this.selectedRows.map((row) => row.userId).forEach((userId) => {
|
||||
params.push("userIds=" + encodeURIComponent(userId))
|
||||
})
|
||||
return params.join("&")
|
||||
},
|
||||
|
||||
// 发送前由后端按当前筛选条件计算实际接收人数。
|
||||
async openReminder() {
|
||||
if (!this.pageForm.projectId) {
|
||||
this.$message.warning("请先选择福利项目")
|
||||
return
|
||||
}
|
||||
const response = await this.$axios.post(
|
||||
"/platform/welfare/selection/situation/previewReminder",
|
||||
this.buildReminderRequest(),
|
||||
{ headers: { "Content-Type": "application/x-www-form-urlencoded" } }
|
||||
)
|
||||
if (response.code !== 0) {
|
||||
this.$message.error(response.msg)
|
||||
return
|
||||
}
|
||||
if (response.data === 0) {
|
||||
this.$message.warning("当前筛选条件下没有可提醒的人员")
|
||||
return
|
||||
}
|
||||
this.$set(this, "reminderCount", response.data)
|
||||
this.$set(this, "reminderContent", "福利选择提醒:请及时完成本次福利选择。")
|
||||
this.$set(this, "reminderVisible", true)
|
||||
},
|
||||
|
||||
// 后端会在发送前再次计算接收人,确保发送范围符合当前权限和筛选条件。
|
||||
async sendReminder() {
|
||||
if (!this.reminderContent || !this.reminderContent.trim()) {
|
||||
this.$message.warning("请输入提醒内容")
|
||||
return
|
||||
}
|
||||
this.$set(this, "reminderSending", true)
|
||||
const request = this.buildReminderRequest() + "&content=" + encodeURIComponent(this.reminderContent.trim())
|
||||
try {
|
||||
const response = await this.$axios.post(
|
||||
"/platform/welfare/selection/situation/sendReminder",
|
||||
request,
|
||||
{ headers: { "Content-Type": "application/x-www-form-urlencoded" } }
|
||||
)
|
||||
if (response.code === 0) {
|
||||
this.$message.success(response.msg)
|
||||
this.closeReminder()
|
||||
} else {
|
||||
this.$message.error(response.msg)
|
||||
}
|
||||
} finally {
|
||||
this.$set(this, "reminderSending", false)
|
||||
}
|
||||
},
|
||||
|
||||
// 关闭提醒弹窗并清空输入内容,避免下次发送误用上次的消息。
|
||||
closeReminder() {
|
||||
this.$set(this, "reminderVisible", false)
|
||||
this.$set(this, "reminderContent", "")
|
||||
},
|
||||
|
||||
// 管理员待选
|
||||
proxySelect(row) {
|
||||
this.optionSelectVisible = true
|
||||
|
||||
Reference in New Issue
Block a user